40606 lines
6.0 MiB
40606 lines
6.0 MiB
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Aere Network <node@aere.network>
|
|
Date: Sun, 11 Oct 2026 11:17:06 +0000
|
|
Subject: [PATCH] Aere Network: the round in the post-quantum commit seal and the v3 anchor certificate (AIP-22 stage TR)
|
|
|
|
AERE patch 0010: the round-bound post-quantum commit seal, the v3 anchor certificate and the decided head, on top of patch 0009
|
|
|
|
Why this patch exists: below the stage TR height (aere.pq.commitRoundBlock, H_r) a post-quantum
|
|
commit seal signs the commit message of a block without its round, so seals given in different
|
|
rounds of the same height are interchangeable, and a certificate can count toward one round seals
|
|
that were given for another. This patch binds the round into the seal and into the anchor
|
|
certificate from H_r. H_r is not set on chain 2800 when this patch is published, and below H_r a
|
|
node built from patches 0001 and 0003 to 0010 executes, on every anchor of the chain, exactly the
|
|
decisions of a node built from patches 0001 and 0003 to 0009 (measured on real anchors of chains
|
|
2800 and 28001, byte for byte, with H_r unset and with H_r set above the anchors).
|
|
|
|
What it changes, as one delta over the tree produced by patches 0001 and 0003 to 0009:
|
|
- from H_r, the post-quantum commit seal (Falcon-512, and the SLH-DSA extras on the anchor
|
|
parent) signs keccak256(RLP["AERE-PQ-COMMIT-2", chainId, height, round, block hash]), with the
|
|
round of the commit; the message is computed in one place, used by the signer and by every
|
|
verifier;
|
|
- from H_r, the anchor certificate is version 3, RLP[3, round, [[scheme, index, signature], ...]],
|
|
with the round written once and covered by a new digest domain (AERE-PQ-ANCHOR-3) inside the
|
|
block hash preimage; every seal is verified over the message of that one round, and a
|
|
certificate that mixes rounds, or a v2 certificate at or above H_r, or a v3 certificate below
|
|
it, is refused with a named code (AERE-PQ-V3-01 to 08);
|
|
- "the parent is decided" (the finalized tag, the restart path, the decided-by evidence) needs at
|
|
least a quorum of verified members of the validator set of ONE round from H_r;
|
|
- the heard-seal store, the head-of-store file and the per-block seal record are keyed by height,
|
|
hash and round; a node puts its own seal in the store only once its commit has been sent;
|
|
- startup guards refuse an H_r that is not a Falcon-only anchor height and an effective threshold
|
|
step from H_r above the quorum of the set;
|
|
- the decided-head wiring of the state machine (inert while its height is not set) and the binding
|
|
of a proposal to its parent (acting from the stage 5 header height only), on which the round
|
|
binding is built;
|
|
- the tests of all of the above, with the vectors they share with the second client.
|
|
|
|
Not changed: the commit message on the wire (the round is already in its payload), prepare,
|
|
proposal and round-change messages, the stage 5 proposer seal, the header outside the certificate
|
|
element, and the single signature per round.
|
|
|
|
Nothing else is left out: patches 0001 and 0003 to 0010 applied on a pristine d2032017 checkout
|
|
reproduce the source tree of the distribution measured against this recipe, file for file, apart
|
|
from the in-file licence notices described below and three source comments that named internal
|
|
paths and now say the same thing without them (same number of lines, so the compiled classes are
|
|
unchanged).
|
|
|
|
Licence notices (Apache License 2.0, section 4(b)): every upstream file that this patch modifies
|
|
for the first time carries, inside the file, the notice "Modifications Copyright contributors to
|
|
the Aere Network" naming this patch; files already modified by an earlier patch keep the notice
|
|
that names it.
|
|
---
|
|
.../main/java/org/hyperledger/besu/controller/AereD412DecidedWiring.java | 491 ++++++
|
|
app/src/main/java/org/hyperledger/besu/controller/PqTipAdoptionGate.java | 110 +-
|
|
.../java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java | 164 +-
|
|
.../java/org/hyperledger/besu/controller/AereCommitRoundStartupTest.java | 296 ++++
|
|
app/src/test/java/org/hyperledger/besu/controller/AereD412BuilderTest.java | 402 +++++
|
|
.../java/org/hyperledger/besu/controller/AereD412DecidedWiringProbe.java | 112 ++
|
|
.../java/org/hyperledger/besu/controller/AereD412DecidedWiringTest.java | 456 +++++
|
|
.../java/org/hyperledger/besu/controller/AereRoundBoundRestartTest.java | 396 +++++
|
|
.../test/java/org/hyperledger/besu/controller/AereRoundFreeRestartTest.java | 330 ++++
|
|
.../java/org/hyperledger/besu/controller/PqTipAdoptionGateModeTest.java | 2 +-
|
|
.../java/org/hyperledger/besu/controller/PqTipAdoptionGateRoundTest.java | 160 ++
|
|
.../test/java/org/hyperledger/besu/controller/PqTipAdoptionGateSetTest.java | 405 +++++
|
|
.../besu/ethereum/eth/sync/BlockPropagationManagerDecidedTest.java | 309 ++++
|
|
.../org/hyperledger/besu/consensus/common/bft/AereCertifiedDecision.java | 288 ++++
|
|
.../hyperledger/besu/consensus/common/bft/AereDecidedBlockChoiceRule.java | 151 ++
|
|
.../java/org/hyperledger/besu/consensus/common/bft/AereDecidedHead.java | 1045 ++++++++++++
|
|
.../java/org/hyperledger/besu/consensus/common/bft/AerePqFinalityTags.java | 100 +-
|
|
.../java/org/hyperledger/besu/consensus/common/bft/BftBlockInterface.java | 3 +
|
|
.../main/java/org/hyperledger/besu/consensus/common/bft/BftExtraData.java | 119 +-
|
|
.../src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchor.java | 137 +-
|
|
.../main/java/org/hyperledger/besu/consensus/common/bft/PqAnchorConfig.java | 274 ++-
|
|
.../org/hyperledger/besu/consensus/common/bft/PqAnchorThresholdGuard.java | 195 ++-
|
|
.../src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchorV3.java | 747 ++++++++
|
|
.../main/java/org/hyperledger/besu/consensus/common/bft/PqSealCache.java | 1021 +++++++++--
|
|
.../main/java/org/hyperledger/besu/consensus/common/bft/PqSealStore.java | 276 ++-
|
|
.../java/org/hyperledger/besu/consensus/common/bft/PqSealWindowStore.java | 56 +-
|
|
.../besu/consensus/common/bft/blockcreation/BftBlockCreator.java | 2 +-
|
|
.../besu/consensus/common/bft/blockcreation/BftMiningCoordinator.java | 2 +-
|
|
.../besu/consensus/common/bft/blockcreation/PqAnchorProducer.java | 497 +++++-
|
|
.../hyperledger/besu/consensus/common/bft/messagewrappers/BftMessage.java | 2 +-
|
|
.../org/hyperledger/besu/consensus/common/bft/AereD454SealCacheTest.java | 16 +-
|
|
.../besu/consensus/common/bft/AereDecidedBlockChoiceRuleTest.java | 333 ++++
|
|
.../org/hyperledger/besu/consensus/common/bft/AereDecidedChainFixture.java | 123 ++
|
|
.../java/org/hyperledger/besu/consensus/common/bft/AereDecidedHeadTest.java | 356 ++++
|
|
.../org/hyperledger/besu/consensus/common/bft/AerePqFinalityTagsTest.java | 2 +-
|
|
.../hyperledger/besu/consensus/common/bft/AereRoundBoundMessageTest.java | 308 ++++
|
|
.../java/org/hyperledger/besu/consensus/common/bft/PqAnchorConfigTest.java | 7 +-
|
|
.../org/hyperledger/besu/consensus/common/bft/PqAnchorProducerCostTest.java | 4 +-
|
|
.../hyperledger/besu/consensus/common/bft/PqAnchorProducerRoundTest.java | 400 +++++
|
|
.../besu/consensus/common/bft/PqAnchorThresholdGuardRound06Test.java | 180 ++
|
|
.../besu/consensus/common/bft/PqAnchorThresholdGuardRoundTest.java | 91 +
|
|
.../org/hyperledger/besu/consensus/common/bft/PqAnchorV2ProducerTest.java | 18 +-
|
|
.../hyperledger/besu/consensus/common/bft/PqForkValidatorSetChangeTest.java | 4 +-
|
|
.../java/org/hyperledger/besu/consensus/common/bft/PqInertBinaryTest.java | 2 +-
|
|
.../org/hyperledger/besu/consensus/common/bft/PqSealCacheRoundTest.java | 522 ++++++
|
|
.../org/hyperledger/besu/consensus/common/bft/PqSealPersistenceTest.java | 12 +-
|
|
.../hyperledger/besu/consensus/common/bft/PqSealWindowPersistenceTest.java | 18 +-
|
|
.../org/hyperledger/besu/consensus/common/bft/PqSealWindowRoundTest.java | 204 +++
|
|
consensus/common/src/test/resources/aere-r1b/VECTORI-R1B.json | 1647 ++++++++++++++++++
|
|
.../hyperledger/besu/consensus/qbft/core/test/AereD412RealRoundTest.java | 299 ++++
|
|
.../hyperledger/besu/consensus/qbft/core/test/AereD412RoundHookTest.java | 175 ++
|
|
.../org/hyperledger/besu/consensus/qbft/core/messagewrappers/Proposal.java | 2 +-
|
|
.../hyperledger/besu/consensus/qbft/core/messagewrappers/RoundChange.java | 2 +-
|
|
.../besu/consensus/qbft/core/statemachine/AereDecidedConsensus.java | 1075 ++++++++++++
|
|
.../hyperledger/besu/consensus/qbft/core/statemachine/AereDecidedHook.java | 130 ++
|
|
.../besu/consensus/qbft/core/statemachine/AereDecisionEvidence.java | 1257 ++++++++++++++
|
|
.../hyperledger/besu/consensus/qbft/core/statemachine/QbftController.java | 58 +-
|
|
.../org/hyperledger/besu/consensus/qbft/core/statemachine/QbftRound.java | 161 +-
|
|
.../org/hyperledger/besu/consensus/qbft/core/types/QbftBlockHeader.java | 16 +
|
|
.../org/hyperledger/besu/consensus/qbft/core/validation/AereVoteCounts.java | 330 ++++
|
|
.../hyperledger/besu/consensus/qbft/core/validation/CommitValidator.java | 120 +-
|
|
.../hyperledger/besu/consensus/qbft/core/validation/MessageValidator.java | 28 +-
|
|
.../besu/consensus/qbft/core/validation/MessageValidatorFactory.java | 10 +-
|
|
.../besu/consensus/qbft/core/validation/PqCommitEnforcement.java | 138 +-
|
|
.../besu/consensus/qbft/core/validation/PqFinalityLayersGuard.java | 195 +++
|
|
.../hyperledger/besu/consensus/qbft/core/validation/ProposalValidator.java | 62 +
|
|
.../besu/consensus/qbft/core/statemachine/AereDecisionEvidenceTest.java | 677 ++++++++
|
|
.../besu/consensus/qbft/core/statemachine/AereLateSalvageRoundTest.java | 204 +++
|
|
.../besu/consensus/qbft/core/statemachine/AereRoundBoundCommitTest.java | 277 +++
|
|
.../besu/consensus/qbft/core/statemachine/AereRoundBoundEmitterTest.java | 354 ++++
|
|
.../besu/consensus/qbft/core/statemachine/AereRoundFreeCommitTest.java | 203 +++
|
|
.../besu/consensus/qbft/core/statemachine/PqLateSealSalvageTest.java | 2 +-
|
|
.../besu/consensus/qbft/core/statemachine/PqSealsWithoutProposalTest.java | 10 +-
|
|
.../hyperledger/besu/consensus/qbft/core/validation/AereD412Fixture.java | 3 +-
|
|
.../besu/consensus/qbft/core/validation/AereD437ParentBindingTest.java | 185 ++
|
|
.../besu/consensus/qbft/core/validation/AereRoundBoundCommitPathTest.java | 157 ++
|
|
.../hyperledger/besu/consensus/qbft/core/validation/AereVoteCountsTest.java | 224 +++
|
|
.../besu/consensus/qbft/core/validation/CommitValidatorAnchorFormTest.java | 4 +-
|
|
.../qbft/core/validation/MessageValidatorAnchorFormPlumbingTest.java | 4 +-
|
|
.../besu/consensus/qbft/core/validation/PqCommitRoundGuardTest.java | 121 ++
|
|
.../besu/consensus/qbft/core/validation/PqRoundBrakeStartupTest.java | 193 +++
|
|
.../main/java/org/hyperledger/besu/consensus/qbft/AereDecidedChainView.java | 271 +++
|
|
.../main/java/org/hyperledger/besu/consensus/qbft/QbftExtraDataCodec.java | 103 +-
|
|
.../hyperledger/besu/consensus/qbft/adaptor/QbftBlockCreatorAdaptor.java | 11 +-
|
|
.../org/hyperledger/besu/consensus/qbft/adaptor/QbftBlockHeaderAdaptor.java | 11 +
|
|
.../org/hyperledger/besu/consensus/qbft/adaptor/QbftBlockchainAdaptor.java | 42 +
|
|
.../org/hyperledger/besu/consensus/qbft/adaptor/QbftFinalStateImpl.java | 60 +-
|
|
.../besu/consensus/qbft/headervalidationrules/PqAnchorDigestRule.java | 50 +-
|
|
.../besu/consensus/qbft/headervalidationrules/PqAnchorSealsRule.java | 120 +-
|
|
.../hyperledger/besu/consensus/qbft/jsonrpc/methods/AereGetPqFinality.java | 249 ++-
|
|
.../java/org/hyperledger/besu/consensus/qbft/AereC1DecisionVectorsTest.java | 508 ++++++
|
|
.../besu/consensus/qbft/AereCertifiedDecisionRealAnchorsTest.java | 248 +++
|
|
.../java/org/hyperledger/besu/consensus/qbft/AereCertifiedDecisionTest.java | 385 +++++
|
|
.../org/hyperledger/besu/consensus/qbft/AereCertifiedDecisionV3Test.java | 377 +++++
|
|
.../java/org/hyperledger/besu/consensus/qbft/AereD412RealHeadersTest.java | 420 +++++
|
|
.../org/hyperledger/besu/consensus/qbft/AereProducerPendingRoundTest.java | 231 +++
|
|
.../org/hyperledger/besu/consensus/qbft/AereRoundBoundCertificateTest.java | 524 ++++++
|
|
.../hyperledger/besu/consensus/qbft/AereRoundBoundL1DifferentialTest.java | 469 +++++
|
|
.../org/hyperledger/besu/consensus/qbft/AereRoundFreeCertificateTest.java | 526 ++++++
|
|
.../org/hyperledger/besu/consensus/qbft/QbftControllerDecidedHeadTest.java | 1364 +++++++++++++++
|
|
.../hyperledger/besu/consensus/qbft/adaptor/AereV3ReconstructionTest.java | 125 ++
|
|
.../besu/consensus/qbft/headervalidationrules/PqAnchorDigestRuleTest.java | 2 +-
|
|
.../consensus/qbft/headervalidationrules/PqAnchorDisarmedWindowTest.java | 4 +-
|
|
.../besu/consensus/qbft/headervalidationrules/PqAnchorTestSupport.java | 2 +-
|
|
.../besu/consensus/qbft/headervalidationrules/PqAnchorV2RulesTest.java | 6 +-
|
|
.../besu/consensus/qbft/headervalidationrules/PqAnchorV3SealsRuleTest.java | 248 +++
|
|
.../besu/consensus/qbft/headervalidationrules/PqAnchorV3Test.java | 467 +++++
|
|
.../besu/consensus/qbft/headervalidationrules/PqHeaderSealStage5Test.java | 12 +-
|
|
.../besu/consensus/qbft/jsonrpc/methods/AereGetPqFinalityRoundTest.java | 211 +++
|
|
.../besu/consensus/qbft/jsonrpc/methods/AereGetPqFinalityTest.java | 2 +-
|
|
consensus/qbft/src/test/resources/aere-d412/2800-hibrid-10.properties | 23 +
|
|
consensus/qbft/src/test/resources/aere-d412/2800-manifest-13014000.json | 48 +
|
|
consensus/qbft/src/test/resources/aere-d412/2800-manifest-18082816.json | 66 +
|
|
.../qbft/src/test/resources/aere-d412/2800-registru-v2-13600000.properties | 63 +
|
|
consensus/qbft/src/test/resources/aere-d412/28001-registry-v3-3080010.json | 97 ++
|
|
consensus/qbft/src/test/resources/aere-d412/28001-registry-v3-3097600.json | 101 ++
|
|
consensus/qbft/src/test/resources/aere-d412/ancore-2800-diferential.json | 3197 +++++++++++++++++++++++++++++++++++
|
|
consensus/qbft/src/test/resources/aere-d412/blocuri-reale.json | 339 ++++
|
|
consensus/qbft/src/test/resources/aere-r1b/VECTORI-R1B.json | 1647 ++++++++++++++++++
|
|
.../java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java | 2 +-
|
|
.../org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java | 2 +-
|
|
.../java/org/hyperledger/besu/ethereum/mainnet/WithdrawalsValidator.java | 2 +-
|
|
.../src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeers.java | 2 +-
|
|
.../main/java/org/hyperledger/besu/ethereum/eth/sync/state/SyncState.java | 2 +-
|
|
.../java/org/hyperledger/besu/ethereum/eth/sync/state/SyncStateTest.java | 2 +-
|
|
ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPInput.java | 2 +-
|
|
evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java | 2 +-
|
|
evm/src/main/java/org/hyperledger/besu/evm/frame/TxValues.java | 2 +-
|
|
.../org/hyperledger/besu/evm/precompile/P256VerifyPrecompiledContract.java | 2 +-
|
|
129 files changed, 31523 insertions(+), 597 deletions(-)
|
|
|
|
diff --git a/app/src/main/java/org/hyperledger/besu/controller/AereD412DecidedWiring.java b/app/src/main/java/org/hyperledger/besu/controller/AereD412DecidedWiring.java
|
|
new file mode 100644
|
|
index 0000000000..b83fc8db34
|
|
--- /dev/null
|
|
+++ b/app/src/main/java/org/hyperledger/besu/controller/AereD412DecidedWiring.java
|
|
@@ -0,0 +1,491 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.controller;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AereCertifiedDecision;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedBlockChoiceRule;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead;
|
|
+import org.hyperledger.besu.consensus.common.bft.AerePqHeaderSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.AerePqIdentity;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftEventQueue;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSealCache;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSignerRegistry;
|
|
+import org.hyperledger.besu.consensus.common.bft.events.NewChainHead;
|
|
+import org.hyperledger.besu.consensus.common.bft.network.ValidatorMulticaster;
|
|
+import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
|
+import org.hyperledger.besu.consensus.qbft.AereDecidedChainView;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.AereDecidedConsensus;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCodec;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.PqCommitEnforcement;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.ethereum.chain.Blockchain;
|
|
+import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.rlp.RLP;
|
|
+
|
|
+import java.nio.file.Path;
|
|
+import java.time.Clock;
|
|
+import java.util.Collection;
|
|
+import java.util.List;
|
|
+import java.util.Locale;
|
|
+import java.util.Optional;
|
|
+import java.util.function.Consumer;
|
|
+import java.util.function.Function;
|
|
+import java.util.function.LongPredicate;
|
|
+import java.util.function.Predicate;
|
|
+
|
|
+import org.slf4j.Logger;
|
|
+import org.slf4j.LoggerFactory;
|
|
+
|
|
+/**
|
|
+ * AERE D-412 / the DECIDED HEAD (rule D), step 3: the decisions the QBFT controller builder makes
|
|
+ * about rule D, in one place a proof can call directly:
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>H_ev ({@value #PROPERTY_HEV} / {@value #ENV_HEV}): UNSET means rule D is off and the node is
|
|
+ * exactly as before; present but not a non-negative height refuses to start ({@value
|
|
+ * #CODE_CONF_01}), never a silent disarm;
|
|
+ * <li>the propagation adoption gate: with rule D it is ALLOW (the D-419 gate is kept as an OBSERVE
|
|
+ * counter and never refuses), and ENFORCE asked for explicitly refuses to start ({@value
|
|
+ * #CODE_CONF_02}, "replaced by rule D"); without rule D the gate is exactly today's;
|
|
+ * <li>the decided head, its block choice rule and the wiring go on VALIDATORS only (a node that seals
|
|
+ * or is in the set at the head); readers keep total difficulty, finalized (B1) and the anchor
|
|
+ * bound (B2), unchanged;
|
|
+ * <li>what a certified anchor proves decided has ONE answer, {@link AereCertifiedDecision} (teza Q3,
|
|
+ * D-470, 2026-10-01): below H_hdr the anchor's parent, from H_hdr its grandparent on f + 1
|
|
+ * re-verified seals of distinct members, with the parent at or above H_ev. Q3 ({@link
|
|
+ * #installConsensus}), the finalized tags (B1, the builder) and the restart ({@link
|
|
+ * #finalizedProves}) all read it;
|
|
+ * <li>at a restart D is taken from the durable file FIRST, and from the finalized tag only when it
|
|
+ * is what a canonical anchor above it decides and is on the durable D's line. The head the
|
|
+ * restored post-quantum commit seals proved ({@code sealedHeadEvidence}, 2026-10-01 morning) is
|
|
+ * GONE: those seals carry no round, so a quorum of them over a block never showed it decided
|
|
+ * (Teorema 1; RF1-4b measured it taking an undecided sibling). The window between the own
|
|
+ * round's import and the durable write of D is open again until the decision journal (project
|
|
+ * 2(c), steps 2 and on).
|
|
+ * </ul>
|
|
+ *
|
|
+ * <p>The builder's own lines (the adaptor and the final state with D, the wiring installed, the
|
|
+ * validator decision) are measured by {@code AereD412BuilderTest}, which runs the real builder.
|
|
+ */
|
|
+public final class AereD412DecidedWiring {
|
|
+
|
|
+ private static final Logger LOG = LoggerFactory.getLogger(AereD412DecidedWiring.class);
|
|
+
|
|
+ /** System property: H_ev, the height from which rule D applies. Unset: rule D is off. */
|
|
+ public static final String PROPERTY_HEV = "aere.d412.hev";
|
|
+
|
|
+ /** Environment twin of {@link #PROPERTY_HEV}. */
|
|
+ public static final String ENV_HEV = "AERE_D412_HEV";
|
|
+
|
|
+ /** H_ev is present but not a non-negative block height. */
|
|
+ public static final String CODE_CONF_01 = "AERE-D412-CONF-01";
|
|
+
|
|
+ /** ENFORCE of the propagation adoption gate was asked for on a node with rule D. */
|
|
+ public static final String CODE_CONF_02 = "AERE-D412-CONF-02";
|
|
+
|
|
+ private AereD412DecidedWiring() {}
|
|
+
|
|
+ /**
|
|
+ * H_ev from a property and an environment value (the property wins).
|
|
+ *
|
|
+ * @param property the system property value, possibly null
|
|
+ * @param env the environment value, possibly null
|
|
+ * @return H_ev, or {@link AerePqIdentity#NEVER} when neither is set
|
|
+ * @throws IllegalStateException {@value #CODE_CONF_01} when a value is present but not a
|
|
+ * non-negative decimal height
|
|
+ */
|
|
+ static long parseActivationHeight(final String property, final String env) {
|
|
+ final String raw = property != null ? property : env;
|
|
+ if (raw == null) {
|
|
+ return AerePqIdentity.NEVER;
|
|
+ }
|
|
+ try {
|
|
+ final long h = Long.parseLong(raw.trim());
|
|
+ if (h < 0) {
|
|
+ throw new NumberFormatException("negative");
|
|
+ }
|
|
+ return h;
|
|
+ } catch (final NumberFormatException e) {
|
|
+ throw new IllegalStateException(
|
|
+ CODE_CONF_01
|
|
+ + ": "
|
|
+ + PROPERTY_HEV
|
|
+ + " / "
|
|
+ + ENV_HEV
|
|
+ + " is set but not a non-negative block height: '"
|
|
+ + raw
|
|
+ + "'. A mistyped value must refuse to start, never silently disarm rule D.");
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * H_ev of this process.
|
|
+ *
|
|
+ * @return H_ev, or {@link AerePqIdentity#NEVER}
|
|
+ */
|
|
+ public static long activationHeightFromSystem() {
|
|
+ return parseActivationHeight(System.getProperty(PROPERTY_HEV), System.getenv(ENV_HEV));
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Whether rule D is configured.
|
|
+ *
|
|
+ * @param hEv H_ev
|
|
+ * @return true when H_ev is set
|
|
+ */
|
|
+ public static boolean configured(final long hEv) {
|
|
+ return hEv != AerePqIdentity.NEVER;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Refuse ENFORCE of the propagation adoption gate on a node with rule D.
|
|
+ *
|
|
+ * @param hEv H_ev
|
|
+ * @param property the gate-mode property value, possibly null
|
|
+ * @param env the gate-mode environment value, possibly null
|
|
+ * @throws IllegalStateException {@value #CODE_CONF_02}
|
|
+ */
|
|
+ static void verifyGateModeOrAbort(final long hEv, final String property, final String env) {
|
|
+ if (configured(hEv) && PqTipAdoptionGate.enforceRequested(property, env)) {
|
|
+ throw new IllegalStateException(
|
|
+ CODE_CONF_02
|
|
+ + ": the propagation adoption gate ENFORCE ("
|
|
+ + PqTipAdoptionGate.PROPERTY_MODE
|
|
+ + " / "
|
|
+ + PqTipAdoptionGate.ENV_MODE
|
|
+ + ") is replaced by rule D on this node (H_ev="
|
|
+ + hEv
|
|
+ + "); ENFORCE refused a block the fleet had decided and wedged a validator (D-419)."
|
|
+ + " Remove the setting: with rule D the gate is ALLOW and the decided head decides.");
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * {@link #verifyGateModeOrAbort} on this process's configuration.
|
|
+ *
|
|
+ * @param hEv H_ev
|
|
+ */
|
|
+ public static void verifyGateModeFromSystemOrAbort(final long hEv) {
|
|
+ verifyGateModeOrAbort(
|
|
+ hEv,
|
|
+ System.getProperty(PqTipAdoptionGate.PROPERTY_MODE),
|
|
+ System.getenv(PqTipAdoptionGate.ENV_MODE));
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The propagation adoption gate of this process: without rule D exactly today's gate; with rule D
|
|
+ * the same gate held in OBSERVE (a counter that adopts every block).
|
|
+ *
|
|
+ * @param hEv H_ev
|
|
+ * @param validatorProvider the validator provider
|
|
+ * @param localAddress this node's ECDSA address
|
|
+ * @param chainId the chain id
|
|
+ * @return the gate
|
|
+ */
|
|
+ public static PqTipAdoptionGate tipGate(
|
|
+ final long hEv,
|
|
+ final ValidatorProvider validatorProvider,
|
|
+ final Address localAddress,
|
|
+ final long chainId) {
|
|
+ if (!configured(hEv)) {
|
|
+ return new PqTipAdoptionGate(validatorProvider, localAddress, chainId);
|
|
+ }
|
|
+ return tipGate(
|
|
+ hEv,
|
|
+ validatorProvider,
|
|
+ localAddress,
|
|
+ chainId,
|
|
+ PqSealCache.instance(),
|
|
+ (n, i, m, s) -> PqSignerRegistry.falconSealSupport().verifyAtHistoric(n, i, m, s),
|
|
+ PqTipAdoptionGate.enforceRequested(
|
|
+ System.getProperty(PqTipAdoptionGate.PROPERTY_MODE),
|
|
+ System.getenv(PqTipAdoptionGate.ENV_MODE)),
|
|
+ AerePqHeaderSeal::active);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The gate with every input given (for the proofs): ENFORCE only when asked for AND rule D is off.
|
|
+ *
|
|
+ * @param hEv H_ev
|
|
+ * @param validatorProvider the validator provider
|
|
+ * @param localAddress this node's ECDSA address
|
|
+ * @param chainId the chain id
|
|
+ * @param cache the seal cache
|
|
+ * @param verifier the seal verifier
|
|
+ * @param enforceRequested whether ENFORCE was asked for
|
|
+ * @param stage5Active whether a height is at or above H_hdr
|
|
+ * @return the gate
|
|
+ */
|
|
+ static PqTipAdoptionGate tipGate(
|
|
+ final long hEv,
|
|
+ final ValidatorProvider validatorProvider,
|
|
+ final Address localAddress,
|
|
+ final long chainId,
|
|
+ final PqSealCache cache,
|
|
+ final PqTipAdoptionGate.SealVerifier verifier,
|
|
+ final boolean enforceRequested,
|
|
+ final LongPredicate stage5Active) {
|
|
+ final boolean enforce = enforceRequested && !configured(hEv);
|
|
+ return new PqTipAdoptionGate(
|
|
+ validatorProvider, localAddress, chainId, cache, verifier, enforce, stage5Active);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Whether this node is a validator for rule D: it seals (holds a validator's post-quantum key) or
|
|
+ * it is in the set at the head.
|
|
+ *
|
|
+ * @param signingEnabled whether this node seals
|
|
+ * @param validatorsAtHead the set at the head
|
|
+ * @param localAddress this node's ECDSA address
|
|
+ * @return true for a validator
|
|
+ */
|
|
+ public static boolean isValidatorNode(
|
|
+ final boolean signingEnabled,
|
|
+ final Collection<Address> validatorsAtHead,
|
|
+ final Address localAddress) {
|
|
+ if (signingEnabled) {
|
|
+ return true;
|
|
+ }
|
|
+ for (final Address a : validatorsAtHead) {
|
|
+ if (AerePqIdentity.isLocal(a, localAddress)) {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The node's {@link AereCertifiedDecision}: the ONE answer to "which block does this anchor's
|
|
+ * certificate prove decided?", read by Q3, by the finalized tags (B1) and by the restart (teza Q3,
|
|
+ * D-470, 2026-10-01). It replaces the Keff reading of 2026-09-30 ({@code certifiedAnchorKeff}): what
|
|
+ * proves is the number of seals of distinct members that verify NOW, at the parent's height, against
|
|
+ * the anchored registry, not the number the configuration asks for.
|
|
+ *
|
|
+ * @param anchorConfig the anchor configuration
|
|
+ * @param extraDataCodec decodes a header's extra data
|
|
+ * @param validatorProvider the validator provider (the set that decides a block)
|
|
+ * @param hEv H_ev, or {@link AerePqIdentity#NEVER}
|
|
+ * @return the decision
|
|
+ */
|
|
+ public static AereCertifiedDecision certifiedDecision(
|
|
+ final PqAnchorConfig anchorConfig,
|
|
+ final BftExtraDataCodec extraDataCodec,
|
|
+ final ValidatorProvider validatorProvider,
|
|
+ final long hEv) {
|
|
+ return certifiedDecision(
|
|
+ anchorConfig,
|
|
+ extraDataCodec,
|
|
+ validatorProvider,
|
|
+ hEv,
|
|
+ PqSignerRegistry.falconSealSupport(),
|
|
+ AerePqHeaderSeal::active);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * {@link #certifiedDecision(PqAnchorConfig, BftExtraDataCodec, ValidatorProvider, long)} with the
|
|
+ * registry and H_hdr given (for the proofs). The set that decides the parent p is the set FOR p
|
|
+ * ({@code getValidatorsForBlock}, the set R2 checks the certificate against), not the set after p:
|
|
+ * with a vote in p the two differ, and so does f.
|
|
+ *
|
|
+ * @param anchorConfig the anchor configuration
|
|
+ * @param extraDataCodec decodes a header's extra data
|
|
+ * @param validatorProvider the validator provider
|
|
+ * @param hEv H_ev
|
|
+ * @param registry the Falcon registry
|
|
+ * @param headerSealActive whether a height is at or above H_hdr
|
|
+ * @return the decision
|
|
+ */
|
|
+ static AereCertifiedDecision certifiedDecision(
|
|
+ final PqAnchorConfig anchorConfig,
|
|
+ final BftExtraDataCodec extraDataCodec,
|
|
+ final ValidatorProvider validatorProvider,
|
|
+ final long hEv,
|
|
+ final PqSignerRegistry registry,
|
|
+ final LongPredicate headerSealActive) {
|
|
+ return new AereCertifiedDecision(
|
|
+ anchorConfig,
|
|
+ extraDataCodec,
|
|
+ registry,
|
|
+ validatorProvider::getValidatorsForBlock,
|
|
+ headerSealActive,
|
|
+ hEv);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Whether the finalized tag's header F is proved decided, the guard a restart applies before D is
|
|
+ * taken from it: F counts only when a canonical anchor at F + 1 or F + 2 (the parent below H_hdr, the
|
|
+ * grandparent from H_hdr) has a certificate whose decision is EXACTLY F ({@link
|
|
+ * AereCertifiedDecision#decidedBy}, the same answer as Q3 and B1; teza Q3, D-470, 2026-10-01). Until
|
|
+ * that day the guard was "F + 1 is a certified anchor with Keff >= f + 1", which took the parent of an
|
|
+ * anchor whose round-free seals proved nothing (RF1-4).
|
|
+ *
|
|
+ * @param blockchain the chain
|
|
+ * @param anchorHeight whether a height is an anchor height
|
|
+ * @param decision the block a stored anchor's certificate decides, empty when none
|
|
+ * @return the predicate on F's header
|
|
+ */
|
|
+ public static Predicate<BlockHeader> finalizedProves(
|
|
+ final Blockchain blockchain,
|
|
+ final LongPredicate anchorHeight,
|
|
+ final Function<BlockHeader, Optional<AereDecidedHead.Decided>> decision) {
|
|
+ return f -> {
|
|
+ for (long a = f.getNumber() + 1L; a <= f.getNumber() + 2L; a++) {
|
|
+ if (!anchorHeight.test(a)) {
|
|
+ continue;
|
|
+ }
|
|
+ final Optional<BlockHeader> anchor = blockchain.getBlockHeader(a);
|
|
+ if (anchor.isEmpty()) {
|
|
+ continue;
|
|
+ }
|
|
+ final Optional<AereDecidedHead.Decided> decided = decision.apply(anchor.get());
|
|
+ if (decided.isPresent()
|
|
+ && decided.get().number() == f.getNumber()
|
|
+ && decided.get().hash().equals(f.getHash())) {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ return false;
|
|
+ };
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * {@link #finalizedProves(Blockchain, LongPredicate, Function)} over the node's anchor configuration
|
|
+ * and its {@link AereCertifiedDecision}.
|
|
+ *
|
|
+ * @param blockchain the chain
|
|
+ * @param anchorConfig the anchor configuration
|
|
+ * @param decision the node's decision ({@link #certifiedDecision})
|
|
+ * @return the predicate on the finalized tag's header
|
|
+ */
|
|
+ public static Predicate<BlockHeader> finalizedProves(
|
|
+ final Blockchain blockchain,
|
|
+ final PqAnchorConfig anchorConfig,
|
|
+ final AereCertifiedDecision decision) {
|
|
+ return finalizedProves(blockchain, anchorConfig::anchorAppliesAt, decision.over(blockchain));
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The decided head of a validator with rule D, with its block choice rule installed on the chain
|
|
+ * and D restored (Q6: the durable file first, then the finalized tag only when {@code
|
|
+ * finalizedProves} says a canonical anchor's certificate decides it and it is on the durable D's
|
|
+ * line). No other restart evidence: the head proved by restored post-quantum commit seals is gone
|
|
+ * (teza Q3, D-470, 2026-10-01). Nothing for a reader or without rule D.
|
|
+ *
|
|
+ * @param blockchain the chain
|
|
+ * @param hEv H_ev
|
|
+ * @param validator whether this node is a validator ({@link #isValidatorNode})
|
|
+ * @param dataDirectory the node's data directory
|
|
+ * @param alarm the path a human reads
|
|
+ * @param finalizedProves the restart guard on the finalized tag ({@link #finalizedProves})
|
|
+ * @return the decided head, or empty
|
|
+ */
|
|
+ public static Optional<AereDecidedHead> installHead(
|
|
+ final MutableBlockchain blockchain,
|
|
+ final long hEv,
|
|
+ final boolean validator,
|
|
+ final Path dataDirectory,
|
|
+ final Consumer<String> alarm,
|
|
+ final Predicate<BlockHeader> finalizedProves) {
|
|
+ if (!configured(hEv) || !validator) {
|
|
+ LOG.info(
|
|
+ "AERE D-412 rule D: {}; the block choice rule stays total difficulty on this node",
|
|
+ configured(hEv) ? "not a validator (reader)" : "H_ev unset");
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ final AereDecidedHead head =
|
|
+ new AereDecidedHead(
|
|
+ blockchain,
|
|
+ hEv,
|
|
+ dataDirectory.resolve(AereDecidedHead.FILE_NAME),
|
|
+ AereDecidedHead.DEFAULT_MAX_WALK,
|
|
+ alarm);
|
|
+ AereDecidedBlockChoiceRule.install(blockchain, head);
|
|
+ head.restore(List.of(), finalizedProves);
|
|
+ LOG.info(
|
|
+ "AERE D-412 rule D: armed from H_ev={} on this validator; decided head D={}, file {}",
|
|
+ hEv,
|
|
+ head.decided(),
|
|
+ head.file());
|
|
+ return Optional.of(head);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The alarm path of rule D (a second ERROR line prefixed "AERE ALARM", which log-based alerting can
|
|
+ * match on its own; the decided head already logs the CRIT line itself).
|
|
+ *
|
|
+ * @return a consumer that logs the alarm
|
|
+ */
|
|
+ public static Consumer<String> alarm() {
|
|
+ return m -> LOG.error("AERE ALARM {}", m);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Build and install the wiring of a validator with rule D (the process hook of the QBFT controller
|
|
+ * and round), connected to the BFT event queue for new chain head events and to a multicaster
|
|
+ * without the send-once filter for the echo.
|
|
+ *
|
|
+ * @param blockchain the chain
|
|
+ * @param head the decided head
|
|
+ * @param validatorProvider the validator provider
|
|
+ * @param blockInterface the QBFT block interface
|
|
+ * @param echoMulticaster sends to every validator without the send-once filter
|
|
+ * @param eventQueue the BFT event queue
|
|
+ * @param anchorConfig the anchor configuration (anchor heights)
|
|
+ * @param decision what a stored anchor's certificate decides (Q3; {@link #certifiedDecision})
|
|
+ * @param blockCodec encodes a block (its size in the collector)
|
|
+ * @return the installed wiring
|
|
+ */
|
|
+ public static AereDecidedConsensus installConsensus(
|
|
+ final MutableBlockchain blockchain,
|
|
+ final AereDecidedHead head,
|
|
+ final ValidatorProvider validatorProvider,
|
|
+ final QbftBlockInterface blockInterface,
|
|
+ final ValidatorMulticaster echoMulticaster,
|
|
+ final BftEventQueue eventQueue,
|
|
+ final PqAnchorConfig anchorConfig,
|
|
+ final AereCertifiedDecision decision,
|
|
+ final QbftBlockCodec blockCodec) {
|
|
+ return AereDecidedChainView.install(
|
|
+ blockchain,
|
|
+ head,
|
|
+ validatorProvider,
|
|
+ blockInterface,
|
|
+ echoMulticaster,
|
|
+ h -> eventQueue.add(new NewChainHead(h)),
|
|
+ anchorConfig::anchorAppliesAt,
|
|
+ decision.over(blockchain),
|
|
+ PqCommitEnforcement.fromSystemConfig(),
|
|
+ blockchain::getChainHeadBlockNumber,
|
|
+ b -> RLP.encode(out -> blockCodec.writeTo(b, out)).size(),
|
|
+ AereDecidedChainView.singleThreadExecutor(),
|
|
+ Clock.systemUTC());
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * A short description of the configuration, for the startup log.
|
|
+ *
|
|
+ * @param hEv H_ev
|
|
+ * @return the description
|
|
+ */
|
|
+ public static String describe(final long hEv) {
|
|
+ return configured(hEv)
|
|
+ ? String.format(Locale.ROOT, "rule D from H_ev=%d", hEv)
|
|
+ : "rule D off (H_ev unset)";
|
|
+ }
|
|
+}
|
|
diff --git a/app/src/main/java/org/hyperledger/besu/controller/PqTipAdoptionGate.java b/app/src/main/java/org/hyperledger/besu/controller/PqTipAdoptionGate.java
|
|
index 5daabf7a6a..998ca96554 100644
|
|
--- a/app/src/main/java/org/hyperledger/besu/controller/PqTipAdoptionGate.java
|
|
+++ b/app/src/main/java/org/hyperledger/besu/controller/PqTipAdoptionGate.java
|
|
@@ -11,67 +11,70 @@
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
package org.hyperledger.besu.controller;
|
|
|
|
import org.hyperledger.besu.consensus.common.bft.AerePqHeaderSeal;
|
|
import org.hyperledger.besu.consensus.common.bft.AerePqIdentity;
|
|
import org.hyperledger.besu.consensus.common.bft.BftHelpers;
|
|
import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
import org.hyperledger.besu.consensus.common.bft.PqSealCache;
|
|
import org.hyperledger.besu.consensus.common.bft.PqSignerRegistry;
|
|
import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
|
import org.hyperledger.besu.datatypes.Address;
|
|
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
import org.hyperledger.besu.ethereum.eth.sync.PropagatedBlockAdoptionGate;
|
|
|
|
import java.util.Collection;
|
|
import java.util.HashSet;
|
|
-import java.util.List;
|
|
import java.util.Set;
|
|
|
|
import org.apache.tuweni.bytes.Bytes;
|
|
import org.apache.tuweni.bytes.Bytes32;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
/**
|
|
* AERE D-412 (2026-09-26), Rule C, the consensus-aware implementation of {@link
|
|
* PropagatedBlockAdoptionGate.Gate}.
|
|
*
|
|
* <p>A validator does not ADOPT, as the new canonical head, a block that arrived by propagation at the
|
|
* tip of its own consensus height unless it holds a post-quantum COMMIT quorum for that exact block
|
|
* hash - the Falcon-512 commit seals it heard on AIP-21 Commit messages, re-verified now against the
|
|
* anchored registry. From H_hdr the header carries only the proposer's single seal, so a valid header no
|
|
* longer proves quorum agreement; that agreement lives in the seal cache, and a single-key forgery has
|
|
* none. The block stays VALID (this is fork choice, not validation), so:
|
|
*
|
|
* <ul>
|
|
* <li>Below H_hdr the gate is inert (the header's ECDSA committed-seals rule already proves a quorum).
|
|
* <li>A reader (not in the validator set) is not gated: it hears no commit seals, so it could never
|
|
* clear the gate and would stall; its canonicity is Rule B, out of this milestone's scope.
|
|
* <li>The sync downloader is a different code path and does not consult this gate, so a validator that
|
|
* fell behind catches up freely and only rejoins the gated tip once it hears commits again.
|
|
* </ul>
|
|
*
|
|
+ * <p>The set is the one that decides the block being adopted, set(h), from its own header; the quorum and the
|
|
+ * question whether this node is a validator at all are asked of that set (corrected 2026-10-09: the set of the
|
|
+ * parent's height was read until then, one block off after every vote).
|
|
+ *
|
|
* <p>The quorum proof is cryptographic: each cached seal is re-verified with Falcon over {@link
|
|
* PqAnchor#commitMessage} (the exact message a commit seal signs from the anchor form, which holds at
|
|
* every height at or above H_hdr), and only distinct verified signer indexes are counted, so junk in the
|
|
* cache cannot forge the proof. To clear the gate an adversary would need the commit quorum's distinct
|
|
* Falcon signatures over the block's commit message - which is exactly the agreement D-412 shows a single
|
|
* key cannot produce.
|
|
*
|
|
* <p><b>OBSERVE by default, since D-419 (2026-09-27).</b> Measured on testnet 28001: validator
|
|
* aere-testnet@1 spent five seconds importing its own 3,366-transaction block, missed the commit messages of
|
|
* the next height, and this gate then refused the block the other four had decided - 226 times over 1 h 45
|
|
* min - while its own consensus climbed to round 10 and could never decide that height again, and the sync
|
|
* downloader never engaged ({@code eth_syncing=false} 4,000 blocks behind). The third bullet above was the
|
|
* premise, and it did not hold. Meanwhile the one scenario the gate was written for had been measured on
|
|
* 2026-09-26 WITHOUT the gate: honest validators holding the honest block at the tip did not adopt the forged
|
|
* one (0 of 3), because the honest block wins the race; the real D-412 exposure is readers and catch-up,
|
|
* which Rule B1 (finality tags) and the anchor bound (PqAnchorSealsRule) cover. So the gate now defaults to
|
|
* OBSERVE: it computes exactly the same verdict and logs every block it WOULD refuse ({@value
|
|
* #OBSERVE_MARKER}), and adopts it. ENFORCE ({@value #PROPERTY_MODE}=enforce or {@value #ENV_MODE}=enforce)
|
|
* keeps the old behaviour and must be asked for; it has no release condition yet, so it can wedge a validator
|
|
* that missed a height. A safe release needs evidence one key cannot forge (a certified anchor above the
|
|
@@ -116,40 +119,41 @@ public class PqTipAdoptionGate implements PropagatedBlockAdoptionGate.Gate {
|
|
public interface SealVerifier {
|
|
/**
|
|
* Verify.
|
|
*
|
|
* @param blockNumber the height
|
|
* @param validatorIndex the signer index in the anchored registry
|
|
* @param message the commit message that was signed
|
|
* @param signature the Falcon signature
|
|
* @return true iff it verifies against the key bound at that height
|
|
*/
|
|
boolean verify(long blockNumber, int validatorIndex, Bytes message, Bytes signature);
|
|
}
|
|
|
|
private final ValidatorProvider validatorProvider;
|
|
private final Address localEcdsaAddress;
|
|
private final long chainId;
|
|
private final PqSealCache cache;
|
|
private final SealVerifier verifier;
|
|
private final boolean enforce;
|
|
private final java.util.function.LongPredicate stage5Active;
|
|
+ private final java.util.function.BiFunction<Long, Integer, Address> memberAt;
|
|
private final java.util.concurrent.atomic.AtomicLong wouldRefuse =
|
|
new java.util.concurrent.atomic.AtomicLong();
|
|
|
|
/**
|
|
* Production wiring; the mode comes from {@link #PROPERTY_MODE} / {@link #ENV_MODE} (OBSERVE unless
|
|
* enforce is asked for).
|
|
*
|
|
* @param validatorProvider the validator provider (the set at a height; ids from H_id, addresses below)
|
|
* @param localEcdsaAddress this node's ECDSA address (from its node key)
|
|
* @param chainId the chain id every commit message carries
|
|
*/
|
|
public PqTipAdoptionGate(
|
|
final ValidatorProvider validatorProvider, final Address localEcdsaAddress, final long chainId) {
|
|
this(
|
|
validatorProvider,
|
|
localEcdsaAddress,
|
|
chainId,
|
|
PqSealCache.instance(),
|
|
(n, i, m, s) -> PqSignerRegistry.falconSealSupport().verifyAtHistoric(n, i, m, s),
|
|
enforceRequested(System.getProperty(PROPERTY_MODE), System.getenv(ENV_MODE)),
|
|
@@ -158,111 +162,191 @@ public class PqTipAdoptionGate implements PropagatedBlockAdoptionGate.Gate {
|
|
|
|
/**
|
|
* Full wiring, for tests.
|
|
*
|
|
* @param validatorProvider the validator provider
|
|
* @param localEcdsaAddress this node's ECDSA address
|
|
* @param chainId the chain id
|
|
* @param cache the seal cache to read
|
|
* @param verifier the seal verifier
|
|
* @param enforce true to refuse (ENFORCE), false to log and adopt (OBSERVE)
|
|
* @param stage5Active whether a height is at or above H_hdr (production: {@link AerePqHeaderSeal#active})
|
|
*/
|
|
PqTipAdoptionGate(
|
|
final ValidatorProvider validatorProvider,
|
|
final Address localEcdsaAddress,
|
|
final long chainId,
|
|
final PqSealCache cache,
|
|
final SealVerifier verifier,
|
|
final boolean enforce,
|
|
final java.util.function.LongPredicate stage5Active) {
|
|
+ this(
|
|
+ validatorProvider,
|
|
+ localEcdsaAddress,
|
|
+ chainId,
|
|
+ cache,
|
|
+ verifier,
|
|
+ enforce,
|
|
+ stage5Active,
|
|
+ (n, i) -> PqSignerRegistry.falconSealSupport().addressForIndexAtHistoric(n, i));
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Full wiring with the member door (1(b), review of step 4), for tests.
|
|
+ *
|
|
+ * @param validatorProvider the validator provider
|
|
+ * @param localEcdsaAddress this node's ECDSA address
|
|
+ * @param chainId the chain id
|
|
+ * @param cache the seal cache to read
|
|
+ * @param verifier the seal verifier
|
|
+ * @param enforce true to refuse (ENFORCE), false to log and adopt (OBSERVE)
|
|
+ * @param stage5Active whether a height is at or above H_hdr
|
|
+ * @param memberAt the member a registry index is bound to at a height (from H_r - 1 a round counts members)
|
|
+ */
|
|
+ PqTipAdoptionGate(
|
|
+ final ValidatorProvider validatorProvider,
|
|
+ final Address localEcdsaAddress,
|
|
+ final long chainId,
|
|
+ final PqSealCache cache,
|
|
+ final SealVerifier verifier,
|
|
+ final boolean enforce,
|
|
+ final java.util.function.LongPredicate stage5Active,
|
|
+ final java.util.function.BiFunction<Long, Integer, Address> memberAt) {
|
|
this.validatorProvider = validatorProvider;
|
|
this.localEcdsaAddress = localEcdsaAddress;
|
|
this.chainId = chainId;
|
|
this.cache = cache;
|
|
this.verifier = verifier;
|
|
this.enforce = enforce;
|
|
this.stage5Active = stage5Active;
|
|
+ this.memberAt = memberAt;
|
|
}
|
|
|
|
/**
|
|
* Whether this gate refuses (ENFORCE) or only logs (OBSERVE).
|
|
*
|
|
* @return true in ENFORCE mode
|
|
*/
|
|
public boolean isEnforcing() {
|
|
return enforce;
|
|
}
|
|
|
|
/**
|
|
* How many propagated blocks this gate judged without a post-quantum commit quorum (refused in ENFORCE,
|
|
* logged and adopted in OBSERVE).
|
|
*
|
|
* @return the count since start
|
|
*/
|
|
public long wouldRefuseCount() {
|
|
return wouldRefuse.get();
|
|
}
|
|
|
|
@Override
|
|
public boolean mayAdopt(final BlockHeader header, final BlockHeader parent) {
|
|
final long h = header.getNumber();
|
|
// Below H_hdr the header still carries a quorum of ECDSA committed seals, whose upstream rule
|
|
// already refuses a single-key block; nothing to add here.
|
|
if (!stage5Active.test(h)) {
|
|
return true;
|
|
}
|
|
- final Collection<Address> validators = validatorProvider.getValidatorsForBlock(parent);
|
|
+ // 1(b) step 11 (2026-10-09, besu-consens/R1): the set, the quorum and "is this node a validator" are those of the
|
|
+ // block BEING ADOPTED, set(h), read from its own header (the block reaches the gate already validated, and the QBFT
|
|
+ // validators rule binds that list to getValidatorsAfterBlock(parent)); AereGetPqFinality reads the block it
|
|
+ // describes the same way. getValidatorsForBlock(parent) is set(p), the set of the height BELOW: until this date the
|
|
+ // gate read it, so after a decisive vote in p (on 2800: 18,083,403 voted 0xd38cb62a in, 9 -> 10) it judged h with
|
|
+ // the old Q (6 instead of 7, or 7 instead of 6 after a removal) and gated the node that left instead of the one
|
|
+ // that joined. Measured by PqTipAdoptionGateSetTest with a provider that answers by the header's number; the
|
|
+ // mocks with any() could not tell the two sets apart.
|
|
+ final Collection<Address> validators = validatorProvider.getValidatorsForBlock(header);
|
|
if (validators == null || validators.isEmpty()) {
|
|
return true;
|
|
}
|
|
// Only a validator hears commit seals; a reader would never clear the gate, so it is not gated
|
|
// (its canonicity is Rule B). isLocal matches this node as an ECDSA address OR its v3 id, so it is
|
|
// correct below H_id (addresses) and from stage 5 (ids), where the set carries ids.
|
|
boolean localIsValidator = false;
|
|
for (final Address v : validators) {
|
|
if (AerePqIdentity.isLocal(v, localEcdsaAddress)) {
|
|
localIsValidator = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!localIsValidator) {
|
|
return true;
|
|
}
|
|
final int quorum = BftHelpers.calculateRequiredValidatorQuorum(validators.size());
|
|
if (quorum <= 0) {
|
|
return true;
|
|
}
|
|
- final Bytes32 message = PqAnchor.commitMessage(chainId, h, header.getHash().getBytes());
|
|
- final List<FalconSeal> heard = cache.sealsFor(h, header.getHash());
|
|
- final Set<Integer> verified = new HashSet<>();
|
|
- for (final FalconSeal seal : heard) {
|
|
- if (seal == null || seal.getValidatorIndex() < 0 || seal.getSignature() == null) {
|
|
+ // AERE 1(b) (2026-10-01, section 3.1 I): each round on its own, over the message of that round, and the
|
|
+ // MAXIMUM over rounds is compared with the quorum; seals of different rounds are never added up. Below H_r the
|
|
+ // store holds one record per block and the message is COMMIT-1, as before (through the one place).
|
|
+ final boolean roundBound =
|
|
+ org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer.commitSealFormAt(
|
|
+ org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer.config(), h)
|
|
+ == org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer.CommitSealForm.ROUND_BOUND;
|
|
+ if (roundBound) {
|
|
+ // review of step 4: Commits of rounds r > 0 heard without the proposal are moved under their round first
|
|
+ org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer.resolvePendingFor(header);
|
|
+ }
|
|
+ Set<Integer> verified = new HashSet<>();
|
|
+ for (final java.util.Map.Entry<Integer, org.hyperledger.besu.consensus.common.bft.PqSealCache.RoundSeals> round :
|
|
+ cache.roundsFor(h, header.getHash()).entrySet()) {
|
|
+ final java.util.Optional<Bytes32> message =
|
|
+ roundBound
|
|
+ ? org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer.roundBoundMessage(
|
|
+ chainId, h, round.getKey(), header.getHash().getBytes())
|
|
+ : java.util.Optional.of(
|
|
+ org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer.roundFreeMessage(
|
|
+ chainId, h, header.getHash().getBytes()));
|
|
+ if (message.isEmpty()) {
|
|
continue;
|
|
}
|
|
- try {
|
|
- if (verifier.verify(h, seal.getValidatorIndex(), message, seal.getSignature())) {
|
|
- verified.add(seal.getValidatorIndex());
|
|
+ final Set<Integer> ofRound = new HashSet<>();
|
|
+ final Set<Address> membersOfRound = new HashSet<>();
|
|
+ for (final FalconSeal seal : round.getValue().falcon()) {
|
|
+ if (seal == null || seal.getValidatorIndex() < 0 || seal.getSignature() == null) {
|
|
+ continue;
|
|
+ }
|
|
+ try {
|
|
+ // review of step 4: from H_r - 1 a round counts DISTINCT ELIGIBLE MEMBERS of the set (as R2 and decidedBy);
|
|
+ // below H_r the count of before, call by call (L1)
|
|
+ Address who = null;
|
|
+ if (roundBound) {
|
|
+ who = memberAt.apply(h, seal.getValidatorIndex());
|
|
+ if (who == null || !validators.contains(who) || membersOfRound.contains(who)) {
|
|
+ continue;
|
|
+ }
|
|
+ }
|
|
+ if (verifier.verify(h, seal.getValidatorIndex(), message.get(), seal.getSignature())) {
|
|
+ ofRound.add(seal.getValidatorIndex());
|
|
+ if (who != null) {
|
|
+ membersOfRound.add(who);
|
|
+ }
|
|
+ }
|
|
+ } catch (final RuntimeException e) {
|
|
+ // a seal this node cannot judge is not counted; never a pass
|
|
+ LOG.debug("AERE D-412: seal of index {} for block {} could not be verified ({})", seal.getValidatorIndex(), h, e.toString());
|
|
}
|
|
- } catch (final RuntimeException e) {
|
|
- // a seal this node cannot judge is not counted; never a pass
|
|
- LOG.debug("AERE D-412: seal of index {} for block {} could not be verified ({})", seal.getValidatorIndex(), h, e.toString());
|
|
+ }
|
|
+ if (ofRound.size() > verified.size()) {
|
|
+ verified = ofRound;
|
|
}
|
|
}
|
|
final boolean ok = verified.size() >= quorum;
|
|
if (ok) {
|
|
return true;
|
|
}
|
|
wouldRefuse.incrementAndGet();
|
|
if (!enforce) {
|
|
// D-419: OBSERVE. Same verdict, recorded, and the block is adopted as before the gate existed.
|
|
LOG.info(
|
|
"{} propagated block {} at tip height {}: it holds {} verified post-quantum commit seal(s), "
|
|
+ "quorum is {}; adopting it (observe mode, D-419).",
|
|
OBSERVE_MARKER,
|
|
header.getHash(),
|
|
h,
|
|
verified.size(),
|
|
quorum);
|
|
return true;
|
|
}
|
|
LOG.info(
|
|
diff --git a/app/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java b/app/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java
|
|
index afca7aca58..fc53798fd9 100644
|
|
--- a/app/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java
|
|
+++ b/app/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java
|
|
@@ -13,40 +13,42 @@
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
* found, as section 4(c) requires. The change itself is in patches/0003-aere-pq-anchor.patch.
|
|
*/
|
|
package org.hyperledger.besu.controller;
|
|
|
|
import static com.google.common.base.Preconditions.checkNotNull;
|
|
|
|
import org.hyperledger.besu.config.BftConfigOptions;
|
|
import org.hyperledger.besu.config.BftFork;
|
|
import org.hyperledger.besu.config.JsonGenesisConfigOptions;
|
|
import org.hyperledger.besu.config.QbftConfigOptions;
|
|
import org.hyperledger.besu.config.QbftFork;
|
|
import org.hyperledger.besu.consensus.common.BftValidatorOverrides;
|
|
import org.hyperledger.besu.consensus.common.EpochManager;
|
|
import org.hyperledger.besu.consensus.common.ForksSchedule;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereCertifiedDecision;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead;
|
|
import org.hyperledger.besu.consensus.common.bft.AerePqFinality;
|
|
import org.hyperledger.besu.consensus.common.bft.AerePqFinalityTags;
|
|
import org.hyperledger.besu.consensus.common.bft.AerePqHeaderSeal;
|
|
import org.hyperledger.besu.consensus.common.bft.AerePqIdentity;
|
|
import org.hyperledger.besu.consensus.common.bft.BftBlockInterface;
|
|
import org.hyperledger.besu.consensus.common.bft.BftContext;
|
|
import org.hyperledger.besu.consensus.common.bft.BftEventQueue;
|
|
import org.hyperledger.besu.consensus.common.bft.BftExecutors;
|
|
import org.hyperledger.besu.consensus.common.bft.BftProcessor;
|
|
import org.hyperledger.besu.consensus.common.bft.BftProtocolSchedule;
|
|
import org.hyperledger.besu.consensus.common.bft.BftRoundExpiryTimeCalculator;
|
|
import org.hyperledger.besu.consensus.common.bft.BlockTimer;
|
|
import org.hyperledger.besu.consensus.common.bft.EthSynchronizerUpdater;
|
|
import org.hyperledger.besu.consensus.common.bft.EventMultiplexer;
|
|
import org.hyperledger.besu.consensus.common.bft.FalconSealSupport;
|
|
import org.hyperledger.besu.consensus.common.bft.HybridSealSupport;
|
|
import org.hyperledger.besu.consensus.common.bft.MessageTracker;
|
|
import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
import org.hyperledger.besu.consensus.common.bft.PqAnchorSyncModeGuard;
|
|
import org.hyperledger.besu.consensus.common.bft.PqAnchorThresholdGuard;
|
|
@@ -466,40 +468,52 @@ public class QbftBesuControllerBuilder extends BesuControllerBuilder {
|
|
// hold its row's keys, or it would go mute at that epoch; refuse to start instead. Inert without H_k.
|
|
FalconSealSupport.instance()
|
|
.verifyLocalKeysCoverV3EpochsOrAbort(Util.publicKeyToAddress(nodeKey.getPublicKey()));
|
|
HybridSealSupport.instance()
|
|
.verifyLocalKeysCoverV3EpochsOrAbort(Util.publicKeyToAddress(nodeKey.getPublicKey()));
|
|
// AERE AIP-22 stage 4: H_fin (aere.pq.finalityBlock), from which a message's author is the id of its post-quantum seal's
|
|
// index once that seal verifies, and the envelope's ECDSA is not read; refuses unless the keys are read from the v3 epochs
|
|
// at or below it (AERE-PQC-FIN-01). Inert when unset, which is every chain today.
|
|
AerePqFinality.installFromSystemProperties(aereAnchorConfig.chainId());
|
|
// ...and the four seal layers must be armed at or below it (AERE-PQC-FIN-02): the commit layer is the one that judges a
|
|
// COMMIT's seal (its author is bound to the commit seal's signer), and the layers stay the second judge of the rest.
|
|
PqFinalityLayersGuard.verifyOrAbort(AerePqFinality.finalityBlock());
|
|
// ...and a node that seals must seal all four messages from H_fin, or it would be mute there (AERE-PQC-FIN-03)
|
|
PqFinalityLayersGuard.verifyEmissionOrAbort(
|
|
AerePqFinality.finalityBlock(),
|
|
FalconSealSupport.instance().signingEnabled(),
|
|
FalconSealSupport.instance().attachBlock(),
|
|
FalconSealSupport.proposalAttachBlock(),
|
|
FalconSealSupport.prepareAttachBlock(),
|
|
FalconSealSupport.roundChangeAttachBlock());
|
|
+ // AERE 1(b) (2026-10-01, project section 2.3): H_r, the height from which the post-quantum commit seal binds its
|
|
+ // round. ROUND-02 beside FIN-02: with H_fin armed and H_r unset or above it, the round of a commit would be bound by
|
|
+ // ECDSA only between the two; refused unless confirmed with lateAfterFinality EQUAL to H_fin (28001 and the
|
|
+ // rehearsal chains, where H_fin came first). ROUND-03: from H_r the commit seal binds the chain id, which must be the
|
|
+ // genesis chain id. Both inert without H_fin / H_r (L1). The COMMIT-ROUND line is the second source the gates read
|
|
+ // (the first is the live process).
|
|
+ final long aereGenesisChainId =
|
|
+ genesisConfigOptions.getChainId().map(java.math.BigInteger::longValue).orElse(0L);
|
|
+ // 1(b) step 11 (2026-10-09): the H_r checks of startup (ROUND-02 with its brake exception, the late confirmation,
|
|
+ // ROUND-03, the COMMIT-ROUND line) live in ONE method of this class, which build() calls here and the probes call
|
|
+ // too (AereCommitRoundStartupTest), so the startup path itself is measured and not a copy of it.
|
|
+ verifyCommitRoundAtStartup(AerePqFinality.finalityBlock(), aereAnchorConfig, aereGenesisChainId);
|
|
// AERE AIP-22 stage 5: H_hdr (aere.pq.headerBlock), from which a header carries the proposer's post-quantum seal
|
|
// and no ECDSA committed seal; refuses unless H_fin is at or below it (AERE-PQC-HDR-01). Inert when unset.
|
|
AerePqHeaderSeal.installFromSystemProperties();
|
|
if (AerePqHeaderSeal.headerBlock() != AerePqIdentity.NEVER) {
|
|
LOG.info(
|
|
"AERE PQ HEADER: H_hdr armed at {}; from it a header carries the proposer's post-quantum seal and NO ECDSA"
|
|
+ " committed seal",
|
|
AerePqHeaderSeal.headerBlock());
|
|
}
|
|
if (AerePqFinality.finalityBlock() != AerePqIdentity.NEVER) {
|
|
LOG.info(
|
|
"AERE PQ FINALITY: H_fin armed at {}; from it a message's author is the id of its VERIFIED post-quantum seal and the"
|
|
+ " envelope's ECDSA is not read (four seal layers armed at or below it, this node seals: {})",
|
|
AerePqFinality.finalityBlock(),
|
|
FalconSealSupport.instance().signingEnabled());
|
|
}
|
|
|
|
PqAnchorSyncModeGuard.verifySyncModeOrAbort(
|
|
syncConfig == null || syncConfig.getSyncMode() == null
|
|
? null
|
|
@@ -566,110 +580,145 @@ public class QbftBesuControllerBuilder extends BesuControllerBuilder {
|
|
aereCapFereastra.getNumber(),
|
|
aereInaltime ->
|
|
blockchain.getBlockHeader(aereInaltime).map(BlockHeader::getHash),
|
|
PqSignerRegistry.falconSealSupport());
|
|
LOG.info(
|
|
"AERE FEREASTRA-SIGILII (AIP-21): {} VERIFIED seal(s) restored into the finality window "
|
|
+ "below chain head {}; aere_getPqFinality answers for those blocks again.",
|
|
aereFereastraRestaurata,
|
|
aereCapFereastra.getNumber());
|
|
} catch (final Exception e) {
|
|
LOG.warn(
|
|
"AERE FEREASTRA-SIGILII (AIP-21): the finality window could not be restored ({}); the "
|
|
+ "node answers 'unavailable' for blocks heard before this restart, as before.",
|
|
e.toString());
|
|
}
|
|
}
|
|
|
|
final BftExecutors bftExecutors =
|
|
BftExecutors.create(metricsSystem, BftExecutors.ConsensusType.QBFT);
|
|
final QbftBlockCodec blockEncoder = new QbftBlockCodecAdaptor(qbftExtraDataCodec);
|
|
+ // AERE 1(b): the producer resolves the pending round-bound seals (D-339 at r > 0) of an anchor's parent by
|
|
+ // rebuilding the parent's round-r hash, which needs this chain's extraData codec.
|
|
+ org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer.useExtraDataCodec(
|
|
+ qbftExtraDataCodec);
|
|
|
|
final Address localAddress = Util.publicKeyToAddress(nodeKey.getPublicKey());
|
|
final BftProtocolSchedule bftProtocolSchedule = (BftProtocolSchedule) protocolSchedule;
|
|
QbftProtocolSchedule qbftProtocolSchedule =
|
|
new QbftProtocolScheduleAdaptor(bftProtocolSchedule, protocolContext);
|
|
final QbftBlockCreatorFactory blockCreatorFactory =
|
|
new QbftBlockCreatorFactory(
|
|
transactionPool,
|
|
protocolContext,
|
|
bftProtocolSchedule,
|
|
qbftForksSchedule,
|
|
miningConfiguration,
|
|
localAddress,
|
|
qbftExtraDataCodec,
|
|
ethProtocolManager.ethContext().getScheduler());
|
|
|
|
final ValidatorProvider validatorProvider;
|
|
if (qbftConfig.getStartBlock().isPresent()) {
|
|
validatorProvider =
|
|
protocolContext
|
|
.getConsensusContext(BftContext.class, qbftConfig.getStartBlock().getAsLong())
|
|
.getValidatorProvider();
|
|
} else {
|
|
validatorProvider =
|
|
protocolContext.getConsensusContext(BftContext.class).getValidatorProvider();
|
|
}
|
|
|
|
// AERE D-412 (2026-09-26), Rule C: arm the propagation adoption gate. From AIP-22 stage 5 a valid
|
|
// header carries only the proposer's single Falcon seal, so it no longer proves a quorum agreed the
|
|
// block; a single key could forge one and, until this gate, honest validators adopted it via NewBlock
|
|
// and built on top (measured on rep28098). The gate lets this node refuse to ADOPT such a propagated
|
|
// block at the tip of its own consensus height unless it holds a post-quantum commit quorum for it
|
|
// (heard on AIP-21 Commit seals). Block VALIDITY is unchanged (sync still imports it); only
|
|
// ADOPTION-at-the-tip is gated, only for a validator, only from H_hdr. Inert here on any chain whose
|
|
// H_hdr is unset, which is chain 2800 today. Placed after the validator set is resolved (localAddress
|
|
// and validatorProvider both exist) and before the network and the QBFT machine start.
|
|
// D-419 (2026-09-27): the gate defaults to OBSERVE (logs every block it would refuse, adopts it); ENFORCE
|
|
// wedged a validator that missed one height's commits on testnet 28001 and must be asked for explicitly.
|
|
+ // AERE D-412 rule D (step 3, 2026-09-30): H_ev (aere.d412.hev) UNSET keeps everything below exactly as
|
|
+ // it was. SET: the gate is ALLOW (kept as an OBSERVE counter, never refusing) because the decided head
|
|
+ // replaces it, and ENFORCE asked for explicitly refuses to start (AERE-D412-CONF-02).
|
|
+ final long aereD412Hev = AereD412DecidedWiring.activationHeightFromSystem();
|
|
+ AereD412DecidedWiring.verifyGateModeFromSystemOrAbort(aereD412Hev);
|
|
+ LOG.info("AERE D-412: {}", AereD412DecidedWiring.describe(aereD412Hev));
|
|
if (aereAnchorConfig.everActive()) {
|
|
final PqTipAdoptionGate tipGate =
|
|
- new PqTipAdoptionGate(validatorProvider, localAddress, aereAnchorConfig.chainId());
|
|
+ AereD412DecidedWiring.tipGate(
|
|
+ aereD412Hev, validatorProvider, localAddress, aereAnchorConfig.chainId());
|
|
PropagatedBlockAdoptionGate.install(tipGate);
|
|
LOG.info(
|
|
"AERE D-412: propagation adoption gate armed in {} mode; a propagated block at the tip {} "
|
|
+ "without a post-quantum commit quorum from H_hdr={} (unset means never on this node).",
|
|
tipGate.isEnforcing() ? "ENFORCE" : "OBSERVE",
|
|
tipGate.isEnforcing() ? "is NOT adopted" : "is adopted and logged",
|
|
AerePqHeaderSeal.headerBlock());
|
|
}
|
|
|
|
- // AERE D-412 (2026-09-26), Rule B1: post-quantum FINALITY TAGS (see AerePqFinalityTags). finalized/safe = the parent of the
|
|
- // last canonical anchor that carries a certificate (v1 Falcon list OR v2 scheme-tagged certificate); monotonic; never moved
|
|
- // back by a reorg (AERE-PQC-FIN-01). No validity, fork-choice or import is touched. Proven live on rep28098 2026-09-26.
|
|
+ // AERE D-412 (2026-09-26), Rule B1: post-quantum FINALITY TAGS (see AerePqFinalityTags). finalized/safe = the block the
|
|
+ // last canonical anchor's certificate DECIDES; monotonic; never moved back by a reorg (AERE-PQC-FIN-01). No validity,
|
|
+ // fork-choice or import is touched. Proven live on rep28098 2026-09-26.
|
|
+ // AERE-Q3-BUNIC (teza Q3, D-470, 2026-10-01): "decides" has ONE answer, AereCertifiedDecision, read here, by Q3 and by the
|
|
+ // restart: below H_hdr the anchor's parent (as before), from H_hdr its grandparent on f + 1 re-verified seals of distinct
|
|
+ // members with the parent at or above H_ev. The post-quantum commit seal carries no round, so K seals over the parent
|
|
+ // never showed the parent decided (Teorema 1, AereRoundFreeCertificateTest). With H_ev unset the tags do not move above
|
|
+ // H_hdr on this node: nothing there proves a block decided.
|
|
+ final AereCertifiedDecision aereCertifiedDecision =
|
|
+ AereD412DecidedWiring.certifiedDecision(
|
|
+ aereAnchorConfig, qbftExtraDataCodec, validatorProvider, aereD412Hev);
|
|
if (aereAnchorConfig.everActive()) {
|
|
- final QbftExtraDataCodec codecForTags = qbftExtraDataCodec;
|
|
- AerePqFinalityTags.install(
|
|
- aereAnchorConfig,
|
|
- blockchain,
|
|
- h -> {
|
|
- try {
|
|
- return AerePqFinalityTags.carriesCertificate(codecForTags.decodeRaw(h.getExtraData()));
|
|
- } catch (final RuntimeException e) {
|
|
- return false; // an undecodable header carries nothing this rule can rely on
|
|
- }
|
|
- });
|
|
+ AerePqFinalityTags.installDecided(
|
|
+ aereAnchorConfig, blockchain, aereCertifiedDecision.over(blockchain));
|
|
LOG.info(
|
|
- "AERE D-412 B1: finalized/safe tags follow the last certified anchor's parent (interval {} at the head).",
|
|
+ "AERE D-412 B1: finalized/safe tags follow what the last certified anchor decides (interval {} at the head).",
|
|
aereAnchorConfig.intervalAt(blockchain.getChainHeadBlockNumber()));
|
|
}
|
|
|
|
+ // AERE D-412 rule D (step 3): the DECIDED HEAD, on validators only. Its block choice rule is installed on
|
|
+ // the chain (a head compatible with D beats an incompatible one, whatever its difficulty), D is restored
|
|
+ // from the durable file and the finalized tag (B1, set just above), and D is handed to the adaptor and the
|
|
+ // final state below, so this node's consensus runs on D, not on a provisional canonical head. A reader, or
|
|
+ // any node with H_ev unset, gets nothing here and stays exactly as before. The durable D is taken FIRST; the
|
|
+ // finalized tag counts at this restart only when it is what a canonical anchor's certificate decides
|
|
+ // (AereCertifiedDecision) and it is on the durable D's line. A durable D whose block was lost stays a floor
|
|
+ // below which the node neither proposes nor votes. 2026-10-01 (teza Q3, D-470): the head proved by the
|
|
+ // restored post-quantum commit seals is NO LONGER taken (sealedHeadEvidence is gone): those seals carry no
|
|
+ // round, so a quorum of them never showed a block decided (RF1-4b took an undecided sibling with it).
|
|
+ final AereDecidedHead aereDecidedHead =
|
|
+ AereD412DecidedWiring.installHead(
|
|
+ blockchain,
|
|
+ aereD412Hev,
|
|
+ AereD412DecidedWiring.configured(aereD412Hev)
|
|
+ && AereD412DecidedWiring.isValidatorNode(
|
|
+ FalconSealSupport.instance().signingEnabled(),
|
|
+ validatorProvider.getValidatorsAtHead(),
|
|
+ localAddress),
|
|
+ dataDirectory,
|
|
+ AereD412DecidedWiring.alarm(),
|
|
+ AereD412DecidedWiring.finalizedProves(
|
|
+ blockchain, aereAnchorConfig, aereCertifiedDecision))
|
|
+ .orElse(null);
|
|
+
|
|
// AERE GARDA-PRAG (2026-08-02): refuse to start on a seal threshold that STOPS the chain.
|
|
//
|
|
// Measured before this line was written: nothing anywhere refused a threshold value. Searched
|
|
// the whole fork tree for any occurrence of minSeals near quorum, throw, refuse, abort or
|
|
// Illegal, and there were ZERO. PqAnchorConfig rejects a negative K and a step scheduled below
|
|
// the activation height, and nothing else; the only other check, PqAnchorProducer's
|
|
// warnIfActivationHeightCanRefuse, writes one LOG.error and returns. So a value at or above the
|
|
// QBFT quorum was a configuration a node accepted in silence and then halted on.
|
|
//
|
|
// Placed here rather than beside the other three startup guards because this is the FIRST point
|
|
// at which the validator set is resolved, and the bound is a function of its size. It is still
|
|
// before the network exists (ValidatorPeers is built below) and before the QBFT state machine is
|
|
// created, so a refusal here is a clean refusal to start rather than a mid-flight halt.
|
|
PqAnchorThresholdGuard.verifyThresholdAgainstQuorumOrAbort(
|
|
aereAnchorConfig, validatorProvider.getValidatorsAtHead().size());
|
|
final QbftValidatorProvider qbftValidatorProvider =
|
|
new QbftValidatorProviderAdaptor(validatorProvider);
|
|
|
|
final QbftBlockInterface qbftBlockInterface = new QbftBlockInterfaceAdaptor(bftBlockInterface);
|
|
|
|
@@ -682,41 +731,42 @@ public class QbftBesuControllerBuilder extends BesuControllerBuilder {
|
|
|
|
final UniqueMessageMulticaster uniqueMessageMulticaster =
|
|
new UniqueMessageMulticaster(peers, qbftConfig.getGossipedHistoryLimit());
|
|
|
|
final QbftGossiperImpl gossiper = new QbftGossiperImpl(uniqueMessageMulticaster, blockEncoder);
|
|
|
|
final QbftFinalState finalState =
|
|
new QbftFinalStateImpl(
|
|
validatorProvider,
|
|
nodeKey,
|
|
Util.publicKeyToAddress(nodeKey.getPublicKey()),
|
|
proposerSelector,
|
|
uniqueMessageMulticaster,
|
|
new RoundTimer(
|
|
bftEventQueue,
|
|
new BftRoundExpiryTimeCalculator(
|
|
Duration.ofSeconds(qbftConfig.getRequestTimeoutSeconds())),
|
|
bftExecutors),
|
|
new BlockTimer(bftEventQueue, qbftForksSchedule, bftExecutors, clock),
|
|
new QbftBlockCreatorFactoryAdaptor(blockCreatorFactory, qbftExtraDataCodec),
|
|
- clock);
|
|
+ clock,
|
|
+ aereDecidedHead);
|
|
|
|
final MessageValidatorFactory messageValidatorFactory =
|
|
new MessageValidatorFactory(
|
|
proposerSelector, qbftProtocolSchedule, qbftValidatorProvider, qbftBlockInterface);
|
|
|
|
final Subscribers<QbftMinedBlockObserver> minedBlockObservers = Subscribers.create();
|
|
minedBlockObservers.subscribe(
|
|
qbftBlock -> ethProtocolManager.blockMined(AdaptorUtil.toBesuBlock(qbftBlock)));
|
|
minedBlockObservers.subscribe(
|
|
qbftBlock ->
|
|
blockLogger(transactionPool, localAddress)
|
|
.blockMined(AdaptorUtil.toBesuBlock(qbftBlock)));
|
|
|
|
final EthSynchronizerUpdater synchronizerUpdater =
|
|
new EthSynchronizerUpdater(ethProtocolManager.ethContext().getEthPeers());
|
|
final FutureMessageBuffer<QbftMessage> futureMessageBuffer =
|
|
new FutureMessageBuffer<>(
|
|
qbftConfig.getFutureMessagesMaxDistance(),
|
|
qbftConfig.getFutureMessagesLimit(),
|
|
blockchain.getChainHeadBlockNumber(),
|
|
@@ -731,47 +781,62 @@ public class QbftBesuControllerBuilder extends BesuControllerBuilder {
|
|
finalState,
|
|
qbftBlockInterface,
|
|
qbftProtocolSchedule,
|
|
minedBlockObservers,
|
|
messageValidatorFactory,
|
|
messageFactory);
|
|
QbftBlockHeightManagerFactory qbftBlockHeightManagerFactory =
|
|
new QbftBlockHeightManagerFactory(
|
|
finalState,
|
|
qbftRoundFactory,
|
|
messageValidatorFactory,
|
|
messageFactory,
|
|
qbftValidatorProvider,
|
|
new QbftValidatorModeTransitionLoggerAdaptor(
|
|
new ValidatorModeTransitionLogger(qbftForksSchedule)));
|
|
|
|
qbftBlockHeightManagerFactory.isEarlyRoundChangeEnabled(isEarlyRoundChangeEnabled);
|
|
|
|
final QbftEventHandler qbftController =
|
|
new QbftController(
|
|
- new QbftBlockchainAdaptor(blockchain),
|
|
+ new QbftBlockchainAdaptor(blockchain, aereDecidedHead),
|
|
finalState,
|
|
qbftBlockHeightManagerFactory,
|
|
gossiper,
|
|
duplicateMessageTracker,
|
|
futureMessageBuffer,
|
|
blockEncoder);
|
|
+ // AERE D-412 rule D (step 3): the wiring (collector, echo, replay, own-round decision, advance of D on its own
|
|
+ // executor, NewChainHead(D) into this event queue) becomes the process hook of the controller and the rounds.
|
|
+ // The echo goes through the validator peers directly: the gossip multicaster sends a message only once.
|
|
+ if (aereDecidedHead != null) {
|
|
+ AereD412DecidedWiring.installConsensus(
|
|
+ blockchain,
|
|
+ aereDecidedHead,
|
|
+ validatorProvider,
|
|
+ qbftBlockInterface,
|
|
+ peers,
|
|
+ bftEventQueue,
|
|
+ aereAnchorConfig,
|
|
+ aereCertifiedDecision,
|
|
+ blockEncoder);
|
|
+ }
|
|
final BftEventHandler bftEventHandler = new BftEventHandlerAdaptor(qbftController);
|
|
|
|
final EventMultiplexer eventMultiplexer = new EventMultiplexer(bftEventHandler);
|
|
final BftProcessor bftProcessor = new BftProcessor(bftEventQueue, eventMultiplexer);
|
|
|
|
final MiningCoordinator miningCoordinator =
|
|
new BftMiningCoordinator(
|
|
bftExecutors,
|
|
bftEventHandler,
|
|
bftProcessor,
|
|
blockCreatorFactory,
|
|
blockchain,
|
|
bftEventQueue,
|
|
syncState);
|
|
|
|
// Update the next block period in seconds according to the transition schedule
|
|
protocolContext
|
|
.getBlockchain()
|
|
.observeBlockAdded(
|
|
o -> {
|
|
@@ -908,36 +973,99 @@ public class QbftBesuControllerBuilder extends BesuControllerBuilder {
|
|
* <p>Returns null when the key is absent, which {@code PqRegistryHash.parseSchedule} turns into
|
|
* the empty schedule, i.e. nothing is enforced and the existing chain is untouched.
|
|
*/
|
|
private com.fasterxml.jackson.databind.JsonNode aereGenesisConfigNode(final String key) {
|
|
if (!(genesisConfigOptions instanceof JsonGenesisConfigOptions)) {
|
|
LOG.warn(
|
|
"AERE PQC A8: the genesis configuration is a {}, not the JSON-backed implementation, so "
|
|
+ "config.{} cannot be read and the Falcon registry binding is NOT ENFORCED on this "
|
|
+ "node. A binding everybody believes is on and is not is worse than no binding.",
|
|
genesisConfigOptions.getClass().getName(),
|
|
key);
|
|
return null;
|
|
}
|
|
final JsonGenesisConfigOptions json = (JsonGenesisConfigOptions) genesisConfigOptions;
|
|
final com.fasterxml.jackson.databind.JsonNode exact = json.aereRawConfigValue(key);
|
|
return exact != null
|
|
? exact
|
|
: json.aereRawConfigValue(key.toLowerCase(java.util.Locale.ROOT));
|
|
}
|
|
|
|
+ /**
|
|
+ * AERE 1(b): the H_r checks of startup, called by {@code build()} with the anchor configuration it read ONCE and the
|
|
+ * genesis chain id; refuses (throws) or returns, and writes the startup lines the gates read.
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>ROUND-02 (project section 2.3): with H_fin armed and H_r unset or above it, the round of a commit would be
|
|
+ * bound by ECDSA only between the two; refused unless confirmed with lateAfterFinality EQUAL to H_fin (28001 and
|
|
+ * the rehearsal chains, where H_fin came first). It takes the configuration OBJECT, not its H_r alone, and is
|
|
+ * inert under the anchor brake on this node (1(b) step 11, 2026-10-09, nm-consens-02): under the brake every
|
|
+ * commit seal signs the round-specific ECDSA committed-seal hash, so the gap ROUND-02 guards does not exist
|
|
+ * (the reasoning is written at {@link PqFinalityLayersGuard#roundGapClosedByEcdsaForm}). Until that date a
|
|
+ * braked node with H_fin armed (2800 from T4) was refused here, because the braked configuration carries no
|
|
+ * H_r: the brake could not engage. The exception is the BRAKE only (2026-10-10, review of consensus M1): a node
|
|
+ * with no anchor at all and no brake, H_fin armed, is refused, as in the second client.
|
|
+ * <li>ROUND-03: from H_r the commit seal binds the chain id, which must be the genesis chain id.
|
|
+ * <li>The line {@code AERE PQ COMMIT-ROUND: H_r=...}, the second source the gates read (the first is the live
|
|
+ * process); its text is unchanged since step 3.
|
|
+ * </ul>
|
|
+ *
|
|
+ * <p>All inert without H_fin / H_r (L1).
|
|
+ *
|
|
+ * @param hFin H_fin as armed on this node ({@code AerePqFinality.finalityBlock()}), or NEVER
|
|
+ * @param anchorConfig the anchor configuration build() read once
|
|
+ * @param genesisChainId the genesis chain id of this node
|
|
+ * @throws IllegalStateException AERE-PQC-ROUND-02 or AERE-PQC-ROUND-03
|
|
+ */
|
|
+ static void verifyCommitRoundAtStartup(
|
|
+ final long hFin, final PqAnchorConfig anchorConfig, final long genesisChainId) {
|
|
+ PqFinalityLayersGuard.verifyRoundOrAbort(hFin, anchorConfig, genesisChainId);
|
|
+ if (hFin != AerePqIdentity.NEVER && PqFinalityLayersGuard.roundGapClosedByEcdsaForm(anchorConfig)) {
|
|
+ // deliberately without the refusal codes in the text: the tools that read this log for a refusal match them
|
|
+ LOG.warn(
|
|
+ "AERE PQ ANCHOR: not in force on this node (the brake) while H_fin={} is armed: every commit seal signs the"
|
|
+ + " round-specific ECDSA committed-seal hash, so the H_fin / H_r order is not checked here. The brake"
|
|
+ + " goes on every node: alone on it, this node's seals sign a form the others do not verify.",
|
|
+ hFin);
|
|
+ } else if (PqFinalityLayersGuard.roundLateConfirmed(
|
|
+ hFin,
|
|
+ anchorConfig.commitRoundBlock(),
|
|
+ PqFinalityLayersGuard.lateAfterFinalityFromSystemConfig(),
|
|
+ genesisChainId)) {
|
|
+ LOG.warn(
|
|
+ "AERE PQ COMMIT-ROUND ({}): H_fin={} came before H_r ({}); between them the round of a commit was bound"
|
|
+ + " by the ECDSA commit seal only (history, confirmed with {}).",
|
|
+ PqFinalityLayersGuard.CODE_ROUND_02,
|
|
+ hFin,
|
|
+ anchorConfig.commitRoundBlock() == PqAnchorConfig.NEVER
|
|
+ ? "unset"
|
|
+ : anchorConfig.commitRoundBlock(),
|
|
+ PqFinalityLayersGuard.PROPERTY_ROUND_LATE_AFTER_FINALITY);
|
|
+ }
|
|
+ final java.util.Optional<String> aereRound03 = anchorConfig.roundChainIdRefusal(genesisChainId);
|
|
+ if (aereRound03.isPresent()) {
|
|
+ throw new IllegalStateException(aereRound03.get());
|
|
+ }
|
|
+ final long aereHr = anchorConfig.commitRoundBlock();
|
|
+ LOG.info(
|
|
+ "AERE PQ COMMIT-ROUND: H_r={}, COMMIT-2 from block {}, certificate v3 from anchor {}",
|
|
+ aereHr == PqAnchorConfig.NEVER ? "unset" : Long.toString(aereHr),
|
|
+ aereHr == PqAnchorConfig.NEVER ? "never" : Long.toString(aereHr - 1L),
|
|
+ aereHr == PqAnchorConfig.NEVER ? "never" : Long.toString(aereHr));
|
|
+ }
|
|
+
|
|
private static MinedBlockObserver blockLogger(
|
|
final TransactionPool transactionPool, final Address localAddress) {
|
|
return block ->
|
|
LOG.info(
|
|
String.format(
|
|
"%s %s #%,d / %d tx / %d pending / %,d (%01.1f%%) gas / (%s)",
|
|
block.getHeader().getCoinbase().equals(localAddress) ? "Produced" : "Imported",
|
|
block.getBody().getTransactions().isEmpty() ? "empty block" : "block",
|
|
block.getHeader().getNumber(),
|
|
block.getBody().getTransactions().size(),
|
|
transactionPool.count(),
|
|
block.getHeader().getGasUsed(),
|
|
(block.getHeader().getGasUsed() * 100.0) / block.getHeader().getGasLimit(),
|
|
block.getHash().getBytes().toHexString()));
|
|
}
|
|
}
|
|
diff --git a/app/src/test/java/org/hyperledger/besu/controller/AereCommitRoundStartupTest.java b/app/src/test/java/org/hyperledger/besu/controller/AereCommitRoundStartupTest.java
|
|
new file mode 100644
|
|
index 0000000000..205acbad9a
|
|
--- /dev/null
|
|
+++ b/app/src/test/java/org/hyperledger/besu/controller/AereCommitRoundStartupTest.java
|
|
@@ -0,0 +1,296 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.controller;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.assertj.core.api.Assertions.assertThatCode;
|
|
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AerePqIdentity;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.PqFinalityLayersGuard;
|
|
+
|
|
+import java.lang.reflect.InvocationHandler;
|
|
+import java.lang.reflect.Method;
|
|
+import java.lang.reflect.Proxy;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collections;
|
|
+import java.util.HashMap;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.stream.Collectors;
|
|
+
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), step 11 (2026-10-09), nm-consens-02, the Besu part, on the STARTUP PATH itself: the H_r checks build() runs
|
|
+ * live in {@link QbftBesuControllerBuilder#verifyCommitRoundAtStartup}, the one method build() calls with the anchor
|
|
+ * configuration it read; this probe reads that configuration with the same reader ({@link
|
|
+ * PqAnchorConfig#fromSystemConfiguration()}, from system properties as on a node) and calls the same method, so a
|
|
+ * regression in the builder (not only in the guard or in the reader) turns it red.
|
|
+ *
|
|
+ * <p>The defect: on 2800 from T4 (H_fin armed) a node with the anchor brake ({@code aere.pq.anchor.disable=true}) was
|
|
+ * REFUSED at startup by AERE-PQC-ROUND-02, because the braked configuration carries no H_r and the builder handed the
|
|
+ * guard that H_r alone ("H_fin armed, H_r unset"): the brake could not engage. Each case has its pair:
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>braked, H_fin armed, chain 2800: starts, writes the brake line WITHOUT any refusal code (the tools that read the
|
|
+ * log for a refusal match the codes) and the COMMIT-ROUND line with {@code H_r=unset}; the same node unbraked and
|
|
+ * without H_r: ROUND-02, with its reason;
|
|
+ * <li>unbraked, H_r at or below H_fin (2800's order): starts, no brake line, the COMMIT-ROUND line with H_r;
|
|
+ * <li>H_fin not armed: today's behaviour (L1), braked or not: no brake line.
|
|
+ * </ul>
|
|
+ *
|
|
+ * <p>What this does not run: build() itself with H_fin armed (AerePqFinality needs the v3 identity and its epochs,
|
|
+ * process-wide singletons, the limit AereD412BuilderTest names); the call from build() to this method is one line,
|
|
+ * {@code verifyCommitRoundAtStartup(AerePqFinality.finalityBlock(), aereAnchorConfig, aereGenesisChainId)}.
|
|
+ */
|
|
+class AereCommitRoundStartupTest {
|
|
+
|
|
+ private static final long MAINNET = 2_800L;
|
|
+ private static final long H_FIN = 21_100_000L;
|
|
+ private static final String BRAKE_LINE = "AERE PQ ANCHOR: not in force on this node";
|
|
+
|
|
+ /** The names this probe sets (system property, environment twin), saved and put back around each case. */
|
|
+ private static final String[][] NAMES = {
|
|
+ {PqAnchorConfig.PROPERTY_CHAIN_ID, PqAnchorConfig.ENV_CHAIN_ID},
|
|
+ {PqAnchorConfig.PROPERTY_ANCHOR_BLOCK, PqAnchorConfig.ENV_ANCHOR_BLOCK},
|
|
+ {PqAnchorConfig.PROPERTY_MIN_SEALS, PqAnchorConfig.ENV_MIN_SEALS},
|
|
+ {PqAnchorConfig.PROPERTY_MIN_SEALS_CEILING, PqAnchorConfig.ENV_MIN_SEALS_CEILING},
|
|
+ {PqAnchorConfig.PROPERTY_DISABLE, PqAnchorConfig.ENV_DISABLE},
|
|
+ {PqAnchorConfig.PROPERTY_MAX_SEALS, PqAnchorConfig.ENV_MAX_SEALS},
|
|
+ {PqAnchorConfig.PROPERTY_ANCHOR_INTERVAL, PqAnchorConfig.ENV_ANCHOR_INTERVAL},
|
|
+ {PqAnchorConfig.PROPERTY_ANCHOR_INTERVAL_SCHEDULE, PqAnchorConfig.ENV_ANCHOR_INTERVAL_SCHEDULE},
|
|
+ {PqAnchorConfig.PROPERTY_ANCHOR_V2_BLOCK, PqAnchorConfig.ENV_ANCHOR_V2_BLOCK},
|
|
+ {PqAnchorConfig.PROPERTY_COMMIT_ROUND_BLOCK, PqAnchorConfig.ENV_COMMIT_ROUND_BLOCK},
|
|
+ {PqFinalityLayersGuard.PROPERTY_ROUND_LATE_AFTER_FINALITY, PqFinalityLayersGuard.ENV_ROUND_LATE_AFTER_FINALITY},
|
|
+ };
|
|
+
|
|
+ private final Map<String, String> before = new HashMap<>();
|
|
+ private LogTap log;
|
|
+
|
|
+ @BeforeEach
|
|
+ void save() throws Exception {
|
|
+ for (final String[] n : NAMES) {
|
|
+ assertThat(System.getenv(n[1]))
|
|
+ .as("control: %s is not set in this JVM's environment (the probe sets the properties only)", n[1])
|
|
+ .isNull();
|
|
+ before.put(n[0], System.getProperty(n[0]));
|
|
+ System.clearProperty(n[0]);
|
|
+ }
|
|
+ log = new LogTap("aere-r1b-pas11-pornire");
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ void putBack() throws Exception {
|
|
+ if (log != null) {
|
|
+ log.close();
|
|
+ }
|
|
+ for (final String[] n : NAMES) {
|
|
+ final String v = before.get(n[0]);
|
|
+ if (v == null) {
|
|
+ System.clearProperty(n[0]);
|
|
+ } else {
|
|
+ System.setProperty(n[0], v);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /** The 2800-shaped anchor of the reader's own probe (AereRoundBoundMessageTest), read as build() reads it. */
|
|
+ private static PqAnchorConfig startupRead(final Map<String, String> extra) {
|
|
+ System.setProperty(PqAnchorConfig.PROPERTY_CHAIN_ID, "2800");
|
|
+ System.setProperty(PqAnchorConfig.PROPERTY_ANCHOR_BLOCK, "1000");
|
|
+ System.setProperty(PqAnchorConfig.PROPERTY_MIN_SEALS, "1000:0,8200:1,15400:3");
|
|
+ System.setProperty(PqAnchorConfig.PROPERTY_ANCHOR_V2_BLOCK, "1064");
|
|
+ for (final Map.Entry<String, String> e : extra.entrySet()) {
|
|
+ System.setProperty(e.getKey(), e.getValue());
|
|
+ }
|
|
+ return PqAnchorConfig.fromSystemConfiguration();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void theBrakeStartsA2800NodeWhoseHfinIsArmed() {
|
|
+ final PqAnchorConfig braked =
|
|
+ startupRead(
|
|
+ Map.of(
|
|
+ PqAnchorConfig.PROPERTY_COMMIT_ROUND_BLOCK, "2000",
|
|
+ PqAnchorConfig.PROPERTY_DISABLE, "true"));
|
|
+ assertThat(braked.disabled()).as("control: the reader braked").isTrue();
|
|
+ assertThat(braked.commitRoundBlock())
|
|
+ .as("control: the braked configuration carries no H_r (the cause of the refusal this probe measures)")
|
|
+ .isEqualTo(PqAnchorConfig.NEVER);
|
|
+ assertThatCode(() -> QbftBesuControllerBuilder.verifyCommitRoundAtStartup(H_FIN, braked, MAINNET))
|
|
+ .as("the brake engages on a 2800 node after T4: the builder's startup checks must not refuse it")
|
|
+ .doesNotThrowAnyException();
|
|
+ final List<String> lines = log.builderLines();
|
|
+ assertThat(lines)
|
|
+ .as("the builder says why the H_fin / H_r order is not checked (lines %s)", lines)
|
|
+ .anyMatch(l -> l.contains(BRAKE_LINE) && l.contains("H_fin=" + H_FIN));
|
|
+ assertThat(lines)
|
|
+ .as("the startup line says the truth of the process: H_r unset under the brake (lines %s)", lines)
|
|
+ .anyMatch(l -> l.contains("AERE PQ COMMIT-ROUND: H_r=unset, COMMIT-2 from block never"));
|
|
+ assertThat(lines)
|
|
+ .as("no refusal code in any line of a node that starts (the tools match the codes; lines %s)", lines)
|
|
+ .noneMatch(l -> l.contains("AERE-PQC-ROUND-0"));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void withoutTheBrakeTheSameNodeWithoutHrIsRefusedByRound02() {
|
|
+ final PqAnchorConfig armed = startupRead(Map.of());
|
|
+ assertThat(armed.everActive()).as("control: the anchor is in force").isTrue();
|
|
+ assertThat(armed.commitRoundBlock()).isEqualTo(PqAnchorConfig.NEVER);
|
|
+ // positive control of the tap IN THIS PROBE (2026-10-10, review of probes m9): the refused call below throws before the
|
|
+ // builder writes any line, so "no brake line" at the end would also pass on a tap that hears nothing; the same
|
|
+ // configuration without H_fin starts and writes the COMMIT-ROUND line, which the tap must hear first
|
|
+ assertThatCode(
|
|
+ () -> QbftBesuControllerBuilder.verifyCommitRoundAtStartup(AerePqIdentity.NEVER, armed, MAINNET))
|
|
+ .doesNotThrowAnyException();
|
|
+ assertThat(log.builderLines())
|
|
+ .as("control: the tap hears the builder in this probe (lines %s)", log.builderLines())
|
|
+ .anyMatch(l -> l.contains("AERE PQ COMMIT-ROUND: H_r=unset"));
|
|
+ assertThatThrownBy(() -> QbftBesuControllerBuilder.verifyCommitRoundAtStartup(H_FIN, armed, MAINNET))
|
|
+ .as("the exception of the brake is not a hole: an armed 2800 node with H_fin and no H_r is refused")
|
|
+ .isInstanceOf(IllegalStateException.class)
|
|
+ .hasMessageStartingWith(PqFinalityLayersGuard.CODE_ROUND_02)
|
|
+ .hasMessageContaining("aere.pq.commitRoundBlock is unset");
|
|
+ assertThat(log.builderLines()).noneMatch(l -> l.contains(BRAKE_LINE));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void withoutTheBrakeHrAtOrBelowHfinStartsWithItsLine() {
|
|
+ final PqAnchorConfig armed = startupRead(Map.of(PqAnchorConfig.PROPERTY_COMMIT_ROUND_BLOCK, "2000"));
|
|
+ assertThat(armed.commitRoundBlock()).as("control: H_r read at startup").isEqualTo(2_000L);
|
|
+ assertThatCode(() -> QbftBesuControllerBuilder.verifyCommitRoundAtStartup(H_FIN, armed, MAINNET))
|
|
+ .as("2800's order, H_r before H_fin")
|
|
+ .doesNotThrowAnyException();
|
|
+ final List<String> lines = log.builderLines();
|
|
+ assertThat(lines)
|
|
+ .as("lines %s", lines)
|
|
+ .anyMatch(l -> l.contains("AERE PQ COMMIT-ROUND: H_r=2000, COMMIT-2 from block 1999, certificate v3 from anchor 2000"));
|
|
+ assertThat(lines).as("not braked: no brake line (lines %s)", lines).noneMatch(l -> l.contains(BRAKE_LINE));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void withoutHfinNothingChangesBrakedOrNot() {
|
|
+ final PqAnchorConfig braked = startupRead(Map.of(PqAnchorConfig.PROPERTY_DISABLE, "true"));
|
|
+ assertThat(braked.disabled()).as("control: the reader braked").isTrue();
|
|
+ assertThatCode(
|
|
+ () -> QbftBesuControllerBuilder.verifyCommitRoundAtStartup(AerePqIdentity.NEVER, braked, MAINNET))
|
|
+ .doesNotThrowAnyException();
|
|
+ final List<String> lines = log.builderLines();
|
|
+ assertThat(lines)
|
|
+ .as("H_fin not armed: today's startup (L1), no brake line (lines %s)", lines)
|
|
+ .noneMatch(l -> l.contains(BRAKE_LINE));
|
|
+ assertThat(lines).anyMatch(l -> l.contains("AERE PQ COMMIT-ROUND: H_r=unset"));
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * A Log4j2 appender built as a dynamic proxy on the root logger (the PqInertBinaryTest method), fully reflective. It
|
|
+ * throws if any step fails: a tap that quietly hears nothing would make every "no such line" assertion pass for
|
|
+ * nothing; here the COMMIT-ROUND line every case requires is its positive control.
|
|
+ */
|
|
+ static final class LogTap implements AutoCloseable {
|
|
+ private final List<String> heard = Collections.synchronizedList(new ArrayList<>());
|
|
+ private final String name;
|
|
+ private final Object rootLoggerConfig;
|
|
+ private final Object ctx;
|
|
+ private final Object priorLevel;
|
|
+ private final Class<?> loggerConfigCls;
|
|
+ private final Class<?> levelCls;
|
|
+ private final Class<?> ctxCls;
|
|
+
|
|
+ LogTap(final String name) throws Exception {
|
|
+ this.name = name;
|
|
+ final Class<?> appenderCls = Class.forName("org.apache.logging.log4j.core.Appender");
|
|
+ final Class<?> eventCls = Class.forName("org.apache.logging.log4j.core.LogEvent");
|
|
+ final Class<?> configCls = Class.forName("org.apache.logging.log4j.core.config.Configuration");
|
|
+ final Class<?> filterCls = Class.forName("org.apache.logging.log4j.core.Filter");
|
|
+ final Class<?> stateCls = Class.forName("org.apache.logging.log4j.core.LifeCycle$State");
|
|
+ final Class<?> messageCls = Class.forName("org.apache.logging.log4j.message.Message");
|
|
+ loggerConfigCls = Class.forName("org.apache.logging.log4j.core.config.LoggerConfig");
|
|
+ levelCls = Class.forName("org.apache.logging.log4j.Level");
|
|
+ ctxCls = Class.forName("org.apache.logging.log4j.core.LoggerContext");
|
|
+ final Object c =
|
|
+ Class.forName("org.apache.logging.log4j.LogManager")
|
|
+ .getMethod("getContext", boolean.class)
|
|
+ .invoke(null, Boolean.FALSE);
|
|
+ if (!ctxCls.isInstance(c)) {
|
|
+ throw new IllegalStateException("the SLF4J binding in this JVM is not log4j-core: " + c.getClass().getName());
|
|
+ }
|
|
+ ctx = c;
|
|
+ rootLoggerConfig = configCls.getMethod("getRootLogger").invoke(ctxCls.getMethod("getConfiguration").invoke(c));
|
|
+ final Method getMessage = eventCls.getMethod("getMessage");
|
|
+ final Method getLoggerName = eventCls.getMethod("getLoggerName");
|
|
+ final Method formatted = messageCls.getMethod("getFormattedMessage");
|
|
+ Object startedState = null;
|
|
+ for (final Object s : stateCls.getEnumConstants()) {
|
|
+ if ("STARTED".equals(((Enum<?>) s).name())) {
|
|
+ startedState = s;
|
|
+ }
|
|
+ }
|
|
+ final Object started = startedState;
|
|
+ final InvocationHandler handler =
|
|
+ (proxy, method, args) -> {
|
|
+ switch (method.getName()) {
|
|
+ case "append":
|
|
+ heard.add(getLoggerName.invoke(args[0]) + " | " + formatted.invoke(getMessage.invoke(args[0])));
|
|
+ return null;
|
|
+ case "getName":
|
|
+ case "toString":
|
|
+ return name;
|
|
+ case "isStarted":
|
|
+ return Boolean.TRUE;
|
|
+ case "isStopped":
|
|
+ return Boolean.FALSE;
|
|
+ case "getState":
|
|
+ return started;
|
|
+ case "ignoreExceptions":
|
|
+ return Boolean.TRUE;
|
|
+ case "equals":
|
|
+ return proxy == args[0];
|
|
+ case "hashCode":
|
|
+ return System.identityHashCode(proxy);
|
|
+ default:
|
|
+ return null;
|
|
+ }
|
|
+ };
|
|
+ final Object appender =
|
|
+ Proxy.newProxyInstance(LogTap.class.getClassLoader(), new Class<?>[] {appenderCls}, handler);
|
|
+ final Object all = levelCls.getField("ALL").get(null);
|
|
+ priorLevel = loggerConfigCls.getMethod("getLevel").invoke(rootLoggerConfig);
|
|
+ loggerConfigCls.getMethod("addAppender", appenderCls, levelCls, filterCls).invoke(rootLoggerConfig, appender, all, null);
|
|
+ loggerConfigCls.getMethod("setLevel", levelCls).invoke(rootLoggerConfig, all);
|
|
+ ctxCls.getMethod("updateLoggers").invoke(ctx);
|
|
+ }
|
|
+
|
|
+ /** The lines the builder itself wrote. */
|
|
+ List<String> builderLines() {
|
|
+ synchronized (heard) {
|
|
+ return heard.stream()
|
|
+ .filter(l -> l.startsWith(QbftBesuControllerBuilder.class.getName() + " | "))
|
|
+ .collect(Collectors.toList());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void close() throws Exception {
|
|
+ loggerConfigCls.getMethod("removeAppender", String.class).invoke(rootLoggerConfig, name);
|
|
+ loggerConfigCls.getMethod("setLevel", levelCls).invoke(rootLoggerConfig, priorLevel);
|
|
+ ctxCls.getMethod("updateLoggers").invoke(ctx);
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/app/src/test/java/org/hyperledger/besu/controller/AereD412BuilderTest.java b/app/src/test/java/org/hyperledger/besu/controller/AereD412BuilderTest.java
|
|
new file mode 100644
|
|
index 0000000000..d97881c50d
|
|
--- /dev/null
|
|
+++ b/app/src/test/java/org/hyperledger/besu/controller/AereD412BuilderTest.java
|
|
@@ -0,0 +1,402 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.controller;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
+import static org.mockito.Mockito.lenient;
|
|
+import static org.mockito.Mockito.mock;
|
|
+
|
|
+import org.hyperledger.besu.components.BesuComponent;
|
|
+import org.hyperledger.besu.config.CheckpointConfigOptions;
|
|
+import org.hyperledger.besu.config.GenesisConfig;
|
|
+import org.hyperledger.besu.config.GenesisConfigOptions;
|
|
+import org.hyperledger.besu.config.JsonQbftConfigOptions;
|
|
+import org.hyperledger.besu.config.TransitionsConfigOptions;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedBlockChoiceRule;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftContext;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSealSupport;
|
|
+import org.hyperledger.besu.consensus.common.bft.Vote;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.BftMiningCoordinator;
|
|
+import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
|
+import org.hyperledger.besu.consensus.qbft.MutableQbftConfigOptions;
|
|
+import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.BftEventHandlerAdaptor;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.AereDecidedConsensus;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.AereDecidedHook;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.QbftController;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockchain;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftFinalState;
|
|
+import org.hyperledger.besu.cryptoservices.NodeKey;
|
|
+import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.api.ImmutableApiConfiguration;
|
|
+import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator;
|
|
+import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
+import org.hyperledger.besu.ethereum.core.Block;
|
|
+import org.hyperledger.besu.ethereum.core.BlockBody;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+import org.hyperledger.besu.ethereum.core.Difficulty;
|
|
+import org.hyperledger.besu.ethereum.core.MiningConfiguration;
|
|
+import org.hyperledger.besu.ethereum.core.Util;
|
|
+import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration;
|
|
+import org.hyperledger.besu.ethereum.eth.sync.SyncMode;
|
|
+import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
|
|
+import org.hyperledger.besu.ethereum.eth.sync.snapsync.SnapSyncConfiguration;
|
|
+import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
|
|
+import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions;
|
|
+import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration;
|
|
+import org.hyperledger.besu.ethereum.storage.StorageProvider;
|
|
+import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage;
|
|
+import org.hyperledger.besu.ethereum.storage.keyvalue.VariablesKeyValueStorage;
|
|
+import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage;
|
|
+import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
|
|
+import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
|
|
+import org.hyperledger.besu.evm.internal.EvmConfiguration;
|
|
+import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
|
+import org.hyperledger.besu.plugin.services.storage.WorldStatePreimageStorage;
|
|
+import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage;
|
|
+
|
|
+import java.lang.reflect.Field;
|
|
+import java.math.BigInteger;
|
|
+import java.nio.file.Path;
|
|
+import java.time.Clock;
|
|
+import java.util.List;
|
|
+import java.util.Optional;
|
|
+
|
|
+import com.google.common.collect.Range;
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.junit.jupiter.api.extension.ExtendWith;
|
|
+import org.junit.jupiter.api.io.TempDir;
|
|
+import org.mockito.Mock;
|
|
+import org.mockito.junit.jupiter.MockitoExtension;
|
|
+
|
|
+/**
|
|
+ * AERE D-412 / the DECIDED HEAD (rule D), step 3, after the adversarial review of 2026-09-30: the REAL
|
|
+ * {@link QbftBesuControllerBuilder}, run through {@code build()} and so through {@code
|
|
+ * createMiningCoordinator}, the method that hands D to the adaptor and to the final state, installs the
|
|
+ * wiring and decides who is a validator. Until this proof nothing executed those lines: the three
|
|
+ * upstream probes that run {@code build()} on a BFT builder fail before it, on a snap configuration
|
|
+ * their fixture does not give ({@code SnapProtocolManager.java:93}, the D-434h patch).
|
|
+ *
|
|
+ * <p>The fixture is the upstream one ({@code AbstractBftBesuControllerBuilderTest}) with two
|
|
+ * differences: the synchronizer configuration GIVES the default snap configuration (what every real
|
|
+ * node has), and the genesis validators and H_ev ({@code aere.d412.hev}) are chosen per proof. What is
|
|
+ * read after the build is what the node runs: the QBFT controller behind the mining coordinator (by
|
|
+ * reflection, three fields), its adaptor and its final state, the process hook, the chain's block
|
|
+ * choice rule.
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>a VALIDATOR with H_ev = 1: after a provisional block 1 that votes a second validator in, the
|
|
+ * controller's head is D (genesis) and its set is the set after D, the wiring is the hook and the
|
|
+ * decided head's rule is on the chain;
|
|
+ * <li>a READER with H_ev = 1: nothing of rule D, the controller follows the canonical head;
|
|
+ * <li>a validator with H_ev UNSET: today's node, nothing of rule D;
|
|
+ * <li>(2026-10-01, second review of step 3) H_ev = 1 with ENFORCE of the old propagation gate asked
|
|
+ * for: the builder itself refuses to start (CONF-02), not only the helper it calls.
|
|
+ * </ul>
|
|
+ *
|
|
+ * <p>What this fixture cannot run: the builder's branch for an ARMED anchor ({@code
|
|
+ * aereAnchorConfig.everActive()}), where the propagation gate is built. Arming the anchor needs the
|
|
+ * Falcon registry (the startup guards refuse an anchor without it) and touches process-wide singletons
|
|
+ * ({@code FalconSealSupport}, {@code PqAnchorProducer.config()}, the seal cache's persistence) that the
|
|
+ * other test classes of the same JVM would inherit. What decides that branch at the builder is the
|
|
+ * CONF-02 call (measured here); the gate's own refusal to be ENFORCE under rule D is measured on the
|
|
+ * helper ({@code AereD412DecidedWiringTest}).
|
|
+ */
|
|
+@ExtendWith(MockitoExtension.class)
|
|
+public class AereD412BuilderTest {
|
|
+
|
|
+ @Mock private GenesisConfig genesisConfig;
|
|
+ @Mock private GenesisConfigOptions genesisConfigOptions;
|
|
+ @Mock private SynchronizerConfiguration synchronizerConfiguration;
|
|
+ @Mock private EthProtocolConfiguration ethProtocolConfiguration;
|
|
+ @Mock private CheckpointConfigOptions checkpointConfigOptions;
|
|
+ @Mock private Clock clock;
|
|
+ @Mock private StorageProvider storageProvider;
|
|
+ @Mock private WorldStatePreimageStorage worldStatePreimageStorage;
|
|
+ @TempDir Path tempDir;
|
|
+
|
|
+ private final NodeKey nodeKey = NodeKeyUtils.generate();
|
|
+ private final Address local = Util.publicKeyToAddress(nodeKey.getPublicKey());
|
|
+ private final Address other = Address.fromHexString("0x00000000000000000000000000000000000000c2");
|
|
+ private final Address voted = Address.fromHexString("0x00000000000000000000000000000000000000c3");
|
|
+ private final QbftExtraDataCodec codec = new QbftExtraDataCodec();
|
|
+
|
|
+ @BeforeEach
|
|
+ public void setUp() {
|
|
+ System.clearProperty(AereD412DecidedWiring.PROPERTY_HEV);
|
|
+ System.clearProperty(PqTipAdoptionGate.PROPERTY_MODE);
|
|
+ AereDecidedHook.reset();
|
|
+ final ForestWorldStateKeyValueStorage worldStateKeyValueStorage =
|
|
+ mock(ForestWorldStateKeyValueStorage.class);
|
|
+ final WorldStateStorageCoordinator worldStateStorageCoordinator =
|
|
+ new WorldStateStorageCoordinator(worldStateKeyValueStorage);
|
|
+ lenient().when(genesisConfig.getParentHash()).thenReturn(Hash.ZERO.getBytes().toHexString());
|
|
+ lenient().when(genesisConfig.getDifficulty()).thenReturn(Bytes.of(0).toHexString());
|
|
+ lenient().when(genesisConfig.getMixHash()).thenReturn(Hash.ZERO.getBytes().toHexString());
|
|
+ lenient().when(genesisConfig.getNonce()).thenReturn(Long.toHexString(1));
|
|
+ lenient().when(genesisConfig.getConfigOptions()).thenReturn(genesisConfigOptions);
|
|
+ lenient().when(genesisConfigOptions.getCheckpointOptions()).thenReturn(checkpointConfigOptions);
|
|
+ lenient()
|
|
+ .when(genesisConfigOptions.getQbftConfigOptions())
|
|
+ .thenReturn(new MutableQbftConfigOptions(JsonQbftConfigOptions.DEFAULT));
|
|
+ lenient().when(genesisConfigOptions.getTransitions()).thenReturn(TransitionsConfigOptions.DEFAULT);
|
|
+ lenient()
|
|
+ .when(storageProvider.createBlockchainStorage(any(), any(), any()))
|
|
+ .thenReturn(
|
|
+ new KeyValueStoragePrefixedKeyBlockchainStorage(
|
|
+ new InMemoryKeyValueStorage(),
|
|
+ new VariablesKeyValueStorage(new InMemoryKeyValueStorage()),
|
|
+ new MainnetBlockHeaderFunctions(),
|
|
+ false));
|
|
+ lenient()
|
|
+ .when(
|
|
+ storageProvider.createWorldStateStorageCoordinator(
|
|
+ DataStorageConfiguration.DEFAULT_FOREST_CONFIG))
|
|
+ .thenReturn(worldStateStorageCoordinator);
|
|
+ lenient().when(worldStateKeyValueStorage.isWorldStateAvailable(any())).thenReturn(true);
|
|
+ lenient()
|
|
+ .when(worldStateKeyValueStorage.updater())
|
|
+ .thenReturn(mock(ForestWorldStateKeyValueStorage.Updater.class));
|
|
+ lenient()
|
|
+ .when(worldStatePreimageStorage.updater())
|
|
+ .thenReturn(mock(WorldStatePreimageStorage.Updater.class));
|
|
+ lenient()
|
|
+ .when(storageProvider.createWorldStatePreimageStorage())
|
|
+ .thenReturn(worldStatePreimageStorage);
|
|
+ lenient().when(synchronizerConfiguration.getDownloaderParallelism()).thenReturn(1);
|
|
+ lenient().when(synchronizerConfiguration.getTransactionsParallelism()).thenReturn(1);
|
|
+ lenient().when(synchronizerConfiguration.getComputationParallelism()).thenReturn(1);
|
|
+ lenient().when(synchronizerConfiguration.getSyncMode()).thenReturn(SyncMode.FULL);
|
|
+ lenient()
|
|
+ .when(synchronizerConfiguration.getBlockPropagationRange())
|
|
+ .thenReturn(Range.closed(1L, 2L));
|
|
+ // the one difference from the upstream fixture: a real node always has a snap configuration
|
|
+ lenient()
|
|
+ .when(synchronizerConfiguration.getSnapSyncConfiguration())
|
|
+ .thenReturn(SnapSyncConfiguration.getDefault());
|
|
+ lenient()
|
|
+ .when(ethProtocolConfiguration.getMaxEthCapability())
|
|
+ .thenReturn(EthProtocolConfiguration.DEFAULT_MAX_CAPABILITY);
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ public void tearDown() {
|
|
+ System.clearProperty(AereD412DecidedWiring.PROPERTY_HEV);
|
|
+ System.clearProperty(PqTipAdoptionGate.PROPERTY_MODE);
|
|
+ AereDecidedHook.reset();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theRealBuilderRefusesEnforceOfTheOldGateUnderRuleD() {
|
|
+ assertThat(System.getenv(PqTipAdoptionGate.ENV_MODE))
|
|
+ .as("control: the gate mode is not set in the environment")
|
|
+ .isNull();
|
|
+ System.setProperty(PqTipAdoptionGate.PROPERTY_MODE, "enforce");
|
|
+ System.setProperty(AereD412DecidedWiring.PROPERTY_HEV, "1");
|
|
+ assertThatThrownBy(() -> build(List.of(local)))
|
|
+ .as("the builder refuses ENFORCE of the old gate on a node with rule D, before it builds anything")
|
|
+ .isInstanceOf(IllegalStateException.class)
|
|
+ .hasMessageContaining(AereD412DecidedWiring.CODE_CONF_02);
|
|
+ assertThat(AereDecidedHook.current())
|
|
+ .as("and nothing of rule D was installed")
|
|
+ .isSameAs(AereDecidedHook.INERT);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theRealBuilderGivesAValidatorDInItsAdaptorAndFinalStateAndInstallsTheWiring() {
|
|
+ System.setProperty(AereD412DecidedWiring.PROPERTY_HEV, "1");
|
|
+ final BesuController controller = build(List.of(local));
|
|
+ final MutableBlockchain chain = chainOf(controller);
|
|
+ final ValidatorProvider vp = validatorProviderOf(controller);
|
|
+ assertThat(AereDecidedHook.current())
|
|
+ .as("the builder installed the wiring as the process hook")
|
|
+ .isInstanceOf(AereDecidedConsensus.class);
|
|
+ assertThat(chain.getBlockChoiceRule())
|
|
+ .as("and the decided head's block choice rule on the chain")
|
|
+ .isInstanceOf(AereDecidedBlockChoiceRule.class);
|
|
+ final BlockHeader genesis = chain.getChainHeadHeader();
|
|
+ chain.appendBlock(blockOne(genesis, local, Optional.of(Vote.authVote(voted)), List.of(local)), List.of());
|
|
+ assertThat(chain.getChainHeadBlockNumber())
|
|
+ .as("control: the canonical head is the provisional block 1")
|
|
+ .isEqualTo(1L);
|
|
+ assertThat(vp.getValidatorsAtHead())
|
|
+ .as("control: block 1 voted a second validator in, so the set at the head is another set")
|
|
+ .containsExactlyInAnyOrder(local, voted);
|
|
+ final QbftController qbft = controllerOf(controller);
|
|
+ final QbftBlockchain adaptor = (QbftBlockchain) field(qbft, "blockchain");
|
|
+ final QbftFinalState finalState = (QbftFinalState) field(qbft, "finalState");
|
|
+ assertThat(adaptor.getChainHeadBlockNumber())
|
|
+ .as("the controller the builder built runs on D (genesis), not on the provisional block 1")
|
|
+ .isZero();
|
|
+ assertThat(adaptor.getChainHeadHeader().getHash()).isEqualTo(genesis.getHash());
|
|
+ assertThat(finalState.getValidators())
|
|
+ .as("and judges with the set after D, not with the set at the canonical head")
|
|
+ .containsExactly(local);
|
|
+ assertThat(finalState.isLocalNodeValidator()).isTrue();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theRealBuilderGivesAReaderNothingOfRuleD() {
|
|
+ assertThat(FalconSealSupport.instance().signingEnabled())
|
|
+ .as("control: this JVM does not seal, so only the set decides the role")
|
|
+ .isFalse();
|
|
+ System.setProperty(AereD412DecidedWiring.PROPERTY_HEV, "1");
|
|
+ final BesuController controller = build(List.of(other));
|
|
+ final MutableBlockchain chain = chainOf(controller);
|
|
+ final ValidatorProvider vp = validatorProviderOf(controller);
|
|
+ assertThat(vp.getValidatorsAtHead()).as("control: this node is not in the set").doesNotContain(local);
|
|
+ assertThat(AereDecidedHook.current())
|
|
+ .as("a reader gets no wiring")
|
|
+ .isSameAs(AereDecidedHook.INERT);
|
|
+ assertThat(chain.getBlockChoiceRule())
|
|
+ .as("and keeps the chain's own rule")
|
|
+ .isNotInstanceOf(AereDecidedBlockChoiceRule.class);
|
|
+ chain.appendBlock(
|
|
+ blockOne(chain.getChainHeadHeader(), other, Optional.empty(), List.of(other)), List.of());
|
|
+ final QbftController qbft = controllerOf(controller);
|
|
+ final QbftBlockchain adaptor = (QbftBlockchain) field(qbft, "blockchain");
|
|
+ final QbftFinalState finalState = (QbftFinalState) field(qbft, "finalState");
|
|
+ assertThat(adaptor.getChainHeadBlockNumber())
|
|
+ .as("the reader's controller follows the canonical head")
|
|
+ .isEqualTo(1L);
|
|
+ assertThat(finalState.getValidators()).containsExactlyElementsOf(vp.getValidatorsAtHead());
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theRealBuilderWithHevUnsetIsTodaysNode() {
|
|
+ assertThat(System.getenv(AereD412DecidedWiring.ENV_HEV))
|
|
+ .as("control: H_ev is not set in the environment either")
|
|
+ .isNull();
|
|
+ final BesuController controller = build(List.of(local));
|
|
+ final MutableBlockchain chain = chainOf(controller);
|
|
+ final ValidatorProvider vp = validatorProviderOf(controller);
|
|
+ assertThat(AereDecidedHook.current()).as("no wiring").isSameAs(AereDecidedHook.INERT);
|
|
+ assertThat(chain.getBlockChoiceRule())
|
|
+ .as("the chain's own rule")
|
|
+ .isNotInstanceOf(AereDecidedBlockChoiceRule.class);
|
|
+ chain.appendBlock(
|
|
+ blockOne(chain.getChainHeadHeader(), local, Optional.of(Vote.authVote(voted)), List.of(local)),
|
|
+ List.of());
|
|
+ assertThat(vp.getValidatorsAtHead())
|
|
+ .as("control: block 1 voted a second validator in")
|
|
+ .containsExactlyInAnyOrder(local, voted);
|
|
+ final QbftController qbft = controllerOf(controller);
|
|
+ final QbftBlockchain adaptor = (QbftBlockchain) field(qbft, "blockchain");
|
|
+ final QbftFinalState finalState = (QbftFinalState) field(qbft, "finalState");
|
|
+ assertThat(adaptor.getChainHeadBlockNumber())
|
|
+ .as("the controller follows the canonical head, as today")
|
|
+ .isEqualTo(1L);
|
|
+ assertThat(finalState.getValidators())
|
|
+ .as("with the set at the canonical head, as today")
|
|
+ .containsExactlyInAnyOrder(local, voted);
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // fixtures
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ private BesuController build(final List<Address> genesisValidators) {
|
|
+ lenient()
|
|
+ .when(genesisConfig.getExtraData())
|
|
+ .thenReturn(QbftExtraDataCodec.createGenesisExtraDataString(genesisValidators));
|
|
+ return new QbftBesuControllerBuilder()
|
|
+ .genesisConfig(genesisConfig)
|
|
+ .synchronizerConfiguration(synchronizerConfiguration)
|
|
+ .ethProtocolConfiguration(ethProtocolConfiguration)
|
|
+ .networkId(BigInteger.ONE)
|
|
+ .miningParameters(MiningConfiguration.newDefault())
|
|
+ .metricsSystem(new NoOpMetricsSystem())
|
|
+ .dataDirectory(tempDir)
|
|
+ .clock(clock)
|
|
+ .transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT)
|
|
+ .dataStorageConfiguration(DataStorageConfiguration.DEFAULT_FOREST_CONFIG)
|
|
+ .nodeKey(nodeKey)
|
|
+ .storageProvider(storageProvider)
|
|
+ .evmConfiguration(EvmConfiguration.DEFAULT)
|
|
+ .besuComponent(mock(BesuComponent.class))
|
|
+ .networkConfiguration(NetworkingConfiguration.DEFAULT)
|
|
+ .apiConfiguration(ImmutableApiConfiguration.builder().build())
|
|
+ .build();
|
|
+ }
|
|
+
|
|
+ private static MutableBlockchain chainOf(final BesuController controller) {
|
|
+ return controller.getProtocolContext().getBlockchain();
|
|
+ }
|
|
+
|
|
+ private static ValidatorProvider validatorProviderOf(final BesuController controller) {
|
|
+ return controller
|
|
+ .getProtocolContext()
|
|
+ .getConsensusContext(BftContext.class)
|
|
+ .getValidatorProvider();
|
|
+ }
|
|
+
|
|
+ /** The QBFT controller the builder built: mining coordinator -> event handler -> controller. */
|
|
+ private static QbftController controllerOf(final BesuController controller) {
|
|
+ final MiningCoordinator coordinator = controller.getMiningCoordinator();
|
|
+ assertThat(coordinator).as("control: the builder's coordinator").isInstanceOf(BftMiningCoordinator.class);
|
|
+ final Object handler = field(coordinator, "eventHandler");
|
|
+ assertThat(handler).as("control: its event handler").isInstanceOf(BftEventHandlerAdaptor.class);
|
|
+ final Object qbft = field(handler, "qbftEventHandler");
|
|
+ assertThat(qbft).as("control: the QBFT controller behind it").isInstanceOf(QbftController.class);
|
|
+ return (QbftController) qbft;
|
|
+ }
|
|
+
|
|
+ private static Object field(final Object target, final String name) {
|
|
+ Class<?> c = target.getClass();
|
|
+ while (c != null) {
|
|
+ try {
|
|
+ final Field f = c.getDeclaredField(name);
|
|
+ f.setAccessible(true);
|
|
+ return f.get(target);
|
|
+ } catch (final NoSuchFieldException e) {
|
|
+ c = c.getSuperclass();
|
|
+ } catch (final IllegalAccessException e) {
|
|
+ throw new IllegalStateException(e);
|
|
+ }
|
|
+ }
|
|
+ throw new IllegalStateException("no field " + name + " on " + target.getClass().getName());
|
|
+ }
|
|
+
|
|
+ /** Block 1 over the genesis, proposed by {@code proposer}, with real QBFT extra data. */
|
|
+ private Block blockOne(
|
|
+ final BlockHeader genesis,
|
|
+ final Address proposer,
|
|
+ final Optional<Vote> vote,
|
|
+ final List<Address> validators) {
|
|
+ final BftExtraData extra = new BftExtraData(Bytes32.ZERO, List.of(), vote, 0, validators);
|
|
+ final BlockHeader header =
|
|
+ new BlockHeaderTestFixture()
|
|
+ .number(1L)
|
|
+ .parentHash(genesis.getHash())
|
|
+ .difficulty(Difficulty.ONE)
|
|
+ .extraData(codec.encode(extra))
|
|
+ .coinbase(proposer)
|
|
+ .timestamp(genesis.getTimestamp() + 1)
|
|
+ .blockHeaderFunctions(BftBlockHeaderFunctions.forOnchainBlock(codec))
|
|
+ .buildHeader();
|
|
+ return new Block(header, BlockBody.empty());
|
|
+ }
|
|
+}
|
|
diff --git a/app/src/test/java/org/hyperledger/besu/controller/AereD412DecidedWiringProbe.java b/app/src/test/java/org/hyperledger/besu/controller/AereD412DecidedWiringProbe.java
|
|
new file mode 100644
|
|
index 0000000000..e227ee9102
|
|
--- /dev/null
|
|
+++ b/app/src/test/java/org/hyperledger/besu/controller/AereD412DecidedWiringProbe.java
|
|
@@ -0,0 +1,112 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.controller;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSealCache;
|
|
+import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.eth.sync.PropagatedBlockAdoptionGate;
|
|
+
|
|
+import java.nio.file.Path;
|
|
+import java.util.Collection;
|
|
+import java.util.Optional;
|
|
+import java.util.function.Consumer;
|
|
+import java.util.function.LongPredicate;
|
|
+import java.util.function.Predicate;
|
|
+
|
|
+/**
|
|
+ * AERE D-412 step 3, TEST support only: the builder's rule-D decisions ({@link AereD412DecidedWiring})
|
|
+ * reached from proofs in another package (the propagation proof lives in the package of the
|
|
+ * upstream {@code BlockPropagationManager}, whose constructor is package-private). Every method
|
|
+ * delegates, unchanged, to production code.
|
|
+ */
|
|
+public final class AereD412DecidedWiringProbe {
|
|
+
|
|
+ private AereD412DecidedWiringProbe() {}
|
|
+
|
|
+ /**
|
|
+ * The gate of {@link AereD412DecidedWiring} with every input given (the eight-argument form).
|
|
+ *
|
|
+ * @param hEv H_ev
|
|
+ * @param validatorProvider the validator provider
|
|
+ * @param localAddress this node's address
|
|
+ * @param chainId the chain id
|
|
+ * @param cache the seal cache
|
|
+ * @param verifier the seal verifier
|
|
+ * @param enforceRequested whether ENFORCE was asked for
|
|
+ * @param stage5Active whether a height is at or above H_hdr
|
|
+ * @return the gate
|
|
+ */
|
|
+ public static PropagatedBlockAdoptionGate.Gate tipGate(
|
|
+ final long hEv,
|
|
+ final ValidatorProvider validatorProvider,
|
|
+ final Address localAddress,
|
|
+ final long chainId,
|
|
+ final PqSealCache cache,
|
|
+ final PqTipAdoptionGate.SealVerifier verifier,
|
|
+ final boolean enforceRequested,
|
|
+ final LongPredicate stage5Active) {
|
|
+ return AereD412DecidedWiring.tipGate(
|
|
+ hEv,
|
|
+ validatorProvider,
|
|
+ localAddress,
|
|
+ chainId,
|
|
+ cache,
|
|
+ verifier,
|
|
+ enforceRequested,
|
|
+ stage5Active);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * {@link AereD412DecidedWiring#isValidatorNode}.
|
|
+ *
|
|
+ * @param signingEnabled whether this node seals
|
|
+ * @param validatorsAtHead the set at the head
|
|
+ * @param localAddress this node's address
|
|
+ * @return true for a validator
|
|
+ */
|
|
+ public static boolean isValidatorNode(
|
|
+ final boolean signingEnabled,
|
|
+ final Collection<Address> validatorsAtHead,
|
|
+ final Address localAddress) {
|
|
+ return AereD412DecidedWiring.isValidatorNode(signingEnabled, validatorsAtHead, localAddress);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * {@link AereD412DecidedWiring#installHead} (since 2026-10-01 it takes no restart evidence besides the
|
|
+ * durable file and the guarded finalized tag: teza Q3, D-470).
|
|
+ *
|
|
+ * @param blockchain the chain
|
|
+ * @param hEv H_ev
|
|
+ * @param validator whether this node is a validator
|
|
+ * @param dataDirectory the data directory
|
|
+ * @param alarm the alarm path
|
|
+ * @param finalizedProves the restart guard on the finalized tag
|
|
+ * @return the decided head, or empty
|
|
+ */
|
|
+ public static Optional<AereDecidedHead> installHead(
|
|
+ final MutableBlockchain blockchain,
|
|
+ final long hEv,
|
|
+ final boolean validator,
|
|
+ final Path dataDirectory,
|
|
+ final Consumer<String> alarm,
|
|
+ final Predicate<BlockHeader> finalizedProves) {
|
|
+ return AereD412DecidedWiring.installHead(
|
|
+ blockchain, hEv, validator, dataDirectory, alarm, finalizedProves);
|
|
+ }
|
|
+}
|
|
diff --git a/app/src/test/java/org/hyperledger/besu/controller/AereD412DecidedWiringTest.java b/app/src/test/java/org/hyperledger/besu/controller/AereD412DecidedWiringTest.java
|
|
new file mode 100644
|
|
index 0000000000..8d7a8cb26e
|
|
--- /dev/null
|
|
+++ b/app/src/test/java/org/hyperledger/besu/controller/AereD412DecidedWiringTest.java
|
|
@@ -0,0 +1,456 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.controller;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
+import static org.mockito.Mockito.mock;
|
|
+import static org.mockito.Mockito.when;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AereCertifiedDecision;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedBlockChoiceRule;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead;
|
|
+import org.hyperledger.besu.consensus.common.bft.AerePqIdentity;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftEventQueue;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSealCache;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSignerRegistry;
|
|
+import org.hyperledger.besu.consensus.common.bft.events.BftEvent;
|
|
+import org.hyperledger.besu.consensus.common.bft.events.NewChainHead;
|
|
+import org.hyperledger.besu.consensus.common.bft.network.ValidatorMulticaster;
|
|
+import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
|
+import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockCodecAdaptor;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockInterfaceAdaptor;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockchainAdaptor;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.AereDecidedConsensus;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.AereDecidedHook;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
+import org.hyperledger.besu.ethereum.core.Block;
|
|
+import org.hyperledger.besu.ethereum.core.BlockBody;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+import org.hyperledger.besu.ethereum.core.Difficulty;
|
|
+import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider;
|
|
+
|
|
+import java.nio.file.Path;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Comparator;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+import java.util.concurrent.TimeUnit;
|
|
+import java.util.function.Predicate;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.junit.jupiter.api.io.TempDir;
|
|
+
|
|
+/**
|
|
+ * AERE D-412 / the DECIDED HEAD (rule D), step 3: the builder's decisions about rule D ({@link
|
|
+ * AereD412DecidedWiring}, which the builder calls): H_ev unset is today's node, H_ev garbage refuses to
|
|
+ * start (CONF-01), ENFORCE under rule D refuses to start (CONF-02) and can never be built anyway, a
|
|
+ * reader gets no decided head and keeps total difficulty, a validator gets the decided head and its
|
|
+ * block choice rule on its chain; a restart takes the finalized tag only when it is what its anchor's
|
|
+ * certificate decides. Since 2026-10-01 (teza Q3, D-470) the restart takes nothing from the restored
|
|
+ * post-quantum commit seals, and the builder's decision counts the set that decides the parent.
|
|
+ */
|
|
+public class AereD412DecidedWiringTest {
|
|
+
|
|
+ @TempDir Path tmp;
|
|
+
|
|
+ private final Address local = Address.fromHexString("0x00000000000000000000000000000000000000b1");
|
|
+ private final Address other = Address.fromHexString("0x00000000000000000000000000000000000000b2");
|
|
+ private long tag;
|
|
+
|
|
+ @Test
|
|
+ public void anUnsetActivationHeightIsTodaysNode() {
|
|
+ assertThat(AereD412DecidedWiring.parseActivationHeight(null, null)).isEqualTo(AerePqIdentity.NEVER);
|
|
+ assertThat(AereD412DecidedWiring.configured(AerePqIdentity.NEVER)).isFalse();
|
|
+ AereD412DecidedWiring.verifyGateModeOrAbort(AerePqIdentity.NEVER, "enforce", null);
|
|
+ final MutableBlockchain chain = chain();
|
|
+ final Comparator<BlockHeader> before = chain.getBlockChoiceRule();
|
|
+ assertThat(
|
|
+ AereD412DecidedWiring.installHead(
|
|
+ chain, AerePqIdentity.NEVER, true, tmp, m -> {}, f -> true))
|
|
+ .isEmpty();
|
|
+ assertThat(chain.getBlockChoiceRule()).as("the chain's rule is untouched").isSameAs(before);
|
|
+ assertThat(tipGate(AerePqIdentity.NEVER, true).isEnforcing())
|
|
+ .as("without rule D, ENFORCE asked for is ENFORCE, as today")
|
|
+ .isTrue();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aMistypedActivationHeightRefusesToStart() {
|
|
+ assertThat(AereD412DecidedWiring.parseActivationHeight(" 1200 ", null)).isEqualTo(1200L);
|
|
+ assertThat(AereD412DecidedWiring.parseActivationHeight(null, "77")).isEqualTo(77L);
|
|
+ assertThat(AereD412DecidedWiring.parseActivationHeight("5", "77")).as("the property wins").isEqualTo(5L);
|
|
+ for (final String bad : List.of("12x", "", "-5", "1,200")) {
|
|
+ assertThatThrownBy(() -> AereD412DecidedWiring.parseActivationHeight(bad, null))
|
|
+ .as("'%s' must refuse, never disarm", bad)
|
|
+ .isInstanceOf(IllegalStateException.class)
|
|
+ .hasMessageContaining(AereD412DecidedWiring.CODE_CONF_01);
|
|
+ }
|
|
+ assertThatThrownBy(() -> AereD412DecidedWiring.parseActivationHeight(null, "x"))
|
|
+ .hasMessageContaining(AereD412DecidedWiring.CODE_CONF_01);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void enforceOfTheOldGateIsRefusedUnderRuleDAndCanNeverBeBuilt() {
|
|
+ assertThatThrownBy(() -> AereD412DecidedWiring.verifyGateModeOrAbort(100L, "enforce", null))
|
|
+ .isInstanceOf(IllegalStateException.class)
|
|
+ .hasMessageContaining(AereD412DecidedWiring.CODE_CONF_02);
|
|
+ assertThatThrownBy(() -> AereD412DecidedWiring.verifyGateModeOrAbort(100L, null, " ENFORCE "))
|
|
+ .hasMessageContaining(AereD412DecidedWiring.CODE_CONF_02);
|
|
+ AereD412DecidedWiring.verifyGateModeOrAbort(100L, "observe", null);
|
|
+ AereD412DecidedWiring.verifyGateModeOrAbort(100L, null, null);
|
|
+ assertThat(tipGate(100L, true).isEnforcing())
|
|
+ .as("under rule D the gate is never ENFORCE, whatever is asked for")
|
|
+ .isFalse();
|
|
+ assertThat(tipGate(100L, false).isEnforcing()).isFalse();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aReaderGetsNoDecidedHeadAndKeepsTotalDifficulty() {
|
|
+ assertThat(AereD412DecidedWiring.isValidatorNode(false, List.of(other), local)).isFalse();
|
|
+ assertThat(AereD412DecidedWiring.isValidatorNode(false, List.of(), local)).isFalse();
|
|
+ assertThat(AereD412DecidedWiring.isValidatorNode(true, List.of(other), local))
|
|
+ .as("a node that seals is a validator")
|
|
+ .isTrue();
|
|
+ assertThat(AereD412DecidedWiring.isValidatorNode(false, List.of(other, local), local))
|
|
+ .as("a node in the set at the head is a validator")
|
|
+ .isTrue();
|
|
+ final MutableBlockchain chain = chain();
|
|
+ final Comparator<BlockHeader> before = chain.getBlockChoiceRule();
|
|
+ final Optional<AereDecidedHead> head =
|
|
+ AereD412DecidedWiring.installHead(
|
|
+ chain,
|
|
+ 2L,
|
|
+ AereD412DecidedWiring.isValidatorNode(false, List.of(other), local),
|
|
+ tmp.resolve("reader"),
|
|
+ m -> {},
|
|
+ f -> true);
|
|
+ assertThat(head).as("a reader has no decided head").isEmpty();
|
|
+ assertThat(chain.getBlockChoiceRule()).as("and keeps total difficulty").isSameAs(before);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aValidatorGetsTheDecidedHeadAndItsBlockChoiceRule() {
|
|
+ final MutableBlockchain chain = chain();
|
|
+ final List<String> alarms = new ArrayList<>();
|
|
+ final Optional<AereDecidedHead> head =
|
|
+ AereD412DecidedWiring.installHead(
|
|
+ chain,
|
|
+ 3L,
|
|
+ AereD412DecidedWiring.isValidatorNode(false, List.of(other, local), local),
|
|
+ tmp.resolve("validator"),
|
|
+ alarms::add,
|
|
+ f -> false);
|
|
+ assertThat(head).isPresent();
|
|
+ assertThat(chain.getBlockChoiceRule())
|
|
+ .as("the decided head's rule is on the chain")
|
|
+ .isInstanceOf(AereDecidedBlockChoiceRule.class);
|
|
+ assertThat(head.get().activationHeight()).isEqualTo(3L);
|
|
+ assertThat(head.get().decided().number())
|
|
+ .as("restored: D is block 1 (Q5 stops below the proof height H_ev - 1 = 2)")
|
|
+ .isEqualTo(1L);
|
|
+ assertThat(head.get().file()).isEqualTo(tmp.resolve("validator").resolve(AereDecidedHead.FILE_NAME));
|
|
+ assertThat(alarms).isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theProductionWiringBecomesTheHookAndPostsTheDecidedHeadToTheEventQueue()
|
|
+ throws InterruptedException {
|
|
+ final MutableBlockchain chain = chain();
|
|
+ final Optional<AereDecidedHead> head =
|
|
+ AereD412DecidedWiring.installHead(chain, 2L, true, tmp.resolve("wired"), m -> {}, f -> false);
|
|
+ assertThat(head).isPresent();
|
|
+ final QbftExtraDataCodec codec = new QbftExtraDataCodec();
|
|
+ final BftEventQueue queue = new BftEventQueue(100);
|
|
+ queue.start();
|
|
+ final ValidatorProvider vp = mock(ValidatorProvider.class);
|
|
+ when(vp.getValidatorsAtHead()).thenReturn(List.of(local, other));
|
|
+ try {
|
|
+ final AereDecidedConsensus wiring =
|
|
+ AereD412DecidedWiring.installConsensus(
|
|
+ chain,
|
|
+ head.get(),
|
|
+ vp,
|
|
+ new QbftBlockInterfaceAdaptor(new BftBlockInterface(codec)),
|
|
+ mock(ValidatorMulticaster.class),
|
|
+ queue,
|
|
+ PqAnchorConfig.never(28001L),
|
|
+ AereD412DecidedWiring.certifiedDecision(PqAnchorConfig.never(28001L), codec, vp, 2L),
|
|
+ new QbftBlockCodecAdaptor(codec));
|
|
+ assertThat(AereDecidedHook.current()).as("the wiring is the process hook").isSameAs(wiring);
|
|
+ final Hash two = chain.getBlockHashByNumber(2L).orElseThrow();
|
|
+ assertThat(head.get().advance(two, AereDecidedHead.Proof.Q1))
|
|
+ .isEqualTo(AereDecidedHead.Outcome.ADVANCED);
|
|
+ final BftEvent event = queue.poll(5, TimeUnit.SECONDS);
|
|
+ assertThat(event).as("the move of D reached the BFT event queue").isInstanceOf(NewChainHead.class);
|
|
+ assertThat(((NewChainHead) event).getNewChainHeadHeader().getHash())
|
|
+ .as("as a new chain head event for D")
|
|
+ .isEqualTo(two);
|
|
+ } finally {
|
|
+ AereDecidedHook.reset();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Review of step 3 (2026-09-30), BLOCKING 2, in the form of 2026-10-01 (teza Q3, D-470): B1 put the
|
|
+ * finalized tag on the PARENT of a canonical certified anchor, and on a validator with rule D the
|
|
+ * canonical head may be a provisional tail. The restart takes the tag only when it is EXACTLY the
|
|
+ * block a canonical anchor above it decides ({@link AereD412DecidedWiring#finalizedProves}, the answer
|
|
+ * of {@link AereCertifiedDecision}). Here the anchor at 4 decides its grandparent 2 (the form from
|
|
+ * H_hdr), so the tag on 3 is not taken and D stays the durable 2. Control on the same fixture: when the
|
|
+ * anchor decides its parent 3 (the form below H_hdr), the restart takes the tag.
|
|
+ */
|
|
+ @Test
|
|
+ public void aRestartTakesTheFinalizedTagOnlyWhenItsAnchorProvesIt() {
|
|
+ assertThat(restartAfterACertifiedTail(tmp.resolve("bunic"), 2L))
|
|
+ .as("the anchor 4 decides 2: the tag on its parent 3 is not taken, the restart keeps the durable D (2)")
|
|
+ .isEqualTo(2L);
|
|
+ assertThat(restartAfterACertifiedTail(tmp.resolve("parinte"), 3L))
|
|
+ .as("control: the same tail and tag, the anchor decides 3, and the restart takes the tag")
|
|
+ .isEqualTo(3L);
|
|
+ }
|
|
+
|
|
+ /** D = 2 durable; a tail 3 <- anchor 4 on top, the tag on 3 (as B1 set it until 2026-10-01); a restart. */
|
|
+ private long restartAfterACertifiedTail(final Path dir, final long decides) {
|
|
+ final MutableBlockchain chain = chain();
|
|
+ final Predicate<BlockHeader> proves =
|
|
+ AereD412DecidedWiring.finalizedProves(
|
|
+ chain,
|
|
+ h -> h == 4L,
|
|
+ a ->
|
|
+ Optional.of(
|
|
+ new AereDecidedHead.Decided(
|
|
+ decides, chain.getBlockHashByNumber(decides).orElseThrow())));
|
|
+ final AereDecidedHead first =
|
|
+ AereD412DecidedWiring.installHead(chain, 2L, true, dir, m -> {}, proves).orElseThrow();
|
|
+ assertThat(first.advance(chain.getBlockHashByNumber(2L).orElseThrow(), AereDecidedHead.Proof.Q1))
|
|
+ .isEqualTo(AereDecidedHead.Outcome.ADVANCED);
|
|
+ final Block anchor = block(chain.getBlockByNumber(3L).orElseThrow());
|
|
+ chain.appendBlock(anchor, List.of());
|
|
+ assertThat(chain.getChainHeadBlockNumber()).as("control: the anchor 4 is the canonical head").isEqualTo(4L);
|
|
+ chain.setFinalized(chain.getBlockHashByNumber(3L).orElseThrow());
|
|
+ final AereDecidedHead restarted =
|
|
+ AereD412DecidedWiring.installHead(chain, 2L, true, dir, m -> {}, proves).orElseThrow();
|
|
+ return restarted.decided().number();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The window between the own round's import and the durable write of D (second review of step 3,
|
|
+ * 2026-10-01). The node's own round imported block 3 (the chain holds it) and the node stopped before
|
|
+ * D = 3 was written (the file says 2). Until the afternoon of 2026-10-01 the restart took 3 back from
|
|
+ * the commit seals of block 3 in the seal cache ({@code sealedHeadEvidence}, the name of this proof was
|
|
+ * aRestartInTheImportToFsyncWindowTakesTheHeadItsRestoredSealsProve). Those seals carry no round, and a
|
|
+ * quorum of them over a block does not show it decided (Teorema 1; RF1-4b measured the restart taking
|
|
+ * an undecided sibling with them), so that evidence is GONE (teza Q3, D-470, step 1 of project 2(c)).
|
|
+ * The restart keeps the durable 2 and the node runs height 3 again: the window is OPEN until the
|
|
+ * decision journal (steps 2 and on of 2(c)), and this proof states it. Control: at the restart the
|
|
+ * cache does hold a quorum of seals over block 3.
|
|
+ */
|
|
+ @Test
|
|
+ public void aRestartInTheImportToFsyncWindowTakesOnlyTheDurableHeadUntilTheJournal() {
|
|
+ final MutableBlockchain chain = chain();
|
|
+ final Path dir = tmp.resolve("window");
|
|
+ PqSealCache.instance().clear();
|
|
+ try {
|
|
+ final AereDecidedHead first =
|
|
+ AereD412DecidedWiring.installHead(chain, 2L, true, dir, m -> {}, f -> false).orElseThrow();
|
|
+ assertThat(first.advance(chain.getBlockHashByNumber(2L).orElseThrow(), AereDecidedHead.Proof.Q1))
|
|
+ .isEqualTo(AereDecidedHead.Outcome.ADVANCED);
|
|
+ assertThat(chain.getChainHeadBlockNumber()).as("control: the chain holds block 3").isEqualTo(3L);
|
|
+ final Hash three = chain.getBlockHashByNumber(3L).orElseThrow();
|
|
+ PqSealCache.instance()
|
|
+ .record(
|
|
+ 3L,
|
|
+ three, 0,
|
|
+ List.of(
|
|
+ new FalconSeal(0, Bytes.of(1)),
|
|
+ new FalconSeal(1, Bytes.of(1)),
|
|
+ new FalconSeal(2, Bytes.of(1))));
|
|
+ assertThat(PqSealCache.instance().sealsFor(3L, three, 0))
|
|
+ .as("control: at the restart the cache holds three seals over block 3, a quorum of four")
|
|
+ .hasSize(3);
|
|
+ final List<String> alarms = new ArrayList<>();
|
|
+ final AereDecidedHead restarted =
|
|
+ AereD412DecidedWiring.installHead(chain, 2L, true, dir, alarms::add, f -> false).orElseThrow();
|
|
+ assertThat(restarted.decided().number())
|
|
+ .as("the restart keeps the durable D, 2: round-free seals over block 3 prove nothing")
|
|
+ .isEqualTo(2L);
|
|
+ assertThat(new QbftBlockchainAdaptor(chain, restarted).getChainHeadBlockNumber())
|
|
+ .as("the controller's head after the restart is D = 2: height 3 runs again (the window of the journal)")
|
|
+ .isEqualTo(2L);
|
|
+ assertThat(alarms).as("no alarm at such a restart").isEmpty();
|
|
+ } finally {
|
|
+ PqSealCache.instance().clear();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Teza Q3 (D-470, 2026-10-01), project 1(a): the builder's decision counts f + 1 in the set that
|
|
+ * decides the anchor's PARENT p (the set FOR p, the one R2 checks the certificate against), not the set
|
|
+ * after p. With a vote in p the two differ: thirteen validators decide p (f + 1 = 5), ten remain after
|
|
+ * it (f + 1 = 4). Four verified seals of members of both are not f + 1 of the thirteen: nothing is
|
|
+ * decided. Control on the same certificate: when the set for p is the ten, the grandparent is decided.
|
|
+ */
|
|
+ @Test
|
|
+ public void theCertifiedDecisionCountsTheSetThatDecidesTheParent() {
|
|
+ final long chainId = 220_880L;
|
|
+ final List<Address> thirteen = new ArrayList<>();
|
|
+ for (int i = 0; i < 13; i++) {
|
|
+ thirteen.add(Address.fromHexString("0x" + "0".repeat(38) + "c" + Integer.toHexString(i)));
|
|
+ }
|
|
+ final List<Address> ten = thirteen.subList(0, 10);
|
|
+ final QbftExtraDataCodec codec = new QbftExtraDataCodec();
|
|
+ final PqAnchorConfig config =
|
|
+ new PqAnchorConfig(chainId, 3L, Map.of(3L, 4), OptionalInt.empty(), false);
|
|
+ final Block g = bftBlock(codec, null, thirteen, List.of());
|
|
+ final Block b1 = bftBlock(codec, g, thirteen, List.of());
|
|
+ final Block p = bftBlock(codec, b1, ten, List.of());
|
|
+ final Bytes32 message = PqAnchor.commitMessage(chainId, 2L, p.getHash().getBytes());
|
|
+ final List<FalconSeal> four = new ArrayList<>();
|
|
+ for (int i = 0; i < 4; i++) {
|
|
+ four.add(new FalconSeal(i, Bytes.of(1)));
|
|
+ }
|
|
+ final Block anchor = bftBlock(codec, p, ten, four);
|
|
+ final MutableBlockchain chain =
|
|
+ InMemoryKeyValueStorageProvider.createInMemoryBlockchain(
|
|
+ g, BftBlockHeaderFunctions.forOnchainBlock(codec));
|
|
+ chain.appendBlock(b1, List.of());
|
|
+ chain.appendBlock(p, List.of());
|
|
+ chain.appendBlock(anchor, List.of());
|
|
+ final PqSignerRegistry registry =
|
|
+ new PqSignerRegistry() {
|
|
+ @Override
|
|
+ public Address addressForIndexAtHistoric(final long blockNumber, final int validatorIndex) {
|
|
+ return validatorIndex >= 0 && validatorIndex < 13 ? thirteen.get(validatorIndex) : null;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Address addressForIndexAtOwnHead(final long blockNumber, final int validatorIndex) {
|
|
+ return addressForIndexAtHistoric(blockNumber, validatorIndex);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtHistoric(
|
|
+ final long blockNumber,
|
|
+ final int validatorIndex,
|
|
+ final Bytes m,
|
|
+ final Bytes signature) {
|
|
+ return blockNumber == 2L && m.equals(message) && signature.equals(Bytes.of(1));
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtOwnHead(
|
|
+ final long blockNumber,
|
|
+ final int validatorIndex,
|
|
+ final Bytes m,
|
|
+ final Bytes signature) {
|
|
+ return verifyAtHistoric(blockNumber, validatorIndex, m, signature);
|
|
+ }
|
|
+ };
|
|
+ final ValidatorProvider vote = mock(ValidatorProvider.class);
|
|
+ when(vote.getValidatorsForBlock(any())).thenReturn(thirteen);
|
|
+ when(vote.getValidatorsAfterBlock(any())).thenReturn(ten);
|
|
+ assertThat(
|
|
+ AereD412DecidedWiring.certifiedDecision(config, codec, vote, 2L, registry, h -> true)
|
|
+ .decidedBy(chain, anchor.getHeader()))
|
|
+ .as("four verified seals are not f + 1 = 5 of the thirteen that decide p: nothing is decided")
|
|
+ .isEmpty();
|
|
+ final ValidatorProvider noVote = mock(ValidatorProvider.class);
|
|
+ when(noVote.getValidatorsForBlock(any())).thenReturn(ten);
|
|
+ when(noVote.getValidatorsAfterBlock(any())).thenReturn(ten);
|
|
+ assertThat(
|
|
+ AereD412DecidedWiring.certifiedDecision(config, codec, noVote, 2L, registry, h -> true)
|
|
+ .decidedBy(chain, anchor.getHeader()))
|
|
+ .as("control: the same four of the ten that decide p are f + 1, and the grandparent is decided")
|
|
+ .contains(new AereDecidedHead.Decided(1L, b1.getHash()));
|
|
+ }
|
|
+
|
|
+ private Block bftBlock(
|
|
+ final QbftExtraDataCodec codec,
|
|
+ final Block parent,
|
|
+ final List<Address> validators,
|
|
+ final List<FalconSeal> certificate) {
|
|
+ tag++;
|
|
+ final long number = parent == null ? 0L : parent.getHeader().getNumber() + 1;
|
|
+ final BftExtraData extra =
|
|
+ certificate.isEmpty()
|
|
+ ? new BftExtraData(
|
|
+ Bytes32.leftPad(Bytes.ofUnsignedLong(tag)), List.of(), Optional.empty(), 0, validators)
|
|
+ : new BftExtraData(
|
|
+ Bytes32.leftPad(Bytes.ofUnsignedLong(tag)),
|
|
+ List.of(),
|
|
+ Optional.empty(),
|
|
+ 0,
|
|
+ validators,
|
|
+ certificate, java.util.List.of(), BftExtraData.NO_CERTIFICATE_ROUND);
|
|
+ return new Block(
|
|
+ new BlockHeaderTestFixture()
|
|
+ .number(number)
|
|
+ .parentHash(parent == null ? Hash.ZERO : parent.getHash())
|
|
+ .difficulty(Difficulty.ONE)
|
|
+ .extraData(codec.encode(extra))
|
|
+ .timestamp(number)
|
|
+ .blockHeaderFunctions(BftBlockHeaderFunctions.forOnchainBlock(codec))
|
|
+ .buildHeader(),
|
|
+ BlockBody.empty());
|
|
+ }
|
|
+
|
|
+ private PqTipAdoptionGate tipGate(final long hEv, final boolean enforceRequested) {
|
|
+ final ValidatorProvider vp = mock(ValidatorProvider.class);
|
|
+ when(vp.getValidatorsForBlock(any())).thenReturn(List.of(local, other));
|
|
+ return AereD412DecidedWiring.tipGate(
|
|
+ hEv, vp, local, 28001L, PqSealCache.instance(), (n, i, m, s) -> false, enforceRequested, h -> true);
|
|
+ }
|
|
+
|
|
+ private MutableBlockchain chain() {
|
|
+ final Block g = block(null);
|
|
+ final MutableBlockchain chain = InMemoryKeyValueStorageProvider.createInMemoryBlockchain(g);
|
|
+ Block p = g;
|
|
+ for (int i = 0; i < 3; i++) {
|
|
+ p = block(p);
|
|
+ chain.appendBlock(p, List.of());
|
|
+ }
|
|
+ return chain;
|
|
+ }
|
|
+
|
|
+ private Block block(final Block parent) {
|
|
+ tag++;
|
|
+ final long number = parent == null ? 0L : parent.getHeader().getNumber() + 1;
|
|
+ return new Block(
|
|
+ new BlockHeaderTestFixture()
|
|
+ .number(number)
|
|
+ .parentHash(parent == null ? Hash.ZERO : parent.getHash())
|
|
+ .difficulty(Difficulty.ONE)
|
|
+ .extraData(Bytes.ofUnsignedLong(tag))
|
|
+ .timestamp(number)
|
|
+ .buildHeader(),
|
|
+ BlockBody.empty());
|
|
+ }
|
|
+}
|
|
diff --git a/app/src/test/java/org/hyperledger/besu/controller/AereRoundBoundRestartTest.java b/app/src/test/java/org/hyperledger/besu/controller/AereRoundBoundRestartTest.java
|
|
new file mode 100644
|
|
index 0000000000..5b342072bf
|
|
--- /dev/null
|
|
+++ b/app/src/test/java/org/hyperledger/besu/controller/AereRoundBoundRestartTest.java
|
|
@@ -0,0 +1,396 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.controller;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
+import static org.mockito.Mockito.mock;
|
|
+import static org.mockito.Mockito.when;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AereCertifiedDecision;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorV2;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorV3;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSealCache;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSealStore;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSignerRegistry;
|
|
+import org.hyperledger.besu.consensus.common.bft.SchemeSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealScheme;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealSchemes;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
|
+import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec;
|
|
+import org.hyperledger.besu.crypto.SecureRandomProvider;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
+import org.hyperledger.besu.ethereum.core.Block;
|
|
+import org.hyperledger.besu.ethereum.core.BlockBody;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+import org.hyperledger.besu.ethereum.core.Difficulty;
|
|
+import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider;
|
|
+
|
|
+import java.nio.file.Files;
|
|
+import java.nio.file.Path;
|
|
+import java.security.SecureRandom;
|
|
+import java.util.ArrayList;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+import java.util.TreeMap;
|
|
+import java.util.TreeSet;
|
|
+import java.util.function.LongPredicate;
|
|
+import java.util.function.Predicate;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.junit.jupiter.api.io.TempDir;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), D-470, pasul 5 (2026-10-02): the restart half of RF1 REDONE ON THE NEW FORM (project 5.4, marker
|
|
+ * AERE-Q3-RF1-V3; the round-free original is {@link AereRoundFreeRestartTest}). The execution: N = 10, X = 9; at height 3
|
|
+ * the seals over p are of rounds 0 (0, 1, 2, X) and 2 (4, 5, 6, X), now over M_0(p) and M_2(p) (H_r = 4), and p' was
|
|
+ * decided at round 3. The node L durably decided block 2, heard rounds 0 and 2 (not 3), adopted p and X's anchor over it
|
|
+ * (the v3 that carries all seven members under round 2), and restarts through the builder's own functions
|
|
+ * (AereD412DecidedWiring.installHead, finalizedProves, certifiedDecision).
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>the restart does not take p from the finalized tag: the guard asks what a canonical anchor's certificate decides,
|
|
+ * and from H_r that is never p for X's certificate (four members of one round at most);
|
|
+ * <li>both from H_hdr and BELOW it (the regime of 2800 at H_r, where the old rule named p through the ECDSA branch);
|
|
+ * <li>the restart from the SEALSTORE-2 head file does not take p: the file is restored (rounds 0 and 2, four rows each,
|
|
+ * re-verified over their own M_r, seven distinct members over p), and the decided head it installs is still the
|
|
+ * durable block 2.
|
|
+ * </ul>
|
|
+ */
|
|
+public class AereRoundBoundRestartTest {
|
|
+
|
|
+ private static final long CHAIN = 220_893L;
|
|
+ private static final long ANCHOR_BLOCK = 2L;
|
|
+ private static final long V2 = 3L;
|
|
+ private static final long HR = 4L;
|
|
+ private static final long H_EV = 3L;
|
|
+ private static final int VALIDATORS = 10;
|
|
+ private static final int X = 9;
|
|
+ private static final int K = 7;
|
|
+ private static final byte FALCON = SealSchemes.FALCON_512.wireId();
|
|
+
|
|
+ @TempDir Path tmp;
|
|
+
|
|
+ private final QbftExtraDataCodec codec = new QbftExtraDataCodec();
|
|
+ private final PqAnchorConfig config =
|
|
+ new PqAnchorConfig(
|
|
+ CHAIN, ANCHOR_BLOCK, Map.of(ANCHOR_BLOCK, K), OptionalInt.empty(), false, OptionalInt.empty(), OptionalInt.empty())
|
|
+ .withAnchorV2Block(V2)
|
|
+ .withCommitRoundBlock(HR);
|
|
+ private final SecureRandom random = SecureRandomProvider.createSecureRandom();
|
|
+ private final List<Address> validators = new ArrayList<>();
|
|
+ private final List<byte[]> falconPublic = new ArrayList<>();
|
|
+ private final List<SealScheme.PrivateHandle> falconPrivate = new ArrayList<>();
|
|
+ private long tag;
|
|
+
|
|
+ private Block genesis;
|
|
+ private Block b1;
|
|
+ private Block b2;
|
|
+ private Block p;
|
|
+ private Block pPrime;
|
|
+ private Block anchor;
|
|
+ private Block honestAnchor;
|
|
+ private final List<FalconSeal> roundZero = new ArrayList<>();
|
|
+ private final List<FalconSeal> roundTwo = new ArrayList<>();
|
|
+
|
|
+ @BeforeEach
|
|
+ public void setUp() {
|
|
+ PqAnchorProducer.useConfigForTesting(config);
|
|
+ PqSealCache.instance().clear();
|
|
+ for (int i = 0; i < VALIDATORS; i++) {
|
|
+ validators.add(Address.fromHexString("0x" + "0".repeat(38) + "b" + i));
|
|
+ final SealScheme.GeneratedPair pair = SealSchemes.FALCON_512.generate(random);
|
|
+ falconPublic.add(pair.publicRegistryForm());
|
|
+ falconPrivate.add(pair.privateKey());
|
|
+ }
|
|
+ genesis = block(null);
|
|
+ b1 = block(genesis);
|
|
+ b2 = block(b1);
|
|
+ p = block(b2);
|
|
+ pPrime = block(b2);
|
|
+ for (final int i : new int[] {0, 1, 2, X}) {
|
|
+ roundZero.add(seal(i, p, 0));
|
|
+ }
|
|
+ for (final int i : new int[] {4, 5, 6, X}) {
|
|
+ roundTwo.add(seal(i, p, 2));
|
|
+ }
|
|
+ final List<FalconSeal> roundThreeOnPPrime = new ArrayList<>();
|
|
+ for (int i = 0; i <= 6; i++) {
|
|
+ roundThreeOnPPrime.add(seal(i, pPrime, 3));
|
|
+ }
|
|
+ honestAnchor = v3AnchorOver(pPrime, 3, rows(roundThreeOnPPrime));
|
|
+ // X's best certificate over p: all seven members under round 2 (its own seal of round 2)
|
|
+ final List<SchemeSeal> rows = new ArrayList<>();
|
|
+ for (final FalconSeal s : roundZero) {
|
|
+ if (s.getValidatorIndex() != X) {
|
|
+ rows.add(new SchemeSeal(FALCON, s.getValidatorIndex(), s.getSignature()));
|
|
+ }
|
|
+ }
|
|
+ for (final FalconSeal s : roundTwo) {
|
|
+ rows.add(new SchemeSeal(FALCON, s.getValidatorIndex(), s.getSignature()));
|
|
+ }
|
|
+ anchor = v3AnchorOver(p, 2, rows);
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ public void tearDown() {
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ PqSealCache.instance().disablePersistence();
|
|
+ PqSealCache.instance().clear();
|
|
+ }
|
|
+
|
|
+ private AereCertifiedDecision decision(final LongPredicate headerSealActive) {
|
|
+ return AereD412DecidedWiring.certifiedDecision(config, codec, validatorProvider(), H_EV, registry(), headerSealActive);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void controlTheProductionDecisionOfXsAnchorIsTheGrandparentFromHhdrAndNothingBelow() {
|
|
+ final MutableBlockchain chain = chain();
|
|
+ chain.appendBlock(p, List.of());
|
|
+ chain.appendBlock(anchor, List.of());
|
|
+ assertThat(decision(h -> h >= HR).decidedBy(chain, anchor.getHeader()))
|
|
+ .as("control: from H_hdr the builder's decision of X's v3 over p is block 2 (four members of round 2, f + 1)")
|
|
+ .contains(new AereDecidedHead.Decided(2L, b2.getHash()));
|
|
+ assertThat(decision(h -> false).decidedBy(chain, anchor.getHeader()))
|
|
+ .as("AERE-Q3-RF1-V3: below H_hdr nothing (round-free, the old rule named p here through the ECDSA branch)")
|
|
+ .isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aRestartDoesNotTakeTheUndecidedSiblingFromTheFinalizedTag() {
|
|
+ restartFromTheFinalizedTag(true);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The regime of 2800 at H_r (review of step 5, point 6): TR comes BEFORE T5, so at H_r the live headers are below H_hdr,
|
|
+ * exactly where the old rule named p through the ECDSA branch.
|
|
+ */
|
|
+ @Test
|
|
+ public void belowHhdrARestartDoesNotTakeTheUndecidedSiblingFromTheFinalizedTag() {
|
|
+ restartFromTheFinalizedTag(false);
|
|
+ // control of the guard below H_hdr: on the chain of p' and its honest certificate (Q of round 3) it does take p'
|
|
+ final MutableBlockchain decided = chain();
|
|
+ decided.appendBlock(pPrime, List.of());
|
|
+ decided.appendBlock(honestAnchor, List.of());
|
|
+ assertThat(AereD412DecidedWiring.finalizedProves(decided, config, decision(h -> false)).test(pPrime.getHeader()))
|
|
+ .as("control: below H_hdr the guard takes p', which seven seals of ONE round decide")
|
|
+ .isTrue();
|
|
+ }
|
|
+
|
|
+ private void restartFromTheFinalizedTag(final boolean fromHhdr) {
|
|
+ final MutableBlockchain chain = chain();
|
|
+ final Path dir = tmp.resolve(fromHhdr ? "finalized-hhdr" : "finalized-sub-hhdr");
|
|
+ final LongPredicate hhdr = fromHhdr ? h -> h >= HR : h -> false;
|
|
+ final Predicate<BlockHeader> proves =
|
|
+ AereD412DecidedWiring.finalizedProves(chain, config, decision(hhdr));
|
|
+ final AereDecidedHead first =
|
|
+ AereD412DecidedWiring.installHead(chain, H_EV, true, dir, m -> {}, proves).orElseThrow();
|
|
+ assertThat(first.advance(b2.getHash(), AereDecidedHead.Proof.Q1))
|
|
+ .as("control: D = block 2, durable")
|
|
+ .isEqualTo(AereDecidedHead.Outcome.ADVANCED);
|
|
+ chain.appendBlock(p, List.of());
|
|
+ chain.appendBlock(anchor, List.of());
|
|
+ assertThat(chain.getChainHeadHeader().getHash())
|
|
+ .as("control: L adopted p and X's anchor over it")
|
|
+ .isEqualTo(anchor.getHash());
|
|
+ chain.setFinalized(p.getHash());
|
|
+ assertThat(proves.test(p.getHeader()))
|
|
+ .as("AERE-Q3-RF1-V3: the guard does not take p from X's certificate")
|
|
+ .isFalse();
|
|
+ final AereDecidedHead restarted =
|
|
+ AereD412DecidedWiring.installHead(chain, H_EV, true, dir, m -> {}, proves).orElseThrow();
|
|
+ assertThat(restarted.decided().hash())
|
|
+ .as(
|
|
+ "AERE-Q3-RF1-V3: the restart must not take p from the finalized tag (from H_hdr: %s); p' is decided at height 3",
|
|
+ fromHhdr)
|
|
+ .isNotEqualTo(p.getHash());
|
|
+ if (fromHhdr) {
|
|
+ assertThat(proves.test(b2.getHeader()))
|
|
+ .as("control: the guard does take the block the certificate decides, block 2")
|
|
+ .isTrue();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Review of step 5, point 5: the restart FROM SEALSTORE-2. The head file a node writes from H_r - 1 (every round, its rows)
|
|
+ * holds the seals of rounds 0 and 2 over p; the restart restores them, re-verified over their own M_r (measured: both
|
|
+ * rounds are back, four rows each), and the decided head it installs is still the durable block 2. The decided head reads
|
|
+ * no seals at all since 1(a) / 2(c); what this pins is that restoring the file does not change that.
|
|
+ */
|
|
+ @Test
|
|
+ public void aRestartFromTheSealStoreFileDoesNotTakeTheUndecidedSibling() throws Exception {
|
|
+ final MutableBlockchain chain = chain();
|
|
+ final Path dir = tmp.resolve("seals");
|
|
+ final Path data = tmp.resolve("data");
|
|
+ Files.createDirectories(data);
|
|
+ final AereDecidedHead first =
|
|
+ AereD412DecidedWiring.installHead(chain, H_EV, true, dir, m -> {}, f -> false).orElseThrow();
|
|
+ assertThat(first.advance(b2.getHash(), AereDecidedHead.Proof.Q1))
|
|
+ .as("control: D = block 2, durable")
|
|
+ .isEqualTo(AereDecidedHead.Outcome.ADVANCED);
|
|
+ chain.appendBlock(p, List.of());
|
|
+ final TreeMap<Integer, List<SchemeSeal>> rounds = new TreeMap<>();
|
|
+ rounds.put(0, rows(roundZero));
|
|
+ rounds.put(2, rows(roundTwo));
|
|
+ PqSealStore.writeAtomically(
|
|
+ PqSealStore.fileIn(data), PqSealStore.encodeRounds(CHAIN, 3L, p.getHash().getBytes(), rounds));
|
|
+ PqSealCache.instance().clear();
|
|
+ PqSealCache.instance().enablePersistence(data, CHAIN);
|
|
+ final int restored = PqSealCache.instance().restoreFromDisk(3L, p.getHash(), registry());
|
|
+ assertThat(restored).as("control: the restart restored seals from the SEALSTORE-2 file").isGreaterThan(0);
|
|
+ assertThat(PqSealCache.instance().roundsFor(3L, p.getHash()).keySet())
|
|
+ .as("control: both rounds came back from the file, apart")
|
|
+ .containsExactly(0, 2);
|
|
+ assertThat(PqSealCache.instance().sealsFor(3L, p.getHash(), 0)).as("control: round 0, four rows").hasSize(4);
|
|
+ assertThat(PqSealCache.instance().sealsFor(3L, p.getHash(), 2))
|
|
+ .as("control: round 2, four rows (re-verified over M_2, not M_0)")
|
|
+ .hasSize(4);
|
|
+ final TreeSet<Integer> members = new TreeSet<>();
|
|
+ PqSealCache.instance()
|
|
+ .roundsFor(3L, p.getHash())
|
|
+ .values()
|
|
+ .forEach(r -> r.falcon().forEach(s -> members.add(s.getValidatorIndex())));
|
|
+ assertThat(members)
|
|
+ .as("control: across the rounds L holds seals of seven distinct members over p (the attack is expressible)")
|
|
+ .containsExactly(0, 1, 2, 4, 5, 6, X);
|
|
+ final AereDecidedHead restarted =
|
|
+ AereD412DecidedWiring.installHead(chain, H_EV, true, dir, m -> {}, f -> false).orElseThrow();
|
|
+ assertThat(restarted.decided().hash())
|
|
+ .as("AERE-Q3-RF1-V3: the restart keeps the durable D, block 2, never p from the seals it holds")
|
|
+ .isEqualTo(b2.getHash());
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // fixture
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /**
|
|
+ * Validator {@code who}'s seal on {@code b} at {@code round}, over the message of the one place under the configuration.
|
|
+ * No assertion on the message here (review of step 5, point 1: an assertion in setUp turned every probe of the class RED
|
|
+ * under a plantation, from setUp and not from the decision); the message is checked in AereRoundBoundCertificateTest.
|
|
+ */
|
|
+ private FalconSeal seal(final int who, final Block b, final int round) {
|
|
+ final Bytes32 m =
|
|
+ PqAnchorProducer.anchorSealMessage(config, b.getHeader().getNumber(), b.getHash().getBytes(), round).orElseThrow();
|
|
+ final byte[] signature = SealSchemes.FALCON_512.sign(falconPrivate.get(who), m.toArray()).orElseThrow();
|
|
+ return new FalconSeal(who, Bytes.wrap(signature));
|
|
+ }
|
|
+
|
|
+ private static List<SchemeSeal> rows(final List<FalconSeal> seals) {
|
|
+ final List<SchemeSeal> out = new ArrayList<>();
|
|
+ for (final FalconSeal s : seals) {
|
|
+ out.add(new SchemeSeal(FALCON, s.getValidatorIndex(), s.getSignature()));
|
|
+ }
|
|
+ out.sort(PqAnchorV2.CANONICAL);
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ private ValidatorProvider validatorProvider() {
|
|
+ final ValidatorProvider vp = mock(ValidatorProvider.class);
|
|
+ when(vp.getValidatorsAtHead()).thenReturn(validators);
|
|
+ when(vp.getValidatorsAfterBlock(any())).thenReturn(validators);
|
|
+ when(vp.getValidatorsForBlock(any())).thenReturn(validators);
|
|
+ return vp;
|
|
+ }
|
|
+
|
|
+ private PqSignerRegistry registry() {
|
|
+ return new PqSignerRegistry() {
|
|
+ @Override
|
|
+ public Address addressForIndexAtHistoric(final long blockNumber, final int validatorIndex) {
|
|
+ return validatorIndex >= 0 && validatorIndex < VALIDATORS ? validators.get(validatorIndex) : null;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Address addressForIndexAtOwnHead(final long blockNumber, final int validatorIndex) {
|
|
+ return addressForIndexAtHistoric(blockNumber, validatorIndex);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtHistoric(
|
|
+ final long blockNumber, final int validatorIndex, final Bytes message, final Bytes signature) {
|
|
+ return validatorIndex >= 0
|
|
+ && validatorIndex < VALIDATORS
|
|
+ && SealSchemes.FALCON_512.verifyRaw(falconPublic.get(validatorIndex), message.toArray(), signature.toArray());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtOwnHead(
|
|
+ final long blockNumber, final int validatorIndex, final Bytes message, final Bytes signature) {
|
|
+ return verifyAtHistoric(blockNumber, validatorIndex, message, signature);
|
|
+ }
|
|
+ };
|
|
+ }
|
|
+
|
|
+ /** L's chain before X's blocks: genesis, 1, 2. */
|
|
+ private MutableBlockchain chain() {
|
|
+ final MutableBlockchain chain =
|
|
+ InMemoryKeyValueStorageProvider.createInMemoryBlockchain(genesis, BftBlockHeaderFunctions.forOnchainBlock(codec));
|
|
+ chain.appendBlock(b1, List.of());
|
|
+ chain.appendBlock(b2, List.of());
|
|
+ return chain;
|
|
+ }
|
|
+
|
|
+ private Block block(final Block parent) {
|
|
+ tag++;
|
|
+ final BftExtraData extra =
|
|
+ new BftExtraData(Bytes32.leftPad(Bytes.ofUnsignedLong(tag)), List.of(), Optional.empty(), 0, validators);
|
|
+ return new Block(header(parent, extra, validators.get(0)), BlockBody.empty());
|
|
+ }
|
|
+
|
|
+ private Block v3AnchorOver(final Block parent, final int round, final List<SchemeSeal> rows) {
|
|
+ final List<SchemeSeal> sorted = new ArrayList<>(rows);
|
|
+ sorted.sort(PqAnchorV2.CANONICAL);
|
|
+ final BftExtraData extra =
|
|
+ new BftExtraData(
|
|
+ PqAnchorV3.anchorDigestV3(
|
|
+ CHAIN, parent.getHeader().getNumber(), parent.getHash().getBytes(), new PqAnchorV3.Certificate(round, sorted)),
|
|
+ List.of(),
|
|
+ Optional.empty(),
|
|
+ X,
|
|
+ validators,
|
|
+ List.of(),
|
|
+ sorted,
|
|
+ round);
|
|
+ return new Block(header(parent, extra, validators.get(X)), BlockBody.empty());
|
|
+ }
|
|
+
|
|
+ private BlockHeader header(final Block parent, final BftExtraData extra, final Address coinbase) {
|
|
+ final long number = parent == null ? 0L : parent.getHeader().getNumber() + 1;
|
|
+ return new BlockHeaderTestFixture()
|
|
+ .number(number)
|
|
+ .parentHash(parent == null ? Hash.ZERO : parent.getHash())
|
|
+ .difficulty(Difficulty.ONE)
|
|
+ .extraData(codec.encode(extra))
|
|
+ .timestamp(number)
|
|
+ .coinbase(coinbase)
|
|
+ .blockHeaderFunctions(BftBlockHeaderFunctions.forOnchainBlock(codec))
|
|
+ .buildHeader();
|
|
+ }
|
|
+}
|
|
diff --git a/app/src/test/java/org/hyperledger/besu/controller/AereRoundFreeRestartTest.java b/app/src/test/java/org/hyperledger/besu/controller/AereRoundFreeRestartTest.java
|
|
new file mode 100644
|
|
index 0000000000..5a9f44b9b5
|
|
--- /dev/null
|
|
+++ b/app/src/test/java/org/hyperledger/besu/controller/AereRoundFreeRestartTest.java
|
|
@@ -0,0 +1,330 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.controller;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
+import static org.mockito.Mockito.mock;
|
|
+import static org.mockito.Mockito.when;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AereCertifiedDecision;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSealCache;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSignerRegistry;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealScheme;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealSchemes;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
|
+import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec;
|
|
+import org.hyperledger.besu.crypto.SecureRandomProvider;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
+import org.hyperledger.besu.ethereum.core.Block;
|
|
+import org.hyperledger.besu.ethereum.core.BlockBody;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+import org.hyperledger.besu.ethereum.core.Difficulty;
|
|
+import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider;
|
|
+
|
|
+import java.nio.file.Path;
|
|
+import java.security.SecureRandom;
|
|
+import java.util.ArrayList;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+import java.util.function.LongPredicate;
|
|
+import java.util.function.Predicate;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.junit.jupiter.api.io.TempDir;
|
|
+
|
|
+/**
|
|
+ * AERE teza Q3, proba RF1, the restart half (marcaj AERE-Q3-RF1; PROIECT-PASUL3-BLOCANTE-2026-10-01.md,
|
|
+ * sectiunile 3.1 and 4.1). In the execution of AereRoundFreeCertificateTest (N = 10, X = 9 the single bad
|
|
+ * key) p collected seven round-free seals over M(p) = keccak(RLP["AERE-PQ-COMMIT-1", chainId, n, hash(p)])
|
|
+ * in rounds 0 and 2 and was never decided, while its sibling p' was decided at round 3.
|
|
+ *
|
|
+ * <p>The node L: D = block 2 durable (Q1), it heard rounds 0 and 2 of height 3 (so its seal cache holds
|
|
+ * the seven seals over M(p)), it did not hear round 3, and X sent it p (and, in (4), the anchor A over p,
|
|
+ * whose B1 tag of the morning of 2026-10-01 named p). Then L restarts, through the builder's own
|
|
+ * functions (AereD412DecidedWiring.installHead, finalizedProves, certifiedDecision).
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>(4) RF1-4: the restart does not take p from the finalized tag;
|
|
+ * <li>(4b) RF1-4b: the restart does not take p from the round-free seals it holds;
|
|
+ * <li>control: the production decision of A, from H_hdr, is block 2 (the grandparent), and below H_hdr
|
|
+ * it is p (the parent): the fixture is in the regime the claim is about.
|
|
+ * </ul>
|
|
+ *
|
|
+ * <p>On the code of 2026-10-01 morning (4) and (4b) came out RED with their markers (RAPORT-RF1.md): the
|
|
+ * restart took p through the Keff guard and through {@code sealedHeadEvidence}. Since project 1(a) and
|
|
+ * step 1 of 2(c) (teza Q3, D-470) the tag counts only when it is what a canonical anchor's certificate
|
|
+ * decides, and the seal evidence is gone, so (4) and (4b) are expected GREEN, each with a control that
|
|
+ * the fixture still expresses the attack (the tag on p, the seven seals over p in the cache).
|
|
+ */
|
|
+public class AereRoundFreeRestartTest {
|
|
+
|
|
+ private static final long CHAIN = 220_879L;
|
|
+ private static final long H_EV = 3L;
|
|
+ private static final long ANCHOR_HEIGHT = 4L;
|
|
+ private static final int VALIDATORS = 10;
|
|
+ private static final int X = 9;
|
|
+ private static final int K = 7;
|
|
+
|
|
+ @TempDir Path tmp;
|
|
+
|
|
+ private final QbftExtraDataCodec codec = new QbftExtraDataCodec();
|
|
+ private final PqAnchorConfig config =
|
|
+ new PqAnchorConfig(
|
|
+ CHAIN,
|
|
+ ANCHOR_HEIGHT,
|
|
+ Map.of(ANCHOR_HEIGHT, K),
|
|
+ OptionalInt.empty(),
|
|
+ false,
|
|
+ OptionalInt.empty(),
|
|
+ OptionalInt.of(4));
|
|
+ private final SecureRandom random = SecureRandomProvider.createSecureRandom();
|
|
+ private final List<Address> validators = new ArrayList<>();
|
|
+ private final List<byte[]> falconPublic = new ArrayList<>();
|
|
+ private final List<SealScheme.PrivateHandle> falconPrivate = new ArrayList<>();
|
|
+ private final List<FalconSeal> sealsOverP = new ArrayList<>();
|
|
+ private long tag;
|
|
+
|
|
+ private Block genesis;
|
|
+ private Block b1;
|
|
+ private Block b2;
|
|
+ private Block p;
|
|
+ private Block anchor;
|
|
+
|
|
+ @BeforeEach
|
|
+ public void setUp() {
|
|
+ PqAnchorProducer.useConfigForTesting(config);
|
|
+ PqSealCache.instance().clear();
|
|
+ for (int i = 0; i < VALIDATORS; i++) {
|
|
+ validators.add(Address.fromHexString("0x" + "0".repeat(38) + "a" + i));
|
|
+ final SealScheme.GeneratedPair pair = SealSchemes.FALCON_512.generate(random);
|
|
+ falconPublic.add(pair.publicRegistryForm());
|
|
+ falconPrivate.add(pair.privateKey());
|
|
+ }
|
|
+ genesis = block(null);
|
|
+ b1 = block(genesis);
|
|
+ b2 = block(b1);
|
|
+ p = block(b2);
|
|
+ // the seals over M(p) of rounds 0 (0, 1, 2), 2 (4, 5, 6) and X's: one message, whatever the round
|
|
+ final Bytes32 message = PqAnchor.commitMessage(CHAIN, p.getHeader().getNumber(), p.getHash().getBytes());
|
|
+ for (final int i : new int[] {0, 1, 2, 4, 5, 6, X}) {
|
|
+ final byte[] signature =
|
|
+ SealSchemes.FALCON_512.sign(falconPrivate.get(i), message.toArray()).orElseThrow();
|
|
+ sealsOverP.add(new FalconSeal(i, Bytes.wrap(signature)));
|
|
+ }
|
|
+ anchor = anchorOver(p, sealsOverP);
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ public void tearDown() {
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ PqSealCache.instance().clear();
|
|
+ }
|
|
+
|
|
+ /** H_hdr of this fixture: the anchor at 4 is in the regime where the header carries no ECDSA quorum. */
|
|
+ private static boolean aboveHhdr(final long height) {
|
|
+ return height >= ANCHOR_HEIGHT;
|
|
+ }
|
|
+
|
|
+ /** The builder's decision, with this fixture's registry and H_hdr. */
|
|
+ private AereCertifiedDecision decision(final LongPredicate headerSealActive) {
|
|
+ return AereD412DecidedWiring.certifiedDecision(
|
|
+ config, codec, validatorProvider(), H_EV, registry(), headerSealActive);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void controlTheProductionDecisionOfTheForgedAnchorIsTheGrandparent() {
|
|
+ final MutableBlockchain chain = chain();
|
|
+ chain.appendBlock(p, List.of());
|
|
+ chain.appendBlock(anchor, List.of());
|
|
+ assertThat(decision(AereRoundFreeRestartTest::aboveHhdr).decidedBy(chain, anchor.getHeader()))
|
|
+ .as("control: from H_hdr the builder's decision of the anchor over p is block 2, its grandparent")
|
|
+ .contains(new AereDecidedHead.Decided(2L, b2.getHash()));
|
|
+ assertThat(decision(h -> false).decidedBy(chain, anchor.getHeader()))
|
|
+ .as("control: below H_hdr (an ECDSA quorum of one round in the anchor's header) it is p, its parent")
|
|
+ .contains(new AereDecidedHead.Decided(3L, p.getHash()));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aRestartDoesNotTakeTheUndecidedSiblingFromTheFinalizedTag() {
|
|
+ final MutableBlockchain chain = chain();
|
|
+ final Path dir = tmp.resolve("finalized");
|
|
+ final Predicate<BlockHeader> proves =
|
|
+ AereD412DecidedWiring.finalizedProves(
|
|
+ chain, config, decision(AereRoundFreeRestartTest::aboveHhdr));
|
|
+ final AereDecidedHead first =
|
|
+ AereD412DecidedWiring.installHead(chain, H_EV, true, dir, m -> {}, proves).orElseThrow();
|
|
+ assertThat(first.advance(b2.getHash(), AereDecidedHead.Proof.Q1))
|
|
+ .as("control: D = block 2, durable")
|
|
+ .isEqualTo(AereDecidedHead.Outcome.ADVANCED);
|
|
+ chain.appendBlock(p, List.of());
|
|
+ chain.appendBlock(anchor, List.of());
|
|
+ assertThat(chain.getChainHeadHeader().getHash())
|
|
+ .as("control: L adopted p and the anchor over it (extensions of its decided head)")
|
|
+ .isEqualTo(anchor.getHash());
|
|
+ // the tag on p, as B1 set it until 2026-10-01 (the parent of the canonical certified anchor)
|
|
+ chain.setFinalized(p.getHash());
|
|
+ final AereDecidedHead restarted =
|
|
+ AereD412DecidedWiring.installHead(chain, H_EV, true, dir, m -> {}, proves).orElseThrow();
|
|
+ assertThat(restarted.decided().hash())
|
|
+ .as(
|
|
+ "RF1-4: the restart must not take p as decided from the finalized tag (its anchor carries seven"
|
|
+ + " round-free seals over M(p)); p' is the decided block at height 3")
|
|
+ .isNotEqualTo(p.getHash());
|
|
+ assertThat(proves.test(b2.getHeader()))
|
|
+ .as("control (4): the guard does take the block the anchor's certificate decides, block 2")
|
|
+ .isTrue();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aRestartDoesNotTakeTheUndecidedSiblingFromRoundFreeSeals() {
|
|
+ final MutableBlockchain chain = chain();
|
|
+ final Path dir = tmp.resolve("seals");
|
|
+ final AereDecidedHead first =
|
|
+ AereD412DecidedWiring.installHead(chain, H_EV, true, dir, m -> {}, f -> false).orElseThrow();
|
|
+ assertThat(first.advance(b2.getHash(), AereDecidedHead.Proof.Q1))
|
|
+ .as("control: D = block 2, durable")
|
|
+ .isEqualTo(AereDecidedHead.Outcome.ADVANCED);
|
|
+ chain.appendBlock(p, List.of());
|
|
+ assertThat(chain.getChainHeadHeader().getHash())
|
|
+ .as("control: L adopted p (an extension of its decided head)")
|
|
+ .isEqualTo(p.getHash());
|
|
+ // the seven seals over M(p) that L heard in rounds 0 and 2, in the node's own seal cache (where the seal
|
|
+ // file restores them at a restart, and where sealedHeadEvidence read them until 2026-10-01)
|
|
+ PqSealCache.instance().record(p.getHeader().getNumber(), p.getHash(), 0, sealsOverP);
|
|
+ assertThat(PqSealCache.instance().sealsFor(p.getHeader().getNumber(), p.getHash(), 0))
|
|
+ .as("control (4b): at the restart the cache holds the seven seals over p, a quorum of ten")
|
|
+ .hasSize(K);
|
|
+ final AereDecidedHead restarted =
|
|
+ AereD412DecidedWiring.installHead(chain, H_EV, true, dir, m -> {}, f -> false).orElseThrow();
|
|
+ assertThat(restarted.decided().hash())
|
|
+ .as(
|
|
+ "RF1-4b: the restart must not take p as decided from the seven seals over M(p) it restored"
|
|
+ + " (rounds 0 and 2, no round decided p); p' is the decided block at height 3")
|
|
+ .isNotEqualTo(p.getHash());
|
|
+ assertThat(restarted.decided().hash())
|
|
+ .as("control (4b): the restart keeps the durable D, block 2")
|
|
+ .isEqualTo(b2.getHash());
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // fixture
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ private ValidatorProvider validatorProvider() {
|
|
+ final ValidatorProvider vp = mock(ValidatorProvider.class);
|
|
+ when(vp.getValidatorsAtHead()).thenReturn(validators);
|
|
+ when(vp.getValidatorsAfterBlock(any())).thenReturn(validators);
|
|
+ when(vp.getValidatorsForBlock(any())).thenReturn(validators);
|
|
+ return vp;
|
|
+ }
|
|
+
|
|
+ /** Index i bound to validator i, verified by the real Falcon-512 scheme with validator i's key. */
|
|
+ private PqSignerRegistry registry() {
|
|
+ return new PqSignerRegistry() {
|
|
+ @Override
|
|
+ public Address addressForIndexAtHistoric(final long blockNumber, final int validatorIndex) {
|
|
+ return addressForIndexAtOwnHead(blockNumber, validatorIndex);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Address addressForIndexAtOwnHead(final long blockNumber, final int validatorIndex) {
|
|
+ return validatorIndex >= 0 && validatorIndex < VALIDATORS
|
|
+ ? validators.get(validatorIndex)
|
|
+ : null;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtHistoric(
|
|
+ final long blockNumber,
|
|
+ final int validatorIndex,
|
|
+ final Bytes message,
|
|
+ final Bytes signature) {
|
|
+ return verifyAtOwnHead(blockNumber, validatorIndex, message, signature);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtOwnHead(
|
|
+ final long blockNumber,
|
|
+ final int validatorIndex,
|
|
+ final Bytes message,
|
|
+ final Bytes signature) {
|
|
+ return validatorIndex >= 0
|
|
+ && validatorIndex < VALIDATORS
|
|
+ && SealSchemes.FALCON_512.verifyRaw(
|
|
+ falconPublic.get(validatorIndex), message.toArray(), signature.toArray());
|
|
+ }
|
|
+ };
|
|
+ }
|
|
+
|
|
+ /** L's chain before X's blocks: genesis, 1, 2. */
|
|
+ private MutableBlockchain chain() {
|
|
+ final MutableBlockchain chain =
|
|
+ InMemoryKeyValueStorageProvider.createInMemoryBlockchain(
|
|
+ genesis, BftBlockHeaderFunctions.forOnchainBlock(codec));
|
|
+ chain.appendBlock(b1, List.of());
|
|
+ chain.appendBlock(b2, List.of());
|
|
+ return chain;
|
|
+ }
|
|
+
|
|
+ /** A block with real QBFT extra data (the ten validators, round 0, a distinct vanity tag). */
|
|
+ private Block block(final Block parent) {
|
|
+ tag++;
|
|
+ final BftExtraData extra =
|
|
+ new BftExtraData(
|
|
+ Bytes32.leftPad(Bytes.ofUnsignedLong(tag)), List.of(), Optional.empty(), 0, validators);
|
|
+ return new Block(header(parent, extra, validators.get(0)), BlockBody.empty());
|
|
+ }
|
|
+
|
|
+ /** X's anchor over {@code parent}: the certificate, sorted, and its digest in vanityData. */
|
|
+ private Block anchorOver(final Block parent, final List<FalconSeal> certificate) {
|
|
+ final List<FalconSeal> sorted = PqAnchor.sortedByIndex(certificate);
|
|
+ final Bytes32 digest =
|
|
+ PqAnchor.anchorDigest(
|
|
+ CHAIN, parent.getHeader().getNumber(), parent.getHash().getBytes(), sorted);
|
|
+ final BftExtraData extra =
|
|
+ new BftExtraData(digest, List.of(), Optional.empty(), X, validators, sorted, java.util.List.of(), BftExtraData.NO_CERTIFICATE_ROUND);
|
|
+ return new Block(header(parent, extra, validators.get(X)), BlockBody.empty());
|
|
+ }
|
|
+
|
|
+ private BlockHeader header(final Block parent, final BftExtraData extra, final Address coinbase) {
|
|
+ final long number = parent == null ? 0L : parent.getHeader().getNumber() + 1;
|
|
+ return new BlockHeaderTestFixture()
|
|
+ .number(number)
|
|
+ .parentHash(parent == null ? Hash.ZERO : parent.getHash())
|
|
+ .difficulty(Difficulty.ONE)
|
|
+ .extraData(codec.encode(extra))
|
|
+ .timestamp(number)
|
|
+ .coinbase(coinbase)
|
|
+ .blockHeaderFunctions(BftBlockHeaderFunctions.forOnchainBlock(codec))
|
|
+ .buildHeader();
|
|
+ }
|
|
+}
|
|
diff --git a/app/src/test/java/org/hyperledger/besu/controller/PqTipAdoptionGateModeTest.java b/app/src/test/java/org/hyperledger/besu/controller/PqTipAdoptionGateModeTest.java
|
|
index 1e87f3b984..fc92b27aa5 100644
|
|
--- a/app/src/test/java/org/hyperledger/besu/controller/PqTipAdoptionGateModeTest.java
|
|
+++ b/app/src/test/java/org/hyperledger/besu/controller/PqTipAdoptionGateModeTest.java
|
|
@@ -73,41 +73,41 @@ class PqTipAdoptionGateModeTest {
|
|
private static BlockHeader header(final long number) {
|
|
return new BlockHeaderTestFixture().number(number).timestamp(TS.incrementAndGet()).buildHeader();
|
|
}
|
|
|
|
private PqTipAdoptionGate gate(final boolean enforce, final boolean sealsVerify) {
|
|
return new PqTipAdoptionGate(
|
|
provider,
|
|
LOCAL,
|
|
CHAIN_ID,
|
|
PqSealCache.instance(),
|
|
(n, i, m, s) -> sealsVerify,
|
|
enforce,
|
|
h -> h >= H_HDR);
|
|
}
|
|
|
|
private static void recordSeals(final BlockHeader h, final int count) {
|
|
final List<FalconSeal> seals =
|
|
java.util.stream.IntStream.range(0, count)
|
|
.mapToObj(i -> new FalconSeal(i, Bytes.of(i + 1)))
|
|
.toList();
|
|
- PqSealCache.instance().record(h.getNumber(), h.getHash(), seals);
|
|
+ PqSealCache.instance().record(h.getNumber(), h.getHash(), 0, seals);
|
|
}
|
|
|
|
@Test
|
|
void enforceRefusesATipBlockWithoutAQuorum() {
|
|
final BlockHeader h = header(150);
|
|
final PqTipAdoptionGate g = gate(true, true);
|
|
assertThat(g.mayAdopt(h, header(149))).isFalse();
|
|
assertThat(g.wouldRefuseCount()).isEqualTo(1);
|
|
}
|
|
|
|
@Test
|
|
void observeAdoptsTheSameBlockAndCountsIt() {
|
|
final BlockHeader h = header(150);
|
|
final PqTipAdoptionGate g = gate(false, true);
|
|
assertThat(g.mayAdopt(h, header(149))).isTrue();
|
|
assertThat(g.wouldRefuseCount()).isEqualTo(1);
|
|
}
|
|
|
|
@Test
|
|
void enforceAdoptsWithAVerifiedQuorum() {
|
|
diff --git a/app/src/test/java/org/hyperledger/besu/controller/PqTipAdoptionGateRoundTest.java b/app/src/test/java/org/hyperledger/besu/controller/PqTipAdoptionGateRoundTest.java
|
|
new file mode 100644
|
|
index 0000000000..c42964c605
|
|
--- /dev/null
|
|
+++ b/app/src/test/java/org/hyperledger/besu/controller/PqTipAdoptionGateRoundTest.java
|
|
@@ -0,0 +1,160 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.controller;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
+import static org.mockito.Mockito.mock;
|
|
+import static org.mockito.Mockito.when;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AerePqIdentity;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSealCache;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+
|
|
+import java.util.ArrayList;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.OptionalInt;
|
|
+import java.util.concurrent.atomic.AtomicLong;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), D-470, pasul 4 (2026-10-01): the propagation adoption gate (D-412 rule C) from H_r - 1 (project section 3.1 I).
|
|
+ * Each round is verified over its own M_r; the MAXIMUM over rounds is compared with the quorum, never the sum. Ten
|
|
+ * validators, Q = 7: r0 = 4 and r2 = 3 verified is refused under ENFORCE (a sum would adopt it), r2 = 7 is adopted, and a
|
|
+ * quorum of seals made over another round's message is refused. The verifier here accepts a seal only over the message of
|
|
+ * the round it was made in, so the gate is measured on WHICH message it asks for, not only on how many it counts.
|
|
+ */
|
|
+class PqTipAdoptionGateRoundTest {
|
|
+
|
|
+ private static final long CHAIN_ID = 28_097L;
|
|
+ private static final long H = 1_000L;
|
|
+ private static final long V2 = 1_005L;
|
|
+ private static final long HR = 1_100L;
|
|
+ private static final Address LOCAL = Address.fromHexString("0x00000000000000000000000000000000000000b0");
|
|
+ private static final AtomicLong TS = new AtomicLong(1_950_000_000L);
|
|
+
|
|
+ private ValidatorProvider provider;
|
|
+ private final List<Address> set = new ArrayList<>();
|
|
+
|
|
+ @BeforeEach
|
|
+ void setUp() {
|
|
+ AerePqIdentity.uninstall();
|
|
+ PqSealCache.instance().clear();
|
|
+ set.clear();
|
|
+ set.add(LOCAL);
|
|
+ for (int i = 1; i < 10; i++) {
|
|
+ set.add(Address.fromHexString(String.format("0x%040x", 0xB0 + i)));
|
|
+ }
|
|
+ provider = mock(ValidatorProvider.class);
|
|
+ when(provider.getValidatorsForBlock(any())).thenReturn(set);
|
|
+ PqAnchorProducer.useConfigForTesting(
|
|
+ new PqAnchorConfig(CHAIN_ID, H, Map.of(H, 3), OptionalInt.empty(), false, OptionalInt.empty(), OptionalInt.empty(), V2)
|
|
+ .withCommitRoundBlock(HR));
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ void tearDown() {
|
|
+ AerePqIdentity.uninstall();
|
|
+ PqSealCache.instance().clear();
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void theMaximumOverRoundsIsComparedNeverTheSum() {
|
|
+ final BlockHeader h = header(HR + 10L);
|
|
+ hear(h, 0, 0, 4);
|
|
+ hear(h, 2, 4, 7);
|
|
+ final PqTipAdoptionGate g = gate(h);
|
|
+ assertThat(g.mayAdopt(h, header(HR + 9L)))
|
|
+ .as("r0 = 4 and r2 = 3 verified, Q = 7: refused (a sum over rounds would have adopted it)")
|
|
+ .isFalse();
|
|
+ assertThat(g.wouldRefuseCount()).isEqualTo(1);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aQuorumOfOneRoundIsAdopted() {
|
|
+ final BlockHeader h = header(HR + 11L);
|
|
+ hear(h, 0, 0, 4);
|
|
+ hear(h, 2, 0, 7);
|
|
+ final PqTipAdoptionGate g = gate(h);
|
|
+ assertThat(g.mayAdopt(h, header(HR + 10L))).isTrue();
|
|
+ assertThat(g.wouldRefuseCount()).isZero();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aQuorumOfSealsOverAnotherRoundsMessageIsRefused() {
|
|
+ final BlockHeader h = header(HR + 12L);
|
|
+ // seven seals recorded under round 3 but made over M_0: none verifies over M_3
|
|
+ final List<FalconSeal> copied = new ArrayList<>();
|
|
+ for (int i = 0; i < 7; i++) {
|
|
+ copied.add(new FalconSeal(i, Bytes.of(0x29, 0, i)));
|
|
+ }
|
|
+ PqSealCache.instance().record(h.getNumber(), h.getHash(), 3, copied);
|
|
+ final PqTipAdoptionGate g = gate(h);
|
|
+ assertThat(g.mayAdopt(h, header(HR + 11L))).isFalse();
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------------------------------
|
|
+
|
|
+ private static BlockHeader header(final long number) {
|
|
+ return new BlockHeaderTestFixture().number(number).timestamp(TS.incrementAndGet()).buildHeader();
|
|
+ }
|
|
+
|
|
+ /** Seals of indices [from, to) made in {@code round} (its byte 1), recorded under that round. */
|
|
+ private static void hear(final BlockHeader h, final int round, final int from, final int to) {
|
|
+ final List<FalconSeal> seals = new ArrayList<>();
|
|
+ for (int i = from; i < to; i++) {
|
|
+ seals.add(new FalconSeal(i, Bytes.of(0x29, round, i)));
|
|
+ }
|
|
+ PqSealCache.instance().record(h.getNumber(), h.getHash(), round, seals);
|
|
+ }
|
|
+
|
|
+ /** ENFORCE, stage 5 active everywhere; a seal verifies only over M_r of the round it was made in (its byte 1). */
|
|
+ private PqTipAdoptionGate gate(final BlockHeader h) {
|
|
+ return new PqTipAdoptionGate(
|
|
+ provider,
|
|
+ LOCAL,
|
|
+ CHAIN_ID,
|
|
+ PqSealCache.instance(),
|
|
+ (n, i, m, s) -> m.equals(PqAnchor.commitMessageRound(CHAIN_ID, n, s.get(1), h.getHash().getBytes())),
|
|
+ true,
|
|
+ x -> true,
|
|
+ // index i is member i; 10 is bound outside the set, 11 is a second index of member 0
|
|
+ (n, i) -> i == 10 ? Address.fromHexString("0x" + "e".repeat(40)) : i == 11 ? set.get(0)
|
|
+ : i >= 0 && i < set.size() ? set.get(i) : null);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aNonMemberAndASecondIndexOfAMemberCountForNothing() {
|
|
+ final BlockHeader h = header(HR + 13L);
|
|
+ hear(h, 1, 0, 6);
|
|
+ hear(h, 1, 10, 12);
|
|
+ assertThat(gate(h).mayAdopt(h, header(HR + 12L)))
|
|
+ .as("six members, an outsider and a second index of member 0: six distinct members, not the quorum of seven")
|
|
+ .isFalse();
|
|
+ }
|
|
+}
|
|
diff --git a/app/src/test/java/org/hyperledger/besu/controller/PqTipAdoptionGateSetTest.java b/app/src/test/java/org/hyperledger/besu/controller/PqTipAdoptionGateSetTest.java
|
|
new file mode 100644
|
|
index 0000000000..13a80a14cf
|
|
--- /dev/null
|
|
+++ b/app/src/test/java/org/hyperledger/besu/controller/PqTipAdoptionGateSetTest.java
|
|
@@ -0,0 +1,405 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.controller;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AerePqIdentity;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftHelpers;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSealCache;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
|
+import org.hyperledger.besu.consensus.common.validator.VoteProvider;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+
|
|
+import java.lang.reflect.InvocationHandler;
|
|
+import java.lang.reflect.Method;
|
|
+import java.lang.reflect.Proxy;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collection;
|
|
+import java.util.Collections;
|
|
+import java.util.HashMap;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+import java.util.concurrent.atomic.AtomicLong;
|
|
+import java.util.stream.Collectors;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), step 11 (2026-10-09), besu-consens/R1: the propagation adoption gate (D-412 rule C) judges a block with the
|
|
+ * set that DECIDES it, set(h), not with the set of the height below, set(p). The two differ exactly at the height after a
|
|
+ * decisive vote in p: on 2800, block 18,083,403 voted 0xd38cb62a in, so set(18,083,403) has 9 members and
|
|
+ * set(18,083,404) has 10, and Q goes from 6 to 7.
|
|
+ *
|
|
+ * <p>Why a provider that answers by the header's NUMBER: the older probes of the gate mock {@code
|
|
+ * getValidatorsForBlock(any())} with one set, so they cannot tell set(p) from set(h) and stay green on both codes. Here
|
|
+ * {@code getValidatorsForBlock(header n)} is the set listed in block n (set(n)) and {@code getValidatorsAfterBlock(header
|
|
+ * n)} is set(n + 1), as BlockValidatorProvider gives them.
|
|
+ *
|
|
+ * <p>Only the cases where the two sets give DIFFERENT verdicts are probes (derived on the model of the review,
|
|
+ * a separate model of the rule): six seals of members of set(h) after a removal (Q falls from 7 to 6:
|
|
+ * adopt), six seals of the old members after an addition with the new member silent (Q rises from 6 to 7: refuse), in
|
|
+ * the form below H_r (seals counted by index) and in the round-bound form (seals counted by member of the set); and the
|
|
+ * question "is this node a validator here": the member that joined at h is gated at h, the one that left at h is not.
|
|
+ * Seven seals including the new member's would adopt under both sets and measure nothing, so it is not a probe here.
|
|
+ *
|
|
+ * <p>Each refusal is read from the gate's own log line (the verified count m and the quorum Q it compared), so a red
|
|
+ * says which m and which Q it judged with, not only that the verdict flipped.
|
|
+ */
|
|
+class PqTipAdoptionGateSetTest {
|
|
+
|
|
+ private static final long CHAIN_ID = 28_097L;
|
|
+ private static final long H = 1_000L;
|
|
+ private static final long V2 = 1_005L;
|
|
+ private static final long HR = 1_100L;
|
|
+ /** Below H_r - 1: anchor form, round-free (COMMIT-1), seals counted by index. */
|
|
+ private static final long FREE = 1_050L;
|
|
+ /** At or above H_r - 1: round-bound (COMMIT-2), seals counted by distinct member of the set. */
|
|
+ private static final long BOUND = HR + 20L;
|
|
+
|
|
+ private static final AtomicLong TS = new AtomicLong(1_960_000_000L);
|
|
+
|
|
+ /** Nine members v0..v8 (registry indices 0..8); X (index 9) joins, Y (index 10) leaves. */
|
|
+ private static final List<Address> NINE = new ArrayList<>();
|
|
+
|
|
+ private static final Address X = Address.fromHexString("0x00000000000000000000000000000000000000c9");
|
|
+ private static final Address Y = Address.fromHexString("0x00000000000000000000000000000000000000ca");
|
|
+
|
|
+ static {
|
|
+ for (int i = 0; i < 9; i++) {
|
|
+ NINE.add(Address.fromHexString(String.format("0x%040x", 0xC0 + i)));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static final List<Address> NINE_AND_X = with(NINE, X);
|
|
+ private static final List<Address> NINE_AND_Y = with(NINE, Y);
|
|
+
|
|
+ private LogTap log;
|
|
+
|
|
+ @BeforeEach
|
|
+ void setUp() throws Exception {
|
|
+ AerePqIdentity.uninstall();
|
|
+ PqSealCache.instance().clear();
|
|
+ PqAnchorProducer.useConfigForTesting(
|
|
+ new PqAnchorConfig(CHAIN_ID, H, Map.of(H, 3), OptionalInt.empty(), false, OptionalInt.empty(), OptionalInt.empty(), V2)
|
|
+ .withCommitRoundBlock(HR));
|
|
+ log = new LogTap("aere-r1b-pas11-poarta");
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ void tearDown() throws Exception {
|
|
+ if (log != null) {
|
|
+ log.close();
|
|
+ }
|
|
+ AerePqIdentity.uninstall();
|
|
+ PqSealCache.instance().clear();
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void theFormsAreTheOnesThisProbeNeeds() {
|
|
+ // control of the fixture: the two heights are in the two forms, and Q moves with the set
|
|
+ assertThat(PqAnchorProducer.commitSealFormAt(PqAnchorProducer.config(), FREE))
|
|
+ .isEqualTo(PqAnchorProducer.CommitSealForm.ROUND_FREE);
|
|
+ assertThat(PqAnchorProducer.commitSealFormAt(PqAnchorProducer.config(), BOUND))
|
|
+ .isEqualTo(PqAnchorProducer.CommitSealForm.ROUND_BOUND);
|
|
+ assertThat(BftHelpers.calculateRequiredValidatorQuorum(9)).isEqualTo(6);
|
|
+ assertThat(BftHelpers.calculateRequiredValidatorQuorum(10)).isEqualTo(7);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void afterARemovalSixSealsOfTheNewSetAreAQuorumBelowHr() {
|
|
+ adoptedAfterRemoval(FREE);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void afterARemovalSixSealsOfTheNewSetAreAQuorumFromHr() {
|
|
+ adoptedAfterRemoval(BOUND);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void afterAnAdditionSixOldSealsAreNotAQuorumBelowHr() {
|
|
+ refusedAfterAddition(FREE);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void afterAnAdditionSixOldSealsAreNotAQuorumFromHr() {
|
|
+ refusedAfterAddition(BOUND);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void theMemberThatJoinedAtHIsGatedAtH() {
|
|
+ // this node is X: not in set(p), in set(h); it decides h, hears its commits, so it is gated (no seals: refused)
|
|
+ final BlockHeader p = header(BOUND - 1L);
|
|
+ final BlockHeader h = header(BOUND);
|
|
+ final PqTipAdoptionGate g = gate(X, provider(p, NINE, h, NINE_AND_X), h);
|
|
+ final boolean adopted = g.mayAdopt(h, p);
|
|
+ assertThat(adopted)
|
|
+ .as(
|
|
+ "X joined at h (set(p) = 9 without X, set(h) = 10 with X): the gate must judge X as a validator of h and "
|
|
+ + "refuse a block with no verified seal; adopted=%s, wouldRefuse=%s, gate lines %s",
|
|
+ adopted, g.wouldRefuseCount(), log.gateLines())
|
|
+ .isFalse();
|
|
+ assertThat(g.wouldRefuseCount()).isEqualTo(1);
|
|
+ refusalLine(0, 7);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void theMemberThatLeftAtHIsNotGatedAtH() {
|
|
+ // this node is Y: in set(p), not in set(h); it does not decide h, hears no commits of h, so it is not gated
|
|
+ final BlockHeader p = header(BOUND + 9L);
|
|
+ final BlockHeader h = header(BOUND + 10L);
|
|
+ final PqTipAdoptionGate g = gate(Y, provider(p, NINE_AND_Y, h, NINE), h);
|
|
+ final boolean adopted = g.mayAdopt(h, p);
|
|
+ assertThat(adopted)
|
|
+ .as(
|
|
+ "Y left at h (set(p) = 10 with Y, set(h) = 9 without Y): Y is not a validator of h and is not gated; "
|
|
+ + "adopted=%s, wouldRefuse=%s, gate lines %s",
|
|
+ adopted, g.wouldRefuseCount(), log.gateLines())
|
|
+ .isTrue();
|
|
+ assertThat(g.wouldRefuseCount()).as("gate lines %s", log.gateLines()).isZero();
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------------------------------
|
|
+
|
|
+ /** set(p) = 10 with Y, set(h) = 9 without Y; six verified seals of members of set(h) (indices 0..5); ENFORCE. */
|
|
+ private void adoptedAfterRemoval(final long at) {
|
|
+ final BlockHeader p = header(at - 1L);
|
|
+ final BlockHeader h = header(at);
|
|
+ hear(h, 0, 0, 6);
|
|
+ final PqTipAdoptionGate g = gate(NINE.get(0), provider(p, NINE_AND_Y, h, NINE), h);
|
|
+ final boolean adopted = g.mayAdopt(h, p);
|
|
+ assertThat(adopted)
|
|
+ .as(
|
|
+ "removal at h: six verified seals of members of set(h) (9 members, Q = 6) are a quorum and the block is adopted;"
|
|
+ + " a refusal here means the gate judged with set(p) (10 members, Q = 7). adopted=%s, gate lines %s",
|
|
+ adopted, log.gateLines())
|
|
+ .isTrue();
|
|
+ assertThat(g.wouldRefuseCount()).as("gate lines %s", log.gateLines()).isZero();
|
|
+ assertThat(log.gateLines()).as("no refusal line").noneMatch(l -> l.contains("NOT adopting"));
|
|
+ }
|
|
+
|
|
+ /** set(p) = 9, set(h) = 10 with X; six verified seals of the old members (indices 0..5), X silent; ENFORCE. */
|
|
+ private void refusedAfterAddition(final long at) {
|
|
+ final BlockHeader p = header(at - 1L);
|
|
+ final BlockHeader h = header(at);
|
|
+ hear(h, 0, 0, 6);
|
|
+ final PqTipAdoptionGate g = gate(NINE.get(0), provider(p, NINE, h, NINE_AND_X), h);
|
|
+ final boolean adopted = g.mayAdopt(h, p);
|
|
+ assertThat(adopted)
|
|
+ .as(
|
|
+ "addition at h: six verified seals out of set(h) (10 members, Q = 7) are NOT a quorum and the block is refused;"
|
|
+ + " an adoption here means the gate judged with set(p) (9 members, Q = 6). adopted=%s, gate lines %s",
|
|
+ adopted, log.gateLines())
|
|
+ .isFalse();
|
|
+ assertThat(g.wouldRefuseCount()).isEqualTo(1);
|
|
+ refusalLine(6, 7);
|
|
+ }
|
|
+
|
|
+ /** The gate's refusal line names m verified and the quorum Q it compared them with. */
|
|
+ private void refusalLine(final int m, final int q) {
|
|
+ assertThat(log.gateLines())
|
|
+ .as("the gate's own refusal line, with m = %s and Q = %s", m, q)
|
|
+ .anyMatch(
|
|
+ l -> l.contains("NOT adopting") && l.contains("holds " + m + " verified") && l.contains("quorum is " + q + ";"));
|
|
+ }
|
|
+
|
|
+ private static List<Address> with(final List<Address> base, final Address extra) {
|
|
+ final List<Address> out = new ArrayList<>(base);
|
|
+ out.add(extra);
|
|
+ return Collections.unmodifiableList(out);
|
|
+ }
|
|
+
|
|
+ private static BlockHeader header(final long number) {
|
|
+ return new BlockHeaderTestFixture().number(number).timestamp(TS.incrementAndGet()).buildHeader();
|
|
+ }
|
|
+
|
|
+ /** Seals of registry indices [from, to), made in {@code round} (byte 1 of the signature), recorded under it. */
|
|
+ private static void hear(final BlockHeader h, final int round, final int from, final int to) {
|
|
+ final List<FalconSeal> seals = new ArrayList<>();
|
|
+ for (int i = from; i < to; i++) {
|
|
+ seals.add(new FalconSeal(i, Bytes.of(0x29, round, i)));
|
|
+ }
|
|
+ PqSealCache.instance().record(h.getNumber(), h.getHash(), round, seals);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * A provider that answers by the header's NUMBER: getValidatorsForBlock(n) = set(n), getValidatorsAfterBlock(n) =
|
|
+ * set(n + 1). Only the two heights of the probe are known; any other number is a fixture error and throws.
|
|
+ */
|
|
+ private static ValidatorProvider provider(
|
|
+ final BlockHeader p, final List<Address> setP, final BlockHeader h, final List<Address> setH) {
|
|
+ final Map<Long, List<Address>> sets = new HashMap<>();
|
|
+ sets.put(p.getNumber(), setP);
|
|
+ sets.put(h.getNumber(), setH);
|
|
+ return new ValidatorProvider() {
|
|
+ private List<Address> at(final long n) {
|
|
+ final List<Address> s = sets.get(n);
|
|
+ if (s == null) {
|
|
+ throw new IllegalStateException("fixture: no set for block " + n);
|
|
+ }
|
|
+ return s;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Collection<Address> getValidatorsAtHead() {
|
|
+ return at(h.getNumber());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Collection<Address> getValidatorsAfterBlock(final BlockHeader header) {
|
|
+ return at(header.getNumber() + 1L);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Collection<Address> getValidatorsForBlock(final BlockHeader header) {
|
|
+ return at(header.getNumber());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Optional<VoteProvider> getVoteProviderAtHead() {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ };
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * ENFORCE, stage 5 active everywhere; this node is {@code local}. A seal verifies only over the message of its own
|
|
+ * form: M_r of the round in its byte 1 from H_r - 1, COMMIT-1 below. Registry index i is member i of the nine, 9 is X,
|
|
+ * 10 is Y.
|
|
+ */
|
|
+ private static PqTipAdoptionGate gate(final Address local, final ValidatorProvider vp, final BlockHeader h) {
|
|
+ return new PqTipAdoptionGate(
|
|
+ vp,
|
|
+ local,
|
|
+ CHAIN_ID,
|
|
+ PqSealCache.instance(),
|
|
+ (n, i, m, s) ->
|
|
+ PqAnchorProducer.commitSealFormAt(PqAnchorProducer.config(), n)
|
|
+ == PqAnchorProducer.CommitSealForm.ROUND_BOUND
|
|
+ ? m.equals(PqAnchor.commitMessageRound(CHAIN_ID, n, s.get(1), h.getHash().getBytes()))
|
|
+ : m.equals(PqAnchorProducer.roundFreeMessage(CHAIN_ID, n, h.getHash().getBytes())),
|
|
+ true,
|
|
+ x -> true,
|
|
+ (n, i) -> i >= 0 && i < 9 ? NINE.get(i) : i == 9 ? X : i == 10 ? Y : null);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * A Log4j2 appender built as a dynamic proxy on the root logger (the PqInertBinaryTest method): reflective, so this
|
|
+ * module takes no compile dependency on log4j, and the build's ban on LogManager in code stays honoured. It throws if
|
|
+ * any step fails: a tap that quietly hears nothing would make every "no refusal line" assertion pass for nothing.
|
|
+ */
|
|
+ static final class LogTap implements AutoCloseable {
|
|
+ private final List<String> lines = Collections.synchronizedList(new ArrayList<>());
|
|
+ private final String name;
|
|
+ private final Object rootLoggerConfig;
|
|
+ private final Object ctx;
|
|
+ private final Object priorLevel;
|
|
+ private final Class<?> loggerConfigCls;
|
|
+ private final Class<?> levelCls;
|
|
+ private final Class<?> ctxCls;
|
|
+
|
|
+ LogTap(final String name) throws Exception {
|
|
+ this.name = name;
|
|
+ final Class<?> appenderCls = Class.forName("org.apache.logging.log4j.core.Appender");
|
|
+ final Class<?> eventCls = Class.forName("org.apache.logging.log4j.core.LogEvent");
|
|
+ final Class<?> configCls = Class.forName("org.apache.logging.log4j.core.config.Configuration");
|
|
+ final Class<?> filterCls = Class.forName("org.apache.logging.log4j.core.Filter");
|
|
+ final Class<?> stateCls = Class.forName("org.apache.logging.log4j.core.LifeCycle$State");
|
|
+ final Class<?> messageCls = Class.forName("org.apache.logging.log4j.message.Message");
|
|
+ loggerConfigCls = Class.forName("org.apache.logging.log4j.core.config.LoggerConfig");
|
|
+ levelCls = Class.forName("org.apache.logging.log4j.Level");
|
|
+ ctxCls = Class.forName("org.apache.logging.log4j.core.LoggerContext");
|
|
+ final Object c =
|
|
+ Class.forName("org.apache.logging.log4j.LogManager")
|
|
+ .getMethod("getContext", boolean.class)
|
|
+ .invoke(null, Boolean.FALSE);
|
|
+ if (!ctxCls.isInstance(c)) {
|
|
+ throw new IllegalStateException("the SLF4J binding in this JVM is not log4j-core: " + c.getClass().getName());
|
|
+ }
|
|
+ ctx = c;
|
|
+ rootLoggerConfig = configCls.getMethod("getRootLogger").invoke(ctxCls.getMethod("getConfiguration").invoke(c));
|
|
+ final Method getMessage = eventCls.getMethod("getMessage");
|
|
+ final Method getLoggerName = eventCls.getMethod("getLoggerName");
|
|
+ final Method formatted = messageCls.getMethod("getFormattedMessage");
|
|
+ Object startedState = null;
|
|
+ for (final Object s : stateCls.getEnumConstants()) {
|
|
+ if ("STARTED".equals(((Enum<?>) s).name())) {
|
|
+ startedState = s;
|
|
+ }
|
|
+ }
|
|
+ final Object started = startedState;
|
|
+ final InvocationHandler handler =
|
|
+ (proxy, method, args) -> {
|
|
+ switch (method.getName()) {
|
|
+ case "append":
|
|
+ lines.add(getLoggerName.invoke(args[0]) + " | " + formatted.invoke(getMessage.invoke(args[0])));
|
|
+ return null;
|
|
+ case "getName":
|
|
+ case "toString":
|
|
+ return name;
|
|
+ case "isStarted":
|
|
+ return Boolean.TRUE;
|
|
+ case "isStopped":
|
|
+ return Boolean.FALSE;
|
|
+ case "getState":
|
|
+ return started;
|
|
+ case "ignoreExceptions":
|
|
+ return Boolean.TRUE;
|
|
+ case "equals":
|
|
+ return proxy == args[0];
|
|
+ case "hashCode":
|
|
+ return System.identityHashCode(proxy);
|
|
+ default:
|
|
+ return null;
|
|
+ }
|
|
+ };
|
|
+ final Object appender =
|
|
+ Proxy.newProxyInstance(LogTap.class.getClassLoader(), new Class<?>[] {appenderCls}, handler);
|
|
+ final Object all = levelCls.getField("ALL").get(null);
|
|
+ priorLevel = loggerConfigCls.getMethod("getLevel").invoke(rootLoggerConfig);
|
|
+ loggerConfigCls.getMethod("addAppender", appenderCls, levelCls, filterCls).invoke(rootLoggerConfig, appender, all, null);
|
|
+ loggerConfigCls.getMethod("setLevel", levelCls).invoke(rootLoggerConfig, all);
|
|
+ ctxCls.getMethod("updateLoggers").invoke(ctx);
|
|
+ }
|
|
+
|
|
+ /** The lines the gate itself wrote. */
|
|
+ List<String> gateLines() {
|
|
+ synchronized (lines) {
|
|
+ return lines.stream()
|
|
+ .filter(l -> l.startsWith(PqTipAdoptionGate.class.getName() + " | "))
|
|
+ .collect(Collectors.toList());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void close() throws Exception {
|
|
+ loggerConfigCls.getMethod("removeAppender", String.class).invoke(rootLoggerConfig, name);
|
|
+ loggerConfigCls.getMethod("setLevel", levelCls).invoke(rootLoggerConfig, priorLevel);
|
|
+ ctxCls.getMethod("updateLoggers").invoke(ctx);
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/app/src/test/java/org/hyperledger/besu/ethereum/eth/sync/BlockPropagationManagerDecidedTest.java b/app/src/test/java/org/hyperledger/besu/ethereum/eth/sync/BlockPropagationManagerDecidedTest.java
|
|
new file mode 100644
|
|
index 0000000000..120ea245c0
|
|
--- /dev/null
|
|
+++ b/app/src/test/java/org/hyperledger/besu/ethereum/eth/sync/BlockPropagationManagerDecidedTest.java
|
|
@@ -0,0 +1,309 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.ethereum.eth.sync;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
+import static org.mockito.Mockito.doAnswer;
|
|
+import static org.mockito.Mockito.mock;
|
|
+import static org.mockito.Mockito.when;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead;
|
|
+import org.hyperledger.besu.consensus.common.bft.AerePqIdentity;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSealCache;
|
|
+import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
|
+import org.hyperledger.besu.controller.AereD412DecidedWiringProbe;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.ProtocolContext;
|
|
+import org.hyperledger.besu.ethereum.chain.BadBlockManager;
|
|
+import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
+import org.hyperledger.besu.ethereum.core.Block;
|
|
+import org.hyperledger.besu.ethereum.core.BlockBody;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+import org.hyperledger.besu.ethereum.core.BlockImporter;
|
|
+import org.hyperledger.besu.ethereum.core.Difficulty;
|
|
+import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider;
|
|
+import org.hyperledger.besu.ethereum.eth.manager.EthContext;
|
|
+import org.hyperledger.besu.ethereum.eth.manager.EthMessages;
|
|
+import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
|
|
+import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
|
|
+import org.hyperledger.besu.ethereum.eth.sync.state.PendingBlocksManager;
|
|
+import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
|
|
+import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator;
|
|
+import org.hyperledger.besu.ethereum.mainnet.BlockImportResult;
|
|
+import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode;
|
|
+import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
|
+import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
|
|
+import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
|
+
|
|
+import java.nio.file.Path;
|
|
+import java.util.ArrayDeque;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Deque;
|
|
+import java.util.List;
|
|
+import java.util.Optional;
|
|
+import java.util.concurrent.CompletableFuture;
|
|
+import java.util.function.Supplier;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.junit.jupiter.api.io.TempDir;
|
|
+
|
|
+/**
|
|
+ * AERE D-412 / the DECIDED HEAD (rule D), step 3, proof P4 of PROIECT-CAP-DECIS-2026-09-29.md: the
|
|
+ * UPSTREAM {@link BlockPropagationManager}, unchanged, over a REAL in-memory DefaultBlockchain on which
|
|
+ * {@code AereD412DecidedWiring} (the class the builder calls for these decisions, reached here through
|
|
+ * {@code AereD412DecidedWiringProbe}, which only delegates) installed or did not install the decided
|
|
+ * head's block choice rule, with the propagation adoption gate that class chose. The builder's OWN lines
|
|
+ * are not run here; {@code AereD412BuilderTest} runs the real builder. Only the network, the scheduler
|
|
+ * (a queue the proof drains, like the sync worker) and block validity (every header valid, import =
|
|
+ * append) are stand-ins.
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>(a) H1 through the pending-children path: D = B*; C' (child of the forged sibling B') arrives
|
|
+ * first and waits for its parent; then B' arrives, is stored as a fork, and C' is imported by
|
|
+ * {@code maybeProcessPendingChildrenBlocks}. The head stays B*. Control in the same proof: the
|
|
+ * same blocks on a node where AereD412DecidedWiring installs no rule (a reader) put C' at the
|
|
+ * head, so the fixture can express the attack.
|
|
+ * <li>(b) the D-419 resumption: the fleet decided B*, this validator missed the commits; B* arrives by
|
|
+ * propagation, is STORED (the gate never refuses under rule D, even with ENFORCE asked for), and
|
|
+ * a later Q2 moves D onto it. Control in the same proof: the gate of a node without rule D, with
|
|
+ * ENFORCE asked for, refuses B*, and the same Q2 cannot move D (the block is not stored).
|
|
+ * </ul>
|
|
+ */
|
|
+public class BlockPropagationManagerDecidedTest {
|
|
+
|
|
+ private static final long H_EV = 2L;
|
|
+
|
|
+ @TempDir Path tmp;
|
|
+
|
|
+ private long tag;
|
|
+ private final Address local = Address.fromHexString("0x00000000000000000000000000000000000000a1");
|
|
+ private final List<Address> set =
|
|
+ List.of(
|
|
+ local,
|
|
+ Address.fromHexString("0x00000000000000000000000000000000000000a2"),
|
|
+ Address.fromHexString("0x00000000000000000000000000000000000000a3"),
|
|
+ Address.fromHexString("0x00000000000000000000000000000000000000a4"));
|
|
+
|
|
+ @AfterEach
|
|
+ public void resetGate() {
|
|
+ PropagatedBlockAdoptionGate.reset();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aPendingChildOfAForgedSiblingDoesNotBecomeTheHead() {
|
|
+ final Block g = block(null, 1);
|
|
+ final Block b1 = block(g, 1);
|
|
+ final Block bStar = block(b1, 1);
|
|
+ final Block bForged = block(b1, 1);
|
|
+ final Block cForged = block(bForged, 1);
|
|
+
|
|
+ final Node validator = new Node(g, List.of(b1, bStar), true);
|
|
+ assertThat(validator.head).as("AereD412DecidedWiring gives a validator the decided head").isPresent();
|
|
+ assertThat(validator.head.get().advance(bStar.getHash(), AereDecidedHead.Proof.Q1))
|
|
+ .isEqualTo(AereDecidedHead.Outcome.ADVANCED);
|
|
+ validator.propagate(cForged);
|
|
+ assertThat(validator.chain.getBlockHeader(cForged.getHash())).as("C' waits for its parent").isEmpty();
|
|
+ validator.propagate(bForged);
|
|
+ assertThat(validator.chain.getBlockHeader(cForged.getHash()))
|
|
+ .as("C' was imported by the pending-children path")
|
|
+ .isPresent();
|
|
+ assertThat(validator.chain.getChainHeadHeader().getHash())
|
|
+ .as("the decided node's head stays B*: C' became head only by total difficulty")
|
|
+ .isEqualTo(bStar.getHash());
|
|
+
|
|
+ final Node reader = new Node(g, List.of(b1, bStar), false);
|
|
+ assertThat(reader.head).as("AereD412DecidedWiring gives a reader no decided head").isEmpty();
|
|
+ reader.propagate(cForged);
|
|
+ reader.propagate(bForged);
|
|
+ assertThat(reader.chain.getChainHeadHeader().getHash())
|
|
+ .as("control: on total difficulty alone the same blocks put C' at the head")
|
|
+ .isEqualTo(cForged.getHash());
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aLaggardStoresThePropagatedBlockAndAChildProofMovesTheDecidedHead() {
|
|
+ final Block g = block(null, 1);
|
|
+ final Block b1 = block(g, 1);
|
|
+ final Block bStar = block(b1, 1);
|
|
+
|
|
+ final Node laggard = new Node(g, List.of(b1), true);
|
|
+ PropagatedBlockAdoptionGate.install(
|
|
+ AereD412DecidedWiringProbe.tipGate(
|
|
+ H_EV, laggard.vp, local, 28001L, PqSealCache.instance(), (n, i, m, s) -> false, true, h -> true));
|
|
+ laggard.propagate(bStar);
|
|
+ assertThat(laggard.chain.getBlockHeader(bStar.getHash()))
|
|
+ .as("under rule D the propagated block is stored, even with ENFORCE asked for")
|
|
+ .isPresent();
|
|
+ assertThat(laggard.head.get().advance(bStar.getHash(), AereDecidedHead.Proof.Q2))
|
|
+ .as("the child proof moves D onto it")
|
|
+ .isEqualTo(AereDecidedHead.Outcome.ADVANCED);
|
|
+ assertThat(laggard.head.get().decided().hash()).isEqualTo(bStar.getHash());
|
|
+
|
|
+ final Node old = new Node(g, List.of(b1), true);
|
|
+ PropagatedBlockAdoptionGate.install(
|
|
+ AereD412DecidedWiringProbe.tipGate(
|
|
+ AerePqIdentity.NEVER,
|
|
+ old.vp,
|
|
+ local,
|
|
+ 28001L,
|
|
+ PqSealCache.instance(),
|
|
+ (n, i, m, s) -> false,
|
|
+ true,
|
|
+ h -> true));
|
|
+ old.propagate(bStar);
|
|
+ assertThat(old.chain.getBlockHeader(bStar.getHash()))
|
|
+ .as("control: the old ENFORCE gate refuses the block the fleet decided")
|
|
+ .isEmpty();
|
|
+ assertThat(old.head.get().advance(bStar.getHash(), AereDecidedHead.Proof.Q2))
|
|
+ .as("control: and no proof can move D onto a block that is not stored (the D-419 wedge)")
|
|
+ .isEqualTo(AereDecidedHead.Outcome.NOT_STORED);
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // fixtures
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /** One node: its chain, the rule-D decision of AereD412DecidedWiring on it, and the upstream propagation manager. */
|
|
+ private final class Node {
|
|
+ private final MutableBlockchain chain;
|
|
+ private final Optional<AereDecidedHead> head;
|
|
+ private final ValidatorProvider vp;
|
|
+ private final Deque<Runnable> queue = new ArrayDeque<>();
|
|
+ private final BlockPropagationManager manager;
|
|
+ private final List<String> alarms = new ArrayList<>();
|
|
+
|
|
+ @SuppressWarnings({"unchecked", "rawtypes"})
|
|
+ Node(final Block genesis, final List<Block> blocks, final boolean validator) {
|
|
+ chain = InMemoryKeyValueStorageProvider.createInMemoryBlockchain(genesis);
|
|
+ for (final Block b : blocks) {
|
|
+ chain.appendBlock(b, List.of());
|
|
+ }
|
|
+ vp = mock(ValidatorProvider.class);
|
|
+ when(vp.getValidatorsForBlock(any())).thenReturn(set);
|
|
+ when(vp.getValidatorsAtHead()).thenReturn(set);
|
|
+ when(vp.getValidatorsAfterBlock(any())).thenReturn(set);
|
|
+ final Path dir = tmp.resolve("node" + (++tag));
|
|
+ head =
|
|
+ AereD412DecidedWiringProbe.installHead(
|
|
+ chain,
|
|
+ H_EV,
|
|
+ AereD412DecidedWiringProbe.isValidatorNode(
|
|
+ false, validator ? set : List.of(set.get(1)), local),
|
|
+ dir,
|
|
+ alarms::add,
|
|
+ f -> false);
|
|
+
|
|
+ final ProtocolContext context = mock(ProtocolContext.class);
|
|
+ when(context.getBlockchain()).thenReturn(chain);
|
|
+ when(context.getBadBlockManager()).thenReturn(new BadBlockManager());
|
|
+ final BlockHeaderValidator headerValidator = mock(BlockHeaderValidator.class);
|
|
+ when(headerValidator.validateHeader(
|
|
+ any(BlockHeader.class),
|
|
+ any(BlockHeader.class),
|
|
+ any(ProtocolContext.class),
|
|
+ any(HeaderValidationMode.class)))
|
|
+ .thenReturn(true);
|
|
+ final BlockImporter importer = mock(BlockImporter.class);
|
|
+ when(importer.importBlock(
|
|
+ any(ProtocolContext.class), any(Block.class), any(HeaderValidationMode.class)))
|
|
+ .thenAnswer(
|
|
+ inv -> {
|
|
+ final Block b = inv.getArgument(1);
|
|
+ chain.appendBlock(b, List.of());
|
|
+ return new BlockImportResult(true);
|
|
+ });
|
|
+ final ProtocolSpec spec = mock(ProtocolSpec.class);
|
|
+ when(spec.getBlockHeaderValidator()).thenReturn(headerValidator);
|
|
+ when(spec.getBlockImporter()).thenReturn(importer);
|
|
+ final ProtocolSchedule schedule = mock(ProtocolSchedule.class);
|
|
+ when(schedule.getByBlockHeader(any())).thenReturn(spec);
|
|
+
|
|
+ final EthScheduler scheduler = mock(EthScheduler.class);
|
|
+ when(scheduler.scheduleSyncWorkerTask(any(Supplier.class)))
|
|
+ .thenAnswer(
|
|
+ inv -> {
|
|
+ final Supplier<CompletableFuture<Object>> task = inv.getArgument(0);
|
|
+ final CompletableFuture<Object> promise = new CompletableFuture<>();
|
|
+ queue.add(
|
|
+ () ->
|
|
+ task.get()
|
|
+ .whenComplete(
|
|
+ (r, t) -> {
|
|
+ if (t != null) {
|
|
+ promise.completeExceptionally(t);
|
|
+ } else {
|
|
+ promise.complete(r);
|
|
+ }
|
|
+ }));
|
|
+ return promise;
|
|
+ });
|
|
+ doAnswer(
|
|
+ inv -> {
|
|
+ queue.add(inv.getArgument(0));
|
|
+ return null;
|
|
+ })
|
|
+ .when(scheduler)
|
|
+ .scheduleSyncWorkerTask(any(Runnable.class));
|
|
+ when(scheduler.scheduleServiceTask(any(Supplier.class))).thenReturn(new CompletableFuture<>());
|
|
+ final EthContext ethContext = mock(EthContext.class);
|
|
+ when(ethContext.getScheduler()).thenReturn(scheduler);
|
|
+ when(ethContext.getEthPeers()).thenReturn(mock(EthPeers.class));
|
|
+ when(ethContext.getEthMessages()).thenReturn(mock(EthMessages.class));
|
|
+
|
|
+ final SynchronizerConfiguration config = SynchronizerConfiguration.builder().build();
|
|
+ manager =
|
|
+ new BlockPropagationManager(
|
|
+ config,
|
|
+ schedule,
|
|
+ context,
|
|
+ ethContext,
|
|
+ mock(SyncState.class),
|
|
+ new PendingBlocksManager(config),
|
|
+ new NoOpMetricsSystem(),
|
|
+ mock(BlockBroadcaster.class));
|
|
+ manager.start();
|
|
+ }
|
|
+
|
|
+ /** A block arrives by propagation (NewBlock), then the sync workers run to completion. */
|
|
+ void propagate(final Block block) {
|
|
+ manager.importOrSavePendingBlock(block, Bytes.of(7));
|
|
+ Runnable r;
|
|
+ int guard = 0;
|
|
+ while ((r = queue.poll()) != null && guard++ < 10_000) {
|
|
+ r.run();
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private Block block(final Block parent, final long difficulty) {
|
|
+ tag++;
|
|
+ final long number = parent == null ? 0L : parent.getHeader().getNumber() + 1;
|
|
+ final Hash parentHash = parent == null ? Hash.ZERO : parent.getHash();
|
|
+ return new Block(
|
|
+ new BlockHeaderTestFixture()
|
|
+ .number(number)
|
|
+ .parentHash(parentHash)
|
|
+ .difficulty(Difficulty.of(difficulty))
|
|
+ .extraData(Bytes.ofUnsignedLong(tag))
|
|
+ .timestamp(number)
|
|
+ .buildHeader(),
|
|
+ BlockBody.empty());
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/AereCertifiedDecision.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/AereCertifiedDecision.java
|
|
new file mode 100644
|
|
index 0000000000..e1842debfd
|
|
--- /dev/null
|
|
+++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/AereCertifiedDecision.java
|
|
@@ -0,0 +1,288 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.common.bft;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.ethereum.chain.Blockchain;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collection;
|
|
+import java.util.HashSet;
|
|
+import java.util.List;
|
|
+import java.util.Objects;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+import java.util.Set;
|
|
+import java.util.function.Function;
|
|
+import java.util.function.LongPredicate;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+
|
|
+/**
|
|
+ * AERE teza Q3 / D-470 (2026-10-01, proiectul 1(a) din PROIECT-PASUL3-BLOCANTE-2026-10-01.md): the ONE
|
|
+ * answer to "which block does this anchor's certificate prove decided?", read by the decided head's
|
|
+ * wiring (Q3), by the finalized tags (B1) and by the restart (the finalized tag is taken only when it is
|
|
+ * this answer). Marker: AERE-Q3-BUNIC.
|
|
+ *
|
|
+ * <p><b>Why not the parent.</b> The post-quantum commit seal signs M(b) =
|
|
+ * keccak(RLP["AERE-PQ-COMMIT-1", chainId, n, hash(b)]), which carries NO round, and an honest QBFT
|
|
+ * validator may commit the same block in two rounds and then another block. So K seals over the parent
|
|
+ * p do not show that p was decided, for ANY K (Teorema 1; measured on today's code by
|
|
+ * AereRoundFreeCertificateTest, RAPORT-RF1.md). What f + 1 seals of distinct members of the set that
|
|
+ * decides p DO show, when every honest validator runs rule D from H_ev (it commits a block only over its
|
|
+ * decided head): at least one honest member committed p, so p's parent was its decided head, so p's
|
|
+ * parent is decided (Teorema 3). Hence:
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li><b>below H_hdr</b>: the anchor's own header carries the ECDSA committed seals of ONE round (the
|
|
+ * upstream rule, checked at import), so the anchor was decided and so was its PARENT. This is the
|
|
+ * finalized tag of today, unchanged below H_hdr;
|
|
+ * <li><b>from H_hdr</b>: the GRANDPARENT, and only when the parent p is at or above H_ev (rule D governs
|
|
+ * the commits on p), the anchor is outside every named lapse window ({@link PqAnchorLapse}: rules
|
|
+ * off, or the threshold lowered; all of them on 2800 and far below any H_hdr, so the check costs
|
|
+ * nothing and keeps a future window out by construction), and at least f + 1 DISTINCT members of the set that decides p carry a
|
|
+ * Falcon-512 seal over M(p) that verifies NOW against the registry at p's height (the seals are
|
|
+ * re-verified here, never trusted from the import: a block stored by another route, or a lapse,
|
|
+ * must not count); f from the size of that set. Keff (the configured threshold) plays no part: what
|
|
+ * proves is the number of verified members, not the number asked for;
|
|
+ * <li>otherwise nothing.
|
|
+ * </ul>
|
|
+ *
|
|
+ * <p><b>From H_r (1(b), 2026-10-01, marker AERE-R1B-PARINTE-Q).</b> The anchor's certificate is v3:
|
|
+ * every seal signs M_r(p), with the round r inside the message, so Q verified distinct members of the
|
|
+ * set that decides p show that p was decided in round r: the PARENT, with no H_ev and no rule D; with
|
|
+ * fewer than Q but at least f + 1 (from H_hdr, p >= H_ev) the grandparent as above; and no ECDSA branch
|
|
+ * at all at a >= H_r. See {@link #decidedByV3}.
|
|
+ *
|
|
+ * <p>What this does NOT give below H_r: the adversary of AIP-22 (every classical key) is not covered,
|
|
+ * since the argument rests on the decided heads of honest validators, and those rest on Q1, whose round
|
|
+ * is bound by the ECDSA commit seal only (RF2, D-470); 1(b) puts the round inside the post-quantum seal
|
|
+ * (the founder said "da" on 2026-10-01), and the parent rule above is that answer from H_r.
|
|
+ */
|
|
+public final class AereCertifiedDecision {
|
|
+
|
|
+ private final PqAnchorConfig config;
|
|
+ private final BftExtraDataCodec codec;
|
|
+ private final PqSignerRegistry registry;
|
|
+ private final Function<BlockHeader, Collection<Address>> setDeciding;
|
|
+ private final LongPredicate headerSealActive;
|
|
+ private final long activationHeight;
|
|
+
|
|
+ /**
|
|
+ * The decision of one node.
|
|
+ *
|
|
+ * @param config the anchor configuration (anchor heights, chain id)
|
|
+ * @param codec decodes a header's extra data (the certificate)
|
|
+ * @param registry the Falcon registry the seals are verified against, at the parent's height
|
|
+ * @param setDeciding the validators that decide a block (production: getValidatorsForBlock)
|
|
+ * @param headerSealActive whether a height is at or above H_hdr (production: AerePqHeaderSeal::active)
|
|
+ * @param activationHeight H_ev of rule D, or {@link AerePqIdentity#NEVER}
|
|
+ */
|
|
+ public AereCertifiedDecision(
|
|
+ final PqAnchorConfig config,
|
|
+ final BftExtraDataCodec codec,
|
|
+ final PqSignerRegistry registry,
|
|
+ final Function<BlockHeader, Collection<Address>> setDeciding,
|
|
+ final LongPredicate headerSealActive,
|
|
+ final long activationHeight) {
|
|
+ this.config = Objects.requireNonNull(config, "config");
|
|
+ this.codec = Objects.requireNonNull(codec, "codec");
|
|
+ this.registry = Objects.requireNonNull(registry, "registry");
|
|
+ this.setDeciding = Objects.requireNonNull(setDeciding, "setDeciding");
|
|
+ this.headerSealActive = Objects.requireNonNull(headerSealActive, "headerSealActive");
|
|
+ this.activationHeight = activationHeight;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * f + 1 of a set of this size: the number of distinct members whose seals show that at least one
|
|
+ * honest member committed the block.
|
|
+ *
|
|
+ * @param setSize the size of the set that decides the block
|
|
+ * @return f + 1
|
|
+ */
|
|
+ public static int threshold(final int setSize) {
|
|
+ return (setSize - 1) / 3 + 1;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The block this anchor's certificate proves decided, or empty.
|
|
+ *
|
|
+ * @param chain where the anchor's parent is looked up (canonical or fork)
|
|
+ * @param anchor the header of a stored block
|
|
+ * @return below H_hdr the parent, from H_hdr the grandparent (see the class), or empty
|
|
+ */
|
|
+ public Optional<AereDecidedHead.Decided> decidedBy(
|
|
+ final Blockchain chain, final BlockHeader anchor) {
|
|
+ try {
|
|
+ final long a = anchor.getNumber();
|
|
+ if (!config.anchorAppliesAt(a)) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ final BftExtraData extra = codec.decodeRaw(anchor.getExtraData());
|
|
+ if (!AerePqFinalityTags.carriesCertificate(extra)) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ if (config.certificateFormAt(a) == PqAnchorConfig.CertificateForm.V3) {
|
|
+ return decidedByV3(chain, anchor, extra);
|
|
+ }
|
|
+ if (!headerSealActive.test(a)) {
|
|
+ return Optional.of(new AereDecidedHead.Decided(a - 1L, anchor.getParentHash()));
|
|
+ }
|
|
+ if (PqAnchorLapse.windowCovering(config.chainId(), a).isPresent()) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ final Optional<BlockHeader> parent = chain.getBlockHeader(anchor.getParentHash());
|
|
+ if (parent.isEmpty() || parent.get().getNumber() != a - 1L) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ final BlockHeader p = parent.get();
|
|
+ if (p.getNumber() < activationHeight || p.getNumber() < 1L) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ final Collection<Address> set = setDeciding.apply(p);
|
|
+ if (set == null || set.isEmpty()) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ if (verifiedMembers(p, extra, set) < threshold(set.size())) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ return Optional.of(new AereDecidedHead.Decided(p.getNumber() - 1L, p.getParentHash()));
|
|
+ } catch (final RuntimeException e) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * AERE-R1B-PARINTE-Q (1(b), section 3.1 B, 2026-10-01): the answer at an anchor a >= H_r, whose
|
|
+ * certificate is v3 (every seal over M_r(p) of ONE round r, the round inside the signed message).
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>m >= Q(|set(p)|) verified distinct members of the set that decides p: the PARENT (Teorema 2: a
|
|
+ * quorum of one round committed p in that round, so p was decided; neither H_ev nor rule D is
|
|
+ * needed);
|
|
+ * <li>otherwise, from H_hdr, with p >= H_ev and m >= f + 1: the GRANDPARENT (Teorema 3 holds with M_r
|
|
+ * too: an honest member committed p, so p's parent was its decided head);
|
|
+ * <li>otherwise nothing. There is NO ECDSA branch at a >= H_r: a v3 anchor below H_hdr whose seals
|
|
+ * do not reach Q proves nothing, even though its header carries the ECDSA committed seals.
|
|
+ * </ul>
|
|
+ *
|
|
+ * <p>The seals are counted by {@link PqAnchorV3#verifiedFalconMembers}, through the same message and
|
|
+ * the same historic registry doors as R2, and re-verified here: never trusted from the import. The
|
|
+ * empty v3 certificate (K_eff = 0, decision H5) counts 0 and proves nothing.
|
|
+ */
|
|
+ private Optional<AereDecidedHead.Decided> decidedByV3(
|
|
+ final Blockchain chain, final BlockHeader anchor, final BftExtraData extra) {
|
|
+ final long a = anchor.getNumber();
|
|
+ final OptionalInt round = extra.getCertificateRound();
|
|
+ if (round.isEmpty()) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ if (PqAnchorLapse.windowCovering(config.chainId(), a).isPresent()) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ final Optional<BlockHeader> parent = chain.getBlockHeader(anchor.getParentHash());
|
|
+ if (parent.isEmpty() || parent.get().getNumber() != a - 1L) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ final BlockHeader p = parent.get();
|
|
+ if (p.getNumber() < 1L) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ final Collection<Address> set = setDeciding.apply(p);
|
|
+ if (set == null || set.isEmpty()) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ final int m = verifiedMembersOfRound(p, extra, set, round.getAsInt());
|
|
+ if (m >= BftHelpers.calculateRequiredValidatorQuorum(set.size())) {
|
|
+ return Optional.of(new AereDecidedHead.Decided(p.getNumber(), p.getHash()));
|
|
+ }
|
|
+ if (headerSealActive.test(a)
|
|
+ && p.getNumber() >= activationHeight
|
|
+ && m >= threshold(set.size())) {
|
|
+ return Optional.of(new AereDecidedHead.Decided(p.getNumber() - 1L, p.getParentHash()));
|
|
+ }
|
|
+ return Optional.empty();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many DISTINCT members of {@code set} carry, in a v3 certificate of round r, a Falcon-512 seal
|
|
+ * over M_r(p) that verifies against the registry at p's height. Through {@link
|
|
+ * PqAnchorV3#verifiedFalconMembers}, the function R2's doors share (1(b), section 3.1 B).
|
|
+ *
|
|
+ * @param p the anchor's parent
|
|
+ * @param extra the anchor's decoded extra data (v3: the rows are the hybrid list)
|
|
+ * @param set the set that decides p
|
|
+ * @param round the certificate's round
|
|
+ * @return the number of verified distinct members of that round
|
|
+ */
|
|
+ public int verifiedMembersOfRound(
|
|
+ final BlockHeader p, final BftExtraData extra, final Collection<Address> set, final int round) {
|
|
+ final long pn = p.getNumber();
|
|
+ return PqAnchorV3.verifiedFalconMembers(
|
|
+ config,
|
|
+ pn,
|
|
+ p.getHash().getBytes(),
|
|
+ new PqAnchorV3.Certificate(round, extra.getHybridSeals()),
|
|
+ PqAnchorV3.historicSigners(registry, pn, () -> set));
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many DISTINCT members of {@code set} carry, in the certificate, a Falcon-512 seal over M(p) that
|
|
+ * verifies against the registry at p's height (v1: the Falcon list; v2: the Falcon rows of the
|
|
+ * scheme-tagged list). A seal of an index bound to no one, to a non-member, to a member already
|
|
+ * counted, or that does not verify, counts for nothing. Below H_r only (the v3 anchors go through
|
|
+ * {@link #verifiedMembersOfRound}); the message is COMMIT-1, taken since 2026-10-01 from the one place.
|
|
+ *
|
|
+ * @param p the anchor's parent
|
|
+ * @param extra the anchor's decoded extra data
|
|
+ * @param set the set that decides p
|
|
+ * @return the number of verified distinct members
|
|
+ */
|
|
+ public int verifiedMembers(
|
|
+ final BlockHeader p, final BftExtraData extra, final Collection<Address> set) {
|
|
+ final List<FalconSeal> falcon = new ArrayList<>(extra.getFalconSeals());
|
|
+ for (final SchemeSeal s : extra.getHybridSeals()) {
|
|
+ if (s.getSchemeWireId() == SealSchemes.FALCON_512.wireId()) {
|
|
+ falcon.add(new FalconSeal(s.getValidatorIndex(), s.getSignature()));
|
|
+ }
|
|
+ }
|
|
+ final Bytes32 message =
|
|
+ PqAnchorProducer.roundFreeMessage(config.chainId(), p.getNumber(), p.getHash().getBytes());
|
|
+ final Set<Address> members = new HashSet<>();
|
|
+ for (final FalconSeal seal : falcon) {
|
|
+ final Address who = registry.addressForIndexAtHistoric(p.getNumber(), seal.getValidatorIndex());
|
|
+ if (who == null || !set.contains(who) || members.contains(who)) {
|
|
+ continue;
|
|
+ }
|
|
+ if (registry.verifyAtHistoric(
|
|
+ p.getNumber(), seal.getValidatorIndex(), message, seal.getSignature())) {
|
|
+ members.add(who);
|
|
+ }
|
|
+ }
|
|
+ return members.size();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The answer as a function over one chain (what the wiring and the tags are handed).
|
|
+ *
|
|
+ * @param chain the chain
|
|
+ * @return anchor header -> the block it proves decided
|
|
+ */
|
|
+ public Function<BlockHeader, Optional<AereDecidedHead.Decided>> over(final Blockchain chain) {
|
|
+ return h -> decidedBy(chain, h);
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/AereDecidedBlockChoiceRule.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/AereDecidedBlockChoiceRule.java
|
|
new file mode 100644
|
|
index 0000000000..cc83994b5e
|
|
--- /dev/null
|
|
+++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/AereDecidedBlockChoiceRule.java
|
|
@@ -0,0 +1,151 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.common.bft;
|
|
+
|
|
+import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+
|
|
+import java.util.Comparator;
|
|
+import java.util.Objects;
|
|
+import java.util.concurrent.atomic.AtomicLong;
|
|
+
|
|
+import org.slf4j.Logger;
|
|
+import org.slf4j.LoggerFactory;
|
|
+
|
|
+/**
|
|
+ * AERE D-412 / the DECIDED HEAD (rule D), step 2: the block choice rule of a VALIDATOR, a wrapper
|
|
+ * over the chain's own rule ({@code DefaultBlockchain.getBlockChoiceRule()}, total difficulty).
|
|
+ *
|
|
+ * <p>{@code DefaultBlockchain} calls it only when a new block does NOT extend the current head (the
|
|
+ * extension of the head is taken without asking, and keeps invariant I). It answers:
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>below H_ev (both blocks lower than the activation height): the chain's own rule, exactly as
|
|
+ * today;
|
|
+ * <li>otherwise, with compat(x) = x descends from D or is an ancestor of D: a compatible new block
|
|
+ * against an incompatible head wins (+1), an incompatible new block against a compatible head
|
|
+ * loses (-1), and in every other case the chain's own rule decides;
|
|
+ * <li>any failure while judging (an ancestry that cannot be followed, a missing header): the
|
|
+ * chain's own rule, with a WARN, so the rule can never stop an import it cannot judge.
|
|
+ * </ul>
|
|
+ *
|
|
+ * <p>So on a node that decided B* at h, a tail B' -> C' built by one key on a sibling of B* stays a
|
|
+ * fork however heavy it is (H1), and a head that is still provisional (above D) follows total
|
|
+ * difficulty as before. It is meant for validators only: readers keep total difficulty.
|
|
+ */
|
|
+public final class AereDecidedBlockChoiceRule implements Comparator<BlockHeader> {
|
|
+
|
|
+ private static final Logger LOG = LoggerFactory.getLogger(AereDecidedBlockChoiceRule.class);
|
|
+
|
|
+ private final Comparator<BlockHeader> upstream;
|
|
+ private final AereDecidedHead decided;
|
|
+ private final AtomicLong calls = new AtomicLong();
|
|
+ private final AtomicLong overrides = new AtomicLong();
|
|
+ private final AtomicLong fallbacks = new AtomicLong();
|
|
+
|
|
+ /**
|
|
+ * The rule over an upstream rule.
|
|
+ *
|
|
+ * @param upstream the chain's own rule (total difficulty)
|
|
+ * @param decided the node's decided head
|
|
+ */
|
|
+ public AereDecidedBlockChoiceRule(
|
|
+ final Comparator<BlockHeader> upstream, final AereDecidedHead decided) {
|
|
+ this.upstream = Objects.requireNonNull(upstream, "upstream");
|
|
+ this.decided = Objects.requireNonNull(decided, "decided");
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Wrap the chain's current rule and install the wrapper on the chain.
|
|
+ *
|
|
+ * @param blockchain the chain
|
|
+ * @param decided the node's decided head
|
|
+ * @return the installed rule
|
|
+ */
|
|
+ public static AereDecidedBlockChoiceRule install(
|
|
+ final MutableBlockchain blockchain, final AereDecidedHead decided) {
|
|
+ final AereDecidedBlockChoiceRule rule =
|
|
+ new AereDecidedBlockChoiceRule(blockchain.getBlockChoiceRule(), decided);
|
|
+ blockchain.setBlockChoiceRule(rule);
|
|
+ return rule;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int compare(final BlockHeader newBlock, final BlockHeader head) {
|
|
+ calls.incrementAndGet();
|
|
+ int verdict;
|
|
+ try {
|
|
+ verdict = decide(newBlock, head);
|
|
+ } catch (final RuntimeException e) {
|
|
+ final long n = fallbacks.incrementAndGet();
|
|
+ LOG.warn(
|
|
+ "AERE D-412 decided head: the block choice rule could not judge block {} against the head"
|
|
+ + " {} ({}); total difficulty decides (fallback {})",
|
|
+ newBlock.getNumber(),
|
|
+ head.getNumber(),
|
|
+ e.getMessage(),
|
|
+ n);
|
|
+ verdict = 0;
|
|
+ }
|
|
+ if (verdict != 0) {
|
|
+ overrides.incrementAndGet();
|
|
+ return verdict;
|
|
+ }
|
|
+ return upstream.compare(newBlock, head);
|
|
+ }
|
|
+
|
|
+ /** +1 / -1 when D decides, 0 when the chain's own rule must. */
|
|
+ private int decide(final BlockHeader newBlock, final BlockHeader head) {
|
|
+ if (!decided.active(Math.max(newBlock.getNumber(), head.getNumber()))) {
|
|
+ return 0;
|
|
+ }
|
|
+ final boolean newCompatible = decided.compatible(newBlock);
|
|
+ final boolean headCompatible = decided.compatible(head);
|
|
+ if (newCompatible && !headCompatible) {
|
|
+ return 1;
|
|
+ }
|
|
+ if (headCompatible && !newCompatible) {
|
|
+ return -1;
|
|
+ }
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many times the chain asked.
|
|
+ *
|
|
+ * @return the count
|
|
+ */
|
|
+ public long calls() {
|
|
+ return calls.get();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many answers came from D rather than from the chain's own rule.
|
|
+ *
|
|
+ * @return the count
|
|
+ */
|
|
+ public long overrides() {
|
|
+ return overrides.get();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many times judging failed and the chain's own rule decided.
|
|
+ *
|
|
+ * @return the count
|
|
+ */
|
|
+ public long fallbacks() {
|
|
+ return fallbacks.get();
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/AereDecidedHead.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/AereDecidedHead.java
|
|
new file mode 100644
|
|
index 0000000000..1b6b325fc4
|
|
--- /dev/null
|
|
+++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/AereDecidedHead.java
|
|
@@ -0,0 +1,1045 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.common.bft;
|
|
+
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+
|
|
+import java.io.IOException;
|
|
+import java.nio.ByteBuffer;
|
|
+import java.nio.channels.FileChannel;
|
|
+import java.nio.charset.StandardCharsets;
|
|
+import java.nio.file.Files;
|
|
+import java.nio.file.Path;
|
|
+import java.nio.file.StandardCopyOption;
|
|
+import java.nio.file.StandardOpenOption;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collection;
|
|
+import java.util.List;
|
|
+import java.util.Objects;
|
|
+import java.util.Optional;
|
|
+import java.util.concurrent.atomic.AtomicLong;
|
|
+import java.util.function.Consumer;
|
|
+import java.util.function.Predicate;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.slf4j.Logger;
|
|
+import org.slf4j.LoggerFactory;
|
|
+
|
|
+/**
|
|
+ * AERE D-412 / the DECIDED HEAD (rule D), step 2 of PROIECT-CAP-DECIS-2026-09-29.md: the node's
|
|
+ * decided head D and the only way it moves. Nothing wires it into the controller, the adaptor or the
|
|
+ * builder yet (that is step 3); this class and {@link AereDecidedBlockChoiceRule} are the pieces.
|
|
+ *
|
|
+ * <p><b>What D is.</b> A stored block, on the canonical chain (invariant I: canonical(D.number) ==
|
|
+ * D.hash), for which the node holds a proof one key cannot forge: a quorum of one round's commits
|
|
+ * (Q1), f+1 commits of the child's set on a child (Q2), the block a certified anchor's certificate
|
|
+ * decides ({@link AereCertifiedDecision}: the parent below H_hdr, the grandparent from H_hdr; teza Q3,
|
|
+ * 2026-10-01) (Q3), ancestry of a decided block (Q4), or the restart evidence (Q6). The proofs themselves are
|
|
+ * judged elsewhere ({@code AereDecisionEvidence} in qbft-core); this class is told "block h is decided
|
|
+ * by proof p" and keeps D consistent with the chain.
|
|
+ *
|
|
+ * <p><b>Below the PROOF height nothing changes</b> (Q5): the canonical head, capped at H_ev - 2, is
|
|
+ * D, nothing is written, and the block choice rule is the chain's own total difficulty. The proof
|
|
+ * height is H_ev - 1, not H_ev (corrected 2026-10-01, review of step 3): rule D governs the consensus
|
|
+ * of heights >= H_ev, so the PARENT of H_ev must be a proved block too. Below H_ev a single key can
|
|
+ * still make honest nodes adopt a sibling (C1 is upstream behaviour there), so the canonical block at
|
|
+ * H_ev - 1 is not the same block on every node; taken as D (Q5) it froze a split at H_ev for good.
|
|
+ * A proof at or above the proof height that does not descend from a Q5 D moves D anyway: Q5 is not a
|
|
+ * proof ({@link #advance}).
|
|
+ *
|
|
+ * <p><b>The durable floor</b> (2026-10-01, review of step 3): a D written durably whose block the
|
|
+ * node does not hold at a restart (the tail of the chain database lost in a power cut) is not
|
|
+ * dropped. It stays a FLOOR: the node neither proposes nor votes at any height up to it ({@link
|
|
+ * #belowFloor}, read by the final state) until D reaches it, by the block stored again ({@link
|
|
+ * #resolveFloor}) or by a proof on its line; a proof against it is a CONFLICT.
|
|
+ *
|
|
+ * <p><b>How D moves ({@link #advance}).</b> Only up, and only onto a block that descends from the
|
|
+ * current D. The new D is written DURABLY first (temporary file, fsync, atomic rename, fsync of the
|
|
+ * directory), then, holding the blockchain's own monitor (the one {@code appendBlock} holds), the
|
|
+ * chain is rewound onto it when it is not canonical, and only then does D change in memory. A write
|
|
+ * that fails leaves D and the chain exactly where they were. A block that is decided but does not
|
|
+ * descend from D, or a second decided block at a decided height, is a CONFLICT: logged and alarmed
|
|
+ * as {@code AERE-D412-DECIDED-CONFLICT} and D does not move (it takes more than f faulty
|
|
+ * validators).
|
|
+ *
|
|
+ * <p><b>Reading D is lock-free</b> ({@link #decided}, {@link #compatible}, {@link #isDecided}):
|
|
+ * the block choice rule calls them while {@code DefaultBlockchain.appendBlock} holds the chain's
|
|
+ * monitor, and a writer holds this object's monitor before it takes the chain's, so a reader that
|
|
+ * took this object's monitor could deadlock against it.
|
|
+ *
|
|
+ * <p>NOT measured here: that an fsync reaches the platter across a power cut, the latency of one
|
|
+ * fsync per block on the fleet's disks, and the Bonsai world state after {@code rewindToBlock}
|
|
+ * (which moves only the chain data).
|
|
+ */
|
|
+public final class AereDecidedHead {
|
|
+
|
|
+ private static final Logger LOG = LoggerFactory.getLogger(AereDecidedHead.class);
|
|
+
|
|
+ /** Two decided blocks at one height, or a decided block off the decided head's line. */
|
|
+ public static final String CODE_CONFLICT = "AERE-D412-DECIDED-CONFLICT";
|
|
+
|
|
+ /** The decided head could not be written durably; it did not move. */
|
|
+ public static final String CODE_NOT_DURABLE = "AERE-D412-DECIDED-NOT-DURABLE";
|
|
+
|
|
+ /** The chain could not be rewound onto a durable decided head; it did not move in memory. */
|
|
+ public static final String CODE_REWIND = "AERE-D412-DECIDED-REWIND";
|
|
+
|
|
+ /**
|
|
+ * A durable D whose block the node does not hold: it neither proposes nor votes up to that height
|
|
+ * until D reaches it. Repeated while it lasts; "RESOLVED" when D reaches it.
|
|
+ */
|
|
+ public static final String CODE_FLOOR = "AERE-D412-DECIDED-FLOOR";
|
|
+
|
|
+ /** The floor alarm is repeated at most this often while the node stays below its floor. */
|
|
+ public static final long FLOOR_ALARM_INTERVAL_MILLIS = 600_000L;
|
|
+
|
|
+ /** The file name the builder is expected to use inside the node's data directory. */
|
|
+ public static final String FILE_NAME = "aere-decided-head";
|
|
+
|
|
+ /** 2 * I_max: how many NON-canonical ancestors a descent check may walk before it gives up. */
|
|
+ public static final int DEFAULT_MAX_WALK = 256;
|
|
+
|
|
+ /** First line of the file. The same form is meant for the Nethermind twin. */
|
|
+ static final String MAGIC = "aere-decided-head v1";
|
|
+
|
|
+ /** The proof that decided a block, written into the file. */
|
|
+ public enum Proof {
|
|
+ /** A quorum of commits of one round (own round included). */
|
|
+ Q1,
|
|
+ /** f+1 commits of the child's set on one child. */
|
|
+ Q2,
|
|
+ /** What a certified anchor's certificate decides ({@link AereCertifiedDecision}). */
|
|
+ Q3,
|
|
+ /** Ancestry of a decided block. */
|
|
+ Q4,
|
|
+ /** Restart evidence. */
|
|
+ Q6
|
|
+ }
|
|
+
|
|
+ /** What {@link #advance} did. */
|
|
+ public enum Outcome {
|
|
+ /** D moved onto the block. */
|
|
+ ADVANCED,
|
|
+ /** The block is D or an ancestor of D: nothing to do. */
|
|
+ UNCHANGED,
|
|
+ /** The block is below the proof height (H_ev - 1): rule D does not apply there (Q5). */
|
|
+ NOT_ACTIVE,
|
|
+ /** The block is not stored on this node. */
|
|
+ NOT_STORED,
|
|
+ /** Two decided blocks at one height, or a decided block off D's line: D did not move. */
|
|
+ CONFLICT,
|
|
+ /** The durable write failed: D and the chain did not move. */
|
|
+ NOT_DURABLE,
|
|
+ /** Written durably, but the chain could not be rewound onto it: D did not move in memory. */
|
|
+ REWIND_FAILED
|
|
+ }
|
|
+
|
|
+ /** A decided block: height and on-chain hash. */
|
|
+ public static final class Decided {
|
|
+ private final long number;
|
|
+ private final Hash hash;
|
|
+
|
|
+ /**
|
|
+ * A decided block.
|
|
+ *
|
|
+ * @param number the height
|
|
+ * @param hash the on-chain hash
|
|
+ */
|
|
+ public Decided(final long number, final Hash hash) {
|
|
+ this.number = number;
|
|
+ this.hash = Objects.requireNonNull(hash, "hash");
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The height.
|
|
+ *
|
|
+ * @return the height
|
|
+ */
|
|
+ public long number() {
|
|
+ return number;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The on-chain hash.
|
|
+ *
|
|
+ * @return the hash
|
|
+ */
|
|
+ public Hash hash() {
|
|
+ return hash;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean equals(final Object o) {
|
|
+ if (!(o instanceof Decided)) {
|
|
+ return false;
|
|
+ }
|
|
+ final Decided other = (Decided) o;
|
|
+ return number == other.number && hash.equals(other.hash);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int hashCode() {
|
|
+ return Objects.hash(number, hash);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public String toString() {
|
|
+ return number + " (" + hash + ")";
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /** What the file holds: the decided block and the proof that decided it. */
|
|
+ public static final class Persisted {
|
|
+ private final Decided decided;
|
|
+ private final Proof proof;
|
|
+
|
|
+ Persisted(final Decided decided, final Proof proof) {
|
|
+ this.decided = decided;
|
|
+ this.proof = proof;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The decided block.
|
|
+ *
|
|
+ * @return the decided block
|
|
+ */
|
|
+ public Decided decided() {
|
|
+ return decided;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The proof.
|
|
+ *
|
|
+ * @return the proof
|
|
+ */
|
|
+ public Proof proof() {
|
|
+ return proof;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /** An ancestry that cannot be followed: a missing header, or more than maxWalk forked steps. */
|
|
+ public static final class AncestryUnknownException extends RuntimeException {
|
|
+ private static final long serialVersionUID = 1L;
|
|
+
|
|
+ AncestryUnknownException(final String message) {
|
|
+ super(message);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private final MutableBlockchain blockchain;
|
|
+ private final long activationHeight;
|
|
+ // max(1, H_ev - 1): the first height whose decided block needs a proof (genesis never does)
|
|
+ private final long proofHeight;
|
|
+ private final Path file;
|
|
+ private final int maxWalk;
|
|
+ private final Consumer<String> alarm;
|
|
+ private final AtomicLong conflicts = new AtomicLong();
|
|
+ private final AtomicLong notDurable = new AtomicLong();
|
|
+ private final AtomicLong rewindFailures = new AtomicLong();
|
|
+
|
|
+ // the highest D moved by a proof (always >= the proof height); null while only Q5 applies
|
|
+ private volatile Decided advanced;
|
|
+ private volatile Consumer<Decided> listener = d -> {};
|
|
+ // a D this node wrote durably and could not take back at its restart (its block not stored, or off the line):
|
|
+ // no proposal and no vote up to its height until D reaches it; null when there is none
|
|
+ private volatile Decided floor;
|
|
+ private volatile boolean floorConflict;
|
|
+ private volatile long floorAlarmMillis;
|
|
+
|
|
+ /**
|
|
+ * The decided head of one node.
|
|
+ *
|
|
+ * @param blockchain the node's chain
|
|
+ * @param activationHeight H_ev: rule D applies to heights >= this
|
|
+ * @param file where D is written durably
|
|
+ * @param maxWalk how many non-canonical ancestors a descent check may walk ({@link
|
|
+ * #DEFAULT_MAX_WALK})
|
|
+ * @param alarm the path a human reads (CONFLICT, NOT_DURABLE, REWIND); it also goes to the log
|
|
+ */
|
|
+ public AereDecidedHead(
|
|
+ final MutableBlockchain blockchain,
|
|
+ final long activationHeight,
|
|
+ final Path file,
|
|
+ final int maxWalk,
|
|
+ final Consumer<String> alarm) {
|
|
+ this.blockchain = Objects.requireNonNull(blockchain, "blockchain");
|
|
+ if (activationHeight < 0) {
|
|
+ throw new IllegalArgumentException(
|
|
+ "AERE-D412-DECIDED-CONF-01: the activation height must be >= 0, got " + activationHeight);
|
|
+ }
|
|
+ if (maxWalk < 1) {
|
|
+ throw new IllegalArgumentException(
|
|
+ "AERE-D412-DECIDED-CONF-02: maxWalk must be >= 1, got " + maxWalk);
|
|
+ }
|
|
+ this.activationHeight = activationHeight;
|
|
+ this.proofHeight = Math.max(1L, activationHeight - 1L);
|
|
+ this.file = Objects.requireNonNull(file, "file");
|
|
+ this.maxWalk = maxWalk;
|
|
+ this.alarm = Objects.requireNonNull(alarm, "alarm");
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // reading D (lock-free: called by the block choice rule under the chain's monitor)
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /**
|
|
+ * Whether rule D applies at a height.
|
|
+ *
|
|
+ * @param height the height
|
|
+ * @return true when height >= H_ev
|
|
+ */
|
|
+ public boolean active(final long height) {
|
|
+ return height >= activationHeight;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Whether the decided block at a height needs a PROOF (2026-10-01, review of step 3: the
|
|
+ * boundary). Rule D governs the consensus of heights >= H_ev, so the parent of H_ev, the block at
|
|
+ * H_ev - 1, needs a proof as well: Q5 covers only the heights below it, and genesis never needs
|
|
+ * one.
|
|
+ *
|
|
+ * @param height the height
|
|
+ * @return true when height >= max(1, H_ev - 1)
|
|
+ */
|
|
+ public boolean provable(final long height) {
|
|
+ return height >= proofHeight;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The proof height, max(1, H_ev - 1).
|
|
+ *
|
|
+ * @return the first height whose decided block needs a proof
|
|
+ */
|
|
+ public long proofHeight() {
|
|
+ return proofHeight;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Whether this node is below its durable floor: it wrote a decision durably at a height whose
|
|
+ * block it does not hold (or could not take back) since its restart, so it must neither propose
|
|
+ * nor vote at any height up to it. Read by the QBFT final state ({@code isLocalNodeValidator}).
|
|
+ *
|
|
+ * @return true while D is below the floor
|
|
+ */
|
|
+ public boolean belowFloor() {
|
|
+ final Decided f = floor;
|
|
+ return f != null && decided().number() < f.number();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The durable floor, if there is one.
|
|
+ *
|
|
+ * @return the floor
|
|
+ */
|
|
+ public Optional<Decided> floor() {
|
|
+ return Optional.ofNullable(floor);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * H_ev.
|
|
+ *
|
|
+ * @return the activation height
|
|
+ */
|
|
+ public long activationHeight() {
|
|
+ return activationHeight;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Where D is written.
|
|
+ *
|
|
+ * @return the file
|
|
+ */
|
|
+ public Path file() {
|
|
+ return file;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The decided head D: the highest block moved by a proof, or, while there is none, the canonical
|
|
+ * head capped below the proof height, at H_ev - 2 (Q5).
|
|
+ *
|
|
+ * @return D
|
|
+ */
|
|
+ public Decided decided() {
|
|
+ final Decided proven = advanced;
|
|
+ return proven != null ? proven : belowActivation();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The header of D.
|
|
+ *
|
|
+ * @return the header, empty only if the chain lost it
|
|
+ */
|
|
+ public Optional<BlockHeader> decidedHeader() {
|
|
+ return blockchain.getBlockHeader(decided().hash());
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Whether a block is compatible with D: it descends from D (or is D), or it is an ancestor of D.
|
|
+ *
|
|
+ * @param block a stored block, or the block being appended
|
|
+ * @return true when compatible
|
|
+ * @throws AncestryUnknownException when the ancestry cannot be followed within maxWalk
|
|
+ */
|
|
+ public boolean compatible(final BlockHeader block) {
|
|
+ final Decided d = decided();
|
|
+ if (block.getNumber() >= d.number()) {
|
|
+ return onAncestry(block, d.number(), d.hash());
|
|
+ }
|
|
+ return onAncestry(headerOf(d), block.getNumber(), block.getHash());
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Q4: whether a block is decided, i.e. it is D or lies on D's own ancestry.
|
|
+ *
|
|
+ * @param block a block
|
|
+ * @return true when decided
|
|
+ * @throws AncestryUnknownException when the ancestry cannot be followed within maxWalk
|
|
+ */
|
|
+ public boolean isDecided(final BlockHeader block) {
|
|
+ final Decided d = decided();
|
|
+ return block.getNumber() <= d.number()
|
|
+ && onAncestry(headerOf(d), block.getNumber(), block.getHash());
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // moving D
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /**
|
|
+ * A listener told of every move of D, after it is durable and the chain is on it. Step 3 posts the
|
|
+ * new chain head event from here.
|
|
+ *
|
|
+ * @param listener the listener
|
|
+ */
|
|
+ public void onAdvanced(final Consumer<Decided> listener) {
|
|
+ this.listener = Objects.requireNonNull(listener, "listener");
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Block {@code hash} is decided by {@code proof}: move D onto it if it is above D and descends from
|
|
+ * it. Durable write first, then the chain, then D.
|
|
+ *
|
|
+ * <p>While D is still the Q5 D (no proof has moved it yet), a proved block that does NOT descend
|
|
+ * from it moves D all the same, rewinding the chain: below the proof height the canonical line is
|
|
+ * upstream's and a single key can bend it (C1), so it is no proof (2026-10-01, review of step 3).
|
|
+ * Once a proof has moved D, a block off D's line is a CONFLICT, as before. A block at or above the
|
|
+ * durable floor must carry the floor's block on its line, otherwise it is a CONFLICT too.
|
|
+ *
|
|
+ * @param hash the on-chain hash of a stored block
|
|
+ * @param proof the proof that decided it
|
|
+ * @return what happened
|
|
+ */
|
|
+ public synchronized Outcome advance(final Hash hash, final Proof proof) {
|
|
+ final Optional<BlockHeader> stored = blockchain.getBlockHeader(hash);
|
|
+ if (stored.isEmpty()) {
|
|
+ LOG.warn(
|
|
+ "AERE D-412 decided head: proof {} names block {}, which is not stored; D stays at {}",
|
|
+ proof,
|
|
+ hash,
|
|
+ decided());
|
|
+ return Outcome.NOT_STORED;
|
|
+ }
|
|
+ final BlockHeader block = stored.get();
|
|
+ if (!provable(block.getNumber())) {
|
|
+ return Outcome.NOT_ACTIVE;
|
|
+ }
|
|
+ final Decided proven = advanced;
|
|
+ final Decided current = proven != null ? proven : belowActivation();
|
|
+ if (block.getNumber() <= current.number()) {
|
|
+ boolean decidedAlready;
|
|
+ try {
|
|
+ decidedAlready = isDecided(block);
|
|
+ } catch (final AncestryUnknownException e) {
|
|
+ return conflict(block, proof, "the decided head's own ancestry is unreadable: " + e.getMessage());
|
|
+ }
|
|
+ if (decidedAlready) {
|
|
+ return Outcome.UNCHANGED;
|
|
+ }
|
|
+ return conflict(block, proof, "another block is already decided at or above this height");
|
|
+ }
|
|
+ boolean descends;
|
|
+ try {
|
|
+ descends = onAncestry(block, current.number(), current.hash());
|
|
+ } catch (final AncestryUnknownException e) {
|
|
+ if (proven != null) {
|
|
+ return conflict(
|
|
+ block, proof, "its descent from the decided head cannot be proved: " + e.getMessage());
|
|
+ }
|
|
+ descends = false;
|
|
+ }
|
|
+ if (!descends) {
|
|
+ if (proven != null) {
|
|
+ return conflict(block, proof, "it does not descend from the decided head");
|
|
+ }
|
|
+ LOG.warn(
|
|
+ "AERE D-412 decided head: proof {} decides block {} ({}) off the canonical line below the proof"
|
|
+ + " height {}; that line is not a proof (Q5), so D moves onto the proved block",
|
|
+ proof,
|
|
+ block.getNumber(),
|
|
+ block.getHash(),
|
|
+ proofHeight);
|
|
+ }
|
|
+ final Decided f = floor;
|
|
+ if (f != null && block.getNumber() >= f.number()) {
|
|
+ boolean onFloorLine;
|
|
+ try {
|
|
+ onFloorLine = onAncestry(block, f.number(), f.hash());
|
|
+ } catch (final AncestryUnknownException e) {
|
|
+ onFloorLine = false;
|
|
+ }
|
|
+ if (!onFloorLine) {
|
|
+ return conflict(
|
|
+ block,
|
|
+ proof,
|
|
+ "it does not carry the block " + f + " this node wrote durably as decided before its restart");
|
|
+ }
|
|
+ }
|
|
+ final Decided next = new Decided(block.getNumber(), block.getHash());
|
|
+ if (!persist(next, proof)) {
|
|
+ return notDurable(next, proof);
|
|
+ }
|
|
+ return moveChainTo(block, next, proof) ? Outcome.ADVANCED : Outcome.REWIND_FAILED;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The durable floor's block is stored again (synchronization, propagation): move D onto it, with
|
|
+ * this node's own durable record as the proof (Q6). Called by the wiring at every evaluation. While
|
|
+ * the node stays below its floor the alarm is repeated every {@link #FLOOR_ALARM_INTERVAL_MILLIS};
|
|
+ * when D reaches the floor the alarm path is told it is over.
|
|
+ *
|
|
+ * @return ADVANCED when D moved onto the floor's block, UNCHANGED when there is no floor (or D is at
|
|
+ * or above it), NOT_STORED while its block is missing, or what the advance answered
|
|
+ */
|
|
+ public synchronized Outcome resolveFloor() {
|
|
+ final Decided f = floor;
|
|
+ if (f == null) {
|
|
+ return Outcome.UNCHANGED;
|
|
+ }
|
|
+ if (decided().number() >= f.number()) {
|
|
+ floorReached(f, decided());
|
|
+ return Outcome.UNCHANGED;
|
|
+ }
|
|
+ if (floorConflict || blockchain.getBlockHeader(f.hash()).isEmpty()) {
|
|
+ final long now = System.currentTimeMillis();
|
|
+ if (now - floorAlarmMillis >= FLOOR_ALARM_INTERVAL_MILLIS) {
|
|
+ floorAlarmMillis = now;
|
|
+ raise(CODE_FLOOR, floorText(f));
|
|
+ }
|
|
+ return floorConflict ? Outcome.CONFLICT : Outcome.NOT_STORED;
|
|
+ }
|
|
+ final Outcome moved = advance(f.hash(), Proof.Q6);
|
|
+ if (moved == Outcome.CONFLICT) {
|
|
+ floorConflict = true;
|
|
+ }
|
|
+ return moved;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Q6, at startup. The persisted D comes FIRST (re-verified: its checksum, stored, same height): stored
|
|
+ * and canonical it is D; stored but NOT canonical it is an advance that was written and stopped
|
|
+ * before the chain moved, and it is completed (rewound onto) when it extends D (or when only Q5
|
|
+ * stands below it, which is no proof), a CONFLICT otherwise. Only then the candidates: the finalized
|
|
+ * tag (B1) and whatever the caller passes (since 2026-10-01 the node passes nothing: the head
|
|
+ * proved by the restored post-quantum seals is gone, teza Q3, D-470). A candidate that does not
|
|
+ * descend from the durable D (above it), or is not on its ancestry (below it), does not move D: it
|
|
+ * is a CONFLICT and D stays the durable one (2026-10-01, teza Q3: until then the candidates came
|
|
+ * first and a higher candidate off the durable line became D). A candidate below the proof height
|
|
+ * is ignored (Q5 covers it). D never goes down.
|
|
+ *
|
|
+ * <p>A persisted D that cannot be taken back (its block is not stored, or it is off the line) is
|
|
+ * not forgotten (2026-10-01, review of step 3): it becomes the durable FLOOR ({@link #belowFloor},
|
|
+ * {@link #resolveFloor}), announced on the alarm path.
|
|
+ *
|
|
+ * <p>This form TRUSTS the finalized tag as it is (the step-2 proofs use it). A node takes the
|
|
+ * guarded form, {@link #restore(Collection, Predicate)}: on a validator with rule D the canonical
|
|
+ * head may be a provisional tail, and the tag is taken only when it is what its covering anchor's
|
|
+ * certificate decides ({@link AereCertifiedDecision}).
|
|
+ *
|
|
+ * @param otherEvidence hashes of blocks the caller has proved decided
|
|
+ * @return D after the restore
|
|
+ */
|
|
+ public synchronized Decided restore(final Collection<Hash> otherEvidence) {
|
|
+ return restore(otherEvidence, finalizedHeader -> true);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Q6 with the finalized tag taken only when {@code finalizedProves} says its covering anchor proves
|
|
+ * it (the node's form: a canonical anchor above it whose certificate decides exactly this block,
|
|
+ * {@link AereCertifiedDecision#decidedBy}; 2026-10-01, teza Q3); otherwise the tag is ignored with
|
|
+ * one WARN and D comes from the durable file and the other evidence alone.
|
|
+ *
|
|
+ * @param otherEvidence hashes of blocks the caller has proved decided
|
|
+ * @param finalizedProves whether the finalized tag's header is proved decided by its anchor
|
|
+ * @return D after the restore
|
|
+ */
|
|
+ public synchronized Decided restore(
|
|
+ final Collection<Hash> otherEvidence, final Predicate<BlockHeader> finalizedProves) {
|
|
+ Objects.requireNonNull(finalizedProves, "finalizedProves");
|
|
+ // 1. the durable D FIRST (2026-10-01, teza Q3, D-470: until then the candidates came first, and a
|
|
+ // higher candidate off the durable line became D while the durable record only raised a CONFLICT)
|
|
+ Decided durable = null;
|
|
+ Decided pendingFloor = null;
|
|
+ final Optional<Persisted> persisted = read(file);
|
|
+ if (persisted.isPresent()) {
|
|
+ final Decided p = persisted.get().decided();
|
|
+ final Optional<BlockHeader> header = blockchain.getBlockHeader(p.hash());
|
|
+ if (!provable(p.number())) {
|
|
+ LOG.warn(
|
|
+ "AERE D-412 decided head: the persisted D {} is below the proof height {}; ignored (Q5)",
|
|
+ p,
|
|
+ proofHeight);
|
|
+ } else if (header.isEmpty()) {
|
|
+ LOG.warn(
|
|
+ "AERE D-412 decided head: the persisted D {} is not a stored block; it stays this node's"
|
|
+ + " FLOOR (no proposal and no vote up to its height until D reaches it)",
|
|
+ p);
|
|
+ pendingFloor = p;
|
|
+ } else if (header.get().getNumber() != p.number()) {
|
|
+ LOG.warn(
|
|
+ "AERE D-412 decided head: the persisted D {} names a block stored at another height ({});"
|
|
+ + " ignored",
|
|
+ p,
|
|
+ header.get().getNumber());
|
|
+ } else if (isCanonical(header.get())) {
|
|
+ durable = p;
|
|
+ } else {
|
|
+ final Decided base = advanced;
|
|
+ boolean completes;
|
|
+ try {
|
|
+ // over Q5 alone (no proof) the durable decision completes even off Q5's line: Q5 is no proof
|
|
+ completes =
|
|
+ base == null
|
|
+ || (p.number() > base.number()
|
|
+ && onAncestry(header.get(), base.number(), base.hash()));
|
|
+ } catch (final AncestryUnknownException e) {
|
|
+ completes = false;
|
|
+ }
|
|
+ if (!completes) {
|
|
+ conflict(header.get(), Proof.Q6, "the persisted decided head is off the decided head's line");
|
|
+ pendingFloor = p;
|
|
+ } else if (moveChainTo(header.get(), p, Proof.Q6)) {
|
|
+ durable = p;
|
|
+ LOG.warn(
|
|
+ "AERE D-412 decided head: completed an advance to {} that was written but not applied"
|
|
+ + " to the chain before the node stopped",
|
|
+ p);
|
|
+ } else {
|
|
+ pendingFloor = p;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ // 2. the candidates, each against the durable record (the durable D, or the floor when its block
|
|
+ // is not held): one off that line does not move D, it is a CONFLICT
|
|
+ final List<Hash> candidates = new ArrayList<>();
|
|
+ final Optional<Hash> finalized = blockchain.getFinalized();
|
|
+ if (finalized.isPresent()) {
|
|
+ final Optional<BlockHeader> finalizedHeader = blockchain.getBlockHeader(finalized.get());
|
|
+ if (finalizedHeader.isPresent() && finalizedProves.test(finalizedHeader.get())) {
|
|
+ candidates.add(finalized.get());
|
|
+ } else if (finalizedHeader.isPresent() && provable(finalizedHeader.get().getNumber())) {
|
|
+ LOG.warn(
|
|
+ "AERE D-412 decided head: the finalized tag {} ({}) is NOT taken as decided at startup: no"
|
|
+ + " canonical anchor above it has a certificate that decides it (AereCertifiedDecision)."
|
|
+ + " D comes from the durable file and the other evidence.",
|
|
+ finalizedHeader.get().getNumber(),
|
|
+ finalized.get());
|
|
+ }
|
|
+ }
|
|
+ candidates.addAll(otherEvidence);
|
|
+ if (durable != null && (advanced == null || durable.number() > advanced.number())) {
|
|
+ advanced = durable;
|
|
+ }
|
|
+ final Decided line = durable != null ? durable : pendingFloor;
|
|
+ Decided best = advanced;
|
|
+ for (final Hash candidate : candidates) {
|
|
+ final Optional<BlockHeader> header = blockchain.getBlockHeader(candidate);
|
|
+ if (header.isEmpty() || !provable(header.get().getNumber())) {
|
|
+ continue;
|
|
+ }
|
|
+ if (line != null && !onDurableLine(header.get(), line)) {
|
|
+ conflict(
|
|
+ header.get(),
|
|
+ Proof.Q6,
|
|
+ "it is not on the line of " + line + ", which this node wrote durably as decided");
|
|
+ continue;
|
|
+ }
|
|
+ if (isCanonical(header.get())) {
|
|
+ best = higher(best, new Decided(header.get().getNumber(), header.get().getHash()));
|
|
+ }
|
|
+ }
|
|
+ if (best != null && (advanced == null || best.number() > advanced.number())) {
|
|
+ advanced = best;
|
|
+ }
|
|
+ if (pendingFloor != null && pendingFloor.number() > decided().number()) {
|
|
+ floor = pendingFloor;
|
|
+ floorConflict = false;
|
|
+ floorAlarmMillis = System.currentTimeMillis();
|
|
+ raise(CODE_FLOOR, floorText(pendingFloor));
|
|
+ }
|
|
+ final Decided now = decided();
|
|
+ LOG.info("AERE D-412 decided head: restored D = {} (activation height {})", now, activationHeight);
|
|
+ return now;
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // measurements
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /**
|
|
+ * How many conflicts were raised.
|
|
+ *
|
|
+ * @return the count
|
|
+ */
|
|
+ public long conflicts() {
|
|
+ return conflicts.get();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many durable writes failed.
|
|
+ *
|
|
+ * @return the count
|
|
+ */
|
|
+ public long notDurableCount() {
|
|
+ return notDurable.get();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many rewinds onto a durable D failed.
|
|
+ *
|
|
+ * @return the count
|
|
+ */
|
|
+ public long rewindFailures() {
|
|
+ return rewindFailures.get();
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // the file
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /**
|
|
+ * Write D durably: a temporary file in the same directory, fsync, atomic rename onto the target,
|
|
+ * fsync of the directory. No fallback to a non-atomic move: a filesystem that cannot do it cannot
|
|
+ * hold D.
|
|
+ *
|
|
+ * @param file the target
|
|
+ * @param decided the decided block
|
|
+ * @param proof the proof
|
|
+ * @throws IOException when any step fails
|
|
+ */
|
|
+ public static void writeDurably(final Path file, final Decided decided, final Proof proof)
|
|
+ throws IOException {
|
|
+ final byte[] payload = encode(decided, proof);
|
|
+ final Path absolute = file.toAbsolutePath();
|
|
+ final Path directory = absolute.getParent();
|
|
+ if (directory == null) {
|
|
+ throw new IOException("no directory for " + absolute);
|
|
+ }
|
|
+ Files.createDirectories(directory);
|
|
+ final Path temp = directory.resolve(absolute.getFileName().toString() + ".tmp");
|
|
+ try (FileChannel channel =
|
|
+ FileChannel.open(
|
|
+ temp,
|
|
+ StandardOpenOption.CREATE,
|
|
+ StandardOpenOption.WRITE,
|
|
+ StandardOpenOption.TRUNCATE_EXISTING)) {
|
|
+ final ByteBuffer buffer = ByteBuffer.wrap(payload);
|
|
+ while (buffer.hasRemaining()) {
|
|
+ channel.write(buffer);
|
|
+ }
|
|
+ channel.force(true);
|
|
+ }
|
|
+ Files.move(temp, absolute, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
|
|
+ try (FileChannel dir = FileChannel.open(directory, StandardOpenOption.READ)) {
|
|
+ dir.force(true);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Read the file: magic line, height, hash, proof, and the keccak256 of those four lines. Anything
|
|
+ * else (missing, torn, wrong checksum, unparsable) is empty.
|
|
+ *
|
|
+ * @param file the file
|
|
+ * @return what it holds, or empty
|
|
+ */
|
|
+ public static Optional<Persisted> read(final Path file) {
|
|
+ final byte[] raw;
|
|
+ try {
|
|
+ if (!Files.isRegularFile(file)) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ raw = Files.readAllBytes(file);
|
|
+ } catch (final IOException e) {
|
|
+ LOG.warn("AERE D-412 decided head: cannot read {}: {}", file, e.getMessage());
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ final String text = new String(raw, StandardCharsets.US_ASCII);
|
|
+ final List<String> lines = text.lines().toList();
|
|
+ if (lines.size() != 5 || !text.endsWith("\n") || !MAGIC.equals(lines.get(0))) {
|
|
+ LOG.warn("AERE D-412 decided head: {} is not a decided-head file; ignored", file);
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ final String expected = "keccak256 " + checksum(bodyOf(lines)).toHexString();
|
|
+ if (!lines.get(4).equals(expected)) {
|
|
+ LOG.warn("AERE D-412 decided head: {} fails its checksum; ignored", file);
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ try {
|
|
+ final long number = Long.parseLong(field(lines.get(1), "number "));
|
|
+ final Hash hash = Hash.fromHexString(field(lines.get(2), "hash "));
|
|
+ final Proof proof = Proof.valueOf(field(lines.get(3), "proof "));
|
|
+ return Optional.of(new Persisted(new Decided(number, hash), proof));
|
|
+ } catch (final IllegalArgumentException e) {
|
|
+ LOG.warn("AERE D-412 decided head: {} does not parse: {}; ignored", file, e.getMessage());
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ static byte[] encode(final Decided decided, final Proof proof) {
|
|
+ final String body =
|
|
+ MAGIC
|
|
+ + "\n"
|
|
+ + "number "
|
|
+ + decided.number()
|
|
+ + "\n"
|
|
+ + "hash "
|
|
+ + decided.hash().toHexString()
|
|
+ + "\n"
|
|
+ + "proof "
|
|
+ + proof.name()
|
|
+ + "\n";
|
|
+ return (body + "keccak256 " + checksum(body).toHexString() + "\n")
|
|
+ .getBytes(StandardCharsets.US_ASCII);
|
|
+ }
|
|
+
|
|
+ private static String bodyOf(final List<String> lines) {
|
|
+ return lines.get(0) + "\n" + lines.get(1) + "\n" + lines.get(2) + "\n" + lines.get(3) + "\n";
|
|
+ }
|
|
+
|
|
+ private static Hash checksum(final String body) {
|
|
+ return Hash.hash(Bytes.wrap(body.getBytes(StandardCharsets.US_ASCII)));
|
|
+ }
|
|
+
|
|
+ private static String field(final String line, final String prefix) {
|
|
+ if (!line.startsWith(prefix)) {
|
|
+ throw new IllegalArgumentException("expected '" + prefix.trim() + "', got '" + line + "'");
|
|
+ }
|
|
+ return line.substring(prefix.length());
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // internals
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /** The chain's own monitor: the one appendBlock, storeBlock and the block choice rule run under. */
|
|
+ private Object monitor() {
|
|
+ return blockchain;
|
|
+ }
|
|
+
|
|
+ private boolean persist(final Decided next, final Proof proof) {
|
|
+ try {
|
|
+ writeDurably(file, next, proof);
|
|
+ final Optional<Persisted> back = read(file);
|
|
+ if (back.isEmpty() || !back.get().decided().equals(next)) {
|
|
+ throw new IOException("the file read back does not name " + next);
|
|
+ }
|
|
+ return true;
|
|
+ } catch (final IOException | RuntimeException e) {
|
|
+ LOG.error("AERE D-412 decided head: durable write of {} to {} failed: {}", next, file, e.getMessage());
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /** Rewind the chain onto the block when needed and move D, all under the chain's monitor. */
|
|
+ private boolean moveChainTo(final BlockHeader block, final Decided next, final Proof proof) {
|
|
+ synchronized (monitor()) {
|
|
+ try {
|
|
+ if (!isCanonical(block)) {
|
|
+ blockchain.rewindToBlock(block.getHash());
|
|
+ }
|
|
+ } catch (final RuntimeException e) {
|
|
+ rewindFailures.incrementAndGet();
|
|
+ raise(CODE_REWIND, "the chain could not be rewound onto the decided block " + next
|
|
+ + " (proof " + proof + "): " + e.getMessage() + "; D stays at " + decided());
|
|
+ return false;
|
|
+ }
|
|
+ if (!isCanonical(block)) {
|
|
+ rewindFailures.incrementAndGet();
|
|
+ raise(CODE_REWIND, "after the rewind the decided block " + next + " (proof " + proof
|
|
+ + ") is still not canonical; D stays at " + decided());
|
|
+ return false;
|
|
+ }
|
|
+ advanced = next;
|
|
+ }
|
|
+ LOG.info("AERE D-412 decided head: D = {} (proof {})", next, proof);
|
|
+ final Decided f = floor;
|
|
+ if (f != null && next.number() >= f.number()) {
|
|
+ floorReached(f, next);
|
|
+ }
|
|
+ listener.accept(next);
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ /** The floor is behind D: the node votes again, and the alarm path is told so. */
|
|
+ private void floorReached(final Decided f, final Decided now) {
|
|
+ floor = null;
|
|
+ floorConflict = false;
|
|
+ final String message =
|
|
+ CODE_FLOOR
|
|
+ + " RESOLVED: D = "
|
|
+ + now
|
|
+ + " reached the floor "
|
|
+ + f
|
|
+ + "; this node proposes and votes again";
|
|
+ LOG.info("AERE D-412 decided head: {}", message);
|
|
+ alarm.accept(message);
|
|
+ }
|
|
+
|
|
+ private String floorText(final Decided f) {
|
|
+ return "this node wrote "
|
|
+ + f
|
|
+ + " durably as decided and "
|
|
+ + (floorConflict ? "a proof contradicts it" : "does not hold that block since its restart")
|
|
+ + "; D is "
|
|
+ + decided()
|
|
+ + ". It neither proposes nor votes at any height up to "
|
|
+ + f.number()
|
|
+ + " until D reaches it (the block stored again by synchronization, or a proof on its line), so"
|
|
+ + " it can never decide those heights a second time. If no node holds the block any more, this"
|
|
+ + " needs a human.";
|
|
+ }
|
|
+
|
|
+ private Outcome conflict(final BlockHeader block, final Proof proof, final String why) {
|
|
+ conflicts.incrementAndGet();
|
|
+ raise(
|
|
+ CODE_CONFLICT,
|
|
+ "block "
|
|
+ + block.getNumber()
|
|
+ + " ("
|
|
+ + block.getHash()
|
|
+ + ", proof "
|
|
+ + proof
|
|
+ + ") cannot become the decided head: "
|
|
+ + why
|
|
+ + ". D stays at "
|
|
+ + decided()
|
|
+ + ". Two decided blocks at one height need more than f faulty validators.");
|
|
+ return Outcome.CONFLICT;
|
|
+ }
|
|
+
|
|
+ private Outcome notDurable(final Decided next, final Proof proof) {
|
|
+ notDurable.incrementAndGet();
|
|
+ raise(
|
|
+ CODE_NOT_DURABLE,
|
|
+ "the decided head "
|
|
+ + next
|
|
+ + " (proof "
|
|
+ + proof
|
|
+ + ") could not be written durably to "
|
|
+ + file
|
|
+ + "; D stays at "
|
|
+ + decided()
|
|
+ + " and the chain was not touched.");
|
|
+ return Outcome.NOT_DURABLE;
|
|
+ }
|
|
+
|
|
+ private void raise(final String code, final String text) {
|
|
+ final String message = "CRIT " + code + ": " + text;
|
|
+ LOG.error(message);
|
|
+ alarm.accept(message);
|
|
+ }
|
|
+
|
|
+ private static Decided higher(final Decided a, final Decided b) {
|
|
+ if (a == null) {
|
|
+ return b;
|
|
+ }
|
|
+ if (b == null) {
|
|
+ return a;
|
|
+ }
|
|
+ return b.number() > a.number() ? b : a;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Whether a restart candidate is on the line of the durable record: at or above it, it descends
|
|
+ * from it; below it, it is on its ancestry (or the record's block is not held, and what is below a
|
|
+ * floor is not judged by it, as in {@link #advance}). An ancestry that cannot be followed is NOT on
|
|
+ * the line.
|
|
+ */
|
|
+ private boolean onDurableLine(final BlockHeader candidate, final Decided line) {
|
|
+ try {
|
|
+ if (candidate.getNumber() >= line.number()) {
|
|
+ return onAncestry(candidate, line.number(), line.hash());
|
|
+ }
|
|
+ final Optional<BlockHeader> lineHeader = blockchain.getBlockHeader(line.hash());
|
|
+ return lineHeader.isEmpty()
|
|
+ || onAncestry(lineHeader.get(), candidate.getNumber(), candidate.getHash());
|
|
+ } catch (final AncestryUnknownException e) {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private Decided belowActivation() {
|
|
+ // Q5 stops BELOW the proof height (H_ev - 2): the canonical block at H_ev - 1 is not a proof
|
|
+ final long top = Math.min(blockchain.getChainHeadBlockNumber(), proofHeight - 1L);
|
|
+ final Hash hash =
|
|
+ blockchain
|
|
+ .getBlockHashByNumber(top)
|
|
+ .orElseThrow(() -> new AncestryUnknownException("no canonical block at " + top));
|
|
+ return new Decided(top, hash);
|
|
+ }
|
|
+
|
|
+ private BlockHeader headerOf(final Decided d) {
|
|
+ return blockchain
|
|
+ .getBlockHeader(d.hash())
|
|
+ .orElseThrow(() -> new AncestryUnknownException("the decided block " + d + " is not stored"));
|
|
+ }
|
|
+
|
|
+ private boolean isCanonical(final BlockHeader block) {
|
|
+ final Hash hash = block.getHash();
|
|
+ return blockchain.getBlockHashByNumber(block.getNumber()).map(hash::equals).orElse(false);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Whether the block at {@code height} on {@code from}'s parentHash path has {@code hash}. Walks
|
|
+ * the non-canonical part only: once a canonical block is reached, its whole ancestry is the
|
|
+ * canonical chain and one lookup answers.
|
|
+ */
|
|
+ private boolean onAncestry(final BlockHeader from, final long height, final Hash hash) {
|
|
+ BlockHeader cur = from;
|
|
+ int steps = 0;
|
|
+ while (cur.getNumber() > height) {
|
|
+ if (isCanonical(cur)) {
|
|
+ return blockchain.getBlockHashByNumber(height).map(hash::equals).orElse(false);
|
|
+ }
|
|
+ steps++;
|
|
+ if (steps > maxWalk) {
|
|
+ throw new AncestryUnknownException(
|
|
+ "more than "
|
|
+ + maxWalk
|
|
+ + " non-canonical ancestors between "
|
|
+ + from.getNumber()
|
|
+ + " and "
|
|
+ + height);
|
|
+ }
|
|
+ final Hash parent = cur.getParentHash();
|
|
+ cur =
|
|
+ blockchain
|
|
+ .getBlockHeader(parent)
|
|
+ .orElseThrow(() -> new AncestryUnknownException("missing parent " + parent));
|
|
+ }
|
|
+ return cur.getNumber() == height && cur.getHash().equals(hash);
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/AerePqFinalityTags.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/AerePqFinalityTags.java
|
|
index e5e11c939f..a365ae95c9 100755
|
|
--- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/AerePqFinalityTags.java
|
|
+++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/AerePqFinalityTags.java
|
|
@@ -7,196 +7,242 @@
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
package org.hyperledger.besu.consensus.common.bft;
|
|
|
|
import org.hyperledger.besu.datatypes.Hash;
|
|
import org.hyperledger.besu.ethereum.chain.BlockAddedEvent;
|
|
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
// in this Besu base (26.4.0-dev, d2032017b) the event type enum lives in the plugin API, not nested in BlockAddedEvent
|
|
// (measured 2026-09-26: "cannot find symbol EventType in class BlockAddedEvent" on the first harness run)
|
|
import org.hyperledger.besu.plugin.data.AddedBlockContext.EventType;
|
|
|
|
import java.util.Optional;
|
|
import java.util.concurrent.atomic.AtomicLong;
|
|
+import java.util.function.Function;
|
|
import java.util.function.Predicate;
|
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
/**
|
|
* AERE D-412 Rule B1 (2026-09-26): the post-quantum FINALITY TAGS.
|
|
*
|
|
* <p><b>What this closes, read in the code and measured on the chain.</b> From AIP-22 stage 5 a valid
|
|
* between-anchor header carries only the proposer's Falcon-512 seal, so a single validator key can
|
|
* forge a header a reader imports as valid and, if that reader is syncing or eclipsed, adopts as its
|
|
* canonical tip (D-412, corrected severity). Such a forged tail is bounded: at the next anchor height
|
|
* {@code PqAnchorSealsRule} (R2, FULL validation, which {@code PqAnchorSyncModeGuard} makes the only
|
|
* sync mode) requires K distinct valid Falcon-512 seals over the parent's commit message, which one key
|
|
* cannot produce, so the tail dies within one anchor interval. What remains is that the reader's
|
|
* {@code latest} can transiently name a forged block, and a consumer who asks for {@code finalized} or
|
|
* {@code safe} - the tags bridges, exchanges and rollups use - received, on every node of chain 2800 and
|
|
* 28001 measured 2026-09-26, the error {@code Unknown block}: QBFT never sets them.
|
|
*
|
|
- * <p><b>The rule.</b> {@code finalized} and {@code safe} name the last block COVERED BY A VALID ANCHOR
|
|
- * CERTIFICATE: when a canonical head at an anchor height carries a certificate, the anchor's PARENT
|
|
- * becomes finalized (the certificate's K seals sign the parent's commit message, AIP-15, and R1/R2 have
|
|
- * already refused the header if that certificate does not bind or does not verify). Between anchors
|
|
- * the tags do not move. A forged between-anchor block can therefore never be reported final: it is
|
|
- * never an anchor's certified parent. This is exactly the finality AIP-22 section 1 defines ("the
|
|
- * finality of the block is established only by the covering anchor"), exposed on the API the world
|
|
- * already reads.
|
|
+ * <p><b>The rule.</b> {@code finalized} and {@code safe} name the last block that a canonical anchor's
|
|
+ * certificate DECIDES, as {@link AereCertifiedDecision#decidedBy} answers it (the one place, read by
|
|
+ * the decided head too). Below H_hdr that is the anchor's PARENT (the anchor's header carries the ECDSA
|
|
+ * committed seals of one round, checked at import). From H_hdr it is the anchor's GRANDPARENT, and only
|
|
+ * on f + 1 re-verified seals of distinct members of the set that decides the parent, with the parent at
|
|
+ * or above H_ev (AERE-Q3-BUNIC, teza Q3, D-470, 2026-10-01): the post-quantum commit seal carries no
|
|
+ * round, so K seals over the parent never showed that the parent was decided (Teorema 1, measured by
|
|
+ * AereRoundFreeCertificateTest), and until that day this rule named the parent above H_hdr too.
|
|
+ * From H_r (1(b), 2026-10-01) the v3 certificate binds the round, and a quorum of one round over the
|
|
+ * parent names the PARENT again (AERE-R1B-PARINTE-Q, {@link AereCertifiedDecision}).
|
|
+ * Between anchors the tags do not move. A forged between-anchor block can therefore never be reported
|
|
+ * final. On a chain where H_hdr is below H_ev (28001, rep28098) the tags do not move on anchors between
|
|
+ * the two, since nothing there proves the grandparent.
|
|
*
|
|
* <p><b>What it deliberately does NOT do.</b> It does not touch fork-choice, block validity or import:
|
|
* nothing here can stop the chain or refuse a block, and a node that lags still catches up exactly as
|
|
* before. It only writes the two tags, monotonically: a later event can only move them forward. If a
|
|
- * canonical reorg ever drops below the finalized block (which would mean K validators signed two
|
|
- * conflicting anchors, outside this rule's adversary), it is logged as {@code AERE-PQC-FIN-01} at
|
|
- * ERROR and the tags are left where they were, never moved back in silence.
|
|
+ * canonical reorg ever drops below the finalized block (which would mean that a block this rule took
|
|
+ * as decided was not: more than f faulty validators, outside this rule's adversary; NOT "K validators
|
|
+ * signed twice": an honest validator may sign the round-free seal of two blocks at one height; from
|
|
+ * H_r the seal names its round, and an honest validator commits at most one block per round, so a
|
|
+ * quorum of one round over two blocks at one height means more than f equivocators), it is logged as
|
|
+ * {@code AERE-PQC-FIN-01} at ERROR and the tags are left where they were, never moved back in silence.
|
|
*
|
|
* <p><b>At startup</b> the tags are initialised by scanning back from the head to the most recent
|
|
- * anchor height that carries a certificate (at most two intervals), so a freshly started node answers
|
|
+ * anchor whose certificate decides a block (at most two intervals), so a freshly started node answers
|
|
* {@code finalized} before it imports its next anchor.
|
|
*
|
|
* <p>Inert on a chain where the anchor was never active (the node never installs it); inert below
|
|
* the activation height (no anchor height applies there). Stated, not measured here: the behaviour on
|
|
* the live fleet, which is the rehearsal's job.
|
|
*/
|
|
public final class AerePqFinalityTags {
|
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(AerePqFinalityTags.class);
|
|
|
|
/** Logged when a canonical reorg would move finality backwards; the tags are not moved. */
|
|
public static final String CODE_REORG_BELOW_FINALIZED = "AERE-PQC-FIN-01";
|
|
|
|
private final PqAnchorConfig config;
|
|
private final MutableBlockchain blockchain;
|
|
- private final Predicate<BlockHeader> carriesCertificate;
|
|
+ private final Function<BlockHeader, Optional<AereDecidedHead.Decided>> decision;
|
|
private final AtomicLong finalizedNumber = new AtomicLong(-1L);
|
|
|
|
AerePqFinalityTags(
|
|
final PqAnchorConfig config,
|
|
final MutableBlockchain blockchain,
|
|
- final Predicate<BlockHeader> carriesCertificate) {
|
|
+ final Function<BlockHeader, Optional<AereDecidedHead.Decided>> decision) {
|
|
this.config = config;
|
|
this.blockchain = blockchain;
|
|
- this.carriesCertificate = carriesCertificate;
|
|
+ this.decision = decision;
|
|
}
|
|
|
|
/**
|
|
- * Install the tags on a blockchain: initialise from the current head, then follow every block added.
|
|
+ * Install the tags on a blockchain, the PARENT of a certified anchor taken as decided: the form below
|
|
+ * H_hdr, kept for the step-2 proofs of the rule's mechanics. A node installs {@link #installDecided}
|
|
+ * with {@link AereCertifiedDecision} (teza Q3, 2026-10-01).
|
|
*
|
|
* @param config the anchor configuration (activation height, interval schedule)
|
|
* @param blockchain the chain whose finalized/safe tags are written
|
|
* @param carriesCertificate whether a header carries a (validated) anchor certificate
|
|
* @return the installed instance, for inspection
|
|
*/
|
|
public static AerePqFinalityTags install(
|
|
final PqAnchorConfig config,
|
|
final MutableBlockchain blockchain,
|
|
final Predicate<BlockHeader> carriesCertificate) {
|
|
- final AerePqFinalityTags tags = new AerePqFinalityTags(config, blockchain, carriesCertificate);
|
|
+ return installDecided(
|
|
+ config,
|
|
+ blockchain,
|
|
+ h ->
|
|
+ carriesCertificate.test(h)
|
|
+ ? Optional.of(new AereDecidedHead.Decided(h.getNumber() - 1L, h.getParentHash()))
|
|
+ : Optional.empty());
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Install the tags on a blockchain: initialise from the current head, then follow every block added.
|
|
+ * The tag is what {@code decision} answers for a canonical anchor (AERE-Q3-BUNIC: the node passes
|
|
+ * {@link AereCertifiedDecision#over}, the same answer the decided head takes for Q3).
|
|
+ *
|
|
+ * @param config the anchor configuration (activation height, interval schedule)
|
|
+ * @param blockchain the chain whose finalized/safe tags are written
|
|
+ * @param decision the block a stored anchor's certificate decides, empty when none
|
|
+ * @return the installed instance, for inspection
|
|
+ */
|
|
+ public static AerePqFinalityTags installDecided(
|
|
+ final PqAnchorConfig config,
|
|
+ final MutableBlockchain blockchain,
|
|
+ final Function<BlockHeader, Optional<AereDecidedHead.Decided>> decision) {
|
|
+ final AerePqFinalityTags tags = new AerePqFinalityTags(config, blockchain, decision);
|
|
tags.initialiseFromHead();
|
|
blockchain.observeBlockAdded(tags::onBlockAdded);
|
|
return tags;
|
|
}
|
|
|
|
/** The height currently reported as finalized, or -1 when none has been set by this rule. */
|
|
public long finalizedNumber() {
|
|
return finalizedNumber.get();
|
|
}
|
|
|
|
/**
|
|
* Whether a decoded header carries an anchor certificate. A header carries the v1 Falcon list OR
|
|
* the v2 scheme-tagged certificate, never both ({@link BftExtraData}), and from AIP-22 stage 5
|
|
* every anchor carries the v2 certificate while {@code getFalconSeals()} is empty. So a predicate
|
|
* that only looked at the v1 list ({@code getFalconSeals()}) never fired on a stage-5 chain -
|
|
* measured 2026-09-26 on the rep28098 rehearsal, where {@code finalized} stayed 0 while the chain
|
|
* ran past certified anchors 1920 and 1952. Both fields are checked here, in one place both the
|
|
* controller and the test read, so the two cannot drift.
|
|
*
|
|
+ * <p>From H_r (1(b), 2026-10-01) the v3 certificate keeps its rows in the same scheme-tagged list
|
|
+ * (the round lives in {@link BftExtraData#getCertificateRound()}), so this predicate sees it with no
|
|
+ * new branch; the EMPTY v3 certificate (K_eff = 0, decision H5) answers false, which is right: it
|
|
+ * proves nothing. Probed on a decoded v3 header by {@code AerePqFinalityTagsV3Test}, so a future
|
|
+ * change of where the v3 rows live cannot make B1 go silent unseen (D-398).
|
|
+ *
|
|
* @param extraData the decoded BFT extra data of the header
|
|
- * @return true when the header carries a (v1 or v2) anchor certificate
|
|
+ * @return true when the header carries a non-empty (v1, v2 or v3) anchor certificate
|
|
*/
|
|
public static boolean carriesCertificate(final BftExtraData extraData) {
|
|
return !extraData.getFalconSeals().isEmpty() || !extraData.getHybridSeals().isEmpty();
|
|
}
|
|
|
|
- /** Scan back from the head, at most two anchor intervals, to the last certified anchor. */
|
|
+ /** Scan back from the head, at most two anchor intervals, to the last anchor that decides a block. */
|
|
void initialiseFromHead() {
|
|
final BlockHeader head = blockchain.getChainHeadHeader();
|
|
if (head == null) {
|
|
return;
|
|
}
|
|
final long top = head.getNumber();
|
|
final long floor = Math.max(0L, top - 2L * Math.max(1, config.intervalAt(top)));
|
|
for (long h = top; h >= floor; h--) {
|
|
if (!config.anchorAppliesAt(h)) {
|
|
continue;
|
|
}
|
|
final Optional<BlockHeader> header = blockchain.getBlockHeader(h);
|
|
- if (header.isPresent() && carriesCertificate.test(header.get())) {
|
|
- set(header.get().getParentHash(), h - 1L, "startup scan");
|
|
+ final Optional<AereDecidedHead.Decided> decided =
|
|
+ header.isPresent() ? decision.apply(header.get()) : Optional.empty();
|
|
+ if (decided.isPresent()) {
|
|
+ set(decided.get().hash(), decided.get().number(), "startup scan, anchor " + h);
|
|
return;
|
|
}
|
|
}
|
|
LOG.info(
|
|
- "AERE PQ FINALITY (B1): no certified anchor between {} and the head {}; finalized/safe stay "
|
|
+ "AERE PQ FINALITY (B1): no anchor that decides a block between {} and the head {}; finalized/safe stay "
|
|
+ "unset until the next anchor is imported.",
|
|
floor,
|
|
top);
|
|
}
|
|
|
|
/**
|
|
* Follow a block added to the chain.
|
|
*
|
|
* @param event the event
|
|
*/
|
|
void onBlockAdded(final BlockAddedEvent event) {
|
|
if (event == null || !event.isNewCanonicalHead()) {
|
|
return;
|
|
}
|
|
final BlockHeader header = event.getHeader();
|
|
if (header == null) {
|
|
return;
|
|
}
|
|
if (event.getEventType() == EventType.CHAIN_REORG && finalizedNumber.get() >= 0) {
|
|
final Hash ancestorHash = event.getCommonAncestorHash();
|
|
final Optional<BlockHeader> ancestor =
|
|
ancestorHash == null ? Optional.empty() : blockchain.getBlockHeader(ancestorHash);
|
|
if (ancestor.isPresent() && ancestor.get().getNumber() < finalizedNumber.get()) {
|
|
LOG.error(
|
|
"{}: a canonical reorg to {} (common ancestor {}) went BELOW the finalized block {}. "
|
|
- + "Finality tags are NOT moved back. Under the anchor rules this needs K validators to "
|
|
- + "have certified two conflicting anchors; investigate before anything else.",
|
|
+ + "Finality tags are NOT moved back. A block taken as decided by a certificate was not: "
|
|
+ + "that needs more than f faulty validators; investigate before anything else.",
|
|
CODE_REORG_BELOW_FINALIZED,
|
|
header.getNumber(),
|
|
ancestor.get().getNumber(),
|
|
finalizedNumber.get());
|
|
}
|
|
}
|
|
final long h = header.getNumber();
|
|
- if (config.anchorAppliesAt(h) && carriesCertificate.test(header)) {
|
|
- set(header.getParentHash(), h - 1L, "anchor " + h);
|
|
+ if (config.anchorAppliesAt(h)) {
|
|
+ // AERE-Q3-BUNIC (teza Q3, D-470, 2026-10-01): what the certificate decides, not its parent
|
|
+ final Optional<AereDecidedHead.Decided> decided = decision.apply(header);
|
|
+ if (decided.isPresent()) {
|
|
+ set(decided.get().hash(), decided.get().number(), "anchor " + h);
|
|
+ }
|
|
}
|
|
}
|
|
|
|
private void set(final Hash finalHash, final long finalNumber, final String why) {
|
|
if (finalNumber <= finalizedNumber.get()) {
|
|
return; // monotonic: never backwards, never twice for the same height
|
|
}
|
|
blockchain.setFinalized(finalHash);
|
|
blockchain.setSafeBlock(finalHash);
|
|
finalizedNumber.set(finalNumber);
|
|
LOG.info(
|
|
- "AERE PQ FINALITY (B1): finalized/safe = {} ({}), covered by the certificate of {}.",
|
|
+ "AERE PQ FINALITY (B1): finalized/safe = {} ({}), decided by the certificate of {}.",
|
|
finalNumber,
|
|
finalHash,
|
|
why);
|
|
}
|
|
}
|
|
diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftBlockInterface.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftBlockInterface.java
|
|
index acefe61665..69b07a4578 100644
|
|
--- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftBlockInterface.java
|
|
+++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftBlockInterface.java
|
|
@@ -101,40 +101,43 @@ public class BftBlockInterface implements BlockInterface {
|
|
* @param block the block
|
|
* @param round the round
|
|
* @param blockHeaderFunctions the block header functions
|
|
* @return the block
|
|
*/
|
|
public Block replaceRoundInBlock(
|
|
final Block block, final int round, final BlockHeaderFunctions blockHeaderFunctions) {
|
|
final BftExtraData prevExtraData = bftExtraDataCodec.decode(block.getHeader());
|
|
final BftExtraData substituteExtraData =
|
|
new BftExtraData(
|
|
prevExtraData.getVanityData(),
|
|
prevExtraData.getSeals(),
|
|
prevExtraData.getVote(),
|
|
round,
|
|
prevExtraData.getValidators(),
|
|
prevExtraData.getFalconSeals(),
|
|
// AERE ANCHOR V2 (2026-09-03, D-328): the scheme-tagged certificate rides along too. Without
|
|
// this line every v2 header lost its certificate at the round substitution and the fleet
|
|
// refused its own first v2 anchor (testnet 28001, block 168032, 3 hours stalled).
|
|
prevExtraData.getHybridSeals(),
|
|
+ // AERE 1(b) (2026-10-01): and the round of a v3 certificate, for the same reason: D3 binds it,
|
|
+ // so a substitution that dropped it would leave a header whose vanity no longer matches
|
|
+ prevExtraData.getCertificateRound().orElse(BftExtraData.NO_CERTIFICATE_ROUND),
|
|
// AERE AIP-22 stage 5: and the proposer's seal (element 6), for the same reason; it sits outside
|
|
// both hash pre-images, so carrying it changes no hash
|
|
prevExtraData.getPqProposerSeal());
|
|
|
|
final BlockHeaderBuilder headerBuilder = BlockHeaderBuilder.fromHeader(block.getHeader());
|
|
headerBuilder
|
|
.extraData(bftExtraDataCodec.encode(substituteExtraData))
|
|
.blockHeaderFunctions(blockHeaderFunctions);
|
|
|
|
final BlockHeader newHeader = headerBuilder.buildBlockHeader();
|
|
|
|
return new Block(newHeader, block.getBody());
|
|
}
|
|
|
|
/**
|
|
* Gets extra data.
|
|
*
|
|
* @param header the header
|
|
* @return the extra data
|
|
*/
|
|
diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftExtraData.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftExtraData.java
|
|
index 4e9ea6f783..0169c284bc 100644
|
|
--- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftExtraData.java
|
|
+++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftExtraData.java
|
|
@@ -13,151 +13,197 @@
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
* found, as section 4(c) requires. The change itself is in patches/0003-aere-pq-anchor.patch.
|
|
*/
|
|
package org.hyperledger.besu.consensus.common.bft;
|
|
|
|
import static com.google.common.base.Preconditions.checkNotNull;
|
|
|
|
import org.hyperledger.besu.crypto.SECPSignature;
|
|
import org.hyperledger.besu.datatypes.Address;
|
|
import org.hyperledger.besu.ethereum.core.ParsedExtraData;
|
|
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
|
|
import org.apache.tuweni.bytes.Bytes;
|
|
|
|
/** The Bft extra data. */
|
|
public class BftExtraData implements ParsedExtraData {
|
|
private final Bytes vanityData;
|
|
private final Collection<SECPSignature> seals;
|
|
private final Collection<Address> validators;
|
|
private final Optional<Vote> vote;
|
|
private final int round;
|
|
|
|
/**
|
|
* Parallel, ADDITIVE post-quantum (Falcon-512) seals. These sit alongside the decisive ECDSA
|
|
* {@link #seals} and are excluded from every signed pre-image, so they never disturb the ECDSA
|
|
* committed seals or the block/header hash.
|
|
*/
|
|
private final Collection<FalconSeal> falconSeals;
|
|
/** AERE ANCHOR V2: the scheme-tagged certificate; empty on every header below the v2 height. */
|
|
private final List<SchemeSeal> hybridSeals;
|
|
/**
|
|
* AERE AIP-22 stage 5: the proposer's post-quantum seal (element 6 of the stored extraData, from
|
|
* H_hdr), the PROPOSAL layer's seal over the proposal digest; outside every hash, like the
|
|
* certificate. Empty on every header below H_hdr.
|
|
*/
|
|
private final Optional<FalconSeal> proposerSeal;
|
|
+ /**
|
|
+ * AERE 1(b): the round r of a v3 certificate, or {@link #NO_CERTIFICATE_ROUND} (no certificate, v1
|
|
+ * or v2). Outside every hash, like the certificate itself; D3 binds it.
|
|
+ */
|
|
+ private final int certificateRound;
|
|
|
|
/**
|
|
* Instantiates a new Bft extra data (no Falcon seals). Retained for callers, notably the IBFT
|
|
* codec, that never carry a parallel post-quantum seal.
|
|
*
|
|
* @param vanityData the vanity data
|
|
* @param seals the seals
|
|
* @param vote the vote
|
|
* @param round the round
|
|
* @param validators the validators
|
|
*/
|
|
public BftExtraData(
|
|
final Bytes vanityData,
|
|
final Collection<SECPSignature> seals,
|
|
final Optional<Vote> vote,
|
|
final int round,
|
|
final Collection<Address> validators) {
|
|
- this(vanityData, seals, vote, round, validators, Collections.emptyList());
|
|
+ this(
|
|
+ vanityData,
|
|
+ seals,
|
|
+ vote,
|
|
+ round,
|
|
+ validators,
|
|
+ Collections.emptyList(),
|
|
+ Collections.emptyList(),
|
|
+ NO_CERTIFICATE_ROUND);
|
|
}
|
|
|
|
/**
|
|
- * Instantiates a new Bft extra data with a parallel Falcon-512 seal list.
|
|
- *
|
|
- * @param vanityData the vanity data
|
|
- * @param seals the ECDSA committed seals (decisive)
|
|
- * @param vote the vote
|
|
- * @param round the round
|
|
- * @param validators the validators
|
|
- * @param falconSeals the parallel post-quantum Falcon seals (additive, log-only)
|
|
+ * The certificate-round value of every header that carries no ROUND-BOUND certificate: no
|
|
+ * certificate at all, the v1 Falcon list, or the scheme-tagged v2 certificate. 1(b), 2026-10-01.
|
|
*/
|
|
- public BftExtraData(
|
|
- final Bytes vanityData,
|
|
- final Collection<SECPSignature> seals,
|
|
- final Optional<Vote> vote,
|
|
- final int round,
|
|
- final Collection<Address> validators,
|
|
- final Collection<FalconSeal> falconSeals) {
|
|
- this(vanityData, seals, vote, round, validators, falconSeals, Collections.emptyList());
|
|
- }
|
|
+ public static final int NO_CERTIFICATE_ROUND = -1;
|
|
|
|
/**
|
|
- * Full constructor.
|
|
+ * Full constructor (1(b), 2026-10-01: the certificate round is MANDATORY).
|
|
*
|
|
- * @param hybridSeals the scheme-tagged (v2) certificate, or empty; a header carries the v1 Falcon
|
|
- * list OR the v2 certificate, never both
|
|
+ * <p>DECISION H10 of the 1(b) project: every constructor that takes a certificate also takes its
|
|
+ * round, with no default anywhere. The constructors that took a certificate WITHOUT a round were
|
|
+ * deleted, so the compiler listed every place that rebuilds an extraData (D-328: a place that
|
|
+ * forgets a field seals the anchor without it and stops the chain at the first such anchor).
|
|
+ *
|
|
+ * @param vanityData the vanity data
|
|
+ * @param seals the ECDSA committed seals (decisive; from H_hdr: empty)
|
|
+ * @param vote the vote
|
|
+ * @param round the round (element 3)
|
|
+ * @param validators the validators
|
|
+ * @param falconSeals the v1 Falcon certificate, or empty
|
|
+ * @param hybridSeals the scheme-tagged rows (v2, or v3 when {@code certificateRound >= 0}), or empty
|
|
+ * @param certificateRound the round r of a v3 certificate (0..PqAnchorV3.MAX_ROUND), or {@link
|
|
+ * #NO_CERTIFICATE_ROUND}
|
|
*/
|
|
public BftExtraData(
|
|
final Bytes vanityData,
|
|
final Collection<SECPSignature> seals,
|
|
final Optional<Vote> vote,
|
|
final int round,
|
|
final Collection<Address> validators,
|
|
final Collection<FalconSeal> falconSeals,
|
|
- final List<SchemeSeal> hybridSeals) {
|
|
- this(vanityData, seals, vote, round, validators, falconSeals, hybridSeals, Optional.empty());
|
|
+ final List<SchemeSeal> hybridSeals,
|
|
+ final int certificateRound) {
|
|
+ this(
|
|
+ vanityData,
|
|
+ seals,
|
|
+ vote,
|
|
+ round,
|
|
+ validators,
|
|
+ falconSeals,
|
|
+ hybridSeals,
|
|
+ certificateRound,
|
|
+ Optional.empty());
|
|
}
|
|
|
|
/**
|
|
* Full constructor with the proposer's post-quantum seal (AIP-22 stage 5).
|
|
*
|
|
+ * <p>Invariants: a header carries the v1 Falcon list OR scheme-tagged rows, never both; a v3
|
|
+ * certificate ({@code certificateRound >= 0}) carries no v1 list, names a round in 0..{@link
|
|
+ * PqAnchorV3#MAX_ROUND}, and may be EMPTY only with round 0 (decision H5).
|
|
+ *
|
|
* @param vanityData the vanity data
|
|
* @param seals the ECDSA committed seals (from H_hdr: empty)
|
|
* @param vote the vote
|
|
* @param round the round
|
|
* @param validators the validators
|
|
* @param falconSeals the v1 Falcon certificate, or empty
|
|
- * @param hybridSeals the v2 certificate, or empty
|
|
- * @param proposerSeal the proposer's seal (element 6), or empty
|
|
+ * @param hybridSeals the scheme-tagged rows (v2 or v3), or empty
|
|
+ * @param certificateRound the v3 round, or {@link #NO_CERTIFICATE_ROUND}
|
|
+ * @param proposerSeal the proposer's seal (element 7), or empty
|
|
*/
|
|
public BftExtraData(
|
|
final Bytes vanityData,
|
|
final Collection<SECPSignature> seals,
|
|
final Optional<Vote> vote,
|
|
final int round,
|
|
final Collection<Address> validators,
|
|
final Collection<FalconSeal> falconSeals,
|
|
final List<SchemeSeal> hybridSeals,
|
|
+ final int certificateRound,
|
|
final Optional<FalconSeal> proposerSeal) {
|
|
checkNotNull(vanityData);
|
|
checkNotNull(proposerSeal);
|
|
this.proposerSeal = proposerSeal;
|
|
checkNotNull(hybridSeals);
|
|
if (!hybridSeals.isEmpty() && falconSeals != null && !falconSeals.isEmpty()) {
|
|
throw new IllegalArgumentException(
|
|
"AERE ANCHOR V2: a header carries the v1 Falcon list OR the v2 certificate, not both");
|
|
}
|
|
+ if (certificateRound != NO_CERTIFICATE_ROUND) {
|
|
+ if (certificateRound < 0 || certificateRound > PqAnchorV3.MAX_ROUND) {
|
|
+ throw new IllegalArgumentException(
|
|
+ "AERE ANCHOR V3: certificate round "
|
|
+ + certificateRound
|
|
+ + " is outside 0.."
|
|
+ + PqAnchorV3.MAX_ROUND);
|
|
+ }
|
|
+ if (falconSeals != null && !falconSeals.isEmpty()) {
|
|
+ throw new IllegalArgumentException(
|
|
+ "AERE ANCHOR V3: a v3 certificate carries no v1 Falcon list");
|
|
+ }
|
|
+ if (hybridSeals.isEmpty() && certificateRound != 0) {
|
|
+ throw new IllegalArgumentException(
|
|
+ "AERE ANCHOR V3: an empty v3 certificate names round 0, not " + certificateRound);
|
|
+ }
|
|
+ }
|
|
+ this.certificateRound = certificateRound;
|
|
this.hybridSeals = List.copyOf(hybridSeals);
|
|
checkNotNull(seals);
|
|
checkNotNull(validators);
|
|
checkNotNull(falconSeals);
|
|
this.vanityData = vanityData;
|
|
this.seals = seals;
|
|
this.validators = validators;
|
|
this.vote = vote;
|
|
this.round = round;
|
|
this.falconSeals = falconSeals;
|
|
}
|
|
|
|
/**
|
|
* Gets vanity data.
|
|
*
|
|
* @return the vanity data
|
|
*/
|
|
public Bytes getVanityData() {
|
|
return vanityData;
|
|
}
|
|
@@ -199,66 +245,87 @@ public class BftExtraData implements ParsedExtraData {
|
|
}
|
|
|
|
/**
|
|
* Gets the parallel post-quantum Falcon seals.
|
|
*
|
|
* @return the Falcon seals (possibly empty, never null)
|
|
*/
|
|
public Collection<FalconSeal> getFalconSeals() {
|
|
return falconSeals;
|
|
}
|
|
|
|
/**
|
|
* The scheme-tagged (v2) certificate.
|
|
*
|
|
* @return the v2 seals, canonical order; empty below the v2 height
|
|
*/
|
|
public List<SchemeSeal> getHybridSeals() {
|
|
return hybridSeals;
|
|
}
|
|
|
|
+ /**
|
|
+ * AERE 1(b): the round a v3 certificate names.
|
|
+ *
|
|
+ * @return the round, or empty when the header carries no v3 certificate (none, v1 or v2)
|
|
+ */
|
|
+ public OptionalInt getCertificateRound() {
|
|
+ return certificateRound == NO_CERTIFICATE_ROUND
|
|
+ ? OptionalInt.empty()
|
|
+ : OptionalInt.of(certificateRound);
|
|
+ }
|
|
+
|
|
/**
|
|
* The proposer's post-quantum seal (AIP-22 stage 5, element 6).
|
|
*
|
|
* @return the seal, or empty below H_hdr
|
|
*/
|
|
public Optional<FalconSeal> getPqProposerSeal() {
|
|
return proposerSeal;
|
|
}
|
|
|
|
/**
|
|
* The same extra data with another proposer seal and ECDSA seals, everything else carried over
|
|
* (the certificate included): the one way to seal a stage-5 header, so no caller can drop the
|
|
* certificate while adding the seal (the lesson of 2026-09-03, D-328).
|
|
*
|
|
* @param newSeals the ECDSA committed seals (from H_hdr: empty)
|
|
* @param newProposerSeal the proposer's seal
|
|
* @return the new extra data
|
|
*/
|
|
public BftExtraData withSeals(
|
|
final Collection<SECPSignature> newSeals, final Optional<FalconSeal> newProposerSeal) {
|
|
return new BftExtraData(
|
|
- vanityData, newSeals, vote, round, validators, falconSeals, hybridSeals, newProposerSeal);
|
|
+ vanityData,
|
|
+ newSeals,
|
|
+ vote,
|
|
+ round,
|
|
+ validators,
|
|
+ falconSeals,
|
|
+ hybridSeals,
|
|
+ certificateRound,
|
|
+ newProposerSeal);
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "BftExtraData{"
|
|
+ "vanityData="
|
|
+ vanityData
|
|
+ ", seals="
|
|
+ seals
|
|
+ ", validators="
|
|
+ validators
|
|
+ ", vote="
|
|
+ vote
|
|
+ ", round="
|
|
+ round
|
|
+ ", falconSeals="
|
|
+ falconSeals
|
|
+ ", hybridSeals="
|
|
+ hybridSeals
|
|
+ // 1(b): only when a v3 certificate is carried, so every other header prints as before (L1)
|
|
+ + (certificateRound == NO_CERTIFICATE_ROUND ? "" : ", certificateRound=" + certificateRound)
|
|
+ ", proposerSeal="
|
|
+ proposerSeal
|
|
+ '}';
|
|
}
|
|
}
|
|
diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchor.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchor.java
|
|
index 5524158c03..7abb948555 100644
|
|
--- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchor.java
|
|
+++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchor.java
|
|
@@ -51,70 +51,94 @@ import org.apache.tuweni.bytes.Bytes32;
|
|
* It is CARRIED in the extraData of block N, chosen by N's proposer and ratified by N's round, and
|
|
* N's vanityData carries its digest over all 32 bytes. The digest therefore depends only on what the
|
|
* PROPOSER WROTE, and those bytes reach every node identically inside the same proposal. A validator
|
|
* never compares the certificate with what it heard: it checks only the threshold, strictly
|
|
* increasing indices, index eligibility in the PARENT's validator set, and k Falcon verifications. A
|
|
* node that heard 7 accepts the proposer's certificate of 5.
|
|
*
|
|
* <p><b>The two pre-images.</b>
|
|
*
|
|
* <pre>
|
|
* D = keccak256( RLP[ "AERE-PQ-ANCHOR-1", chainId, parentNumber, parentHash, C ] )
|
|
* M = keccak256( RLP[ "AERE-PQ-COMMIT-1", chainId, blockNumber, blockHash ] )
|
|
* C = RLP[ [idx, sig], [idx, sig], ... ] indices STRICTLY INCREASING
|
|
* </pre>
|
|
*
|
|
* <p>D occupies all 32 bytes of vanityData: no magic, no version byte, no padding. The budget is 32
|
|
* bytes and cannot grow, because two LIVE length checks require exactly 32 (AereQbftFinalityVerifier
|
|
* .sol line 194 and the second client's decoder). Versioning is by ACTIVATION HEIGHT, not by an
|
|
* in-band version byte, because any format change needs a governance-decided height anyway.
|
|
*
|
|
- * <p>M is deliberately NOT the ECDSA commit hash. The commit hash includes the ROUND, which is not
|
|
- * in the block-hash pre-image, and rounds above zero do occur on this chain (measured 1 in 307).
|
|
- * Defining M over the block HASH makes the message reconstructible by any node holding the parent
|
|
- * header: no state, no round, no local memory.
|
|
+ * <p>HISTORY (the reasoning of 2026-08-01, kept as written for COMMIT-1): M is deliberately NOT the
|
|
+ * ECDSA commit hash. The commit hash includes the ROUND, which is not in the block-hash pre-image,
|
|
+ * and rounds above zero do occur on this chain (measured 1 in 307). Defining M over the block HASH
|
|
+ * makes the message reconstructible by any node holding the parent header: no state, no round, no
|
|
+ * local memory.
|
|
+ *
|
|
+ * <p>CORRECTED 2026-10-01 (D-470, project 1(b)): leaving the round out was the defect, not the
|
|
+ * feature. Without it a post-quantum commit seal given honestly in one round can be pasted under a
|
|
+ * forged ECDSA commit of another round (an adversary that breaks ECDSA, A_q), and a certificate can
|
|
+ * add seals from different rounds into one "quorum" that no single round ever reached. From the
|
|
+ * configured height {@code aere.pq.commitRoundBlock} (H_r) the commit seal signs {@link
|
|
+ * #commitMessageRound}: M_r = keccak256(RLP["AERE-PQ-COMMIT-2", chainId, n, r, hash]), the field
|
|
+ * order of PREPARE-1 and PROPOSAL-1, and the certificate carries that single r ({@link
|
|
+ * PqAnchorV3}). The round still comes from the COMMIT message (or the certificate), never from a
|
|
+ * stored header, whose element 3 differs legitimately between nodes. Below H_r nothing changes:
|
|
+ * {@link #commitMessage} stays, byte for byte, for the history. Which form applies to a block is
|
|
+ * decided in exactly one place, {@code PqAnchorProducer.commitSealFormAt}.
|
|
*
|
|
* <p>The domain labels are what stops a Falcon signature produced for another subsystem (the
|
|
* AerePQCTxAccount rail, ML-KEM intents, any application message) from being reinterpreted as a
|
|
* consensus seal, and the chainId is what stops a certificate produced on the 442807 proving chain,
|
|
* which runs the SAME binaries and may run the same Falcon keys, from being material here.
|
|
*
|
|
* <p>CONSENSUS IS STILL CLASSICAL secp256k1 ECDSA. This class does not make consensus post-quantum
|
|
* and must never be described as doing so. The post-quantum layer is signature, precompile and
|
|
* account level.
|
|
*/
|
|
public final class PqAnchor {
|
|
|
|
/** Domain label for the anchor digest D. Exactly 16 ASCII bytes. */
|
|
public static final String ANCHOR_DOMAIN = "AERE-PQ-ANCHOR-1";
|
|
|
|
/** Domain label for the signed commit message M. Exactly 16 ASCII bytes. */
|
|
public static final String COMMIT_DOMAIN = "AERE-PQ-COMMIT-1";
|
|
|
|
/** The anchor domain label as raw bytes. */
|
|
public static final Bytes ANCHOR_DOMAIN_BYTES =
|
|
Bytes.wrap(ANCHOR_DOMAIN.getBytes(StandardCharsets.US_ASCII));
|
|
|
|
/** The commit domain label as raw bytes. */
|
|
public static final Bytes COMMIT_DOMAIN_BYTES =
|
|
Bytes.wrap(COMMIT_DOMAIN.getBytes(StandardCharsets.US_ASCII));
|
|
|
|
+ /**
|
|
+ * Domain label of the ROUND-BOUND commit message M_r (D-470, 1(b), 2026-10-01). Exactly 16 ASCII
|
|
+ * bytes, like COMMIT-1, so the two can never collide and a COMMIT-1 seal never verifies as a
|
|
+ * COMMIT-2 one.
|
|
+ */
|
|
+ public static final String COMMIT_DOMAIN_2 = "AERE-PQ-COMMIT-2";
|
|
+
|
|
+ /** The round-bound commit domain label as raw bytes. */
|
|
+ public static final Bytes COMMIT_DOMAIN_2_BYTES =
|
|
+ Bytes.wrap(COMMIT_DOMAIN_2.getBytes(StandardCharsets.US_ASCII));
|
|
+
|
|
/**
|
|
* The PREPARE domain label. AERE PQ (2026-08-28).
|
|
*
|
|
* <p>SEPARATE FROM COMMIT, and the separation is a security requirement, not a matter of style.
|
|
* If a PREPARE seal signed the same bytes as a commit seal, an adversary could take a PREPARE
|
|
* seal given HONESTLY by a validator and paste it onto a forged COMMIT: the signature would
|
|
* verify, and the very rule meant to defend the commit would be bypassed. One changed string in
|
|
* the preimage makes the two signatures non-transferable.
|
|
*/
|
|
public static final String PREPARE_DOMAIN = "AERE-PQ-PREPARE-1";
|
|
|
|
/** The prepare domain label as raw bytes. */
|
|
public static final Bytes PREPARE_DOMAIN_BYTES =
|
|
Bytes.wrap(PREPARE_DOMAIN.getBytes(StandardCharsets.US_ASCII));
|
|
|
|
/**
|
|
* The PROPOSAL domain label. AERE PQ (2026-08-30), the next hot-path step after PREPARE.
|
|
*
|
|
* <p>SEPARATE FROM BOTH PREPARE AND COMMIT, for the same non-transferability reason: a seal a
|
|
* proposer gives HONESTLY over its own proposal must not be usable as a vote. A proposal is an
|
|
@@ -261,103 +285,148 @@ public final class PqAnchor {
|
|
return Hash.keccak256(out.encoded());
|
|
}
|
|
|
|
/**
|
|
* The message a PREPARE seal signs: M = keccak256(RLP[PREPARE_DOMAIN, chainId, blockNumber,
|
|
* round, digest]).
|
|
*
|
|
* <p>RUNDA E IN PREIMAGINE, spre deosebire de commit, si asta e al doilea lucru care nu se sare:
|
|
* doua PREPARE-uri ale aceluiasi bloc in runde diferite sunt doua afirmatii diferite, iar un
|
|
* a seal given in one round must not be movable into another. Without the round, a seal from a
|
|
* PREPARE of a failed round could be reused to justify another one.
|
|
*
|
|
* @param chainId the chain id
|
|
* @param blockNumber the height being prepared
|
|
* @param round the round number of the prepare
|
|
* @param digest the block digest the prepare speaks about
|
|
* @return the 32-byte message to sign
|
|
*/
|
|
public static Bytes32 prepareMessage(
|
|
final long chainId, final long blockNumber, final int round, final Bytes digest) {
|
|
+ return roundedMessage(
|
|
+ "AERE PQ PREPARE", "digest", PREPARE_DOMAIN_BYTES, chainId, blockNumber, round, digest);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The ROUND-BOUND commit message M_r that a validator's post-quantum commit seal signs from the
|
|
+ * height {@code aere.pq.commitRoundBlock} (D-470, 1(b), 2026-10-01):
|
|
+ *
|
|
+ * <pre>
|
|
+ * M_r = keccak256( RLP[ "AERE-PQ-COMMIT-2", chainId, n, r, hash ] )
|
|
+ * </pre>
|
|
+ *
|
|
+ * <p>The field order is the PREPARE-1 / PROPOSAL-1 order (decision H1 of the project), produced by
|
|
+ * the same private builder, so there is one shape for "a round-scoped statement about a block".
|
|
+ * {@code hash} is the ON-CHAIN hash (round set to 0, seals and certificate excluded), never the
|
|
+ * ECDSA commit digest; {@code r} is the round of the COMMIT that carries the seal, written as a
|
|
+ * minimal scalar (round 0 is {@code 0x80}, the empty string).
|
|
+ *
|
|
+ * <p>This is a primitive. Production code never calls it directly: it goes through {@code
|
|
+ * PqAnchorProducer.anchorSealMessage}, the single place that decides the form by height and
|
|
+ * refuses a round outside 0..{@link PqAnchorV3#MAX_ROUND} with an empty result (code {@code
|
|
+ * AERE-PQ-COMMIT-R-03}) before this method can see it. The range check here is a second guard for
|
|
+ * a programming error, not a path a peer can reach.
|
|
+ *
|
|
+ * @param chainId the chain id
|
|
+ * @param blockNumber the number of the block being sealed
|
|
+ * @param round the round of the commit, 0..{@link PqAnchorV3#MAX_ROUND}
|
|
+ * @param blockHash the on-chain hash of the block being sealed
|
|
+ * @return the 32-byte message M_r that Falcon (and every extra scheme) signs
|
|
+ */
|
|
+ public static Bytes32 commitMessageRound(
|
|
+ final long chainId, final long blockNumber, final int round, final Bytes blockHash) {
|
|
+ if (round > PqAnchorV3.MAX_ROUND) {
|
|
+ throw new IllegalArgumentException(
|
|
+ "AERE PQ COMMIT-2: round must be at most "
|
|
+ + PqAnchorV3.MAX_ROUND
|
|
+ + " (got "
|
|
+ + round
|
|
+ + ")");
|
|
+ }
|
|
+ return roundedMessage(
|
|
+ "AERE PQ COMMIT-2",
|
|
+ "blockHash",
|
|
+ COMMIT_DOMAIN_2_BYTES,
|
|
+ chainId,
|
|
+ blockNumber,
|
|
+ round,
|
|
+ blockHash);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The one builder of every round-scoped message: keccak256(RLP[domain, chainId, n, round, x32]).
|
|
+ * PREPARE-1, PROPOSAL-1 and COMMIT-2 differ ONLY by the domain (decision H1, 1(b)); one function
|
|
+ * means the three cannot drift apart in field order or scalar encoding.
|
|
+ */
|
|
+ private static Bytes32 roundedMessage(
|
|
+ final String label,
|
|
+ final String what,
|
|
+ final Bytes domain,
|
|
+ final long chainId,
|
|
+ final long blockNumber,
|
|
+ final int round,
|
|
+ final Bytes x32) {
|
|
if (blockNumber < 0) {
|
|
throw new IllegalArgumentException(
|
|
- "AERE PQ PREPARE: blockNumber must not be negative (got " + blockNumber + ")");
|
|
+ label + ": blockNumber must not be negative (got " + blockNumber + ")");
|
|
}
|
|
if (round < 0) {
|
|
throw new IllegalArgumentException(
|
|
- "AERE PQ PREPARE: round must not be negative (got " + round + ")");
|
|
+ label + ": round must not be negative (got " + round + ")");
|
|
}
|
|
- if (digest == null || digest.size() != 32) {
|
|
+ if (x32 == null || x32.size() != 32) {
|
|
throw new IllegalArgumentException(
|
|
- "AERE PQ PREPARE: digest must be 32 bytes (got "
|
|
- + (digest == null ? "null" : digest.size() + " bytes")
|
|
+ label
|
|
+ + ": "
|
|
+ + what
|
|
+ + " must be 32 bytes (got "
|
|
+ + (x32 == null ? "null" : x32.size() + " bytes")
|
|
+ ")");
|
|
}
|
|
final BytesValueRLPOutput out = new BytesValueRLPOutput();
|
|
out.startList();
|
|
- out.writeBytes(PREPARE_DOMAIN_BYTES);
|
|
+ out.writeBytes(domain);
|
|
out.writeLongScalar(chainId);
|
|
out.writeLongScalar(blockNumber);
|
|
out.writeLongScalar(round);
|
|
- out.writeBytes(digest);
|
|
+ out.writeBytes(x32);
|
|
out.endList();
|
|
return Hash.keccak256(out.encoded());
|
|
}
|
|
|
|
/**
|
|
* The 32-byte message a proposer's post-quantum PROPOSAL seal signs.
|
|
*
|
|
* <p>Same shape as {@link #prepareMessage}, different domain, and the ROUND is in the preimage
|
|
* for the same reason: a proposal for the same block in a different round is a different
|
|
* assertion, and a seal from a failed round must not open another one.
|
|
*
|
|
* @param chainId the chain id
|
|
* @param blockNumber the height being proposed
|
|
* @param round the round number of the proposal
|
|
* @param digest the digest of the proposed block
|
|
* @return the 32-byte message to sign
|
|
*/
|
|
public static Bytes32 proposalMessage(
|
|
final long chainId, final long blockNumber, final int round, final Bytes digest) {
|
|
- if (blockNumber < 0) {
|
|
- throw new IllegalArgumentException(
|
|
- "AERE PQ PROPOSAL: blockNumber must not be negative (got " + blockNumber + ")");
|
|
- }
|
|
- if (round < 0) {
|
|
- throw new IllegalArgumentException(
|
|
- "AERE PQ PROPOSAL: round must not be negative (got " + round + ")");
|
|
- }
|
|
- if (digest == null || digest.size() != 32) {
|
|
- throw new IllegalArgumentException(
|
|
- "AERE PQ PROPOSAL: digest must be 32 bytes (got "
|
|
- + (digest == null ? "null" : digest.size() + " bytes")
|
|
- + ")");
|
|
- }
|
|
- final BytesValueRLPOutput out = new BytesValueRLPOutput();
|
|
- out.startList();
|
|
- out.writeBytes(PROPOSAL_DOMAIN_BYTES);
|
|
- out.writeLongScalar(chainId);
|
|
- out.writeLongScalar(blockNumber);
|
|
- out.writeLongScalar(round);
|
|
- out.writeBytes(digest);
|
|
- out.endList();
|
|
- return Hash.keccak256(out.encoded());
|
|
+ return roundedMessage(
|
|
+ "AERE PQ PROPOSAL", "digest", PROPOSAL_DOMAIN_BYTES, chainId, blockNumber, round, digest);
|
|
}
|
|
|
|
/**
|
|
* The 32-byte message a validator's post-quantum ROUND-CHANGE seal signs, for a round-change
|
|
* that carries NO prepared-round metadata.
|
|
*
|
|
* <p>The preimage writes an explicit presence flag of 0 and empty placeholders, so a bare
|
|
* round-change and one prepared at round 0 can never collide: the flag, not the emptiness of a
|
|
* field, is what says whether metadata exists.
|
|
*
|
|
* @param chainId the chain id
|
|
* @param blockNumber the height the round-change targets (its sequence number)
|
|
* @param targetRound the round the sender wants to move to
|
|
* @return the 32-byte message to sign
|
|
*/
|
|
public static Bytes32 roundChangeMessage(
|
|
final long chainId, final long blockNumber, final int targetRound) {
|
|
return roundChangePreimage(chainId, blockNumber, targetRound, false, 0, Bytes.EMPTY);
|
|
}
|
|
|
|
diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchorConfig.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchorConfig.java
|
|
index d04d528291..a4b75a40a1 100755
|
|
--- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchorConfig.java
|
|
+++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchorConfig.java
|
|
@@ -1,40 +1,41 @@
|
|
/*
|
|
* Copyright contributors to Besu / AERE Network.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
package org.hyperledger.besu.consensus.common.bft;
|
|
|
|
import java.util.Collections;
|
|
import java.util.Locale;
|
|
import java.util.Map;
|
|
import java.util.NavigableMap;
|
|
+import java.util.Optional;
|
|
import java.util.OptionalInt;
|
|
import java.util.TreeMap;
|
|
|
|
import com.google.common.base.Splitter;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
/**
|
|
* Height-indexed activation configuration for the V2 certificate anchor: {@code pqAnchorBlock} (H)
|
|
* and the staged {@code pqAnchorMinSeals} threshold schedule K(height), plus the two LOCAL emergency
|
|
* de-arm controls.
|
|
*
|
|
* <p><b>The gate is on the BLOCK NUMBER.</b> Below H no new rule applies at all: {@link
|
|
* #activeAt(long)} returns false and both new rules return true as their first statement, before
|
|
* they decode anything. The existing chain history is therefore untouched, with the same hashes,
|
|
* because neither the hash formula, nor the codec, nor the existing rule set changes for it. That
|
|
* property is cheap precisely because the gate is on the number and not on the content, and it is
|
|
* the condition under which a binary built from this code can be warmed on a live node without risk.
|
|
*
|
|
* <p><b>Emergency de-arm.</b> Two controls exist and are deliberately LOCAL to the node, not
|
|
@@ -212,40 +213,69 @@ public final class PqAnchorConfig {
|
|
* month per node; a scheduled interval lets the fleet move to 128 at a coordinated height.
|
|
*/
|
|
public static final String PROPERTY_ANCHOR_INTERVAL_SCHEDULE = "aere.pq.anchorIntervalSchedule";
|
|
|
|
/** Environment variable twin of {@link #PROPERTY_ANCHOR_INTERVAL_SCHEDULE}. */
|
|
public static final String ENV_ANCHOR_INTERVAL_SCHEDULE = "AERE_PQ_ANCHOR_INTERVAL_SCHEDULE";
|
|
|
|
/**
|
|
* AERE ANCHOR V2 (2026-09-03): from this height every anchor header carries the SCHEME-TAGGED
|
|
* certificate (PqAnchorV2: Falcon-512 plus every extra scheme the scheme schedule names at the
|
|
* parent height, K seals per scheme) and vanityData is the v2 digest under "AERE-PQ-ANCHOR-2".
|
|
* Below it nothing changes. A v2 certificate is refused below this height and a v1 one from it,
|
|
* so the switch is a consensus fork: every node of the fleet must carry the same value, exactly
|
|
* like {@link #PROPERTY_ANCHOR_BLOCK}. Absent means never. Env: {@code AERE_PQ_ANCHOR_V2_BLOCK}.
|
|
*/
|
|
public static final String PROPERTY_ANCHOR_V2_BLOCK = "aere.pq.anchorV2Block";
|
|
|
|
/** Environment variable twin of {@link #PROPERTY_ANCHOR_V2_BLOCK}. */
|
|
public static final String ENV_ANCHOR_V2_BLOCK = "AERE_PQ_ANCHOR_V2_BLOCK";
|
|
|
|
+ /**
|
|
+ * AERE 1(b) (D-470, 2026-10-01): H_r, the height from which the post-quantum commit seal is bound to
|
|
+ * its ROUND. The commit seal of block n signs M_r = keccak256(RLP["AERE-PQ-COMMIT-2", chainId, n, r,
|
|
+ * hash]) iff {@code n + 1 >= H_r} (the convention of the anchor form, so the parent of the first v3
|
|
+ * anchor already carries round-bound seals), and every anchor a >= H_r carries the v3 certificate
|
|
+ * (one round, {@link PqAnchorV3}). Below it nothing changes, byte for byte. A consensus fork:
|
|
+ * every node that judges headers must carry the same value. Absent means never. H_r must be an
|
|
+ * anchor height above {@link #PROPERTY_ANCHOR_V2_BLOCK}; anything else is refused at startup with
|
|
+ * {@link #REFUSAL_ROUND_01}. Env: {@code AERE_PQ_COMMIT_ROUND_BLOCK}.
|
|
+ */
|
|
+ public static final String PROPERTY_COMMIT_ROUND_BLOCK = "aere.pq.commitRoundBlock";
|
|
+
|
|
+ /** Environment variable twin of {@link #PROPERTY_COMMIT_ROUND_BLOCK}. */
|
|
+ public static final String ENV_COMMIT_ROUND_BLOCK = "AERE_PQ_COMMIT_ROUND_BLOCK";
|
|
+
|
|
+ /**
|
|
+ * The startup refusal for an H_r that cannot work (1(b), section 2.3): not a positive whole number,
|
|
+ * no armed anchor, not above the v2 height, or not an anchor height. Same code in both clients.
|
|
+ */
|
|
+ public static final String REFUSAL_ROUND_01 = "AERE-PQC-ROUND-01";
|
|
+
|
|
+ /**
|
|
+ * 1(b) refusal code (section 2.3): with H_r set, the chain id the post-quantum messages carry
|
|
+ * ({@code aere.pq.chainId}) differs from the genesis chain id. COMMIT-2 binds the chain id, so a node
|
|
+ * that signs another chain's id would be refused by every honest neighbour from H_r - 1 and look
|
|
+ * healthy until then; refused at startup instead (D-334). Same code in both clients.
|
|
+ */
|
|
+ public static final String REFUSAL_ROUND_03 = "AERE-PQC-ROUND-03";
|
|
+
|
|
/** Environment variable twin of {@link #PROPERTY_ANCHOR_BLOCK}. */
|
|
public static final String ENV_ANCHOR_BLOCK = "AERE_PQ_ANCHOR_BLOCK";
|
|
|
|
/** Environment variable twin of {@link #PROPERTY_MIN_SEALS}. */
|
|
public static final String ENV_MIN_SEALS = "AERE_PQ_ANCHOR_MINSEALS";
|
|
|
|
/** Environment variable twin of {@link #PROPERTY_CHAIN_ID}. */
|
|
public static final String ENV_CHAIN_ID = "AERE_PQ_CHAINID";
|
|
|
|
/** Environment variable twin of {@link #PROPERTY_MIN_SEALS_CEILING}. */
|
|
public static final String ENV_MIN_SEALS_CEILING = "AERE_PQ_ANCHOR_MIN_SEALS_MAX";
|
|
|
|
/** Environment variable twin of {@link #PROPERTY_DISABLE}. */
|
|
public static final String ENV_DISABLE = "AERE_PQ_ANCHOR_DISABLE";
|
|
|
|
/**
|
|
* The stable, greppable code carried by every startup refusal raised while reading this
|
|
* configuration, in the shape of the A8 registry refusal {@code AERE-PQC-REG-MISMATCH-01}.
|
|
*/
|
|
public static final String REFUSAL_CODE = "AERE-PQC-ANCHOR-CONF-01";
|
|
@@ -257,54 +287,56 @@ public final class PqAnchorConfig {
|
|
*/
|
|
public static final String REFUSAL_MIN_SEALS_FLOOR = REFUSAL_CODE + "/minSealsFloor";
|
|
|
|
/** Sentinel meaning "the anchor never activates". */
|
|
public static final long NEVER = Long.MAX_VALUE;
|
|
|
|
/**
|
|
* Every name this loader reads, property first and environment twin second. Presence of ANY of
|
|
* them is what switches the loader from "this node has no anchor configuration" to "this node has
|
|
* an anchor configuration and every field of it must be readable".
|
|
*/
|
|
private static final String[][] ANCHOR_NAMES = {
|
|
{PROPERTY_ANCHOR_BLOCK, ENV_ANCHOR_BLOCK},
|
|
{PROPERTY_MIN_SEALS, ENV_MIN_SEALS},
|
|
{PROPERTY_CHAIN_ID, ENV_CHAIN_ID},
|
|
{PROPERTY_MIN_SEALS_CEILING, ENV_MIN_SEALS_CEILING},
|
|
{PROPERTY_MAX_SEALS, ENV_MAX_SEALS},
|
|
{PROPERTY_ANCHOR_INTERVAL, ENV_ANCHOR_INTERVAL},
|
|
{PROPERTY_ANCHOR_INTERVAL_SCHEDULE, ENV_ANCHOR_INTERVAL_SCHEDULE},
|
|
{PROPERTY_ANCHOR_V2_BLOCK, ENV_ANCHOR_V2_BLOCK},
|
|
+ {PROPERTY_COMMIT_ROUND_BLOCK, ENV_COMMIT_ROUND_BLOCK},
|
|
{PROPERTY_DISABLE, ENV_DISABLE}
|
|
};
|
|
|
|
private static final String SOURCE_PROPERTY = "system property (BESU_OPTS)";
|
|
|
|
private final long chainId;
|
|
private final long anchorBlock;
|
|
private final NavigableMap<Long, Integer> minSealsSchedule;
|
|
private final OptionalInt minSealsCeiling;
|
|
private final boolean disabled;
|
|
private final OptionalInt maxSealsCarried;
|
|
private final OptionalInt anchorInterval;
|
|
private final long anchorV2Block;
|
|
private final NavigableMap<Long, Integer> anchorIntervalSchedule;
|
|
+ private final long commitRoundBlock;
|
|
|
|
/**
|
|
* Build an explicit configuration.
|
|
*
|
|
* @param chainId the chain id used in the D and M pre-images
|
|
* @param anchorBlock the activation height H, or {@link #NEVER}; must be at least 1 when set,
|
|
* because block H needs a parent
|
|
* @param minSealsSchedule the staged threshold, keyed on the height each step takes effect at; may
|
|
* be empty, in which case K is 0 everywhere
|
|
* @param minSealsCeiling an emergency upper bound on K, or empty
|
|
* @param disabled true to switch the anchor rules off entirely
|
|
*/
|
|
public PqAnchorConfig(
|
|
final long chainId,
|
|
final long anchorBlock,
|
|
final Map<Long, Integer> minSealsSchedule,
|
|
final OptionalInt minSealsCeiling,
|
|
final boolean disabled) {
|
|
this(chainId, anchorBlock, minSealsSchedule, minSealsCeiling, disabled, OptionalInt.empty());
|
|
}
|
|
@@ -351,63 +383,67 @@ public final class PqAnchorConfig {
|
|
this(chainId, anchorBlock, minSealsSchedule, minSealsCeiling, disabled, maxSealsCarried,
|
|
anchorInterval, NEVER);
|
|
}
|
|
|
|
/**
|
|
* Full constructor.
|
|
*
|
|
* @param anchorV2Block the height from which anchor headers carry the scheme-tagged v2
|
|
* certificate and the v2 digest, or {@link #NEVER}
|
|
*/
|
|
public PqAnchorConfig(
|
|
final long chainId,
|
|
final long anchorBlock,
|
|
final Map<Long, Integer> minSealsSchedule,
|
|
final OptionalInt minSealsCeiling,
|
|
final boolean disabled,
|
|
final OptionalInt maxSealsCarried,
|
|
final OptionalInt anchorInterval,
|
|
final long anchorV2Block) {
|
|
this(chainId, anchorBlock, minSealsSchedule, minSealsCeiling, disabled, maxSealsCarried,
|
|
- anchorInterval, anchorV2Block, new TreeMap<>());
|
|
+ anchorInterval, anchorV2Block, new TreeMap<>(), NEVER);
|
|
}
|
|
|
|
/**
|
|
* Full constructor with the interval schedule (D-336).
|
|
*
|
|
* @param anchorIntervalSchedule heights from which the interval changes; every interval must be a
|
|
* positive multiple of the base interval and every height must sit on the NEW grid counted
|
|
* from H, so that the anchors of the new regime are a subset of the old ones and the change
|
|
* never invents an anchor height the old regime did not have
|
|
+ * @param commitRoundBlock H_r of 1(b), or {@link #NEVER}; a PRIVATE-constructor field, so the
|
|
+ * compiler lists every copy method that must carry it
|
|
*/
|
|
private PqAnchorConfig(
|
|
final long chainId,
|
|
final long anchorBlock,
|
|
final Map<Long, Integer> minSealsSchedule,
|
|
final OptionalInt minSealsCeiling,
|
|
final boolean disabled,
|
|
final OptionalInt maxSealsCarried,
|
|
final OptionalInt anchorInterval,
|
|
final long anchorV2Block,
|
|
- final NavigableMap<Long, Integer> anchorIntervalSchedule) {
|
|
+ final NavigableMap<Long, Integer> anchorIntervalSchedule,
|
|
+ final long commitRoundBlock) {
|
|
this.anchorInterval = anchorInterval;
|
|
this.anchorV2Block = anchorV2Block;
|
|
+ this.commitRoundBlock = commitRoundBlock;
|
|
this.anchorIntervalSchedule = new TreeMap<>(anchorIntervalSchedule);
|
|
if (!this.anchorIntervalSchedule.isEmpty()) {
|
|
if (anchorInterval.isEmpty()) {
|
|
throw new IllegalArgumentException(
|
|
"AERE PQ ANCHOR: " + PROPERTY_ANCHOR_INTERVAL_SCHEDULE + " is set but "
|
|
+ PROPERTY_ANCHOR_INTERVAL + " is not: a schedule changes an interval, it cannot"
|
|
+ " create one");
|
|
}
|
|
if (anchorBlock == NEVER) {
|
|
throw new IllegalArgumentException(
|
|
"AERE PQ ANCHOR: " + PROPERTY_ANCHOR_INTERVAL_SCHEDULE
|
|
+ " is set but no anchor activation height is");
|
|
}
|
|
final int base = anchorInterval.getAsInt();
|
|
for (final Map.Entry<Long, Integer> e : this.anchorIntervalSchedule.entrySet()) {
|
|
final long h = e.getKey();
|
|
final int iv = e.getValue();
|
|
if (iv < 1 || iv % base != 0) {
|
|
throw new IllegalArgumentException(
|
|
"AERE PQ ANCHOR: " + PROPERTY_ANCHOR_INTERVAL_SCHEDULE + " names interval " + iv
|
|
@@ -476,53 +512,123 @@ public final class PqAnchorConfig {
|
|
}
|
|
if (anchorBlock != NEVER && at < anchorBlock) {
|
|
throw new IllegalArgumentException(
|
|
"AERE PQ ANCHOR: pqAnchorMinSeals step at "
|
|
+ at
|
|
+ " is below pqAnchorBlock "
|
|
+ anchorBlock
|
|
+ "; a threshold cannot take effect before the rules do");
|
|
}
|
|
schedule.put(at, k);
|
|
}
|
|
if (minSealsCeiling.isPresent() && minSealsCeiling.getAsInt() < 0) {
|
|
throw new IllegalArgumentException(
|
|
"AERE PQ ANCHOR: emergency min-seals ceiling must not be negative");
|
|
}
|
|
this.chainId = chainId;
|
|
this.anchorBlock = anchorBlock;
|
|
this.minSealsSchedule = Collections.unmodifiableNavigableMap(schedule);
|
|
this.minSealsCeiling = minSealsCeiling;
|
|
this.disabled = disabled;
|
|
+ requireUsableCommitRoundBlock();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * AERE-PQC-ROUND-01 (1(b), section 2.3), at the end of construction, when every field it reads is
|
|
+ * set: an H_r that is not a positive whole number, sits on a node with no armed anchor, is not above
|
|
+ * the v2 height, or is not an anchor height is refused. A refusal at STARTUP, never at the first use
|
|
+ * (D-334): a wrong H_r found at the first anchor would stop the chain on every node that carries it.
|
|
+ *
|
|
+ * <p>The emergency brake never reaches this: a braked node is built without H_r (see {@link
|
|
+ * #fromSystemConfiguration()}), so the brake cannot be refused by it, and a braked node signs the
|
|
+ * ECDSA-digest form anyway.
|
|
+ */
|
|
+ private void requireUsableCommitRoundBlock() {
|
|
+ if (commitRoundBlock == NEVER) {
|
|
+ return;
|
|
+ }
|
|
+ final String head =
|
|
+ REFUSAL_ROUND_01 + ": " + PROPERTY_COMMIT_ROUND_BLOCK + "=" + commitRoundBlock;
|
|
+ if (commitRoundBlock < 1) {
|
|
+ throw new IllegalArgumentException(head + " is not a positive height.");
|
|
+ }
|
|
+ if (anchorBlock == NEVER || disabled) {
|
|
+ throw new IllegalArgumentException(
|
|
+ head
|
|
+ + " is set on a node whose anchor is "
|
|
+ + (anchorBlock == NEVER ? "not configured" : "disarmed")
|
|
+ + ": the round-bound commit seal is a form of the anchor's commit seal and cannot exist"
|
|
+ + " where the anchor does not.");
|
|
+ }
|
|
+ if (anchorV2Block == NEVER || commitRoundBlock <= anchorV2Block) {
|
|
+ throw new IllegalArgumentException(
|
|
+ head
|
|
+ + " is not above "
|
|
+ + PROPERTY_ANCHOR_V2_BLOCK
|
|
+ + "="
|
|
+ + (anchorV2Block == NEVER ? "NEVER" : anchorV2Block)
|
|
+ + ": the v3 certificate replaces the scheme-tagged v2 one and has to come after it.");
|
|
+ }
|
|
+ if (!anchorAppliesAt(commitRoundBlock)) {
|
|
+ throw new IllegalArgumentException(
|
|
+ head
|
|
+ + " is not an anchor height (interval "
|
|
+ + intervalAt(commitRoundBlock)
|
|
+ + " from H="
|
|
+ + anchorBlock
|
|
+ + "): the first v3 certificate must be carried by the anchor AT H_r, so every node can"
|
|
+ + " check the boundary by hand.");
|
|
+ }
|
|
}
|
|
|
|
/**
|
|
* The configuration that behaves exactly like today: the anchor never activates, so both new rules
|
|
* are inert at every height.
|
|
*
|
|
* @param chainId the chain id (unused while inactive, carried for diagnostics)
|
|
* @return an inactive configuration
|
|
*/
|
|
public static PqAnchorConfig never(final long chainId) {
|
|
return new PqAnchorConfig(chainId, NEVER, Collections.emptyMap(), OptionalInt.empty(), false);
|
|
}
|
|
|
|
+ /**
|
|
+ * The configuration of a node whose emergency brake is in force but whose rest cannot be read: every
|
|
+ * rule inert, exactly like {@link #never(long)}, AND the brake flag carried ({@link #disabled()} is
|
|
+ * true), so that a reader asking "is the brake in force on this node" gets the truth.
|
|
+ *
|
|
+ * <p>1(b) step 11, 2026-10-10 (review of consensus M1). Until this date the reader returned {@code
|
|
+ * never(0)} here, which says "not braked"; to keep the brake absolute on such a node, the ROUND-02
|
|
+ * exception ({@code PqFinalityLayersGuard.roundGapClosedByEcdsaForm}) had been widened to "no anchor
|
|
+ * at all", and that let a node whose anchor names were LOST from its options start with H_fin armed
|
|
+ * (the second client refuses it). With the flag carried the exception is the brake only, in both
|
|
+ * clients. Side effect, and the reason the log line of this branch is now true: R1's "a v3 certificate
|
|
+ * only at a v3 height" check is inert here too, as it already was on every braked node whose
|
|
+ * configuration reads cleanly ("every anchor rule is inert under the brake").
|
|
+ *
|
|
+ * @param chainId the chain id (unused while inactive, carried for diagnostics)
|
|
+ * @return an inactive, braked configuration
|
|
+ */
|
|
+ public static PqAnchorConfig brakedNever(final long chainId) {
|
|
+ return new PqAnchorConfig(chainId, NEVER, Collections.emptyMap(), OptionalInt.empty(), true);
|
|
+ }
|
|
+
|
|
// -----------------------------------------------------------------------------------------------
|
|
// Reading the names. ONE seam, used by both controls of the proof: a recording reader shows that
|
|
// the unconfigured path touches nothing, and a reader whose presence probe always answers "absent"
|
|
// is the negative control that makes every refusal below disappear.
|
|
// -----------------------------------------------------------------------------------------------
|
|
|
|
/** How this class reaches system properties and environment variables. */
|
|
interface NameReader {
|
|
|
|
/**
|
|
* The raw system property, or null when the name is not set.
|
|
*
|
|
* @param name the system property name
|
|
* @return the value as set, possibly empty, or null when absent
|
|
*/
|
|
String property(String name);
|
|
|
|
/**
|
|
* The raw environment variable, or null when the name is not set.
|
|
*
|
|
@@ -647,51 +753,57 @@ public final class PqAnchorConfig {
|
|
try {
|
|
final PqAnchorConfig braked = strict(block, seals, chain, ceiling, true);
|
|
if (braked.anchorConfigured()) {
|
|
LOG.warn(
|
|
"AERE PQ ANCHOR: DISABLED by emergency override {} even though {}={} is configured. "
|
|
+ "Both anchor rules are inert on this node.",
|
|
PROPERTY_DISABLE,
|
|
PROPERTY_ANCHOR_BLOCK,
|
|
braked.anchorBlock);
|
|
}
|
|
return braked;
|
|
} catch (final RuntimeException e) {
|
|
LOG.error(
|
|
"AERE PQ ANCHOR: the emergency disarm {} is in force, so this node STARTS, but the rest "
|
|
+ "of the anchor configuration cannot be read and is therefore NOT carried: {}. The "
|
|
+ "node runs fully inert and the per-block disarm announcement is LOST, because "
|
|
+ "there is no readable activation height to announce. Fix the configuration before "
|
|
+ "removing the disarm.",
|
|
PROPERTY_DISABLE,
|
|
e.getMessage());
|
|
- return never(0L);
|
|
+ // 1(b) step 11 (2026-10-10): braked, not just "never": the brake flag is carried (see brakedNever)
|
|
+ return brakedNever(0L);
|
|
}
|
|
}
|
|
|
|
final PqAnchorConfig bare = strict(block, seals, chain, ceiling, false);
|
|
final PqAnchorConfig config =
|
|
bare.withMaxSealsCarried(readMaxSeals())
|
|
.withAnchorInterval(readAnchorInterval())
|
|
.withAnchorIntervalSchedule(readAnchorIntervalSchedule())
|
|
- .withAnchorV2Block(readAnchorV2Block());
|
|
+ .withAnchorV2Block(readAnchorV2Block())
|
|
+ // 1(b): LAST, so every field ROUND-01 reads is already in place when it is judged
|
|
+ .withCommitRoundBlock(readCommitRoundBlock());
|
|
requireMinSealsFloorOrRefuse(config);
|
|
+ // HISTORY (1(b) step 3, 2026-10-01): the step-3 build refused H_r here at startup (AERE-R1B-APPLYV3-PAS4), because
|
|
+ // it could not yet produce a v3 certificate. Step 4 brings the producer (PqAnchorProducer.applyV3) and removes the
|
|
+ // refusal together with the stub, in the same change.
|
|
if (config.anchorInterval().isPresent() && config.everActive()) {
|
|
final int iv = config.anchorInterval().getAsInt();
|
|
LOG.warn(
|
|
"AERE PQ ANCHOR: certificate carried every {} block(s) from H={}, not every block. The "
|
|
+ "hash chain makes each anchor protect everything BELOW it, so what stays rewritable "
|
|
+ "by an adversary holding every classical validator key is the TAIL since the last "
|
|
+ "anchor: fork depth <= {} blocks. This is a DELIBERATE weakening bought for disk: "
|
|
+ "at K=3 capped it is about {} GB per node per year instead of about 120.",
|
|
iv,
|
|
config.anchorBlock,
|
|
iv,
|
|
String.format("%.1f", 120.5 / iv));
|
|
}
|
|
if (!config.anchorIntervalSchedule().isEmpty() && config.everActive()) {
|
|
LOG.warn(
|
|
"AERE PQ ANCHOR: interval SCHEDULE in force - {} (height:interval). From each height the"
|
|
+ " certificate is carried every that-many blocks; the anchors of every later regime are"
|
|
+ " a subset of the earlier ones (D-336, disk).",
|
|
config.anchorIntervalSchedule());
|
|
}
|
|
@@ -927,40 +1039,66 @@ public final class PqAnchorConfig {
|
|
if (!v2.hasValue()) {
|
|
return NEVER;
|
|
}
|
|
try {
|
|
return Long.parseLong(v2.raw().trim());
|
|
} catch (final NumberFormatException e) {
|
|
throw new IllegalArgumentException(
|
|
REFUSAL_CODE
|
|
+ ": "
|
|
+ PROPERTY_ANCHOR_V2_BLOCK
|
|
+ " is set to '"
|
|
+ v2.raw()
|
|
+ "' from "
|
|
+ v2.source()
|
|
+ ", which is not a whole number. It is NOT ignored: this height decides which form of"
|
|
+ " the anchor certificate is valid, and a node guessing it differently from its peers"
|
|
+ " parts from the chain at the first anchor.");
|
|
}
|
|
}
|
|
|
|
+ /**
|
|
+ * Read H_r (1(b)). Absent means never; an unreadable value is a refusal with {@link
|
|
+ * #REFUSAL_ROUND_01}, for the reason {@link #readAnchorV2Block()} gives: this height decides which
|
|
+ * commit message is signed and which certificate is valid.
|
|
+ */
|
|
+ private static long readCommitRoundBlock() {
|
|
+ final Read hr = read(PROPERTY_COMMIT_ROUND_BLOCK, ENV_COMMIT_ROUND_BLOCK);
|
|
+ if (!hr.hasValue()) {
|
|
+ return NEVER;
|
|
+ }
|
|
+ try {
|
|
+ return Long.parseLong(hr.raw().trim());
|
|
+ } catch (final NumberFormatException e) {
|
|
+ throw new IllegalArgumentException(
|
|
+ REFUSAL_ROUND_01
|
|
+ + ": "
|
|
+ + PROPERTY_COMMIT_ROUND_BLOCK
|
|
+ + " is set to '"
|
|
+ + hr.raw()
|
|
+ + "' from "
|
|
+ + hr.source()
|
|
+ + ", which is not a whole number. It is NOT ignored: a node guessing H_r differently"
|
|
+ + " from its peers signs the other commit message and loses its votes.");
|
|
+ }
|
|
+ }
|
|
+
|
|
private static NavigableMap<Long, Integer> readAnchorIntervalSchedule() {
|
|
final Read sc = read(PROPERTY_ANCHOR_INTERVAL_SCHEDULE, ENV_ANCHOR_INTERVAL_SCHEDULE);
|
|
final NavigableMap<Long, Integer> out = new TreeMap<>();
|
|
if (!sc.hasValue()) {
|
|
return out;
|
|
}
|
|
for (final String part : Splitter.on(',').split(sc.raw())) {
|
|
final String p = part.trim();
|
|
if (p.isEmpty()) {
|
|
continue;
|
|
}
|
|
final int colon = p.indexOf(':');
|
|
try {
|
|
if (colon < 1) {
|
|
throw new NumberFormatException(p);
|
|
}
|
|
out.put(Long.parseLong(p.substring(0, colon).trim()), Integer.parseInt(p.substring(colon + 1).trim()));
|
|
} catch (final NumberFormatException e) {
|
|
throw new IllegalArgumentException(
|
|
REFUSAL_CODE
|
|
@@ -1345,43 +1483,46 @@ public final class PqAnchorConfig {
|
|
if (cap.isPresent()) {
|
|
final int highest = highestEffectiveMinSeals();
|
|
if (cap.getAsInt() < highest) {
|
|
throw new IllegalArgumentException(
|
|
REFUSAL_CODE
|
|
+ ": "
|
|
+ PROPERTY_MAX_SEALS
|
|
+ "="
|
|
+ cap.getAsInt()
|
|
+ " is below the highest threshold this schedule ever demands, K="
|
|
+ highest
|
|
+ ". A proposer capped below K writes certificates its own fleet rejects, and every "
|
|
+ "existing check stays GREEN while it happens, because each one measures what was "
|
|
+ "asked. Raise the cap to at least "
|
|
+ highest
|
|
+ ", or lower the schedule.");
|
|
}
|
|
}
|
|
// CAREFUL: the interval is carried across too. A copy method that drops a field along the way
|
|
// is exactly how a disarm or an interval would vanish silently when the other control is set.
|
|
+ // CORRECTED 2026-10-01 (1(b)): this copy went through the public 8-argument constructor and so
|
|
+ // DROPPED the interval schedule (D-336) and would have dropped H_r; harmless only because
|
|
+ // fromSystemConfiguration calls it first. It now carries every field, like the other copies.
|
|
return new PqAnchorConfig(
|
|
chainId, anchorBlock, minSealsSchedule, minSealsCeiling, disabled, cap, anchorInterval,
|
|
- anchorV2Block);
|
|
+ anchorV2Block, anchorIntervalSchedule, commitRoundBlock);
|
|
}
|
|
|
|
/**
|
|
* How often a certificate is carried, counted from H. Empty means every block, which is the
|
|
* strongest setting and today's design.
|
|
*
|
|
* @return the anchor interval
|
|
*/
|
|
public OptionalInt anchorInterval() {
|
|
return anchorInterval;
|
|
}
|
|
|
|
/**
|
|
* The interval in force at a height: the base interval, or the last scheduled change at or below
|
|
* the height (D-336).
|
|
*
|
|
* @param blockNumber the height
|
|
* @return the interval in force there; 1 when no interval is configured
|
|
*/
|
|
public int intervalAt(final long blockNumber) {
|
|
@@ -1394,41 +1535,41 @@ public final class PqAnchorConfig {
|
|
|
|
/**
|
|
* The interval schedule (D-336), possibly empty.
|
|
*
|
|
* @return an unmodifiable view, height to interval
|
|
*/
|
|
public NavigableMap<Long, Integer> anchorIntervalSchedule() {
|
|
return java.util.Collections.unmodifiableNavigableMap(anchorIntervalSchedule);
|
|
}
|
|
|
|
/**
|
|
* Return a copy carrying an interval schedule (D-336). Refused unless every entry keeps the new
|
|
* anchors a subset of the old ones; see the private constructor.
|
|
*
|
|
* @param schedule heights to intervals
|
|
* @return a copy of this configuration carrying the schedule
|
|
*/
|
|
public PqAnchorConfig withAnchorIntervalSchedule(final Map<Long, Integer> schedule) {
|
|
return new PqAnchorConfig(
|
|
chainId, anchorBlock, minSealsSchedule, minSealsCeiling, disabled, maxSealsCarried,
|
|
- anchorInterval, anchorV2Block, new TreeMap<>(schedule));
|
|
+ anchorInterval, anchorV2Block, new TreeMap<>(schedule), commitRoundBlock);
|
|
}
|
|
|
|
/**
|
|
* Is this a height at which a certificate is carried and demanded?
|
|
*
|
|
* <p>Counted FROM H, so H itself is always an anchor height. That matters because H is the single
|
|
* height the whole fleet coordinates on, and a scheme whose first anchor lands somewhere else
|
|
* would be a scheme nobody can check by hand on activation day.
|
|
*
|
|
* @param blockNumber the height to test
|
|
* @return true if a certificate belongs in this block
|
|
*/
|
|
public boolean isAnchorHeight(final long blockNumber) {
|
|
if (anchorInterval.isEmpty()) {
|
|
return true;
|
|
}
|
|
if (anchorBlock == NEVER || blockNumber < anchorBlock) {
|
|
return false;
|
|
}
|
|
return (blockNumber - anchorBlock) % intervalAt(blockNumber) == 0;
|
|
@@ -1443,80 +1584,185 @@ public final class PqAnchorConfig {
|
|
* is deliberate: two rules asking the same question two different ways is exactly how R1 and R2
|
|
* would drift apart, and a header accepted by one and refused by the other is a chain split.
|
|
*
|
|
* @param blockNumber the height to test
|
|
* @return true if the anchor rules judge this header
|
|
*/
|
|
public boolean anchorAppliesAt(final long blockNumber) {
|
|
return activeAt(blockNumber) && isAnchorHeight(blockNumber);
|
|
}
|
|
|
|
/**
|
|
* The v2 activation height, or {@link #NEVER}.
|
|
*
|
|
* @return the height from which anchor headers carry the scheme-tagged certificate
|
|
*/
|
|
public long anchorV2Block() {
|
|
return anchorV2Block;
|
|
}
|
|
|
|
/**
|
|
- * Whether the header at this height must carry the SCHEME-TAGGED (v2) certificate and the v2
|
|
- * digest. True only at an anchor height ({@link #anchorAppliesAt}) at or above the v2 activation
|
|
- * height. The producer and both rules ask THIS question, not one that resembles it.
|
|
+ * Whether the header at this height must carry a SCHEME-TAGGED certificate: v2 or, from H_r, v3
|
|
+ * (1(b)). True only at an anchor height ({@link #anchorAppliesAt}) at or above the v2 activation
|
|
+ * height. Since 2026-10-01 it is only a delegation to {@link #certificateFormAt}: the producer and
|
|
+ * both rules decide WHICH form with that method, never with this one.
|
|
*
|
|
* @param blockNumber the height
|
|
- * @return true when the v2 form is the only accepted form at this height
|
|
+ * @return true when the scheme-tagged form (v2 or v3) is the only accepted family at this height
|
|
*/
|
|
public boolean anchorV2AppliesAt(final long blockNumber) {
|
|
- return anchorV2Block != NEVER && blockNumber >= anchorV2Block && anchorAppliesAt(blockNumber);
|
|
+ final CertificateForm f = certificateFormAt(blockNumber);
|
|
+ return f == CertificateForm.V2 || f == CertificateForm.V3;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The certificate form a header at this height must carry (1(b), section 2.1). The ONE place R1,
|
|
+ * R2, the producer, decidedBy, AIP-21 and the probes ask.
|
|
+ */
|
|
+ public enum CertificateForm {
|
|
+ /** Not an anchor height, or the anchor is not active here: no certificate is judged. */
|
|
+ NONE,
|
|
+ /** The legacy Falcon list RLP[[index, signature], ...] under "AERE-PQ-ANCHOR-1". */
|
|
+ V1,
|
|
+ /** The scheme-tagged certificate RLP[2, [[scheme, index, signature], ...]], no round. */
|
|
+ V2,
|
|
+ /** RLP[3, r, [[scheme, index, signature], ...]]: every seal over M_r of the SAME round r. */
|
|
+ V3
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Which certificate a header at this height carries: {@code NONE} off the anchor grid or where the
|
|
+ * anchor is not active; {@code V3} at or above H_r; {@code V2} at or above the v2 height; {@code V1}
|
|
+ * otherwise.
|
|
+ *
|
|
+ * @param blockNumber the anchor height a
|
|
+ * @return the form; never null
|
|
+ */
|
|
+ public CertificateForm certificateFormAt(final long blockNumber) {
|
|
+ if (!anchorAppliesAt(blockNumber)) {
|
|
+ return CertificateForm.NONE;
|
|
+ }
|
|
+ if (commitRoundBlock != NEVER && blockNumber >= commitRoundBlock) {
|
|
+ return CertificateForm.V3;
|
|
+ }
|
|
+ if (anchorV2Block != NEVER && blockNumber >= anchorV2Block) {
|
|
+ return CertificateForm.V2;
|
|
+ }
|
|
+ return CertificateForm.V1;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * H_r, or {@link #NEVER}.
|
|
+ *
|
|
+ * @return the height from which the commit seal binds its round (1(b))
|
|
+ */
|
|
+ public long commitRoundBlock() {
|
|
+ return commitRoundBlock;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * AERE-PQC-ROUND-03 (1(b), section 2.3): the refusal when H_r is set on an armed anchor and the
|
|
+ * configured {@code aere.pq.chainId} differs from the genesis chain id. Inert when H_r is unset or the
|
|
+ * anchor is not armed, so a node without H_r behaves as before (L1).
|
|
+ *
|
|
+ * @param genesisChainId the chain id of the genesis this node runs
|
|
+ * @return the refusal text, or empty
|
|
+ */
|
|
+ public Optional<String> roundChainIdRefusal(final long genesisChainId) {
|
|
+ if (commitRoundBlock == NEVER || !everActive()) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ if (chainId == genesisChainId) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ return Optional.of(
|
|
+ REFUSAL_ROUND_03
|
|
+ + ": aere.pq.commitRoundBlock="
|
|
+ + commitRoundBlock
|
|
+ + " is set, and aere.pq.chainId="
|
|
+ + chainId
|
|
+ + " differs from the genesis chain id "
|
|
+ + genesisChainId
|
|
+ + ": from H_r - 1 every commit seal binds the chain id, so this node would sign seals no honest"
|
|
+ + " neighbour accepts. Set aere.pq.chainId to the genesis chain id.");
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Whether the post-quantum commit seal of block n is ROUND-BOUND (COMMIT-2): the anchor form is in
|
|
+ * force for n ({@code n + 1 >= anchorBlock}, the convention of {@code
|
|
+ * PqAnchorProducer.sealMessageIsAnchorForm}) and {@code n + 1 >= H_r}. Because ROUND-01 keeps H_r
|
|
+ * above the anchor height, the second condition implies the first; both are written so the
|
|
+ * predicate reads the same as section 2.1 of the project. Decision H3: the parent of the first v3
|
|
+ * anchor (n = H_r - 1) already carries round-bound seals.
|
|
+ *
|
|
+ * @param blockNumber the number n of the block being sealed
|
|
+ * @return true when the commit seal of n signs M_r
|
|
+ */
|
|
+ public boolean roundBoundAt(final long blockNumber) {
|
|
+ return everActive()
|
|
+ && blockNumber + 1 >= anchorBlock
|
|
+ && commitRoundBlock != NEVER
|
|
+ && blockNumber + 1 >= commitRoundBlock;
|
|
}
|
|
|
|
/**
|
|
* Copy with a v2 activation height.
|
|
*
|
|
* @param v2Block the height, or {@link #NEVER}
|
|
* @return a configuration identical to this one except for the v2 height
|
|
*/
|
|
public PqAnchorConfig withAnchorV2Block(final long v2Block) {
|
|
return new PqAnchorConfig(
|
|
chainId, anchorBlock, minSealsSchedule, minSealsCeiling, disabled, maxSealsCarried,
|
|
- anchorInterval, v2Block, anchorIntervalSchedule);
|
|
+ anchorInterval, v2Block, anchorIntervalSchedule, commitRoundBlock);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Copy with H_r (1(b)). Refused with {@link #REFUSAL_ROUND_01} unless H_r is an anchor height above
|
|
+ * the v2 height on an armed anchor.
|
|
+ *
|
|
+ * @param hr the height, or {@link #NEVER}
|
|
+ * @return a configuration identical to this one except for H_r
|
|
+ */
|
|
+ public PqAnchorConfig withCommitRoundBlock(final long hr) {
|
|
+ return new PqAnchorConfig(
|
|
+ chainId, anchorBlock, minSealsSchedule, minSealsCeiling, disabled, maxSealsCarried,
|
|
+ anchorInterval, anchorV2Block, anchorIntervalSchedule, hr);
|
|
}
|
|
|
|
/**
|
|
* Return a copy carrying an anchor interval.
|
|
*
|
|
* <p>THE SECURITY PROPERTY, stated so it can be argued with: block hashes chain, so an anchor at
|
|
* height A protects everything below A, because rewriting anything under A changes A's parent hash
|
|
* and forces A to be reproduced, which needs a Falcon quorum. What an adversary holding every
|
|
* classical validator key can still rewrite is the TAIL since the last anchor. Therefore
|
|
* {@code fork depth <= interval}. At ~523 ms a block, an interval of 100 is about 52 seconds of
|
|
* rewritable tail, against about half a second at interval 1, and it costs a hundredth of the disk.
|
|
*
|
|
* @param interval the interval, or empty for every block
|
|
* @return a copy of this configuration carrying the interval
|
|
*/
|
|
public PqAnchorConfig withAnchorInterval(final OptionalInt interval) {
|
|
return new PqAnchorConfig(
|
|
chainId, anchorBlock, minSealsSchedule, minSealsCeiling, disabled, maxSealsCarried, interval,
|
|
- anchorV2Block, anchorIntervalSchedule);
|
|
+ anchorV2Block, anchorIntervalSchedule, commitRoundBlock);
|
|
}
|
|
|
|
/**
|
|
* Whether the anchor is configured at all, INDEPENDENTLY of whether it has been emergency
|
|
* disarmed.
|
|
*
|
|
* <p>{@link #everActive()} answers "will the rules ever fire", which is false both when nothing is
|
|
* configured and when a configured anchor has been disarmed. Telling those two states apart is the
|
|
* whole point of the per-block disarm announcement: a node that never had an anchor has nothing to
|
|
* shout about, and a node running disarmed over a configured anchor has to shout at every block.
|
|
*
|
|
* @return true iff an activation height is configured
|
|
*/
|
|
public boolean anchorConfigured() {
|
|
return anchorBlock != NEVER;
|
|
}
|
|
|
|
/**
|
|
* The activation height H.
|
|
*
|
|
@@ -1558,23 +1804,25 @@ public final class PqAnchorConfig {
|
|
* Whether the emergency disable override is in force.
|
|
*
|
|
* @return true iff the anchor rules are switched off on this node
|
|
*/
|
|
public boolean disabled() {
|
|
return disabled;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "PqAnchorConfig{chainId="
|
|
+ chainId
|
|
+ ", anchorBlock="
|
|
+ (anchorBlock == NEVER ? "NEVER" : anchorBlock)
|
|
+ ", minSeals="
|
|
+ minSealsSchedule
|
|
+ ", ceiling="
|
|
+ (minSealsCeiling.isPresent() ? minSealsCeiling.getAsInt() : "none")
|
|
+ ", disabled="
|
|
+ disabled
|
|
+ // 1(b): written only when set, so the line of a node without H_r is the line of today (L1)
|
|
+ + (commitRoundBlock == NEVER ? "" : ", commitRoundBlock=" + commitRoundBlock)
|
|
+ '}';
|
|
}
|
|
}
|
|
diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchorThresholdGuard.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchorThresholdGuard.java
|
|
index 963c64b23a..d6a136200f 100755
|
|
--- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchorThresholdGuard.java
|
|
+++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchorThresholdGuard.java
|
|
@@ -3,177 +3,203 @@
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
package org.hyperledger.besu.consensus.common.bft;
|
|
|
|
import java.util.Map;
|
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
/**
|
|
- * AERE GARDA-PRAG (2026-08-02). Refuse to start when the staged Falcon seal threshold K is set to a
|
|
- * value that STOPS THE CHAIN, instead of letting the node boot quietly and discover it one block
|
|
- * later.
|
|
+ * AERE GARDA-PRAG (2026-08-02; doctrine revised 2026-08-20, see THE BOUND below). Refuse to start when
|
|
+ * the staged Falcon seal threshold K is set to a value that STOPS THE ANCHORS, instead of letting the
|
|
+ * node boot quietly and discover it one block later.
|
|
*
|
|
* <p><b>The hole this closes, measured before it was written.</b> Searched across the whole fork
|
|
* tree, {@code grep -rn "minSeals" --include=*.java consensus app} filtered for any of {@code
|
|
* quorum}, {@code throw}, {@code refus}, {@code abort} or {@code Illegal}: ZERO matches. {@link
|
|
* PqAnchorConfig} refuses a NEGATIVE threshold and a step scheduled below the activation height, and
|
|
* nothing else. The only guard that looked at the threshold at all was {@code
|
|
* PqAnchorProducer.warnIfActivationHeightCanRefuse}, and it covers a different question (K at the
|
|
* activation height itself), reaches only {@code LOG.error}, and returns. A halting threshold was
|
|
* therefore a configuration a node accepted in silence.
|
|
*
|
|
- * <p><b>THE BOUND, AND WHERE THE ARITHMETIC COMES FROM.</b> The refusal is {@code K >= quorum(N)},
|
|
- * i.e. the highest value that may be configured is {@code quorum(N) - 1}.
|
|
+ * <p><b>THE BOUND (doctrine of 2026-08-20, after the late-seal salvage D-227), AND WHERE THE
|
|
+ * ARITHMETIC COMES FROM.</b> THRESHOLD-01 ({@value #CODE}) refuses a schedule in which any effective
|
|
+ * step is above {@code N - f}, with {@code f = floor((N-1)/3)} ({@link #byzantineBudget(int)}): the
|
|
+ * highest value that may be configured is {@link #maxConfigurableThreshold(int)} {@code = N - f}.
|
|
*
|
|
* <ul>
|
|
- * <li>{@code quorum(N)} is Besu's own {@link BftHelpers#calculateRequiredValidatorQuorum(int)},
|
|
- * {@code ceil(2N/3)}. At N=7 that is {@code ceil(14/3) = 5}, so the highest configurable
|
|
- * threshold on chain 2800 as it stands is <b>4</b>.
|
|
- * <li>{@code K = quorum} is a GUARANTEED HALT, and that is measured, not argued. A proposer
|
|
- * assembles its certificate out of the Falcon seals it heard on Commit messages, and the block
|
|
- * is IMPORTED at the quorum-th Commit; after the import {@code QbftController.consumeMessage}
|
|
- * discards every message that targets a height not above the chain head, so the Commits that
|
|
- * arrive afterwards never reach the seal cache. A proposer can therefore gather at most {@code
|
|
- * quorum} seals, at ANY N. Measured on an isolated N=4 network (quorum 3): {@code k = 3} on
|
|
- * EVERY header above the activation height, never 4, with all four nodes keyed and healthy.
|
|
- * Requiring K=quorum thus requires that ALL of the first {@code quorum} Commits carry a valid,
|
|
- * eligible Falcon seal: one validator without a key among them, or one seal that does not
|
|
- * verify, and no proposer can ever propose again.
|
|
- * <li><b>{@code K > N - f} is the WRONG bound and this guard deliberately does not use it.</b> At
|
|
- * N=7 the two agree by coincidence, because {@code N - f = 7 - 2 = 5} equals {@code quorum} and
|
|
- * both reject 5. They part company as soon as the set grows: at N=9, {@code quorum = 6} while
|
|
- * {@code N - f = 7}, so {@code K > N - f} would happily accept K=7, which is two rungs above
|
|
- * what a proposer can physically gather. Growing the validator set does not buy quorum margin;
|
|
- * that was measured too, and it is asserted in the test.
|
|
+ * <li>Why {@code N - f}. Since D-227 (2026-08-14) the Falcon seal of a Commit is taken BEFORE the
|
|
+ * height gate discards the message, so the seal cache keeps the seals of every ALIVE keyed
|
|
+ * validator, not only those of the first quorum Commits; measured on mainnet 2800 across 5,400
|
|
+ * anchor blocks (2026-08-18..20): 8 and 9 seals per certificate at N=9. With f validators
|
|
+ * Byzantine or down, the design's own fault budget, at most {@code N - f} seals can ever exist,
|
|
+ * so a K above {@code N - f} makes anchor blocks unreachable inside the tolerated fault model.
|
|
+ * That is a halt bought by configuration, and it is refused.
|
|
+ * <li>The arithmetic, with Besu's own quorum {@code Q = ceil(2N/3)} ({@link
|
|
+ * BftHelpers#calculateRequiredValidatorQuorum(int)}): at N=7, Q=5 and N-f=5; at N=9, Q=6 and
|
|
+ * N-f=7, so K=7 starts; at N=10, Q=7 and N-f=7. Which N a chain runs is read from the set at
|
|
+ * startup, never written here.
|
|
+ * <li>{@code K >= Q} is a LIVENESS TAX, not a halt: anchors wait for late seals. It gets a loud WARN
|
|
+ * and the node starts; it is the operator's explicit choice of a quorum-grade certificate.
|
|
+ * <li>From H_r (1(b), 2026-10-01) a certificate holds the seals of ONE round, so every effective
|
|
+ * step that applies at an anchor at or above H_r must also be at most Q: THRESHOLD-02
|
|
+ * ({@value #CODE_ROUND_BOUND}), a refusal; below Q there, ROUND-05, a warning; a proposer cap
|
|
+ * below Q, ROUND-06, a warning (the v3 producer carries {@code max(cap, Q)}).
|
|
* </ul>
|
|
*
|
|
* <p><b>What is a refusal and what is only a shout.</b> Above {@code quorum - f} the schedule is
|
|
* still reachable but has no margin against f silent or keyless signers, which is the measured A10
|
|
* and A13 exposure. That is a deliberate operator choice with a real cost, so it gets a loud WARN and
|
|
- * the node starts. At or above {@code quorum} the schedule is not reachable at all, so it gets a
|
|
- * refusal. A guard that refused both would take the emergency ladder away; a guard that shouted for
|
|
- * both would be the log line this class exists to replace.
|
|
+ * the node starts; so does a schedule at or above the quorum (the liveness tax above). Above {@code
|
|
+ * N - f} the schedule is not reachable inside the fault model at all, so it gets a refusal. A guard
|
|
+ * that refused all of these would take the emergency ladder away; a guard that shouted for all of
|
|
+ * them would be the log line this class exists to replace.
|
|
+ *
|
|
+ * <p><b>HISTORY, until 2026-08-20 (kept dated, not rewritten; retired by D-227).</b> As written on
|
|
+ * 2026-08-02, before the late-seal salvage, this guard refused at {@code K >= quorum(N)} and allowed
|
|
+ * at most {@code quorum(N) - 1}, which was 4 on chain 2800 at N=7 then. The mechanics of that date:
|
|
+ * the block was IMPORTED at the quorum-th Commit and {@code QbftController.consumeMessage} discarded
|
|
+ * every later message for a height not above the head, so a proposer could gather at most {@code
|
|
+ * quorum} seals at any N; measured on an isolated N=4 network (quorum 3): {@code k = 3} on every
|
|
+ * header above the activation height, never 4, with all four nodes keyed and healthy. Requiring
|
|
+ * K=quorum then required every one of the first quorum Commits to carry a valid, eligible Falcon
|
|
+ * seal. The text of that date also named {@code N - f} the wrong bound, because at N=9 it accepts
|
|
+ * K=7, two rungs above what a proposer could then gather. D-227 made the gathering continue past the
|
|
+ * quorum, and on 2026-08-20 the refusal moved to {@code N - f} (the threshold plan of 2026-08-19,
|
|
+ * section 7, test {@code
|
|
+ * atNineValidatorsTheQuorumIsReachableAndAboveNMinusFIsNot}). The loop, the refusal message and the
|
|
+ * doc of {@link #maxConfigurableThreshold(int)} were revised then; this class doc, the doc of {@link
|
|
+ * #verifyThresholdAgainstQuorumOrAbort} and the fail-closed message kept the old doctrine in the
|
|
+ * present tense until 2026-10-09 (1(b) step 11, consumatori/R9).
|
|
*
|
|
* <p><b>The verdict is computed from the SAME code path enforcement reads.</b> Every step is scored
|
|
* with {@link PqAnchorConfig#minSealsAt(long)}, the exact method the producer calls, not with a
|
|
* second reading of the raw schedule. That is why the emergency ceiling is honoured here for free: a
|
|
* ceiling that lowers a fatal schedule below the bound makes the node start, which is precisely what
|
|
* an operator needs at three in the morning, and a ceiling ABOVE the schedule rescues nothing,
|
|
* because the ceiling can only ever lower.
|
|
*
|
|
* <p><b>Fail closed on the unknown.</b> A validator-set size of zero or less aborts. "I could not
|
|
* count the validators" is not "the threshold is probably fine".
|
|
*
|
|
* <p><b>Inert when the anchor is not armed.</b> With no {@code aere.pq.anchorBlock}, or with the
|
|
- * anchor emergency-disarmed, this method returns before it computes anything, so a binary carrying it
|
|
- * behaves exactly as today on chain 2800, where the anchor is armed on no node.
|
|
+ * anchor emergency-disarmed, this method returns before it computes anything, so a node without the
|
|
+ * anchor starts exactly as one without this guard. (Corrected 2026-10-09: written on 2026-08-02, this
|
|
+ * paragraph added "on chain 2800, where the anchor is armed on no node", which was true that day; on
|
|
+ * 2800 the anchor is armed from block 13,014,000.)
|
|
*/
|
|
public final class PqAnchorThresholdGuard {
|
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(PqAnchorThresholdGuard.class);
|
|
|
|
/** The stable machine-readable code emitted when this guard refuses to start a node. */
|
|
public static final String CODE = "AERE-PQC-THRESHOLD-01";
|
|
|
|
private PqAnchorThresholdGuard() {}
|
|
|
|
/**
|
|
* The highest seal threshold that may be configured for a validator set of this size.
|
|
*
|
|
* <p>REVISED 2026-08-20, and the revision is a measurement, not an opinion. Until D-227
|
|
* (2026-08-14) a proposer could gather at most {@code quorum} seals: the block imported at the
|
|
* quorum-th Commit and {@code QbftController.consumeMessage} discarded every later Commit, so this
|
|
- * method returned {@code quorum - 1} and the class doc below carries that history. D-227 (the
|
|
+ * method returned {@code quorum - 1} and the class doc above carries that history (its HISTORY
|
|
+ * paragraph). D-227 (the
|
|
* late-seal salvage, {@code PqLateSealSalvageTest}) extracts the Falcon seal BEFORE the height
|
|
* gate discards the message, so the cache now accumulates seals from every ALIVE keyed validator.
|
|
* Measured on mainnet 2800 across 5,400 anchor blocks (2026-08-18..20): certificates carry 8 and 9
|
|
* seals at N=9, i.e. strictly more than quorum=6, which under the old mechanics was impossible.
|
|
*
|
|
* <p>The bound that remains fatal is availability under the tolerated fault budget: with f
|
|
* validators Byzantine or down, at most {@code N - f} seals can ever exist, so a threshold above
|
|
* {@code N - f} halts anchors inside the design's own fault model. At N=9 this is 7; at N=7 it is
|
|
* 5. A threshold at or above the quorum is now a LIVENESS TAX (anchors wait for late seals),
|
|
* shouted below, not a guaranteed halt.
|
|
*
|
|
* @param validatorCount the number of validators, at least 1
|
|
* @return the highest configurable threshold K, {@code N - f}
|
|
*/
|
|
public static int maxConfigurableThreshold(final int validatorCount) {
|
|
return validatorCount - byzantineBudget(validatorCount);
|
|
}
|
|
|
|
/**
|
|
* The number of faulty validators QBFT tolerates at this set size, {@code floor((N-1)/3)}.
|
|
*
|
|
* @param validatorCount the number of validators, at least 1
|
|
* @return f
|
|
*/
|
|
public static int byzantineBudget(final int validatorCount) {
|
|
return (validatorCount - 1) / 3;
|
|
}
|
|
|
|
/**
|
|
- * Refuse to start when any step of the staged threshold schedule is at or above the QBFT quorum.
|
|
+ * Refuse to start when any effective step of the staged threshold schedule is above {@code N - f}
|
|
+ * (THRESHOLD-01), or, from H_r, when a step that applies at an anchor at or above H_r is above the
|
|
+ * QBFT quorum (THRESHOLD-02). A schedule at or above the quorum below H_r starts with a loud WARN
|
|
+ * (the liveness tax of the class doc). Until 2026-10-09 this doc said the refusal was at the quorum,
|
|
+ * the doctrine retired on 2026-08-20 (class doc, HISTORY).
|
|
*
|
|
* <p>Call this exactly once during node startup, from a point where the validator set is already
|
|
* known and before the network and the consensus state machine are started, so that a refusal is a
|
|
* clean refusal to start rather than a mid-flight halt.
|
|
*
|
|
* @param anchorConfig the height-indexed certificate-anchor configuration; a null, never-active or
|
|
* disarmed configuration makes this method a no-op
|
|
* @param validatorCount the size of the validator set this node is starting into; zero or less
|
|
* aborts
|
|
* @throws FalconSealSupport.ActivationConfigException when the anchor is armed and any step of the
|
|
- * effective threshold schedule reaches the quorum, or when the validator set size is unknown
|
|
+ * effective threshold schedule is above {@code N - f}, or, from H_r, above the quorum, or when
|
|
+ * the validator set size is unknown
|
|
*/
|
|
public static void verifyThresholdAgainstQuorumOrAbort(
|
|
final PqAnchorConfig anchorConfig, final int validatorCount) {
|
|
|
|
if (anchorConfig == null || !anchorConfig.everActive()) {
|
|
LOG.debug(
|
|
"AERE PQ ANCHOR: threshold guard inert, the certificate anchor is not armed on this node.");
|
|
return;
|
|
}
|
|
|
|
if (validatorCount < 1) {
|
|
throw new FalconSealSupport.ActivationConfigException(
|
|
FalconSealSupport.ActivationConfigException.Kind.UNSAFE,
|
|
CODE,
|
|
"AERE PQ ANCHOR: REFUSING TO START (fail-closed). The V2 certificate anchor is armed at H="
|
|
+ anchorConfig.anchorBlock()
|
|
+ " but this node counted "
|
|
+ validatorCount
|
|
- + " validators, so the QBFT quorum cannot be computed and the configured seal "
|
|
- + "threshold cannot be checked against it. A threshold at or above the quorum stops "
|
|
- + "the chain, and a guard that treated an uncountable validator set as safe would be "
|
|
+ + " validators, so the QBFT quorum and N - f cannot be computed and the configured seal "
|
|
+ + "threshold cannot be checked against them. A threshold above N - f stops the "
|
|
+ + "anchors, and a guard that treated an uncountable validator set as safe would be "
|
|
+ "exactly the silence this guard exists to remove. WHAT TO DO: start this node "
|
|
+ "without aere.pq.anchorBlock to diagnose, or fix whatever prevented the validator "
|
|
+ "set from being read.");
|
|
}
|
|
|
|
final int quorum = BftHelpers.calculateRequiredValidatorQuorum(validatorCount);
|
|
final int maxConfigurable = maxConfigurableThreshold(validatorCount);
|
|
final int f = byzantineBudget(validatorCount);
|
|
final int noMarginAbove = quorum - f;
|
|
|
|
long fatalHeight = -1L;
|
|
int fatalThreshold = -1;
|
|
long highestAt = anchorConfig.anchorBlock();
|
|
int highest = anchorConfig.minSealsAt(anchorConfig.anchorBlock());
|
|
|
|
for (final Map.Entry<Long, Integer> step : anchorConfig.minSealsSchedule().entrySet()) {
|
|
final long at = step.getKey();
|
|
// Scored through minSealsAt, the SAME method the producer calls, so the emergency ceiling is
|
|
// applied here by exactly the code that will apply it in enforcement. A guard that re-derived
|
|
// the effective threshold from the raw schedule could drift away from what is in force.
|
|
@@ -212,40 +238,42 @@ public final class PqAnchorThresholdGuard {
|
|
+ fatalThreshold
|
|
+ " makes anchor blocks unreachable inside the tolerated fault model. That is a halt "
|
|
+ "bought by configuration, and it starts at height "
|
|
+ fatalHeight
|
|
+ ". WHAT TO DO: lower the step to at most "
|
|
+ maxConfigurable
|
|
+ " in aere.pq.anchorMinSeals, or, if the chain is already stopped, restart with "
|
|
+ "--Xaere-pq-anchor-min-seals-max="
|
|
+ maxConfigurable
|
|
+ " which lowers the effective threshold without editing the schedule, or with "
|
|
+ "--Xaere-pq-anchor-disarm to switch the anchor rules off on this node entirely. "
|
|
+ "Schedule as read: "
|
|
+ anchorConfig.minSealsSchedule()
|
|
+ ", emergency ceiling: "
|
|
+ (anchorConfig.minSealsCeiling().isPresent()
|
|
? Integer.toString(anchorConfig.minSealsCeiling().getAsInt())
|
|
: "none")
|
|
+ ".");
|
|
}
|
|
|
|
+ verifyRoundBoundThresholdsOrAbort(anchorConfig, validatorCount, quorum);
|
|
+
|
|
if (highest >= quorum) {
|
|
LOG.warn(
|
|
"AERE PQ ANCHOR: threshold guard PASSED at a QUORUM-OR-ABOVE threshold. K reaches {} at "
|
|
+ "height {}; quorum for {} validators is {} and N - f is {}. Reachability now rests "
|
|
+ "on the D-227 late-seal salvage (measured on mainnet: 8-9 seals per certificate), "
|
|
+ "and the margin under the fault budget is {}: with f={} validators down, anchors "
|
|
+ "wait until {} of the remaining {} carry valid seals. This is the operator's "
|
|
+ "explicit choice of a liveness tax for a quorum-grade certificate.",
|
|
highest,
|
|
highestAt,
|
|
validatorCount,
|
|
quorum,
|
|
validatorCount - f,
|
|
(validatorCount - f) - highest,
|
|
f,
|
|
highest,
|
|
validatorCount - f);
|
|
return;
|
|
}
|
|
|
|
@@ -262,21 +290,118 @@ public final class PqAnchorThresholdGuard {
|
|
quorum,
|
|
f,
|
|
noMarginAbove,
|
|
quorum,
|
|
quorum - highest);
|
|
return;
|
|
}
|
|
|
|
LOG.info(
|
|
"AERE PQ ANCHOR: threshold guard passed. K reaches {} at height {}; quorum for {} "
|
|
+ "validators is {}, highest configurable threshold is {}, margin against silent "
|
|
+ "signers is {} of a tolerated f={}.",
|
|
highest,
|
|
highestAt,
|
|
validatorCount,
|
|
quorum,
|
|
maxConfigurable,
|
|
noMarginAbove - highest,
|
|
f);
|
|
}
|
|
+
|
|
+ /** 1(b): K_eff above the quorum at an anchor a >= H_r. */
|
|
+ public static final String CODE_ROUND_BOUND = "AERE-PQC-THRESHOLD-02";
|
|
+
|
|
+ /** 1(b): K_eff below the quorum at an anchor a >= H_r (a warning, not a refusal). */
|
|
+ public static final String CODE_ROUND_05 = "AERE-PQC-ROUND-05";
|
|
+
|
|
+ /** 1(b): the proposer cap below the quorum (a warning; the producer carries max(maxSeals, Q)). */
|
|
+ public static final String CODE_ROUND_06 = "AERE-PQC-ROUND-06";
|
|
+
|
|
+ /**
|
|
+ * AERE 1(b) (2026-10-01): from H_r a certificate holds the seals of ONE round, so the arithmetic of
|
|
+ * "what a proposer can gather" is per round, not over all the seals heard. A round decided with
|
|
+ * exactly Q Commit messages gives exactly Q seals of that round; with K_eff above Q the anchor can stay
|
|
+ * unreachable although its parent was decided. So every effective step that applies to an anchor at
|
|
+ * or above H_r (the step in force AT H_r, and every step above it) must be at most Q(N) of the set
|
|
+ * this node starts into: THRESHOLD-02, a refusal at startup (D-334: never at first use). Below Q the
|
|
+ * anchors do not prove their parent decided (decidedBy needs Q of one round): ROUND-05, a warning.
|
|
+ * A proposer cap below Q would cut a deciding round short: ROUND-06, a warning (the producer carries
|
|
+ * max(maxSeals, Q) anyway). Like THRESHOLD-01 this judges the set at startup; a vote that later
|
|
+ * lowers N is held off by the voting tool and by the gate {@code pragul-k-cel-mult-cvorumul}.
|
|
+ */
|
|
+ private static void verifyRoundBoundThresholdsOrAbort(
|
|
+ final PqAnchorConfig anchorConfig, final int validatorCount, final int quorum) {
|
|
+ final long hr = anchorConfig.commitRoundBlock();
|
|
+ if (hr == PqAnchorConfig.NEVER) {
|
|
+ return;
|
|
+ }
|
|
+ // the steps that apply at a >= H_r: the one in force at H_r, and every one above it
|
|
+ final java.util.NavigableMap<Long, Integer> from = new java.util.TreeMap<>();
|
|
+ from.put(hr, anchorConfig.minSealsAt(hr));
|
|
+ for (final Map.Entry<Long, Integer> step :
|
|
+ anchorConfig.minSealsSchedule().tailMap(hr, false).entrySet()) {
|
|
+ from.put(step.getKey(), anchorConfig.minSealsAt(step.getKey()));
|
|
+ }
|
|
+ int lowest = Integer.MAX_VALUE;
|
|
+ long lowestAt = hr;
|
|
+ for (final Map.Entry<Long, Integer> step : from.entrySet()) {
|
|
+ final int effective = step.getValue();
|
|
+ if (effective > quorum) {
|
|
+ throw new FalconSealSupport.ActivationConfigException(
|
|
+ FalconSealSupport.ActivationConfigException.Kind.UNSAFE,
|
|
+ CODE_ROUND_BOUND,
|
|
+ "AERE PQ ANCHOR: REFUSING TO START (fail-closed). From H_r="
|
|
+ + hr
|
|
+ + " a certificate carries the seals of ONE round, and the effective threshold reaches "
|
|
+ + effective
|
|
+ + " at height "
|
|
+ + step.getKey()
|
|
+ + ", above the quorum "
|
|
+ + quorum
|
|
+ + " of the "
|
|
+ + validatorCount
|
|
+ + " validators this node starts into. A round decided with exactly "
|
|
+ + quorum
|
|
+ + " Commit messages gives "
|
|
+ + quorum
|
|
+ + " seals of that round, so such an anchor can stay unreachable over a decided parent."
|
|
+ + " WHAT TO DO: a step of at most "
|
|
+ + quorum
|
|
+ + " at or below H_r, or the emergency ceiling --Xaere-pq-anchor-min-seals-max="
|
|
+ + quorum
|
|
+ + ", put on every node.");
|
|
+ }
|
|
+ if (effective < lowest) {
|
|
+ lowest = effective;
|
|
+ lowestAt = step.getKey();
|
|
+ }
|
|
+ }
|
|
+ if (lowest < quorum) {
|
|
+ LOG.warn(
|
|
+ "{}: from H_r={} the effective threshold is {} at height {}, below the quorum {}: the anchors"
|
|
+ + " there are valid but do not prove their parent decided (decidedBy and B1 need {} seals"
|
|
+ + " of one round), so the decided head advances only where a certificate carries a quorum.",
|
|
+ CODE_ROUND_05,
|
|
+ hr,
|
|
+ lowest,
|
|
+ lowestAt,
|
|
+ quorum,
|
|
+ quorum);
|
|
+ }
|
|
+ if (anchorConfig.maxSealsCarried().isPresent()
|
|
+ && anchorConfig.maxSealsCarried().getAsInt() < quorum) {
|
|
+ // 1(b) step 11 (2026-10-09, besu-consens/R2): until this date the line ended by saying that this build's
|
|
+ // producer wrote no v3 certificate at all, true of the step-3 build only; step 4 (0f58e00c, 2026-10-02)
|
|
+ // brought PqAnchorProducer.applyV3, which carries cap' = max(maxSeals, Q). The second client's ROUND-06
|
|
+ // line says the same (AereCommitRoundConfig: "the producer carries max(cap, Q)").
|
|
+ LOG.warn(
|
|
+ "{}: the proposer cap {} is below the quorum {}; from H_r={} the v3 producer carries"
|
|
+ + " max(cap, quorum) = {} seals of one round, never fewer than the quorum (1(b) section 3.1 C).",
|
|
+ CODE_ROUND_06,
|
|
+ anchorConfig.maxSealsCarried().getAsInt(),
|
|
+ quorum,
|
|
+ hr,
|
|
+ quorum);
|
|
+ }
|
|
+ }
|
|
}
|
|
diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchorV3.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchorV3.java
|
|
new file mode 100644
|
|
index 0000000000..d19345e487
|
|
--- /dev/null
|
|
+++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchorV3.java
|
|
@@ -0,0 +1,747 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+/*
|
|
+ * AERE 1(b), D-470 (2026-10-01): the v3 anchor certificate, ONE ROUND per certificate.
|
|
+ *
|
|
+ * WHY A THIRD FORMAT. Up to v2 every post-quantum commit seal signed M = keccak256(RLP["AERE-PQ-COMMIT-1",
|
|
+ * chainId, n, hash]), WITHOUT the round, so a certificate could add up seals given in different rounds:
|
|
+ * a "quorum" that no single round ever reached, and, under an adversary that breaks ECDSA (A_q), a seal
|
|
+ * given honestly in round 0 could be pasted under a forged commit of round 4. From H_r the commit seal
|
|
+ * signs M_r = keccak256(RLP["AERE-PQ-COMMIT-2", chainId, n, r, hash]) and the certificate names the ONE
|
|
+ * round r its seals were given in:
|
|
+ *
|
|
+ * C3 = RLP[ 3, r, [ [scheme, index, signature], ... ] ]
|
|
+ * D3 = keccak256( RLP[ "AERE-PQ-ANCHOR-3", chainId, a-1, hash(a-1), BYTES(C3) ] )
|
|
+ *
|
|
+ * WHY r SITS BEFORE THE LIST. Old readers must fail LOUDLY on a v3: the v2 decoder of this binary says
|
|
+ * "unknown certificate version 3", the second client's v2 decoder demands exactly two elements, and the
|
|
+ * old gateway finds a scalar where it expects the list. With r after the list an old reader would count
|
|
+ * the seals without seeing the round, in silence.
|
|
+ *
|
|
+ * CANONICAL, like v2: rows strictly increasing by (index, scheme), at most 64, no empty signature, a
|
|
+ * known scheme; r a minimal scalar 0..1024 (0 is 0x80); the empty row list only with r = 0 (and it is
|
|
+ * VALID only where K_eff = 0, decision H5 of the project, judged by R2, not here); and the decoder
|
|
+ * demands that the re-encoding equals the bytes it was given. A certificate with two encodings would
|
|
+ * have two digests.
|
|
+ *
|
|
+ * THE CODES (section 1.4 of PROIECT-1B-RUNDA-IN-SIGILIU-2026-10-01.md) are the same strings in both
|
|
+ * clients, the public verifier and the shared vectors, which compare the CODE, never the text. The
|
|
+ * judging functions below are pure functions of their arguments: R1, R2, the producer's self-check and
|
|
+ * decidedBy call them, so the five cannot judge the same certificate in five ways.
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.common.bft;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.crypto.Hash;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput;
|
|
+import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
|
|
+import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
|
+
|
|
+import java.nio.charset.StandardCharsets;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collection;
|
|
+import java.util.HashMap;
|
|
+import java.util.HashSet;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Objects;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+import java.util.Set;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+
|
|
+/** Encoder, decoder, digest and judge of the v3 (one-round) anchor certificate. */
|
|
+public final class PqAnchorV3 {
|
|
+
|
|
+ /** The version scalar that opens every v3 certificate. */
|
|
+ public static final int VERSION = 3;
|
|
+
|
|
+ /** Domain of the v3 anchor digest. A NEW string: v1, v2 and v3 digests can never collide. */
|
|
+ public static final String ANCHOR_DOMAIN_V3 = "AERE-PQ-ANCHOR-3";
|
|
+
|
|
+ /** The domain bytes written into every v3 digest preimage. */
|
|
+ public static final Bytes ANCHOR_DOMAIN_V3_BYTES =
|
|
+ Bytes.wrap(ANCHOR_DOMAIN_V3.getBytes(StandardCharsets.US_ASCII));
|
|
+
|
|
+ /**
|
|
+ * The highest round a round-bound commit seal or a v3 certificate may name (decision H2). The same
|
|
+ * constant as the stage-5 header rule and the public verifier, and a superset of the round cap of
|
|
+ * D-434, so an honest round is never refused for its number.
|
|
+ */
|
|
+ public static final int MAX_ROUND = 1024;
|
|
+
|
|
+ /** Hard cap on the rows of one certificate, as in v2. */
|
|
+ public static final int MAX_SEALS = 64;
|
|
+
|
|
+ /** A v3 certificate at an anchor below H_r. */
|
|
+ public static final String V3_01 = "AERE-PQ-V3-01";
|
|
+
|
|
+ /** At an anchor at or above H_r the header carries no v3 certificate (v1, v2 or none). */
|
|
+ public static final String V3_02 = "AERE-PQ-V3-02";
|
|
+
|
|
+ /** Shape or encoding: element count, r, empty list with r != 0, order, duplicate, scheme, cap, round trip. */
|
|
+ public static final String V3_03 = "AERE-PQ-V3-03";
|
|
+
|
|
+ /** vanityData is not D3 of the carried certificate. */
|
|
+ public static final String V3_04 = "AERE-PQ-V3-04";
|
|
+
|
|
+ /** Below the threshold: Falcon seals under K_eff, empty with K_eff > 0, a required scheme under K_eff. */
|
|
+ public static final String V3_05 = "AERE-PQ-V3-05";
|
|
+
|
|
+ /** Binding: parent set unresolvable, index unbound, bound to a non-member, two indices one member, no key. */
|
|
+ public static final String V3_06 = "AERE-PQ-V3-06";
|
|
+
|
|
+ /** A seal (Falcon or extra) does not verify over M_r(a-1) with the certificate's r. */
|
|
+ public static final String V3_07 = "AERE-PQ-V3-07";
|
|
+
|
|
+ /** An extra seal without a Falcon seal of the same index here, or of a scheme not named at a-1. */
|
|
+ public static final String V3_08 = "AERE-PQ-V3-08";
|
|
+
|
|
+ /** The PQ seal of a Commit does not verify over M_r of the round of the message. */
|
|
+ public static final String COMMIT_R_01 = "AERE-PQ-COMMIT-R-01";
|
|
+
|
|
+ /** (second client) the Commit's round is not the round being counted. */
|
|
+ public static final String COMMIT_R_02 = "AERE-PQ-COMMIT-R-02";
|
|
+
|
|
+ /** A round outside 0..{@link #MAX_ROUND} where the commit seal is round-bound: no message exists. */
|
|
+ public static final String COMMIT_R_03 = "AERE-PQ-COMMIT-R-03";
|
|
+
|
|
+ private PqAnchorV3() {}
|
|
+
|
|
+ /**
|
|
+ * A v3 certificate: one round and its rows.
|
|
+ *
|
|
+ * <p>Shape is judged by {@link #encode} and {@link #decode}, not here (a compact constructor that
|
|
+ * copied the list would reassign a parameter, which this build's errorprone refuses).
|
|
+ *
|
|
+ * @param round the round r every seal was given in, 0..{@link #MAX_ROUND}
|
|
+ * @param seals the rows, canonical order
|
|
+ */
|
|
+ public record Certificate(int round, List<SchemeSeal> seals) {}
|
|
+
|
|
+ /**
|
|
+ * A verdict with its code. {@link #accepted()} when the code is null.
|
|
+ *
|
|
+ * @param code the refusal code of section 1.4, or null when accepted
|
|
+ * @param reason a human sentence, for the log; never compared by a probe
|
|
+ * @param falconMembers on acceptance by {@link #judgeSeals}: the distinct members of the parent's set
|
|
+ * whose Falcon seal verified (what decidedBy compares with Q); 0 otherwise
|
|
+ */
|
|
+ public record Verdict(String code, String reason, int falconMembers) {
|
|
+ /**
|
|
+ * Accepted, with the number of verified distinct Falcon members.
|
|
+ *
|
|
+ * @param members the verified distinct Falcon members (0 where nothing was counted)
|
|
+ * @return the verdict
|
|
+ */
|
|
+ public static Verdict ok(final int members) {
|
|
+ return new Verdict(null, "accepted", members);
|
|
+ }
|
|
+
|
|
+ /** Refused with a code. */
|
|
+ public static Verdict refused(final String code, final String reason) {
|
|
+ return new Verdict(Objects.requireNonNull(code, "code"), reason, 0);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Whether the certificate was accepted.
|
|
+ *
|
|
+ * @return true when there is no refusal code
|
|
+ */
|
|
+ public boolean accepted() {
|
|
+ return code == null;
|
|
+ }
|
|
+
|
|
+ /** "CODE: reason", the form every WARN line carries. */
|
|
+ public String describe() {
|
|
+ return accepted() ? "accepted" : code + ": " + reason;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * What R2 needs from the world to judge the seals, at the PARENT's height (the height the seals
|
|
+ * commit to). An interface so the judge stays a pure function and the producer, R2 and decidedBy
|
|
+ * hand it the same doors: the historic registry door (D2), never the node's own head.
|
|
+ */
|
|
+ public interface Signers {
|
|
+ /**
|
|
+ * The validator set of the parent, read from the parent (votes inside the parent included).
|
|
+ *
|
|
+ * @return the set, or null or empty when it cannot be resolved
|
|
+ */
|
|
+ Collection<Address> parentSet();
|
|
+
|
|
+ /**
|
|
+ * The member the registry binds this index to at the parent height.
|
|
+ *
|
|
+ * @param index the registry index
|
|
+ * @return the member, or null when the index is bound to nobody at that height
|
|
+ */
|
|
+ Address memberAt(int index);
|
|
+
|
|
+ /**
|
|
+ * Falcon-512 verification with the key in force at the parent height.
|
|
+ *
|
|
+ * @param index the registry index
|
|
+ * @param message M_r(a-1)
|
|
+ * @param signature the seal
|
|
+ * @return true when it verifies
|
|
+ */
|
|
+ boolean verifyFalcon(int index, Bytes32 message, Bytes signature);
|
|
+
|
|
+ /**
|
|
+ * The registry form of the public key of an extra scheme for this index at the parent height.
|
|
+ *
|
|
+ * @param index the registry index
|
|
+ * @param scheme the scheme
|
|
+ * @return the key, or empty when none is held
|
|
+ */
|
|
+ Optional<byte[]> extraKey(int index, SealScheme scheme);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * THE doors R2 judges a v3 certificate with (D2, the HISTORY door at the parent's height): the registry's
|
|
+ * historic binding and verification at a-1, and for the extra schemes the v3 epoch key from H_k or the hybrid
|
|
+ * registry before it. One factory, used by R2 ({@code PqAnchorSealsRule}), by the producer's self-check and by
|
|
+ * decidedBy (1(b), review of step 4, 2026-10-01): a self-check on other doors than R2's could pass a certificate
|
|
+ * R2 then refuses at an epoch boundary.
|
|
+ *
|
|
+ * @param registry the Falcon registry
|
|
+ * @param parentNumber a-1
|
|
+ * @param parentSet the validator set that decides the parent
|
|
+ * @return the doors
|
|
+ */
|
|
+ public static Signers historicSigners(
|
|
+ final PqSignerRegistry registry,
|
|
+ final long parentNumber,
|
|
+ final java.util.function.Supplier<Collection<Address>> parentSet) {
|
|
+ return new Signers() {
|
|
+ @Override
|
|
+ public Collection<Address> parentSet() {
|
|
+ return parentSet.get();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Address memberAt(final int index) {
|
|
+ return registry.addressForIndexAtHistoric(parentNumber, index);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyFalcon(final int index, final Bytes32 message, final Bytes signature) {
|
|
+ return registry.verifyAtHistoric(parentNumber, index, message, signature);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Optional<byte[]> extraKey(final int index, final SealScheme scheme) {
|
|
+ // AIP-22 stage 3b: from H_k the keys come from the v3 epoch in force at the parent
|
|
+ if (AerePqIdentity.keysFromV3(parentNumber)) {
|
|
+ return AerePqIdentity.v3KeyAt(parentNumber, index, scheme.id());
|
|
+ }
|
|
+ return HybridSealSupport.instance().registry().flatMap(r -> r.publicKey(index, scheme.id()));
|
|
+ }
|
|
+ };
|
|
+ }
|
|
+
|
|
+ // ----------------------------------------------------------------------------------------------
|
|
+ // Encoding
|
|
+ // ----------------------------------------------------------------------------------------------
|
|
+
|
|
+ /**
|
|
+ * Encode a v3 certificate. The input must already be canonical; anything else throws with {@link
|
|
+ * #V3_03}: an encoder that repaired its input would let two byte strings claim one certificate.
|
|
+ *
|
|
+ * @param certificate the certificate
|
|
+ * @return the canonical bytes of C3
|
|
+ */
|
|
+ public static Bytes encode(final Certificate certificate) {
|
|
+ requireCanonical(certificate.round(), certificate.seals());
|
|
+ final BytesValueRLPOutput out = new BytesValueRLPOutput();
|
|
+ out.startList();
|
|
+ out.writeIntScalar(VERSION);
|
|
+ out.writeIntScalar(certificate.round());
|
|
+ out.writeList(
|
|
+ certificate.seals(),
|
|
+ (seal, rlp) -> {
|
|
+ rlp.startList();
|
|
+ rlp.writeIntScalar(seal.getSchemeWireId() & 0xff);
|
|
+ rlp.writeIntScalar(seal.getValidatorIndex());
|
|
+ rlp.writeBytes(seal.getSignature());
|
|
+ rlp.endList();
|
|
+ });
|
|
+ out.endList();
|
|
+ return out.encoded();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Decode a v3 certificate. Throws IllegalArgumentException whose message starts with {@link
|
|
+ * #V3_03} on anything that is not exactly a canonical v3 certificate: another version, another
|
|
+ * element count, a round that is a list, carries a leading zero, has more than two bytes or exceeds
|
|
+ * {@link #MAX_ROUND}, a non-canonical row list, trailing bytes, or a re-encoding that differs.
|
|
+ *
|
|
+ * @param encoded the bytes of element 6 of the header
|
|
+ * @return the certificate
|
|
+ */
|
|
+ public static Certificate decode(final Bytes encoded) {
|
|
+ if (encoded == null || encoded.isEmpty()) {
|
|
+ throw shape("empty certificate bytes");
|
|
+ }
|
|
+ final Certificate decoded;
|
|
+ try {
|
|
+ final RLPInput in = new BytesValueRLPInput(encoded, false);
|
|
+ in.enterList();
|
|
+ if (in.isEndOfCurrentList() || in.nextIsList()) {
|
|
+ throw shape("the first element is not the version scalar");
|
|
+ }
|
|
+ final int version = in.readIntScalar();
|
|
+ if (version != VERSION) {
|
|
+ throw shape("version " + version + ", not " + VERSION);
|
|
+ }
|
|
+ if (in.isEndOfCurrentList()) {
|
|
+ throw shape("two elements: the round is missing");
|
|
+ }
|
|
+ if (in.nextIsList()) {
|
|
+ throw shape("the round is a list");
|
|
+ }
|
|
+ // EXPLICIT, not left to the RLP library (section 1.3): at most two bytes, no leading zero (round
|
|
+ // 0 is the empty string 0x80, never 0x00), at most MAX_ROUND. The round trip below would catch a
|
|
+ // non-minimal form too; this names it.
|
|
+ final Bytes roundBytes = in.readBytes();
|
|
+ if (roundBytes.size() > 2) {
|
|
+ throw shape("the round is " + roundBytes.size() + " bytes long");
|
|
+ }
|
|
+ if (!roundBytes.isEmpty() && roundBytes.get(0) == 0) {
|
|
+ throw shape("the round carries a leading zero byte");
|
|
+ }
|
|
+ final int round = roundBytes.isEmpty() ? 0 : roundBytes.toUnsignedBigInteger().intValueExact();
|
|
+ if (round > MAX_ROUND) {
|
|
+ throw shape("round " + round + " is above " + MAX_ROUND);
|
|
+ }
|
|
+ if (in.isEndOfCurrentList() || !in.nextIsList()) {
|
|
+ throw shape("the third element is not the list of rows");
|
|
+ }
|
|
+ final List<SchemeSeal> seals = new ArrayList<>();
|
|
+ in.enterList();
|
|
+ while (!in.isEndOfCurrentList()) {
|
|
+ if (seals.size() >= MAX_SEALS) {
|
|
+ throw shape("more than " + MAX_SEALS + " rows");
|
|
+ }
|
|
+ if (!in.nextIsList()) {
|
|
+ throw shape("a row is not a list");
|
|
+ }
|
|
+ in.enterList();
|
|
+ final int scheme = in.readIntScalar();
|
|
+ final int index = in.readIntScalar();
|
|
+ final Bytes signature = in.readBytes();
|
|
+ in.leaveList();
|
|
+ if (scheme < 0 || scheme > 0xff) {
|
|
+ throw shape("scheme tag out of byte range: " + scheme);
|
|
+ }
|
|
+ seals.add(new SchemeSeal((byte) scheme, index, signature));
|
|
+ }
|
|
+ in.leaveList();
|
|
+ in.leaveList();
|
|
+ if (!in.isDone()) {
|
|
+ throw shape("bytes follow the certificate");
|
|
+ }
|
|
+ decoded = new Certificate(round, List.copyOf(seals));
|
|
+ } catch (final IllegalArgumentException e) {
|
|
+ throw e.getMessage() != null && e.getMessage().startsWith(V3_03) ? e : shape(e.getMessage());
|
|
+ } catch (final RuntimeException e) {
|
|
+ throw shape(e.getClass().getSimpleName() + ": " + e.getMessage());
|
|
+ }
|
|
+ requireCanonical(decoded.round(), decoded.seals());
|
|
+ if (!encode(decoded).equals(encoded)) {
|
|
+ throw shape("the re-encoding differs from the bytes carried (non-canonical RLP)");
|
|
+ }
|
|
+ return decoded;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * D3, the v3 anchor digest: keccak256(RLP["AERE-PQ-ANCHOR-3", chainId, a-1, hash(a-1), BYTES(C3)]).
|
|
+ *
|
|
+ * @param chainId the chain id
|
|
+ * @param parentNumber a-1
|
|
+ * @param parentHash hash(a-1), 32 bytes
|
|
+ * @param certificate the certificate (must be canonical; refused with {@link #V3_03} otherwise)
|
|
+ * @return D3
|
|
+ */
|
|
+ public static Bytes32 anchorDigestV3(
|
|
+ final long chainId,
|
|
+ final long parentNumber,
|
|
+ final Bytes parentHash,
|
|
+ final Certificate certificate) {
|
|
+ if (parentNumber < 0) {
|
|
+ throw new IllegalArgumentException("AERE PQ V3: parentNumber must not be negative");
|
|
+ }
|
|
+ if (parentHash == null || parentHash.size() != 32) {
|
|
+ throw new IllegalArgumentException("AERE PQ V3: parentHash must be 32 bytes");
|
|
+ }
|
|
+ final BytesValueRLPOutput out = new BytesValueRLPOutput();
|
|
+ out.startList();
|
|
+ out.writeBytes(ANCHOR_DOMAIN_V3_BYTES);
|
|
+ out.writeLongScalar(chainId);
|
|
+ out.writeLongScalar(parentNumber);
|
|
+ out.writeBytes(parentHash);
|
|
+ out.writeBytes(encode(certificate));
|
|
+ out.endList();
|
|
+ return Hash.keccak256(out.encoded());
|
|
+ }
|
|
+
|
|
+ // ----------------------------------------------------------------------------------------------
|
|
+ // Judging (section 1.4). Fixed order; the first failure returns its code.
|
|
+ // ----------------------------------------------------------------------------------------------
|
|
+
|
|
+ /**
|
|
+ * R1 for the v3 era: the form by height (01, 02), the shape (03) and D3 (04). Below H_r a header
|
|
+ * without a v3 certificate is ACCEPTED here and the caller continues with its v1 or v2 judgement; a
|
|
+ * height that is not judged ({@link PqAnchorConfig.CertificateForm#NONE}) is accepted unjudged.
|
|
+ *
|
|
+ * @param form the form the configuration demands at a ({@link PqAnchorConfig#certificateFormAt})
|
|
+ * @param certificateRound the round the header's certificate names (empty: v1, v2 or none)
|
|
+ * @param rows the header's scheme-tagged rows
|
|
+ * @param vanity the header's vanityData
|
|
+ * @param chainId the chain id
|
|
+ * @param anchorNumber a
|
|
+ * @param parentHash the hash the header names as its parent
|
|
+ * @return the verdict
|
|
+ */
|
|
+ public static Verdict judgeForm(
|
|
+ final PqAnchorConfig.CertificateForm form,
|
|
+ final OptionalInt certificateRound,
|
|
+ final List<SchemeSeal> rows,
|
|
+ final Bytes vanity,
|
|
+ final long chainId,
|
|
+ final long anchorNumber,
|
|
+ final Bytes parentHash) {
|
|
+ if (form == PqAnchorConfig.CertificateForm.NONE) {
|
|
+ return Verdict.ok(0);
|
|
+ }
|
|
+ if (form != PqAnchorConfig.CertificateForm.V3) {
|
|
+ return certificateRound.isPresent()
|
|
+ ? Verdict.refused(
|
|
+ V3_01,
|
|
+ "block " + anchorNumber + " carries a v3 certificate below H_r (the form here is " + form
|
|
+ + ")")
|
|
+ : Verdict.ok(0);
|
|
+ }
|
|
+ if (certificateRound.isEmpty()) {
|
|
+ return Verdict.refused(
|
|
+ V3_02,
|
|
+ "block " + anchorNumber + " is at or above H_r and carries no v3 certificate ("
|
|
+ + (rows.isEmpty() ? "v1 or none" : "v2") + ")");
|
|
+ }
|
|
+ final Certificate certificate = new Certificate(certificateRound.getAsInt(), rows);
|
|
+ final Bytes32 expected;
|
|
+ try {
|
|
+ expected = anchorDigestV3(chainId, anchorNumber - 1L, parentHash, certificate);
|
|
+ } catch (final IllegalArgumentException e) {
|
|
+ return Verdict.refused(V3_03, String.valueOf(e.getMessage()));
|
|
+ }
|
|
+ if (vanity == null || vanity.size() != 32 || !expected.equals(Bytes32.wrap(vanity))) {
|
|
+ return Verdict.refused(
|
|
+ V3_04,
|
|
+ "block " + anchorNumber + ": vanityData " + vanity + " is not D3 " + expected
|
|
+ + " of the carried certificate (round " + certificate.round() + ", "
|
|
+ + certificate.seals().size() + " row(s))");
|
|
+ }
|
|
+ return Verdict.ok(0);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * R2 for a v3 certificate: the count (05), then each Falcon row in canonical order (binding 06,
|
|
+ * signature 07), then each extra row (08, key 06, signature 07), then each required scheme (05).
|
|
+ * All or nothing: one bad seal refuses the certificate. The round r is NOT compared with element 3
|
|
+ * of the parent or of the anchor: it is bound by the message, and the decision is the parent's.
|
|
+ * Every seal is checked over M_r(a-1) taken from the one place ({@link
|
|
+ * PqAnchorProducer#anchorSealMessage}) with the certificate's r.
|
|
+ *
|
|
+ * @param cfg the configuration (chain id, and the form, which must be round-bound at a-1)
|
|
+ * @param anchorNumber a
|
|
+ * @param parentHash hash(a-1)
|
|
+ * @param certificate the certificate the header carries
|
|
+ * @param kEff K_eff(a): the scheduled K after the emergency ceiling
|
|
+ * @param namedExtraSchemes the non-Falcon schemes the schedule names at a-1
|
|
+ * @param requiredExtraSchemes the non-Falcon schemes this anchor height requires (each needs K_eff)
|
|
+ * @param signers the doors to the parent's set and keys
|
|
+ * @return the verdict; on acceptance, the number of verified distinct Falcon members
|
|
+ */
|
|
+ public static Verdict judgeSeals(
|
|
+ final PqAnchorConfig cfg,
|
|
+ final long anchorNumber,
|
|
+ final Bytes parentHash,
|
|
+ final Certificate certificate,
|
|
+ final int kEff,
|
|
+ final Set<String> namedExtraSchemes,
|
|
+ final Set<String> requiredExtraSchemes,
|
|
+ final Signers signers) {
|
|
+ final long parentNumber = anchorNumber - 1L;
|
|
+ // A precondition, not a seal check: this judge speaks only about a parent whose commit seals are ROUND-BOUND. Called
|
|
+ // anywhere else (a misuse), a ROUND_FREE parent would silently be judged over COMMIT-1; it is refused by name instead.
|
|
+ if (PqAnchorProducer.commitSealFormAt(cfg, parentNumber) != PqAnchorProducer.CommitSealForm.ROUND_BOUND) {
|
|
+ return Verdict.refused(
|
|
+ V3_01,
|
|
+ "block " + anchorNumber + ": the parent " + parentNumber
|
|
+ + " is not in the round-bound form, so no v3 certificate can be judged over it");
|
|
+ }
|
|
+ final List<SchemeSeal> falcon = new ArrayList<>();
|
|
+ final Set<Integer> falconIndices = new HashSet<>();
|
|
+ for (final SchemeSeal s : certificate.seals()) {
|
|
+ if (s.getSchemeWireId() == SealSchemes.FALCON_512.wireId()) {
|
|
+ falcon.add(s);
|
|
+ falconIndices.add(s.getValidatorIndex());
|
|
+ }
|
|
+ }
|
|
+ if (falcon.size() < kEff) {
|
|
+ return Verdict.refused(
|
|
+ V3_05,
|
|
+ "block " + anchorNumber + ": " + falcon.size() + " Falcon seal(s) of round "
|
|
+ + certificate.round() + ", below K=" + kEff);
|
|
+ }
|
|
+ if (certificate.seals().isEmpty()) {
|
|
+ // H5: the empty v3 is valid only where K_eff = 0 (the check above refused it otherwise). It
|
|
+ // proves nothing: decidedBy and B1 never advance on it, and consumers say "not proven".
|
|
+ return Verdict.ok(0);
|
|
+ }
|
|
+ final Optional<Bytes32> message =
|
|
+ PqAnchorProducer.anchorSealMessage(cfg, parentNumber, parentHash, certificate.round());
|
|
+ if (message.isEmpty()) {
|
|
+ return Verdict.refused(
|
|
+ V3_03,
|
|
+ "block " + anchorNumber + ": no round-bound message exists for parent " + parentNumber
|
|
+ + " and round " + certificate.round());
|
|
+ }
|
|
+ Set<Address> set = null;
|
|
+ final Set<Address> counted = new HashSet<>();
|
|
+ for (final SchemeSeal seal : falcon) {
|
|
+ if (set == null) {
|
|
+ // TOTAL (decision H11): what a door throws is a refusal with its code, never an exception out of this
|
|
+ // function, which the producer's self-check and decidedBy call outside any rule's catch
|
|
+ Collection<Address> resolved;
|
|
+ try {
|
|
+ resolved = signers.parentSet();
|
|
+ } catch (final RuntimeException e) {
|
|
+ resolved = null;
|
|
+ }
|
|
+ if (resolved == null || resolved.isEmpty()) {
|
|
+ return Verdict.refused(
|
|
+ V3_06,
|
|
+ "block " + anchorNumber + ": the validator set of the parent " + parentNumber
|
|
+ + " could not be resolved");
|
|
+ }
|
|
+ set = new HashSet<>(resolved);
|
|
+ }
|
|
+ final int index = seal.getValidatorIndex();
|
|
+ Address member;
|
|
+ try {
|
|
+ member = signers.memberAt(index);
|
|
+ } catch (final RuntimeException e) {
|
|
+ member = null;
|
|
+ }
|
|
+ if (member == null) {
|
|
+ return Verdict.refused(
|
|
+ V3_06, "block " + anchorNumber + ": index " + index + " is bound to nobody at " + parentNumber);
|
|
+ }
|
|
+ if (!set.contains(member)) {
|
|
+ return Verdict.refused(
|
|
+ V3_06,
|
|
+ "block " + anchorNumber + ": index " + index + " (" + member
|
|
+ + ") is not a validator of the parent " + parentNumber);
|
|
+ }
|
|
+ if (!counted.add(member)) {
|
|
+ return Verdict.refused(
|
|
+ V3_06,
|
|
+ "block " + anchorNumber + ": two indices, including " + index + ", resolve to the member "
|
|
+ + member);
|
|
+ }
|
|
+ if (!verifiesFalcon(signers, index, message.get(), seal.getSignature())) {
|
|
+ return Verdict.refused(
|
|
+ V3_07,
|
|
+ "block " + anchorNumber + ": the Falcon seal of index " + index
|
|
+ + " does not verify over M_r(" + parentNumber + ") for round " + certificate.round());
|
|
+ }
|
|
+ }
|
|
+ final Map<String, Integer> extrasCounted = new HashMap<>();
|
|
+ for (final SchemeSeal seal : certificate.seals()) {
|
|
+ if (seal.getSchemeWireId() == SealSchemes.FALCON_512.wireId()) {
|
|
+ continue;
|
|
+ }
|
|
+ final Optional<SealScheme> scheme = SealSchemes.byWireId(seal.getSchemeWireId());
|
|
+ if (scheme.isEmpty() || !namedExtraSchemes.contains(scheme.get().id())) {
|
|
+ return Verdict.refused(
|
|
+ V3_08,
|
|
+ "block " + anchorNumber + ": a seal of scheme 0x"
|
|
+ + Integer.toHexString(seal.getSchemeWireId() & 0xff)
|
|
+ + " that the schedule does not name at " + parentNumber);
|
|
+ }
|
|
+ if (!falconIndices.contains(seal.getValidatorIndex())) {
|
|
+ return Verdict.refused(
|
|
+ V3_08,
|
|
+ "block " + anchorNumber + ": a " + scheme.get().id() + " seal of index "
|
|
+ + seal.getValidatorIndex() + " without a Falcon seal of the same index here");
|
|
+ }
|
|
+ Optional<byte[]> key;
|
|
+ try {
|
|
+ key = signers.extraKey(seal.getValidatorIndex(), scheme.get());
|
|
+ } catch (final RuntimeException e) {
|
|
+ key = Optional.empty();
|
|
+ }
|
|
+ if (key == null || key.isEmpty()) {
|
|
+ return Verdict.refused(
|
|
+ V3_06,
|
|
+ "block " + anchorNumber + ": no " + scheme.get().id() + " key for index "
|
|
+ + seal.getValidatorIndex() + " at " + parentNumber);
|
|
+ }
|
|
+ if (!verifiesExtra(scheme.get(), key.get(), message.get(), seal.getSignature())) {
|
|
+ return Verdict.refused(
|
|
+ V3_07,
|
|
+ "block " + anchorNumber + ": the " + scheme.get().id() + " seal of index "
|
|
+ + seal.getValidatorIndex() + " does not verify over M_r(" + parentNumber
|
|
+ + ") for round " + certificate.round());
|
|
+ }
|
|
+ extrasCounted.merge(scheme.get().id(), 1, Integer::sum);
|
|
+ }
|
|
+ for (final String schemeId : requiredExtraSchemes) {
|
|
+ if (SealSchemes.FALCON_512.id().equals(schemeId)) {
|
|
+ continue;
|
|
+ }
|
|
+ final int have = extrasCounted.getOrDefault(schemeId, 0);
|
|
+ if (have < kEff) {
|
|
+ return Verdict.refused(
|
|
+ V3_05,
|
|
+ "block " + anchorNumber + ": " + have + " valid " + schemeId + " seal(s), below K="
|
|
+ + kEff);
|
|
+ }
|
|
+ }
|
|
+ return Verdict.ok(counted.size());
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many DISTINCT members of the parent's set carry, in a v3 certificate, a Falcon-512 seal over
|
|
+ * M_r(a-1) of the certificate's round that verifies now through {@code signers} (1(b), section 3.1 B,
|
|
+ * marker AERE-R1B-PARINTE-Q). Unlike {@link #judgeSeals} it is a COUNT, not a verdict: a seal of an
|
|
+ * index bound to nobody, of a non-member, of a member already counted, or that does not verify, counts
|
|
+ * for nothing and refuses nothing (the header was judged at import; decidedBy re-verifies and counts,
|
|
+ * it never trusts the import). The same message ({@link PqAnchorProducer#anchorSealMessage}) and the
|
|
+ * same doors as R2. Total: 0 where the parent is not round-bound, the message does not exist, or a
|
|
+ * door throws.
|
|
+ *
|
|
+ * @param cfg the configuration
|
|
+ * @param parentNumber a-1
|
|
+ * @param parentHash hash(a-1)
|
|
+ * @param certificate the anchor's v3 certificate
|
|
+ * @param signers the doors to the parent's set and keys
|
|
+ * @return the number of verified distinct Falcon members of the round
|
|
+ */
|
|
+ public static int verifiedFalconMembers(
|
|
+ final PqAnchorConfig cfg,
|
|
+ final long parentNumber,
|
|
+ final Bytes parentHash,
|
|
+ final Certificate certificate,
|
|
+ final Signers signers) {
|
|
+ try {
|
|
+ if (PqAnchorProducer.commitSealFormAt(cfg, parentNumber)
|
|
+ != PqAnchorProducer.CommitSealForm.ROUND_BOUND) {
|
|
+ return 0;
|
|
+ }
|
|
+ final Optional<Bytes32> message =
|
|
+ PqAnchorProducer.anchorSealMessage(cfg, parentNumber, parentHash, certificate.round());
|
|
+ if (message.isEmpty()) {
|
|
+ return 0;
|
|
+ }
|
|
+ final Collection<Address> resolved = signers.parentSet();
|
|
+ if (resolved == null || resolved.isEmpty()) {
|
|
+ return 0;
|
|
+ }
|
|
+ final Set<Address> set = new HashSet<>(resolved);
|
|
+ final Set<Address> counted = new HashSet<>();
|
|
+ for (final SchemeSeal seal : certificate.seals()) {
|
|
+ if (seal.getSchemeWireId() != SealSchemes.FALCON_512.wireId()) {
|
|
+ continue;
|
|
+ }
|
|
+ Address member;
|
|
+ try {
|
|
+ member = signers.memberAt(seal.getValidatorIndex());
|
|
+ } catch (final RuntimeException e) {
|
|
+ member = null;
|
|
+ }
|
|
+ if (member == null || !set.contains(member) || counted.contains(member)) {
|
|
+ continue;
|
|
+ }
|
|
+ if (verifiesFalcon(signers, seal.getValidatorIndex(), message.get(), seal.getSignature())) {
|
|
+ counted.add(member);
|
|
+ }
|
|
+ }
|
|
+ return counted.size();
|
|
+ } catch (final RuntimeException e) {
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static boolean verifiesExtra(
|
|
+ final SealScheme scheme, final byte[] key, final Bytes32 message, final Bytes signature) {
|
|
+ try {
|
|
+ return scheme.verifyRaw(key, message.toArray(), signature.toArray());
|
|
+ } catch (final RuntimeException e) {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static boolean verifiesFalcon(
|
|
+ final Signers signers, final int index, final Bytes32 message, final Bytes signature) {
|
|
+ try {
|
|
+ return signers.verifyFalcon(index, message, signature);
|
|
+ } catch (final RuntimeException e) {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static IllegalArgumentException shape(final String what) {
|
|
+ return new IllegalArgumentException(V3_03 + ": " + what);
|
|
+ }
|
|
+
|
|
+ private static void requireCanonical(final int round, final List<SchemeSeal> seals) {
|
|
+ if (round < 0 || round > MAX_ROUND) {
|
|
+ throw shape("round " + round + " is outside 0.." + MAX_ROUND);
|
|
+ }
|
|
+ if (seals == null) {
|
|
+ throw shape("null row list");
|
|
+ }
|
|
+ if (seals.isEmpty() && round != 0) {
|
|
+ throw shape("an empty certificate must name round 0, not " + round);
|
|
+ }
|
|
+ if (seals.size() > MAX_SEALS) {
|
|
+ throw shape(seals.size() + " rows, above " + MAX_SEALS);
|
|
+ }
|
|
+ SchemeSeal prev = null;
|
|
+ for (final SchemeSeal s : seals) {
|
|
+ if (s.getValidatorIndex() < 0) {
|
|
+ throw shape("negative validator index " + s.getValidatorIndex());
|
|
+ }
|
|
+ if (SealSchemes.byWireId(s.getSchemeWireId()).isEmpty()) {
|
|
+ throw shape("unknown scheme tag 0x" + Integer.toHexString(s.getSchemeWireId() & 0xff));
|
|
+ }
|
|
+ if (s.getSignature() == null || s.getSignature().isEmpty()) {
|
|
+ throw shape("an empty signature at index " + s.getValidatorIndex());
|
|
+ }
|
|
+ if (prev != null && PqAnchorV2.CANONICAL.compare(prev, s) >= 0) {
|
|
+ throw shape("rows not strictly increasing by (index, scheme): " + prev + " then " + s);
|
|
+ }
|
|
+ prev = s;
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqSealCache.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqSealCache.java
|
|
index e3ddc481f2..fd4e0d36c2 100755
|
|
--- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqSealCache.java
|
|
+++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqSealCache.java
|
|
@@ -1,518 +1,641 @@
|
|
/*
|
|
* Copyright contributors to Besu / AERE Network.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
package org.hyperledger.besu.consensus.common.bft;
|
|
|
|
import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
import org.hyperledger.besu.datatypes.Hash;
|
|
|
|
import java.nio.file.Path;
|
|
+import java.util.ArrayDeque;
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
+import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.Iterator;
|
|
import java.util.LinkedHashMap;
|
|
+import java.util.LinkedHashSet;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
+import java.util.NavigableMap;
|
|
import java.util.Optional;
|
|
import java.util.Set;
|
|
+import java.util.TreeMap;
|
|
+import java.util.function.IntFunction;
|
|
|
|
import org.apache.tuweni.bytes.Bytes;
|
|
import org.apache.tuweni.bytes.Bytes32;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
/**
|
|
* AERE ANCHOR V2: the bounded store of Falcon seals this node HEARD for recent blocks, in memory and
|
|
* - for the chain head only - on disk.
|
|
*
|
|
* <p>WHAT IT IS FOR. The proposer of block N must carry a certificate over block N-1. Under
|
|
* V2 that certificate is chosen by the proposer out of what it heard, so the seals gossiped on
|
|
* Commit messages have to survive from the height where they arrive to the height where the next
|
|
* block is built. That is all this class does.
|
|
*
|
|
* <p>KEYED ON THE ON-CHAIN BLOCK HASH, NEVER ON THE COMMIT DIGEST. The digest carried by a Commit
|
|
* message is the committed-seal hash, which INCLUDES the round number, so it differs between rounds
|
|
* for one and the same block. The producer looks the certificate up by {@code
|
|
* parentHeader.getHash()}, which is the round-independent on-chain hash. Storing under anything
|
|
* else would silently produce empty certificates at every round change.
|
|
*
|
|
- * <p>AERE PERSISTENTA-SIGILII (2026-08-05): PERSISTENT FOR THE CHAIN HEAD, AND THE OLD REASONING FOR
|
|
- * NOT BEING SO WAS MEASURED WRONG. This class used to say, in this exact place, that losing the map
|
|
- * on restart costs "at most one proposer turn per restart". That reasoning is correct for ONE node
|
|
- * restarted inside a LIVE fleet, which is the case it was written for. For a fleet restarted
|
|
- * ENTIRELY it is false, and the falsehood was measured on a seven-node network: with K>0 every
|
|
- * node came back holding zero seals, no certificate could reach K, nobody could propose, so no
|
|
- * Commit was ever sent, so no node ever heard a seal again. The chain was dead, permanently, and no
|
|
- * amount of waiting healed it. The seals over M(head) exist nowhere else: they travel only on the
|
|
- * Commit messages of the head block, and those are never replayed.
|
|
- *
|
|
- * <p>AND IT IS NOT DEFECT A8 IN ANOTHER COAT. A8 was a registry of public keys read from a file and
|
|
- * BELIEVED. Every seal read back here is re-verified, cryptographically, against the anchored
|
|
- * registry over M rebuilt from the header this process just loaded - see {@link PqSealStore}. A
|
|
- * forged file cannot inject a seal without forging a Falcon-512 signature; the worst it achieves is
|
|
- * the empty cache an absent file already gives. Persistence is OFF unless a caller enables it, and
|
|
- * the only caller that does is the QBFT controller builder, only when the anchor is actually armed.
|
|
+ * <p>AERE 1(b), D-470 (2026-10-01), AERE-R1B-MAGAZIE: FROM H_r - 1 THE KEY IS (on-chain hash, ROUND). From the
|
|
+ * height {@code aere.pq.commitRoundBlock} on, a commit seal signs M_r, the message of its own round, so seals of
|
|
+ * different rounds verify over different messages and may never be added up into one "quorum" (the defect D-470
|
|
+ * names). Below that height the round key is {@link #ANY_ROUND} for every record and this store is the store of
|
|
+ * before, call by call: one record per block, the same window, the same first-seal and D-454 rules, the same
|
|
+ * SEALSTORE-1 head file and SEALWINDOW-1 frames, byte for byte (L1). From it: one record per (hash, round), at most
|
|
+ * {@link #MAX_ROUNDS_PER_BLOCK} rounds per block (the one with the fewest VERIFIED seals leaves, the larger round on
|
|
+ * a tie: the round that decided holds Q seals that verify, at most f byzantine validators can sign a round of their
|
|
+ * choosing, and garbage verifies nothing; at most {@link #MAX_SEALS_PER_ROUND} indices per record, the lowest kept;
|
|
+ * a quota per author on the pending store; review of step 4, 2026-10-01); every
|
|
+ * read and write names its round, and the forms without it were DELETED (decision H11: a form that would have to
|
|
+ * throw at H_r cannot be reached); the D-454 judge verifies over M_r; the head file is SEALSTORE-2, with every
|
|
+ * round and the extras; the window frames are SEALWINDOW-2, one per (n, r, hash); a Commit of a round r > 0
|
|
+ * heard WITHOUT the proposal (D-339) is held aside under its digest and moved under its round when the block is
|
|
+ * imported ({@link #resolvePending}).
|
|
*
|
|
- * <p>WHAT IT DOES NOT DO. Whether a seal index maps to an eligible validator, and whether there are
|
|
- * enough seals, are decided at SELECTION time by the producer, against the message M of the specific
|
|
- * parent. A seal that was signed under the pre-fork message simply fails that check and is dropped,
|
|
- * which is what makes the height switch safe without any coordination beyond the shared activation
|
|
- * height.
|
|
+ * <p>AERE PERSISTENTA-SIGILII (2026-08-05): PERSISTENT FOR THE CHAIN HEAD, AND THE OLD REASONING FOR
|
|
+ * NOT BEING SO WAS MEASURED WRONG. A fleet restarted ENTIRELY with K>0 came back holding zero seals, no
|
|
+ * certificate could reach K, nobody could propose, so no Commit was ever sent, so no node ever heard a seal again.
|
|
+ * The seals over M(head) exist nowhere else. Every seal read back is re-verified against the anchored registry
|
|
+ * over the message rebuilt from the header this process just loaded - see {@link PqSealStore}.
|
|
*
|
|
- * <p>D-454 FAMILY (adversarial review of 2026-09-30): ONE SLOT PER INDEX, AND AN UNVERIFIED SEAL NEVER
|
|
- * HOLDS IT AGAINST A VERIFIED ONE. Until this date the in-memory path verified nothing and the FIRST
|
|
- * seal heard for an index won for good. The Commits feeding it are not all judged first: the D-339
|
|
- * path keeps the seal of any Commit heard before the proposal, the late-seal salvage keeps any
|
|
- * validator's late Commit, and below the commit enforcement no Commit's post-quantum seal is judged
|
|
- * at all. So a garbage seal naming A's index, heard before A's own (below H_fin any validator can
|
|
- * send one; from H_fin, when the author of a Commit is read from its seal, a copy of A's public
|
|
- * commit seal in anyone's envelope), kept A's genuine seal out of every certificate this node could
|
|
- * build - and enough of them, at the parent of an anchor, left no proposer able to reach K. Now, from
|
|
- * H_fin ({@link AerePqFinality#PROPERTY}, AIP-22 stage 4, {@link #judgeGoverns}) and once the anchor
|
|
- * is armed on this node ({@link #enablePersistence}, the one production entry point), a seal is
|
|
- * JUDGED as it arrives, with the producer's own check ({@link #verifiesAsTheProducerDoes}): a seal
|
|
- * that verifies replaces one that does not, a seal that does not verify never replaces anything, and
|
|
- * a verified seal is never replaced. Without the judge (anchor not armed, or a height whose seal is
|
|
- * not in the anchor form) every seal is unverified, which is exactly the first-seal-wins store of
|
|
- * before. BELOW H_fin (and on every node where H_fin is unset) the store is the one of before, call
|
|
- * by call: first seal per index wins, nothing is verified, the restore and the head file follow the
|
|
- * rules of before (second review of D-454, 2026-10-01: armed from enablePersistence alone, the judge
|
|
- * changed the live chain below the stage that needs it and put post-quantum verifications on its
|
|
- * consensus thread). The producer still re-verifies every seal it carries; the judge decides only
|
|
- * which seal is KEPT.
|
|
+ * <p>D-454 FAMILY (adversarial review of 2026-09-30): ONE SLOT PER INDEX, AND AN UNVERIFIED SEAL NEVER HOLDS IT
|
|
+ * AGAINST A VERIFIED ONE, from H_fin ({@link AerePqFinality#PROPERTY}) and once the anchor is armed on this node
|
|
+ * ({@link #enablePersistence}). Below H_fin (and on every node where H_fin is unset) the store is the one of
|
|
+ * before, call by call: first seal per index wins, nothing is verified. The producer still re-verifies every
|
|
+ * seal it carries; the judge decides only which seal is KEPT. From H_r the slot is per (hash, round, index).
|
|
*/
|
|
public final class PqSealCache {
|
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(PqSealCache.class);
|
|
|
|
/**
|
|
* AIP-21 (AERE, 2026-09-18): how far below the highest seen height entries are kept, in blocks. The
|
|
* consensus default stays 256 (what the producer needs is the parent); a node that serves
|
|
* aere_getPqFinality may keep more through the system property, at ~7 kB per block for ten seals.
|
|
* Read once, never below 256, never a consensus value: two nodes with different windows import
|
|
* the same chain.
|
|
*/
|
|
public static final String PROPERTY_FINALITY_WINDOW = "aere.pq.finality.window";
|
|
|
|
+ /** 1(b): the round key of every record below H_r - 1: one record per block, as before. */
|
|
+ public static final int ANY_ROUND = -1;
|
|
+
|
|
+ /** 1(b): a round that cannot be valid at a round-bound height (outside 0..MAX_ROUND): never stored. */
|
|
+ private static final int INVALID_ROUND = -2;
|
|
+
|
|
+ /** 1(b): at most this many rounds are held per (n, hash) from H_r - 1. */
|
|
+ public static final int MAX_ROUNDS_PER_BLOCK = 8;
|
|
+
|
|
+ /** 1(b): at most this many pending (D-339, r > 0) Commits are held aside. */
|
|
+ public static final int MAX_PENDING = 256;
|
|
+
|
|
+ /**
|
|
+ * 1(b), review of step 4 (2026-10-01): at most this many pending entries per AUTHOR. A Byzantine validator can name any
|
|
+ * digest; without a quota per author it could push the honest late Commits of every other validator out of the
|
|
+ * {@link #MAX_PENDING} first-in-first-out store. With it, f authors hold at most f * 16 entries.
|
|
+ */
|
|
+ public static final int MAX_PENDING_PER_AUTHOR = 16;
|
|
+
|
|
+ /**
|
|
+ * 1(b), review of step 4: at most this many distinct indices per record from H_r - 1 (and per pending entry). A full
|
|
+ * record keeps the LOWEST indices: the registry's indices are dense from 0, so a flood of indices above the set can
|
|
+ * never push an honest index out, and the cost of judging a record stays bounded.
|
|
+ */
|
|
+ public static final int MAX_SEALS_PER_ROUND = PqAnchorV3.MAX_SEALS;
|
|
+
|
|
private static final long DEFAULT_HEIGHT_WINDOW = 256L;
|
|
|
|
/** How far below the highest seen height entries are kept, in blocks. */
|
|
private static final long HEIGHT_WINDOW = readWindow();
|
|
|
|
- /** How many distinct block hashes are retained. Several rounds at one height each add one. */
|
|
+ /** How many records are retained. Several rounds at one height each add one. */
|
|
private static final int MAX_ENTRIES = (int) Math.max(1024L, Math.min(HEIGHT_WINDOW * 4L, 1 << 20));
|
|
|
|
private static long readWindow() {
|
|
final Long v = Long.getLong(PROPERTY_FINALITY_WINDOW);
|
|
if (v == null) {
|
|
return DEFAULT_HEIGHT_WINDOW;
|
|
}
|
|
return Math.max(DEFAULT_HEIGHT_WINDOW, Math.min(v, 1L << 18));
|
|
}
|
|
|
|
/**
|
|
* The retention window in blocks, as this node runs it.
|
|
*
|
|
* @return the window
|
|
*/
|
|
public long retentionBlocks() {
|
|
return HEIGHT_WINDOW;
|
|
}
|
|
|
|
+ /**
|
|
+ * 1(b): the seals one round holds for a block, Falcon (index order) and extras (canonical order).
|
|
+ *
|
|
+ * @param falcon the Falcon-512 seals
|
|
+ * @param extras the extra-scheme seals
|
|
+ */
|
|
+ public record RoundSeals(List<FalconSeal> falcon, List<SchemeSeal> extras) {}
|
|
+
|
|
+ /** 1(b): the key of a record. Below H_r the round is always {@link #ANY_ROUND}. */
|
|
+ private record Key(Hash hash, int round) {}
|
|
+
|
|
+ /** 1(b): a Commit of round r > 0 heard without the proposal (D-339), held under its own digest. */
|
|
+ private record PendingKey(long blockNumber, Hash commitDigest, int round) {}
|
|
+
|
|
private static final PqSealCache INSTANCE = new PqSealCache();
|
|
|
|
- private final LinkedHashMap<Hash, Entry> byHash = new LinkedHashMap<>();
|
|
+ private final LinkedHashMap<Key, Entry> byKey = new LinkedHashMap<>();
|
|
+ private final LinkedHashMap<PendingKey, PendingEntry> pending = new LinkedHashMap<>();
|
|
+ /** 1(b): the pending keys each author contributed to, oldest first (the quota {@link #MAX_PENDING_PER_AUTHOR}). */
|
|
+ private final Map<Address, ArrayDeque<PendingKey>> pendingByAuthor = new HashMap<>();
|
|
private long highestSeen = -1L;
|
|
|
|
/** Guards the file, never the map, so a slow disk cannot hold up the consensus thread's map. */
|
|
private final Object writeLock = new Object();
|
|
|
|
private volatile Path persistenceFile;
|
|
private volatile long persistenceChainId;
|
|
|
|
private long persistedBlock = -1L;
|
|
private Hash persistedHash;
|
|
private int persistedCount = -1;
|
|
|
|
// AIP-21, SECOND HALF (2026-09-18): the finality window survives a restart. Heard heights are
|
|
// appended to a segmented journal (PqSealWindowStore) when the NEXT height begins, and read back,
|
|
// re-verified seal by seal against the canonical chain, at startup. Null = journal off.
|
|
private volatile Path windowDirectory;
|
|
private volatile long windowPrunedSegment = -1L;
|
|
private long windowJournaledThrough = -1L;
|
|
|
|
/** Heights restored at startup at most, newest first, whatever the configured window. */
|
|
private static final long MAX_RESTORED_HEIGHTS = 4096L;
|
|
|
|
/** D-454 family: the seals last written to the head file (compared, not only counted). */
|
|
private List<FalconSeal> persistedSeals = List.of();
|
|
|
|
+ /** 1(b): the bytes last written to a SEALSTORE-2 head file, compared before a rewrite. */
|
|
+ private Bytes persistedRoundsBytes = Bytes.EMPTY;
|
|
+
|
|
/**
|
|
* D-454 FAMILY (2026-09-30): whether a heard seal VERIFIES. Must never throw; false means "not
|
|
- * shown valid", never "shown invalid".
|
|
+ * shown valid", never "shown invalid". 1(b): it takes the ROUND; below H_r the round is ignored.
|
|
*/
|
|
@FunctionalInterface
|
|
public interface SealJudge {
|
|
/**
|
|
* Judge one heard seal.
|
|
*
|
|
* @param blockNumber the height of the block the seal attests
|
|
* @param onchainBlockHash the ON-CHAIN hash of that block
|
|
+ * @param round the round of the Commit that carried it (ignored below H_r)
|
|
* @param schemeWireId the certificate-v2 wire tag of the seal's scheme (Falcon-512 for the v1 list)
|
|
* @param validatorIndex the registry index the seal names
|
|
* @param signature the seal's signature bytes
|
|
* @return true only when the signature verifies under the key the index names at that height
|
|
*/
|
|
boolean verifies(
|
|
long blockNumber,
|
|
Hash onchainBlockHash,
|
|
+ int round,
|
|
byte schemeWireId,
|
|
int validatorIndex,
|
|
Bytes signature);
|
|
|
|
/** Judges nothing: every seal is unverified, which is exactly the first-seal-wins store of before. */
|
|
- SealJudge NONE = (h, hash, wire, index, sig) -> false;
|
|
+ SealJudge NONE = (h, hash, r, wire, index, sig) -> false;
|
|
}
|
|
|
|
private volatile SealJudge judge = SealJudge.NONE;
|
|
|
|
private PqSealCache() {}
|
|
|
|
/**
|
|
* D-454 FAMILY, BOUND TO H_FIN (second review, 2026-10-01): whether the judge of heard seals governs
|
|
- * a height. Only from H_fin ({@link AerePqFinality#PROPERTY}, {@code aere.pq.finalityBlock}, AIP-22
|
|
- * stage 4: the height from which the author of a Commit is read from its seal, the one
|
|
- * RoundState's pending commits are governed by too); below it, and on every node where H_fin is
|
|
- * unset, the store is the one of before, call by call, and no seal is verified on hearing.
|
|
+ * a height. Only from H_fin; below it, and on every node where H_fin is unset, the store is the one
|
|
+ * of before, call by call, and no seal is verified on hearing.
|
|
*
|
|
* @param blockNumber the height of the block the seals attest
|
|
* @return true from H_fin
|
|
*/
|
|
static boolean judgeGoverns(final long blockNumber) {
|
|
return AerePqFinality.active(blockNumber);
|
|
}
|
|
|
|
+ /**
|
|
+ * 1(b): the round key of round r at height n. {@link #ANY_ROUND} below H_r - 1 (whatever r); r from it, when r
|
|
+ * is a valid round; {@link #INVALID_ROUND} otherwise (such a seal cannot verify over any message and is not kept).
|
|
+ *
|
|
+ * @param blockNumber n
|
|
+ * @param round r
|
|
+ * @return the round key
|
|
+ */
|
|
+ static int roundKey(final long blockNumber, final int round) {
|
|
+ if (PqAnchorProducer.commitSealFormAt(PqAnchorProducer.config(), blockNumber)
|
|
+ != PqAnchorProducer.CommitSealForm.ROUND_BOUND) {
|
|
+ return ANY_ROUND;
|
|
+ }
|
|
+ return round < 0 || round > PqAnchorV3.MAX_ROUND ? INVALID_ROUND : round;
|
|
+ }
|
|
+
|
|
/**
|
|
* Arms the judge of heard seals ({@link SealJudge#NONE} or null disarms it). The one way in:
|
|
* production arms it from {@link #enablePersistence}; the cost measurement gives a counting judge.
|
|
*
|
|
* @param sealJudge the judge
|
|
*/
|
|
void judgeWith(final SealJudge sealJudge) {
|
|
this.judge = sealJudge == null ? SealJudge.NONE : sealJudge;
|
|
}
|
|
|
|
/**
|
|
- * D-454 FAMILY (2026-09-30): THE PRODUCER'S OWN CHECK, applied to a seal as it is heard. The message
|
|
- * is the anchor form over the block's on-chain hash ({@link PqAnchor#commitMessage}, what the
|
|
- * producer verifies against at selection time); a Falcon-512 seal is verified by the registry's
|
|
- * own-head door at the seal's height, exactly as the producer verifies it at the parent's height; an
|
|
- * extra scheme seal under the key the producer resolves (the v3 epoch from H_k, the hybrid registry
|
|
- * before). Below the anchor form (the committed-seal digest, which needs the block) nothing is
|
|
- * verified here and the store keeps its first-seal-wins rule. Never throws.
|
|
+ * D-454 FAMILY (2026-09-30): THE PRODUCER'S OWN CHECK, applied to a seal as it is heard. The message comes
|
|
+ * from the one place ({@link PqAnchorProducer#anchorSealMessage}): COMMIT-1 below H_r (as before), M_r of the
|
|
+ * Commit's round from H_r - 1 (1(b)); below the anchor form there is none and nothing is verified here. A
|
|
+ * Falcon-512 seal is verified by the registry's own-head door at the seal's height, exactly as the producer
|
|
+ * verifies it at the parent's height; an extra scheme seal under the key the producer resolves. Never throws.
|
|
*
|
|
* @param blockNumber the height of the block the seal attests
|
|
* @param onchainBlockHash the ON-CHAIN hash of that block
|
|
+ * @param round the round of the Commit that carried it
|
|
* @param schemeWireId the wire tag of the seal's scheme
|
|
* @param validatorIndex the registry index the seal names
|
|
* @param signature the seal's signature bytes
|
|
* @return true only when the seal verifies as the producer would verify it
|
|
*/
|
|
static boolean verifiesAsTheProducerDoes(
|
|
final long blockNumber,
|
|
final Hash onchainBlockHash,
|
|
+ final int round,
|
|
final byte schemeWireId,
|
|
final int validatorIndex,
|
|
final Bytes signature) {
|
|
try {
|
|
- if (!PqAnchorProducer.sealMessageIsAnchorForm(blockNumber)) {
|
|
+ final Optional<Bytes32> message =
|
|
+ PqAnchorProducer.anchorSealMessage(
|
|
+ PqAnchorProducer.config(), blockNumber, onchainBlockHash.getBytes(), round);
|
|
+ if (message.isEmpty()) {
|
|
return false;
|
|
}
|
|
- final Bytes32 message =
|
|
- PqAnchor.commitMessage(
|
|
- PqAnchorProducer.config().chainId(), blockNumber, onchainBlockHash.getBytes());
|
|
if (schemeWireId == SealSchemes.FALCON_512.wireId()) {
|
|
return PqSignerRegistry.falconSealSupport()
|
|
- .verifyAtOwnHead(blockNumber, validatorIndex, message, signature);
|
|
+ .verifyAtOwnHead(blockNumber, validatorIndex, message.get(), signature);
|
|
}
|
|
final Optional<SealScheme> scheme = SealSchemes.byWireId(schemeWireId);
|
|
if (scheme.isEmpty()) {
|
|
return false;
|
|
}
|
|
final String schemeId = scheme.get().id();
|
|
final Optional<byte[]> publicKey =
|
|
AerePqIdentity.keysFromV3(blockNumber)
|
|
? AerePqIdentity.v3KeyAt(blockNumber, validatorIndex, schemeId)
|
|
: HybridSealSupport.instance()
|
|
.registry()
|
|
.flatMap(r -> r.publicKey(validatorIndex, schemeId));
|
|
return publicKey.isPresent()
|
|
- && scheme.get().verifyRaw(publicKey.get(), message.toArray(), signature.toArray());
|
|
+ && scheme.get().verifyRaw(publicKey.get(), message.get().toArray(), signature.toArray());
|
|
} catch (final RuntimeException e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Whether the seal an index already holds for a block stays when another one arrives: always when it
|
|
* was verified, and when the newcomer is not verified. One place, so no caller can half-apply it (the
|
|
* second client's KeepsHeardSeal is the same rule).
|
|
*
|
|
* @param held whether the index holds a seal
|
|
* @param heldVerified whether that seal was verified
|
|
* @param newVerified whether the newcomer verified
|
|
* @return true when the held seal stays
|
|
*/
|
|
static boolean keepsHeldSeal(
|
|
final boolean held, final boolean heldVerified, final boolean newVerified) {
|
|
return held && (heldVerified || !newVerified);
|
|
}
|
|
|
|
/**
|
|
* The process-wide cache.
|
|
*
|
|
* @return the singleton
|
|
*/
|
|
public static PqSealCache instance() {
|
|
return INSTANCE;
|
|
}
|
|
|
|
/**
|
|
- * Turn on writing the chain head's seals to the node's data directory.
|
|
- *
|
|
- * <p>The path is DERIVED from the data directory Besu was started with, never configured
|
|
- * separately: a second configurable path is a second thing that can be pointed at the wrong node's
|
|
- * state, and this file is per-node by construction.
|
|
- *
|
|
- * <p>D-454 FAMILY (2026-09-30): this is the one production entry point reached only with the anchor
|
|
- * armed (the QBFT controller builder, after the registry is active), so it also arms the judge of
|
|
- * heard seals ({@link #verifiesAsTheProducerDoes}), with or without a data directory. Arming it
|
|
- * here, and never lazily from the store itself, keeps a node or a test without the anchor from
|
|
- * initialising the registry singletons as a side effect of hearing a seal. Armed is not governing:
|
|
- * the judge is consulted only from H_fin ({@link #judgeGoverns}, bound 2026-10-01).
|
|
+ * Turn on writing the chain head's seals to the node's data directory, and arm the judge of heard seals
|
|
+ * (D-454 family). The path is DERIVED from the data directory, never configured separately.
|
|
*
|
|
* @param dataDirectory the node's data directory, or null to leave persistence off
|
|
- * @param chainId the chain id used in the M pre-image, which must be the SAME value the producer
|
|
- * uses or every restored seal would fail verification
|
|
+ * @param chainId the chain id used in the message pre-images, which must be the SAME value the producer uses
|
|
*/
|
|
public void enablePersistence(final Path dataDirectory, final long chainId) {
|
|
judgeWith(PqSealCache::verifiesAsTheProducerDoes);
|
|
if (dataDirectory == null) {
|
|
LOG.warn(
|
|
"AERE PERSISTENTA-SIGILII: no data directory was supplied, so heard seals stay in memory "
|
|
+ "only. A simultaneous restart of the whole fleet with K>0 stops the chain.");
|
|
return;
|
|
}
|
|
this.persistenceChainId = chainId;
|
|
this.persistenceFile = PqSealStore.fileIn(dataDirectory);
|
|
this.windowPrunedSegment = -1L;
|
|
this.windowDirectory =
|
|
PqSealWindowStore.enabled() ? PqSealWindowStore.directoryIn(dataDirectory) : null;
|
|
LOG.info(
|
|
"AERE PERSISTENTA-SIGILII: heard seals for the chain head are kept in {} (chainId={}). "
|
|
+ "Every seal read back is re-verified against the anchored registry before it is used.",
|
|
this.persistenceFile,
|
|
chainId);
|
|
}
|
|
|
|
/**
|
|
* Turn persistence off again. For tests, and for an operator who wants the previous behaviour. It
|
|
* also disarms the judge of heard seals (D-454 family), back to the first-seal-wins store.
|
|
*/
|
|
public void disablePersistence() {
|
|
this.persistenceFile = null;
|
|
this.judge = SealJudge.NONE;
|
|
this.windowDirectory = null;
|
|
synchronized (writeLock) {
|
|
persistedBlock = -1L;
|
|
persistedHash = null;
|
|
persistedCount = -1;
|
|
+ persistedRoundsBytes = Bytes.EMPTY;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* The file heard seals are written to, or null when persistence is off.
|
|
*
|
|
* @return the seal file, or null
|
|
*/
|
|
public Path persistenceFile() {
|
|
return persistenceFile;
|
|
}
|
|
|
|
/**
|
|
- * Refill the cache from disk for a specific block, normally this node's chain head at startup.
|
|
- *
|
|
- * <p>Call this AFTER the Falcon registry has been activated, or every seal will be rejected for
|
|
- * the entirely correct reason that the registry cannot resolve its index yet, and the restore will
|
|
- * silently do nothing.
|
|
+ * Refill the cache from disk for a specific block, normally this node's chain head at startup. Below H_r - 1
|
|
+ * the SEALSTORE-1 file, as before; from it the SEALSTORE-2 file, every round with its extras (1(b)). Call this
|
|
+ * AFTER the Falcon registry has been activated.
|
|
*
|
|
* @param blockNumber the head block's height
|
|
* @param onchainBlockHash the head block's ON-CHAIN hash
|
|
* @param registry the anchored registry every restored seal is re-verified against
|
|
* @return how many seals survived verification and entered the cache
|
|
*/
|
|
public int restoreFromDisk(
|
|
final long blockNumber, final Hash onchainBlockHash, final PqSignerRegistry registry) {
|
|
final Path file = persistenceFile;
|
|
if (file == null) {
|
|
return 0;
|
|
}
|
|
+ if (roundKey(blockNumber, 0) != ANY_ROUND) {
|
|
+ return restoreRoundsFromDisk(file, blockNumber, onchainBlockHash, registry);
|
|
+ }
|
|
List<FalconSeal> verified;
|
|
try {
|
|
verified =
|
|
PqSealStore.readVerified(
|
|
file, persistenceChainId, blockNumber, onchainBlockHash, registry);
|
|
if (verified.isEmpty()) {
|
|
// MAGAZIA TINE VARFUL (D-330): the main file may hold a later height that never imported;
|
|
// the previous slot may hold exactly the head. Same verification, same registry.
|
|
final Path previous = file.resolveSibling(PqSealStore.PREVIOUS_FILE_NAME);
|
|
verified =
|
|
PqSealStore.readVerified(
|
|
previous, persistenceChainId, blockNumber, onchainBlockHash, registry);
|
|
if (!verified.isEmpty()) {
|
|
LOG.info(
|
|
"AERE PERSISTENTA-SIGILII: {} seal(s) for the chain head {} restored from the PREVIOUS slot {}"
|
|
+ " (the main file held a later height).",
|
|
verified.size(),
|
|
blockNumber,
|
|
previous);
|
|
}
|
|
}
|
|
} catch (final RuntimeException e) {
|
|
- // readVerified is written not to throw; this is the belt on top of the braces, because an
|
|
- // exception escaping here would turn a lost cache into a node that refuses to start.
|
|
LOG.warn(
|
|
"AERE PERSISTENTA-SIGILII: restoring seals from {} failed unexpectedly ({}); the cache "
|
|
+ "starts empty, which is exactly the behaviour before this file existed.",
|
|
file,
|
|
e.toString());
|
|
return 0;
|
|
}
|
|
if (verified.isEmpty()) {
|
|
return 0;
|
|
}
|
|
synchronized (this) {
|
|
final Entry entry =
|
|
- byHash.computeIfAbsent(onchainBlockHash, unused -> new Entry(blockNumber));
|
|
+ byKey.computeIfAbsent(new Key(onchainBlockHash, ANY_ROUND), unused -> new Entry(blockNumber));
|
|
for (final FalconSeal seal : verified) {
|
|
if (!judgeGoverns(blockNumber)) {
|
|
// below H_fin: the restore of before, call by call (D-454 family, bound to H_fin)
|
|
entry.seals.putIfAbsent(seal.getValidatorIndex(), seal);
|
|
continue;
|
|
}
|
|
// re-verified by readVerified: it displaces an unverified seal held for its index (D-454 family)
|
|
final int index = seal.getValidatorIndex();
|
|
if (!keepsHeldSeal(entry.seals.containsKey(index), entry.verified.contains(index), true)) {
|
|
entry.seals.put(index, seal);
|
|
entry.verified.add(index);
|
|
}
|
|
}
|
|
if (blockNumber > highestSeen) {
|
|
highestSeen = blockNumber;
|
|
}
|
|
prune();
|
|
}
|
|
return verified.size();
|
|
}
|
|
|
|
+ /** 1(b): the SEALSTORE-2 restore, main file then the previous slot; every row re-verified over M_r. */
|
|
+ private int restoreRoundsFromDisk(
|
|
+ final Path file, final long blockNumber, final Hash onchainBlockHash, final PqSignerRegistry registry) {
|
|
+ NavigableMap<Integer, List<SchemeSeal>> rounds;
|
|
+ try {
|
|
+ rounds = PqSealStore.readVerifiedRounds(file, persistenceChainId, blockNumber, onchainBlockHash, registry);
|
|
+ if (rounds.isEmpty()) {
|
|
+ rounds =
|
|
+ PqSealStore.readVerifiedRounds(
|
|
+ file.resolveSibling(PqSealStore.PREVIOUS_FILE_NAME),
|
|
+ persistenceChainId,
|
|
+ blockNumber,
|
|
+ onchainBlockHash,
|
|
+ registry);
|
|
+ }
|
|
+ } catch (final RuntimeException e) {
|
|
+ LOG.warn(
|
|
+ "AERE PERSISTENTA-SIGILII: restoring the rounds of block {} from {} failed unexpectedly ({}); the cache"
|
|
+ + " starts empty.",
|
|
+ blockNumber,
|
|
+ file,
|
|
+ e.toString());
|
|
+ return 0;
|
|
+ }
|
|
+ int restored = 0;
|
|
+ synchronized (this) {
|
|
+ for (final Map.Entry<Integer, List<SchemeSeal>> e : rounds.entrySet()) {
|
|
+ final Entry entry =
|
|
+ byKey.computeIfAbsent(new Key(onchainBlockHash, e.getKey()), unused -> new Entry(blockNumber));
|
|
+ for (final SchemeSeal s : e.getValue()) {
|
|
+ if (s.getSchemeWireId() == SealSchemes.FALCON_512.wireId()) {
|
|
+ final int index = s.getValidatorIndex();
|
|
+ if (!keepsHeldSeal(entry.seals.containsKey(index), entry.verified.contains(index), true)) {
|
|
+ entry.seals.put(index, new FalconSeal(index, s.getSignature()));
|
|
+ entry.verified.add(index);
|
|
+ restored++;
|
|
+ }
|
|
+ } else {
|
|
+ final long key = extraKey(s);
|
|
+ if (!keepsHeldSeal(entry.extras.containsKey(key), entry.extrasVerified.contains(key), true)) {
|
|
+ entry.extras.put(key, s);
|
|
+ entry.extrasVerified.add(key);
|
|
+ restored++;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ enforceRoundCap(blockNumber, onchainBlockHash);
|
|
+ if (blockNumber > highestSeen) {
|
|
+ highestSeen = blockNumber;
|
|
+ }
|
|
+ prune();
|
|
+ }
|
|
+ return restored;
|
|
+ }
|
|
+
|
|
/**
|
|
- * Remember the seals heard for a block. One slot per validator index: a later duplicate cannot
|
|
- * displace the seal held, and (D-454 family, 2026-09-30) from H_fin neither can any seal that does
|
|
- * not verify; a seal that verifies displaces one that did not ({@link #keepsHeldSeal}). Below H_fin,
|
|
- * or without the judge armed, nothing is verified and the first seal seen for an index wins, as
|
|
- * before.
|
|
+ * Remember the Falcon seals heard for a block in a round (1(b): the round is mandatory; below H_r it is ignored
|
|
+ * and the record is the block's one record, as before). One slot per validator index: a later duplicate cannot
|
|
+ * displace the seal held, and from H_fin neither can any seal that does not verify; a seal that verifies
|
|
+ * displaces one that did not ({@link #keepsHeldSeal}).
|
|
*
|
|
* @param blockNumber the height of the block the seals attest
|
|
* @param onchainBlockHash the ON-CHAIN hash of that block
|
|
+ * @param round the round of the Commit(s) that carried the seals
|
|
* @param seals the seals heard, possibly empty
|
|
*/
|
|
public void record(
|
|
- final long blockNumber, final Hash onchainBlockHash, final Collection<FalconSeal> seals) {
|
|
+ final long blockNumber,
|
|
+ final Hash onchainBlockHash,
|
|
+ final int round,
|
|
+ final Collection<FalconSeal> seals) {
|
|
+ final int rk = roundKey(blockNumber, round);
|
|
+ if (rk == INVALID_ROUND) {
|
|
+ return;
|
|
+ }
|
|
final List<FalconSeal> toPersist;
|
|
+ NavigableMap<Integer, List<SchemeSeal>> roundsToPersist = null;
|
|
List<PqSealWindowStore.Heard> windowToJournal = List.of();
|
|
synchronized (this) {
|
|
if (onchainBlockHash == null || seals == null || seals.isEmpty()) {
|
|
return;
|
|
}
|
|
- final Entry entry =
|
|
- byHash.computeIfAbsent(onchainBlockHash, unused -> new Entry(blockNumber));
|
|
+ final Key key = new Key(onchainBlockHash, rk);
|
|
+ final boolean created = !byKey.containsKey(key);
|
|
+ final Entry entry = byKey.computeIfAbsent(key, unused -> new Entry(blockNumber));
|
|
for (final FalconSeal seal : seals) {
|
|
if (seal != null && seal.getValidatorIndex() >= 0 && seal.getSignature() != null) {
|
|
+ // 1(b), review of step 4: from H_r - 1 a record holds at most MAX_SEALS_PER_ROUND indices, the lowest
|
|
+ if (rk != ANY_ROUND && !admitIndex(entry.seals, seal.getValidatorIndex(), entry)) {
|
|
+ continue;
|
|
+ }
|
|
if (!judgeGoverns(blockNumber)) {
|
|
// below H_fin: the store of before, call by call (first seal per index wins, nothing judged)
|
|
entry.seals.putIfAbsent(seal.getValidatorIndex(), seal);
|
|
continue;
|
|
}
|
|
final int index = seal.getValidatorIndex();
|
|
final FalconSeal held = entry.seals.get(index);
|
|
// the same bytes again (every commit re-offers the round's seals), or a verified seal held:
|
|
// nothing to judge, the held seal stays
|
|
if (held != null
|
|
&& (entry.verified.contains(index) || held.getSignature().equals(seal.getSignature()))) {
|
|
continue;
|
|
}
|
|
final boolean verified =
|
|
judge.verifies(
|
|
blockNumber,
|
|
onchainBlockHash,
|
|
+ rk == ANY_ROUND ? 0 : rk,
|
|
SealSchemes.FALCON_512.wireId(),
|
|
index,
|
|
seal.getSignature());
|
|
if (keepsHeldSeal(held != null, false, verified)) {
|
|
continue;
|
|
}
|
|
entry.seals.put(index, seal);
|
|
if (verified) {
|
|
entry.verified.add(index);
|
|
}
|
|
}
|
|
}
|
|
+ if (created && rk != ANY_ROUND) {
|
|
+ enforceRoundCap(blockNumber, onchainBlockHash);
|
|
+ }
|
|
if (blockNumber > highestSeen) {
|
|
// AIP-21 second half: a NEW height begins, so what was heard for the heights below it is as
|
|
// complete as this node will ever hold it. It goes to the window journal, outside this lock.
|
|
windowToJournal = windowSnapshotBelow(blockNumber);
|
|
highestSeen = blockNumber;
|
|
}
|
|
prune();
|
|
if (persistenceFile == null || blockNumber < highestSeen) {
|
|
// Only the HIGHEST block is worth a file: the producer of the next block asks for the head's
|
|
// seals and nothing else, and writing older heights would just churn the disk.
|
|
return;
|
|
}
|
|
- toPersist = PqAnchor.sortedByIndex(new ArrayList<>(entry.seals.values()));
|
|
+ if (rk == ANY_ROUND) {
|
|
+ toPersist = PqAnchor.sortedByIndex(new ArrayList<>(entry.seals.values()));
|
|
+ } else {
|
|
+ toPersist = null;
|
|
+ roundsToPersist = roundsOf(blockNumber, onchainBlockHash);
|
|
+ }
|
|
}
|
|
// Deliberately OUTSIDE the map lock: a file write must never be able to stall a caller that only
|
|
// wants to read the cache.
|
|
- persist(blockNumber, onchainBlockHash, toPersist);
|
|
+ if (roundsToPersist != null) {
|
|
+ persistRounds(blockNumber, onchainBlockHash, roundsToPersist);
|
|
+ } else {
|
|
+ persist(blockNumber, onchainBlockHash, toPersist);
|
|
+ }
|
|
// the head file first (liveness depends on it), the window journal after (best effort)
|
|
persistWindow(windowToJournal);
|
|
}
|
|
|
|
/** Same indices and the same signature bytes, in the same (canonical) order. */
|
|
private static boolean sameSeals(final List<FalconSeal> a, final List<FalconSeal> b) {
|
|
if (a.size() != b.size()) {
|
|
return false;
|
|
}
|
|
for (int i = 0; i < a.size(); i++) {
|
|
if (a.get(i).getValidatorIndex() != b.get(i).getValidatorIndex()
|
|
|| !a.get(i).getSignature().equals(b.get(i).getSignature())) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private void persist(
|
|
final long blockNumber, final Hash onchainBlockHash, final List<FalconSeal> seals) {
|
|
@@ -521,364 +644,962 @@ public final class PqSealCache {
|
|
return;
|
|
}
|
|
synchronized (writeLock) {
|
|
if (blockNumber < persistedBlock) {
|
|
return;
|
|
}
|
|
// D-454 family (2026-09-30): from H_fin a verified seal can REPLACE an unverified one without
|
|
// changing the count, so "no more seals than the file holds" is no longer "nothing new" there: the
|
|
// file is kept only when it holds more seals, or the very same ones. Below H_fin nothing is ever
|
|
// replaced and the rule of before stands, call by call (bound to H_fin, 2026-10-01).
|
|
if (blockNumber == persistedBlock
|
|
&& onchainBlockHash.equals(persistedHash)
|
|
&& (judgeGoverns(blockNumber)
|
|
? (seals.size() < persistedCount
|
|
|| (seals.size() == persistedCount && sameSeals(seals, persistedSeals)))
|
|
: seals.size() <= persistedCount)) {
|
|
return;
|
|
}
|
|
try {
|
|
// MAGAZIA TINE VARFUL (D-330, 2026-09-03): before the main file moves to a HIGHER height, what it
|
|
- // held becomes the previous slot. The main file may hold a proposal that never imports; the
|
|
- // previous slot then still holds the head, and a restart can restore the head's seals from it.
|
|
+ // held becomes the previous slot.
|
|
if (persistedBlock >= 0 && blockNumber > persistedBlock && java.nio.file.Files.isRegularFile(file)) {
|
|
java.nio.file.Files.move(
|
|
file,
|
|
file.resolveSibling(PqSealStore.PREVIOUS_FILE_NAME),
|
|
java.nio.file.StandardCopyOption.REPLACE_EXISTING);
|
|
}
|
|
PqSealStore.writeAtomically(
|
|
file,
|
|
PqSealStore.encode(
|
|
persistenceChainId, blockNumber, onchainBlockHash.getBytes(), seals));
|
|
persistedBlock = blockNumber;
|
|
persistedHash = onchainBlockHash;
|
|
persistedCount = seals.size();
|
|
if (judgeGoverns(blockNumber)) {
|
|
persistedSeals = List.copyOf(seals);
|
|
}
|
|
} catch (final Exception e) {
|
|
// A disk fault must not be able to stop this node from taking part in consensus. It costs
|
|
// the restart protection, which is what the log line says, and nothing else.
|
|
LOG.warn(
|
|
"AERE PERSISTENTA-SIGILII: could not write the {} heard seal(s) for block {} to {} "
|
|
+ "({}). This node keeps working; it just loses its seals if it restarts now.",
|
|
seals.size(),
|
|
blockNumber,
|
|
file,
|
|
e.toString());
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
- * The seals heard for a block, in canonical order.
|
|
- *
|
|
- * @param blockNumber the height of the block the seals must attest
|
|
- * @param onchainBlockHash the ON-CHAIN hash of that block
|
|
- * @return the seals, sorted by strictly increasing validator index, possibly empty
|
|
+ * 1(b): the SEALSTORE-2 head file. Rewritten when the TOTAL over all rounds grows, or (from H_fin) when the
|
|
+ * bytes change at the same total (a verified seal replaced an unverified one); otherwise kept. The same
|
|
+ * previous-slot rotation as form 1 (D-330).
|
|
*/
|
|
+ private void persistRounds(
|
|
+ final long blockNumber,
|
|
+ final Hash onchainBlockHash,
|
|
+ final NavigableMap<Integer, List<SchemeSeal>> rounds) {
|
|
+ final Path file = persistenceFile;
|
|
+ if (file == null) {
|
|
+ return;
|
|
+ }
|
|
+ int total = 0;
|
|
+ for (final List<SchemeSeal> rows : rounds.values()) {
|
|
+ total += rows.size();
|
|
+ }
|
|
+ synchronized (writeLock) {
|
|
+ if (blockNumber < persistedBlock) {
|
|
+ return;
|
|
+ }
|
|
+ final byte[] payload =
|
|
+ PqSealStore.encodeRounds(persistenceChainId, blockNumber, onchainBlockHash.getBytes(), rounds);
|
|
+ if (blockNumber == persistedBlock
|
|
+ && onchainBlockHash.equals(persistedHash)
|
|
+ && (total < persistedCount
|
|
+ || (total == persistedCount
|
|
+ && (!judgeGoverns(blockNumber) || Bytes.wrap(payload).equals(persistedRoundsBytes))))) {
|
|
+ return;
|
|
+ }
|
|
+ try {
|
|
+ if (persistedBlock >= 0 && blockNumber > persistedBlock && java.nio.file.Files.isRegularFile(file)) {
|
|
+ java.nio.file.Files.move(
|
|
+ file,
|
|
+ file.resolveSibling(PqSealStore.PREVIOUS_FILE_NAME),
|
|
+ java.nio.file.StandardCopyOption.REPLACE_EXISTING);
|
|
+ }
|
|
+ PqSealStore.writeAtomically(file, payload);
|
|
+ persistedBlock = blockNumber;
|
|
+ persistedHash = onchainBlockHash;
|
|
+ persistedCount = total;
|
|
+ persistedRoundsBytes = Bytes.wrap(payload);
|
|
+ } catch (final Exception e) {
|
|
+ LOG.warn(
|
|
+ "AERE PERSISTENTA-SIGILII: could not write the {} heard seal(s) of {} round(s) for block {} to {} ({}).",
|
|
+ total,
|
|
+ rounds.size(),
|
|
+ blockNumber,
|
|
+ file,
|
|
+ e.toString());
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
/**
|
|
- * AERE ANCHOR V2: remember the extra (non-Falcon) scheme seals heard on the commits of a block.
|
|
- * Same key as {@link #record}, same window, same slot rule per validator and scheme (D-454 family:
|
|
- * from H_fin an unverified seal never displaces a verified one and a verified one displaces an
|
|
- * unverified one; below H_fin, or without the judge, the first seal wins, as before). NOT persisted
|
|
- * across a restart: a node that restarts holds no extras until it
|
|
- * takes part in one commit, exactly the Falcon situation before PqSealStore, and the producer
|
|
- * then refuses the v2 certificate for one proposer turn rather than writing a short one.
|
|
+ * AERE ANCHOR V2: remember the extra (non-Falcon) scheme seals heard on the commits of a block in a round
|
|
+ * (1(b): mandatory round, ignored below H_r). Same key as {@link #record}, same window, same slot rule per
|
|
+ * validator and scheme (D-454 family). Below H_r NOT persisted, as before; from H_r - 1 they enter the
|
|
+ * SEALSTORE-2 head file with the Falcon seals of their round (the gap of 2026-09-04).
|
|
*
|
|
* @param blockNumber the height of the block the seals are over
|
|
* @param onchainBlockHash the round-independent on-chain hash of that block
|
|
+ * @param round the round of the Commit(s) that carried them
|
|
* @param extraSeals the heard scheme seals, unverified
|
|
*/
|
|
public void recordExtras(
|
|
- final long blockNumber, final Hash onchainBlockHash, final Collection<SchemeSeal> extraSeals) {
|
|
+ final long blockNumber,
|
|
+ final Hash onchainBlockHash,
|
|
+ final int round,
|
|
+ final Collection<SchemeSeal> extraSeals) {
|
|
+ final int rk = roundKey(blockNumber, round);
|
|
+ if (rk == INVALID_ROUND) {
|
|
+ return;
|
|
+ }
|
|
+ NavigableMap<Integer, List<SchemeSeal>> roundsToPersist = null;
|
|
synchronized (this) {
|
|
if (onchainBlockHash == null || extraSeals == null || extraSeals.isEmpty()) {
|
|
return;
|
|
}
|
|
- final Entry entry =
|
|
- byHash.computeIfAbsent(onchainBlockHash, unused -> new Entry(blockNumber));
|
|
+ final Key k = new Key(onchainBlockHash, rk);
|
|
+ final boolean created = !byKey.containsKey(k);
|
|
+ final Entry entry = byKey.computeIfAbsent(k, unused -> new Entry(blockNumber));
|
|
for (final SchemeSeal seal : extraSeals) {
|
|
if (seal == null
|
|
|| seal.getValidatorIndex() < 0
|
|
|| seal.getSignature() == null
|
|
|| seal.getSchemeWireId() == SealSchemes.FALCON_512.wireId()) {
|
|
continue;
|
|
}
|
|
- final long key = ((long) seal.getValidatorIndex() << 8) | (seal.getSchemeWireId() & 0xffL);
|
|
+ final long key = extraKey(seal);
|
|
+ // 1(b), review of step 4: the same bound per record for the extras, the lowest keys kept
|
|
+ if (rk != ANY_ROUND && !admitExtra(entry, key)) {
|
|
+ continue;
|
|
+ }
|
|
if (!judgeGoverns(blockNumber)) {
|
|
// below H_fin: the store of before, call by call (first seal per index and scheme wins)
|
|
entry.extras.putIfAbsent(key, seal);
|
|
continue;
|
|
}
|
|
// D-454 family (2026-09-30): the same rule as the Falcon slot, per (index, scheme)
|
|
final SchemeSeal held = entry.extras.get(key);
|
|
if (held != null
|
|
&& (entry.extrasVerified.contains(key) || held.getSignature().equals(seal.getSignature()))) {
|
|
continue;
|
|
}
|
|
final boolean verified =
|
|
judge.verifies(
|
|
blockNumber,
|
|
onchainBlockHash,
|
|
+ rk == ANY_ROUND ? 0 : rk,
|
|
seal.getSchemeWireId(),
|
|
seal.getValidatorIndex(),
|
|
seal.getSignature());
|
|
if (keepsHeldSeal(held != null, false, verified)) {
|
|
continue;
|
|
}
|
|
entry.extras.put(key, seal);
|
|
if (verified) {
|
|
entry.extrasVerified.add(key);
|
|
}
|
|
}
|
|
+ if (created && rk != ANY_ROUND) {
|
|
+ enforceRoundCap(blockNumber, onchainBlockHash);
|
|
+ }
|
|
if (blockNumber > highestSeen) {
|
|
highestSeen = blockNumber;
|
|
}
|
|
prune();
|
|
+ if (rk != ANY_ROUND && persistenceFile != null && blockNumber >= highestSeen) {
|
|
+ roundsToPersist = roundsOf(blockNumber, onchainBlockHash);
|
|
+ }
|
|
+ }
|
|
+ if (roundsToPersist != null) {
|
|
+ persistRounds(blockNumber, onchainBlockHash, roundsToPersist);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static long extraKey(final SchemeSeal seal) {
|
|
+ return ((long) seal.getValidatorIndex() << 8) | (seal.getSchemeWireId() & 0xffL);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * 1(b): hold aside the seals of a Commit of round r > 0 heard WITHOUT the proposal (D-339), under the commit
|
|
+ * digest the Commit names, until the block is imported and its digest at round r can be compared
|
|
+ * ({@link #resolvePending}). Below H_r, and at r = 0 (whose digest IS the on-chain hash), the caller records
|
|
+ * directly, as before. Bounded (review of step 4, 2026-10-01): one slot per index (the first heard), at most {@link
|
|
+ * #MAX_SEALS_PER_ROUND} indices per entry (the lowest), at most {@link #MAX_PENDING_PER_AUTHOR} entries per author
|
|
+ * (a validator that names digests at will only ever displaces its OWN oldest entries), {@link #MAX_PENDING} in all,
|
|
+ * and the height window. Nothing here is believed: what is moved under a round still goes through the store's
|
|
+ * rules, and the producer verifies every seal it carries.
|
|
+ *
|
|
+ * @param blockNumber n
|
|
+ * @param commitDigest the digest the Commit names (the commit hash of its round)
|
|
+ * @param round r
|
|
+ * @param author the validator that sent the Commit (its quota); null counts as one anonymous author
|
|
+ * @param falcon the Falcon seal(s) it carried
|
|
+ * @param extras the extra seals it carried
|
|
+ */
|
|
+ public synchronized void recordPendingRound(
|
|
+ final long blockNumber,
|
|
+ final Hash commitDigest,
|
|
+ final int round,
|
|
+ final Address author,
|
|
+ final Collection<FalconSeal> falcon,
|
|
+ final Collection<SchemeSeal> extras) {
|
|
+ if (commitDigest == null || roundKey(blockNumber, round) <= 0) {
|
|
+ return;
|
|
+ }
|
|
+ final PendingKey key = new PendingKey(blockNumber, commitDigest, round);
|
|
+ final PendingEntry entry = pending.computeIfAbsent(key, unused -> new PendingEntry());
|
|
+ final Address who = author == null ? Address.ZERO : author;
|
|
+ // one slot per (index, AUTHOR), not per index (second review of step 4): a byzantine author that names an honest
|
|
+ // index first must not drop that index's genuine seal before the store's judge (D-454, from H_fin) ever sees it.
|
|
+ // Every variant is handed to record() at resolution, in arrival order, so the store applies its own rule.
|
|
+ if (falcon != null) {
|
|
+ for (final FalconSeal s : falcon) {
|
|
+ if (s != null && s.getValidatorIndex() >= 0 && s.getSignature() != null
|
|
+ && admitIndexKey(entry.falcon, (long) s.getValidatorIndex(), MAX_SEALS_PER_ROUND)) {
|
|
+ entry.falcon.computeIfAbsent((long) s.getValidatorIndex(), unused -> new LinkedHashMap<>()).putIfAbsent(who, s);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ if (extras != null) {
|
|
+ for (final SchemeSeal s : extras) {
|
|
+ if (s != null && s.getValidatorIndex() >= 0 && s.getSignature() != null
|
|
+ && s.getSchemeWireId() != SealSchemes.FALCON_512.wireId()) {
|
|
+ final long k = extraKey(s);
|
|
+ if (admitIndexKey(entry.extras, k, 2 * MAX_SEALS_PER_ROUND)) {
|
|
+ entry.extras.computeIfAbsent(k, unused -> new LinkedHashMap<>()).putIfAbsent(who, s);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ if (entry.authors.add(who)) {
|
|
+ final ArrayDeque<PendingKey> mine = pendingByAuthor.computeIfAbsent(who, unused -> new ArrayDeque<>());
|
|
+ mine.addLast(key);
|
|
+ while (mine.size() > MAX_PENDING_PER_AUTHOR) {
|
|
+ final PendingKey dropped = mine.pollFirst();
|
|
+ final PendingEntry d = pending.get(dropped);
|
|
+ if (d != null) {
|
|
+ d.authors.remove(who);
|
|
+ if (d.authors.isEmpty()) {
|
|
+ pending.remove(dropped);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ final List<PendingKey> gone = new ArrayList<>();
|
|
+ for (final PendingKey k : pending.keySet()) {
|
|
+ if (highestSeen - k.blockNumber() > HEIGHT_WINDOW) {
|
|
+ gone.add(k);
|
|
+ }
|
|
+ }
|
|
+ final Iterator<PendingKey> oldest = pending.keySet().iterator();
|
|
+ for (int extra = pending.size() - gone.size() - MAX_PENDING; extra > 0 && oldest.hasNext(); ) {
|
|
+ final PendingKey k = oldest.next();
|
|
+ if (!gone.contains(k)) {
|
|
+ gone.add(k);
|
|
+ extra--;
|
|
+ }
|
|
+ }
|
|
+ gone.forEach(this::forgetPending);
|
|
+ }
|
|
+
|
|
+ /** Removes a pending entry and its place in every author's quota. Lock held. */
|
|
+ private void forgetPending(final PendingKey key) {
|
|
+ final PendingEntry e = pending.remove(key);
|
|
+ if (e == null) {
|
|
+ return;
|
|
+ }
|
|
+ for (final Address a : e.authors) {
|
|
+ final ArrayDeque<PendingKey> mine = pendingByAuthor.get(a);
|
|
+ if (mine != null) {
|
|
+ mine.remove(key);
|
|
+ if (mine.isEmpty()) {
|
|
+ pendingByAuthor.remove(a);
|
|
+ }
|
|
+ }
|
|
}
|
|
}
|
|
|
|
/**
|
|
- * AERE ANCHOR V2: the extra scheme seals heard for a block, canonical order, unverified.
|
|
+ * 1(b): move the pending seals of block n under their round, once the block is known: a pending entry whose
|
|
+ * digest is the block's commit digest at its round is recorded under (n, hash, r), through the same rules as a
|
|
+ * heard seal; one whose digest is not (a losing proposal) stays until it falls out of the window.
|
|
+ *
|
|
+ * @param blockNumber n
|
|
+ * @param onchainBlockHash hash(n)
|
|
+ * @param commitDigestAtRound the block's commit digest at a round (the QBFT state machine computes it)
|
|
+ * @return how many pending entries were moved
|
|
+ */
|
|
+ public int resolvePending(
|
|
+ final long blockNumber, final Hash onchainBlockHash, final IntFunction<Hash> commitDigestAtRound) {
|
|
+ final List<Map.Entry<PendingKey, PendingEntry>> matched = new ArrayList<>();
|
|
+ synchronized (this) {
|
|
+ final Map<Integer, Hash> digestOfRound = new HashMap<>();
|
|
+ final List<PendingKey> keys = new ArrayList<>(pending.keySet());
|
|
+ for (final PendingKey k : keys) {
|
|
+ if (k.blockNumber() != blockNumber) {
|
|
+ continue;
|
|
+ }
|
|
+ Hash digest = digestOfRound.get(k.round());
|
|
+ if (digest == null) {
|
|
+ try {
|
|
+ digest = commitDigestAtRound.apply(k.round());
|
|
+ } catch (final RuntimeException ex) {
|
|
+ continue;
|
|
+ }
|
|
+ if (digest == null) {
|
|
+ continue;
|
|
+ }
|
|
+ digestOfRound.put(k.round(), digest);
|
|
+ }
|
|
+ if (k.commitDigest().equals(digest)) {
|
|
+ matched.add(Map.entry(k, pending.get(k)));
|
|
+ forgetPending(k);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ final List<PqSealWindowStore.Heard> lateFrames = new ArrayList<>();
|
|
+ for (final Map.Entry<PendingKey, PendingEntry> e : matched) {
|
|
+ final List<FalconSeal> f = new ArrayList<>();
|
|
+ for (final Map<Address, FalconSeal> byAuthor : e.getValue().falcon.values()) {
|
|
+ f.addAll(verifiedFirst(blockNumber, onchainBlockHash, e.getKey().round(), byAuthor.values()));
|
|
+ }
|
|
+ final List<SchemeSeal> x = new ArrayList<>();
|
|
+ for (final Map<Address, SchemeSeal> byAuthor : e.getValue().extras.values()) {
|
|
+ x.addAll(verifiedFirstExtras(blockNumber, onchainBlockHash, e.getKey().round(), byAuthor.values()));
|
|
+ }
|
|
+ record(blockNumber, onchainBlockHash, e.getKey().round(), f);
|
|
+ recordExtras(blockNumber, onchainBlockHash, e.getKey().round(), x);
|
|
+ lateFrames.addAll(lateWindowFrame(blockNumber, onchainBlockHash, e.getKey().round()));
|
|
+ }
|
|
+ // second review of step 4: a height already handed to the window journal does not reach it again on its own, so
|
|
+ // seals resolved after that would be lost at a restart; the round's record goes to the journal now (the reader
|
|
+ // merges frames of one (n, r, hash) slot by slot)
|
|
+ persistWindow(lateFrames);
|
|
+ return matched.size();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * 1(b): how many pending entries are held (for the probes).
|
|
+ *
|
|
+ * @return the count
|
|
+ */
|
|
+ public synchronized int pendingCount() {
|
|
+ return pending.size();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The extra scheme seals heard for a block in a round, canonical order, unverified (below H_r the round is
|
|
+ * ignored: the block's one record).
|
|
*
|
|
* @param blockNumber the height
|
|
* @param onchainBlockHash the round-independent on-chain hash
|
|
+ * @param round the round
|
|
* @return the seals, or empty when nothing was heard under that key
|
|
*/
|
|
public synchronized List<SchemeSeal> extrasFor(
|
|
- final long blockNumber, final Hash onchainBlockHash) {
|
|
- final Entry entry = byHash.get(onchainBlockHash);
|
|
+ final long blockNumber, final Hash onchainBlockHash, final int round) {
|
|
+ final Entry entry = byKey.get(new Key(onchainBlockHash, roundKey(blockNumber, round)));
|
|
if (entry == null || entry.blockNumber != blockNumber) {
|
|
return List.of();
|
|
}
|
|
final List<SchemeSeal> out = new ArrayList<>(entry.extras.values());
|
|
out.sort(PqAnchorV2.CANONICAL);
|
|
return out;
|
|
}
|
|
|
|
+ /**
|
|
+ * The Falcon seals heard for a block in a round, in canonical order (below H_r the round is ignored).
|
|
+ *
|
|
+ * @param blockNumber the height of the block the seals must attest
|
|
+ * @param onchainBlockHash the ON-CHAIN hash of that block
|
|
+ * @param round the round
|
|
+ * @return the seals, sorted by strictly increasing validator index, possibly empty
|
|
+ */
|
|
public synchronized List<FalconSeal> sealsFor(
|
|
- final long blockNumber, final Hash onchainBlockHash) {
|
|
- final Entry entry = byHash.get(onchainBlockHash);
|
|
+ final long blockNumber, final Hash onchainBlockHash, final int round) {
|
|
+ final Entry entry = byKey.get(new Key(onchainBlockHash, roundKey(blockNumber, round)));
|
|
if (entry == null || entry.blockNumber != blockNumber) {
|
|
return List.of();
|
|
}
|
|
return PqAnchor.sortedByIndex(new ArrayList<>(entry.seals.values()));
|
|
}
|
|
|
|
/**
|
|
- * How many block hashes are currently retained.
|
|
+ * 1(b): every round held for a block, increasing. Below H_r one entry under {@link #ANY_ROUND} (the block's
|
|
+ * one record), or none.
|
|
+ *
|
|
+ * @param blockNumber n
|
|
+ * @param onchainBlockHash hash(n)
|
|
+ * @return round to its seals
|
|
+ */
|
|
+ public synchronized NavigableMap<Integer, RoundSeals> roundsFor(
|
|
+ final long blockNumber, final Hash onchainBlockHash) {
|
|
+ final TreeMap<Integer, RoundSeals> out = new TreeMap<>();
|
|
+ for (final Map.Entry<Key, Entry> e : byKey.entrySet()) {
|
|
+ if (e.getKey().hash().equals(onchainBlockHash) && e.getValue().blockNumber == blockNumber) {
|
|
+ final List<SchemeSeal> extras = new ArrayList<>(e.getValue().extras.values());
|
|
+ extras.sort(PqAnchorV2.CANONICAL);
|
|
+ out.put(
|
|
+ e.getKey().round(),
|
|
+ new RoundSeals(PqAnchor.sortedByIndex(new ArrayList<>(e.getValue().seals.values())), List.copyOf(extras)));
|
|
+ }
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ /** 1(b): rows (Falcon tagged, plus extras) of every round of a block, for the SEALSTORE-2 file. Lock held. */
|
|
+ private NavigableMap<Integer, List<SchemeSeal>> roundsOf(final long blockNumber, final Hash onchainBlockHash) {
|
|
+ final TreeMap<Integer, List<SchemeSeal>> out = new TreeMap<>();
|
|
+ for (final Map.Entry<Key, Entry> e : byKey.entrySet()) {
|
|
+ if (e.getKey().round() >= 0
|
|
+ && e.getKey().hash().equals(onchainBlockHash)
|
|
+ && e.getValue().blockNumber == blockNumber) {
|
|
+ // second review of step 4: the head file holds only Falcon rows that VERIFY over their round's message (the
|
|
+ // store's judge, memoised) and the extras bound to them, each row bounded; garbage rounds never reach the file,
|
|
+ // so they cannot push the round that decided out of its 1 MiB, and the reader re-verifies everything anyway
|
|
+ final List<SchemeSeal> rows = new ArrayList<>();
|
|
+ final Set<Integer> kept = new HashSet<>();
|
|
+ for (final FalconSeal f : e.getValue().seals.values()) {
|
|
+ if (heldSealVerifies(
|
|
+ e.getValue(), blockNumber, onchainBlockHash, e.getKey().round(), f.getValidatorIndex(), f.getSignature())) {
|
|
+ rows.add(new SchemeSeal(SealSchemes.FALCON_512.wireId(), f.getValidatorIndex(), f.getSignature()));
|
|
+ kept.add(f.getValidatorIndex());
|
|
+ }
|
|
+ }
|
|
+ rows.addAll(boundExtras(e.getValue(), kept));
|
|
+ if (!rows.isEmpty()) {
|
|
+ rows.sort(PqAnchorV2.CANONICAL);
|
|
+ out.put(e.getKey().round(), rows);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ /** A row longer than this is never written to the head file (the largest seal of any scheme is ~7.9 kB). */
|
|
+ private static final int MAX_ROW_BYTES = 16 * 1024;
|
|
+
|
|
+ /** The extras of a record whose index keeps a verified Falcon row, each within {@link #MAX_ROW_BYTES}. */
|
|
+ private static List<SchemeSeal> boundExtras(final Entry entry, final Set<Integer> keptFalcon) {
|
|
+ final List<SchemeSeal> out = new ArrayList<>();
|
|
+ for (final SchemeSeal x : entry.extras.values()) {
|
|
+ if (keptFalcon.contains(x.getValidatorIndex()) && x.getSignature().size() <= MAX_ROW_BYTES) {
|
|
+ out.add(x);
|
|
+ }
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * 1(b): at most {@link #MAX_ROUNDS_PER_BLOCK} rounds per (n, hash). The round with the fewest VERIFIED Falcon seals
|
|
+ * leaves, the LARGER round on a tie. Lock held.
|
|
+ *
|
|
+ * <p>Review of step 4 (2026-10-01, a blocker): the first form ranked by seals HEARD and removed the smaller round on
|
|
+ * a tie, so one validator could send late Commits of eight rounds it chose, each with garbage seals of every index,
|
|
+ * and push the deciding round out of every proposer's store: no anchor from H_r on. Ranked by seals that verify over
|
|
+ * their own M_r (the store's judge, the producer's door; memoised per held seal, so each is judged once), a round
|
|
+ * of garbage counts 0, at most f byzantine members can sign a round of their choosing, and the round that decided
|
|
+ * holds a quorum. The larger round leaves on a tie because the attacker chooses round numbers and the honest round
|
|
+ * is the one that came first. With no judge armed (SealJudge.NONE: tests, a node without persistence) every round
|
|
+ * counts 0 and the tie rule alone decides.
|
|
+ */
|
|
+ private void enforceRoundCap(final long blockNumber, final Hash onchainBlockHash) {
|
|
+ while (true) {
|
|
+ // rank (and judge) only when the cap is exceeded: below it nothing leaves, and nothing is judged on the
|
|
+ // consensus thread for nothing (second review of step 4)
|
|
+ int held = 0;
|
|
+ for (final Map.Entry<Key, Entry> e : byKey.entrySet()) {
|
|
+ final Key k = e.getKey();
|
|
+ if (k.round() >= 0 && k.hash().equals(onchainBlockHash) && e.getValue().blockNumber == blockNumber) {
|
|
+ held++;
|
|
+ }
|
|
+ }
|
|
+ if (held <= MAX_ROUNDS_PER_BLOCK) {
|
|
+ return;
|
|
+ }
|
|
+ Key weakest = null;
|
|
+ int weakestVerified = 0;
|
|
+ int rounds = 0;
|
|
+ for (final Map.Entry<Key, Entry> e : byKey.entrySet()) {
|
|
+ final Key k = e.getKey();
|
|
+ if (k.round() < 0 || !k.hash().equals(onchainBlockHash) || e.getValue().blockNumber != blockNumber) {
|
|
+ continue;
|
|
+ }
|
|
+ rounds++;
|
|
+ final int v = verifiedForRank(e.getValue(), blockNumber, onchainBlockHash, k.round());
|
|
+ if (weakest == null || v < weakestVerified || (v == weakestVerified && k.round() > weakest.round())) {
|
|
+ weakest = k;
|
|
+ weakestVerified = v;
|
|
+ }
|
|
+ }
|
|
+ if (rounds <= MAX_ROUNDS_PER_BLOCK || weakest == null) {
|
|
+ return;
|
|
+ }
|
|
+ byKey.remove(weakest);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many held Falcon seals of a record verify over the message of its round, for the round cap only. A seal already
|
|
+ * known verified (D-454) counts without a new judgement; any other is judged once per held signature. Lock held.
|
|
+ */
|
|
+ private int verifiedForRank(final Entry entry, final long blockNumber, final Hash onchainBlockHash, final int round) {
|
|
+ int count = 0;
|
|
+ for (final Map.Entry<Integer, FalconSeal> s : entry.seals.entrySet()) {
|
|
+ if (heldSealVerifies(entry, blockNumber, onchainBlockHash, round, s.getKey(), s.getValue().getSignature())) {
|
|
+ count++;
|
|
+ }
|
|
+ }
|
|
+ return count;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Whether the Falcon seal a record holds for an index verifies over its round's message: known verified (D-454), or
|
|
+ * judged by the store's judge, once per held signature (memoised in the record). Lock held.
|
|
+ */
|
|
+ private boolean heldSealVerifies(
|
|
+ final Entry entry,
|
|
+ final long blockNumber,
|
|
+ final Hash onchainBlockHash,
|
|
+ final int round,
|
|
+ final int index,
|
|
+ final Bytes signature) {
|
|
+ if (entry.verified.contains(index)) {
|
|
+ return true;
|
|
+ }
|
|
+ if (signature.equals(entry.rankJudgedSignature.get(index))) {
|
|
+ return entry.rankVerified.contains(index);
|
|
+ }
|
|
+ boolean ok;
|
|
+ try {
|
|
+ ok = judge.verifies(blockNumber, onchainBlockHash, round, SealSchemes.FALCON_512.wireId(), index, signature);
|
|
+ } catch (final RuntimeException e) {
|
|
+ ok = false;
|
|
+ }
|
|
+ if (ok) {
|
|
+ entry.rankJudgedSignature.put(index, signature);
|
|
+ entry.rankVerified.add(index);
|
|
+ } else if (registryCanJudge(blockNumber, index)) {
|
|
+ // a NEGATIVE verdict is remembered only when the registry could judge it (bound and the index resolving): false
|
|
+ // from a door that was not ready (registry PENDING, D-358) means "not shown valid", never "shown invalid", and a
|
|
+ // genuine seal must be judged again once the door works (third review of step 4; the AereVoteCounts lesson of
|
|
+ // 2026-09-30). Unbound indices are not remembered and cost no Falcon verification to judge again.
|
|
+ entry.rankJudgedSignature.put(index, signature);
|
|
+ entry.rankVerified.remove(index);
|
|
+ } else {
|
|
+ entry.rankJudgedSignature.remove(index);
|
|
+ entry.rankVerified.remove(index);
|
|
+ }
|
|
+ return ok;
|
|
+ }
|
|
+
|
|
+ /** Whether the registry can give a FINAL negative verdict for this index at this height (bound and resolving). */
|
|
+ private static boolean registryCanJudge(final long blockNumber, final int index) {
|
|
+ try {
|
|
+ return FalconSealSupport.instance().addressBound()
|
|
+ && PqSignerRegistry.falconSealSupport().addressForIndexAtOwnHead(blockNumber, index) != null;
|
|
+ } catch (final RuntimeException e) {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Whether a record (or a pending entry) bounded to {@link #MAX_SEALS_PER_ROUND} indices takes a seal of this index:
|
|
+ * yes when the index is held or there is room; when full, yes only if a HIGHER index is held, which then leaves (and
|
|
+ * its judgements with it, when {@code entry} is given). The registry's indices are dense from 0, so a flood above them
|
|
+ * cannot displace an honest seal. Lock held.
|
|
+ */
|
|
+ private static boolean admitIndex(final Map<Integer, FalconSeal> slots, final int index, final Entry entry) {
|
|
+ if (slots.containsKey(index) || slots.size() < MAX_SEALS_PER_ROUND) {
|
|
+ return true;
|
|
+ }
|
|
+ int highest = -1;
|
|
+ for (final int i : slots.keySet()) {
|
|
+ highest = Math.max(highest, i);
|
|
+ }
|
|
+ if (index >= highest) {
|
|
+ return false;
|
|
+ }
|
|
+ slots.remove(highest);
|
|
+ if (entry != null) {
|
|
+ entry.verified.remove(highest);
|
|
+ entry.rankVerified.remove(highest);
|
|
+ entry.rankJudgedSignature.remove(highest);
|
|
+ }
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ /** The same bound for the extras of a record (keyed index << 8 | scheme), at twice the Falcon bound. Lock held. */
|
|
+ private static boolean admitExtra(final Entry entry, final long key) {
|
|
+ final boolean ok = admitIndexKey(entry.extras, key, 2 * MAX_SEALS_PER_ROUND);
|
|
+ // a key that left takes its D-454 judgement with it
|
|
+ entry.extrasVerified.retainAll(entry.extras.keySet());
|
|
+ return ok;
|
|
+ }
|
|
+
|
|
+ private static <V> boolean admitIndexKey(final Map<Long, V> slots, final long key, final int bound) {
|
|
+ if (slots.containsKey(key) || slots.size() < bound) {
|
|
+ return true;
|
|
+ }
|
|
+ long highest = -1L;
|
|
+ for (final long k : slots.keySet()) {
|
|
+ highest = Math.max(highest, k);
|
|
+ }
|
|
+ if (key >= highest) {
|
|
+ return false;
|
|
+ }
|
|
+ slots.remove(highest);
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many records are currently retained (below H_r: one per block hash, as before).
|
|
*
|
|
* @return the number of entries
|
|
*/
|
|
public synchronized int entryCount() {
|
|
- return byHash.size();
|
|
+ return byKey.size();
|
|
}
|
|
|
|
/**
|
|
- * How many seals are retained for a block hash.
|
|
+ * How many seals are retained for a block hash, over every round.
|
|
*
|
|
* @param onchainBlockHash the ON-CHAIN hash
|
|
* @return the seal count, 0 when nothing is retained
|
|
*/
|
|
public synchronized int sealCount(final Hash onchainBlockHash) {
|
|
- final Entry entry = byHash.get(onchainBlockHash);
|
|
- return entry == null ? 0 : entry.seals.size();
|
|
+ int count = 0;
|
|
+ for (final Map.Entry<Key, Entry> e : byKey.entrySet()) {
|
|
+ if (e.getKey().hash().equals(onchainBlockHash)) {
|
|
+ count += e.getValue().seals.size();
|
|
+ }
|
|
+ }
|
|
+ return count;
|
|
}
|
|
|
|
/**
|
|
* Drop everything held in memory. For tests, and for a deliberate operator reset. The file, if
|
|
* one exists, is deliberately left alone: it is rewritten by the next commit this node hears.
|
|
*/
|
|
public synchronized void clear() {
|
|
- byHash.clear();
|
|
+ byKey.clear();
|
|
+ pending.clear();
|
|
+ pendingByAuthor.clear();
|
|
highestSeen = -1L;
|
|
windowJournaledThrough = -1L; // what clear() forgets, the journal mark forgets too
|
|
synchronized (writeLock) {
|
|
persistedBlock = -1L;
|
|
persistedHash = null;
|
|
persistedCount = -1;
|
|
+ persistedRoundsBytes = Bytes.EMPTY;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* AIP-21, second half. Everything heard BELOW a height that has just begun and not yet handed to
|
|
- * the window journal. Caller holds the map lock.
|
|
+ * the window journal. Caller holds the map lock. 1(b): a record of a round-bound height becomes a
|
|
+ * SEALWINDOW-2 frame, one per (n, r, hash); below H_r a SEALWINDOW-1 frame, as before.
|
|
*
|
|
* @param newHeight the height that has just begun
|
|
* @return the heard blocks to journal, possibly empty
|
|
*/
|
|
private List<PqSealWindowStore.Heard> windowSnapshotBelow(final long newHeight) {
|
|
if (windowDirectory == null) {
|
|
return List.of();
|
|
}
|
|
final List<PqSealWindowStore.Heard> out = new ArrayList<>();
|
|
- for (final Map.Entry<Hash, Entry> e : byHash.entrySet()) {
|
|
+ for (final Map.Entry<Key, Entry> e : byKey.entrySet()) {
|
|
final long n = e.getValue().blockNumber;
|
|
if (n > windowJournaledThrough && n < newHeight && !e.getValue().seals.isEmpty()) {
|
|
- out.add(PqSealWindowStore.heard(n, e.getKey().getBytes(), e.getValue().seals.values()));
|
|
+ out.add(
|
|
+ e.getKey().round() == ANY_ROUND
|
|
+ ? PqSealWindowStore.heard(n, e.getKey().hash().getBytes(), e.getValue().seals.values())
|
|
+ : PqSealWindowStore.heardRound(
|
|
+ n, e.getKey().round(), e.getKey().hash().getBytes(), e.getValue().seals.values()));
|
|
}
|
|
}
|
|
windowJournaledThrough = Math.max(windowJournaledThrough, newHeight - 1L);
|
|
return out;
|
|
}
|
|
|
|
private void persistWindow(final List<PqSealWindowStore.Heard> heard) {
|
|
final Path directory = windowDirectory;
|
|
if (directory == null || heard.isEmpty()) {
|
|
return;
|
|
}
|
|
synchronized (writeLock) {
|
|
try {
|
|
long highest = -1L;
|
|
for (final PqSealWindowStore.Heard h : heard) {
|
|
PqSealWindowStore.append(directory, persistenceChainId, h);
|
|
highest = Math.max(highest, h.blockNumber());
|
|
}
|
|
final long segment = highest / PqSealWindowStore.SEGMENT_BLOCKS;
|
|
if (segment != windowPrunedSegment) {
|
|
PqSealWindowStore.pruneSegments(directory, highest, HEIGHT_WINDOW);
|
|
windowPrunedSegment = segment;
|
|
}
|
|
} catch (final Exception e) {
|
|
// A disk fault must not be able to stop this node from taking part in consensus. It costs the
|
|
// answer aere_getPqFinality gives for these blocks after a restart, and nothing else.
|
|
LOG.warn(
|
|
"AERE FEREASTRA-SIGILII: could not append {} heard block(s) to the window journal {} ({}). "
|
|
+ "This node keeps working; after a restart it answers 'unavailable' for them.",
|
|
heard.size(),
|
|
directory,
|
|
e.toString());
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* AIP-21, second half. Bring the finality window back after a restart. Nothing in the journal is
|
|
* believed: a frame counts only if its hash is the CANONICAL hash this node's own chain holds at
|
|
- * that height, and each seal only if it verifies, against the registry epoch bound at that height,
|
|
- * over the commit message rebuilt from that canonical hash. Never throws.
|
|
+ * that height, its FORM is the form of its height (1(b): a SEALWINDOW-1 frame at a round-bound height, or a
|
|
+ * SEALWINDOW-2 frame below it, is dropped), and each seal only if it verifies, against the registry epoch bound
|
|
+ * at that height, over the commit message rebuilt (through the one place) from that canonical hash and the
|
|
+ * frame's round. Never throws.
|
|
*
|
|
* @param headNumber this node's chain head
|
|
* @param canonicalHashAt the canonical on-chain hash at a height, empty when the chain holds none
|
|
* @param registry the anchored registry seals are verified against
|
|
* @return how many verified seals entered the window
|
|
*/
|
|
public int restoreWindowFromDisk(
|
|
final long headNumber,
|
|
final java.util.function.LongFunction<java.util.Optional<Hash>> canonicalHashAt,
|
|
final PqSignerRegistry registry) {
|
|
final Path directory = windowDirectory;
|
|
if (directory == null || canonicalHashAt == null || registry == null) {
|
|
return 0;
|
|
}
|
|
int restored = 0;
|
|
try {
|
|
final long from = Math.max(0L, headNumber - Math.min(HEIGHT_WINDOW, MAX_RESTORED_HEIGHTS));
|
|
final List<PqSealWindowStore.Heard> frames =
|
|
PqSealWindowStore.readAll(directory, persistenceChainId, from, headNumber);
|
|
long highestInJournal = -1L;
|
|
int notCanonical = 0;
|
|
+ int wrongForm = 0;
|
|
int rejected = 0;
|
|
- final LinkedHashMap<Hash, Entry> verified = new LinkedHashMap<>();
|
|
+ final LinkedHashMap<Key, Entry> verified = new LinkedHashMap<>();
|
|
for (final PqSealWindowStore.Heard frame : frames) {
|
|
final long n = frame.blockNumber();
|
|
highestInJournal = Math.max(highestInJournal, n);
|
|
final java.util.Optional<Hash> canonical = canonicalHashAt.apply(n);
|
|
if (canonical == null
|
|
|| canonical.isEmpty()
|
|
|| !canonical.get().getBytes().equals(frame.blockHash())) {
|
|
notCanonical++;
|
|
continue;
|
|
}
|
|
- final org.apache.tuweni.bytes.Bytes32 message =
|
|
- PqAnchor.commitMessage(persistenceChainId, n, frame.blockHash());
|
|
+ final boolean roundBound = roundKey(n, 0) != ANY_ROUND;
|
|
+ final boolean form2 = frame.round() != PqSealWindowStore.NO_ROUND;
|
|
+ if (roundBound != form2) {
|
|
+ wrongForm++;
|
|
+ continue;
|
|
+ }
|
|
+ final java.util.Optional<org.apache.tuweni.bytes.Bytes32> message =
|
|
+ form2
|
|
+ ? PqAnchorProducer.roundBoundMessage(persistenceChainId, n, frame.round(), frame.blockHash())
|
|
+ : java.util.Optional.of(PqAnchorProducer.roundFreeMessage(persistenceChainId, n, frame.blockHash()));
|
|
+ if (message.isEmpty()) {
|
|
+ wrongForm++;
|
|
+ continue;
|
|
+ }
|
|
+ final Key key = new Key(canonical.get(), form2 ? frame.round() : ANY_ROUND);
|
|
for (final FalconSeal seal : frame.seals()) {
|
|
if (seal == null
|
|
|| seal.getValidatorIndex() < 0
|
|
|| seal.getSignature() == null
|
|
|| !registry.verifyAtHistoric(
|
|
- n, seal.getValidatorIndex(), message, seal.getSignature())) {
|
|
+ n, seal.getValidatorIndex(), message.get(), seal.getSignature())) {
|
|
rejected++;
|
|
continue;
|
|
}
|
|
- final Entry entry = verified.computeIfAbsent(canonical.get(), unused -> new Entry(n));
|
|
+ final Entry entry = verified.computeIfAbsent(key, unused -> new Entry(n));
|
|
if (entry.seals.putIfAbsent(seal.getValidatorIndex(), seal) == null) {
|
|
restored++;
|
|
}
|
|
}
|
|
}
|
|
synchronized (this) {
|
|
// Oldest first, so the size cap still evicts the oldest: the restored heights go in BEFORE
|
|
// what this node already holds (its head, restored a moment ago from the head file).
|
|
- final LinkedHashMap<Hash, Entry> held = new LinkedHashMap<>(byHash);
|
|
- byHash.clear();
|
|
- byHash.putAll(verified);
|
|
- for (final Map.Entry<Hash, Entry> e : held.entrySet()) {
|
|
- final Entry target = byHash.get(e.getKey());
|
|
+ final LinkedHashMap<Key, Entry> held = new LinkedHashMap<>(byKey);
|
|
+ byKey.clear();
|
|
+ byKey.putAll(verified);
|
|
+ for (final Map.Entry<Key, Entry> e : held.entrySet()) {
|
|
+ final Entry target = byKey.get(e.getKey());
|
|
if (target == null) {
|
|
- byHash.put(e.getKey(), e.getValue());
|
|
+ byKey.put(e.getKey(), e.getValue());
|
|
} else {
|
|
e.getValue().seals.forEach(target.seals::putIfAbsent);
|
|
e.getValue().extras.forEach(target.extras::putIfAbsent);
|
|
}
|
|
}
|
|
- for (final Entry entry : verified.values()) {
|
|
- if (entry.blockNumber > highestSeen) {
|
|
- highestSeen = entry.blockNumber;
|
|
+ for (final Map.Entry<Key, Entry> e : verified.entrySet()) {
|
|
+ if (e.getValue().blockNumber > highestSeen) {
|
|
+ highestSeen = e.getValue().blockNumber;
|
|
+ }
|
|
+ if (e.getKey().round() >= 0) {
|
|
+ enforceRoundCap(e.getValue().blockNumber, e.getKey().hash());
|
|
}
|
|
}
|
|
windowJournaledThrough = Math.max(windowJournaledThrough, highestInJournal);
|
|
prune();
|
|
}
|
|
LOG.info(
|
|
- "AERE FEREASTRA-SIGILII: {} verified seal(s) over {} block(s) restored into the finality "
|
|
- + "window from {} ({} frame(s) read, {} not canonical on this chain, {} seal(s) FAILED "
|
|
- + "verification and were dropped).",
|
|
+ "AERE FEREASTRA-SIGILII: {} verified seal(s) over {} record(s) restored into the finality "
|
|
+ + "window from {} ({} frame(s) read, {} not canonical on this chain, {} in the wrong form for "
|
|
+ + "their height, {} seal(s) FAILED verification and were dropped).",
|
|
restored,
|
|
verified.size(),
|
|
directory,
|
|
frames.size(),
|
|
notCanonical,
|
|
+ wrongForm,
|
|
rejected);
|
|
} catch (final RuntimeException e) {
|
|
LOG.warn(
|
|
"AERE FEREASTRA-SIGILII: restoring the finality window from {} failed unexpectedly ({}); "
|
|
+ "the window starts empty, exactly as before this journal existed.",
|
|
directory,
|
|
e.toString());
|
|
return 0;
|
|
}
|
|
return restored;
|
|
}
|
|
|
|
private void prune() {
|
|
- final Iterator<Map.Entry<Hash, Entry>> it = byHash.entrySet().iterator();
|
|
+ final Iterator<Map.Entry<Key, Entry>> it = byKey.entrySet().iterator();
|
|
while (it.hasNext()) {
|
|
- final Map.Entry<Hash, Entry> e = it.next();
|
|
+ final Map.Entry<Key, Entry> e = it.next();
|
|
if (highestSeen - e.getValue().blockNumber > HEIGHT_WINDOW) {
|
|
it.remove();
|
|
}
|
|
}
|
|
- while (byHash.size() > MAX_ENTRIES) {
|
|
- final Iterator<Hash> oldest = byHash.keySet().iterator();
|
|
+ while (byKey.size() > MAX_ENTRIES) {
|
|
+ final Iterator<Key> oldest = byKey.keySet().iterator();
|
|
oldest.next();
|
|
oldest.remove();
|
|
}
|
|
}
|
|
|
|
private static final class Entry {
|
|
private final long blockNumber;
|
|
private final Map<Integer, FalconSeal> seals = new LinkedHashMap<>();
|
|
/** AERE ANCHOR V2: heard extra (non-Falcon) scheme seals, keyed (index << 8 | wire). */
|
|
private final Map<Long, SchemeSeal> extras = new LinkedHashMap<>();
|
|
/** D-454 family: the indices (and the extra-seal keys) whose held seal VERIFIED. */
|
|
private final Set<Integer> verified = new HashSet<>();
|
|
|
|
private final Set<Long> extrasVerified = new HashSet<>();
|
|
|
|
+ /** 1(b): for the round cap, the indices whose held seal was judged and the signature that was judged. */
|
|
+ private final Map<Integer, Bytes> rankJudgedSignature = new HashMap<>();
|
|
+
|
|
+ /** 1(b): for the round cap, the indices whose judged seal verified. */
|
|
+ private final Set<Integer> rankVerified = new HashSet<>();
|
|
+
|
|
private Entry(final long blockNumber) {
|
|
this.blockNumber = blockNumber;
|
|
}
|
|
}
|
|
+
|
|
+ /**
|
|
+ * 1(b): a pending entry (D-339 at r > 0): per index (at most {@link #MAX_SEALS_PER_ROUND}, the lowest), one seal per
|
|
+ * AUTHOR that named it; the same for the extras (keyed index << 8 | scheme); the authors that contributed (their
|
|
+ * quota).
|
|
+ */
|
|
+ private static final class PendingEntry {
|
|
+ private final Map<Long, Map<Address, FalconSeal>> falcon = new LinkedHashMap<>();
|
|
+ private final Map<Long, Map<Address, SchemeSeal>> extras = new LinkedHashMap<>();
|
|
+ private final Set<Address> authors = new LinkedHashSet<>();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The variants several authors gave for ONE index of a pending entry, the first that the store's judge verifies over
|
|
+ * the round's message first (second review of step 4): a garbage seal named first by a byzantine author must not win
|
|
+ * the slot over the genuine one, below H_fin either. One variant: returned as is, nothing judged.
|
|
+ */
|
|
+ private List<FalconSeal> verifiedFirst(
|
|
+ final long blockNumber, final Hash onchainBlockHash, final int round, final Collection<FalconSeal> variants) {
|
|
+ final List<FalconSeal> out = new ArrayList<>(variants);
|
|
+ if (out.size() < 2) {
|
|
+ return out;
|
|
+ }
|
|
+ final SealJudge j = judge;
|
|
+ for (int i = 0; i < out.size(); i++) {
|
|
+ final FalconSeal s = out.get(i);
|
|
+ boolean ok;
|
|
+ try {
|
|
+ ok = j.verifies(blockNumber, onchainBlockHash, round, SealSchemes.FALCON_512.wireId(), s.getValidatorIndex(), s.getSignature());
|
|
+ } catch (final RuntimeException e) {
|
|
+ ok = false;
|
|
+ }
|
|
+ if (ok) {
|
|
+ out.remove(i);
|
|
+ out.add(0, s);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ /** The same ordering for the variants of one (index, scheme) of the extras (third review of step 4). */
|
|
+ private List<SchemeSeal> verifiedFirstExtras(
|
|
+ final long blockNumber, final Hash onchainBlockHash, final int round, final Collection<SchemeSeal> variants) {
|
|
+ final List<SchemeSeal> out = new ArrayList<>(variants);
|
|
+ if (out.size() < 2) {
|
|
+ return out;
|
|
+ }
|
|
+ final SealJudge j = judge;
|
|
+ for (int i = 0; i < out.size(); i++) {
|
|
+ final SchemeSeal s = out.get(i);
|
|
+ boolean ok;
|
|
+ try {
|
|
+ ok = j.verifies(blockNumber, onchainBlockHash, round, s.getSchemeWireId(), s.getValidatorIndex(), s.getSignature());
|
|
+ } catch (final RuntimeException e) {
|
|
+ ok = false;
|
|
+ }
|
|
+ if (ok) {
|
|
+ out.remove(i);
|
|
+ out.add(0, s);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The SEALWINDOW-2 frame of one round of a height ALREADY handed to the window journal (empty otherwise, and below
|
|
+ * H_r, where nothing is resolved late).
|
|
+ */
|
|
+ private synchronized List<PqSealWindowStore.Heard> lateWindowFrame(
|
|
+ final long blockNumber, final Hash onchainBlockHash, final int round) {
|
|
+ final int rk = roundKey(blockNumber, round);
|
|
+ if (windowDirectory == null || rk < 0 || blockNumber > windowJournaledThrough) {
|
|
+ return List.of();
|
|
+ }
|
|
+ final Entry entry = byKey.get(new Key(onchainBlockHash, rk));
|
|
+ if (entry == null || entry.seals.isEmpty()) {
|
|
+ return List.of();
|
|
+ }
|
|
+ return List.of(PqSealWindowStore.heardRound(blockNumber, rk, onchainBlockHash.getBytes(), entry.seals.values()));
|
|
+ }
|
|
}
|
|
diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqSealStore.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqSealStore.java
|
|
index 6427140deb..507fa4329b 100755
|
|
--- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqSealStore.java
|
|
+++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqSealStore.java
|
|
@@ -312,80 +312,354 @@ public final class PqSealStore {
|
|
+ "cache starts empty. This costs at most one proposer turn; refusing to start would "
|
|
+ "cost the chain.",
|
|
file,
|
|
e.toString());
|
|
return List.of();
|
|
}
|
|
|
|
if (storedNumber != blockNumber || !storedHash.equals(blockHash.getBytes())) {
|
|
LOG.info(
|
|
"AERE PERSISTENTA-SIGILII: seal file {} holds seals for block {} ({}), this node's head is "
|
|
+ "{} ({}); IGNORED. Seals over another block are of no use to the proposer of the "
|
|
+ "next one.",
|
|
file,
|
|
storedNumber,
|
|
storedHash,
|
|
blockNumber,
|
|
blockHash);
|
|
return List.of();
|
|
}
|
|
|
|
- final Bytes32 message = PqAnchor.commitMessage(chainId, blockNumber, blockHash.getBytes());
|
|
+ // 1(b) (2026-10-01): a form-1 file names no round. At a height whose commit seals are ROUND-BOUND it cannot be
|
|
+ // verified honestly and is never reinterpreted as round 0: dropped with a WARN (the head then restores from a
|
|
+ // SEALSTORE-2 file, readVerifiedRounds). Below H_r the reading of before, byte for byte, through the one place.
|
|
+ if (org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer.commitSealFormAt(
|
|
+ org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer.config(), blockNumber)
|
|
+ == org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer.CommitSealForm.ROUND_BOUND) {
|
|
+ LOG.warn(
|
|
+ "AERE PERSISTENTA-SIGILII: seal file {} is in the round-free form {} for block {}, whose commit seals are"
|
|
+ + " bound to their round (H_r); IGNORED, never read as round 0.",
|
|
+ file,
|
|
+ DOMAIN,
|
|
+ blockNumber);
|
|
+ return List.of();
|
|
+ }
|
|
+ final Bytes32 message =
|
|
+ org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer.roundFreeMessage(
|
|
+ chainId, blockNumber, blockHash.getBytes());
|
|
final List<FalconSeal> verified = new ArrayList<>();
|
|
final Set<Integer> seen = new LinkedHashSet<>();
|
|
int rejectedUnknownIndex = 0;
|
|
int rejectedSignature = 0;
|
|
for (final FalconSeal seal : PqAnchor.sortedByIndex(decoded)) {
|
|
if (seal.getValidatorIndex() < 0
|
|
|| seal.getSignature() == null
|
|
|| !seen.add(seal.getValidatorIndex())
|
|
// D2 (2026-08-06): height-resolved. These seals are over block `blockNumber`, which the
|
|
// caller has already matched against the stored header, so the height is known exactly.
|
|
// On a restart at the head this resolves to the same registry it always did; the point is
|
|
// that it can no longer resolve to a DIFFERENT one without saying so.
|
|
// D2 (b-v2): the OWN-HEAD door. The caller has already refused this file unless the
|
|
// stored block number and hash equal this node's head, so the subject is this node's
|
|
// own head by construction.
|
|
|| registry.addressForIndexAtOwnHead(blockNumber, seal.getValidatorIndex()) == null) {
|
|
rejectedUnknownIndex++;
|
|
continue;
|
|
}
|
|
if (!sealVerifiesAgainstAnchoredRegistry(
|
|
registry, blockNumber, message, seal.getValidatorIndex(), seal.getSignature())) {
|
|
rejectedSignature++;
|
|
continue;
|
|
}
|
|
verified.add(seal);
|
|
}
|
|
|
|
LOG.info(
|
|
"AERE PERSISTENTA-SIGILII: restored {} of {} stored seal(s) for head {} from {}; {} had no "
|
|
+ "registry index, {} FAILED Falcon verification over M(head) and were dropped.",
|
|
verified.size(),
|
|
decoded.size(),
|
|
blockNumber,
|
|
file,
|
|
rejectedUnknownIndex,
|
|
rejectedSignature);
|
|
return verified;
|
|
}
|
|
|
|
+ /** 1(b) (2026-10-01): the domain of the ROUND-BOUND head file, from H_r - 1. */
|
|
+ public static final String DOMAIN_2 = "AERE-PQ-SEALSTORE-2";
|
|
+
|
|
+ private static final Bytes DOMAIN_2_BYTES = Bytes.wrap(DOMAIN_2.getBytes(StandardCharsets.US_ASCII));
|
|
+
|
|
+ /**
|
|
+ * AERE 1(b), SEALSTORE-2 (section 3.1 G): the head's seals of EVERY round this node holds, extras included
|
|
+ * (the gap that stopped 2800 on 2026-09-04: extras were never persisted), as
|
|
+ * RLP["AERE-PQ-SEALSTORE-2", chainId, n, hash, [[r, [[scheme, index, signature], ...]], ...]] with the rounds
|
|
+ * strictly increasing and every row list canonical. Above {@link #MAX_FILE_BYTES} the rounds with the most
|
|
+ * seals are kept and the rest dropped with a WARN: a short file is a lost proposer turn, a missing one the
|
|
+ * same, an oversized one nothing a reader accepts.
|
|
+ *
|
|
+ * @param chainId the chain id
|
|
+ * @param blockNumber n
|
|
+ * @param blockHash hash(n)
|
|
+ * @param rounds round to rows (Falcon and extras), any order
|
|
+ * @return the file payload
|
|
+ */
|
|
+ public static byte[] encodeRounds(
|
|
+ final long chainId,
|
|
+ final long blockNumber,
|
|
+ final Bytes blockHash,
|
|
+ final java.util.NavigableMap<Integer, List<SchemeSeal>> rounds) {
|
|
+ final java.util.TreeMap<Integer, List<SchemeSeal>> kept = new java.util.TreeMap<>(rounds);
|
|
+ while (true) {
|
|
+ final byte[] bytes = encodeRoundsOnce(chainId, blockNumber, blockHash, kept);
|
|
+ if (bytes.length <= MAX_FILE_BYTES || kept.size() <= 1) {
|
|
+ return bytes;
|
|
+ }
|
|
+ // the same ranking as the store's round cap (review of step 4): the fewest FALCON rows leaves, the larger round
|
|
+ // on a tie; extras do not make a round stronger (a SLH-DSA row is ten times a Falcon row, not ten seals)
|
|
+ Integer weakest = null;
|
|
+ int weakestFalcon = 0;
|
|
+ for (final java.util.Map.Entry<Integer, List<SchemeSeal>> e : kept.entrySet()) {
|
|
+ final int falcon =
|
|
+ (int) e.getValue().stream().filter(s -> s.getSchemeWireId() == SealSchemes.FALCON_512.wireId()).count();
|
|
+ if (weakest == null || falcon < weakestFalcon || (falcon == weakestFalcon && e.getKey() > weakest)) {
|
|
+ weakest = e.getKey();
|
|
+ weakestFalcon = falcon;
|
|
+ }
|
|
+ }
|
|
+ LOG.warn(
|
|
+ "AERE PERSISTENTA-SIGILII: the seals of block {} exceed {} bytes; round {} ({} seal(s)) is not written.",
|
|
+ blockNumber,
|
|
+ MAX_FILE_BYTES,
|
|
+ weakest,
|
|
+ kept.get(weakest).size());
|
|
+ kept.remove(weakest);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static byte[] encodeRoundsOnce(
|
|
+ final long chainId,
|
|
+ final long blockNumber,
|
|
+ final Bytes blockHash,
|
|
+ final java.util.NavigableMap<Integer, List<SchemeSeal>> rounds) {
|
|
+ final BytesValueRLPOutput out = new BytesValueRLPOutput();
|
|
+ out.startList();
|
|
+ out.writeBytes(DOMAIN_2_BYTES);
|
|
+ out.writeLongScalar(chainId);
|
|
+ out.writeLongScalar(blockNumber);
|
|
+ out.writeBytes(blockHash);
|
|
+ out.startList();
|
|
+ for (final java.util.Map.Entry<Integer, List<SchemeSeal>> e : rounds.entrySet()) {
|
|
+ final List<SchemeSeal> rows = new ArrayList<>(e.getValue());
|
|
+ rows.sort(PqAnchorV2.CANONICAL);
|
|
+ out.startList();
|
|
+ out.writeIntScalar(e.getKey());
|
|
+ out.writeList(
|
|
+ rows,
|
|
+ (seal, rlp) -> {
|
|
+ rlp.startList();
|
|
+ rlp.writeIntScalar(seal.getSchemeWireId() & 0xff);
|
|
+ rlp.writeIntScalar(seal.getValidatorIndex());
|
|
+ rlp.writeBytes(seal.getSignature());
|
|
+ rlp.endList();
|
|
+ });
|
|
+ out.endList();
|
|
+ }
|
|
+ out.endList();
|
|
+ out.endList();
|
|
+ return out.encoded().toArrayUnsafe();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * AERE 1(b): read a SEALSTORE-2 file for the head and return, per round, ONLY the rows that verify RIGHT NOW
|
|
+ * over M_r(head): Falcon seals of distinct bound indices on the own-head door (as the producer), and extras
|
|
+ * bound to a Falcon seal of the same index kept in the same round, under the key the producer resolves.
|
|
+ * Nothing is believed because it is in the file. Never throws: any fault gives an empty map and a log line.
|
|
+ *
|
|
+ * @param file the seal file
|
|
+ * @param chainId the chain id this node runs
|
|
+ * @param blockNumber the head's height
|
|
+ * @param blockHash the head's on-chain hash
|
|
+ * @param registry the anchored Falcon registry
|
|
+ * @return round to verified rows (canonical), possibly empty
|
|
+ */
|
|
+ public static java.util.NavigableMap<Integer, List<SchemeSeal>> readVerifiedRounds(
|
|
+ final Path file,
|
|
+ final long chainId,
|
|
+ final long blockNumber,
|
|
+ final Hash blockHash,
|
|
+ final PqSignerRegistry registry) {
|
|
+ final java.util.TreeMap<Integer, List<SchemeSeal>> out = new java.util.TreeMap<>();
|
|
+ if (file == null || registry == null || blockHash == null) {
|
|
+ return out;
|
|
+ }
|
|
+ final byte[] raw;
|
|
+ try {
|
|
+ if (!Files.isRegularFile(file)) {
|
|
+ return out;
|
|
+ }
|
|
+ final long size = Files.size(file);
|
|
+ if (size <= 0 || size > MAX_FILE_BYTES) {
|
|
+ LOG.warn("AERE PERSISTENTA-SIGILII: seal file {} has an implausible size ({} bytes); IGNORED.", file, size);
|
|
+ return out;
|
|
+ }
|
|
+ raw = Files.readAllBytes(file);
|
|
+ } catch (final Exception e) {
|
|
+ LOG.warn("AERE PERSISTENTA-SIGILII: seal file {} could not be read ({}); IGNORED.", file, e.toString());
|
|
+ return out;
|
|
+ }
|
|
+ final java.util.TreeMap<Integer, List<SchemeSeal>> decoded = new java.util.TreeMap<>();
|
|
+ try {
|
|
+ final RLPInput in = new BytesValueRLPInput(Bytes.wrap(raw), false);
|
|
+ in.enterList();
|
|
+ final Bytes domain = in.readBytes();
|
|
+ if (!DOMAIN_2_BYTES.equals(domain)) {
|
|
+ LOG.info("AERE PERSISTENTA-SIGILII: seal file {} carries domain {} instead of {}; IGNORED.", file, domain, DOMAIN_2);
|
|
+ return out;
|
|
+ }
|
|
+ if (in.readLongScalar() != chainId) {
|
|
+ LOG.warn("AERE PERSISTENTA-SIGILII: seal file {} was written for another chain; IGNORED.", file);
|
|
+ return out;
|
|
+ }
|
|
+ final long storedNumber = in.readLongScalar();
|
|
+ final Bytes storedHash = in.readBytes();
|
|
+ if (storedNumber != blockNumber || !storedHash.equals(blockHash.getBytes())) {
|
|
+ LOG.info(
|
|
+ "AERE PERSISTENTA-SIGILII: seal file {} holds block {} ({}), the head is {} ({}); IGNORED.",
|
|
+ file, storedNumber, storedHash, blockNumber, blockHash);
|
|
+ return out;
|
|
+ }
|
|
+ int total = 0;
|
|
+ int previousRound = -1;
|
|
+ in.enterList();
|
|
+ while (!in.isEndOfCurrentList()) {
|
|
+ in.enterList();
|
|
+ final int round = in.readIntScalar();
|
|
+ if (round <= previousRound) {
|
|
+ LOG.warn("AERE PERSISTENTA-SIGILII: seal file {} has rounds out of order; IGNORED.", file);
|
|
+ return out;
|
|
+ }
|
|
+ previousRound = round;
|
|
+ final List<SchemeSeal> rows = new ArrayList<>();
|
|
+ in.enterList();
|
|
+ while (!in.isEndOfCurrentList()) {
|
|
+ if (++total > MAX_SEALS) {
|
|
+ LOG.warn("AERE PERSISTENTA-SIGILII: seal file {} holds more than {} seals; IGNORED.", file, MAX_SEALS);
|
|
+ return out;
|
|
+ }
|
|
+ in.enterList();
|
|
+ final int scheme = in.readIntScalar();
|
|
+ final int index = in.readIntScalar();
|
|
+ final Bytes signature = in.readBytes();
|
|
+ in.leaveList();
|
|
+ if (scheme < 0 || scheme > 0xff) {
|
|
+ return out;
|
|
+ }
|
|
+ rows.add(new SchemeSeal((byte) scheme, index, signature));
|
|
+ }
|
|
+ in.leaveList();
|
|
+ in.leaveList();
|
|
+ decoded.put(round, rows);
|
|
+ }
|
|
+ in.leaveList();
|
|
+ in.leaveList();
|
|
+ if (!in.isDone()) {
|
|
+ LOG.warn("AERE PERSISTENTA-SIGILII: seal file {} has bytes after its record; IGNORED.", file);
|
|
+ return out;
|
|
+ }
|
|
+ } catch (final RuntimeException e) {
|
|
+ LOG.warn("AERE PERSISTENTA-SIGILII: seal file {} is CORRUPT ({}); IGNORED.", file, e.toString());
|
|
+ return out;
|
|
+ }
|
|
+ int kept = 0;
|
|
+ int dropped = 0;
|
|
+ for (final java.util.Map.Entry<Integer, List<SchemeSeal>> e : decoded.entrySet()) {
|
|
+ final java.util.Optional<Bytes32> message =
|
|
+ org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer.roundBoundMessage(
|
|
+ chainId, blockNumber, e.getKey(), blockHash.getBytes());
|
|
+ if (message.isEmpty()) {
|
|
+ dropped += e.getValue().size();
|
|
+ continue;
|
|
+ }
|
|
+ final Set<Integer> falconKept = new LinkedHashSet<>();
|
|
+ final List<SchemeSeal> rows = new ArrayList<>();
|
|
+ for (final SchemeSeal s : e.getValue()) {
|
|
+ if (s.getSchemeWireId() != SealSchemes.FALCON_512.wireId()) {
|
|
+ continue;
|
|
+ }
|
|
+ if (s.getValidatorIndex() >= 0
|
|
+ && s.getSignature() != null
|
|
+ && !falconKept.contains(s.getValidatorIndex())
|
|
+ && registry.addressForIndexAtOwnHead(blockNumber, s.getValidatorIndex()) != null
|
|
+ && sealVerifiesAgainstAnchoredRegistry(registry, blockNumber, message.get(), s.getValidatorIndex(), s.getSignature())) {
|
|
+ falconKept.add(s.getValidatorIndex());
|
|
+ rows.add(s);
|
|
+ } else {
|
|
+ dropped++;
|
|
+ }
|
|
+ }
|
|
+ for (final SchemeSeal s : e.getValue()) {
|
|
+ if (s.getSchemeWireId() == SealSchemes.FALCON_512.wireId()) {
|
|
+ continue;
|
|
+ }
|
|
+ if (falconKept.contains(s.getValidatorIndex()) && extraVerifies(blockNumber, s, message.get())) {
|
|
+ rows.add(s);
|
|
+ } else {
|
|
+ dropped++;
|
|
+ }
|
|
+ }
|
|
+ if (!rows.isEmpty()) {
|
|
+ rows.sort(PqAnchorV2.CANONICAL);
|
|
+ out.put(e.getKey(), rows);
|
|
+ kept += rows.size();
|
|
+ }
|
|
+ }
|
|
+ LOG.info(
|
|
+ "AERE PERSISTENTA-SIGILII: restored {} seal(s) over {} round(s) for head {} from {} ({}); {} dropped"
|
|
+ + " (unbound, repeated, unverified, or an extra without its Falcon seal).",
|
|
+ kept,
|
|
+ out.size(),
|
|
+ blockNumber,
|
|
+ file,
|
|
+ DOMAIN_2,
|
|
+ dropped);
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ /** An extra seal verified under the key the producer resolves (the v3 epoch from H_k, the hybrid registry before). */
|
|
+ private static boolean extraVerifies(final long blockNumber, final SchemeSeal s, final Bytes32 message) {
|
|
+ try {
|
|
+ final java.util.Optional<SealScheme> scheme = SealSchemes.byWireId(s.getSchemeWireId());
|
|
+ if (scheme.isEmpty()) {
|
|
+ return false;
|
|
+ }
|
|
+ final java.util.Optional<byte[]> pk =
|
|
+ AerePqIdentity.keysFromV3(blockNumber)
|
|
+ ? AerePqIdentity.v3KeyAt(blockNumber, s.getValidatorIndex(), scheme.get().id())
|
|
+ : HybridSealSupport.instance().registry().flatMap(r -> r.publicKey(s.getValidatorIndex(), scheme.get().id()));
|
|
+ return pk.isPresent() && scheme.get().verifyRaw(pk.get(), message.toArray(), s.getSignature().toArray());
|
|
+ } catch (final RuntimeException e) {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
/**
|
|
* THE LOAD-BEARING LINE OF THIS WHOLE FILE, isolated so that removing it is a one-line edit and
|
|
* the test suite's negative control can prove that removing it turns the forged-seal test RED.
|
|
*
|
|
* <p>This is the same call, on the same registry interface, that {@code PqAnchorProducer.apply}
|
|
* makes when it decides which heard seals may enter a certificate. Nothing about a seal is trusted
|
|
* because it was on disk.
|
|
*
|
|
* <p>D2 (2026-08-06): it now carries the HEIGHT the seals belong to. The adversarial review of
|
|
* 2026-08-02 measured that every registry question in this stack was height-less, so a restart
|
|
* after a key rotation re-checked seals over an old block against today's keys and dropped them
|
|
* all as forged. Here the height is not in doubt: the caller has already refused the file unless
|
|
* the stored block number and hash equal this node's head.
|
|
*
|
|
* @param registry the anchored Falcon registry
|
|
* @param blockNumber the height of the block the stored seals attest
|
|
* @param message the message M over the block the seals attest
|
|
* @param validatorIndex the seal's registry index
|
|
* @param signature the Falcon-512 signature bytes
|
|
* @return true iff the signature verifies
|
|
diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqSealWindowStore.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqSealWindowStore.java
|
|
index b224d8fb2d..4254c173f8 100755
|
|
--- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqSealWindowStore.java
|
|
+++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqSealWindowStore.java
|
|
@@ -62,67 +62,91 @@ import org.slf4j.LoggerFactory;
|
|
* empty window an absent journal already gives, and nothing else.
|
|
*
|
|
* <p>WHAT A FAULT COSTS. Every method here is written not to throw on bad input: a torn tail (the
|
|
* node died mid-append), a flipped byte, a directory where a file should be, a journal from another
|
|
* chain. A bad frame costs that frame and what FOLLOWS it in the same segment (a frame boundary
|
|
* cannot be trusted after a bad length), never the node. Writes are best effort and unsynced: the
|
|
* head file of {@link PqSealStore} is the one liveness depends on, and it keeps its fsync.
|
|
*/
|
|
public final class PqSealWindowStore {
|
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(PqSealWindowStore.class);
|
|
|
|
/** Directory name under the node's data directory. */
|
|
public static final String DIRECTORY_NAME = "aere-pq-seal-window";
|
|
|
|
/** Domain separator of a frame payload. */
|
|
public static final String DOMAIN = "AERE-PQ-SEALWINDOW-1";
|
|
|
|
private static final Bytes DOMAIN_BYTES = Bytes.wrap(DOMAIN.getBytes(StandardCharsets.US_ASCII));
|
|
|
|
+ /**
|
|
+ * 1(b) (2026-10-01): the domain of a ROUND-BOUND frame, one per (n, r, hash), for the heights whose commit seals
|
|
+ * name their round: RLP["AERE-PQ-SEALWINDOW-2", chainId, n, r, hash, [[index, signature], ...]]. Below H_r the
|
|
+ * frames are form 1, byte for byte as before; the reader drops a frame whose form is wrong for its height.
|
|
+ */
|
|
+ public static final String DOMAIN_2 = "AERE-PQ-SEALWINDOW-2";
|
|
+
|
|
+ private static final Bytes DOMAIN_2_BYTES = Bytes.wrap(DOMAIN_2.getBytes(StandardCharsets.US_ASCII));
|
|
+
|
|
+ /** The round of a form-1 frame: none. */
|
|
+ public static final int NO_ROUND = -1;
|
|
+
|
|
/** Heights per segment file. */
|
|
public static final long SEGMENT_BLOCKS = 64L;
|
|
|
|
/** A segment larger than this is ignored whole. */
|
|
public static final long MAX_SEGMENT_BYTES = 64L * 1024L * 1024L;
|
|
|
|
/** A frame payload larger than this ends the reading of its segment. */
|
|
public static final int MAX_FRAME_BYTES = 4 * 1024 * 1024;
|
|
|
|
/** More seals than this in one frame is not a certificate. */
|
|
public static final int MAX_SEALS = 1024;
|
|
|
|
/** System property: {@code false} turns the journal off (the window is then memory only). */
|
|
public static final String PROPERTY_PERSIST = "aere.pq.finality.persist";
|
|
|
|
private static final Pattern SEGMENT_NAME = Pattern.compile("^w-(\\d{1,18})\\.rlp$");
|
|
|
|
private PqSealWindowStore() {}
|
|
|
|
/**
|
|
* One heard block as the journal holds it. Unverified: the caller verifies.
|
|
*
|
|
* @param blockNumber the height
|
|
+ * @param round the round the seals were given in (form 2), or {@link #NO_ROUND} (form 1)
|
|
* @param blockHash the round-independent on-chain hash the seals were heard for
|
|
* @param seals the heard seals, index-sorted
|
|
*/
|
|
- public record Heard(long blockNumber, Bytes blockHash, List<FalconSeal> seals) {}
|
|
+ public record Heard(long blockNumber, int round, Bytes blockHash, List<FalconSeal> seals) {
|
|
+ /**
|
|
+ * A form-1 frame (no round), as before 1(b).
|
|
+ *
|
|
+ * @param blockNumber the height
|
|
+ * @param blockHash the on-chain hash
|
|
+ * @param seals the heard seals
|
|
+ */
|
|
+ public Heard(final long blockNumber, final Bytes blockHash, final List<FalconSeal> seals) {
|
|
+ this(blockNumber, NO_ROUND, blockHash, seals);
|
|
+ }
|
|
+ }
|
|
|
|
/**
|
|
* Whether the journal is enabled for this process.
|
|
*
|
|
* @return false only when {@value #PROPERTY_PERSIST} is {@code false}
|
|
*/
|
|
public static boolean enabled() {
|
|
return !"false".equalsIgnoreCase(System.getProperty(PROPERTY_PERSIST));
|
|
}
|
|
|
|
/**
|
|
* The journal directory of a node.
|
|
*
|
|
* @param dataDirectory the node's data directory
|
|
* @return the directory the segments live in
|
|
*/
|
|
public static Path directoryIn(final Path dataDirectory) {
|
|
return dataDirectory.resolve(DIRECTORY_NAME);
|
|
}
|
|
|
|
@@ -130,43 +154,47 @@ public final class PqSealWindowStore {
|
|
* The segment file a height belongs to.
|
|
*
|
|
* @param directory the journal directory
|
|
* @param blockNumber the height
|
|
* @return the segment path
|
|
*/
|
|
public static Path segmentFor(final Path directory, final long blockNumber) {
|
|
return directory.resolve("w-" + (blockNumber / SEGMENT_BLOCKS) + ".rlp");
|
|
}
|
|
|
|
/**
|
|
* Encode one frame payload.
|
|
*
|
|
* @param chainId the chain id
|
|
* @param heard the heard block
|
|
* @return the RLP payload
|
|
*/
|
|
public static byte[] encode(final long chainId, final Heard heard) {
|
|
final BytesValueRLPOutput out = new BytesValueRLPOutput();
|
|
out.startList();
|
|
- out.writeBytes(DOMAIN_BYTES);
|
|
+ final boolean form2 = heard.round() != NO_ROUND;
|
|
+ out.writeBytes(form2 ? DOMAIN_2_BYTES : DOMAIN_BYTES);
|
|
out.writeLongScalar(chainId);
|
|
out.writeLongScalar(heard.blockNumber());
|
|
+ if (form2) {
|
|
+ out.writeIntScalar(heard.round());
|
|
+ }
|
|
out.writeBytes(heard.blockHash());
|
|
PqAnchor.writeCertificate(out, heard.seals());
|
|
out.endList();
|
|
return out.encoded().toArrayUnsafe();
|
|
}
|
|
|
|
/**
|
|
* Append one heard block to its segment. Best effort, unsynced.
|
|
*
|
|
* @param directory the journal directory
|
|
* @param chainId the chain id
|
|
* @param heard the heard block
|
|
* @throws IOException when the file system refuses; the caller logs and carries on
|
|
*/
|
|
public static void append(final Path directory, final long chainId, final Heard heard)
|
|
throws IOException {
|
|
Files.createDirectories(directory);
|
|
final byte[] payload = encode(chainId, heard);
|
|
final CRC32 crc = new CRC32();
|
|
crc.update(payload, 0, payload.length);
|
|
@@ -313,75 +341,95 @@ public final class PqSealWindowStore {
|
|
if ((int) crc.getValue() != storedCrc) {
|
|
LOG.warn(
|
|
"AERE FEREASTRA-SIGILII: segment {} holds a frame whose checksum does not match after "
|
|
+ "{} good frame(s); it and what follows it are dropped.",
|
|
segment,
|
|
frames);
|
|
return;
|
|
}
|
|
frames++;
|
|
final Heard heard = decode(payload, chainId);
|
|
if (heard != null && heard.blockNumber() >= fromBlock && heard.blockNumber() <= toBlock) {
|
|
out.add(heard);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static Heard decode(final byte[] payload, final long chainId) {
|
|
try {
|
|
final RLPInput in = new BytesValueRLPInput(Bytes.wrap(payload), false);
|
|
in.enterList();
|
|
- if (!DOMAIN_BYTES.equals(in.readBytes())) {
|
|
+ final Bytes domain = in.readBytes();
|
|
+ final boolean form2 = DOMAIN_2_BYTES.equals(domain);
|
|
+ if (!form2 && !DOMAIN_BYTES.equals(domain)) {
|
|
return null;
|
|
}
|
|
if (in.readLongScalar() != chainId) {
|
|
return null;
|
|
}
|
|
final long blockNumber = in.readLongScalar();
|
|
+ final int round = form2 ? in.readIntScalar() : NO_ROUND;
|
|
+ if (form2 && (round < 0 || round > PqAnchorV3.MAX_ROUND)) {
|
|
+ return null;
|
|
+ }
|
|
final Bytes blockHash = in.readBytes();
|
|
if (blockNumber < 0 || blockHash.size() != 32) {
|
|
return null;
|
|
}
|
|
final List<FalconSeal> seals = new ArrayList<>();
|
|
in.enterList();
|
|
while (!in.isEndOfCurrentList()) {
|
|
if (seals.size() >= MAX_SEALS) {
|
|
return null;
|
|
}
|
|
in.enterList();
|
|
final int index = in.readIntScalar();
|
|
final Bytes signature = in.readBytes();
|
|
in.leaveList();
|
|
seals.add(new FalconSeal(index, signature));
|
|
}
|
|
in.leaveList();
|
|
in.leaveList();
|
|
- return new Heard(blockNumber, blockHash, seals);
|
|
+ return new Heard(blockNumber, round, blockHash, seals);
|
|
} catch (final RuntimeException e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Count the frames of a journal, for tests and for the operator's curiosity. Never throws.
|
|
*
|
|
* @param directory the journal directory
|
|
* @param chainId the chain id
|
|
* @return how many frames decode for this chain, at any height
|
|
*/
|
|
public static int frameCount(final Path directory, final long chainId) {
|
|
return readAll(directory, chainId, 0L, Long.MAX_VALUE).size();
|
|
}
|
|
|
|
/**
|
|
* The seals of one frame collection, for callers that hold a plain collection.
|
|
*
|
|
* @param blockNumber the height
|
|
* @param blockHash the on-chain hash
|
|
* @param seals the heard seals
|
|
* @return the frame value, seals index-sorted
|
|
*/
|
|
public static Heard heard(
|
|
final long blockNumber, final Bytes blockHash, final Collection<FalconSeal> seals) {
|
|
return new Heard(blockNumber, blockHash, PqAnchor.sortedByIndex(new ArrayList<>(seals)));
|
|
}
|
|
+
|
|
+ /**
|
|
+ * A form-2 frame value: the seals of ONE round of a round-bound height (1(b)).
|
|
+ *
|
|
+ * @param blockNumber the height
|
|
+ * @param round the round
|
|
+ * @param blockHash the on-chain hash
|
|
+ * @param seals the heard seals of that round
|
|
+ * @return the frame value, seals index-sorted
|
|
+ */
|
|
+ public static Heard heardRound(
|
|
+ final long blockNumber, final int round, final Bytes blockHash, final Collection<FalconSeal> seals) {
|
|
+ return new Heard(blockNumber, round, blockHash, PqAnchor.sortedByIndex(new ArrayList<>(seals)));
|
|
+ }
|
|
}
|
|
diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreator.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreator.java
|
|
index ff1a09cf83..8136a53c02 100644
|
|
--- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreator.java
|
|
+++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreator.java
|
|
@@ -1,39 +1,39 @@
|
|
/*
|
|
* Copyright ConsenSys AG.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
- * found, as section 4(c) requires. The change itself is in patches/0008-aere-pq-aip22.patch.
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0009-aere-pq-seal-judge-snap-cap.patch.
|
|
*/
|
|
package org.hyperledger.besu.consensus.common.bft.blockcreation;
|
|
|
|
import org.hyperledger.besu.config.BftConfigOptions;
|
|
import org.hyperledger.besu.consensus.common.ForksSchedule;
|
|
import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
|
|
import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec;
|
|
import org.hyperledger.besu.consensus.common.bft.BftHelpers;
|
|
import org.hyperledger.besu.consensus.common.bft.BftProtocolSchedule;
|
|
import org.hyperledger.besu.datatypes.Address;
|
|
import org.hyperledger.besu.ethereum.ProtocolContext;
|
|
import org.hyperledger.besu.ethereum.blockcreation.AbstractBlockCreator;
|
|
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
|
|
import org.hyperledger.besu.ethereum.core.MiningConfiguration;
|
|
import org.hyperledger.besu.ethereum.core.SealableBlockHeader;
|
|
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
|
|
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
|
|
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
|
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
|
|
diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinator.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinator.java
|
|
index fa9f480ed1..208635ea6c 100644
|
|
--- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinator.java
|
|
+++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinator.java
|
|
@@ -1,39 +1,39 @@
|
|
/*
|
|
* Copyright ConsenSys AG.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
- * found, as section 4(c) requires. The change itself is in patches/0008-aere-pq-aip22.patch.
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0009-aere-pq-seal-judge-snap-cap.patch.
|
|
*/
|
|
package org.hyperledger.besu.consensus.common.bft.blockcreation;
|
|
|
|
import org.hyperledger.besu.consensus.common.bft.BftEventQueue;
|
|
import org.hyperledger.besu.consensus.common.bft.BftExecutors;
|
|
import org.hyperledger.besu.consensus.common.bft.BftProcessor;
|
|
import org.hyperledger.besu.consensus.common.bft.events.NewChainHead;
|
|
import org.hyperledger.besu.consensus.common.bft.statemachine.BftEventHandler;
|
|
import org.hyperledger.besu.datatypes.Address;
|
|
import org.hyperledger.besu.datatypes.Wei;
|
|
import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator;
|
|
import org.hyperledger.besu.ethereum.chain.BlockAddedEvent;
|
|
import org.hyperledger.besu.ethereum.chain.BlockAddedObserver;
|
|
import org.hyperledger.besu.ethereum.chain.Blockchain;
|
|
import org.hyperledger.besu.ethereum.core.Block;
|
|
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
import org.hyperledger.besu.ethereum.core.Transaction;
|
|
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
|
|
import org.hyperledger.besu.plugin.services.BesuEvents;
|
|
|
|
diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/PqAnchorProducer.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/PqAnchorProducer.java
|
|
index e8fc683458..324aa2d2db 100755
|
|
--- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/PqAnchorProducer.java
|
|
+++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/PqAnchorProducer.java
|
|
@@ -2,48 +2,50 @@
|
|
* Copyright contributors to Besu / AERE Network.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
package org.hyperledger.besu.consensus.common.bft.blockcreation;
|
|
|
|
import org.apache.tuweni.bytes.Bytes;
|
|
import org.hyperledger.besu.datatypes.Hash;
|
|
import org.hyperledger.besu.consensus.common.bft.AerePqIdentity;
|
|
import org.hyperledger.besu.consensus.common.bft.BftContext;
|
|
import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftHelpers;
|
|
import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
import org.hyperledger.besu.consensus.common.bft.FalconSealSupport;
|
|
import org.hyperledger.besu.consensus.common.bft.HybridSealSupport;
|
|
import org.hyperledger.besu.consensus.common.bft.HybridSignerRegistry;
|
|
import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
import org.hyperledger.besu.consensus.common.bft.PqAnchorNotReadyException;
|
|
import org.hyperledger.besu.consensus.common.bft.PqAnchorV2;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorV3;
|
|
import org.hyperledger.besu.consensus.common.bft.PqSealCache;
|
|
import org.hyperledger.besu.consensus.common.bft.PqSignerRegistry;
|
|
import org.hyperledger.besu.consensus.common.bft.SchemeSeal;
|
|
import org.hyperledger.besu.consensus.common.bft.SealScheme;
|
|
import org.hyperledger.besu.consensus.common.bft.SealSchemes;
|
|
import org.hyperledger.besu.datatypes.Address;
|
|
import org.hyperledger.besu.ethereum.ProtocolContext;
|
|
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
import java.util.LinkedHashSet;
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
import java.util.Set;
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
|
import org.apache.tuweni.bytes.Bytes32;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
@@ -133,137 +135,255 @@ public final class PqAnchorProducer {
|
|
public static void useConfigForTesting(final PqAnchorConfig replacement) {
|
|
synchronized (PqAnchorProducer.class) {
|
|
config = replacement;
|
|
LOGGED_ACTIVATION_THRESHOLD.set(false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Whether a Falcon seal produced FOR this block must be signed over the V2 message M rather than
|
|
* over the legacy ECDSA committed-seal hash.
|
|
*
|
|
* <p>ONE BLOCK EARLIER than {@link PqAnchorConfig#activeAt(long)}, and that offset is the whole
|
|
* bootstrap of the scheme: the certificate carried by block H is made of seals over block H-1, so
|
|
* H-1 must already be sealed in the new form. Every node flips at the same height because the
|
|
* height is a pure function of the same configured H.
|
|
*
|
|
* @param blockNumber the number of the block being sealed
|
|
* @return true iff the seal must be over M
|
|
*/
|
|
public static boolean sealMessageIsAnchorForm(final long blockNumber) {
|
|
- final PqAnchorConfig cfg = config();
|
|
+ // 1(b): only a view of the one decider, commitSealFormAt.
|
|
+ return commitSealFormAt(config(), blockNumber) != CommitSealForm.ECDSA_DIGEST;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The three forms of the post-quantum commit seal (1(b), section 1.1). Decided ONLY by {@link
|
|
+ * #commitSealFormAt}, and only by the height n.
|
|
+ */
|
|
+ public enum CommitSealForm {
|
|
+ /** Below the anchor form ({@code n + 1 < anchorBlock}, or the anchor disarmed): the ECDSA digest. */
|
|
+ ECDSA_DIGEST,
|
|
+ /** The anchor form without the round (COMMIT-1): H_r unset or {@code n + 1 < H_r}. History, L1. */
|
|
+ ROUND_FREE,
|
|
+ /** The round-bound form (COMMIT-2): {@code n + 1 >= H_r}. */
|
|
+ ROUND_BOUND
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * AERE-R1B-LOC-UNIC: the one decider of the commit-seal form of block n.
|
|
+ *
|
|
+ * @param cfg the configuration
|
|
+ * @param blockNumber the number n of the block being sealed
|
|
+ * @return the form
|
|
+ */
|
|
+ public static CommitSealForm commitSealFormAt(final PqAnchorConfig cfg, final long blockNumber) {
|
|
+ if (!anchorFormAt(cfg, blockNumber)) {
|
|
+ return CommitSealForm.ECDSA_DIGEST;
|
|
+ }
|
|
+ return cfg.roundBoundAt(blockNumber) ? CommitSealForm.ROUND_BOUND : CommitSealForm.ROUND_FREE;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * AERE-R1B-LOC-UNIC: the message an ANCHOR-FORM commit seal of block n signs, for round r. The one
|
|
+ * place the producer, R2, the commit enforcement, the seal store, the AIP-21 window and decidedBy
|
|
+ * take it from.
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>{@code ROUND_BOUND}: M_r (COMMIT-2) for r in 0..{@link PqAnchorV3#MAX_ROUND}; any other r
|
|
+ * gives EMPTY (code {@code AERE-PQ-COMMIT-R-03}), never an exception (decision H11);
|
|
+ * <li>{@code ROUND_FREE}: COMMIT-1, the round ignored: today's bytes, byte for byte (L1);
|
|
+ * <li>{@code ECDSA_DIGEST}: empty, there is no anchor message below the anchor form.
|
|
+ * </ul>
|
|
+ *
|
|
+ * @param cfg the configuration
|
|
+ * @param blockNumber n
|
|
+ * @param onchainHash the on-chain hash of block n (round 0, seals and certificate excluded)
|
|
+ * @param round the round of the commit (or the certificate)
|
|
+ * @return the 32 bytes to sign or verify, or empty
|
|
+ */
|
|
+ public static Optional<Bytes32> anchorSealMessage(
|
|
+ final PqAnchorConfig cfg, final long blockNumber, final Bytes onchainHash, final int round) {
|
|
+ switch (commitSealFormAt(cfg, blockNumber)) {
|
|
+ case ROUND_BOUND:
|
|
+ if (round < 0 || round > PqAnchorV3.MAX_ROUND) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ return roundBoundMessage(cfg.chainId(), blockNumber, round, onchainHash);
|
|
+ case ROUND_FREE:
|
|
+ return Optional.of(roundFreeMessage(cfg.chainId(), blockNumber, onchainHash));
|
|
+ case ECDSA_DIGEST:
|
|
+ default:
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * COMMIT-1 for a record that is round-free BY CONSTRUCTION: a SEALSTORE-1 head file or a SEALWINDOW-1
|
|
+ * frame, which carry no round, and whose reader has already asked {@link #commitSealFormAt} that the
|
|
+ * height is not round-bound (a form-1 record at a round-bound height is dropped, never reinterpreted
|
|
+ * as round 0). With {@link #roundBoundMessage} the only two callers of the primitives outside this
|
|
+ * class's own decision, so the gate {@code r1b/locul-unic-besu.py} can demand that nothing else calls
|
|
+ * them.
|
|
+ *
|
|
+ * @param chainId the chain id the record was written for
|
|
+ * @param blockNumber n
|
|
+ * @param onchainHash hash(n)
|
|
+ * @return COMMIT-1
|
|
+ */
|
|
+ public static Bytes32 roundFreeMessage(
|
|
+ final long chainId, final long blockNumber, final Bytes onchainHash) {
|
|
+ return PqAnchor.commitMessage(chainId, blockNumber, onchainHash);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * COMMIT-2 for a record that names its round (SEALSTORE-2, SEALWINDOW-2), with the same range rule as
|
|
+ * {@link #anchorSealMessage}: a round outside 0..{@link PqAnchorV3#MAX_ROUND} gives empty, never an
|
|
+ * exception.
|
|
+ *
|
|
+ * @param chainId the chain id the record was written for
|
|
+ * @param blockNumber n
|
|
+ * @param round r
|
|
+ * @param onchainHash hash(n)
|
|
+ * @return M_r, or empty
|
|
+ */
|
|
+ public static Optional<Bytes32> roundBoundMessage(
|
|
+ final long chainId, final long blockNumber, final int round, final Bytes onchainHash) {
|
|
+ if (round < 0 || round > PqAnchorV3.MAX_ROUND) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ return Optional.of(PqAnchor.commitMessageRound(chainId, blockNumber, round, onchainHash));
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The anchor form of the commit seal, before the round question: one block BEFORE {@link
|
|
+ * PqAnchorConfig#activeAt(long)} (see {@link #sealMessageIsAnchorForm}).
|
|
+ */
|
|
+ private static boolean anchorFormAt(final PqAnchorConfig cfg, final long blockNumber) {
|
|
// DELIBERATELY LEFT UNTOUCHED BY THE INTERVAL, 2026-08-07. With an interval in force,
|
|
// seals made at heights that feed no anchor reach no certificate at all, so they are WASTE.
|
|
// The temptation is to stop signing them. It is not done here, and the reason is that this
|
|
// method decides the FORM of the seal: if the form depended on the interval, two nodes
|
|
// reading the interval differently would sign different forms and would no longer recognise
|
|
// each other. The form stays a function of H alone, which is the one value the fleet
|
|
// coordinates anyway.
|
|
//
|
|
// The waste remains, and it is BANDWIDTH, not DISK: the seals still travel on the Commit
|
|
// messages of every block, they simply no longer reach any header. The disk, which was the
|
|
// problem, drops by a factor of <interval>. Cutting the pointless signing is done separately,
|
|
// at the attachment gate, where it cannot change the form.
|
|
return cfg.everActive() && blockNumber + 1L >= cfg.anchorBlock();
|
|
}
|
|
|
|
/**
|
|
* AERE D-311 (2026-09-02): THE ONE PLACE that says which bytes a commit's post-quantum seal
|
|
* signs. Both the emitter ({@code QbftRound.pqSealMessageFor}) and the verifier
|
|
* ({@code MessageValidator.SubsequentMessageValidator}, feeding {@code PqCommitEnforcement})
|
|
* call this and nothing else.
|
|
*
|
|
* <p>Why it exists, measured on the public testnet 28001 the day it was born: with the anchor
|
|
* armed (as on 2800 since 13,014,000) the emitter signed the anchor form, while the commit
|
|
* enforcement verified over the ECDSA committed-seal hash. Two copies of one rule, and they
|
|
* drifted: at {@code aere.pq.commitPq.forkBlock} every commit of every validator was refused
|
|
* ("does NOT verify over the commit digest") and the chain stopped. The rehearsal (F95) never
|
|
* saw it because its kit runs without the anchor armed. Arming H1 on 2800 with the old
|
|
* verifier would have stopped the live chain.
|
|
*
|
|
- * @param blockNumber the height of the block the commit votes for
|
|
- * @param onchainHash the ROUND-INDEPENDENT on-chain hash of that block (round forced to 0)
|
|
- * @param commitHash the ECDSA committed-seal hash (round-specific)
|
|
- * @return the 32 bytes the Falcon seal (and any hybrid extras) must sign at this height
|
|
- */
|
|
- public static Bytes32 commitSealMessage(
|
|
- final long blockNumber, final Bytes onchainHash, final Hash commitHash) {
|
|
- return commitSealMessage(blockNumber, () -> onchainHash, commitHash);
|
|
- }
|
|
-
|
|
- /**
|
|
- * Same as {@link #commitSealMessage(long, Bytes, Hash)}, with the on-chain hash supplied LAZILY:
|
|
- * it is only needed (and only computed) in the anchor form. Below the anchor the ECDSA digest is
|
|
- * the message and no round-0 re-encoding happens, which is also what keeps every upstream test
|
|
- * that mocks {@code QbftBlockInterface} exactly as it was.
|
|
+ * <p>1(b), 2026-10-01: the ROUND is now a mandatory argument. The two overloads without it were
|
|
+ * DELETED, not kept beside this one, so every caller fell at compile time and was moved
|
|
+ * consciously (decision H11: no form can be reached at run time that throws for a missing round).
|
|
+ * The on-chain hash is supplied LAZILY: it is only needed (and only computed) in the anchor form.
|
|
+ * Below the anchor the ECDSA digest is the message and no round-0 re-encoding happens, which is
|
|
+ * also what keeps every upstream test that mocks {@code QbftBlockInterface} exactly as it was.
|
|
*
|
|
* @param blockNumber the height of the block the commit votes for
|
|
* @param onchainHash supplier of the ROUND-INDEPENDENT on-chain hash (round forced to 0)
|
|
* @param commitHash the ECDSA committed-seal hash (round-specific)
|
|
- * @return the 32 bytes the Falcon seal (and any hybrid extras) must sign at this height
|
|
+ * @param round the round of the commit
|
|
+ * @return the 32 bytes the Falcon seal (and any hybrid extras) must sign at this height; EMPTY only
|
|
+ * at a round-bound height with a round outside 0..{@link PqAnchorV3#MAX_ROUND} (no PQ seal is
|
|
+ * emitted, and one carried is refused with {@code AERE-PQ-COMMIT-R-03})
|
|
*/
|
|
- public static Bytes32 commitSealMessage(
|
|
+ public static Optional<Bytes32> commitSealMessage(
|
|
final long blockNumber,
|
|
final java.util.function.Supplier<Bytes> onchainHash,
|
|
- final Hash commitHash) {
|
|
- if (sealMessageIsAnchorForm(blockNumber)) {
|
|
- return PqAnchor.commitMessage(config().chainId(), blockNumber, onchainHash.get());
|
|
+ final Hash commitHash,
|
|
+ final int round) {
|
|
+ final PqAnchorConfig cfg = config();
|
|
+ if (commitSealFormAt(cfg, blockNumber) == CommitSealForm.ECDSA_DIGEST) {
|
|
+ return Optional.of(Bytes32.wrap(commitHash.getBytes()));
|
|
}
|
|
- return Bytes32.wrap(commitHash.getBytes());
|
|
+ return anchorSealMessage(cfg, blockNumber, onchainHash.get(), round);
|
|
}
|
|
|
|
/**
|
|
* Return the extra data the proposer should encode for a block on top of this parent.
|
|
*
|
|
* <p>Below the activation height the input is returned UNCHANGED, so pre-fork behaviour is
|
|
* identical byte for byte and the 11.8 million existing blocks stay untouched. The gate is on the
|
|
* block NUMBER, never on content.
|
|
*
|
|
* @param base the extra data the unmodified Besu path would have produced
|
|
* @param parentHeader the parent header, whose number and ON-CHAIN hash bind the certificate
|
|
* @param protocolContext the protocol context, used only to read the validator set for the parent
|
|
* @return either {@code base} itself, or a copy carrying the certificate and the anchor digest
|
|
* @throws PqAnchorNotReadyException when the staged threshold cannot be met, meaning this node
|
|
* must not propose at all this round
|
|
*/
|
|
public static BftExtraData apply(
|
|
final BftExtraData base,
|
|
final BlockHeader parentHeader,
|
|
final ProtocolContext protocolContext) {
|
|
|
|
final PqAnchorConfig cfg = config();
|
|
final long blockNumber = parentHeader.getNumber() + 1L;
|
|
// THE SAME QUESTION BOTH RULES ASK, through the same method: anchorAppliesAt.
|
|
// The producer and the validator have to agree on which heights carry a certificate. If the
|
|
// producer wrote one where the rule does not ask for it, that would only be waste; if it
|
|
// skipped one where the rule DOES ask for it, every block it proposes would be rejected. So
|
|
// the same question is asked, not one that merely resembles it.
|
|
if (!cfg.anchorAppliesAt(blockNumber)) {
|
|
return base;
|
|
}
|
|
|
|
final long parentNumber = parentHeader.getNumber();
|
|
- final Bytes32 message =
|
|
- PqAnchor.commitMessage(cfg.chainId(), parentNumber, parentHeader.getHash().getBytes());
|
|
+ if (cfg.certificateFormAt(blockNumber) == PqAnchorConfig.CertificateForm.V3) {
|
|
+ // AERE-R1B-PRODUCATOR: from H_r the certificate holds the seals of ONE round (section 3.1 C)
|
|
+ return applyV3(cfg, blockNumber, parentHeader, base, protocolContext);
|
|
+ }
|
|
+ // 1(b): through the one place; below H_r it is COMMIT-1, byte for byte (the round is ignored)
|
|
+ final Optional<Bytes32> roundFree =
|
|
+ anchorSealMessage(cfg, parentNumber, parentHeader.getHash().getBytes(), 0);
|
|
+ if (roundFree.isEmpty()) {
|
|
+ throw new PqAnchorNotReadyException(
|
|
+ parentNumber,
|
|
+ 0,
|
|
+ cfg.minSealsAt(blockNumber),
|
|
+ "no anchor-form commit message exists for the parent (form "
|
|
+ + commitSealFormAt(cfg, parentNumber)
|
|
+ + "); this cannot happen at an anchor height and is a defect");
|
|
+ }
|
|
+ final Bytes32 message = roundFree.get();
|
|
|
|
+ // 1(b): the store's API takes the round; below H_r it is ignored (one record per block, as before)
|
|
final List<FalconSeal> heard =
|
|
- PqSealCache.instance().sealsFor(parentNumber, parentHeader.getHash());
|
|
+ PqSealCache.instance().sealsFor(parentNumber, parentHeader.getHash(), PqSealCache.ANY_ROUND);
|
|
|
|
final PqSignerRegistry registry = PqSignerRegistry.falconSealSupport();
|
|
final Set<Address> eligible = validatorsForParent(parentHeader, protocolContext);
|
|
|
|
final List<FalconSeal> certificate = new ArrayList<>();
|
|
final Set<Address> seen = new LinkedHashSet<>();
|
|
// Integer.MAX_VALUE means "no cap", i.e. exactly what every node did before 2026-08-07.
|
|
final int sealCap = cfg.maxSealsCarried().orElse(Integer.MAX_VALUE);
|
|
int rejectedIneligible = 0;
|
|
int rejectedInvalid = 0;
|
|
// D2 (2026-08-06): the proposer resolves keys AT THE PARENT'S HEIGHT, the same height R2 will
|
|
// use when it re-checks this certificate. Before this the producer asked a height-less registry
|
|
// while R2 asked a height-resolved one, so at a rotation height the two could disagree about
|
|
// which key set applies - the proposer would assemble a certificate the fleet then refuses, and
|
|
// the round would fail for a reason no log named. Building and validating now read the same
|
|
// question.
|
|
for (final FalconSeal seal : PqAnchor.sortedByIndex(heard)) {
|
|
// D2 (b-v2): the OWN-HEAD door. parentHeader is this node's own head - this method is
|
|
// reached only from the proposer, building the block on top of it. Refusing here for a
|
|
// missing schedule is what stopped block production in PqForkValidatorSetChangeTest.
|
|
@@ -313,101 +433,104 @@ public final class PqAnchorProducer {
|
|
+ FalconSealSupport.instance().addressBound()
|
|
+ ", validators for the parent="
|
|
+ eligible.size()
|
|
+ ") and "
|
|
+ rejectedInvalid
|
|
+ " did not verify over M(parent). Schedule="
|
|
+ cfg.minSealsSchedule()
|
|
+ ". A node that has just restarted holds no seals until it takes part in one commit,"
|
|
+ " which costs at most one proposer turn.");
|
|
}
|
|
|
|
// The list is already ascending by index and de-duplicated by signer address; assert the format
|
|
// invariant here rather than trusting the loop, because this is the exact property the digest
|
|
// rule and the seals rule both depend on.
|
|
if (!PqAnchor.hasStrictlyIncreasingIndices(certificate)) {
|
|
throw new IllegalStateException(
|
|
"AERE PQ-ANCHOR: assembled a certificate whose indices are not strictly increasing; "
|
|
+ "refusing to write it. This is a bug in the producer, not a configuration fault.");
|
|
}
|
|
|
|
- if (cfg.anchorV2AppliesAt(blockNumber)) {
|
|
+ // 1(b): the form from the one method; anchorV2AppliesAt now means "v2 or v3" and must not pick the v2 producer
|
|
+ if (cfg.certificateFormAt(blockNumber) == PqAnchorConfig.CertificateForm.V2) {
|
|
return applyV2(cfg, blockNumber, parentHeader, base, certificate, message, required, sealCap);
|
|
}
|
|
final Bytes32 digest =
|
|
PqAnchor.anchorDigest(
|
|
cfg.chainId(), parentNumber, parentHeader.getHash().getBytes(), certificate);
|
|
|
|
LOG.debug(
|
|
"AERE PQ-ANCHOR: block {} carries a {}-seal certificate over parent {} (K={}), vanity D={}",
|
|
blockNumber,
|
|
certificate.size(),
|
|
parentNumber,
|
|
required,
|
|
digest);
|
|
|
|
return new BftExtraData(
|
|
digest,
|
|
base.getSeals(),
|
|
base.getVote(),
|
|
base.getRound(),
|
|
base.getValidators(),
|
|
- certificate);
|
|
+ certificate,
|
|
+ List.of(),
|
|
+ BftExtraData.NO_CERTIFICATE_ROUND);
|
|
}
|
|
|
|
/**
|
|
* AERE ANCHOR V2 (2026-09-03): the SCHEME-TAGGED certificate. Carries the Falcon seals already
|
|
* verified by the caller, tagged 0x01, plus, for every extra scheme the scheme schedule names at
|
|
* the PARENT height, the heard seals of that scheme that (a) come from an index that also holds a
|
|
* Falcon seal in this very certificate, the binding that stops a lone hash-based seal from
|
|
* standing in for a validator, and (b) verify under the hybrid registry's key for that index and
|
|
* scheme, over the SAME message M(parent) the Falcon seal signs. K seals per scheme, capped like
|
|
* Falcon. vanityData becomes the v2 digest under "AERE-PQ-ANCHOR-2". Refuses, through the same
|
|
* not-ready exception the v1 path uses, rather than writing a certificate short of a scheme.
|
|
*/
|
|
private static BftExtraData applyV2(
|
|
final PqAnchorConfig cfg,
|
|
final long blockNumber,
|
|
final BlockHeader parentHeader,
|
|
final BftExtraData base,
|
|
final List<FalconSeal> falconCertificate,
|
|
final Bytes32 message,
|
|
final int required,
|
|
final int sealCap) {
|
|
final long parentNumber = parentHeader.getNumber();
|
|
final List<SchemeSeal> v2 = new ArrayList<>();
|
|
final Set<Integer> falconIndices = new LinkedHashSet<>();
|
|
for (final FalconSeal f : falconCertificate) {
|
|
v2.add(new SchemeSeal(SealSchemes.FALCON_512.wireId(), f.getValidatorIndex(), f.getSignature()));
|
|
falconIndices.add(f.getValidatorIndex());
|
|
}
|
|
final HybridSealSupport hybrid = HybridSealSupport.instance();
|
|
// AIP-22 stage 2: only the schemes THIS anchor height demands (per-scheme grids counted from
|
|
// the activation height); at a Falcon-only anchor no SLH-DSA seal is gathered or written, which
|
|
// is the whole disk saving of the two-grid design
|
|
final Set<String> schemes =
|
|
hybrid
|
|
.schedule()
|
|
.map(sch -> sch.schemesRequiredForAnchor(blockNumber, cfg.anchorBlock()))
|
|
.orElse(Set.of());
|
|
final List<SchemeSeal> heard =
|
|
- PqSealCache.instance().extrasFor(parentNumber, parentHeader.getHash());
|
|
+ PqSealCache.instance().extrasFor(parentNumber, parentHeader.getHash(), PqSealCache.ANY_ROUND);
|
|
for (final String schemeId : schemes) {
|
|
if (SealSchemes.FALCON_512.id().equals(schemeId)) {
|
|
continue;
|
|
}
|
|
final Optional<SealScheme> scheme = SealSchemes.byId(schemeId);
|
|
if (scheme.isEmpty()) {
|
|
throw new PqAnchorNotReadyException(
|
|
parentNumber,
|
|
0,
|
|
required,
|
|
"the scheme schedule names '" + schemeId + "', which this binary does not implement");
|
|
}
|
|
final Optional<HybridSignerRegistry> registry = hybrid.registry();
|
|
// AERE AIP-22 stage 3b: from H_k the keys come from the v3 epoch in force at the parent
|
|
final boolean v3Keys = AerePqIdentity.keysFromV3(parentNumber);
|
|
if (registry.isEmpty() && !v3Keys) {
|
|
throw new PqAnchorNotReadyException(
|
|
parentNumber,
|
|
0,
|
|
required,
|
|
@@ -465,43 +588,359 @@ public final class PqAnchorProducer {
|
|
v2.sort(PqAnchorV2.CANONICAL);
|
|
final Bytes32 digest =
|
|
PqAnchorV2.anchorDigestV2(
|
|
cfg.chainId(), parentNumber, parentHeader.getHash().getBytes(), v2);
|
|
LOG.debug(
|
|
"AERE PQ-ANCHOR V2: block {} carries a {}-seal scheme-tagged certificate over parent {} "
|
|
+ "(K={} per scheme, schemes={}), vanity D2={}",
|
|
blockNumber,
|
|
v2.size(),
|
|
parentNumber,
|
|
required,
|
|
schemes,
|
|
digest);
|
|
return new BftExtraData(
|
|
digest,
|
|
base.getSeals(),
|
|
base.getVote(),
|
|
base.getRound(),
|
|
base.getValidators(),
|
|
List.of(),
|
|
- v2);
|
|
+ v2,
|
|
+ BftExtraData.NO_CERTIFICATE_ROUND);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * AERE 1(b), AERE-R1B-PRODUCATOR (section 3.1 C): the v3 certificate, the seals of ONE round of the
|
|
+ * parent. The rounds this node holds for (p, hash(p)) are walked by the number of Falcon seals heard
|
|
+ * (more first), then by round (smaller first), and verified LAZILY, one round at a time, on the own-head
|
|
+ * doors the v1 and v2 producers use: the Falcon seals of distinct eligible members over M_r(p), then the
|
|
+ * extras of the SAME round bound to a kept Falcon index, over the same M_r. The first round with Falcon
|
|
+ * at least max(K_eff, Q(set(p))) and every required scheme at least K_eff is taken; otherwise the best
|
|
+ * round that reaches K_eff (most Falcon, then smallest r). The cap is max(maxSeals, Q), applied AFTER
|
|
+ * verification, never below Q. Before it is written the certificate is judged by {@link
|
|
+ * PqAnchorV3#judgeSeals}, the function R2 uses; a refusal there is a defect, logged as an ERROR with its
|
|
+ * code, and nothing is proposed. No round at K_eff: not ready, with the count of every round in the
|
|
+ * message. K_eff = 0 and nothing held: the empty certificate (decision H5).
|
|
+ *
|
|
+ * <p>Pending D-339 seals (a Commit of round r > 0 heard without the proposal) are moved under their
|
|
+ * round when the block they name is imported (the QBFT state machine resolves them with the commit
|
|
+ * digest of each round); this method only reads what is held.
|
|
+ */
|
|
+ private static BftExtraData applyV3(
|
|
+ final PqAnchorConfig cfg,
|
|
+ final long blockNumber,
|
|
+ final BlockHeader parentHeader,
|
|
+ final BftExtraData base,
|
|
+ final ProtocolContext protocolContext) {
|
|
+ final long parentNumber = parentHeader.getNumber();
|
|
+ final Bytes parentHash = parentHeader.getHash().getBytes();
|
|
+ // section 3.1 C, step 1: the Commits of rounds r > 0 held aside under their digest (D-339, D-227) are moved
|
|
+ // under (p, hash(p), r) first, the digest of each round rebuilt here from the parent's header
|
|
+ resolvePendingFor(parentHeader);
|
|
+ final PqSignerRegistry registry = PqSignerRegistry.falconSealSupport();
|
|
+ final Set<Address> eligible = validatorsForParent(parentHeader, protocolContext);
|
|
+ final int quorum = BftHelpers.calculateRequiredValidatorQuorum(eligible.size());
|
|
+ final int kEff = cfg.minSealsAt(blockNumber);
|
|
+ final int cap = Math.max(cfg.maxSealsCarried().orElse(Integer.MAX_VALUE), quorum);
|
|
+ final HybridSealSupport hybrid = HybridSealSupport.instance();
|
|
+ final Set<String> named = new LinkedHashSet<>();
|
|
+ final Set<String> required = new LinkedHashSet<>();
|
|
+ hybrid
|
|
+ .schedule()
|
|
+ .ifPresent(
|
|
+ sch -> {
|
|
+ named.addAll(sch.schemesAt(parentNumber));
|
|
+ required.addAll(sch.schemesRequiredForAnchor(blockNumber, cfg.anchorBlock()));
|
|
+ });
|
|
+ named.remove(SealSchemes.FALCON_512.id());
|
|
+ required.remove(SealSchemes.FALCON_512.id());
|
|
+
|
|
+ final java.util.NavigableMap<Integer, PqSealCache.RoundSeals> held =
|
|
+ PqSealCache.instance().roundsFor(parentNumber, parentHeader.getHash());
|
|
+ final List<Integer> order = new ArrayList<>(held.keySet());
|
|
+ order.sort(
|
|
+ java.util.Comparator.<Integer>comparingInt(r -> -held.get(r).falcon().size())
|
|
+ .thenComparingInt(r -> r));
|
|
+ final StringBuilder counts = new StringBuilder();
|
|
+ int bestRound = -1;
|
|
+ List<SchemeSeal> bestRows = null;
|
|
+ int bestFalcon = -1;
|
|
+ for (final int r : order) {
|
|
+ final Optional<Bytes32> message = anchorSealMessage(cfg, parentNumber, parentHash, r);
|
|
+ if (message.isEmpty()) {
|
|
+ continue;
|
|
+ }
|
|
+ final List<FalconSeal> falcon = new ArrayList<>();
|
|
+ final Set<Address> seen = new LinkedHashSet<>();
|
|
+ // gathered on R2's own doors (the HISTORY doors at the parent, second review of step 4): rows chosen on the own-head
|
|
+ // doors could be rows R2 refuses at an epoch boundary, and the self-check would then refuse every proposal
|
|
+ final PqAnchorV3.Signers doors = PqAnchorV3.historicSigners(registry, parentNumber, () -> eligible);
|
|
+ for (final FalconSeal seal : PqAnchor.sortedByIndex(held.get(r).falcon())) {
|
|
+ final Address signer = doors.memberAt(seal.getValidatorIndex());
|
|
+ if (signer == null || !eligible.contains(signer) || !seen.add(signer)) {
|
|
+ continue;
|
|
+ }
|
|
+ if (doors.verifyFalcon(seal.getValidatorIndex(), message.get(), seal.getSignature())) {
|
|
+ falcon.add(seal);
|
|
+ }
|
|
+ }
|
|
+ final Set<Integer> falconIndices = new LinkedHashSet<>();
|
|
+ falcon.forEach(f -> falconIndices.add(f.getValidatorIndex()));
|
|
+ final List<SchemeSeal> extras = verifiedExtrasOfRound(doors, held.get(r).extras(), falconIndices, required, message.get());
|
|
+ final java.util.Map<String, Integer> perScheme = new java.util.HashMap<>();
|
|
+ for (final SchemeSeal s : extras) {
|
|
+ SealSchemes.byWireId(s.getSchemeWireId()).ifPresent(sc -> perScheme.merge(sc.id(), 1, Integer::sum));
|
|
+ }
|
|
+ final boolean schemesOk = required.stream().allMatch(id -> perScheme.getOrDefault(id, 0) >= kEff);
|
|
+ counts.append(" r").append(r).append(':').append(falcon.size());
|
|
+ if (!schemesOk || falcon.size() < kEff) {
|
|
+ continue;
|
|
+ }
|
|
+ final List<SchemeSeal> rows = capped(falcon, extras, required, kEff, cap);
|
|
+ if (falcon.size() >= Math.max(kEff, quorum)) {
|
|
+ bestRound = r;
|
|
+ bestRows = rows;
|
|
+ break;
|
|
+ }
|
|
+ if (falcon.size() > bestFalcon) {
|
|
+ bestFalcon = falcon.size();
|
|
+ bestRound = r;
|
|
+ bestRows = rows;
|
|
+ }
|
|
+ }
|
|
+ // review of step 4 (2026-10-01, HIGH): a round can be "best" with ZERO verified rows at K_eff = 0 (garbage held
|
|
+ // under round r > 0); the empty v3 certificate must name round 0 (decision H5), or encode() throws into the QBFT
|
|
+ // state machine. An empty certificate is the empty certificate, whatever round was held.
|
|
+ if (bestRows != null && bestRows.isEmpty()) {
|
|
+ bestRound = 0;
|
|
+ }
|
|
+ if (bestRows == null) {
|
|
+ if (kEff == 0) {
|
|
+ bestRound = 0;
|
|
+ bestRows = List.of();
|
|
+ } else {
|
|
+ throw new PqAnchorNotReadyException(
|
|
+ parentNumber,
|
|
+ Math.max(0, bestFalcon),
|
|
+ kEff,
|
|
+ "AERE PQ ANCHOR: no single round of parent "
|
|
+ + parentNumber
|
|
+ + " reaches K="
|
|
+ + kEff
|
|
+ + (required.isEmpty() ? "" : " with every scheme " + required)
|
|
+ + "; rounds"
|
|
+ + (counts.length() == 0 ? " none held" : counts.toString())
|
|
+ + " (verified Falcon seals per round). Seals of different rounds are never added up.");
|
|
+ }
|
|
+ }
|
|
+ final PqAnchorV3.Certificate certificate = new PqAnchorV3.Certificate(bestRound, bestRows);
|
|
+ // the self-check is R2's judgement on R2's doors (the HISTORY doors at the parent, review of step 4): a check on the
|
|
+ // own-head doors the rows were gathered with could pass what R2 refuses at an epoch boundary
|
|
+ final PqAnchorV3.Verdict self =
|
|
+ PqAnchorV3.judgeSeals(
|
|
+ cfg,
|
|
+ blockNumber,
|
|
+ parentHash,
|
|
+ certificate,
|
|
+ kEff,
|
|
+ named,
|
|
+ required,
|
|
+ PqAnchorV3.historicSigners(registry, parentNumber, () -> eligible));
|
|
+ if (!self.accepted()) {
|
|
+ LOG.error(
|
|
+ "AERE PQ ANCHOR: the v3 certificate this node assembled for block {} is REFUSED by its own R2 judgement ({});"
|
|
+ + " not proposing. This must never happen: it is a defect of the producer, not a lost round.",
|
|
+ blockNumber,
|
|
+ self.describe());
|
|
+ throw new PqAnchorNotReadyException(parentNumber, bestRows.size(), kEff, self.describe());
|
|
+ }
|
|
+ final Bytes32 digest;
|
|
+ try {
|
|
+ digest = PqAnchorV3.anchorDigestV3(cfg.chainId(), parentNumber, parentHash, certificate);
|
|
+ } catch (final RuntimeException e) {
|
|
+ // H11: nothing the assembly can throw reaches the QBFT state machine; a refusal to propose instead
|
|
+ LOG.error("AERE PQ ANCHOR: the v3 certificate of block {} could not be encoded ({}); not proposing.", blockNumber, e.toString());
|
|
+ throw new PqAnchorNotReadyException(parentNumber, bestRows.size(), kEff, PqAnchorV3.V3_03 + ": " + e.getMessage());
|
|
+ }
|
|
+ LOG.debug(
|
|
+ "AERE PQ-ANCHOR V3: block {} carries a {}-row certificate of round {} over parent {} (K={}, Q={}, cap={}), vanity D3={}",
|
|
+ blockNumber,
|
|
+ bestRows.size(),
|
|
+ bestRound,
|
|
+ parentNumber,
|
|
+ kEff,
|
|
+ quorum,
|
|
+ cap,
|
|
+ digest);
|
|
+ return new BftExtraData(
|
|
+ digest,
|
|
+ base.getSeals(),
|
|
+ base.getVote(),
|
|
+ base.getRound(),
|
|
+ base.getValidators(),
|
|
+ List.of(),
|
|
+ bestRows,
|
|
+ bestRound);
|
|
}
|
|
|
|
+ /**
|
|
+ * 1(b): the extraData codec of the chain, installed once at startup (QbftBesuControllerBuilder), so the producer can
|
|
+ * rebuild the digest a Commit of round r names for the parent (the hash of the parent's header with its round set
|
|
+ * to r, under the committed-seal header functions). Without it pending seals stay pending: a lost proposer turn at
|
|
+ * worst, never a wrong certificate.
|
|
+ */
|
|
+ private static volatile org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec extraDataCodec;
|
|
+
|
|
+ /**
|
|
+ * Install the chain's extraData codec (1(b), pending seals). For the controller builder and the probes.
|
|
+ *
|
|
+ * @param codec the codec, or null to forget it
|
|
+ */
|
|
+ public static void useExtraDataCodec(
|
|
+ final org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec codec) {
|
|
+ extraDataCodec = codec;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * 1(b): move the pending round-bound seals of a STORED block (D-339 / D-227 at r > 0, held under the digest their
|
|
+ * Commit names) under (n, hash, r), rebuilding the digest of each round from the header with the chain's codec. The
|
|
+ * producer calls it for the anchor's parent; the AIP-21 record and the tip gate call it before they read the rounds
|
|
+ * (review of step 4: the import path of the node's own round never runs in the D-339 case, which is exactly the case
|
|
+ * without a proposal). Never throws; without a codec installed it does nothing.
|
|
+ *
|
|
+ * @param header the stored block's header
|
|
+ */
|
|
+ public static void resolvePendingFor(final BlockHeader header) {
|
|
+ if (header == null || commitSealFormAt(config(), header.getNumber()) != CommitSealForm.ROUND_BOUND) {
|
|
+ return;
|
|
+ }
|
|
+ resolvePendingOf(header);
|
|
+ }
|
|
+
|
|
+ private static void resolvePendingOf(final BlockHeader parentHeader) {
|
|
+ final org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec codec = extraDataCodec;
|
|
+ if (codec == null) {
|
|
+ return;
|
|
+ }
|
|
+ try {
|
|
+ final org.hyperledger.besu.consensus.common.bft.BftBlockInterface blockInterface =
|
|
+ new org.hyperledger.besu.consensus.common.bft.BftBlockInterface(codec);
|
|
+ final org.hyperledger.besu.ethereum.core.Block block =
|
|
+ new org.hyperledger.besu.ethereum.core.Block(
|
|
+ parentHeader, org.hyperledger.besu.ethereum.core.BlockBody.empty());
|
|
+ final int moved =
|
|
+ PqSealCache.instance()
|
|
+ .resolvePending(
|
|
+ parentHeader.getNumber(),
|
|
+ parentHeader.getHash(),
|
|
+ r ->
|
|
+ blockInterface
|
|
+ .replaceRoundInBlock(
|
|
+ block,
|
|
+ r,
|
|
+ org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions
|
|
+ .forCommittedSeal(codec))
|
|
+ .getHash());
|
|
+ if (moved > 0) {
|
|
+ LOG.debug("AERE PQ-ANCHOR V3: {} pending Commit(s) of parent {} moved under their round", moved, parentHeader.getNumber());
|
|
+ }
|
|
+ } catch (final RuntimeException e) {
|
|
+ LOG.debug("AERE PQ-ANCHOR V3: pending seals of parent {} not resolved ({})", parentHeader.getNumber(), e.toString());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /** The extras of one round, each bound to a kept Falcon index and verified over the same M_r. */
|
|
+ private static List<SchemeSeal> verifiedExtrasOfRound(
|
|
+ final PqAnchorV3.Signers doors,
|
|
+ final List<SchemeSeal> heard,
|
|
+ final Set<Integer> falconIndices,
|
|
+ final Set<String> required,
|
|
+ final Bytes32 message) {
|
|
+ final List<SchemeSeal> out = new ArrayList<>();
|
|
+ for (final SchemeSeal s : heard) {
|
|
+ final Optional<SealScheme> scheme = SealSchemes.byWireId(s.getSchemeWireId());
|
|
+ if (scheme.isEmpty() || !required.contains(scheme.get().id()) || !falconIndices.contains(s.getValidatorIndex())) {
|
|
+ continue;
|
|
+ }
|
|
+ // the key from R2's door (the v3 epoch from H_k, the hybrid registry before it)
|
|
+ Optional<byte[]> pk;
|
|
+ try {
|
|
+ pk = doors.extraKey(s.getValidatorIndex(), scheme.get());
|
|
+ } catch (final RuntimeException e) {
|
|
+ pk = Optional.empty();
|
|
+ }
|
|
+ boolean ok;
|
|
+ try {
|
|
+ ok = pk != null && pk.isPresent() && scheme.get().verifyRaw(pk.get(), message.toArray(), s.getSignature().toArray());
|
|
+ } catch (final RuntimeException e) {
|
|
+ ok = false;
|
|
+ }
|
|
+ if (ok) {
|
|
+ out.add(s);
|
|
+ }
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The rows of the chosen round after the cap (max(maxSeals, Q), never below Q): the Falcon indices that
|
|
+ * carry every required extra first, then by index, so a cap never drops a scheme below K_eff while a
|
|
+ * kept index could have carried it; if it would anyway, the cap is not applied (it is a cost control, the
|
|
+ * threshold is not).
|
|
+ */
|
|
+ private static List<SchemeSeal> capped(
|
|
+ final List<FalconSeal> falcon,
|
|
+ final List<SchemeSeal> extras,
|
|
+ final Set<String> required,
|
|
+ final int kEff,
|
|
+ final int cap) {
|
|
+ final java.util.Map<Integer, Integer> extrasOf = new java.util.HashMap<>();
|
|
+ for (final SchemeSeal s : extras) {
|
|
+ extrasOf.merge(s.getValidatorIndex(), 1, Integer::sum);
|
|
+ }
|
|
+ final List<FalconSeal> ordered = new ArrayList<>(falcon);
|
|
+ ordered.sort(
|
|
+ java.util.Comparator.<FalconSeal>comparingInt(f -> -extrasOf.getOrDefault(f.getValidatorIndex(), 0))
|
|
+ .thenComparingInt(FalconSeal::getValidatorIndex));
|
|
+ final List<FalconSeal> kept = ordered.size() > cap ? ordered.subList(0, cap) : ordered;
|
|
+ final Set<Integer> keptIndices = new LinkedHashSet<>();
|
|
+ kept.forEach(f -> keptIndices.add(f.getValidatorIndex()));
|
|
+ final List<SchemeSeal> rows = new ArrayList<>();
|
|
+ for (final FalconSeal f : kept) {
|
|
+ rows.add(new SchemeSeal(SealSchemes.FALCON_512.wireId(), f.getValidatorIndex(), f.getSignature()));
|
|
+ }
|
|
+ final java.util.Map<String, Integer> perScheme = new java.util.HashMap<>();
|
|
+ for (final SchemeSeal s : extras) {
|
|
+ if (keptIndices.contains(s.getValidatorIndex())) {
|
|
+ rows.add(s);
|
|
+ SealSchemes.byWireId(s.getSchemeWireId()).ifPresent(sc -> perScheme.merge(sc.id(), 1, Integer::sum));
|
|
+ }
|
|
+ }
|
|
+ if (kept.size() < falcon.size() && !required.stream().allMatch(id -> perScheme.getOrDefault(id, 0) >= kEff)) {
|
|
+ return capped(falcon, extras, required, kEff, Integer.MAX_VALUE);
|
|
+ }
|
|
+ rows.sort(PqAnchorV2.CANONICAL);
|
|
+ return rows;
|
|
+ }
|
|
+
|
|
+
|
|
/**
|
|
* The validator set FOR the parent block: the nodes that were entitled to seal it.
|
|
*
|
|
* <p>Taken for the PARENT, not for the block being built, because those are the nodes whose seals
|
|
* a certificate over the parent may contain. On a validator-set change the two sets differ, and
|
|
* using the wrong one would either admit a seal the validator side rejects or drop one it
|
|
* accepts.
|
|
*/
|
|
private static Set<Address> validatorsForParent(
|
|
final BlockHeader parentHeader, final ProtocolContext protocolContext) {
|
|
final Collection<Address> validators =
|
|
protocolContext
|
|
.getConsensusContext(BftContext.class)
|
|
.getValidatorProvider()
|
|
.getValidatorsForBlock(parentHeader);
|
|
return new LinkedHashSet<>(validators);
|
|
}
|
|
|
|
/**
|
|
* The first stage must not be able to block anything. K at the activation height itself has to be
|
|
diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/messagewrappers/BftMessage.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/messagewrappers/BftMessage.java
|
|
index c99dfc45a5..66c7815acf 100644
|
|
--- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/messagewrappers/BftMessage.java
|
|
+++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/messagewrappers/BftMessage.java
|
|
@@ -1,39 +1,39 @@
|
|
/*
|
|
* Copyright ConsenSys AG.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
- * found, as section 4(c) requires. The change itself is in patches/0008-aere-pq-aip22.patch.
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0009-aere-pq-seal-judge-snap-cap.patch.
|
|
*/
|
|
package org.hyperledger.besu.consensus.common.bft.messagewrappers;
|
|
|
|
import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
|
import org.hyperledger.besu.consensus.common.bft.payload.Authored;
|
|
import org.hyperledger.besu.consensus.common.bft.payload.Payload;
|
|
import org.hyperledger.besu.consensus.common.bft.payload.RoundSpecific;
|
|
import org.hyperledger.besu.consensus.common.bft.payload.SignedData;
|
|
import org.hyperledger.besu.crypto.SECPSignature;
|
|
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
|
import org.hyperledger.besu.datatypes.Address;
|
|
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
|
|
import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
|
|
|
import java.util.Objects;
|
|
import java.util.StringJoiner;
|
|
import java.util.function.Function;
|
|
|
|
import org.apache.tuweni.bytes.Bytes;
|
|
|
|
diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AereD454SealCacheTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AereD454SealCacheTest.java
|
|
index ac0f0ea657..aaa5732f1b 100644
|
|
--- a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AereD454SealCacheTest.java
|
|
+++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AereD454SealCacheTest.java
|
|
@@ -188,41 +188,41 @@ public class AereD454SealCacheTest {
|
|
hearGarbageFalcon(head, (byte) 0x32);
|
|
hearFalcon(head, 0, 1); // A's genuine seal is the LAST change: same count, other bytes
|
|
PqSealCache.instance().clear(); // the restart: memory gone, the file stays
|
|
final int restored =
|
|
PqSealCache.instance()
|
|
.restoreFromDisk(head.getNumber(), head.getHash(), PqSignerRegistry.falconSealSupport());
|
|
assertThat(restored).describedAs("the K genuine seals come back from the file, A's included").isEqualTo(K);
|
|
assertThat(PqAnchorProducer.apply(base(), head, contextWith(validators)).getFalconSeals())
|
|
.hasSize(K)
|
|
.anyMatch(s -> s.getValidatorIndex() == 0);
|
|
}
|
|
|
|
/** The same rule for the extra scheme of a v2 certificate. */
|
|
@Test
|
|
public void aGarbageSlhDsaSealHeardFirstNoLongerKeepsTheGenuineOneOut() {
|
|
final BlockHeader parent = parentOf(V2 + 9L); // a v2 anchor parent: Falcon and SLH-DSA
|
|
hearFalcon(parent, 0, K);
|
|
PqSealCache.instance()
|
|
.recordExtras(
|
|
parent.getNumber(),
|
|
- parent.getHash(),
|
|
+ parent.getHash(), 0,
|
|
List.of(new SchemeSeal(SealSchemes.SLH_DSA_128S.wireId(), 0, garbage(7856, (byte) 0x33))));
|
|
hearSlh(parent, 0, K);
|
|
final List<SchemeSeal> tagged =
|
|
PqAnchorProducer.apply(base(), parent, contextWith(validators)).getHybridSeals();
|
|
assertThat(PqAnchorV2.distinctValidatorsWith(tagged, SealSchemes.SLH_DSA_128S.wireId()))
|
|
.describedAs("K SLH-DSA seals, A's genuine one among them")
|
|
.isEqualTo(K);
|
|
assertThat(tagged)
|
|
.anyMatch(
|
|
s -> s.getSchemeWireId() == SealSchemes.SLH_DSA_128S.wireId() && s.getValidatorIndex() == 0);
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------ nothing else moved
|
|
|
|
/** A verified seal is never displaced, by anything heard after it. */
|
|
@Test
|
|
public void aGarbageFalconSealAfterTheGenuineOneDisplacesNothing() {
|
|
final BlockHeader parent = parentOf(V2 - 2L);
|
|
hearFalcon(parent, 0, K);
|
|
hearGarbageFalcon(parent, (byte) 0x34);
|
|
@@ -259,44 +259,44 @@ public class AereD454SealCacheTest {
|
|
@Test
|
|
public void belowHFinAGarbageFalconSealHeardFirstStaysAsToday() throws Exception {
|
|
setFinalityBlock(H_FIN_ABOVE);
|
|
final BlockHeader parent = parentOf(V2 - 2L);
|
|
hearGarbageFalcon(parent, (byte) 0x38);
|
|
hearFalcon(parent, 0, K);
|
|
assertThat(heldFalcon(parent, 0))
|
|
.describedAs("below H_fin the first seal of index 0 stays, as in today's binary")
|
|
.isEqualTo(garbage(666, (byte) 0x38));
|
|
assertThat(heldFalcon(parent, 1)).isEqualTo(genuine.get(1));
|
|
}
|
|
|
|
/** Below H_fin the first SLH-DSA seal of an index stays too. */
|
|
@Test
|
|
public void belowHFinAGarbageSlhDsaSealHeardFirstStaysAsToday() throws Exception {
|
|
setFinalityBlock(H_FIN_ABOVE);
|
|
final BlockHeader parent = parentOf(V2 + 9L);
|
|
PqSealCache.instance()
|
|
.recordExtras(
|
|
parent.getNumber(),
|
|
- parent.getHash(),
|
|
+ parent.getHash(), 0,
|
|
List.of(new SchemeSeal(SealSchemes.SLH_DSA_128S.wireId(), 0, garbage(7856, (byte) 0x39))));
|
|
hearSlh(parent, 0, K);
|
|
- final List<SchemeSeal> held = PqSealCache.instance().extrasFor(parent.getNumber(), parent.getHash());
|
|
+ final List<SchemeSeal> held = PqSealCache.instance().extrasFor(parent.getNumber(), parent.getHash(), 0);
|
|
assertThat(held).describedAs("one SLH-DSA slot per index, K indices").hasSize(K);
|
|
assertThat(held)
|
|
.filteredOn(s -> s.getValidatorIndex() == 0)
|
|
.extracting(SchemeSeal::getSignature)
|
|
.describedAs("below H_fin the first SLH-DSA seal of index 0 stays, as in today's binary")
|
|
.containsExactly(garbage(7856, (byte) 0x39));
|
|
}
|
|
|
|
/** Below H_fin a restore from the head file displaces nothing held (putIfAbsent, as today). */
|
|
@Test
|
|
public void belowHFinTheRestoreDisplacesNothingAsToday() throws Exception {
|
|
setFinalityBlock(H_FIN_ABOVE);
|
|
final BlockHeader head = parentOf(V2 - 2L);
|
|
hearGarbageFalcon(head, (byte) 0x3a); // index 0 holds garbage in memory
|
|
final List<FalconSeal> onFile = new ArrayList<>();
|
|
for (int i = 0; i < K; i++) {
|
|
onFile.add(new FalconSeal(i, genuineFalcon(head, i)));
|
|
}
|
|
// the head file holds the K genuine seals (as after a restart onto a head whose seals were written)
|
|
PqSealStore.writeAtomically(
|
|
@@ -336,89 +336,89 @@ public class AereD454SealCacheTest {
|
|
.append(".key.")
|
|
.append(SLH)
|
|
.append('=')
|
|
.append(Bytes.wrap(slhKeys.get(i).publicRegistryForm()).toHexString())
|
|
.append('\n');
|
|
}
|
|
final Path reg = tmp.resolve("hybrid-registry.properties");
|
|
Files.writeString(reg, p.toString());
|
|
System.setProperty(HybridSealSupport.PROPERTY_SCHEDULE, schedule);
|
|
System.setProperty(HybridSealSupport.PROPERTY_REGISTRY, reg.toAbsolutePath().toString());
|
|
HybridSealSupport.resetForTesting();
|
|
assertThat(HybridSealSupport.instance().registry()).describedAs("hybrid registry loaded").isPresent();
|
|
}
|
|
|
|
private static BlockHeader parentOf(final long number) {
|
|
return new BlockHeaderTestFixture().number(number).buildHeader();
|
|
}
|
|
|
|
private BftExtraData base() {
|
|
return new BftExtraData(
|
|
- Bytes32.ZERO, Collections.emptyList(), Optional.empty(), 0, validators, Collections.emptyList());
|
|
+ Bytes32.ZERO, Collections.emptyList(), Optional.empty(), 0, validators, Collections.emptyList(), java.util.List.of(), BftExtraData.NO_CERTIFICATE_ROUND);
|
|
}
|
|
|
|
private static Bytes32 message(final BlockHeader parent) {
|
|
return PqAnchor.commitMessage(CHAIN_ID, parent.getNumber(), parent.getHash().getBytes());
|
|
}
|
|
|
|
private final Map<Integer, Bytes> genuine = new HashMap<>();
|
|
|
|
private Bytes genuineFalcon(final BlockHeader parent, final int i) {
|
|
final FalconSigner signer = new FalconSigner();
|
|
signer.init(true, falconKeys.get(i));
|
|
return Bytes.wrap(signer.generateSignature(message(parent).toArray()));
|
|
}
|
|
|
|
/** Records the genuine Falcon seals of indices [from, to); a Falcon signature is randomised, so the
|
|
* seal of an index is the one recorded here ({@link #genuine}, one parent per test). */
|
|
private void hearFalcon(final BlockHeader parent, final int from, final int to) {
|
|
final List<FalconSeal> heard = new ArrayList<>();
|
|
for (int i = from; i < to; i++) {
|
|
final Bytes sig = genuineFalcon(parent, i);
|
|
genuine.put(i, sig);
|
|
heard.add(new FalconSeal(i, sig));
|
|
}
|
|
- PqSealCache.instance().record(parent.getNumber(), parent.getHash(), heard);
|
|
+ PqSealCache.instance().record(parent.getNumber(), parent.getHash(), 0, heard);
|
|
}
|
|
|
|
private void hearGarbageFalcon(final BlockHeader parent, final byte fill) {
|
|
PqSealCache.instance()
|
|
- .record(parent.getNumber(), parent.getHash(), List.of(new FalconSeal(0, garbage(666, fill))));
|
|
+ .record(parent.getNumber(), parent.getHash(), 0, List.of(new FalconSeal(0, garbage(666, fill))));
|
|
}
|
|
|
|
private void hearSlh(final BlockHeader parent, final int from, final int to) {
|
|
final List<SchemeSeal> extras = new ArrayList<>();
|
|
for (int i = from; i < to; i++) {
|
|
extras.add(
|
|
new SchemeSeal(
|
|
SealSchemes.SLH_DSA_128S.wireId(),
|
|
i,
|
|
Bytes.wrap(
|
|
SealSchemes.SLH_DSA_128S
|
|
.sign(slhKeys.get(i).privateKey(), message(parent).toArray())
|
|
.orElseThrow())));
|
|
}
|
|
- PqSealCache.instance().recordExtras(parent.getNumber(), parent.getHash(), extras);
|
|
+ PqSealCache.instance().recordExtras(parent.getNumber(), parent.getHash(), 0, extras);
|
|
}
|
|
|
|
private static Bytes heldFalcon(final BlockHeader parent, final int index) {
|
|
- return PqSealCache.instance().sealsFor(parent.getNumber(), parent.getHash()).stream()
|
|
+ return PqSealCache.instance().sealsFor(parent.getNumber(), parent.getHash(), 0).stream()
|
|
.filter(s -> s.getValidatorIndex() == index)
|
|
.map(FalconSeal::getSignature)
|
|
.findFirst()
|
|
.orElse(Bytes.EMPTY);
|
|
}
|
|
|
|
private static Bytes garbage(final int length, final byte fill) {
|
|
final byte[] b = new byte[length];
|
|
Arrays.fill(b, fill);
|
|
return Bytes.wrap(b);
|
|
}
|
|
|
|
private static ProtocolContext contextWith(final Collection<Address> vs) {
|
|
final ValidatorProvider validatorProvider =
|
|
mock(ValidatorProvider.class, withSettings().strictness(Strictness.LENIENT));
|
|
when(validatorProvider.getValidatorsForBlock(any())).thenReturn(vs);
|
|
when(validatorProvider.getValidatorsAfterBlock(any())).thenReturn(vs);
|
|
final BftContext bftContext =
|
|
mock(BftContext.class, withSettings().strictness(Strictness.LENIENT));
|
|
when(bftContext.getValidatorProvider()).thenReturn(validatorProvider);
|
|
diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AereDecidedBlockChoiceRuleTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AereDecidedBlockChoiceRuleTest.java
|
|
new file mode 100644
|
|
index 0000000000..ba16aade9f
|
|
--- /dev/null
|
|
+++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AereDecidedBlockChoiceRuleTest.java
|
|
@@ -0,0 +1,333 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.common.bft;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.hyperledger.besu.consensus.common.bft.AereDecidedChainFixture.append;
|
|
+import static org.hyperledger.besu.consensus.common.bft.AereDecidedChainFixture.chain;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead.Decided;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead.Outcome;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead.Proof;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
+import org.hyperledger.besu.ethereum.core.Block;
|
|
+
|
|
+import java.nio.file.Path;
|
|
+import java.util.ArrayList;
|
|
+import java.util.List;
|
|
+import java.util.Optional;
|
|
+import java.util.Random;
|
|
+import java.util.concurrent.atomic.AtomicBoolean;
|
|
+
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.junit.jupiter.api.io.TempDir;
|
|
+import org.slf4j.Logger;
|
|
+import org.slf4j.LoggerFactory;
|
|
+
|
|
+/**
|
|
+ * AERE D-412 rule D, step 2, P1 of PROIECT-CAP-DECIS-2026-09-29.md: the block choice rule of a
|
|
+ * validator, on a REAL DefaultBlockchain.
|
|
+ *
|
|
+ * <p>(a) H1: a node that decided B* keeps it as head when a two-block tail B' -> C' built on a
|
|
+ * sibling arrives, however heavy (and the same blocks on a chain without rule D DO adopt the tail:
|
|
+ * the fixture can express the attack). (b) When D advances onto a fork block the chain is rewound
|
|
+ * onto it, after the durable write and under the chain's own monitor. (c) Below the activation height
|
|
+ * the rule is total difficulty: 1000 random trees, 0 divergences, with a positive control that total
|
|
+ * difficulty did reorganise. (d) A CONFLICT leaves D where it was. (e) A failure inside the rule
|
|
+ * falls back to total difficulty. Each property has a planted defect (planteaza-pasul2.py) that turns
|
|
+ * exactly the named probe red.
|
|
+ */
|
|
+class AereDecidedBlockChoiceRuleTest {
|
|
+
|
|
+ private static final Logger LOG = LoggerFactory.getLogger(AereDecidedBlockChoiceRuleTest.class);
|
|
+
|
|
+ private final List<String> alarms = new ArrayList<>();
|
|
+
|
|
+ private AereDecidedHead headOn(
|
|
+ final MutableBlockchain chain, final long activation, final Path file, final int maxWalk) {
|
|
+ return new AereDecidedHead(chain, activation, file, maxWalk, alarms::add);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aDecidedNodeKeepsItsHeadWhenATwoBlockTailArrivesOnASibling(@TempDir final Path tmp) {
|
|
+ final AereDecidedChainFixture fx = new AereDecidedChainFixture();
|
|
+ final Block genesis = fx.genesis();
|
|
+ final List<Block> line = fx.line(genesis, 4);
|
|
+ final Block a4 = line.get(4);
|
|
+ final Block bStar = fx.child(a4, 1L);
|
|
+ final Block bPrime = fx.child(a4, 5L);
|
|
+ final Block cPrime = fx.child(bPrime, 5L);
|
|
+
|
|
+ // control: the same blocks on a chain WITHOUT rule D adopt the tail on total difficulty
|
|
+ final MutableBlockchain plain = chain(genesis);
|
|
+ append(plain, line.subList(1, 5));
|
|
+ append(plain, bStar, bPrime, cPrime);
|
|
+ assertThat(plain.getChainHeadHash())
|
|
+ .as("control: without rule D the tail B' -> C' becomes the head")
|
|
+ .isEqualTo(cPrime.getHash());
|
|
+
|
|
+ final MutableBlockchain chain = chain(genesis);
|
|
+ final AereDecidedHead head =
|
|
+ headOn(chain, 1L, tmp.resolve(AereDecidedHead.FILE_NAME), AereDecidedHead.DEFAULT_MAX_WALK);
|
|
+ final AereDecidedBlockChoiceRule rule = AereDecidedBlockChoiceRule.install(chain, head);
|
|
+ append(chain, line.subList(1, 5));
|
|
+ append(chain, bStar);
|
|
+ assertThat(head.advance(bStar.getHash(), Proof.Q1)).isEqualTo(Outcome.ADVANCED);
|
|
+ append(chain, bPrime, cPrime);
|
|
+
|
|
+ assertThat(chain.getChainHeadHash())
|
|
+ .as("the head of a node that decided B* (C' became head?)")
|
|
+ .isEqualTo(bStar.getHash());
|
|
+ assertThat(chain.getBlockHashByNumber(5L)).contains(bStar.getHash());
|
|
+ assertThat(chain.getBlockHashByNumber(6L)).isEmpty();
|
|
+ assertThat(chain.getBlockHeader(cPrime.getHash())).as("the tail is kept, as a fork").isPresent();
|
|
+ assertThat(head.decided()).isEqualTo(new Decided(5L, bStar.getHash()));
|
|
+ assertThat(rule.overrides()).as("D answered for B' and for C'").isEqualTo(2L);
|
|
+ assertThat(rule.fallbacks()).isZero();
|
|
+ assertThat(alarms).isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void advancingOntoAForkRewindsTheChainAfterTheDurableWriteAndUnderTheChainMonitor(
|
|
+ @TempDir final Path tmp) {
|
|
+ final AereDecidedChainFixture fx = new AereDecidedChainFixture();
|
|
+ final Block genesis = fx.genesis();
|
|
+ final List<Block> line = fx.line(genesis, 4);
|
|
+ final Block a4 = line.get(4);
|
|
+ final Block bPrime = fx.child(a4, 5L);
|
|
+ final Block cPrime = fx.child(bPrime, 5L);
|
|
+ final Block bStar = fx.child(a4, 1L);
|
|
+ final Path file = tmp.resolve(AereDecidedHead.FILE_NAME);
|
|
+
|
|
+ final MutableBlockchain chain = chain(genesis);
|
|
+ final AereDecidedHead head = headOn(chain, 1L, file, AereDecidedHead.DEFAULT_MAX_WALK);
|
|
+ AereDecidedBlockChoiceRule.install(chain, head);
|
|
+ append(chain, line.subList(1, 5));
|
|
+ append(chain, bPrime, cPrime, bStar);
|
|
+ assertThat(chain.getChainHeadHash())
|
|
+ .as("undecided at 5: the provisional head follows total difficulty")
|
|
+ .isEqualTo(cPrime.getHash());
|
|
+
|
|
+ final AtomicBoolean watching = new AtomicBoolean(false);
|
|
+ final List<Boolean> monitorHeld = new ArrayList<>();
|
|
+ final List<Optional<Hash>> fileWhenTheChainMoved = new ArrayList<>();
|
|
+ chain.observeBlockAdded(
|
|
+ event -> {
|
|
+ if (watching.get()) {
|
|
+ monitorHeld.add(Thread.holdsLock(chain));
|
|
+ fileWhenTheChainMoved.add(AereDecidedHead.read(file).map(p -> p.decided().hash()));
|
|
+ }
|
|
+ });
|
|
+ watching.set(true);
|
|
+ final Outcome outcome = head.advance(bStar.getHash(), Proof.Q2);
|
|
+ watching.set(false);
|
|
+
|
|
+ assertThat(outcome).isEqualTo(Outcome.ADVANCED);
|
|
+ assertThat(chain.getChainHeadHash()).as("the head after D moved onto B*").isEqualTo(bStar.getHash());
|
|
+ assertThat(chain.getBlockHashByNumber(5L)).contains(bStar.getHash());
|
|
+ assertThat(chain.getBlockHashByNumber(6L)).as("C' is no longer canonical").isEmpty();
|
|
+ assertThat(head.decided()).isEqualTo(new Decided(5L, bStar.getHash()));
|
|
+ assertThat(monitorHeld).as("the chain moved (a reorg event was seen)").isNotEmpty();
|
|
+ assertThat(monitorHeld)
|
|
+ .as("every chain event of the rewind ran holding the chain's own monitor")
|
|
+ .containsOnly(true);
|
|
+ assertThat(fileWhenTheChainMoved)
|
|
+ .as("the decided head was durable before the chain moved")
|
|
+ .containsOnly(Optional.of(bStar.getHash()));
|
|
+ assertThat(alarms).isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void belowTheActivationHeightTheRuleIsTotalDifficultyOnAThousandRandomTrees(
|
|
+ @TempDir final Path tmp) {
|
|
+ final Differential d = differential(1000, 1_000_000L, tmp, 20260930L);
|
|
+ assertThat(d.blocks).as("blocks appended").isGreaterThan(20_000L);
|
|
+ assertThat(d.divergences).as("heads or canonical blocks that differ from total difficulty").isZero();
|
|
+ assertThat(d.reorgs).as("positive control: total difficulty reorganised the chains").isGreaterThan(100L);
|
|
+ assertThat(d.calls).as("positive control: the chain asked the rule").isGreaterThan(100L);
|
|
+ assertThat(d.overrides).isZero();
|
|
+ assertThat(d.fallbacks).isZero();
|
|
+ assertThat(alarms).isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aboveTheActivationHeightWithNothingDecidedTheRuleIsStillTotalDifficulty(
|
|
+ @TempDir final Path tmp) {
|
|
+ final Differential d = differential(200, 1L, tmp, 20260931L);
|
|
+ assertThat(d.divergences).isZero();
|
|
+ assertThat(d.reorgs).as("positive control: total difficulty reorganised the chains").isGreaterThan(10L);
|
|
+ assertThat(d.calls).isGreaterThan(10L);
|
|
+ assertThat(d.overrides).as("D is genesis: every block is compatible").isZero();
|
|
+ assertThat(d.fallbacks).isZero();
|
|
+ assertThat(alarms).isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aSecondBlockAtTheDecidedHeightIsAConflictAndTheDecidedHeadStays(@TempDir final Path tmp) {
|
|
+ final AereDecidedChainFixture fx = new AereDecidedChainFixture();
|
|
+ final Block genesis = fx.genesis();
|
|
+ final List<Block> line = fx.line(genesis, 4);
|
|
+ final Block a4 = line.get(4);
|
|
+ final Block bStar = fx.child(a4, 10L);
|
|
+ final Block bPrime = fx.child(a4, 1L);
|
|
+
|
|
+ final MutableBlockchain chain = chain(genesis);
|
|
+ final AereDecidedHead head =
|
|
+ headOn(chain, 1L, tmp.resolve(AereDecidedHead.FILE_NAME), AereDecidedHead.DEFAULT_MAX_WALK);
|
|
+ append(chain, line.subList(1, 5));
|
|
+ append(chain, bStar);
|
|
+ assertThat(head.advance(bStar.getHash(), Proof.Q1)).isEqualTo(Outcome.ADVANCED);
|
|
+ append(chain, bPrime);
|
|
+ assertThat(chain.getChainHeadHash()).as("fixture: B' is a fork").isEqualTo(bStar.getHash());
|
|
+
|
|
+ assertThat(head.advance(bPrime.getHash(), Proof.Q2)).isEqualTo(Outcome.CONFLICT);
|
|
+ assertThat(head.decided()).as("D after a conflict").isEqualTo(new Decided(5L, bStar.getHash()));
|
|
+ assertThat(chain.getChainHeadHash()).isEqualTo(bStar.getHash());
|
|
+ assertThat(head.conflicts()).isEqualTo(1L);
|
|
+ assertThat(alarms).hasSize(1);
|
|
+ assertThat(alarms.get(0)).startsWith("CRIT " + AereDecidedHead.CODE_CONFLICT);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aBlockThatDoesNotDescendFromTheDecidedHeadIsAConflictAndTheDecidedHeadStays(
|
|
+ @TempDir final Path tmp) {
|
|
+ final AereDecidedChainFixture fx = new AereDecidedChainFixture();
|
|
+ final Block genesis = fx.genesis();
|
|
+ final List<Block> line = fx.line(genesis, 4);
|
|
+ final Block a4 = line.get(4);
|
|
+ final Block bStar = fx.child(a4, 10L);
|
|
+ final Block bPrime = fx.child(a4, 1L);
|
|
+ final Block cPrime = fx.child(bPrime, 1L);
|
|
+
|
|
+ final MutableBlockchain chain = chain(genesis);
|
|
+ final AereDecidedHead head =
|
|
+ headOn(chain, 1L, tmp.resolve(AereDecidedHead.FILE_NAME), AereDecidedHead.DEFAULT_MAX_WALK);
|
|
+ append(chain, line.subList(1, 5));
|
|
+ append(chain, bStar);
|
|
+ assertThat(head.advance(bStar.getHash(), Proof.Q1)).isEqualTo(Outcome.ADVANCED);
|
|
+ append(chain, bPrime, cPrime);
|
|
+ assertThat(chain.getChainHeadHash()).as("fixture: B' -> C' is a fork").isEqualTo(bStar.getHash());
|
|
+
|
|
+ assertThat(head.advance(cPrime.getHash(), Proof.Q2)).isEqualTo(Outcome.CONFLICT);
|
|
+ assertThat(head.decided()).as("D after a conflict").isEqualTo(new Decided(5L, bStar.getHash()));
|
|
+ assertThat(chain.getChainHeadHash()).isEqualTo(bStar.getHash());
|
|
+ assertThat(chain.getBlockHashByNumber(5L)).contains(bStar.getHash());
|
|
+ assertThat(chain.getBlockHashByNumber(6L)).isEmpty();
|
|
+ assertThat(head.conflicts()).isEqualTo(1L);
|
|
+ assertThat(alarms).hasSize(1);
|
|
+ assertThat(alarms.get(0)).startsWith("CRIT " + AereDecidedHead.CODE_CONFLICT);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aFailureInsideTheRuleFallsBackToTotalDifficultyWithAWarning(@TempDir final Path tmp) {
|
|
+ final AereDecidedChainFixture fx = new AereDecidedChainFixture();
|
|
+ final Block genesis = fx.genesis();
|
|
+ final List<Block> line = fx.line(genesis, 5);
|
|
+ final Block a2 = line.get(2);
|
|
+ final Block f3 = fx.child(a2, 1L);
|
|
+ final Block f4 = fx.child(f3, 1L);
|
|
+ final Block f5 = fx.child(f4, 1L);
|
|
+ final Block f6 = fx.child(f5, 1L);
|
|
+
|
|
+ final MutableBlockchain chain = chain(genesis);
|
|
+ // maxWalk = 2: the ancestry of F5 and F6 down to D = A2 is deeper than that, so judging fails
|
|
+ final AereDecidedHead head = headOn(chain, 1L, tmp.resolve(AereDecidedHead.FILE_NAME), 2);
|
|
+ final AereDecidedBlockChoiceRule rule = AereDecidedBlockChoiceRule.install(chain, head);
|
|
+ append(chain, line.subList(1, 3));
|
|
+ assertThat(head.advance(a2.getHash(), Proof.Q1)).isEqualTo(Outcome.ADVANCED);
|
|
+ append(chain, line.subList(3, 6));
|
|
+ append(chain, f3, f4, f5, f6);
|
|
+
|
|
+ assertThat(rule.fallbacks()).as("judging F5 and F6 failed").isEqualTo(2L);
|
|
+ assertThat(chain.getChainHeadHash())
|
|
+ .as("where the rule cannot judge, total difficulty decides")
|
|
+ .isEqualTo(f6.getHash());
|
|
+ assertThat(head.decided()).isEqualTo(new Decided(2L, a2.getHash()));
|
|
+ assertThat(alarms).isEmpty();
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // the differential: the same random trees on a plain chain and on a chain with rule D
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ private static final class Differential {
|
|
+ private long blocks;
|
|
+ private long divergences;
|
|
+ private long reorgs;
|
|
+ private long calls;
|
|
+ private long overrides;
|
|
+ private long fallbacks;
|
|
+ }
|
|
+
|
|
+ private Differential differential(
|
|
+ final int trees, final long activation, final Path tmp, final long seed) {
|
|
+ final Differential out = new Differential();
|
|
+ final Random random = new Random(seed);
|
|
+ for (int t = 0; t < trees; t++) {
|
|
+ final AereDecidedChainFixture fx = new AereDecidedChainFixture();
|
|
+ final Block genesis = fx.genesis();
|
|
+ final MutableBlockchain plain = chain(genesis);
|
|
+ final MutableBlockchain ruled = chain(genesis);
|
|
+ final AereDecidedHead head =
|
|
+ headOn(ruled, activation, tmp.resolve("tree-" + t), AereDecidedHead.DEFAULT_MAX_WALK);
|
|
+ final AereDecidedBlockChoiceRule rule = AereDecidedBlockChoiceRule.install(ruled, head);
|
|
+ final List<Block> blocks = new ArrayList<>();
|
|
+ blocks.add(genesis);
|
|
+ final int size = 20 + random.nextInt(20);
|
|
+ for (int i = 0; i < size; i++) {
|
|
+ // mostly near the tips, sometimes anywhere: deep and shallow forks both happen
|
|
+ final Block parent =
|
|
+ random.nextInt(10) < 7
|
|
+ ? blocks.get(Math.max(0, blocks.size() - 1 - random.nextInt(4)))
|
|
+ : blocks.get(random.nextInt(blocks.size()));
|
|
+ final Block block = fx.child(parent, 1L + random.nextInt(6));
|
|
+ blocks.add(block);
|
|
+ final Hash before = plain.getChainHeadHash();
|
|
+ append(plain, block);
|
|
+ append(ruled, block);
|
|
+ out.blocks++;
|
|
+ final Hash after = plain.getChainHeadHash();
|
|
+ if (!after.equals(before) && !block.getHeader().getParentHash().equals(before)) {
|
|
+ out.reorgs++;
|
|
+ }
|
|
+ if (!after.equals(ruled.getChainHeadHash())) {
|
|
+ out.divergences++;
|
|
+ }
|
|
+ }
|
|
+ final long top = Math.max(plain.getChainHeadBlockNumber(), ruled.getChainHeadBlockNumber());
|
|
+ for (long n = 0; n <= top; n++) {
|
|
+ if (!plain.getBlockHashByNumber(n).equals(ruled.getBlockHashByNumber(n))) {
|
|
+ out.divergences++;
|
|
+ }
|
|
+ }
|
|
+ out.calls += rule.calls();
|
|
+ out.overrides += rule.overrides();
|
|
+ out.fallbacks += rule.fallbacks();
|
|
+ }
|
|
+ LOG.info(
|
|
+ "AERE D-412 differential (activation {}, {} trees): blocks {}, divergences {}, reorgs {},"
|
|
+ + " rule calls {}, overrides {}, fallbacks {}",
|
|
+ activation,
|
|
+ trees,
|
|
+ out.blocks,
|
|
+ out.divergences,
|
|
+ out.reorgs,
|
|
+ out.calls,
|
|
+ out.overrides,
|
|
+ out.fallbacks);
|
|
+ return out;
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AereDecidedChainFixture.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AereDecidedChainFixture.java
|
|
new file mode 100644
|
|
index 0000000000..603b5ecf68
|
|
--- /dev/null
|
|
+++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AereDecidedChainFixture.java
|
|
@@ -0,0 +1,123 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.common.bft;
|
|
+
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
+import org.hyperledger.besu.ethereum.core.Block;
|
|
+import org.hyperledger.besu.ethereum.core.BlockBody;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+import org.hyperledger.besu.ethereum.core.Difficulty;
|
|
+import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider;
|
|
+
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collections;
|
|
+import java.util.List;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+
|
|
+/**
|
|
+ * AERE D-412 rule D, step 2: blocks with a chosen parent and a chosen difficulty, appended to a REAL
|
|
+ * {@code DefaultBlockchain} (in-memory storage, the chain's own total-difficulty rule). Every block
|
|
+ * carries a distinct tag in its extra data, so two siblings with the same parent and difficulty are
|
|
+ * still two blocks (two actors, two contents, two positions).
|
|
+ */
|
|
+final class AereDecidedChainFixture {
|
|
+
|
|
+ private long tag;
|
|
+
|
|
+ /**
|
|
+ * A genesis block of difficulty 1.
|
|
+ *
|
|
+ * @return the genesis block
|
|
+ */
|
|
+ Block genesis() {
|
|
+ return block(0L, Hash.ZERO, 1L);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * A child of {@code parent}.
|
|
+ *
|
|
+ * @param parent the parent
|
|
+ * @param difficulty the child's difficulty
|
|
+ * @return the child
|
|
+ */
|
|
+ Block child(final Block parent, final long difficulty) {
|
|
+ return block(parent.getHeader().getNumber() + 1L, parent.getHash(), difficulty);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * A line of {@code count} blocks of difficulty 1 above {@code genesis}.
|
|
+ *
|
|
+ * @param genesis the genesis block
|
|
+ * @param count how many blocks above it
|
|
+ * @return the genesis block followed by the line; index i is height i
|
|
+ */
|
|
+ List<Block> line(final Block genesis, final int count) {
|
|
+ final List<Block> out = new ArrayList<>();
|
|
+ out.add(genesis);
|
|
+ for (int i = 0; i < count; i++) {
|
|
+ out.add(child(out.get(out.size() - 1), 1L));
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * A real in-memory DefaultBlockchain.
|
|
+ *
|
|
+ * @param genesis the genesis block
|
|
+ * @return the chain
|
|
+ */
|
|
+ static MutableBlockchain chain(final Block genesis) {
|
|
+ return InMemoryKeyValueStorageProvider.createInMemoryBlockchain(genesis);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Append blocks in order.
|
|
+ *
|
|
+ * @param chain the chain
|
|
+ * @param blocks the blocks
|
|
+ */
|
|
+ static void append(final MutableBlockchain chain, final Block... blocks) {
|
|
+ for (final Block b : blocks) {
|
|
+ chain.appendBlock(b, Collections.emptyList());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Append blocks in order.
|
|
+ *
|
|
+ * @param chain the chain
|
|
+ * @param blocks the blocks
|
|
+ */
|
|
+ static void append(final MutableBlockchain chain, final List<Block> blocks) {
|
|
+ for (final Block b : blocks) {
|
|
+ chain.appendBlock(b, Collections.emptyList());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private Block block(final long number, final Hash parent, final long difficulty) {
|
|
+ tag++;
|
|
+ return new Block(
|
|
+ new BlockHeaderTestFixture()
|
|
+ .number(number)
|
|
+ .parentHash(parent)
|
|
+ .difficulty(Difficulty.of(difficulty))
|
|
+ .extraData(Bytes.ofUnsignedLong(tag))
|
|
+ .timestamp(number)
|
|
+ .buildHeader(),
|
|
+ BlockBody.empty());
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AereDecidedHeadTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AereDecidedHeadTest.java
|
|
new file mode 100644
|
|
index 0000000000..fe64b923f4
|
|
--- /dev/null
|
|
+++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AereDecidedHeadTest.java
|
|
@@ -0,0 +1,356 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.common.bft;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.hyperledger.besu.consensus.common.bft.AereDecidedChainFixture.append;
|
|
+import static org.hyperledger.besu.consensus.common.bft.AereDecidedChainFixture.chain;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead.Decided;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead.Outcome;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead.Persisted;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead.Proof;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
+import org.hyperledger.besu.ethereum.core.Block;
|
|
+
|
|
+import java.io.IOException;
|
|
+import java.nio.charset.StandardCharsets;
|
|
+import java.nio.file.Files;
|
|
+import java.nio.file.Path;
|
|
+import java.util.ArrayList;
|
|
+import java.util.List;
|
|
+import java.util.Optional;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.junit.jupiter.api.io.TempDir;
|
|
+
|
|
+/**
|
|
+ * AERE D-412 rule D, step 2: the decided head itself, on a REAL DefaultBlockchain. D only goes up;
|
|
+ * it is written durably before anyone is told it moved, and a write that fails moves nothing; a
|
|
+ * restart (Q6) takes back the highest decided block on the chain, never takes D from a file that names
|
|
+ * an unknown block, the wrong height or fails its checksum (the unknown block stays a floor, from
|
|
+ * 2026-10-01), and completes an advance that was written but not applied, taking the durable D FIRST and a
|
|
+ * candidate off its line as a CONFLICT (teza Q3, D-470, 2026-10-01); below the proof height
|
|
+ * (H_ev - 1, from 2026-10-01; H_ev before) the canonical head is decided and nothing is written (Q5);
|
|
+ * an ancestor of D is decided and a sibling is not (Q4).
|
|
+ */
|
|
+class AereDecidedHeadTest {
|
|
+
|
|
+ private final List<String> alarms = new ArrayList<>();
|
|
+
|
|
+ private AereDecidedHead headOn(
|
|
+ final MutableBlockchain chain, final long activation, final Path file) {
|
|
+ return new AereDecidedHead(
|
|
+ chain, activation, file, AereDecidedHead.DEFAULT_MAX_WALK, alarms::add);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void theDecidedHeadOnlyGoesUp(@TempDir final Path tmp) {
|
|
+ final AereDecidedChainFixture fx = new AereDecidedChainFixture();
|
|
+ final Block genesis = fx.genesis();
|
|
+ final List<Block> line = fx.line(genesis, 4);
|
|
+ final Block bStar = fx.child(line.get(4), 1L);
|
|
+ final MutableBlockchain chain = chain(genesis);
|
|
+ append(chain, line.subList(1, 5));
|
|
+ append(chain, bStar);
|
|
+ final AereDecidedHead head = headOn(chain, 1L, tmp.resolve(AereDecidedHead.FILE_NAME));
|
|
+ final Decided top = new Decided(5L, bStar.getHash());
|
|
+
|
|
+ assertThat(head.advance(bStar.getHash(), Proof.Q1)).isEqualTo(Outcome.ADVANCED);
|
|
+ assertThat(head.advance(line.get(4).getHash(), Proof.Q4)).isEqualTo(Outcome.UNCHANGED);
|
|
+ assertThat(head.decided()).as("D after proving its parent decided").isEqualTo(top);
|
|
+ assertThat(head.advance(line.get(2).getHash(), Proof.Q3)).isEqualTo(Outcome.UNCHANGED);
|
|
+ assertThat(head.decided()).as("D after proving an older ancestor decided").isEqualTo(top);
|
|
+ assertThat(head.advance(bStar.getHash(), Proof.Q1)).isEqualTo(Outcome.UNCHANGED);
|
|
+ assertThat(head.decided()).isEqualTo(top);
|
|
+ assertThat(head.conflicts()).isZero();
|
|
+ assertThat(alarms).isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void theDecidedHeadIsWrittenDurablyBeforeAnyoneIsToldItMoved(@TempDir final Path tmp)
|
|
+ throws IOException {
|
|
+ final AereDecidedChainFixture fx = new AereDecidedChainFixture();
|
|
+ final Block genesis = fx.genesis();
|
|
+ final List<Block> line = fx.line(genesis, 4);
|
|
+ final Block bStar = fx.child(line.get(4), 1L);
|
|
+ final MutableBlockchain chain = chain(genesis);
|
|
+ append(chain, line.subList(1, 5));
|
|
+ append(chain, bStar);
|
|
+ final Path file = tmp.resolve(AereDecidedHead.FILE_NAME);
|
|
+ final AereDecidedHead head = headOn(chain, 1L, file);
|
|
+ final Decided top = new Decided(5L, bStar.getHash());
|
|
+ final List<Optional<Decided>> fileWhenTold = new ArrayList<>();
|
|
+ head.onAdvanced(d -> fileWhenTold.add(AereDecidedHead.read(file).map(Persisted::decided)));
|
|
+
|
|
+ assertThat(head.advance(bStar.getHash(), Proof.Q1)).isEqualTo(Outcome.ADVANCED);
|
|
+
|
|
+ assertThat(fileWhenTold).as("the listener was told once").hasSize(1);
|
|
+ assertThat(fileWhenTold.get(0)).as("the file when the listener was told").contains(top);
|
|
+ final Optional<Persisted> onDisk = AereDecidedHead.read(file);
|
|
+ assertThat(onDisk.map(Persisted::decided)).contains(top);
|
|
+ assertThat(onDisk.map(Persisted::proof)).contains(Proof.Q1);
|
|
+ assertThat(Files.readAllBytes(file)).isEqualTo(AereDecidedHead.encode(top, Proof.Q1));
|
|
+ assertThat(new String(Files.readAllBytes(file), StandardCharsets.US_ASCII))
|
|
+ .startsWith(AereDecidedHead.MAGIC + "\n");
|
|
+ assertThat(Files.exists(tmp.resolve(AereDecidedHead.FILE_NAME + ".tmp")))
|
|
+ .as("no temporary file left behind")
|
|
+ .isFalse();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aWriteThatFailsLeavesTheDecidedHeadAndTheChainWhereTheyWere(@TempDir final Path tmp)
|
|
+ throws IOException {
|
|
+ final AereDecidedChainFixture fx = new AereDecidedChainFixture();
|
|
+ final Block genesis = fx.genesis();
|
|
+ final List<Block> line = fx.line(genesis, 4);
|
|
+ final Block bPrime = fx.child(line.get(4), 5L);
|
|
+ final Block bStar = fx.child(line.get(4), 1L);
|
|
+ final MutableBlockchain chain = chain(genesis);
|
|
+ append(chain, line.subList(1, 5));
|
|
+ append(chain, bPrime, bStar);
|
|
+ assertThat(chain.getChainHeadHash()).as("fixture: B' is the head, B* a fork").isEqualTo(bPrime.getHash());
|
|
+ // the file's directory is a regular file: every durable write fails
|
|
+ final Path notADirectory = tmp.resolve("not-a-directory");
|
|
+ Files.write(notADirectory, new byte[] {'x'});
|
|
+ final AereDecidedHead head =
|
|
+ headOn(chain, 1L, notADirectory.resolve(AereDecidedHead.FILE_NAME));
|
|
+ final Decided before = head.decided();
|
|
+
|
|
+ assertThat(head.advance(bStar.getHash(), Proof.Q1)).isEqualTo(Outcome.NOT_DURABLE);
|
|
+ assertThat(head.decided()).as("D after a failed write").isEqualTo(before);
|
|
+ assertThat(chain.getChainHeadHash()).as("the chain after a failed write").isEqualTo(bPrime.getHash());
|
|
+ assertThat(head.notDurableCount()).isEqualTo(1L);
|
|
+ assertThat(alarms).hasSize(1);
|
|
+ assertThat(alarms.get(0)).startsWith("CRIT " + AereDecidedHead.CODE_NOT_DURABLE);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aRestartTakesBackTheHighestDecidedBlockThatIsOnTheChain(@TempDir final Path tmp) {
|
|
+ final AereDecidedChainFixture fx = new AereDecidedChainFixture();
|
|
+ final Block genesis = fx.genesis();
|
|
+ final List<Block> line = fx.line(genesis, 4);
|
|
+ final Block bStar = fx.child(line.get(4), 1L);
|
|
+ final Block d6 = fx.child(bStar, 1L);
|
|
+ final MutableBlockchain chain = chain(genesis);
|
|
+ append(chain, line.subList(1, 5));
|
|
+ append(chain, bStar);
|
|
+ final Path file = tmp.resolve(AereDecidedHead.FILE_NAME);
|
|
+ assertThat(headOn(chain, 1L, file).advance(bStar.getHash(), Proof.Q1)).isEqualTo(Outcome.ADVANCED);
|
|
+ append(chain, d6);
|
|
+ final Decided fromFile = new Decided(5L, bStar.getHash());
|
|
+
|
|
+ final AereDecidedHead restarted = headOn(chain, 1L, file);
|
|
+ assertThat(restarted.decided())
|
|
+ .as("before the restore only Q5 applies")
|
|
+ .isEqualTo(new Decided(0L, genesis.getHash()));
|
|
+ assertThat(restarted.restore(List.of())).as("D restored from the file").isEqualTo(fromFile);
|
|
+
|
|
+ assertThat(headOn(chain, 1L, file).restore(List.of(d6.getHash())))
|
|
+ .as("evidence above the file wins")
|
|
+ .isEqualTo(new Decided(6L, d6.getHash()));
|
|
+
|
|
+ chain.setFinalized(line.get(3).getHash());
|
|
+ assertThat(headOn(chain, 1L, file).restore(List.of()))
|
|
+ .as("a finalized tag below the file does not lower D")
|
|
+ .isEqualTo(fromFile);
|
|
+ assertThat(alarms).isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aRestartIgnoresAFileThatNamesAnUnknownBlockOrFailsItsChecksumOrItsHeight(
|
|
+ @TempDir final Path tmp) throws IOException {
|
|
+ final AereDecidedChainFixture fx = new AereDecidedChainFixture();
|
|
+ final Block genesis = fx.genesis();
|
|
+ final List<Block> line = fx.line(genesis, 4);
|
|
+ final Block bStar = fx.child(line.get(4), 10L);
|
|
+ final Block bPrime = fx.child(line.get(4), 1L);
|
|
+ final Block cPrime = fx.child(bPrime, 1L);
|
|
+ final MutableBlockchain chain = chain(genesis);
|
|
+ append(chain, line.subList(1, 5));
|
|
+ append(chain, bStar, bPrime, cPrime);
|
|
+ assertThat(chain.getChainHeadHash()).as("fixture: B' -> C' is a fork").isEqualTo(bStar.getHash());
|
|
+ final Path file = tmp.resolve(AereDecidedHead.FILE_NAME);
|
|
+ final Decided onlyQ5 = new Decided(0L, genesis.getHash());
|
|
+
|
|
+ AereDecidedHead.writeDurably(file, new Decided(5L, Hash.hash(Bytes.of(1, 2, 3))), Proof.Q1);
|
|
+ assertThat(headOn(chain, 1L, file).restore(List.of())).as("an unknown block").isEqualTo(onlyQ5);
|
|
+
|
|
+ AereDecidedHead.writeDurably(file, new Decided(7L, bStar.getHash()), Proof.Q1);
|
|
+ assertThat(headOn(chain, 1L, file).restore(List.of())).as("the wrong height").isEqualTo(onlyQ5);
|
|
+
|
|
+ // a well-formed file naming the fork block C', with one digit of its checksum changed: taken at
|
|
+ // face value it would rewind the chain onto a block nobody decided
|
|
+ final byte[] bad = AereDecidedHead.encode(new Decided(6L, cPrime.getHash()), Proof.Q1);
|
|
+ final int last = bad.length - 2;
|
|
+ bad[last] = (byte) (bad[last] == '0' ? '1' : '0');
|
|
+ Files.write(file, bad);
|
|
+ assertThat(headOn(chain, 1L, file).restore(List.of())).as("a wrong checksum").isEqualTo(onlyQ5);
|
|
+ assertThat(chain.getChainHeadHash()).as("the chain after the restores").isEqualTo(bStar.getHash());
|
|
+ // 2026-10-01 (second review of step 3): D is never taken from such a file, but a well-formed file
|
|
+ // naming a block the chain does not hold is this node's own durable decision whose block was lost,
|
|
+ // so it stays a FLOOR, announced once on the alarm path; the wrong height and the wrong checksum
|
|
+ // are not records of a decision and raise nothing
|
|
+ assertThat(alarms).as("one alarm: the floor of the unknown block").hasSize(1);
|
|
+ assertThat(alarms.get(0)).startsWith("CRIT " + AereDecidedHead.CODE_FLOOR);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aRestartCompletesAnAdvanceThatWasWrittenButNotAppliedToTheChain(@TempDir final Path tmp)
|
|
+ throws IOException {
|
|
+ final AereDecidedChainFixture fx = new AereDecidedChainFixture();
|
|
+ final Block genesis = fx.genesis();
|
|
+ final List<Block> line = fx.line(genesis, 4);
|
|
+ final Block bPrime = fx.child(line.get(4), 5L);
|
|
+ final Block cPrime = fx.child(bPrime, 5L);
|
|
+ final Block bStar = fx.child(line.get(4), 1L);
|
|
+ final MutableBlockchain chain = chain(genesis);
|
|
+ append(chain, line.subList(1, 5));
|
|
+ append(chain, bPrime, cPrime, bStar);
|
|
+ assertThat(chain.getChainHeadHash()).as("fixture: the head is C'").isEqualTo(cPrime.getHash());
|
|
+ final Path file = tmp.resolve(AereDecidedHead.FILE_NAME);
|
|
+ // the node wrote D = B* and stopped before the chain was rewound onto it
|
|
+ AereDecidedHead.writeDurably(file, new Decided(5L, bStar.getHash()), Proof.Q1);
|
|
+
|
|
+ final AereDecidedHead head = headOn(chain, 1L, file);
|
|
+ assertThat(head.restore(List.of())).isEqualTo(new Decided(5L, bStar.getHash()));
|
|
+ assertThat(chain.getChainHeadHash()).as("the head after the restore").isEqualTo(bStar.getHash());
|
|
+ assertThat(chain.getBlockHashByNumber(6L)).isEmpty();
|
|
+ assertThat(head.conflicts()).isZero();
|
|
+ assertThat(alarms).isEmpty();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Teza Q3 (D-470, 2026-10-01): at a restart the durable D comes FIRST. The node wrote D = B* and
|
|
+ * stopped before the chain was rewound onto it, while a heavier fork B' <- C' stayed canonical and a
|
|
+ * finalized tag sits on C'. Until 2026-10-01 the candidates came first: C' (6) was taken, the durable
|
|
+ * B* (5) could not complete under it, raised a CONFLICT, and D became C', a block off the line this
|
|
+ * node had durably decided. Now B* is completed (the chain rewound onto it), C' is the CONFLICT, and D
|
|
+ * stays B*.
|
|
+ */
|
|
+ @Test
|
|
+ void aRestartCompletesTheDurableHeadBeforeACandidateOffItsLine(@TempDir final Path tmp)
|
|
+ throws IOException {
|
|
+ final AereDecidedChainFixture fx = new AereDecidedChainFixture();
|
|
+ final Block genesis = fx.genesis();
|
|
+ final List<Block> line = fx.line(genesis, 4);
|
|
+ final Block bPrime = fx.child(line.get(4), 5L);
|
|
+ final Block cPrime = fx.child(bPrime, 5L);
|
|
+ final Block bStar = fx.child(line.get(4), 1L);
|
|
+ final MutableBlockchain chain = chain(genesis);
|
|
+ append(chain, line.subList(1, 5));
|
|
+ append(chain, bPrime, cPrime, bStar);
|
|
+ assertThat(chain.getChainHeadHash()).as("fixture: the head is C'").isEqualTo(cPrime.getHash());
|
|
+ final Path file = tmp.resolve(AereDecidedHead.FILE_NAME);
|
|
+ AereDecidedHead.writeDurably(file, new Decided(5L, bStar.getHash()), Proof.Q1);
|
|
+ chain.setFinalized(cPrime.getHash());
|
|
+
|
|
+ final AereDecidedHead head = headOn(chain, 1L, file);
|
|
+ assertThat(head.restore(List.of()))
|
|
+ .as("the durable B* comes first; the tag on C', off its line, does not move D")
|
|
+ .isEqualTo(new Decided(5L, bStar.getHash()));
|
|
+ assertThat(chain.getChainHeadHash()).as("the chain was rewound onto B*").isEqualTo(bStar.getHash());
|
|
+ assertThat(head.conflicts()).as("the candidate off the durable line is a conflict").isEqualTo(1L);
|
|
+ assertThat(alarms).hasSize(1);
|
|
+ assertThat(alarms.get(0)).startsWith("CRIT " + AereDecidedHead.CODE_CONFLICT);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Teza Q3 (D-470, 2026-10-01), the same order when the durable block is lost: the file names a block
|
|
+ * at 5 the chain does not hold (the floor), and a finalized tag sits on the canonical block 6, whose
|
|
+ * ancestor at 5 is another block. Until 2026-10-01 the tag was taken (D = 6) and the floor dropped
|
|
+ * silently, since it was below D. Now the tag is a CONFLICT, D stays below the floor, and the node
|
|
+ * neither proposes nor votes up to 5 until the recorded block is stored again.
|
|
+ */
|
|
+ @Test
|
|
+ void aRestartKeepsTheDurableFloorAgainstACandidateOffItsLine(@TempDir final Path tmp)
|
|
+ throws IOException {
|
|
+ final AereDecidedChainFixture fx = new AereDecidedChainFixture();
|
|
+ final Block genesis = fx.genesis();
|
|
+ final List<Block> line = fx.line(genesis, 6);
|
|
+ final MutableBlockchain chain = chain(genesis);
|
|
+ append(chain, line.subList(1, 7));
|
|
+ final Path file = tmp.resolve(AereDecidedHead.FILE_NAME);
|
|
+ final Decided lost = new Decided(5L, Hash.hash(Bytes.of(5, 5, 5)));
|
|
+ AereDecidedHead.writeDurably(file, lost, Proof.Q1);
|
|
+ chain.setFinalized(line.get(6).getHash());
|
|
+
|
|
+ final AereDecidedHead head = headOn(chain, 1L, file);
|
|
+ final Decided restored = head.restore(List.of());
|
|
+ assertThat(restored.number())
|
|
+ .as("the tag on 6 does not carry the recorded block at 5: D stays below the floor")
|
|
+ .isLessThan(5L);
|
|
+ assertThat(head.floor()).as("the recorded block stays the floor").contains(lost);
|
|
+ assertThat(head.belowFloor()).as("and the node neither proposes nor votes up to it").isTrue();
|
|
+ assertThat(head.conflicts()).as("the tag off the durable line is a conflict").isEqualTo(1L);
|
|
+ assertThat(alarms).hasSize(2);
|
|
+ assertThat(alarms.get(0)).startsWith("CRIT " + AereDecidedHead.CODE_CONFLICT);
|
|
+ assertThat(alarms.get(1)).startsWith("CRIT " + AereDecidedHead.CODE_FLOOR);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void belowTheActivationHeightTheCanonicalHeadIsDecidedAndNothingIsWritten(
|
|
+ @TempDir final Path tmp) {
|
|
+ final AereDecidedChainFixture fx = new AereDecidedChainFixture();
|
|
+ final Block genesis = fx.genesis();
|
|
+ final List<Block> line = fx.line(genesis, 15);
|
|
+ final MutableBlockchain chain = chain(genesis);
|
|
+ append(chain, line.subList(1, 6));
|
|
+ final Path file = tmp.resolve(AereDecidedHead.FILE_NAME);
|
|
+ final AereDecidedHead head = headOn(chain, 10L, file);
|
|
+
|
|
+ assertThat(head.decided()).isEqualTo(new Decided(5L, line.get(5).getHash()));
|
|
+ assertThat(head.advance(line.get(3).getHash(), Proof.Q1)).isEqualTo(Outcome.NOT_ACTIVE);
|
|
+ assertThat(Files.exists(file)).as("nothing written below the activation height").isFalse();
|
|
+
|
|
+ append(chain, line.subList(6, 16));
|
|
+ // 2026-10-01 (second review of step 3): the parent of H_ev must be PROVED, so Q5 stops at
|
|
+ // H_ev - 2 and the block at H_ev - 1 needs a proof like every block above it
|
|
+ assertThat(head.decided())
|
|
+ .as("Q5 stops at H_ev - 2, below the proof height")
|
|
+ .isEqualTo(new Decided(8L, line.get(8).getHash()));
|
|
+ assertThat(head.provable(9L)).as("H_ev - 1 needs a proof").isTrue();
|
|
+ assertThat(head.provable(8L)).as("H_ev - 2 does not").isFalse();
|
|
+ assertThat(head.advance(line.get(12).getHash(), Proof.Q1)).isEqualTo(Outcome.ADVANCED);
|
|
+ assertThat(head.decided()).isEqualTo(new Decided(12L, line.get(12).getHash()));
|
|
+ assertThat(alarms).isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void anAncestorOfTheDecidedHeadIsDecidedAndASiblingIsNot(@TempDir final Path tmp) {
|
|
+ final AereDecidedChainFixture fx = new AereDecidedChainFixture();
|
|
+ final Block genesis = fx.genesis();
|
|
+ final List<Block> line = fx.line(genesis, 4);
|
|
+ final Block bStar = fx.child(line.get(4), 10L);
|
|
+ final Block bPrime = fx.child(line.get(4), 1L);
|
|
+ final Block cStar = fx.child(bStar, 1L);
|
|
+ final MutableBlockchain chain = chain(genesis);
|
|
+ append(chain, line.subList(1, 5));
|
|
+ append(chain, bStar, bPrime, cStar);
|
|
+ final AereDecidedHead head = headOn(chain, 1L, tmp.resolve(AereDecidedHead.FILE_NAME));
|
|
+ assertThat(head.advance(bStar.getHash(), Proof.Q1)).isEqualTo(Outcome.ADVANCED);
|
|
+
|
|
+ assertThat(head.isDecided(line.get(2).getHeader())).isTrue();
|
|
+ assertThat(head.isDecided(bStar.getHeader())).isTrue();
|
|
+ assertThat(head.isDecided(bPrime.getHeader())).as("a sibling of D").isFalse();
|
|
+ assertThat(head.isDecided(cStar.getHeader())).as("a child of D is not yet decided").isFalse();
|
|
+ assertThat(head.compatible(cStar.getHeader())).isTrue();
|
|
+ assertThat(head.compatible(line.get(2).getHeader())).isTrue();
|
|
+ assertThat(head.compatible(bPrime.getHeader())).isFalse();
|
|
+ assertThat(alarms).isEmpty();
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AerePqFinalityTagsTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AerePqFinalityTagsTest.java
|
|
index f171b392e0..a1ec3a963f 100755
|
|
--- a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AerePqFinalityTagsTest.java
|
|
+++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AerePqFinalityTagsTest.java
|
|
@@ -187,41 +187,41 @@ class AerePqFinalityTagsTest {
|
|
final BlockAddedEvent fork = mock(BlockAddedEvent.class);
|
|
when(fork.isNewCanonicalHead()).thenReturn(false);
|
|
when(fork.getHeader()).thenReturn(byNumber.get(128L));
|
|
tags.onBlockAdded(fork);
|
|
assertThat(tags.finalizedNumber()).isEqualTo(95L);
|
|
}
|
|
|
|
@Test
|
|
void headersAreLinkedByParentHashInTheFixture() {
|
|
assertThat(byNumber.get(128L).getParentHash()).isEqualTo(byNumber.get(127L).getHash());
|
|
assertThat(byNumber.get(127L).getHash().size()).isEqualTo(32);
|
|
}
|
|
|
|
// --- the certificate predicate: the controller feeds carriesCertificate(decode(header)) into install(),
|
|
// so it decides which anchors move the tags. On a stage-5 chain the certificate is the v2 (hybrid) list
|
|
// and getFalconSeals() is empty; a predicate that read only the v1 list never fired (rep28098 rehearsal,
|
|
// 2026-09-26). These three cases are the control that both fields are read.
|
|
|
|
private static BftExtraData extraWith(final List<FalconSeal> v1, final List<SchemeSeal> v2) {
|
|
return new BftExtraData(
|
|
- Bytes.EMPTY, Collections.emptyList(), Optional.empty(), 0, Collections.emptyList(), v1, v2);
|
|
+ Bytes.EMPTY, Collections.emptyList(), Optional.empty(), 0, Collections.emptyList(), v1, v2, BftExtraData.NO_CERTIFICATE_ROUND);
|
|
}
|
|
|
|
@Test
|
|
void carriesCertificate_trueForAV1FalconList() {
|
|
assertThat(
|
|
AerePqFinalityTags.carriesCertificate(
|
|
extraWith(List.of(new FalconSeal(0, Bytes.of(1, 2, 3))), Collections.emptyList())))
|
|
.isTrue();
|
|
}
|
|
|
|
@Test
|
|
void carriesCertificate_trueForAV2HybridCertificate_thisIsTheStage5AnchorThatWasBeingMissed() {
|
|
assertThat(
|
|
AerePqFinalityTags.carriesCertificate(
|
|
extraWith(
|
|
Collections.emptyList(),
|
|
List.of(new SchemeSeal((byte) 1, 0, Bytes.of(1, 2, 3))))))
|
|
.isTrue();
|
|
}
|
|
|
|
diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AereRoundBoundMessageTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AereRoundBoundMessageTest.java
|
|
new file mode 100644
|
|
index 0000000000..f9e942f4a6
|
|
--- /dev/null
|
|
+++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AereRoundBoundMessageTest.java
|
|
@@ -0,0 +1,308 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.common.bft;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
+import static org.assertj.core.api.Assertions.fail;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+
|
|
+import java.io.InputStream;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+
|
|
+import com.fasterxml.jackson.databind.JsonNode;
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), step 3 (2026-10-01): the round-bound commit message and the one place that decides its form, judged
|
|
+ * against the COMMON vectors (aips/aip22-conformitate/r1b/VECTORI-R1B.json, classes VM and VMF), which a third
|
|
+ * implementation computed (hand-written RLP, @noble/hashes), never this code. The vectors reach the classpath as
|
|
+ * the resource /aere-r1b/VECTORI-R1B.json, copied by the harness with cmp against the generator's file; a missing
|
|
+ * resource FAILS with the marker AERE-R1B-VECTORI, it is never skipped.
|
|
+ *
|
|
+ * <p>What is asked, each from the reason written next to it in the project (PROIECT-1B, 1.1, 1.2, 2.1, 2.3):
|
|
+ * COMMIT-1 and PREPARE-1 reproduced first (the method's positive control); M_r for eight rounds on two chains; the
|
|
+ * form exactly at H_r - 1 (H3); a round outside 0..1024 gives an EMPTY message, never an exception (H11); below H_r
|
|
+ * nothing changes (L1); ROUND-01 refuses an H_r that cannot work; a copy of the configuration carries every field.
|
|
+ */
|
|
+public class AereRoundBoundMessageTest {
|
|
+
|
|
+ private static final String RES = "/aere-r1b/VECTORI-R1B.json";
|
|
+
|
|
+ @AfterEach
|
|
+ public void reset() {
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ }
|
|
+
|
|
+ private static JsonNode vectors() {
|
|
+ try (InputStream in = AereRoundBoundMessageTest.class.getResourceAsStream(RES)) {
|
|
+ if (in == null) {
|
|
+ fail("AERE-R1B-VECTORI: the resource " + RES + " is missing; the harness copies it, a run without it measures nothing");
|
|
+ }
|
|
+ return new ObjectMapper().readTree(in);
|
|
+ } catch (final java.io.IOException e) {
|
|
+ throw new IllegalStateException("AERE-R1B-VECTORI: " + e.getMessage(), e);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static Bytes32 b32(final JsonNode n) {
|
|
+ return Bytes32.fromHexString(n.asText());
|
|
+ }
|
|
+
|
|
+ /** The configuration of a VMF vector: anchor armed at anchorBlock, v2 from the same height, H_r if set. */
|
|
+ private static PqAnchorConfig cfgOf(final JsonNode x) {
|
|
+ final long chain = x.get("chainId").asLong();
|
|
+ final long ab = x.get("anchorBlock").asLong();
|
|
+ if (x.get("anchorDisabled").asBoolean()) {
|
|
+ // a braked node is built WITHOUT H_r (PqAnchorConfig.fromSystemConfiguration), so the brake cannot be refused
|
|
+ return new PqAnchorConfig(chain, ab, Map.of(ab, 0), OptionalInt.empty(), true);
|
|
+ }
|
|
+ final PqAnchorConfig base =
|
|
+ new PqAnchorConfig(chain, ab, Map.of(ab, 0), OptionalInt.empty(), false).withAnchorV2Block(ab);
|
|
+ return x.get("commitRoundBlock").isNull()
|
|
+ ? base
|
|
+ : base.withCommitRoundBlock(x.get("commitRoundBlock").asLong());
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theMethodReproducesCommitOneAndPrepareOneFirst() {
|
|
+ final JsonNode c = vectors().get("control");
|
|
+ final Bytes32 h = Bytes32.fromHexString("0x" + "11".repeat(32));
|
|
+ assertThat(c.get(0).get("id").asText()).isEqualTo("COMMIT-1(28001,1000,0x11)");
|
|
+ assertThat(PqAnchor.commitMessage(28001L, 1000L, h)).isEqualTo(b32(c.get(0).get("value")));
|
|
+ assertThat(c.get(1).get("id").asText()).isEqualTo("PREPARE-1(28001,1000,r=2,0x11)");
|
|
+ assertThat(PqAnchor.prepareMessage(28001L, 1000L, 2, h)).isEqualTo(b32(c.get(1).get("value")));
|
|
+ assertThat(c.get(2).get("id").asText()).isEqualTo("PREPARE-1(28001,1000,r=0,0x11)");
|
|
+ assertThat(PqAnchor.prepareMessage(28001L, 1000L, 0, h)).isEqualTo(b32(c.get(2).get("value")));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void vmTheRoundBoundMessageForEveryRoundOfTheVectors() {
|
|
+ final JsonNode vm = vectors().get("VM");
|
|
+ assertThat(vm.size()).as("AERE-R1B-VM: the vectors file carries the VM class").isEqualTo(10);
|
|
+ for (final JsonNode x : vm) {
|
|
+ final long chain = x.get("chainId").asLong();
|
|
+ final long n = x.get("n").asLong();
|
|
+ final int r = x.get("round").asInt();
|
|
+ final Bytes32 h = b32(x.get("hash"));
|
|
+ final Bytes32 m2 = PqAnchor.commitMessageRound(chain, n, r, h);
|
|
+ assertThat(m2).as("AERE-R1B-VM %s: COMMIT-2", x.get("id").asText()).isEqualTo(b32(x.get("commit2")));
|
|
+ assertThat(PqAnchor.commitMessage(chain, n, h))
|
|
+ .as("AERE-R1B-VM %s: COMMIT-1 on the same inputs", x.get("id").asText())
|
|
+ .isEqualTo(b32(x.get("commit1")));
|
|
+ assertThat(m2).as("AERE-R1B-VM %s: the two domains never meet", x.get("id").asText()).isNotEqualTo(b32(x.get("commit1")));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void vmfTheFormAndTheMessageComeFromTheOnePlaceByHeightOnly() {
|
|
+ final JsonNode vmf = vectors().get("VMF");
|
|
+ assertThat(vmf.size()).as("AERE-R1B-VMF: the vectors file carries the VMF class").isEqualTo(12);
|
|
+ for (final JsonNode x : vmf) {
|
|
+ final String id = x.get("id").asText();
|
|
+ final PqAnchorConfig cfg = cfgOf(x);
|
|
+ final long n = x.get("n").asLong();
|
|
+ final int r = x.get("round").asInt();
|
|
+ final Bytes32 onchain = b32(x.get("onchainHash"));
|
|
+ final Bytes32 commitDigest = b32(x.get("commitDigest"));
|
|
+ final JsonNode e = x.get("expected");
|
|
+ assertThat(PqAnchorProducer.commitSealFormAt(cfg, n).name()).as("AERE-R1B-VMF %s: form", id).isEqualTo(e.get("form").asText());
|
|
+ PqAnchorProducer.useConfigForTesting(cfg);
|
|
+ final Optional<Bytes32> message =
|
|
+ PqAnchorProducer.commitSealMessage(n, () -> onchain, Hash.wrap(commitDigest), r);
|
|
+ final Optional<Bytes32> anchor = PqAnchorProducer.anchorSealMessage(cfg, n, onchain, r);
|
|
+ if (e.get("message").isNull()) {
|
|
+ assertThat(message).as("AERE-R1B-VMF %s: no message (code %s), and no exception", id, e.get("code").asText()).isEmpty();
|
|
+ assertThat(e.get("code").asText()).isEqualTo(PqAnchorV3.COMMIT_R_03);
|
|
+ } else {
|
|
+ assertThat(message).as("AERE-R1B-VMF %s: message", id).hasValue(b32(e.get("message")));
|
|
+ }
|
|
+ if (e.get("anchorMessage").isNull()) {
|
|
+ assertThat(anchor).as("AERE-R1B-VMF %s: no anchor message", id).isEmpty();
|
|
+ } else {
|
|
+ assertThat(anchor).as("AERE-R1B-VMF %s: anchor message", id).hasValue(b32(e.get("anchorMessage")));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theBoundaryIsExactlyHrMinusOneAndTheCertificateFormIsV3FromHr() {
|
|
+ final PqAnchorConfig cfg =
|
|
+ new PqAnchorConfig(28001L, 64L, Map.of(64L, 0), OptionalInt.empty(), false)
|
|
+ .withAnchorV2Block(64L)
|
|
+ .withCommitRoundBlock(1000L);
|
|
+ assertThat(PqAnchorProducer.commitSealFormAt(cfg, 998L)).isEqualTo(PqAnchorProducer.CommitSealForm.ROUND_FREE);
|
|
+ assertThat(PqAnchorProducer.commitSealFormAt(cfg, 999L)).isEqualTo(PqAnchorProducer.CommitSealForm.ROUND_BOUND);
|
|
+ assertThat(cfg.roundBoundAt(998L)).isFalse();
|
|
+ assertThat(cfg.roundBoundAt(999L)).isTrue();
|
|
+ assertThat(cfg.certificateFormAt(999L)).isEqualTo(PqAnchorConfig.CertificateForm.V2);
|
|
+ assertThat(cfg.certificateFormAt(1000L)).isEqualTo(PqAnchorConfig.CertificateForm.V3);
|
|
+ assertThat(cfg.certificateFormAt(63L)).isEqualTo(PqAnchorConfig.CertificateForm.NONE);
|
|
+ assertThat(cfg.anchorV2AppliesAt(1000L)).as("the scheme-tagged family covers v3 too").isTrue();
|
|
+ final PqAnchorConfig v1only = new PqAnchorConfig(28001L, 64L, Map.of(64L, 0), OptionalInt.empty(), false);
|
|
+ assertThat(v1only.certificateFormAt(5000L)).isEqualTo(PqAnchorConfig.CertificateForm.V1);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aRoundOutsideTheRangeGivesNoMessageAndNeverThrows() {
|
|
+ final PqAnchorConfig cfg =
|
|
+ new PqAnchorConfig(28001L, 64L, Map.of(64L, 0), OptionalInt.empty(), false)
|
|
+ .withAnchorV2Block(64L)
|
|
+ .withCommitRoundBlock(1000L);
|
|
+ final Bytes32 h = Bytes32.fromHexString("0x" + "22".repeat(32));
|
|
+ for (final int r : new int[] {-5, -1, 1025, 4096, Integer.MAX_VALUE, Integer.MIN_VALUE}) {
|
|
+ assertThat(PqAnchorProducer.anchorSealMessage(cfg, 999L, h, r)).as("round %s at H_r - 1", r).isEmpty();
|
|
+ assertThat(PqAnchorProducer.anchorSealMessage(cfg, 998L, h, r))
|
|
+ .as("round %s at H_r - 2: COMMIT-1, the round ignored (L1)", r)
|
|
+ .hasValue(PqAnchor.commitMessage(28001L, 998L, h));
|
|
+ }
|
|
+ assertThat(PqAnchorProducer.anchorSealMessage(cfg, 999L, h, 1024)).hasValue(PqAnchor.commitMessageRound(28001L, 999L, 1024, h));
|
|
+ assertThatThrownBy(() -> PqAnchor.commitMessageRound(28001L, 999L, 1025, h))
|
|
+ .as("the primitive keeps a second guard for a programming error")
|
|
+ .isInstanceOf(IllegalArgumentException.class);
|
|
+ assertThat(PqAnchorV3.MAX_ROUND).isEqualTo(vectors().get("constants").get("MAX_ROUND").asInt());
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void withoutHrNothingChanges() {
|
|
+ final PqAnchorConfig cfg =
|
|
+ new PqAnchorConfig(28001L, 64L, Map.of(64L, 0), OptionalInt.empty(), false).withAnchorV2Block(64L);
|
|
+ final Bytes32 h = Bytes32.fromHexString("0x" + "33".repeat(32));
|
|
+ for (long n = 60L; n < 100_000L; n += 997L) {
|
|
+ assertThat(PqAnchorProducer.commitSealFormAt(cfg, n)).isNotEqualTo(PqAnchorProducer.CommitSealForm.ROUND_BOUND);
|
|
+ assertThat(cfg.certificateFormAt(n)).isNotEqualTo(PqAnchorConfig.CertificateForm.V3);
|
|
+ if (n + 1 >= 64L) {
|
|
+ for (final int r : new int[] {0, 3, 1025}) {
|
|
+ assertThat(PqAnchorProducer.anchorSealMessage(cfg, n, h, r)).hasValue(PqAnchor.commitMessage(28001L, n, h));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ assertThat(cfg.toString()).doesNotContain("commitRoundBlock");
|
|
+ assertThat(cfg.commitRoundBlock()).isEqualTo(PqAnchorConfig.NEVER);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void round01RefusesAnHrThatCannotWork() {
|
|
+ final PqAnchorConfig armed =
|
|
+ new PqAnchorConfig(2800L, 1_000L, Map.of(1_000L, 3), OptionalInt.empty(), false)
|
|
+ .withAnchorInterval(OptionalInt.of(32))
|
|
+ .withAnchorV2Block(1_000L + 32L * 10);
|
|
+ // accepted: an anchor height above the v2 height
|
|
+ assertThat(armed.withCommitRoundBlock(1_000L + 32L * 20).commitRoundBlock()).isEqualTo(1_640L);
|
|
+ // refused, each for the reason written
|
|
+ assertRound01(() -> armed.withCommitRoundBlock(0L), "not a positive height");
|
|
+ assertRound01(() -> armed.withCommitRoundBlock(1_000L + 32L * 10), "is not above");
|
|
+ assertRound01(() -> armed.withCommitRoundBlock(1_000L + 32L * 5), "is not above");
|
|
+ assertRound01(() -> armed.withCommitRoundBlock(1_000L + 32L * 20 + 1), "is not an anchor height");
|
|
+ assertRound01(
|
|
+ () ->
|
|
+ new PqAnchorConfig(2800L, 1_000L, Map.of(1_000L, 3), OptionalInt.empty(), false)
|
|
+ .withCommitRoundBlock(2_000L),
|
|
+ "is not above");
|
|
+ assertRound01(
|
|
+ () -> PqAnchorConfig.never(2800L).withCommitRoundBlock(2_000L), "not configured");
|
|
+ assertRound01(
|
|
+ () ->
|
|
+ new PqAnchorConfig(2800L, 1_000L, Map.of(1_000L, 3), OptionalInt.empty(), true)
|
|
+ .withAnchorV2Block(1_000L)
|
|
+ .withCommitRoundBlock(2_000L),
|
|
+ "disarmed");
|
|
+ }
|
|
+
|
|
+ private static void assertRound01(final org.assertj.core.api.ThrowableAssert.ThrowingCallable c, final String why) {
|
|
+ assertThatThrownBy(c)
|
|
+ .isInstanceOf(IllegalArgumentException.class)
|
|
+ .hasMessageStartingWith(PqAnchorConfig.REFUSAL_ROUND_01)
|
|
+ .hasMessageContaining(why);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * HISTORY (1(b), 2026-10-01): in the step-3 build this probe was "thisBuildRefusesHrAtStartup...": that build had no v3
|
|
+ * producer and refused H_r at startup (AERE-R1B-APPLYV3-PAS4). Step 4 brings PqAnchorProducer.applyV3, so H_r is now
|
|
+ * ACCEPTED at startup; what stays refused at startup is a malformed H_r (ROUND-01), and the brake still engages.
|
|
+ */
|
|
+ @Test
|
|
+ public void thisBuildAcceptsHrAtStartupRefusesAMalformedOneAndTheBrakeStillEngages() {
|
|
+ final Map<String, String> props = new java.util.HashMap<>();
|
|
+ props.put(PqAnchorConfig.PROPERTY_CHAIN_ID, "2800");
|
|
+ props.put(PqAnchorConfig.PROPERTY_ANCHOR_BLOCK, "1000");
|
|
+ props.put(PqAnchorConfig.PROPERTY_MIN_SEALS, "1000:0,8200:1,15400:3");
|
|
+ props.put(PqAnchorConfig.PROPERTY_ANCHOR_V2_BLOCK, "1064");
|
|
+ PqAnchorConfig.useNameReaderForTesting(
|
|
+ new PqAnchorConfig.NameReader() {
|
|
+ @Override
|
|
+ public String property(final String name) {
|
|
+ return props.get(name);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public String environment(final String name) {
|
|
+ return null;
|
|
+ }
|
|
+ });
|
|
+ try {
|
|
+ assertThat(PqAnchorConfig.fromSystemConfiguration().commitRoundBlock())
|
|
+ .as("control: the same configuration without H_r starts")
|
|
+ .isEqualTo(PqAnchorConfig.NEVER);
|
|
+ props.put(PqAnchorConfig.PROPERTY_COMMIT_ROUND_BLOCK, "2000");
|
|
+ final PqAnchorConfig armed = PqAnchorConfig.fromSystemConfiguration();
|
|
+ assertThat(armed.commitRoundBlock())
|
|
+ .as("step 4: the v3 producer exists, so H_r is accepted at startup")
|
|
+ .isEqualTo(2_000L);
|
|
+ assertThat(armed.certificateFormAt(2_000L)).isEqualTo(PqAnchorConfig.CertificateForm.V3);
|
|
+ assertThat(armed.roundBoundAt(1_999L)).as("H3: the parent of the first v3 anchor is round-bound").isTrue();
|
|
+ assertThat(armed.roundBoundAt(1_998L)).isFalse();
|
|
+ props.put(PqAnchorConfig.PROPERTY_COMMIT_ROUND_BLOCK, "1064");
|
|
+ assertThatThrownBy(PqAnchorConfig::fromSystemConfiguration)
|
|
+ .as("a malformed H_r (at the v2 height) is still refused at STARTUP, never at the first anchor")
|
|
+ .isInstanceOf(IllegalArgumentException.class)
|
|
+ .hasMessageStartingWith(PqAnchorConfig.REFUSAL_ROUND_01);
|
|
+ props.put(PqAnchorConfig.PROPERTY_COMMIT_ROUND_BLOCK, "2000");
|
|
+ props.put(PqAnchorConfig.PROPERTY_DISABLE, "true");
|
|
+ assertThat(PqAnchorConfig.fromSystemConfiguration().disabled())
|
|
+ .as("the emergency brake engages whatever H_r says: a brake that can be refused is not a brake")
|
|
+ .isTrue();
|
|
+ } finally {
|
|
+ PqAnchorConfig.useNameReaderForTesting(null);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void everyCopyCarriesTheScheduleAndHr() {
|
|
+ final PqAnchorConfig cfg =
|
|
+ new PqAnchorConfig(2800L, 1_000L, Map.of(1_000L, 3), OptionalInt.empty(), false)
|
|
+ .withAnchorInterval(OptionalInt.of(32))
|
|
+ .withAnchorIntervalSchedule(Map.of(1_000L + 32L * 4, 128))
|
|
+ .withAnchorV2Block(1_000L + 32L * 4)
|
|
+ .withCommitRoundBlock(1_000L + 32L * 4 + 128L * 3);
|
|
+ final PqAnchorConfig capped = cfg.withMaxSealsCarried(OptionalInt.of(5));
|
|
+ assertThat(capped.anchorIntervalSchedule())
|
|
+ .as("the copy through withMaxSealsCarried used to DROP the interval schedule")
|
|
+ .isEqualTo(cfg.anchorIntervalSchedule());
|
|
+ assertThat(capped.commitRoundBlock()).isEqualTo(cfg.commitRoundBlock());
|
|
+ assertThat(cfg.withAnchorV2Block(cfg.anchorV2Block()).commitRoundBlock()).isEqualTo(cfg.commitRoundBlock());
|
|
+ assertThat(cfg.withAnchorIntervalSchedule(cfg.anchorIntervalSchedule()).commitRoundBlock()).isEqualTo(cfg.commitRoundBlock());
|
|
+ assertThat(cfg.withAnchorInterval(cfg.anchorInterval()).commitRoundBlock()).isEqualTo(cfg.commitRoundBlock());
|
|
+ assertThat(cfg.toString()).contains("commitRoundBlock=" + cfg.commitRoundBlock());
|
|
+ assertThat(PqAnchor.COMMIT_DOMAIN_2_BYTES.size()).isEqualTo(16);
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorConfigTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorConfigTest.java
|
|
index 6f31c94f9b..036da7c13c 100755
|
|
--- a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorConfigTest.java
|
|
+++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorConfigTest.java
|
|
@@ -229,63 +229,68 @@ public class PqAnchorConfigTest {
|
|
assertThat(config.emergencyCeilingLowersAt(height)).isFalse();
|
|
}
|
|
|
|
// THE LOAD-BEARING ASSERTION of this test. SEVEN names, each probed exactly once as a system
|
|
// property and once as an environment variable, and then nothing: fourteen accesses, not
|
|
// fifteen. A loader that went any further and decoded would read the same names a second time
|
|
// and this number would be 28.
|
|
//
|
|
// IT WAS TEN UNTIL 2026-08-07, and it went up TWICE on the same day, for
|
|
// `aere.pq.anchor.maxSeals` and then for `aere.pq.anchorInterval`. Each time the test failed
|
|
// and forced somebody to look, which is exactly what it was asked to do. The number is raised
|
|
// DELIBERATELY, with the reason written next to it; the assertion is never weakened and never
|
|
// deleted.
|
|
//
|
|
// The consequence of adding a name, and it is intended: a node that has ONLY a cost control
|
|
// set, with no anchor height, is no longer "a node with no anchor configuration"; it becomes
|
|
// one with an incomplete configuration, and it refuses to start. A cap or an interval with no
|
|
// anchor means nothing, and it is better for it to shout than to keep quiet.
|
|
// 16 since 2026-09-03: the v2 activation height (property + environment) joined the names
|
|
// 18 since 2026-09-04: the interval SCHEDULE (D-336, disk) joined them, between the interval and the v2 height
|
|
- assertThat(reader.accesses).hasSize(18);
|
|
+ // 20 since 2026-10-01: H_r of 1(b), aere.pq.commitRoundBlock (D-470), between the v2 height and the disarm; this
|
|
+ // test went red on the first run of the 1(b) harness exactly as it was written to, and is raised here, not weakened
|
|
+ assertThat(reader.accesses).hasSize(20);
|
|
assertThat(reader.accesses)
|
|
.containsExactly(
|
|
"property:" + PqAnchorConfig.PROPERTY_ANCHOR_BLOCK,
|
|
"environment:" + PqAnchorConfig.ENV_ANCHOR_BLOCK,
|
|
"property:" + PqAnchorConfig.PROPERTY_MIN_SEALS,
|
|
"environment:" + PqAnchorConfig.ENV_MIN_SEALS,
|
|
"property:" + PqAnchorConfig.PROPERTY_CHAIN_ID,
|
|
"environment:" + PqAnchorConfig.ENV_CHAIN_ID,
|
|
"property:" + PqAnchorConfig.PROPERTY_MIN_SEALS_CEILING,
|
|
"environment:" + PqAnchorConfig.ENV_MIN_SEALS_CEILING,
|
|
// added 2026-08-07 together with the cost cap; the ORDER matters and it is the one in
|
|
// ANCHOR_NAMES, where maxSeals sits between the emergency ceiling and the disarm
|
|
"property:" + PqAnchorConfig.PROPERTY_MAX_SEALS,
|
|
"environment:" + PqAnchorConfig.ENV_MAX_SEALS,
|
|
"property:" + PqAnchorConfig.PROPERTY_ANCHOR_INTERVAL,
|
|
"environment:" + PqAnchorConfig.ENV_ANCHOR_INTERVAL,
|
|
"property:" + PqAnchorConfig.PROPERTY_ANCHOR_INTERVAL_SCHEDULE,
|
|
"environment:" + PqAnchorConfig.ENV_ANCHOR_INTERVAL_SCHEDULE,
|
|
// added 2026-09-03 with the scheme-tagged (v2) certificate: its activation height sits
|
|
// between the interval and the disarm, as in ANCHOR_NAMES
|
|
"property:" + PqAnchorConfig.PROPERTY_ANCHOR_V2_BLOCK,
|
|
"environment:" + PqAnchorConfig.ENV_ANCHOR_V2_BLOCK,
|
|
+ // added 2026-10-01 with 1(b): H_r, between the v2 height and the disarm, as in ANCHOR_NAMES
|
|
+ "property:" + PqAnchorConfig.PROPERTY_COMMIT_ROUND_BLOCK,
|
|
+ "environment:" + PqAnchorConfig.ENV_COMMIT_ROUND_BLOCK,
|
|
"property:" + PqAnchorConfig.PROPERTY_DISABLE,
|
|
"environment:" + PqAnchorConfig.ENV_DISABLE);
|
|
}
|
|
|
|
// ===============================================================================================
|
|
// 3. THE ARMED PATH. A correct configuration still starts, and the threshold in force is the one
|
|
// that was asked for. Without this, "refuses everything" would score as a pass.
|
|
// ===============================================================================================
|
|
|
|
@Test
|
|
public void aCorrectConfigurationStartsAndTheThresholdIsTheOneThatWasAskedFor() {
|
|
armCorrectly();
|
|
final PqAnchorConfig config = PqAnchorConfig.fromSystemConfiguration();
|
|
|
|
assertThat(config.everActive()).isTrue();
|
|
assertThat(config.anchorConfigured()).isTrue();
|
|
assertThat(config.chainId()).isEqualTo(2800L);
|
|
assertThat(config.anchorBlock()).isEqualTo(H);
|
|
assertThat(config.activeAt(H - 1)).isFalse();
|
|
assertThat(config.activeAt(H)).isTrue();
|
|
diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorProducerCostTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorProducerCostTest.java
|
|
index d337674835..218eb6030f 100755
|
|
--- a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorProducerCostTest.java
|
|
+++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorProducerCostTest.java
|
|
@@ -194,51 +194,51 @@ class PqAnchorProducerCostTest {
|
|
assertThat(PqAnchorProducer.apply(base(), parent, contextWith(validators)).getFalconSeals())
|
|
.describedAs("the only difference from the proof before is the interval")
|
|
.hasSize(3);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------------------------
|
|
// Helpers.
|
|
// ---------------------------------------------------------------------------------------------
|
|
|
|
private static PqAnchorConfig armedConfig(final OptionalInt cap, final OptionalInt interval) {
|
|
return new PqAnchorConfig(
|
|
CHAIN_ID, H, Map.of(H, 3), OptionalInt.empty(), false, cap, interval);
|
|
}
|
|
|
|
private static BlockHeader parentOf(final long number) {
|
|
return new BlockHeaderTestFixture().number(number).buildHeader();
|
|
}
|
|
|
|
private BftExtraData base() {
|
|
return new BftExtraData(
|
|
- Bytes32.ZERO, Collections.emptyList(), Optional.empty(), 0, validators, Collections.emptyList());
|
|
+ Bytes32.ZERO, Collections.emptyList(), Optional.empty(), 0, validators, Collections.emptyList(), java.util.List.of(), BftExtraData.NO_CERTIFICATE_ROUND);
|
|
}
|
|
|
|
private void hearAllSevenSealsFor(final BlockHeader parent) {
|
|
final Bytes32 m =
|
|
PqAnchor.commitMessage(CHAIN_ID, parent.getNumber(), parent.getHash().getBytes());
|
|
final List<FalconSeal> heard = new ArrayList<>();
|
|
for (int i = 0; i < N; i++) {
|
|
heard.add(new FalconSeal(i, Bytes.wrap(falconSign(privateKeys.get(i), m))));
|
|
}
|
|
- PqSealCache.instance().record(parent.getNumber(), parent.getHash(), heard);
|
|
+ PqSealCache.instance().record(parent.getNumber(), parent.getHash(), 0, heard);
|
|
}
|
|
|
|
private static byte[] falconSign(final FalconPrivateKeyParameters key, final Bytes32 m) {
|
|
final FalconSigner signer = new FalconSigner();
|
|
signer.init(true, key);
|
|
return signer.generateSignature(m.toArray());
|
|
}
|
|
|
|
private static ProtocolContext contextWith(final Collection<Address> vs) {
|
|
final ValidatorProvider validatorProvider =
|
|
mock(ValidatorProvider.class, withSettings().strictness(Strictness.LENIENT));
|
|
when(validatorProvider.getValidatorsForBlock(any())).thenReturn(vs);
|
|
when(validatorProvider.getValidatorsAfterBlock(any())).thenReturn(vs);
|
|
final BftContext bftContext =
|
|
mock(BftContext.class, withSettings().strictness(Strictness.LENIENT));
|
|
when(bftContext.getValidatorProvider()).thenReturn(validatorProvider);
|
|
when(bftContext.as(any())).thenReturn(bftContext);
|
|
return new ProtocolContext.Builder().withConsensusContext(bftContext).build();
|
|
}
|
|
|
|
diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorProducerRoundTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorProducerRoundTest.java
|
|
new file mode 100644
|
|
index 0000000000..2a731051cb
|
|
--- /dev/null
|
|
+++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorProducerRoundTest.java
|
|
@@ -0,0 +1,400 @@
|
|
+/*
|
|
+ * Copyright contributors to Aere Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
|
|
+ * compliance with the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is
|
|
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
+ * implied. See the License for the specific language governing permissions and limitations under the
|
|
+ * License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.common.bft;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
+import static org.mockito.Mockito.mock;
|
|
+import static org.mockito.Mockito.when;
|
|
+import static org.mockito.Mockito.withSettings;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
|
+import org.hyperledger.besu.crypto.SecureRandomProvider;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.ethereum.ProtocolContext;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+
|
|
+import java.lang.reflect.Field;
|
|
+import java.nio.file.Files;
|
|
+import java.nio.file.Path;
|
|
+import java.security.SecureRandom;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collection;
|
|
+import java.util.Collections;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.bouncycastle.crypto.digests.KeccakDigest;
|
|
+import org.bouncycastle.pqc.crypto.falcon.FalconPrivateKeyParameters;
|
|
+import org.bouncycastle.pqc.crypto.falcon.FalconSigner;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.junit.jupiter.api.io.TempDir;
|
|
+import org.mockito.quality.Strictness;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), D-470, pasul 4 (2026-10-01): the PRODUCER of the v3 certificate (project section 3.1 C, marker
|
|
+ * AERE-R1B-PRODUCATOR), on the harness of {@link PqAnchorV2ProducerTest}: ten Falcon probe keys anchored in a genesis registry
|
|
+ * (Q(10) = 7), the store loaded by hand per round, a mocked validator provider. Each case has its pair:
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>r0 holds 4 verified seals and r3 holds 7, K = 7: the certificate is v3 of round 3, never a mix; with r3 at 5 nobody
|
|
+ * reaches K and the proposer refuses, naming the count of EVERY round (seals of different rounds are never added up);
|
|
+ * <li>a round with MORE seals heard but fewer that VERIFY over its own M_r loses to a smaller round that verifies;
|
|
+ * <li>the cap: maxSeals = 9 never cuts below K, and maxSeals below Q is raised to Q (cap' = max(maxSeals, Q));
|
|
+ * <li>an extra (SLH-DSA) seal of the right index signed over ANOTHER round's message does not count for this round;
|
|
+ * <li>K_eff = 0 and nothing held: the empty v3 certificate [3, 0, []] (decision H5), with D3 over it;
|
|
+ * <li>below H_r nothing changes: a v2 certificate, no round (L1).
|
|
+ * </ul>
|
|
+ */
|
|
+class PqAnchorProducerRoundTest {
|
|
+
|
|
+ private static final long CHAIN_ID = 220_879L;
|
|
+ private static final long H = 1_000L;
|
|
+ private static final long V2 = 1_005L;
|
|
+ private static final long HR = 1_100L;
|
|
+ private static final int N = 10;
|
|
+ private static final int Q = 7;
|
|
+ private static final String SLH = "slh-dsa-sha2-128s";
|
|
+
|
|
+ @TempDir private Path tmp;
|
|
+
|
|
+ private final List<FalconPrivateKeyParameters> falconKeys = new ArrayList<>();
|
|
+ private final List<SealScheme.GeneratedPair> slhKeys = new ArrayList<>();
|
|
+ private final List<Address> validators = new ArrayList<>();
|
|
+ private final SecureRandom random = SecureRandomProvider.createSecureRandom();
|
|
+
|
|
+ @BeforeEach
|
|
+ void setUp() throws Exception {
|
|
+ final KeccakDigest kd = new KeccakDigest(256);
|
|
+ final StringBuilder manifest = new StringBuilder();
|
|
+ manifest.append("{\"config\":{\"aereFalconRegistry\":{").append(PqV2Fixture.manifestHeader(N, CHAIN_ID, H));
|
|
+ for (int i = 0; i < N; i++) {
|
|
+ falconKeys.add(PqV2Fixture.privateKey(i));
|
|
+ validators.add(PqV2Fixture.address(i));
|
|
+ final byte[] row = PqV2Fixture.anchorPreimageRow(i);
|
|
+ kd.update(row, 0, row.length);
|
|
+ manifest.append(',').append(PqV2Fixture.manifestEntry(i, N, CHAIN_ID, H));
|
|
+ }
|
|
+ manifest
|
|
+ .append("}},\"alloc\":{\"0000000000000000000000000000000000000fa1\":{\"storage\":{\"0x")
|
|
+ .append("0".repeat(64))
|
|
+ .append("\":\"0x");
|
|
+ final byte[] anchoredHash = new byte[32];
|
|
+ kd.doFinal(anchoredHash, 0);
|
|
+ manifest.append(Bytes.wrap(anchoredHash).toUnprefixedHexString()).append("\"}}}}");
|
|
+ final Path genesis = tmp.resolve("genesis-registry.json");
|
|
+ Files.writeString(genesis, manifest.toString());
|
|
+ System.setProperty("aere.falcon.genesis", genesis.toAbsolutePath().toString());
|
|
+ System.setProperty("aere.falcon.attachBlock", Long.toString(H - 100L));
|
|
+ resetFalconSingleton();
|
|
+ // the producer's self-check judges on R2's HISTORY doors (review of step 4), which refuse above the arming height
|
|
+ // without the registry schedule; bound here the way a live node binds it from its genesis (PqSealWindowPersistenceTest)
|
|
+ final PqRegistryHash.Registry held = PqRegistryHash.loadAuto(genesis);
|
|
+ String hash = PqRegistryHash.hashFor(held, CHAIN_ID);
|
|
+ if (!hash.startsWith("0x")) {
|
|
+ hash = "0x" + hash;
|
|
+ }
|
|
+ final Path schedule = tmp.resolve("genesis-schedule.json");
|
|
+ Files.writeString(schedule, "{\"config\":{\"pqRegistryHash\":[{\"block\":" + H + ",\"hash\":\"" + hash + "\"}]}}");
|
|
+ FalconSealSupport.instance()
|
|
+ .verifyRegistryBindingOrAbort(0L, CHAIN_ID, PqRegistryHash.loadScheduleFromGenesis(schedule));
|
|
+ PqSealCache.instance().clear();
|
|
+ HybridSealSupport.resetForTesting();
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ void tearDown() throws Exception {
|
|
+ System.clearProperty("aere.falcon.genesis");
|
|
+ System.clearProperty("aere.falcon.attachBlock");
|
|
+ System.clearProperty(HybridSealSupport.PROPERTY_SCHEDULE);
|
|
+ System.clearProperty(HybridSealSupport.PROPERTY_REGISTRY);
|
|
+ HybridSealSupport.resetForTesting();
|
|
+ resetFalconSingleton();
|
|
+ PqSealCache.instance().clear();
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void theCertificateIsTheRoundThatReachesTheQuorumNeverAMix() {
|
|
+ PqAnchorProducer.useConfigForTesting(config(Map.of(H, Q), OptionalInt.empty()));
|
|
+ final BlockHeader parent = parentOf(HR + 49L);
|
|
+ hear(parent, 0, 0, 4); // r0: indices 0..3
|
|
+ hear(parent, 3, 3, 10); // r3: indices 3..9, seven
|
|
+ final BftExtraData produced = PqAnchorProducer.apply(base(), parent, contextWith(validators));
|
|
+ assertThat(produced.getCertificateRound()).hasValue(3);
|
|
+ assertThat(produced.getFalconSeals()).describedAs("no v1 list on a v3 header").isEmpty();
|
|
+ assertThat(produced.getHybridSeals()).extracting(SchemeSeal::getValidatorIndex).containsExactly(3, 4, 5, 6, 7, 8, 9);
|
|
+ assertThat(produced.getVanityData())
|
|
+ .describedAs("vanityData is D3 over exactly the carried rows and their round")
|
|
+ .isEqualTo(
|
|
+ PqAnchorV3.anchorDigestV3(
|
|
+ CHAIN_ID,
|
|
+ parent.getNumber(),
|
|
+ parent.getHash().getBytes(),
|
|
+ new PqAnchorV3.Certificate(3, produced.getHybridSeals())));
|
|
+ final PqAnchorV3.Verdict r2 =
|
|
+ PqAnchorV3.judgeSeals(
|
|
+ config(Map.of(H, Q), OptionalInt.empty()),
|
|
+ parent.getNumber() + 1L,
|
|
+ parent.getHash().getBytes(),
|
|
+ new PqAnchorV3.Certificate(3, produced.getHybridSeals()),
|
|
+ Q,
|
|
+ java.util.Set.of(),
|
|
+ java.util.Set.of(),
|
|
+ signers());
|
|
+ assertThat(r2.accepted()).describedAs("R2 accepts what the producer wrote: %s", r2.describe()).isTrue();
|
|
+ assertThat(r2.falconMembers()).isEqualTo(Q);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void whenNoSingleRoundReachesKTheProposerRefusesAndNamesEveryRound() {
|
|
+ PqAnchorProducer.useConfigForTesting(config(Map.of(H, Q), OptionalInt.empty()));
|
|
+ final BlockHeader parent = parentOf(HR + 49L);
|
|
+ hear(parent, 0, 0, 4); // r0: 0..3
|
|
+ hear(parent, 3, 4, 9); // r3: 4..8, five; 4 + 5 = 9 >= 7 if pooled, which must never happen
|
|
+ assertThatThrownBy(() -> PqAnchorProducer.apply(base(), parent, contextWith(validators)))
|
|
+ .isInstanceOf(PqAnchorNotReadyException.class)
|
|
+ .hasMessageContaining("no single round of parent " + parent.getNumber())
|
|
+ .hasMessageContaining("r3:5")
|
|
+ .hasMessageContaining("r0:4");
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aRoundWithMoreSealsHeardButFewerVerifiedLosesToOneThatVerifies() {
|
|
+ PqAnchorProducer.useConfigForTesting(config(Map.of(H, Q), OptionalInt.empty()));
|
|
+ final BlockHeader parent = parentOf(HR + 49L);
|
|
+ // r1: nine seals heard, all signed over M_0 (copied from round 0): none verifies over M_1
|
|
+ final Bytes32 m0 = PqAnchor.commitMessageRound(CHAIN_ID, parent.getNumber(), 0, parent.getHash().getBytes());
|
|
+ final List<FalconSeal> copied = new ArrayList<>();
|
|
+ for (int i = 0; i < 9; i++) {
|
|
+ copied.add(new FalconSeal(i, Bytes.wrap(falconSign(falconKeys.get(i), m0))));
|
|
+ }
|
|
+ PqSealCache.instance().record(parent.getNumber(), parent.getHash(), 1, copied);
|
|
+ hear(parent, 2, 0, 7); // r2: seven genuine
|
|
+ final BftExtraData produced = PqAnchorProducer.apply(base(), parent, contextWith(validators));
|
|
+ assertThat(produced.getCertificateRound())
|
|
+ .describedAs("the round is chosen on VERIFIED seals of its own message, not on what was heard")
|
|
+ .hasValue(2);
|
|
+ assertThat(produced.getHybridSeals()).hasSize(Q);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void theCapNeverCutsBelowKAndIsRaisedToTheQuorum() {
|
|
+ // maxSeals 9 with K = 7: ten verified, nine carried
|
|
+ PqAnchorProducer.useConfigForTesting(config(Map.of(H, Q), OptionalInt.of(9)));
|
|
+ final BlockHeader parent = parentOf(HR + 49L);
|
|
+ hear(parent, 0, 0, 10);
|
|
+ assertThat(PqAnchorProducer.apply(base(), parent, contextWith(validators)).getHybridSeals()).hasSize(9);
|
|
+ // maxSeals 5 (below Q = 7) with K = 5: cap' = max(5, 7) = 7, so a deciding round is never cut short
|
|
+ PqSealCache.instance().clear();
|
|
+ PqAnchorProducer.useConfigForTesting(config(Map.of(H, 5), OptionalInt.of(5)));
|
|
+ hear(parent, 0, 0, 10);
|
|
+ assertThat(PqAnchorProducer.apply(base(), parent, contextWith(validators)).getHybridSeals())
|
|
+ .describedAs("cap' = max(maxSeals, Q)")
|
|
+ .hasSize(Q);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void anExtraSealSignedOverAnotherRoundDoesNotCountForThisRound() throws Exception {
|
|
+ armHybrid("0:falcon-512+" + SLH);
|
|
+ PqAnchorProducer.useConfigForTesting(config(Map.of(H, 2), OptionalInt.empty()));
|
|
+ final BlockHeader parent = parentOf(HR + 49L);
|
|
+ hear(parent, 1, 0, Q); // r1: seven Falcon
|
|
+ final Bytes32 m0 = PqAnchor.commitMessageRound(CHAIN_ID, parent.getNumber(), 0, parent.getHash().getBytes());
|
|
+ final Bytes32 m1 = PqAnchor.commitMessageRound(CHAIN_ID, parent.getNumber(), 1, parent.getHash().getBytes());
|
|
+ PqSealCache.instance()
|
|
+ .recordExtras(parent.getNumber(), parent.getHash(), 1, List.of(slh(0, m0), slh(1, m0)));
|
|
+ assertThatThrownBy(() -> PqAnchorProducer.apply(base(), parent, contextWith(validators)))
|
|
+ .describedAs("two SLH-DSA seals of indices 0 and 1, but over M_0: round 1 has none")
|
|
+ .isInstanceOf(PqAnchorNotReadyException.class);
|
|
+ PqSealCache.instance().clear();
|
|
+ hear(parent, 1, 0, Q);
|
|
+ PqSealCache.instance()
|
|
+ .recordExtras(parent.getNumber(), parent.getHash(), 1, List.of(slh(0, m1), slh(1, m1)));
|
|
+ final BftExtraData produced = PqAnchorProducer.apply(base(), parent, contextWith(validators));
|
|
+ assertThat(produced.getCertificateRound()).hasValue(1);
|
|
+ assertThat(PqAnchorV2.distinctValidatorsWith(produced.getHybridSeals(), SealSchemes.SLH_DSA_128S.wireId()))
|
|
+ .describedAs("control: the same indices over M_1 are carried")
|
|
+ .isEqualTo(2);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void atKZeroWithNothingHeldTheCertificateIsTheEmptyV3() {
|
|
+ // H:0 alone is refused (D-147); a warm-up window at 0 followed by a step is legal
|
|
+ PqAnchorProducer.useConfigForTesting(config(Map.of(H, 0, HR + 500L, 3), OptionalInt.empty()));
|
|
+ final BlockHeader parent = parentOf(HR + 49L);
|
|
+ final BftExtraData produced = PqAnchorProducer.apply(base(), parent, contextWith(validators));
|
|
+ assertThat(produced.getCertificateRound()).hasValue(0);
|
|
+ assertThat(produced.getHybridSeals()).isEmpty();
|
|
+ assertThat(produced.getVanityData())
|
|
+ .isEqualTo(
|
|
+ PqAnchorV3.anchorDigestV3(
|
|
+ CHAIN_ID, parent.getNumber(), parent.getHash().getBytes(), new PqAnchorV3.Certificate(0, List.of())));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void atKZeroARoundHeldWithNothingThatVerifiesStillGivesTheEmptyV3OfRoundZero() {
|
|
+ // review of step 4 (HIGH): garbage held under round 3 at K_eff = 0 made the "best" round 3 with no rows, and the
|
|
+ // empty certificate of round 3 threw out of encode() into the QBFT state machine
|
|
+ PqAnchorProducer.useConfigForTesting(config(Map.of(H, 0, HR + 500L, 3), OptionalInt.empty()));
|
|
+ final BlockHeader parent = parentOf(HR + 49L);
|
|
+ final List<FalconSeal> garbage = new ArrayList<>();
|
|
+ for (int i = 0; i < 3; i++) {
|
|
+ garbage.add(new FalconSeal(i, Bytes.of(0x29, i, 3, 3, 3)));
|
|
+ }
|
|
+ PqSealCache.instance().record(parent.getNumber(), parent.getHash(), 3, garbage);
|
|
+ final BftExtraData produced = PqAnchorProducer.apply(base(), parent, contextWith(validators));
|
|
+ assertThat(produced.getCertificateRound()).hasValue(0);
|
|
+ assertThat(produced.getHybridSeals()).isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void belowHrTheProducerWritesTheV2CertificateWithoutARound() {
|
|
+ PqAnchorProducer.useConfigForTesting(config(Map.of(H, 3), OptionalInt.of(3)));
|
|
+ final BlockHeader parent = parentOf(HR - 51L);
|
|
+ final Bytes32 m = PqAnchor.commitMessage(CHAIN_ID, parent.getNumber(), parent.getHash().getBytes());
|
|
+ final List<FalconSeal> heard = new ArrayList<>();
|
|
+ for (int i = 0; i < N; i++) {
|
|
+ heard.add(new FalconSeal(i, Bytes.wrap(falconSign(falconKeys.get(i), m))));
|
|
+ }
|
|
+ PqSealCache.instance().record(parent.getNumber(), parent.getHash(), 0, heard);
|
|
+ final BftExtraData produced = PqAnchorProducer.apply(base(), parent, contextWith(validators));
|
|
+ assertThat(produced.getCertificateRound()).describedAs("L1: no round below H_r").isEmpty();
|
|
+ assertThat(produced.getHybridSeals()).hasSize(3);
|
|
+ assertThat(produced.getVanityData())
|
|
+ .isEqualTo(
|
|
+ PqAnchorV2.anchorDigestV2(CHAIN_ID, parent.getNumber(), parent.getHash().getBytes(), produced.getHybridSeals()));
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------ helpers
|
|
+
|
|
+ private static PqAnchorConfig config(final Map<Long, Integer> schedule, final OptionalInt cap) {
|
|
+ return new PqAnchorConfig(CHAIN_ID, H, schedule, OptionalInt.empty(), false, cap, OptionalInt.empty(), V2)
|
|
+ .withCommitRoundBlock(HR);
|
|
+ }
|
|
+
|
|
+ private static BlockHeader parentOf(final long number) {
|
|
+ return new BlockHeaderTestFixture().number(number).buildHeader();
|
|
+ }
|
|
+
|
|
+ private BftExtraData base() {
|
|
+ return new BftExtraData(
|
|
+ Bytes32.ZERO,
|
|
+ Collections.emptyList(),
|
|
+ Optional.empty(),
|
|
+ 0,
|
|
+ validators,
|
|
+ Collections.emptyList(),
|
|
+ List.of(),
|
|
+ BftExtraData.NO_CERTIFICATE_ROUND);
|
|
+ }
|
|
+
|
|
+ /** Genuine Falcon seals of indices [from, to) over M_r(parent), recorded under round r. */
|
|
+ private void hear(final BlockHeader parent, final int round, final int from, final int to) {
|
|
+ final Bytes32 m = PqAnchor.commitMessageRound(CHAIN_ID, parent.getNumber(), round, parent.getHash().getBytes());
|
|
+ final List<FalconSeal> heard = new ArrayList<>();
|
|
+ for (int i = from; i < to; i++) {
|
|
+ heard.add(new FalconSeal(i, Bytes.wrap(falconSign(falconKeys.get(i), m))));
|
|
+ }
|
|
+ PqSealCache.instance().record(parent.getNumber(), parent.getHash(), round, heard);
|
|
+ }
|
|
+
|
|
+ private SchemeSeal slh(final int index, final Bytes32 m) {
|
|
+ return new SchemeSeal(
|
|
+ SealSchemes.SLH_DSA_128S.wireId(),
|
|
+ index,
|
|
+ Bytes.wrap(SealSchemes.SLH_DSA_128S.sign(slhKeys.get(index).privateKey(), m.toArray()).orElseThrow()));
|
|
+ }
|
|
+
|
|
+ private PqAnchorV3.Signers signers() {
|
|
+ final PqSignerRegistry registry = PqSignerRegistry.falconSealSupport();
|
|
+ return new PqAnchorV3.Signers() {
|
|
+ @Override
|
|
+ public Collection<Address> parentSet() {
|
|
+ return validators;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Address memberAt(final int index) {
|
|
+ return registry.addressForIndexAtOwnHead(HR + 49L, index);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyFalcon(final int index, final Bytes32 message, final Bytes signature) {
|
|
+ return registry.verifyAtOwnHead(HR + 49L, index, message, signature);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Optional<byte[]> extraKey(final int index, final SealScheme scheme) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ };
|
|
+ }
|
|
+
|
|
+ /** A hybrid-1 registry with the ten Falcon addresses and ten SLH-DSA keys, loaded with this schedule. */
|
|
+ private void armHybrid(final String schedule) throws Exception {
|
|
+ if (slhKeys.isEmpty()) {
|
|
+ for (int i = 0; i < N; i++) {
|
|
+ slhKeys.add(SealSchemes.SLH_DSA_128S.generate(random));
|
|
+ }
|
|
+ }
|
|
+ final StringBuilder p = new StringBuilder();
|
|
+ p.append("formatVersion=hybrid-1\nchainId=").append(CHAIN_ID).append("\ncount=").append(N).append('\n');
|
|
+ for (int i = 0; i < N; i++) {
|
|
+ p.append(i).append(".addr=").append(validators.get(i).toHexString()).append('\n');
|
|
+ p.append(i).append(".key.").append(SLH).append('=')
|
|
+ .append(Bytes.wrap(slhKeys.get(i).publicRegistryForm()).toHexString()).append('\n');
|
|
+ }
|
|
+ final Path reg = tmp.resolve("hybrid-registry-" + schedule.hashCode() + ".properties");
|
|
+ Files.writeString(reg, p.toString());
|
|
+ System.setProperty(HybridSealSupport.PROPERTY_SCHEDULE, schedule);
|
|
+ System.setProperty(HybridSealSupport.PROPERTY_REGISTRY, reg.toAbsolutePath().toString());
|
|
+ HybridSealSupport.resetForTesting();
|
|
+ assertThat(HybridSealSupport.instance().registry()).describedAs("hybrid registry loaded").isPresent();
|
|
+ }
|
|
+
|
|
+ private static byte[] falconSign(final FalconPrivateKeyParameters key, final Bytes32 m) {
|
|
+ final FalconSigner signer = new FalconSigner();
|
|
+ signer.init(true, key);
|
|
+ return signer.generateSignature(m.toArray());
|
|
+ }
|
|
+
|
|
+ private static ProtocolContext contextWith(final Collection<Address> vs) {
|
|
+ final ValidatorProvider validatorProvider =
|
|
+ mock(ValidatorProvider.class, withSettings().strictness(Strictness.LENIENT));
|
|
+ when(validatorProvider.getValidatorsForBlock(any())).thenReturn(vs);
|
|
+ when(validatorProvider.getValidatorsAfterBlock(any())).thenReturn(vs);
|
|
+ final BftContext bftContext = mock(BftContext.class, withSettings().strictness(Strictness.LENIENT));
|
|
+ when(bftContext.getValidatorProvider()).thenReturn(validatorProvider);
|
|
+ when(bftContext.as(any())).thenReturn(bftContext);
|
|
+ return new ProtocolContext.Builder().withConsensusContext(bftContext).build();
|
|
+ }
|
|
+
|
|
+ private static void resetFalconSingleton() throws Exception {
|
|
+ final Field f = FalconSealSupport.class.getDeclaredField("instance");
|
|
+ f.setAccessible(true);
|
|
+ f.set(null, null);
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorThresholdGuardRound06Test.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorThresholdGuardRound06Test.java
|
|
new file mode 100644
|
|
index 0000000000..2723d2ac7f
|
|
--- /dev/null
|
|
+++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorThresholdGuardRound06Test.java
|
|
@@ -0,0 +1,180 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.common.bft;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.assertj.core.api.Assertions.assertThatCode;
|
|
+
|
|
+import java.lang.reflect.InvocationHandler;
|
|
+import java.lang.reflect.Method;
|
|
+import java.lang.reflect.Proxy;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collections;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.OptionalInt;
|
|
+import java.util.stream.Collectors;
|
|
+
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), step 11 (2026-10-09), besu-consens/R2: the ROUND-06 warning says what the v3 producer of THIS build does. Until
|
|
+ * that date the line ended by saying the build's producer wrote no v3 certificate at all, true of the step-3 build only;
|
|
+ * from step 4 (PqAnchorProducer.applyV3) the v3 producer carries {@code max(cap, Q)} seals of one round, which is what the
|
|
+ * line now says (the second client's ROUND-06 says the same). Read from the real logging pipeline, at N = 10 (Q = 7,
|
|
+ * N - f = 7) with a proposer cap of 5 and K = 5 from H_r; the ROUND-05 line of the same call is the positive control of the
|
|
+ * tap (its text did not change), and the same configuration without the cap is the control that ROUND-06 is the cap's.
|
|
+ */
|
|
+public class PqAnchorThresholdGuardRound06Test {
|
|
+
|
|
+ private static final int N = 10;
|
|
+
|
|
+ private static PqAnchorConfig cfg(final OptionalInt cap) {
|
|
+ return new PqAnchorConfig(2800L, 1_000L, Map.of(1_000L, 3, 2_000L, 5), OptionalInt.empty(), false)
|
|
+ .withAnchorV2Block(1_000L)
|
|
+ .withMaxSealsCarried(cap)
|
|
+ .withCommitRoundBlock(2_000L);
|
|
+ }
|
|
+
|
|
+ private static List<String> guardLines(final PqAnchorConfig c) throws Exception {
|
|
+ try (LogTap tap = new LogTap("aere-r1b-pas11-round06")) {
|
|
+ assertThatCode(() -> PqAnchorThresholdGuard.verifyThresholdAgainstQuorumOrAbort(c, N))
|
|
+ .as("K = 5 <= Q = 7 from H_r, and 5 <= N - f = 7: the node starts")
|
|
+ .doesNotThrowAnyException();
|
|
+ return tap.lines(PqAnchorThresholdGuard.class.getName());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void round06SaysTheV3ProducerCarriesMaxOfCapAndQuorum() throws Exception {
|
|
+ assertThat(BftHelpers.calculateRequiredValidatorQuorum(N)).isEqualTo(7);
|
|
+ final List<String> lines = guardLines(cfg(OptionalInt.of(5)));
|
|
+ assertThat(lines)
|
|
+ .as("positive control of the tap: the ROUND-05 line of the same call is heard (lines %s)", lines)
|
|
+ .anyMatch(l -> l.contains(PqAnchorThresholdGuard.CODE_ROUND_05));
|
|
+ final List<String> r06 =
|
|
+ lines.stream().filter(l -> l.contains(PqAnchorThresholdGuard.CODE_ROUND_06)).collect(Collectors.toList());
|
|
+ assertThat(r06).as("exactly one ROUND-06 line (lines %s)", lines).hasSize(1);
|
|
+ assertThat(r06.get(0))
|
|
+ .as("ROUND-06 names what the v3 producer of this build carries: max(cap, quorum) = 7")
|
|
+ .contains("the v3 producer carries max(cap, quorum) = 7 seals of one round")
|
|
+ .doesNotContain("makes no v3");
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void withoutTheCapThereIsNoRound06() throws Exception {
|
|
+ final List<String> lines = guardLines(cfg(OptionalInt.empty()));
|
|
+ assertThat(lines)
|
|
+ .as("positive control of the tap: ROUND-05 is heard (lines %s)", lines)
|
|
+ .anyMatch(l -> l.contains(PqAnchorThresholdGuard.CODE_ROUND_05));
|
|
+ assertThat(lines)
|
|
+ .as("no cap, no ROUND-06")
|
|
+ .noneMatch(l -> l.contains(PqAnchorThresholdGuard.CODE_ROUND_06));
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * A Log4j2 appender built as a dynamic proxy on the root logger (the PqInertBinaryTest method), fully reflective. It
|
|
+ * throws if any step fails: a tap that quietly hears nothing would make every "no such line" assertion pass for
|
|
+ * nothing, and here the ROUND-05 control would then fail first.
|
|
+ */
|
|
+ static final class LogTap implements AutoCloseable {
|
|
+ private final List<String> heard = Collections.synchronizedList(new ArrayList<>());
|
|
+ private final String name;
|
|
+ private final Object rootLoggerConfig;
|
|
+ private final Object ctx;
|
|
+ private final Object priorLevel;
|
|
+ private final Class<?> loggerConfigCls;
|
|
+ private final Class<?> levelCls;
|
|
+ private final Class<?> ctxCls;
|
|
+
|
|
+ LogTap(final String name) throws Exception {
|
|
+ this.name = name;
|
|
+ final Class<?> appenderCls = Class.forName("org.apache.logging.log4j.core.Appender");
|
|
+ final Class<?> eventCls = Class.forName("org.apache.logging.log4j.core.LogEvent");
|
|
+ final Class<?> configCls = Class.forName("org.apache.logging.log4j.core.config.Configuration");
|
|
+ final Class<?> filterCls = Class.forName("org.apache.logging.log4j.core.Filter");
|
|
+ final Class<?> stateCls = Class.forName("org.apache.logging.log4j.core.LifeCycle$State");
|
|
+ final Class<?> messageCls = Class.forName("org.apache.logging.log4j.message.Message");
|
|
+ loggerConfigCls = Class.forName("org.apache.logging.log4j.core.config.LoggerConfig");
|
|
+ levelCls = Class.forName("org.apache.logging.log4j.Level");
|
|
+ ctxCls = Class.forName("org.apache.logging.log4j.core.LoggerContext");
|
|
+ final Object c =
|
|
+ Class.forName("org.apache.logging.log4j.LogManager")
|
|
+ .getMethod("getContext", boolean.class)
|
|
+ .invoke(null, Boolean.FALSE);
|
|
+ if (!ctxCls.isInstance(c)) {
|
|
+ throw new IllegalStateException("the SLF4J binding in this JVM is not log4j-core: " + c.getClass().getName());
|
|
+ }
|
|
+ ctx = c;
|
|
+ rootLoggerConfig = configCls.getMethod("getRootLogger").invoke(ctxCls.getMethod("getConfiguration").invoke(c));
|
|
+ final Method getMessage = eventCls.getMethod("getMessage");
|
|
+ final Method getLoggerName = eventCls.getMethod("getLoggerName");
|
|
+ final Method formatted = messageCls.getMethod("getFormattedMessage");
|
|
+ Object startedState = null;
|
|
+ for (final Object s : stateCls.getEnumConstants()) {
|
|
+ if ("STARTED".equals(((Enum<?>) s).name())) {
|
|
+ startedState = s;
|
|
+ }
|
|
+ }
|
|
+ final Object started = startedState;
|
|
+ final InvocationHandler handler =
|
|
+ (proxy, method, args) -> {
|
|
+ switch (method.getName()) {
|
|
+ case "append":
|
|
+ heard.add(getLoggerName.invoke(args[0]) + " | " + formatted.invoke(getMessage.invoke(args[0])));
|
|
+ return null;
|
|
+ case "getName":
|
|
+ case "toString":
|
|
+ return name;
|
|
+ case "isStarted":
|
|
+ return Boolean.TRUE;
|
|
+ case "isStopped":
|
|
+ return Boolean.FALSE;
|
|
+ case "getState":
|
|
+ return started;
|
|
+ case "ignoreExceptions":
|
|
+ return Boolean.TRUE;
|
|
+ case "equals":
|
|
+ return proxy == args[0];
|
|
+ case "hashCode":
|
|
+ return System.identityHashCode(proxy);
|
|
+ default:
|
|
+ return null;
|
|
+ }
|
|
+ };
|
|
+ final Object appender =
|
|
+ Proxy.newProxyInstance(LogTap.class.getClassLoader(), new Class<?>[] {appenderCls}, handler);
|
|
+ final Object all = levelCls.getField("ALL").get(null);
|
|
+ priorLevel = loggerConfigCls.getMethod("getLevel").invoke(rootLoggerConfig);
|
|
+ loggerConfigCls.getMethod("addAppender", appenderCls, levelCls, filterCls).invoke(rootLoggerConfig, appender, all, null);
|
|
+ loggerConfigCls.getMethod("setLevel", levelCls).invoke(rootLoggerConfig, all);
|
|
+ ctxCls.getMethod("updateLoggers").invoke(ctx);
|
|
+ }
|
|
+
|
|
+ /** The lines written by the named logger. */
|
|
+ List<String> lines(final String logger) {
|
|
+ synchronized (heard) {
|
|
+ return heard.stream().filter(l -> l.startsWith(logger + " | ")).collect(Collectors.toList());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void close() throws Exception {
|
|
+ loggerConfigCls.getMethod("removeAppender", String.class).invoke(rootLoggerConfig, name);
|
|
+ loggerConfigCls.getMethod("setLevel", levelCls).invoke(rootLoggerConfig, priorLevel);
|
|
+ ctxCls.getMethod("updateLoggers").invoke(ctx);
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorThresholdGuardRoundTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorThresholdGuardRoundTest.java
|
|
new file mode 100644
|
|
index 0000000000..85b1a79b81
|
|
--- /dev/null
|
|
+++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorThresholdGuardRoundTest.java
|
|
@@ -0,0 +1,91 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.common.bft;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.assertj.core.api.Assertions.assertThatCode;
|
|
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
+
|
|
+import java.util.Map;
|
|
+import java.util.OptionalInt;
|
|
+
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), step 3 (2026-10-01): AERE-PQC-THRESHOLD-02 (PROIECT-1B 2.3, decision H6). From H_r a certificate holds the
|
|
+ * seals of ONE round, so K_eff above the quorum Q at an anchor a >= H_r is refused at startup. Measured at N = 9 on
|
|
+ * purpose: Q = 6 and N - f = 7, the one size where THRESHOLD-02 (K <= Q) and THRESHOLD-01 (K <= N - f) can be told
|
|
+ * apart; at N = 10 both lines are 7 and a probe could not say which guard refused.
|
|
+ */
|
|
+public class PqAnchorThresholdGuardRoundTest {
|
|
+
|
|
+ private static final int N = 9;
|
|
+
|
|
+ private static PqAnchorConfig cfg(final Map<Long, Integer> schedule, final boolean hr, final OptionalInt ceiling) {
|
|
+ final PqAnchorConfig base =
|
|
+ new PqAnchorConfig(2800L, 1_000L, schedule, ceiling, false).withAnchorV2Block(1_000L);
|
|
+ return hr ? base.withCommitRoundBlock(2_000L) : base;
|
|
+ }
|
|
+
|
|
+ private static void refusedWith(final PqAnchorConfig c, final String code) {
|
|
+ assertThatThrownBy(() -> PqAnchorThresholdGuard.verifyThresholdAgainstQuorumOrAbort(c, N))
|
|
+ .isInstanceOfSatisfying(
|
|
+ FalconSealSupport.ActivationConfigException.class, e -> assertThat(e.code()).isEqualTo(code));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theArithmeticOfTheSizeIsWhatTheProbeNeeds() {
|
|
+ assertThat(BftHelpers.calculateRequiredValidatorQuorum(N)).isEqualTo(6);
|
|
+ assertThat(PqAnchorThresholdGuard.maxConfigurableThreshold(N)).isEqualTo(7);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aStepAboveTheQuorumFromHrIsRefused() {
|
|
+ refusedWith(cfg(Map.of(1_000L, 3, 2_000L, 7), true, OptionalInt.empty()), PqAnchorThresholdGuard.CODE_ROUND_BOUND);
|
|
+ refusedWith(cfg(Map.of(1_000L, 3, 3_000L, 7), true, OptionalInt.empty()), PqAnchorThresholdGuard.CODE_ROUND_BOUND);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theStepInForceAtHrCountsToo() {
|
|
+ refusedWith(cfg(Map.of(1_000L, 7), true, OptionalInt.empty()), PqAnchorThresholdGuard.CODE_ROUND_BOUND);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aStepAboveTheQuorumOnlyBelowHrIsAllowed() {
|
|
+ assertThatCode(
|
|
+ () -> PqAnchorThresholdGuard.verifyThresholdAgainstQuorumOrAbort(cfg(Map.of(1_000L, 7, 1_500L, 6), true, OptionalInt.empty()), N))
|
|
+ .doesNotThrowAnyException();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void withoutHrNothingChanges() {
|
|
+ assertThatCode(
|
|
+ () -> PqAnchorThresholdGuard.verifyThresholdAgainstQuorumOrAbort(cfg(Map.of(1_000L, 7), false, OptionalInt.empty()), N))
|
|
+ .as("THRESHOLD-01 allows 7 = N - f at N = 9, and without H_r there is no second guard (L1)")
|
|
+ .doesNotThrowAnyException();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theEmergencyCeilingLowersItBelowTheQuorum() {
|
|
+ assertThatCode(
|
|
+ () -> PqAnchorThresholdGuard.verifyThresholdAgainstQuorumOrAbort(cfg(Map.of(1_000L, 3, 2_000L, 7), true, OptionalInt.of(6)), N))
|
|
+ .doesNotThrowAnyException();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void controlAboveNMinusFTheFirstGuardStillRefusesFirst() {
|
|
+ refusedWith(cfg(Map.of(1_000L, 8), true, OptionalInt.empty()), PqAnchorThresholdGuard.CODE);
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorV2ProducerTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorV2ProducerTest.java
|
|
index 76c274993f..23e169aaa5 100755
|
|
--- a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorV2ProducerTest.java
|
|
+++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorV2ProducerTest.java
|
|
@@ -208,109 +208,109 @@ class PqAnchorV2ProducerTest {
|
|
.isInstanceOf(PqAnchorNotReadyException.class)
|
|
.hasMessageContaining(SLH);
|
|
// and with only K-1 SLH-DSA seals it still refuses: K per scheme, not "some"
|
|
hearExtras(parent, K - 1);
|
|
assertThatThrownBy(() -> PqAnchorProducer.apply(base(), parent, contextWith(validators)))
|
|
.isInstanceOf(PqAnchorNotReadyException.class)
|
|
.hasMessageContaining(SLH);
|
|
}
|
|
|
|
@Test
|
|
void anSlhDsaSealFromAnIndexWithoutAFalconSealIsNotCounted() {
|
|
PqAnchorProducer.useConfigForTesting(config(V2, OptionalInt.of(K)));
|
|
final BlockHeader parent = parentOf(V2 + 9L);
|
|
hearFalcon(parent, K); // Falcon from indices 0..K-1 only
|
|
// SLH-DSA from indices K..N-1 only: none of them is Falcon-certified
|
|
final Bytes32 m = PqAnchor.commitMessage(CHAIN_ID, parent.getNumber(), parent.getHash().getBytes());
|
|
final List<SchemeSeal> extras = new ArrayList<>();
|
|
for (int i = K; i < N; i++) {
|
|
extras.add(new SchemeSeal(SealSchemes.SLH_DSA_128S.wireId(), i, Bytes.wrap(slhSign(i, m))));
|
|
}
|
|
- PqSealCache.instance().recordExtras(parent.getNumber(), parent.getHash(), extras);
|
|
+ PqSealCache.instance().recordExtras(parent.getNumber(), parent.getHash(), 0, extras);
|
|
assertThatThrownBy(() -> PqAnchorProducer.apply(base(), parent, contextWith(validators)))
|
|
.isInstanceOf(PqAnchorNotReadyException.class)
|
|
.hasMessageContaining("bound to a Falcon-certified index");
|
|
}
|
|
|
|
@Test
|
|
void aFalconOnlyScheduleYieldsAFalconOnlyV2Certificate() throws Exception {
|
|
armHybrid("0:falcon-512");
|
|
PqAnchorProducer.useConfigForTesting(config(V2, OptionalInt.of(K)));
|
|
final BlockHeader parent = parentOf(V2 + 9L);
|
|
hearFalcon(parent, N);
|
|
hearExtras(parent, N); // heard, but the schedule does not ask for them
|
|
final BftExtraData produced = PqAnchorProducer.apply(base(), parent, contextWith(validators));
|
|
assertThat(produced.getHybridSeals()).hasSize(K);
|
|
assertThat(PqAnchorV2.distinctValidatorsWith(produced.getHybridSeals(), SealSchemes.SLH_DSA_128S.wireId()))
|
|
.describedAs("a scheme the schedule does not name is never written, heard or not")
|
|
.isZero();
|
|
}
|
|
|
|
@Test
|
|
void theSealCacheKeepsExtrasBesideTheFalconSealsUnderTheSameKey() {
|
|
final BlockHeader parent = parentOf(V2 + 9L);
|
|
hearFalcon(parent, N);
|
|
hearExtras(parent, N);
|
|
- assertThat(PqSealCache.instance().sealsFor(parent.getNumber(), parent.getHash())).hasSize(N);
|
|
- final List<SchemeSeal> extras = PqSealCache.instance().extrasFor(parent.getNumber(), parent.getHash());
|
|
+ assertThat(PqSealCache.instance().sealsFor(parent.getNumber(), parent.getHash(), 0)).hasSize(N);
|
|
+ final List<SchemeSeal> extras = PqSealCache.instance().extrasFor(parent.getNumber(), parent.getHash(), 0);
|
|
assertThat(extras).hasSize(N);
|
|
assertThat(extras).isSortedAccordingTo(PqAnchorV2.CANONICAL);
|
|
// a Falcon-tagged seal offered to the extras slot is dropped: Falcon has its own slot
|
|
- PqSealCache.instance().recordExtras(parent.getNumber(), parent.getHash(),
|
|
+ PqSealCache.instance().recordExtras(parent.getNumber(), parent.getHash(), 0,
|
|
List.of(new SchemeSeal(SealSchemes.FALCON_512.wireId(), 0, Bytes.of(1, 2, 3))));
|
|
- assertThat(PqSealCache.instance().extrasFor(parent.getNumber(), parent.getHash())).hasSize(N);
|
|
+ assertThat(PqSealCache.instance().extrasFor(parent.getNumber(), parent.getHash(), 0)).hasSize(N);
|
|
// and a different hash under the same height is a different entry
|
|
- assertThat(PqSealCache.instance().extrasFor(parent.getNumber(), parentOf(V2 + 8L).getHash())).isEmpty();
|
|
+ assertThat(PqSealCache.instance().extrasFor(parent.getNumber(), parentOf(V2 + 8L).getHash(), 0)).isEmpty();
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------ helpers
|
|
|
|
private static PqAnchorConfig config(final long v2Block, final OptionalInt cap) {
|
|
return new PqAnchorConfig(
|
|
CHAIN_ID, H, Map.of(H, K), OptionalInt.empty(), false, cap, OptionalInt.empty(), v2Block);
|
|
}
|
|
|
|
private static BlockHeader parentOf(final long number) {
|
|
return new BlockHeaderTestFixture().number(number).buildHeader();
|
|
}
|
|
|
|
private BftExtraData base() {
|
|
return new BftExtraData(
|
|
- Bytes32.ZERO, Collections.emptyList(), Optional.empty(), 0, validators, Collections.emptyList());
|
|
+ Bytes32.ZERO, Collections.emptyList(), Optional.empty(), 0, validators, Collections.emptyList(), java.util.List.of(), BftExtraData.NO_CERTIFICATE_ROUND);
|
|
}
|
|
|
|
private void hearFalcon(final BlockHeader parent, final int howMany) {
|
|
final Bytes32 m = PqAnchor.commitMessage(CHAIN_ID, parent.getNumber(), parent.getHash().getBytes());
|
|
final List<FalconSeal> heard = new ArrayList<>();
|
|
for (int i = 0; i < howMany; i++) {
|
|
heard.add(new FalconSeal(i, Bytes.wrap(falconSign(falconKeys.get(i), m))));
|
|
}
|
|
- PqSealCache.instance().record(parent.getNumber(), parent.getHash(), heard);
|
|
+ PqSealCache.instance().record(parent.getNumber(), parent.getHash(), 0, heard);
|
|
}
|
|
|
|
private void hearExtras(final BlockHeader parent, final int howMany) {
|
|
final Bytes32 m = PqAnchor.commitMessage(CHAIN_ID, parent.getNumber(), parent.getHash().getBytes());
|
|
final List<SchemeSeal> extras = new ArrayList<>();
|
|
for (int i = 0; i < howMany; i++) {
|
|
extras.add(new SchemeSeal(SealSchemes.SLH_DSA_128S.wireId(), i, Bytes.wrap(slhSign(i, m))));
|
|
}
|
|
- PqSealCache.instance().recordExtras(parent.getNumber(), parent.getHash(), extras);
|
|
+ PqSealCache.instance().recordExtras(parent.getNumber(), parent.getHash(), 0, extras);
|
|
}
|
|
|
|
private byte[] slhSign(final int index, final Bytes32 m) {
|
|
return SealSchemes.SLH_DSA_128S.sign(slhKeys.get(index).privateKey(), m.toArray()).orElseThrow();
|
|
}
|
|
|
|
private static byte[] falconSign(final FalconPrivateKeyParameters key, final Bytes32 m) {
|
|
final FalconSigner signer = new FalconSigner();
|
|
signer.init(true, key);
|
|
return signer.generateSignature(m.toArray());
|
|
}
|
|
|
|
private static ProtocolContext contextWith(final Collection<Address> vs) {
|
|
final ValidatorProvider validatorProvider =
|
|
mock(ValidatorProvider.class, withSettings().strictness(Strictness.LENIENT));
|
|
when(validatorProvider.getValidatorsForBlock(any())).thenReturn(vs);
|
|
when(validatorProvider.getValidatorsAfterBlock(any())).thenReturn(vs);
|
|
final BftContext bftContext =
|
|
mock(BftContext.class, withSettings().strictness(Strictness.LENIENT));
|
|
when(bftContext.getValidatorProvider()).thenReturn(validatorProvider);
|
|
diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqForkValidatorSetChangeTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqForkValidatorSetChangeTest.java
|
|
index 724650d858..8e3c7264fb 100755
|
|
--- a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqForkValidatorSetChangeTest.java
|
|
+++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqForkValidatorSetChangeTest.java
|
|
@@ -261,55 +261,55 @@ public class PqForkValidatorSetChangeTest {
|
|
+ "answer is the halt. Restarting a node is an ordinary operation.")
|
|
.isTrue();
|
|
assertThat(pqc.sign(H + 50L, message(H + 49L))).isPresent();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------------------
|
|
// 4. The causal link, measured in BOTH directions.
|
|
// -----------------------------------------------------------------------------------------
|
|
|
|
@Test
|
|
public void theProposerRefusesWhenNothingWasAttachedAndProposesWhenSomethingWas() {
|
|
final BlockHeader parent = new BlockHeaderTestFixture().number(K_AT + 20L).buildHeader();
|
|
final ProtocolContext context = contextWith(keyedValidators);
|
|
final BftExtraData base =
|
|
new BftExtraData(
|
|
Bytes32.ZERO,
|
|
Collections.emptyList(),
|
|
Optional.empty(),
|
|
0,
|
|
keyedValidators,
|
|
- Collections.emptyList());
|
|
+ Collections.emptyList(), java.util.List.of(), BftExtraData.NO_CERTIFICATE_ROUND);
|
|
|
|
// (a) nothing heard, because nothing was attached: the proposer cannot propose.
|
|
assertThatThrownBy(() -> PqAnchorProducer.apply(base, parent, context))
|
|
.isInstanceOf(PqAnchorNotReadyException.class);
|
|
|
|
// (b) five real Falcon seals heard: the same proposer, same inputs, produces a certificate.
|
|
// Without this half, (a) would be satisfied by a producer that always refuses.
|
|
final Bytes32 m =
|
|
PqAnchor.commitMessage(CHAIN_ID, parent.getNumber(), parent.getHash().getBytes());
|
|
final List<FalconSeal> heard = new ArrayList<>();
|
|
for (int i = 0; i < K; i++) {
|
|
heard.add(new FalconSeal(i, Bytes.wrap(falconSign(privateKeys.get(i), m))));
|
|
}
|
|
- PqSealCache.instance().record(parent.getNumber(), parent.getHash(), heard);
|
|
+ PqSealCache.instance().record(parent.getNumber(), parent.getHash(), 0, heard);
|
|
|
|
final BftExtraData produced = PqAnchorProducer.apply(base, parent, context);
|
|
assertThat(produced.getFalconSeals()).hasSize(K);
|
|
assertThat(produced.getVanityData())
|
|
.isEqualTo(
|
|
PqAnchor.anchorDigest(
|
|
CHAIN_ID,
|
|
parent.getNumber(),
|
|
parent.getHash().getBytes(),
|
|
PqAnchor.sortedByIndex(heard)));
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------------------
|
|
// 4b. What an unkeyed validator actually costs, as a number rather than as a worry.
|
|
// -----------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Removing coverage from the attachment gate stops the halt; it does not make adding an unkeyed
|
|
* validator free. The price is the guaranteed number of anchored-key holders among a block's ECDSA
|
|
* committers, and it is arithmetic, not opinion: a block needs {@code ceil(2N/3)} committers, and
|
|
diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqInertBinaryTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqInertBinaryTest.java
|
|
index 80a2cefe9c..a2c59ce51a 100755
|
|
--- a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqInertBinaryTest.java
|
|
+++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqInertBinaryTest.java
|
|
@@ -263,41 +263,41 @@ public class PqInertBinaryTest {
|
|
|
|
assertThat(captor.anchorLines())
|
|
.describedAs(
|
|
"the captor must be able to hear the anchor, or the silence next door is worthless")
|
|
.isNotEmpty();
|
|
assertThat(String.join("\n", captor.anchorLines())).contains("producer armed");
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------------------------
|
|
// Helpers.
|
|
// ---------------------------------------------------------------------------------------------
|
|
|
|
/** Extra data with no anchor digest, i.e. exactly what a pre-fork proposer builds. */
|
|
private static BftExtraData plainExtraData() {
|
|
return new BftExtraData(
|
|
Bytes32.ZERO,
|
|
Collections.emptyList(),
|
|
Optional.empty(),
|
|
0,
|
|
Collections.emptyList(),
|
|
- Collections.emptyList());
|
|
+ Collections.emptyList(), java.util.List.of(), BftExtraData.NO_CERTIFICATE_ROUND);
|
|
}
|
|
|
|
private static ProtocolContext contextWith(final Collection<Address> validators) {
|
|
final ValidatorProvider validatorProvider =
|
|
mock(ValidatorProvider.class, withSettings().strictness(Strictness.LENIENT));
|
|
when(validatorProvider.getValidatorsForBlock(any())).thenReturn(validators);
|
|
when(validatorProvider.getValidatorsAfterBlock(any())).thenReturn(validators);
|
|
final BftContext bftContext =
|
|
mock(BftContext.class, withSettings().strictness(Strictness.LENIENT));
|
|
when(bftContext.getValidatorProvider()).thenReturn(validatorProvider);
|
|
when(bftContext.as(any())).thenReturn(bftContext);
|
|
return new ProtocolContext.Builder().withConsensusContext(bftContext).build();
|
|
}
|
|
|
|
private static List<String> systemPropertiesStartingWith(final String prefix) {
|
|
final Properties p = System.getProperties();
|
|
return p.stringPropertyNames().stream()
|
|
.filter(n -> n.startsWith(prefix))
|
|
.sorted()
|
|
.collect(Collectors.toList());
|
|
diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqSealCacheRoundTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqSealCacheRoundTest.java
|
|
new file mode 100644
|
|
index 0000000000..b4dd30ce73
|
|
--- /dev/null
|
|
+++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqSealCacheRoundTest.java
|
|
@@ -0,0 +1,522 @@
|
|
+/*
|
|
+ * Copyright contributors to Aere Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
|
|
+ * compliance with the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is
|
|
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
+ * implied. See the License for the specific language governing permissions and limitations under the
|
|
+ * License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.common.bft;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+
|
|
+import java.lang.reflect.Field;
|
|
+import java.nio.file.Files;
|
|
+import java.nio.file.Path;
|
|
+import java.util.ArrayList;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.NavigableMap;
|
|
+import java.util.OptionalInt;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.bouncycastle.crypto.digests.KeccakDigest;
|
|
+import org.bouncycastle.pqc.crypto.falcon.FalconPrivateKeyParameters;
|
|
+import org.bouncycastle.pqc.crypto.falcon.FalconSigner;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.junit.jupiter.api.io.TempDir;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), D-470, pasul 4 (2026-10-01): the store of heard seals keyed by (hash, round) from H_r - 1 (project section 3.1 D, F
|
|
+ * and G). Below H_r the round is ignored and a block has ONE record, exactly as before (L1). From H_r - 1 each round is its own
|
|
+ * record, with its own slot per index; at most eight rounds per block, the weakest leaving; the D-339 seals of a round r > 0
|
|
+ * heard without the proposal wait under their commit digest and move under their round once the block is known; and the head
|
|
+ * file is SEALSTORE-2, every round with its seals, each seal re-verified over M_r at the restore, a seal of another round
|
|
+ * dropped, and a SEALSTORE-1 file at a round-bound height ignored (never reinterpreted as round 0).
|
|
+ */
|
|
+class PqSealCacheRoundTest {
|
|
+
|
|
+ private static final long CHAIN_ID = 220_879L;
|
|
+ private static final long H = 1_000L;
|
|
+ private static final long V2 = 1_005L;
|
|
+ private static final long HR = 1_100L;
|
|
+ private static final int N = 10;
|
|
+
|
|
+ @TempDir private Path tmp;
|
|
+
|
|
+ private final List<FalconPrivateKeyParameters> keys = new ArrayList<>();
|
|
+
|
|
+ @BeforeEach
|
|
+ void setUp() throws Exception {
|
|
+ final KeccakDigest kd = new KeccakDigest(256);
|
|
+ final StringBuilder manifest = new StringBuilder();
|
|
+ manifest.append("{\"config\":{\"aereFalconRegistry\":{").append(PqV2Fixture.manifestHeader(N, CHAIN_ID, H));
|
|
+ for (int i = 0; i < N; i++) {
|
|
+ keys.add(PqV2Fixture.privateKey(i));
|
|
+ final byte[] row = PqV2Fixture.anchorPreimageRow(i);
|
|
+ kd.update(row, 0, row.length);
|
|
+ manifest.append(',').append(PqV2Fixture.manifestEntry(i, N, CHAIN_ID, H));
|
|
+ }
|
|
+ manifest
|
|
+ .append("}},\"alloc\":{\"0000000000000000000000000000000000000fa1\":{\"storage\":{\"0x")
|
|
+ .append("0".repeat(64))
|
|
+ .append("\":\"0x");
|
|
+ final byte[] anchoredHash = new byte[32];
|
|
+ kd.doFinal(anchoredHash, 0);
|
|
+ manifest.append(Bytes.wrap(anchoredHash).toUnprefixedHexString()).append("\"}}}}");
|
|
+ final Path genesis = tmp.resolve("genesis-registry.json");
|
|
+ Files.writeString(genesis, manifest.toString());
|
|
+ System.setProperty("aere.falcon.genesis", genesis.toAbsolutePath().toString());
|
|
+ resetFalconSingleton();
|
|
+ PqSealCache.instance().clear();
|
|
+ PqAnchorProducer.useConfigForTesting(config());
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ void tearDown() throws Exception {
|
|
+ PqSealCache.instance().disablePersistence();
|
|
+ PqSealCache.instance().clear();
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ System.clearProperty("aere.falcon.genesis");
|
|
+ System.clearProperty(HybridSealSupport.PROPERTY_SCHEDULE);
|
|
+ System.clearProperty(HybridSealSupport.PROPERTY_REGISTRY);
|
|
+ HybridSealSupport.resetForTesting();
|
|
+ resetFalconSingleton();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void belowHrTheRoundIsIgnoredAndTheBlockKeepsOneRecord() {
|
|
+ final long n = HR - 2L; // COMMIT-1 still: the last round-free block
|
|
+ final Hash h = header(n).getHash();
|
|
+ PqSealCache.instance().record(n, h, 0, List.of(seal(0, (byte) 1), seal(1, (byte) 1)));
|
|
+ PqSealCache.instance().record(n, h, 5, List.of(seal(2, (byte) 1)));
|
|
+ final NavigableMap<Integer, PqSealCache.RoundSeals> rounds = PqSealCache.instance().roundsFor(n, h);
|
|
+ assertThat(rounds.keySet())
|
|
+ .describedAs("L1: below H_r - 1 one record per block, under ANY, whatever round the caller names")
|
|
+ .containsExactly(PqSealCache.ANY_ROUND);
|
|
+ assertThat(PqSealCache.instance().sealsFor(n, h, 0)).hasSize(3);
|
|
+ assertThat(PqSealCache.instance().sealsFor(n, h, 7)).hasSize(3);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void fromHrMinusOneEachRoundIsItsOwnRecord() {
|
|
+ final long n = HR - 1L; // H3: the parent of the first v3 anchor is already round-bound
|
|
+ final Hash h = header(n).getHash();
|
|
+ PqSealCache.instance().record(n, h, 0, seals(0, 4, (byte) 1));
|
|
+ PqSealCache.instance().record(n, h, 2, seals(4, 7, (byte) 2));
|
|
+ final NavigableMap<Integer, PqSealCache.RoundSeals> rounds = PqSealCache.instance().roundsFor(n, h);
|
|
+ assertThat(rounds.keySet()).containsExactly(0, 2);
|
|
+ assertThat(rounds.get(0).falcon()).hasSize(4);
|
|
+ assertThat(rounds.get(2).falcon()).hasSize(3);
|
|
+ assertThat(PqSealCache.instance().sealsFor(n, h, 0)).hasSize(4);
|
|
+ assertThat(PqSealCache.instance().sealsFor(n, h, 2)).hasSize(3);
|
|
+ assertThat(PqSealCache.instance().sealsFor(n, h, 1))
|
|
+ .describedAs("a round nothing was heard in holds nothing; seals of two rounds are never pooled")
|
|
+ .isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aRoundOutsideTheRangeIsDroppedAndNothingThrows() {
|
|
+ final long n = HR + 50L;
|
|
+ final Hash h = header(n).getHash();
|
|
+ PqSealCache.instance().record(n, h, PqAnchorV3.MAX_ROUND + 1, List.of(seal(0, (byte) 1)));
|
|
+ PqSealCache.instance().record(n, h, -5, List.of(seal(1, (byte) 1)));
|
|
+ PqSealCache.instance()
|
|
+ .recordExtras(
|
|
+ n, h, PqAnchorV3.MAX_ROUND + 1, List.of(new SchemeSeal(SealSchemes.SLH_DSA_128S.wireId(), 0, Bytes.of(1))));
|
|
+ assertThat(PqSealCache.instance().roundsFor(n, h))
|
|
+ .describedAs("H11: a round outside 0..MAX_ROUND is not a key, and it is not an exception either")
|
|
+ .isEmpty();
|
|
+ assertThat(PqSealCache.instance().sealsFor(n, h, PqAnchorV3.MAX_ROUND + 1)).isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void atMostEightRoundsPerBlockAndOnATieTheLargerRoundLeaves() {
|
|
+ final long n = HR + 50L;
|
|
+ final Hash h = header(n).getHash();
|
|
+ PqSealCache.instance().record(n, h, 0, seals(0, 5, (byte) 1));
|
|
+ for (int r = 1; r <= 8; r++) {
|
|
+ PqSealCache.instance().record(n, h, r, List.of(seal(r % N, (byte) (10 + r))));
|
|
+ }
|
|
+ assertThat(PqSealCache.instance().roundsFor(n, h).keySet())
|
|
+ .describedAs("nine rounds offered, eight kept; nothing verifies (no judge armed), so the LARGER round leaves")
|
|
+ .containsExactly(0, 1, 2, 3, 4, 5, 6, 7);
|
|
+ PqSealCache.instance().record(n, h, 9, seals(0, 2, (byte) 9));
|
|
+ assertThat(PqSealCache.instance().roundsFor(n, h).keySet())
|
|
+ .describedAs("a newcomer that verifies no more than the others is itself the larger round: it leaves")
|
|
+ .containsExactly(0, 1, 2, 3, 4, 5, 6, 7);
|
|
+ assertThat(PqSealCache.instance().sealsFor(n, h, 0)).hasSize(5);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void eightRoundsOfGarbageCannotPushOutTheRoundThatVerifies() {
|
|
+ // the blocker of the step-4 review: one validator sends late Commits of eight rounds it chooses, each with garbage
|
|
+ // seals of EVERY index; ranked by seals heard, the honest round left. Ranked by seals that verify over their round's
|
|
+ // message (the store's judge, the producer's door), garbage counts nothing.
|
|
+ PqSealCache.instance().judgeWith(PqSealCache::verifiesAsTheProducerDoes);
|
|
+ final long n = HR + 50L;
|
|
+ final Hash h = header(n).getHash();
|
|
+ PqSealCache.instance().record(n, h, 0, genuine(n, h, 0, 0, 7));
|
|
+ for (int r = 1; r <= 12; r++) {
|
|
+ PqSealCache.instance().record(n, h, r, seals(0, N, (byte) (40 + r)));
|
|
+ }
|
|
+ assertThat(PqSealCache.instance().roundsFor(n, h)).containsKey(0).hasSize(PqSealCache.MAX_ROUNDS_PER_BLOCK);
|
|
+ assertThat(PqSealCache.instance().sealsFor(n, h, 0)).hasSize(7);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aRecordKeepsAtMostSixtyFourIndicesAndAFloodAboveTheSetDisplacesNoHonestIndex() {
|
|
+ final long n = HR + 50L;
|
|
+ final Hash h = header(n).getHash();
|
|
+ PqSealCache.instance().record(n, h, 1, seals(100, 100 + PqSealCache.MAX_SEALS_PER_ROUND, (byte) 7));
|
|
+ assertThat(PqSealCache.instance().sealsFor(n, h, 1)).hasSize(PqSealCache.MAX_SEALS_PER_ROUND);
|
|
+ PqSealCache.instance().record(n, h, 1, seals(0, N, (byte) 8));
|
|
+ final List<FalconSeal> held = PqSealCache.instance().sealsFor(n, h, 1);
|
|
+ assertThat(held).hasSize(PqSealCache.MAX_SEALS_PER_ROUND);
|
|
+ assertThat(held)
|
|
+ .extracting(FalconSeal::getValidatorIndex)
|
|
+ .describedAs("the ten honest indices entered; the highest of the flood left")
|
|
+ .contains(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
|
|
+ .doesNotContain(163, 162);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aValidatorThatFloodsPendingDigestsDisplacesOnlyItsOwnEntries() {
|
|
+ final long n = HR + 50L;
|
|
+ final Hash h = header(n).getHash();
|
|
+ final org.hyperledger.besu.datatypes.Address attacker =
|
|
+ org.hyperledger.besu.datatypes.Address.fromHexString("0x" + "0".repeat(38) + "a1");
|
|
+ final org.hyperledger.besu.datatypes.Address honest =
|
|
+ org.hyperledger.besu.datatypes.Address.fromHexString("0x" + "0".repeat(38) + "b2");
|
|
+ final Hash honestDigest = Hash.hash(Bytes.of(2, 2, 2));
|
|
+ PqSealCache.instance().recordPendingRound(n, honestDigest, 2, honest, seals(4, 5, (byte) 2), List.of());
|
|
+ for (int i = 0; i < 300; i++) {
|
|
+ PqSealCache.instance()
|
|
+ .recordPendingRound(n, Hash.hash(Bytes.ofUnsignedInt(i)), 2, attacker, seals(0, 1, (byte) 9), List.of());
|
|
+ }
|
|
+ assertThat(PqSealCache.instance().pendingCount())
|
|
+ .describedAs("the attacker keeps its own quota, the honest entry stays")
|
|
+ .isEqualTo(PqSealCache.MAX_PENDING_PER_AUTHOR + 1);
|
|
+ // the same seal offered twice is one slot
|
|
+ PqSealCache.instance().recordPendingRound(n, honestDigest, 2, honest, seals(4, 5, (byte) 2), List.of());
|
|
+ assertThat(PqSealCache.instance().resolvePending(n, h, r -> r == 2 ? honestDigest : Hash.ZERO)).isEqualTo(1);
|
|
+ assertThat(PqSealCache.instance().sealsFor(n, h, 2)).hasSize(1);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void theSlotOfAnIndexInOneRoundIsNotTheSlotOfAnotherRound() {
|
|
+ final long n = HR + 50L;
|
|
+ final Hash h = header(n).getHash();
|
|
+ PqSealCache.instance().record(n, h, 0, List.of(seal(0, (byte) 0x30)));
|
|
+ PqSealCache.instance().record(n, h, 2, List.of(seal(0, (byte) 0x32)));
|
|
+ assertThat(PqSealCache.instance().sealsFor(n, h, 2))
|
|
+ .describedAs("index 0 of round 2 is not blocked by index 0 of round 0 (D-454 is per round)")
|
|
+ .singleElement()
|
|
+ .satisfies(s -> assertThat(s.getSignature()).isEqualTo(seal(0, (byte) 0x32).getSignature()));
|
|
+ assertThat(PqSealCache.instance().sealsFor(n, h, 0))
|
|
+ .singleElement()
|
|
+ .satisfies(s -> assertThat(s.getSignature()).isEqualTo(seal(0, (byte) 0x30).getSignature()));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void pendingSealsOfARoundMoveUnderItWhenTheBlockIsKnown() {
|
|
+ final long n = HR + 50L;
|
|
+ final Hash h = header(n).getHash();
|
|
+ final Hash digest3 = Hash.hash(Bytes.of(3, 3, 3));
|
|
+ final Hash losing = Hash.hash(Bytes.of(2, 2, 2));
|
|
+ PqSealCache.instance().recordPendingRound(n, digest3, 3, null, seals(0, 2, (byte) 3), List.of());
|
|
+ PqSealCache.instance().recordPendingRound(n, losing, 2, null, seals(2, 3, (byte) 2), List.of());
|
|
+ PqSealCache.instance().recordPendingRound(n, h, 0, null, seals(5, 6, (byte) 0), List.of());
|
|
+ PqSealCache.instance().recordPendingRound(HR - 50L, digest3, 3, null, seals(0, 1, (byte) 3), List.of());
|
|
+ assertThat(PqSealCache.instance().pendingCount())
|
|
+ .describedAs("round 0 (its digest IS the on-chain hash) and heights below H_r are never held aside")
|
|
+ .isEqualTo(2);
|
|
+ final int moved = PqSealCache.instance().resolvePending(n, h, r -> r == 3 ? digest3 : Hash.ZERO);
|
|
+ assertThat(moved).isEqualTo(1);
|
|
+ assertThat(PqSealCache.instance().sealsFor(n, h, 3))
|
|
+ .describedAs("the Commit of round 3 heard without the proposal is now under (n, hash, 3)")
|
|
+ .hasSize(2);
|
|
+ assertThat(PqSealCache.instance().sealsFor(n, h, 2))
|
|
+ .describedAs("a pending entry whose digest is not this block's at its round (a losing proposal) is not moved")
|
|
+ .isEmpty();
|
|
+ assertThat(PqSealCache.instance().pendingCount()).isEqualTo(1);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void theHeadFileKeepsEveryRoundAndTheRestoreReVerifiesOverItsOwnRound() throws Exception {
|
|
+ final long n = HR + 50L;
|
|
+ final BlockHeader head = header(n);
|
|
+ final Hash h = head.getHash();
|
|
+ final Path data = Files.createDirectories(tmp.resolve("data"));
|
|
+ PqSealCache.instance().enablePersistence(data, CHAIN_ID);
|
|
+ PqSealCache.instance().record(n, h, 0, genuine(n, h, 0, 0, 4));
|
|
+ final List<FalconSeal> round2 = new ArrayList<>(genuine(n, h, 2, 4, 7));
|
|
+ // index 7 signed over M_0, offered as a seal of round 2: it must not survive the restore
|
|
+ round2.addAll(genuine(n, h, 0, 7, 8));
|
|
+ PqSealCache.instance().record(n, h, 2, round2);
|
|
+ final Path file = PqSealCache.instance().persistenceFile();
|
|
+ assertThat(Files.isRegularFile(file)).isTrue();
|
|
+ final byte[] raw = Files.readAllBytes(file);
|
|
+ assertThat(Bytes.wrap(raw).toHexString())
|
|
+ .describedAs("the head file at a round-bound height is SEALSTORE-2")
|
|
+ .contains(Bytes.wrap(PqSealStore.DOMAIN_2.getBytes(java.nio.charset.StandardCharsets.US_ASCII)).toUnprefixedHexString());
|
|
+ PqSealCache.instance().clear();
|
|
+ final int restored =
|
|
+ PqSealCache.instance().restoreFromDisk(n, h, PqSignerRegistry.falconSealSupport());
|
|
+ assertThat(restored).describedAs("4 of round 0 and 3 of round 2; the seal over another round's message is dropped").isEqualTo(7);
|
|
+ final NavigableMap<Integer, PqSealCache.RoundSeals> rounds = PqSealCache.instance().roundsFor(n, h);
|
|
+ assertThat(rounds.keySet()).containsExactly(0, 2);
|
|
+ assertThat(rounds.get(0).falcon()).hasSize(4);
|
|
+ assertThat(rounds.get(2).falcon()).extracting(FalconSeal::getValidatorIndex).containsExactly(4, 5, 6);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void theHeadFileKeepsTheExtrasOfARoundAndTheRestoreReVerifiesThemOverItsMessage() throws Exception {
|
|
+ // the gap that stopped 2800 on 2026-09-04: the extras (SLH-DSA) of the head were never persisted
|
|
+ final long n = HR + 50L;
|
|
+ final Hash h = header(n).getHash();
|
|
+ final List<SealScheme.GeneratedPair> slh = armHybrid();
|
|
+ final Path data = Files.createDirectories(tmp.resolve("data-extras"));
|
|
+ PqSealCache.instance().enablePersistence(data, CHAIN_ID);
|
|
+ PqSealCache.instance().record(n, h, 1, genuine(n, h, 1, 0, 3));
|
|
+ final Bytes32 m1 = PqAnchor.commitMessageRound(CHAIN_ID, n, 1, h.getBytes());
|
|
+ final Bytes32 m0 = PqAnchor.commitMessageRound(CHAIN_ID, n, 0, h.getBytes());
|
|
+ PqSealCache.instance()
|
|
+ .recordExtras(
|
|
+ n,
|
|
+ h,
|
|
+ 1,
|
|
+ List.of(
|
|
+ new SchemeSeal(
|
|
+ SealSchemes.SLH_DSA_128S.wireId(),
|
|
+ 0,
|
|
+ Bytes.wrap(SealSchemes.SLH_DSA_128S.sign(slh.get(0).privateKey(), m1.toArray()).orElseThrow())),
|
|
+ // index 1 signed over M_0: dropped at the restore
|
|
+ new SchemeSeal(
|
|
+ SealSchemes.SLH_DSA_128S.wireId(),
|
|
+ 1,
|
|
+ Bytes.wrap(SealSchemes.SLH_DSA_128S.sign(slh.get(1).privateKey(), m0.toArray()).orElseThrow()))));
|
|
+ PqSealCache.instance().clear();
|
|
+ PqSealCache.instance().restoreFromDisk(n, h, PqSignerRegistry.falconSealSupport());
|
|
+ assertThat(PqSealCache.instance().sealsFor(n, h, 1)).hasSize(3);
|
|
+ assertThat(PqSealCache.instance().extrasFor(n, h, 1))
|
|
+ .describedAs("the extra of round 1 over M_1 came back; the one over M_0 did not")
|
|
+ .extracting(SchemeSeal::getValidatorIndex)
|
|
+ .containsExactly(0);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void theHeadFileHoldsOnlyRowsThatVerify() throws Exception {
|
|
+ // second review of step 4: rows that do not verify never reach the head file, so a round of garbage cannot push the
|
|
+ // round that decided out of the file's 1 MiB
|
|
+ final long n = HR + 50L;
|
|
+ final Hash h = header(n).getHash();
|
|
+ final Path data = Files.createDirectories(tmp.resolve("data-garbage"));
|
|
+ PqSealCache.instance().enablePersistence(data, CHAIN_ID);
|
|
+ PqSealCache.instance().record(n, h, 0, genuine(n, h, 0, 0, 3));
|
|
+ final byte[] marker = new byte[40];
|
|
+ java.util.Arrays.fill(marker, (byte) 0xab);
|
|
+ marker[0] = 0x29;
|
|
+ PqSealCache.instance()
|
|
+ .record(n, h, 5, List.of(new FalconSeal(4, Bytes.wrap(marker)), new FalconSeal(5, Bytes.wrap(marker))));
|
|
+ final byte[] raw = Files.readAllBytes(PqSealCache.instance().persistenceFile());
|
|
+ assertThat(Bytes.wrap(raw).toUnprefixedHexString())
|
|
+ .describedAs("the garbage rows of round 5 are not in the file")
|
|
+ .doesNotContain("ab".repeat(39));
|
|
+ PqSealCache.instance().clear();
|
|
+ assertThat(PqSealCache.instance().restoreFromDisk(n, h, PqSignerRegistry.falconSealSupport()))
|
|
+ .describedAs("control: the genuine rows of round 0 are")
|
|
+ .isEqualTo(3);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aNegativeVerdictFromARegistryNotReadyIsJudgedAgainOnceItIs() throws Exception {
|
|
+ // third review of step 4: "false" from a door that was not ready (registry PENDING, D-358) is "not shown valid",
|
|
+ // never "shown invalid"; genuine seals heard then must count once the registry works
|
|
+ final long n = HR + 50L;
|
|
+ final Hash h = header(n).getHash();
|
|
+ final List<FalconSeal> early = genuine(n, h, 0, 0, 3);
|
|
+ final List<FalconSeal> late = genuine(n, h, 0, 3, 4);
|
|
+ final String genesis = System.getProperty("aere.falcon.genesis");
|
|
+ System.clearProperty("aere.falcon.genesis");
|
|
+ resetFalconSingleton();
|
|
+ final Path data = Files.createDirectories(tmp.resolve("data-pending-registry"));
|
|
+ PqSealCache.instance().enablePersistence(data, CHAIN_ID);
|
|
+ PqSealCache.instance().record(n, h, 0, early);
|
|
+ // the registry comes up
|
|
+ System.setProperty("aere.falcon.genesis", genesis);
|
|
+ resetFalconSingleton();
|
|
+ PqSealCache.instance().record(n, h, 0, late);
|
|
+ PqSealCache.instance().clear();
|
|
+ assertThat(PqSealCache.instance().restoreFromDisk(n, h, PqSignerRegistry.falconSealSupport()))
|
|
+ .describedAs("the three seals heard while the registry was not ready are judged again and written")
|
|
+ .isEqualTo(4);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aGarbageVariantNamedFirstDoesNotWinThePendingSlot() {
|
|
+ // second review of step 4: one slot per (index, author) in the pending store, the variant that verifies first at
|
|
+ // resolution; a byzantine author naming honest index 2 with garbage BEFORE index 2's own late Commit arrives
|
|
+ PqSealCache.instance().judgeWith(PqSealCache::verifiesAsTheProducerDoes);
|
|
+ final long n = HR + 50L;
|
|
+ final Hash h = header(n).getHash();
|
|
+ final Hash digest = Hash.hash(Bytes.of(7, 7, 7));
|
|
+ final org.hyperledger.besu.datatypes.Address byzantine =
|
|
+ org.hyperledger.besu.datatypes.Address.fromHexString("0x" + "0".repeat(38) + "c3");
|
|
+ final org.hyperledger.besu.datatypes.Address honest =
|
|
+ org.hyperledger.besu.datatypes.Address.fromHexString("0x" + "0".repeat(38) + "d4");
|
|
+ PqSealCache.instance().recordPendingRound(n, digest, 2, byzantine, List.of(seal(2, (byte) 0x66)), List.of());
|
|
+ final List<FalconSeal> genuine2 = genuine(n, h, 2, 2, 3);
|
|
+ PqSealCache.instance().recordPendingRound(n, digest, 2, honest, genuine2, List.of());
|
|
+ assertThat(PqSealCache.instance().resolvePending(n, h, r -> r == 2 ? digest : Hash.ZERO)).isEqualTo(1);
|
|
+ assertThat(PqSealCache.instance().sealsFor(n, h, 2))
|
|
+ .singleElement()
|
|
+ .satisfies(s -> assertThat(s.getSignature()).isEqualTo(genuine2.get(0).getSignature()));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aGarbageExtraNamedFirstDoesNotWinThePendingSlotOfItsScheme() throws Exception {
|
|
+ // third review of step 4: the same rule for the extras, per (index, scheme)
|
|
+ final List<SealScheme.GeneratedPair> slh = armHybrid();
|
|
+ PqSealCache.instance().judgeWith(PqSealCache::verifiesAsTheProducerDoes);
|
|
+ final long n = HR + 50L;
|
|
+ final Hash h = header(n).getHash();
|
|
+ final Hash digest = Hash.hash(Bytes.of(8, 8, 8));
|
|
+ final Bytes32 m2 = PqAnchor.commitMessageRound(CHAIN_ID, n, 2, h.getBytes());
|
|
+ final SchemeSeal garbage = new SchemeSeal(SealSchemes.SLH_DSA_128S.wireId(), 2, Bytes.of(1, 2, 3, 4));
|
|
+ final SchemeSeal genuine =
|
|
+ new SchemeSeal(
|
|
+ SealSchemes.SLH_DSA_128S.wireId(),
|
|
+ 2,
|
|
+ Bytes.wrap(SealSchemes.SLH_DSA_128S.sign(slh.get(2).privateKey(), m2.toArray()).orElseThrow()));
|
|
+ PqSealCache.instance()
|
|
+ .recordPendingRound(
|
|
+ n, digest, 2, org.hyperledger.besu.datatypes.Address.fromHexString("0x" + "0".repeat(38) + "c3"), List.of(), List.of(garbage));
|
|
+ PqSealCache.instance()
|
|
+ .recordPendingRound(
|
|
+ n, digest, 2, org.hyperledger.besu.datatypes.Address.fromHexString("0x" + "0".repeat(38) + "d4"), genuine(n, h, 2, 2, 3),
|
|
+ List.of(genuine));
|
|
+ assertThat(PqSealCache.instance().resolvePending(n, h, r -> r == 2 ? digest : Hash.ZERO)).isEqualTo(1);
|
|
+ assertThat(PqSealCache.instance().extrasFor(n, h, 2))
|
|
+ .singleElement()
|
|
+ .satisfies(s -> assertThat(s.getSignature()).isEqualTo(genuine.getSignature()));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aSealstore1FileAtARoundBoundHeightIsIgnoredNeverReadAsRoundZero() throws Exception {
|
|
+ final long n = HR + 50L;
|
|
+ final Hash h = header(n).getHash();
|
|
+ final Path data = Files.createDirectories(tmp.resolve("data1"));
|
|
+ PqSealCache.instance().enablePersistence(data, CHAIN_ID);
|
|
+ final Bytes32 m1 = PqAnchor.commitMessage(CHAIN_ID, n, h.getBytes());
|
|
+ final List<FalconSeal> overCommit1 = new ArrayList<>();
|
|
+ for (int i = 0; i < 4; i++) {
|
|
+ overCommit1.add(new FalconSeal(i, Bytes.wrap(sign(keys.get(i), m1))));
|
|
+ }
|
|
+ PqSealStore.writeAtomically(
|
|
+ PqSealCache.instance().persistenceFile(), PqSealStore.encode(CHAIN_ID, n, h.getBytes(), overCommit1));
|
|
+ final int restored = PqSealCache.instance().restoreFromDisk(n, h, PqSignerRegistry.falconSealSupport());
|
|
+ assertThat(restored).isZero();
|
|
+ assertThat(PqSealCache.instance().roundsFor(n, h)).isEmpty();
|
|
+ // control of the fixture: the same seals ARE restored below H_r, where SEALSTORE-1 is the form
|
|
+ final long below = HR - 50L;
|
|
+ final Hash hb = header(below).getHash();
|
|
+ final Bytes32 mb = PqAnchor.commitMessage(CHAIN_ID, below, hb.getBytes());
|
|
+ final List<FalconSeal> belowSeals = new ArrayList<>();
|
|
+ for (int i = 0; i < 4; i++) {
|
|
+ belowSeals.add(new FalconSeal(i, Bytes.wrap(sign(keys.get(i), mb))));
|
|
+ }
|
|
+ PqSealStore.writeAtomically(
|
|
+ PqSealCache.instance().persistenceFile(), PqSealStore.encode(CHAIN_ID, below, hb.getBytes(), belowSeals));
|
|
+ PqSealCache.instance().clear();
|
|
+ assertThat(PqSealCache.instance().restoreFromDisk(below, hb, PqSignerRegistry.falconSealSupport()))
|
|
+ .describedAs("positive control: a SEALSTORE-1 file below H_r is restored as before")
|
|
+ .isEqualTo(4);
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------ helpers
|
|
+
|
|
+ /** A hybrid-1 registry with the ten Falcon addresses and ten SLH-DSA probe keys; Falcon + SLH-DSA from 0. */
|
|
+ private List<SealScheme.GeneratedPair> armHybrid() throws Exception {
|
|
+ final java.security.SecureRandom random = org.hyperledger.besu.crypto.SecureRandomProvider.createSecureRandom();
|
|
+ final List<SealScheme.GeneratedPair> slh = new ArrayList<>();
|
|
+ final StringBuilder p = new StringBuilder();
|
|
+ p.append("formatVersion=hybrid-1\nchainId=").append(CHAIN_ID).append("\ncount=").append(N).append('\n');
|
|
+ for (int i = 0; i < N; i++) {
|
|
+ slh.add(SealSchemes.SLH_DSA_128S.generate(random));
|
|
+ p.append(i).append(".addr=").append(PqV2Fixture.address(i).toHexString()).append('\n');
|
|
+ p.append(i).append(".key.slh-dsa-sha2-128s=")
|
|
+ .append(Bytes.wrap(slh.get(i).publicRegistryForm()).toHexString()).append('\n');
|
|
+ }
|
|
+ final Path reg = tmp.resolve("hybrid-registry.properties");
|
|
+ Files.writeString(reg, p.toString());
|
|
+ System.setProperty(HybridSealSupport.PROPERTY_SCHEDULE, "0:falcon-512+slh-dsa-sha2-128s");
|
|
+ System.setProperty(HybridSealSupport.PROPERTY_REGISTRY, reg.toAbsolutePath().toString());
|
|
+ HybridSealSupport.resetForTesting();
|
|
+ assertThat(HybridSealSupport.instance().registry()).describedAs("hybrid registry loaded").isPresent();
|
|
+ return slh;
|
|
+ }
|
|
+
|
|
+ private static PqAnchorConfig config() {
|
|
+ return new PqAnchorConfig(
|
|
+ CHAIN_ID, H, Map.of(H, 3), OptionalInt.empty(), false, OptionalInt.empty(), OptionalInt.empty(), V2)
|
|
+ .withCommitRoundBlock(HR);
|
|
+ }
|
|
+
|
|
+ private static BlockHeader header(final long number) {
|
|
+ return new BlockHeaderTestFixture().number(number).buildHeader();
|
|
+ }
|
|
+
|
|
+ private static FalconSeal seal(final int index, final byte fill) {
|
|
+ final byte[] b = new byte[40];
|
|
+ java.util.Arrays.fill(b, fill);
|
|
+ b[0] = 0x29;
|
|
+ b[1] = (byte) index;
|
|
+ return new FalconSeal(index, Bytes.wrap(b));
|
|
+ }
|
|
+
|
|
+ private static List<FalconSeal> seals(final int from, final int to, final byte fill) {
|
|
+ final List<FalconSeal> out = new ArrayList<>();
|
|
+ for (int i = from; i < to; i++) {
|
|
+ out.add(seal(i, fill));
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ /** Genuine seals of indices [from, to) over M_r(n) (COMMIT-2), computed with the primitive, not the code under test. */
|
|
+ private List<FalconSeal> genuine(final long n, final Hash h, final int round, final int from, final int to) {
|
|
+ final Bytes32 m = PqAnchor.commitMessageRound(CHAIN_ID, n, round, h.getBytes());
|
|
+ final List<FalconSeal> out = new ArrayList<>();
|
|
+ for (int i = from; i < to; i++) {
|
|
+ out.add(new FalconSeal(i, Bytes.wrap(sign(keys.get(i), m))));
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ private static byte[] sign(final FalconPrivateKeyParameters key, final Bytes32 m) {
|
|
+ final FalconSigner signer = new FalconSigner();
|
|
+ signer.init(true, key);
|
|
+ return signer.generateSignature(m.toArray());
|
|
+ }
|
|
+
|
|
+ private static void resetFalconSingleton() throws Exception {
|
|
+ final Field f = FalconSealSupport.class.getDeclaredField("instance");
|
|
+ f.setAccessible(true);
|
|
+ f.set(null, null);
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqSealPersistenceTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqSealPersistenceTest.java
|
|
index f0ffc4cab8..b34d70d687 100755
|
|
--- a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqSealPersistenceTest.java
|
|
+++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqSealPersistenceTest.java
|
|
@@ -161,71 +161,71 @@ public class PqSealPersistenceTest {
|
|
final Path genesisPath = tmp.resolve("genesis-registry.json");
|
|
Files.writeString(genesisPath, manifest.toString());
|
|
System.setProperty("aere.falcon.genesis", genesisPath.toAbsolutePath().toString());
|
|
System.setProperty("aere.falcon.attachBlock", Long.toString(ATTACH));
|
|
|
|
resetFalconSingleton();
|
|
PqSealCache.instance().disablePersistence();
|
|
PqSealCache.instance().clear();
|
|
PqAnchorProducer.useConfigForTesting(
|
|
new PqAnchorConfig(CHAIN_ID, H, Map.of(H, 0, K_AT, K), OptionalInt.empty(), false));
|
|
|
|
head = new BlockHeaderTestFixture().number(K_AT + 20L).buildHeader();
|
|
context = contextWith(validators);
|
|
base =
|
|
new BftExtraData(
|
|
Bytes32.ZERO,
|
|
Collections.emptyList(),
|
|
Optional.empty(),
|
|
0,
|
|
validators,
|
|
- Collections.emptyList());
|
|
+ Collections.emptyList(), java.util.List.of(), BftExtraData.NO_CERTIFICATE_ROUND);
|
|
}
|
|
|
|
@AfterEach
|
|
public void tearDown() throws Exception {
|
|
System.clearProperty("aere.falcon.genesis");
|
|
System.clearProperty("aere.falcon.attachBlock");
|
|
PqSealCache.instance().disablePersistence();
|
|
PqSealCache.instance().clear();
|
|
PqAnchorProducer.useConfigForTesting(null);
|
|
resetFalconSingleton();
|
|
}
|
|
|
|
// -------------------------------------------------------------------------------------------
|
|
// 1. The chain death, and its exit, in one method.
|
|
// -------------------------------------------------------------------------------------------
|
|
|
|
@Test
|
|
public void restartWithNoFileIsTheMeasuredDeadlockAndTheFileIsTheWayOut() {
|
|
// Fixture control: without a genuinely armed registry every assertion below would be about
|
|
// nothing at all.
|
|
assertThat(FalconSealSupport.instance().genesisAnchored()).isTrue();
|
|
assertThat(FalconSealSupport.instance().addressBound()).isTrue();
|
|
assertThat(FalconSealSupport.instance().registrySize()).isEqualTo(N);
|
|
|
|
// --- BEFORE THE RESTART. The node is running, persistence is on, and it hears K Commits for
|
|
// its head exactly the way QbftRound.pqCacheHeardSeals feeds them in.
|
|
PqSealCache.instance().enablePersistence(dataDirectory, CHAIN_ID);
|
|
final Path file = PqSealStore.fileIn(dataDirectory);
|
|
for (int i = 0; i < K; i++) {
|
|
- PqSealCache.instance().record(head.getNumber(), head.getHash(), List.of(genuineSeal(i)));
|
|
+ PqSealCache.instance().record(head.getNumber(), head.getHash(), 0, List.of(genuineSeal(i)));
|
|
}
|
|
assertThat(file).exists();
|
|
assertThat(PqSealCache.instance().sealCount(head.getHash())).isEqualTo(K);
|
|
|
|
// --- THE RESTART. A fresh process: the map is gone, the file is not. Nothing else changes.
|
|
PqSealCache.instance().clear();
|
|
assertThat(PqSealCache.instance().sealCount(head.getHash()))
|
|
.describedAs("the in-memory map does not survive a restart, which is the whole problem")
|
|
.isZero();
|
|
|
|
// --- THE DEADLOCK, as measured on the seven-node network. Without the file this is terminal:
|
|
// no proposal means no Commit, and no Commit means no seal, for ever.
|
|
assertThatThrownBy(() -> PqAnchorProducer.apply(base, head, context))
|
|
.describedAs(
|
|
"the measured chain death: a restarted node holds no seals over M(head), so it cannot "
|
|
+ "assemble a certificate and cannot propose")
|
|
.isInstanceOf(PqAnchorNotReadyException.class)
|
|
.hasMessageContaining("Heard 0 seal(s)");
|
|
|
|
// --- THE REPAIR. One read, every seal re-verified, and the same producer on the same inputs
|
|
@@ -293,41 +293,41 @@ public class PqSealPersistenceTest {
|
|
final Path file = PqSealStore.fileIn(dataDirectory);
|
|
PqSealStore.writeAtomically(
|
|
file,
|
|
PqSealStore.encode(CHAIN_ID, head.getNumber(), head.getHash().getBytes(), all));
|
|
assertThat(file).exists();
|
|
|
|
PqSealCache.instance().enablePersistence(dataDirectory, CHAIN_ID);
|
|
final int restored =
|
|
PqSealCache.instance()
|
|
.restoreFromDisk(
|
|
head.getNumber(), head.getHash(), PqSignerRegistry.falconSealSupport());
|
|
|
|
assertThat(restored)
|
|
.describedAs(
|
|
"THE LOAD-BEARING ASSERTION. Six seals were in the file and only the three genuine ones "
|
|
+ "may come out. Delete the verify() call in PqSealStore and this line goes red, "
|
|
+ "which is exactly what the build-time negative control proves.")
|
|
.isEqualTo(3);
|
|
|
|
final List<FalconSeal> inCache =
|
|
- PqSealCache.instance().sealsFor(head.getNumber(), head.getHash());
|
|
+ PqSealCache.instance().sealsFor(head.getNumber(), head.getHash(), 0);
|
|
assertThat(inCache).hasSize(3);
|
|
assertThat(inCache.stream().map(FalconSeal::getValidatorIndex))
|
|
.describedAs("no forged index may reach the cache at all")
|
|
.containsExactly(0, 1, 2);
|
|
assertThat(inCache).containsExactlyInAnyOrderElementsOf(genuine);
|
|
|
|
// And the genuine ones are not merely present, they are usable: the producer, which verifies
|
|
// again at selection, accepts exactly these three. Without this half the test would be
|
|
// satisfied by a reader that rejected everything.
|
|
final BftExtraData produced = PqAnchorProducer.apply(base, head, context);
|
|
assertThat(produced.getFalconSeals()).hasSize(K).containsExactlyElementsOf(genuine);
|
|
}
|
|
|
|
// -------------------------------------------------------------------------------------------
|
|
// 3. A corrupt file must never be able to stop a node.
|
|
// -------------------------------------------------------------------------------------------
|
|
|
|
@Test
|
|
public void aCorruptFileDoesNotStopTheNode() throws Exception {
|
|
final Path file = PqSealStore.fileIn(dataDirectory);
|
|
@@ -504,41 +504,41 @@ public class PqSealPersistenceTest {
|
|
@Test
|
|
public void thePathComesFromTheDataDirectory() {
|
|
assertThat(PqSealStore.fileIn(dataDirectory))
|
|
.isEqualTo(dataDirectory.resolve(PqSealStore.FILE_NAME));
|
|
|
|
PqSealCache.instance().enablePersistence(dataDirectory, CHAIN_ID);
|
|
assertThat(PqSealCache.instance().persistenceFile())
|
|
.isEqualTo(dataDirectory.resolve(PqSealStore.FILE_NAME));
|
|
|
|
final Path other = tmp.resolve("another-node");
|
|
PqSealCache.instance().enablePersistence(other, CHAIN_ID);
|
|
assertThat(PqSealCache.instance().persistenceFile())
|
|
.describedAs("two nodes on one machine never share the file")
|
|
.isEqualTo(other.resolve(PqSealStore.FILE_NAME))
|
|
.isNotEqualTo(dataDirectory.resolve(PqSealStore.FILE_NAME));
|
|
|
|
// A null data directory leaves persistence off rather than inventing a path.
|
|
PqSealCache.instance().disablePersistence();
|
|
PqSealCache.instance().enablePersistence(null, CHAIN_ID);
|
|
assertThat(PqSealCache.instance().persistenceFile()).isNull();
|
|
- PqSealCache.instance().record(head.getNumber(), head.getHash(), List.of(genuineSeal(0)));
|
|
+ PqSealCache.instance().record(head.getNumber(), head.getHash(), 0, List.of(genuineSeal(0)));
|
|
assertThat(PqSealCache.instance().sealCount(head.getHash()))
|
|
.describedAs("with persistence off the cache still works exactly as before")
|
|
.isEqualTo(1);
|
|
}
|
|
|
|
// -------------------------------------------------------------------------------------------
|
|
// 7. The price, as a number.
|
|
// -------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
* The write happens on the consensus thread, once per Commit heard, so its cost is a real
|
|
* property of this change and not a footnote. Seven seals is the whole fleet.
|
|
*/
|
|
@Test
|
|
public void whatOneWriteCostsAgainstTheBlockInterval() throws Exception {
|
|
final Path file = PqSealStore.fileIn(dataDirectory);
|
|
final List<FalconSeal> seals = new ArrayList<>();
|
|
for (int i = 0; i < N; i++) {
|
|
seals.add(genuineSeal(i));
|
|
}
|
|
@@ -613,40 +613,40 @@ public class PqSealPersistenceTest {
|
|
when(bftContext.getValidatorProvider()).thenReturn(validatorProvider);
|
|
when(bftContext.as(any())).thenReturn(bftContext);
|
|
return new ProtocolContext.Builder().withConsensusContext(bftContext).build();
|
|
}
|
|
|
|
private static void resetFalconSingleton() throws Exception {
|
|
final Field f = FalconSealSupport.class.getDeclaredField("instance");
|
|
f.setAccessible(true);
|
|
f.set(null, null);
|
|
}
|
|
|
|
/**
|
|
* D-330 (2026-09-03, testnet 28001): the main file followed the highest height HEARD, which was a
|
|
* proposal that never imported (168032), so after a fleet-wide restart no node held the seals of
|
|
* the head (168031). The previous slot keeps them one height longer.
|
|
*/
|
|
@Test
|
|
public void theSealsOfTheHeadSurviveTheStoreMovingToALaterHeightThatNeverImported() {
|
|
PqSealCache.instance().enablePersistence(dataDirectory, CHAIN_ID);
|
|
for (int i = 0; i < K; i++) {
|
|
- PqSealCache.instance().record(head.getNumber(), head.getHash(), List.of(genuineSeal(i)));
|
|
+ PqSealCache.instance().record(head.getNumber(), head.getHash(), 0, List.of(genuineSeal(i)));
|
|
}
|
|
// the fleet now hears commits for a NEXT block that will never import
|
|
final BlockHeader next = new BlockHeaderTestFixture().number(head.getNumber() + 1L).buildHeader();
|
|
final Bytes32 mNext = PqAnchor.commitMessage(CHAIN_ID, next.getNumber(), next.getHash().getBytes());
|
|
final FalconSigner signer = new FalconSigner();
|
|
signer.init(true, privateKeys.get(0));
|
|
PqSealCache.instance()
|
|
- .record(next.getNumber(), next.getHash(),
|
|
+ .record(next.getNumber(), next.getHash(), 0,
|
|
List.of(new FalconSeal(0, Bytes.wrap(signer.generateSignature(mNext.toArray())))));
|
|
assertThat(PqSealStore.previousFileIn(dataDirectory)).describedAs("the previous slot exists after the rotation").exists();
|
|
// restart: memory gone, the main file holds the never-imported height
|
|
PqSealCache.instance().clear();
|
|
final int restored =
|
|
PqSealCache.instance()
|
|
.restoreFromDisk(head.getNumber(), head.getHash(), PqSignerRegistry.falconSealSupport());
|
|
assertThat(restored).describedAs("the head's seals come back from the previous slot").isEqualTo(K);
|
|
assertThat(PqAnchorProducer.apply(base, head, context).getFalconSeals()).hasSize(K);
|
|
}
|
|
}
|
|
diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqSealWindowPersistenceTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqSealWindowPersistenceTest.java
|
|
index 5c661d32d6..dad4d65e30 100755
|
|
--- a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqSealWindowPersistenceTest.java
|
|
+++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqSealWindowPersistenceTest.java
|
|
@@ -149,115 +149,115 @@ public class PqSealWindowPersistenceTest {
|
|
@AfterEach
|
|
public void tearDown() throws Exception {
|
|
System.clearProperty("aere.falcon.genesis");
|
|
System.clearProperty("aere.falcon.attachBlock");
|
|
System.clearProperty(PqSealWindowStore.PROPERTY_PERSIST);
|
|
PqSealCache.instance().disablePersistence();
|
|
PqSealCache.instance().clear();
|
|
PqAnchorProducer.useConfigForTesting(null);
|
|
resetFalconSingleton();
|
|
}
|
|
|
|
@Test
|
|
public void theWindowSurvivesARestartAndOnlyCanonicalBlocksComeBack() {
|
|
assertThat(FalconSealSupport.instance().genesisAnchored()).isTrue();
|
|
PqSealCache.instance().enablePersistence(dataDirectory, CHAIN_ID);
|
|
|
|
// Ten heights heard live, three genuine seals each. A height reaches the journal when the NEXT
|
|
// one begins, so after hearing HEAD the journal holds HEAD-9 .. HEAD-1 and the head file HEAD.
|
|
for (long n = HEAD - 9L; n <= HEAD; n++) {
|
|
for (int i = 0; i < 3; i++) {
|
|
- PqSealCache.instance().record(n, header(n).getHash(), List.of(genuineSeal(i, header(n))));
|
|
+ PqSealCache.instance().record(n, header(n).getHash(), 0, List.of(genuineSeal(i, header(n))));
|
|
}
|
|
}
|
|
// and one losing proposal at HEAD-4: heard, journaled, NOT canonical
|
|
final BlockHeader loser =
|
|
new BlockHeaderTestFixture().number(HEAD - 4L).extraData(Bytes.of(7, 7, 7)).buildHeader();
|
|
assertThat(loser.getHash()).isNotEqualTo(header(HEAD - 4L).getHash());
|
|
|
|
final Path journal = PqSealWindowStore.directoryIn(dataDirectory);
|
|
assertThat(journal).isDirectory();
|
|
assertThat(PqSealWindowStore.frameCount(journal, CHAIN_ID)).isEqualTo(9);
|
|
appendUnchecked(journal, loser, List.of(genuineSeal(0, loser)));
|
|
|
|
// THE RESTART: the in-memory window is gone
|
|
PqSealCache.instance().clear();
|
|
assertThat(PqSealCache.instance().sealCount(header(HEAD - 5L).getHash())).isZero();
|
|
|
|
// this node's chain holds every height except HEAD-7 (the negative: a height it cannot vouch for)
|
|
final LongFunction<Optional<Hash>> canonical =
|
|
n -> n == HEAD - 7L ? Optional.empty() : Optional.of(header(n).getHash());
|
|
final int restored =
|
|
PqSealCache.instance()
|
|
.restoreWindowFromDisk(HEAD, canonical, PqSignerRegistry.falconSealSupport());
|
|
|
|
assertThat(restored)
|
|
.describedAs("nine journaled heights, minus the one the chain does not hold, three seals each")
|
|
.isEqualTo(8 * 3);
|
|
for (long n = HEAD - 9L; n < HEAD; n++) {
|
|
assertThat(PqSealCache.instance().sealCount(header(n).getHash()))
|
|
.describedAs("height %d", n)
|
|
.isEqualTo(n == HEAD - 7L ? 0 : 3);
|
|
}
|
|
assertThat(PqSealCache.instance().sealCount(loser.getHash()))
|
|
.describedAs("a frame for a hash that is not canonical at its height never comes back")
|
|
.isZero();
|
|
- assertThat(PqSealCache.instance().sealsFor(HEAD - 2L, header(HEAD - 2L).getHash()))
|
|
+ assertThat(PqSealCache.instance().sealsFor(HEAD - 2L, header(HEAD - 2L).getHash(), 0))
|
|
.extracting(FalconSeal::getValidatorIndex)
|
|
.containsExactly(0, 1, 2);
|
|
}
|
|
|
|
@Test
|
|
public void aForgedSealInTheJournalNeverEntersTheWindow() throws Exception {
|
|
final BlockHeader block = header(HEAD - 3L);
|
|
final FalconSeal genuine0 = genuineSeal(0, block);
|
|
final FalconSeal genuine1 = genuineSeal(1, block);
|
|
final Bytes32 anotherBlocksMessage =
|
|
PqAnchor.commitMessage(CHAIN_ID, block.getNumber() - 1L, Bytes32.leftPad(Bytes.of(9)));
|
|
final byte[] randomBytes = new byte[genuine0.getSignature().size()];
|
|
SecureRandomProvider.createSecureRandom().nextBytes(randomBytes);
|
|
final List<FalconSeal> all =
|
|
List.of(
|
|
genuine0,
|
|
genuine1,
|
|
new FalconSeal(2, Bytes.wrap(falconSign(privateKeys.get(2), anotherBlocksMessage))),
|
|
new FalconSeal(3, Bytes.wrap(randomBytes)),
|
|
new FalconSeal(4, genuine0.getSignature()));
|
|
final Path journal = PqSealWindowStore.directoryIn(dataDirectory);
|
|
PqSealWindowStore.append(
|
|
journal, CHAIN_ID, PqSealWindowStore.heard(block.getNumber(), block.getHash().getBytes(), all));
|
|
|
|
PqSealCache.instance().enablePersistence(dataDirectory, CHAIN_ID);
|
|
final int restored =
|
|
PqSealCache.instance()
|
|
.restoreWindowFromDisk(
|
|
HEAD, n -> Optional.of(header(n).getHash()), PqSignerRegistry.falconSealSupport());
|
|
|
|
assertThat(restored)
|
|
.describedAs(
|
|
"THE LOAD-BEARING ASSERTION. Five seals were in the frame and only the two genuine ones "
|
|
+ "may come out: a signature over another block's message, random bytes and a "
|
|
+ "genuine seal re-labelled under another index all die at the verifier. Take the "
|
|
+ "verifier out of restoreWindowFromDisk and this line goes red, which is what the "
|
|
+ "build-time negative control proves.")
|
|
.isEqualTo(2);
|
|
- assertThat(PqSealCache.instance().sealsFor(block.getNumber(), block.getHash()))
|
|
+ assertThat(PqSealCache.instance().sealsFor(block.getNumber(), block.getHash(), 0))
|
|
.extracting(FalconSeal::getValidatorIndex)
|
|
.containsExactly(0, 1);
|
|
}
|
|
|
|
@Test
|
|
public void aTornTailOrAFlippedByteCostsOnlyWhatFollowsIt() throws Exception {
|
|
final Path journal = PqSealWindowStore.directoryIn(dataDirectory);
|
|
// five heights in ONE segment (64 heights per segment; HEAD-5 .. HEAD-1 share 4992/64 = 78)
|
|
for (long n = HEAD - 5L; n < HEAD; n++) {
|
|
PqSealWindowStore.append(
|
|
journal,
|
|
CHAIN_ID,
|
|
PqSealWindowStore.heard(n, header(n).getHash().getBytes(), List.of(genuineSeal(0, header(n)))));
|
|
}
|
|
final Path segment = PqSealWindowStore.segmentFor(journal, HEAD - 1L);
|
|
assertThat(PqSealWindowStore.segmentFor(journal, HEAD - 5L)).isEqualTo(segment);
|
|
final byte[] whole = Files.readAllBytes(segment);
|
|
PqSealCache.instance().enablePersistence(dataDirectory, CHAIN_ID);
|
|
|
|
// positive control first: the undamaged journal gives all five
|
|
@@ -306,103 +306,103 @@ public class PqSealWindowPersistenceTest {
|
|
PqSealCache.instance().enablePersistence(dataDirectory, CHAIN_ID);
|
|
assertThat(restoreAll())
|
|
.describedAs("another chain's frame and a height below the window: neither comes back")
|
|
.isZero();
|
|
// positive pair: the same height, this chain
|
|
PqSealWindowStore.append(
|
|
journal,
|
|
CHAIN_ID,
|
|
PqSealWindowStore.heard(
|
|
inWindow.getNumber(), inWindow.getHash().getBytes(), List.of(genuineSeal(0, inWindow))));
|
|
assertThat(restoreAll()).isEqualTo(1);
|
|
}
|
|
|
|
@Test
|
|
public void oldSegmentsAreDeletedSoTheFootprintStaysBounded() throws Exception {
|
|
PqSealCache.instance().enablePersistence(dataDirectory, CHAIN_ID);
|
|
final long window = PqSealCache.instance().retentionBlocks();
|
|
final long heights = window + 5L * PqSealWindowStore.SEGMENT_BLOCKS;
|
|
final FalconSeal one = new FalconSeal(0, Bytes.wrap(new byte[650]));
|
|
for (long n = HEAD; n < HEAD + heights; n++) {
|
|
- PqSealCache.instance().record(n, Hash.hash(Bytes.ofUnsignedLong(n)), List.of(one));
|
|
+ PqSealCache.instance().record(n, Hash.hash(Bytes.ofUnsignedLong(n)), 0, List.of(one));
|
|
}
|
|
final Path journal = PqSealWindowStore.directoryIn(dataDirectory);
|
|
final long highest = HEAD + heights - 1L;
|
|
try (Stream<Path> files = Files.list(journal)) {
|
|
final List<Path> segments = files.toList();
|
|
assertThat(segments.size())
|
|
.describedAs("segments kept: the window plus the one being written plus one of slack")
|
|
.isLessThanOrEqualTo((int) (window / PqSealWindowStore.SEGMENT_BLOCKS) + 2);
|
|
assertThat(segments)
|
|
.describedAs("no segment wholly below the window is left behind")
|
|
.doesNotContain(PqSealWindowStore.segmentFor(journal, highest - window - 2L * PqSealWindowStore.SEGMENT_BLOCKS));
|
|
assertThat(segments).contains(PqSealWindowStore.segmentFor(journal, highest - 1L));
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void theJournalIsOffWhenPersistenceIsOffOrThePropertySaysSo() throws Exception {
|
|
final Path journal = PqSealWindowStore.directoryIn(dataDirectory);
|
|
// persistence never enabled: memory only, exactly as before this class existed
|
|
for (long n = HEAD; n < HEAD + 3L; n++) {
|
|
- PqSealCache.instance().record(n, header(n).getHash(), List.of(genuineSeal(0, header(n))));
|
|
+ PqSealCache.instance().record(n, header(n).getHash(), 0, List.of(genuineSeal(0, header(n))));
|
|
}
|
|
assertThat(journal).doesNotExist();
|
|
|
|
// the operator's switch
|
|
System.setProperty(PqSealWindowStore.PROPERTY_PERSIST, "false");
|
|
PqSealCache.instance().enablePersistence(dataDirectory, CHAIN_ID);
|
|
for (long n = HEAD + 3L; n < HEAD + 6L; n++) {
|
|
- PqSealCache.instance().record(n, header(n).getHash(), List.of(genuineSeal(0, header(n))));
|
|
+ PqSealCache.instance().record(n, header(n).getHash(), 0, List.of(genuineSeal(0, header(n))));
|
|
}
|
|
assertThat(journal).doesNotExist();
|
|
assertThat(PqSealStore.fileIn(dataDirectory))
|
|
.describedAs("the head file, which liveness depends on, is NOT governed by this switch")
|
|
.exists();
|
|
|
|
// positive pair: the switch back on
|
|
System.clearProperty(PqSealWindowStore.PROPERTY_PERSIST);
|
|
PqSealCache.instance().enablePersistence(dataDirectory, CHAIN_ID);
|
|
for (long n = HEAD + 6L; n < HEAD + 9L; n++) {
|
|
- PqSealCache.instance().record(n, header(n).getHash(), List.of(genuineSeal(0, header(n))));
|
|
+ PqSealCache.instance().record(n, header(n).getHash(), 0, List.of(genuineSeal(0, header(n))));
|
|
}
|
|
assertThat(journal).isDirectory();
|
|
assertThat(PqSealWindowStore.frameCount(journal, CHAIN_ID)).isGreaterThanOrEqualTo(2);
|
|
}
|
|
|
|
@Test
|
|
public void aRestoredWindowIsNotAppendedASecondTime() {
|
|
PqSealCache.instance().enablePersistence(dataDirectory, CHAIN_ID);
|
|
for (long n = HEAD - 4L; n <= HEAD; n++) {
|
|
- PqSealCache.instance().record(n, header(n).getHash(), List.of(genuineSeal(0, header(n))));
|
|
+ PqSealCache.instance().record(n, header(n).getHash(), 0, List.of(genuineSeal(0, header(n))));
|
|
}
|
|
final Path journal = PqSealWindowStore.directoryIn(dataDirectory);
|
|
assertThat(PqSealWindowStore.frameCount(journal, CHAIN_ID)).isEqualTo(4);
|
|
|
|
PqSealCache.instance().clear();
|
|
PqSealCache.instance()
|
|
.restoreFromDisk(HEAD, header(HEAD).getHash(), PqSignerRegistry.falconSealSupport());
|
|
assertThat(restoreAll()).isEqualTo(4);
|
|
|
|
// the chain moves on: exactly ONE new frame (the head, which was only in the head file)
|
|
PqSealCache.instance()
|
|
- .record(HEAD + 1L, header(HEAD + 1L).getHash(), List.of(genuineSeal(0, header(HEAD + 1L))));
|
|
+ .record(HEAD + 1L, header(HEAD + 1L).getHash(), 0, List.of(genuineSeal(0, header(HEAD + 1L))));
|
|
assertThat(PqSealWindowStore.frameCount(journal, CHAIN_ID))
|
|
.describedAs("four restored heights are not written again; the head is written once")
|
|
.isEqualTo(5);
|
|
}
|
|
|
|
@Test
|
|
public void whatOneAppendCostsAgainstTheBlockInterval() throws Exception {
|
|
final Path journal = PqSealWindowStore.directoryIn(dataDirectory);
|
|
final List<FalconSeal> ten = new ArrayList<>();
|
|
for (int i = 0; i < 10; i++) {
|
|
ten.add(new FalconSeal(i, Bytes.wrap(new byte[660])));
|
|
}
|
|
final int rounds = 200;
|
|
final long t0 = System.nanoTime();
|
|
for (int r = 0; r < rounds; r++) {
|
|
PqSealWindowStore.append(
|
|
journal, CHAIN_ID, PqSealWindowStore.heard(HEAD + r, Bytes32.leftPad(Bytes.of(r)), ten));
|
|
}
|
|
final double meanMs = (System.nanoTime() - t0) / 1_000_000.0 / rounds;
|
|
System.out.printf(
|
|
diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqSealWindowRoundTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqSealWindowRoundTest.java
|
|
new file mode 100644
|
|
index 0000000000..4f6426e2dd
|
|
--- /dev/null
|
|
+++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqSealWindowRoundTest.java
|
|
@@ -0,0 +1,204 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.common.bft;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+
|
|
+import java.lang.reflect.Field;
|
|
+import java.nio.file.Files;
|
|
+import java.nio.file.Path;
|
|
+import java.util.ArrayList;
|
|
+import java.util.HashMap;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+import java.util.function.LongFunction;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.bouncycastle.crypto.digests.KeccakDigest;
|
|
+import org.bouncycastle.pqc.crypto.falcon.FalconPrivateKeyParameters;
|
|
+import org.bouncycastle.pqc.crypto.falcon.FalconSigner;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.junit.jupiter.api.io.TempDir;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), D-470, pasul 4 (2026-10-01): the AIP-21 window journal from H_r - 1 (project section 3.1 G, SEALWINDOW-2), on
|
|
+ * the fixture of {@link PqSealWindowPersistenceTest} (genesis registry bound the way a live node binds it, so the history
|
|
+ * door answers). A round-bound height is journaled as one frame per (n, r, hash) and comes back under its round after a
|
|
+ * restart, each seal re-verified over M_r; a SEALWINDOW-1 frame at a round-bound height is dropped (never read as round
|
|
+ * 0), while below H_r the SEALWINDOW-1 frame is restored as before (L1).
|
|
+ */
|
|
+public class PqSealWindowRoundTest {
|
|
+
|
|
+ private static final long H = 1_000L;
|
|
+ private static final long ATTACH = 900L;
|
|
+ private static final int N = 7;
|
|
+ private static final long CHAIN_ID = 220_889L;
|
|
+ private static final long V2 = 1_005L;
|
|
+ // inside the restored window (the last 256 heights below HEAD), so both sides of H_r are read back
|
|
+ private static final long HR = 4_900L;
|
|
+ private static final long HEAD = 5_000L;
|
|
+
|
|
+ @TempDir private Path tmp;
|
|
+
|
|
+ private Path dataDirectory;
|
|
+ private final List<FalconPrivateKeyParameters> privateKeys = new ArrayList<>();
|
|
+ private final Map<Long, BlockHeader> chain = new HashMap<>();
|
|
+
|
|
+ @BeforeEach
|
|
+ public void setUp() throws Exception {
|
|
+ dataDirectory = Files.createDirectories(tmp.resolve("besu-data"));
|
|
+ final KeccakDigest kd = new KeccakDigest(256);
|
|
+ final StringBuilder manifest =
|
|
+ new StringBuilder("{\"config\":{\"aereFalconRegistry\":{").append(PqV2Fixture.manifestHeader(N, CHAIN_ID, H));
|
|
+ for (int i = 0; i < N; i++) {
|
|
+ privateKeys.add(PqV2Fixture.privateKey(i));
|
|
+ final byte[] anchoredRow = PqV2Fixture.anchorPreimageRow(i);
|
|
+ kd.update(anchoredRow, 0, anchoredRow.length);
|
|
+ manifest.append(',').append(PqV2Fixture.manifestEntry(i, N, CHAIN_ID, H));
|
|
+ }
|
|
+ final byte[] anchoredHash = new byte[32];
|
|
+ kd.doFinal(anchoredHash, 0);
|
|
+ manifest
|
|
+ .append("}},\"alloc\":{\"0000000000000000000000000000000000000fa1\":{\"storage\":{\"0x")
|
|
+ .append("0".repeat(64))
|
|
+ .append("\":\"0x")
|
|
+ .append(Bytes.wrap(anchoredHash).toUnprefixedHexString())
|
|
+ .append("\"}}}}");
|
|
+ final Path genesisPath = tmp.resolve("genesis-registry.json");
|
|
+ Files.writeString(genesisPath, manifest.toString());
|
|
+ System.setProperty("aere.falcon.genesis", genesisPath.toAbsolutePath().toString());
|
|
+ System.setProperty("aere.falcon.attachBlock", Long.toString(ATTACH));
|
|
+ System.clearProperty(PqSealWindowStore.PROPERTY_PERSIST);
|
|
+ resetFalconSingleton();
|
|
+ final PqRegistryHash.Registry held = PqRegistryHash.loadAuto(genesisPath);
|
|
+ String hash = PqRegistryHash.hashFor(held, CHAIN_ID);
|
|
+ if (!hash.startsWith("0x")) {
|
|
+ hash = "0x" + hash;
|
|
+ }
|
|
+ final Path schedule = tmp.resolve("genesis-schedule.json");
|
|
+ Files.writeString(schedule, "{\"config\":{\"pqRegistryHash\":[{\"block\":" + H + ",\"hash\":\"" + hash + "\"}]}}");
|
|
+ FalconSealSupport.instance()
|
|
+ .verifyRegistryBindingOrAbort(0L, CHAIN_ID, PqRegistryHash.loadScheduleFromGenesis(schedule));
|
|
+ PqSealCache.instance().disablePersistence();
|
|
+ PqSealCache.instance().clear();
|
|
+ PqAnchorProducer.useConfigForTesting(
|
|
+ new PqAnchorConfig(CHAIN_ID, H, Map.of(H, 0, H + 10L, 3), OptionalInt.empty(), false)
|
|
+ .withAnchorV2Block(V2)
|
|
+ .withCommitRoundBlock(HR));
|
|
+ chain.clear();
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ public void tearDown() throws Exception {
|
|
+ PqSealCache.instance().disablePersistence();
|
|
+ PqSealCache.instance().clear();
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ System.clearProperty("aere.falcon.genesis");
|
|
+ System.clearProperty("aere.falcon.attachBlock");
|
|
+ resetFalconSingleton();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aRoundBoundHeightIsJournaledPerRoundAndComesBackUnderItsRound() {
|
|
+ PqSealCache.instance().enablePersistence(dataDirectory, CHAIN_ID);
|
|
+ final BlockHeader block = header(HEAD - 3L);
|
|
+ PqSealCache.instance().record(block.getNumber(), block.getHash(), 2, roundSeals(block, 2, 0, 3));
|
|
+ PqSealCache.instance().record(block.getNumber(), block.getHash(), 0, roundSeals(block, 0, 3, 5));
|
|
+ // a new height begins: the heights below it go to the journal
|
|
+ final BlockHeader next = header(HEAD - 2L);
|
|
+ PqSealCache.instance().record(next.getNumber(), next.getHash(), 0, roundSeals(next, 0, 0, 1));
|
|
+ PqSealCache.instance().clear();
|
|
+ final LongFunction<Optional<Hash>> canonical = n -> Optional.of(header(n).getHash());
|
|
+ final int restored =
|
|
+ PqSealCache.instance().restoreWindowFromDisk(next.getNumber(), canonical, PqSignerRegistry.falconSealSupport());
|
|
+ assertThat(restored).as("3 seals of round 2 and 2 of round 0, each re-verified over its own M_r").isEqualTo(5);
|
|
+ final java.util.NavigableMap<Integer, PqSealCache.RoundSeals> rounds =
|
|
+ PqSealCache.instance().roundsFor(block.getNumber(), block.getHash());
|
|
+ assertThat(rounds.keySet()).containsExactly(0, 2);
|
|
+ assertThat(rounds.get(2).falcon()).extracting(FalconSeal::getValidatorIndex).containsExactly(0, 1, 2);
|
|
+ assertThat(rounds.get(0).falcon()).extracting(FalconSeal::getValidatorIndex).containsExactly(3, 4);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aFormOneFrameAtARoundBoundHeightIsDroppedButBelowHrItComesBack() throws Exception {
|
|
+ PqSealCache.instance().enablePersistence(dataDirectory, CHAIN_ID);
|
|
+ final Path journal = PqSealWindowStore.directoryIn(dataDirectory);
|
|
+ Files.createDirectories(journal);
|
|
+ final BlockHeader roundBound = header(HEAD - 3L);
|
|
+ final BlockHeader below = header(HR - 100L);
|
|
+ PqSealWindowStore.append(
|
|
+ journal, CHAIN_ID, PqSealWindowStore.heard(below.getNumber(), below.getHash().getBytes(), commit1Seals(below)));
|
|
+ PqSealWindowStore.append(
|
|
+ journal,
|
|
+ CHAIN_ID,
|
|
+ PqSealWindowStore.heard(roundBound.getNumber(), roundBound.getHash().getBytes(), commit1Seals(roundBound)));
|
|
+ PqSealCache.instance().clear();
|
|
+ final LongFunction<Optional<Hash>> canonical = n -> Optional.of(header(n).getHash());
|
|
+ PqSealCache.instance().restoreWindowFromDisk(HEAD - 1L, canonical, PqSignerRegistry.falconSealSupport());
|
|
+ assertThat(PqSealCache.instance().roundsFor(roundBound.getNumber(), roundBound.getHash()))
|
|
+ .as("a SEALWINDOW-1 frame at a round-bound height is dropped, never read as round 0")
|
|
+ .isEmpty();
|
|
+ assertThat(PqSealCache.instance().sealsFor(below.getNumber(), below.getHash(), 0))
|
|
+ .as("positive control: below H_r the SEALWINDOW-1 frame comes back, as before")
|
|
+ .hasSize(3);
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------------------------------
|
|
+
|
|
+ private BlockHeader header(final long number) {
|
|
+ return chain.computeIfAbsent(number, n -> new BlockHeaderTestFixture().number(n).buildHeader());
|
|
+ }
|
|
+
|
|
+ /** Genuine seals of indices [from, to) over M_r (COMMIT-2, from the primitive, not the code under test). */
|
|
+ private List<FalconSeal> roundSeals(final BlockHeader block, final int round, final int from, final int to) {
|
|
+ final Bytes32 m = PqAnchor.commitMessageRound(CHAIN_ID, block.getNumber(), round, block.getHash().getBytes());
|
|
+ final List<FalconSeal> out = new ArrayList<>();
|
|
+ for (int i = from; i < to; i++) {
|
|
+ out.add(new FalconSeal(i, Bytes.wrap(falconSign(privateKeys.get(i), m))));
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ private List<FalconSeal> commit1Seals(final BlockHeader block) {
|
|
+ final Bytes32 m = PqAnchor.commitMessage(CHAIN_ID, block.getNumber(), block.getHash().getBytes());
|
|
+ final List<FalconSeal> out = new ArrayList<>();
|
|
+ for (int i = 0; i < 3; i++) {
|
|
+ out.add(new FalconSeal(i, Bytes.wrap(falconSign(privateKeys.get(i), m))));
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ private static byte[] falconSign(final FalconPrivateKeyParameters key, final Bytes32 m) {
|
|
+ final FalconSigner signer = new FalconSigner();
|
|
+ signer.init(true, key);
|
|
+ return signer.generateSignature(m.toArray());
|
|
+ }
|
|
+
|
|
+ private static void resetFalconSingleton() throws Exception {
|
|
+ final Field f = FalconSealSupport.class.getDeclaredField("instance");
|
|
+ f.setAccessible(true);
|
|
+ f.set(null, null);
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/common/src/test/resources/aere-r1b/VECTORI-R1B.json b/consensus/common/src/test/resources/aere-r1b/VECTORI-R1B.json
|
|
new file mode 100644
|
|
index 0000000000..8516345029
|
|
--- /dev/null
|
|
+++ b/consensus/common/src/test/resources/aere-r1b/VECTORI-R1B.json
|
|
@@ -0,0 +1,1647 @@
|
|
+{
|
|
+ "schema": "aere-r1b-vectori-1",
|
|
+ "spec": "D-470 / 1(b): the round-bound commit seal (AERE-PQ-COMMIT-2), the v3 anchor certificate (AERE-PQ-ANCHOR-3), the per-round seal store and window frames. Common vectors for both clients; classes that need real headers (VR, VSET, VDEC, VL) are added from the rehearsal.",
|
|
+ "generator": "aips/aip22-conformitate/r1b/construieste-vectori-r1b.mjs: hand-written RLP, keccak from @noble/hashes, Falcon-512 and SLH-DSA-SHA2-128s from @noble/post-quantum 0.7.1; every Falcon signature also verified by the public verifier's falcon512.mjs. Keys are SYNTHETIC (AERE-SINTETIC), deterministic from named seeds; Falcon signing is deterministic; a rerun writes the same bytes.",
|
|
+ "constants": {
|
|
+ "MAX_ROUND": 1024,
|
|
+ "MAX_SEALS": 64,
|
|
+ "domains": {
|
|
+ "C1": "AERE-PQ-COMMIT-1",
|
|
+ "C2": "AERE-PQ-COMMIT-2",
|
|
+ "P1": "AERE-PQ-PREPARE-1",
|
|
+ "A2": "AERE-PQ-ANCHOR-2",
|
|
+ "A3": "AERE-PQ-ANCHOR-3",
|
|
+ "ST1": "AERE-PQ-SEALSTORE-1",
|
|
+ "ST2": "AERE-PQ-SEALSTORE-2",
|
|
+ "W1": "AERE-PQ-SEALWINDOW-1",
|
|
+ "W2": "AERE-PQ-SEALWINDOW-2"
|
|
+ },
|
|
+ "schemes": {
|
|
+ "falcon-512": 1,
|
|
+ "slh-dsa-sha2-128s": 2
|
|
+ },
|
|
+ "codes": [
|
|
+ "AERE-PQ-V3-01",
|
|
+ "AERE-PQ-V3-02",
|
|
+ "AERE-PQ-V3-03",
|
|
+ "AERE-PQ-V3-04",
|
|
+ "AERE-PQ-V3-05",
|
|
+ "AERE-PQ-V3-06",
|
|
+ "AERE-PQ-V3-07",
|
|
+ "AERE-PQ-V3-08",
|
|
+ "AERE-PQ-COMMIT-R-01",
|
|
+ "AERE-PQ-COMMIT-R-02",
|
|
+ "AERE-PQ-COMMIT-R-03"
|
|
+ ]
|
|
+ },
|
|
+ "keys": [
|
|
+ {
|
|
+ "index": 0,
|
|
+ "marker": "AERE-SINTETIC",
|
|
+ "address": "0x1e8630cbd37b6f3c1b9ccf77380a25b68e27eb3d",
|
|
+ "falcon-512": {
|
|
+ "publicKeyFull": "0x09907e5eaaae1b77934d09772120320f641bd78d5ad5847d623be3ec273b5af0b41f281a1ae0e8c5b6862748b5d73a6301e8102895e40487e2762e2000656c8a846dec068211093db2315396a71f111667b3a85ba24eb5c274522ead7da017c05dcc747cc46155adcfc54e40f4e7718d08a7ba4050969f4587009eb44c92891392acea1156612aede47373ce048a6ab8bb4a9d469caa482396900d671546bb2d1910b73c3d36c8a312975401d8676ea1216e3fa787685d36a573a2189bd4a5de2b839950f812e24ae21f809c9775c8b624ccc042d672d2b81dae3a85f917bda3a6a2ad0296a1c9aa29444cb69f9e516d9626e90684b93a805243b76a5b746c8a92fd6ee26f718e9091eff976c6b9a6ff0525197095a7e029003e429b67e1d5ee348a3f775262919314da93e5135576d5a251bed8f80810622733662e868a7c9bbec404866c5e75aee66c9b243ef7745a4a0b32a4111189752538bc53f0cfcaa59e8cea3f1c421f9ae26bc299eb54450ad47a5d9940001ca0115bfd563ecea043dac77c9c542144d1b2bce1c48084e9293b566ae08a435eb8dce3f4b4eff4604d7a09f1e4f5349a6c10b55051810d5b24f1a3af865001c57b4b642ecaeb393300a763fca17345efeb64dd66f9a36a0eb2c42d4155dce21feacdc74dcc27a0cc76e91e85b50a88aeb79a463ba18282e1950fbf68d52256086ed3024506867f6ffa0aadc40afc640c526d3ea52604e174c0a860791c92541547c40d274466191db5020631befc8cc0ae8ae38d192f86a08b16372c86eba88eb79fd19ea4d4871f19f8e6e67fd8077101a557dc15a393c48b798fd4166b11f8c9a04522953c32c98e9a8577fe06521c00e9a5d03221c9a57a9742f8cac583cab2548550d70e79705c5980cb957664f5f135ab029531e25169411a663d2acde6daddca64c2ec584198925262ba113bdb33728010b9efcb7636c9390a4b07580e8620215d662b2aa9f6b0fcc879a0b921476980f3703cc552e967e40721e58bd42caa5535aac8572327be5a0157a0827c47844bb51edea5185033d5aa026a942e15f93421f4a4b2224991e51065418cfbb3e2beb9a8ed82da60cf48e144161fa3ba4d915ca10ba1366c20ba3033c8b362850416d242ad2e1ec9061f62c5567d3fb7f16b092628579a3c2cbd342c604521ea334eb285ab4798a0bca8b645c9d73c5f5d4081332fc374a0c8f0b75f39631c6b25561d2c163ed082052d1fa55472b65c5f7d34252bbb09c034",
|
|
+ "publicKeyRegistry": "0x907e5eaaae1b77934d09772120320f641bd78d5ad5847d623be3ec273b5af0b41f281a1ae0e8c5b6862748b5d73a6301e8102895e40487e2762e2000656c8a846dec068211093db2315396a71f111667b3a85ba24eb5c274522ead7da017c05dcc747cc46155adcfc54e40f4e7718d08a7ba4050969f4587009eb44c92891392acea1156612aede47373ce048a6ab8bb4a9d469caa482396900d671546bb2d1910b73c3d36c8a312975401d8676ea1216e3fa787685d36a573a2189bd4a5de2b839950f812e24ae21f809c9775c8b624ccc042d672d2b81dae3a85f917bda3a6a2ad0296a1c9aa29444cb69f9e516d9626e90684b93a805243b76a5b746c8a92fd6ee26f718e9091eff976c6b9a6ff0525197095a7e029003e429b67e1d5ee348a3f775262919314da93e5135576d5a251bed8f80810622733662e868a7c9bbec404866c5e75aee66c9b243ef7745a4a0b32a4111189752538bc53f0cfcaa59e8cea3f1c421f9ae26bc299eb54450ad47a5d9940001ca0115bfd563ecea043dac77c9c542144d1b2bce1c48084e9293b566ae08a435eb8dce3f4b4eff4604d7a09f1e4f5349a6c10b55051810d5b24f1a3af865001c57b4b642ecaeb393300a763fca17345efeb64dd66f9a36a0eb2c42d4155dce21feacdc74dcc27a0cc76e91e85b50a88aeb79a463ba18282e1950fbf68d52256086ed3024506867f6ffa0aadc40afc640c526d3ea52604e174c0a860791c92541547c40d274466191db5020631befc8cc0ae8ae38d192f86a08b16372c86eba88eb79fd19ea4d4871f19f8e6e67fd8077101a557dc15a393c48b798fd4166b11f8c9a04522953c32c98e9a8577fe06521c00e9a5d03221c9a57a9742f8cac583cab2548550d70e79705c5980cb957664f5f135ab029531e25169411a663d2acde6daddca64c2ec584198925262ba113bdb33728010b9efcb7636c9390a4b07580e8620215d662b2aa9f6b0fcc879a0b921476980f3703cc552e967e40721e58bd42caa5535aac8572327be5a0157a0827c47844bb51edea5185033d5aa026a942e15f93421f4a4b2224991e51065418cfbb3e2beb9a8ed82da60cf48e144161fa3ba4d915ca10ba1366c20ba3033c8b362850416d242ad2e1ec9061f62c5567d3fb7f16b092628579a3c2cbd342c604521ea334eb285ab4798a0bca8b645c9d73c5f5d4081332fc374a0c8f0b75f39631c6b25561d2c163ed082052d1fa55472b65c5f7d34252bbb09c034"
|
|
+ },
|
|
+ "slh-dsa-sha2-128s": {
|
|
+ "publicKey": "0x47f965d096ad83f700a93901371f03d4a5e87601fbcca4e1dd05bdec4ea65e3e"
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "index": 1,
|
|
+ "marker": "AERE-SINTETIC",
|
|
+ "address": "0x92253d235aae6fce64524698594062a74e32e604",
|
|
+ "falcon-512": {
|
|
+ "publicKeyFull": "0x09957e196011a27e4a6576b6f2df8679d48125c7aa6e5aacbac9210eda50959ed4725a473bb2d8618283943bad1821af641abe7887e5fe9983aae564d425ed0021ae95a90997a78872a77a025e812c2eb1f9070a6b9ec6f0745e1293a1bcf47a249fce1592c0b415873f5901ad45d7afa9015dfb79d717419b1af8f5cd4067921d62a6ee482f40987a70aa2a0c49c50717e05998a1d560bb03c6cc53f195563d9fea8d2826ab764baf5a1aa7d97fea4a3ac9db561dee6b4f3e51417810c22918fb8198aa8746cef7c2eaa5ec8a3ecc91bf0ab666b4e7849445a5ab6c35bb025509442cccb7c560971f1c490998a6e6a71197f64d231eafa487772426e60e409572d4c529ad8ca6ab3a90401ee9e5b47e4f3e2b68563166871abe6cdb37afe87749d4d25833a21d7e70cb08fb128e4a393c72e2c1d32da09328abcb3aa6b5a5cbae12f67558519547494a95f17b048dc0d76a5d571283630a3aa61b501c161a2a66a0e714dcf70d646d118584fda2e6c553bd042f1256bde2455107b01ae2faaee9eb18d08152ce028126b1e514d7145689c51d81b080785e85e7e17d8ab1ab4d788653d70d6432692ab72ce8a5ed1121f8563a4345af28556242028612f047979e3a129c4681eb4f1a65d03bd2aaff4df5bc8abc2f7130ba67b3db280f11da3672962fdd78125d5160d10603d566b13b239a2a52f2754f47e0a6012e56ead07e9f85a006e8933a6c6965c374dccb50d0fed745470850ec6ba19d5b7838b15f03af1566501522f003c3edbc16576172c3c3ab6500485108039d6271b6911e58bd9d3dbbb78e3a91a95c9252954c7cdae843a784849fbded6b6250ab7b528a3041940343a4b8477c88595d4a41a7f31b8220dee7cb4000022c469b13efd19e271a56f9ad51b215164fe7d9d11291acd7255a2ba5029a9490d9999a1caaa36082616b73a0288889cc00bbc6b61128dcdd77e411524a2adb22f0e0d0d1e85413a80c63640c8b2b090b0bebca763fa218b07e86e31aa5be9a95c1811310fa7b0890e5b47ac4127947f89189f6d7cc5a317101ec213ee7e508fd5fc121e6571aa40929978f900380b3593fd83e4da9a64455c03f9658b2e7ff8e081d76e9f3099d7b725653c3ae6881aedc61024107967e09c542721f45a4300e95a7255f6db159e933670f9c84487a042334355a251410ae9156b92b104b8aab929864d77ed41bb7d848c07ac317b49d2ca8be02857e80e9da6aacd6a429f415ab9586369c8f07714168",
|
|
+ "publicKeyRegistry": "0x957e196011a27e4a6576b6f2df8679d48125c7aa6e5aacbac9210eda50959ed4725a473bb2d8618283943bad1821af641abe7887e5fe9983aae564d425ed0021ae95a90997a78872a77a025e812c2eb1f9070a6b9ec6f0745e1293a1bcf47a249fce1592c0b415873f5901ad45d7afa9015dfb79d717419b1af8f5cd4067921d62a6ee482f40987a70aa2a0c49c50717e05998a1d560bb03c6cc53f195563d9fea8d2826ab764baf5a1aa7d97fea4a3ac9db561dee6b4f3e51417810c22918fb8198aa8746cef7c2eaa5ec8a3ecc91bf0ab666b4e7849445a5ab6c35bb025509442cccb7c560971f1c490998a6e6a71197f64d231eafa487772426e60e409572d4c529ad8ca6ab3a90401ee9e5b47e4f3e2b68563166871abe6cdb37afe87749d4d25833a21d7e70cb08fb128e4a393c72e2c1d32da09328abcb3aa6b5a5cbae12f67558519547494a95f17b048dc0d76a5d571283630a3aa61b501c161a2a66a0e714dcf70d646d118584fda2e6c553bd042f1256bde2455107b01ae2faaee9eb18d08152ce028126b1e514d7145689c51d81b080785e85e7e17d8ab1ab4d788653d70d6432692ab72ce8a5ed1121f8563a4345af28556242028612f047979e3a129c4681eb4f1a65d03bd2aaff4df5bc8abc2f7130ba67b3db280f11da3672962fdd78125d5160d10603d566b13b239a2a52f2754f47e0a6012e56ead07e9f85a006e8933a6c6965c374dccb50d0fed745470850ec6ba19d5b7838b15f03af1566501522f003c3edbc16576172c3c3ab6500485108039d6271b6911e58bd9d3dbbb78e3a91a95c9252954c7cdae843a784849fbded6b6250ab7b528a3041940343a4b8477c88595d4a41a7f31b8220dee7cb4000022c469b13efd19e271a56f9ad51b215164fe7d9d11291acd7255a2ba5029a9490d9999a1caaa36082616b73a0288889cc00bbc6b61128dcdd77e411524a2adb22f0e0d0d1e85413a80c63640c8b2b090b0bebca763fa218b07e86e31aa5be9a95c1811310fa7b0890e5b47ac4127947f89189f6d7cc5a317101ec213ee7e508fd5fc121e6571aa40929978f900380b3593fd83e4da9a64455c03f9658b2e7ff8e081d76e9f3099d7b725653c3ae6881aedc61024107967e09c542721f45a4300e95a7255f6db159e933670f9c84487a042334355a251410ae9156b92b104b8aab929864d77ed41bb7d848c07ac317b49d2ca8be02857e80e9da6aacd6a429f415ab9586369c8f07714168"
|
|
+ },
|
|
+ "slh-dsa-sha2-128s": {
|
|
+ "publicKey": "0x97b3e5119fa40a74aa17f23662430fa759adc106bef8eb738f1ab7a76b73f694"
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "index": 2,
|
|
+ "marker": "AERE-SINTETIC",
|
|
+ "address": "0xfe7df8ea09662aab17cd0926e24333ab4c514560",
|
|
+ "falcon-512": {
|
|
+ "publicKeyFull": "0x0991153454ea8b852d5c17b700ef3a5c58fdd1d664d23949db875b83d56c32aa2610ea435d71f6cb9b11a608a69836cd8d27acb92787431f9745e97713b8084144562899d51b916c6e4824e46968acd9152a01e30f95d0567782dd3708c08ee8a529b871fe3715ca19f821166e66028a235409f4e7e0eaf58929ba12f143cc13a559b6588efeb60d6f53d72b063fd250c0faae74621a0044f28ba63dea3838324fbd769290a9161f481a3953f5a467eaa9ddae2590e4206fdcdab345c9565afc43e36218bf3ecd4fd029dda11eb4c1cb35104b6d88dcd81dc8738636d7c9c768ff579d7dc6e3c713a5da8a71f36edbb4ee2855ddc6d806840a587bddba73dab934ef0d44790cbde76895d507c8ad090cc1f5440ae2259f8f0b71422f28349c0ab8a96d47168667815d7143e42b1d737545d52b13d28a29f8f9cadce0a02a82d618944c3a6c05c69f9d0cb4c9a9336e2a955c2a0e568ad30246861eb2b7dafd9ca4df07b0aac114b4c426bd9f5abffa0e70da00a234389e52af20e58874cfc0d7c41c7576e0096aedc8b5051639dcea062e34f3c8dd0f66174472a606a51c78367567cf2413ab6059073154791c98f6b382dc6eb5543d483c0ebc15edb970e609ad2f99ec911202e02e68487551852b426019802b9935ba1958d9a64f57a6d6bf96ca94093c2893a26190c99efa3ef9391ccd1e960333912932078167b0e9ce823ea2a634934c9458593d451593c360c14b037c9fd57714fbb3eca9de113679a21826fa480803a513223814e26117cf55202331de8a10de027e850e00fec636a190b5389d99832a644eb6a8cc02357eb9169a6858b54e3ef4fe590a44d1a6c5d7098c15d6a2d7df2b878ac65162b52c652658a688d023c84bc214949b6dd42e329f934dc53022bd3be88b11216e35fd00ab5db909aeeec532cd8bab2022e26c23176e258a193cabf91010ff854f97488801cbf11e63184e1d1517068a9b07c53350feed0a02ed4bf3ba12b0285ead3a65058d781cb023351ac8195d519460e1d644885eb18ed15455086d4748d4ae8f1ee1c3a31d0026f4bba3bd507ba265008b60559967b595790c414f247c7853c94eb065967f59660b6e7385e6a976dd798fcd19f4ad658506dc25b512a1ae9585cfb94f2dcc815a64d60093326774b52625c83da0410c7082df24759de8003ca10d74e25db5e9ed7ea1cee9ead85734bb24883abea9c04670cca8a703b96fbeabf3df0dfb847d02903b22d4a85acbd881a258",
|
|
+ "publicKeyRegistry": "0x91153454ea8b852d5c17b700ef3a5c58fdd1d664d23949db875b83d56c32aa2610ea435d71f6cb9b11a608a69836cd8d27acb92787431f9745e97713b8084144562899d51b916c6e4824e46968acd9152a01e30f95d0567782dd3708c08ee8a529b871fe3715ca19f821166e66028a235409f4e7e0eaf58929ba12f143cc13a559b6588efeb60d6f53d72b063fd250c0faae74621a0044f28ba63dea3838324fbd769290a9161f481a3953f5a467eaa9ddae2590e4206fdcdab345c9565afc43e36218bf3ecd4fd029dda11eb4c1cb35104b6d88dcd81dc8738636d7c9c768ff579d7dc6e3c713a5da8a71f36edbb4ee2855ddc6d806840a587bddba73dab934ef0d44790cbde76895d507c8ad090cc1f5440ae2259f8f0b71422f28349c0ab8a96d47168667815d7143e42b1d737545d52b13d28a29f8f9cadce0a02a82d618944c3a6c05c69f9d0cb4c9a9336e2a955c2a0e568ad30246861eb2b7dafd9ca4df07b0aac114b4c426bd9f5abffa0e70da00a234389e52af20e58874cfc0d7c41c7576e0096aedc8b5051639dcea062e34f3c8dd0f66174472a606a51c78367567cf2413ab6059073154791c98f6b382dc6eb5543d483c0ebc15edb970e609ad2f99ec911202e02e68487551852b426019802b9935ba1958d9a64f57a6d6bf96ca94093c2893a26190c99efa3ef9391ccd1e960333912932078167b0e9ce823ea2a634934c9458593d451593c360c14b037c9fd57714fbb3eca9de113679a21826fa480803a513223814e26117cf55202331de8a10de027e850e00fec636a190b5389d99832a644eb6a8cc02357eb9169a6858b54e3ef4fe590a44d1a6c5d7098c15d6a2d7df2b878ac65162b52c652658a688d023c84bc214949b6dd42e329f934dc53022bd3be88b11216e35fd00ab5db909aeeec532cd8bab2022e26c23176e258a193cabf91010ff854f97488801cbf11e63184e1d1517068a9b07c53350feed0a02ed4bf3ba12b0285ead3a65058d781cb023351ac8195d519460e1d644885eb18ed15455086d4748d4ae8f1ee1c3a31d0026f4bba3bd507ba265008b60559967b595790c414f247c7853c94eb065967f59660b6e7385e6a976dd798fcd19f4ad658506dc25b512a1ae9585cfb94f2dcc815a64d60093326774b52625c83da0410c7082df24759de8003ca10d74e25db5e9ed7ea1cee9ead85734bb24883abea9c04670cca8a703b96fbeabf3df0dfb847d02903b22d4a85acbd881a258"
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "index": 3,
|
|
+ "marker": "AERE-SINTETIC",
|
|
+ "address": "0x0a1f732db9f0a1f53b932e7d3dda365698e3e617",
|
|
+ "falcon-512": {
|
|
+ "publicKeyFull": "0x09b532d3b13ea7a507fcd2e449ee2085d1eb891861fd8b750eb170ec4a7c9edf11c704a61281dea8a417509626ef368624026502a906db4f470d8c94cbb50e426f4566537283b2898d6308ba12405f8a9a36c82dd8880cdd108167f04762ad473e4ea0afa08bb1ee0e8c6d12a7e97cc647b214e83180a0f19f45f0d0a5e6f06f00f75281d382abb6626a92e7031025c184430fa591854adaab96f068a2ffd2d0ee64777aa667d1264f079af0d9ed294c5924415ae18016a8c6d7aadcc58182908c8b5c00f02fec99c0255fa615aa99d3a2ac87a6dd6f74f7491f142c1d718a2be41ebef50923c0ae9d81c256885171074266552564e18675372493a9d86a7e05963aa5280ef616a24e0b53157ab268804ef0522893e2eb1f2bb4189247e9561c30f5eb635fd916b811dc90264c621ed2188891d6d5b42cfd0867823b7f29d055551ab1109c1bdb3d8119215a2b03ead28a9af24925c61f846a083c1b67ea23a4fcebc93b59500b9110b272a59032e20ae5dc09d69cee8f9b378b29afac94235ca5841b72e0b8169ba8872ce0167fc33e4a9a303af16dbf75517970582e4fb57e029592a5bf497e0e546c217f967e2df1b89d16006ae2e5c545a543a1d7d575a475a4dd82ba3a49740655b008c698857ead1ce3dee7cc928c63d32aa7d4ac2d972602df1845ba7f14f76b9b7ee2c4c80be09e47089780fd104e5d020470a490ea1eca7fd2d047f3621c6835212f3745bc0f560bac940c64f72b290c9d53b4537167094e56fde9f856ed19019d9067661724675edc29be017fb2fee853a917a6874af5cac766f44a0142854b8c812ea1d979b1056130c862e763431d99fc57e24dab043d799591dea06760307990d645e0b736e44a1455067d124f68ecc9eb60d06e3add88b382297948a0a1e45bb23185fee32433c62ebb030d46430867f5e3e41b96aee53343d7b89dba8d03f82e0c52562f501419ea3e227c01d31be58a56780b08440a64fa187504ec21a834aa08435e0dbb7e05183490fb10761a8788c5867a5ee79618922a8866427405615d2df62b002f511289b96b2049ae49b8169f670f4a2953ae32b1f521a88c7242d4f89064a1f5fd764cdd68a936f4d7668f424651e6786ca648a6d843f387895f5fe25e475f981e645d021a8f14db920932f1f4195d7cc23953bf83b753901545c96c281eee9f03da43c563f18459a6a9de09640647148b50a1940aa99a6dff9c04a5b6be5962449c94c71b668c3966c531d34afb",
|
|
+ "publicKeyRegistry": "0xb532d3b13ea7a507fcd2e449ee2085d1eb891861fd8b750eb170ec4a7c9edf11c704a61281dea8a417509626ef368624026502a906db4f470d8c94cbb50e426f4566537283b2898d6308ba12405f8a9a36c82dd8880cdd108167f04762ad473e4ea0afa08bb1ee0e8c6d12a7e97cc647b214e83180a0f19f45f0d0a5e6f06f00f75281d382abb6626a92e7031025c184430fa591854adaab96f068a2ffd2d0ee64777aa667d1264f079af0d9ed294c5924415ae18016a8c6d7aadcc58182908c8b5c00f02fec99c0255fa615aa99d3a2ac87a6dd6f74f7491f142c1d718a2be41ebef50923c0ae9d81c256885171074266552564e18675372493a9d86a7e05963aa5280ef616a24e0b53157ab268804ef0522893e2eb1f2bb4189247e9561c30f5eb635fd916b811dc90264c621ed2188891d6d5b42cfd0867823b7f29d055551ab1109c1bdb3d8119215a2b03ead28a9af24925c61f846a083c1b67ea23a4fcebc93b59500b9110b272a59032e20ae5dc09d69cee8f9b378b29afac94235ca5841b72e0b8169ba8872ce0167fc33e4a9a303af16dbf75517970582e4fb57e029592a5bf497e0e546c217f967e2df1b89d16006ae2e5c545a543a1d7d575a475a4dd82ba3a49740655b008c698857ead1ce3dee7cc928c63d32aa7d4ac2d972602df1845ba7f14f76b9b7ee2c4c80be09e47089780fd104e5d020470a490ea1eca7fd2d047f3621c6835212f3745bc0f560bac940c64f72b290c9d53b4537167094e56fde9f856ed19019d9067661724675edc29be017fb2fee853a917a6874af5cac766f44a0142854b8c812ea1d979b1056130c862e763431d99fc57e24dab043d799591dea06760307990d645e0b736e44a1455067d124f68ecc9eb60d06e3add88b382297948a0a1e45bb23185fee32433c62ebb030d46430867f5e3e41b96aee53343d7b89dba8d03f82e0c52562f501419ea3e227c01d31be58a56780b08440a64fa187504ec21a834aa08435e0dbb7e05183490fb10761a8788c5867a5ee79618922a8866427405615d2df62b002f511289b96b2049ae49b8169f670f4a2953ae32b1f521a88c7242d4f89064a1f5fd764cdd68a936f4d7668f424651e6786ca648a6d843f387895f5fe25e475f981e645d021a8f14db920932f1f4195d7cc23953bf83b753901545c96c281eee9f03da43c563f18459a6a9de09640647148b50a1940aa99a6dff9c04a5b6be5962449c94c71b668c3966c531d34afb"
|
|
+ }
|
|
+ }
|
|
+ ],
|
|
+ "control": [
|
|
+ {
|
|
+ "id": "COMMIT-1(28001,1000,0x11)",
|
|
+ "value": "0xe710f04a8517e5af495f33d47bd3dc19e20afaaec3435ce7124cb1d56ef5e27b"
|
|
+ },
|
|
+ {
|
|
+ "id": "PREPARE-1(28001,1000,r=2,0x11)",
|
|
+ "value": "0x6ea2394db1ccded2dc5107d9aacf5be6c5a769218ba2eb4b004088466da4ba84"
|
|
+ },
|
|
+ {
|
|
+ "id": "PREPARE-1(28001,1000,r=0,0x11)",
|
|
+ "value": "0x10f5d7f8368a2533c05df0bc5cc39fabdc055c9d60fc8bc7e1ff403ea9e64909"
|
|
+ }
|
|
+ ],
|
|
+ "VM": [
|
|
+ {
|
|
+ "id": "vm-28001-1000-r0",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": 0,
|
|
+ "hash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commit2": "0x5fdbfd2f4066eacbc275682817f0e4410d3d762ea8a6c5061586041010298eeb",
|
|
+ "commit1": "0xe710f04a8517e5af495f33d47bd3dc19e20afaaec3435ce7124cb1d56ef5e27b"
|
|
+ },
|
|
+ {
|
|
+ "id": "vm-28001-1000-r1",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": 1,
|
|
+ "hash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commit2": "0x921fab44cf68919646c8bba40c37c1d0211a14654e777b6dd516fc74c7a7c715",
|
|
+ "commit1": "0xe710f04a8517e5af495f33d47bd3dc19e20afaaec3435ce7124cb1d56ef5e27b"
|
|
+ },
|
|
+ {
|
|
+ "id": "vm-28001-1000-r2",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": 2,
|
|
+ "hash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commit2": "0x28d5e1e414ea100e42db14144e5a7721b0137994a1461d2d71a554c18b782a0a",
|
|
+ "commit1": "0xe710f04a8517e5af495f33d47bd3dc19e20afaaec3435ce7124cb1d56ef5e27b"
|
|
+ },
|
|
+ {
|
|
+ "id": "vm-28001-1000-r3",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": 3,
|
|
+ "hash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commit2": "0xb247791ed3715ee9a9974a23c135331bf094d0681fa6131fc44eb1fa26b89062",
|
|
+ "commit1": "0xe710f04a8517e5af495f33d47bd3dc19e20afaaec3435ce7124cb1d56ef5e27b"
|
|
+ },
|
|
+ {
|
|
+ "id": "vm-28001-1000-r127",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": 127,
|
|
+ "hash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commit2": "0x6b926d6c5afc90bdca785dc3a744234bfbfa7979fcf9839bebff39bcff513ff4",
|
|
+ "commit1": "0xe710f04a8517e5af495f33d47bd3dc19e20afaaec3435ce7124cb1d56ef5e27b"
|
|
+ },
|
|
+ {
|
|
+ "id": "vm-28001-1000-r128",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": 128,
|
|
+ "hash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commit2": "0x4df364d8deaeb218976a342a4b10954d3c5f41e2c1863e51fb664c7a8f5181de",
|
|
+ "commit1": "0xe710f04a8517e5af495f33d47bd3dc19e20afaaec3435ce7124cb1d56ef5e27b"
|
|
+ },
|
|
+ {
|
|
+ "id": "vm-28001-1000-r1000",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": 1000,
|
|
+ "hash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commit2": "0xe5c8b97d504ebd57a5c74000e37ffe8dd4c0a70d64c43c5faf43ac7975feef5f",
|
|
+ "commit1": "0xe710f04a8517e5af495f33d47bd3dc19e20afaaec3435ce7124cb1d56ef5e27b"
|
|
+ },
|
|
+ {
|
|
+ "id": "vm-28001-1000-r1024",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": 1024,
|
|
+ "hash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commit2": "0xb10b5e143e201dc0f538db90dd4cea7dd21c174b7ab575b0a353270f2cba5083",
|
|
+ "commit1": "0xe710f04a8517e5af495f33d47bd3dc19e20afaaec3435ce7124cb1d56ef5e27b"
|
|
+ },
|
|
+ {
|
|
+ "id": "vm-2800-21000000-r0",
|
|
+ "chainId": 2800,
|
|
+ "n": 21000000,
|
|
+ "round": 0,
|
|
+ "hash": "0x2222222222222222222222222222222222222222222222222222222222222222",
|
|
+ "commit2": "0x9edb252de1978b0d7eded7a9df0584a36e16eb9eab7b1fa4bdc30ac2496401a2",
|
|
+ "commit1": "0x84c859aba10282d049a02e0f5bc4e5290f7809be8f5bc20722ec65aa2ccf3aae"
|
|
+ },
|
|
+ {
|
|
+ "id": "vm-2800-21000000-r3",
|
|
+ "chainId": 2800,
|
|
+ "n": 21000000,
|
|
+ "round": 3,
|
|
+ "hash": "0x2222222222222222222222222222222222222222222222222222222222222222",
|
|
+ "commit2": "0x2290c0ef39679154fac1b81e6baeabc21928ff4be5bad6d1344eefd960896f1d",
|
|
+ "commit1": "0x84c859aba10282d049a02e0f5bc4e5290f7809be8f5bc20722ec65aa2ccf3aae"
|
|
+ }
|
|
+ ],
|
|
+ "VMF": [
|
|
+ {
|
|
+ "id": "vmf-sub-forma-ancorei",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 62,
|
|
+ "round": 0,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ECDSA_DIGEST",
|
|
+ "message": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "anchorMessage": null,
|
|
+ "code": null
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-prima-forma-ancorei",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 63,
|
|
+ "round": 0,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ROUND_FREE",
|
|
+ "message": "0x846d66aa91cd24e636ef448f81644e6a3357cba87430e7edee57bd1f576e6e1b",
|
|
+ "anchorMessage": "0x846d66aa91cd24e636ef448f81644e6a3357cba87430e7edee57bd1f576e6e1b",
|
|
+ "code": null
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-H_r-2",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 998,
|
|
+ "round": 2,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ROUND_FREE",
|
|
+ "message": "0x4adfc6303cba6f63575d27571d35dab5b6e7149d46392b69c0599040933a37d9",
|
|
+ "anchorMessage": "0x4adfc6303cba6f63575d27571d35dab5b6e7149d46392b69c0599040933a37d9",
|
|
+ "code": null
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-H_r-2-runda-1025",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 998,
|
|
+ "round": 1025,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ROUND_FREE",
|
|
+ "message": "0x4adfc6303cba6f63575d27571d35dab5b6e7149d46392b69c0599040933a37d9",
|
|
+ "anchorMessage": "0x4adfc6303cba6f63575d27571d35dab5b6e7149d46392b69c0599040933a37d9",
|
|
+ "code": null
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-H_r-1",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 999,
|
|
+ "round": 2,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ROUND_BOUND",
|
|
+ "message": "0x8456d2e42a843ad59e833ef6d8db12f39e6160a170b5c7a7db113b56f905f239",
|
|
+ "anchorMessage": "0x8456d2e42a843ad59e833ef6d8db12f39e6160a170b5c7a7db113b56f905f239",
|
|
+ "code": null
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-H_r-1-runda-0",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 999,
|
|
+ "round": 0,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ROUND_BOUND",
|
|
+ "message": "0x6773d14e263051c70708a039c3d8742b13d6fc1115c56c750a1c1b0e0bf6a861",
|
|
+ "anchorMessage": "0x6773d14e263051c70708a039c3d8742b13d6fc1115c56c750a1c1b0e0bf6a861",
|
|
+ "code": null
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-H_r",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 1000,
|
|
+ "round": 0,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ROUND_BOUND",
|
|
+ "message": "0x5fdbfd2f4066eacbc275682817f0e4410d3d762ea8a6c5061586041010298eeb",
|
|
+ "anchorMessage": "0x5fdbfd2f4066eacbc275682817f0e4410d3d762ea8a6c5061586041010298eeb",
|
|
+ "code": null
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-H_r-1-runda-1024",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 999,
|
|
+ "round": 1024,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ROUND_BOUND",
|
|
+ "message": "0x478927028074b30abc32ff89e49448bcda247430c5ae6ad27e17824b1e39e9cd",
|
|
+ "anchorMessage": "0x478927028074b30abc32ff89e49448bcda247430c5ae6ad27e17824b1e39e9cd",
|
|
+ "code": null
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-H_r-1-runda-1025",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 999,
|
|
+ "round": 1025,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ROUND_BOUND",
|
|
+ "message": null,
|
|
+ "anchorMessage": null,
|
|
+ "code": "AERE-PQ-COMMIT-R-03"
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-H_r-1-runda-minus-1",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 999,
|
|
+ "round": -1,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ROUND_BOUND",
|
|
+ "message": null,
|
|
+ "anchorMessage": null,
|
|
+ "code": "AERE-PQ-COMMIT-R-03"
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-H_r-nesetat",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": null,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 5000,
|
|
+ "round": 3,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ROUND_FREE",
|
|
+ "message": "0x76d4e8d9eedf4c6b59895536b5790a2698c4cbc80eab2531422e2f60e90bf996",
|
|
+ "anchorMessage": "0x76d4e8d9eedf4c6b59895536b5790a2698c4cbc80eab2531422e2f60e90bf996",
|
|
+ "code": null
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-ancora-dezarmata",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": true,
|
|
+ "n": 5000,
|
|
+ "round": 3,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ECDSA_DIGEST",
|
|
+ "message": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "anchorMessage": null,
|
|
+ "code": null
|
|
+ }
|
|
+ }
|
|
+ ],
|
|
+ "VC": [
|
|
+ {
|
|
+ "id": "vc-r0",
|
|
+ "valid": true,
|
|
+ "round": 0,
|
|
+ "rows": [
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 0,
|
|
+ "signature": "0xaaaaaaaa"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 2,
|
|
+ "signature": "0xbbbbbbbb"
|
|
+ }
|
|
+ ],
|
|
+ "bytes": "0xd30380d0c7018084aaaaaaaac7010284bbbbbbbb"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-r3",
|
|
+ "valid": true,
|
|
+ "round": 3,
|
|
+ "rows": [
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 0,
|
|
+ "signature": "0xaaaaaaaa"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 2,
|
|
+ "signature": "0xbbbbbbbb"
|
|
+ }
|
|
+ ],
|
|
+ "bytes": "0xd30303d0c7018084aaaaaaaac7010284bbbbbbbb"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-r128",
|
|
+ "valid": true,
|
|
+ "round": 128,
|
|
+ "rows": [
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 0,
|
|
+ "signature": "0xaaaaaaaa"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 2,
|
|
+ "signature": "0xbbbbbbbb"
|
|
+ }
|
|
+ ],
|
|
+ "bytes": "0xd4038180d0c7018084aaaaaaaac7010284bbbbbbbb"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-r1024",
|
|
+ "valid": true,
|
|
+ "round": 1024,
|
|
+ "rows": [
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 0,
|
|
+ "signature": "0xaaaaaaaa"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 2,
|
|
+ "signature": "0xbbbbbbbb"
|
|
+ }
|
|
+ ],
|
|
+ "bytes": "0xd503820400d0c7018084aaaaaaaac7010284bbbbbbbb"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-gol-r0",
|
|
+ "valid": true,
|
|
+ "round": 0,
|
|
+ "rows": [],
|
|
+ "bytes": "0xc30380c0"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-r1-hibrid",
|
|
+ "valid": true,
|
|
+ "round": 1,
|
|
+ "rows": [
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 0,
|
|
+ "signature": "0xaaaaaaaa"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 2,
|
|
+ "index": 0,
|
|
+ "signature": "0xcccccccc"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 3,
|
|
+ "signature": "0xbbbbbbbb"
|
|
+ }
|
|
+ ],
|
|
+ "bytes": "0xdb0301d8c7018084aaaaaaaac7028084ccccccccc7010384bbbbbbbb"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-r0-hibrid",
|
|
+ "valid": true,
|
|
+ "round": 0,
|
|
+ "rows": [
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 0,
|
|
+ "signature": "0xa0a0a0a0"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 2,
|
|
+ "signature": "0xa2a2a2a2"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 2,
|
|
+ "index": 2,
|
|
+ "signature": "0xb2b2b2b2"
|
|
+ }
|
|
+ ],
|
|
+ "bytes": "0xdb0380d8c7018084a0a0a0a0c7010284a2a2a2a2c7020284b2b2b2b2"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-64-randuri",
|
|
+ "valid": true,
|
|
+ "round": 0,
|
|
+ "rows": [
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 0,
|
|
+ "signature": "0x1010"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 1,
|
|
+ "signature": "0x1111"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 2,
|
|
+ "signature": "0x1212"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 3,
|
|
+ "signature": "0x1313"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 4,
|
|
+ "signature": "0x1414"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 5,
|
|
+ "signature": "0x1515"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 6,
|
|
+ "signature": "0x1616"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 7,
|
|
+ "signature": "0x1717"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 8,
|
|
+ "signature": "0x1818"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 9,
|
|
+ "signature": "0x1919"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 10,
|
|
+ "signature": "0x1a1a"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 11,
|
|
+ "signature": "0x1b1b"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 12,
|
|
+ "signature": "0x1c1c"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 13,
|
|
+ "signature": "0x1d1d"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 14,
|
|
+ "signature": "0x1e1e"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 15,
|
|
+ "signature": "0x1f1f"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 16,
|
|
+ "signature": "0x2020"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 17,
|
|
+ "signature": "0x2121"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 18,
|
|
+ "signature": "0x2222"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 19,
|
|
+ "signature": "0x2323"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 20,
|
|
+ "signature": "0x2424"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 21,
|
|
+ "signature": "0x2525"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 22,
|
|
+ "signature": "0x2626"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 23,
|
|
+ "signature": "0x2727"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 24,
|
|
+ "signature": "0x2828"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 25,
|
|
+ "signature": "0x2929"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 26,
|
|
+ "signature": "0x2a2a"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 27,
|
|
+ "signature": "0x2b2b"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 28,
|
|
+ "signature": "0x2c2c"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 29,
|
|
+ "signature": "0x2d2d"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 30,
|
|
+ "signature": "0x2e2e"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 31,
|
|
+ "signature": "0x2f2f"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 32,
|
|
+ "signature": "0x3030"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 33,
|
|
+ "signature": "0x3131"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 34,
|
|
+ "signature": "0x3232"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 35,
|
|
+ "signature": "0x3333"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 36,
|
|
+ "signature": "0x3434"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 37,
|
|
+ "signature": "0x3535"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 38,
|
|
+ "signature": "0x3636"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 39,
|
|
+ "signature": "0x3737"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 40,
|
|
+ "signature": "0x3838"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 41,
|
|
+ "signature": "0x3939"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 42,
|
|
+ "signature": "0x3a3a"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 43,
|
|
+ "signature": "0x3b3b"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 44,
|
|
+ "signature": "0x3c3c"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 45,
|
|
+ "signature": "0x3d3d"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 46,
|
|
+ "signature": "0x3e3e"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 47,
|
|
+ "signature": "0x3f3f"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 48,
|
|
+ "signature": "0x4040"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 49,
|
|
+ "signature": "0x4141"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 50,
|
|
+ "signature": "0x4242"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 51,
|
|
+ "signature": "0x4343"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 52,
|
|
+ "signature": "0x4444"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 53,
|
|
+ "signature": "0x4545"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 54,
|
|
+ "signature": "0x4646"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 55,
|
|
+ "signature": "0x4747"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 56,
|
|
+ "signature": "0x4848"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 57,
|
|
+ "signature": "0x4949"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 58,
|
|
+ "signature": "0x4a4a"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 59,
|
|
+ "signature": "0x4b4b"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 60,
|
|
+ "signature": "0x4c4c"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 61,
|
|
+ "signature": "0x4d4d"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 62,
|
|
+ "signature": "0x4e4e"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 63,
|
|
+ "signature": "0x4f4f"
|
|
+ }
|
|
+ ],
|
|
+ "bytes": "0xf901850380f90180c50180821010c50101821111c50102821212c50103821313c50104821414c50105821515c50106821616c50107821717c50108821818c50109821919c5010a821a1ac5010b821b1bc5010c821c1cc5010d821d1dc5010e821e1ec5010f821f1fc50110822020c50111822121c50112822222c50113822323c50114822424c50115822525c50116822626c50117822727c50118822828c50119822929c5011a822a2ac5011b822b2bc5011c822c2cc5011d822d2dc5011e822e2ec5011f822f2fc50120823030c50121823131c50122823232c50123823333c50124823434c50125823535c50126823636c50127823737c50128823838c50129823939c5012a823a3ac5012b823b3bc5012c823c3cc5012d823d3dc5012e823e3ec5012f823f3fc50130824040c50131824141c50132824242c50133824343c50134824444c50135824545c50136824646c50137824747c50138824848c50139824949c5013a824a4ac5013b824b4bc5013c824c4cc5013d824d4dc5013e824e4ec5013f824f4f"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-doua-elemente",
|
|
+ "valid": false,
|
|
+ "bytes": "0xd203d0c7018084aaaaaaaac7010284bbbbbbbb",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "two elements with version 3 (the v2 shape)"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-patru-elemente",
|
|
+ "valid": false,
|
|
+ "bytes": "0xd40380d0c7018084aaaaaaaac7010284bbbbbbbb01",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "four elements"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-runda-lista",
|
|
+ "valid": false,
|
|
+ "bytes": "0xd303c0d0c7018084aaaaaaaac7010284bbbbbbbb",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "the round is a list"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-runda-1025",
|
|
+ "valid": false,
|
|
+ "bytes": "0xd503820401d0c7018084aaaaaaaac7010284bbbbbbbb",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "round above 1024"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-runda-820005",
|
|
+ "valid": false,
|
|
+ "bytes": "0xd503820005d0c7018084aaaaaaaac7010284bbbbbbbb",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "round 0x820005: a leading zero byte (non-canonical scalar)"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-runda-trei-octeti",
|
|
+ "valid": false,
|
|
+ "bytes": "0xd60383010000d0c7018084aaaaaaaac7010284bbbbbbbb",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "round on three bytes (65536)"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-runda-00",
|
|
+ "valid": false,
|
|
+ "bytes": "0xd30300d0c7018084aaaaaaaac7010284bbbbbbbb",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "round written as the single byte 0x00 instead of 0x80"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-gol-r1",
|
|
+ "valid": false,
|
|
+ "bytes": "0xc30301c0",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "an empty list is valid only with round 0"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-ordine",
|
|
+ "valid": false,
|
|
+ "bytes": "0xd30380d0c7010284bbbbbbbbc7018084aaaaaaaa",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "rows not in strictly increasing (index, scheme) order"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-dublura",
|
|
+ "valid": false,
|
|
+ "bytes": "0xd30380d0c7018084aaaaaaaac7018084aaaaaaaa",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "a repeated row"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-schema-09",
|
|
+ "valid": false,
|
|
+ "bytes": "0xcb0380c8c7098084aaaaaaaa",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "unknown scheme tag 0x09"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-65-randuri",
|
|
+ "valid": false,
|
|
+ "bytes": "0xf9018b0380f90186c50180821010c50101821010c50102821010c50103821010c50104821010c50105821010c50106821010c50107821010c50108821010c50109821010c5010a821010c5010b821010c5010c821010c5010d821010c5010e821010c5010f821010c50110821010c50111821010c50112821010c50113821010c50114821010c50115821010c50116821010c50117821010c50118821010c50119821010c5011a821010c5011b821010c5011c821010c5011d821010c5011e821010c5011f821010c50120821010c50121821010c50122821010c50123821010c50124821010c50125821010c50126821010c50127821010c50128821010c50129821010c5012a821010c5012b821010c5012c821010c5012d821010c5012e821010c5012f821010c50130821010c50131821010c50132821010c50133821010c50134821010c50135821010c50136821010c50137821010c50138821010c50139821010c5013a821010c5013b821010c5013c821010c5013d821010c5013e821010c5013f821010c50140821010",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "more than 64 rows"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-semnatura-goala",
|
|
+ "valid": false,
|
|
+ "bytes": "0xc70380c4c3018080",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "an empty signature"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-index-necanonic",
|
|
+ "valid": false,
|
|
+ "bytes": "0xcd0380cac90182000284aaaaaaaa",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "row index with a leading zero byte"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-versiune-necanonica",
|
|
+ "valid": false,
|
|
+ "bytes": "0xd4810380d0c7018084aaaaaaaac7010284bbbbbbbb",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "version 3 written as 0x8103 (non-canonical RLP)"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-rand-doua-elemente",
|
|
+ "valid": false,
|
|
+ "bytes": "0xc60380c3c20180",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "a row of two elements"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-lungime-necanonica",
|
|
+ "valid": false,
|
|
+ "bytes": "0xf8130380d0c7018084aaaaaaaac7010284bbbbbbbb",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "outer list with a long-form length for a short payload (round trip differs)"
|
|
+ }
|
|
+ ],
|
|
+ "VD": [
|
|
+ {
|
|
+ "id": "vd-r0-28001-999",
|
|
+ "chainId": 28001,
|
|
+ "parentNumber": 999,
|
|
+ "parentHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "certificate": "0xd30380d0c7018084aaaaaaaac7010284bbbbbbbb",
|
|
+ "d3": "0x1897321916421f85c4f8dfbe4c8175b6ae471289ed36f979b9beff0d18380058"
|
|
+ },
|
|
+ {
|
|
+ "id": "vd-r1-hibrid-28001-1000",
|
|
+ "chainId": 28001,
|
|
+ "parentNumber": 1000,
|
|
+ "parentHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "certificate": "0xdb0301d8c7018084aaaaaaaac7028084ccccccccc7010384bbbbbbbb",
|
|
+ "d3": "0x86dce0ecc8add933368a081470f5df3b73f9c93e1d56a69e9fd1abd14d26122d"
|
|
+ },
|
|
+ {
|
|
+ "id": "vd-r0-hibrid-28001-1000",
|
|
+ "chainId": 28001,
|
|
+ "parentNumber": 1000,
|
|
+ "parentHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "certificate": "0xdb0380d8c7018084a0a0a0a0c7010284a2a2a2a2c7020284b2b2b2b2",
|
|
+ "d3": "0x949513ad3546ae8c66716adbd38e653c4e6c4d78677fe76a2e8e3313f3230a39"
|
|
+ },
|
|
+ {
|
|
+ "id": "vd-r3-hibrid-28001-1000",
|
|
+ "chainId": 28001,
|
|
+ "parentNumber": 1000,
|
|
+ "parentHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "certificate": "0xdb0303d8c7018084a0a0a0a0c7010284a2a2a2a2c7020284b2b2b2b2",
|
|
+ "d3": "0x8cce761fab70ab5159df6d09e2e7e8fd20ec7ba442765a9bab6e9abbe86e3320"
|
|
+ },
|
|
+ {
|
|
+ "id": "vd-gol-28001-1000",
|
|
+ "chainId": 28001,
|
|
+ "parentNumber": 1000,
|
|
+ "parentHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "certificate": "0xc30380c0",
|
|
+ "d3": "0x5fe600bc94da68fed339b7c9999fc8f4e402017559f3642c6df010d7138cedde"
|
|
+ },
|
|
+ {
|
|
+ "id": "vd-control-d2",
|
|
+ "chainId": 28001,
|
|
+ "parentNumber": 1000,
|
|
+ "parentHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "certificateV2": "0xda02d8c7018084a0a0a0a0c7010284a2a2a2a2c7020284b2b2b2b2",
|
|
+ "d2": "0x233b4974075d102e94e660aae44ed9abca1c63b127aa3497a5cbeb465faf5ded",
|
|
+ "mustDifferFrom": "vd-r0-hibrid-28001-1000"
|
|
+ }
|
|
+ ],
|
|
+ "VS": [
|
|
+ {
|
|
+ "id": "vs-28001-1000-r0-r2",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "hash": "0x3333333333333333333333333333333333333333333333333333333333333333",
|
|
+ "groups": [
|
|
+ {
|
|
+ "round": 0,
|
|
+ "rows": [
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 0,
|
|
+ "signature": "0x39bd3aadc5f485f3f17ab3ef996de30f40a4dbb98f4c70db2fbf505d86835dcfd8e1b067a325d98da059a8597b2e5ee62751d4fd8efc9985223f68c9b2725df62d7af9b091a129944bb0d86464ae20b5bd1c5cf3b29bec1fce23c562d6d8d3ea81215b2a061f05e1ea271c4f5da79f528ae113bb9ba6afdaa1eebb715d3171344fd4bce746d22de14f5a0454a7e371086667b9d586907f6b6969a528ba9ce5ceb7c8cbe30c939b4d76d3eaee2882cc898f374b94355329fae7e6d591e9166d7f71d9c58defb0bcade36ce313d62519c41a7973b149b4f2f8e51d6afd5154eb794343a3acdcc7436e4ff22dda41b236295314daef2a4b98c5343684e20ee7f1f6d27e4a66eaa79ce6a32b2fecf43c43237a40f3545f4af5f6d93109d8e15da5f28db19eac72f8641d14a079198fdf9f8ee292b2d0fc7d3fccd68525dbcfafff2a9d29a3cc361e4674d29e5af5ee408adc0d9725f7939065d0ceef4a4b64c0972943a69739b0aaf57562533888315d7a5d24fa759ed5661454ee58ce491e5f2fcf0d07608f524c50f36cab968c1d8cbee3313a7854744d1cd7e5ac70e20092bab2e5c59736351d014d71af7c19926b232bf1bc36676f81a1a6f7166e97d8e066f6a78d98f13974beed35449f3d9506fab1c0ab356b092273b42d4aedb6cdbedb736e6928fd2d4926b94106fbbf0923e3b759e1fb89ecaf24bea45bd406d509d611550061897b71c39ea3fa6a8f47a50a31849546df90137114491b55ce36fe1d6f64851c8647eb5906d13369b97ab5721a44db1f9d7712aa45c87f5f8b8bef5c92a9f715c432ef6262c8d22af0eb2943e40cda27921cb865b7d79a4b70ec14f7deb96916cc13eeb764a5f3f35189a9bace816de3f88b57aecea4ad102412e121f84ab7474a04d0c0d92526178821f0dce4"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 2,
|
|
+ "index": 0,
|
|
+ "signature": "0xb04a645ad8d00ab495a1abf55dcdc235878fec9db0c64b021945e225e20fe4dbd3f148227ec3f11a5241706c3941ffff52adca321f313d8155be79374ea93e2ee9fc8e91b95cf14324d936cdc4cd2a54f5d499562370820a04d141492a0e8cf43aff6ede6640aadc4d978d41025bab7d9a76d7b593cbb3d1753bb84fcad1bfb64ce0a9a708fb3c183b39e94582c983805fa040dc6063f3311c3e932085b964ad6d608c689ba5d7ef452c7ae27bb66bb706a6e413182d029285acaac3252c309fa9eb7da2bbfca67359d74947416a5d399a50cef4493a6ba27dfd43a60945e7a709d0c0332bb1f581e40ec93b62acde90caffbafd1e12738b6873ec38bd33908f94302058298a1154c48454796f73ff325faf6c435405a9bd6d6c3453af15186974c311d8f4fc384314a88932629c141779bfb8b039183d550c9d65f840c64b97fc81d672b91e5db8c2f11e6e910893c67c5bf8db89b209d699a4ff7c02c96b5e791ae65c2afb94baf1d9e6277f7c4583d3a504a932892f8e5ecb92e217d0161c32e643c3ec6e86adb91d1da9bdbb1399b50008e2ed446a719a63196e0bb4ea7b548df66c93e1e9bc65c5149db54d8e2fb97ae5573182b56373463fd259cad0f36b54f853b0178d0959ad4941e63658525c1489f45eeaf173dc8cb24be5d6cdc6690fccf42d53ea72171ebff5090cca10e3e7ced1d33a8b7a8afc3427c6bc3360dc7f111c62ab2c65109332315c672c983966c4b6fecd36242605bf81722e0c570354bae6eea7eec53b55fcc4160c2e6f2b6cb712ca31fa5a21f8ae785da5fe0560a3f87d7fcbffe06540f2adc5489feceb1777613715c50605f22bc291cbbd74ea037e2c749b76574bfd9b14499b62828bbf12a19d43ad41fbf761b089f47420a618e7b59138bafb843b7e64dc15b672f05705062f42655b0ea4d21dc5b326b5f038a550c2b5b956e19995d8ae6d0aa580cba6034dbfe55fd0600e824fbabab3e195c329b0c99b61d7c0691d72147c614e93dd8bee087d2a501db32a65fb11b6a2e5f983babda2406a5f409ffd531fe9446f2bf468b132fa662c8f476fe35061c73824a7d2f6e6bc5483aa5f97c1a816e1131dcca03e98bf347fe6fa66f7c08eb5f4000ebedd6d1f5f74847bcd17d07c66ab8ec09ac7a9e9fda156efab32ee478b41b1676c61d69b9e8612118712f0998a4f2b3384c1a4fb55d71146a15986b461a93f549895a1c9d2a32c8f6acc60f926f6f24450a8d281eba1d42184ce6670a052c289c9f00bc52610792d4327244c984e6d789faf36c3b15d3298f2b9d0205c66fbcb302097ad29a0d98c943233f75e22c40436e08868e17e5c29f249ea500e4d381e2b0c949a51b98b3e8ed3fe0c94f5801d58cfa78fa96239c97b4278183d68b9d0fc17be277036513f8593285aaf46ac566aef4c5390b68d2dc937f2f704dff3e675cf3def2216ac9b1148aef653be944c185eb642b2ab9d8edc9d5dcebb41ea33887aaf1d6df7c92593dbe38f308e3b6fe4c5dee0d81f08cd86a721a7c1feb4ac7c4abaa65c5a9e5f41b17be59b449b46e5d271b343baa346c24598e15f9ecab7c9de5862a7b78f75f5079926760cb1ad6e3851c248e12eb2b657a7adddb4ddf415cfb5585045639ccb7e4a9d02791b37c43891e040243151d68bb91547f6a53889090402ba84b0ec43b5cfb27a7ff01f349101b50d338831867623bf2886d5c679bdeebb714d8686321b0be9e2ede4605fa3c6fe6d55d82c8982d9f2356e9e0665570552206370fd635221f637dadf48dbc89f8cba78511cd49c88227d238069d73b04d0b7f57150827946ed44d391a79609f8b18443c445b8c690e6c98145fdf47fd99ba62de46705886d6b8e23001bc01920dd38304f37c94e895dfcade604cbb5780d1f19f2dba3aaa45daea0559c91ab896568b6daa4c854c906a5ebd01ce7a038a71b9fbac5e9856a0f50b62326b8bcf17956a627ececbdd1b922c0ba2963919b988a4b1289b8e45c92741e94b1b8317f4a1e47566bf53fea4bef7697ee04522bc43f90f605646e0e2cf7bb49e499c8f2395a6cda3d55fe1218cdf0139c52c4ea5d556397dd77f1d53c31cb040a52d66dcaa4cabcaae83b9d1fa807dac16ad18b487cc3b2c026189ac4a0b3724cacb6f008928bf8d361ec5c3098b528444296a45f142dba8696db82b596b8ddc420763acaf68a738967260e592677d5fe24b31b99e2884aafd11dc22c28b0ed0e3dad21b6545f587c0a7d04b77f5a1bf170d7c50c3c5b9505a8dba065b488eafbff7e1dec22850e10fc97715948768b0d63edd7748616cb22013f4b49a6c1581beed6ac019fb941b93b3cea858f05d3f75a59f430d0b44f1bbc20bab919558efe3f6a5ae52026e460d0eb8cfdb3a2d1cc728d44f5819f52a0c7331563ae1bad62b2fb49136de8030ef1dcd745e4e1c9c2f3db86e6c9ea6ae1dccdcae62541d01de5b7c1069396141a7be3559f1195160a38269a26f14f925f39ea52e9444bd4c2f68e767e9b197ecbc25218b7c8b60d1530496afed51fa58e230641221bded814d9610b8b1f472b7b9b0fbeb2a288549dae98521a4e958e8e50c7e1c6551152296205703ee5cb8ce85161f47e8a480b126ea96b2d63c8c2cf83b45d54120f49627d011bb8bf039804ec588e7a16b97b21f9f12bd811af15c07de4ac369b182da0bd71dac83d544fd181be78d29cf111cec43d496b514d5e1b40fd5103f3fa260ee6f161f6b4faf3fd6c9b39e5076b1f131e519abab53b5e421890b0754f3afd85213eaf0a092af028ee2c94a894e5938c59e777857b1d3a728c2c986ed03a6f4ff1c1de439b61100a0e6523d9ebb62c812315be304d19975f9560f5fd7b1a82b02dffab6db711df8462978effcf011203edd2a8f34223c47cbee141b3b39780e43708c8fa76d34a862536d91ba7422c5e65052e42678872a80a9669d5083280440bc90725bdb067181bb7a5e4088d03358022527bf1f626ede6b37deb7bd496211855272256d00e2ebb308d3982893e878ab67d5814afdb24af656f0968f0bc0c063a64ceb0431d048c3032c55dcc8680e113f046a223fd2d3b23a8134f8be07c509e18bc70c52e93102a8d32fdd8a9c3cf50d807ee979571afbf9f08dd23ff0ce4116fc4b823147193cc67f8b922c1be6892d276e0dbac473db17f1003c38c34c07da91091c3af5f3e4c423be6d526a9b8b37684da5cffc1552faddf4d0f60dc591bf9edd213402f4b4ef635c92bef5132e4343d0b065332d7e98b9c70e364b889cd970290edbc80325ba4bee26bc39044428746b502f3a9a58f1a7797cc6df8711bbd8a38bab0416caa5b0e2022810b1024e3520cb587df8c5f6eed2dd6bfb941f550b3872e15d024c2c75e4e80fc15f78e2083cd08ee1595e34e75c02c12024cf1f34a5bc6f7bbdb9c7d2bcd0620d7840143ab28d08907fe8a214765da83d42566991fb0eaa3f2fb4515038b9b824aaf29e34da9040f9bb2f2e06b95f2767a6264b163205abf3bf0aef569b9c47493752e5a664ab55ed75ae5937245a390b6266da873e098c61883e86e4ec832e42e8f1c763bb8e99fd389c7db7eacbe9c270c1327527d232cd2bbdd0b3f0357b1725f41c2f4fc772c0ee1ac40f62e34480547bd7ff705074585d131e57da8e320611f95710af1c5c266a0430b0021e2c27d039803e575fb0d424a29af75fd3dcea32700de27e5472ae8395090cc2ca40f39bfa53cb79d3598f4bb96b0f8e9a60543ed954e45282be914443649befaad010fd19ec21472ec7e1b69d2f7033a65c07549c22584c1ae358b007e52d20164dcc13a787db5f512ac845ee0324833fa24f416a778578ef3aa0d6dd209473719286b35b8460ad0568d954ee5c3e17d709188d9ce4f87f2e7ff0d01adaf766649b4539f7f9b336d54c0761bfd0c15c1526a8c0cca95665aea6907f0a6e58643dc20d400f46a2fba86a31bd13f7908912093557174a985f1fdb91b68a30ccee379385e339b983c1d2660f93d1c030f041ba4a23efdba9da621d957673d66705dd502bb7f1ddb760e926794878260828e6a0951d8d77a90fb1fead9d3ed55e48fd3a2289564814e62f216186cee9306850e19adde3cebe220b570e3f6950553fbf7f9767075c0dc456ddd3ca9c29e994de5b513709ecb8e610db6802a3de15b6b5b4963394b7c7b062869e1f8829f70ad2c075a7fb44777842389a5204811fb30dc1173b7c53449d2d6d50b32c73825e27be01c73b42f229e134e7417cf5621e023b9d2f3556bc02fec6a0a86614bd3b62e31f436321e8a2e1be9733e94e84db8ae4cc3ab40dc035779af21e4c2357ac72ac5f79d6decfd00a38101ec3074a4bbfcd55cf2afb3cdb4f44c53834b08e6aaafa51caebc463d315cdce59e0de67df69bbe68235fd9351f26c4e3eabcdc1d6130e44742a18435e96313852630cc9342a2b49a4b875fcf1830936aa0368cba7d954aabd1e9abcf044874b3c650b78a3925f3f01dcd959618ece352a1346203f70aacb3f45ad2d15d6a2d8b22b99f55057b8efd22fd8d1cf950a3b7703e3f7a9d5d62af451b9ba32a199dcd345c39647609c58e6f7ad0340165f850176c8e8a1f8b20a96e3654457e20afe0b30db2ff6c72770383ee75a910f676332bf6d35a6310336b2a23bf0d1dc30e7b144207f5b9dc1be181632190c53913d18b6644c3ae00ba5b3eb6a8350a22c87da65fccc233a814c8fb21c3c56b137a3bc6e1ff9fabd32f27c693c043158e445ae9434972083bf45bbd6d5d185aa32e85524147bbf026d686ff54b8b9c2e4de35d32072b394867cb126ddefcf26b63d37a7d3c09b38040aa7c006ed6713c769857354aa7d9b95e3c6d58edd7eaeed2208d41bbc5cda78440aa747dec89259c1644e4d7a41d50cc8d46c3d10efaa9791874a9f3df9738c66ffc6d638736daa1302d70a8919598b15b3b3fad18590321c11998bc3161b033601f5fcebc1df369232270a16a6cc9998035c1c49792211e9941e362e8db5623e24280e5db8d8e6605c0b5a91212b7993b84ea2970c524bbaa78a05406b9282a8a86cc529b6c128b99b637197cfac7d0b730fda3f80c7ba72dfc82c1092bae4efd4e169220cbcec19cc88031aa9b402b4d2c20dce8a24ac33b6dc501852a29d595f337ec82bf16021065a7375483e1b3ea58d0fcce31537f24e640b0607e736bb8f4b83d18c3bced0819680e78fc46b6ee6c10a72d01fa7b9d5f8d6b3d834b5d0c881262e5a44d4ddb4fa19927adf705824de725467817ba6a3fd987cd976c6e6b6c196b50b2bbcc5f6e976b13b26881c41acedce5ebe075020007ca737c21138b98f7625ef4a7fe19f56721cdf21f786f396ee7abf62295a37ff1ddb1c65287dabfc7491dfa061060c6e9458ea231d868cb1c6863988a0014ed6b152438c79c2b74468f07d0de1351172345a9a31049f52c38840b42e67bf68fad5871cff9983bcbd1293f3c1e9bdbb658a1401fbe2bfa9d3cc32de3ca5156256269a6930e40aab9d1a2b06e57959d541694a4d6ef918f1aded4554694b67ad67086da6d43a0e9df85ef5d30d91f1d1f789b444e6e164a0cfef372e5f98892fceb2b5909301f51989bf1e5877eabf3a13e7cc09c68f441e80417b341a7bfb575c4c5ca9ae540a73787ce707b51e03bae956503936d17dc6129b6f83215bd409a5bd9a74b878358d360e311090a1c706244a58a9023c9f94b1bbbeb5e4246bb36e863e9b39bc0a717dbd957c43234cd0c5e9b95a1a0b7a16c47ce07be6bc3f855f7ecd542311cd2081f8bfbd1950b1495de54b15defdb9c3725535a68814d804912fec0488bf1f6f992f9b1ae3467ddc98efd1e7d8690ad4c31743342ea094ac481cec9bf755260e67dc28e4f25def2782c6b1396feea479ad04f61797e1b5bcbb9a826c8db993b8cd56ffcd575890aaf3b24e2f300348a708fa1236dfa2245176014bb3799aa30a6ede2b10bfdadc1fceb863039e0db2e45191b64158cceaf090071f5cd3f95ab7b8f6b6406e6e7d486bbff9d0d298fa8b8cad2c69438951b2abf744428f9e0e1f838e6709cdc4fed2bfa1b5c43ce2ca68edf4f77b5faf89a5a5e41fbb7b599a08fa59419326447c507fe4e3f425eacc26c6a7334a9600250e0cb598d1b1830f1e92c145a03f1c695e31a1540604ea6a7848aee653cd501fe2d9ccf777a655a25acb08e0cc49f039c0975a4189dc7158d35343eefc1959b2a320b82322ea5aa93d9c803816ae01093069b8dd9544b06c7555d5bd74e6c2abf2e2ef6ff04aa1a5c16a7be046d8dbf3a2796df0057a4c012f0df58b55112528630e70caa28b805fda123733de937afe2157c00b8fb026b75cd1787fab07ede1531a0111713566956772a026461ad6fb23c5b56d89c36c7ccf4191641c8400a400b61b83772a4958b86ed63b9d4a528ec85d4b4e72c853cf4079046b05df723bb3fe4f3d5587cbddad1f11ee21df03fcfd312bee42e0c9863009213142b48647691b2b55bb4f102223c033222c8c26fe69282505d8d9d1515e0d302c439a840bc57831e4edd751c27b62cc9dc28f5aaa6d43eb2271e02a3332c885964db0513a9eee7a22fb7733fbe311e815d178d5df6e1801756d4a9602ecf9f3b71b80c82a3997d0b2892c3b0cc0b86d36bf2fdfa132e5e99a446a33c1777ff01c92bf3888f62d9f518004ea21c75bf6de90089224cd0a92d00f9493f1650dc736c5f9fd25d7c54e3ad2f584bdb5ded06673bfc41d213cccedd945b02c0140f2b93906e7f1f3d73905ad4250a2fc1f8a3b63b8557ad9f9d6e2814ab316b37134292de3180caf1bafdfbf307a993cddcea6e02641ed147cbf9743c25d816236c0a37b0ac01086d21d755c4ee3a6eef1c2005d99fb361cf19ea0df5501ff757ef33c0e20dcd317a033e51659af249e1257e7ab177e80573f66a8755d8adf08e69cbc22d11c87105ab56aff00e96591811e19b27ce7a7caab152710df5f3412e525f70933ad3a3bfd9f627d30bdcf34495e493b4e74cdc91cf4920803cbf8120439ec3159ee9600617c2f2043f84617ddd8e31f82c1a413d3abb21b53ff64afbb5a2a42863ee021c8ba4154d8e017374a6ca281f17fc88b1606af64828dc7114ea8bef8b39b5d24b848aa3106f8bb8f09a00a4795aa0d8b9a1e39cd081c4afc773a7959d22adf2b92a316009a24686834f64273d529d156dbcda127c44115897743b34ac26f1ddadc09db5cb27cd946dbb66a846381dc4d7b4c5768429b5ca03c16c19476b83bf01258bf48aa564605652b87fd51fa4252527dff906c51f5304fcd32199db884a5f487ba0de118f0033774b456b4112dd6079754c05a9269ddc4a905a415ef44a1a24d00e918b3dc3ff57d91f4e33a61c0a282cd9521bed291149f1dd37a7a748b0265d00137a8f28e648ee632febec505d1072c542cfbb561836f0146a17dcff0855fd237efd802c2d81591c2d5a46a140e5a571fa16e563220393da247d3e842683b3eedfe885e33b63d942e65b1861c5fc08a31a81a4341c795d4dc9cd19233816317ce826bc3cdde411ada45e62fda38909c7ea8e891801a85a81ebd58a2ecee99266855793c448dc4fec234b0e5e39661de62ce31ae723692dca2d7309749fdaad058f55f6337b6db5d3eff49ff39c441222bbdd14a2f84d997d58a4227acd0853699600f065942d3064096553dfcd6e4b3e6802823c907a0598201be0727b62263d879d170383ed4b4ffc296dbc32ddf619a14148f27c1518f192c1f2280af4b1397a3adda07a5f3482526ed2cf9c1ac4af9191e9271db6c3ebf8d63adaa88bd36aa04a0fe34f7c3cbed5175258b0f028727e713dd04980eef58d669cf9758d6701e68e3225e8a34a410e2b57350c4f5c37f4b547a1ce677a5a204d068cdedafbf44f63657eaf60b27ec276d4ea560faf3f4074e8d0489d293ad84dc742fd63d4c00597007c53fc45f83647def72163de949f906cbfc0509ceb468376e220743fdef733dd3f0f97f46d530fae025941c7868963e2bae5f94ad980a72dfd781dd52b7f2f77e9d22d4c735644f46391ef8a9d22b02bfc302956691330b096993b5d1626d86fbc823cd617130286c1b7e47604c29fcfe52e76af83ea3e78937b1e54abd5d284f276c9e9b80a0ac165af9c4faca72a64928d6e86e795a6f01a047f87a890e1ffc60b390046ad7036afd996bf9ff2db53406c0ce0e333152178a32012db88b02726162e4e356b859dacd183eb9ab5d478ab1a5e5e5579893f591ce3c02f9b64d26dea2ce034ad06502c4ccd0a44483c4ab0cd621fa8683455b133e103c5fe2181f93f5681fac0bde7e849398ab302988c0654b40d91b69d18e32675d8e32b35cdd73efeea37e49cc2efd8d31e5a722ba04d56c57975af32fc0085d2866f06daae82fdd23479f6221896a8888962ec78c485343941ee76162551b0fdcbdbddc14fead4767144f3c92fccd31e79b86f5157337c5c2da9194fe3f2adc6ef388d0ad9b670944a790a58723cab465f89e9285268e84d0395f9286b947c0c9936da548cdef820a8f60fe3938fc70d0304103319c43f122b5fd04a0a3b90f22826c267c94fac91e36ab2572dfc211f45094f4aa7d2672955c73723decf4167698e27d330861520fc3ec4e081933e4dea66c513770254a9113910417fb90c004e11d439b39da7578de0547f98d141f15497395d1799df29dff1d074cb49d119d1e743629a1e1f810285e4d0ef32ac3e086368c5a465bf6afd8bc787dd8d5d7f1f0ad9d218ab6a83b2f233a147405eee13f9b1499ab2de89f5b8da0c3db11c4d8f2d02d7274b97ceaa3f561545baac10c6a0b2fd95ee8ace160f561b285bf5ef6c393b13e3a9ac42cd1a9ec94c5a1bea7c7734ffb4a51c58f0ce98c5414c0c76d5d2d5b8ca1c3a256f3113d9fd04213488ba16ade9cd92149d4a19ae849347fc2108e569a0f2289347d78a825ec1a05f2c8b11097439c0da067476b6d19a12ea866dfa6942c5ac460fcf77710aeb9b61f434b8666f35ab54fc07662f8a38b8b3c2534bf6bc01540de7d0ade8c975d4528775ed799b93652f5542158398e8d348ec32be403b7c15d7a482ce0990efe0e034e65cba275c242c802f0a7ed1494369efc95870c2daef748672cc9b7d68bab41b5aeebdc9cf8168d15b2301ab21e3a11a30c2a1561c2834639d8a398b629d4a8a5619a1d2ca5a2498ed8afcacc4fac615c61c4cabd4b7a93cc91b126df93852a94da379e8a144571fc4430da3f38beada24b1ad654f795ea04175f1d2e77d2bbb7b1b6c8b36d14e251caedf7adacf58b26bda3e57856348ce3d4efd41bf2f5c17f0db9f689044e6ff1eba4ff11cb4bd545e11fcad281a4f10b9d6637e2f027c4b07d8a93a1ef174d636000fa30b38cfbd2a65553e24e45050482438bfd65125a1bc5f289cb4e821bc2cfa82b1287bd2d2680bb0111c56a1bd731cefb21a7ffd58a8eb027d42928833be272c741a67f5c75e74b3169c6f5119592e2c736ee23430c79926476b3c455e37f0b788218044b49a5912153660939d9d1bb2ba481c2c3bd2c2f5ffc35210eab8f48b23adb999912390c8d38bccbd5704f7c95b7ce33ed1d8621b5c249df16ed02899f4a8de149ec6bf485ad49c744f3dab7b24a21c977b6156b060071a305af2f6b5a7dfda458be4f8aaf007d71cb326a52815d2a8b8688adc0991199634a75997732ea1cecddebc8275c623b094795d5029a8dee5135e767569f72166bbe06c7f15e5cb0756bfe17f2c5a96756971bb640ada85ac15711a6abec03f4e0bf067eecf7e1ab44714ba511efdc5af11726cbeb6eff38c16bd6d5e24916139c434e52c789a3d76da81f27cf5d5c7a4a01e0fadb8441b6e3f938aa6dd75c772fcd3b66ba5cb2eeb1b66d8f343805712bdbe1dbc359907263f90a7fdc7958e7fc514ad914383aed1fea67b6351ea4a0f22b98d67c9d607c89fcc05717dbb3f67ec43beb9f387cbc7e1ee214ad02c0401a198f2c5bd7d9e7945d0f7b8818990a9bdc87f5b123a342458acf27dca726290cc027c874ff03f57d13f840293773a63f0f4aaafbd961938b18480bf8b140ccf6cfe57bbca7e693e15b4c504bd3d3e4bfdf5051ee10fe540cae980ccf5bf7db196fbef7142dfac744aaa1660f86c8df21551497e14532de29377b9708656250567b127020c2923172c4519109c99260411799a21815a41d35e984d9af778d83be0c42b8d3790c84a2bdd61ca8bc53efdbb7ccc1c0bd3b5918e3d3e7c8cc67a54e5de558059140741aa9ddc75a3306153e8d5f63a10843cac5e81dddf8949be87423677ffaff9a8a7473e5d7dea5c23f300981817fb2955ef5ad27becf3e488f7f3f6f4c4b5054aa778844638705ac4f8bdd701c38d58562cbbeddc85bc9694a289921b071c650f46f8736cfb0bc6ed1b9104a515db7814f9f7f1ec5415782b69f64e85bc5b959f49fd9eceb08ec4f70c0b605f16fbededa35aedbc4463368d77694b4f4b683e472eef36de641a39e09f835c7b627106a285a084de8a8b8f8b0d065428404c5e4b5054bc018f526b0d8ad3969c15acf779bbaaaee96e9d8f2d690d163f2e1d75e7d064d4d304d8754779c66c7483f6a1a7541acdd118ad0999108fe7fe2fcde3dfdafa64cb7a9df117733b27bada89b92932bc29b2b33ccbb62e544e9b50223b8a44d807b3c328f763cbf4e6084d1fa03866d1a295b894195be5e11b88082c26044e17b870ad8a1e822c65f34fe0b8cf59e5d21f98adb5585ff4f52c86511911f512f31b41d1114edf2b60965963a43366c08b8f1aad223b9d8494b676190160fbe82350b9010e8750a7a8af183aaa3b1913c34e1f8f51982ac74616a6036bb03510c67db65950bf12f3df281b31f48ef7256b08d8bb89faea78784435e40c203eba007504b9e1e1317069cb0da8c5f9d15191494c2dfc4f6bb5778d4220ddbd87d4a0e03c89e72d04c29f4cb0581cf43be3894624f4822741da52f9cb4a37bb5cee591279d7bb75e7d4861afd69515889318176daffb49fe2e95a4832ebbb974a118d069c39e69d568470a48dcb063c250653387afc3cf41ed437f8bfaa436a513a26f357c"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 2,
|
|
+ "signature": "0x396a36b66a0a22e592388270709d8157c2723ef44785eb78273e04d136262e2363f336309e5b727f3678f3e4a9762eaa10ab21b3126953c5444ae59d76a6f2b752a2166e0ed214ba9468e116ffbbdda85c03c762a2b9682a6e93f0520235067a15119c620d3c8cd56c69064277a3d7510df62cc91cbcfce9ff20b36c22c19f633ff97f7fdf63b756ec3289b9a8d7adb4c385164a6828b665f14e1dd7c7319dadf51fe90658945a902d0a29b8f7fc38395847baff0983ba3928069988906b99751d12aa3c536e4efe87032cdad83b91506e080182df4151ca2abf9887ca157599469c28f549b8d343786c7666531cc4e18e6235d54962acc31e711318dc619eaf29d4ccdf3b06b430e2b82fd975e73e38e10532fae497c64e13e8622c5f9aa41a3d5ce655a3c2f58c824bcceb1548c662e1cd9272c631268b8eb91471d0acd73add4bc2eccab8d36c6c27030ab175146abafbbcf0e62bd1c8d6715ea34df30c090de1f4a9ccb3d7bd5cb05b4c855bcadd5c96e43a89c7934d49e294d954e0ca75d677a0695cb7734f8d404872c9fa64b20f3283523d1f2f9a657a69d89a9923bc3ba9873e9d1481e89b8d46cc6b72f8df5f0e66f346e859a429547f6e102f8342bf5c25695b5cecb508dc8941934af2a48d04451048d4060a92cb3a8e648262f0fa3b13abe7758d250c85f657c0c7ec7cc8d1b722c233404e8b3792d718b423c40133fe5250a2cbbd6e10f42f555670e378236ff4452a04d29116bfe1a38c2593215a23e6a90f6c083cd84866554e86069d2e797b6f7c877b40370ed1077ecd03d19859dbe4a4989b47d60691776353a9b17ec1644e0f0481356c923a4118458f9cc29ca6c57aed3f0cdb10f079216523c4b5d83e333618e815f3423bcc37a923266bce432b35ea1b168671accf68adbf74"
|
|
+ }
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "round": 2,
|
|
+ "rows": [
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 1,
|
|
+ "signature": "0x392d747efa5df9ec7976b575ebbbbc4e50e48f494255067d00c8fb6ab805f5dde05d0240f101c33dd0aadb317a173e25a7dec0ceb77ce150099f5ca19dc2df6e44a5b5fc87cab441dc4e6ee717e77d3ffc2bc57ea828567dcbcdb8831dbbb613c0f747fc497e218f903efb5f5c5a2c4e61879bfb069a67eec30acb8af36d1f4a245b9f120c6bea336d8ba3eba72be78a3ded415117b3ed0babab6ce775e1c1ebee9d08f4a0923ef969747533a3a9fc13d19b4c5b1eabe6ade431ad5731c5ccfe98681c31ade95e7d5bf469024456082d06df3fd4e6970fc2533bb9cf6688bb595edacd95f68d1b31a396d8af954e37fd43d6a366757853a1185d62e18587e2cdb51f0a7023f2b3cb9646ffda39e46e98c47f68bb3954a140f5bce405977eb8974c229305c2ca3c7017891f208a041a89d48d3344695cd9106bff8b80a0a48dde46ba4ecb942344cd1887e2f889a5b97e96651dfe7d3116a2b17a86bf11be8ab8bb69f214b7a0dce316367e827192ec0e9a0ac2199b1c4f1042655ca7cf3d1f8da99341afe8f0b1f21338492ecff73f65239f4ea6a5dfcbd08ca9bcadd559dff34a6a8cd9a28a579fd54384f35ceaabab930b87b14779fdc822a587d04910b4d693f288b26d56688e5ffb2d65d9374a32c27dab9778f618df54c15f555f54828113a595fc1ce107ad2ae7592b41e944b0cfe48cd21d36d4fb35dad4de5ffe9531f9e927a25942461a4c9726a292d2ef9dbc0b1d0456b703037b4df9d0c446d707285b9489e8845211cf0e8a3f0a32a5cfc713902df29af2813293a48c2f02b8dc336befa797d3d3f67d90cd4fa25466bbe70d394713fa06b606de967d5a5aa9f8d0310363f7be1a75708d4c72511f67eb2b0495c43e75ca6e085d35c53cdac3cc09142647e68fcbbe921ad25080"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 2,
|
|
+ "index": 1,
|
|
+ "signature": "0xe85ef5afbd04ae28867b1e81b818d79445b1a8e98c272154ab5e8a7797af50d972b241bc0d536481095419bb18be70860dbe9c5d355d74451f31e27209f3d43cd2a633cd961971c381058ad667a9b2e69f0fe9c2a557ba89835fabb16decc1915b54de7b5f00aa5787a39e8d97fdff315a7a0d2aaa5d3e10fc1a02ae74797c43a2719d3361805f5415dbceb716bfb7b07ff4a415a938008f0f9a668395801ee590a83b20d5749facd7f99bece768e7e3adc0e036b82604cf9a9e5c7010db9b54965d094ba9c248f9f4e29045be7962aa6e7243d450caee40bc4dfb9b333e6c289509f899b254d85539a78f1194553bbed9dfca1044372ba2530f2b05ed4a467728474a1d603eba54e4fcf2295c6a559e9c606b6b70c40d4c8cee286f2d79d6f46a8c0079130c2f58cbf4b3ec7fc109cc1ca3dea2ddfaf377eb357ac6b5877aa6f2e1f56df3421daa6ed5d043b5188c6ef1c71d765b3d94815027ea7838d8f448d0fc008d3a0189958ae6fafac687990f5b7d43c103ab97780087f48bc3b7a19f76a945a0d90e1ff279ceef8d32e2b5fdaf3c5d1a5ba52e60dd934cdfdc2492330a5f150f2106ecad186cf1f6ca3907707e34becc8b442ad3dc5ecaa7abfc7bc19cb7a7664ecc127c1d4d0f0515eaa3099def31f3ba376c30d4044ce8cf7669ca465f140ac5ca43f9e856721be03231e6b0cbc655c03b9f237036a504ba29da42b5959029b68f0171ccb5d1a2ca379250d3eb5591ddb52333b954e152e644bf8c8c22ed3c3b471021eeb4a25f2adc63f792c01382e9c01693c4dd9ad333c198e4da0b8af182bd87d2919f2bf4ae94130931cebe0524c1df1cdaed0767ae040ee0f042ae8b2e0674fedaac068db64ae2998f1e29d4fe208f3ca498a1832634f7183a8d6902d86823e12f5bbecdcaf9935f808d72e18e62c1a117ab27bc9acc3287afbd6f7442f4eb48063a381495170171af2d76e3672c37462bcb6c1710afcc873b9168e4bb6887117a9925e3a2b2bc33d0db4fb33809e3768d47ab3b52bd655c71539d8a7e391bcaeafafc71c554e0616d6f6d9ddac0285ce5b9dd9bfe015739925705edf72abe615a376e3fadf3e5807d97a7ca5e4a378ead2a466db9773d3a7d3f7627b29f1183816edb236b4b20af6a212b9ba1b86ed143974777a3de41aaa3a17371aae38dffd3779f254a0da8d9219d98d89049ad55d71e731192bb769ae72e466a67e82dc1b133b9e5129192e2e611d8d8035f6e0dba92d6cade096c56b248237d9405a534d6205e59186c1e5ffdb1dfaafeadc15eb2d11c736b0e57ceee75c6ebdc78c2ce24fd852e87eeb969e14d8d2aef1ed623914bd1932d8dc26bad8e6b3b2afcf8139ee97a4afb1db36a23a94f0ba00c6c6ecd072851c456e72a69af515c7e7d872ec112729168879f1812c9de0cc380a994182a80e4195765d53eac82085ea751cb09eac5f9db99aecf51e9111515b083ba65cad1d6687363c3155f39e5c7124602a879f1ff153f4ecddad23ba9d99384840272613f40e8975118e17a50a27029b5714cf9f3db14c3ded35e31b45fe73fc06a7fe8cc96937ba3e82dcb226be47e45bb6e971ef5e7ba2013cbccb6edaa51d3611452f3c26860232193512e1ca915ca1e82d1e81da1a84b228d92d855a09721f662ff3d58eda5846977f40d2f6fe0845ad3c8cc2c9e6d9e673673d9245f5e55a2f02b6e47e01d27e809572a003809b75177880cc5ded3fde42ac59eeac1f0508eda86e4b4eb7f2de0f9b8500f766798ac7f9583cef34c7faca5efc97ded5585b0c39e0f16fb2401fc50a588017ebcdae043bc236f9309bc4d6c04f089a898263c7897feb006a6af16240547c96bb52d275130bfbeb20f2493713f29eef0455c41134f4f9f27c38d29dd1a2fbb6ecc40bf41d9f32e33352443c299ca7ef6881575dcd4f18ecbe874dde9e796628b21e6a7dc6827587c61fad8a8fc63b886c6f383243a20dcd95fea8e323d0e9811bccc2fd97cb0a347097ef1b5296ea8da5361c3df81672bb179e51f41082ccbc4c4f0c2e2eed5f8f131a2d58aa68caf0aa1a6d9c8aac9f424f7cdd2acd2875d4e0238f35c70ce48c966e114344ba6c5403545a4e8a467bf9cf7ebba117701a5e69a2e71a546d3b674468d4a31bedfc6e70fc0c4c8c3efff332b4b8e1dc604541091dd34a584d333d7291304c08286542b0075f371429605798bbd71ed7ca52ba6b812c7ca91c8c35c2a4f853eb7509c12049150eb7abca4498f5ef4d8dafef8998afb4527b65cd3e6ef1399041887f204cbc81fc030e6242c4395e7752a6545da4996b69740922c07881c1d5bbdc79beab8b17b5b0980d8fad7eeeb5785fbab08a7963bff7e95aa7b526dbe201b968a40f8db9399e7ff8aa18e6f095b9aa4cf4c41e57a78f10f6fc580a955e84f48a8c2b16d13b8b8efa525f1d51426a13325ea3384a5638577f32267f00e2e262f08d46bdeea4891ac5acaa3e3a31fd503dc76a3c92ded39edaa65043b60d52ffb6ea27cbf810899552d4dd5a55e95e172e267be645a3f2c6468b5b1ce76a0b951b85f98efb93aca8b3948c43cbefe76504f90128788e7e08f7f6685ee03b70ac35314d3a64a57a4a8cb7512a9254f3a9aa7e9c1990606ce8ca25e6b9c816b56903e10d7ca1db41a7f991f292acb51337230d0a0ac5604259d7daf5b684493ce3344a8892152fb6baca94f5b02237bfdeef0f9dc6fd372b078a05489f81ee232e63a27726746d52c3d9531bdec03f2d4d56b604231b233592babfe12c64b915200f1e16672b0798982293d768278909bb1352dd42381d7e87c15ba92aae469fae5ed023c643b45c08a5d15b29f34714016ce5c52ac648d4a32a4bb02c701f3a68fb873581ac392ea34277ff3262fba6ecbe274c840751ff28235fb3168cf30bee0fab5cb92c89c8ae3ffd8b03c4253078c31ce19864c8b6f128f6e3e80efda9141bedef5b60adc0d6f8357fe6cb6828b3605e02275deabb5326eff3d52861f072523c5695333b4d51c58c08a44be8e90ff8244da37295e1a1550ce715d08fe600349a9f9870ac83fbaada48cc392b75ab1ab456429e5b236f6b3b1751063b274bf6a75dc2283ca0ae8db757fb856e8c7442e4a3cf6f26e608bca09235f05dc6a2a53862cbae5a5bdcf1bff925ff3c25e38d5ee04591b8c228b215e5f82c21f39462aaa6c548c8d581b4df4386b97fd832a46e2212a3bc5ef4716a10e75cd5e46797dc12241bdec3074d19f971caea7a8f24bc522faf8322301e3e4d2188136ddccc53c6488d5d9df6298befecaf637a2693e8d3db2ed2f8e120e6f1ef5a52471e905bc7f62a3b93b534c9e234d72a75f38e443a05ff62ca45cd25293c23e4ae71784fd1649c61b9469eb152642d8fa2db77b85c26340f4b21b1e8ec7ab58b66fea1397e69665dd9116ce6ecb7d642ec9c2114a4c893b795c1be06893697924c42ed8bc97e0c930898d80e71536dedd3ddcd9b4b35ef5eb462ab984b28925aef1cb524439e36273f7056b17036a1f3ab44eed99199dd6d53b564d2f210a7d52ca896ef0af8de172415b518e92c578d256729744bf79ef3ab444960189cc0cddb9c961bc0a7f0bc51be6ffdf2e057331dd7d05eacd8e6e81e08f90b96539b9d323455428e9abcea706fa357949f2d1067b600af355d435bc71094ed8e29d699504d24427639b4d612d3d2c7e50129145a161cbed02955a0f32615b30cc968c41f2d062c32f796da497b379f5955a0ed5a653ee51f52e6a702b478a9a7af4d48fa25353a258e575c2e0c475b169df4471c22e2ccb1ed607bf831eb28e4487ab655f07520391309d3590ad63436ba31d1c37ecbf586dcaefb56d6110386d6a6a5d785b365701ae291b0a3d13b3dec21729e42591de8ef9f7a7216d9dc23489a3fe8d874a76f146aa26536c1dab083681cc00e9dc9e6603d53d74a1c79558c6fc7bf32d98a485dd562f261e7d2751fefc320c5a2c9a536c84ba467d7a82df93b5803cf60a2726ed8fe7287863fa2a674d01c77b053bcf88a9a502b0fb786f47e50401aa643394624968fb5d5dca34b009a3a32bdce673fd2d0c8e05238b82ee1479cb9b8b7007ca03974e1c56e9bf903c2d0c274cae9f588fcc6b47e02754dc0e7de3cb5a80ace5f98ae68244082144ecbac94d53abb9c89e7d102063107c0ddbb6633d0f987b14217a9d9378007cebdb260a9a89596b11422ec3f1136d469e3c188dfc94ebb1cf8c7f7decfef77995e8334d4321525ad76f32a2efd4c953a319e18c4da8981ee89415f7e2f07914d4fe63d6246504b90fbf03b54bd905661705fb65d00d28c530b7b3c690fb5f88aa1edc6f6dc861d79a1e8c4a6dc1df27b7c2f0b897f1231f176adafae599f4aa29c6a5070103a24468677320b9462cb9a2d40696a5966ca205af33e350742e7e50b27252d2ecf50420cd4fbff8e4570e04b2137722814c64ce0b81d13c14af64eaf36207ae8f9224a47b3c3c0c0996db171544bbe11f2407203eddde94614c9d41945645dcdcabff12cf2fcd01cf062b942bede9184d830fea37df7576b10bbfabdb4a4626979576f403f33060ddfc6f53df73ca618654768001f1e08bbd66de39e8eac625d4f1deb25681c2dc67c6764d555338b4293102191a96cffd8859eb08ecda0489af07c301c12913762fa3f9d192f74c762f50556726c3bacfccc66a038536e913d95186d8aecf381312733beb68b6cedad321fa4e3fdcdcfc5553548a30e1ecf0041f823ec863086c34b3b6e6a7af8a2214122332a4d27392e64cfabb1a9c66c498efb6515f32f01f23073693a37a72240df9709d577b3e184cccc8b9cbf34669b0653e16848ad0a9dbc9d7b0ce3ab88e98616492c83d8b88673aa6a1b93d2f7866caf1984da384145361fcad93640c7481a085b0be84ffb4870705371cabe56f82a233b3d5aab737a2f2b9877fe2885d48163e6c55a53627e6db0a9c7103c867bf829633af2e1379a537267a15765c5ffbf7457eb853d0049f497a7823c0489dd0a1490667b600ccc80f9ebf9afbc007280e4a93b4c20dbb07c10ec4646ce9cd1b3dddacf5ec7bb07d588501daa9ee422da47b4f69f6cb49b3201e1b461b5d4d60d4230995acc88dcc8c928251ebc8d37f3e0dcf8218bbac5e47653e510b270586859238c526c46b7db46e817e467c7fe3f41066e234f4756ac833c9d010fe800e51106deae8eae63d2d9d02c2eda4ab19d63600a5261e69075cc0e28220a3ca4cbfd53f14f654c09a62f6c70fa75368678a7e3936aaae6a3c94d800f95888777bfd394907860ff4446b285345768556f34b1c62cacf50b4ab820d02a18cacfa3a42f086906213e170f26a21a0c7f478d7dff393d68989622e4f89a46845984d1d28ef6584f13f135d6a18fa438e635f7670e3b9e0236d7dc9f99328a807e4468fd7438c56449556c1c13e478072602172f923d0cdff16786fec072f0629a0423025594808ca65d0ee3144947a44519e04b6abd779dc2d119ee4473103e1d608c0e254e0b7698bc876f2d810e4b41f37c9884648d0536069a80f9891d0e2ec4394446b70bb0ffb8032959bb04b82e75f577b8c136b6c87d1f98a962955af7286e4f1a098adb1bef56655757dc5e24cfea40eeb8f37b57edc8b85685c7f1681108f793b7c12df1a203596b57c92f9fa62bc9a1db3e7ed9c802500c7e305606fb82ac11df65c7e40c1fb09084fdd390f55a94873c7a32c0c9d389206d7695220951ff3fcc62cdb39a015649bb65040a06e54111127fd947f344d782f99b59392660917838f2dde4b04038b0baac6966593a8ea2eefa1423c4e9537eb804cb7d58fcbb1eef505ba06b1682cfffc4eab227161bbb9c3aabaec99f2e08fa650ce99e9c02745927ebaaef4f2c70713c97b34b734016a65a0e69db084101289443770fce47722a4c1af6ce554d09aeb9b3e2f076fada5f5fd9c772ee2cb65fff9da7b33e1b2f6a08f1536a403188c771fff5a84c8bc1509ef2dacd23cc699a242f5492bbdb82f13f4b9766cb1465d3d79e5ff9499fd812d346b8ac6e7c8cb83a603250a52daa0a55e04521f22a4246c5c149bb3426639d84dc651f7246d11ff49a2597b9a77104bc2cb1880f0347f2110b2cf33866aaa6bcce8e058e03aee01191adfee651694b506d952210398513a9313836e1457e5e8de9bdf26ed7301c3b6578a291d73cdf2602f6493e7685dff5e7b4db4c0fc151e253009234b251ecebeb10c2facce66e125b8fc8c6a78926dff9dd250037a12aa32c086c155f980601ab25de4bac8ce364c7fa8fdd965ddd03dedc8de498dfd3cfdc86b0b56398b10245dce984f2c5087610efd29aadec6eb78c18956d6912203f7016f3f47452578d1b718b6d221b38782bab9e29b344dee9deb594d8798a6a01296f5da1f143743c61c402700fd33904b43d8d6a44dc6fc04fcb9841544dd9116a5b908f06dd39be385750a4371f7dbce8b9b75aa01fcb4d2a1a94f22b7bf876153543f410e7f8c1504aced875a2e054dd5a2138eec9607d5d5ae7bae91da662c415ac6f0a9bb981393f660695e4b65b16dbaf35ec0d40c68ff4fd991e8152e03152c332e92a62c2bea76c0a239387148409b6a7c2c98c24b506b059869cb911a30cf15c22e0ea0f86db884040f7cc8f58b1d3fcdc251d223a285f191ee4bb2de83365ef74726c7abfaa9146c308530edde09be20e9d6eaeef850d00b165e768463b8793a914c421bb81e8905938540c64b77e82ee6a4a6a15f5cfb1df20a41305ad3dffafc7e8d882a3c9e3635d115c9314d8f3602ba752734e34e188c3cf46b3dd5cd83bb46b12e1ec2a8b9d7dd5b61c5a9f4f0704504e2882068034db62e8a9abf3c7c5b9a8bfde509d36899fc5b4e5bef940fd447b9275024febdc9a91d6d56012f1c6a44f94b96397ff2c78fd617870bf089067c6343ae4270f6e6dc495a260bc1ccd0a1c0771821895d26dd66a203825d19e621b86b57f9a51bceae9bb14d1f9961c5a904a64a1dad73c89129ac4920cc4e86e3696959be3305f6d5e33baee00c7f978bf7a1a7864ed89132ff350b45226e6e4db39122bd344c315208edafdfe6b567677f869b64532bed2f7f9087e3c6c1137004f205ce1485f1b9c3ec798b0509c00f6a2b6663048492caa3889328ea6216e34b959fd244249048cec8c0f7de2ff97105ad030a536ec6c4103b33c26acf4539a1b74a0792b9b6c80f95ee4326b09934e068429242495e51a49a712f8513ce91da60573e83443a0e12ac2a174b82d090813b930e10ed7cd44ed72d20b061e9eb253d715408d79d8a77d67919bb196dadcfb84bdc4eb647a4ae09c436d220e0ce914188c49fe9ffaa2fb87f08809d5021cb632a6642bdc1e3664e84dc0afca031f0150c4190893da6462dd917655930a6d1deebdf4a0b1e461126fb2d54d374e4d5a455a6207291d03d2d138e34260ca0ba2286044afc4d95822bead1eefdf0509cb4a0c09c3425c8b0e9236703cbdf4ba833ebea4942d4e0ea84df284c438ffae28b3ec7ded12dda8bbbeabdd07bd1925912aeb74bfda42a62f8a5e716949f4a195f38c9f7a041776c69a7a1599d6880299f50c3b75e6a9b5e0314731611154d1f755a1381fd7575a6b34019d37c40aabb4bcd6965411f48f3b893e5627748deed82de02e9d47af8d3a087f661dc5f2c65ea16fdb6455a6211c77fd41532017ac4aa17bdc43e33aa4bf6ebdd453fb90b863aefe4281691a736594d714bdc26520fb954fa4a3c8d8f5620316e7b8a3b736b28859514bb2ac434001a129975e0f53f473c41ad752670598a2b356feacdb9e4a609a44e83167539d4e3223143d19f79738b96a27171009f17fca174a8821c3f0bd7dd15b2e98eb3fe1437dbdbe881f9c86c0844db5ee82b627c519fae5ea7b5dabc382c9938529dc031f8cdf0ab320f479d8793081f1ecf45a2af3d339db470bea05607148a060348cfb344edcd773efff7645f021d67db2dc0abbe9a8fc343016e9e57933f642f487d649e3a01ad4f815fe3701750d67b1db3c74c6b30f7923d08a807e78e58aeec28691475bbe4260db35b8f850330fbf68f73f944b745208748261f32a9ee5929cf924193fbca8f7d15d0118e3ef205f6a639e4a25bb23c28f036764ba7dfb4f8203eb0b69e757fe5a40b560cae416eda6195f15330aa7f4ea8cd113c30583675a94c486da43a0f26dc5d922aeaa8b084124f5c5dbd0ef31e4ed52de942b1f8ec6b494fa9e730e8f0cac9ea3153610e13ab589d8840e5ecef5570b619574477e457c529d431a48fd3679f0a831832b9a1ad4cb6c99c25e0c1bcd2cc73ed79b2a589501e2abab2d2a64c9fbc4cd8bf14800f8a67d46ef10a68db32411d63fc36e8125bd0e79b27d861324afa6929be5cee98c245f0af5755595f60d29d485222c4a43e2614d315723c5eecbc836242a028053ff8a4c83324edbd6899887c3ab3394d5725effbb55ff056c35fdde91c28a34362aa8ab06f0f1da408e7be1863ef007b57ee062c5e660e2bd221a306774e7b7ed5fe5d04e3a2fa49a61a9d15e4aea12bfe588f7f7fe357581772356998126b1deb48988b56506eb805be01c07f3706100658b5be1e96b1531f8838d78cbb849a4e51c1a80d3776987407c0a1610d43178962c5a34cac6a62e8aaa963b8833549f8ef954e155f962b6d6ea4ceaa9f711959fdab71a74e8ef57ab16b477bbe47b78718f8aeb29239958220b079e13dab8f77ec24be4c3df3db9d9e306c9da8bcff284c27becdeba20ccbdf94f7853069c936ebb209f2dcef4d5b0c73a68c5bfa67a2366f68ea00603ce2b1fbcb897e80b1f7013d50355df6e989c660aabfecf886ccd69d86352c81350520bced1a2beaa0dffb1362c8b3857f1f1c17393fbf45ef639b1f6be41ace5f1e132e257a96af92727bfdba6b1cc09864c5b085d13be7986a4e720a49065f1c70e140f69cc462ab7bec075108d1384f6935781bec4dce9efad2c8e238e7f41b8e430ba231e9e23c6af52bb0dea07e6a0ffb0a3549db69ff05b1c7d57b1fb5f98b75122b0d53d038a37f3c499d9c891fe571015bf6fae1f27cd1c4790f633cc88b9f018bcc79e1857328fdb72eb7e0fc50558e2ab338fb902be7535c12c0235b21ccc3102454e75b20d5652231393ee2f14b5c0bf2ec8a485c02fdead3fb371b41f43d69a518444a92a6967ef3846db7661d973206eab07fd08f69b5a3a36cfe749acf67c2db8df7994821df76a74d8a36521cc6f4de3e1035e18e9640417363427082daf240e71f60df231fc22b8175620c74e2899eccc35387901cf57f8ea34d3f2a4165a4b7f9c41082ce46980480608c539d7f248a41c1ac1a7d5d28884b7ef5d184938d94dd473fa28ba674ce934807f56276fa821da3dfe5f932bef6565aed54f5c3517ace0c9221214417b2d523ddb65eb4bf68c547b4c40ec52ce09c51e1fa64422b21b412a8cb416db685469ed047e2ae26ca06de8e10abb64bec6ca07884927b51968daa05573e35fed3d2ae343126287069190029b9a7a724c177057dba050c3b18c0222de84a50e2413eea9a12f50d94ceefe48995ddf907de29a46ce561cd8242946eaed26474e50984ac005be37fb745254f3df97f880cd24732a46626bf4975bc6c749ac1c75833ed99b4dbab1d71267b82758229bdcb11cd234b8c990478de16160cf4989df335f646f6286d6f62f350811942df2f645afb14768f50ddf221d8e029674d40994c2ec2c4eb12f9ea6aa14d81a0bd8c3b62aea41877104ba9f50ed75c53b5f0cf4d913b7878b38dac9dd45abc35feacc53dd9cbb3029689cef401df37529318390341babe225094f268a886ce3bd6c6e5bee7849ab4f37c11505c9fb71ea7ca9db1c882dff90d91f1c046bc0b2306f341126b6becc475c6dee4d5aa9bd77852316b72a9189a6c309002f9be5296a0307895a6f729d7e3386cc9b18aed6b2168847a160c11db23400a80d3121febde4e480f2c7399dc71594ddfafcf868e60cc97ce8dd6861efefd9f92e61987ea7aa5baec0117866c387e07a798a1efce156b5ec8ddb3794b3035e34544e9d9a447c9a57aaaa63766fad9be9bf6ea08aff67c90792613b5b54b483f2965cde93f4b9bafc90e3510bbe1d3bc13ef88b08fdabce53bfec8b26eba2f09f5701915cf72c095388b635c8a6aa14d9c1d836367860450591c35230ed1759928b80575ac152b97ece0e025a283f62ef90ecfa1f3a3eed39068ca91d6b0f35f22edbd54637e29382244c8dc62e4714d6c729a1825dbc13e4e245ea5ce221e98a8d25aff7f65336f634f944c5e33fd99cc20202fce700fe053207ec9a73237da10ab2da53ff5f0ac0adcbcdfd31a642dd69541b7661469a97e87fdb91f1c9a533e0cabfd12e0a015e96fb3f5154d6cdf4e2a593780bcc79f918bd1844ffa62a0637c7957866e779e491d864b409627129fd5442cceab809755ba78aa08885e7daca24366554dc75839e75a66c30c5937987f197c9bdf377b3eddc8f24447e96f17bf8633645ac81ca2baf52f4738a52afbe0b12068ff44d5bc35a3f83986825aefaba9fc29ae57f74dba2d3f24d3692bfa33beb46b75449dfdb162b0ca5afe93d3f54d897c8aa7e3f7fc9f632cd348a47e1837e3aec9da2fb675b169af643854a2714daeb2f060480d18f0fc84eb1becde4368c2886867a9b621ac3966222ea1a5c1b2e2aad5a6d24ed21533c91f9a8b019195529a6e08eccf10f40563c65ca50bfa78d83ae54ca01cc21925375ac8d10de1adbe763ca9d885e5b28565332d184878947f6b89a51db652ecd0155625e4cd472e5f366dcf79b36e79465ca7a3c236f3ef8c4acbd83ccceb8b19b91855dee1122f15627c57eebc26967f4263434b321bd4cec915975821e08f9095ce6d7705493d850c0da356fb8cfe51395d1d7ba7efa5d4f1cda7b735f13d0183f8f1a282f28a24ca0f0e719b5e567186ee1255d241e66790bcab2e55846085d1f025e38a2d36ee014b40cc2c5afe253b858774e34c026bd8dd65264e08df28f22498f88e64aa4d42eed7f98d9b81b593b9adbbe99cccf617f5bc2809198bdfb460e8335eb8d6d94e278a50"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 3,
|
|
+ "signature": "0x3941e6e79ed44f046543182b5bc91c08ba91a53a50351470a6a64215b1b87c4487df0d23a191f8eb1429db96776bcf42b0ee0556ad1fbe54589ed283901d3269a783e1ffad95d3b98c52b6d6de730edd4c93a652f53d76f8f3d343f04953d81c43c9e96934df194297fbfda8098baf1a277fa49615b9e429562f2b5cc029a76da5915d35c96922639f5d2f3157f5edb63918b663d299a2ebba2727117c328d73f83959a82cfb392161c98ceb2b1d6b8f0b78ded12dcad63da02414be8c853c5a7186f13d6c8d9f7f738356fdfbda49449bd2873e7fc5e3d7135d59cad6abd758dd954c72b9ac2a52a9f4d40e675f17807f69af4c7119f4dbd26492d194d64a18334c5afdb8d4ed18eef34578d9a4f9bca31ab5c6c6219a3a2fa5b9d29feaca1b37c24115d4fbb2f8a8282df604b24a18cc56215c791042a7f28eb859d2e57d43ce6cc50edc48688a0e449ad4aa6f5c00c72dcf0322d2a022b7fe495028bbc89ab53982595755f384b4bd723a7f49d77a7288b2b5b51ab4871624132bacc0fc1315250635bfb8bab3efa73b75b890b8701a48eb67ba421c64e50d2d6c823b7ba0e8a6bf7b371f65e08da37ab9424b876910fcae73aec09b44210aa4a4b8e401d055a9dcd5bf5e4869c72b0eb51a9d0a1e3405cf91564554a549b16e1a6b9fd90f435e2d652b45be313ac6b7bdeacd499bbbc61a00f4efa6932b3f01c0c24f7eac31955296677a50fee299536aa9df12168f3e91edcd2b634eb8fd6570f99a24abddf4d94cd77f2f087dc905dfd0eaa228c436935cd1a74f6f9d72f0ca11283e15632403d786258cab7d224e99e7fa7b59db465f26965532450cc5260e3951a32102795e2d0d5cd968fb356e142103f5204762e194d130789caa35995091faaf9167d3e3d144159b659a0f673dfdf2c6a0"
|
|
+ }
|
|
+ ]
|
|
+ }
|
|
+ ],
|
|
+ "messages": {
|
|
+ "0": "0xcce50ac23422233040f0fda9105a626e3160b12064ec678b34819b029fc204a1",
|
|
+ "2": "0x9b03be36eb916bd6ff4868240bfc66a2631dc806818ae44db48178aefb6a997b"
|
|
+ },
|
|
+ "bytes": "0xf9481a93414552452d50512d5345414c53544f52452d32826d618203e8a03333333333333333333333333333333333333333333333333333333333333333f947dcf923ed80f923e9f902950180b9029039bd3aadc5f485f3f17ab3ef996de30f40a4dbb98f4c70db2fbf505d86835dcfd8e1b067a325d98da059a8597b2e5ee62751d4fd8efc9985223f68c9b2725df62d7af9b091a129944bb0d86464ae20b5bd1c5cf3b29bec1fce23c562d6d8d3ea81215b2a061f05e1ea271c4f5da79f528ae113bb9ba6afdaa1eebb715d3171344fd4bce746d22de14f5a0454a7e371086667b9d586907f6b6969a528ba9ce5ceb7c8cbe30c939b4d76d3eaee2882cc898f374b94355329fae7e6d591e9166d7f71d9c58defb0bcade36ce313d62519c41a7973b149b4f2f8e51d6afd5154eb794343a3acdcc7436e4ff22dda41b236295314daef2a4b98c5343684e20ee7f1f6d27e4a66eaa79ce6a32b2fecf43c43237a40f3545f4af5f6d93109d8e15da5f28db19eac72f8641d14a079198fdf9f8ee292b2d0fc7d3fccd68525dbcfafff2a9d29a3cc361e4674d29e5af5ee408adc0d9725f7939065d0ceef4a4b64c0972943a69739b0aaf57562533888315d7a5d24fa759ed5661454ee58ce491e5f2fcf0d07608f524c50f36cab968c1d8cbee3313a7854744d1cd7e5ac70e20092bab2e5c59736351d014d71af7c19926b232bf1bc36676f81a1a6f7166e97d8e066f6a78d98f13974beed35449f3d9506fab1c0ab356b092273b42d4aedb6cdbedb736e6928fd2d4926b94106fbbf0923e3b759e1fb89ecaf24bea45bd406d509d611550061897b71c39ea3fa6a8f47a50a31849546df90137114491b55ce36fe1d6f64851c8647eb5906d13369b97ab5721a44db1f9d7712aa45c87f5f8b8bef5c92a9f715c432ef6262c8d22af0eb2943e40cda27921cb865b7d79a4b70ec14f7deb96916cc13eeb764a5f3f35189a9bace816de3f88b57aecea4ad102412e121f84ab7474a04d0c0d92526178821f0dce4f91eb50280b91eb0b04a645ad8d00ab495a1abf55dcdc235878fec9db0c64b021945e225e20fe4dbd3f148227ec3f11a5241706c3941ffff52adca321f313d8155be79374ea93e2ee9fc8e91b95cf14324d936cdc4cd2a54f5d499562370820a04d141492a0e8cf43aff6ede6640aadc4d978d41025bab7d9a76d7b593cbb3d1753bb84fcad1bfb64ce0a9a708fb3c183b39e94582c983805fa040dc6063f3311c3e932085b964ad6d608c689ba5d7ef452c7ae27bb66bb706a6e413182d029285acaac3252c309fa9eb7da2bbfca67359d74947416a5d399a50cef4493a6ba27dfd43a60945e7a709d0c0332bb1f581e40ec93b62acde90caffbafd1e12738b6873ec38bd33908f94302058298a1154c48454796f73ff325faf6c435405a9bd6d6c3453af15186974c311d8f4fc384314a88932629c141779bfb8b039183d550c9d65f840c64b97fc81d672b91e5db8c2f11e6e910893c67c5bf8db89b209d699a4ff7c02c96b5e791ae65c2afb94baf1d9e6277f7c4583d3a504a932892f8e5ecb92e217d0161c32e643c3ec6e86adb91d1da9bdbb1399b50008e2ed446a719a63196e0bb4ea7b548df66c93e1e9bc65c5149db54d8e2fb97ae5573182b56373463fd259cad0f36b54f853b0178d0959ad4941e63658525c1489f45eeaf173dc8cb24be5d6cdc6690fccf42d53ea72171ebff5090cca10e3e7ced1d33a8b7a8afc3427c6bc3360dc7f111c62ab2c65109332315c672c983966c4b6fecd36242605bf81722e0c570354bae6eea7eec53b55fcc4160c2e6f2b6cb712ca31fa5a21f8ae785da5fe0560a3f87d7fcbffe06540f2adc5489feceb1777613715c50605f22bc291cbbd74ea037e2c749b76574bfd9b14499b62828bbf12a19d43ad41fbf761b089f47420a618e7b59138bafb843b7e64dc15b672f05705062f42655b0ea4d21dc5b326b5f038a550c2b5b956e19995d8ae6d0aa580cba6034dbfe55fd0600e824fbabab3e195c329b0c99b61d7c0691d72147c614e93dd8bee087d2a501db32a65fb11b6a2e5f983babda2406a5f409ffd531fe9446f2bf468b132fa662c8f476fe35061c73824a7d2f6e6bc5483aa5f97c1a816e1131dcca03e98bf347fe6fa66f7c08eb5f4000ebedd6d1f5f74847bcd17d07c66ab8ec09ac7a9e9fda156efab32ee478b41b1676c61d69b9e8612118712f0998a4f2b3384c1a4fb55d71146a15986b461a93f549895a1c9d2a32c8f6acc60f926f6f24450a8d281eba1d42184ce6670a052c289c9f00bc52610792d4327244c984e6d789faf36c3b15d3298f2b9d0205c66fbcb302097ad29a0d98c943233f75e22c40436e08868e17e5c29f249ea500e4d381e2b0c949a51b98b3e8ed3fe0c94f5801d58cfa78fa96239c97b4278183d68b9d0fc17be277036513f8593285aaf46ac566aef4c5390b68d2dc937f2f704dff3e675cf3def2216ac9b1148aef653be944c185eb642b2ab9d8edc9d5dcebb41ea33887aaf1d6df7c92593dbe38f308e3b6fe4c5dee0d81f08cd86a721a7c1feb4ac7c4abaa65c5a9e5f41b17be59b449b46e5d271b343baa346c24598e15f9ecab7c9de5862a7b78f75f5079926760cb1ad6e3851c248e12eb2b657a7adddb4ddf415cfb5585045639ccb7e4a9d02791b37c43891e040243151d68bb91547f6a53889090402ba84b0ec43b5cfb27a7ff01f349101b50d338831867623bf2886d5c679bdeebb714d8686321b0be9e2ede4605fa3c6fe6d55d82c8982d9f2356e9e0665570552206370fd635221f637dadf48dbc89f8cba78511cd49c88227d238069d73b04d0b7f57150827946ed44d391a79609f8b18443c445b8c690e6c98145fdf47fd99ba62de46705886d6b8e23001bc01920dd38304f37c94e895dfcade604cbb5780d1f19f2dba3aaa45daea0559c91ab896568b6daa4c854c906a5ebd01ce7a038a71b9fbac5e9856a0f50b62326b8bcf17956a627ececbdd1b922c0ba2963919b988a4b1289b8e45c92741e94b1b8317f4a1e47566bf53fea4bef7697ee04522bc43f90f605646e0e2cf7bb49e499c8f2395a6cda3d55fe1218cdf0139c52c4ea5d556397dd77f1d53c31cb040a52d66dcaa4cabcaae83b9d1fa807dac16ad18b487cc3b2c026189ac4a0b3724cacb6f008928bf8d361ec5c3098b528444296a45f142dba8696db82b596b8ddc420763acaf68a738967260e592677d5fe24b31b99e2884aafd11dc22c28b0ed0e3dad21b6545f587c0a7d04b77f5a1bf170d7c50c3c5b9505a8dba065b488eafbff7e1dec22850e10fc97715948768b0d63edd7748616cb22013f4b49a6c1581beed6ac019fb941b93b3cea858f05d3f75a59f430d0b44f1bbc20bab919558efe3f6a5ae52026e460d0eb8cfdb3a2d1cc728d44f5819f52a0c7331563ae1bad62b2fb49136de8030ef1dcd745e4e1c9c2f3db86e6c9ea6ae1dccdcae62541d01de5b7c1069396141a7be3559f1195160a38269a26f14f925f39ea52e9444bd4c2f68e767e9b197ecbc25218b7c8b60d1530496afed51fa58e230641221bded814d9610b8b1f472b7b9b0fbeb2a288549dae98521a4e958e8e50c7e1c6551152296205703ee5cb8ce85161f47e8a480b126ea96b2d63c8c2cf83b45d54120f49627d011bb8bf039804ec588e7a16b97b21f9f12bd811af15c07de4ac369b182da0bd71dac83d544fd181be78d29cf111cec43d496b514d5e1b40fd5103f3fa260ee6f161f6b4faf3fd6c9b39e5076b1f131e519abab53b5e421890b0754f3afd85213eaf0a092af028ee2c94a894e5938c59e777857b1d3a728c2c986ed03a6f4ff1c1de439b61100a0e6523d9ebb62c812315be304d19975f9560f5fd7b1a82b02dffab6db711df8462978effcf011203edd2a8f34223c47cbee141b3b39780e43708c8fa76d34a862536d91ba7422c5e65052e42678872a80a9669d5083280440bc90725bdb067181bb7a5e4088d03358022527bf1f626ede6b37deb7bd496211855272256d00e2ebb308d3982893e878ab67d5814afdb24af656f0968f0bc0c063a64ceb0431d048c3032c55dcc8680e113f046a223fd2d3b23a8134f8be07c509e18bc70c52e93102a8d32fdd8a9c3cf50d807ee979571afbf9f08dd23ff0ce4116fc4b823147193cc67f8b922c1be6892d276e0dbac473db17f1003c38c34c07da91091c3af5f3e4c423be6d526a9b8b37684da5cffc1552faddf4d0f60dc591bf9edd213402f4b4ef635c92bef5132e4343d0b065332d7e98b9c70e364b889cd970290edbc80325ba4bee26bc39044428746b502f3a9a58f1a7797cc6df8711bbd8a38bab0416caa5b0e2022810b1024e3520cb587df8c5f6eed2dd6bfb941f550b3872e15d024c2c75e4e80fc15f78e2083cd08ee1595e34e75c02c12024cf1f34a5bc6f7bbdb9c7d2bcd0620d7840143ab28d08907fe8a214765da83d42566991fb0eaa3f2fb4515038b9b824aaf29e34da9040f9bb2f2e06b95f2767a6264b163205abf3bf0aef569b9c47493752e5a664ab55ed75ae5937245a390b6266da873e098c61883e86e4ec832e42e8f1c763bb8e99fd389c7db7eacbe9c270c1327527d232cd2bbdd0b3f0357b1725f41c2f4fc772c0ee1ac40f62e34480547bd7ff705074585d131e57da8e320611f95710af1c5c266a0430b0021e2c27d039803e575fb0d424a29af75fd3dcea32700de27e5472ae8395090cc2ca40f39bfa53cb79d3598f4bb96b0f8e9a60543ed954e45282be914443649befaad010fd19ec21472ec7e1b69d2f7033a65c07549c22584c1ae358b007e52d20164dcc13a787db5f512ac845ee0324833fa24f416a778578ef3aa0d6dd209473719286b35b8460ad0568d954ee5c3e17d709188d9ce4f87f2e7ff0d01adaf766649b4539f7f9b336d54c0761bfd0c15c1526a8c0cca95665aea6907f0a6e58643dc20d400f46a2fba86a31bd13f7908912093557174a985f1fdb91b68a30ccee379385e339b983c1d2660f93d1c030f041ba4a23efdba9da621d957673d66705dd502bb7f1ddb760e926794878260828e6a0951d8d77a90fb1fead9d3ed55e48fd3a2289564814e62f216186cee9306850e19adde3cebe220b570e3f6950553fbf7f9767075c0dc456ddd3ca9c29e994de5b513709ecb8e610db6802a3de15b6b5b4963394b7c7b062869e1f8829f70ad2c075a7fb44777842389a5204811fb30dc1173b7c53449d2d6d50b32c73825e27be01c73b42f229e134e7417cf5621e023b9d2f3556bc02fec6a0a86614bd3b62e31f436321e8a2e1be9733e94e84db8ae4cc3ab40dc035779af21e4c2357ac72ac5f79d6decfd00a38101ec3074a4bbfcd55cf2afb3cdb4f44c53834b08e6aaafa51caebc463d315cdce59e0de67df69bbe68235fd9351f26c4e3eabcdc1d6130e44742a18435e96313852630cc9342a2b49a4b875fcf1830936aa0368cba7d954aabd1e9abcf044874b3c650b78a3925f3f01dcd959618ece352a1346203f70aacb3f45ad2d15d6a2d8b22b99f55057b8efd22fd8d1cf950a3b7703e3f7a9d5d62af451b9ba32a199dcd345c39647609c58e6f7ad0340165f850176c8e8a1f8b20a96e3654457e20afe0b30db2ff6c72770383ee75a910f676332bf6d35a6310336b2a23bf0d1dc30e7b144207f5b9dc1be181632190c53913d18b6644c3ae00ba5b3eb6a8350a22c87da65fccc233a814c8fb21c3c56b137a3bc6e1ff9fabd32f27c693c043158e445ae9434972083bf45bbd6d5d185aa32e85524147bbf026d686ff54b8b9c2e4de35d32072b394867cb126ddefcf26b63d37a7d3c09b38040aa7c006ed6713c769857354aa7d9b95e3c6d58edd7eaeed2208d41bbc5cda78440aa747dec89259c1644e4d7a41d50cc8d46c3d10efaa9791874a9f3df9738c66ffc6d638736daa1302d70a8919598b15b3b3fad18590321c11998bc3161b033601f5fcebc1df369232270a16a6cc9998035c1c49792211e9941e362e8db5623e24280e5db8d8e6605c0b5a91212b7993b84ea2970c524bbaa78a05406b9282a8a86cc529b6c128b99b637197cfac7d0b730fda3f80c7ba72dfc82c1092bae4efd4e169220cbcec19cc88031aa9b402b4d2c20dce8a24ac33b6dc501852a29d595f337ec82bf16021065a7375483e1b3ea58d0fcce31537f24e640b0607e736bb8f4b83d18c3bced0819680e78fc46b6ee6c10a72d01fa7b9d5f8d6b3d834b5d0c881262e5a44d4ddb4fa19927adf705824de725467817ba6a3fd987cd976c6e6b6c196b50b2bbcc5f6e976b13b26881c41acedce5ebe075020007ca737c21138b98f7625ef4a7fe19f56721cdf21f786f396ee7abf62295a37ff1ddb1c65287dabfc7491dfa061060c6e9458ea231d868cb1c6863988a0014ed6b152438c79c2b74468f07d0de1351172345a9a31049f52c38840b42e67bf68fad5871cff9983bcbd1293f3c1e9bdbb658a1401fbe2bfa9d3cc32de3ca5156256269a6930e40aab9d1a2b06e57959d541694a4d6ef918f1aded4554694b67ad67086da6d43a0e9df85ef5d30d91f1d1f789b444e6e164a0cfef372e5f98892fceb2b5909301f51989bf1e5877eabf3a13e7cc09c68f441e80417b341a7bfb575c4c5ca9ae540a73787ce707b51e03bae956503936d17dc6129b6f83215bd409a5bd9a74b878358d360e311090a1c706244a58a9023c9f94b1bbbeb5e4246bb36e863e9b39bc0a717dbd957c43234cd0c5e9b95a1a0b7a16c47ce07be6bc3f855f7ecd542311cd2081f8bfbd1950b1495de54b15defdb9c3725535a68814d804912fec0488bf1f6f992f9b1ae3467ddc98efd1e7d8690ad4c31743342ea094ac481cec9bf755260e67dc28e4f25def2782c6b1396feea479ad04f61797e1b5bcbb9a826c8db993b8cd56ffcd575890aaf3b24e2f300348a708fa1236dfa2245176014bb3799aa30a6ede2b10bfdadc1fceb863039e0db2e45191b64158cceaf090071f5cd3f95ab7b8f6b6406e6e7d486bbff9d0d298fa8b8cad2c69438951b2abf744428f9e0e1f838e6709cdc4fed2bfa1b5c43ce2ca68edf4f77b5faf89a5a5e41fbb7b599a08fa59419326447c507fe4e3f425eacc26c6a7334a9600250e0cb598d1b1830f1e92c145a03f1c695e31a1540604ea6a7848aee653cd501fe2d9ccf777a655a25acb08e0cc49f039c0975a4189dc7158d35343eefc1959b2a320b82322ea5aa93d9c803816ae01093069b8dd9544b06c7555d5bd74e6c2abf2e2ef6ff04aa1a5c16a7be046d8dbf3a2796df0057a4c012f0df58b55112528630e70caa28b805fda123733de937afe2157c00b8fb026b75cd1787fab07ede1531a0111713566956772a026461ad6fb23c5b56d89c36c7ccf4191641c8400a400b61b83772a4958b86ed63b9d4a528ec85d4b4e72c853cf4079046b05df723bb3fe4f3d5587cbddad1f11ee21df03fcfd312bee42e0c9863009213142b48647691b2b55bb4f102223c033222c8c26fe69282505d8d9d1515e0d302c439a840bc57831e4edd751c27b62cc9dc28f5aaa6d43eb2271e02a3332c885964db0513a9eee7a22fb7733fbe311e815d178d5df6e1801756d4a9602ecf9f3b71b80c82a3997d0b2892c3b0cc0b86d36bf2fdfa132e5e99a446a33c1777ff01c92bf3888f62d9f518004ea21c75bf6de90089224cd0a92d00f9493f1650dc736c5f9fd25d7c54e3ad2f584bdb5ded06673bfc41d213cccedd945b02c0140f2b93906e7f1f3d73905ad4250a2fc1f8a3b63b8557ad9f9d6e2814ab316b37134292de3180caf1bafdfbf307a993cddcea6e02641ed147cbf9743c25d816236c0a37b0ac01086d21d755c4ee3a6eef1c2005d99fb361cf19ea0df5501ff757ef33c0e20dcd317a033e51659af249e1257e7ab177e80573f66a8755d8adf08e69cbc22d11c87105ab56aff00e96591811e19b27ce7a7caab152710df5f3412e525f70933ad3a3bfd9f627d30bdcf34495e493b4e74cdc91cf4920803cbf8120439ec3159ee9600617c2f2043f84617ddd8e31f82c1a413d3abb21b53ff64afbb5a2a42863ee021c8ba4154d8e017374a6ca281f17fc88b1606af64828dc7114ea8bef8b39b5d24b848aa3106f8bb8f09a00a4795aa0d8b9a1e39cd081c4afc773a7959d22adf2b92a316009a24686834f64273d529d156dbcda127c44115897743b34ac26f1ddadc09db5cb27cd946dbb66a846381dc4d7b4c5768429b5ca03c16c19476b83bf01258bf48aa564605652b87fd51fa4252527dff906c51f5304fcd32199db884a5f487ba0de118f0033774b456b4112dd6079754c05a9269ddc4a905a415ef44a1a24d00e918b3dc3ff57d91f4e33a61c0a282cd9521bed291149f1dd37a7a748b0265d00137a8f28e648ee632febec505d1072c542cfbb561836f0146a17dcff0855fd237efd802c2d81591c2d5a46a140e5a571fa16e563220393da247d3e842683b3eedfe885e33b63d942e65b1861c5fc08a31a81a4341c795d4dc9cd19233816317ce826bc3cdde411ada45e62fda38909c7ea8e891801a85a81ebd58a2ecee99266855793c448dc4fec234b0e5e39661de62ce31ae723692dca2d7309749fdaad058f55f6337b6db5d3eff49ff39c441222bbdd14a2f84d997d58a4227acd0853699600f065942d3064096553dfcd6e4b3e6802823c907a0598201be0727b62263d879d170383ed4b4ffc296dbc32ddf619a14148f27c1518f192c1f2280af4b1397a3adda07a5f3482526ed2cf9c1ac4af9191e9271db6c3ebf8d63adaa88bd36aa04a0fe34f7c3cbed5175258b0f028727e713dd04980eef58d669cf9758d6701e68e3225e8a34a410e2b57350c4f5c37f4b547a1ce677a5a204d068cdedafbf44f63657eaf60b27ec276d4ea560faf3f4074e8d0489d293ad84dc742fd63d4c00597007c53fc45f83647def72163de949f906cbfc0509ceb468376e220743fdef733dd3f0f97f46d530fae025941c7868963e2bae5f94ad980a72dfd781dd52b7f2f77e9d22d4c735644f46391ef8a9d22b02bfc302956691330b096993b5d1626d86fbc823cd617130286c1b7e47604c29fcfe52e76af83ea3e78937b1e54abd5d284f276c9e9b80a0ac165af9c4faca72a64928d6e86e795a6f01a047f87a890e1ffc60b390046ad7036afd996bf9ff2db53406c0ce0e333152178a32012db88b02726162e4e356b859dacd183eb9ab5d478ab1a5e5e5579893f591ce3c02f9b64d26dea2ce034ad06502c4ccd0a44483c4ab0cd621fa8683455b133e103c5fe2181f93f5681fac0bde7e849398ab302988c0654b40d91b69d18e32675d8e32b35cdd73efeea37e49cc2efd8d31e5a722ba04d56c57975af32fc0085d2866f06daae82fdd23479f6221896a8888962ec78c485343941ee76162551b0fdcbdbddc14fead4767144f3c92fccd31e79b86f5157337c5c2da9194fe3f2adc6ef388d0ad9b670944a790a58723cab465f89e9285268e84d0395f9286b947c0c9936da548cdef820a8f60fe3938fc70d0304103319c43f122b5fd04a0a3b90f22826c267c94fac91e36ab2572dfc211f45094f4aa7d2672955c73723decf4167698e27d330861520fc3ec4e081933e4dea66c513770254a9113910417fb90c004e11d439b39da7578de0547f98d141f15497395d1799df29dff1d074cb49d119d1e743629a1e1f810285e4d0ef32ac3e086368c5a465bf6afd8bc787dd8d5d7f1f0ad9d218ab6a83b2f233a147405eee13f9b1499ab2de89f5b8da0c3db11c4d8f2d02d7274b97ceaa3f561545baac10c6a0b2fd95ee8ace160f561b285bf5ef6c393b13e3a9ac42cd1a9ec94c5a1bea7c7734ffb4a51c58f0ce98c5414c0c76d5d2d5b8ca1c3a256f3113d9fd04213488ba16ade9cd92149d4a19ae849347fc2108e569a0f2289347d78a825ec1a05f2c8b11097439c0da067476b6d19a12ea866dfa6942c5ac460fcf77710aeb9b61f434b8666f35ab54fc07662f8a38b8b3c2534bf6bc01540de7d0ade8c975d4528775ed799b93652f5542158398e8d348ec32be403b7c15d7a482ce0990efe0e034e65cba275c242c802f0a7ed1494369efc95870c2daef748672cc9b7d68bab41b5aeebdc9cf8168d15b2301ab21e3a11a30c2a1561c2834639d8a398b629d4a8a5619a1d2ca5a2498ed8afcacc4fac615c61c4cabd4b7a93cc91b126df93852a94da379e8a144571fc4430da3f38beada24b1ad654f795ea04175f1d2e77d2bbb7b1b6c8b36d14e251caedf7adacf58b26bda3e57856348ce3d4efd41bf2f5c17f0db9f689044e6ff1eba4ff11cb4bd545e11fcad281a4f10b9d6637e2f027c4b07d8a93a1ef174d636000fa30b38cfbd2a65553e24e45050482438bfd65125a1bc5f289cb4e821bc2cfa82b1287bd2d2680bb0111c56a1bd731cefb21a7ffd58a8eb027d42928833be272c741a67f5c75e74b3169c6f5119592e2c736ee23430c79926476b3c455e37f0b788218044b49a5912153660939d9d1bb2ba481c2c3bd2c2f5ffc35210eab8f48b23adb999912390c8d38bccbd5704f7c95b7ce33ed1d8621b5c249df16ed02899f4a8de149ec6bf485ad49c744f3dab7b24a21c977b6156b060071a305af2f6b5a7dfda458be4f8aaf007d71cb326a52815d2a8b8688adc0991199634a75997732ea1cecddebc8275c623b094795d5029a8dee5135e767569f72166bbe06c7f15e5cb0756bfe17f2c5a96756971bb640ada85ac15711a6abec03f4e0bf067eecf7e1ab44714ba511efdc5af11726cbeb6eff38c16bd6d5e24916139c434e52c789a3d76da81f27cf5d5c7a4a01e0fadb8441b6e3f938aa6dd75c772fcd3b66ba5cb2eeb1b66d8f343805712bdbe1dbc359907263f90a7fdc7958e7fc514ad914383aed1fea67b6351ea4a0f22b98d67c9d607c89fcc05717dbb3f67ec43beb9f387cbc7e1ee214ad02c0401a198f2c5bd7d9e7945d0f7b8818990a9bdc87f5b123a342458acf27dca726290cc027c874ff03f57d13f840293773a63f0f4aaafbd961938b18480bf8b140ccf6cfe57bbca7e693e15b4c504bd3d3e4bfdf5051ee10fe540cae980ccf5bf7db196fbef7142dfac744aaa1660f86c8df21551497e14532de29377b9708656250567b127020c2923172c4519109c99260411799a21815a41d35e984d9af778d83be0c42b8d3790c84a2bdd61ca8bc53efdbb7ccc1c0bd3b5918e3d3e7c8cc67a54e5de558059140741aa9ddc75a3306153e8d5f63a10843cac5e81dddf8949be87423677ffaff9a8a7473e5d7dea5c23f300981817fb2955ef5ad27becf3e488f7f3f6f4c4b5054aa778844638705ac4f8bdd701c38d58562cbbeddc85bc9694a289921b071c650f46f8736cfb0bc6ed1b9104a515db7814f9f7f1ec5415782b69f64e85bc5b959f49fd9eceb08ec4f70c0b605f16fbededa35aedbc4463368d77694b4f4b683e472eef36de641a39e09f835c7b627106a285a084de8a8b8f8b0d065428404c5e4b5054bc018f526b0d8ad3969c15acf779bbaaaee96e9d8f2d690d163f2e1d75e7d064d4d304d8754779c66c7483f6a1a7541acdd118ad0999108fe7fe2fcde3dfdafa64cb7a9df117733b27bada89b92932bc29b2b33ccbb62e544e9b50223b8a44d807b3c328f763cbf4e6084d1fa03866d1a295b894195be5e11b88082c26044e17b870ad8a1e822c65f34fe0b8cf59e5d21f98adb5585ff4f52c86511911f512f31b41d1114edf2b60965963a43366c08b8f1aad223b9d8494b676190160fbe82350b9010e8750a7a8af183aaa3b1913c34e1f8f51982ac74616a6036bb03510c67db65950bf12f3df281b31f48ef7256b08d8bb89faea78784435e40c203eba007504b9e1e1317069cb0da8c5f9d15191494c2dfc4f6bb5778d4220ddbd87d4a0e03c89e72d04c29f4cb0581cf43be3894624f4822741da52f9cb4a37bb5cee591279d7bb75e7d4861afd69515889318176daffb49fe2e95a4832ebbb974a118d069c39e69d568470a48dcb063c250653387afc3cf41ed437f8bfaa436a513a26f357cf902960102b90291396a36b66a0a22e592388270709d8157c2723ef44785eb78273e04d136262e2363f336309e5b727f3678f3e4a9762eaa10ab21b3126953c5444ae59d76a6f2b752a2166e0ed214ba9468e116ffbbdda85c03c762a2b9682a6e93f0520235067a15119c620d3c8cd56c69064277a3d7510df62cc91cbcfce9ff20b36c22c19f633ff97f7fdf63b756ec3289b9a8d7adb4c385164a6828b665f14e1dd7c7319dadf51fe90658945a902d0a29b8f7fc38395847baff0983ba3928069988906b99751d12aa3c536e4efe87032cdad83b91506e080182df4151ca2abf9887ca157599469c28f549b8d343786c7666531cc4e18e6235d54962acc31e711318dc619eaf29d4ccdf3b06b430e2b82fd975e73e38e10532fae497c64e13e8622c5f9aa41a3d5ce655a3c2f58c824bcceb1548c662e1cd9272c631268b8eb91471d0acd73add4bc2eccab8d36c6c27030ab175146abafbbcf0e62bd1c8d6715ea34df30c090de1f4a9ccb3d7bd5cb05b4c855bcadd5c96e43a89c7934d49e294d954e0ca75d677a0695cb7734f8d404872c9fa64b20f3283523d1f2f9a657a69d89a9923bc3ba9873e9d1481e89b8d46cc6b72f8df5f0e66f346e859a429547f6e102f8342bf5c25695b5cecb508dc8941934af2a48d04451048d4060a92cb3a8e648262f0fa3b13abe7758d250c85f657c0c7ec7cc8d1b722c233404e8b3792d718b423c40133fe5250a2cbbd6e10f42f555670e378236ff4452a04d29116bfe1a38c2593215a23e6a90f6c083cd84866554e86069d2e797b6f7c877b40370ed1077ecd03d19859dbe4a4989b47d60691776353a9b17ec1644e0f0481356c923a4118458f9cc29ca6c57aed3f0cdb10f079216523c4b5d83e333618e815f3423bcc37a923266bce432b35ea1b168671accf68adbf74f923e902f923e5f902920101b9028d392d747efa5df9ec7976b575ebbbbc4e50e48f494255067d00c8fb6ab805f5dde05d0240f101c33dd0aadb317a173e25a7dec0ceb77ce150099f5ca19dc2df6e44a5b5fc87cab441dc4e6ee717e77d3ffc2bc57ea828567dcbcdb8831dbbb613c0f747fc497e218f903efb5f5c5a2c4e61879bfb069a67eec30acb8af36d1f4a245b9f120c6bea336d8ba3eba72be78a3ded415117b3ed0babab6ce775e1c1ebee9d08f4a0923ef969747533a3a9fc13d19b4c5b1eabe6ade431ad5731c5ccfe98681c31ade95e7d5bf469024456082d06df3fd4e6970fc2533bb9cf6688bb595edacd95f68d1b31a396d8af954e37fd43d6a366757853a1185d62e18587e2cdb51f0a7023f2b3cb9646ffda39e46e98c47f68bb3954a140f5bce405977eb8974c229305c2ca3c7017891f208a041a89d48d3344695cd9106bff8b80a0a48dde46ba4ecb942344cd1887e2f889a5b97e96651dfe7d3116a2b17a86bf11be8ab8bb69f214b7a0dce316367e827192ec0e9a0ac2199b1c4f1042655ca7cf3d1f8da99341afe8f0b1f21338492ecff73f65239f4ea6a5dfcbd08ca9bcadd559dff34a6a8cd9a28a579fd54384f35ceaabab930b87b14779fdc822a587d04910b4d693f288b26d56688e5ffb2d65d9374a32c27dab9778f618df54c15f555f54828113a595fc1ce107ad2ae7592b41e944b0cfe48cd21d36d4fb35dad4de5ffe9531f9e927a25942461a4c9726a292d2ef9dbc0b1d0456b703037b4df9d0c446d707285b9489e8845211cf0e8a3f0a32a5cfc713902df29af2813293a48c2f02b8dc336befa797d3d3f67d90cd4fa25466bbe70d394713fa06b606de967d5a5aa9f8d0310363f7be1a75708d4c72511f67eb2b0495c43e75ca6e085d35c53cdac3cc09142647e68fcbbe921ad25080f91eb50201b91eb0e85ef5afbd04ae28867b1e81b818d79445b1a8e98c272154ab5e8a7797af50d972b241bc0d536481095419bb18be70860dbe9c5d355d74451f31e27209f3d43cd2a633cd961971c381058ad667a9b2e69f0fe9c2a557ba89835fabb16decc1915b54de7b5f00aa5787a39e8d97fdff315a7a0d2aaa5d3e10fc1a02ae74797c43a2719d3361805f5415dbceb716bfb7b07ff4a415a938008f0f9a668395801ee590a83b20d5749facd7f99bece768e7e3adc0e036b82604cf9a9e5c7010db9b54965d094ba9c248f9f4e29045be7962aa6e7243d450caee40bc4dfb9b333e6c289509f899b254d85539a78f1194553bbed9dfca1044372ba2530f2b05ed4a467728474a1d603eba54e4fcf2295c6a559e9c606b6b70c40d4c8cee286f2d79d6f46a8c0079130c2f58cbf4b3ec7fc109cc1ca3dea2ddfaf377eb357ac6b5877aa6f2e1f56df3421daa6ed5d043b5188c6ef1c71d765b3d94815027ea7838d8f448d0fc008d3a0189958ae6fafac687990f5b7d43c103ab97780087f48bc3b7a19f76a945a0d90e1ff279ceef8d32e2b5fdaf3c5d1a5ba52e60dd934cdfdc2492330a5f150f2106ecad186cf1f6ca3907707e34becc8b442ad3dc5ecaa7abfc7bc19cb7a7664ecc127c1d4d0f0515eaa3099def31f3ba376c30d4044ce8cf7669ca465f140ac5ca43f9e856721be03231e6b0cbc655c03b9f237036a504ba29da42b5959029b68f0171ccb5d1a2ca379250d3eb5591ddb52333b954e152e644bf8c8c22ed3c3b471021eeb4a25f2adc63f792c01382e9c01693c4dd9ad333c198e4da0b8af182bd87d2919f2bf4ae94130931cebe0524c1df1cdaed0767ae040ee0f042ae8b2e0674fedaac068db64ae2998f1e29d4fe208f3ca498a1832634f7183a8d6902d86823e12f5bbecdcaf9935f808d72e18e62c1a117ab27bc9acc3287afbd6f7442f4eb48063a381495170171af2d76e3672c37462bcb6c1710afcc873b9168e4bb6887117a9925e3a2b2bc33d0db4fb33809e3768d47ab3b52bd655c71539d8a7e391bcaeafafc71c554e0616d6f6d9ddac0285ce5b9dd9bfe015739925705edf72abe615a376e3fadf3e5807d97a7ca5e4a378ead2a466db9773d3a7d3f7627b29f1183816edb236b4b20af6a212b9ba1b86ed143974777a3de41aaa3a17371aae38dffd3779f254a0da8d9219d98d89049ad55d71e731192bb769ae72e466a67e82dc1b133b9e5129192e2e611d8d8035f6e0dba92d6cade096c56b248237d9405a534d6205e59186c1e5ffdb1dfaafeadc15eb2d11c736b0e57ceee75c6ebdc78c2ce24fd852e87eeb969e14d8d2aef1ed623914bd1932d8dc26bad8e6b3b2afcf8139ee97a4afb1db36a23a94f0ba00c6c6ecd072851c456e72a69af515c7e7d872ec112729168879f1812c9de0cc380a994182a80e4195765d53eac82085ea751cb09eac5f9db99aecf51e9111515b083ba65cad1d6687363c3155f39e5c7124602a879f1ff153f4ecddad23ba9d99384840272613f40e8975118e17a50a27029b5714cf9f3db14c3ded35e31b45fe73fc06a7fe8cc96937ba3e82dcb226be47e45bb6e971ef5e7ba2013cbccb6edaa51d3611452f3c26860232193512e1ca915ca1e82d1e81da1a84b228d92d855a09721f662ff3d58eda5846977f40d2f6fe0845ad3c8cc2c9e6d9e673673d9245f5e55a2f02b6e47e01d27e809572a003809b75177880cc5ded3fde42ac59eeac1f0508eda86e4b4eb7f2de0f9b8500f766798ac7f9583cef34c7faca5efc97ded5585b0c39e0f16fb2401fc50a588017ebcdae043bc236f9309bc4d6c04f089a898263c7897feb006a6af16240547c96bb52d275130bfbeb20f2493713f29eef0455c41134f4f9f27c38d29dd1a2fbb6ecc40bf41d9f32e33352443c299ca7ef6881575dcd4f18ecbe874dde9e796628b21e6a7dc6827587c61fad8a8fc63b886c6f383243a20dcd95fea8e323d0e9811bccc2fd97cb0a347097ef1b5296ea8da5361c3df81672bb179e51f41082ccbc4c4f0c2e2eed5f8f131a2d58aa68caf0aa1a6d9c8aac9f424f7cdd2acd2875d4e0238f35c70ce48c966e114344ba6c5403545a4e8a467bf9cf7ebba117701a5e69a2e71a546d3b674468d4a31bedfc6e70fc0c4c8c3efff332b4b8e1dc604541091dd34a584d333d7291304c08286542b0075f371429605798bbd71ed7ca52ba6b812c7ca91c8c35c2a4f853eb7509c12049150eb7abca4498f5ef4d8dafef8998afb4527b65cd3e6ef1399041887f204cbc81fc030e6242c4395e7752a6545da4996b69740922c07881c1d5bbdc79beab8b17b5b0980d8fad7eeeb5785fbab08a7963bff7e95aa7b526dbe201b968a40f8db9399e7ff8aa18e6f095b9aa4cf4c41e57a78f10f6fc580a955e84f48a8c2b16d13b8b8efa525f1d51426a13325ea3384a5638577f32267f00e2e262f08d46bdeea4891ac5acaa3e3a31fd503dc76a3c92ded39edaa65043b60d52ffb6ea27cbf810899552d4dd5a55e95e172e267be645a3f2c6468b5b1ce76a0b951b85f98efb93aca8b3948c43cbefe76504f90128788e7e08f7f6685ee03b70ac35314d3a64a57a4a8cb7512a9254f3a9aa7e9c1990606ce8ca25e6b9c816b56903e10d7ca1db41a7f991f292acb51337230d0a0ac5604259d7daf5b684493ce3344a8892152fb6baca94f5b02237bfdeef0f9dc6fd372b078a05489f81ee232e63a27726746d52c3d9531bdec03f2d4d56b604231b233592babfe12c64b915200f1e16672b0798982293d768278909bb1352dd42381d7e87c15ba92aae469fae5ed023c643b45c08a5d15b29f34714016ce5c52ac648d4a32a4bb02c701f3a68fb873581ac392ea34277ff3262fba6ecbe274c840751ff28235fb3168cf30bee0fab5cb92c89c8ae3ffd8b03c4253078c31ce19864c8b6f128f6e3e80efda9141bedef5b60adc0d6f8357fe6cb6828b3605e02275deabb5326eff3d52861f072523c5695333b4d51c58c08a44be8e90ff8244da37295e1a1550ce715d08fe600349a9f9870ac83fbaada48cc392b75ab1ab456429e5b236f6b3b1751063b274bf6a75dc2283ca0ae8db757fb856e8c7442e4a3cf6f26e608bca09235f05dc6a2a53862cbae5a5bdcf1bff925ff3c25e38d5ee04591b8c228b215e5f82c21f39462aaa6c548c8d581b4df4386b97fd832a46e2212a3bc5ef4716a10e75cd5e46797dc12241bdec3074d19f971caea7a8f24bc522faf8322301e3e4d2188136ddccc53c6488d5d9df6298befecaf637a2693e8d3db2ed2f8e120e6f1ef5a52471e905bc7f62a3b93b534c9e234d72a75f38e443a05ff62ca45cd25293c23e4ae71784fd1649c61b9469eb152642d8fa2db77b85c26340f4b21b1e8ec7ab58b66fea1397e69665dd9116ce6ecb7d642ec9c2114a4c893b795c1be06893697924c42ed8bc97e0c930898d80e71536dedd3ddcd9b4b35ef5eb462ab984b28925aef1cb524439e36273f7056b17036a1f3ab44eed99199dd6d53b564d2f210a7d52ca896ef0af8de172415b518e92c578d256729744bf79ef3ab444960189cc0cddb9c961bc0a7f0bc51be6ffdf2e057331dd7d05eacd8e6e81e08f90b96539b9d323455428e9abcea706fa357949f2d1067b600af355d435bc71094ed8e29d699504d24427639b4d612d3d2c7e50129145a161cbed02955a0f32615b30cc968c41f2d062c32f796da497b379f5955a0ed5a653ee51f52e6a702b478a9a7af4d48fa25353a258e575c2e0c475b169df4471c22e2ccb1ed607bf831eb28e4487ab655f07520391309d3590ad63436ba31d1c37ecbf586dcaefb56d6110386d6a6a5d785b365701ae291b0a3d13b3dec21729e42591de8ef9f7a7216d9dc23489a3fe8d874a76f146aa26536c1dab083681cc00e9dc9e6603d53d74a1c79558c6fc7bf32d98a485dd562f261e7d2751fefc320c5a2c9a536c84ba467d7a82df93b5803cf60a2726ed8fe7287863fa2a674d01c77b053bcf88a9a502b0fb786f47e50401aa643394624968fb5d5dca34b009a3a32bdce673fd2d0c8e05238b82ee1479cb9b8b7007ca03974e1c56e9bf903c2d0c274cae9f588fcc6b47e02754dc0e7de3cb5a80ace5f98ae68244082144ecbac94d53abb9c89e7d102063107c0ddbb6633d0f987b14217a9d9378007cebdb260a9a89596b11422ec3f1136d469e3c188dfc94ebb1cf8c7f7decfef77995e8334d4321525ad76f32a2efd4c953a319e18c4da8981ee89415f7e2f07914d4fe63d6246504b90fbf03b54bd905661705fb65d00d28c530b7b3c690fb5f88aa1edc6f6dc861d79a1e8c4a6dc1df27b7c2f0b897f1231f176adafae599f4aa29c6a5070103a24468677320b9462cb9a2d40696a5966ca205af33e350742e7e50b27252d2ecf50420cd4fbff8e4570e04b2137722814c64ce0b81d13c14af64eaf36207ae8f9224a47b3c3c0c0996db171544bbe11f2407203eddde94614c9d41945645dcdcabff12cf2fcd01cf062b942bede9184d830fea37df7576b10bbfabdb4a4626979576f403f33060ddfc6f53df73ca618654768001f1e08bbd66de39e8eac625d4f1deb25681c2dc67c6764d555338b4293102191a96cffd8859eb08ecda0489af07c301c12913762fa3f9d192f74c762f50556726c3bacfccc66a038536e913d95186d8aecf381312733beb68b6cedad321fa4e3fdcdcfc5553548a30e1ecf0041f823ec863086c34b3b6e6a7af8a2214122332a4d27392e64cfabb1a9c66c498efb6515f32f01f23073693a37a72240df9709d577b3e184cccc8b9cbf34669b0653e16848ad0a9dbc9d7b0ce3ab88e98616492c83d8b88673aa6a1b93d2f7866caf1984da384145361fcad93640c7481a085b0be84ffb4870705371cabe56f82a233b3d5aab737a2f2b9877fe2885d48163e6c55a53627e6db0a9c7103c867bf829633af2e1379a537267a15765c5ffbf7457eb853d0049f497a7823c0489dd0a1490667b600ccc80f9ebf9afbc007280e4a93b4c20dbb07c10ec4646ce9cd1b3dddacf5ec7bb07d588501daa9ee422da47b4f69f6cb49b3201e1b461b5d4d60d4230995acc88dcc8c928251ebc8d37f3e0dcf8218bbac5e47653e510b270586859238c526c46b7db46e817e467c7fe3f41066e234f4756ac833c9d010fe800e51106deae8eae63d2d9d02c2eda4ab19d63600a5261e69075cc0e28220a3ca4cbfd53f14f654c09a62f6c70fa75368678a7e3936aaae6a3c94d800f95888777bfd394907860ff4446b285345768556f34b1c62cacf50b4ab820d02a18cacfa3a42f086906213e170f26a21a0c7f478d7dff393d68989622e4f89a46845984d1d28ef6584f13f135d6a18fa438e635f7670e3b9e0236d7dc9f99328a807e4468fd7438c56449556c1c13e478072602172f923d0cdff16786fec072f0629a0423025594808ca65d0ee3144947a44519e04b6abd779dc2d119ee4473103e1d608c0e254e0b7698bc876f2d810e4b41f37c9884648d0536069a80f9891d0e2ec4394446b70bb0ffb8032959bb04b82e75f577b8c136b6c87d1f98a962955af7286e4f1a098adb1bef56655757dc5e24cfea40eeb8f37b57edc8b85685c7f1681108f793b7c12df1a203596b57c92f9fa62bc9a1db3e7ed9c802500c7e305606fb82ac11df65c7e40c1fb09084fdd390f55a94873c7a32c0c9d389206d7695220951ff3fcc62cdb39a015649bb65040a06e54111127fd947f344d782f99b59392660917838f2dde4b04038b0baac6966593a8ea2eefa1423c4e9537eb804cb7d58fcbb1eef505ba06b1682cfffc4eab227161bbb9c3aabaec99f2e08fa650ce99e9c02745927ebaaef4f2c70713c97b34b734016a65a0e69db084101289443770fce47722a4c1af6ce554d09aeb9b3e2f076fada5f5fd9c772ee2cb65fff9da7b33e1b2f6a08f1536a403188c771fff5a84c8bc1509ef2dacd23cc699a242f5492bbdb82f13f4b9766cb1465d3d79e5ff9499fd812d346b8ac6e7c8cb83a603250a52daa0a55e04521f22a4246c5c149bb3426639d84dc651f7246d11ff49a2597b9a77104bc2cb1880f0347f2110b2cf33866aaa6bcce8e058e03aee01191adfee651694b506d952210398513a9313836e1457e5e8de9bdf26ed7301c3b6578a291d73cdf2602f6493e7685dff5e7b4db4c0fc151e253009234b251ecebeb10c2facce66e125b8fc8c6a78926dff9dd250037a12aa32c086c155f980601ab25de4bac8ce364c7fa8fdd965ddd03dedc8de498dfd3cfdc86b0b56398b10245dce984f2c5087610efd29aadec6eb78c18956d6912203f7016f3f47452578d1b718b6d221b38782bab9e29b344dee9deb594d8798a6a01296f5da1f143743c61c402700fd33904b43d8d6a44dc6fc04fcb9841544dd9116a5b908f06dd39be385750a4371f7dbce8b9b75aa01fcb4d2a1a94f22b7bf876153543f410e7f8c1504aced875a2e054dd5a2138eec9607d5d5ae7bae91da662c415ac6f0a9bb981393f660695e4b65b16dbaf35ec0d40c68ff4fd991e8152e03152c332e92a62c2bea76c0a239387148409b6a7c2c98c24b506b059869cb911a30cf15c22e0ea0f86db884040f7cc8f58b1d3fcdc251d223a285f191ee4bb2de83365ef74726c7abfaa9146c308530edde09be20e9d6eaeef850d00b165e768463b8793a914c421bb81e8905938540c64b77e82ee6a4a6a15f5cfb1df20a41305ad3dffafc7e8d882a3c9e3635d115c9314d8f3602ba752734e34e188c3cf46b3dd5cd83bb46b12e1ec2a8b9d7dd5b61c5a9f4f0704504e2882068034db62e8a9abf3c7c5b9a8bfde509d36899fc5b4e5bef940fd447b9275024febdc9a91d6d56012f1c6a44f94b96397ff2c78fd617870bf089067c6343ae4270f6e6dc495a260bc1ccd0a1c0771821895d26dd66a203825d19e621b86b57f9a51bceae9bb14d1f9961c5a904a64a1dad73c89129ac4920cc4e86e3696959be3305f6d5e33baee00c7f978bf7a1a7864ed89132ff350b45226e6e4db39122bd344c315208edafdfe6b567677f869b64532bed2f7f9087e3c6c1137004f205ce1485f1b9c3ec798b0509c00f6a2b6663048492caa3889328ea6216e34b959fd244249048cec8c0f7de2ff97105ad030a536ec6c4103b33c26acf4539a1b74a0792b9b6c80f95ee4326b09934e068429242495e51a49a712f8513ce91da60573e83443a0e12ac2a174b82d090813b930e10ed7cd44ed72d20b061e9eb253d715408d79d8a77d67919bb196dadcfb84bdc4eb647a4ae09c436d220e0ce914188c49fe9ffaa2fb87f08809d5021cb632a6642bdc1e3664e84dc0afca031f0150c4190893da6462dd917655930a6d1deebdf4a0b1e461126fb2d54d374e4d5a455a6207291d03d2d138e34260ca0ba2286044afc4d95822bead1eefdf0509cb4a0c09c3425c8b0e9236703cbdf4ba833ebea4942d4e0ea84df284c438ffae28b3ec7ded12dda8bbbeabdd07bd1925912aeb74bfda42a62f8a5e716949f4a195f38c9f7a041776c69a7a1599d6880299f50c3b75e6a9b5e0314731611154d1f755a1381fd7575a6b34019d37c40aabb4bcd6965411f48f3b893e5627748deed82de02e9d47af8d3a087f661dc5f2c65ea16fdb6455a6211c77fd41532017ac4aa17bdc43e33aa4bf6ebdd453fb90b863aefe4281691a736594d714bdc26520fb954fa4a3c8d8f5620316e7b8a3b736b28859514bb2ac434001a129975e0f53f473c41ad752670598a2b356feacdb9e4a609a44e83167539d4e3223143d19f79738b96a27171009f17fca174a8821c3f0bd7dd15b2e98eb3fe1437dbdbe881f9c86c0844db5ee82b627c519fae5ea7b5dabc382c9938529dc031f8cdf0ab320f479d8793081f1ecf45a2af3d339db470bea05607148a060348cfb344edcd773efff7645f021d67db2dc0abbe9a8fc343016e9e57933f642f487d649e3a01ad4f815fe3701750d67b1db3c74c6b30f7923d08a807e78e58aeec28691475bbe4260db35b8f850330fbf68f73f944b745208748261f32a9ee5929cf924193fbca8f7d15d0118e3ef205f6a639e4a25bb23c28f036764ba7dfb4f8203eb0b69e757fe5a40b560cae416eda6195f15330aa7f4ea8cd113c30583675a94c486da43a0f26dc5d922aeaa8b084124f5c5dbd0ef31e4ed52de942b1f8ec6b494fa9e730e8f0cac9ea3153610e13ab589d8840e5ecef5570b619574477e457c529d431a48fd3679f0a831832b9a1ad4cb6c99c25e0c1bcd2cc73ed79b2a589501e2abab2d2a64c9fbc4cd8bf14800f8a67d46ef10a68db32411d63fc36e8125bd0e79b27d861324afa6929be5cee98c245f0af5755595f60d29d485222c4a43e2614d315723c5eecbc836242a028053ff8a4c83324edbd6899887c3ab3394d5725effbb55ff056c35fdde91c28a34362aa8ab06f0f1da408e7be1863ef007b57ee062c5e660e2bd221a306774e7b7ed5fe5d04e3a2fa49a61a9d15e4aea12bfe588f7f7fe357581772356998126b1deb48988b56506eb805be01c07f3706100658b5be1e96b1531f8838d78cbb849a4e51c1a80d3776987407c0a1610d43178962c5a34cac6a62e8aaa963b8833549f8ef954e155f962b6d6ea4ceaa9f711959fdab71a74e8ef57ab16b477bbe47b78718f8aeb29239958220b079e13dab8f77ec24be4c3df3db9d9e306c9da8bcff284c27becdeba20ccbdf94f7853069c936ebb209f2dcef4d5b0c73a68c5bfa67a2366f68ea00603ce2b1fbcb897e80b1f7013d50355df6e989c660aabfecf886ccd69d86352c81350520bced1a2beaa0dffb1362c8b3857f1f1c17393fbf45ef639b1f6be41ace5f1e132e257a96af92727bfdba6b1cc09864c5b085d13be7986a4e720a49065f1c70e140f69cc462ab7bec075108d1384f6935781bec4dce9efad2c8e238e7f41b8e430ba231e9e23c6af52bb0dea07e6a0ffb0a3549db69ff05b1c7d57b1fb5f98b75122b0d53d038a37f3c499d9c891fe571015bf6fae1f27cd1c4790f633cc88b9f018bcc79e1857328fdb72eb7e0fc50558e2ab338fb902be7535c12c0235b21ccc3102454e75b20d5652231393ee2f14b5c0bf2ec8a485c02fdead3fb371b41f43d69a518444a92a6967ef3846db7661d973206eab07fd08f69b5a3a36cfe749acf67c2db8df7994821df76a74d8a36521cc6f4de3e1035e18e9640417363427082daf240e71f60df231fc22b8175620c74e2899eccc35387901cf57f8ea34d3f2a4165a4b7f9c41082ce46980480608c539d7f248a41c1ac1a7d5d28884b7ef5d184938d94dd473fa28ba674ce934807f56276fa821da3dfe5f932bef6565aed54f5c3517ace0c9221214417b2d523ddb65eb4bf68c547b4c40ec52ce09c51e1fa64422b21b412a8cb416db685469ed047e2ae26ca06de8e10abb64bec6ca07884927b51968daa05573e35fed3d2ae343126287069190029b9a7a724c177057dba050c3b18c0222de84a50e2413eea9a12f50d94ceefe48995ddf907de29a46ce561cd8242946eaed26474e50984ac005be37fb745254f3df97f880cd24732a46626bf4975bc6c749ac1c75833ed99b4dbab1d71267b82758229bdcb11cd234b8c990478de16160cf4989df335f646f6286d6f62f350811942df2f645afb14768f50ddf221d8e029674d40994c2ec2c4eb12f9ea6aa14d81a0bd8c3b62aea41877104ba9f50ed75c53b5f0cf4d913b7878b38dac9dd45abc35feacc53dd9cbb3029689cef401df37529318390341babe225094f268a886ce3bd6c6e5bee7849ab4f37c11505c9fb71ea7ca9db1c882dff90d91f1c046bc0b2306f341126b6becc475c6dee4d5aa9bd77852316b72a9189a6c309002f9be5296a0307895a6f729d7e3386cc9b18aed6b2168847a160c11db23400a80d3121febde4e480f2c7399dc71594ddfafcf868e60cc97ce8dd6861efefd9f92e61987ea7aa5baec0117866c387e07a798a1efce156b5ec8ddb3794b3035e34544e9d9a447c9a57aaaa63766fad9be9bf6ea08aff67c90792613b5b54b483f2965cde93f4b9bafc90e3510bbe1d3bc13ef88b08fdabce53bfec8b26eba2f09f5701915cf72c095388b635c8a6aa14d9c1d836367860450591c35230ed1759928b80575ac152b97ece0e025a283f62ef90ecfa1f3a3eed39068ca91d6b0f35f22edbd54637e29382244c8dc62e4714d6c729a1825dbc13e4e245ea5ce221e98a8d25aff7f65336f634f944c5e33fd99cc20202fce700fe053207ec9a73237da10ab2da53ff5f0ac0adcbcdfd31a642dd69541b7661469a97e87fdb91f1c9a533e0cabfd12e0a015e96fb3f5154d6cdf4e2a593780bcc79f918bd1844ffa62a0637c7957866e779e491d864b409627129fd5442cceab809755ba78aa08885e7daca24366554dc75839e75a66c30c5937987f197c9bdf377b3eddc8f24447e96f17bf8633645ac81ca2baf52f4738a52afbe0b12068ff44d5bc35a3f83986825aefaba9fc29ae57f74dba2d3f24d3692bfa33beb46b75449dfdb162b0ca5afe93d3f54d897c8aa7e3f7fc9f632cd348a47e1837e3aec9da2fb675b169af643854a2714daeb2f060480d18f0fc84eb1becde4368c2886867a9b621ac3966222ea1a5c1b2e2aad5a6d24ed21533c91f9a8b019195529a6e08eccf10f40563c65ca50bfa78d83ae54ca01cc21925375ac8d10de1adbe763ca9d885e5b28565332d184878947f6b89a51db652ecd0155625e4cd472e5f366dcf79b36e79465ca7a3c236f3ef8c4acbd83ccceb8b19b91855dee1122f15627c57eebc26967f4263434b321bd4cec915975821e08f9095ce6d7705493d850c0da356fb8cfe51395d1d7ba7efa5d4f1cda7b735f13d0183f8f1a282f28a24ca0f0e719b5e567186ee1255d241e66790bcab2e55846085d1f025e38a2d36ee014b40cc2c5afe253b858774e34c026bd8dd65264e08df28f22498f88e64aa4d42eed7f98d9b81b593b9adbbe99cccf617f5bc2809198bdfb460e8335eb8d6d94e278a50f902950103b902903941e6e79ed44f046543182b5bc91c08ba91a53a50351470a6a64215b1b87c4487df0d23a191f8eb1429db96776bcf42b0ee0556ad1fbe54589ed283901d3269a783e1ffad95d3b98c52b6d6de730edd4c93a652f53d76f8f3d343f04953d81c43c9e96934df194297fbfda8098baf1a277fa49615b9e429562f2b5cc029a76da5915d35c96922639f5d2f3157f5edb63918b663d299a2ebba2727117c328d73f83959a82cfb392161c98ceb2b1d6b8f0b78ded12dcad63da02414be8c853c5a7186f13d6c8d9f7f738356fdfbda49449bd2873e7fc5e3d7135d59cad6abd758dd954c72b9ac2a52a9f4d40e675f17807f69af4c7119f4dbd26492d194d64a18334c5afdb8d4ed18eef34578d9a4f9bca31ab5c6c6219a3a2fa5b9d29feaca1b37c24115d4fbb2f8a8282df604b24a18cc56215c791042a7f28eb859d2e57d43ce6cc50edc48688a0e449ad4aa6f5c00c72dcf0322d2a022b7fe495028bbc89ab53982595755f384b4bd723a7f49d77a7288b2b5b51ab4871624132bacc0fc1315250635bfb8bab3efa73b75b890b8701a48eb67ba421c64e50d2d6c823b7ba0e8a6bf7b371f65e08da37ab9424b876910fcae73aec09b44210aa4a4b8e401d055a9dcd5bf5e4869c72b0eb51a9d0a1e3405cf91564554a549b16e1a6b9fd90f435e2d652b45be313ac6b7bdeacd499bbbc61a00f4efa6932b3f01c0c24f7eac31955296677a50fee299536aa9df12168f3e91edcd2b634eb8fd6570f99a24abddf4d94cd77f2f087dc905dfd0eaa228c436935cd1a74f6f9d72f0ca11283e15632403d786258cab7d224e99e7fa7b59db465f26965532450cc5260e3951a32102795e2d0d5cd968fb356e142103f5204762e194d130789caa35995091faaf9167d3e3d144159b659a0f673dfdf2c6a0",
|
|
+ "note": "rounds strictly increasing; rows canonical as in v2 (index, then scheme); every Falcon row verifies over M_r of its round with the key of its index (keys below), the SLH-DSA rows likewise"
|
|
+ },
|
|
+ {
|
|
+ "id": "vs-28001-1000-numai-r2",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "hash": "0x3333333333333333333333333333333333333333333333333333333333333333",
|
|
+ "groups": [
|
|
+ {
|
|
+ "round": 2,
|
|
+ "rows": [
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 1,
|
|
+ "signature": "0x392d747efa5df9ec7976b575ebbbbc4e50e48f494255067d00c8fb6ab805f5dde05d0240f101c33dd0aadb317a173e25a7dec0ceb77ce150099f5ca19dc2df6e44a5b5fc87cab441dc4e6ee717e77d3ffc2bc57ea828567dcbcdb8831dbbb613c0f747fc497e218f903efb5f5c5a2c4e61879bfb069a67eec30acb8af36d1f4a245b9f120c6bea336d8ba3eba72be78a3ded415117b3ed0babab6ce775e1c1ebee9d08f4a0923ef969747533a3a9fc13d19b4c5b1eabe6ade431ad5731c5ccfe98681c31ade95e7d5bf469024456082d06df3fd4e6970fc2533bb9cf6688bb595edacd95f68d1b31a396d8af954e37fd43d6a366757853a1185d62e18587e2cdb51f0a7023f2b3cb9646ffda39e46e98c47f68bb3954a140f5bce405977eb8974c229305c2ca3c7017891f208a041a89d48d3344695cd9106bff8b80a0a48dde46ba4ecb942344cd1887e2f889a5b97e96651dfe7d3116a2b17a86bf11be8ab8bb69f214b7a0dce316367e827192ec0e9a0ac2199b1c4f1042655ca7cf3d1f8da99341afe8f0b1f21338492ecff73f65239f4ea6a5dfcbd08ca9bcadd559dff34a6a8cd9a28a579fd54384f35ceaabab930b87b14779fdc822a587d04910b4d693f288b26d56688e5ffb2d65d9374a32c27dab9778f618df54c15f555f54828113a595fc1ce107ad2ae7592b41e944b0cfe48cd21d36d4fb35dad4de5ffe9531f9e927a25942461a4c9726a292d2ef9dbc0b1d0456b703037b4df9d0c446d707285b9489e8845211cf0e8a3f0a32a5cfc713902df29af2813293a48c2f02b8dc336befa797d3d3f67d90cd4fa25466bbe70d394713fa06b606de967d5a5aa9f8d0310363f7be1a75708d4c72511f67eb2b0495c43e75ca6e085d35c53cdac3cc09142647e68fcbbe921ad25080"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 2,
|
|
+ "index": 1,
|
|
+ "signature": "0xe85ef5afbd04ae28867b1e81b818d79445b1a8e98c272154ab5e8a7797af50d972b241bc0d536481095419bb18be70860dbe9c5d355d74451f31e27209f3d43cd2a633cd961971c381058ad667a9b2e69f0fe9c2a557ba89835fabb16decc1915b54de7b5f00aa5787a39e8d97fdff315a7a0d2aaa5d3e10fc1a02ae74797c43a2719d3361805f5415dbceb716bfb7b07ff4a415a938008f0f9a668395801ee590a83b20d5749facd7f99bece768e7e3adc0e036b82604cf9a9e5c7010db9b54965d094ba9c248f9f4e29045be7962aa6e7243d450caee40bc4dfb9b333e6c289509f899b254d85539a78f1194553bbed9dfca1044372ba2530f2b05ed4a467728474a1d603eba54e4fcf2295c6a559e9c606b6b70c40d4c8cee286f2d79d6f46a8c0079130c2f58cbf4b3ec7fc109cc1ca3dea2ddfaf377eb357ac6b5877aa6f2e1f56df3421daa6ed5d043b5188c6ef1c71d765b3d94815027ea7838d8f448d0fc008d3a0189958ae6fafac687990f5b7d43c103ab97780087f48bc3b7a19f76a945a0d90e1ff279ceef8d32e2b5fdaf3c5d1a5ba52e60dd934cdfdc2492330a5f150f2106ecad186cf1f6ca3907707e34becc8b442ad3dc5ecaa7abfc7bc19cb7a7664ecc127c1d4d0f0515eaa3099def31f3ba376c30d4044ce8cf7669ca465f140ac5ca43f9e856721be03231e6b0cbc655c03b9f237036a504ba29da42b5959029b68f0171ccb5d1a2ca379250d3eb5591ddb52333b954e152e644bf8c8c22ed3c3b471021eeb4a25f2adc63f792c01382e9c01693c4dd9ad333c198e4da0b8af182bd87d2919f2bf4ae94130931cebe0524c1df1cdaed0767ae040ee0f042ae8b2e0674fedaac068db64ae2998f1e29d4fe208f3ca498a1832634f7183a8d6902d86823e12f5bbecdcaf9935f808d72e18e62c1a117ab27bc9acc3287afbd6f7442f4eb48063a381495170171af2d76e3672c37462bcb6c1710afcc873b9168e4bb6887117a9925e3a2b2bc33d0db4fb33809e3768d47ab3b52bd655c71539d8a7e391bcaeafafc71c554e0616d6f6d9ddac0285ce5b9dd9bfe015739925705edf72abe615a376e3fadf3e5807d97a7ca5e4a378ead2a466db9773d3a7d3f7627b29f1183816edb236b4b20af6a212b9ba1b86ed143974777a3de41aaa3a17371aae38dffd3779f254a0da8d9219d98d89049ad55d71e731192bb769ae72e466a67e82dc1b133b9e5129192e2e611d8d8035f6e0dba92d6cade096c56b248237d9405a534d6205e59186c1e5ffdb1dfaafeadc15eb2d11c736b0e57ceee75c6ebdc78c2ce24fd852e87eeb969e14d8d2aef1ed623914bd1932d8dc26bad8e6b3b2afcf8139ee97a4afb1db36a23a94f0ba00c6c6ecd072851c456e72a69af515c7e7d872ec112729168879f1812c9de0cc380a994182a80e4195765d53eac82085ea751cb09eac5f9db99aecf51e9111515b083ba65cad1d6687363c3155f39e5c7124602a879f1ff153f4ecddad23ba9d99384840272613f40e8975118e17a50a27029b5714cf9f3db14c3ded35e31b45fe73fc06a7fe8cc96937ba3e82dcb226be47e45bb6e971ef5e7ba2013cbccb6edaa51d3611452f3c26860232193512e1ca915ca1e82d1e81da1a84b228d92d855a09721f662ff3d58eda5846977f40d2f6fe0845ad3c8cc2c9e6d9e673673d9245f5e55a2f02b6e47e01d27e809572a003809b75177880cc5ded3fde42ac59eeac1f0508eda86e4b4eb7f2de0f9b8500f766798ac7f9583cef34c7faca5efc97ded5585b0c39e0f16fb2401fc50a588017ebcdae043bc236f9309bc4d6c04f089a898263c7897feb006a6af16240547c96bb52d275130bfbeb20f2493713f29eef0455c41134f4f9f27c38d29dd1a2fbb6ecc40bf41d9f32e33352443c299ca7ef6881575dcd4f18ecbe874dde9e796628b21e6a7dc6827587c61fad8a8fc63b886c6f383243a20dcd95fea8e323d0e9811bccc2fd97cb0a347097ef1b5296ea8da5361c3df81672bb179e51f41082ccbc4c4f0c2e2eed5f8f131a2d58aa68caf0aa1a6d9c8aac9f424f7cdd2acd2875d4e0238f35c70ce48c966e114344ba6c5403545a4e8a467bf9cf7ebba117701a5e69a2e71a546d3b674468d4a31bedfc6e70fc0c4c8c3efff332b4b8e1dc604541091dd34a584d333d7291304c08286542b0075f371429605798bbd71ed7ca52ba6b812c7ca91c8c35c2a4f853eb7509c12049150eb7abca4498f5ef4d8dafef8998afb4527b65cd3e6ef1399041887f204cbc81fc030e6242c4395e7752a6545da4996b69740922c07881c1d5bbdc79beab8b17b5b0980d8fad7eeeb5785fbab08a7963bff7e95aa7b526dbe201b968a40f8db9399e7ff8aa18e6f095b9aa4cf4c41e57a78f10f6fc580a955e84f48a8c2b16d13b8b8efa525f1d51426a13325ea3384a5638577f32267f00e2e262f08d46bdeea4891ac5acaa3e3a31fd503dc76a3c92ded39edaa65043b60d52ffb6ea27cbf810899552d4dd5a55e95e172e267be645a3f2c6468b5b1ce76a0b951b85f98efb93aca8b3948c43cbefe76504f90128788e7e08f7f6685ee03b70ac35314d3a64a57a4a8cb7512a9254f3a9aa7e9c1990606ce8ca25e6b9c816b56903e10d7ca1db41a7f991f292acb51337230d0a0ac5604259d7daf5b684493ce3344a8892152fb6baca94f5b02237bfdeef0f9dc6fd372b078a05489f81ee232e63a27726746d52c3d9531bdec03f2d4d56b604231b233592babfe12c64b915200f1e16672b0798982293d768278909bb1352dd42381d7e87c15ba92aae469fae5ed023c643b45c08a5d15b29f34714016ce5c52ac648d4a32a4bb02c701f3a68fb873581ac392ea34277ff3262fba6ecbe274c840751ff28235fb3168cf30bee0fab5cb92c89c8ae3ffd8b03c4253078c31ce19864c8b6f128f6e3e80efda9141bedef5b60adc0d6f8357fe6cb6828b3605e02275deabb5326eff3d52861f072523c5695333b4d51c58c08a44be8e90ff8244da37295e1a1550ce715d08fe600349a9f9870ac83fbaada48cc392b75ab1ab456429e5b236f6b3b1751063b274bf6a75dc2283ca0ae8db757fb856e8c7442e4a3cf6f26e608bca09235f05dc6a2a53862cbae5a5bdcf1bff925ff3c25e38d5ee04591b8c228b215e5f82c21f39462aaa6c548c8d581b4df4386b97fd832a46e2212a3bc5ef4716a10e75cd5e46797dc12241bdec3074d19f971caea7a8f24bc522faf8322301e3e4d2188136ddccc53c6488d5d9df6298befecaf637a2693e8d3db2ed2f8e120e6f1ef5a52471e905bc7f62a3b93b534c9e234d72a75f38e443a05ff62ca45cd25293c23e4ae71784fd1649c61b9469eb152642d8fa2db77b85c26340f4b21b1e8ec7ab58b66fea1397e69665dd9116ce6ecb7d642ec9c2114a4c893b795c1be06893697924c42ed8bc97e0c930898d80e71536dedd3ddcd9b4b35ef5eb462ab984b28925aef1cb524439e36273f7056b17036a1f3ab44eed99199dd6d53b564d2f210a7d52ca896ef0af8de172415b518e92c578d256729744bf79ef3ab444960189cc0cddb9c961bc0a7f0bc51be6ffdf2e057331dd7d05eacd8e6e81e08f90b96539b9d323455428e9abcea706fa357949f2d1067b600af355d435bc71094ed8e29d699504d24427639b4d612d3d2c7e50129145a161cbed02955a0f32615b30cc968c41f2d062c32f796da497b379f5955a0ed5a653ee51f52e6a702b478a9a7af4d48fa25353a258e575c2e0c475b169df4471c22e2ccb1ed607bf831eb28e4487ab655f07520391309d3590ad63436ba31d1c37ecbf586dcaefb56d6110386d6a6a5d785b365701ae291b0a3d13b3dec21729e42591de8ef9f7a7216d9dc23489a3fe8d874a76f146aa26536c1dab083681cc00e9dc9e6603d53d74a1c79558c6fc7bf32d98a485dd562f261e7d2751fefc320c5a2c9a536c84ba467d7a82df93b5803cf60a2726ed8fe7287863fa2a674d01c77b053bcf88a9a502b0fb786f47e50401aa643394624968fb5d5dca34b009a3a32bdce673fd2d0c8e05238b82ee1479cb9b8b7007ca03974e1c56e9bf903c2d0c274cae9f588fcc6b47e02754dc0e7de3cb5a80ace5f98ae68244082144ecbac94d53abb9c89e7d102063107c0ddbb6633d0f987b14217a9d9378007cebdb260a9a89596b11422ec3f1136d469e3c188dfc94ebb1cf8c7f7decfef77995e8334d4321525ad76f32a2efd4c953a319e18c4da8981ee89415f7e2f07914d4fe63d6246504b90fbf03b54bd905661705fb65d00d28c530b7b3c690fb5f88aa1edc6f6dc861d79a1e8c4a6dc1df27b7c2f0b897f1231f176adafae599f4aa29c6a5070103a24468677320b9462cb9a2d40696a5966ca205af33e350742e7e50b27252d2ecf50420cd4fbff8e4570e04b2137722814c64ce0b81d13c14af64eaf36207ae8f9224a47b3c3c0c0996db171544bbe11f2407203eddde94614c9d41945645dcdcabff12cf2fcd01cf062b942bede9184d830fea37df7576b10bbfabdb4a4626979576f403f33060ddfc6f53df73ca618654768001f1e08bbd66de39e8eac625d4f1deb25681c2dc67c6764d555338b4293102191a96cffd8859eb08ecda0489af07c301c12913762fa3f9d192f74c762f50556726c3bacfccc66a038536e913d95186d8aecf381312733beb68b6cedad321fa4e3fdcdcfc5553548a30e1ecf0041f823ec863086c34b3b6e6a7af8a2214122332a4d27392e64cfabb1a9c66c498efb6515f32f01f23073693a37a72240df9709d577b3e184cccc8b9cbf34669b0653e16848ad0a9dbc9d7b0ce3ab88e98616492c83d8b88673aa6a1b93d2f7866caf1984da384145361fcad93640c7481a085b0be84ffb4870705371cabe56f82a233b3d5aab737a2f2b9877fe2885d48163e6c55a53627e6db0a9c7103c867bf829633af2e1379a537267a15765c5ffbf7457eb853d0049f497a7823c0489dd0a1490667b600ccc80f9ebf9afbc007280e4a93b4c20dbb07c10ec4646ce9cd1b3dddacf5ec7bb07d588501daa9ee422da47b4f69f6cb49b3201e1b461b5d4d60d4230995acc88dcc8c928251ebc8d37f3e0dcf8218bbac5e47653e510b270586859238c526c46b7db46e817e467c7fe3f41066e234f4756ac833c9d010fe800e51106deae8eae63d2d9d02c2eda4ab19d63600a5261e69075cc0e28220a3ca4cbfd53f14f654c09a62f6c70fa75368678a7e3936aaae6a3c94d800f95888777bfd394907860ff4446b285345768556f34b1c62cacf50b4ab820d02a18cacfa3a42f086906213e170f26a21a0c7f478d7dff393d68989622e4f89a46845984d1d28ef6584f13f135d6a18fa438e635f7670e3b9e0236d7dc9f99328a807e4468fd7438c56449556c1c13e478072602172f923d0cdff16786fec072f0629a0423025594808ca65d0ee3144947a44519e04b6abd779dc2d119ee4473103e1d608c0e254e0b7698bc876f2d810e4b41f37c9884648d0536069a80f9891d0e2ec4394446b70bb0ffb8032959bb04b82e75f577b8c136b6c87d1f98a962955af7286e4f1a098adb1bef56655757dc5e24cfea40eeb8f37b57edc8b85685c7f1681108f793b7c12df1a203596b57c92f9fa62bc9a1db3e7ed9c802500c7e305606fb82ac11df65c7e40c1fb09084fdd390f55a94873c7a32c0c9d389206d7695220951ff3fcc62cdb39a015649bb65040a06e54111127fd947f344d782f99b59392660917838f2dde4b04038b0baac6966593a8ea2eefa1423c4e9537eb804cb7d58fcbb1eef505ba06b1682cfffc4eab227161bbb9c3aabaec99f2e08fa650ce99e9c02745927ebaaef4f2c70713c97b34b734016a65a0e69db084101289443770fce47722a4c1af6ce554d09aeb9b3e2f076fada5f5fd9c772ee2cb65fff9da7b33e1b2f6a08f1536a403188c771fff5a84c8bc1509ef2dacd23cc699a242f5492bbdb82f13f4b9766cb1465d3d79e5ff9499fd812d346b8ac6e7c8cb83a603250a52daa0a55e04521f22a4246c5c149bb3426639d84dc651f7246d11ff49a2597b9a77104bc2cb1880f0347f2110b2cf33866aaa6bcce8e058e03aee01191adfee651694b506d952210398513a9313836e1457e5e8de9bdf26ed7301c3b6578a291d73cdf2602f6493e7685dff5e7b4db4c0fc151e253009234b251ecebeb10c2facce66e125b8fc8c6a78926dff9dd250037a12aa32c086c155f980601ab25de4bac8ce364c7fa8fdd965ddd03dedc8de498dfd3cfdc86b0b56398b10245dce984f2c5087610efd29aadec6eb78c18956d6912203f7016f3f47452578d1b718b6d221b38782bab9e29b344dee9deb594d8798a6a01296f5da1f143743c61c402700fd33904b43d8d6a44dc6fc04fcb9841544dd9116a5b908f06dd39be385750a4371f7dbce8b9b75aa01fcb4d2a1a94f22b7bf876153543f410e7f8c1504aced875a2e054dd5a2138eec9607d5d5ae7bae91da662c415ac6f0a9bb981393f660695e4b65b16dbaf35ec0d40c68ff4fd991e8152e03152c332e92a62c2bea76c0a239387148409b6a7c2c98c24b506b059869cb911a30cf15c22e0ea0f86db884040f7cc8f58b1d3fcdc251d223a285f191ee4bb2de83365ef74726c7abfaa9146c308530edde09be20e9d6eaeef850d00b165e768463b8793a914c421bb81e8905938540c64b77e82ee6a4a6a15f5cfb1df20a41305ad3dffafc7e8d882a3c9e3635d115c9314d8f3602ba752734e34e188c3cf46b3dd5cd83bb46b12e1ec2a8b9d7dd5b61c5a9f4f0704504e2882068034db62e8a9abf3c7c5b9a8bfde509d36899fc5b4e5bef940fd447b9275024febdc9a91d6d56012f1c6a44f94b96397ff2c78fd617870bf089067c6343ae4270f6e6dc495a260bc1ccd0a1c0771821895d26dd66a203825d19e621b86b57f9a51bceae9bb14d1f9961c5a904a64a1dad73c89129ac4920cc4e86e3696959be3305f6d5e33baee00c7f978bf7a1a7864ed89132ff350b45226e6e4db39122bd344c315208edafdfe6b567677f869b64532bed2f7f9087e3c6c1137004f205ce1485f1b9c3ec798b0509c00f6a2b6663048492caa3889328ea6216e34b959fd244249048cec8c0f7de2ff97105ad030a536ec6c4103b33c26acf4539a1b74a0792b9b6c80f95ee4326b09934e068429242495e51a49a712f8513ce91da60573e83443a0e12ac2a174b82d090813b930e10ed7cd44ed72d20b061e9eb253d715408d79d8a77d67919bb196dadcfb84bdc4eb647a4ae09c436d220e0ce914188c49fe9ffaa2fb87f08809d5021cb632a6642bdc1e3664e84dc0afca031f0150c4190893da6462dd917655930a6d1deebdf4a0b1e461126fb2d54d374e4d5a455a6207291d03d2d138e34260ca0ba2286044afc4d95822bead1eefdf0509cb4a0c09c3425c8b0e9236703cbdf4ba833ebea4942d4e0ea84df284c438ffae28b3ec7ded12dda8bbbeabdd07bd1925912aeb74bfda42a62f8a5e716949f4a195f38c9f7a041776c69a7a1599d6880299f50c3b75e6a9b5e0314731611154d1f755a1381fd7575a6b34019d37c40aabb4bcd6965411f48f3b893e5627748deed82de02e9d47af8d3a087f661dc5f2c65ea16fdb6455a6211c77fd41532017ac4aa17bdc43e33aa4bf6ebdd453fb90b863aefe4281691a736594d714bdc26520fb954fa4a3c8d8f5620316e7b8a3b736b28859514bb2ac434001a129975e0f53f473c41ad752670598a2b356feacdb9e4a609a44e83167539d4e3223143d19f79738b96a27171009f17fca174a8821c3f0bd7dd15b2e98eb3fe1437dbdbe881f9c86c0844db5ee82b627c519fae5ea7b5dabc382c9938529dc031f8cdf0ab320f479d8793081f1ecf45a2af3d339db470bea05607148a060348cfb344edcd773efff7645f021d67db2dc0abbe9a8fc343016e9e57933f642f487d649e3a01ad4f815fe3701750d67b1db3c74c6b30f7923d08a807e78e58aeec28691475bbe4260db35b8f850330fbf68f73f944b745208748261f32a9ee5929cf924193fbca8f7d15d0118e3ef205f6a639e4a25bb23c28f036764ba7dfb4f8203eb0b69e757fe5a40b560cae416eda6195f15330aa7f4ea8cd113c30583675a94c486da43a0f26dc5d922aeaa8b084124f5c5dbd0ef31e4ed52de942b1f8ec6b494fa9e730e8f0cac9ea3153610e13ab589d8840e5ecef5570b619574477e457c529d431a48fd3679f0a831832b9a1ad4cb6c99c25e0c1bcd2cc73ed79b2a589501e2abab2d2a64c9fbc4cd8bf14800f8a67d46ef10a68db32411d63fc36e8125bd0e79b27d861324afa6929be5cee98c245f0af5755595f60d29d485222c4a43e2614d315723c5eecbc836242a028053ff8a4c83324edbd6899887c3ab3394d5725effbb55ff056c35fdde91c28a34362aa8ab06f0f1da408e7be1863ef007b57ee062c5e660e2bd221a306774e7b7ed5fe5d04e3a2fa49a61a9d15e4aea12bfe588f7f7fe357581772356998126b1deb48988b56506eb805be01c07f3706100658b5be1e96b1531f8838d78cbb849a4e51c1a80d3776987407c0a1610d43178962c5a34cac6a62e8aaa963b8833549f8ef954e155f962b6d6ea4ceaa9f711959fdab71a74e8ef57ab16b477bbe47b78718f8aeb29239958220b079e13dab8f77ec24be4c3df3db9d9e306c9da8bcff284c27becdeba20ccbdf94f7853069c936ebb209f2dcef4d5b0c73a68c5bfa67a2366f68ea00603ce2b1fbcb897e80b1f7013d50355df6e989c660aabfecf886ccd69d86352c81350520bced1a2beaa0dffb1362c8b3857f1f1c17393fbf45ef639b1f6be41ace5f1e132e257a96af92727bfdba6b1cc09864c5b085d13be7986a4e720a49065f1c70e140f69cc462ab7bec075108d1384f6935781bec4dce9efad2c8e238e7f41b8e430ba231e9e23c6af52bb0dea07e6a0ffb0a3549db69ff05b1c7d57b1fb5f98b75122b0d53d038a37f3c499d9c891fe571015bf6fae1f27cd1c4790f633cc88b9f018bcc79e1857328fdb72eb7e0fc50558e2ab338fb902be7535c12c0235b21ccc3102454e75b20d5652231393ee2f14b5c0bf2ec8a485c02fdead3fb371b41f43d69a518444a92a6967ef3846db7661d973206eab07fd08f69b5a3a36cfe749acf67c2db8df7994821df76a74d8a36521cc6f4de3e1035e18e9640417363427082daf240e71f60df231fc22b8175620c74e2899eccc35387901cf57f8ea34d3f2a4165a4b7f9c41082ce46980480608c539d7f248a41c1ac1a7d5d28884b7ef5d184938d94dd473fa28ba674ce934807f56276fa821da3dfe5f932bef6565aed54f5c3517ace0c9221214417b2d523ddb65eb4bf68c547b4c40ec52ce09c51e1fa64422b21b412a8cb416db685469ed047e2ae26ca06de8e10abb64bec6ca07884927b51968daa05573e35fed3d2ae343126287069190029b9a7a724c177057dba050c3b18c0222de84a50e2413eea9a12f50d94ceefe48995ddf907de29a46ce561cd8242946eaed26474e50984ac005be37fb745254f3df97f880cd24732a46626bf4975bc6c749ac1c75833ed99b4dbab1d71267b82758229bdcb11cd234b8c990478de16160cf4989df335f646f6286d6f62f350811942df2f645afb14768f50ddf221d8e029674d40994c2ec2c4eb12f9ea6aa14d81a0bd8c3b62aea41877104ba9f50ed75c53b5f0cf4d913b7878b38dac9dd45abc35feacc53dd9cbb3029689cef401df37529318390341babe225094f268a886ce3bd6c6e5bee7849ab4f37c11505c9fb71ea7ca9db1c882dff90d91f1c046bc0b2306f341126b6becc475c6dee4d5aa9bd77852316b72a9189a6c309002f9be5296a0307895a6f729d7e3386cc9b18aed6b2168847a160c11db23400a80d3121febde4e480f2c7399dc71594ddfafcf868e60cc97ce8dd6861efefd9f92e61987ea7aa5baec0117866c387e07a798a1efce156b5ec8ddb3794b3035e34544e9d9a447c9a57aaaa63766fad9be9bf6ea08aff67c90792613b5b54b483f2965cde93f4b9bafc90e3510bbe1d3bc13ef88b08fdabce53bfec8b26eba2f09f5701915cf72c095388b635c8a6aa14d9c1d836367860450591c35230ed1759928b80575ac152b97ece0e025a283f62ef90ecfa1f3a3eed39068ca91d6b0f35f22edbd54637e29382244c8dc62e4714d6c729a1825dbc13e4e245ea5ce221e98a8d25aff7f65336f634f944c5e33fd99cc20202fce700fe053207ec9a73237da10ab2da53ff5f0ac0adcbcdfd31a642dd69541b7661469a97e87fdb91f1c9a533e0cabfd12e0a015e96fb3f5154d6cdf4e2a593780bcc79f918bd1844ffa62a0637c7957866e779e491d864b409627129fd5442cceab809755ba78aa08885e7daca24366554dc75839e75a66c30c5937987f197c9bdf377b3eddc8f24447e96f17bf8633645ac81ca2baf52f4738a52afbe0b12068ff44d5bc35a3f83986825aefaba9fc29ae57f74dba2d3f24d3692bfa33beb46b75449dfdb162b0ca5afe93d3f54d897c8aa7e3f7fc9f632cd348a47e1837e3aec9da2fb675b169af643854a2714daeb2f060480d18f0fc84eb1becde4368c2886867a9b621ac3966222ea1a5c1b2e2aad5a6d24ed21533c91f9a8b019195529a6e08eccf10f40563c65ca50bfa78d83ae54ca01cc21925375ac8d10de1adbe763ca9d885e5b28565332d184878947f6b89a51db652ecd0155625e4cd472e5f366dcf79b36e79465ca7a3c236f3ef8c4acbd83ccceb8b19b91855dee1122f15627c57eebc26967f4263434b321bd4cec915975821e08f9095ce6d7705493d850c0da356fb8cfe51395d1d7ba7efa5d4f1cda7b735f13d0183f8f1a282f28a24ca0f0e719b5e567186ee1255d241e66790bcab2e55846085d1f025e38a2d36ee014b40cc2c5afe253b858774e34c026bd8dd65264e08df28f22498f88e64aa4d42eed7f98d9b81b593b9adbbe99cccf617f5bc2809198bdfb460e8335eb8d6d94e278a50"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 3,
|
|
+ "signature": "0x3941e6e79ed44f046543182b5bc91c08ba91a53a50351470a6a64215b1b87c4487df0d23a191f8eb1429db96776bcf42b0ee0556ad1fbe54589ed283901d3269a783e1ffad95d3b98c52b6d6de730edd4c93a652f53d76f8f3d343f04953d81c43c9e96934df194297fbfda8098baf1a277fa49615b9e429562f2b5cc029a76da5915d35c96922639f5d2f3157f5edb63918b663d299a2ebba2727117c328d73f83959a82cfb392161c98ceb2b1d6b8f0b78ded12dcad63da02414be8c853c5a7186f13d6c8d9f7f738356fdfbda49449bd2873e7fc5e3d7135d59cad6abd758dd954c72b9ac2a52a9f4d40e675f17807f69af4c7119f4dbd26492d194d64a18334c5afdb8d4ed18eef34578d9a4f9bca31ab5c6c6219a3a2fa5b9d29feaca1b37c24115d4fbb2f8a8282df604b24a18cc56215c791042a7f28eb859d2e57d43ce6cc50edc48688a0e449ad4aa6f5c00c72dcf0322d2a022b7fe495028bbc89ab53982595755f384b4bd723a7f49d77a7288b2b5b51ab4871624132bacc0fc1315250635bfb8bab3efa73b75b890b8701a48eb67ba421c64e50d2d6c823b7ba0e8a6bf7b371f65e08da37ab9424b876910fcae73aec09b44210aa4a4b8e401d055a9dcd5bf5e4869c72b0eb51a9d0a1e3405cf91564554a549b16e1a6b9fd90f435e2d652b45be313ac6b7bdeacd499bbbc61a00f4efa6932b3f01c0c24f7eac31955296677a50fee299536aa9df12168f3e91edcd2b634eb8fd6570f99a24abddf4d94cd77f2f087dc905dfd0eaa228c436935cd1a74f6f9d72f0ca11283e15632403d786258cab7d224e99e7fa7b59db465f26965532450cc5260e3951a32102795e2d0d5cd968fb356e142103f5204762e194d130789caa35995091faaf9167d3e3d144159b659a0f673dfdf2c6a0"
|
|
+ }
|
|
+ ]
|
|
+ }
|
|
+ ],
|
|
+ "messages": {
|
|
+ "2": "0x9b03be36eb916bd6ff4868240bfc66a2631dc806818ae44db48178aefb6a997b"
|
|
+ },
|
|
+ "bytes": "0xf9242a93414552452d50512d5345414c53544f52452d32826d618203e8a03333333333333333333333333333333333333333333333333333333333333333f923ecf923e902f923e5f902920101b9028d392d747efa5df9ec7976b575ebbbbc4e50e48f494255067d00c8fb6ab805f5dde05d0240f101c33dd0aadb317a173e25a7dec0ceb77ce150099f5ca19dc2df6e44a5b5fc87cab441dc4e6ee717e77d3ffc2bc57ea828567dcbcdb8831dbbb613c0f747fc497e218f903efb5f5c5a2c4e61879bfb069a67eec30acb8af36d1f4a245b9f120c6bea336d8ba3eba72be78a3ded415117b3ed0babab6ce775e1c1ebee9d08f4a0923ef969747533a3a9fc13d19b4c5b1eabe6ade431ad5731c5ccfe98681c31ade95e7d5bf469024456082d06df3fd4e6970fc2533bb9cf6688bb595edacd95f68d1b31a396d8af954e37fd43d6a366757853a1185d62e18587e2cdb51f0a7023f2b3cb9646ffda39e46e98c47f68bb3954a140f5bce405977eb8974c229305c2ca3c7017891f208a041a89d48d3344695cd9106bff8b80a0a48dde46ba4ecb942344cd1887e2f889a5b97e96651dfe7d3116a2b17a86bf11be8ab8bb69f214b7a0dce316367e827192ec0e9a0ac2199b1c4f1042655ca7cf3d1f8da99341afe8f0b1f21338492ecff73f65239f4ea6a5dfcbd08ca9bcadd559dff34a6a8cd9a28a579fd54384f35ceaabab930b87b14779fdc822a587d04910b4d693f288b26d56688e5ffb2d65d9374a32c27dab9778f618df54c15f555f54828113a595fc1ce107ad2ae7592b41e944b0cfe48cd21d36d4fb35dad4de5ffe9531f9e927a25942461a4c9726a292d2ef9dbc0b1d0456b703037b4df9d0c446d707285b9489e8845211cf0e8a3f0a32a5cfc713902df29af2813293a48c2f02b8dc336befa797d3d3f67d90cd4fa25466bbe70d394713fa06b606de967d5a5aa9f8d0310363f7be1a75708d4c72511f67eb2b0495c43e75ca6e085d35c53cdac3cc09142647e68fcbbe921ad25080f91eb50201b91eb0e85ef5afbd04ae28867b1e81b818d79445b1a8e98c272154ab5e8a7797af50d972b241bc0d536481095419bb18be70860dbe9c5d355d74451f31e27209f3d43cd2a633cd961971c381058ad667a9b2e69f0fe9c2a557ba89835fabb16decc1915b54de7b5f00aa5787a39e8d97fdff315a7a0d2aaa5d3e10fc1a02ae74797c43a2719d3361805f5415dbceb716bfb7b07ff4a415a938008f0f9a668395801ee590a83b20d5749facd7f99bece768e7e3adc0e036b82604cf9a9e5c7010db9b54965d094ba9c248f9f4e29045be7962aa6e7243d450caee40bc4dfb9b333e6c289509f899b254d85539a78f1194553bbed9dfca1044372ba2530f2b05ed4a467728474a1d603eba54e4fcf2295c6a559e9c606b6b70c40d4c8cee286f2d79d6f46a8c0079130c2f58cbf4b3ec7fc109cc1ca3dea2ddfaf377eb357ac6b5877aa6f2e1f56df3421daa6ed5d043b5188c6ef1c71d765b3d94815027ea7838d8f448d0fc008d3a0189958ae6fafac687990f5b7d43c103ab97780087f48bc3b7a19f76a945a0d90e1ff279ceef8d32e2b5fdaf3c5d1a5ba52e60dd934cdfdc2492330a5f150f2106ecad186cf1f6ca3907707e34becc8b442ad3dc5ecaa7abfc7bc19cb7a7664ecc127c1d4d0f0515eaa3099def31f3ba376c30d4044ce8cf7669ca465f140ac5ca43f9e856721be03231e6b0cbc655c03b9f237036a504ba29da42b5959029b68f0171ccb5d1a2ca379250d3eb5591ddb52333b954e152e644bf8c8c22ed3c3b471021eeb4a25f2adc63f792c01382e9c01693c4dd9ad333c198e4da0b8af182bd87d2919f2bf4ae94130931cebe0524c1df1cdaed0767ae040ee0f042ae8b2e0674fedaac068db64ae2998f1e29d4fe208f3ca498a1832634f7183a8d6902d86823e12f5bbecdcaf9935f808d72e18e62c1a117ab27bc9acc3287afbd6f7442f4eb48063a381495170171af2d76e3672c37462bcb6c1710afcc873b9168e4bb6887117a9925e3a2b2bc33d0db4fb33809e3768d47ab3b52bd655c71539d8a7e391bcaeafafc71c554e0616d6f6d9ddac0285ce5b9dd9bfe015739925705edf72abe615a376e3fadf3e5807d97a7ca5e4a378ead2a466db9773d3a7d3f7627b29f1183816edb236b4b20af6a212b9ba1b86ed143974777a3de41aaa3a17371aae38dffd3779f254a0da8d9219d98d89049ad55d71e731192bb769ae72e466a67e82dc1b133b9e5129192e2e611d8d8035f6e0dba92d6cade096c56b248237d9405a534d6205e59186c1e5ffdb1dfaafeadc15eb2d11c736b0e57ceee75c6ebdc78c2ce24fd852e87eeb969e14d8d2aef1ed623914bd1932d8dc26bad8e6b3b2afcf8139ee97a4afb1db36a23a94f0ba00c6c6ecd072851c456e72a69af515c7e7d872ec112729168879f1812c9de0cc380a994182a80e4195765d53eac82085ea751cb09eac5f9db99aecf51e9111515b083ba65cad1d6687363c3155f39e5c7124602a879f1ff153f4ecddad23ba9d99384840272613f40e8975118e17a50a27029b5714cf9f3db14c3ded35e31b45fe73fc06a7fe8cc96937ba3e82dcb226be47e45bb6e971ef5e7ba2013cbccb6edaa51d3611452f3c26860232193512e1ca915ca1e82d1e81da1a84b228d92d855a09721f662ff3d58eda5846977f40d2f6fe0845ad3c8cc2c9e6d9e673673d9245f5e55a2f02b6e47e01d27e809572a003809b75177880cc5ded3fde42ac59eeac1f0508eda86e4b4eb7f2de0f9b8500f766798ac7f9583cef34c7faca5efc97ded5585b0c39e0f16fb2401fc50a588017ebcdae043bc236f9309bc4d6c04f089a898263c7897feb006a6af16240547c96bb52d275130bfbeb20f2493713f29eef0455c41134f4f9f27c38d29dd1a2fbb6ecc40bf41d9f32e33352443c299ca7ef6881575dcd4f18ecbe874dde9e796628b21e6a7dc6827587c61fad8a8fc63b886c6f383243a20dcd95fea8e323d0e9811bccc2fd97cb0a347097ef1b5296ea8da5361c3df81672bb179e51f41082ccbc4c4f0c2e2eed5f8f131a2d58aa68caf0aa1a6d9c8aac9f424f7cdd2acd2875d4e0238f35c70ce48c966e114344ba6c5403545a4e8a467bf9cf7ebba117701a5e69a2e71a546d3b674468d4a31bedfc6e70fc0c4c8c3efff332b4b8e1dc604541091dd34a584d333d7291304c08286542b0075f371429605798bbd71ed7ca52ba6b812c7ca91c8c35c2a4f853eb7509c12049150eb7abca4498f5ef4d8dafef8998afb4527b65cd3e6ef1399041887f204cbc81fc030e6242c4395e7752a6545da4996b69740922c07881c1d5bbdc79beab8b17b5b0980d8fad7eeeb5785fbab08a7963bff7e95aa7b526dbe201b968a40f8db9399e7ff8aa18e6f095b9aa4cf4c41e57a78f10f6fc580a955e84f48a8c2b16d13b8b8efa525f1d51426a13325ea3384a5638577f32267f00e2e262f08d46bdeea4891ac5acaa3e3a31fd503dc76a3c92ded39edaa65043b60d52ffb6ea27cbf810899552d4dd5a55e95e172e267be645a3f2c6468b5b1ce76a0b951b85f98efb93aca8b3948c43cbefe76504f90128788e7e08f7f6685ee03b70ac35314d3a64a57a4a8cb7512a9254f3a9aa7e9c1990606ce8ca25e6b9c816b56903e10d7ca1db41a7f991f292acb51337230d0a0ac5604259d7daf5b684493ce3344a8892152fb6baca94f5b02237bfdeef0f9dc6fd372b078a05489f81ee232e63a27726746d52c3d9531bdec03f2d4d56b604231b233592babfe12c64b915200f1e16672b0798982293d768278909bb1352dd42381d7e87c15ba92aae469fae5ed023c643b45c08a5d15b29f34714016ce5c52ac648d4a32a4bb02c701f3a68fb873581ac392ea34277ff3262fba6ecbe274c840751ff28235fb3168cf30bee0fab5cb92c89c8ae3ffd8b03c4253078c31ce19864c8b6f128f6e3e80efda9141bedef5b60adc0d6f8357fe6cb6828b3605e02275deabb5326eff3d52861f072523c5695333b4d51c58c08a44be8e90ff8244da37295e1a1550ce715d08fe600349a9f9870ac83fbaada48cc392b75ab1ab456429e5b236f6b3b1751063b274bf6a75dc2283ca0ae8db757fb856e8c7442e4a3cf6f26e608bca09235f05dc6a2a53862cbae5a5bdcf1bff925ff3c25e38d5ee04591b8c228b215e5f82c21f39462aaa6c548c8d581b4df4386b97fd832a46e2212a3bc5ef4716a10e75cd5e46797dc12241bdec3074d19f971caea7a8f24bc522faf8322301e3e4d2188136ddccc53c6488d5d9df6298befecaf637a2693e8d3db2ed2f8e120e6f1ef5a52471e905bc7f62a3b93b534c9e234d72a75f38e443a05ff62ca45cd25293c23e4ae71784fd1649c61b9469eb152642d8fa2db77b85c26340f4b21b1e8ec7ab58b66fea1397e69665dd9116ce6ecb7d642ec9c2114a4c893b795c1be06893697924c42ed8bc97e0c930898d80e71536dedd3ddcd9b4b35ef5eb462ab984b28925aef1cb524439e36273f7056b17036a1f3ab44eed99199dd6d53b564d2f210a7d52ca896ef0af8de172415b518e92c578d256729744bf79ef3ab444960189cc0cddb9c961bc0a7f0bc51be6ffdf2e057331dd7d05eacd8e6e81e08f90b96539b9d323455428e9abcea706fa357949f2d1067b600af355d435bc71094ed8e29d699504d24427639b4d612d3d2c7e50129145a161cbed02955a0f32615b30cc968c41f2d062c32f796da497b379f5955a0ed5a653ee51f52e6a702b478a9a7af4d48fa25353a258e575c2e0c475b169df4471c22e2ccb1ed607bf831eb28e4487ab655f07520391309d3590ad63436ba31d1c37ecbf586dcaefb56d6110386d6a6a5d785b365701ae291b0a3d13b3dec21729e42591de8ef9f7a7216d9dc23489a3fe8d874a76f146aa26536c1dab083681cc00e9dc9e6603d53d74a1c79558c6fc7bf32d98a485dd562f261e7d2751fefc320c5a2c9a536c84ba467d7a82df93b5803cf60a2726ed8fe7287863fa2a674d01c77b053bcf88a9a502b0fb786f47e50401aa643394624968fb5d5dca34b009a3a32bdce673fd2d0c8e05238b82ee1479cb9b8b7007ca03974e1c56e9bf903c2d0c274cae9f588fcc6b47e02754dc0e7de3cb5a80ace5f98ae68244082144ecbac94d53abb9c89e7d102063107c0ddbb6633d0f987b14217a9d9378007cebdb260a9a89596b11422ec3f1136d469e3c188dfc94ebb1cf8c7f7decfef77995e8334d4321525ad76f32a2efd4c953a319e18c4da8981ee89415f7e2f07914d4fe63d6246504b90fbf03b54bd905661705fb65d00d28c530b7b3c690fb5f88aa1edc6f6dc861d79a1e8c4a6dc1df27b7c2f0b897f1231f176adafae599f4aa29c6a5070103a24468677320b9462cb9a2d40696a5966ca205af33e350742e7e50b27252d2ecf50420cd4fbff8e4570e04b2137722814c64ce0b81d13c14af64eaf36207ae8f9224a47b3c3c0c0996db171544bbe11f2407203eddde94614c9d41945645dcdcabff12cf2fcd01cf062b942bede9184d830fea37df7576b10bbfabdb4a4626979576f403f33060ddfc6f53df73ca618654768001f1e08bbd66de39e8eac625d4f1deb25681c2dc67c6764d555338b4293102191a96cffd8859eb08ecda0489af07c301c12913762fa3f9d192f74c762f50556726c3bacfccc66a038536e913d95186d8aecf381312733beb68b6cedad321fa4e3fdcdcfc5553548a30e1ecf0041f823ec863086c34b3b6e6a7af8a2214122332a4d27392e64cfabb1a9c66c498efb6515f32f01f23073693a37a72240df9709d577b3e184cccc8b9cbf34669b0653e16848ad0a9dbc9d7b0ce3ab88e98616492c83d8b88673aa6a1b93d2f7866caf1984da384145361fcad93640c7481a085b0be84ffb4870705371cabe56f82a233b3d5aab737a2f2b9877fe2885d48163e6c55a53627e6db0a9c7103c867bf829633af2e1379a537267a15765c5ffbf7457eb853d0049f497a7823c0489dd0a1490667b600ccc80f9ebf9afbc007280e4a93b4c20dbb07c10ec4646ce9cd1b3dddacf5ec7bb07d588501daa9ee422da47b4f69f6cb49b3201e1b461b5d4d60d4230995acc88dcc8c928251ebc8d37f3e0dcf8218bbac5e47653e510b270586859238c526c46b7db46e817e467c7fe3f41066e234f4756ac833c9d010fe800e51106deae8eae63d2d9d02c2eda4ab19d63600a5261e69075cc0e28220a3ca4cbfd53f14f654c09a62f6c70fa75368678a7e3936aaae6a3c94d800f95888777bfd394907860ff4446b285345768556f34b1c62cacf50b4ab820d02a18cacfa3a42f086906213e170f26a21a0c7f478d7dff393d68989622e4f89a46845984d1d28ef6584f13f135d6a18fa438e635f7670e3b9e0236d7dc9f99328a807e4468fd7438c56449556c1c13e478072602172f923d0cdff16786fec072f0629a0423025594808ca65d0ee3144947a44519e04b6abd779dc2d119ee4473103e1d608c0e254e0b7698bc876f2d810e4b41f37c9884648d0536069a80f9891d0e2ec4394446b70bb0ffb8032959bb04b82e75f577b8c136b6c87d1f98a962955af7286e4f1a098adb1bef56655757dc5e24cfea40eeb8f37b57edc8b85685c7f1681108f793b7c12df1a203596b57c92f9fa62bc9a1db3e7ed9c802500c7e305606fb82ac11df65c7e40c1fb09084fdd390f55a94873c7a32c0c9d389206d7695220951ff3fcc62cdb39a015649bb65040a06e54111127fd947f344d782f99b59392660917838f2dde4b04038b0baac6966593a8ea2eefa1423c4e9537eb804cb7d58fcbb1eef505ba06b1682cfffc4eab227161bbb9c3aabaec99f2e08fa650ce99e9c02745927ebaaef4f2c70713c97b34b734016a65a0e69db084101289443770fce47722a4c1af6ce554d09aeb9b3e2f076fada5f5fd9c772ee2cb65fff9da7b33e1b2f6a08f1536a403188c771fff5a84c8bc1509ef2dacd23cc699a242f5492bbdb82f13f4b9766cb1465d3d79e5ff9499fd812d346b8ac6e7c8cb83a603250a52daa0a55e04521f22a4246c5c149bb3426639d84dc651f7246d11ff49a2597b9a77104bc2cb1880f0347f2110b2cf33866aaa6bcce8e058e03aee01191adfee651694b506d952210398513a9313836e1457e5e8de9bdf26ed7301c3b6578a291d73cdf2602f6493e7685dff5e7b4db4c0fc151e253009234b251ecebeb10c2facce66e125b8fc8c6a78926dff9dd250037a12aa32c086c155f980601ab25de4bac8ce364c7fa8fdd965ddd03dedc8de498dfd3cfdc86b0b56398b10245dce984f2c5087610efd29aadec6eb78c18956d6912203f7016f3f47452578d1b718b6d221b38782bab9e29b344dee9deb594d8798a6a01296f5da1f143743c61c402700fd33904b43d8d6a44dc6fc04fcb9841544dd9116a5b908f06dd39be385750a4371f7dbce8b9b75aa01fcb4d2a1a94f22b7bf876153543f410e7f8c1504aced875a2e054dd5a2138eec9607d5d5ae7bae91da662c415ac6f0a9bb981393f660695e4b65b16dbaf35ec0d40c68ff4fd991e8152e03152c332e92a62c2bea76c0a239387148409b6a7c2c98c24b506b059869cb911a30cf15c22e0ea0f86db884040f7cc8f58b1d3fcdc251d223a285f191ee4bb2de83365ef74726c7abfaa9146c308530edde09be20e9d6eaeef850d00b165e768463b8793a914c421bb81e8905938540c64b77e82ee6a4a6a15f5cfb1df20a41305ad3dffafc7e8d882a3c9e3635d115c9314d8f3602ba752734e34e188c3cf46b3dd5cd83bb46b12e1ec2a8b9d7dd5b61c5a9f4f0704504e2882068034db62e8a9abf3c7c5b9a8bfde509d36899fc5b4e5bef940fd447b9275024febdc9a91d6d56012f1c6a44f94b96397ff2c78fd617870bf089067c6343ae4270f6e6dc495a260bc1ccd0a1c0771821895d26dd66a203825d19e621b86b57f9a51bceae9bb14d1f9961c5a904a64a1dad73c89129ac4920cc4e86e3696959be3305f6d5e33baee00c7f978bf7a1a7864ed89132ff350b45226e6e4db39122bd344c315208edafdfe6b567677f869b64532bed2f7f9087e3c6c1137004f205ce1485f1b9c3ec798b0509c00f6a2b6663048492caa3889328ea6216e34b959fd244249048cec8c0f7de2ff97105ad030a536ec6c4103b33c26acf4539a1b74a0792b9b6c80f95ee4326b09934e068429242495e51a49a712f8513ce91da60573e83443a0e12ac2a174b82d090813b930e10ed7cd44ed72d20b061e9eb253d715408d79d8a77d67919bb196dadcfb84bdc4eb647a4ae09c436d220e0ce914188c49fe9ffaa2fb87f08809d5021cb632a6642bdc1e3664e84dc0afca031f0150c4190893da6462dd917655930a6d1deebdf4a0b1e461126fb2d54d374e4d5a455a6207291d03d2d138e34260ca0ba2286044afc4d95822bead1eefdf0509cb4a0c09c3425c8b0e9236703cbdf4ba833ebea4942d4e0ea84df284c438ffae28b3ec7ded12dda8bbbeabdd07bd1925912aeb74bfda42a62f8a5e716949f4a195f38c9f7a041776c69a7a1599d6880299f50c3b75e6a9b5e0314731611154d1f755a1381fd7575a6b34019d37c40aabb4bcd6965411f48f3b893e5627748deed82de02e9d47af8d3a087f661dc5f2c65ea16fdb6455a6211c77fd41532017ac4aa17bdc43e33aa4bf6ebdd453fb90b863aefe4281691a736594d714bdc26520fb954fa4a3c8d8f5620316e7b8a3b736b28859514bb2ac434001a129975e0f53f473c41ad752670598a2b356feacdb9e4a609a44e83167539d4e3223143d19f79738b96a27171009f17fca174a8821c3f0bd7dd15b2e98eb3fe1437dbdbe881f9c86c0844db5ee82b627c519fae5ea7b5dabc382c9938529dc031f8cdf0ab320f479d8793081f1ecf45a2af3d339db470bea05607148a060348cfb344edcd773efff7645f021d67db2dc0abbe9a8fc343016e9e57933f642f487d649e3a01ad4f815fe3701750d67b1db3c74c6b30f7923d08a807e78e58aeec28691475bbe4260db35b8f850330fbf68f73f944b745208748261f32a9ee5929cf924193fbca8f7d15d0118e3ef205f6a639e4a25bb23c28f036764ba7dfb4f8203eb0b69e757fe5a40b560cae416eda6195f15330aa7f4ea8cd113c30583675a94c486da43a0f26dc5d922aeaa8b084124f5c5dbd0ef31e4ed52de942b1f8ec6b494fa9e730e8f0cac9ea3153610e13ab589d8840e5ecef5570b619574477e457c529d431a48fd3679f0a831832b9a1ad4cb6c99c25e0c1bcd2cc73ed79b2a589501e2abab2d2a64c9fbc4cd8bf14800f8a67d46ef10a68db32411d63fc36e8125bd0e79b27d861324afa6929be5cee98c245f0af5755595f60d29d485222c4a43e2614d315723c5eecbc836242a028053ff8a4c83324edbd6899887c3ab3394d5725effbb55ff056c35fdde91c28a34362aa8ab06f0f1da408e7be1863ef007b57ee062c5e660e2bd221a306774e7b7ed5fe5d04e3a2fa49a61a9d15e4aea12bfe588f7f7fe357581772356998126b1deb48988b56506eb805be01c07f3706100658b5be1e96b1531f8838d78cbb849a4e51c1a80d3776987407c0a1610d43178962c5a34cac6a62e8aaa963b8833549f8ef954e155f962b6d6ea4ceaa9f711959fdab71a74e8ef57ab16b477bbe47b78718f8aeb29239958220b079e13dab8f77ec24be4c3df3db9d9e306c9da8bcff284c27becdeba20ccbdf94f7853069c936ebb209f2dcef4d5b0c73a68c5bfa67a2366f68ea00603ce2b1fbcb897e80b1f7013d50355df6e989c660aabfecf886ccd69d86352c81350520bced1a2beaa0dffb1362c8b3857f1f1c17393fbf45ef639b1f6be41ace5f1e132e257a96af92727bfdba6b1cc09864c5b085d13be7986a4e720a49065f1c70e140f69cc462ab7bec075108d1384f6935781bec4dce9efad2c8e238e7f41b8e430ba231e9e23c6af52bb0dea07e6a0ffb0a3549db69ff05b1c7d57b1fb5f98b75122b0d53d038a37f3c499d9c891fe571015bf6fae1f27cd1c4790f633cc88b9f018bcc79e1857328fdb72eb7e0fc50558e2ab338fb902be7535c12c0235b21ccc3102454e75b20d5652231393ee2f14b5c0bf2ec8a485c02fdead3fb371b41f43d69a518444a92a6967ef3846db7661d973206eab07fd08f69b5a3a36cfe749acf67c2db8df7994821df76a74d8a36521cc6f4de3e1035e18e9640417363427082daf240e71f60df231fc22b8175620c74e2899eccc35387901cf57f8ea34d3f2a4165a4b7f9c41082ce46980480608c539d7f248a41c1ac1a7d5d28884b7ef5d184938d94dd473fa28ba674ce934807f56276fa821da3dfe5f932bef6565aed54f5c3517ace0c9221214417b2d523ddb65eb4bf68c547b4c40ec52ce09c51e1fa64422b21b412a8cb416db685469ed047e2ae26ca06de8e10abb64bec6ca07884927b51968daa05573e35fed3d2ae343126287069190029b9a7a724c177057dba050c3b18c0222de84a50e2413eea9a12f50d94ceefe48995ddf907de29a46ce561cd8242946eaed26474e50984ac005be37fb745254f3df97f880cd24732a46626bf4975bc6c749ac1c75833ed99b4dbab1d71267b82758229bdcb11cd234b8c990478de16160cf4989df335f646f6286d6f62f350811942df2f645afb14768f50ddf221d8e029674d40994c2ec2c4eb12f9ea6aa14d81a0bd8c3b62aea41877104ba9f50ed75c53b5f0cf4d913b7878b38dac9dd45abc35feacc53dd9cbb3029689cef401df37529318390341babe225094f268a886ce3bd6c6e5bee7849ab4f37c11505c9fb71ea7ca9db1c882dff90d91f1c046bc0b2306f341126b6becc475c6dee4d5aa9bd77852316b72a9189a6c309002f9be5296a0307895a6f729d7e3386cc9b18aed6b2168847a160c11db23400a80d3121febde4e480f2c7399dc71594ddfafcf868e60cc97ce8dd6861efefd9f92e61987ea7aa5baec0117866c387e07a798a1efce156b5ec8ddb3794b3035e34544e9d9a447c9a57aaaa63766fad9be9bf6ea08aff67c90792613b5b54b483f2965cde93f4b9bafc90e3510bbe1d3bc13ef88b08fdabce53bfec8b26eba2f09f5701915cf72c095388b635c8a6aa14d9c1d836367860450591c35230ed1759928b80575ac152b97ece0e025a283f62ef90ecfa1f3a3eed39068ca91d6b0f35f22edbd54637e29382244c8dc62e4714d6c729a1825dbc13e4e245ea5ce221e98a8d25aff7f65336f634f944c5e33fd99cc20202fce700fe053207ec9a73237da10ab2da53ff5f0ac0adcbcdfd31a642dd69541b7661469a97e87fdb91f1c9a533e0cabfd12e0a015e96fb3f5154d6cdf4e2a593780bcc79f918bd1844ffa62a0637c7957866e779e491d864b409627129fd5442cceab809755ba78aa08885e7daca24366554dc75839e75a66c30c5937987f197c9bdf377b3eddc8f24447e96f17bf8633645ac81ca2baf52f4738a52afbe0b12068ff44d5bc35a3f83986825aefaba9fc29ae57f74dba2d3f24d3692bfa33beb46b75449dfdb162b0ca5afe93d3f54d897c8aa7e3f7fc9f632cd348a47e1837e3aec9da2fb675b169af643854a2714daeb2f060480d18f0fc84eb1becde4368c2886867a9b621ac3966222ea1a5c1b2e2aad5a6d24ed21533c91f9a8b019195529a6e08eccf10f40563c65ca50bfa78d83ae54ca01cc21925375ac8d10de1adbe763ca9d885e5b28565332d184878947f6b89a51db652ecd0155625e4cd472e5f366dcf79b36e79465ca7a3c236f3ef8c4acbd83ccceb8b19b91855dee1122f15627c57eebc26967f4263434b321bd4cec915975821e08f9095ce6d7705493d850c0da356fb8cfe51395d1d7ba7efa5d4f1cda7b735f13d0183f8f1a282f28a24ca0f0e719b5e567186ee1255d241e66790bcab2e55846085d1f025e38a2d36ee014b40cc2c5afe253b858774e34c026bd8dd65264e08df28f22498f88e64aa4d42eed7f98d9b81b593b9adbbe99cccf617f5bc2809198bdfb460e8335eb8d6d94e278a50f902950103b902903941e6e79ed44f046543182b5bc91c08ba91a53a50351470a6a64215b1b87c4487df0d23a191f8eb1429db96776bcf42b0ee0556ad1fbe54589ed283901d3269a783e1ffad95d3b98c52b6d6de730edd4c93a652f53d76f8f3d343f04953d81c43c9e96934df194297fbfda8098baf1a277fa49615b9e429562f2b5cc029a76da5915d35c96922639f5d2f3157f5edb63918b663d299a2ebba2727117c328d73f83959a82cfb392161c98ceb2b1d6b8f0b78ded12dcad63da02414be8c853c5a7186f13d6c8d9f7f738356fdfbda49449bd2873e7fc5e3d7135d59cad6abd758dd954c72b9ac2a52a9f4d40e675f17807f69af4c7119f4dbd26492d194d64a18334c5afdb8d4ed18eef34578d9a4f9bca31ab5c6c6219a3a2fa5b9d29feaca1b37c24115d4fbb2f8a8282df604b24a18cc56215c791042a7f28eb859d2e57d43ce6cc50edc48688a0e449ad4aa6f5c00c72dcf0322d2a022b7fe495028bbc89ab53982595755f384b4bd723a7f49d77a7288b2b5b51ab4871624132bacc0fc1315250635bfb8bab3efa73b75b890b8701a48eb67ba421c64e50d2d6c823b7ba0e8a6bf7b371f65e08da37ab9424b876910fcae73aec09b44210aa4a4b8e401d055a9dcd5bf5e4869c72b0eb51a9d0a1e3405cf91564554a549b16e1a6b9fd90f435e2d652b45be313ac6b7bdeacd499bbbc61a00f4efa6932b3f01c0c24f7eac31955296677a50fee299536aa9df12168f3e91edcd2b634eb8fd6570f99a24abddf4d94cd77f2f087dc905dfd0eaa228c436935cd1a74f6f9d72f0ca11283e15632403d786258cab7d224e99e7fa7b59db465f26965532450cc5260e3951a32102795e2d0d5cd968fb356e142103f5204762e194d130789caa35995091faaf9167d3e3d144159b659a0f673dfdf2c6a0"
|
|
+ },
|
|
+ {
|
|
+ "id": "vs-sealstore-1-peste-forma-noua",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "hash": "0x3333333333333333333333333333333333333333333333333333333333333333",
|
|
+ "commitRoundBlock": 1000,
|
|
+ "bytes": "0xf902d593414552452d50512d5345414c53544f52452d31826d618203e8a03333333333333333333333333333333333333333333333333333333333333333f90297f9029480b9029039bd3aadc5f485f3f17ab3ef996de30f40a4dbb98f4c70db2fbf505d86835dcfd8e1b067a325d98da059a8597b2e5ee62751d4fd8efc9985223f68c9b2725df62d7af9b091a129944bb0d86464ae20b5bd1c5cf3b29bec1fce23c562d6d8d3ea81215b2a061f05e1ea271c4f5da79f528ae113bb9ba6afdaa1eebb715d3171344fd4bce746d22de14f5a0454a7e371086667b9d586907f6b6969a528ba9ce5ceb7c8cbe30c939b4d76d3eaee2882cc898f374b94355329fae7e6d591e9166d7f71d9c58defb0bcade36ce313d62519c41a7973b149b4f2f8e51d6afd5154eb794343a3acdcc7436e4ff22dda41b236295314daef2a4b98c5343684e20ee7f1f6d27e4a66eaa79ce6a32b2fecf43c43237a40f3545f4af5f6d93109d8e15da5f28db19eac72f8641d14a079198fdf9f8ee292b2d0fc7d3fccd68525dbcfafff2a9d29a3cc361e4674d29e5af5ee408adc0d9725f7939065d0ceef4a4b64c0972943a69739b0aaf57562533888315d7a5d24fa759ed5661454ee58ce491e5f2fcf0d07608f524c50f36cab968c1d8cbee3313a7854744d1cd7e5ac70e20092bab2e5c59736351d014d71af7c19926b232bf1bc36676f81a1a6f7166e97d8e066f6a78d98f13974beed35449f3d9506fab1c0ab356b092273b42d4aedb6cdbedb736e6928fd2d4926b94106fbbf0923e3b759e1fb89ecaf24bea45bd406d509d611550061897b71c39ea3fa6a8f47a50a31849546df90137114491b55ce36fe1d6f64851c8647eb5906d13369b97ab5721a44db1f9d7712aa45c87f5f8b8bef5c92a9f715c432ef6262c8d22af0eb2943e40cda27921cb865b7d79a4b70ec14f7deb96916cc13eeb764a5f3f35189a9bace816de3f88b57aecea4ad102412e121f84ab7474a04d0c0d92526178821f0dce4",
|
|
+ "expected": "ignored"
|
|
+ }
|
|
+ ],
|
|
+ "VJ": [
|
|
+ {
|
|
+ "id": "vj-28001-1000-r2",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": 2,
|
|
+ "hash": "0x3333333333333333333333333333333333333333333333333333333333333333",
|
|
+ "seals": [
|
|
+ {
|
|
+ "index": 1,
|
|
+ "signature": "0x392d747efa5df9ec7976b575ebbbbc4e50e48f494255067d00c8fb6ab805f5dde05d0240f101c33dd0aadb317a173e25a7dec0ceb77ce150099f5ca19dc2df6e44a5b5fc87cab441dc4e6ee717e77d3ffc2bc57ea828567dcbcdb8831dbbb613c0f747fc497e218f903efb5f5c5a2c4e61879bfb069a67eec30acb8af36d1f4a245b9f120c6bea336d8ba3eba72be78a3ded415117b3ed0babab6ce775e1c1ebee9d08f4a0923ef969747533a3a9fc13d19b4c5b1eabe6ade431ad5731c5ccfe98681c31ade95e7d5bf469024456082d06df3fd4e6970fc2533bb9cf6688bb595edacd95f68d1b31a396d8af954e37fd43d6a366757853a1185d62e18587e2cdb51f0a7023f2b3cb9646ffda39e46e98c47f68bb3954a140f5bce405977eb8974c229305c2ca3c7017891f208a041a89d48d3344695cd9106bff8b80a0a48dde46ba4ecb942344cd1887e2f889a5b97e96651dfe7d3116a2b17a86bf11be8ab8bb69f214b7a0dce316367e827192ec0e9a0ac2199b1c4f1042655ca7cf3d1f8da99341afe8f0b1f21338492ecff73f65239f4ea6a5dfcbd08ca9bcadd559dff34a6a8cd9a28a579fd54384f35ceaabab930b87b14779fdc822a587d04910b4d693f288b26d56688e5ffb2d65d9374a32c27dab9778f618df54c15f555f54828113a595fc1ce107ad2ae7592b41e944b0cfe48cd21d36d4fb35dad4de5ffe9531f9e927a25942461a4c9726a292d2ef9dbc0b1d0456b703037b4df9d0c446d707285b9489e8845211cf0e8a3f0a32a5cfc713902df29af2813293a48c2f02b8dc336befa797d3d3f67d90cd4fa25466bbe70d394713fa06b606de967d5a5aa9f8d0310363f7be1a75708d4c72511f67eb2b0495c43e75ca6e085d35c53cdac3cc09142647e68fcbbe921ad25080"
|
|
+ },
|
|
+ {
|
|
+ "index": 3,
|
|
+ "signature": "0x3941e6e79ed44f046543182b5bc91c08ba91a53a50351470a6a64215b1b87c4487df0d23a191f8eb1429db96776bcf42b0ee0556ad1fbe54589ed283901d3269a783e1ffad95d3b98c52b6d6de730edd4c93a652f53d76f8f3d343f04953d81c43c9e96934df194297fbfda8098baf1a277fa49615b9e429562f2b5cc029a76da5915d35c96922639f5d2f3157f5edb63918b663d299a2ebba2727117c328d73f83959a82cfb392161c98ceb2b1d6b8f0b78ded12dcad63da02414be8c853c5a7186f13d6c8d9f7f738356fdfbda49449bd2873e7fc5e3d7135d59cad6abd758dd954c72b9ac2a52a9f4d40e675f17807f69af4c7119f4dbd26492d194d64a18334c5afdb8d4ed18eef34578d9a4f9bca31ab5c6c6219a3a2fa5b9d29feaca1b37c24115d4fbb2f8a8282df604b24a18cc56215c791042a7f28eb859d2e57d43ce6cc50edc48688a0e449ad4aa6f5c00c72dcf0322d2a022b7fe495028bbc89ab53982595755f384b4bd723a7f49d77a7288b2b5b51ab4871624132bacc0fc1315250635bfb8bab3efa73b75b890b8701a48eb67ba421c64e50d2d6c823b7ba0e8a6bf7b371f65e08da37ab9424b876910fcae73aec09b44210aa4a4b8e401d055a9dcd5bf5e4869c72b0eb51a9d0a1e3405cf91564554a549b16e1a6b9fd90f435e2d652b45be313ac6b7bdeacd499bbbc61a00f4efa6932b3f01c0c24f7eac31955296677a50fee299536aa9df12168f3e91edcd2b634eb8fd6570f99a24abddf4d94cd77f2f087dc905dfd0eaa228c436935cd1a74f6f9d72f0ca11283e15632403d786258cab7d224e99e7fa7b59db465f26965532450cc5260e3951a32102795e2d0d5cd968fb356e142103f5204762e194d130789caa35995091faaf9167d3e3d144159b659a0f673dfdf2c6a0"
|
|
+ }
|
|
+ ],
|
|
+ "message": "0x9b03be36eb916bd6ff4868240bfc66a2631dc806818ae44db48178aefb6a997b",
|
|
+ "bytes": "0xf9056b94414552452d50512d5345414c57494e444f572d32826d618203e802a03333333333333333333333333333333333333333333333333333333333333333f9052bf9029101b9028d392d747efa5df9ec7976b575ebbbbc4e50e48f494255067d00c8fb6ab805f5dde05d0240f101c33dd0aadb317a173e25a7dec0ceb77ce150099f5ca19dc2df6e44a5b5fc87cab441dc4e6ee717e77d3ffc2bc57ea828567dcbcdb8831dbbb613c0f747fc497e218f903efb5f5c5a2c4e61879bfb069a67eec30acb8af36d1f4a245b9f120c6bea336d8ba3eba72be78a3ded415117b3ed0babab6ce775e1c1ebee9d08f4a0923ef969747533a3a9fc13d19b4c5b1eabe6ade431ad5731c5ccfe98681c31ade95e7d5bf469024456082d06df3fd4e6970fc2533bb9cf6688bb595edacd95f68d1b31a396d8af954e37fd43d6a366757853a1185d62e18587e2cdb51f0a7023f2b3cb9646ffda39e46e98c47f68bb3954a140f5bce405977eb8974c229305c2ca3c7017891f208a041a89d48d3344695cd9106bff8b80a0a48dde46ba4ecb942344cd1887e2f889a5b97e96651dfe7d3116a2b17a86bf11be8ab8bb69f214b7a0dce316367e827192ec0e9a0ac2199b1c4f1042655ca7cf3d1f8da99341afe8f0b1f21338492ecff73f65239f4ea6a5dfcbd08ca9bcadd559dff34a6a8cd9a28a579fd54384f35ceaabab930b87b14779fdc822a587d04910b4d693f288b26d56688e5ffb2d65d9374a32c27dab9778f618df54c15f555f54828113a595fc1ce107ad2ae7592b41e944b0cfe48cd21d36d4fb35dad4de5ffe9531f9e927a25942461a4c9726a292d2ef9dbc0b1d0456b703037b4df9d0c446d707285b9489e8845211cf0e8a3f0a32a5cfc713902df29af2813293a48c2f02b8dc336befa797d3d3f67d90cd4fa25466bbe70d394713fa06b606de967d5a5aa9f8d0310363f7be1a75708d4c72511f67eb2b0495c43e75ca6e085d35c53cdac3cc09142647e68fcbbe921ad25080f9029403b902903941e6e79ed44f046543182b5bc91c08ba91a53a50351470a6a64215b1b87c4487df0d23a191f8eb1429db96776bcf42b0ee0556ad1fbe54589ed283901d3269a783e1ffad95d3b98c52b6d6de730edd4c93a652f53d76f8f3d343f04953d81c43c9e96934df194297fbfda8098baf1a277fa49615b9e429562f2b5cc029a76da5915d35c96922639f5d2f3157f5edb63918b663d299a2ebba2727117c328d73f83959a82cfb392161c98ceb2b1d6b8f0b78ded12dcad63da02414be8c853c5a7186f13d6c8d9f7f738356fdfbda49449bd2873e7fc5e3d7135d59cad6abd758dd954c72b9ac2a52a9f4d40e675f17807f69af4c7119f4dbd26492d194d64a18334c5afdb8d4ed18eef34578d9a4f9bca31ab5c6c6219a3a2fa5b9d29feaca1b37c24115d4fbb2f8a8282df604b24a18cc56215c791042a7f28eb859d2e57d43ce6cc50edc48688a0e449ad4aa6f5c00c72dcf0322d2a022b7fe495028bbc89ab53982595755f384b4bd723a7f49d77a7288b2b5b51ab4871624132bacc0fc1315250635bfb8bab3efa73b75b890b8701a48eb67ba421c64e50d2d6c823b7ba0e8a6bf7b371f65e08da37ab9424b876910fcae73aec09b44210aa4a4b8e401d055a9dcd5bf5e4869c72b0eb51a9d0a1e3405cf91564554a549b16e1a6b9fd90f435e2d652b45be313ac6b7bdeacd499bbbc61a00f4efa6932b3f01c0c24f7eac31955296677a50fee299536aa9df12168f3e91edcd2b634eb8fd6570f99a24abddf4d94cd77f2f087dc905dfd0eaa228c436935cd1a74f6f9d72f0ca11283e15632403d786258cab7d224e99e7fa7b59db465f26965532450cc5260e3951a32102795e2d0d5cd968fb356e142103f5204762e194d130789caa35995091faaf9167d3e3d144159b659a0f673dfdf2c6a0"
|
|
+ },
|
|
+ {
|
|
+ "id": "vj-28001-1000-r0",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": 0,
|
|
+ "hash": "0x3333333333333333333333333333333333333333333333333333333333333333",
|
|
+ "seals": [
|
|
+ {
|
|
+ "index": 0,
|
|
+ "signature": "0x39bd3aadc5f485f3f17ab3ef996de30f40a4dbb98f4c70db2fbf505d86835dcfd8e1b067a325d98da059a8597b2e5ee62751d4fd8efc9985223f68c9b2725df62d7af9b091a129944bb0d86464ae20b5bd1c5cf3b29bec1fce23c562d6d8d3ea81215b2a061f05e1ea271c4f5da79f528ae113bb9ba6afdaa1eebb715d3171344fd4bce746d22de14f5a0454a7e371086667b9d586907f6b6969a528ba9ce5ceb7c8cbe30c939b4d76d3eaee2882cc898f374b94355329fae7e6d591e9166d7f71d9c58defb0bcade36ce313d62519c41a7973b149b4f2f8e51d6afd5154eb794343a3acdcc7436e4ff22dda41b236295314daef2a4b98c5343684e20ee7f1f6d27e4a66eaa79ce6a32b2fecf43c43237a40f3545f4af5f6d93109d8e15da5f28db19eac72f8641d14a079198fdf9f8ee292b2d0fc7d3fccd68525dbcfafff2a9d29a3cc361e4674d29e5af5ee408adc0d9725f7939065d0ceef4a4b64c0972943a69739b0aaf57562533888315d7a5d24fa759ed5661454ee58ce491e5f2fcf0d07608f524c50f36cab968c1d8cbee3313a7854744d1cd7e5ac70e20092bab2e5c59736351d014d71af7c19926b232bf1bc36676f81a1a6f7166e97d8e066f6a78d98f13974beed35449f3d9506fab1c0ab356b092273b42d4aedb6cdbedb736e6928fd2d4926b94106fbbf0923e3b759e1fb89ecaf24bea45bd406d509d611550061897b71c39ea3fa6a8f47a50a31849546df90137114491b55ce36fe1d6f64851c8647eb5906d13369b97ab5721a44db1f9d7712aa45c87f5f8b8bef5c92a9f715c432ef6262c8d22af0eb2943e40cda27921cb865b7d79a4b70ec14f7deb96916cc13eeb764a5f3f35189a9bace816de3f88b57aecea4ad102412e121f84ab7474a04d0c0d92526178821f0dce4"
|
|
+ }
|
|
+ ],
|
|
+ "message": "0xcce50ac23422233040f0fda9105a626e3160b12064ec678b34819b029fc204a1",
|
|
+ "bytes": "0xf902d794414552452d50512d5345414c57494e444f572d32826d618203e880a03333333333333333333333333333333333333333333333333333333333333333f90297f9029480b9029039bd3aadc5f485f3f17ab3ef996de30f40a4dbb98f4c70db2fbf505d86835dcfd8e1b067a325d98da059a8597b2e5ee62751d4fd8efc9985223f68c9b2725df62d7af9b091a129944bb0d86464ae20b5bd1c5cf3b29bec1fce23c562d6d8d3ea81215b2a061f05e1ea271c4f5da79f528ae113bb9ba6afdaa1eebb715d3171344fd4bce746d22de14f5a0454a7e371086667b9d586907f6b6969a528ba9ce5ceb7c8cbe30c939b4d76d3eaee2882cc898f374b94355329fae7e6d591e9166d7f71d9c58defb0bcade36ce313d62519c41a7973b149b4f2f8e51d6afd5154eb794343a3acdcc7436e4ff22dda41b236295314daef2a4b98c5343684e20ee7f1f6d27e4a66eaa79ce6a32b2fecf43c43237a40f3545f4af5f6d93109d8e15da5f28db19eac72f8641d14a079198fdf9f8ee292b2d0fc7d3fccd68525dbcfafff2a9d29a3cc361e4674d29e5af5ee408adc0d9725f7939065d0ceef4a4b64c0972943a69739b0aaf57562533888315d7a5d24fa759ed5661454ee58ce491e5f2fcf0d07608f524c50f36cab968c1d8cbee3313a7854744d1cd7e5ac70e20092bab2e5c59736351d014d71af7c19926b232bf1bc36676f81a1a6f7166e97d8e066f6a78d98f13974beed35449f3d9506fab1c0ab356b092273b42d4aedb6cdbedb736e6928fd2d4926b94106fbbf0923e3b759e1fb89ecaf24bea45bd406d509d611550061897b71c39ea3fa6a8f47a50a31849546df90137114491b55ce36fe1d6f64851c8647eb5906d13369b97ab5721a44db1f9d7712aa45c87f5f8b8bef5c92a9f715c432ef6262c8d22af0eb2943e40cda27921cb865b7d79a4b70ec14f7deb96916cc13eeb764a5f3f35189a9bace816de3f88b57aecea4ad102412e121f84ab7474a04d0c0d92526178821f0dce4"
|
|
+ },
|
|
+ {
|
|
+ "id": "vj-cadru-1-sub-hr",
|
|
+ "chainId": 28001,
|
|
+ "n": 900,
|
|
+ "round": null,
|
|
+ "hash": "0x3333333333333333333333333333333333333333333333333333333333333333",
|
|
+ "commitRoundBlock": 1000,
|
|
+ "message": "0x02cddf26d98250e54a2447f107b76a0a9d76c8530ba82a599cbf7e798c4e88c3",
|
|
+ "seals": [
|
|
+ {
|
|
+ "index": 0,
|
|
+ "signature": "0x39a3460081ebf9704527062c06e3b80a50032c21a0fff93a9ecee2ef463fe82837f3271af1898d432914220e9ad9d947e5e828a4b26410d7bbd31bce84921edc5479a84eb7881745c0a14bec262a0e94247e699e3f9475251089ca8a220b242ed7da59191b66e58f139369996de1a981f939aace4799242bc22eff59b68896eb7754804bf8889d2a619dc451f6d408f9b3411b87392f4a76b1dd61a1cfa1b6a7a398b1a0ba7a8c3a56dfbe51eb246f0f906658e8f6ecc63c6b54c724ec42a5ac426903c6f3f1b2f41a7463941709eb48194cd50157ae7b7939fd373533f3e0ba87936523e2c49a3a9105f3799ce7ab947ed2031d5aa17fce47a2835b96422986ae0a89a1a9666f59dc6b3844d4bdaf720a5125c45afaf558ecee8958c0ae48944d4ce224142dbbdfb625f2b61f773c64e99e3d9db14d4274f20dbbd2c549db648275f0ead6ad5d3b2f0fbd07b4f2e834b61a97839a1be8c7195eba384393a08ab551a78b70de6c3c6d7915535574958cfae4b65025a30f1c8172a330fe17b243a3f5aa2b99839fb16f2620a718e312c877627e466db9426792994591195a12d5c10a4ca39c77ac83cef0bdf561f86f9add7b3742d1c634ad0474cec688558f507132ff1b2b30dc103b2a49515eb7a985065f86fefc39bd8c4b2684da96bf666ec52d6f94c1bebcb44be78e3ac861290ed2cb55626dac02dd8033484190a3366a0ed52ab85c704576664e3355b912409c3b32870380a5f6c9e3d787cf77fb50d3e28379553cc2c96b15891f050b6ae71745491f5cfd592c3b83ef88a40ede773f5f61b71a3cc16deb626db00dea08c77fae10799c82329284faf3a8e76687035552b3c45a377ab8765e6d5ed147275554275898ba288ccce862186515bb349f225f9186204b3abae2e3a928592b40"
|
|
+ }
|
|
+ ],
|
|
+ "bytes": "0xf902d494414552452d50512d5345414c57494e444f572d31826d61820384a03333333333333333333333333333333333333333333333333333333333333333f90295f9029280b9028e39a3460081ebf9704527062c06e3b80a50032c21a0fff93a9ecee2ef463fe82837f3271af1898d432914220e9ad9d947e5e828a4b26410d7bbd31bce84921edc5479a84eb7881745c0a14bec262a0e94247e699e3f9475251089ca8a220b242ed7da59191b66e58f139369996de1a981f939aace4799242bc22eff59b68896eb7754804bf8889d2a619dc451f6d408f9b3411b87392f4a76b1dd61a1cfa1b6a7a398b1a0ba7a8c3a56dfbe51eb246f0f906658e8f6ecc63c6b54c724ec42a5ac426903c6f3f1b2f41a7463941709eb48194cd50157ae7b7939fd373533f3e0ba87936523e2c49a3a9105f3799ce7ab947ed2031d5aa17fce47a2835b96422986ae0a89a1a9666f59dc6b3844d4bdaf720a5125c45afaf558ecee8958c0ae48944d4ce224142dbbdfb625f2b61f773c64e99e3d9db14d4274f20dbbd2c549db648275f0ead6ad5d3b2f0fbd07b4f2e834b61a97839a1be8c7195eba384393a08ab551a78b70de6c3c6d7915535574958cfae4b65025a30f1c8172a330fe17b243a3f5aa2b99839fb16f2620a718e312c877627e466db9426792994591195a12d5c10a4ca39c77ac83cef0bdf561f86f9add7b3742d1c634ad0474cec688558f507132ff1b2b30dc103b2a49515eb7a985065f86fefc39bd8c4b2684da96bf666ec52d6f94c1bebcb44be78e3ac861290ed2cb55626dac02dd8033484190a3366a0ed52ab85c704576664e3355b912409c3b32870380a5f6c9e3d787cf77fb50d3e28379553cc2c96b15891f050b6ae71745491f5cfd592c3b83ef88a40ede773f5f61b71a3cc16deb626db00dea08c77fae10799c82329284faf3a8e76687035552b3c45a377ab8765e6d5ed147275554275898ba288ccce862186515bb349f225f9186204b3abae2e3a928592b40",
|
|
+ "expected": "read below H_r"
|
|
+ },
|
|
+ {
|
|
+ "id": "vj-cadru-2-sub-hr",
|
|
+ "chainId": 28001,
|
|
+ "n": 900,
|
|
+ "round": 0,
|
|
+ "hash": "0x3333333333333333333333333333333333333333333333333333333333333333",
|
|
+ "commitRoundBlock": 1000,
|
|
+ "bytes": "0xf902d594414552452d50512d5345414c57494e444f572d32826d6182038480a03333333333333333333333333333333333333333333333333333333333333333f90295f9029280b9028e39a3460081ebf9704527062c06e3b80a50032c21a0fff93a9ecee2ef463fe82837f3271af1898d432914220e9ad9d947e5e828a4b26410d7bbd31bce84921edc5479a84eb7881745c0a14bec262a0e94247e699e3f9475251089ca8a220b242ed7da59191b66e58f139369996de1a981f939aace4799242bc22eff59b68896eb7754804bf8889d2a619dc451f6d408f9b3411b87392f4a76b1dd61a1cfa1b6a7a398b1a0ba7a8c3a56dfbe51eb246f0f906658e8f6ecc63c6b54c724ec42a5ac426903c6f3f1b2f41a7463941709eb48194cd50157ae7b7939fd373533f3e0ba87936523e2c49a3a9105f3799ce7ab947ed2031d5aa17fce47a2835b96422986ae0a89a1a9666f59dc6b3844d4bdaf720a5125c45afaf558ecee8958c0ae48944d4ce224142dbbdfb625f2b61f773c64e99e3d9db14d4274f20dbbd2c549db648275f0ead6ad5d3b2f0fbd07b4f2e834b61a97839a1be8c7195eba384393a08ab551a78b70de6c3c6d7915535574958cfae4b65025a30f1c8172a330fe17b243a3f5aa2b99839fb16f2620a718e312c877627e466db9426792994591195a12d5c10a4ca39c77ac83cef0bdf561f86f9add7b3742d1c634ad0474cec688558f507132ff1b2b30dc103b2a49515eb7a985065f86fefc39bd8c4b2684da96bf666ec52d6f94c1bebcb44be78e3ac861290ed2cb55626dac02dd8033484190a3366a0ed52ab85c704576664e3355b912409c3b32870380a5f6c9e3d787cf77fb50d3e28379553cc2c96b15891f050b6ae71745491f5cfd592c3b83ef88a40ede773f5f61b71a3cc16deb626db00dea08c77fae10799c82329284faf3a8e76687035552b3c45a377ab8765e6d5ed147275554275898ba288ccce862186515bb349f225f9186204b3abae2e3a928592b40",
|
|
+ "expected": "dropped: a frame in the wrong form for its height"
|
|
+ },
|
|
+ {
|
|
+ "id": "vj-cadru-1-peste-hr",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": null,
|
|
+ "hash": "0x3333333333333333333333333333333333333333333333333333333333333333",
|
|
+ "commitRoundBlock": 1000,
|
|
+ "bytes": "0xf902d694414552452d50512d5345414c57494e444f572d31826d618203e8a03333333333333333333333333333333333333333333333333333333333333333f90297f9029480b9029039bd3aadc5f485f3f17ab3ef996de30f40a4dbb98f4c70db2fbf505d86835dcfd8e1b067a325d98da059a8597b2e5ee62751d4fd8efc9985223f68c9b2725df62d7af9b091a129944bb0d86464ae20b5bd1c5cf3b29bec1fce23c562d6d8d3ea81215b2a061f05e1ea271c4f5da79f528ae113bb9ba6afdaa1eebb715d3171344fd4bce746d22de14f5a0454a7e371086667b9d586907f6b6969a528ba9ce5ceb7c8cbe30c939b4d76d3eaee2882cc898f374b94355329fae7e6d591e9166d7f71d9c58defb0bcade36ce313d62519c41a7973b149b4f2f8e51d6afd5154eb794343a3acdcc7436e4ff22dda41b236295314daef2a4b98c5343684e20ee7f1f6d27e4a66eaa79ce6a32b2fecf43c43237a40f3545f4af5f6d93109d8e15da5f28db19eac72f8641d14a079198fdf9f8ee292b2d0fc7d3fccd68525dbcfafff2a9d29a3cc361e4674d29e5af5ee408adc0d9725f7939065d0ceef4a4b64c0972943a69739b0aaf57562533888315d7a5d24fa759ed5661454ee58ce491e5f2fcf0d07608f524c50f36cab968c1d8cbee3313a7854744d1cd7e5ac70e20092bab2e5c59736351d014d71af7c19926b232bf1bc36676f81a1a6f7166e97d8e066f6a78d98f13974beed35449f3d9506fab1c0ab356b092273b42d4aedb6cdbedb736e6928fd2d4926b94106fbbf0923e3b759e1fb89ecaf24bea45bd406d509d611550061897b71c39ea3fa6a8f47a50a31849546df90137114491b55ce36fe1d6f64851c8647eb5906d13369b97ab5721a44db1f9d7712aa45c87f5f8b8bef5c92a9f715c432ef6262c8d22af0eb2943e40cda27921cb865b7d79a4b70ec14f7deb96916cc13eeb764a5f3f35189a9bace816de3f88b57aecea4ad102412e121f84ab7474a04d0c0d92526178821f0dce4",
|
|
+ "expected": "dropped: a frame in the wrong form for its height"
|
|
+ }
|
|
+ ],
|
|
+ "VF": [
|
|
+ {
|
|
+ "id": "vf-r0-4-r2-3-q7",
|
|
+ "n": 1000,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "quorum": 7,
|
|
+ "store": [
|
|
+ {
|
|
+ "round": 0,
|
|
+ "heard": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3
|
|
+ ],
|
|
+ "verified": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "round": 2,
|
|
+ "heard": [
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ],
|
|
+ "verified": [
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ }
|
|
+ ],
|
|
+ "expected": {
|
|
+ "sealForm": "anchor-round",
|
|
+ "finality": "partial",
|
|
+ "decidedRound": null,
|
|
+ "recordRound": 0,
|
|
+ "falconSealsVerified": 4,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3
|
|
+ ],
|
|
+ "rounds": [
|
|
+ {
|
|
+ "round": 0,
|
|
+ "falconSealsHeard": 4,
|
|
+ "falconSealsVerified": 4,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "round": 2,
|
|
+ "falconSealsHeard": 3,
|
|
+ "falconSealsVerified": 3,
|
|
+ "verifiedIndexes": [
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ }
|
|
+ ]
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vf-r0-4-r2-7-q7",
|
|
+ "n": 1000,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "quorum": 7,
|
|
+ "store": [
|
|
+ {
|
|
+ "round": 0,
|
|
+ "heard": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3
|
|
+ ],
|
|
+ "verified": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "round": 2,
|
|
+ "heard": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ],
|
|
+ "verified": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ }
|
|
+ ],
|
|
+ "expected": {
|
|
+ "sealForm": "anchor-round",
|
|
+ "finality": "post-quantum",
|
|
+ "decidedRound": 2,
|
|
+ "recordRound": 2,
|
|
+ "falconSealsVerified": 7,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ],
|
|
+ "rounds": [
|
|
+ {
|
|
+ "round": 0,
|
|
+ "falconSealsHeard": 4,
|
|
+ "falconSealsVerified": 4,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "round": 2,
|
|
+ "falconSealsHeard": 7,
|
|
+ "falconSealsVerified": 7,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ }
|
|
+ ]
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vf-r0-7-r1-7-q7",
|
|
+ "n": 1000,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "quorum": 7,
|
|
+ "store": [
|
|
+ {
|
|
+ "round": 1,
|
|
+ "heard": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ],
|
|
+ "verified": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "round": 0,
|
|
+ "heard": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 9
|
|
+ ],
|
|
+ "verified": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 9
|
|
+ ]
|
|
+ }
|
|
+ ],
|
|
+ "expected": {
|
|
+ "sealForm": "anchor-round",
|
|
+ "finality": "post-quantum",
|
|
+ "decidedRound": 0,
|
|
+ "recordRound": 0,
|
|
+ "falconSealsVerified": 7,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 9
|
|
+ ],
|
|
+ "rounds": [
|
|
+ {
|
|
+ "round": 0,
|
|
+ "falconSealsHeard": 7,
|
|
+ "falconSealsVerified": 7,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 9
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "round": 1,
|
|
+ "falconSealsHeard": 7,
|
|
+ "falconSealsVerified": 7,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ }
|
|
+ ]
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vf-r1-3-r3-3-egal",
|
|
+ "n": 1000,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "quorum": 7,
|
|
+ "store": [
|
|
+ {
|
|
+ "round": 3,
|
|
+ "heard": [
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ],
|
|
+ "verified": [
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "round": 1,
|
|
+ "heard": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2
|
|
+ ],
|
|
+ "verified": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2
|
|
+ ]
|
|
+ }
|
|
+ ],
|
|
+ "expected": {
|
|
+ "sealForm": "anchor-round",
|
|
+ "finality": "partial",
|
|
+ "decidedRound": null,
|
|
+ "recordRound": 1,
|
|
+ "falconSealsVerified": 3,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2
|
|
+ ],
|
|
+ "rounds": [
|
|
+ {
|
|
+ "round": 1,
|
|
+ "falconSealsHeard": 3,
|
|
+ "falconSealsVerified": 3,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "round": 3,
|
|
+ "falconSealsHeard": 3,
|
|
+ "falconSealsVerified": 3,
|
|
+ "verifiedIndexes": [
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ }
|
|
+ ]
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vf-nimic-auzit",
|
|
+ "n": 1000,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "quorum": 7,
|
|
+ "store": [],
|
|
+ "expected": {
|
|
+ "sealForm": "anchor-round",
|
|
+ "finality": "unavailable",
|
|
+ "decidedRound": null,
|
|
+ "recordRound": null,
|
|
+ "falconSealsVerified": 0,
|
|
+ "verifiedIndexes": [],
|
|
+ "rounds": []
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vf-auzite-neverificate",
|
|
+ "n": 1000,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "quorum": 7,
|
|
+ "store": [
|
|
+ {
|
|
+ "round": 0,
|
|
+ "heard": [
|
|
+ 0,
|
|
+ 1
|
|
+ ],
|
|
+ "verified": []
|
|
+ }
|
|
+ ],
|
|
+ "expected": {
|
|
+ "sealForm": "anchor-round",
|
|
+ "finality": "none",
|
|
+ "decidedRound": null,
|
|
+ "recordRound": 0,
|
|
+ "falconSealsVerified": 0,
|
|
+ "verifiedIndexes": [],
|
|
+ "rounds": [
|
|
+ {
|
|
+ "round": 0,
|
|
+ "falconSealsHeard": 2,
|
|
+ "falconSealsVerified": 0,
|
|
+ "verifiedIndexes": []
|
|
+ }
|
|
+ ]
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vf-sub-hr-4-plus-3",
|
|
+ "n": 998,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "quorum": 7,
|
|
+ "store": [
|
|
+ {
|
|
+ "round": null,
|
|
+ "heard": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ],
|
|
+ "verified": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ }
|
|
+ ],
|
|
+ "expected": {
|
|
+ "sealForm": "anchor",
|
|
+ "finality": "post-quantum",
|
|
+ "falconSealsVerified": 7,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vf-hr-nesetat",
|
|
+ "n": 5000,
|
|
+ "commitRoundBlock": null,
|
|
+ "quorum": 7,
|
|
+ "store": [
|
|
+ {
|
|
+ "round": null,
|
|
+ "heard": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ],
|
|
+ "verified": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ }
|
|
+ ],
|
|
+ "expected": {
|
|
+ "sealForm": "anchor",
|
|
+ "finality": "post-quantum",
|
|
+ "falconSealsVerified": 7,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ }
|
|
+ }
|
|
+ ]
|
|
+}
|
|
diff --git a/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/AereD412RealRoundTest.java b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/AereD412RealRoundTest.java
|
|
new file mode 100644
|
|
index 0000000000..75b504116c
|
|
--- /dev/null
|
|
+++ b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/AereD412RealRoundTest.java
|
|
@@ -0,0 +1,299 @@
|
|
+/*
|
|
+ * AERE D-412 / capul decis, pasul 1 (2026-09-30, dupa revizuire): colectorul pe drumul REAL al rundei.
|
|
+ *
|
|
+ * DE CE EXISTA. Probele pe unitate ale colectorului (AereDecisionEvidenceTest) folosesc un model de bloc si o fixtura; revizuirea
|
|
+ * a aratat pe drept ca ele nu pot spune daca Target.atRound pe blocul STOCAT da digestul, sigiliul ECDSA si mesajul PQ pe care
|
|
+ * le emite QbftRound prin adaptorul real. Aici nimic nu e modelat: TestContext porneste controlerul QBFT real al amontelui, cu
|
|
+ * QbftBlockInterfaceAdaptor, QbftExtraDataCodec, fabrica de blocuri si lantul reale. Inaltimea 1 se decide la RUNDA 5 (propunere
|
|
+ * de runda viitoare cu certificat de schimbare de runda, pregatiri, commit-uri); commit-ul nodului local il emite QbftRound
|
|
+ * insusi (citit din ce au primit vecinii), iar blocul judecat e antetul IMPORTAT in lant (cu sigiliile ECDSA si runda 5).
|
|
+ *
|
|
+ * CE MASOARA:
|
|
+ * - digestul si sigiliul: Target.atRound(bloc stocat, 1, 5) da exact digestul fiecarui commit, iar sigiliul fiecaruia se
|
|
+ * recupereaza peste commitDigest-ul lui la autorul mesajului;
|
|
+ * - Q1: colectorul, hranit cu commit-urile (blocul cunoscut numai ca stocat), gaseste cvorumul la runda 5 pe blocul stocat si
|
|
+ * pe forma lui de propunere, cu amprenta de pe lant egala cu hash-ul din lant;
|
|
+ * - mesajul PQ: cu ancora armata, mesajul pe care l-ar semna emitatorul (PqAnchorProducer.commitSealMessage peste amprenta de
|
|
+ * runda 0 a PROPUNERII, ca QbftRound.pqSealMessageFor) e egal cu cel pe care colectorul il cere pe blocul STOCAT;
|
|
+ * - formele stocate AERE: acelasi antet cu certificat v1, cu certificat v2 hibrid, cu sigiliul propunatorului (elementul 6) si
|
|
+ * fara sigilii ECDSA (forma de la H_hdr): digestul, amprenta si Q1 raman aceleasi.
|
|
+ * - limita, masurata si fixata: amontele NU cere ca runda scrisa in blocul propus sa fie runda propunerii (FutureRoundTest
|
|
+ * propune la runda 5 un bloc cu runda 0); un asemenea bloc se decide sub H_fin, dar digestul commit-urilor lui e amprenta
|
|
+ * formei de runda 0, nu a formei de runda 5, iar Q1 nu il gaseste. De la H_fin commit-urile lui nu au autor (semnatarul
|
|
+ * sigiliului se recupereaza peste digestul mesajului, AereDecisionEvidenceTest.aBlockProposedWithAnotherRoundHasNoCommitAuthor),
|
|
+ * deci nu se poate decide deloc; colectorul lucreaza de la H_ev >= H_hdr >= H_fin.
|
|
+ * CE NU MASOARA, spus: sigiliile Falcon/SLH-DSA ale commit-urilor (TestContext nu are chei PQ: FalconSealSupport nu semneaza
|
|
+ * fara cheie), deci impunerea PQ nu ruleaza aici; asta o masoara, pe semnaturi REALE de pe 2800 si 28001,
|
|
+ * AereD412RealHeadersTest (consensus/qbft). Formele stocate AERE de mai sus sunt construite din antetul real, nu capturate.
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft.core.test;
|
|
+
|
|
+import static java.util.Collections.emptyList;
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftHelpers;
|
|
+import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.SchemeSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealSchemes;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.common.bft.payload.SignedData;
|
|
+import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.AdaptorUtil;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockAdaptor;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockInterfaceAdaptor;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagedata.CommitMessageData;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagedata.QbftV1;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit;
|
|
+import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.AereDecisionEvidence;
|
|
+import org.hyperledger.besu.consensus.qbft.core.support.RoundSpecificPeers;
|
|
+import org.hyperledger.besu.consensus.qbft.core.support.TestContext;
|
|
+import org.hyperledger.besu.consensus.qbft.core.support.TestContextBuilder;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.AereVoteCounts;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.core.Block;
|
|
+import org.hyperledger.besu.ethereum.core.BlockBody;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
|
|
+import org.hyperledger.besu.ethereum.core.Util;
|
|
+import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData;
|
|
+
|
|
+import java.time.Clock;
|
|
+import java.time.Instant;
|
|
+import java.time.ZoneId;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collection;
|
|
+import java.util.Comparator;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+public class AereD412RealRoundTest {
|
|
+
|
|
+ private static final int NETWORK_SIZE = 5;
|
|
+ private static final int ROUND = 5;
|
|
+ private static final long CHAIN = 28001L;
|
|
+
|
|
+ private final Clock fixedClock = Clock.fixed(Instant.ofEpochSecond(100), ZoneId.systemDefault());
|
|
+ private final TestContext context =
|
|
+ new TestContextBuilder()
|
|
+ .validatorCount(NETWORK_SIZE)
|
|
+ .indexOfFirstLocallyProposedBlock(0)
|
|
+ .clock(fixedClock)
|
|
+ .buildAndStart();
|
|
+ private final ConsensusRoundIdentifier futureRoundId = new ConsensusRoundIdentifier(1, ROUND);
|
|
+ private final RoundSpecificPeers futurePeers = context.roundSpecificPeers(futureRoundId);
|
|
+ private final QbftExtraDataCodec codec = new QbftExtraDataCodec();
|
|
+ private final QbftBlockInterface blockInterface =
|
|
+ new QbftBlockInterfaceAdaptor(new BftBlockInterface(codec));
|
|
+
|
|
+ @AfterEach
|
|
+ public void forgetAnchorConfig() {
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ }
|
|
+
|
|
+ /** Height 1 decided at round 5 by the real controller; the local commit as the peers received it, then the peers'. */
|
|
+ private List<Commit> decideAtRoundFive(final QbftBlock proposal) {
|
|
+ final int quorum = BftHelpers.calculateRequiredValidatorQuorum(NETWORK_SIZE);
|
|
+ final List<SignedData<RoundChangePayload>> roundChanges =
|
|
+ futurePeers.createSignedRoundChangePayload(futureRoundId);
|
|
+ futurePeers.getProposer().injectProposalForFutureRound(futureRoundId, roundChanges, emptyList(), proposal);
|
|
+ for (int i = 0; i < quorum - 1; i++) {
|
|
+ futurePeers.getNonProposing(i).injectPrepare(futureRoundId, proposal.getHash());
|
|
+ }
|
|
+ final List<Commit> commits = new ArrayList<>();
|
|
+ for (final MessageData m : futurePeers.getNonProposing(0).getReceivedMessages()) {
|
|
+ if (m.getCode() == QbftV1.COMMIT) {
|
|
+ commits.add(CommitMessageData.fromMessageData(m).decode());
|
|
+ }
|
|
+ }
|
|
+ assertThat(commits).as("the local node's QbftRound emitted exactly one commit").hasSize(1);
|
|
+ assertThat(commits.get(0).getAuthor()).isEqualTo(context.getLocalNodeParams().getAddress());
|
|
+ for (int i = 0; i < quorum - 1; i++) {
|
|
+ commits.add(futurePeers.getNonProposing(i).injectCommit(futureRoundId, proposal));
|
|
+ }
|
|
+ assertThat(context.getBlockchain().getChainHeadBlockNumber()).as("height 1 imported").isEqualTo(1);
|
|
+ return commits;
|
|
+ }
|
|
+
|
|
+ /** A round-5 proposal as an honest proposer builds it: the round of the proposal written in the block. */
|
|
+ private QbftBlock honestProposal() {
|
|
+ return context.createBlockForProposalFromChainHead(60, futurePeers.getProposer().getNodeAddress(), ROUND);
|
|
+ }
|
|
+
|
|
+ private BlockHeader storedHeader() {
|
|
+ return AdaptorUtil.toBesuBlockHeader(context.getBlockchain().getChainHeadHeader());
|
|
+ }
|
|
+
|
|
+ private static QbftBlock asBlock(final BlockHeader header) {
|
|
+ return new QbftBlockAdaptor(new Block(header, new BlockBody(emptyList(), emptyList())));
|
|
+ }
|
|
+
|
|
+ private AereDecisionEvidence collector() {
|
|
+ final Collection<Address> validators =
|
|
+ context.getValidatorProvider().getValidatorsAfterBlock(context.getBlockHeader(0));
|
|
+ final Hash genesis = context.getBlockHeader(0).getHash();
|
|
+ final AereDecisionEvidence.ValidatorSets sets =
|
|
+ new AereDecisionEvidence.ValidatorSets() {
|
|
+ @Override
|
|
+ public Optional<Collection<Address>> afterBlock(final Hash onchainHash) {
|
|
+ return onchainHash.equals(genesis) ? Optional.of(validators) : Optional.empty();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Collection<Address> admission(final long height) {
|
|
+ return validators;
|
|
+ }
|
|
+ };
|
|
+ return new AereDecisionEvidence(blockInterface, sets, null, () -> 0L, b -> 0L, 0L, 256);
|
|
+ }
|
|
+
|
|
+ /** The stored header with its extra data rewritten, hashed as an on-chain header. */
|
|
+ private QbftBlock storedWith(final BlockHeader stored, final BftExtraData extraData) {
|
|
+ return asBlock(
|
|
+ BlockHeaderBuilder.fromHeader(stored)
|
|
+ .extraData(codec.encode(extraData))
|
|
+ .blockHeaderFunctions(BftBlockHeaderFunctions.forOnchainBlock(codec))
|
|
+ .buildBlockHeader());
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theCollectorFindsTheRoundFiveQuorumOnTheStoredBlock() {
|
|
+ final QbftBlock proposal = honestProposal();
|
|
+ final List<Commit> commits = decideAtRoundFive(proposal);
|
|
+ final BlockHeader storedHeader = storedHeader();
|
|
+ final BftExtraData storedExtra = codec.decodeRaw(storedHeader.getExtraData());
|
|
+ assertThat(storedExtra.getRound()).as("the stored block carries the decision round").isEqualTo(ROUND);
|
|
+ assertThat(storedExtra.getSeals()).hasSize(commits.size());
|
|
+ final QbftBlock stored = asBlock(storedHeader);
|
|
+
|
|
+ final AereVoteCounts.Target target = AereVoteCounts.Target.atRound(blockInterface, stored, 1, ROUND);
|
|
+ for (final Commit c : commits) {
|
|
+ assertThat(target.digest()).as("digest_5(stored) is the digest of %s's commit", c.getAuthor()).isEqualTo(c.getDigest());
|
|
+ assertThat(Util.signatureToAddress(c.getCommitSeal(), target.commitDigest()))
|
|
+ .as("the commit seal recovers over the collector's commit digest")
|
|
+ .isEqualTo(c.getAuthor());
|
|
+ }
|
|
+ assertThat(AereVoteCounts.Target.atRound(blockInterface, stored, 1, 0).digest())
|
|
+ .as("control: at another round the digest differs")
|
|
+ .isNotEqualTo(commits.get(0).getDigest());
|
|
+
|
|
+ final AereDecisionEvidence ev = collector();
|
|
+ for (final Commit c : commits) {
|
|
+ assertThat(ev.observeCommit(c)).isTrue();
|
|
+ }
|
|
+ assertThat(ev.countedAuthors(1)).as("no block heard: nothing counted yet").isEmpty();
|
|
+ final AereDecisionEvidence.Proof proof = ev.quorumFor(stored).orElseThrow();
|
|
+ assertThat(proof.round()).isEqualTo(ROUND);
|
|
+ assertThat(proof.onchainHash()).as("the on-chain hash the collector derives is the chain's").isEqualTo(storedHeader.getHash());
|
|
+ assertThat(proof.authors()).contains(context.getLocalNodeParams().getAddress()).hasSize(commits.size());
|
|
+ assertThat(ev.quorumFor(proposal)).as("the proposal form of the same block").isPresent();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theAnchorFormOfTheStoredBlockIsTheEmittersMessage() {
|
|
+ final QbftBlock proposal = honestProposal();
|
|
+ final List<Commit> commits = decideAtRoundFive(proposal);
|
|
+ final QbftBlock stored = asBlock(storedHeader());
|
|
+ PqAnchorProducer.useConfigForTesting(new PqAnchorConfig(CHAIN, 1L, Map.of(1L, 0), OptionalInt.empty(), false));
|
|
+ // the emitter's expression (QbftRound.pqSealMessageFor with pqOnchainHashOf and commitHashFor), on the PROPOSAL
|
|
+ final Hash commitHash = blockInterface.replaceRoundForCommitBlock(proposal, ROUND).getHash();
|
|
+ final Hash emitted =
|
|
+ Hash.wrap(
|
|
+ PqAnchorProducer.commitSealMessage(
|
|
+ 1L, () -> blockInterface.replaceRoundForCommitBlock(proposal, 0).getHash().getBytes(), commitHash, ROUND)
|
|
+ .orElseThrow());
|
|
+ final AereVoteCounts.Target onStored = AereVoteCounts.Target.atRound(blockInterface, stored, 1, ROUND);
|
|
+ assertThat(onStored.pqSealMessage()).as("the collector asks, on the stored block, for the message the emitter signs").hasValue(emitted);
|
|
+ assertThat(emitted)
|
|
+ .as("and it is the anchor form over the chain's own hash of the block")
|
|
+ .isEqualTo(Hash.wrap(PqAnchor.commitMessage(CHAIN, 1L, stored.getHeader().getHash().getBytes())));
|
|
+ assertThat(emitted).isNotEqualTo(commits.get(0).getDigest());
|
|
+ assertThat(AereVoteCounts.Target.of(blockInterface, proposal, futureRoundId).pqSealMessage())
|
|
+ .as("and the verifier's (MessageValidator) target on the proposal")
|
|
+ .hasValue(emitted);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theAereStoredFormsKeepTheDigestAndTheQuorum() {
|
|
+ final QbftBlock proposal = honestProposal();
|
|
+ final List<Commit> commits = decideAtRoundFive(proposal);
|
|
+ final BlockHeader storedHeader = storedHeader();
|
|
+ final BftExtraData e = codec.decodeRaw(storedHeader.getExtraData());
|
|
+ final Bytes sig = Bytes.repeat((byte) 0x29, 660);
|
|
+ final List<FalconSeal> certificateV1 = List.of(new FalconSeal(0, sig), new FalconSeal(1, sig), new FalconSeal(3, sig));
|
|
+ final List<SchemeSeal> certificateV2 = new ArrayList<>();
|
|
+ for (final int i : new int[] {0, 1, 3}) {
|
|
+ certificateV2.add(new SchemeSeal(SealSchemes.FALCON_512.wireId(), i, sig));
|
|
+ certificateV2.add(new SchemeSeal(SealSchemes.SLH_DSA_128S.wireId(), i, Bytes.repeat((byte) 7, 7856)));
|
|
+ }
|
|
+ certificateV2.sort(
|
|
+ Comparator.comparingInt(SchemeSeal::getValidatorIndex).thenComparingInt(s -> s.getSchemeWireId() & 0xff));
|
|
+ final Optional<FalconSeal> proposerSeal = Optional.of(new FalconSeal(2, sig));
|
|
+ final Map<String, BftExtraData> forms =
|
|
+ Map.of(
|
|
+ "certificat v1",
|
|
+ new BftExtraData(e.getVanityData(), e.getSeals(), e.getVote(), e.getRound(), e.getValidators(), certificateV1, java.util.List.of(), BftExtraData.NO_CERTIFICATE_ROUND),
|
|
+ "certificat v2 hibrid",
|
|
+ new BftExtraData(
|
|
+ e.getVanityData(), e.getSeals(), e.getVote(), e.getRound(), e.getValidators(), List.of(), certificateV2, BftExtraData.NO_CERTIFICATE_ROUND),
|
|
+ "elementul 6",
|
|
+ new BftExtraData(
|
|
+ e.getVanityData(), e.getSeals(), e.getVote(), e.getRound(), e.getValidators(), List.of(), List.of(), BftExtraData.NO_CERTIFICATE_ROUND, proposerSeal),
|
|
+ "forma H_hdr: fara sigilii ECDSA, certificat v2 si elementul 6",
|
|
+ new BftExtraData(
|
|
+ e.getVanityData(), List.of(), e.getVote(), e.getRound(), e.getValidators(), List.of(), certificateV2, BftExtraData.NO_CERTIFICATE_ROUND, proposerSeal));
|
|
+ for (final Map.Entry<String, BftExtraData> f : forms.entrySet()) {
|
|
+ final QbftBlock form = storedWith(storedHeader, f.getValue());
|
|
+ assertThat(
|
|
+ codec
|
|
+ .decodeRaw(AdaptorUtil.toBesuBlockHeader(form.getHeader()).getExtraData())
|
|
+ .getPqProposerSeal()
|
|
+ .isPresent())
|
|
+ .as("%s: the element 6 is where the form puts it", f.getKey())
|
|
+ .isEqualTo(f.getValue().getPqProposerSeal().isPresent());
|
|
+ assertThat(form.getHeader().getHash()).as("%s: the on-chain hash is unchanged", f.getKey()).isEqualTo(storedHeader.getHash());
|
|
+ assertThat(AereVoteCounts.Target.atRound(blockInterface, form, 1, ROUND).digest())
|
|
+ .as("%s: digest_5 is still the commits' digest", f.getKey())
|
|
+ .isEqualTo(commits.get(0).getDigest());
|
|
+ final AereDecisionEvidence ev = collector();
|
|
+ commits.forEach(ev::observeCommit);
|
|
+ assertThat(ev.quorumFor(form)).as("%s: Q1 on this stored form", f.getKey()).isPresent();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aBlockProposedWithAnotherRoundIsNotSeenByQ1BelowHFin() {
|
|
+ // the upstream test shape: the block of the round-5 proposal carries round 0; the real controller decides it anyway
|
|
+ final QbftBlock proposal =
|
|
+ context.createBlockForProposalFromChainHead(60, futurePeers.getProposer().getNodeAddress());
|
|
+ final List<Commit> commits = decideAtRoundFive(proposal);
|
|
+ final QbftBlock stored = asBlock(storedHeader());
|
|
+ assertThat(codec.decodeRaw(storedHeader().getExtraData()).getRound()).isEqualTo(ROUND);
|
|
+ final AereVoteCounts.Target target = AereVoteCounts.Target.atRound(blockInterface, stored, 1, ROUND);
|
|
+ assertThat(target.digest())
|
|
+ .as("the commits carry the hash of the round-0 form, not digest_5(stored)")
|
|
+ .isNotEqualTo(commits.get(0).getDigest());
|
|
+ assertThat(AereVoteCounts.Target.atRound(blockInterface, stored, 1, 0).digest()).isEqualTo(commits.get(0).getDigest());
|
|
+ assertThat(Util.signatureToAddress(commits.get(0).getCommitSeal(), target.commitDigest()))
|
|
+ .as("the commit seals still sign the round-5 form of the stored block")
|
|
+ .isEqualTo(commits.get(0).getAuthor());
|
|
+ final AereDecisionEvidence ev = collector();
|
|
+ commits.forEach(ev::observeCommit);
|
|
+ assertThat(ev.quorumFor(stored)).as("the known limit: Q1 does not see this decision below H_fin").isEmpty();
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/AereD412RoundHookTest.java b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/AereD412RoundHookTest.java
|
|
new file mode 100644
|
|
index 0000000000..d470201e4b
|
|
--- /dev/null
|
|
+++ b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/AereD412RoundHookTest.java
|
|
@@ -0,0 +1,175 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft.core.test;
|
|
+
|
|
+import static java.util.Collections.emptyList;
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftHelpers;
|
|
+import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
|
+import org.hyperledger.besu.consensus.common.bft.messagewrappers.BftMessage;
|
|
+import org.hyperledger.besu.consensus.common.bft.payload.SignedData;
|
|
+import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockInterfaceAdaptor;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit;
|
|
+import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.AereDecidedConsensus;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.AereDecidedHook;
|
|
+import org.hyperledger.besu.consensus.qbft.core.support.RoundSpecificPeers;
|
|
+import org.hyperledger.besu.consensus.qbft.core.support.TestContext;
|
|
+import org.hyperledger.besu.consensus.qbft.core.support.TestContextBuilder;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftMessage;
|
|
+
|
|
+import java.time.Clock;
|
|
+import java.time.Instant;
|
|
+import java.time.ZoneId;
|
|
+import java.util.ArrayList;
|
|
+import java.util.List;
|
|
+
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+/**
|
|
+ * AERE D-412 / the DECIDED HEAD (rule D), step 3: the two wiring points inside the REAL {@code
|
|
+ * QbftRound} (and the observe point inside the real {@code QbftController}), run by the upstream
|
|
+ * integration harness (TestContext: the real controller, rounds, block importer and chain).
|
|
+ *
|
|
+ * <p>A recording hook is installed as the process hook; height 1 is decided at round 5 (a future-round
|
|
+ * proposal with a round-change certificate, the peers' prepares, the peers' commits). What the round
|
|
+ * must hand the hook:
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>its own Commit, when it creates it (at the proposal), exactly once, authored by the local node;
|
|
+ * <li>the decision of its own round, exactly once, AFTER the block is in the chain, with the block
|
|
+ * the chain now holds at height 1;
|
|
+ * <li>and those two must fit the wiring's own filter ({@code
|
|
+ * AereDecidedConsensus.isVoteOfOwnDecision}): the real own commit is a vote of the real decision
|
|
+ * (2026-10-01).
|
|
+ * </ul>
|
|
+ *
|
|
+ * And the controller must have shown the hook the consensus messages it received.
|
|
+ */
|
|
+public class AereD412RoundHookTest {
|
|
+
|
|
+ private static final int NETWORK_SIZE = 5;
|
|
+ private static final int ROUND = 5;
|
|
+
|
|
+ private final Clock fixedClock = Clock.fixed(Instant.ofEpochSecond(100), ZoneId.systemDefault());
|
|
+ private final TestContext context =
|
|
+ new TestContextBuilder()
|
|
+ .validatorCount(NETWORK_SIZE)
|
|
+ .indexOfFirstLocallyProposedBlock(0)
|
|
+ .clock(fixedClock)
|
|
+ .buildAndStart();
|
|
+ private final ConsensusRoundIdentifier futureRoundId = new ConsensusRoundIdentifier(1, ROUND);
|
|
+ private final RoundSpecificPeers futurePeers = context.roundSpecificPeers(futureRoundId);
|
|
+
|
|
+ /** What the round and the controller hand the hook, and the chain height at each call. */
|
|
+ private final class Recording extends AereDecidedHook {
|
|
+ private final List<Commit> ownCommits = new ArrayList<>();
|
|
+ private final List<QbftBlock> decided = new ArrayList<>();
|
|
+ private final List<Integer> decidedRounds = new ArrayList<>();
|
|
+ private final List<Long> heightAtDecision = new ArrayList<>();
|
|
+ private int observed;
|
|
+
|
|
+ @Override
|
|
+ public void observe(final BftMessage<?> message, final QbftMessage raw) {
|
|
+ observed++;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void ownCommit(final Commit localCommit) {
|
|
+ ownCommits.add(localCommit);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void ownRoundDecided(final QbftBlock imported, final int round) {
|
|
+ decided.add(imported);
|
|
+ decidedRounds.add(round);
|
|
+ heightAtDecision.add(context.getBlockchain().getChainHeadBlockNumber());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ public void resetHook() {
|
|
+ AereDecidedHook.reset();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theRealRoundHandsTheHookItsOwnCommitAndItsDecisionAfterTheImport() {
|
|
+ final Recording hook = new Recording();
|
|
+ AereDecidedHook.install(hook);
|
|
+ final QbftBlock proposal =
|
|
+ context.createBlockForProposalFromChainHead(
|
|
+ 60, futurePeers.getProposer().getNodeAddress(), ROUND);
|
|
+ final int quorum = BftHelpers.calculateRequiredValidatorQuorum(NETWORK_SIZE);
|
|
+ final List<SignedData<RoundChangePayload>> roundChanges =
|
|
+ futurePeers.createSignedRoundChangePayload(futureRoundId);
|
|
+ futurePeers
|
|
+ .getProposer()
|
|
+ .injectProposalForFutureRound(futureRoundId, roundChanges, emptyList(), proposal);
|
|
+ assertThat(hook.ownCommits)
|
|
+ .as("the round hands its own commit to the hook when it creates it (proposal accepted)")
|
|
+ .hasSize(1);
|
|
+ assertThat(hook.ownCommits.get(0).getAuthor())
|
|
+ .isEqualTo(context.getLocalNodeParams().getAddress());
|
|
+ assertThat(hook.ownCommits.get(0).getRoundIdentifier()).isEqualTo(futureRoundId);
|
|
+ assertThat(hook.decided).as("nothing is decided at the proposal").isEmpty();
|
|
+ for (int i = 0; i < quorum - 1; i++) {
|
|
+ futurePeers.getNonProposing(i).injectPrepare(futureRoundId, proposal.getHash());
|
|
+ }
|
|
+ for (int i = 0; i < quorum - 1; i++) {
|
|
+ futurePeers.getNonProposing(i).injectCommit(futureRoundId, proposal);
|
|
+ }
|
|
+ assertThat(context.getBlockchain().getChainHeadBlockNumber()).as("height 1 imported").isEqualTo(1);
|
|
+ assertThat(hook.decided).as("the decision of the own round, once").hasSize(1);
|
|
+ assertThat(hook.decided.get(0).getHeader().getNumber()).isEqualTo(1);
|
|
+ assertThat(hook.decided.get(0).getHash())
|
|
+ .as("the decided block is the block the chain holds at height 1")
|
|
+ .isEqualTo(context.getBlockchain().getChainHeadHeader().getHash());
|
|
+ assertThat(hook.heightAtDecision)
|
|
+ .as("the hook is told after the block is in the chain")
|
|
+ .containsExactly(1L);
|
|
+ assertThat(hook.decidedRounds)
|
|
+ .as("with the round that COMMITTED, the round of the own commit handed at the proposal")
|
|
+ .containsExactly(ROUND);
|
|
+ assertThat(hook.ownCommits.get(0).getRoundIdentifier().getRoundNumber())
|
|
+ .isEqualTo(hook.decidedRounds.get(0));
|
|
+ // 2026-10-01: the wiring keeps an own commit as a vote only through AereDecidedConsensus
|
|
+ // .isVoteOfOwnDecision; its own proofs build the own commit the way the filter presumes, so here
|
|
+ // the filter is asked about the REAL round's own commit, the REAL imported (sealed) block and the
|
|
+ // REAL round. If it said no, the wiring would drop every own commit in production, and a node that
|
|
+ // is one of exactly Q deciders would never retain the proof the echo needs.
|
|
+ final QbftBlockInterface blockInterface =
|
|
+ new QbftBlockInterfaceAdaptor(new BftBlockInterface(new QbftExtraDataCodec()));
|
|
+ assertThat(
|
|
+ AereDecidedConsensus.isVoteOfOwnDecision(
|
|
+ blockInterface, hook.ownCommits.get(0), hook.decided.get(0), hook.decidedRounds.get(0)))
|
|
+ .as("the wiring's filter keeps the real round's own commit, on the real imported block and round")
|
|
+ .isTrue();
|
|
+ assertThat(
|
|
+ AereDecidedConsensus.isVoteOfOwnDecision(
|
|
+ blockInterface, hook.ownCommits.get(0), hook.decided.get(0), 0))
|
|
+ .as("control: at round 0, where this node never voted, the same commit is no vote")
|
|
+ .isFalse();
|
|
+ assertThat(hook.ownCommits).as("still one own commit").hasSize(1);
|
|
+ assertThat(hook.observed)
|
|
+ .as("the controller showed the hook every message it received (proposal, prepares, commits)")
|
|
+ .isGreaterThanOrEqualTo(1 + 2 * (quorum - 1));
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/Proposal.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/Proposal.java
|
|
index 7d9ee23bb0..7f4ee3a4e2 100644
|
|
--- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/Proposal.java
|
|
+++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/Proposal.java
|
|
@@ -1,39 +1,39 @@
|
|
/*
|
|
* Copyright ConsenSys AG.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
- * found, as section 4(c) requires. The change itself is in patches/0008-aere-pq-aip22.patch.
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0009-aere-pq-seal-judge-snap-cap.patch.
|
|
*/
|
|
package org.hyperledger.besu.consensus.qbft.core.messagewrappers;
|
|
|
|
import org.hyperledger.besu.consensus.common.bft.messagewrappers.BftMessage;
|
|
import org.hyperledger.besu.consensus.common.bft.payload.SignedData;
|
|
import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload;
|
|
import org.hyperledger.besu.consensus.qbft.core.payload.ProposalPayload;
|
|
import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCodec;
|
|
import org.hyperledger.besu.ethereum.mainnet.block.access.list.BlockAccessList;
|
|
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
|
|
import org.hyperledger.besu.ethereum.rlp.RLP;
|
|
import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
|
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
|
|
import org.apache.tuweni.bytes.Bytes;
|
|
|
|
diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/RoundChange.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/RoundChange.java
|
|
index 35efb6ae75..ee9615f619 100644
|
|
--- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/RoundChange.java
|
|
+++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/RoundChange.java
|
|
@@ -1,39 +1,39 @@
|
|
/*
|
|
* Copyright ConsenSys AG.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
- * found, as section 4(c) requires. The change itself is in patches/0008-aere-pq-aip22.patch.
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0009-aere-pq-seal-judge-snap-cap.patch.
|
|
*/
|
|
package org.hyperledger.besu.consensus.qbft.core.messagewrappers;
|
|
|
|
import org.hyperledger.besu.consensus.common.bft.messagewrappers.BftMessage;
|
|
import org.hyperledger.besu.consensus.common.bft.payload.SignedData;
|
|
import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload;
|
|
import org.hyperledger.besu.consensus.qbft.core.payload.PreparedRoundMetadata;
|
|
import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCodec;
|
|
import org.hyperledger.besu.ethereum.core.encoding.BlockAccessListDecoder;
|
|
import org.hyperledger.besu.ethereum.mainnet.block.access.list.BlockAccessList;
|
|
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
|
|
import org.hyperledger.besu.ethereum.rlp.RLP;
|
|
import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
|
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
|
|
import org.apache.tuweni.bytes.Bytes;
|
|
diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereDecidedConsensus.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereDecidedConsensus.java
|
|
new file mode 100644
|
|
index 0000000000..3fa2c83a4c
|
|
--- /dev/null
|
|
+++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereDecidedConsensus.java
|
|
@@ -0,0 +1,1075 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft.core.statemachine;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead;
|
|
+import org.hyperledger.besu.consensus.common.bft.messagewrappers.BftMessage;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagedata.CommitMessageData;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagedata.ProposalMessageData;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockHeader;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftMessage;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.AereVoteCounts;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.PqCommitEnforcement;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData;
|
|
+
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collection;
|
|
+import java.util.HashMap;
|
|
+import java.util.HashSet;
|
|
+import java.util.LinkedHashMap;
|
|
+import java.util.LinkedHashSet;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.NavigableMap;
|
|
+import java.util.Objects;
|
|
+import java.util.Optional;
|
|
+import java.util.Set;
|
|
+import java.util.TreeMap;
|
|
+import java.util.TreeSet;
|
|
+import java.util.concurrent.Executor;
|
|
+import java.util.concurrent.atomic.AtomicBoolean;
|
|
+import java.util.concurrent.atomic.AtomicLong;
|
|
+import java.util.function.LongSupplier;
|
|
+import java.util.function.ToLongFunction;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.slf4j.Logger;
|
|
+import org.slf4j.LoggerFactory;
|
|
+
|
|
+/**
|
|
+ * AERE D-412 / the DECIDED HEAD (rule D), step 3: the wiring between the QBFT state machine, the
|
|
+ * decision-evidence collector ({@link AereDecisionEvidence}, step 1) and the decided head D
|
|
+ * ({@code AereDecidedHead}, step 2), for ONE validator.
|
|
+ *
|
|
+ * <p>What it does, per PROIECT-CAP-DECIS-2026-09-29.md sections 2-5:
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>{@link #observe}: every consensus message for a height in (D, D+W] is handed to the collector
|
|
+ * (commits; proposals and the blocks of round-change certificates) before any height guard or
|
|
+ * round filter sees it, and, when its author is a validator, kept raw for the replay; then an
|
|
+ * evaluation is scheduled;
|
|
+ * <li>the evaluation, on its OWN executor (never the QBFT thread): Q1 and Q2 on the stored blocks the
|
|
+ * node knows in the window (canonical, heard, stored as a fork), Q3 on stored certified anchors;
|
|
+ * a proof moves D through {@link Chain#advance} (durable write, then the chain, then D), and the
|
|
+ * collector retains the proof for the echo;
|
|
+ * <li>{@link #ownRoundDecided}: this node's own round committed (Q1 of the own round); the node's own
|
|
+ * commit, kept aside by {@link #ownCommit} until then, is fed to the collector only now, so an
|
|
+ * unsent commit of a node that never got prepared is never counted;
|
|
+ * <li>{@link #echoIfRoundChange}: a RoundChange for a height in [D-W, D] from a member of that height's
|
|
+ * set is answered with the raw messages of the retained proof, multicast to the validators, at
|
|
+ * most once per AUTHOR every {@link #ECHO_INTERVAL_MILLIS} ms whatever the height (an honest
|
|
+ * laggard asks for one height at a time; a key asking for every height of the window gets one
|
|
+ * echo per interval, not W);
|
|
+ * <li>{@link #ignoresNewHead}: while rule D governs the next height, only D starts a height;
|
|
+ * <li>{@link #replay}: the messages of the height just started that the future-message buffer did not
|
|
+ * keep (it only keeps futureMessagesMaxDistance heights).
|
|
+ * </ul>
|
|
+ *
|
|
+ * <p>Bounded against one key: the raw store keeps messages of validators only, at most {@link
|
|
+ * #MAX_RAW_PER_AUTHOR_HEIGHT} per (height, author) and {@link #MAX_RAW_BYTES_PER_AUTHOR} bytes per
|
|
+ * author; the blocks heard (admitted by the collector's own quotas) and the blocks stored as forks are
|
|
+ * remembered in two separate sets, so forged siblings stored by propagation cannot push out the blocks
|
|
+ * the collector heard.
|
|
+ *
|
|
+ * <p>Corrected 2026-09-30 after the adversarial review of step 3 (each with its proof and plant in
|
|
+ * QbftControllerDecidedHeadTest):
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>the collector's D comes from ONE source, the chain's, at every call ({@code syncCollector}):
|
|
+ * it was set once at construction, and a D moved below H_ev by the canonical head (Q5) left the
|
|
+ * collector refusing every message of H_ev on a node started more than W blocks before it;
|
|
+ * <li>besides (D, D+W], the LIVE heights around the canonical head are admitted and judged for Q1
|
|
+ * only, so a validator whose D fell more than W behind comes back on a full quorum of the
|
|
+ * height being decided now even when no certificate proves anything (Q3 silent);
|
|
+ * <li>at the own round's decision only the own commit of the round that COMMITTED, on the
|
|
+ * imported block, becomes a vote.
|
|
+ * </ul>
|
|
+ *
|
|
+ * <p>Below the PROOF height (H_ev - 1, corrected 2026-10-01 after the second review of step 3: the
|
|
+ * parent of H_ev must be a proved block, since below H_ev one key can still bend the canonical line)
|
|
+ * every method returns at its first line: the collector is never fed, no new head is ignored, no
|
|
+ * own commit is kept. The raw store and the replay start at H_ev itself, where rule D starts
|
|
+ * heights. At every evaluation the durable floor is resolved first ({@link Chain#resolveFloor}).
|
|
+ *
|
|
+ * <p>No method throws into the state machine: a failure is logged at WARN, counted ({@link
|
|
+ * #failures()}), and upstream processing continues as if the hook were {@link AereDecidedHook#INERT}.
|
|
+ */
|
|
+public final class AereDecidedConsensus extends AereDecidedHook {
|
|
+
|
|
+ private static final Logger LOG = LoggerFactory.getLogger(AereDecidedConsensus.class);
|
|
+
|
|
+ /** One echo per author at most this often. */
|
|
+ public static final long ECHO_INTERVAL_MILLIS = 10_000L;
|
|
+
|
|
+ /** At most this many raw messages kept per height for the replay. */
|
|
+ public static final int MAX_RAW_PER_HEIGHT = 512;
|
|
+
|
|
+ /** At most this many raw messages kept per (height, author). */
|
|
+ public static final int MAX_RAW_PER_AUTHOR_HEIGHT = 16;
|
|
+
|
|
+ /** At most this many bytes of raw messages kept per author, all heights together. */
|
|
+ public static final long MAX_RAW_BYTES_PER_AUTHOR = 4L * 1024 * 1024;
|
|
+
|
|
+ /** At most this many bytes of raw messages kept for the replay, all heights together. */
|
|
+ public static final long MAX_RAW_BYTES = 48L * 1024 * 1024;
|
|
+
|
|
+ /** At most this many heard blocks (and parents of heard blocks) remembered per height. */
|
|
+ public static final int MAX_HEARD_CANDIDATES_PER_HEIGHT = 64;
|
|
+
|
|
+ /** At most this many stored blocks (canonical or fork) remembered per height. */
|
|
+ public static final int MAX_STORED_CANDIDATES_PER_HEIGHT = 32;
|
|
+
|
|
+ /** At most this many own commits kept per height (one per round the node accepted a proposal in). */
|
|
+ public static final int MAX_OWN_COMMITS_PER_HEIGHT = 8;
|
|
+
|
|
+ /** At most this many echo marks (authors) remembered. */
|
|
+ public static final int MAX_ECHO_MARKS = 4096;
|
|
+
|
|
+ /**
|
|
+ * What the wiring needs from the node: its chain, its decided head, its validator sets and its
|
|
+ * network. Implemented over Besu types in {@code consensus/qbft} ({@code AereDecidedChainView}).
|
|
+ */
|
|
+ public interface Chain {
|
|
+ /**
|
|
+ * Whether rule D applies at a height (height >= H_ev).
|
|
+ *
|
|
+ * @param height the height
|
|
+ * @return true from H_ev
|
|
+ */
|
|
+ boolean active(long height);
|
|
+
|
|
+ /**
|
|
+ * Whether the decided block at a height needs a proof (height >= max(1, H_ev - 1)): the evidence,
|
|
+ * the own round, the echo and the new-head rule work from here, one height below H_ev, because
|
|
+ * the parent of H_ev must be a proved block (2026-10-01, review of step 3).
|
|
+ *
|
|
+ * @param height the height
|
|
+ * @return true from the proof height
|
|
+ */
|
|
+ boolean provable(long height);
|
|
+
|
|
+ /**
|
|
+ * Move D onto the durable floor's block when it is stored again (the decided head's own record).
|
|
+ *
|
|
+ * @return what the decided head did (UNCHANGED when there is no floor)
|
|
+ */
|
|
+ AereDecidedHead.Outcome resolveFloor();
|
|
+
|
|
+ /**
|
|
+ * The decided head D.
|
|
+ *
|
|
+ * @return D
|
|
+ */
|
|
+ AereDecidedHead.Decided decided();
|
|
+
|
|
+ /**
|
|
+ * A stored block by its on-chain hash.
|
|
+ *
|
|
+ * @param onchainHash the on-chain hash
|
|
+ * @return the block, or empty when it is not stored
|
|
+ */
|
|
+ Optional<QbftBlock> storedBlock(Hash onchainHash);
|
|
+
|
|
+ /**
|
|
+ * The hash of the canonical block at a height.
|
|
+ *
|
|
+ * @param height the height
|
|
+ * @return the hash, or empty
|
|
+ */
|
|
+ Optional<Hash> canonicalHash(long height);
|
|
+
|
|
+ /**
|
|
+ * The canonical head's height.
|
|
+ *
|
|
+ * @return the height
|
|
+ */
|
|
+ long canonicalHeadNumber();
|
|
+
|
|
+ /**
|
|
+ * The validators after the block with this on-chain hash (the set that decides its child).
|
|
+ *
|
|
+ * @param onchainHash the on-chain hash
|
|
+ * @return the set, or empty when the block is unknown
|
|
+ */
|
|
+ Optional<Collection<Address>> validatorsAfter(Hash onchainHash);
|
|
+
|
|
+ /**
|
|
+ * The validators at the canonical head.
|
|
+ *
|
|
+ * @return the set
|
|
+ */
|
|
+ Collection<Address> validatorsAtHead();
|
|
+
|
|
+ /**
|
|
+ * The validators that decide the canonical block at a height (the set after its parent).
|
|
+ *
|
|
+ * @param height a height at or below D
|
|
+ * @return the set, or empty when there is no canonical block there
|
|
+ */
|
|
+ Optional<Collection<Address>> validatorsDeciding(long height);
|
|
+
|
|
+ /**
|
|
+ * Move D onto a stored block decided by a proof.
|
|
+ *
|
|
+ * @param onchainHash the on-chain hash of the decided block
|
|
+ * @param proof the kind of proof
|
|
+ * @return what the decided head did
|
|
+ */
|
|
+ AereDecidedHead.Outcome advance(Hash onchainHash, AereDecidedHead.Proof proof);
|
|
+
|
|
+ /**
|
|
+ * Whether a height is an anchor height (a certificate belongs in its block).
|
|
+ *
|
|
+ * @param height the height
|
|
+ * @return true at an anchor height
|
|
+ */
|
|
+ boolean anchorHeight(long height);
|
|
+
|
|
+ /**
|
|
+ * The block a stored anchor's certificate proves decided (AereCertifiedDecision, the one place;
|
|
+ * teza Q3, 2026-10-01): below H_hdr its parent, from H_hdr its GRANDPARENT with f + 1 re-verified
|
|
+ * seals of distinct members, empty when it proves nothing.
|
|
+ *
|
|
+ * @param onchainHash the on-chain hash of a stored block
|
|
+ * @return the block its certificate proves decided, or empty
|
|
+ */
|
|
+ Optional<AereDecidedHead.Decided> certifiedDecision(Hash onchainHash);
|
|
+
|
|
+ /**
|
|
+ * Send a message to every validator, WITHOUT the send-once filter of the gossip multicaster (the
|
|
+ * echo re-sends messages this node already gossiped).
|
|
+ *
|
|
+ * @param message the message
|
|
+ */
|
|
+ void multicast(MessageData message);
|
|
+
|
|
+ /**
|
|
+ * The clock of the echo rate limit.
|
|
+ *
|
|
+ * @return milliseconds
|
|
+ */
|
|
+ long nowMillis();
|
|
+ }
|
|
+
|
|
+ /** A raw message kept for the replay, with its author and the bytes charged for it. */
|
|
+ private static final class Raw {
|
|
+ private final QbftMessage message;
|
|
+ private final Address author;
|
|
+ private final long bytes;
|
|
+
|
|
+ Raw(final QbftMessage message, final Address author, final long bytes) {
|
|
+ this.message = message;
|
|
+ this.author = author;
|
|
+ this.bytes = bytes;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private final Chain chain;
|
|
+ private final QbftBlockInterface blockInterface;
|
|
+ private final AereDecisionEvidence evidence;
|
|
+ private final Executor executor;
|
|
+ private final int window;
|
|
+
|
|
+ // height -> fingerprint of the raw message data -> raw message, in the order heard
|
|
+ private final TreeMap<Long, LinkedHashMap<Hash, Raw>> raw = new TreeMap<>();
|
|
+ private final Map<Address, Long> rawBytesByAuthor = new HashMap<>();
|
|
+ private long rawBytes;
|
|
+ // height -> on-chain hashes of blocks heard (admitted by the collector) and parents of heard blocks
|
|
+ private final NavigableMap<Long, Set<Hash>> heard = new TreeMap<>();
|
|
+ // height -> on-chain hashes of blocks stored (canonical, fork, reorg) and parents of stored blocks
|
|
+ private final NavigableMap<Long, Set<Hash>> stored = new TreeMap<>();
|
|
+ // height -> this node's own commits, waiting for its own round to commit
|
|
+ private final TreeMap<Long, List<Commit>> ownCommits = new TreeMap<>();
|
|
+ // author -> last echo time
|
|
+ private final LinkedHashMap<Address, Long> lastEcho = new LinkedHashMap<>();
|
|
+
|
|
+ private final AtomicBoolean evaluationScheduled = new AtomicBoolean();
|
|
+ private final AtomicLong evaluations = new AtomicLong();
|
|
+ private final AtomicLong advances = new AtomicLong();
|
|
+ private final AtomicLong echoes = new AtomicLong();
|
|
+ private final AtomicLong echoesWithoutProof = new AtomicLong();
|
|
+ private final AtomicLong replayed = new AtomicLong();
|
|
+ private final AtomicLong rawRefused = new AtomicLong();
|
|
+ private final AtomicLong ownCommitsNotCounted = new AtomicLong();
|
|
+ private final AtomicLong failures = new AtomicLong();
|
|
+
|
|
+ /**
|
|
+ * The wiring of one validator.
|
|
+ *
|
|
+ * @param chain the node's chain, decided head, sets and network
|
|
+ * @param blockInterface replaces the round of a block (digest_r and the on-chain hash)
|
|
+ * @param enforcement the node's PQ commit enforcement, or null for upstream behaviour
|
|
+ * @param verifierGeneration changes whenever the registry the enforcement reads may have changed
|
|
+ * @param sizeOf the bytes a proposed block is charged in the collector
|
|
+ * @param executor where evaluations and advances run (a single thread, never the QBFT thread)
|
|
+ * @param window W
|
|
+ */
|
|
+ public AereDecidedConsensus(
|
|
+ final Chain chain,
|
|
+ final QbftBlockInterface blockInterface,
|
|
+ final PqCommitEnforcement enforcement,
|
|
+ final LongSupplier verifierGeneration,
|
|
+ final ToLongFunction<QbftBlock> sizeOf,
|
|
+ final Executor executor,
|
|
+ final int window) {
|
|
+ this.chain = Objects.requireNonNull(chain, "chain");
|
|
+ this.blockInterface = Objects.requireNonNull(blockInterface, "blockInterface");
|
|
+ this.executor = Objects.requireNonNull(executor, "executor");
|
|
+ if (window < 1) {
|
|
+ throw new IllegalArgumentException("AERE-D412-WIRING-CONF-01: window must be >= 1");
|
|
+ }
|
|
+ this.window = window;
|
|
+ this.evidence =
|
|
+ new AereDecisionEvidence(
|
|
+ blockInterface,
|
|
+ new AereDecisionEvidence.ValidatorSets() {
|
|
+ @Override
|
|
+ public Optional<Collection<Address>> afterBlock(final Hash onchainHash) {
|
|
+ return chain.validatorsAfter(onchainHash);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Collection<Address> admission(final long height) {
|
|
+ return admissionSet();
|
|
+ }
|
|
+ },
|
|
+ enforcement,
|
|
+ verifierGeneration,
|
|
+ sizeOf,
|
|
+ chain.decided().number(),
|
|
+ window);
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // the hook
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Override
|
|
+ public void observe(final BftMessage<?> message, final QbftMessage rawMessage) {
|
|
+ try {
|
|
+ final long n = message.getRoundIdentifier().getSequenceNumber();
|
|
+ if (!chain.provable(n)) {
|
|
+ return;
|
|
+ }
|
|
+ final long d = syncCollector();
|
|
+ if (!admits(n, d)) {
|
|
+ return;
|
|
+ }
|
|
+ final Address author = message.getAuthor();
|
|
+ // the raw store feeds only the replay, which runs from H_ev (where rule D starts heights); the
|
|
+ // proof height H_ev - 1 is still started the upstream way and nothing is replayed into it
|
|
+ if (chain.active(n) && admissionSet().contains(author)) {
|
|
+ keepRaw(n, author, rawMessage);
|
|
+ }
|
|
+ if (message instanceof Commit commit) {
|
|
+ evidence.observeCommit(commit);
|
|
+ } else if (message instanceof Proposal proposal) {
|
|
+ if (evidence.observeProposal(proposal)) {
|
|
+ rememberHeard(proposal.getBlock());
|
|
+ }
|
|
+ } else if (message instanceof RoundChange roundChange) {
|
|
+ final Optional<QbftBlock> prepared = roundChange.getProposedBlock();
|
|
+ if (prepared.isPresent()
|
|
+ && prepared.get().getHeader().getNumber() == n
|
|
+ && evidence.observeProposedBlock(author, prepared.get(), Optional.empty())) {
|
|
+ rememberHeard(prepared.get());
|
|
+ }
|
|
+ }
|
|
+ scheduleEvaluation();
|
|
+ } catch (final RuntimeException e) {
|
|
+ failed("observe", e);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void echoIfRoundChange(final BftMessage<?> message) {
|
|
+ try {
|
|
+ if (!(message instanceof RoundChange)) {
|
|
+ return;
|
|
+ }
|
|
+ final long n = message.getRoundIdentifier().getSequenceNumber();
|
|
+ if (!chain.provable(n)) {
|
|
+ return;
|
|
+ }
|
|
+ final long d = syncCollector();
|
|
+ if (n > d || n < d - window) {
|
|
+ return;
|
|
+ }
|
|
+ final Address author = message.getAuthor();
|
|
+ final Optional<Collection<Address>> set = chain.validatorsDeciding(n);
|
|
+ if (set.isEmpty() || !set.get().contains(author)) {
|
|
+ return;
|
|
+ }
|
|
+ final long now = chain.nowMillis();
|
|
+ synchronized (lastEcho) {
|
|
+ final Long last = lastEcho.get(author);
|
|
+ if (last != null && now - last < ECHO_INTERVAL_MILLIS) {
|
|
+ return;
|
|
+ }
|
|
+ lastEcho.remove(author);
|
|
+ lastEcho.put(author, now);
|
|
+ while (lastEcho.size() > MAX_ECHO_MARKS) {
|
|
+ lastEcho.remove(lastEcho.keySet().iterator().next());
|
|
+ }
|
|
+ }
|
|
+ final Optional<AereDecisionEvidence.Proof> proof = evidence.retainedProof(n);
|
|
+ if (proof.isEmpty()) {
|
|
+ echoesWithoutProof.incrementAndGet();
|
|
+ LOG.debug("AERE D-412 echo: RoundChange at decided height {} from {}, no retained proof", n, author);
|
|
+ return;
|
|
+ }
|
|
+ for (final Commit c : proof.get().commits()) {
|
|
+ chain.multicast(CommitMessageData.create(c));
|
|
+ }
|
|
+ proof.get().childProposal().ifPresent(p -> chain.multicast(ProposalMessageData.create(p)));
|
|
+ echoes.incrementAndGet();
|
|
+ LOG.debug(
|
|
+ "AERE D-412 echo: RoundChange at decided height {} from {}; re-sent {} commit(s) of the {} proof",
|
|
+ n,
|
|
+ author,
|
|
+ proof.get().commits().size(),
|
|
+ proof.get().kind());
|
|
+ } catch (final RuntimeException e) {
|
|
+ failed("echo", e);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean ignoresNewHead(final QbftBlockHeader header) {
|
|
+ try {
|
|
+ final AereDecidedHead.Decided d = chain.decided();
|
|
+ // from the proof height on, only D starts a height: a canonical block at H_ev - 1 that no proof
|
|
+ // decided must not start H_ev (2026-10-01, review of step 3)
|
|
+ if (!chain.provable(d.number() + 1)) {
|
|
+ return false;
|
|
+ }
|
|
+ return !header.getHash().equals(d.hash());
|
|
+ } catch (final RuntimeException e) {
|
|
+ failed("new head", e);
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public List<QbftMessage> replay(final long height, final List<QbftMessage> alreadyReplayed) {
|
|
+ try {
|
|
+ if (!chain.active(height)) {
|
|
+ return List.of();
|
|
+ }
|
|
+ final LinkedHashMap<Hash, Raw> kept;
|
|
+ synchronized (raw) {
|
|
+ kept = raw.remove(height);
|
|
+ dropRawAtOrBelow(height - 1);
|
|
+ recountRaw();
|
|
+ }
|
|
+ if (kept == null || kept.isEmpty()) {
|
|
+ return List.of();
|
|
+ }
|
|
+ final Set<Hash> seen = new HashSet<>();
|
|
+ for (final QbftMessage m : alreadyReplayed) {
|
|
+ seen.add(fingerprint(m));
|
|
+ }
|
|
+ final List<QbftMessage> out = new ArrayList<>();
|
|
+ for (final Map.Entry<Hash, Raw> e : kept.entrySet()) {
|
|
+ if (!seen.contains(e.getKey())) {
|
|
+ out.add(e.getValue().message);
|
|
+ }
|
|
+ }
|
|
+ replayed.addAndGet(out.size());
|
|
+ return out;
|
|
+ } catch (final RuntimeException e) {
|
|
+ failed("replay", e);
|
|
+ return List.of();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void ownCommit(final Commit localCommit) {
|
|
+ try {
|
|
+ final long n = localCommit.getRoundIdentifier().getSequenceNumber();
|
|
+ if (!chain.provable(n) || n <= chain.decided().number()) {
|
|
+ return;
|
|
+ }
|
|
+ synchronized (ownCommits) {
|
|
+ final List<Commit> mine = ownCommits.computeIfAbsent(n, k -> new ArrayList<>());
|
|
+ if (mine.size() < MAX_OWN_COMMITS_PER_HEIGHT) {
|
|
+ mine.add(localCommit);
|
|
+ }
|
|
+ while (ownCommits.size() > window) {
|
|
+ ownCommits.pollFirstEntry();
|
|
+ }
|
|
+ }
|
|
+ } catch (final RuntimeException e) {
|
|
+ failed("own commit", e);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void ownRoundDecided(final QbftBlock imported, final int round) {
|
|
+ try {
|
|
+ final long n = imported.getHeader().getNumber();
|
|
+ if (!chain.provable(n)) {
|
|
+ return;
|
|
+ }
|
|
+ final Hash hash = imported.getHash();
|
|
+ // only the own commit of the round that COMMITTED, on this very block (digest_r of the imported
|
|
+ // block at that round), becomes a vote. The commits of earlier rounds in which the node accepted
|
|
+ // a proposal were created at the proposal but sent only if the node got prepared; counting them
|
|
+ // would give the collector a quorum that never existed on the network (2026-09-30, review).
|
|
+ final List<Commit> mine = new ArrayList<>();
|
|
+ synchronized (ownCommits) {
|
|
+ final List<Commit> kept = ownCommits.remove(n);
|
|
+ if (kept != null) {
|
|
+ for (final Commit c : kept) {
|
|
+ if (isVoteOfOwnDecision(blockInterface, c, imported, round)) {
|
|
+ mine.add(c);
|
|
+ } else {
|
|
+ ownCommitsNotCounted.incrementAndGet();
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ executor.execute(() -> decideOwnRound(n, hash, mine));
|
|
+ } catch (final RuntimeException e) {
|
|
+ failed("own round", e);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Whether an own commit, kept aside when the node accepted a proposal, is a vote of the decision
|
|
+ * of the node's own round: it targets the imported block's height, it is of the round that
|
|
+ * COMMITTED, and its digest is digest_r of the imported block at that round (the digest every
|
|
+ * commit of that round carries). The ONE place this is decided (2026-10-01): {@link
|
|
+ * #ownRoundDecided} keeps exactly the commits it accepts, and the proof that runs the REAL round
|
|
+ * (AereD412RoundHookTest) asks it about the round's own commit, imported block and round, so the
|
|
+ * filter is measured on production objects, not on a fixture built the way the filter presumes.
|
|
+ *
|
|
+ * @param blockInterface replaces the round of a block
|
|
+ * @param ownCommit an own commit kept aside
|
|
+ * @param imported the imported (sealed) block
|
|
+ * @param round the round that committed it
|
|
+ * @return true when the commit is a vote of this decision
|
|
+ */
|
|
+ public static boolean isVoteOfOwnDecision(
|
|
+ final QbftBlockInterface blockInterface,
|
|
+ final Commit ownCommit,
|
|
+ final QbftBlock imported,
|
|
+ final int round) {
|
|
+ final long n = imported.getHeader().getNumber();
|
|
+ return ownCommit.getRoundIdentifier().getSequenceNumber() == n
|
|
+ && ownCommit.getRoundIdentifier().getRoundNumber() == round
|
|
+ && ownCommit
|
|
+ .getDigest()
|
|
+ .equals(AereVoteCounts.Target.atRound(blockInterface, imported, n, round).digest());
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // the chain side
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /**
|
|
+ * A block was stored (canonical, a fork, or by a reorg): remember it and schedule an evaluation.
|
|
+ *
|
|
+ * @param onchainHash its on-chain hash
|
|
+ * @param number its height
|
|
+ * @param parentHash its parent's on-chain hash
|
|
+ */
|
|
+ public void blockStored(final Hash onchainHash, final long number, final Hash parentHash) {
|
|
+ try {
|
|
+ if (!chain.provable(number)) {
|
|
+ return;
|
|
+ }
|
|
+ addCandidate(stored, MAX_STORED_CANDIDATES_PER_HEIGHT, number, onchainHash);
|
|
+ if (parentHash != null) {
|
|
+ addCandidate(stored, MAX_STORED_CANDIDATES_PER_HEIGHT, number - 1, parentHash);
|
|
+ }
|
|
+ scheduleEvaluation();
|
|
+ } catch (final RuntimeException e) {
|
|
+ failed("block stored", e);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Evaluate now, on the calling thread (the executor runs exactly this).
|
|
+ *
|
|
+ * @return how many times D moved
|
|
+ */
|
|
+ public int evaluate() {
|
|
+ evaluationScheduled.set(false);
|
|
+ evaluations.incrementAndGet();
|
|
+ int moved = 0;
|
|
+ try {
|
|
+ for (int pass = 0; pass < 2 * window; pass++) {
|
|
+ if (!advanceOnce()) {
|
|
+ break;
|
|
+ }
|
|
+ moved++;
|
|
+ }
|
|
+ } catch (final RuntimeException e) {
|
|
+ failed("evaluate", e);
|
|
+ }
|
|
+ return moved;
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // measurements
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /**
|
|
+ * The collector (for the proofs and the log).
|
|
+ *
|
|
+ * @return the collector
|
|
+ */
|
|
+ public AereDecisionEvidence evidence() {
|
|
+ return evidence;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many evaluations ran.
|
|
+ *
|
|
+ * @return the count
|
|
+ */
|
|
+ public long evaluations() {
|
|
+ return evaluations.get();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many times this wiring moved D.
|
|
+ *
|
|
+ * @return the count
|
|
+ */
|
|
+ public long advances() {
|
|
+ return advances.get();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many echoes were sent.
|
|
+ *
|
|
+ * @return the count
|
|
+ */
|
|
+ public long echoes() {
|
|
+ return echoes.get();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many echo requests found no retained proof.
|
|
+ *
|
|
+ * @return the count
|
|
+ */
|
|
+ public long echoesWithoutProof() {
|
|
+ return echoesWithoutProof.get();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many messages were replayed from the raw store.
|
|
+ *
|
|
+ * @return the count
|
|
+ */
|
|
+ public long replayed() {
|
|
+ return replayed.get();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many raw messages of validators were not kept because a bound was reached.
|
|
+ *
|
|
+ * @return the count
|
|
+ */
|
|
+ public long rawRefused() {
|
|
+ return rawRefused.get();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many own commits were dropped at a decision because they were not of the committing round
|
|
+ * on the imported block.
|
|
+ *
|
|
+ * @return the count
|
|
+ */
|
|
+ public long ownCommitsNotCounted() {
|
|
+ return ownCommitsNotCounted.get();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many hook calls failed (and fell back to upstream behaviour).
|
|
+ *
|
|
+ * @return the count
|
|
+ */
|
|
+ public long failures() {
|
|
+ return failures.get();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The raw messages kept for a height.
|
|
+ *
|
|
+ * @param height the height
|
|
+ * @return how many
|
|
+ */
|
|
+ public int rawAt(final long height) {
|
|
+ synchronized (raw) {
|
|
+ final LinkedHashMap<Hash, Raw> m = raw.get(height);
|
|
+ return m == null ? 0 : m.size();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The bytes of raw messages kept for one author.
|
|
+ *
|
|
+ * @param author the author
|
|
+ * @return the bytes
|
|
+ */
|
|
+ public long rawBytesOf(final Address author) {
|
|
+ synchronized (raw) {
|
|
+ return rawBytesByAuthor.getOrDefault(author, 0L);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // internals
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /** The authors whose messages are kept at all: the set at the head and the set after D. */
|
|
+ private Collection<Address> admissionSet() {
|
|
+ final Set<Address> out = new LinkedHashSet<>(chain.validatorsAtHead());
|
|
+ chain.validatorsAfter(chain.decided().hash()).ifPresent(out::addAll);
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ private void scheduleEvaluation() {
|
|
+ if (evaluationScheduled.compareAndSet(false, true)) {
|
|
+ executor.execute(this::evaluate);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private void decideOwnRound(final long n, final Hash hash, final List<Commit> mine) {
|
|
+ try {
|
|
+ syncCollector();
|
|
+ for (final Commit c : mine) {
|
|
+ evidence.observeCommit(c);
|
|
+ }
|
|
+ final Optional<QbftBlock> storedBlock = chain.storedBlock(hash);
|
|
+ final Optional<AereDecisionEvidence.Proof> proof = storedBlock.flatMap(evidence::quorumFor);
|
|
+ final AereDecidedHead.Outcome outcome = chain.advance(hash, AereDecidedHead.Proof.Q1);
|
|
+ if (outcome == AereDecidedHead.Outcome.ADVANCED) {
|
|
+ advances.incrementAndGet();
|
|
+ if (proof.isPresent()) {
|
|
+ evidence.markDecided(proof.get());
|
|
+ } else {
|
|
+ evidence.markDecidedHeight(n);
|
|
+ }
|
|
+ trim(n);
|
|
+ }
|
|
+ LOG.debug(
|
|
+ "AERE D-412: own round decided {} ({}); D {} ({}, collector proof {})",
|
|
+ n,
|
|
+ hash,
|
|
+ outcome == AereDecidedHead.Outcome.ADVANCED ? "moved" : "did not move",
|
|
+ outcome,
|
|
+ proof.isPresent() ? "retained" : "absent");
|
|
+ scheduleEvaluation();
|
|
+ } catch (final RuntimeException e) {
|
|
+ failed("own round", e);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /** One pass: the lowest block of the window that a proof decides moves D. */
|
|
+ private boolean advanceOnce() {
|
|
+ // the durable floor (a decision this node wrote and whose block it lost at a restart): D goes onto
|
|
+ // it as soon as its block is stored again (2026-10-01, review of step 3)
|
|
+ if (chain.resolveFloor() == AereDecidedHead.Outcome.ADVANCED) {
|
|
+ advances.incrementAndGet();
|
|
+ return true;
|
|
+ }
|
|
+ final long d = syncCollector();
|
|
+ trim(d);
|
|
+ final long top = Math.min(d + window, Math.max(chain.canonicalHeadNumber(), d));
|
|
+ final TreeSet<Long> heights = new TreeSet<>();
|
|
+ for (final long h : evidence.heights()) {
|
|
+ if (h > d && h <= d + window) {
|
|
+ heights.add(h);
|
|
+ if (h - 1 > d) {
|
|
+ heights.add(h - 1);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ for (final NavigableMap<Long, Set<Hash>> known : List.of(heard, stored)) {
|
|
+ synchronized (known) {
|
|
+ for (final long h : known.keySet()) {
|
|
+ if (h > d && h <= d + window) {
|
|
+ heights.add(h);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ for (long h = d + 1; h <= top; h++) {
|
|
+ if (chain.anchorHeight(h)) {
|
|
+ heights.add(h);
|
|
+ }
|
|
+ }
|
|
+ for (final long n : heights) {
|
|
+ for (final Hash hash : blocksAt(n)) {
|
|
+ final Optional<QbftBlock> b = chain.storedBlock(hash);
|
|
+ if (b.isEmpty() || b.get().getHeader().getNumber() != n) {
|
|
+ continue;
|
|
+ }
|
|
+ final Optional<AereDecisionEvidence.Proof> q1 = evidence.quorumFor(b.get());
|
|
+ if (q1.isPresent() && moved(hash, AereDecidedHead.Proof.Q1, Optional.of(q1.get()), n)) {
|
|
+ return true;
|
|
+ }
|
|
+ final Optional<AereDecisionEvidence.Proof> q2 =
|
|
+ evidence.childProofFor(b.get(), storedChildren(b.get(), n));
|
|
+ if (q2.isPresent() && moved(hash, AereDecidedHead.Proof.Q2, Optional.of(q2.get()), n)) {
|
|
+ return true;
|
|
+ }
|
|
+ if (chain.anchorHeight(n)) {
|
|
+ // AERE-Q3-BUNIC (teza Q3, D-470, 2026-10-01): the certificate's seals carry no round, so from H_hdr they prove the
|
|
+ // anchor's GRANDPARENT, never its parent; the answer comes from ONE place (AereCertifiedDecision), shared with
|
|
+ // the finalized tags (B1) and the restart
|
|
+ final Optional<AereDecidedHead.Decided> byCertificate = chain.certifiedDecision(hash);
|
|
+ if (byCertificate.isPresent()
|
|
+ && byCertificate.get().number() > d
|
|
+ && moved(
|
|
+ byCertificate.get().hash(),
|
|
+ AereDecidedHead.Proof.Q3,
|
|
+ Optional.empty(),
|
|
+ byCertificate.get().number())) {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ // the LIVE heights beyond the window (D more than W behind the canonical head): a full quorum of
|
|
+ // one round (Q1) only, the highest height first; the move still needs the block to descend from D
|
|
+ final long cap = chain.canonicalHeadNumber();
|
|
+ final long lowestLive = Math.max(d + window + 1, cap - AereDecisionEvidence.LIVE_BELOW);
|
|
+ for (long n = cap + AereDecisionEvidence.LIVE_ABOVE; n >= lowestLive; n--) {
|
|
+ for (final Hash hash : blocksAt(n)) {
|
|
+ final Optional<QbftBlock> b = chain.storedBlock(hash);
|
|
+ if (b.isEmpty() || b.get().getHeader().getNumber() != n) {
|
|
+ continue;
|
|
+ }
|
|
+ final Optional<AereDecisionEvidence.Proof> q1 = evidence.quorumFor(b.get());
|
|
+ if (q1.isPresent() && moved(hash, AereDecidedHead.Proof.Q1, Optional.of(q1.get()), n)) {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The ONE source of D for the collector (2026-09-30, review of step 3): D is read from the chain at
|
|
+ * every call and handed to the collector, so a D that moved without the wiring (below H_ev the
|
|
+ * canonical head capped at H_ev - 1, Q5) is followed, and the live heights follow the canonical
|
|
+ * head. What falls between the window and the live heights is dropped.
|
|
+ *
|
|
+ * @return D's height
|
|
+ */
|
|
+ private long syncCollector() {
|
|
+ final long d = chain.decided().number();
|
|
+ evidence.markDecidedHeight(d);
|
|
+ final long cap = chain.canonicalHeadNumber();
|
|
+ evidence.followLiveHead(cap);
|
|
+ trimStaleLive(d, cap);
|
|
+ return d;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The heights the wiring admits: (D, D + W], and the LIVE heights around the canonical head beyond
|
|
+ * it (judged for Q1 only).
|
|
+ */
|
|
+ private boolean admits(final long n, final long d) {
|
|
+ if (n <= d) {
|
|
+ return false;
|
|
+ }
|
|
+ if (n <= d + window) {
|
|
+ return true;
|
|
+ }
|
|
+ final long cap = chain.canonicalHeadNumber();
|
|
+ return n >= cap - AereDecisionEvidence.LIVE_BELOW && n <= cap + AereDecisionEvidence.LIVE_ABOVE;
|
|
+ }
|
|
+
|
|
+ /** Drop the raw messages and candidates of heights above the window and below the live heights. */
|
|
+ private void trimStaleLive(final long d, final long cap) {
|
|
+ final long from = d + window;
|
|
+ final long to = cap - AereDecisionEvidence.LIVE_BELOW;
|
|
+ if (to <= from + 1) {
|
|
+ return;
|
|
+ }
|
|
+ synchronized (raw) {
|
|
+ final NavigableMap<Long, LinkedHashMap<Hash, Raw>> stale = raw.subMap(from, false, to, false);
|
|
+ if (!stale.isEmpty()) {
|
|
+ stale.clear();
|
|
+ recountRaw();
|
|
+ }
|
|
+ }
|
|
+ for (final NavigableMap<Long, Set<Hash>> known : List.of(heard, stored)) {
|
|
+ synchronized (known) {
|
|
+ known.subMap(from, false, to, false).clear();
|
|
+ }
|
|
+ }
|
|
+ synchronized (ownCommits) {
|
|
+ ownCommits.subMap(from, false, to, false).clear();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private boolean moved(
|
|
+ final Hash hash,
|
|
+ final AereDecidedHead.Proof kind,
|
|
+ final Optional<AereDecisionEvidence.Proof> proof,
|
|
+ final long height) {
|
|
+ final AereDecidedHead.Outcome outcome = chain.advance(hash, kind);
|
|
+ if (outcome != AereDecidedHead.Outcome.ADVANCED) {
|
|
+ return false;
|
|
+ }
|
|
+ advances.incrementAndGet();
|
|
+ if (proof.isPresent()) {
|
|
+ evidence.markDecided(proof.get());
|
|
+ } else {
|
|
+ evidence.markDecidedHeight(height);
|
|
+ }
|
|
+ trim(height);
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ private List<Hash> blocksAt(final long n) {
|
|
+ final LinkedHashSet<Hash> out = new LinkedHashSet<>();
|
|
+ chain.canonicalHash(n).ifPresent(out::add);
|
|
+ for (final NavigableMap<Long, Set<Hash>> known : List.of(heard, stored)) {
|
|
+ synchronized (known) {
|
|
+ final Set<Hash> at = known.get(n);
|
|
+ if (at != null) {
|
|
+ out.addAll(at);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return new ArrayList<>(out);
|
|
+ }
|
|
+
|
|
+ private List<QbftBlock> storedChildren(final QbftBlock b, final long n) {
|
|
+ final Hash onchainB = onchainOf(b);
|
|
+ final List<QbftBlock> out = new ArrayList<>();
|
|
+ for (final Hash h : blocksAt(n + 1)) {
|
|
+ final Optional<QbftBlock> c = chain.storedBlock(h);
|
|
+ if (c.isPresent() && onchainB.equals(c.get().getHeader().getParentHash())) {
|
|
+ out.add(c.get());
|
|
+ }
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ private void rememberHeard(final QbftBlock block) {
|
|
+ final long n = block.getHeader().getNumber();
|
|
+ addCandidate(heard, MAX_HEARD_CANDIDATES_PER_HEIGHT, n, onchainOf(block));
|
|
+ final Hash parent = block.getHeader().getParentHash();
|
|
+ if (parent != null) {
|
|
+ addCandidate(heard, MAX_HEARD_CANDIDATES_PER_HEIGHT, n - 1, parent);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private void addCandidate(
|
|
+ final NavigableMap<Long, Set<Hash>> known, final int cap, final long n, final Hash hash) {
|
|
+ if (!admits(n, chain.decided().number())) {
|
|
+ return;
|
|
+ }
|
|
+ synchronized (known) {
|
|
+ final Set<Hash> at = known.computeIfAbsent(n, k -> new LinkedHashSet<>());
|
|
+ if (at.size() < cap) {
|
|
+ at.add(hash);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private void keepRaw(final long n, final Address author, final QbftMessage message) {
|
|
+ final Hash fp = fingerprint(message);
|
|
+ final long size = message.getData().getSize();
|
|
+ synchronized (raw) {
|
|
+ final LinkedHashMap<Hash, Raw> at = raw.computeIfAbsent(n, k -> new LinkedHashMap<>());
|
|
+ if (at.containsKey(fp)) {
|
|
+ return;
|
|
+ }
|
|
+ int ofAuthor = 0;
|
|
+ for (final Raw r : at.values()) {
|
|
+ if (r.author.equals(author)) {
|
|
+ ofAuthor++;
|
|
+ }
|
|
+ }
|
|
+ if (at.size() >= MAX_RAW_PER_HEIGHT
|
|
+ || ofAuthor >= MAX_RAW_PER_AUTHOR_HEIGHT
|
|
+ || rawBytesByAuthor.getOrDefault(author, 0L) + size > MAX_RAW_BYTES_PER_AUTHOR
|
|
+ || rawBytes + size > MAX_RAW_BYTES) {
|
|
+ rawRefused.incrementAndGet();
|
|
+ return;
|
|
+ }
|
|
+ at.put(fp, new Raw(message, author, size));
|
|
+ rawBytesByAuthor.merge(author, size, Long::sum);
|
|
+ rawBytes += size;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private void trim(final long d) {
|
|
+ synchronized (raw) {
|
|
+ dropRawAtOrBelow(d);
|
|
+ recountRaw();
|
|
+ }
|
|
+ for (final NavigableMap<Long, Set<Hash>> known : List.of(heard, stored)) {
|
|
+ synchronized (known) {
|
|
+ known.headMap(d, true).clear();
|
|
+ }
|
|
+ }
|
|
+ synchronized (ownCommits) {
|
|
+ ownCommits.headMap(d, true).clear();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private void dropRawAtOrBelow(final long height) {
|
|
+ raw.headMap(height, true).clear();
|
|
+ }
|
|
+
|
|
+ private void recountRaw() {
|
|
+ long total = 0;
|
|
+ rawBytesByAuthor.clear();
|
|
+ for (final LinkedHashMap<Hash, Raw> m : raw.values()) {
|
|
+ for (final Raw r : m.values()) {
|
|
+ total += r.bytes;
|
|
+ rawBytesByAuthor.merge(r.author, r.bytes, Long::sum);
|
|
+ }
|
|
+ }
|
|
+ rawBytes = total;
|
|
+ }
|
|
+
|
|
+ private Hash onchainOf(final QbftBlock block) {
|
|
+ return blockInterface.replaceRoundForCommitBlock(block, 0).getHash();
|
|
+ }
|
|
+
|
|
+ private static Hash fingerprint(final QbftMessage message) {
|
|
+ final MessageData data = message.getData();
|
|
+ return Hash.hash(Bytes.concatenate(Bytes.ofUnsignedInt(data.getCode()), data.getData()));
|
|
+ }
|
|
+
|
|
+ private void failed(final String where, final RuntimeException e) {
|
|
+ final long n = failures.incrementAndGet();
|
|
+ LOG.warn(
|
|
+ "AERE D-412 wiring: {} failed ({}); upstream behaviour for this call (failure {})",
|
|
+ where,
|
|
+ e.toString(),
|
|
+ n);
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereDecidedHook.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereDecidedHook.java
|
|
new file mode 100644
|
|
index 0000000000..842dbf3a55
|
|
--- /dev/null
|
|
+++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereDecidedHook.java
|
|
@@ -0,0 +1,130 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft.core.statemachine;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.messagewrappers.BftMessage;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockHeader;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftMessage;
|
|
+
|
|
+import java.util.List;
|
|
+import java.util.Objects;
|
|
+
|
|
+/**
|
|
+ * AERE D-412 / the DECIDED HEAD (rule D), step 3 of PROIECT-CAP-DECIS-2026-09-29.md: the one place
|
|
+ * through which the upstream QBFT state machine ({@code QbftController}, {@code QbftRound}) reaches
|
|
+ * rule D. The overlay copies of {@code QbftController} and {@code QbftRound} carry one call per wiring
|
|
+ * point (since 2026-09-30; the patch that adds them refuses a tree whose
|
|
+ * controller or round lacks them); every call goes through {@link #current()}.
|
|
+ *
|
|
+ * <p>The hook installed by default is {@link #INERT}: every method does nothing, answers "no" and
|
|
+ * returns nothing, which is exactly the upstream behaviour. A node without rule D (a reader, a node
|
|
+ * with {@code aere.d412.hev} unset, every upstream test) never installs anything else. A validator with
|
|
+ * rule D installs {@link AereDecidedConsensus} at startup, once per process, the way the other AERE
|
|
+ * consensus singletons are process-wide ({@code PqSealCache.instance()},
|
|
+ * {@code PropagatedBlockAdoptionGate}).
|
|
+ *
|
|
+ * <p>An implementation must never throw into the state machine: a failure inside the hook is its own
|
|
+ * failure, logged and counted, and upstream processing continues.
|
|
+ */
|
|
+public abstract class AereDecidedHook {
|
|
+
|
|
+ /** The hook of a node without rule D: upstream behaviour. */
|
|
+ public static final AereDecidedHook INERT = new AereDecidedHook() {};
|
|
+
|
|
+ private static volatile AereDecidedHook current = INERT;
|
|
+
|
|
+ /** For subclasses. */
|
|
+ protected AereDecidedHook() {}
|
|
+
|
|
+ /**
|
|
+ * The hook this process uses.
|
|
+ *
|
|
+ * @return the installed hook, {@link #INERT} when none
|
|
+ */
|
|
+ public static AereDecidedHook current() {
|
|
+ return current;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Install the hook of this process.
|
|
+ *
|
|
+ * @param hook the hook
|
|
+ */
|
|
+ public static void install(final AereDecidedHook hook) {
|
|
+ current = Objects.requireNonNull(hook, "hook");
|
|
+ }
|
|
+
|
|
+ /** Back to {@link #INERT}. For tests and a deliberate reset. */
|
|
+ public static void reset() {
|
|
+ current = INERT;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * A consensus message was received, before any height guard or round filter looks at it.
|
|
+ *
|
|
+ * @param message the decoded message
|
|
+ * @param raw the raw message, for a later replay
|
|
+ */
|
|
+ public void observe(final BftMessage<?> message, final QbftMessage raw) {}
|
|
+
|
|
+ /**
|
|
+ * A message is being discarded because its height is at or below the head this node's consensus
|
|
+ * runs on. A RoundChange among them may be answered with the proof of that height.
|
|
+ *
|
|
+ * @param message the discarded message
|
|
+ */
|
|
+ public void echoIfRoundChange(final BftMessage<?> message) {}
|
|
+
|
|
+ /**
|
|
+ * Whether a new chain head must NOT start a new height: under rule D only the decided head does.
|
|
+ *
|
|
+ * @param header the header of the new chain head event
|
|
+ * @return true to ignore the event
|
|
+ */
|
|
+ public boolean ignoresNewHead(final QbftBlockHeader header) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Messages of a height the node just started, beyond what the future-message buffer returned.
|
|
+ *
|
|
+ * @param height the height just started
|
|
+ * @param alreadyReplayed what the future-message buffer already replayed for it
|
|
+ * @return the further messages to replay, in the order they were heard
|
|
+ */
|
|
+ public List<QbftMessage> replay(final long height, final List<QbftMessage> alreadyReplayed) {
|
|
+ return List.of();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * This node created its own Commit for a round (it becomes a vote only if the round commits).
|
|
+ *
|
|
+ * @param localCommit the local commit
|
|
+ */
|
|
+ public void ownCommit(final Commit localCommit) {}
|
|
+
|
|
+ /**
|
|
+ * This node's own round committed and its block was imported into the chain. The round is the
|
|
+ * round that COMMITTED: of the node's own commits kept aside, only the one of this round (on this
|
|
+ * block) becomes a vote; a commit of an earlier round in which the node accepted a proposal but was
|
|
+ * never prepared (so it never sent that commit) is never counted (2026-09-30, review of step 3).
|
|
+ *
|
|
+ * @param imported the imported (sealed) block
|
|
+ * @param round the round that committed it
|
|
+ */
|
|
+ public void ownRoundDecided(final QbftBlock imported, final int round) {}
|
|
+}
|
|
diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereDecisionEvidence.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereDecisionEvidence.java
|
|
new file mode 100644
|
|
index 0000000000..c4fe8e9faf
|
|
--- /dev/null
|
|
+++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereDecisionEvidence.java
|
|
@@ -0,0 +1,1257 @@
|
|
+/*
|
|
+ * AERE D-412 / capul decis (regula D), pasul 1: the DECISION-EVIDENCE COLLECTOR, a pure piece
|
|
+ * (nothing wires it into the controller yet; that is step 3 of PROIECT-CAP-DECIS-2026-09-29.md).
|
|
+ *
|
|
+ * WHAT IT DOES. It keeps, in memory and bounded, the Commit messages and the proposed blocks a
|
|
+ * validator hears for the heights just above its decided head D, and answers two questions about
|
|
+ * a stored block b at height n, each with the ONE counting predicate of the round
|
|
+ * (AereVoteCounts.judge):
|
|
+ * Q1 is there a round r with >= Q(set(b)) counted commits on digest_r(b), the message digest of
|
|
+ * b at round r (round included), where set(b) = validators after parent(b)? One round: votes
|
|
+ * of different rounds are never added together.
|
|
+ * Q2 is there a child c (c.parentHash == onchain(b), known from a heard proposal or a stored
|
|
+ * block) with >= f(set(c)) + 1 distinct authors of set(c) = validators after b, each with a
|
|
+ * counted commit at n+1 on c at ANY round?
|
|
+ * plus Q4 (an ancestor of a
|
|
+ * decided block, on the parentHash path, is decided), and it retains the raw messages of each proof
|
|
+ * over [D-W, D] for the echo. Q3 (what a certified anchor proves) is NOT judged here since 2026-10-01
|
|
+ * (teza Q3, D-470): it is AereCertifiedDecision's, the one place, read by the wiring, the finalized
|
|
+ * tags and the restart.
|
|
+ *
|
|
+ * STEP 3 CORRECTIONS (2026-09-30, adversarial review of the wiring): D is the one the wiring reads from
|
|
+ * the chain (markDecidedHeight at every call, so D moved below H_ev by the canonical head, Q5, is
|
|
+ * followed too), a proof is retained even when D already reached its height, and besides (D, D+W]
|
|
+ * the LIVE heights around the canonical head are admitted (LIVE_BELOW, LIVE_ABOVE), for a validator
|
|
+ * whose D fell more than W behind.
|
|
+ *
|
|
+ * WHAT IT MUST NOT DO, each one a property with its own proof and plant (AereDecisionEvidenceTest):
|
|
+ * - a commit takes a counted slot only AFTER it passed the predicate; the slot is the message's
|
|
+ * RECOVERED author, never the post-quantum index the message claims;
|
|
+ * - it never touches PqSealCache (no record, no disk, highestSeen untouched);
|
|
+ * - a message that has not been verified can never push out another one. From H_fin the author of
|
|
+ * a Commit is the id its seal index names when that id is the commit seal's signer, and the
|
|
+ * commit seal is recovered over the digest alone (AerePqFinality.authorFromSeal,
|
|
+ * CommitPayload.commitSealSigner): anybody holding a copy of A's commit seal can make messages
|
|
+ * "by A" with another round or a garbage post-quantum seal. So waiting messages are keyed by
|
|
+ * their FINGERPRINT (the hash of the signed message), never by (height, author, digest), and a
|
|
+ * message whose envelope is signed by the same ECDSA key as its commit seal (SELF, what Besu and
|
|
+ * Nethermind emit) has its own quota, which no FOREIGN-enveloped copy can fill;
|
|
+ * - it is bounded in work and in memory. Per (height, author, envelope class) at most
|
|
+ * MAX_PER_AUTHOR distinct (round, digest) pairs are admitted, and for each pair at most
|
|
+ * MAX_VARIANTS messages are EVER admitted: the count only grows, so a message refused for good
|
|
+ * keeps its place taken (2026-09-30, second review: counting only the messages still WAITING let
|
|
+ * a key buy one predicate run per fresh envelope on the same pair, since a refusal of the message
|
|
+ * removes it from waiting). Everything beyond is dropped BEFORE any round replacement or
|
|
+ * verification. So per (height, author) the predicate runs at most 2 * MAX_PER_AUTHOR *
|
|
+ * MAX_VARIANTS times per verifier generation, whatever the rounds and envelopes a key sends.
|
|
+ * What is NOT bounded by the collector is the cost of HEARING a message before its admission is
|
|
+ * decided: one encoding, one keccak, and, only while one of the two classes still has room for
|
|
+ * its (round, digest), the two ECDSA recoveries of the envelope class (counted by
|
|
+ * classifications()); that is a constant cost per message heard, bounded by the rate of the
|
|
+ * network, not by this class. Proposed blocks are kept whole (the echo re-sends the proposal)
|
|
+ * but charged in BYTES: per author over the window, in total, and per height in count;
|
|
+ * - each distinct message is verified once per registry state: the memo keeps a count and a
|
|
+ * refusal of the MESSAGE for good, but a refusal that depends on the registry (a late anchor
|
|
+ * still PENDING, D-358) only for the verifier generation it was made in, and such a message stays
|
|
+ * waiting (bounded) so a later generation can count it;
|
|
+ * - both digest keys are kept: the message digest (round included) under which the commit arrived,
|
|
+ * and the on-chain hash (round 0) of the block it was verified against, since Q1 looks up the
|
|
+ * first and Q2 the second.
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft.core.statemachine;
|
|
+
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockHeader;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.AereVoteCounts;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.PqCommitEnforcement;
|
|
+import org.hyperledger.besu.crypto.SECPSignature;
|
|
+import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.core.Util;
|
|
+import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput;
|
|
+import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
|
+
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collection;
|
|
+import java.util.HashMap;
|
|
+import java.util.LinkedHashMap;
|
|
+import java.util.LinkedHashSet;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Objects;
|
|
+import java.util.Optional;
|
|
+import java.util.Set;
|
|
+import java.util.TreeMap;
|
|
+import java.util.TreeSet;
|
|
+import java.util.function.Function;
|
|
+import java.util.function.LongSupplier;
|
|
+import java.util.function.ToLongFunction;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.slf4j.Logger;
|
|
+import org.slf4j.LoggerFactory;
|
|
+
|
|
+/** Bounded in-memory evidence that a stored block is decided (AERE D-412, regula D). */
|
|
+public final class AereDecisionEvidence {
|
|
+
|
|
+ private static final Logger LOG = LoggerFactory.getLogger(AereDecisionEvidence.class);
|
|
+
|
|
+ /** W = 2 * I_max: how far above the decided head evidence is kept, and below it for the echo. */
|
|
+ public static final int DEFAULT_WINDOW = 256;
|
|
+
|
|
+ /**
|
|
+ * Per (height, author, envelope class): at most this many distinct (round, digest) pairs admitted
|
|
+ * (everything beyond is dropped before any work). Per (height, author): at most this many counted
|
|
+ * digests. An honest author signs one commit per round in which it prepared.
|
|
+ */
|
|
+ public static final int MAX_PER_AUTHOR = 4;
|
|
+
|
|
+ /**
|
|
+ * Messages EVER admitted per (height, author, envelope class, round, digest); a refused message
|
|
+ * does not give its place back.
|
|
+ */
|
|
+ public static final int MAX_VARIANTS = 2;
|
|
+
|
|
+ /** At most this many proposed blocks per (height, author). */
|
|
+ public static final int MAX_PROPOSALS_PER_AUTHOR = 4;
|
|
+
|
|
+ /** At most this many proposed blocks per height, all authors together. */
|
|
+ public static final int MAX_PROPOSALS_PER_HEIGHT = 16;
|
|
+
|
|
+ /** Bytes of proposed blocks one author may hold across the whole window. */
|
|
+ public static final long MAX_PROPOSAL_BYTES_PER_AUTHOR = 16L * 1024 * 1024;
|
|
+
|
|
+ /** Bytes of proposed blocks held in total. */
|
|
+ public static final long MAX_PROPOSAL_BYTES = 64L * 1024 * 1024;
|
|
+
|
|
+ /** Bytes of the retained echo proofs (commits and child proposals) held in total. */
|
|
+ public static final long MAX_RETAINED_BYTES = 32L * 1024 * 1024;
|
|
+
|
|
+ /** Hard cap on waiting plus counted entries at one height, whatever the admission set says. */
|
|
+ public static final int MAX_PER_HEIGHT = 1024;
|
|
+
|
|
+ /** Capacity of the verification memo (least recently used entries are dropped). */
|
|
+ public static final int MEMO_CAPACITY = 8192;
|
|
+
|
|
+ /**
|
|
+ * The LIVE heights (2026-09-30, review of step 3): besides (D, D+W], the collector admits the
|
|
+ * heights [head - LIVE_BELOW, head + LIVE_ABOVE] around the canonical head, so a validator whose D
|
|
+ * fell more than W behind the chain (a stop longer than W blocks, a lost decided-head file, H_ev
|
|
+ * set in the past) can come back on a full quorum of the height being decided now, even when no
|
|
+ * certificate proves anything. The wiring judges those heights for Q1 only.
|
|
+ */
|
|
+ public static final int LIVE_BELOW = 2;
|
|
+
|
|
+ /** See {@link #LIVE_BELOW}. */
|
|
+ public static final int LIVE_ABOVE = 1;
|
|
+
|
|
+ private static final int SELF = 0;
|
|
+ private static final int FOREIGN = 1;
|
|
+ private static final long NOT_REFUSED = Long.MIN_VALUE;
|
|
+
|
|
+ /** The validator sets the collector judges with, supplied by the chain. */
|
|
+ public interface ValidatorSets {
|
|
+ /**
|
|
+ * The validators after the block with this ON-CHAIN hash, i.e. the set that decides its
|
|
+ * child. Empty while that block is not known to the node.
|
|
+ *
|
|
+ * @param onchainHash the on-chain hash (round 0) of a block
|
|
+ * @return the set, or empty when the block is unknown
|
|
+ */
|
|
+ Optional<Collection<Address>> afterBlock(Hash onchainHash);
|
|
+
|
|
+ /**
|
|
+ * The authors whose messages at {@code height} may even be buffered. Only a MEMORY filter: it
|
|
+ * never decides whether a vote counts (that is set(b), computed when the parent is known).
|
|
+ *
|
|
+ * @param height the height of the message
|
|
+ * @return the admissible authors
|
|
+ */
|
|
+ Collection<Address> admission(long height);
|
|
+ }
|
|
+
|
|
+ /** One counted vote: the commit, and the on-chain hash of the block it was verified against. */
|
|
+ public static final class Vote {
|
|
+ private final Commit commit;
|
|
+ private final Hash onchainHash;
|
|
+ private final Hash fingerprint;
|
|
+
|
|
+ Vote(final Commit commit, final Hash onchainHash, final Hash fingerprint) {
|
|
+ this.commit = commit;
|
|
+ this.onchainHash = onchainHash;
|
|
+ this.fingerprint = fingerprint;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The commit message.
|
|
+ *
|
|
+ * @return the commit
|
|
+ */
|
|
+ public Commit commit() {
|
|
+ return commit;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The on-chain hash (round 0) of the block this vote was verified against.
|
|
+ *
|
|
+ * @return the on-chain hash
|
|
+ */
|
|
+ public Hash onchainHash() {
|
|
+ return onchainHash;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /** A decision proof: which kind, for which block, and the raw messages that make it. */
|
|
+ public static final class Proof {
|
|
+ /** The kind of proof. */
|
|
+ public enum Kind {
|
|
+ /** Q1: a quorum of commits of one round on the block itself. */
|
|
+ QUORUM_OF_ROUND,
|
|
+ /** Q2: f+1 commits of the child's set on one child. */
|
|
+ CHILD_F_PLUS_ONE
|
|
+ }
|
|
+
|
|
+ private final Kind kind;
|
|
+ private final long height;
|
|
+ private final Hash onchainHash;
|
|
+ private final int round;
|
|
+ private final Optional<Hash> childOnchainHash;
|
|
+ private final List<Commit> commits;
|
|
+ private final Optional<Proposal> childProposal;
|
|
+
|
|
+ Proof(
|
|
+ final Kind kind,
|
|
+ final long height,
|
|
+ final Hash onchainHash,
|
|
+ final int round,
|
|
+ final Optional<Hash> childOnchainHash,
|
|
+ final List<Commit> commits,
|
|
+ final Optional<Proposal> childProposal) {
|
|
+ this.kind = kind;
|
|
+ this.height = height;
|
|
+ this.onchainHash = onchainHash;
|
|
+ this.round = round;
|
|
+ this.childOnchainHash = childOnchainHash;
|
|
+ this.commits = List.copyOf(commits);
|
|
+ this.childProposal = childProposal;
|
|
+ }
|
|
+
|
|
+ Proof withoutChildProposal() {
|
|
+ return new Proof(kind, height, onchainHash, round, childOnchainHash, commits, Optional.empty());
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The kind.
|
|
+ *
|
|
+ * @return the kind
|
|
+ */
|
|
+ public Kind kind() {
|
|
+ return kind;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The height of the decided block.
|
|
+ *
|
|
+ * @return the height
|
|
+ */
|
|
+ public long height() {
|
|
+ return height;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The on-chain hash of the decided block.
|
|
+ *
|
|
+ * @return the hash
|
|
+ */
|
|
+ public Hash onchainHash() {
|
|
+ return onchainHash;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The round of a Q1 proof, -1 for Q2.
|
|
+ *
|
|
+ * @return the round
|
|
+ */
|
|
+ public int round() {
|
|
+ return round;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The on-chain hash of the child, for Q2.
|
|
+ *
|
|
+ * @return the child hash, or empty for Q1
|
|
+ */
|
|
+ public Optional<Hash> childOnchainHash() {
|
|
+ return childOnchainHash;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The commits that make the proof, one per author.
|
|
+ *
|
|
+ * @return the commits
|
|
+ */
|
|
+ public List<Commit> commits() {
|
|
+ return commits;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The heard proposal of the child, when Q2 found the child that way (and the retained bytes
|
|
+ * allowed keeping it).
|
|
+ *
|
|
+ * @return the proposal, or empty
|
|
+ */
|
|
+ public Optional<Proposal> childProposal() {
|
|
+ return childProposal;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The distinct authors of the commits.
|
|
+ *
|
|
+ * @return the authors
|
|
+ */
|
|
+ public Set<Address> authors() {
|
|
+ final Set<Address> out = new LinkedHashSet<>();
|
|
+ for (final Commit c : commits) {
|
|
+ out.add(c.getAuthor());
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /** A proposed block heard, with its message when there is one, and the bytes charged for it. */
|
|
+ private static final class Heard {
|
|
+ private final QbftBlock block;
|
|
+ private final Optional<Proposal> message;
|
|
+ private final long bytes;
|
|
+
|
|
+ Heard(final QbftBlock block, final Optional<Proposal> message, final long bytes) {
|
|
+ this.block = block;
|
|
+ this.message = message;
|
|
+ this.bytes = bytes;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /** (round, digest): the unit an author's quota is counted in. */
|
|
+ private static final class RoundDigest {
|
|
+ private final int round;
|
|
+ private final Hash digest;
|
|
+
|
|
+ RoundDigest(final int round, final Hash digest) {
|
|
+ this.round = round;
|
|
+ this.digest = digest;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean equals(final Object o) {
|
|
+ return o instanceof RoundDigest other && other.round == round && other.digest.equals(digest);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int hashCode() {
|
|
+ return Objects.hash(round, digest);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /** A message not yet counted: never verified, or refused for a reason of the registry state. */
|
|
+ private static final class Waiting {
|
|
+ private final Commit commit;
|
|
+ private final Hash fingerprint;
|
|
+ private final int envelope;
|
|
+ private long refusedAt = NOT_REFUSED;
|
|
+
|
|
+ Waiting(final Commit commit, final Hash fingerprint, final int envelope) {
|
|
+ this.commit = commit;
|
|
+ this.fingerprint = fingerprint;
|
|
+ this.envelope = envelope;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /** Everything the collector holds for one (height, author). */
|
|
+ private static final class AuthorAt {
|
|
+ // message digest -> counted vote
|
|
+ private final LinkedHashMap<Hash, Vote> votes = new LinkedHashMap<>();
|
|
+ // message fingerprint -> waiting message
|
|
+ private final LinkedHashMap<Hash, Waiting> waiting = new LinkedHashMap<>();
|
|
+ // per envelope class: (round, digest) admitted so far -> how many messages were EVER admitted for
|
|
+ // it. Monotone: a message refused for good leaves its place taken (2026-09-30, second review).
|
|
+ private final List<Map<RoundDigest, Integer>> admitted = List.of(new HashMap<>(), new HashMap<>());
|
|
+
|
|
+ int size() {
|
|
+ return votes.size() + waiting.size();
|
|
+ }
|
|
+
|
|
+ /** Whether one more message of this class may be admitted for this (round, digest). */
|
|
+ boolean canAdmit(final int envelope, final RoundDigest key) {
|
|
+ final Map<RoundDigest, Integer> quota = admitted.get(envelope);
|
|
+ final Integer ever = quota.get(key);
|
|
+ if (ever == null) {
|
|
+ return quota.size() < MAX_PER_AUTHOR;
|
|
+ }
|
|
+ return ever < MAX_VARIANTS;
|
|
+ }
|
|
+
|
|
+ boolean holds(final Hash fingerprint, final Hash digest) {
|
|
+ final Vote v = votes.get(digest);
|
|
+ return waiting.containsKey(fingerprint) || (v != null && v.fingerprint.equals(fingerprint));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private enum Outcome {
|
|
+ MISMATCH,
|
|
+ COUNTED,
|
|
+ REFUSED,
|
|
+ KEPT_REFUSED
|
|
+ }
|
|
+
|
|
+ /** A memoized verdict, and the verifier generation it was made in. */
|
|
+ private static final class Memo {
|
|
+ private final AereVoteCounts.Judgement judgement;
|
|
+ private final long generation;
|
|
+
|
|
+ Memo(final AereVoteCounts.Judgement judgement, final long generation) {
|
|
+ this.judgement = judgement;
|
|
+ this.generation = generation;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private final QbftBlockInterface blockInterface;
|
|
+ private final ValidatorSets sets;
|
|
+ private final PqCommitEnforcement enforcement;
|
|
+ private final LongSupplier verifierGeneration;
|
|
+ private final ToLongFunction<QbftBlock> sizeOf;
|
|
+ private final int window;
|
|
+
|
|
+ private long decided;
|
|
+ // the canonical head the live heights are counted around; Long.MIN_VALUE until the wiring says
|
|
+ private long liveHead = Long.MIN_VALUE;
|
|
+ // height -> author -> what is held for that author
|
|
+ private final TreeMap<Long, Map<Address, AuthorAt>> byHeight = new TreeMap<>();
|
|
+ // height -> author -> on-chain hash -> heard proposed block
|
|
+ private final TreeMap<Long, Map<Address, LinkedHashMap<Hash, Heard>>> proposals = new TreeMap<>();
|
|
+ private final Map<Address, Long> proposalBytesByAuthor = new HashMap<>();
|
|
+ private long proposalBytes;
|
|
+ // decided height -> the raw messages of its proof, for the echo
|
|
+ private final TreeMap<Long, Proof> retained = new TreeMap<>();
|
|
+ private final Map<Long, Long> retainedBytesByHeight = new HashMap<>();
|
|
+ private long retainedBytes;
|
|
+ private final LinkedHashMap<String, Memo> memo =
|
|
+ new LinkedHashMap<>(256, 0.75f, true) {
|
|
+ private static final long serialVersionUID = 1L;
|
|
+
|
|
+ @Override
|
|
+ protected boolean removeEldestEntry(final Map.Entry<String, Memo> eldest) {
|
|
+ return size() > MEMO_CAPACITY;
|
|
+ }
|
|
+ };
|
|
+
|
|
+ private long verifications;
|
|
+ private long refused;
|
|
+ private long dropped;
|
|
+ private long classifications;
|
|
+
|
|
+ /**
|
|
+ * A collector above the decided head {@code decidedHeight}.
|
|
+ *
|
|
+ * @param blockInterface replaces the round of a block, to derive digest_r
|
|
+ * @param sets the validator sets
|
|
+ * @param enforcement the PQ commit enforcement of the node, or null for upstream behaviour
|
|
+ * @param verifierGeneration changes whenever the registry the enforcement reads changes state
|
|
+ * (late-anchor activation, a new epoch); a registry-dependent refusal is remembered only for
|
|
+ * the generation it was made in
|
|
+ * @param sizeOf the bytes a proposed block is charged (its encoded size in production)
|
|
+ * @param decidedHeight the current decided height D
|
|
+ * @param window W
|
|
+ */
|
|
+ public AereDecisionEvidence(
|
|
+ final QbftBlockInterface blockInterface,
|
|
+ final ValidatorSets sets,
|
|
+ final PqCommitEnforcement enforcement,
|
|
+ final LongSupplier verifierGeneration,
|
|
+ final ToLongFunction<QbftBlock> sizeOf,
|
|
+ final long decidedHeight,
|
|
+ final int window) {
|
|
+ this.blockInterface = Objects.requireNonNull(blockInterface, "blockInterface");
|
|
+ this.sets = Objects.requireNonNull(sets, "sets");
|
|
+ this.enforcement = enforcement;
|
|
+ this.verifierGeneration = Objects.requireNonNull(verifierGeneration, "verifierGeneration");
|
|
+ this.sizeOf = Objects.requireNonNull(sizeOf, "sizeOf");
|
|
+ this.decided = decidedHeight;
|
|
+ if (window < 1) {
|
|
+ throw new IllegalArgumentException("AERE-D412-EVIDENCE-CONF-01: window must be >= 1");
|
|
+ }
|
|
+ this.window = window;
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // observing
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /**
|
|
+ * Observe a Commit heard for a height in (D, D+W]. Within the author's quota it is kept, keyed by
|
|
+ * its fingerprint, and verified against every block already heard for its height; it takes the
|
|
+ * counted slot of its recovered author only once the predicate passes. The quota is checked
|
|
+ * twice: before the envelope class is recovered (dropped when neither class has room for the
|
|
+ * message's (round, digest)), and for its class after; an admission is never given back.
|
|
+ *
|
|
+ * @param commit the commit
|
|
+ * @return true when this very message is held (waiting, or as the counted vote of its author)
|
|
+ */
|
|
+ public synchronized boolean observeCommit(final Commit commit) {
|
|
+ final long n = commit.getRoundIdentifier().getSequenceNumber();
|
|
+ if (!inWindow(n)) {
|
|
+ return false;
|
|
+ }
|
|
+ final Address author = commit.getAuthor();
|
|
+ if (!sets.admission(n).contains(author)) {
|
|
+ dropped++;
|
|
+ return false;
|
|
+ }
|
|
+ final Hash digest = commit.getDigest();
|
|
+ final Bytes signed = commit.getSignedPayload().encode();
|
|
+ final Hash fingerprint = Hash.hash(signed);
|
|
+ final AuthorAt existing = byHeight.getOrDefault(n, Map.of()).get(author);
|
|
+ if (existing != null) {
|
|
+ final Vote counted = existing.votes.get(digest);
|
|
+ if (counted != null) {
|
|
+ // the vote of this author on this digest is counted; nothing more to verify
|
|
+ return counted.fingerprint.equals(fingerprint);
|
|
+ }
|
|
+ final Waiting known = existing.waiting.get(fingerprint);
|
|
+ if (known != null) {
|
|
+ if (known.refusedAt != NOT_REFUSED && known.refusedAt != verifierGeneration.getAsLong()) {
|
|
+ judgeAgainstHeard(n, author, existing, known);
|
|
+ }
|
|
+ return existing.holds(fingerprint, digest);
|
|
+ }
|
|
+ }
|
|
+ final RoundDigest key = new RoundDigest(commit.getRoundIdentifier().getRoundNumber(), digest);
|
|
+ if (existing != null && !existing.canAdmit(SELF, key) && !existing.canAdmit(FOREIGN, key)) {
|
|
+ // no class has room left for this (round, digest): dropped before the two ECDSA recoveries
|
|
+ dropped++;
|
|
+ return false;
|
|
+ }
|
|
+ final int envelope = envelopeOf(commit, signed);
|
|
+ classifications++;
|
|
+ if (existing != null && !existing.canAdmit(envelope, key)) {
|
|
+ dropped++;
|
|
+ return false;
|
|
+ }
|
|
+ if (entriesAt(n) >= MAX_PER_HEIGHT) {
|
|
+ dropped++;
|
|
+ return false;
|
|
+ }
|
|
+ final AuthorAt st = authorAt(n, author);
|
|
+ st.admitted.get(envelope).merge(key, 1, Integer::sum);
|
|
+ final Waiting w = new Waiting(commit, fingerprint, envelope);
|
|
+ st.waiting.put(fingerprint, w);
|
|
+ judgeAgainstHeard(n, author, st, w);
|
|
+ return st.holds(fingerprint, digest);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Observe a Proposal heard for a height in (D, D+W]. The author is the recovered author of the
|
|
+ * signed message.
|
|
+ *
|
|
+ * @param proposal the proposal
|
|
+ * @return true when the block was kept
|
|
+ */
|
|
+ public synchronized boolean observeProposal(final Proposal proposal) {
|
|
+ return observeProposedBlock(proposal.getAuthor(), proposal.getBlock(), Optional.of(proposal));
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Observe a proposed block, by the recovered author of the message that carried it. It is kept
|
|
+ * whole (the echo re-sends the proposal), charged {@code sizeOf(block)} plus the encoded size of
|
|
+ * the carrying message, and refused when the author's bytes, the total bytes, the author's count
|
|
+ * at the height or the height's count would be exceeded; nothing already held is evicted for it.
|
|
+ *
|
|
+ * @param author the recovered author of the carrying message
|
|
+ * @param block the proposed block
|
|
+ * @param message the carrying proposal, retained for the echo, when there is one
|
|
+ * @return true when the block is held
|
|
+ */
|
|
+ synchronized boolean observeProposedBlock(
|
|
+ final Address author, final QbftBlock block, final Optional<Proposal> message) {
|
|
+ final long n = block.getHeader().getNumber();
|
|
+ if (!inWindow(n) || !sets.admission(n).contains(author)) {
|
|
+ dropped++;
|
|
+ return false;
|
|
+ }
|
|
+ final Hash onchain = onchainOf(block);
|
|
+ final LinkedHashMap<Hash, Heard> mine =
|
|
+ proposals.getOrDefault(n, Map.of()).get(author);
|
|
+ if (mine != null && mine.containsKey(onchain)) {
|
|
+ promote(n, block);
|
|
+ return true;
|
|
+ }
|
|
+ final long bytes =
|
|
+ Math.max(0L, sizeOf.applyAsLong(block))
|
|
+ + message.map(m -> (long) m.encode().size()).orElse(0L);
|
|
+ if ((mine != null && mine.size() >= MAX_PROPOSALS_PER_AUTHOR)
|
|
+ || heardCountAt(n) >= MAX_PROPOSALS_PER_HEIGHT
|
|
+ || proposalBytesByAuthor.getOrDefault(author, 0L) + bytes > MAX_PROPOSAL_BYTES_PER_AUTHOR
|
|
+ || proposalBytes + bytes > MAX_PROPOSAL_BYTES) {
|
|
+ dropped++;
|
|
+ return false;
|
|
+ }
|
|
+ proposals
|
|
+ .computeIfAbsent(n, k -> new LinkedHashMap<>())
|
|
+ .computeIfAbsent(author, k -> new LinkedHashMap<>())
|
|
+ .put(onchain, new Heard(block, message, bytes));
|
|
+ proposalBytesByAuthor.merge(author, bytes, Long::sum);
|
|
+ proposalBytes += bytes;
|
|
+ promote(n, block);
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // judging
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /**
|
|
+ * Q1: is the stored block {@code b} decided by a quorum of one round's commits?
|
|
+ *
|
|
+ * @param b a stored block (any round form)
|
|
+ * @return the proof, or empty
|
|
+ */
|
|
+ public synchronized Optional<Proof> quorumFor(final QbftBlock b) {
|
|
+ final long n = b.getHeader().getNumber();
|
|
+ final Optional<Collection<Address>> set = setOf(b);
|
|
+ if (set.isEmpty()) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ promoteWithSet(n, b, set.get());
|
|
+ final int quorum = quorum(set.get().size());
|
|
+ final Hash onchain = onchainOf(b);
|
|
+ final Map<Address, AuthorAt> atN = byHeight.getOrDefault(n, Map.of());
|
|
+ for (final int r : roundsCountedAt(n)) {
|
|
+ final Hash digestR =
|
|
+ AereVoteCounts.Target.atRound(blockInterface, b, n, r)
|
|
+ .digest();
|
|
+ final List<Commit> votes = new ArrayList<>();
|
|
+ for (final Map.Entry<Address, AuthorAt> e : atN.entrySet()) {
|
|
+ final Vote v = e.getValue().votes.get(digestR);
|
|
+ if (v != null && set.get().contains(e.getKey())) {
|
|
+ votes.add(v.commit());
|
|
+ }
|
|
+ }
|
|
+ if (votes.size() >= quorum) {
|
|
+ return Optional.of(
|
|
+ new Proof(
|
|
+ Proof.Kind.QUORUM_OF_ROUND, n, onchain, r, Optional.empty(), votes, Optional.empty()));
|
|
+ }
|
|
+ }
|
|
+ return Optional.empty();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Q2: is the stored block {@code b} decided by f+1 commits, of the child's set, on one child?
|
|
+ *
|
|
+ * @param b a stored block
|
|
+ * @param storedChildren children of {@code b} the node has stored, besides the heard proposals
|
|
+ * @return the proof, or empty
|
|
+ */
|
|
+ public synchronized Optional<Proof> childProofFor(
|
|
+ final QbftBlock b, final Collection<QbftBlock> storedChildren) {
|
|
+ final long n = b.getHeader().getNumber();
|
|
+ final Hash onchainB = onchainOf(b);
|
|
+ // set(c) = validators AFTER b: the set that decides the child, not the one written in b
|
|
+ final Optional<Collection<Address>> childSet =
|
|
+ sets.afterBlock(onchainB);
|
|
+ if (childSet.isEmpty()) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ final int f = (childSet.get().size() - 1) / 3;
|
|
+ final int threshold = f + 1;
|
|
+ final List<Heard> children = new ArrayList<>();
|
|
+ for (final QbftBlock c : storedChildren) {
|
|
+ if (onchainB.equals(c.getHeader().getParentHash()) && c.getHeader().getNumber() == n + 1) {
|
|
+ children.add(new Heard(c, Optional.empty(), 0L));
|
|
+ }
|
|
+ }
|
|
+ for (final Heard h : heardAt(n + 1)) {
|
|
+ if (onchainB.equals(h.block.getHeader().getParentHash())) {
|
|
+ children.add(h);
|
|
+ }
|
|
+ }
|
|
+ for (final Heard child : children) {
|
|
+ promoteWithSet(n + 1, child.block, childSet.get());
|
|
+ final Hash onchainC = onchainOf(child.block);
|
|
+ final List<Commit> votes = new ArrayList<>();
|
|
+ for (final Map.Entry<Address, AuthorAt> e :
|
|
+ byHeight.getOrDefault(n + 1, Map.of()).entrySet()) {
|
|
+ if (!childSet.get().contains(e.getKey())) {
|
|
+ continue;
|
|
+ }
|
|
+ for (final Vote v : e.getValue().votes.values()) {
|
|
+ if (v.onchainHash().equals(onchainC)) {
|
|
+ votes.add(v.commit());
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ if (votes.size() >= threshold) {
|
|
+ return Optional.of(
|
|
+ new Proof(
|
|
+ Proof.Kind.CHILD_F_PLUS_ONE,
|
|
+ n,
|
|
+ onchainB,
|
|
+ -1,
|
|
+ Optional.of(onchainC),
|
|
+ votes,
|
|
+ child.message));
|
|
+ }
|
|
+ }
|
|
+ return Optional.empty();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Q4: is {@code candidate} an ancestor (or the block itself) of the decided block, on the
|
|
+ * parentHash path, within {@code limit} steps?
|
|
+ *
|
|
+ * @param decided the header of a decided block
|
|
+ * @param candidate the header asked about
|
|
+ * @param headerByHash stored headers by on-chain hash
|
|
+ * @param limit how many parent steps at most
|
|
+ * @return true when the candidate lies on the decided block's own ancestry
|
|
+ */
|
|
+ public static boolean decidedByAncestry(
|
|
+ final QbftBlockHeader decided,
|
|
+ final QbftBlockHeader candidate,
|
|
+ final Function<Hash, Optional<QbftBlockHeader>> headerByHash,
|
|
+ final int limit) {
|
|
+ if (candidate.getNumber() > decided.getNumber()
|
|
+ || decided.getNumber() - candidate.getNumber() > limit) {
|
|
+ return false;
|
|
+ }
|
|
+ QbftBlockHeader cur = decided;
|
|
+ while (cur.getNumber() > candidate.getNumber()) {
|
|
+ final Hash parent = cur.getParentHash();
|
|
+ if (parent == null) {
|
|
+ return false;
|
|
+ }
|
|
+ final Optional<QbftBlockHeader> next = headerByHash.apply(parent);
|
|
+ if (next.isEmpty()) {
|
|
+ return false;
|
|
+ }
|
|
+ cur = next.get();
|
|
+ }
|
|
+ return cur.getNumber() == candidate.getNumber()
|
|
+ && cur.getHash().equals(candidate.getHash());
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // the decided head moves, and the echo
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /**
|
|
+ * The decided head advanced to the block the proof names: keep the proof's raw messages for the
|
|
+ * echo (the child proposal only while MAX_RETAINED_BYTES allows, oldest stripped first), drop
|
|
+ * everything at or below it that is not retained, and drop retained proofs below D-W.
|
|
+ *
|
|
+ * <p>The proof is retained even when this collector already follows D at or above its height
|
|
+ * (2026-09-30, review of step 3): the wiring moves D on the chain first and tells this collector
|
|
+ * after, and in between the QBFT thread may already have brought the collector up to the chain's
|
|
+ * D ({@link #markDecidedHeight}); refusing the proof then would leave that decided height without
|
|
+ * an echo. A proof below D - W, or of a height already retained, changes nothing.
|
|
+ *
|
|
+ * @param proof the proof of the new decided head
|
|
+ */
|
|
+ public synchronized void markDecided(final Proof proof) {
|
|
+ final long h = proof.height();
|
|
+ if (h > decided) {
|
|
+ decided = h;
|
|
+ } else if (h < decided - window || retained.containsKey(h)) {
|
|
+ return;
|
|
+ }
|
|
+ retain(h, proof);
|
|
+ dropAtOrBelow(decided);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The canonical head the LIVE heights are counted around ({@link #LIVE_BELOW}, {@link
|
|
+ * #LIVE_ABOVE}). Heights above D + W that fall below the live heights are dropped.
|
|
+ *
|
|
+ * @param head the canonical head's height
|
|
+ */
|
|
+ public synchronized void followLiveHead(final long head) {
|
|
+ if (head == liveHead) {
|
|
+ return;
|
|
+ }
|
|
+ liveHead = head;
|
|
+ final long from = decided + window;
|
|
+ final long to = head - LIVE_BELOW;
|
|
+ if (to > from + 1) {
|
|
+ dropBetween(from, to);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The decided head advanced by a proof this collector does not hold (Q3, Q4, Q5, Q6): drop what
|
|
+ * is at or below it, keep what is retained.
|
|
+ *
|
|
+ * @param height the new decided height
|
|
+ */
|
|
+ public synchronized void markDecidedHeight(final long height) {
|
|
+ if (height <= decided) {
|
|
+ return;
|
|
+ }
|
|
+ decided = height;
|
|
+ dropAtOrBelow(decided);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The decided height D this collector works above.
|
|
+ *
|
|
+ * @return D
|
|
+ */
|
|
+ public synchronized long decidedHeight() {
|
|
+ return decided;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The raw messages of the proof of a decided height in [D-W, D], for the echo.
|
|
+ *
|
|
+ * @param height the decided height
|
|
+ * @return the retained proof, or empty
|
|
+ */
|
|
+ public synchronized Optional<Proof> retainedProof(final long height) {
|
|
+ return Optional.ofNullable(retained.get(height));
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // measurements, for the proofs and the log
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /**
|
|
+ * How many times the shared predicate was actually run (memo misses).
|
|
+ *
|
|
+ * @return the count
|
|
+ */
|
|
+ public synchronized long verifications() {
|
|
+ return verifications;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many predicate runs refused.
|
|
+ *
|
|
+ * @return the count
|
|
+ */
|
|
+ public synchronized long refused() {
|
|
+ return refused;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many messages were dropped by the bounds or the admission filter.
|
|
+ *
|
|
+ * @return the count
|
|
+ */
|
|
+ public synchronized long dropped() {
|
|
+ return dropped;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * How many heard messages had their envelope class recovered (two ECDSA recoveries each): only
|
|
+ * those whose (round, digest) still had room in at least one class.
|
|
+ *
|
|
+ * @return the count
|
|
+ */
|
|
+ public synchronized long classifications() {
|
|
+ return classifications;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Waiting plus counted entries across all heights.
|
|
+ *
|
|
+ * @return the count
|
|
+ */
|
|
+ public synchronized int entries() {
|
|
+ int total = 0;
|
|
+ for (final long n : new TreeSet<>(byHeight.keySet())) {
|
|
+ total += entriesAt(n);
|
|
+ }
|
|
+ return total;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Waiting plus counted entries of one author across all heights.
|
|
+ *
|
|
+ * @param author the author
|
|
+ * @return the count
|
|
+ */
|
|
+ public synchronized int entriesOf(final Address author) {
|
|
+ int total = 0;
|
|
+ for (final Map<Address, AuthorAt> m : byHeight.values()) {
|
|
+ final AuthorAt st = m.get(author);
|
|
+ if (st != null) {
|
|
+ total += st.size();
|
|
+ }
|
|
+ }
|
|
+ return total;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The bytes charged for the proposed blocks of one author.
|
|
+ *
|
|
+ * @param author the author
|
|
+ * @return the bytes
|
|
+ */
|
|
+ public synchronized long proposalBytesOf(final Address author) {
|
|
+ return proposalBytesByAuthor.getOrDefault(author, 0L);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The bytes charged for all proposed blocks held.
|
|
+ *
|
|
+ * @return the bytes
|
|
+ */
|
|
+ public synchronized long proposalBytes() {
|
|
+ return proposalBytes;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The bytes charged for the retained echo proofs.
|
|
+ *
|
|
+ * @return the bytes
|
|
+ */
|
|
+ public synchronized long retainedBytes() {
|
|
+ return retainedBytes;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The heights the collector holds entries or proposals for.
|
|
+ *
|
|
+ * @return the heights
|
|
+ */
|
|
+ public synchronized Set<Long> heights() {
|
|
+ final Set<Long> out = new TreeSet<>(byHeight.keySet());
|
|
+ out.addAll(proposals.keySet());
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The counted voters at a height (any digest).
|
|
+ *
|
|
+ * @param height the height
|
|
+ * @return the authors with at least one counted vote
|
|
+ */
|
|
+ public synchronized Set<Address> countedAuthors(final long height) {
|
|
+ final Set<Address> out = new LinkedHashSet<>();
|
|
+ for (final Map.Entry<Address, AuthorAt> e : byHeight.getOrDefault(height, Map.of()).entrySet()) {
|
|
+ if (!e.getValue().votes.isEmpty()) {
|
|
+ out.add(e.getKey());
|
|
+ }
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // internals
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ private boolean inWindow(final long n) {
|
|
+ return (n > decided && n <= decided + window) || live(n);
|
|
+ }
|
|
+
|
|
+ /** A LIVE height beyond the window: around the canonical head, above D + W. */
|
|
+ private boolean live(final long n) {
|
|
+ return liveHead != Long.MIN_VALUE
|
|
+ && n > decided + window
|
|
+ && n >= liveHead - LIVE_BELOW
|
|
+ && n <= liveHead + LIVE_ABOVE;
|
|
+ }
|
|
+
|
|
+ /** Drop what is held for the heights strictly between {@code from} and {@code to}. */
|
|
+ private void dropBetween(final long from, final long to) {
|
|
+ byHeight.subMap(from, false, to, false).clear();
|
|
+ final Map<Long, Map<Address, LinkedHashMap<Hash, Heard>>> gone =
|
|
+ proposals.subMap(from, false, to, false);
|
|
+ for (final Map<Address, LinkedHashMap<Hash, Heard>> m : gone.values()) {
|
|
+ for (final Map.Entry<Address, LinkedHashMap<Hash, Heard>> e : m.entrySet()) {
|
|
+ for (final Heard h : e.getValue().values()) {
|
|
+ proposalBytesByAuthor.merge(e.getKey(), -h.bytes, Long::sum);
|
|
+ proposalBytes -= h.bytes;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ gone.clear();
|
|
+ proposalBytesByAuthor.values().removeIf(v -> v <= 0L);
|
|
+ }
|
|
+
|
|
+ private AuthorAt authorAt(final long n, final Address author) {
|
|
+ return byHeight.computeIfAbsent(n, k -> new LinkedHashMap<>()).computeIfAbsent(author, k -> new AuthorAt());
|
|
+ }
|
|
+
|
|
+ private List<Heard> heardAt(final long n) {
|
|
+ final List<Heard> out = new ArrayList<>();
|
|
+ for (final LinkedHashMap<Hash, Heard> m : proposals.getOrDefault(n, Map.of()).values()) {
|
|
+ out.addAll(m.values());
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ private int heardCountAt(final long n) {
|
|
+ int total = 0;
|
|
+ for (final LinkedHashMap<Hash, Heard> m : proposals.getOrDefault(n, Map.of()).values()) {
|
|
+ total += m.size();
|
|
+ }
|
|
+ return total;
|
|
+ }
|
|
+
|
|
+ private int entriesAt(final long n) {
|
|
+ int total = 0;
|
|
+ for (final AuthorAt st : byHeight.getOrDefault(n, Map.of()).values()) {
|
|
+ total += st.size();
|
|
+ }
|
|
+ return total;
|
|
+ }
|
|
+
|
|
+ private Set<Integer> roundsCountedAt(final long n) {
|
|
+ final Set<Integer> rounds = new TreeSet<>();
|
|
+ for (final AuthorAt st : byHeight.getOrDefault(n, Map.of()).values()) {
|
|
+ for (final Vote v : st.votes.values()) {
|
|
+ rounds.add(v.commit().getRoundIdentifier().getRoundNumber());
|
|
+ }
|
|
+ }
|
|
+ return rounds;
|
|
+ }
|
|
+
|
|
+ private Hash onchainOf(final QbftBlock block) {
|
|
+ return blockInterface.replaceRoundForCommitBlock(block, 0).getHash();
|
|
+ }
|
|
+
|
|
+ private static Hash parentOf(final QbftBlock block) {
|
|
+ return block.getHeader().getParentHash();
|
|
+ }
|
|
+
|
|
+ private Optional<Collection<Address>> setOf(final QbftBlock block) {
|
|
+ final Hash parent = parentOf(block);
|
|
+ return parent == null ? Optional.empty() : sets.afterBlock(parent);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * SELF when the envelope is signed by the same ECDSA key as the commit seal (what Besu and
|
|
+ * Nethermind emit), FOREIGN otherwise. From H_fin the envelope does not decide the author, so a
|
|
+ * FOREIGN message may still be an honest vote; it only has its own, separate quota.
|
|
+ */
|
|
+ private static int envelopeOf(final Commit commit, final Bytes signed) {
|
|
+ try {
|
|
+ final Optional<Address> sealSigner = commit.getSignedPayload().getPayload().commitSealSigner();
|
|
+ if (sealSigner.isEmpty()) {
|
|
+ return FOREIGN;
|
|
+ }
|
|
+ final RLPInput in = new BytesValueRLPInput(signed, false);
|
|
+ in.enterList();
|
|
+ in.skipNext();
|
|
+ final SECPSignature envelope =
|
|
+ in.readBytes(SignatureAlgorithmFactory.getInstance()::decodeSignature);
|
|
+ final Address envelopeSigner =
|
|
+ Util.signatureToAddress(envelope, commit.getSignedPayload().getPayload().hashForSignature());
|
|
+ return sealSigner.get().equals(envelopeSigner) ? SELF : FOREIGN;
|
|
+ } catch (final RuntimeException e) {
|
|
+ return FOREIGN;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private void promote(final long n, final QbftBlock block) {
|
|
+ final Optional<Collection<Address>> set = setOf(block);
|
|
+ if (set.isPresent()) {
|
|
+ promoteWithSet(n, block, set.get());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /** Judge the waiting commits of height n against {@code block}, SELF-enveloped first. */
|
|
+ private void promoteWithSet(final long n, final QbftBlock block, final Collection<Address> set) {
|
|
+ final Map<Address, AuthorAt> atN = byHeight.get(n);
|
|
+ if (atN == null) {
|
|
+ return;
|
|
+ }
|
|
+ for (final Map.Entry<Address, AuthorAt> e : new ArrayList<>(atN.entrySet())) {
|
|
+ final AuthorAt st = e.getValue();
|
|
+ final List<Waiting> order = new ArrayList<>();
|
|
+ for (final Waiting w : st.waiting.values()) {
|
|
+ if (w.envelope == SELF) {
|
|
+ order.add(w);
|
|
+ }
|
|
+ }
|
|
+ for (final Waiting w : st.waiting.values()) {
|
|
+ if (w.envelope != SELF) {
|
|
+ order.add(w);
|
|
+ }
|
|
+ }
|
|
+ for (final Waiting w : order) {
|
|
+ if (st.waiting.containsKey(w.fingerprint)) {
|
|
+ judge(n, e.getKey(), st, w, block, set);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private void judgeAgainstHeard(final long n, final Address author, final AuthorAt st, final Waiting w) {
|
|
+ for (final Heard h : heardAt(n)) {
|
|
+ final Optional<Collection<Address>> set = setOf(h.block);
|
|
+ if (set.isEmpty()) {
|
|
+ continue;
|
|
+ }
|
|
+ if (judge(n, author, st, w, h.block, set.get()) != Outcome.MISMATCH) {
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Judge one waiting commit against one block, when the commit's digest is that block's digest at
|
|
+ * the commit's round. A count takes the author's slot and makes every other waiting message of
|
|
+ * that author on that digest redundant; a refusal of the message drops only this message (its
|
|
+ * admitted place stays taken: the admission count never goes down); a refusal of the registry
|
|
+ * state keeps it waiting for another generation.
|
|
+ */
|
|
+ private Outcome judge(
|
|
+ final long n,
|
|
+ final Address author,
|
|
+ final AuthorAt st,
|
|
+ final Waiting w,
|
|
+ final QbftBlock block,
|
|
+ final Collection<Address> set) {
|
|
+ final Commit c = w.commit;
|
|
+ if (block.getHeader().getNumber() != n) {
|
|
+ return Outcome.MISMATCH;
|
|
+ }
|
|
+ final int r = c.getRoundIdentifier().getRoundNumber();
|
|
+ final AereVoteCounts.Target target =
|
|
+ AereVoteCounts.Target.atRound(blockInterface, block, n, r);
|
|
+ if (!target.digest().equals(c.getDigest())) {
|
|
+ return Outcome.MISMATCH;
|
|
+ }
|
|
+ final AereVoteCounts.Judgement j = verdict(w, author, target, set);
|
|
+ if (j.counts()) {
|
|
+ final AuthorAt slot = st;
|
|
+ slot.votes.put(c.getDigest(), new Vote(c, onchainOf(block), w.fingerprint));
|
|
+ st.waiting.values().removeIf(x -> x.commit.getDigest().equals(c.getDigest()));
|
|
+ trimVotes(slot);
|
|
+ return Outcome.COUNTED;
|
|
+ }
|
|
+ LOG.debug("AERE D-412 evidence: commit of {} at {} not counted: {}", author, n, j.refusal().orElse(""));
|
|
+ if (!j.dependsOnRegistryState()) {
|
|
+ st.waiting.remove(w.fingerprint);
|
|
+ return Outcome.REFUSED;
|
|
+ }
|
|
+ w.refusedAt = verifierGeneration.getAsLong();
|
|
+ return Outcome.KEPT_REFUSED;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The shared predicate, memoized per (message, target, set membership of its author). A count and
|
|
+ * a refusal of the message are remembered for good; a registry-dependent refusal only for the
|
|
+ * verifier generation it was made in.
|
|
+ */
|
|
+ private AereVoteCounts.Judgement verdict(
|
|
+ final Waiting w,
|
|
+ final Address author,
|
|
+ final AereVoteCounts.Target target,
|
|
+ final Collection<Address> set) {
|
|
+ final String key =
|
|
+ w.fingerprint.toHexString()
|
|
+ + "|"
|
|
+ + target.commitDigest().toHexString()
|
|
+ + "|"
|
|
+ // 1(b): the round-bound message differs per round, so the memo key does too; "none" only at
|
|
+ // a round outside 0..1024 (a refusal that depends on the message, the same forever)
|
|
+ + target.pqSealMessage().map(Hash::toHexString).orElse("none")
|
|
+ + "|"
|
|
+ + set.contains(author);
|
|
+ final long generation = verifierGeneration.getAsLong();
|
|
+ final Memo known = memo.get(key);
|
|
+ if (known != null
|
|
+ && (!known.judgement.dependsOnRegistryState()
|
|
+ || known.generation == generation)) {
|
|
+ return known.judgement;
|
|
+ }
|
|
+ verifications++;
|
|
+ final AereVoteCounts.Judgement j =
|
|
+ AereVoteCounts.judge(w.commit.getSignedPayload(), set, target, enforcement);
|
|
+ if (!j.counts()) {
|
|
+ refused++;
|
|
+ }
|
|
+ memo.put(key, new Memo(j, generation));
|
|
+ return j;
|
|
+ }
|
|
+
|
|
+ /** Keep the MAX_PER_AUTHOR highest rounds of counted votes (their rounds are verified). */
|
|
+ private void trimVotes(final AuthorAt st) {
|
|
+ while (st.votes.size() > MAX_PER_AUTHOR) {
|
|
+ Hash lowest = null;
|
|
+ int lowestRound = Integer.MAX_VALUE;
|
|
+ for (final Map.Entry<Hash, Vote> e : st.votes.entrySet()) {
|
|
+ final int r = e.getValue().commit().getRoundIdentifier().getRoundNumber();
|
|
+ if (r < lowestRound) {
|
|
+ lowestRound = r;
|
|
+ lowest = e.getKey();
|
|
+ }
|
|
+ }
|
|
+ st.votes.remove(lowest);
|
|
+ dropped++;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private void dropAtOrBelow(final long height) {
|
|
+ byHeight.headMap(height, true).clear();
|
|
+ final Map<Long, Map<Address, LinkedHashMap<Hash, Heard>>> gone = proposals.headMap(height, true);
|
|
+ for (final Map<Address, LinkedHashMap<Hash, Heard>> m : gone.values()) {
|
|
+ for (final Map.Entry<Address, LinkedHashMap<Hash, Heard>> e : m.entrySet()) {
|
|
+ for (final Heard h : e.getValue().values()) {
|
|
+ proposalBytesByAuthor.merge(e.getKey(), -h.bytes, Long::sum);
|
|
+ proposalBytes -= h.bytes;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ gone.clear();
|
|
+ proposalBytesByAuthor.values().removeIf(v -> v <= 0L);
|
|
+ for (final Long h : new ArrayList<>(retained.headMap(height - window).keySet())) {
|
|
+ retained.remove(h);
|
|
+ retainedBytes -= retainedBytesByHeight.getOrDefault(h, 0L);
|
|
+ retainedBytesByHeight.remove(h);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /** Retain a proof for the echo, stripping child proposals oldest first while over the byte cap. */
|
|
+ private void retain(final long height, final Proof proof) {
|
|
+ long bytes = 0;
|
|
+ for (final Commit c : proof.commits()) {
|
|
+ bytes += c.getSignedPayload().encode().size();
|
|
+ }
|
|
+ Proof kept = proof;
|
|
+ if (proof.childProposal().isPresent()) {
|
|
+ final long child = proof.childProposal().get().encode().size();
|
|
+ if (bytes + child <= MAX_RETAINED_BYTES) {
|
|
+ bytes += child;
|
|
+ } else {
|
|
+ kept = proof.withoutChildProposal();
|
|
+ }
|
|
+ }
|
|
+ retained.put(height, kept);
|
|
+ retainedBytesByHeight.put(height, bytes);
|
|
+ retainedBytes += bytes;
|
|
+ for (final Long h : new ArrayList<>(retained.keySet())) {
|
|
+ if (retainedBytes <= MAX_RETAINED_BYTES) {
|
|
+ break;
|
|
+ }
|
|
+ final Proof p = retained.get(h);
|
|
+ if (p.childProposal().isPresent()) {
|
|
+ final long child = p.childProposal().get().encode().size();
|
|
+ retained.put(h, p.withoutChildProposal());
|
|
+ retainedBytesByHeight.merge(h, -child, Long::sum);
|
|
+ retainedBytes -= child;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static int quorum(final int setSize) {
|
|
+ return org.hyperledger.besu.consensus.common.bft.BftHelpers.calculateRequiredValidatorQuorum(
|
|
+ setSize);
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftController.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftController.java
|
|
index 50100fd7a8..b6306ea09e 100644
|
|
--- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftController.java
|
|
+++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftController.java
|
|
@@ -10,40 +10,41 @@
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
* found, as section 4(c) requires. The change itself is in patches/0003-aere-pq-anchor.patch.
|
|
*/
|
|
package org.hyperledger.besu.consensus.qbft.core.statemachine;
|
|
|
|
import static org.hyperledger.besu.consensus.qbft.core.validation.ValidatorUtil.isMsgForCurrentHeight;
|
|
import static org.hyperledger.besu.consensus.qbft.core.validation.ValidatorUtil.isMsgForFutureChainHeight;
|
|
import static org.hyperledger.besu.consensus.qbft.core.validation.ValidatorUtil.isMsgFromKnownValidator;
|
|
|
|
import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
|
import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
import org.hyperledger.besu.consensus.common.bft.PqSealCache;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
import org.hyperledger.besu.consensus.common.bft.MessageTracker;
|
|
import org.hyperledger.besu.consensus.common.bft.events.BlockTimerExpiry;
|
|
import org.hyperledger.besu.consensus.common.bft.events.RoundExpiry;
|
|
import org.hyperledger.besu.consensus.common.bft.messagewrappers.BftMessage;
|
|
import org.hyperledger.besu.consensus.common.bft.statemachine.FutureMessageBuffer;
|
|
import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit;
|
|
import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare;
|
|
import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal;
|
|
import org.hyperledger.besu.consensus.qbft.core.messagewrappers.QbftMessageDecoder;
|
|
import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCodec;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockHeader;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockchain;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftEventHandler;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftFinalState;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftGossiper;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftMessage;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftNewChainHead;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftReceivedMessageEvent;
|
|
import org.hyperledger.besu.consensus.qbft.core.validation.MessageValidator;
|
|
@@ -198,47 +199,54 @@ public class QbftController implements QbftEventHandler {
|
|
} else {
|
|
LOG.trace("Discarded duplicate message");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Consume message.
|
|
*
|
|
* @param <P> the type parameter of BftMessage
|
|
* @param message the message
|
|
* @param bftMessage the bft message
|
|
* @param handleMessage the handle message
|
|
* @param isReplayed the message is being replayed
|
|
*/
|
|
protected <P extends BftMessage<?>> void consumeMessage(
|
|
final QbftMessage message,
|
|
final P bftMessage,
|
|
final Consumer<P> handleMessage,
|
|
final boolean isReplayed) {
|
|
LOG.trace("Received BFT {} message", bftMessage.getClass().getSimpleName());
|
|
+ // AERE D-412 rule D (step 3): the decision-evidence collector sees every message of the window
|
|
+ // (D, D+W] BEFORE the height guard and the round filters below, so it also holds commits of old
|
|
+ // rounds and messages beyond the future-message buffer. Inert below H_ev and without rule D.
|
|
+ AereDecidedHook.current().observe(bftMessage, message);
|
|
|
|
// Discard all messages which target the BLOCKCHAIN height (which SHOULD be 1 less than
|
|
// the currentHeightManager, but CAN be the same directly following import).
|
|
if (bftMessage.getRoundIdentifier().getSequenceNumber()
|
|
<= blockchain.getChainHeadBlockNumber()) {
|
|
// AERE D-227: before the message dies here, keep its Falcon seal if it is still useful.
|
|
pqSalvageLateSeal(bftMessage);
|
|
+ // AERE D-412 rule D: a RoundChange for a height this node already decided is answered with the
|
|
+ // raw commits of that decision (the echo), so validators that missed them can decide too.
|
|
+ AereDecidedHook.current().echoIfRoundChange(bftMessage);
|
|
LOG.debug(
|
|
"Discarding a message which targets a height {} not above current chain height {}.",
|
|
bftMessage.getRoundIdentifier().getSequenceNumber(),
|
|
blockchain.getChainHeadBlockNumber());
|
|
return;
|
|
}
|
|
|
|
if (processMessage(bftMessage, message)) {
|
|
gossiper.send(message, isReplayed);
|
|
handleMessage.accept(bftMessage);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* AERE D-227 (2026-08-14): keep the Falcon seal of a Commit that arrives AFTER its block was
|
|
* imported, instead of discarding it with the message.
|
|
*
|
|
* <p>Why this exists, measured on chain 2800: a block imports on the quorum-th Commit, and the
|
|
* Commits of the slowest validators consistently arrive tens of milliseconds later - after the
|
|
* height gate above starts discarding them. Their Falcon seals never reached the seal cache, so
|
|
@@ -252,61 +260,94 @@ public class QbftController implements QbftEventHandler {
|
|
* out, and only when ALL of the following hold: the message is a Commit carrying a seal, its
|
|
* height is EXACTLY the chain head (an older seal can never be asked for again), its digest is
|
|
* the head's own hash (a losing round or a fork sibling is not ours to keep), and its author is
|
|
* a known validator (so a non-validator peer cannot write into the cache). A seal that lies
|
|
* about its signer index still cannot reach a header: the producer Falcon-verifies every cached
|
|
* seal against the anchored registry before carrying it.
|
|
*/
|
|
private void pqSalvageLateSeal(final BftMessage<?> bftMessage) {
|
|
if (!(bftMessage instanceof Commit commit)) {
|
|
return;
|
|
}
|
|
final Optional<FalconSeal> seal = commit.getFalconSeal();
|
|
if (seal.isEmpty()) {
|
|
return;
|
|
}
|
|
final long head = blockchain.getChainHeadBlockNumber();
|
|
if (commit.getRoundIdentifier().getSequenceNumber() != head) {
|
|
return;
|
|
}
|
|
final QbftBlockHeader headHeader = blockchain.getChainHeadHeader();
|
|
+ final int round = commit.getRoundIdentifier().getRoundNumber();
|
|
+ final List<org.hyperledger.besu.consensus.common.bft.SchemeSeal> extras =
|
|
+ commit.getExtraSeals();
|
|
+ // AERE 1(b) (2026-10-01, section 3.1 F): from H_r - 1 the salvage keeps the late Commit of ANY round. Round 0's
|
|
+ // digest is the head's on-chain hash and goes straight under (n, hash, 0); a round r > 0 names the head's digest
|
|
+ // AT r, which this controller cannot rebuild from a header, so its seals are held aside under that digest and
|
|
+ // moved under (n, hash, r) by the producer of the next block, which rebuilds the digest of each round from the
|
|
+ // header (PqAnchorProducer, resolvePending), before it reads the rounds. Below H_r: the salvage of before, round
|
|
+ // 0 only, call by call (J17).
|
|
+ if (PqAnchorProducer.commitSealFormAt(PqAnchorProducer.config(), head)
|
|
+ == PqAnchorProducer.CommitSealForm.ROUND_BOUND) {
|
|
+ if (!finalState.getValidators().contains(commit.getAuthor())) {
|
|
+ return;
|
|
+ }
|
|
+ if (round == 0 && commit.getDigest().equals(headHeader.getHash())) {
|
|
+ PqSealCache.instance().record(head, headHeader.getHash(), 0, List.of(seal.get()));
|
|
+ if (!extras.isEmpty()) {
|
|
+ PqSealCache.instance().recordExtras(head, headHeader.getHash(), 0, extras);
|
|
+ }
|
|
+ } else if (round > 0) {
|
|
+ PqSealCache.instance()
|
|
+ .recordPendingRound(head, commit.getDigest(), round, commit.getAuthor(), List.of(seal.get()), extras);
|
|
+ }
|
|
+ LOG.trace("AERE D-227: salvaged a late Falcon seal of round {} for imported block {}", round, head);
|
|
+ return;
|
|
+ }
|
|
if (!commit.getDigest().equals(headHeader.getHash())) {
|
|
return;
|
|
}
|
|
if (!finalState.getValidators().contains(commit.getAuthor())) {
|
|
return;
|
|
}
|
|
- PqSealCache.instance().record(head, headHeader.getHash(), List.of(seal.get()));
|
|
+ PqSealCache.instance().record(head, headHeader.getHash(), round, List.of(seal.get()));
|
|
// D-339 (2026-09-04): the hybrid extras ride the SAME late commits, and until today this path
|
|
// dropped them. The anchor needs K seals of EVERY scheme, so a salvaged Falcon seal without its
|
|
// SLH-DSA twin still left the proposer short and the anchor still lost its round.
|
|
- final List<org.hyperledger.besu.consensus.common.bft.SchemeSeal> extras =
|
|
- commit.getExtraSeals();
|
|
if (!extras.isEmpty()) {
|
|
- PqSealCache.instance().recordExtras(head, headHeader.getHash(), extras);
|
|
+ PqSealCache.instance().recordExtras(head, headHeader.getHash(), round, extras);
|
|
}
|
|
LOG.trace("AERE D-227: salvaged a late Falcon seal for imported block {}", head);
|
|
}
|
|
|
|
@Override
|
|
public void handleNewBlockEvent(final QbftNewChainHead newChainHead) {
|
|
final QbftBlockHeader newBlockHeader = newChainHead.newChainHeadHeader();
|
|
+ // AERE D-412 rule D: from H_ev only the decided head D starts a height; a canonical head above D
|
|
+ // is provisional (it may be a block one key forged) and must not move this node's consensus.
|
|
+ if (AereDecidedHook.current().ignoresNewHead(newBlockHeader)) {
|
|
+ LOG.debug(
|
|
+ "AERE D-412: new chain head {} ({}) is not the decided head; consensus stays where it is",
|
|
+ newBlockHeader.getNumber(),
|
|
+ newBlockHeader.getHash());
|
|
+ return;
|
|
+ }
|
|
final QbftBlockHeader currentMiningParent = getCurrentHeightManager().getParentBlockHeader();
|
|
LOG.debug(
|
|
"New chain head detected (block number={})," + " currently mining on top of {}.",
|
|
newBlockHeader.getNumber(),
|
|
currentMiningParent.getNumber());
|
|
if (newBlockHeader.getNumber() < currentMiningParent.getNumber()) {
|
|
LOG.trace(
|
|
"Discarding NewChainHead event, was for previous block height. chainHeight={} eventHeight={}",
|
|
currentMiningParent.getNumber(),
|
|
newBlockHeader.getNumber());
|
|
return;
|
|
}
|
|
|
|
if (newBlockHeader.getNumber() == currentMiningParent.getNumber()) {
|
|
if (newBlockHeader.getHash().equals(currentMiningParent.getHash())) {
|
|
LOG.trace(
|
|
"Discarding duplicate NewChainHead event. chainHeight={} newBlockHash={} parentBlockHash={}",
|
|
newBlockHeader.getNumber(),
|
|
newBlockHeader.getHash(),
|
|
currentMiningParent.getHash());
|
|
@@ -344,43 +385,46 @@ public class QbftController implements QbftEventHandler {
|
|
// Discard all messages which target the BLOCKCHAIN height (which SHOULD be 1 less than
|
|
// the currentHeightManager, but CAN be the same directly following import).
|
|
if (roundExpiry.getView().getSequenceNumber() <= blockchain.getChainHeadBlockNumber()) {
|
|
LOG.debug("Discarding a round-expiry which targets a height not above current chain height.");
|
|
return;
|
|
}
|
|
|
|
if (isMsgForCurrentHeight(roundExpiry.getView(), getCurrentChainHeight())) {
|
|
getCurrentHeightManager().roundExpired(roundExpiry);
|
|
} else {
|
|
LOG.trace(
|
|
"Round expiry event discarded as it is not for current block height chainHeight={} eventHeight={}",
|
|
getCurrentHeightManager().getChainHeight(),
|
|
roundExpiry.getView().getSequenceNumber());
|
|
}
|
|
}
|
|
|
|
private void startNewHeightManager(final QbftBlockHeader parentHeader) {
|
|
createNewHeightManager(parentHeader);
|
|
final long newChainHeight = getCurrentHeightManager().getChainHeight();
|
|
- futureMessageBuffer
|
|
- .retrieveMessagesForHeight(newChainHeight)
|
|
- .forEach(msg -> handleMessage(msg, true));
|
|
+ final List<QbftMessage> aereBuffered =
|
|
+ futureMessageBuffer.retrieveMessagesForHeight(newChainHeight);
|
|
+ aereBuffered.forEach(msg -> handleMessage(msg, true));
|
|
+ // AERE D-412 rule D: the future-message buffer keeps only futureMessagesMaxDistance heights; the
|
|
+ // messages of this height it did not keep are replayed from the collector's raw store.
|
|
+ AereDecidedHook.current().replay(newChainHeight, aereBuffered).forEach(msg -> handleMessage(msg, true));
|
|
}
|
|
|
|
private boolean processMessage(final BftMessage<?> msg, final QbftMessage rawMsg) {
|
|
final ConsensusRoundIdentifier msgRoundIdentifier = msg.getRoundIdentifier();
|
|
if (isMsgForCurrentHeight(msg, getCurrentChainHeight())) {
|
|
return isMsgFromKnownValidator(msg, finalState.getValidators())
|
|
&& finalState.isLocalNodeValidator();
|
|
} else if (isMsgForFutureChainHeight(msg, getCurrentChainHeight())) {
|
|
LOG.trace("Received message for future block height round={}", msgRoundIdentifier);
|
|
futureMessageBuffer.addMessage(msgRoundIdentifier.getSequenceNumber(), rawMsg);
|
|
} else {
|
|
LOG.trace(
|
|
"BFT message discarded as it is from a previous block height messageType={} chainHeight={} eventHeight={}",
|
|
msg.getMessageType(),
|
|
getCurrentHeightManager().getChainHeight(),
|
|
msgRoundIdentifier.getSequenceNumber());
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftRound.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftRound.java
|
|
index 8dc438b412..b4c60810f9 100644
|
|
--- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftRound.java
|
|
+++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftRound.java
|
|
@@ -105,40 +105,57 @@ public class QbftRound {
|
|
// on-chain pre-image, so this is the same hash the parent header will carry once imported.
|
|
private Hash pqOnchainHash;
|
|
|
|
// AERE D-337 (2026-09-28): the post-quantum seals of THIS node's Commit in this round, signed ONCE.
|
|
//
|
|
// Two paths emit this node's Commit: accepting the proposal (the local copy, and the wire copy in
|
|
// the rare case the node is already prepared) and becoming prepared later (the wire copy, the
|
|
// usual case). Each used to sign on its own, so at the parent of an anchor every Besu validator
|
|
// made two SLH-DSA signatures back to back on the consensus thread, the first before its Prepare
|
|
// and the second between "prepared" and its Commit. Measured on 2800 (2026-09-28, import times in
|
|
// ms measured at a reading node of the network): the anchor-parent slot 1,036 ms against
|
|
// 599 for the other slots. The message is fixed by (block, commit hash), both fixed for the round
|
|
// once the proposal is accepted, so the second signing could only produce another valid seal over
|
|
// the same bytes. It now reuses the first, and the local and wire Commits carry the same seals
|
|
// (Falcon is randomised: before this, they carried two different valid Falcon seals).
|
|
//
|
|
// What is NOT reused: an attempt that produced no Falcon seal, or no extras where extras apply.
|
|
// Those are retried exactly as before, so a node whose first attempt failed keeps its second chance.
|
|
private Hash pqSealedCommitHash;
|
|
private Optional<FalconSeal> pqSealedFalcon = Optional.empty();
|
|
+
|
|
+ // AERE 1(b), AERE-R1B-OWNTARGET (decision H9): THE ONE TARGET of this node's own vote in this round. The ECDSA
|
|
+ // commit seal signs its commitDigest, the post-quantum seals sign its pqSealMessage (M_r of THIS round from
|
|
+ // H_r - 1), and the verifier judges every Commit against the same object (MessageValidator through
|
|
+ // AereVoteCounts.Target.of), so the emitter and the verifier cannot compute the message in two ways. Memoised
|
|
+ // per round on the block it was computed for.
|
|
+ private org.hyperledger.besu.consensus.qbft.core.validation.AereVoteCounts.Target pqOwnTarget;
|
|
+ private Hash pqOwnTargetBlock;
|
|
+
|
|
+ // AERE 1(b), H8: whether this node's Commit of this round has been SENT. From H_r - 1 the node's own seal enters
|
|
+ // the seal store only then: a node that merely accepted the proposal (and never got prepared) holds a seal it
|
|
+ // never gave, and counting it would let the store reach Q for a round that never had Q Commits (judgement 1,
|
|
+ // C1). Below H_r the store is the one of before (the own seal enters at acceptance), call by call.
|
|
+ private boolean pqOwnCommitSent = false;
|
|
+ // AERE 1(b): this node's Commit of this round, created at acceptance; from H_r - 1 handed to the decided-head
|
|
+ // evidence only once sent (H8)
|
|
+ private Commit pqLocalCommit;
|
|
private java.util.List<org.hyperledger.besu.consensus.common.bft.SchemeSeal> pqSealedExtras =
|
|
java.util.List.of();
|
|
|
|
/**
|
|
* Instantiates a new Qbft round.
|
|
*
|
|
* @param roundState the round state
|
|
* @param blockCreator the block creator
|
|
* @param blockInterface the block interface
|
|
* @param protocolSchedule the protocol schedule
|
|
* @param observers the observers
|
|
* @param nodeKey the node key
|
|
* @param localAddress the local address
|
|
* @param messageFactory the message factory
|
|
* @param transmitter the transmitter
|
|
* @param roundTimer the round timer
|
|
* @param parentHeader the parent header
|
|
*/
|
|
public QbftRound(
|
|
final RoundState roundState,
|
|
@@ -426,120 +443,140 @@ public class QbftRound {
|
|
*
|
|
* @return the optional PreparedCertificate
|
|
*/
|
|
public Optional<PreparedCertificate> constructPreparedCertificate() {
|
|
return roundState.constructPreparedCertificate();
|
|
}
|
|
|
|
private boolean updateStateWithProposedBlock(final Proposal msg) {
|
|
final boolean wasPrepared = roundState.isPrepared();
|
|
final boolean blockAccepted = roundState.setProposedBlock(msg);
|
|
|
|
if (blockAccepted) {
|
|
final QbftBlock block = roundState.getProposedBlock().get();
|
|
|
|
// AERE hybrid PQC: compute the commit hash once, then produce BOTH the decisive ECDSA commit
|
|
// seal and the parallel Falcon-512 seal over the SAME commit hash. The Falcon seal is gossiped
|
|
// on the commit message so every validator's post-quantum seal reaches the block assembler.
|
|
final Hash commitHash;
|
|
final SECPSignature commitSeal;
|
|
try {
|
|
- commitHash = commitHashFor(block);
|
|
+ commitHash = ownTarget(block).commitDigest();
|
|
commitSeal = nodeKey.sign(Bytes32.wrap(commitHash.getBytes()));
|
|
} catch (final SecurityModuleException e) {
|
|
LOG.warn("Failed to construct commit seal; {}", e.getMessage());
|
|
return true;
|
|
}
|
|
// AERE HYBRID: the Falcon seal and the other schemes' extras, over the SAME message, signed
|
|
// once per round (D-337, pqSealCommitOnce).
|
|
pqSealCommitOnce(block, commitHash);
|
|
final Optional<FalconSeal> falconSeal = pqSealedFalcon;
|
|
final java.util.List<org.hyperledger.besu.consensus.common.bft.SchemeSeal> extraSeals =
|
|
pqSealedExtras;
|
|
|
|
// There are times handling a proposed block is enough to enter prepared.
|
|
if (wasPrepared != roundState.isPrepared()) {
|
|
LOG.debug("Sending commit message. round={}", roundState.getRoundIdentifier());
|
|
if (!extraSeals.isEmpty()) {
|
|
transmitter.multicastCommit(
|
|
getRoundIdentifier(), block.getHash(), commitSeal, falconSeal, extraSeals);
|
|
} else if (falconSeal.isPresent()) {
|
|
transmitter.multicastCommit(getRoundIdentifier(), block.getHash(), commitSeal, falconSeal);
|
|
} else {
|
|
transmitter.multicastCommit(getRoundIdentifier(), block.getHash(), commitSeal);
|
|
}
|
|
+ pqOwnCommitSent = true; // AERE 1(b), H8
|
|
}
|
|
|
|
// can automatically add _our_ commit message to the roundState
|
|
// cannot create a prepare message here, as it may be _our_ proposal, and thus we cannot also
|
|
// prepare
|
|
try {
|
|
final Commit localCommitMessage =
|
|
falconSeal.isPresent()
|
|
? messageFactory.createCommit(
|
|
roundState.getRoundIdentifier(),
|
|
msg.getBlock().getHash(),
|
|
commitSeal,
|
|
falconSeal,
|
|
extraSeals)
|
|
: messageFactory.createCommit(
|
|
roundState.getRoundIdentifier(), msg.getBlock().getHash(), commitSeal);
|
|
roundState.addCommitMessage(localCommitMessage);
|
|
+ // AERE D-412 rule D: kept aside by the decided-head wiring; it becomes evidence only if this
|
|
+ // round commits (a commit of a node that never got prepared is never counted).
|
|
+ // AERE 1(b), H8 for the evidence (review of step 4, 2026-10-01): from H_r - 1 the own Commit carries a seal
|
|
+ // over M_r, and the decided-head proof re-sends what it keeps (the echo on a round change); a Commit that was
|
|
+ // never SENT must not leave the node that way either. So from H_r - 1 it is handed over only once sent (here
|
|
+ // when the proposal already made the node prepared, else in peerIsPrepared). Below H_r: as before (L1).
|
|
+ pqLocalCommit = localCommitMessage;
|
|
+ if (!pqRoundBound(block.getHeader().getNumber()) || pqOwnCommitSent) {
|
|
+ AereDecidedHook.current().ownCommit(localCommitMessage);
|
|
+ }
|
|
} catch (final SecurityModuleException e) {
|
|
LOG.warn("Failed to create signed Commit message; {}", e.getMessage());
|
|
return true;
|
|
}
|
|
|
|
// AERE ANCHOR V2: remember every Falcon seal heard for THIS block, so the proposer of the
|
|
// NEXT block can carry a certificate over it. This is the local node's own seal.
|
|
pqCacheHeardSeals(block);
|
|
|
|
// It is possible sufficient commit seals are now available and the block should be imported
|
|
maybeImportBlock();
|
|
}
|
|
|
|
return blockAccepted;
|
|
}
|
|
|
|
private void peerIsPrepared(final Prepare msg) {
|
|
final boolean wasPrepared = roundState.isPrepared();
|
|
roundState.addPrepareMessage(msg);
|
|
if (wasPrepared != roundState.isPrepared()) {
|
|
LOG.debug("Sending commit message. round={}", roundState.getRoundIdentifier());
|
|
final QbftBlock block = roundState.getProposedBlock().get();
|
|
try {
|
|
- final Hash commitHash = commitHashFor(block);
|
|
+ final Hash commitHash = ownTarget(block).commitDigest();
|
|
final SECPSignature commitSeal = nodeKey.sign(Bytes32.wrap(commitHash.getBytes()));
|
|
// AERE HIBRID: aceleasi sigilii si pe drumul tarziu, ca cele doua locuri sa nu divearga; D-337:
|
|
// chiar ACELEASI, semnate o data la acceptarea propunerii, nu o a doua semnare SLH-DSA aici.
|
|
pqSealCommitOnce(block, commitHash);
|
|
final Optional<FalconSeal> falconSeal = pqSealedFalcon;
|
|
final java.util.List<org.hyperledger.besu.consensus.common.bft.SchemeSeal> extraSeals =
|
|
pqSealedExtras;
|
|
if (!extraSeals.isEmpty()) {
|
|
transmitter.multicastCommit(
|
|
getRoundIdentifier(), block.getHash(), commitSeal, falconSeal, extraSeals);
|
|
} else if (falconSeal.isPresent()) {
|
|
transmitter.multicastCommit(getRoundIdentifier(), block.getHash(), commitSeal, falconSeal);
|
|
} else {
|
|
transmitter.multicastCommit(getRoundIdentifier(), block.getHash(), commitSeal);
|
|
}
|
|
+ // AERE 1(b), H8: the Commit is sent now; from H_r - 1 this is when the node's own seal enters the store
|
|
+ pqOwnCommitSent = true;
|
|
+ if (pqRoundBound(block.getHeader().getNumber())) {
|
|
+ pqCacheHeardSeals(block);
|
|
+ // H8 for the evidence: the own Commit kept at acceptance becomes evidence now that it was sent
|
|
+ if (pqLocalCommit != null) {
|
|
+ AereDecidedHook.current().ownCommit(pqLocalCommit);
|
|
+ }
|
|
+ }
|
|
// Note: the local-node's commit message was added to RoundState on block acceptance
|
|
// and thus does not need to be done again here.
|
|
} catch (final SecurityModuleException e) {
|
|
LOG.warn("Failed to construct a commit seal: {}", e.getMessage());
|
|
}
|
|
}
|
|
}
|
|
|
|
private void peerIsCommitted(final Commit msg) {
|
|
roundState.addCommitMessage(msg);
|
|
// AERE ANCHOR V2: top up the seal cache on EVERY commit, including commits that arrive after
|
|
// this node has already imported the block. Those late seals are exactly the ones that let a
|
|
// proposer reach the threshold K without waiting for its own round to be re-run.
|
|
roundState.getProposedBlock().ifPresent(this::pqCacheHeardSeals);
|
|
if (roundState.getProposedBlock().isEmpty()) {
|
|
pqCacheSealsOfCommitWithoutProposal(msg);
|
|
}
|
|
// AERE hybrid PQC: attempt import on every commit while not yet imported. In the common case
|
|
// this fires exactly once (on the quorum-th commit). Post-fork, if the first attempt lacked a
|
|
// complete Falcon quorum certificate (e.g. one of the quorum's validators had a faulty Falcon
|
|
@@ -612,133 +649,196 @@ public class QbftRound {
|
|
} else {
|
|
LOG.debug(
|
|
"Importing proposed block to chain. round={}, hash={}",
|
|
getRoundIdentifier(),
|
|
blockToImport.getHash());
|
|
}
|
|
|
|
final QbftBlockImporter blockImporter =
|
|
protocolSchedule.getBlockImporter(blockToImport.getHeader());
|
|
final boolean result =
|
|
blockImporter.importBlock(blockToImport, roundState.getProposedBlockAccessList());
|
|
if (!result) {
|
|
// Do NOT set blockImported: a post-fork block whose Falcon quorum certificate is not yet
|
|
// complete can be retried as more commits (with valid Falcon seals) arrive this round.
|
|
LOG.error(
|
|
"Failed to import proposed block to chain. block={} blockHeader={}",
|
|
blockNumber,
|
|
blockToImport.getHeader());
|
|
} else {
|
|
blockImported = true;
|
|
+ // AERE 1(b): Commits of rounds r > 0 heard without the proposal were held aside under their digest; now that the
|
|
+ // block is known, each one whose digest is this block's digest at its round moves under (n, hash, r)
|
|
+ if (pqRoundBound(blockNumber)) {
|
|
+ PqSealCache.instance()
|
|
+ .resolvePending(
|
|
+ blockNumber,
|
|
+ pqOnchainHashOf(blockToImport),
|
|
+ rr ->
|
|
+ org.hyperledger.besu.consensus.qbft.core.validation.AereVoteCounts.Target.atRound(
|
|
+ blockInterface, blockToImport, blockNumber, rr)
|
|
+ .digest());
|
|
+ }
|
|
+ // AERE D-412 rule D: this node's own round committed and its block is in the chain: Q1 of the
|
|
+ // own round moves the decided head (on the wiring's own executor, not on this thread). The round
|
|
+ // is the one that committed: only this round's own commit becomes a vote.
|
|
+ AereDecidedHook.current().ownRoundDecided(blockToImport, getRoundIdentifier().getRoundNumber());
|
|
notifyNewBlockListeners(blockToImport);
|
|
}
|
|
}
|
|
|
|
- private Hash commitHashFor(final QbftBlock block) {
|
|
- final QbftBlock commitBlock = createCommitBlock(block);
|
|
- return commitBlock.getHash();
|
|
+ /**
|
|
+ * AERE 1(b): the target of this node's own vote for {@code block} in this round, computed
|
|
+ * once per round by {@code AereVoteCounts.Target.of}, the function the verifier uses. Replaces the deleted
|
|
+ * commitHashFor and pqSealMessageFor (decision H9).
|
|
+ */
|
|
+ private org.hyperledger.besu.consensus.qbft.core.validation.AereVoteCounts.Target ownTarget(
|
|
+ final QbftBlock block) {
|
|
+ if (pqOwnTarget == null || !block.getHash().equals(pqOwnTargetBlock)) {
|
|
+ pqOwnTarget =
|
|
+ org.hyperledger.besu.consensus.qbft.core.validation.AereVoteCounts.Target.of(
|
|
+ blockInterface, block, getRoundIdentifier());
|
|
+ pqOwnTargetBlock = block.getHash();
|
|
+ }
|
|
+ return pqOwnTarget;
|
|
+ }
|
|
+
|
|
+ /** AERE 1(b): whether the commit seals of height n are round-bound (the one decider, PqAnchorProducer). */
|
|
+ private static boolean pqRoundBound(final long blockNumber) {
|
|
+ return PqAnchorProducer.commitSealFormAt(PqAnchorProducer.config(), blockNumber)
|
|
+ == PqAnchorProducer.CommitSealForm.ROUND_BOUND;
|
|
}
|
|
|
|
/**
|
|
* AERE ANCHOR V2: remember the Falcon seals heard for a block, keyed on its ROUND-INDEPENDENT
|
|
* on-chain hash, which is the key the producer of the next block looks under. Cheap and
|
|
* idempotent: the cache keeps the first seal seen per validator index.
|
|
*/
|
|
/**
|
|
* D-339 (2026-09-04): keep the seals of a Commit even when this node has NO proposal for the
|
|
* round, keyed on the digest the Commit itself names.
|
|
*
|
|
* <p>Why, measured on chain 2800 the same evening: the proposer of an anchor kept refusing with
|
|
* "this node holds 1 valid eligible Falcon seal ... 0 rejected" - it was not rejecting seals, it
|
|
* had never heard them. The path above caches only when the round holds the proposed block, so a
|
|
* node that missed the proposal of the parent's round (or imported that block by any route other
|
|
* than its own round) collected the Commits and threw their seals away. It then could not build
|
|
* the certificate of the next anchor, the round expired, and every 32nd height paid the
|
|
* round-change timeout. Eleven of twelve anchors measured before this fix.
|
|
*
|
|
* <p>Safety: only the seal is copied, never the message; the digest is the one the Commit names,
|
|
* so a losing round writes an entry under a hash that never becomes canonical and is simply never
|
|
* looked up; and the producer Falcon-verifies every cached seal against the anchored registry
|
|
* before carrying it, so a seal that lies about its index still cannot reach a header.
|
|
*
|
|
* @param msg the commit whose seals are kept
|
|
*/
|
|
private void pqCacheSealsOfCommitWithoutProposal(final Commit msg) {
|
|
final long height = roundState.getRoundIdentifier().getSequenceNumber();
|
|
+ final int r = msg.getRoundIdentifier().getRoundNumber();
|
|
+ final java.util.List<org.hyperledger.besu.consensus.common.bft.SchemeSeal> extras =
|
|
+ msg.getExtraSeals();
|
|
+ // AERE 1(b): from H_r - 1, at a round r > 0 the digest the Commit names is not the on-chain hash; the seals are
|
|
+ // held aside under it and moved under (n, hash, r) when the block is imported (resolvePending). At r = 0, and
|
|
+ // below H_r at every round, the store of before, call by call (the round is ignored below H_r).
|
|
+ if (r > 0 && pqRoundBound(height)) {
|
|
+ PqSealCache.instance()
|
|
+ .recordPendingRound(
|
|
+ height,
|
|
+ msg.getDigest(),
|
|
+ r,
|
|
+ msg.getAuthor(),
|
|
+ msg.getFalconSeal().map(java.util.List::of).orElse(java.util.List.of()),
|
|
+ extras);
|
|
+ return;
|
|
+ }
|
|
msg.getFalconSeal()
|
|
.ifPresent(
|
|
seal ->
|
|
PqSealCache.instance()
|
|
- .record(height, msg.getDigest(), java.util.List.of(seal)));
|
|
- final java.util.List<org.hyperledger.besu.consensus.common.bft.SchemeSeal> extras =
|
|
- msg.getExtraSeals();
|
|
+ .record(height, msg.getDigest(), r, java.util.List.of(seal)));
|
|
if (!extras.isEmpty()) {
|
|
- PqSealCache.instance().recordExtras(height, msg.getDigest(), extras);
|
|
+ PqSealCache.instance().recordExtras(height, msg.getDigest(), r, extras);
|
|
}
|
|
}
|
|
|
|
private void pqCacheHeardSeals(final QbftBlock block) {
|
|
- final Collection<FalconSeal> seals = roundState.getFalconSeals();
|
|
+ Collection<FalconSeal> seals = roundState.getFalconSeals();
|
|
if (seals.isEmpty()) {
|
|
return;
|
|
}
|
|
+ final long n = block.getHeader().getNumber();
|
|
+ final int r = getRoundIdentifier().getRoundNumber();
|
|
+ java.util.List<org.hyperledger.besu.consensus.common.bft.SchemeSeal> extras =
|
|
+ roundState.getExtraSeals();
|
|
+ // AERE 1(b), H8: from H_r - 1 the node's OWN seal is kept out of the store until its Commit was sent
|
|
+ if (pqRoundBound(n) && !pqOwnCommitSent && pqSealedFalcon.isPresent()) {
|
|
+ final int own = pqSealedFalcon.get().getValidatorIndex();
|
|
+ seals = seals.stream().filter(s -> s.getValidatorIndex() != own).toList();
|
|
+ extras = extras.stream().filter(s -> s.getValidatorIndex() != own).toList();
|
|
+ if (seals.isEmpty()) {
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
final Hash onchain = pqOnchainHashOf(block);
|
|
- PqSealCache.instance().record(block.getHeader().getNumber(), onchain, seals);
|
|
+ PqSealCache.instance().record(n, onchain, r, seals);
|
|
// AERE ANCHOR V2: the extra scheme seals ride the same commits and go under the same key.
|
|
- final java.util.List<org.hyperledger.besu.consensus.common.bft.SchemeSeal> extras =
|
|
- roundState.getExtraSeals();
|
|
if (!extras.isEmpty()) {
|
|
- PqSealCache.instance().recordExtras(block.getHeader().getNumber(), onchain, extras);
|
|
+ PqSealCache.instance().recordExtras(n, onchain, r, extras);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* AERE ANCHOR V2: the round-independent on-chain hash of the block this round is deciding,
|
|
* computed once per round. Replacing the round with 0 in the committed-seal encoding produces
|
|
* byte-for-byte the on-chain pre-image, because that encoding differs from the on-chain one only
|
|
* by writing the real round instead of a forced zero.
|
|
*/
|
|
private Hash pqOnchainHashOf(final QbftBlock block) {
|
|
if (pqOnchainHash == null) {
|
|
pqOnchainHash = blockInterface.replaceRoundForCommitBlock(block, 0).getHash();
|
|
}
|
|
return pqOnchainHash;
|
|
}
|
|
|
|
/**
|
|
* AERE HIBRID (2026-08-25): the non-Falcon seals of this node's hybrid certificate, over the
|
|
* SAME message the Falcon seal signs (the two are one certificate; two messages would be two
|
|
* certificates and the verifier could not bind them). Empty on every node that is not
|
|
* hybrid-configured, and below the emission gate: {@link HybridSealProducer} never throws and
|
|
* never emits half a certificate.
|
|
*/
|
|
java.util.List<org.hyperledger.besu.consensus.common.bft.SchemeSeal> extraSealsFor(
|
|
final QbftBlock block, final Hash commitHash) {
|
|
// ANCHOR PARENTS ONLY (2026-09-03, D-329): an SLH-DSA-128s signature costs seconds here; it is
|
|
// only ever used in the next anchor's certificate, which is built over the anchor's parent. So
|
|
// the extras are signed only when the block being committed is the parent of an anchor height.
|
|
// The same predicate gates the enforcement (PqCommitEnforcement.anchorParentByConfig).
|
|
final long number = block.getHeader().getNumber();
|
|
if (!pqExtrasApplyAt(number)) {
|
|
return java.util.List.of();
|
|
}
|
|
- return hybridExtrasOrEmpty(number, pqSealMessageFor(block, commitHash));
|
|
+ // 1(b): no message (a round outside 0..1024 at a round-bound height) means no extras (R-03)
|
|
+ return ownTarget(block)
|
|
+ .pqSealMessage()
|
|
+ .map(message -> hybridExtrasOrEmpty(number, Bytes32.wrap(message.getBytes())))
|
|
+ .orElse(java.util.List.of());
|
|
}
|
|
|
|
/** The anchor-parent predicate of {@link #extraSealsFor}, in one place for it and the D-337 reuse. */
|
|
static boolean pqExtrasApplyAt(final long number) {
|
|
return org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer.config()
|
|
.anchorAppliesAt(number + 1L);
|
|
}
|
|
|
|
/**
|
|
* D-337 (2026-09-28): signs this node's Commit seals for this round at most once. A result is
|
|
* reused only when it is complete - a Falcon seal, and the extras wherever extras apply - so an
|
|
* attempt that failed is retried on the next path exactly as before this change.
|
|
*
|
|
* <p>Package-private, with {@link #falconSealFor} and {@link #extraSealsFor}, for the probe that
|
|
* counts the signings on the two paths (PqCommitSealsSignedOnceTest).
|
|
*
|
|
* @param block the proposed block of this round
|
|
* @param commitHash its commit hash in this round
|
|
*/
|
|
void pqSealCommitOnce(final QbftBlock block, final Hash commitHash) {
|
|
@@ -765,62 +865,65 @@ public class QbftRound {
|
|
* @param number the height being committed
|
|
* @param message the seal message
|
|
* @return the extras, or an empty list with an ERROR line when the hybrid support cannot sign
|
|
*/
|
|
static java.util.List<org.hyperledger.besu.consensus.common.bft.SchemeSeal> hybridExtrasOrEmpty(
|
|
final long number, final Bytes32 message) {
|
|
try {
|
|
return org.hyperledger.besu.consensus.common.bft.HybridSealSupport.instance()
|
|
.producer()
|
|
.sealsFor(number, message);
|
|
} catch (final RuntimeException e) {
|
|
LOG.error(
|
|
"AERE HIBRID: extras NOT signed at height {} - {}. This node keeps voting but contributes no"
|
|
+ " SLH-DSA seal until the hybrid configuration is repaired (D-334).",
|
|
number,
|
|
e.getMessage());
|
|
return java.util.List.of();
|
|
}
|
|
}
|
|
|
|
- /** The exact bytes a PQ seal over this block signs; shared by Falcon and the hybrid extras,
|
|
- * so the two halves of a hybrid certificate can never drift onto different messages. */
|
|
- private Bytes32 pqSealMessageFor(final QbftBlock block, final Hash commitHash) {
|
|
- // AERE D-311 (2026-09-02): the form is decided in ONE place, shared with the verifier
|
|
- // (MessageValidator.SubsequentMessageValidator). A second copy of this rule drifted once and
|
|
- // stopped a chain; see PqAnchorProducer.commitSealMessage.
|
|
- return PqAnchorProducer.commitSealMessage(
|
|
- block.getHeader().getNumber(), () -> pqOnchainHashOf(block).getBytes(), commitHash);
|
|
- }
|
|
|
|
Optional<FalconSeal> falconSealFor(final QbftBlock block, final Hash commitHash) {
|
|
// FalconSealSupport.sign never throws (any fault is swallowed and logged), and returns empty
|
|
// when this node holds no Falcon signing key, so the ECDSA commit path is never affected.
|
|
//
|
|
// AERE FIX-OPRIRE-CONSENS (b): the block NUMBER is now a mandatory argument. Seal ATTACHMENT is
|
|
// gated on the activation height (and on registry coverage of the whole validator set) inside
|
|
// FalconSealSupport.sign, so merely holding a Falcon key no longer makes a node emit a
|
|
// Falcon-carrying Commit. There is deliberately no height-less sign() overload left: a call site
|
|
// physically cannot bypass the gate.
|
|
//
|
|
// AERE ANCHOR V2: WHAT IS SIGNED changes one block BEFORE the anchor activates, because the
|
|
// certificate carried by block H is made of seals over block H-1. From that height the message
|
|
// is M = keccak256(RLP["AERE-PQ-COMMIT-1", chainId, number, ON-CHAIN block hash]) instead of the
|
|
// ECDSA committed-seal hash. The committed-seal hash could not be used: it includes the ROUND,
|
|
// which is not in the block-hash pre-image, so a validator holding only the parent header could
|
|
// not rebuild it. Every node flips at the same height, since the height is a pure function of
|
|
// the same configured H; a node configured with a different H emits seals nobody can use, and
|
|
// the producer drops them on verification rather than carrying them into a header.
|
|
- // AERE HIBRID (2026-08-25): mesajul se calculeaza acum intr-UN singur loc, pqSealMessageFor,
|
|
- // impartit cu extrasele hibride; doua copii ale acestei logici ar fi divergat intr-o zi.
|
|
+ // AERE HIBRID (2026-08-25): mesajul se calcula intr-UN singur loc, pqSealMessageFor, impartit cu extrasele
|
|
+ // hibride; din 1(b) (2026-10-01) locul acela e tinta unica ownTarget, aceeasi pe care o judeca verificatorul.
|
|
final long blockNumber = block.getHeader().getNumber();
|
|
- return FalconSealSupport.instance().sign(blockNumber, pqSealMessageFor(block, commitHash));
|
|
+ // AERE 1(b): the message of the one target (H9); empty at a round outside 0..1024 (AERE-PQ-COMMIT-R-03)
|
|
+ return ownTarget(block)
|
|
+ .pqSealMessage()
|
|
+ .flatMap(message -> pqSign(blockNumber, Bytes32.wrap(message.getBytes())));
|
|
}
|
|
|
|
- private QbftBlock createCommitBlock(final QbftBlock block) {
|
|
- return blockInterface.replaceRoundForCommitBlock(block, getRoundIdentifier().getRoundNumber());
|
|
+ /**
|
|
+ * The one call that signs this node's Falcon commit seal, over the message {@link #falconSealFor} took from the one
|
|
+ * target. Package-private so the emitter probe (AereRoundBoundEmitterTest) can see WHICH message is signed, on the
|
|
+ * real state machine, instead of stubbing the whole seal (review of step 4).
|
|
+ *
|
|
+ * @param blockNumber the height being committed
|
|
+ * @param message the message to sign
|
|
+ * @return the seal, or empty when this node holds no Falcon key or the attachment gate is closed
|
|
+ */
|
|
+ Optional<FalconSeal> pqSign(final long blockNumber, final Bytes32 message) {
|
|
+ return FalconSealSupport.instance().sign(blockNumber, message);
|
|
}
|
|
|
|
private void notifyNewBlockListeners(final QbftBlock block) {
|
|
observers.forEach(obs -> obs.blockMined(block));
|
|
}
|
|
}
|
|
diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/types/QbftBlockHeader.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/types/QbftBlockHeader.java
|
|
index e3bf30e3a4..c748b4b84e 100644
|
|
--- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/types/QbftBlockHeader.java
|
|
+++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/types/QbftBlockHeader.java
|
|
@@ -1,50 +1,66 @@
|
|
/*
|
|
* Copyright contributors to Besu.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
+ *
|
|
+ * Modifications Copyright contributors to the Aere Network.
|
|
+ *
|
|
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0010-aere-pq-round-bound-commit-seal.patch.
|
|
*/
|
|
package org.hyperledger.besu.consensus.qbft.core.types;
|
|
|
|
import org.hyperledger.besu.datatypes.Address;
|
|
import org.hyperledger.besu.datatypes.Hash;
|
|
|
|
/** Represents a block header in the context of the QBFT consensus mechanism. */
|
|
public interface QbftBlockHeader {
|
|
|
|
/**
|
|
* Returns the block number of the block.
|
|
*
|
|
* @return the block number.
|
|
*/
|
|
long getNumber();
|
|
|
|
/**
|
|
* Returns the timestamp of the block.
|
|
*
|
|
* @return the timestamp.
|
|
*/
|
|
long getTimestamp();
|
|
|
|
/**
|
|
* Returns the coinbase of the block.
|
|
*
|
|
* @return the coinbase.
|
|
*/
|
|
Address getCoinbase();
|
|
|
|
/**
|
|
* Returns the hash of the block.
|
|
*
|
|
* @return the hash.
|
|
*/
|
|
Hash getHash();
|
|
+
|
|
+ /**
|
|
+ * Returns the hash of the parent block, when this header wraps a real one. AERE D-437 (2026-09-29): from AIP-22
|
|
+ * stage 5 a proposal must extend the decided head of its height, so the proposal validator needs the parent.
|
|
+ *
|
|
+ * @return the parent hash, or null when this header does not know it (such a proposal is refused from stage 5)
|
|
+ */
|
|
+ default Hash getParentHash() {
|
|
+ return null;
|
|
+ }
|
|
}
|
|
diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/AereVoteCounts.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/AereVoteCounts.java
|
|
new file mode 100644
|
|
index 0000000000..460a11476f
|
|
--- /dev/null
|
|
+++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/AereVoteCounts.java
|
|
@@ -0,0 +1,330 @@
|
|
+/*
|
|
+ * AERE D-412 / capul decis (regula D), pasul 1: THE ONE PLACE that decides whether a Commit counts
|
|
+ * toward a quorum.
|
|
+ *
|
|
+ * WHY IT EXISTS. Until now the only code that decided "this Commit counts" was the body of
|
|
+ * CommitValidator.validate, bound to the one (height, round, digest) of the round that built it.
|
|
+ * The decided-head design (PROIECT-CAP-DECIS-2026-09-29.md, section 1) needs the SAME predicate in
|
|
+ * a second place: the decision-evidence collector judges commits of rounds the node never ran, on
|
|
+ * blocks it only heard about. The paid-for lesson of D-311 is that two copies of one consensus rule
|
|
+ * drift in silence (the emitter and the verifier of the PQ seal message did, and the testnet
|
|
+ * stopped). So the predicate is EXTRACTED here, parametrized on the target (height, round, the
|
|
+ * voted digest and the two digests derived from it), and CommitValidator now calls it; it is not
|
|
+ * copied.
|
|
+ *
|
|
+ * WHAT IT DECIDES, in the order CommitValidator always decided it, with the same refusal texts:
|
|
+ * the message author is in the set; the payload targets the round; the payload carries the voted
|
|
+ * digest; the ECDSA committed seal recovers (through AerePqIdentity from H_id) to the message
|
|
+ * author; and, when enforcement is supplied, the post-quantum seal(s) pass PqCommitEnforcement over
|
|
+ * the seal message PqAnchorProducer.commitSealMessage names at that height.
|
|
+ *
|
|
+ * 2026-09-30 (review of step 1): judge() returns the same verdict with its kind, so the collector can
|
|
+ * tell a refusal of the MESSAGE (final) from a refusal of the REGISTRY STATE (a late-anchor registry
|
|
+ * still PENDING, D-358), which must not be remembered as final. refusal() is judge(), text only.
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft.core.validation;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AerePqIdentity;
|
|
+import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorV3;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.common.bft.payload.SignedData;
|
|
+import org.hyperledger.besu.consensus.qbft.core.payload.CommitPayload;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.core.Util;
|
|
+
|
|
+import java.util.Collection;
|
|
+import java.util.Objects;
|
|
+import java.util.Optional;
|
|
+
|
|
+/** The shared vote-counting predicate for QBFT Commit messages (AERE D-412, regula D). */
|
|
+public final class AereVoteCounts {
|
|
+
|
|
+ private AereVoteCounts() {}
|
|
+
|
|
+ /**
|
|
+ * What a Commit is judged against: a height and round, the voted (message) digest of the block
|
|
+ * at that round, the ECDSA committed-seal digest, and the message the post-quantum seal signs.
|
|
+ */
|
|
+ public static final class Target {
|
|
+ private final ConsensusRoundIdentifier round;
|
|
+ private final Hash digest;
|
|
+ private final Hash commitDigest;
|
|
+ private final Optional<Hash> pqSealMessage;
|
|
+
|
|
+ /**
|
|
+ * PRIVATE since 1(b) (2026-10-01, decision H9): the emitter and every verifier get a target only
|
|
+ * through {@link #of} or {@link #atRound}, so the message the post-quantum seal signs is computed in
|
|
+ * one place, with the round of the target. An empty PQ message means a round-bound height with a
|
|
+ * round outside 0..1024: no PQ seal exists there, and {@link AereVoteCounts#judge} refuses a vote
|
|
+ * under armed enforcement with {@code AERE-PQ-COMMIT-R-03}, never with an exception.
|
|
+ */
|
|
+ private Target(
|
|
+ final ConsensusRoundIdentifier round,
|
|
+ final Hash digest,
|
|
+ final Hash commitDigest,
|
|
+ final Optional<Hash> pqSealMessage) {
|
|
+ this.round = Objects.requireNonNull(round, "round");
|
|
+ this.digest = Objects.requireNonNull(digest, "digest");
|
|
+ this.commitDigest = Objects.requireNonNull(commitDigest, "commitDigest");
|
|
+ this.pqSealMessage = Objects.requireNonNull(pqSealMessage, "pqSealMessage");
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The target CommitValidator's upstream-shaped constructors build from explicit hashes, for the
|
|
+ * probes inherited from upstream Besu only; production code builds targets with {@link #of}. A
|
|
+ * gate counts the production callers of those constructors (zero).
|
|
+ *
|
|
+ * @param round the height and round the commit must target
|
|
+ * @param digest the digest the commit payload must carry
|
|
+ * @param commitDigest the digest the ECDSA committed seal signs at this round
|
|
+ * @param pqSealMessage the message the post-quantum seal must have signed
|
|
+ * @return the target
|
|
+ */
|
|
+ static Target explicit(
|
|
+ final ConsensusRoundIdentifier round,
|
|
+ final Hash digest,
|
|
+ final Hash commitDigest,
|
|
+ final Hash pqSealMessage) {
|
|
+ return new Target(
|
|
+ round, digest, commitDigest, Optional.of(Objects.requireNonNull(pqSealMessage, "pq")));
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The target of a vote for {@code proposalBlock} at {@code round}, computed exactly as the
|
|
+ * production validator (MessageValidator.SubsequentMessageValidator) computes it: the commit
|
|
+ * digest from the round-replaced block, the PQ seal message from the one helper the emitter
|
|
+ * also uses, with the round-0 (on-chain) hash supplied lazily.
|
|
+ *
|
|
+ * @param blockInterface the block interface that replaces the round
|
|
+ * @param proposalBlock the block voted for, in its proposal form at this round
|
|
+ * @param round the height and round
|
|
+ * @return the target
|
|
+ */
|
|
+ public static Target of(
|
|
+ final QbftBlockInterface blockInterface,
|
|
+ final QbftBlock proposalBlock,
|
|
+ final ConsensusRoundIdentifier round) {
|
|
+ final QbftBlock commitBlock =
|
|
+ blockInterface.replaceRoundForCommitBlock(proposalBlock, round.getRoundNumber());
|
|
+ // 1(b): the round of the TARGET goes into the message (COMMIT-2 from H_r - 1); the round-0
|
|
+ // on-chain hash stays lazy, so below the anchor form nothing is re-encoded (L1)
|
|
+ final Optional<Hash> pqSealMessage =
|
|
+ PqAnchorProducer.commitSealMessage(
|
|
+ round.getSequenceNumber(),
|
|
+ () ->
|
|
+ blockInterface
|
|
+ .replaceRoundForCommitBlock(proposalBlock, 0)
|
|
+ .getHash()
|
|
+ .getBytes(),
|
|
+ commitBlock.getHash(),
|
|
+ round.getRoundNumber())
|
|
+ .map(Hash::wrap);
|
|
+ return new Target(round, proposalBlock.getHash(), commitBlock.getHash(), pqSealMessage);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The target of a vote for the block {@code anyForm} (stored, or a proposal of any round) at
|
|
+ * the given round: the block is first put in its proposal form at that round. This is the
|
|
+ * parametrization the decision-evidence collector needs; it goes through {@link #of}.
|
|
+ *
|
|
+ * @param blockInterface the block interface that replaces the round
|
|
+ * @param anyForm the block in any round form
|
|
+ * @param height the block height
|
|
+ * @param roundNumber the round
|
|
+ * @return the target
|
|
+ */
|
|
+ public static Target atRound(
|
|
+ final QbftBlockInterface blockInterface,
|
|
+ final QbftBlock anyForm,
|
|
+ final long height,
|
|
+ final int roundNumber) {
|
|
+ return of(
|
|
+ blockInterface,
|
|
+ blockInterface.replaceRoundForCommitBlock(anyForm, roundNumber),
|
|
+ new ConsensusRoundIdentifier(height, roundNumber));
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The height and round.
|
|
+ *
|
|
+ * @return the round identifier
|
|
+ */
|
|
+ public ConsensusRoundIdentifier round() {
|
|
+ return round;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The voted (message) digest, round included.
|
|
+ *
|
|
+ * @return the digest
|
|
+ */
|
|
+ public Hash digest() {
|
|
+ return digest;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The ECDSA committed-seal digest.
|
|
+ *
|
|
+ * @return the commit digest
|
|
+ */
|
|
+ public Hash commitDigest() {
|
|
+ return commitDigest;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The message the post-quantum seal signs.
|
|
+ *
|
|
+ * @return the PQ seal message; empty only at a round-bound height with a round outside 0..1024
|
|
+ */
|
|
+ public Optional<Hash> pqSealMessage() {
|
|
+ return pqSealMessage;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The verdict of the predicate with its kind (2026-09-30): a refusal that comes from the message and
|
|
+ * the set is FINAL for that message, target and set; one that comes from the state of the PQ
|
|
+ * registry (PqCommitEnforcement.Refusal#dependsOnRegistryState) may change at run time, so a
|
|
+ * collector that remembers verdicts must not remember it as final.
|
|
+ */
|
|
+ public static final class Judgement {
|
|
+ private static final Judgement COUNTS = new Judgement(Optional.empty(), false);
|
|
+
|
|
+ private final Optional<String> refusal;
|
|
+ private final boolean dependsOnRegistryState;
|
|
+
|
|
+ private Judgement(final Optional<String> refusal, final boolean dependsOnRegistryState) {
|
|
+ this.refusal = refusal;
|
|
+ this.dependsOnRegistryState = dependsOnRegistryState;
|
|
+ }
|
|
+
|
|
+ private static Judgement refused(final String text) {
|
|
+ return new Judgement(Optional.of(text), false);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Whether the commit counts.
|
|
+ *
|
|
+ * @return true when it counts
|
|
+ */
|
|
+ public boolean counts() {
|
|
+ return refusal.isEmpty();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The refusal, in CommitValidator's words.
|
|
+ *
|
|
+ * @return the refusal, or empty when the commit counts
|
|
+ */
|
|
+ public Optional<String> refusal() {
|
|
+ return refusal;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Whether this refusal can change with the state of the PQ registry (never true for a count).
|
|
+ *
|
|
+ * @return true for a registry-dependent refusal
|
|
+ */
|
|
+ public boolean dependsOnRegistryState() {
|
|
+ return dependsOnRegistryState;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Does this Commit count toward the quorum of {@code target}?
|
|
+ *
|
|
+ * @param signedPayload the signed commit (its author is the recovered author of the message)
|
|
+ * @param validators the validator set that decides the voted height
|
|
+ * @param target the height, round and digests the commit must match
|
|
+ * @param pqEnforcement the height-gated PQ enforcement, or null for upstream behaviour
|
|
+ * @return empty when the commit counts; otherwise the refusal, in CommitValidator's words
|
|
+ */
|
|
+ public static Optional<String> refusal(
|
|
+ final SignedData<CommitPayload> signedPayload,
|
|
+ final Collection<Address> validators,
|
|
+ final Target target,
|
|
+ final PqCommitEnforcement pqEnforcement) {
|
|
+ return judge(signedPayload, validators, target, pqEnforcement).refusal();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The one predicate, with the kind of its refusal. {@link #refusal} is exactly this, text only.
|
|
+ *
|
|
+ * @param signedPayload the signed commit (its author is the recovered author of the message)
|
|
+ * @param validators the validator set that decides the voted height
|
|
+ * @param target the height, round and digests the commit must match
|
|
+ * @param pqEnforcement the height-gated PQ enforcement, or null for upstream behaviour
|
|
+ * @return the judgement
|
|
+ */
|
|
+ public static Judgement judge(
|
|
+ final SignedData<CommitPayload> signedPayload,
|
|
+ final Collection<Address> validators,
|
|
+ final Target target,
|
|
+ final PqCommitEnforcement pqEnforcement) {
|
|
+ if (!validators.contains(signedPayload.getAuthor())) {
|
|
+ return Judgement.refused("did not originate from a recognized validator.");
|
|
+ }
|
|
+
|
|
+ final CommitPayload payload = signedPayload.getPayload();
|
|
+ final ConsensusRoundIdentifier targetRound = target.round();
|
|
+
|
|
+ if (!payload.getRoundIdentifier().equals(targetRound)) {
|
|
+ return Judgement.refused(
|
|
+ "did not target expected round " + targetRound + " was " + payload.getRoundIdentifier());
|
|
+ }
|
|
+
|
|
+ if (!payload.getDigest().equals(target.digest())) {
|
|
+ return Judgement.refused(
|
|
+ "did not contain expected digest " + target.digest() + " was " + payload.getDigest());
|
|
+ }
|
|
+
|
|
+ final Address commitSealCreator =
|
|
+ AerePqIdentity.author(
|
|
+ Util.signatureToAddress(payload.getCommitSeal(), target.commitDigest()),
|
|
+ targetRound.getSequenceNumber());
|
|
+
|
|
+ if (!commitSealCreator.equals(signedPayload.getAuthor())) {
|
|
+ return Judgement.refused(
|
|
+ "Seal was not created by the message transmitter "
|
|
+ + commitSealCreator
|
|
+ + " was "
|
|
+ + signedPayload.getAuthor());
|
|
+ }
|
|
+
|
|
+ // AERE full-PQ: above the arming height a commit vote only counts with a valid post-quantum
|
|
+ // seal bound to this very author. Below it (or with no enforcement supplied) nothing changes.
|
|
+ if (pqEnforcement != null) {
|
|
+ if (target.pqSealMessage().isEmpty()) {
|
|
+ // 1(b): a round-bound height with a round outside 0..1024 has no PQ message at all. Under armed
|
|
+ // enforcement that vote cannot count (a FINAL refusal: it depends on the message, not on the
|
|
+ // registry); unarmed, nothing changes, as for every other PQ question.
|
|
+ return pqEnforcement.armedAt(targetRound.getSequenceNumber())
|
|
+ ? Judgement.refused(
|
|
+ PqAnchorV3.COMMIT_R_03
|
|
+ + ": commit at height "
|
|
+ + targetRound.getSequenceNumber()
|
|
+ + " round "
|
|
+ + targetRound.getRoundNumber()
|
|
+ + " has no round-bound post-quantum message (rounds 0.."
|
|
+ + PqAnchorV3.MAX_ROUND
|
|
+ + ") - the vote does not count")
|
|
+ : Judgement.COUNTS;
|
|
+ }
|
|
+ return pqEnforcement
|
|
+ .judge(
|
|
+ targetRound.getSequenceNumber(),
|
|
+ signedPayload.getAuthor(),
|
|
+ target.pqSealMessage().get(),
|
|
+ payload.getFalconSeal(),
|
|
+ payload.getExtraSeals())
|
|
+ .map(r -> new Judgement(Optional.of(r.text()), r.dependsOnRegistryState()))
|
|
+ .orElse(Judgement.COUNTS);
|
|
+ }
|
|
+
|
|
+ return Judgement.COUNTS;
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/CommitValidator.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/CommitValidator.java
|
|
index 680c53f44a..fb44246fb7 100644
|
|
--- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/CommitValidator.java
|
|
+++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/CommitValidator.java
|
|
@@ -2,74 +2,73 @@
|
|
* Copyright 2020 ConsenSys AG.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
* found, as section 4(c) requires. The change: an OPTIONAL, height-gated post-quantum enforcement
|
|
* hook (see PqCommitEnforcement). When no enforcement is supplied, behaviour is byte-for-byte the
|
|
* upstream behaviour; the existing constructor keeps that contract for every existing caller.
|
|
+ * AERE D-412 (2026-09-29, regula D pasul 1): the body of validate() moved, unchanged in order
|
|
+ * and in its refusal texts, into AereVoteCounts.refusal, parametrized on (height, round, digest),
|
|
+ * so the decision-evidence collector counts a Commit with this very predicate, not a copy.
|
|
*/
|
|
package org.hyperledger.besu.consensus.qbft.core.validation;
|
|
|
|
-import org.hyperledger.besu.consensus.common.bft.AerePqIdentity;
|
|
import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
|
import org.hyperledger.besu.consensus.common.bft.payload.SignedData;
|
|
import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit;
|
|
import org.hyperledger.besu.consensus.qbft.core.payload.CommitPayload;
|
|
import org.hyperledger.besu.datatypes.Address;
|
|
import org.hyperledger.besu.datatypes.Hash;
|
|
-import org.hyperledger.besu.ethereum.core.Util;
|
|
|
|
import java.util.Collection;
|
|
import java.util.Optional;
|
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
/** The Commit validator. */
|
|
public class CommitValidator {
|
|
|
|
private static final String ERROR_PREFIX = "Invalid Commit Message";
|
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(CommitValidator.class);
|
|
|
|
private final Collection<Address> validators;
|
|
- private final ConsensusRoundIdentifier targetRound;
|
|
- private final Hash expectedDigest;
|
|
- private final Hash expectedCommitDigest;
|
|
- // AERE D-311 (2026-09-02): the message the post-quantum seal must have signed. It is NOT always
|
|
- // the committed-seal digest: once the anchor is armed the emitter signs the anchor form (see
|
|
- // PqAnchorProducer.commitSealMessage). The upstream-shaped constructors keep the digest, so no
|
|
- // existing caller changes behaviour; the production path (MessageValidator) passes the real one.
|
|
- private final Hash expectedPqSealMessage;
|
|
+ // AERE D-311 (2026-09-02): the target carries the message the post-quantum seal must have
|
|
+ // signed. It is NOT always the committed-seal digest: once the anchor is armed the emitter signs
|
|
+ // the anchor form (see PqAnchorProducer.commitSealMessage). The upstream-shaped constructors keep
|
|
+ // the digest, so no existing caller changes behaviour; the production path (MessageValidator)
|
|
+ // passes the real one. AERE D-412: round and digests live in one AereVoteCounts.Target.
|
|
+ private final AereVoteCounts.Target target;
|
|
// AERE full-PQ: optional height-gated enforcement. Null means "upstream behaviour", which is
|
|
// exactly what the pre-existing constructor supplies, so nothing changes for existing callers.
|
|
private final PqCommitEnforcement pqEnforcement;
|
|
|
|
/**
|
|
* Instantiates a new Commit validator, self-wiring the AERE post-quantum enforcement from the
|
|
* system configuration.
|
|
*
|
|
* <p>With {@code aere.pq.commitPq.forkBlock} absent -- every fleet node today, and every test
|
|
* JVM -- this is byte-for-byte the upstream behaviour. With it set, commits at or above that
|
|
* height only count with a valid post-quantum seal of their own author. A present but broken
|
|
* value refuses loudly here rather than silently disarming.
|
|
*
|
|
* @param validators the validators
|
|
* @param targetRound the target round
|
|
* @param expectedDigest the expected digest
|
|
* @param expectedCommitDigest the expected commit digest
|
|
*/
|
|
public CommitValidator(
|
|
final Collection<Address> validators,
|
|
@@ -119,124 +118,107 @@ public class CommitValidator {
|
|
* author and whose signature verifies over the commit digest. A vote without valid PQ does not
|
|
* count toward quorum.
|
|
*
|
|
* @param validators the validators
|
|
* @param targetRound the target round
|
|
* @param expectedDigest the expected digest
|
|
* @param expectedCommitDigest the expected commit digest
|
|
* @param pqEnforcement the height-gated enforcement, or null for upstream behaviour
|
|
*/
|
|
public CommitValidator(
|
|
final Collection<Address> validators,
|
|
final ConsensusRoundIdentifier targetRound,
|
|
final Hash expectedDigest,
|
|
final Hash expectedCommitDigest,
|
|
final PqCommitEnforcement pqEnforcement) {
|
|
this(validators, targetRound, expectedDigest, expectedCommitDigest, expectedCommitDigest, pqEnforcement);
|
|
}
|
|
|
|
/** AERE D-311: the message the post-quantum seal must have signed; for the plumbing proof only. */
|
|
@com.google.common.annotations.VisibleForTesting
|
|
- Hash expectedPqSealMessageForTesting() {
|
|
- return expectedPqSealMessage;
|
|
+ Optional<Hash> expectedPqSealMessageForTesting() {
|
|
+ return target.pqSealMessage();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * AERE 1(b) (2026-10-01, decision H9): THE PRODUCTION CONSTRUCTOR. The validator judges against the
|
|
+ * very target object the emitter signs from ({@code AereVoteCounts.Target.of}): round, digest,
|
|
+ * commit digest and the round-bound PQ message, in one object, so the two can never be computed in
|
|
+ * two ways. The constructors with explicit hashes remain for the probes inherited from upstream;
|
|
+ * a gate demands zero production callers of them.
|
|
+ *
|
|
+ * @param validators the validators
|
|
+ * @param target the target, from {@code AereVoteCounts.Target.of} or {@code atRound}
|
|
+ * @param pqEnforcement the height-gated enforcement, or null for upstream behaviour
|
|
+ */
|
|
+ public CommitValidator(
|
|
+ final Collection<Address> validators,
|
|
+ final AereVoteCounts.Target target,
|
|
+ final PqCommitEnforcement pqEnforcement) {
|
|
+ this.validators = validators;
|
|
+ this.target = java.util.Objects.requireNonNull(target, "target");
|
|
+ this.pqEnforcement = pqEnforcement;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * AERE D-412 (2026-09-30): the whole target this validator was handed (round, digest, commit
|
|
+ * digest, PQ seal message), so a proof can compare the production wiring with the emitter's own
|
|
+ * expressions instead of with the function that computed it.
|
|
+ *
|
|
+ * @return the target
|
|
+ */
|
|
+ @com.google.common.annotations.VisibleForTesting
|
|
+ AereVoteCounts.Target targetForTesting() {
|
|
+ return target;
|
|
}
|
|
|
|
/**
|
|
* AERE D-311: the fully explicit constructor (tests and the production constructor above).
|
|
*
|
|
* @param validators the validators
|
|
* @param targetRound the target round
|
|
* @param expectedDigest the expected digest
|
|
* @param expectedCommitDigest the expected commit digest (ECDSA committed seal)
|
|
* @param expectedPqSealMessage the message the post-quantum seal must have signed
|
|
* @param pqEnforcement the enforcement, or null for upstream behaviour
|
|
*/
|
|
public CommitValidator(
|
|
final Collection<Address> validators,
|
|
final ConsensusRoundIdentifier targetRound,
|
|
final Hash expectedDigest,
|
|
final Hash expectedCommitDigest,
|
|
final Hash expectedPqSealMessage,
|
|
final PqCommitEnforcement pqEnforcement) {
|
|
this.validators = validators;
|
|
- this.targetRound = targetRound;
|
|
- this.expectedDigest = expectedDigest;
|
|
- this.expectedCommitDigest = expectedCommitDigest;
|
|
- this.expectedPqSealMessage = expectedPqSealMessage;
|
|
+ this.target =
|
|
+ AereVoteCounts.Target.explicit(
|
|
+ targetRound, expectedDigest, expectedCommitDigest, expectedPqSealMessage);
|
|
this.pqEnforcement = pqEnforcement;
|
|
}
|
|
|
|
/**
|
|
* Validate.
|
|
*
|
|
* @param msg the msg
|
|
* @return the boolean
|
|
*/
|
|
public boolean validate(final Commit msg) {
|
|
return validate(msg.getSignedPayload());
|
|
}
|
|
|
|
/**
|
|
* Validate.
|
|
*
|
|
* @param signedPayload the signed payload
|
|
* @return the boolean
|
|
*/
|
|
public boolean validate(final SignedData<CommitPayload> signedPayload) {
|
|
- if (!validators.contains(signedPayload.getAuthor())) {
|
|
- LOG.info("{}: did not originate from a recognized validator.", ERROR_PREFIX);
|
|
- return false;
|
|
- }
|
|
-
|
|
- final CommitPayload payload = signedPayload.getPayload();
|
|
-
|
|
- if (!payload.getRoundIdentifier().equals(targetRound)) {
|
|
- LOG.info(
|
|
- "{}: did not target expected round {} was {}",
|
|
- ERROR_PREFIX,
|
|
- targetRound,
|
|
- payload.getRoundIdentifier());
|
|
+ // AERE D-412: the one shared predicate (AereVoteCounts), same checks, same order, same texts.
|
|
+ final Optional<String> refusal =
|
|
+ AereVoteCounts.refusal(signedPayload, validators, target, pqEnforcement);
|
|
+ if (refusal.isPresent()) {
|
|
+ LOG.info("{}: {}", ERROR_PREFIX, refusal.get());
|
|
return false;
|
|
}
|
|
-
|
|
- if (!payload.getDigest().equals(expectedDigest)) {
|
|
- LOG.info(
|
|
- "{}: did not contain expected digest {} was {}",
|
|
- ERROR_PREFIX,
|
|
- expectedDigest,
|
|
- payload.getDigest());
|
|
- return false;
|
|
- }
|
|
-
|
|
- final Address commitSealCreator =
|
|
- AerePqIdentity.author(
|
|
- Util.signatureToAddress(payload.getCommitSeal(), expectedCommitDigest),
|
|
- targetRound.getSequenceNumber());
|
|
-
|
|
- if (!commitSealCreator.equals(signedPayload.getAuthor())) {
|
|
- LOG.info(
|
|
- "{}: Seal was not created by the message transmitter {} was {}",
|
|
- ERROR_PREFIX,
|
|
- commitSealCreator,
|
|
- signedPayload.getAuthor());
|
|
- return false;
|
|
- }
|
|
-
|
|
- // AERE full-PQ: above the arming height a commit vote only counts with a valid post-quantum
|
|
- // seal bound to this very author. Below it (or with no enforcement supplied) nothing changes.
|
|
- if (pqEnforcement != null) {
|
|
- final Optional<String> refusal =
|
|
- pqEnforcement.refusal(
|
|
- targetRound.getSequenceNumber(),
|
|
- signedPayload.getAuthor(),
|
|
- expectedPqSealMessage,
|
|
- payload.getFalconSeal(),
|
|
- payload.getExtraSeals());
|
|
- if (refusal.isPresent()) {
|
|
- LOG.info("{}: {}", ERROR_PREFIX, refusal.get());
|
|
- return false;
|
|
- }
|
|
- }
|
|
-
|
|
return true;
|
|
}
|
|
}
|
|
diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidator.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidator.java
|
|
index 0f26c79a82..03a46b8f9a 100644
|
|
--- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidator.java
|
|
+++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidator.java
|
|
@@ -1,102 +1,94 @@
|
|
/*
|
|
* Copyright ConsenSys AG.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
* found, as section 4(c) requires. The change itself is in patches/0003-aere-pq-anchor.patch.
|
|
+ * AERE D-412 (2026-09-29): the commit target is computed by AereVoteCounts.Target.of.
|
|
*/
|
|
package org.hyperledger.besu.consensus.qbft.core.validation;
|
|
|
|
import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
|
-import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit;
|
|
import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare;
|
|
import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
|
|
import org.hyperledger.besu.datatypes.Address;
|
|
-import org.hyperledger.besu.datatypes.Hash;
|
|
|
|
import java.util.Collection;
|
|
import java.util.Optional;
|
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
/** The Message validator. */
|
|
public class MessageValidator {
|
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(MessageValidator.class);
|
|
|
|
/** The Subsequent message validator. */
|
|
public static class SubsequentMessageValidator {
|
|
|
|
private final PrepareValidator prepareValidator;
|
|
private final CommitValidator commitValidator;
|
|
|
|
/**
|
|
* Instantiates a new Subsequent message validator.
|
|
*
|
|
* @param validators the validators
|
|
* @param targetRound the target round
|
|
* @param proposalBlock the proposal block
|
|
* @param blockInterface the block interface
|
|
*/
|
|
public SubsequentMessageValidator(
|
|
final Collection<Address> validators,
|
|
final ConsensusRoundIdentifier targetRound,
|
|
final QbftBlock proposalBlock,
|
|
final QbftBlockInterface blockInterface) {
|
|
- final QbftBlock commitBlock =
|
|
- blockInterface.replaceRoundForCommitBlock(proposalBlock, targetRound.getRoundNumber());
|
|
- prepareValidator = new PrepareValidator(validators, targetRound, proposalBlock.getHash());
|
|
// AERE D-311 (2026-09-02): the post-quantum seal on a commit signs the message that
|
|
// PqAnchorProducer.commitSealMessage names (the anchor form once the anchor is armed, the
|
|
- // ECDSA committed-seal hash before), computed here exactly as the emitter computes it in
|
|
+ // ECDSA committed-seal hash before), computed exactly as the emitter computes it in
|
|
// QbftRound.pqSealMessageFor: same helper, same round-independent on-chain hash.
|
|
- final Hash expectedPqSealMessage =
|
|
- Hash.wrap(
|
|
- PqAnchorProducer.commitSealMessage(
|
|
- targetRound.getSequenceNumber(),
|
|
- () -> blockInterface.replaceRoundForCommitBlock(proposalBlock, 0).getHash().getBytes(),
|
|
- commitBlock.getHash()));
|
|
+ // AERE D-412 (2026-09-29): that computation now lives in AereVoteCounts.Target.of, the one
|
|
+ // place the decision-evidence collector also uses; the calls and their order are unchanged.
|
|
+ final AereVoteCounts.Target target =
|
|
+ AereVoteCounts.Target.of(blockInterface, proposalBlock, targetRound);
|
|
+ prepareValidator = new PrepareValidator(validators, targetRound, proposalBlock.getHash());
|
|
+ // 1(b) (2026-10-01, H9): the validator receives the TARGET itself, the object the emitter signs
|
|
+ // from; enforcement self-wired from the system configuration, exactly as before
|
|
commitValidator =
|
|
- new CommitValidator(
|
|
- validators,
|
|
- targetRound,
|
|
- proposalBlock.getHash(),
|
|
- commitBlock.getHash(),
|
|
- expectedPqSealMessage);
|
|
+ new CommitValidator(validators, target, PqCommitEnforcement.fromSystemConfig());
|
|
}
|
|
|
|
/**
|
|
* Validate.
|
|
*
|
|
* @param msg the Prepare payload msg
|
|
* @return the boolean
|
|
*/
|
|
public boolean validate(final Prepare msg) {
|
|
return prepareValidator.validate(msg);
|
|
}
|
|
|
|
/**
|
|
* Validate.
|
|
*
|
|
* @param msg the Commit payload msg
|
|
* @return the boolean
|
|
*/
|
|
/** AERE D-311: the commit validator this wiring built; for the plumbing proof only. */
|
|
@com.google.common.annotations.VisibleForTesting
|
|
diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidatorFactory.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidatorFactory.java
|
|
index 404ff28bd5..2f93ce8b86 100644
|
|
--- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidatorFactory.java
|
|
+++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidatorFactory.java
|
|
@@ -1,33 +1,39 @@
|
|
/*
|
|
* Copyright 2020 ConsenSys AG.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
+ *
|
|
+ * Modifications Copyright contributors to the Aere Network.
|
|
+ *
|
|
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0010-aere-pq-round-bound-commit-seal.patch.
|
|
*/
|
|
package org.hyperledger.besu.consensus.qbft.core.validation;
|
|
|
|
import org.hyperledger.besu.consensus.common.bft.BftHelpers;
|
|
import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
|
import org.hyperledger.besu.consensus.common.bft.blockcreation.ProposerSelector;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockHeader;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftProtocolSchedule;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftValidatorProvider;
|
|
import org.hyperledger.besu.consensus.qbft.core.validation.MessageValidator.SubsequentMessageValidator;
|
|
import org.hyperledger.besu.datatypes.Address;
|
|
|
|
import java.util.Collection;
|
|
|
|
/** The Message validator factory. */
|
|
public class MessageValidatorFactory {
|
|
|
|
private final ProposerSelector proposerSelector;
|
|
private final QbftProtocolSchedule protocolSchedule;
|
|
@@ -79,41 +85,43 @@ public class MessageValidatorFactory {
|
|
|
|
/**
|
|
* Create message validator.
|
|
*
|
|
* @param roundIdentifier the round identifier
|
|
* @param parentHeader the parent header
|
|
* @return the message validator
|
|
*/
|
|
public MessageValidator createMessageValidator(
|
|
final ConsensusRoundIdentifier roundIdentifier, final QbftBlockHeader parentHeader) {
|
|
final Collection<Address> validatorsForHeight =
|
|
validatorProvider.getValidatorsAfterBlock(parentHeader);
|
|
|
|
final ProposalValidator proposalValidator =
|
|
new ProposalValidator(
|
|
blockInterface,
|
|
protocolSchedule,
|
|
BftHelpers.calculateRequiredValidatorQuorum(validatorsForHeight.size()),
|
|
validatorsForHeight,
|
|
roundIdentifier,
|
|
- proposerSelector);
|
|
+ proposerSelector,
|
|
+ parentHeader.getHash(),
|
|
+ org.hyperledger.besu.consensus.common.bft.AerePqHeaderSeal::active);
|
|
|
|
return new MessageValidator(
|
|
block ->
|
|
new SubsequentMessageValidator(
|
|
validatorsForHeight, roundIdentifier, block, blockInterface),
|
|
proposalValidator);
|
|
}
|
|
|
|
/**
|
|
* Create future round proposal message validator.
|
|
*
|
|
* @param chainHeight the chain height
|
|
* @param parentHeader the parent header
|
|
* @return the future round proposal message validator
|
|
*/
|
|
public FutureRoundProposalMessageValidator createFutureRoundProposalMessageValidator(
|
|
final long chainHeight, final QbftBlockHeader parentHeader) {
|
|
return new FutureRoundProposalMessageValidator(this, chainHeight, parentHeader);
|
|
}
|
|
}
|
|
diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PqCommitEnforcement.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PqCommitEnforcement.java
|
|
index 074459cbe7..ced46942f7 100755
|
|
--- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PqCommitEnforcement.java
|
|
+++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PqCommitEnforcement.java
|
|
@@ -207,206 +207,306 @@ public final class PqCommitEnforcement {
|
|
this.armedFromBlock = armedFromBlock;
|
|
this.registry = registry;
|
|
this.schemeSchedule = schemeSchedule;
|
|
this.hybridRegistry = hybridRegistry;
|
|
this.extrasRequiredAt = extrasRequiredAt;
|
|
this.anchorBlock = anchorBlock;
|
|
if ((schemeSchedule == null) != (hybridRegistry == null)) {
|
|
// Half a hybrid configuration is the shape that starts a node believing it enforces
|
|
// something it does not. Refuse at construction, the same stance as every other AERE gate.
|
|
throw new IllegalStateException(
|
|
"AERE-PQC-COMMIT-CONF-03: the scheme schedule and the hybrid registry are a PAIR;"
|
|
+ " configure both or neither.");
|
|
}
|
|
}
|
|
|
|
/** Whether enforcement is active at {@code height}. */
|
|
public boolean armedAt(final long height) {
|
|
return height >= armedFromBlock;
|
|
}
|
|
|
|
+ /**
|
|
+ * A refusal, and whether it could change with the state of the registries this enforcement reads.
|
|
+ *
|
|
+ * <p>AERE D-412 (2026-09-30). The decision-evidence collector memoizes verdicts so a re-gossiped
|
|
+ * message is verified once. A refusal that comes from the MESSAGE (no seal, an index bound to
|
|
+ * another author, a missing scheme) is the same forever; a refusal that comes from the REGISTRY
|
|
+ * (nothing bound to the index yet, no key, a verifier that threw, a signature that does not verify
|
|
+ * under whatever key is held now) is not: a late-anchor registry stays PENDING, with every Commit
|
|
+ * refused, until it activates at run time (D-358 held one PENDING for 55 minutes on 2800). "Does
|
|
+ * not verify" is counted as registry-dependent on purpose: a missing key and a bad signature give
|
|
+ * the same answer from outside, and taking a registry fault for a final verdict is the worse error.
|
|
+ * The texts are exactly those {@link #refusal} has always returned.
|
|
+ */
|
|
+ public static final class Refusal {
|
|
+ private final String text;
|
|
+ private final boolean dependsOnRegistryState;
|
|
+
|
|
+ private Refusal(final String text, final boolean dependsOnRegistryState) {
|
|
+ this.text = text;
|
|
+ this.dependsOnRegistryState = dependsOnRegistryState;
|
|
+ }
|
|
+
|
|
+ private static Optional<Refusal> ofMessage(final String text) {
|
|
+ return Optional.of(new Refusal(text, false));
|
|
+ }
|
|
+
|
|
+ private static Optional<Refusal> ofRegistry(final String text) {
|
|
+ return Optional.of(new Refusal(text, true));
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The refusal text, unchanged.
|
|
+ *
|
|
+ * @return the text
|
|
+ */
|
|
+ public String text() {
|
|
+ return text;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Whether the same message could be judged differently once the registry state changes.
|
|
+ *
|
|
+ * @return true for a registry-dependent refusal
|
|
+ */
|
|
+ public boolean dependsOnRegistryState() {
|
|
+ return dependsOnRegistryState;
|
|
+ }
|
|
+ }
|
|
+
|
|
/**
|
|
* Decide whether a Commit may count toward quorum.
|
|
*
|
|
* @param height the block height the commit targets (the round's sequence number)
|
|
* @param author the RECOVERED author of the signed Commit message (from its ECDSA signature)
|
|
* @param commitDigest the commit digest the PQ seal must have signed
|
|
* @param seal the optional PQ seal carried inside the payload
|
|
* @return empty when the commit counts; otherwise the refusal, with names and numbers
|
|
*/
|
|
public Optional<String> refusal(
|
|
final long height,
|
|
final Address author,
|
|
final Hash commitDigest,
|
|
final Optional<FalconSeal> seal) {
|
|
return refusal(height, author, commitDigest, seal, List.of());
|
|
}
|
|
|
|
/**
|
|
* Decide whether a Commit may count toward quorum, hybrid certificate included.
|
|
*
|
|
* @param height the block height the commit targets
|
|
* @param author the RECOVERED author of the signed Commit message
|
|
* @param commitDigest the commit digest every seal must have signed
|
|
* @param seal the Falcon seal carried in its own slot
|
|
* @param extraSeals the non-Falcon scheme seals carried alongside it
|
|
* @return empty when the commit counts; otherwise the refusal, with names and numbers
|
|
*/
|
|
public Optional<String> refusal(
|
|
final long height,
|
|
final Address author,
|
|
final Hash commitDigest,
|
|
final Optional<FalconSeal> seal,
|
|
final List<SchemeSeal> extraSeals) {
|
|
- final Optional<String> falconVerdict = falconRefusal(height, author, commitDigest, seal);
|
|
+ return judge(height, author, commitDigest, seal, extraSeals).map(Refusal::text);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The same decision as {@link #refusal(long, Address, Hash, Optional, List)}, with the kind of each
|
|
+ * refusal (AERE D-412): the one place both answers come from, so the text and the kind cannot drift.
|
|
+ *
|
|
+ * @param height the block height the commit targets
|
|
+ * @param author the RECOVERED author of the signed Commit message
|
|
+ * @param commitDigest the commit digest every seal must have signed
|
|
+ * @param seal the Falcon seal carried in its own slot
|
|
+ * @param extraSeals the non-Falcon scheme seals carried alongside it
|
|
+ * @return empty when the commit counts; otherwise the refusal and whether it depends on the registry
|
|
+ */
|
|
+ public Optional<Refusal> judge(
|
|
+ final long height,
|
|
+ final Address author,
|
|
+ final Hash commitDigest,
|
|
+ final Optional<FalconSeal> seal,
|
|
+ final List<SchemeSeal> extraSeals) {
|
|
+ final Optional<Refusal> falconVerdict = falconRefusal(height, author, commitDigest, seal);
|
|
if (falconVerdict.isPresent()
|
|
|| !armedAt(height)
|
|
|| schemeSchedule == null
|
|
|| !extrasRequiredAt.test(height)) {
|
|
return falconVerdict;
|
|
}
|
|
return hybridRefusal(height, author, commitDigest, seal.orElseThrow(), extraSeals);
|
|
}
|
|
|
|
/**
|
|
* Every scheme the schedule names at this height, other than Falcon, must be present and valid.
|
|
* The height is an anchor PARENT (that is the only place extras are demanded), so the schemes
|
|
* are those the anchor at {@code height + 1} requires: with per-scheme intervals (AIP-22 stage
|
|
* 2) a commit at the parent of a Falcon-only anchor counts without an SLH-DSA seal.
|
|
*/
|
|
- private Optional<String> hybridRefusal(
|
|
+ private Optional<Refusal> hybridRefusal(
|
|
final long height,
|
|
final Address author,
|
|
final Hash commitDigest,
|
|
final FalconSeal falconSeal,
|
|
final List<SchemeSeal> extraSeals) {
|
|
final Set<String> required =
|
|
schemeSchedule.schemesRequiredForAnchor(height + 1L, anchorBlock.getAsLong());
|
|
for (final String schemeId : required) {
|
|
if (SealSchemes.FALCON_512.id().equals(schemeId)) {
|
|
continue; // already decided by the Falcon path above
|
|
}
|
|
final Optional<SealScheme> scheme = SealSchemes.byId(schemeId);
|
|
if (scheme.isEmpty()) {
|
|
- return Optional.of(
|
|
+ return Refusal.ofRegistry(
|
|
"AERE HIBRID: the schedule requires scheme '" + schemeId + "' at height " + height
|
|
+ " and this binary does not implement it - refusing rather than ignoring it");
|
|
}
|
|
final byte wire = scheme.get().wireId();
|
|
SchemeSeal found = null;
|
|
for (final SchemeSeal candidate : extraSeals) {
|
|
if (candidate.getSchemeWireId() == wire) {
|
|
found = candidate;
|
|
break;
|
|
}
|
|
}
|
|
if (found == null) {
|
|
- return Optional.of(
|
|
+ return Refusal.ofMessage(
|
|
"AERE HIBRID: commit at height " + height + " carries no " + schemeId
|
|
+ " seal, which the schedule requires - the vote does not count");
|
|
}
|
|
// One identity per message: the hybrid seal must speak for the same validator as the Falcon
|
|
// seal, and that index must be THIS author in the hybrid registry. Neither is assumed.
|
|
if (found.getValidatorIndex() != falconSeal.getValidatorIndex()) {
|
|
- return Optional.of(
|
|
+ return Refusal.ofMessage(
|
|
"AERE HIBRID: " + schemeId + " seal is index " + found.getValidatorIndex()
|
|
+ " but the Falcon seal on the same commit is index "
|
|
+ falconSeal.getValidatorIndex() + " - one commit, one signer");
|
|
}
|
|
// AIP-22 stage 3b: from H_k the keys and the index->author binding are those of the v3 epoch in force, as in the anchor
|
|
// producer and PqAnchorSealsRule. Paid 2026-09-23 on testnet 28001: this check alone still read the static v2 hybrid
|
|
// registry, so after the rotation at 3,097,600 the ROTATED row (index 2) signed with its new SLH-DSA key and every one of its
|
|
// commits at an anchor's parent was refused here; latent while four other validators sufficed, it stopped the chain at
|
|
// 3,135,679 when the Nethermind validator fell behind.
|
|
final boolean v3 = AerePqIdentity.keysFromV3(height);
|
|
final Optional<Address> boundId =
|
|
v3
|
|
? AerePqIdentity.v3IdAt(height, found.getValidatorIndex())
|
|
: hybridRegistry
|
|
.address(found.getValidatorIndex())
|
|
.map(a -> AerePqIdentity.author(Address.wrap(Bytes.wrap(a)), height));
|
|
if (boundId.isEmpty() || !boundId.get().equals(author)) {
|
|
- return Optional.of(
|
|
+ final String text =
|
|
"AERE HIBRID: index " + found.getValidatorIndex()
|
|
+ " is not bound to the commit author " + author
|
|
- + (v3 ? " in the v3 epoch in force" : " in the hybrid registry"));
|
|
+ + (v3 ? " in the v3 epoch in force" : " in the hybrid registry");
|
|
+ // AERE D-412: nothing bound yet is the registry's state; bound to someone else is the message's
|
|
+ return boundId.isEmpty() ? Refusal.ofRegistry(text) : Refusal.ofMessage(text);
|
|
}
|
|
final Optional<byte[]> publicKey =
|
|
v3
|
|
? AerePqIdentity.v3KeyAt(height, found.getValidatorIndex(), schemeId)
|
|
: hybridRegistry.publicKey(found.getValidatorIndex(), schemeId);
|
|
if (publicKey.isEmpty()) {
|
|
- return Optional.of(
|
|
+ return Refusal.ofRegistry(
|
|
"AERE HIBRID: the hybrid registry holds no " + schemeId + " key for index "
|
|
+ found.getValidatorIndex());
|
|
}
|
|
final boolean valid;
|
|
try {
|
|
valid =
|
|
scheme
|
|
.get()
|
|
.verifyRaw(
|
|
publicKey.get(),
|
|
commitDigest.getBytes().toArray(),
|
|
found.getSignature().toArray());
|
|
} catch (final RuntimeException e) {
|
|
- return Optional.of(
|
|
+ return Refusal.ofRegistry(
|
|
"AERE HIBRID: " + schemeId + " verification threw at height " + height + ": "
|
|
+ e.getMessage());
|
|
}
|
|
if (!valid) {
|
|
- return Optional.of(
|
|
- "AERE HIBRID: the " + schemeId + " seal of index " + found.getValidatorIndex()
|
|
+ return Refusal.ofRegistry(
|
|
+ roundBoundCode(height)
|
|
+ + "AERE HIBRID: the " + schemeId + " seal of index " + found.getValidatorIndex()
|
|
+ " does NOT verify over the commit digest at height " + height
|
|
+ " - the vote does not count");
|
|
}
|
|
}
|
|
return Optional.empty();
|
|
}
|
|
|
|
- private Optional<String> falconRefusal(
|
|
+ private Optional<Refusal> falconRefusal(
|
|
final long height,
|
|
final Address author,
|
|
final Hash commitDigest,
|
|
final Optional<FalconSeal> seal) {
|
|
if (!armedAt(height)) {
|
|
return Optional.empty();
|
|
}
|
|
if (seal == null || seal.isEmpty()) {
|
|
- return Optional.of(
|
|
+ return Refusal.ofMessage(
|
|
"AERE FULL-PQ: commit at height " + height + " carries NO post-quantum seal and "
|
|
+ "enforcement is armed from " + armedFromBlock + " - the vote does not count");
|
|
}
|
|
final FalconSeal fs = seal.get();
|
|
final Address bound;
|
|
try {
|
|
bound = registry.addressForIndexAtOwnHead(height, fs.getValidatorIndex());
|
|
} catch (final RuntimeException e) {
|
|
- return Optional.of(
|
|
+ return Refusal.ofRegistry(
|
|
"AERE FULL-PQ: registry refused index " + fs.getValidatorIndex() + " at height "
|
|
+ height + ": " + e.getMessage());
|
|
}
|
|
if (bound == null || !bound.equals(author)) {
|
|
- return Optional.of(
|
|
+ final String text =
|
|
"AERE FULL-PQ: seal index " + fs.getValidatorIndex() + " is bound to "
|
|
+ bound + " but the commit was authored by " + author
|
|
- + " - a seal cannot vouch for someone else's vote");
|
|
+ + " - a seal cannot vouch for someone else's vote";
|
|
+ // AERE D-412: an index bound to nobody is a registry that has not activated (D-358 PENDING); one
|
|
+ // bound to another author is the message claiming someone else's index, the same under any state
|
|
+ return bound == null ? Refusal.ofRegistry(text) : Refusal.ofMessage(text);
|
|
}
|
|
final boolean valid;
|
|
try {
|
|
valid =
|
|
registry.verifyAtOwnHead(
|
|
height, fs.getValidatorIndex(), commitDigest.getBytes(), fs.getSignature());
|
|
} catch (final RuntimeException e) {
|
|
- return Optional.of(
|
|
+ return Refusal.ofRegistry(
|
|
"AERE FULL-PQ: verification threw for index " + fs.getValidatorIndex() + " at height "
|
|
+ height + ": " + e.getMessage());
|
|
}
|
|
if (!valid) {
|
|
- return Optional.of(
|
|
- "AERE FULL-PQ: post-quantum seal of index " + fs.getValidatorIndex()
|
|
+ return Refusal.ofRegistry(
|
|
+ roundBoundCode(height)
|
|
+ + "AERE FULL-PQ: post-quantum seal of index " + fs.getValidatorIndex()
|
|
+ " does NOT verify over the commit digest at height " + height
|
|
+ " - the vote does not count");
|
|
}
|
|
return Optional.empty();
|
|
}
|
|
+
|
|
+ /**
|
|
+ * AERE 1(b) (2026-10-01): from H_r - 1 the "commit digest" a seal is checked against is M_r, the
|
|
+ * round-bound message of the round the Commit names (the caller hands it in, from the one target
|
|
+ * object). A seal copied from another round, or given over COMMIT-1, does not verify, and the refusal
|
|
+ * carries in front the code {@code AERE-PQ-COMMIT-R-01} that the r1b vectors name for this refusal. Below
|
|
+ * that height the text is today's, byte for byte (L1).
|
|
+ *
|
|
+ * <p>CORRECTED 2026-10-09 (1(b) step 11, consumatori/R3): this comment said "the same string as the
|
|
+ * second client". On that date the second client refused these commits WITHOUT the code (its
|
|
+ * {@code PqAnchorV3.CommitR01} was defined and used nowhere), a divergence the r1b vectors carried as
|
|
+ * declared on the four VL-C vectors. Whether both clients write the code is what the r1b conformity
|
|
+ * judge measures ({@code aips/aip22-conformitate/r1b/judeca-conformitatea-r1b.mjs}); a comment here
|
|
+ * cannot promise it.
|
|
+ */
|
|
+ private static String roundBoundCode(final long height) {
|
|
+ return org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer.commitSealFormAt(
|
|
+ org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer.config(),
|
|
+ height)
|
|
+ == org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer.CommitSealForm
|
|
+ .ROUND_BOUND
|
|
+ ? org.hyperledger.besu.consensus.common.bft.PqAnchorV3.COMMIT_R_01 + ": "
|
|
+ : "";
|
|
+ }
|
|
}
|
|
diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PqFinalityLayersGuard.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PqFinalityLayersGuard.java
|
|
index ea85af1542..1417de169f 100644
|
|
--- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PqFinalityLayersGuard.java
|
|
+++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PqFinalityLayersGuard.java
|
|
@@ -1,37 +1,38 @@
|
|
/*
|
|
* Copyright contributors to Besu / AERE Network.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
package org.hyperledger.besu.consensus.qbft.core.validation;
|
|
|
|
import org.hyperledger.besu.consensus.common.bft.AerePqIdentity;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
import java.util.function.LongPredicate;
|
|
|
|
/**
|
|
* AIP-22 stage 4: H_fin may be armed only where every post-quantum seal is VERIFIED from H_fin.
|
|
*
|
|
* <p>From H_fin a message's author is the id of its seal's index ({@code AerePqFinality}), and the
|
|
* envelope's ECDSA signature is no longer read. For a PROPOSAL, PREPARE or ROUND-CHANGE the author is
|
|
* given only once the seal verifies; a COMMIT's author is its index's id only when that is the commit
|
|
* seal signer's id, and what judges the COMMIT's post-quantum seal is the commit layer alone. Each
|
|
* layer is armed on its own height. With the commit layer unset, or armed above H_fin, a Commit whose
|
|
* ECDSA commit seal was forged (the adversary stage 4 exists for) would count with any bytes as its
|
|
* post-quantum seal; and the other three layers are the second judge of what the author already
|
|
* checked. So this guard refuses to start such a node (AERE-PQC-FIN-02), before the network is up.
|
|
* Emergency disarming of a layer after H_fin therefore needs H_fin unset too, on every node: one
|
|
* uniform step back to ECDSA authorship, never a node that trusts unverified seals.
|
|
*/
|
|
@@ -137,40 +138,234 @@ public final class PqFinalityLayersGuard {
|
|
gate(missing, "aere.pq.roundChangePq.attachBlock", attachRoundChange, hFin);
|
|
if (missing.isEmpty()) {
|
|
return Optional.empty();
|
|
}
|
|
return Optional.of(
|
|
"AERE-PQC-FIN-03: aere.pq.finalityBlock="
|
|
+ hFin
|
|
+ " makes an unsealed message authorless, and this node would not seal from H_fin: "
|
|
+ String.join(", ", missing)
|
|
+ ". It would go mute at H_fin. Arm them at or below H_fin, or unset H_fin, on every validator.");
|
|
}
|
|
|
|
private static void gate(final List<String> missing, final String property, final long h, final long hFin) {
|
|
if (h < 0 || h == Long.MAX_VALUE) {
|
|
missing.add(property + " unset");
|
|
} else if (h > hFin) {
|
|
missing.add(property + " armed above H_fin (" + h + ")");
|
|
}
|
|
}
|
|
|
|
+ /** 1(b): the confirmation that a chain armed H_fin before H_r (28001 and the rehearsal chains). */
|
|
+ public static final String PROPERTY_ROUND_LATE_AFTER_FINALITY =
|
|
+ "aere.pq.commitRoundBlock.lateAfterFinality";
|
|
+
|
|
+ /** The environment form of {@link #PROPERTY_ROUND_LATE_AFTER_FINALITY}. */
|
|
+ public static final String ENV_ROUND_LATE_AFTER_FINALITY =
|
|
+ "AERE_PQ_COMMIT_ROUND_LATE_AFTER_FINALITY";
|
|
+
|
|
+ /** The refusal code (FIN-04 in the project's numbering of the finality guards). */
|
|
+ public static final String CODE_ROUND_02 = "AERE-PQC-ROUND-02";
|
|
+
|
|
+ /** The chain on which the ROUND-02 confirmation is refused (H_r before H_fin there, section 2.4). */
|
|
+ public static final long MAINNET_CHAIN_ID = 2800L;
|
|
+
|
|
+ /**
|
|
+ * AERE-PQC-ROUND-02 (1(b), section 2.3, beside FIN-02): from H_fin a COMMIT's author is the id of its
|
|
+ * post-quantum seal's index, and below H_r that seal carries no round, so between H_fin and H_r the
|
|
+ * round of a commit is bound by the ECDSA commit seal only (the gap A_q of D-470). A node with H_fin
|
|
+ * set therefore refuses to start unless H_r is set at or below H_fin, or the operator confirms the
|
|
+ * history with {@link #PROPERTY_ROUND_LATE_AFTER_FINALITY} EQUAL to H_fin (a value that names the
|
|
+ * exact window, so a confirmation copied from another chain does not pass). Inert when H_fin is
|
|
+ * unset: 2800 today, and every node whose H_fin is not armed, sees nothing (L1). The confirmation is
|
|
+ * REFUSED on chain {@value #MAINNET_CHAIN_ID} (decision H14, review of step 4): there H_r comes before
|
|
+ * H_fin (section 2.4), so a 2800 node with H_fin above H_r unset is a configuration error, never history.
|
|
+ *
|
|
+ * <p>This form judges the heights alone and does not know the anchor brake; the startup path calls the
|
|
+ * form that takes the anchor configuration ({@link #verifyRoundOrAbort(long, PqAnchorConfig, long)}),
|
|
+ * which is inert under the brake ({@link #roundGapClosedByEcdsaForm}, 2026-10-09).
|
|
+ *
|
|
+ * @param hFin H_fin, or {@link AerePqIdentity#NEVER}
|
|
+ * @param hR H_r, or {@link AerePqIdentity#NEVER} (the same value as PqAnchorConfig.NEVER)
|
|
+ * @param lateAfterFinality the raw confirmation, or null when unset
|
|
+ * @param chainId the genesis chain id of this node
|
|
+ * @return the refusal, or empty
|
|
+ */
|
|
+ public static Optional<String> roundRefusal(
|
|
+ final long hFin, final long hR, final String lateAfterFinality, final long chainId) {
|
|
+ if (hFin == AerePqIdentity.NEVER) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ if (hR != AerePqIdentity.NEVER && hR <= hFin) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ if (lateAfterFinality != null && !lateAfterFinality.isBlank() && chainId == MAINNET_CHAIN_ID) {
|
|
+ return Optional.of(
|
|
+ CODE_ROUND_02 + ": " + PROPERTY_ROUND_LATE_AFTER_FINALITY + " is set on chain " + MAINNET_CHAIN_ID
|
|
+ + ", where H_r comes before H_fin; the confirmation is for 28001 and the rehearsal chains only."
|
|
+ + " Set aere.pq.commitRoundBlock at or below aere.pq.finalityBlock=" + hFin);
|
|
+ }
|
|
+ if (lateAfterFinality != null && !lateAfterFinality.isBlank()) {
|
|
+ final long confirmed;
|
|
+ try {
|
|
+ confirmed = Long.parseLong(lateAfterFinality.trim());
|
|
+ } catch (final NumberFormatException e) {
|
|
+ return Optional.of(
|
|
+ CODE_ROUND_02 + ": " + PROPERTY_ROUND_LATE_AFTER_FINALITY + "='" + lateAfterFinality
|
|
+ + "' is not a height; it must equal aere.pq.finalityBlock=" + hFin);
|
|
+ }
|
|
+ if (confirmed == hFin) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ return Optional.of(
|
|
+ CODE_ROUND_02 + ": " + PROPERTY_ROUND_LATE_AFTER_FINALITY + "=" + confirmed
|
|
+ + " does not name this chain's H_fin=" + hFin + "; it must be EQUAL to it");
|
|
+ }
|
|
+ return Optional.of(
|
|
+ CODE_ROUND_02 + ": aere.pq.finalityBlock=" + hFin + " is armed and aere.pq.commitRoundBlock is "
|
|
+ + (hR == AerePqIdentity.NEVER ? "unset" : "above it (" + hR + ")")
|
|
+ + ": from H_fin a commit's author is its post-quantum seal, which below H_r carries no round,"
|
|
+ + " so the round of a commit would be bound by ECDSA only. Set H_r at or below H_fin, or confirm"
|
|
+ + " that history with " + PROPERTY_ROUND_LATE_AFTER_FINALITY + "=" + hFin + " (28001 and the"
|
|
+ + " rehearsal chains, where H_fin came first).");
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Whether the ROUND-02 confirmation is what lets this node start (so the startup log can name the
|
|
+ * window as history).
|
|
+ *
|
|
+ * @param hFin H_fin, or {@link AerePqIdentity#NEVER}
|
|
+ * @param hR H_r, or {@link AerePqIdentity#NEVER}
|
|
+ * @param lateAfterFinality the raw confirmation, or null
|
|
+ * @param chainId the genesis chain id of this node
|
|
+ * @return true when H_fin is set, H_r is unset or above it, and the confirmation equals H_fin
|
|
+ */
|
|
+ public static boolean roundLateConfirmed(
|
|
+ final long hFin, final long hR, final String lateAfterFinality, final long chainId) {
|
|
+ return hFin != AerePqIdentity.NEVER
|
|
+ && (hR == AerePqIdentity.NEVER || hR > hFin)
|
|
+ && lateAfterFinality != null
|
|
+ && !lateAfterFinality.isBlank()
|
|
+ && roundRefusal(hFin, hR, lateAfterFinality, chainId).isEmpty();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The raw confirmation as this node's configuration carries it: the system property, else the
|
|
+ * environment variable.
|
|
+ *
|
|
+ * @return the raw value, or null when neither is set
|
|
+ */
|
|
+ public static String lateAfterFinalityFromSystemConfig() {
|
|
+ final String p = System.getProperty(PROPERTY_ROUND_LATE_AFTER_FINALITY);
|
|
+ if (p != null && !p.isBlank()) {
|
|
+ return p;
|
|
+ }
|
|
+ final String e = System.getenv(ENV_ROUND_LATE_AFTER_FINALITY);
|
|
+ return e == null || e.isBlank() ? null : e;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Whether the gap ROUND-02 guards cannot exist on this node BY THE BRAKE: the emergency brake {@code
|
|
+ * aere.pq.anchor.disable} is in force (also when the rest of a braked configuration cannot be read:
|
|
+ * the reader then carries {@link PqAnchorConfig#brakedNever}, flag included), so {@code
|
|
+ * PqAnchorProducer.commitSealFormAt} gives {@code ECDSA_DIGEST} at every height.
|
|
+ *
|
|
+ * <p>THE BRAKE ONLY (2026-10-10, review of consensus M1). The step-11 form of 2026-10-09 answered
|
|
+ * "{@code anchorConfig == null || !anchorConfig.everActive()}", that is the brake OR no anchor at
|
|
+ * all, because the reader carried a braked configuration it could not read as {@code never(0)}, which
|
|
+ * says "not braked". That also exempted a node whose anchor names were LOST from its options while
|
|
+ * H_fin stayed armed (the family of the {@code grep -v} of 9 August): it started with a warning and
|
|
+ * no code, where until then ROUND-02 refused it, and where the second client refuses it
|
|
+ * ({@code AereCommitRoundConfig.Round02Refusal} is inert on its brake flag alone). This javadoc also
|
|
+ * said the second client took "the same predicate (brake, or no anchor block)": it never did. Now the
|
|
+ * reader carries the flag on the unreadable branch and the exception reads the flag only, in both
|
|
+ * clients. {@code null} still counts as not in force (no caller passes it; the builder reads the
|
|
+ * configuration once and hands the object in).
|
|
+ *
|
|
+ * <p>WHY THIS LIFTS ROUND-02 (1(b) step 11, 2026-10-09, nm-consens-02). ROUND-02 exists for the gap
|
|
+ * A_q of D-470: from H_fin a commit's author is its post-quantum seal, and in the anchor form below
|
|
+ * H_r that seal signs COMMIT-1, which carries no round. In the ECDSA_DIGEST form the post-quantum
|
|
+ * commit seal signs the ECDSA committed-seal hash itself ({@code PqAnchorProducer.commitSealMessage}:
|
|
+ * {@code Bytes32.wrap(commitHash)}), and that hash is ROUND-SPECIFIC (the round is in the header the
|
|
+ * QBFT committed seal hashes; it is the hash {@code PqAnchorProducer} calls "round-specific"), so the
|
|
+ * round of every commit stays bound and there is no A_q to guard. Without this, a braked 2800 node
|
|
+ * whose H_fin is armed (from T4) and whose braked configuration carries no H_r (the brake reads no
|
|
+ * H_r: {@code PqAnchorConfig.fromSystemConfiguration}) was REFUSED by ROUND-02: the brake could not
|
|
+ * engage, and "a brake that can be refused is not a brake" (the reader's own rule). Parity: the second
|
|
+ * client's ROUND-02 ({@code AereCommitRoundConfig.Round02Refusal}) takes the same exception on the same
|
|
+ * predicate, the brake flag alone (2026-10-10: measured there by its probe R1bNM_BRAKE_ROUND02, which
|
|
+ * also asks that a node without an anchor block and without the brake is refused).
|
|
+ *
|
|
+ * <p>What it does NOT make safe: a brake on ONE node. Its seals then sign a form the others do not
|
|
+ * verify, so from H_fin its commits are expected to count for nothing on them (deduced from the code,
|
|
+ * not measured on a network): a loss of liveness for that node, not of safety. The brake goes on
|
|
+ * every node, as its runbook says.
|
|
+ *
|
|
+ * @param anchorConfig the anchor configuration this node runs with, as read at startup
|
|
+ * @return true when the brake is in force on this node (null counts as such: no caller passes it)
|
|
+ */
|
|
+ public static boolean roundGapClosedByEcdsaForm(final PqAnchorConfig anchorConfig) {
|
|
+ return anchorConfig == null || anchorConfig.disabled();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * ROUND-02 as a node judges it at startup: inert when {@link #roundGapClosedByEcdsaForm} (the
|
|
+ * brake), otherwise {@link #roundRefusal(long, long, String, long)} with the H_r this configuration
|
|
+ * carries.
|
|
+ *
|
|
+ * @param hFin H_fin, or {@link AerePqIdentity#NEVER}
|
|
+ * @param anchorConfig the anchor configuration this node runs with (the object read at startup)
|
|
+ * @param lateAfterFinality the raw confirmation, or null when unset
|
|
+ * @param chainId the genesis chain id of this node
|
|
+ * @return the refusal, or empty
|
|
+ */
|
|
+ public static Optional<String> roundRefusal(
|
|
+ final long hFin,
|
|
+ final PqAnchorConfig anchorConfig,
|
|
+ final String lateAfterFinality,
|
|
+ final long chainId) {
|
|
+ if (roundGapClosedByEcdsaForm(anchorConfig)) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ return roundRefusal(hFin, anchorConfig.commitRoundBlock(), lateAfterFinality, chainId);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Refuses to start on AERE-PQC-ROUND-02. Takes the anchor configuration itself, not its H_r (1(b)
|
|
+ * step 11, 2026-10-09): the builder hands in the object it read, so the brake cannot be forgotten
|
|
+ * between the reader and the guard; the form that took H_r alone was deleted, so no caller can reach
|
|
+ * the guard without it.
|
|
+ *
|
|
+ * @param hFin H_fin as armed on this node
|
|
+ * @param anchorConfig the anchor configuration this node runs with (the object read at startup)
|
|
+ * @param chainId the genesis chain id of this node
|
|
+ * @throws IllegalStateException AERE-PQC-ROUND-02
|
|
+ */
|
|
+ public static void verifyRoundOrAbort(
|
|
+ final long hFin, final PqAnchorConfig anchorConfig, final long chainId) {
|
|
+ final Optional<String> r =
|
|
+ roundRefusal(hFin, anchorConfig, lateAfterFinalityFromSystemConfig(), chainId);
|
|
+ if (r.isPresent()) {
|
|
+ throw new IllegalStateException(r.get());
|
|
+ }
|
|
+ }
|
|
+
|
|
/**
|
|
* Refuses to start when a sealing node would not seal every message from H_fin.
|
|
*
|
|
* @param hFin H_fin as armed on this node
|
|
* @param signs whether this node seals
|
|
* @param attachCommit commit attachment height
|
|
* @param attachProposal proposal attachment height
|
|
* @param attachPrepare prepare attachment height
|
|
* @param attachRoundChange round-change attachment height
|
|
* @throws IllegalStateException AERE-PQC-FIN-03
|
|
*/
|
|
public static void verifyEmissionOrAbort(
|
|
final long hFin,
|
|
final boolean signs,
|
|
final long attachCommit,
|
|
final long attachProposal,
|
|
final long attachPrepare,
|
|
final long attachRoundChange) {
|
|
final Optional<String> r =
|
|
emissionRefusal(hFin, signs, attachCommit, attachProposal, attachPrepare, attachRoundChange);
|
|
diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalValidator.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalValidator.java
|
|
index f0432d83c3..3aebdf8fdc 100644
|
|
--- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalValidator.java
|
|
+++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalValidator.java
|
|
@@ -1,128 +1,190 @@
|
|
/*
|
|
* Copyright 2020 ConsenSys AG.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
+ *
|
|
+ * Modifications Copyright contributors to the Aere Network.
|
|
+ *
|
|
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0010-aere-pq-round-bound-commit-seal.patch.
|
|
*/
|
|
package org.hyperledger.besu.consensus.qbft.core.validation;
|
|
|
|
import static org.hyperledger.besu.consensus.common.bft.validation.ValidationHelpers.hasDuplicateAuthors;
|
|
import static org.hyperledger.besu.consensus.common.bft.validation.ValidationHelpers.hasSufficientEntries;
|
|
|
|
import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
|
import org.hyperledger.besu.consensus.common.bft.blockcreation.ProposerSelector;
|
|
import org.hyperledger.besu.consensus.common.bft.payload.Payload;
|
|
import org.hyperledger.besu.consensus.common.bft.payload.SignedData;
|
|
import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal;
|
|
import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload;
|
|
import org.hyperledger.besu.consensus.qbft.core.payload.PreparedRoundMetadata;
|
|
import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockValidator;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftProtocolSchedule;
|
|
import org.hyperledger.besu.datatypes.Address;
|
|
import org.hyperledger.besu.datatypes.Hash;
|
|
|
|
import java.util.Collection;
|
|
import java.util.Comparator;
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
+import java.util.function.LongPredicate;
|
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
/** The Proposal validator. */
|
|
public class ProposalValidator {
|
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(ProposalValidator.class);
|
|
private static final String ERROR_PREFIX = "Invalid Proposal Payload";
|
|
|
|
private final QbftBlockInterface blockInterface;
|
|
private final QbftProtocolSchedule protocolSchedule;
|
|
private final int quorumMessageCount;
|
|
private final Collection<Address> validators;
|
|
private final ConsensusRoundIdentifier roundIdentifier;
|
|
private final ProposerSelector proposerSelector;
|
|
+ private final Hash expectedParentHash;
|
|
+ private final LongPredicate parentBindingActive;
|
|
|
|
/**
|
|
* Instantiates a new Proposal validator.
|
|
*
|
|
* @param blockInterface the block interface
|
|
* @param protocolSchedule the protocol schedule
|
|
* @param quorumMessageCount the quorum message count
|
|
* @param validators the validators
|
|
* @param roundIdentifier the round identifier
|
|
* @param proposerSelector the proposer selector
|
|
*/
|
|
public ProposalValidator(
|
|
final QbftBlockInterface blockInterface,
|
|
final QbftProtocolSchedule protocolSchedule,
|
|
final int quorumMessageCount,
|
|
final Collection<Address> validators,
|
|
final ConsensusRoundIdentifier roundIdentifier,
|
|
final ProposerSelector proposerSelector) {
|
|
+ this(
|
|
+ blockInterface,
|
|
+ protocolSchedule,
|
|
+ quorumMessageCount,
|
|
+ validators,
|
|
+ roundIdentifier,
|
|
+ proposerSelector,
|
|
+ null,
|
|
+ height -> false);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Instantiates a Proposal validator that, where {@code parentBindingActive} holds for the height, also requires the
|
|
+ * proposed block to extend the decided head of the height (AERE D-437, AIP-22 stage 5).
|
|
+ *
|
|
+ * @param blockInterface the block interface
|
|
+ * @param protocolSchedule the protocol schedule
|
|
+ * @param quorumMessageCount the quorum message count
|
|
+ * @param validators the validators
|
|
+ * @param roundIdentifier the round identifier
|
|
+ * @param proposerSelector the proposer selector
|
|
+ * @param expectedParentHash the hash of the decided head this height's consensus runs on
|
|
+ * @param parentBindingActive whether the binding applies at a height (production: AerePqHeaderSeal::active)
|
|
+ */
|
|
+ public ProposalValidator(
|
|
+ final QbftBlockInterface blockInterface,
|
|
+ final QbftProtocolSchedule protocolSchedule,
|
|
+ final int quorumMessageCount,
|
|
+ final Collection<Address> validators,
|
|
+ final ConsensusRoundIdentifier roundIdentifier,
|
|
+ final ProposerSelector proposerSelector,
|
|
+ final Hash expectedParentHash,
|
|
+ final LongPredicate parentBindingActive) {
|
|
this.blockInterface = blockInterface;
|
|
this.protocolSchedule = protocolSchedule;
|
|
this.quorumMessageCount = quorumMessageCount;
|
|
this.validators = validators;
|
|
this.roundIdentifier = roundIdentifier;
|
|
this.proposerSelector = proposerSelector;
|
|
+ this.expectedParentHash = expectedParentHash;
|
|
+ this.parentBindingActive = parentBindingActive;
|
|
}
|
|
|
|
/**
|
|
* Validate.
|
|
*
|
|
* @param msg the Proposal msg
|
|
* @return the boolean
|
|
*/
|
|
public boolean validate(final Proposal msg) {
|
|
return validate(msg, true);
|
|
}
|
|
|
|
/**
|
|
* Validate without block validation.
|
|
*
|
|
* @param msg the Proposal msg
|
|
* @return the boolean
|
|
*/
|
|
public boolean validateWithoutBlockValidation(final Proposal msg) {
|
|
return validate(msg, false);
|
|
}
|
|
|
|
/**
|
|
* Validate with optional block validation.
|
|
*
|
|
* @param msg the Proposal msg
|
|
* @param validateBlock whether to validate the block
|
|
* @return the boolean
|
|
*/
|
|
private boolean validate(final Proposal msg, final boolean validateBlock) {
|
|
+ // AERE D-437 (2026-09-29): from AIP-22 stage 5 (H_hdr) a header between anchors carries one proposer seal, so a
|
|
+ // sibling of the decided block can be forged by one key and stored as a fork. A proposal must extend the head this
|
|
+ // height's consensus runs on, not any stored parent, or one key could make honest validators commit a child of a
|
|
+ // forged sibling and revert a decided block. Below H_hdr a sibling needs an ECDSA commit quorum; nothing changes.
|
|
+ if (parentBindingActive.test(roundIdentifier.getSequenceNumber())) {
|
|
+ final Hash proposedParent = msg.getBlock().getHeader().getParentHash();
|
|
+ if (expectedParentHash == null
|
|
+ || proposedParent == null
|
|
+ || !proposedParent.equals(expectedParentHash)) {
|
|
+ LOG.info(
|
|
+ "{}: AERE-D437 proposal at {} builds on parent {}, but this height's decided head is {}; not accepting it",
|
|
+ ERROR_PREFIX,
|
|
+ roundIdentifier.getSequenceNumber(),
|
|
+ proposedParent,
|
|
+ expectedParentHash);
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
final QbftBlockValidator blockValidator =
|
|
protocolSchedule.getBlockValidator(msg.getBlock().getHeader());
|
|
|
|
final Address expectedProposer = proposerSelector.selectProposerForRound(roundIdentifier);
|
|
final ProposalPayloadValidator payloadValidator =
|
|
new ProposalPayloadValidator(expectedProposer, roundIdentifier, blockValidator);
|
|
|
|
final boolean payloadValid =
|
|
validateBlock
|
|
? payloadValidator.validate(msg.getSignedPayload())
|
|
: payloadValidator.validateWithoutBlockValidation(msg.getSignedPayload());
|
|
|
|
if (!payloadValid) {
|
|
LOG.info("{}: invalid proposal payload in proposal message", ERROR_PREFIX);
|
|
return false;
|
|
}
|
|
|
|
if (!validateProposalAndRoundChangeAreConsistent(msg)) {
|
|
return false;
|
|
}
|
|
diff --git a/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereDecisionEvidenceTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereDecisionEvidenceTest.java
|
|
new file mode 100644
|
|
index 0000000000..e180a50b00
|
|
--- /dev/null
|
|
+++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereDecisionEvidenceTest.java
|
|
@@ -0,0 +1,677 @@
|
|
+/* AERE D-412 / capul decis, pasul 1: proba P2 a colectorului de dovezi (AereDecisionEvidence).
|
|
+ *
|
|
+ * O proba pe proprietate, si fiecare are plantarea ei (cap-decis-besu/planteaza-pasul1.py):
|
|
+ * - q1FoundUnderTheDigestOfItsRound: Q1 la runda 1 se gaseste sub digest_1 (runda inclusa), nu sub
|
|
+ * amprenta de pe lant; commit-urile fara bloc cunoscut nu ocupa niciun loc numarat pana nu sunt
|
|
+ * verificate. Plantarea "numai onchain" -> 0 din Q.
|
|
+ * - indexClaimsTakeNoSlot: X (o cheie) trimite INAINTEA cinstitilor commit-uri care revendica
|
|
+ * indexurile PQ ale altora (cu sigiliile lor adevarate copiate) si isi umple propriul loc: nu ia
|
|
+ * niciun loc, nu scoate niciun vot cinstit, isi tine cel mult MAX_PER_AUTHOR intrari. Plantarea
|
|
+ * "refuzul ignorat" -> ROSU.
|
|
+ * - floodIsBoundedAndNeverTouchesTheSealCache: 100.000 de commit-uri: plafonul tine, iar
|
|
+ * PqSealCache (entryCount, highestSeen) si dosarul lui de persistenta raman neatinse. Plantarea
|
|
+ * "rutare prin record" -> ROSU.
|
|
+ * - eachMessageIsVerifiedOnce: un commit refuzat, re-difuzat de cinci ori, se verifica o data; a doua
|
|
+ * judecata face 0 verificari. Plantarea "fara memo" -> ROSU.
|
|
+ * - childSetIsTheSetAfterTheBlock: Q2 numara in set(c) = setul DUPA b, nu in setul scris in b.
|
|
+ * Plantarea "getValidatorsForBlock(b)" -> ROSU.
|
|
+ * - childNeedsFPlusOne: Q2 cu f commit-uri NU, cu f+1 DA (si pe drumul copilului stocat). Plantarea
|
|
+ * "pragul Q2 = f" -> ROSU.
|
|
+ * - (anchorEvidenceIsOffBelowFPlusOne a fost RETRASA 2026-10-01, teza Q3, D-470: Q3 nu se mai judeca in colector;
|
|
+ * raspunsul unic e AereCertifiedDecision, masurat de AereCertifiedDecisionTest, cu plantarile lui.)
|
|
+ * - ancestryIsOnTheParentPath: Q4 numai pe drumul parentHash. Plantarea "numai inaltimea" -> ROSU.
|
|
+ * - retainsTheProofForTheEcho / windowIsDecidedPlusW: retinerea pentru ecou si fereastra (D, D+W].
|
|
+ * Adaugate 2026-09-30, dupa revizuire, fiecare cu plantarea ei:
|
|
+ * - aCopiedCommitSealCannotShadowTheHonestVote: in regimul REAL de la H_fin, X copiaza sigiliul de
|
|
+ * commit al lui A si trimite INAINTE o copie cu alta runda si copii cu sigiliu Falcon gunoi; blocul
|
|
+ * e cunoscut doar ca stocat; votul lui A se numara. Plantarile "umbrire pe (n, autor, digest)" si
|
|
+ * "clasa plicului ignorata" -> ROSU.
|
|
+ * - aRegistryRefusalIsRetriedInTheNextGeneration: registrul PENDING refuza, apoi se activeaza; acelasi
|
|
+ * mesaj, retrimis, se numara. Plantarea "memo pe refuz" -> ROSU.
|
|
+ * - verificationsPerAuthorAreBounded: X propune un bloc si trimite commit-uri pe el la rundele 0..99:
|
|
+ * verificarile si inlocuirile de runda raman plafonate. Plantarea "plafon scos" -> ROSU.
|
|
+ * - proposalBytesAreBounded: X inunda cu propuneri de 1 MiB; octetii lui si totalul raman plafonate,
|
|
+ * iar propunerea unui cinstit inca intra si da Q2. Plantarea "plafon de octeti scos" -> ROSU.
|
|
+ * - anIndexClaimIsNoSlotWithoutEnforcement: fara impunere, X revendica indexurile 0 si 1: nicio
|
|
+ * dovada Q1 din X plus un singur cinstit. Plantarea "locul dupa index" -> ROSU.
|
|
+ * - q1NeedsOneRound: 2 voturi la runda 0 plus 1 la runda 1 nu fac Q1. Plantarea "uniune peste
|
|
+ * runde" -> ROSU.
|
|
+ * - q1CountsInTheSetAfterTheParent: set(b) e setul de dupa PARINTE. Plantarea "setul de dupa b"
|
|
+ * -> ROSU.
|
|
+ * - q1UnderTheAnchorForm: cu ancora armata, sigiliul PQ numarat e cel peste forma de ancora; unul
|
|
+ * peste digestul simplu nu se numara.
|
|
+ * Adaugate 2026-09-30, a doua revizuire:
|
|
+ * - refusedVariantsDoNotFreeTheirPlace: cota de variante se numara pe ce s-a ADMIS vreodata, nu pe
|
|
+ * ce inca asteapta; 100 de plicuri noi ale aceluiasi commit refuzat de mesaj (dupa o verificare
|
|
+ * Falcon) costa MAX_VARIANTS predicate pe clasa, iar dupa ce ambele clase sunt pline nici macar
|
|
+ * recuperarile ECDSA ale clasei plicului nu se mai fac. Plantarile "varianta eliberata la refuz"
|
|
+ * si "clasificare inainte de cota" -> ROSU;
|
|
+ * - indexClaimsTakeNoSlot cere acum si numarul exact: MAX_VARIANTS refuzuri, restul aruncat;
|
|
+ * - fereastra (D, D+W] si retinerea/curatarea au plantarile lor (fereastra-fara-capat,
|
|
+ * fereastra-fara-podea, retinere-oprita, retinere-fara-curatare, curatare-fara-d);
|
|
+ * - aBlockProposedWithAnotherRoundHasNoCommitAuthor: partea ei din colector e filtrul de admitere (un commit FARA autor se
|
|
+ * arunca); plantarea "admitere-ignorata" -> ROSU. Partea "nu are autor" e a lui AerePqFinality, nu a pasului 1. */
|
|
+package org.hyperledger.besu.consensus.qbft.core.statemachine;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSealCache;
|
|
+import org.hyperledger.besu.consensus.common.bft.SchemeSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealSchemes;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockHeader;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.AereD412Fixture;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.AereD412Fixture.TBlock;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.PqCommitEnforcement;
|
|
+import org.hyperledger.besu.crypto.SECPSignature;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+
|
|
+import java.io.IOException;
|
|
+import java.lang.reflect.Field;
|
|
+import java.nio.file.Files;
|
|
+import java.nio.file.Path;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collection;
|
|
+import java.util.HashMap;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+import java.util.Set;
|
|
+import java.util.stream.Stream;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.junit.jupiter.api.io.TempDir;
|
|
+
|
|
+public class AereDecisionEvidenceTest {
|
|
+
|
|
+ private static final long D = 1_000_000L;
|
|
+ private static final long N = D + 1;
|
|
+ private static final int W = AereDecisionEvidence.DEFAULT_WINDOW;
|
|
+ private static final Hash P = Hash.hash(Bytes.of(9));
|
|
+
|
|
+ @AfterEach
|
|
+ public void disarm() {
|
|
+ AereD412Fixture.uninstallAll();
|
|
+ }
|
|
+
|
|
+ /** Sets by on-chain hash, a default for any other hash, and an admission list. */
|
|
+ private static AereDecisionEvidence.ValidatorSets sets(
|
|
+ final Map<Hash, Collection<Address>> after,
|
|
+ final Collection<Address> byDefault,
|
|
+ final Collection<Address> admission) {
|
|
+ return new AereDecisionEvidence.ValidatorSets() {
|
|
+ @Override
|
|
+ public Optional<Collection<Address>> afterBlock(final Hash onchainHash) {
|
|
+ return Optional.ofNullable(after.getOrDefault(onchainHash, byDefault));
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Collection<Address> admission(final long height) {
|
|
+ return admission;
|
|
+ }
|
|
+ };
|
|
+ }
|
|
+
|
|
+ private static AereDecisionEvidence collector(
|
|
+ final AereD412Fixture fx,
|
|
+ final AereDecisionEvidence.ValidatorSets sets,
|
|
+ final PqCommitEnforcement enforcement) {
|
|
+ return new AereDecisionEvidence(
|
|
+ fx.blockInterface, sets, enforcement, fx::generation, fx::sizeOf, D, W);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void q1FoundUnderTheDigestOfItsRound() {
|
|
+ final AereD412Fixture fx = new AereD412Fixture(4, true);
|
|
+ final List<Address> all = fx.addresses(0, 1, 2, 3);
|
|
+ final AereDecisionEvidence ev = collector(fx, sets(Map.of(), all, all), fx.armed());
|
|
+ final TBlock b = new TBlock(N, P, Bytes.of(0x0b), 0);
|
|
+ final TBlock sibling = new TBlock(N, P, Bytes.of(0x5b), 0);
|
|
+ for (final int i : new int[] {0, 1, 2}) {
|
|
+ assertThat(ev.observeCommit(fx.honest(i, b, 1))).isTrue();
|
|
+ }
|
|
+ assertThat(ev.countedAuthors(N)).as("no block known yet: nothing counted before it is verified").isEmpty();
|
|
+ assertThat(ev.quorumFor(sibling)).as("a sibling is not decided by votes on b").isEmpty();
|
|
+ final Optional<AereDecisionEvidence.Proof> proof = ev.quorumFor(b);
|
|
+ assertThat(proof)
|
|
+ .as("Q1 at round 1 under digest_1 (verified authors %d, Q=3)", ev.countedAuthors(N).size())
|
|
+ .isPresent();
|
|
+ assertThat(proof.get().kind()).isEqualTo(AereDecisionEvidence.Proof.Kind.QUORUM_OF_ROUND);
|
|
+ assertThat(proof.get().round()).isEqualTo(1);
|
|
+ assertThat(proof.get().onchainHash()).isEqualTo(b.onchain());
|
|
+ assertThat(proof.get().authors()).containsExactlyInAnyOrderElementsOf(fx.addresses(0, 1, 2));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void indexClaimsTakeNoSlot() {
|
|
+ final AereD412Fixture fx = new AereD412Fixture(4, true);
|
|
+ final List<Address> all = fx.addresses(0, 1, 2, 3);
|
|
+ final AereDecisionEvidence ev = collector(fx, sets(Map.of(), all, all), fx.armed());
|
|
+ final TBlock b = new TBlock(N, P, Bytes.of(0x0b), 0);
|
|
+ ev.observeProposedBlock(fx.address(0), b, Optional.empty());
|
|
+ // X = node 3, FIRST: its own commits carrying the genuine seals of indexes 0, 1, 2
|
|
+ for (final int i : new int[] {0, 1, 2}) {
|
|
+ assertThat(ev.observeCommit(fx.commit(3, b, 0, i, i)))
|
|
+ .as("X claiming index %d must not take a slot", i)
|
|
+ .isFalse();
|
|
+ }
|
|
+ // 2026-09-30 (second review): the three claims share one (round, digest) of X's own class; a refusal does not give the
|
|
+ // place back, so the first MAX_VARIANTS are judged and refused and the rest is dropped before any verification
|
|
+ assertThat(ev.refused()).isEqualTo(AereDecisionEvidence.MAX_VARIANTS);
|
|
+ assertThat(ev.dropped()).isEqualTo(3 - AereDecisionEvidence.MAX_VARIANTS);
|
|
+ assertThat(ev.countedAuthors(N)).isEmpty();
|
|
+ // X fills its own slot with other digests
|
|
+ final SECPSignature seal = fx.nodes.getNode(3).getNodeKey().sign(Bytes32.ZERO);
|
|
+ for (int k = 0; k < 40; k++) {
|
|
+ ev.observeCommit(fx.flood(3, N, k % 10, Hash.hash(Bytes.ofUnsignedInt(k)), seal));
|
|
+ }
|
|
+ assertThat(ev.entriesOf(fx.address(3))).isLessThanOrEqualTo(AereDecisionEvidence.MAX_PER_AUTHOR);
|
|
+ // the honest votes arrive after, and all of them count
|
|
+ for (final int i : new int[] {0, 1, 2}) {
|
|
+ assertThat(ev.observeCommit(fx.honest(i, b, 0))).as("honest %d counts", i).isTrue();
|
|
+ }
|
|
+ final Optional<AereDecisionEvidence.Proof> proof = ev.quorumFor(b);
|
|
+ assertThat(proof).as("the honest quorum survives X's claims").isPresent();
|
|
+ assertThat(proof.get().authors()).containsExactlyInAnyOrderElementsOf(fx.addresses(0, 1, 2));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void floodIsBoundedAndNeverTouchesTheSealCache(@TempDir final Path dir) throws Exception {
|
|
+ final AereD412Fixture fx = new AereD412Fixture(5, false);
|
|
+ final List<Address> admitted = fx.addresses(0, 1, 2, 3);
|
|
+ final AereDecisionEvidence ev = collector(fx, sets(Map.of(), admitted, admitted), null);
|
|
+ final PqSealCache cache = PqSealCache.instance();
|
|
+ cache.enablePersistence(dir, 2800L);
|
|
+ try {
|
|
+ final int entriesBefore = cache.entryCount();
|
|
+ final long highestBefore = highestSeen(cache);
|
|
+ final long filesBefore = filesIn(dir);
|
|
+ final SECPSignature seal = fx.nodes.getNode(3).getNodeKey().sign(Bytes32.ZERO);
|
|
+ final int flood = 100_000;
|
|
+ for (int i = 0; i < flood; i++) {
|
|
+ final long height = D - 20 + (i % (W + 60));
|
|
+ ev.observeCommit(fx.flood(3, height, i / (W + 60), Hash.hash(Bytes.ofUnsignedInt(i)), seal));
|
|
+ }
|
|
+ final SECPSignature outsiderSeal = fx.nodes.getNode(4).getNodeKey().sign(Bytes32.ZERO);
|
|
+ for (int i = 0; i < 1_000; i++) {
|
|
+ ev.observeCommit(fx.flood(4, N + (i % W), 0, Hash.hash(Bytes.ofUnsignedInt(i)), outsiderSeal));
|
|
+ }
|
|
+ assertThat(ev.entriesOf(fx.address(3)))
|
|
+ .as("one author, W heights, MAX_PER_AUTHOR each")
|
|
+ .isLessThanOrEqualTo(W * AereDecisionEvidence.MAX_PER_AUTHOR);
|
|
+ assertThat(ev.entries()).isLessThanOrEqualTo(W * AereDecisionEvidence.MAX_PER_AUTHOR);
|
|
+ assertThat(ev.entriesOf(fx.address(4))).as("an author outside the admission set").isZero();
|
|
+ final Set<Long> heights = ev.heights();
|
|
+ assertThat(heights).isNotEmpty();
|
|
+ assertThat(heights).allMatch(h -> h > D && h <= D + W);
|
|
+ assertThat(cache.entryCount()).as("PqSealCache.entryCount untouched").isEqualTo(entriesBefore);
|
|
+ assertThat(highestSeen(cache)).as("PqSealCache.highestSeen untouched").isEqualTo(highestBefore);
|
|
+ assertThat(filesIn(dir)).as("no seal file written").isEqualTo(filesBefore);
|
|
+ } finally {
|
|
+ cache.disablePersistence();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void eachMessageIsVerifiedOnce() {
|
|
+ final AereD412Fixture fx = new AereD412Fixture(4, true);
|
|
+ final List<Address> all = fx.addresses(0, 1, 2, 3);
|
|
+ final AereDecisionEvidence ev = collector(fx, sets(Map.of(), all, all), fx.armed());
|
|
+ final TBlock b = new TBlock(N, P, Bytes.of(0x0b), 0);
|
|
+ ev.observeProposedBlock(fx.address(1), b, Optional.empty());
|
|
+ // X's seal claims its own index 3 but is signed by key 0: the PQ verification refuses it
|
|
+ final Commit bad = fx.commit(3, b, 0, 3, 0);
|
|
+ for (int copy = 0; copy < 5; copy++) {
|
|
+ ev.observeCommit(bad);
|
|
+ }
|
|
+ assertThat(ev.verifications()).as("a refused message re-gossiped 5 times").isEqualTo(1);
|
|
+ assertThat(fx.pqVerifyCalls()).isEqualTo(1);
|
|
+ for (final int i : new int[] {0, 1, 2}) {
|
|
+ ev.observeCommit(fx.honest(i, b, 0));
|
|
+ }
|
|
+ assertThat(ev.verifications()).isEqualTo(4);
|
|
+ assertThat(ev.quorumFor(b)).isPresent();
|
|
+ assertThat(ev.quorumFor(b)).isPresent();
|
|
+ ev.observeCommit(fx.honest(0, b, 0));
|
|
+ assertThat(ev.verifications()).as("a second judgement makes 0 verifications").isEqualTo(4);
|
|
+ assertThat(fx.pqVerifyCalls()).isEqualTo(4);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void childSetIsTheSetAfterTheBlock() {
|
|
+ final AereD412Fixture fx = new AereD412Fixture(5, true);
|
|
+ final TBlock b = new TBlock(N, P, Bytes.of(0x0b), 0);
|
|
+ final Map<Hash, Collection<Address>> after = new HashMap<>();
|
|
+ after.put(P, fx.addresses(0, 1, 2, 3));
|
|
+ after.put(b.onchain(), fx.addresses(0, 1, 2, 3, 4));
|
|
+ final AereDecisionEvidence ev =
|
|
+ collector(fx, sets(after, List.of(), fx.addresses(0, 1, 2, 3, 4)), fx.armed());
|
|
+ final TBlock c = new TBlock(N + 1, b.onchain(), Bytes.of(0x0c), 0);
|
|
+ ev.observeCommit(fx.honest(4, c, 0));
|
|
+ ev.observeCommit(fx.honest(0, c, 0));
|
|
+ final Optional<AereDecisionEvidence.Proof> proof = ev.childProofFor(b, List.of(c));
|
|
+ assertThat(proof).as("node 4 was voted in by b: it counts on the child").isPresent();
|
|
+ assertThat(proof.get().authors()).containsExactlyInAnyOrderElementsOf(fx.addresses(0, 4));
|
|
+ assertThat(proof.get().childOnchainHash()).contains(c.onchain());
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void childNeedsFPlusOne() {
|
|
+ final AereD412Fixture fx = new AereD412Fixture(4, true);
|
|
+ final List<Address> all = fx.addresses(0, 1, 2, 3);
|
|
+ final TBlock b = new TBlock(N, P, Bytes.of(0x0b), 0);
|
|
+ final TBlock c = new TBlock(N + 1, b.onchain(), Bytes.of(0x0c), 0);
|
|
+ // child heard as a proposal
|
|
+ final AereDecisionEvidence ev = collector(fx, sets(Map.of(), all, all), fx.armed());
|
|
+ ev.observeProposedBlock(fx.address(1), c, Optional.empty());
|
|
+ ev.observeCommit(fx.honest(0, c, 0));
|
|
+ assertThat(ev.childProofFor(b, List.of())).as("f=1 commit on the child: not a proof").isEmpty();
|
|
+ ev.observeCommit(fx.honest(2, c, 1));
|
|
+ final Optional<AereDecisionEvidence.Proof> proof = ev.childProofFor(b, List.of());
|
|
+ assertThat(proof).as("f+1=2 commits, any round").isPresent();
|
|
+ assertThat(proof.get().kind()).isEqualTo(AereDecisionEvidence.Proof.Kind.CHILD_F_PLUS_ONE);
|
|
+ // child stored, commits heard before it was known
|
|
+ final AereDecisionEvidence ev2 = collector(fx, sets(Map.of(), all, all), fx.armed());
|
|
+ ev2.observeCommit(fx.honest(1, c, 0));
|
|
+ assertThat(ev2.childProofFor(b, List.of(c))).isEmpty();
|
|
+ ev2.observeCommit(fx.honest(3, c, 0));
|
|
+ assertThat(ev2.childProofFor(b, List.of(c))).isPresent();
|
|
+ // a child of ANOTHER parent proves nothing about b
|
|
+ final TBlock stranger = new TBlock(N + 1, P, Bytes.of(0x0d), 0);
|
|
+ final AereDecisionEvidence ev3 = collector(fx, sets(Map.of(), all, all), fx.armed());
|
|
+ ev3.observeCommit(fx.honest(0, stranger, 0));
|
|
+ ev3.observeCommit(fx.honest(1, stranger, 0));
|
|
+ assertThat(ev3.childProofFor(b, List.of(stranger))).isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void ancestryIsOnTheParentPath() {
|
|
+ final TBlock a = new TBlock(N, P, Bytes.of(1), 0);
|
|
+ final TBlock siblingOfA = new TBlock(N, P, Bytes.of(9), 0);
|
|
+ final TBlock bb = new TBlock(N + 1, a.onchain(), Bytes.of(2), 0);
|
|
+ final TBlock c = new TBlock(N + 2, bb.onchain(), Bytes.of(3), 0);
|
|
+ final Map<Hash, QbftBlockHeader> byHash = new HashMap<>();
|
|
+ for (final TBlock t : List.of(a, siblingOfA, bb, c)) {
|
|
+ byHash.put(t.onchain(), t.getHeader());
|
|
+ }
|
|
+ assertThat(AereDecisionEvidence.decidedByAncestry(c.getHeader(), a.getHeader(), h -> Optional.ofNullable(byHash.get(h)), 16))
|
|
+ .isTrue();
|
|
+ assertThat(AereDecisionEvidence.decidedByAncestry(c.getHeader(), c.getHeader(), h -> Optional.ofNullable(byHash.get(h)), 16))
|
|
+ .isTrue();
|
|
+ assertThat(AereDecisionEvidence.decidedByAncestry(c.getHeader(), siblingOfA.getHeader(), h -> Optional.ofNullable(byHash.get(h)), 16))
|
|
+ .as("a sibling at the same height is not an ancestor")
|
|
+ .isFalse();
|
|
+ assertThat(AereDecisionEvidence.decidedByAncestry(c.getHeader(), a.getHeader(), h -> Optional.ofNullable(byHash.get(h)), 1))
|
|
+ .as("beyond the walk limit")
|
|
+ .isFalse();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void retainsTheProofForTheEcho() {
|
|
+ final AereD412Fixture fx = new AereD412Fixture(4, false);
|
|
+ final List<Address> all = fx.addresses(0, 1, 2, 3);
|
|
+ final AereDecisionEvidence ev = collector(fx, sets(Map.of(), all, all), null);
|
|
+ final TBlock b = new TBlock(N, P, Bytes.of(0x0b), 0);
|
|
+ for (final int i : new int[] {0, 1, 2}) {
|
|
+ ev.observeCommit(fx.commit(i, b, 0, -1, -1));
|
|
+ }
|
|
+ final AereDecisionEvidence.Proof proof = ev.quorumFor(b).orElseThrow();
|
|
+ ev.markDecided(proof);
|
|
+ assertThat(ev.decidedHeight()).isEqualTo(N);
|
|
+ assertThat(ev.retainedProof(N)).isPresent();
|
|
+ assertThat(ev.retainedProof(N).get().commits()).hasSize(3);
|
|
+ assertThat(ev.retainedBytes()).isPositive().isLessThanOrEqualTo(AereDecisionEvidence.MAX_RETAINED_BYTES);
|
|
+ assertThat(ev.observeCommit(fx.commit(3, b, 0, -1, -1))).as("seq <= D is not collected").isFalse();
|
|
+ assertThat(ev.heights()).isEmpty();
|
|
+ ev.markDecidedHeight(N + W);
|
|
+ assertThat(ev.retainedProof(N)).as("D-W is still kept").isPresent();
|
|
+ ev.markDecidedHeight(N + W + 1);
|
|
+ assertThat(ev.retainedProof(N)).as("below D-W the proof is dropped").isEmpty();
|
|
+ assertThat(ev.retainedBytes()).isZero();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void windowIsDecidedPlusW() {
|
|
+ final AereD412Fixture fx = new AereD412Fixture(4, false);
|
|
+ final List<Address> all = fx.addresses(0, 1, 2, 3);
|
|
+ final AereDecisionEvidence ev = collector(fx, sets(Map.of(), all, all), null);
|
|
+ final SECPSignature seal = fx.nodes.getNode(0).getNodeKey().sign(Bytes32.ZERO);
|
|
+ assertThat(ev.observeCommit(fx.flood(0, D, 0, Hash.hash(Bytes.of(1)), seal))).isFalse();
|
|
+ assertThat(ev.observeCommit(fx.flood(0, D + W + 1, 0, Hash.hash(Bytes.of(2)), seal))).isFalse();
|
|
+ assertThat(ev.observeCommit(fx.flood(0, D + W, 0, Hash.hash(Bytes.of(3)), seal))).isTrue();
|
|
+ assertThat(ev.observeCommit(fx.flood(0, D + 1, 0, Hash.hash(Bytes.of(4)), seal))).isTrue();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aCopiedCommitSealCannotShadowTheHonestVote() {
|
|
+ final AereD412Fixture fx = new AereD412Fixture(4, true);
|
|
+ fx.installFinality();
|
|
+ final List<Address> all = fx.addresses(0, 1, 2, 3);
|
|
+ final AereDecisionEvidence ev = collector(fx, sets(Map.of(), all, all), fx.armed());
|
|
+ final TBlock b = new TBlock(N, P, Bytes.of(0x0b), 0);
|
|
+ final Commit honestA = fx.honest(0, b, 1);
|
|
+ // X = node 3 copies A's commit seal: once with another round and A's genuine Falcon seal, and
|
|
+ // MAX_VARIANTS times at A's round with a garbage Falcon seal claiming A's index; X signs the envelopes
|
|
+ final List<Commit> copies = new ArrayList<>();
|
|
+ copies.add(fx.copyOf(honestA, 3, 2, honestA.getFalconSeal()));
|
|
+ for (int k = 0; k < AereDecisionEvidence.MAX_VARIANTS; k++) {
|
|
+ copies.add(
|
|
+ fx.copyOf(honestA, 3, 1, Optional.of(new FalconSeal(0, Bytes.repeat((byte) (k + 1), 600)))));
|
|
+ }
|
|
+ for (final Commit c : copies) {
|
|
+ assertThat(c.getAuthor())
|
|
+ .as("from H_fin a copy of A's commit seal is authored by A (the regime under test)")
|
|
+ .isEqualTo(fx.address(0));
|
|
+ ev.observeCommit(c);
|
|
+ }
|
|
+ // the block is known only as STORED: every vote waits, and the honest ones arrive after the copies
|
|
+ assertThat(ev.observeCommit(honestA)).as("A's own vote is kept after X's copies").isTrue();
|
|
+ assertThat(ev.observeCommit(fx.honest(1, b, 1))).isTrue();
|
|
+ assertThat(ev.observeCommit(fx.honest(2, b, 1))).isTrue();
|
|
+ final Optional<AereDecisionEvidence.Proof> proof = ev.quorumFor(b);
|
|
+ assertThat(proof).as("Q1 with A's vote, whatever X sent first").isPresent();
|
|
+ assertThat(proof.get().round()).isEqualTo(1);
|
|
+ assertThat(proof.get().authors()).containsExactlyInAnyOrderElementsOf(fx.addresses(0, 1, 2));
|
|
+ final Commit countedForA =
|
|
+ proof.get().commits().stream().filter(c -> c.getAuthor().equals(fx.address(0))).findFirst().orElseThrow();
|
|
+ assertThat(countedForA.encode()).as("the vote counted for A is A's own message").isEqualTo(honestA.encode());
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aRegistryRefusalIsRetriedInTheNextGeneration() {
|
|
+ final AereD412Fixture fx = new AereD412Fixture(4, true);
|
|
+ final List<Address> all = fx.addresses(0, 1, 2, 3);
|
|
+ final AereDecisionEvidence ev = collector(fx, sets(Map.of(), all, all), fx.armed());
|
|
+ final TBlock b = new TBlock(N, P, Bytes.of(0x0b), 0);
|
|
+ ev.observeProposedBlock(fx.address(3), b, Optional.empty());
|
|
+ // the late-anchor registry is still PENDING (D-358): every commit is refused for the registry's state
|
|
+ fx.setRegistryPending(true);
|
|
+ final Commit a = fx.honest(0, b, 0);
|
|
+ assertThat(ev.observeCommit(a)).as("a registry refusal keeps the message").isTrue();
|
|
+ assertThat(ev.observeCommit(fx.honest(1, b, 0))).isTrue();
|
|
+ assertThat(ev.observeCommit(fx.honest(2, b, 0))).isTrue();
|
|
+ assertThat(ev.countedAuthors(N)).as("nothing counts while the registry is PENDING").isEmpty();
|
|
+ assertThat(ev.quorumFor(b)).isEmpty();
|
|
+ assertThat(ev.verifications()).isEqualTo(3);
|
|
+ ev.observeCommit(a);
|
|
+ assertThat(ev.verifications()).as("the same message, the same registry state: no new verification").isEqualTo(3);
|
|
+ // the registry activates; the very same message arrives again (re-gossip, or the echo)
|
|
+ fx.setRegistryPending(false);
|
|
+ assertThat(ev.observeCommit(a)).isTrue();
|
|
+ assertThat(ev.countedAuthors(N)).as("A's vote counts once the registry is active").containsExactly(fx.address(0));
|
|
+ final Optional<AereDecisionEvidence.Proof> proof = ev.quorumFor(b);
|
|
+ assertThat(proof).as("the waiting votes of B and C are judged again in the new generation").isPresent();
|
|
+ assertThat(proof.get().authors()).containsExactlyInAnyOrderElementsOf(fx.addresses(0, 1, 2));
|
|
+ assertThat(ev.verifications()).isEqualTo(6);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void verificationsPerAuthorAreBounded() {
|
|
+ final AereD412Fixture fx = new AereD412Fixture(4, true);
|
|
+ final List<Address> all = fx.addresses(0, 1, 2, 3);
|
|
+ final AereDecisionEvidence ev = collector(fx, sets(Map.of(), all, all), fx.armed());
|
|
+ final TBlock bx = new TBlock(N, P, Bytes.of(0x3b), 0);
|
|
+ assertThat(ev.observeProposedBlock(fx.address(3), bx, Optional.empty())).isTrue();
|
|
+ // X = node 3 commits on its own heard block at rounds 0, 1, 2, ... 99: every message is new and valid
|
|
+ // (built first: the fixture's emitter path uses the same counted block interface)
|
|
+ final int rounds = 100;
|
|
+ final List<Commit> flood = new ArrayList<>();
|
|
+ for (int r = 0; r < rounds; r++) {
|
|
+ flood.add(fx.honest(3, bx, r));
|
|
+ }
|
|
+ final long replacementsBefore = fx.blockInterface.replacements();
|
|
+ for (final Commit c : flood) {
|
|
+ ev.observeCommit(c);
|
|
+ }
|
|
+ assertThat(ev.verifications())
|
|
+ .as("one key, one height: at most MAX_PER_AUTHOR rounds are ever verified")
|
|
+ .isLessThanOrEqualTo(AereDecisionEvidence.MAX_PER_AUTHOR);
|
|
+ assertThat(fx.pqVerifyCalls()).isLessThanOrEqualTo(AereDecisionEvidence.MAX_PER_AUTHOR);
|
|
+ assertThat(fx.blockInterface.replacements() - replacementsBefore)
|
|
+ .as("round replacements (recoding) bounded too")
|
|
+ .isLessThanOrEqualTo(4L * AereDecisionEvidence.MAX_PER_AUTHOR);
|
|
+ assertThat(ev.entriesOf(fx.address(3))).isLessThanOrEqualTo(AereDecisionEvidence.MAX_PER_AUTHOR);
|
|
+ assertThat(ev.dropped()).isGreaterThanOrEqualTo(rounds - AereDecisionEvidence.MAX_PER_AUTHOR);
|
|
+ // another author is untouched by X's budget
|
|
+ assertThat(ev.observeCommit(fx.honest(0, bx, 7))).isTrue();
|
|
+ assertThat(ev.countedAuthors(N)).contains(fx.address(0));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void refusedVariantsDoNotFreeTheirPlace() {
|
|
+ // 2026-09-30, second review of step 1: the variant cap counted only the messages still WAITING, and a refusal of the
|
|
+ // MESSAGE removes it from waiting, so one key could buy a predicate run (and a Falcon verification) per fresh envelope on
|
|
+ // ONE (round, digest). Here the enforcement demands SLH-DSA at every height (as at an anchor parent): X's own commit with a
|
|
+ // VALID Falcon seal and an SLH-DSA seal of another index is refused by the message ("one commit, one signer") only AFTER
|
|
+ // its Falcon seal was verified, the most expensive refusal a key can order.
|
|
+ final AereD412Fixture fx = new AereD412Fixture(4, true);
|
|
+ final List<Address> all = fx.addresses(0, 1, 2, 3);
|
|
+ final AereDecisionEvidence ev = collector(fx, sets(Map.of(), all, all), fx.hybridArmed());
|
|
+ final TBlock bx = new TBlock(N, P, Bytes.of(0x3b), 0);
|
|
+ assertThat(ev.observeProposedBlock(fx.address(3), bx, Optional.empty())).isTrue();
|
|
+ final int copies = 100;
|
|
+ final int max = AereDecisionEvidence.MAX_VARIANTS;
|
|
+ // SELF: X = node 3, its own envelope and commit seal, a valid Falcon seal of its own index, each message new by its extra seal
|
|
+ for (int k = 0; k < copies; k++) {
|
|
+ assertThat(ev.observeCommit(fx.commit(3, bx, 0, 3, 3, List.of(slhOfIndex(2, k)))))
|
|
+ .as("SELF variant %d is refused, never counted", k)
|
|
+ .isFalse();
|
|
+ }
|
|
+ assertThat(ev.refused()).as("SELF: refused by the message").isEqualTo(max);
|
|
+ assertThat(ev.verifications()).as("SELF: one (round, digest), %d fresh envelopes", copies).isEqualTo(max);
|
|
+ assertThat(fx.pqVerifyCalls()).as("SELF: Falcon verifications bought by X").isEqualTo(max);
|
|
+ assertThat(ev.classifications())
|
|
+ .as("SELF: the other class still had room, so every message paid the two envelope recoveries")
|
|
+ .isEqualTo(copies);
|
|
+ // FOREIGN: X's envelope over A's commit seal, same (round, digest): refused by the message at the ECDSA check
|
|
+ final Commit ofA = fx.honest(0, bx, 0);
|
|
+ for (int k = 0; k < copies; k++) {
|
|
+ assertThat(ev.observeCommit(fx.copyOf(ofA, 3, 0, Optional.of(new FalconSeal(3, garbage(64, k))))))
|
|
+ .as("FOREIGN variant %d is refused, never counted", k)
|
|
+ .isFalse();
|
|
+ }
|
|
+ assertThat(ev.verifications()).as("FOREIGN: its own class, its own MAX_VARIANTS").isEqualTo(2L * max);
|
|
+ assertThat(fx.pqVerifyCalls()).as("the FOREIGN copies never reach a Falcon verification").isEqualTo(max);
|
|
+ assertThat(ev.classifications()).as("FOREIGN: recovered only while its class had room").isEqualTo(copies + max);
|
|
+ // both classes are full for this (round, digest): nothing more is verified, and nothing more is even classified
|
|
+ for (int k = 0; k < copies; k++) {
|
|
+ ev.observeCommit(fx.commit(3, bx, 0, 3, 3, List.of(slhOfIndex(2, copies + k))));
|
|
+ ev.observeCommit(fx.copyOf(ofA, 3, 0, Optional.of(new FalconSeal(3, garbage(64, copies + k)))));
|
|
+ }
|
|
+ assertThat(ev.classifications())
|
|
+ .as("no class has room: dropped before the two ECDSA recoveries")
|
|
+ .isEqualTo(copies + max);
|
|
+ assertThat(ev.verifications()).isEqualTo(2L * max);
|
|
+ assertThat(fx.pqVerifyCalls()).isEqualTo(max);
|
|
+ assertThat(ev.entriesOf(fx.address(3))).as("nothing of X is held: every admitted variant was refused").isZero();
|
|
+ // X's budget is X's: A's own message on the same block still reaches the predicate (and is refused only for its own
|
|
+ // missing SLH-DSA seal, which this enforcement demands of everybody)
|
|
+ ev.observeCommit(ofA);
|
|
+ assertThat(ev.verifications()).as("A's message is judged").isEqualTo(2L * max + 1);
|
|
+ assertThat(fx.pqVerifyCalls()).as("A's Falcon seal is verified").isEqualTo(max + 1L);
|
|
+ }
|
|
+
|
|
+ private static SchemeSeal slhOfIndex(final int index, final int k) {
|
|
+ return new SchemeSeal(SealSchemes.SLH_DSA_128S.wireId(), index, garbage(7856, k));
|
|
+ }
|
|
+
|
|
+ private static Bytes garbage(final int size, final int k) {
|
|
+ return Bytes.concatenate(Bytes.repeat((byte) 0x5a, size - 4), Bytes.ofUnsignedInt(k));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void proposalBytesAreBounded() {
|
|
+ final AereD412Fixture fx = new AereD412Fixture(4, false);
|
|
+ final List<Address> all = fx.addresses(0, 1, 2, 3);
|
|
+ final AereDecisionEvidence ev = collector(fx, sets(Map.of(), all, all), null);
|
|
+ final long big = 1L << 20;
|
|
+ int keptX = 0;
|
|
+ for (int h = 0; h < W; h++) {
|
|
+ for (int k = 0; k < AereDecisionEvidence.MAX_PROPOSALS_PER_AUTHOR; k++) {
|
|
+ final TBlock blk = new TBlock(N + h, P, Bytes.ofUnsignedInt(h * 8L + k), 0, big);
|
|
+ if (ev.observeProposedBlock(fx.address(3), blk, Optional.empty())) {
|
|
+ keptX++;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ assertThat(ev.proposalBytesOf(fx.address(3)))
|
|
+ .as("one author's proposed blocks, in bytes")
|
|
+ .isLessThanOrEqualTo(AereDecisionEvidence.MAX_PROPOSAL_BYTES_PER_AUTHOR);
|
|
+ assertThat(ev.proposalBytes()).isLessThanOrEqualTo(AereDecisionEvidence.MAX_PROPOSAL_BYTES);
|
|
+ assertThat(keptX)
|
|
+ .as("X keeps what its byte budget holds and no more")
|
|
+ .isEqualTo((int) (AereDecisionEvidence.MAX_PROPOSAL_BYTES_PER_AUTHOR / fx.sizeOf(new TBlock(N, P, Bytes.EMPTY, 0, big))));
|
|
+ // an honest proposal of a child of b is still held, and Q2 goes through it
|
|
+ final TBlock b = new TBlock(N, P, Bytes.of(0x0b), 0);
|
|
+ final TBlock c = new TBlock(N + 1, b.onchain(), Bytes.of(0x0c), 0);
|
|
+ assertThat(ev.observeProposedBlock(fx.address(1), c, Optional.empty())).isTrue();
|
|
+ ev.observeCommit(fx.commit(0, c, 0, -1, -1));
|
|
+ ev.observeCommit(fx.commit(2, c, 0, -1, -1));
|
|
+ assertThat(ev.childProofFor(b, List.of())).isPresent();
|
|
+ // everything at or below the decided head is released
|
|
+ ev.markDecidedHeight(N + W);
|
|
+ assertThat(ev.proposalBytes()).isZero();
|
|
+ assertThat(ev.proposalBytesOf(fx.address(3))).isZero();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void anIndexClaimIsNoSlotWithoutEnforcement() {
|
|
+ final AereD412Fixture fx = new AereD412Fixture(4, true);
|
|
+ final List<Address> all = fx.addresses(0, 1, 2, 3);
|
|
+ final AereDecisionEvidence ev = collector(fx, sets(Map.of(), all, all), null);
|
|
+ final TBlock b = new TBlock(N, P, Bytes.of(0x0b), 0);
|
|
+ ev.observeProposedBlock(fx.address(1), b, Optional.empty());
|
|
+ // X = node 3: a valid ECDSA vote, whose Falcon seal claims index 0, then another claiming index 1
|
|
+ assertThat(ev.observeCommit(fx.commit(3, b, 0, 0, 0))).isTrue();
|
|
+ ev.observeCommit(fx.commit(3, b, 0, 1, 1));
|
|
+ ev.observeCommit(fx.honest(2, b, 0));
|
|
+ assertThat(ev.entriesOf(fx.address(3))).isLessThanOrEqualTo(AereDecisionEvidence.MAX_PER_AUTHOR);
|
|
+ assertThat(ev.countedAuthors(N))
|
|
+ .as("the slots are the recovered authors, not the claimed indexes")
|
|
+ .containsExactlyInAnyOrderElementsOf(fx.addresses(3, 2));
|
|
+ assertThat(ev.quorumFor(b)).as("X plus one honest is not a quorum, whatever indexes X claims").isEmpty();
|
|
+ ev.observeCommit(fx.honest(1, b, 0));
|
|
+ final AereDecisionEvidence.Proof proof = ev.quorumFor(b).orElseThrow();
|
|
+ assertThat(proof.authors()).hasSize(proof.commits().size());
|
|
+ assertThat(proof.authors()).containsExactlyInAnyOrderElementsOf(fx.addresses(3, 2, 1));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void q1NeedsOneRound() {
|
|
+ final AereD412Fixture fx = new AereD412Fixture(4, true);
|
|
+ final List<Address> all = fx.addresses(0, 1, 2, 3);
|
|
+ final AereDecisionEvidence ev = collector(fx, sets(Map.of(), all, all), fx.armed());
|
|
+ final TBlock b = new TBlock(N, P, Bytes.of(0x0b), 0);
|
|
+ ev.observeCommit(fx.honest(0, b, 0));
|
|
+ ev.observeCommit(fx.honest(1, b, 0));
|
|
+ ev.observeCommit(fx.honest(2, b, 1));
|
|
+ assertThat(ev.quorumFor(b)).as("2 votes at round 0 and 1 at round 1 are not a quorum of one round").isEmpty();
|
|
+ assertThat(ev.countedAuthors(N)).as("all three were verified and counted").hasSize(3);
|
|
+ ev.observeCommit(fx.honest(3, b, 0));
|
|
+ final AereDecisionEvidence.Proof proof = ev.quorumFor(b).orElseThrow();
|
|
+ assertThat(proof.round()).isZero();
|
|
+ assertThat(proof.authors()).containsExactlyInAnyOrderElementsOf(fx.addresses(0, 1, 3));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void q1CountsInTheSetAfterTheParent() {
|
|
+ final AereD412Fixture fx = new AereD412Fixture(5, true);
|
|
+ final TBlock b = new TBlock(N, P, Bytes.of(0x0b), 0);
|
|
+ final Map<Hash, Collection<Address>> after = new HashMap<>();
|
|
+ after.put(P, fx.addresses(0, 1, 2, 3));
|
|
+ after.put(b.onchain(), fx.addresses(0, 1, 2, 4));
|
|
+ final AereDecisionEvidence ev =
|
|
+ collector(fx, sets(after, List.of(), fx.addresses(0, 1, 2, 3, 4)), fx.armed());
|
|
+ ev.observeCommit(fx.honest(4, b, 0));
|
|
+ ev.observeCommit(fx.honest(0, b, 0));
|
|
+ ev.observeCommit(fx.honest(1, b, 0));
|
|
+ assertThat(ev.quorumFor(b)).as("node 4 joins AFTER b: its vote is not one of set(b)").isEmpty();
|
|
+ ev.observeCommit(fx.honest(3, b, 0));
|
|
+ final AereDecisionEvidence.Proof proof = ev.quorumFor(b).orElseThrow();
|
|
+ assertThat(proof.authors()).as("node 3 leaves after b and still decides b").containsExactlyInAnyOrderElementsOf(fx.addresses(0, 1, 3));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void q1UnderTheAnchorForm() {
|
|
+ PqAnchorProducer.useConfigForTesting(
|
|
+ new PqAnchorConfig(AereD412Fixture.CHAIN, D - 10, Map.of(D - 10, 0), OptionalInt.empty(), false));
|
|
+ final AereD412Fixture fx = new AereD412Fixture(4, true);
|
|
+ final List<Address> all = fx.addresses(0, 1, 2, 3);
|
|
+ final AereDecisionEvidence ev = collector(fx, sets(Map.of(), all, all), fx.armed());
|
|
+ final TBlock b = new TBlock(N, P, Bytes.of(0x0b), 0);
|
|
+ final Commit c0 = fx.honest(0, b, 2);
|
|
+ final Bytes32 anchorForm = PqAnchor.commitMessage(AereD412Fixture.CHAIN, N, b.onchain().getBytes());
|
|
+ assertThat(anchorForm).as("the anchor form is not the committed-seal digest").isNotEqualTo(Bytes32.wrap(c0.getDigest().getBytes()));
|
|
+ assertThat(fx.registry.verifyAtOwnHead(N, 0, anchorForm, c0.getFalconSeal().orElseThrow().getSignature()))
|
|
+ .as("the emitter path signs the anchor form over the round-0 hash")
|
|
+ .isTrue();
|
|
+ // node 1's seal over the plain committed-seal digest (the form below the anchor) must not count here
|
|
+ final TBlock p2 = b.atRound(2);
|
|
+ final Commit stale =
|
|
+ fx.nodes
|
|
+ .getMessageFactory(1)
|
|
+ .createCommit(
|
|
+ new ConsensusRoundIdentifier(N, 2),
|
|
+ p2.getHash(),
|
|
+ fx.nodes.getNode(1).getNodeKey().sign(Bytes32.wrap(p2.getHash().getBytes())),
|
|
+ Optional.of(fx.falconSeal(1, 1, Bytes32.wrap(p2.getHash().getBytes()))));
|
|
+ ev.observeCommit(c0);
|
|
+ ev.observeCommit(stale);
|
|
+ ev.observeCommit(fx.honest(2, b, 2));
|
|
+ assertThat(ev.quorumFor(b)).as("a seal over the pre-anchor form does not count under the anchor").isEmpty();
|
|
+ assertThat(ev.countedAuthors(N)).containsExactlyInAnyOrderElementsOf(fx.addresses(0, 2));
|
|
+ ev.observeCommit(fx.honest(1, b, 2));
|
|
+ final AereDecisionEvidence.Proof proof = ev.quorumFor(b).orElseThrow();
|
|
+ assertThat(proof.round()).isEqualTo(2);
|
|
+ assertThat(proof.authors()).containsExactlyInAnyOrderElementsOf(fx.addresses(0, 1, 2));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aBlockProposedWithAnotherRoundHasNoCommitAuthor() {
|
|
+ // the shape AereD412RealRoundTest shows Q1 cannot see below H_fin: the round-5 proposal carries a block written with round 0,
|
|
+ // so the commit's digest is the round-0 form while its seal signs the round-5 form (QbftRound.commitHashFor)
|
|
+ final AereD412Fixture fx = new AereD412Fixture(4, true);
|
|
+ fx.installFinality();
|
|
+ final TBlock proposedAtRoundZero = new TBlock(N, P, Bytes.of(0x0b), 0);
|
|
+ final Hash commitHash = fx.blockInterface.replaceRoundForCommitBlock(proposedAtRoundZero, 5).getHash();
|
|
+ final Commit c =
|
|
+ fx.nodes
|
|
+ .getMessageFactory(0)
|
|
+ .createCommit(
|
|
+ new ConsensusRoundIdentifier(N, 5),
|
|
+ proposedAtRoundZero.getHash(),
|
|
+ fx.nodes.getNode(0).getNodeKey().sign(Bytes32.wrap(commitHash.getBytes())),
|
|
+ Optional.of(fx.falconSeal(0, 0, Bytes32.wrap(commitHash.getBytes()))));
|
|
+ assertThat(c.getAuthor())
|
|
+ .as("from H_fin the commit seal is recovered over the message digest: such a commit has no author")
|
|
+ .isEqualTo(org.hyperledger.besu.consensus.common.bft.AerePqFinality.NO_AUTHOR);
|
|
+ final List<Address> all = fx.addresses(0, 1, 2, 3);
|
|
+ final AereDecisionEvidence ev = collector(fx, sets(Map.of(), all, all), fx.armed());
|
|
+ assertThat(ev.observeCommit(c)).isFalse();
|
|
+ assertThat(ev.observeCommit(fx.honest(0, proposedAtRoundZero, 5)))
|
|
+ .as("control: the honest shape (the proposal's round in the block) has its author")
|
|
+ .isTrue();
|
|
+ }
|
|
+
|
|
+ private static long highestSeen(final PqSealCache cache) throws ReflectiveOperationException {
|
|
+ final Field f = PqSealCache.class.getDeclaredField("highestSeen");
|
|
+ f.setAccessible(true);
|
|
+ return f.getLong(cache);
|
|
+ }
|
|
+
|
|
+ private static long filesIn(final Path dir) throws IOException {
|
|
+ try (Stream<Path> s = Files.walk(dir)) {
|
|
+ return s.filter(Files::isRegularFile).count();
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereLateSalvageRoundTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereLateSalvageRoundTest.java
|
|
new file mode 100644
|
|
index 0000000000..e668e813fc
|
|
--- /dev/null
|
|
+++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereLateSalvageRoundTest.java
|
|
@@ -0,0 +1,204 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft.core.statemachine;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
+import static org.mockito.Mockito.when;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.MessageTracker;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSealCache;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.common.bft.statemachine.FutureMessageBuffer;
|
|
+import org.hyperledger.besu.consensus.qbft.core.QbftMessageFixture;
|
|
+import org.hyperledger.besu.consensus.qbft.core.QbftReceivedMessageEventFixture;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagedata.CommitMessageData;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagedata.QbftV1;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCodec;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockHeader;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockchain;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftFinalState;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftGossiper;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftMessage;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+
|
|
+import com.google.common.collect.ImmutableList;
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.junit.jupiter.api.extension.ExtendWith;
|
|
+import org.mockito.Mock;
|
|
+import org.mockito.junit.jupiter.MockitoExtension;
|
|
+import org.mockito.junit.jupiter.MockitoSettings;
|
|
+import org.mockito.quality.Strictness;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), D-470, pasul 5 (2026-10-02): the D-227 salvage of LATE Commits in {@link QbftController} on the round-bound
|
|
+ * form (project 3.1 F; the probe the step-4 review left for step 5). Above H_r - 1 the late Commit of round 0 whose digest is
|
|
+ * the head's on-chain hash goes straight under (n, hash, 0); a late Commit of a round r > 0 names the head's digest AT r,
|
|
+ * which the controller cannot rebuild, so it is held aside (pending) under that digest and NEVER lands under round 0 (a seal
|
|
+ * over M_r filed under round 0 would be a seal of another round in that round's record). Below H_r the salvage of before,
|
|
+ * call by call (L1). The same five refusals as PqLateSealSalvageTest guard the new branch (non-validator, older height).
|
|
+ */
|
|
+@ExtendWith(MockitoExtension.class)
|
|
+@MockitoSettings(strictness = Strictness.LENIENT)
|
|
+public class AereLateSalvageRoundTest {
|
|
+
|
|
+ private static final long CHAIN = 220_895L;
|
|
+ private static final long HEAD = 3L;
|
|
+ private static final Hash HEAD_HASH = Hash.hash(Bytes.fromHexString("0xaa"));
|
|
+ private static final Hash DIGEST_AT_TWO = Hash.hash(Bytes.fromHexString("0xa2"));
|
|
+
|
|
+ @Mock private QbftBlockchain blockChain;
|
|
+ @Mock private QbftFinalState qbftFinalState;
|
|
+ @Mock private QbftBlockHeightManagerFactory blockHeightManagerFactory;
|
|
+ @Mock private QbftBlockHeader chainHeadBlockHeader;
|
|
+ @Mock private BaseQbftBlockHeightManager blockHeightManager;
|
|
+ @Mock private Commit commit;
|
|
+ @Mock private CommitMessageData commitMessageData;
|
|
+ @Mock private MessageTracker messageTracker;
|
|
+ @Mock private FutureMessageBuffer<QbftMessage> futureMessageBuffer;
|
|
+ @Mock private QbftGossiper qbftGossiper;
|
|
+ @Mock private QbftBlockCodec blockEncoder;
|
|
+
|
|
+ private final Address validator = Address.fromHexString("0x1");
|
|
+ private final Address nonValidator = Address.fromHexString("0x2");
|
|
+ private final FalconSeal seal = new FalconSeal(4, Bytes.fromHexString("0x29aabbcc"));
|
|
+
|
|
+ private QbftController qbftController;
|
|
+
|
|
+ /** H_r = 4: the head at 3 = H_r - 1 is round-bound. */
|
|
+ private static PqAnchorConfig withHr() {
|
|
+ return new PqAnchorConfig(CHAIN, 1L, Map.of(1L, 0), OptionalInt.empty(), false)
|
|
+ .withAnchorV2Block(2L)
|
|
+ .withCommitRoundBlock(4L);
|
|
+ }
|
|
+
|
|
+ private static PqAnchorConfig withoutHr() {
|
|
+ return new PqAnchorConfig(CHAIN, 1L, Map.of(1L, 0), OptionalInt.empty(), false).withAnchorV2Block(2L);
|
|
+ }
|
|
+
|
|
+ @BeforeEach
|
|
+ public void setup() {
|
|
+ PqSealCache.instance().clear();
|
|
+ when(blockChain.getChainHeadHeader()).thenReturn(chainHeadBlockHeader);
|
|
+ when(blockChain.getChainHeadBlockNumber()).thenReturn(HEAD);
|
|
+ when(blockHeightManagerFactory.create(any())).thenReturn(blockHeightManager);
|
|
+ when(qbftFinalState.getValidators()).thenReturn(ImmutableList.of(validator));
|
|
+ when(chainHeadBlockHeader.getNumber()).thenReturn(HEAD);
|
|
+ when(chainHeadBlockHeader.getHash()).thenReturn(HEAD_HASH);
|
|
+ when(blockHeightManager.getParentBlockHeader()).thenReturn(chainHeadBlockHeader);
|
|
+ when(blockHeightManager.getChainHeight()).thenReturn(HEAD + 1);
|
|
+ when(qbftFinalState.isLocalNodeValidator()).thenReturn(true);
|
|
+ when(messageTracker.hasSeenMessage(any())).thenReturn(false);
|
|
+ qbftController =
|
|
+ new QbftController(
|
|
+ blockChain,
|
|
+ qbftFinalState,
|
|
+ blockHeightManagerFactory,
|
|
+ qbftGossiper,
|
|
+ messageTracker,
|
|
+ futureMessageBuffer,
|
|
+ blockEncoder);
|
|
+ qbftController.start();
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ public void cleanup() {
|
|
+ PqSealCache.instance().clear();
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ }
|
|
+
|
|
+ private void deliverCommit(final long height, final int round, final Hash digest, final Address author) {
|
|
+ when(commit.getAuthor()).thenReturn(author);
|
|
+ when(commit.getRoundIdentifier()).thenReturn(new ConsensusRoundIdentifier(height, round));
|
|
+ when(commit.getDigest()).thenReturn(digest);
|
|
+ when(commit.getFalconSeal()).thenReturn(Optional.of(seal));
|
|
+ when(commitMessageData.getCode()).thenReturn(QbftV1.COMMIT);
|
|
+ when(commitMessageData.decode()).thenReturn(commit);
|
|
+ qbftController.handleMessageEvent(new QbftReceivedMessageEventFixture(new QbftMessageFixture(commitMessageData)));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void fromHrMinusOneALateCommitOfRoundZeroGoesUnderRoundZero() {
|
|
+ PqAnchorProducer.useConfigForTesting(withHr());
|
|
+ deliverCommit(HEAD, 0, HEAD_HASH, validator);
|
|
+ assertThat(PqSealCache.instance().sealsFor(HEAD, HEAD_HASH, 0))
|
|
+ .as("control: round 0 names the on-chain hash, so the salvage files it under (n, hash, 0)")
|
|
+ .containsExactly(seal);
|
|
+ assertThat(PqSealCache.instance().pendingCount()).isZero();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void fromHrMinusOneALateCommitOfRoundTwoIsHeldAsideAndNeverFiledUnderRoundZero() {
|
|
+ PqAnchorProducer.useConfigForTesting(withHr());
|
|
+ deliverCommit(HEAD, 2, DIGEST_AT_TWO, validator);
|
|
+ assertThat(PqSealCache.instance().sealsFor(HEAD, HEAD_HASH, 0))
|
|
+ .as("AERE-R1B-SALVARE: a late round-2 seal (over M_2) is never filed under round 0")
|
|
+ .isEmpty();
|
|
+ assertThat(PqSealCache.instance().sealsFor(HEAD, HEAD_HASH, 2))
|
|
+ .as("nor under round 2 directly: its digest is the head's digest AT 2, which the controller cannot check")
|
|
+ .isEmpty();
|
|
+ assertThat(PqSealCache.instance().pendingCount())
|
|
+ .as("it is held aside under the digest it names, for the producer to resolve")
|
|
+ .isEqualTo(1);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void fromHrMinusOneALateRoundTwoCommitNamingTheOnchainHashIsNotFiledUnderRoundZeroEither() {
|
|
+ PqAnchorProducer.useConfigForTesting(withHr());
|
|
+ deliverCommit(HEAD, 2, HEAD_HASH, validator);
|
|
+ assertThat(PqSealCache.instance().sealsFor(HEAD, HEAD_HASH, 0))
|
|
+ .as("AERE-R1B-SALVARE: round 2 claiming the round-0 digest still does not reach round 0")
|
|
+ .isEmpty();
|
|
+ assertThat(PqSealCache.instance().pendingCount()).isEqualTo(1);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void fromHrMinusOneTheRefusalsOfBeforeStillHold() {
|
|
+ PqAnchorProducer.useConfigForTesting(withHr());
|
|
+ deliverCommit(HEAD, 2, DIGEST_AT_TWO, nonValidator);
|
|
+ deliverCommit(HEAD - 1, 2, DIGEST_AT_TWO, validator);
|
|
+ deliverCommit(HEAD, 0, DIGEST_AT_TWO, validator);
|
|
+ assertThat(PqSealCache.instance().entryCount())
|
|
+ .as("a non-validator, an older height, a round-0 commit over another digest: nothing filed")
|
|
+ .isZero();
|
|
+ assertThat(PqSealCache.instance().pendingCount()).as("and nothing held aside").isZero();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void belowHrTheSalvageIsTheOneOfBeforeTheRoundIgnored() {
|
|
+ PqAnchorProducer.useConfigForTesting(withoutHr());
|
|
+ deliverCommit(HEAD, 2, HEAD_HASH, validator);
|
|
+ assertThat(PqSealCache.instance().sealsFor(HEAD, HEAD_HASH, 0))
|
|
+ .as("L1: below H_r a late commit over the head's hash is kept, whatever its round, as before")
|
|
+ .containsExactly(seal);
|
|
+ assertThat(PqSealCache.instance().pendingCount()).isZero();
|
|
+ PqSealCache.instance().clear();
|
|
+ deliverCommit(HEAD, 2, DIGEST_AT_TWO, validator);
|
|
+ assertThat(PqSealCache.instance().entryCount()).as("L1: over another digest, nothing").isZero();
|
|
+ assertThat(PqSealCache.instance().pendingCount()).isZero();
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereRoundBoundCommitTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereRoundBoundCommitTest.java
|
|
new file mode 100644
|
|
index 0000000000..15ff71e39c
|
|
--- /dev/null
|
|
+++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereRoundBoundCommitTest.java
|
|
@@ -0,0 +1,277 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft.core.statemachine;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
+import static org.mockito.Mockito.mock;
|
|
+import static org.mockito.Mockito.when;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorV3;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.AereD412Fixture;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.AereD412Fixture.TBlock;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.AereVoteCounts;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.CommitValidator;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.MessageValidator;
|
|
+import org.hyperledger.besu.crypto.SECPSignature;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+
|
|
+import java.util.Collection;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), D-470, pasul 5 (2026-10-02): RF2 REDONE ON THE NEW FORM (project 5.4; marker AERE-Q3-RF2-V3). The adversary of
|
|
+ * AIP-22 holds every classical key and no post-quantum key: it signs a commit of round 4 with A's classical key and copies A's
|
|
+ * genuine post-quantum seal from A's honest round-0 (or round-2) commit. {@link AereRoundFreeCommitTest} measures the gap below
|
|
+ * H_r (RED by design: the round-free seal vouches for any round). Here each defect probe is run on BOTH sides of H_r: below H_r
|
|
+ * it must count (the control that the fixture expresses the attack; if it did not, the probe above would prove nothing), from
|
|
+ * H_r - 1 it must not, and the honest round-4 vote must still count (the refusal is about the round, nothing else).
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>RF2-A: the copy is refused with AERE-PQ-COMMIT-R-01;
|
|
+ * <li>RF2-Q1: the collector of the decided head does not assemble a round-2 quorum from seals of rounds 0 and 2;
|
|
+ * <li>RF2-RS (closes a NEMASURAT of D-470): the RoundState of the lab (the D-454 path from H_fin, the REAL CommitValidator
|
|
+ * on the one target) does not commit on Q forged round-4 commits carrying seals of rounds 0 and 2.
|
|
+ * </ul>
|
|
+ */
|
|
+public class AereRoundBoundCommitTest {
|
|
+
|
|
+ private static final long ANCHOR = 50L;
|
|
+ private static final long V2 = 51L;
|
|
+ private static final long HR = 52L;
|
|
+ private static final long N = 100L;
|
|
+ private static final Hash P = Hash.hash(Bytes.of(9));
|
|
+
|
|
+ private AereD412Fixture fx;
|
|
+ private TBlock block;
|
|
+ private TBlock other;
|
|
+
|
|
+ @BeforeEach
|
|
+ public void arm() {
|
|
+ AereD412Fixture.uninstallAll();
|
|
+ fx = new AereD412Fixture(4, true);
|
|
+ fx.installFinality();
|
|
+ block = new TBlock(N, P, Bytes.of(0x0b), 0);
|
|
+ other = new TBlock(N, P, Bytes.of(0x0c), 0);
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ public void disarm() {
|
|
+ AereD412Fixture.uninstallAll();
|
|
+ }
|
|
+
|
|
+ private static void below() {
|
|
+ PqAnchorProducer.useConfigForTesting(
|
|
+ new PqAnchorConfig(AereD412Fixture.CHAIN, ANCHOR, Map.of(ANCHOR, 0), OptionalInt.empty(), false)
|
|
+ .withAnchorV2Block(V2));
|
|
+ }
|
|
+
|
|
+ private static void above() {
|
|
+ PqAnchorProducer.useConfigForTesting(
|
|
+ new PqAnchorConfig(AereD412Fixture.CHAIN, ANCHOR, Map.of(ANCHOR, 0), OptionalInt.empty(), false)
|
|
+ .withAnchorV2Block(V2)
|
|
+ .withCommitRoundBlock(HR));
|
|
+ }
|
|
+
|
|
+ /** The adversary's commit of {@code round} on {@code b}: A's classical seal over the round's digest, a copied PQ seal. */
|
|
+ private Commit forged(final int who, final TBlock b, final int round, final Optional<FalconSeal> seal) {
|
|
+ final TBlock proposal = b.atRound(round);
|
|
+ final Hash commitHash = fx.blockInterface.replaceRoundForCommitBlock(proposal, round).getHash();
|
|
+ final SECPSignature ecdsa = fx.nodes.getNode(who).getNodeKey().sign(Bytes32.wrap(commitHash.getBytes()));
|
|
+ return fx.nodes
|
|
+ .getMessageFactory(who)
|
|
+ .createCommit(new ConsensusRoundIdentifier(N, round), proposal.getHash(), ecdsa, seal);
|
|
+ }
|
|
+
|
|
+ private AereVoteCounts.Target target(final int round) {
|
|
+ return AereVoteCounts.Target.atRound(fx.blockInterface, block, N, round);
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------ RF2-A
|
|
+
|
|
+ @Test
|
|
+ public void rf2aBelowHrTheCopyCountsWhichIsTheGapTheFixtureExpresses() {
|
|
+ below();
|
|
+ final Collection<Address> set = fx.addresses(0, 1, 2, 3);
|
|
+ final Commit copied = forged(0, block, 4, fx.honest(0, block, 0).getFalconSeal());
|
|
+ assertThat(AereVoteCounts.refusal(copied.getSignedPayload(), set, target(4), fx.armed()))
|
|
+ .as("control: below H_r the round-0 seal vouches for the round-4 vote (the gap A_q, documented)")
|
|
+ .isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void rf2aFromHrMinusOneTheCopyIsRefusedWithR01AndTheHonestVoteCounts() {
|
|
+ above();
|
|
+ final Collection<Address> set = fx.addresses(0, 1, 2, 3);
|
|
+ final Commit copied = forged(0, block, 4, fx.honest(0, block, 0).getFalconSeal());
|
|
+ final Optional<String> refusal = AereVoteCounts.refusal(copied.getSignedPayload(), set, target(4), fx.armed());
|
|
+ assertThat(refusal).as("AERE-Q3-RF2-V3 RF2-A: a round-0 seal does not vouch for a round-4 vote").isPresent();
|
|
+ assertThat(refusal.get()).startsWith(PqAnchorV3.COMMIT_R_01);
|
|
+ assertThat(AereVoteCounts.refusal(fx.honest(0, block, 4).getSignedPayload(), set, target(4), fx.armed()))
|
|
+ .as("control: the honest round-4 vote over M_4 counts")
|
|
+ .isEmpty();
|
|
+ assertThat(
|
|
+ AereVoteCounts.refusal(
|
|
+ forged(0, block, 4, fx.honest(0, other, 4).getFalconSeal()).getSignedPayload(), set, target(4), fx.armed()))
|
|
+ .as("control: a genuine seal over another block is refused")
|
|
+ .isPresent();
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------ RF2-Q1
|
|
+
|
|
+ private AereDecisionEvidence evidence() {
|
|
+ final List<Address> all = fx.addresses(0, 1, 2, 3);
|
|
+ return new AereDecisionEvidence(
|
|
+ fx.blockInterface,
|
|
+ new AereDecisionEvidence.ValidatorSets() {
|
|
+ @Override
|
|
+ public Optional<Collection<Address>> afterBlock(final Hash onchainHash) {
|
|
+ return Optional.of(all);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Collection<Address> admission(final long height) {
|
|
+ return all;
|
|
+ }
|
|
+ },
|
|
+ fx.armed(),
|
|
+ fx::generation,
|
|
+ fx::sizeOf,
|
|
+ ANCHOR,
|
|
+ AereDecisionEvidence.DEFAULT_WINDOW);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * A and B commit honestly at round 0, C at round 2; then A and B's classical seals for round 2 with their round-0 PQ seals.
|
|
+ * With {@code cToo}, C committed at round 0 (and the collector never heard a round-2 commit of C), and the adversary copies
|
|
+ * C's round-0 seal into round 2 as well: every copied seal of ONE other round, and no honest vote of C to shadow the copy (review
|
|
+ * of step 5, second pass, point 7: a counted honest vote of the same author and digest would make the copy invisible).
|
|
+ */
|
|
+ private Optional<?> quorumAfterTheAttack(final boolean cToo) {
|
|
+ final AereDecisionEvidence ev = evidence();
|
|
+ final Commit a0 = fx.honest(0, block, 0);
|
|
+ final Commit b0 = fx.honest(1, block, 0);
|
|
+ ev.observeCommit(a0);
|
|
+ ev.observeCommit(b0);
|
|
+ if (!cToo) {
|
|
+ ev.observeCommit(fx.honest(2, block, 2));
|
|
+ }
|
|
+ assertThat(ev.quorumFor(block)).as("control: honestly no round holds Q = 3 commits").isEmpty();
|
|
+ ev.observeCommit(forged(0, block, 2, a0.getFalconSeal()));
|
|
+ ev.observeCommit(forged(1, block, 2, b0.getFalconSeal()));
|
|
+ if (cToo) {
|
|
+ ev.observeCommit(forged(2, block, 2, fx.honest(2, block, 0).getFalconSeal()));
|
|
+ }
|
|
+ return ev.quorumFor(block);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void rf2q1BelowHrTheQuorumIsAssembledWhichIsTheGap() {
|
|
+ below();
|
|
+ assertThat(quorumAfterTheAttack(false))
|
|
+ .as("control: below H_r the collector assembles a round-2 quorum from seals made in rounds 0 and 2 (the gap)")
|
|
+ .isPresent();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void rf2q1FromHrMinusOneNoQuorumIsAssembledFromSealsOfOtherRounds() {
|
|
+ above();
|
|
+ assertThat(quorumAfterTheAttack(false))
|
|
+ .as("AERE-Q3-RF2-V3 RF2-Q1: only the seals of round 2 count, so there is no round-2 quorum")
|
|
+ .isEmpty();
|
|
+ assertThat(quorumAfterTheAttack(true))
|
|
+ .as("AERE-Q3-RF2-V3 RF2-Q1: nor from three copied seals of round 0")
|
|
+ .isEmpty();
|
|
+ final AereDecisionEvidence ev = evidence();
|
|
+ ev.observeCommit(fx.honest(0, block, 2));
|
|
+ ev.observeCommit(fx.honest(1, block, 2));
|
|
+ ev.observeCommit(fx.honest(2, block, 2));
|
|
+ assertThat(ev.quorumFor(block)).as("control: three honest round-2 commits ARE a quorum").isPresent();
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------ RF2-RS
|
|
+
|
|
+ /** A RoundState of round 4 on the block, whose commit validation is the REAL CommitValidator on the one target. */
|
|
+ private RoundState roundFour() {
|
|
+ final CommitValidator real = new CommitValidator(fx.addresses(0, 1, 2, 3), target(4), fx.armed());
|
|
+ final MessageValidator mv = mock(MessageValidator.class);
|
|
+ when(mv.validateProposal(any())).thenReturn(true);
|
|
+ when(mv.validateCommit(any()))
|
|
+ .thenAnswer(
|
|
+ inv -> {
|
|
+ final Commit c = inv.getArgument(0);
|
|
+ return real.validate(c);
|
|
+ });
|
|
+ return new RoundState(new ConsensusRoundIdentifier(N, 4), 3, mv);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Q forged round-4 commits: A's and B's classical seals with their post-quantum seals of round 0, and C's with its seal of
|
|
+ * round 2 (or of round 0, {@code cOfRoundZero}: then every copied seal is of ONE other round, the variant a defect that
|
|
+ * judges every vote against round 0 would let through; review of step 5, point 7).
|
|
+ */
|
|
+ private boolean committedOnForgedCommits(final boolean cOfRoundZero) {
|
|
+ final Commit a0 = fx.honest(0, block, 0);
|
|
+ final Commit b0 = fx.honest(1, block, 0);
|
|
+ final Commit c = fx.honest(2, block, cOfRoundZero ? 0 : 2);
|
|
+ final RoundState rs = roundFour();
|
|
+ rs.addCommitMessage(forged(0, block, 4, a0.getFalconSeal()));
|
|
+ rs.addCommitMessage(forged(1, block, 4, b0.getFalconSeal()));
|
|
+ rs.addCommitMessage(forged(2, block, 4, c.getFalconSeal()));
|
|
+ rs.setProposedBlock(mock(Proposal.class));
|
|
+ return rs.isCommitted();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void rf2rsBelowHrTheRoundStateCommitsOnTheForgedRoundWhichIsTheGap() {
|
|
+ below();
|
|
+ assertThat(committedOnForgedCommits(false))
|
|
+ .as("control: below H_r three forged round-4 commits with copied seals commit the round (the gap)")
|
|
+ .isTrue();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void rf2rsFromHrMinusOneTheRoundStateDoesNotCommitOnTheForgedRound() {
|
|
+ above();
|
|
+ assertThat(committedOnForgedCommits(false))
|
|
+ .as("AERE-Q3-RF2-V3 RF2-RS: seals of rounds 0 and 2 do not commit round 4")
|
|
+ .isFalse();
|
|
+ assertThat(committedOnForgedCommits(true))
|
|
+ .as("AERE-Q3-RF2-V3 RF2-RS: nor do three seals of round 0")
|
|
+ .isFalse();
|
|
+ final RoundState rs = roundFour();
|
|
+ rs.addCommitMessage(fx.honest(0, block, 4));
|
|
+ rs.addCommitMessage(fx.honest(1, block, 4));
|
|
+ rs.addCommitMessage(fx.honest(2, block, 4));
|
|
+ rs.setProposedBlock(mock(Proposal.class));
|
|
+ assertThat(rs.isCommitted()).as("control: three honest round-4 commits commit the round").isTrue();
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereRoundBoundEmitterTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereRoundBoundEmitterTest.java
|
|
new file mode 100644
|
|
index 0000000000..292876c9ea
|
|
--- /dev/null
|
|
+++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereRoundBoundEmitterTest.java
|
|
@@ -0,0 +1,354 @@
|
|
+/*
|
|
+ * Copyright contributors to Aere Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
|
|
+ * compliance with the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is
|
|
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
+ * implied. See the License for the specific language governing permissions and limitations under the
|
|
+ * License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft.core.statemachine;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
+import static org.mockito.ArgumentMatchers.anyInt;
|
|
+import static org.mockito.ArgumentMatchers.anyLong;
|
|
+import static org.mockito.ArgumentMatchers.eq;
|
|
+import static org.mockito.Mockito.doAnswer;
|
|
+import static org.mockito.Mockito.doReturn;
|
|
+import static org.mockito.Mockito.spy;
|
|
+import static org.mockito.Mockito.times;
|
|
+import static org.mockito.Mockito.verify;
|
|
+import static org.mockito.Mockito.when;
|
|
+
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collections;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSealCache;
|
|
+import org.hyperledger.besu.consensus.common.bft.RoundTimer;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.qbft.core.QbftBlockTestFixture;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit;
|
|
+import org.hyperledger.besu.consensus.qbft.core.network.QbftMessageTransmitter;
|
|
+import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCodec;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCreator;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockHeader;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockImporter;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftMinedBlockObserver;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftProtocolSchedule;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.MessageValidator;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.QbftBlockHeaderTestFixture;
|
|
+import org.hyperledger.besu.cryptoservices.NodeKey;
|
|
+import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.util.Subscribers;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.junit.jupiter.api.extension.ExtendWith;
|
|
+import org.mockito.Mock;
|
|
+import org.mockito.junit.jupiter.MockitoExtension;
|
|
+import org.mockito.junit.jupiter.MockitoSettings;
|
|
+import org.mockito.quality.Strictness;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), D-470, pasul 4 (2026-10-01): the EMITTER on the real state machine at a round r > 0 (the probe the step-3
|
|
+ * review asked for, made sharper by the step-4 review). The block has THREE distinct forms here: the proposal of round
|
|
+ * 3 (what the Commit names), its commit form at round 3 (what ECDSA seals) and its round-0 on-chain form (what COMMIT-2
|
|
+ * binds), so a message over the wrong one is told apart; and only the final signing call is stubbed (pqSign), so the
|
|
+ * probe sees WHICH message the node signs.
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>the one target (decision H9): the seal signed at round 3 is over M_3 of the round-0 on-chain hash, and the Commit
|
|
+ * on the wire carries it;
|
|
+ * <li>H8 (judgement 1, C1): from H_r - 1 the node's OWN seal enters the store of round 3 only once its Commit was SENT,
|
|
+ * keyed by the on-chain hash; and (review of step 4) the own Commit reaches the decided-head evidence only then;
|
|
+ * <li>below H_r both happen at acceptance, as before (L1).
|
|
+ * </ul>
|
|
+ */
|
|
+@ExtendWith(MockitoExtension.class)
|
|
+@MockitoSettings(strictness = Strictness.LENIENT)
|
|
+public class AereRoundBoundEmitterTest {
|
|
+
|
|
+ private static final long CHAIN = 220_887L;
|
|
+ private static final long H = 1_000L;
|
|
+ private static final long V2 = 1_005L;
|
|
+ private static final long HR = 1_100L;
|
|
+ private static final int ROUND = 3;
|
|
+
|
|
+ private final NodeKey nodeKey = NodeKeyUtils.generate();
|
|
+ private final Address localAddress = Address.extract(nodeKey.getPublicKey());
|
|
+ private final NodeKey peerKey = NodeKeyUtils.generate();
|
|
+ private final Subscribers<QbftMinedBlockObserver> subscribers = Subscribers.create();
|
|
+ private final FalconSeal own = new FalconSeal(4, Bytes.fromHexString("0x29aabbcc04"));
|
|
+ private final List<Bytes32> signed = new ArrayList<>();
|
|
+ private final List<Commit> evidence = new ArrayList<>();
|
|
+
|
|
+ private MessageFactory localFactory;
|
|
+ private MessageFactory peerFactory;
|
|
+ private QbftBlock onchainForm;
|
|
+ private QbftBlock commitForm;
|
|
+
|
|
+ @Mock private QbftBlockCodec blockEncoder;
|
|
+ @Mock private QbftProtocolSchedule protocolSchedule;
|
|
+ @Mock private QbftMessageTransmitter transmitter;
|
|
+ @Mock private MessageValidator messageValidator;
|
|
+ @Mock private RoundTimer roundTimer;
|
|
+ @Mock private QbftBlockCreator blockCreator;
|
|
+ @Mock private QbftBlockInterface blockInterface;
|
|
+
|
|
+ @BeforeEach
|
|
+ public void setup() {
|
|
+ PqSealCache.instance().clear();
|
|
+ PqAnchorProducer.useConfigForTesting(
|
|
+ new PqAnchorConfig(CHAIN, H, Map.of(H, 3), OptionalInt.empty(), false, OptionalInt.empty(), OptionalInt.empty(), V2)
|
|
+ .withCommitRoundBlock(HR));
|
|
+ localFactory = new MessageFactory(nodeKey, blockEncoder);
|
|
+ peerFactory = new MessageFactory(peerKey, blockEncoder);
|
|
+ when(messageValidator.validateProposal(any())).thenReturn(true);
|
|
+ when(messageValidator.validatePrepare(any())).thenReturn(true);
|
|
+ when(messageValidator.validateCommit(any())).thenReturn(true);
|
|
+ AereDecidedHook.install(
|
|
+ new AereDecidedHook() {
|
|
+ @Override
|
|
+ public void ownCommit(final Commit localCommit) {
|
|
+ evidence.add(localCommit);
|
|
+ }
|
|
+ });
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ public void clean() {
|
|
+ PqSealCache.instance().clear();
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ AereDecidedHook.reset();
|
|
+ }
|
|
+
|
|
+ private static QbftBlock form(final long height, final int tag) {
|
|
+ return new QbftBlockTestFixture()
|
|
+ .blockHeader(
|
|
+ new QbftBlockHeaderTestFixture()
|
|
+ .number(height)
|
|
+ .hash(Hash.hash(Bytes.of(0x0f, tag, (int) (height & 0xff))))
|
|
+ .buildHeader())
|
|
+ .build();
|
|
+ }
|
|
+
|
|
+ /** The proposal of round 3; its commit form (any round) and its round-0 on-chain form are distinct blocks. */
|
|
+ private QbftBlock proposalAt(final long height) {
|
|
+ final QbftBlock proposal = form(height, 1);
|
|
+ commitForm = form(height, 2);
|
|
+ onchainForm = form(height, 3);
|
|
+ when(blockInterface.replaceRoundForCommitBlock(any(), anyInt())).thenReturn(commitForm);
|
|
+ when(blockInterface.replaceRoundForCommitBlock(any(), eq(0))).thenReturn(onchainForm);
|
|
+ return proposal;
|
|
+ }
|
|
+
|
|
+ /** A round of quorum 2 at (height, ROUND): the local Prepare plus ONE peer Prepare make it prepared. */
|
|
+ private QbftRound spiedRound(final long height) {
|
|
+ return spiedRound(height, 2);
|
|
+ }
|
|
+
|
|
+ /** A round of the given quorum at (height, ROUND). */
|
|
+ private QbftRound spiedRound(final long height, final int quorum) {
|
|
+ final ConsensusRoundIdentifier id = new ConsensusRoundIdentifier(height, ROUND);
|
|
+ final QbftBlockHeader parentHeader = new QbftBlockHeaderTestFixture().number(height - 1).buildHeader();
|
|
+ final QbftRound round =
|
|
+ spy(
|
|
+ new QbftRound(
|
|
+ new RoundState(id, quorum, messageValidator),
|
|
+ blockCreator,
|
|
+ blockInterface,
|
|
+ protocolSchedule,
|
|
+ subscribers,
|
|
+ nodeKey,
|
|
+ localAddress,
|
|
+ localFactory,
|
|
+ transmitter,
|
|
+ roundTimer,
|
|
+ parentHeader));
|
|
+ doAnswer(
|
|
+ inv -> {
|
|
+ signed.add(inv.getArgument(1));
|
|
+ return Optional.of(own);
|
|
+ })
|
|
+ .when(round)
|
|
+ .pqSign(anyLong(), any());
|
|
+ doReturn(List.of()).when(round).extraSealsFor(any(), any());
|
|
+ return round;
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void atRoundThreeTheNodeSignsMThreeOverTheOnchainHashAndTheWireCarriesThatSeal() {
|
|
+ final long height = HR + 20L;
|
|
+ final QbftBlock proposal = proposalAt(height);
|
|
+ final ConsensusRoundIdentifier id = new ConsensusRoundIdentifier(height, ROUND);
|
|
+ final QbftRound round = spiedRound(height);
|
|
+ round.handleProposalMessage(
|
|
+ peerFactory.createProposal(id, proposal, Collections.emptyList(), Collections.emptyList()));
|
|
+ round.handlePrepareMessage(peerFactory.createPrepare(id, proposal.getHash()));
|
|
+ assertThat(signed).isNotEmpty();
|
|
+ assertThat(signed.get(0))
|
|
+ .as("H9: the seal of round 3 signs M_3 over the round-0 ON-CHAIN hash (COMMIT-2)")
|
|
+ .isEqualTo(PqAnchor.commitMessageRound(CHAIN, height, ROUND, onchainForm.getHash().getBytes()));
|
|
+ assertThat(signed.get(0))
|
|
+ .as("never over the commit form (what ECDSA seals) nor over the proposal hash")
|
|
+ .isNotEqualTo(PqAnchor.commitMessageRound(CHAIN, height, ROUND, commitForm.getHash().getBytes()))
|
|
+ .isNotEqualTo(PqAnchor.commitMessageRound(CHAIN, height, ROUND, proposal.getHash().getBytes()));
|
|
+ verify(transmitter, times(1)).multicastCommit(eq(id), eq(proposal.getHash()), any(), eq(Optional.of(own)));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void fromHrMinusOneTheOwnSealEntersTheStoreOnlyOnceTheCommitWasSent() {
|
|
+ final long height = HR + 20L;
|
|
+ final QbftBlock proposal = proposalAt(height);
|
|
+ final ConsensusRoundIdentifier id = new ConsensusRoundIdentifier(height, ROUND);
|
|
+ final QbftRound round = spiedRound(height);
|
|
+ round.handleProposalMessage(
|
|
+ peerFactory.createProposal(id, proposal, Collections.emptyList(), Collections.emptyList()));
|
|
+ assertThat(round.getRoundState().isPrepared()).as("control: accepted, not prepared").isFalse();
|
|
+ assertThat(PqSealCache.instance().sealsFor(height, onchainForm.getHash(), ROUND))
|
|
+ .as("H8: a node that only ACCEPTED the proposal never gave its seal; it is not in the store")
|
|
+ .isEmpty();
|
|
+ round.handlePrepareMessage(peerFactory.createPrepare(id, proposal.getHash()));
|
|
+ assertThat(round.getRoundState().isPrepared()).isTrue();
|
|
+ assertThat(PqSealCache.instance().sealsFor(height, onchainForm.getHash(), ROUND))
|
|
+ .as("after the Commit was sent the own seal is in the store, under round 3, keyed by the on-chain hash")
|
|
+ .containsExactly(own);
|
|
+ assertThat(PqSealCache.instance().sealsFor(height, onchainForm.getHash(), 0))
|
|
+ .as("and never under round 0")
|
|
+ .isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void fromHrMinusOneTheOwnCommitReachesTheDecidedHeadEvidenceOnlyOnceSent() {
|
|
+ final long height = HR + 20L;
|
|
+ final QbftBlock proposal = proposalAt(height);
|
|
+ final ConsensusRoundIdentifier id = new ConsensusRoundIdentifier(height, ROUND);
|
|
+ final QbftRound round = spiedRound(height);
|
|
+ round.handleProposalMessage(
|
|
+ peerFactory.createProposal(id, proposal, Collections.emptyList(), Collections.emptyList()));
|
|
+ assertThat(evidence)
|
|
+ .as("H8 for the evidence: an own Commit that was never sent is not handed to the decided-head proof")
|
|
+ .isEmpty();
|
|
+ round.handlePrepareMessage(peerFactory.createPrepare(id, proposal.getHash()));
|
|
+ assertThat(evidence).as("once sent, it is").hasSize(1);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void belowHrTheOwnSealAndTheOwnCommitAreKeptAtAcceptanceAsBefore() {
|
|
+ final long height = HR - 30L;
|
|
+ final QbftBlock proposal = proposalAt(height);
|
|
+ final ConsensusRoundIdentifier id = new ConsensusRoundIdentifier(height, ROUND);
|
|
+ final QbftRound round = spiedRound(height);
|
|
+ round.handleProposalMessage(
|
|
+ peerFactory.createProposal(id, proposal, Collections.emptyList(), Collections.emptyList()));
|
|
+ assertThat(round.getRoundState().isPrepared()).isFalse();
|
|
+ assertThat(PqSealCache.instance().sealsFor(height, onchainForm.getHash(), 0))
|
|
+ .as("L1: below H_r the own seal is stored at acceptance, call by call as before")
|
|
+ .containsExactly(own);
|
|
+ assertThat(evidence).as("L1: and the own Commit is handed over at acceptance, as before").hasSize(1);
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // RF-C1 (project 5.4, judgement 1 C1; pasul 5, 2026-10-02): N = 10, Q = 7. The node h4 (own index 4) accepts p in round 3
|
|
+ // and is NOT prepared; the Commits of six others of round 3 reach its RoundState. Its round commits on six plus
|
|
+ // its own Commit (upstream QBFT counts the own Commit kept at acceptance) and imports p. Its store under (p, 3) must
|
|
+ // hold the six seals it HEARD, never its own: it never sent a Commit, so no other node holds its seal, and a
|
|
+ // certificate over p carrying it would be a seal no Commit gave. Six < Q: the producer over p is NotReady and AIP-21 is
|
|
+ // not "post-quantum" on six (PqAnchorProducerRoundTest, AereGetPqFinalityRoundTest); what is measured here is the six.
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ private static final int[] PEERS = {0, 1, 2, 3, 5, 6};
|
|
+
|
|
+ @Mock private QbftBlockImporter blockImporter;
|
|
+
|
|
+ private void importsSucceed() {
|
|
+ when(blockCreator.createSealedBlock(any(), anyInt(), any(), any())).thenReturn(commitForm);
|
|
+ when(protocolSchedule.getBlockImporter(any())).thenReturn(blockImporter);
|
|
+ when(blockImporter.importBlock(any(), any())).thenReturn(true);
|
|
+ }
|
|
+
|
|
+ private void sixCommitsOfRoundThree(final QbftRound round, final ConsensusRoundIdentifier id, final QbftBlock proposal) {
|
|
+ for (final int index : PEERS) {
|
|
+ final NodeKey k = NodeKeyUtils.generate();
|
|
+ round.handleCommitMessage(
|
|
+ new MessageFactory(k, blockEncoder)
|
|
+ .createCommit(
|
|
+ id,
|
|
+ proposal.getHash(),
|
|
+ k.sign(Bytes32.wrap(commitForm.getHash().getBytes())),
|
|
+ Optional.of(new FalconSeal(index, Bytes.of(0x29, index, 0x5e)))));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void rfC1AnUnpreparedNodeHoldsTheSixSealsItHeardAndNeverItsOwn() {
|
|
+ final long height = HR + 20L;
|
|
+ final QbftBlock proposal = proposalAt(height);
|
|
+ importsSucceed();
|
|
+ final ConsensusRoundIdentifier id = new ConsensusRoundIdentifier(height, ROUND);
|
|
+ final QbftRound round = spiedRound(height, 7);
|
|
+ round.handleProposalMessage(
|
|
+ peerFactory.createProposal(id, proposal, Collections.emptyList(), Collections.emptyList()));
|
|
+ assertThat(round.getRoundState().isPrepared()).as("control: h4 accepted p and is not prepared").isFalse();
|
|
+ sixCommitsOfRoundThree(round, id, proposal);
|
|
+ assertThat(round.getRoundState().isCommitted())
|
|
+ .as("control: six Commits heard and the own one kept at acceptance commit the round (upstream QBFT)")
|
|
+ .isTrue();
|
|
+ verify(blockImporter, times(1)).importBlock(any(), any());
|
|
+ // no Commit left the node, on any of the three forms of the transmitter (review of step 5, point 9)
|
|
+ verify(transmitter, times(0)).multicastCommit(any(), any(), any());
|
|
+ verify(transmitter, times(0)).multicastCommit(any(), any(), any(), any());
|
|
+ verify(transmitter, times(0)).multicastCommit(any(), any(), any(), any(), any());
|
|
+ final List<FalconSeal> held = PqSealCache.instance().sealsFor(height, onchainForm.getHash(), ROUND);
|
|
+ assertThat(held)
|
|
+ .as("RF-C1: the store (p, 3) of an unprepared node holds the six seals it heard, not seven")
|
|
+ .hasSize(6)
|
|
+ .doesNotContain(own);
|
|
+ assertThat(held.stream().map(FalconSeal::getValidatorIndex).toList()).containsExactly(0, 1, 2, 3, 5, 6);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void rfC1ControlAPreparedNodeHoldsItsOwnSealOnceTheCommitWasSent() {
|
|
+ final long height = HR + 20L;
|
|
+ final QbftBlock proposal = proposalAt(height);
|
|
+ importsSucceed();
|
|
+ final ConsensusRoundIdentifier id = new ConsensusRoundIdentifier(height, ROUND);
|
|
+ final QbftRound round = spiedRound(height, 7);
|
|
+ round.handleProposalMessage(
|
|
+ peerFactory.createProposal(id, proposal, Collections.emptyList(), Collections.emptyList()));
|
|
+ for (int i = 0; i < PEERS.length; i++) {
|
|
+ round.handlePrepareMessage(
|
|
+ new MessageFactory(NodeKeyUtils.generate(), blockEncoder).createPrepare(id, proposal.getHash()));
|
|
+ }
|
|
+ assertThat(round.getRoundState().isPrepared())
|
|
+ .as("control: the own Prepare and six others prepare the round")
|
|
+ .isTrue();
|
|
+ verify(transmitter, times(1)).multicastCommit(eq(id), eq(proposal.getHash()), any(), eq(Optional.of(own)));
|
|
+ sixCommitsOfRoundThree(round, id, proposal);
|
|
+ assertThat(PqSealCache.instance().sealsFor(height, onchainForm.getHash(), ROUND))
|
|
+ .as("positive control of RF-C1: once its Commit was sent, the own seal IS in the store, seven in all")
|
|
+ .hasSize(7)
|
|
+ .contains(own);
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereRoundFreeCommitTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereRoundFreeCommitTest.java
|
|
new file mode 100644
|
|
index 0000000000..f30c7ef531
|
|
--- /dev/null
|
|
+++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/AereRoundFreeCommitTest.java
|
|
@@ -0,0 +1,203 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft.core.statemachine;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.AereD412Fixture;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.AereD412Fixture.TBlock;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.AereVoteCounts;
|
|
+import org.hyperledger.besu.crypto.SECPSignature;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+
|
|
+import java.util.Collection;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+/**
|
|
+ * AERE teza Q3, proba RF2 (2026-10-01; PROIECT-PASUL3-BLOCANTE-2026-10-01.md, sectiunea 2.5): under the
|
|
+ * adversary of AIP-22 (every classical key, no post-quantum key), from H_fin the ROUND of a commit is
|
|
+ * bound only by its ECDSA commit seal, because under the anchor form the post-quantum commit seal
|
|
+ * signs M(b) = keccak(RLP["AERE-PQ-COMMIT-1", chainId, n, hash(b)]), which carries no round
|
|
+ * (QbftRound.pqSealMessageFor, PqAnchorProducer.commitSealMessage).
|
|
+ *
|
|
+ * <p>The adversary is simulated by signing the classical commit seal with A's own key (the adversary
|
|
+ * holds it) over p's digest at round 4, and copying the post-quantum seal from A's honest round-0
|
|
+ * commit. The defect probes assert the property a round-bound seal would give and are expected to be
|
|
+ * RED on today's code, each with its marker in the failure text (RF2-A, RF2-Q1); the controls are
|
|
+ * expected GREEN: the fixture can count an honest round-4 vote, it refuses the same copy carrying a
|
|
+ * seal over another block, and below the anchor form (the seal signs the round's commit digest) the
|
|
+ * copy is refused. Real ECDSA keys, real Falcon-512 keys, the real finality regime of the fixture.
|
|
+ */
|
|
+public class AereRoundFreeCommitTest {
|
|
+
|
|
+ private static final long D = 1_000_000L;
|
|
+ private static final long N = D + 1;
|
|
+ private static final Hash P = Hash.hash(Bytes.of(9));
|
|
+
|
|
+ private AereD412Fixture fx;
|
|
+ private TBlock block;
|
|
+ private TBlock other;
|
|
+
|
|
+ @BeforeEach
|
|
+ public void arm() {
|
|
+ PqAnchorProducer.useConfigForTesting(
|
|
+ new PqAnchorConfig(
|
|
+ AereD412Fixture.CHAIN, D - 10, Map.of(D - 10, 0), OptionalInt.empty(), false));
|
|
+ fx = new AereD412Fixture(4, true);
|
|
+ fx.installFinality();
|
|
+ block = new TBlock(N, P, Bytes.of(0x0b), 0);
|
|
+ other = new TBlock(N, P, Bytes.of(0x0c), 0);
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ public void disarm() {
|
|
+ AereD412Fixture.uninstallAll();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Node {@code who}'s commit "of round {@code round}" on {@code b}, as the adversary makes it: the
|
|
+ * classical commit seal over the round's commit digest signed with the node's own classical key,
|
|
+ * the envelope signed with it too, and the given post-quantum seal.
|
|
+ */
|
|
+ private Commit forged(
|
|
+ final int who, final TBlock b, final int round, final Optional<FalconSeal> seal) {
|
|
+ final TBlock proposal = b.atRound(round);
|
|
+ final Hash commitHash = fx.blockInterface.replaceRoundForCommitBlock(proposal, round).getHash();
|
|
+ final SECPSignature ecdsa =
|
|
+ fx.nodes.getNode(who).getNodeKey().sign(Bytes32.wrap(commitHash.getBytes()));
|
|
+ return fx.nodes
|
|
+ .getMessageFactory(who)
|
|
+ .createCommit(new ConsensusRoundIdentifier(N, round), proposal.getHash(), ecdsa, seal);
|
|
+ }
|
|
+
|
|
+ private AereVoteCounts.Target target(final int round) {
|
|
+ return AereVoteCounts.Target.atRound(fx.blockInterface, block, N, round);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void controlsTheFixtureCountsAnHonestRoundFourVoteAndRefusesASealOverAnotherBlock() {
|
|
+ final Collection<Address> set = fx.addresses(0, 1, 2, 3);
|
|
+ assertThat(target(4).pqSealMessage())
|
|
+ .as("control, the fact under test: under the anchor form the post-quantum message is the same in every round")
|
|
+ .isEqualTo(target(0).pqSealMessage());
|
|
+ assertThat(target(4).commitDigest())
|
|
+ .as("control: while the classical commit digest carries the round")
|
|
+ .isNotEqualTo(target(0).commitDigest());
|
|
+ assertThat(
|
|
+ AereVoteCounts.refusal(
|
|
+ fx.honest(0, block, 4).getSignedPayload(), set, target(4), fx.armed()))
|
|
+ .as("control: A's honest round-4 commit counts (the fixture can express a counted round-4 vote)")
|
|
+ .isEmpty();
|
|
+ final Commit overOther = fx.honest(0, other, 0);
|
|
+ assertThat(
|
|
+ AereVoteCounts.refusal(
|
|
+ forged(0, block, 4, overOther.getFalconSeal()).getSignedPayload(),
|
|
+ set,
|
|
+ target(4),
|
|
+ fx.armed()))
|
|
+ .as("control: the same copy carrying A's genuine seal over ANOTHER block is refused")
|
|
+ .isPresent();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void controlBelowTheAnchorFormTheSealCarriesTheRoundAndTheCopyIsRefused() {
|
|
+ PqAnchorProducer.useConfigForTesting(PqAnchorConfig.never(AereD412Fixture.CHAIN));
|
|
+ final Collection<Address> set = fx.addresses(0, 1, 2, 3);
|
|
+ final Commit honestRoundZero = fx.honest(0, block, 0);
|
|
+ assertThat(
|
|
+ AereVoteCounts.refusal(
|
|
+ forged(0, block, 4, honestRoundZero.getFalconSeal()).getSignedPayload(),
|
|
+ set,
|
|
+ target(4),
|
|
+ fx.armed()))
|
|
+ .as(
|
|
+ "control: below the anchor form the post-quantum seal signs the round's commit digest, so a"
|
|
+ + " round-0 seal does not vote in round 4")
|
|
+ .isPresent();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aCommitOfRoundFourCarryingARoundZeroSealDoesNotCount() {
|
|
+ final Collection<Address> set = fx.addresses(0, 1, 2, 3);
|
|
+ final Commit honestRoundZero = fx.honest(0, block, 0);
|
|
+ final Commit copied = forged(0, block, 4, honestRoundZero.getFalconSeal());
|
|
+ assertThat(copied.getAuthor())
|
|
+ .as("control: from H_fin the copy is authored by A (index 0, the signer of its commit seal)")
|
|
+ .isEqualTo(fx.address(0));
|
|
+ assertThat(AereVoteCounts.refusal(copied.getSignedPayload(), set, target(4), fx.armed()))
|
|
+ .as(
|
|
+ "RF2-A: a post-quantum seal made in round 0 must not vouch for a round-4 vote; under the anchor"
|
|
+ + " form the seal message carries no round, so only the classical commit seal binds it")
|
|
+ .isPresent();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aQuorumOfOneRoundIsNotAssembledFromSealsOfOtherRounds() {
|
|
+ final List<Address> all = fx.addresses(0, 1, 2, 3);
|
|
+ final AereDecisionEvidence.ValidatorSets sets =
|
|
+ new AereDecisionEvidence.ValidatorSets() {
|
|
+ @Override
|
|
+ public Optional<Collection<Address>> afterBlock(final Hash onchainHash) {
|
|
+ return Optional.of(all);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Collection<Address> admission(final long height) {
|
|
+ return all;
|
|
+ }
|
|
+ };
|
|
+ final AereDecisionEvidence ev =
|
|
+ new AereDecisionEvidence(
|
|
+ fx.blockInterface,
|
|
+ sets,
|
|
+ fx.armed(),
|
|
+ fx::generation,
|
|
+ fx::sizeOf,
|
|
+ D,
|
|
+ AereDecisionEvidence.DEFAULT_WINDOW);
|
|
+ // honestly: A and B commit at round 0, C at round 2; no round holds Q = 3 commits on the block
|
|
+ final Commit a0 = fx.honest(0, block, 0);
|
|
+ final Commit b0 = fx.honest(1, block, 0);
|
|
+ ev.observeCommit(a0);
|
|
+ ev.observeCommit(b0);
|
|
+ ev.observeCommit(fx.honest(2, block, 2));
|
|
+ assertThat(ev.quorumFor(block))
|
|
+ .as("control: honestly no round holds Q = 3 commits on the block")
|
|
+ .isEmpty();
|
|
+ // the adversary: A's and B's classical commit seals for round 2, their post-quantum seals copied from round 0
|
|
+ ev.observeCommit(forged(0, block, 2, a0.getFalconSeal()));
|
|
+ ev.observeCommit(forged(1, block, 2, b0.getFalconSeal()));
|
|
+ assertThat(ev.quorumFor(block))
|
|
+ .as(
|
|
+ "RF2-Q1: Q1 must not hold a round-2 quorum assembled from post-quantum seals made in round 0"
|
|
+ + " (A, B) and round 2 (C)")
|
|
+ .isEmpty();
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/PqLateSealSalvageTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/PqLateSealSalvageTest.java
|
|
index 82586ae250..f7441e1d81 100755
|
|
--- a/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/PqLateSealSalvageTest.java
|
|
+++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/PqLateSealSalvageTest.java
|
|
@@ -118,41 +118,41 @@ public class PqLateSealSalvageTest {
|
|
@AfterEach
|
|
public void cleanup() {
|
|
// The cache is a singleton: a seal left behind would leak into unrelated tests and buy them
|
|
// an unearned green.
|
|
PqSealCache.instance().clear();
|
|
}
|
|
|
|
private void deliverCommit(
|
|
final long height, final Hash digest, final Address author, final Optional<FalconSeal> fs) {
|
|
when(commit.getAuthor()).thenReturn(author);
|
|
when(commit.getRoundIdentifier()).thenReturn(new ConsensusRoundIdentifier(height, 0));
|
|
when(commit.getDigest()).thenReturn(digest);
|
|
when(commit.getFalconSeal()).thenReturn(fs);
|
|
when(commitMessageData.getCode()).thenReturn(QbftV1.COMMIT);
|
|
when(commitMessageData.decode()).thenReturn(commit);
|
|
qbftController.handleMessageEvent(
|
|
new QbftReceivedMessageEventFixture(new QbftMessageFixture(commitMessageData)));
|
|
}
|
|
|
|
private List<FalconSeal> cached() {
|
|
- return PqSealCache.instance().sealsFor(HEAD, HEAD_HASH);
|
|
+ return PqSealCache.instance().sealsFor(HEAD, HEAD_HASH, 0);
|
|
}
|
|
|
|
@Test
|
|
public void lateCommitSealForImportedHeadIsSalvaged() {
|
|
deliverCommit(HEAD, HEAD_HASH, validator, Optional.of(seal));
|
|
assertThat(cached()).containsExactly(seal);
|
|
}
|
|
|
|
@Test
|
|
public void salvagedMessageStillDies() {
|
|
// The pair of the test above, on the same delivery: only the seal survives. Resurrecting the
|
|
// message would reopen the very height gate the upstream code closed on purpose.
|
|
deliverCommit(HEAD, HEAD_HASH, validator, Optional.of(seal));
|
|
verify(blockHeightManager, never()).handleCommitPayload(any());
|
|
}
|
|
|
|
@Test
|
|
public void sealOlderThanHeadIsNotSalvaged() {
|
|
// The proposer of block HEAD+1 carries a certificate over HEAD. A seal for HEAD-1 can never
|
|
// be asked for again; keeping it would only grow the cache.
|
|
diff --git a/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/PqSealsWithoutProposalTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/PqSealsWithoutProposalTest.java
|
|
index 47a2256c46..7422bc5406 100755
|
|
--- a/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/PqSealsWithoutProposalTest.java
|
|
+++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/PqSealsWithoutProposalTest.java
|
|
@@ -116,53 +116,53 @@ public class PqSealsWithoutProposalTest {
|
|
subscribers,
|
|
nodeKey,
|
|
localAddress,
|
|
localFactory,
|
|
transmitter,
|
|
roundTimer,
|
|
parentHeader);
|
|
}
|
|
|
|
@Test
|
|
public void aCommitWithoutAProposalStillTeachesItsSeals() {
|
|
final QbftRound round = roundWithoutProposal();
|
|
round.handleCommitMessage(
|
|
peerFactory.createCommit(
|
|
roundIdentifier,
|
|
digest,
|
|
peerKey.sign(org.apache.tuweni.bytes.Bytes32.ZERO),
|
|
Optional.of(falcon),
|
|
List.of(slh)));
|
|
|
|
- assertThat(PqSealCache.instance().sealsFor(roundIdentifier.getSequenceNumber(), digest))
|
|
+ assertThat(PqSealCache.instance().sealsFor(roundIdentifier.getSequenceNumber(), digest, 0))
|
|
.containsExactly(falcon);
|
|
- assertThat(PqSealCache.instance().extrasFor(roundIdentifier.getSequenceNumber(), digest))
|
|
+ assertThat(PqSealCache.instance().extrasFor(roundIdentifier.getSequenceNumber(), digest, 0))
|
|
.containsExactly(slh);
|
|
}
|
|
|
|
@Test
|
|
public void aCommitWithoutSealsLeavesTheCacheEmpty() {
|
|
// the negative control: the path must not write an entry just because a Commit arrived
|
|
final QbftRound round = roundWithoutProposal();
|
|
round.handleCommitMessage(
|
|
peerFactory.createCommit(roundIdentifier, digest, peerKey.sign(org.apache.tuweni.bytes.Bytes32.ZERO)));
|
|
|
|
- assertThat(PqSealCache.instance().sealsFor(roundIdentifier.getSequenceNumber(), digest))
|
|
+ assertThat(PqSealCache.instance().sealsFor(roundIdentifier.getSequenceNumber(), digest, 0))
|
|
.isEmpty();
|
|
- assertThat(PqSealCache.instance().extrasFor(roundIdentifier.getSequenceNumber(), digest))
|
|
+ assertThat(PqSealCache.instance().extrasFor(roundIdentifier.getSequenceNumber(), digest, 0))
|
|
.isEmpty();
|
|
assertThat(PqSealCache.instance().entryCount()).isZero();
|
|
}
|
|
|
|
@Test
|
|
public void sealsLandUnderTheDigestTheCommitNames() {
|
|
// a seal must never be filed under some other block's hash: the producer looks up by the
|
|
// parent's on-chain hash, and a mis-filed seal would be an invisible way to poison a lookup
|
|
final QbftRound round = roundWithoutProposal();
|
|
round.handleCommitMessage(
|
|
peerFactory.createCommit(
|
|
roundIdentifier, digest, peerKey.sign(org.apache.tuweni.bytes.Bytes32.ZERO), Optional.of(falcon), List.of(slh)));
|
|
|
|
final Hash altul = Hash.hash(Bytes.fromHexString("0xfeedface"));
|
|
- assertThat(PqSealCache.instance().sealsFor(roundIdentifier.getSequenceNumber(), altul)).isEmpty();
|
|
+ assertThat(PqSealCache.instance().sealsFor(roundIdentifier.getSequenceNumber(), altul, 0)).isEmpty();
|
|
}
|
|
}
|
|
diff --git a/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/AereD412Fixture.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/AereD412Fixture.java
|
|
index 7d2a8d97e6..a9b2ab4fb1 100644
|
|
--- a/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/AereD412Fixture.java
|
|
+++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/AereD412Fixture.java
|
|
@@ -490,41 +490,42 @@ public final class AereD412Fixture {
|
|
* @param claimedIndex the index written in the seal, or -1 for no seal
|
|
* @param signerIndex whose Falcon key signs
|
|
* @param extras the extra scheme seals
|
|
* @return the commit
|
|
*/
|
|
public Commit commit(
|
|
final int author,
|
|
final TBlock block,
|
|
final int round,
|
|
final int claimedIndex,
|
|
final int signerIndex,
|
|
final List<SchemeSeal> extras) {
|
|
final TBlock proposal = block.atRound(round);
|
|
final Hash commitHash = blockInterface.replaceRoundForCommitBlock(proposal, round).getHash();
|
|
final SECPSignature ecdsa =
|
|
nodes.getNode(author).getNodeKey().sign(Bytes32.wrap(commitHash.getBytes()));
|
|
final Bytes32 pqMessage =
|
|
PqAnchorProducer.commitSealMessage(
|
|
proposal.number(),
|
|
() -> blockInterface.replaceRoundForCommitBlock(proposal, 0).getHash().getBytes(),
|
|
- commitHash);
|
|
+ commitHash,
|
|
+ round).orElseThrow();
|
|
Optional<FalconSeal> seal = Optional.empty();
|
|
if (claimedIndex >= 0) {
|
|
seal = Optional.of(falconSeal(claimedIndex, signerIndex, pqMessage));
|
|
}
|
|
return nodes
|
|
.getMessageFactory(author)
|
|
.createCommit(
|
|
new ConsensusRoundIdentifier(proposal.number(), round), proposal.getHash(), ecdsa, seal, extras);
|
|
}
|
|
|
|
/**
|
|
* A Falcon seal claiming {@code claimedIndex}, signed by the key of {@code signerIndex} over
|
|
* {@code message}.
|
|
*
|
|
* @param claimedIndex the index written in the seal
|
|
* @param signerIndex whose key signs
|
|
* @param message the signed message
|
|
* @return the seal
|
|
*/
|
|
public FalconSeal falconSeal(final int claimedIndex, final int signerIndex, final Bytes32 message) {
|
|
diff --git a/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/AereD437ParentBindingTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/AereD437ParentBindingTest.java
|
|
new file mode 100644
|
|
index 0000000000..fb55566b09
|
|
--- /dev/null
|
|
+++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/AereD437ParentBindingTest.java
|
|
@@ -0,0 +1,185 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft.core.validation;
|
|
+
|
|
+import static java.util.Collections.emptyList;
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.hyperledger.besu.consensus.qbft.core.validation.ValidationTestHelpers.createEmptyRoundChangePayloads;
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
+import static org.mockito.Mockito.when;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.BftHelpers;
|
|
+import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.ProposerSelector;
|
|
+import org.hyperledger.besu.consensus.common.bft.payload.SignedData;
|
|
+import org.hyperledger.besu.consensus.qbft.core.QbftBlockTestFixture;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal;
|
|
+import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCodec;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockHeader;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockValidator;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftProtocolSchedule;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+
|
|
+import java.util.List;
|
|
+import java.util.Optional;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.junit.jupiter.api.extension.ExtendWith;
|
|
+import org.mockito.Mock;
|
|
+import org.mockito.junit.jupiter.MockitoExtension;
|
|
+import org.mockito.junit.jupiter.MockitoSettings;
|
|
+import org.mockito.quality.Strictness;
|
|
+
|
|
+/**
|
|
+ * AERE D-437 (2026-09-29): from AIP-22 stage 5 a proposal must extend the DECIDED head of its height. The block validator
|
|
+ * is mocked to accept every block (as a stored fork parent would make it), so the only thing that can refuse is the
|
|
+ * binding. Every refusal has its twin that passes: the same proposal on the decided head, the same proposal below H_hdr,
|
|
+ * the same proposal through the legacy constructor.
|
|
+ */
|
|
+@ExtendWith(MockitoExtension.class)
|
|
+@MockitoSettings(strictness = Strictness.LENIENT)
|
|
+public class AereD437ParentBindingTest {
|
|
+
|
|
+ private static final int VALIDATOR_COUNT = 4;
|
|
+ private static final long HEIGHT = 1;
|
|
+ private static final Hash DECIDED_HEAD = Hash.hash(Bytes.of(0x0d));
|
|
+ private static final Hash FORGED_SIBLING = Hash.hash(Bytes.of(0x0f));
|
|
+
|
|
+ @Mock private QbftBlockValidator blockValidator;
|
|
+ @Mock private QbftProtocolSchedule protocolSchedule;
|
|
+ @Mock private QbftBlockCodec blockEncoder;
|
|
+ @Mock private QbftBlockInterface blockInterface;
|
|
+ @Mock private ProposerSelector proposerSelector;
|
|
+ private QbftNodeList validators;
|
|
+
|
|
+ @BeforeEach
|
|
+ public void setup() {
|
|
+ validators = QbftNodeList.createNodes(VALIDATOR_COUNT, blockEncoder);
|
|
+ when(blockValidator.validateBlock(any(), any()))
|
|
+ .thenReturn(new QbftBlockValidator.ValidationResult(true, Optional.empty()));
|
|
+ when(protocolSchedule.getBlockValidator(any())).thenReturn(blockValidator);
|
|
+ when(proposerSelector.selectProposerForRound(any()))
|
|
+ .thenReturn(validators.getNode(0).getAddress());
|
|
+ }
|
|
+
|
|
+ private QbftBlock block(final Hash parent) {
|
|
+ final Address coinbase = validators.getNodeAddresses().getFirst();
|
|
+ final QbftBlockHeader header =
|
|
+ new QbftBlockHeader() {
|
|
+ @Override
|
|
+ public long getNumber() {
|
|
+ return HEIGHT;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public long getTimestamp() {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Address getCoinbase() {
|
|
+ return coinbase;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Hash getHash() {
|
|
+ return Hash.hash(Bytes.concatenate(Bytes.of(0x01), parent == null ? Bytes.EMPTY : parent.getBytes()));
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Hash getParentHash() {
|
|
+ return parent;
|
|
+ }
|
|
+ };
|
|
+ return new QbftBlockTestFixture().blockHeader(header).build();
|
|
+ }
|
|
+
|
|
+ private ProposalValidator validator(final int round, final boolean stage5) {
|
|
+ return new ProposalValidator(
|
|
+ blockInterface,
|
|
+ protocolSchedule,
|
|
+ BftHelpers.calculateRequiredValidatorQuorum(VALIDATOR_COUNT),
|
|
+ validators.getNodeAddresses(),
|
|
+ new ConsensusRoundIdentifier(HEIGHT, round),
|
|
+ proposerSelector,
|
|
+ DECIDED_HEAD,
|
|
+ h -> stage5);
|
|
+ }
|
|
+
|
|
+ private Proposal roundZero(final QbftBlock block) {
|
|
+ return validators
|
|
+ .getMessageFactory(0)
|
|
+ .createProposal(new ConsensusRoundIdentifier(HEIGHT, 0), block, Optional.empty(), emptyList(), emptyList());
|
|
+ }
|
|
+
|
|
+ private Proposal roundOne(final QbftBlock block) {
|
|
+ final ConsensusRoundIdentifier r1 = new ConsensusRoundIdentifier(HEIGHT, 1);
|
|
+ final List<SignedData<RoundChangePayload>> roundChanges =
|
|
+ createEmptyRoundChangePayloads(r1, validators.getNode(0), validators.getNode(1), validators.getNode(2));
|
|
+ return validators.getMessageFactory(0).createProposal(r1, block, roundChanges, emptyList());
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aChildOfTheDecidedHeadIsAccepted() {
|
|
+ assertThat(validator(0, true).validate(roundZero(block(DECIDED_HEAD)))).isTrue();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aChildOfAForgedSiblingIsRefusedAtRoundZero() {
|
|
+ assertThat(validator(0, true).validate(roundZero(block(FORGED_SIBLING)))).isFalse();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aReproposalAtRoundOneIsBoundToo() {
|
|
+ assertThat(validator(1, true).validate(roundOne(block(DECIDED_HEAD)))).isTrue();
|
|
+ assertThat(validator(1, true).validate(roundOne(block(FORGED_SIBLING)))).isFalse();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void anUnknownParentIsRefusedFromStageFive() {
|
|
+ assertThat(validator(0, true).validate(roundZero(block(null)))).isFalse();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void belowHdrNothingChanges() {
|
|
+ assertThat(validator(0, false).validate(roundZero(block(FORGED_SIBLING)))).isTrue();
|
|
+ assertThat(validator(0, false).validate(roundZero(block(null)))).isTrue();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theLegacyConstructorNeverBinds() {
|
|
+ final ProposalValidator legacy =
|
|
+ new ProposalValidator(
|
|
+ blockInterface,
|
|
+ protocolSchedule,
|
|
+ BftHelpers.calculateRequiredValidatorQuorum(VALIDATOR_COUNT),
|
|
+ validators.getNodeAddresses(),
|
|
+ new ConsensusRoundIdentifier(HEIGHT, 0),
|
|
+ proposerSelector);
|
|
+ assertThat(legacy.validate(roundZero(block(FORGED_SIBLING)))).isTrue();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void validateWithoutBlockValidationIsBoundToo() {
|
|
+ assertThat(validator(0, true).validateWithoutBlockValidation(roundZero(block(FORGED_SIBLING)))).isFalse();
|
|
+ assertThat(validator(0, true).validateWithoutBlockValidation(roundZero(block(DECIDED_HEAD)))).isTrue();
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/AereRoundBoundCommitPathTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/AereRoundBoundCommitPathTest.java
|
|
new file mode 100644
|
|
index 0000000000..f3e22c8181
|
|
--- /dev/null
|
|
+++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/AereRoundBoundCommitPathTest.java
|
|
@@ -0,0 +1,157 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft.core.validation;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorV3;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.AereD412Fixture.TBlock;
|
|
+import org.hyperledger.besu.crypto.SECPSignature;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+
|
|
+import java.util.Collection;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), step 3 (2026-10-01): the commit path through the ONE target object (decision H9) once the commit seal
|
|
+ * is round-bound. Two actors' worth of material: the honest round-4 vote of node A, and the vote an adversary that
|
|
+ * breaks ECDSA (A_q) assembles for round 4 out of A's HONEST round-0 post-quantum seal. Below H_r the two are the
|
|
+ * same bytes, so the copy counts (the gap D-470 names, shown here as the control that the fixture can express the
|
|
+ * attack); from H_r - 1 the copy is refused with AERE-PQ-COMMIT-R-01 and the honest vote counts. A round outside
|
|
+ * 0..1024 has no message: refused with AERE-PQ-COMMIT-R-03 under armed enforcement, never an exception. The full RF2
|
|
+ * proofs (Q1, the RoundState of the laboratory) are step 5.
|
|
+ */
|
|
+public class AereRoundBoundCommitPathTest {
|
|
+
|
|
+ private static final long HR = 50L;
|
|
+ private static final long HEIGHT = 60L;
|
|
+
|
|
+ private final AereD412Fixture fx = new AereD412Fixture(4, true);
|
|
+ private final TBlock block = new TBlock(HEIGHT, Hash.hash(Bytes.of(1)), Bytes.of(0x0c), 0);
|
|
+
|
|
+ @AfterEach
|
|
+ public void forgetAnchorConfig() {
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ }
|
|
+
|
|
+ private static PqAnchorConfig withHr(final boolean hr) {
|
|
+ final PqAnchorConfig base =
|
|
+ new PqAnchorConfig(AereD412Fixture.CHAIN, 5L, Map.of(5L, 0), OptionalInt.empty(), false).withAnchorV2Block(5L);
|
|
+ return hr ? base.withCommitRoundBlock(HR) : base;
|
|
+ }
|
|
+
|
|
+ /** The A_q vote: the ECDSA commit seal of {@code author} for {@code round}, the PQ seal of its round-0 vote. */
|
|
+ private Commit copiedFromRoundZero(final int author, final int round) {
|
|
+ final Commit honestZero = fx.honest(author, block, 0);
|
|
+ final TBlock proposal = block.atRound(round);
|
|
+ final Hash commitHash = fx.blockInterface.replaceRoundForCommitBlock(proposal, round).getHash();
|
|
+ final SECPSignature ecdsa = fx.nodes.getNode(author).getNodeKey().sign(Bytes32.wrap(commitHash.getBytes()));
|
|
+ return fx.nodes
|
|
+ .getMessageFactory(author)
|
|
+ .createCommit(new ConsensusRoundIdentifier(HEIGHT, round), proposal.getHash(), ecdsa, honestZero.getFalconSeal(), List.of());
|
|
+ }
|
|
+
|
|
+ private Optional<String> judge(final Commit c, final int round, final PqCommitEnforcement e) {
|
|
+ final AereVoteCounts.Target t = AereVoteCounts.Target.atRound(fx.blockInterface, block, HEIGHT, round);
|
|
+ final Collection<Address> set = fx.addresses(0, 1, 2, 3);
|
|
+ return AereVoteCounts.refusal(c.getSignedPayload(), set, t, e);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void belowHrTheRoundZeroSealCountsForRoundFourWhichIsTheGap() {
|
|
+ PqAnchorProducer.useConfigForTesting(withHr(false));
|
|
+ assertThat(judge(fx.honest(1, block, 4), 4, fx.armed())).as("honest round-4 vote").isEmpty();
|
|
+ assertThat(judge(copiedFromRoundZero(1, 4), 4, fx.armed()))
|
|
+ .as("control: below H_r the copy is indistinguishable and counts (the fixture expresses the attack)")
|
|
+ .isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void fromHrMinusOneTheCopyIsRefusedWithR01AndTheHonestVoteCounts() {
|
|
+ PqAnchorProducer.useConfigForTesting(withHr(true));
|
|
+ assertThat(PqAnchorProducer.commitSealFormAt(withHr(true), HEIGHT)).isEqualTo(PqAnchorProducer.CommitSealForm.ROUND_BOUND);
|
|
+ assertThat(judge(fx.honest(1, block, 4), 4, fx.armed())).as("honest round-4 vote over M_4").isEmpty();
|
|
+ final Optional<String> copy = judge(copiedFromRoundZero(1, 4), 4, fx.armed());
|
|
+ assertThat(copy).as("the round-0 seal under a round-4 commit").isPresent();
|
|
+ assertThat(copy.get()).startsWith(PqAnchorV3.COMMIT_R_01);
|
|
+ // the honest round-0 vote still counts for round 0: the refusal is about the ROUND, nothing else
|
|
+ assertThat(judge(fx.honest(1, block, 0), 0, fx.armed())).isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theTargetCarriesTheMessageOfItsOwnRound() {
|
|
+ PqAnchorProducer.useConfigForTesting(withHr(true));
|
|
+ final Bytes32 onchain = Bytes32.wrap(block.onchain().getBytes());
|
|
+ for (final int r : new int[] {0, 1, 4, 1024}) {
|
|
+ final AereVoteCounts.Target t = AereVoteCounts.Target.atRound(fx.blockInterface, block, HEIGHT, r);
|
|
+ assertThat(t.pqSealMessage())
|
|
+ .as("round %s", r)
|
|
+ .hasValue(Hash.wrap(PqAnchor.commitMessageRound(AereD412Fixture.CHAIN, HEIGHT, r, onchain)));
|
|
+ }
|
|
+ PqAnchorProducer.useConfigForTesting(withHr(false));
|
|
+ final AereVoteCounts.Target t0 = AereVoteCounts.Target.atRound(fx.blockInterface, block, HEIGHT, 0);
|
|
+ final AereVoteCounts.Target t4 = AereVoteCounts.Target.atRound(fx.blockInterface, block, HEIGHT, 4);
|
|
+ assertThat(t4.pqSealMessage()).as("below H_r one message for every round (L1)").isEqualTo(t0.pqSealMessage());
|
|
+ assertThat(t0.pqSealMessage()).hasValue(Hash.wrap(PqAnchor.commitMessage(AereD412Fixture.CHAIN, HEIGHT, onchain)));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aRoundOutsideTheRangeHasNoMessageAndIsRefusedWithR03OnlyWhenArmed() {
|
|
+ PqAnchorProducer.useConfigForTesting(withHr(true));
|
|
+ final int r = 1025;
|
|
+ final AereVoteCounts.Target t = AereVoteCounts.Target.atRound(fx.blockInterface, block, HEIGHT, r);
|
|
+ assertThat(t.pqSealMessage()).isEmpty();
|
|
+ final TBlock proposal = block.atRound(r);
|
|
+ final Hash commitHash = fx.blockInterface.replaceRoundForCommitBlock(proposal, r).getHash();
|
|
+ final SECPSignature ecdsa = fx.nodes.getNode(2).getNodeKey().sign(Bytes32.wrap(commitHash.getBytes()));
|
|
+ final Commit noSeal =
|
|
+ fx.nodes.getMessageFactory(2).createCommit(new ConsensusRoundIdentifier(HEIGHT, r), proposal.getHash(), ecdsa, Optional.<FalconSeal>empty(), List.of());
|
|
+ final Optional<String> armed = judge(noSeal, r, fx.armed());
|
|
+ assertThat(armed).isPresent();
|
|
+ assertThat(armed.get()).startsWith(PqAnchorV3.COMMIT_R_03);
|
|
+ assertThat(judge(noSeal, r, new PqCommitEnforcement(PqCommitEnforcement.DISARMED, fx.registry)))
|
|
+ .as("unarmed enforcement: nothing changes, as for every other PQ question")
|
|
+ .isEmpty();
|
|
+ assertThat(judge(noSeal, r, null)).as("no enforcement: upstream").isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void belowHrTheRefusalTextIsTodaysWithoutTheCode() {
|
|
+ PqAnchorProducer.useConfigForTesting(withHr(false));
|
|
+ final Commit badSeal = fx.commit(1, block, 4, 1, 2);
|
|
+ final Optional<String> r = judge(badSeal, 4, fx.armed());
|
|
+ assertThat(r).isPresent();
|
|
+ assertThat(r.get()).doesNotStartWith(PqAnchorV3.COMMIT_R_01).contains("does NOT verify");
|
|
+ PqAnchorProducer.useConfigForTesting(withHr(true));
|
|
+ final Optional<String> r2 = judge(fx.commit(1, block, 4, 1, 2), 4, fx.armed());
|
|
+ assertThat(r2).isPresent();
|
|
+ assertThat(r2.get()).startsWith(PqAnchorV3.COMMIT_R_01).contains("does NOT verify");
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/AereVoteCountsTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/AereVoteCountsTest.java
|
|
new file mode 100644
|
|
index 0000000000..20607f8fa9
|
|
--- /dev/null
|
|
+++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/AereVoteCountsTest.java
|
|
@@ -0,0 +1,224 @@
|
|
+/* AERE D-412 / capul decis, pasul 1: proba predicatului UNIC de numarare a unui Commit.
|
|
+ *
|
|
+ * Ce dovedeste fiecare caz:
|
|
+ * - commitValidatorAndPredicateAgreeOnEveryCase: pe o matrice de sapte cazuri (autor in afara
|
|
+ * setului, alta runda, alt digest, sigiliu ECDSA al altuia, fara sigiliu PQ, sigiliu PQ al altui
|
|
+ * index, vot bun) CommitValidator si AereVoteCounts dau ACELASI verdict, iar refuzurile vin in
|
|
+ * ordinea si cu textele de dinainte;
|
|
+ * - pqRefusalComesFromTheSharedPredicate: refuzul PQ il da predicatul insusi, prin
|
|
+ * PqCommitEnforcement. Plantarea "PQ oprit in predicat" il face ROSU, si ODATA cu el doua probe
|
|
+ * VECHI ale lui CommitValidator (CommitValidatorPqEnforcementTest): asta arata ca CommitValidator
|
|
+ * trece prin predicatul unic, nu printr-o copie;
|
|
+ * - messageValidatorTargetIsTheEmittersExpression (2026-09-30, a doua revizuire; fosta
|
|
+ * messageValidatorTargetIsTargetOf, CIRCULARA: compara iesirea lui Target.of cu Target.of): tinta
|
|
+ * pe care o primeste validatorul de productie (MessageValidator.SubsequentMessageValidator ->
|
|
+ * CommitValidator) e egala cu expresiile EMITATORULUI scrise aici (QbftRound), la rundele 0 si 2,
|
|
+ * fara ancora si cu ancora armata, iar commit-ul emitatorului trece prin validatorul de productie.
|
|
+ * Ca productia trece prin Target.of (nu printr-o copie) o arata plantarile din Target.of
|
|
+ * (tinta-lenesa-cu-runda, sigiliu-fara-runda), care o inrosesc impreuna cu
|
|
+ * MessageValidatorAnchorFormPlumbingTest (veche);
|
|
+ * - atRoundIsParametrizedOnTheRound: aceeasi tinta pentru acelasi bloc la doua runde are digesturi
|
|
+ * diferite, iar mesajul PQ sub ancora e digestul de sigiliu al rundei;
|
|
+ * - theEmitterPathAndTheTargetAgree (2026-09-30): commit-urile fixturii se fac acum pe drumul
|
|
+ * emitatorului (QbftRound), nu prin Target; aici se cere ca Target.atRound pe blocul in forma de
|
|
+ * runda 0 sa dea exact digestul, sigiliul ECDSA si mesajul PQ ale emitatorului, la rundele 0, 1, 3,
|
|
+ * fara ancora si cu ancora armata (forma de ancora peste amprenta de runda 0). In model; pe blocuri si
|
|
+ * mesaje reale o masoara AereD412RealHeadersTest si AereD412RealRoundTest. */
|
|
+package org.hyperledger.besu.consensus.qbft.core.validation;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.AereD412Fixture.TBlock;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collection;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+public class AereVoteCountsTest {
|
|
+
|
|
+ private static final long HEIGHT = 7_000L;
|
|
+
|
|
+ private final AereD412Fixture fx = new AereD412Fixture(4, true);
|
|
+ private final TBlock block =
|
|
+ new TBlock(HEIGHT, Hash.hash(Bytes.of(1)), Bytes.of(0x0a), 0);
|
|
+ private final TBlock other =
|
|
+ new TBlock(HEIGHT, Hash.hash(Bytes.of(1)), Bytes.of(0x0b), 0);
|
|
+
|
|
+ @AfterEach
|
|
+ public void forgetAnchorConfig() {
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ }
|
|
+
|
|
+ private AereVoteCounts.Target target(final int round) {
|
|
+ return AereVoteCounts.Target.atRound(fx.blockInterface, block, HEIGHT, round);
|
|
+ }
|
|
+
|
|
+ private CommitValidator validatorFor(
|
|
+ final Collection<Address> set, final AereVoteCounts.Target t, final PqCommitEnforcement e) {
|
|
+ return new CommitValidator(set, t, e);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void commitValidatorAndPredicateAgreeOnEveryCase() {
|
|
+ final List<Address> setOfThree = fx.addresses(0, 1, 2);
|
|
+ final AereVoteCounts.Target t1 = target(1);
|
|
+ final PqCommitEnforcement e = fx.armed();
|
|
+ final List<Commit> cases = new ArrayList<>();
|
|
+ final List<String> expectedPrefix = new ArrayList<>();
|
|
+ cases.add(fx.honest(3, block, 1));
|
|
+ expectedPrefix.add("did not originate from a recognized validator.");
|
|
+ cases.add(fx.honest(0, block, 2));
|
|
+ expectedPrefix.add("did not target expected round");
|
|
+ cases.add(fx.honest(0, other, 1));
|
|
+ expectedPrefix.add("did not contain expected digest");
|
|
+ // node 1's message carrying node 0's committed seal: rebuilt with node 0's seal
|
|
+ final Commit sealOfNode0 = fx.honest(0, block, 1);
|
|
+ cases.add(
|
|
+ fx.nodes
|
|
+ .getMessageFactory(1)
|
|
+ .createCommit(t1.round(), t1.digest(), sealOfNode0.getCommitSeal(), sealOfNode0.getFalconSeal()));
|
|
+ expectedPrefix.add("Seal was not created by the message transmitter");
|
|
+ cases.add(fx.commit(1, block, 1, -1, -1));
|
|
+ expectedPrefix.add("AERE FULL-PQ: commit at height");
|
|
+ cases.add(fx.commit(1, block, 1, 0, 0));
|
|
+ expectedPrefix.add("AERE FULL-PQ: seal index 0 is bound to");
|
|
+ cases.add(fx.honest(2, block, 1));
|
|
+ expectedPrefix.add("");
|
|
+
|
|
+ for (int i = 0; i < cases.size(); i++) {
|
|
+ final Commit c = cases.get(i);
|
|
+ final Optional<String> r =
|
|
+ AereVoteCounts.refusal(c.getSignedPayload(), setOfThree, t1, e);
|
|
+ final boolean validated = validatorFor(setOfThree, t1, e).validate(c);
|
|
+ assertThat(validated).as("case %d: CommitValidator and the predicate agree", i).isEqualTo(r.isEmpty());
|
|
+ if (expectedPrefix.get(i).isEmpty()) {
|
|
+ assertThat(r).as("case %d counts", i).isEmpty();
|
|
+ } else {
|
|
+ assertThat(r).as("case %d refused", i).isPresent();
|
|
+ assertThat(r.get()).as("case %d refusal text", i).startsWith(expectedPrefix.get(i));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void pqRefusalComesFromTheSharedPredicate() {
|
|
+ final AereVoteCounts.Target t0 = target(0);
|
|
+ final Optional<String> r =
|
|
+ AereVoteCounts.refusal(
|
|
+ fx.commit(1, block, 0, -1, -1).getSignedPayload(), fx.addresses(0, 1, 2, 3), t0, fx.armed());
|
|
+ assertThat(r).as("a commit without a PQ seal, enforcement armed, must not count").isPresent();
|
|
+ assertThat(r.get()).contains("carries NO post-quantum seal");
|
|
+ final Optional<String> stolen =
|
|
+ AereVoteCounts.refusal(
|
|
+ fx.commit(3, block, 0, 1, 1).getSignedPayload(), fx.addresses(0, 1, 2, 3), t0, fx.armed());
|
|
+ assertThat(stolen).as("node 3 carrying index 1's genuine seal must not count").isPresent();
|
|
+ assertThat(stolen.get()).contains("a seal cannot vouch for someone else's vote");
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void messageValidatorTargetIsTheEmittersExpression() {
|
|
+ // 2026-09-30, second review: the old form compared SubsequentMessageValidator (which calls Target.of) with Target.of, so it
|
|
+ // stayed green with a wrong Target.of and with a copy of it inside MessageValidator. Here the reference is the EMITTER's own
|
|
+ // expressions (QbftRound: createCommit(round, block.getHash(), ...), commitHashFor, pqSealMessageFor with pqOnchainHashOf),
|
|
+ // written out below, never taken from AereVoteCounts. That Target.of is the ROUTE of the production validator is shown by
|
|
+ // the plants in Target.of (tinta-lenesa-cu-runda, sigiliu-fara-runda) turning this proof, and the older
|
|
+ // MessageValidatorAnchorFormPlumbingTest, red.
|
|
+ for (final boolean anchor : new boolean[] {false, true}) {
|
|
+ PqAnchorProducer.useConfigForTesting(
|
|
+ anchor
|
|
+ ? new PqAnchorConfig(
|
|
+ AereD412Fixture.CHAIN, HEIGHT - 5, Map.of(HEIGHT - 5, 0), OptionalInt.empty(), false)
|
|
+ : PqAnchorConfig.never(AereD412Fixture.CHAIN));
|
|
+ for (final int round : new int[] {0, 2}) {
|
|
+ final ConsensusRoundIdentifier rid = new ConsensusRoundIdentifier(HEIGHT, round);
|
|
+ final TBlock proposal = block.atRound(round);
|
|
+ final Hash emittedDigest = proposal.getHash();
|
|
+ final Hash emittedCommitHash = fx.blockInterface.replaceRoundForCommitBlock(proposal, round).getHash();
|
|
+ final Hash emittedPq =
|
|
+ Hash.wrap(
|
|
+ PqAnchorProducer.commitSealMessage(
|
|
+ HEIGHT,
|
|
+ () -> fx.blockInterface.replaceRoundForCommitBlock(proposal, 0).getHash().getBytes(),
|
|
+ emittedCommitHash,
|
|
+ round).orElseThrow());
|
|
+ final MessageValidator.SubsequentMessageValidator smv =
|
|
+ new MessageValidator.SubsequentMessageValidator(
|
|
+ fx.addresses(0, 1, 2, 3), rid, proposal, fx.blockInterface);
|
|
+ final AereVoteCounts.Target handed = smv.commitValidatorForTesting().targetForTesting();
|
|
+ assertThat(handed.round()).as("anchor %s round %s: round", anchor, round).isEqualTo(rid);
|
|
+ assertThat(handed.digest()).as("anchor %s round %s: digest", anchor, round).isEqualTo(emittedDigest);
|
|
+ assertThat(handed.commitDigest())
|
|
+ .as("anchor %s round %s: commit digest", anchor, round)
|
|
+ .isEqualTo(emittedCommitHash);
|
|
+ assertThat(handed.pqSealMessage())
|
|
+ .as("anchor %s round %s: PQ seal message", anchor, round)
|
|
+ .hasValue(emittedPq);
|
|
+ assertThat(smv.validate(fx.honest(1, block, round)))
|
|
+ .as("anchor %s round %s: the emitter's commit passes the production validator", anchor, round)
|
|
+ .isTrue();
|
|
+ // and the collector's parametrization, on the block in its stored (round-0) form, asks for the same
|
|
+ final AereVoteCounts.Target viaAtRound = target(round);
|
|
+ assertThat(viaAtRound.digest()).isEqualTo(emittedDigest);
|
|
+ assertThat(viaAtRound.commitDigest()).isEqualTo(emittedCommitHash);
|
|
+ assertThat(viaAtRound.pqSealMessage()).hasValue(emittedPq);
|
|
+ if (anchor) {
|
|
+ assertThat(emittedPq).as("control: under the anchor the PQ message is not the commit digest").isNotEqualTo(emittedCommitHash);
|
|
+ }
|
|
+ }
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void atRoundIsParametrizedOnTheRound() {
|
|
+ final AereVoteCounts.Target t0 = target(0);
|
|
+ final AereVoteCounts.Target t1 = target(1);
|
|
+ assertThat(t0.digest()).isEqualTo(block.onchain());
|
|
+ assertThat(t1.digest()).isNotEqualTo(t0.digest());
|
|
+ assertThat(t1.commitDigest()).isEqualTo(t1.digest());
|
|
+ assertThat(t1.round().getRoundNumber()).isEqualTo(1);
|
|
+ assertThat(t1.round().getSequenceNumber()).isEqualTo(HEIGHT);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theEmitterPathAndTheTargetAgree() {
|
|
+ for (final boolean anchor : new boolean[] {false, true}) {
|
|
+ PqAnchorProducer.useConfigForTesting(
|
|
+ anchor
|
|
+ ? new PqAnchorConfig(
|
|
+ AereD412Fixture.CHAIN, HEIGHT - 5, Map.of(HEIGHT - 5, 0), OptionalInt.empty(), false)
|
|
+ : PqAnchorConfig.never(AereD412Fixture.CHAIN));
|
|
+ for (final int r : new int[] {0, 1, 3}) {
|
|
+ final Commit c = fx.honest(1, block, r);
|
|
+ final AereVoteCounts.Target t = target(r);
|
|
+ assertThat(c.getDigest()).as("anchor %s round %s: digest", anchor, r).isEqualTo(t.digest());
|
|
+ assertThat(
|
|
+ AereVoteCounts.refusal(c.getSignedPayload(), fx.addresses(0, 1, 2, 3), t, fx.armed()))
|
|
+ .as("anchor %s round %s: the emitter's commit counts against Target.atRound", anchor, r)
|
|
+ .isEmpty();
|
|
+ if (anchor) {
|
|
+ assertThat(t.pqSealMessage())
|
|
+ .hasValue(Hash.wrap(PqAnchor.commitMessage(AereD412Fixture.CHAIN, HEIGHT, block.onchain().getBytes())));
|
|
+ assertThat(t.pqSealMessage()).isNotEqualTo(Optional.of(t.commitDigest()));
|
|
+ } else {
|
|
+ assertThat(t.pqSealMessage()).hasValue(t.commitDigest());
|
|
+ }
|
|
+ }
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/CommitValidatorAnchorFormTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/CommitValidatorAnchorFormTest.java
|
|
index 4d055a04f4..47d20cc906 100755
|
|
--- a/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/CommitValidatorAnchorFormTest.java
|
|
+++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/CommitValidatorAnchorFormTest.java
|
|
@@ -123,41 +123,43 @@ public class CommitValidatorAnchorFormTest {
|
|
final SealScheme.GeneratedPair pereche = SealSchemes.FALCON_512.generate(random);
|
|
bindings.put(i, validators.getNode(i).getAddress());
|
|
cheiPublice.put(i, pereche.publicRegistryForm());
|
|
cheiPrivate.put(i, pereche.privateKey());
|
|
}
|
|
}
|
|
|
|
@AfterEach
|
|
public void forgetAnchorConfig() {
|
|
PqAnchorProducer.useConfigForTesting(null);
|
|
}
|
|
|
|
private void armAnchorAt(final long anchorBlock) {
|
|
PqAnchorProducer.useConfigForTesting(
|
|
new PqAnchorConfig(
|
|
CHAIN_ID, anchorBlock, Map.of(anchorBlock, 0), OptionalInt.empty(), false));
|
|
}
|
|
|
|
/** Exactly what the emitter (QbftRound.pqSealMessageFor) signs at HEIGHT. */
|
|
private Bytes32 emitterMessage() {
|
|
- return PqAnchorProducer.commitSealMessage(HEIGHT, onchainHash.getBytes(), commitDigest);
|
|
+ return PqAnchorProducer.commitSealMessage(
|
|
+ HEIGHT, onchainHash::getBytes, commitDigest, round.getRoundNumber())
|
|
+ .orElseThrow();
|
|
}
|
|
|
|
/** The fixed production shape: the verifier is handed the same message the emitter signs. */
|
|
private CommitValidator verificatorReparat(final Bytes32 expectedPqSealMessage) {
|
|
return new CommitValidator(
|
|
validators.getNodeAddresses(),
|
|
round,
|
|
commitDigest,
|
|
commitDigest,
|
|
Hash.wrap(expectedPqSealMessage),
|
|
new PqCommitEnforcement(HEIGHT, registry));
|
|
}
|
|
|
|
/** The pre-D-311 shape: enforcement verifies over the commit digest, whatever the emitter signed. */
|
|
private CommitValidator verificatorVechi() {
|
|
return new CommitValidator(
|
|
validators.getNodeAddresses(),
|
|
round,
|
|
commitDigest,
|
|
commitDigest,
|
|
diff --git a/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidatorAnchorFormPlumbingTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidatorAnchorFormPlumbingTest.java
|
|
index a5a78d58e3..7c12d8b07e 100755
|
|
--- a/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidatorAnchorFormPlumbingTest.java
|
|
+++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidatorAnchorFormPlumbingTest.java
|
|
@@ -72,38 +72,38 @@ public class MessageValidatorAnchorFormPlumbingTest {
|
|
when(commitBlock.getHash()).thenReturn(commitHash);
|
|
}
|
|
|
|
@AfterEach
|
|
public void forgetAnchorConfig() {
|
|
PqAnchorProducer.useConfigForTesting(null);
|
|
}
|
|
|
|
private MessageValidator.SubsequentMessageValidator build() {
|
|
return new MessageValidator.SubsequentMessageValidator(
|
|
List.of(Address.fromHexString("0x1")), round, proposalBlock, blockInterface);
|
|
}
|
|
|
|
@Test
|
|
public void anchorArmedTheVerifierIsHandedTheAnchorFormOverTheRoundZeroHash() {
|
|
PqAnchorProducer.useConfigForTesting(
|
|
new PqAnchorConfig(CHAIN_ID, HEIGHT, Map.of(HEIGHT, 0), OptionalInt.empty(), false));
|
|
when(blockInterface.replaceRoundForCommitBlock(proposalBlock, 0)).thenReturn(roundZeroBlock);
|
|
when(roundZeroBlock.getHash()).thenReturn(onchainHash);
|
|
|
|
- final Hash handed = build().commitValidatorForTesting().expectedPqSealMessageForTesting();
|
|
+ final Hash handed = build().commitValidatorForTesting().expectedPqSealMessageForTesting().orElseThrow();
|
|
|
|
assertThat(handed)
|
|
.isEqualTo(Hash.wrap(PqAnchor.commitMessage(CHAIN_ID, HEIGHT, onchainHash.getBytes())));
|
|
assertThat(handed).isNotEqualTo(commitHash);
|
|
verify(blockInterface).replaceRoundForCommitBlock(proposalBlock, 0);
|
|
}
|
|
|
|
@Test
|
|
public void anchorNeverArmedTheVerifierIsHandedTheCommitDigestAndRoundZeroIsNeverAsked() {
|
|
PqAnchorProducer.useConfigForTesting(PqAnchorConfig.never(CHAIN_ID));
|
|
|
|
- final Hash handed = build().commitValidatorForTesting().expectedPqSealMessageForTesting();
|
|
+ final Hash handed = build().commitValidatorForTesting().expectedPqSealMessageForTesting().orElseThrow();
|
|
|
|
assertThat(handed).isEqualTo(commitHash);
|
|
verify(blockInterface, never()).replaceRoundForCommitBlock(any(), eq(0));
|
|
}
|
|
}
|
|
diff --git a/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/PqCommitRoundGuardTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/PqCommitRoundGuardTest.java
|
|
new file mode 100644
|
|
index 0000000000..ecbe5e68fb
|
|
--- /dev/null
|
|
+++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/PqCommitRoundGuardTest.java
|
|
@@ -0,0 +1,121 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft.core.validation;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AerePqIdentity;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+
|
|
+import java.util.Map;
|
|
+import java.util.OptionalInt;
|
|
+
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), D-470, pasul 4 (2026-10-01): the startup guards of section 2.3 that live in the node's constructor path,
|
|
+ * each from the reason written for it, each with its pair.
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>AERE-PQC-ROUND-02 (beside FIN-02): H_fin set and H_r unset or above it refuses unless the confirmation names H_fin
|
|
+ * EXACTLY; the confirmation itself is refused on 2800 (decision H14: H_r comes first there); H_r at or below H_fin
|
|
+ * passes; H_fin unset passes whatever H_r says (L1);
|
|
+ * <li>AERE-PQC-ROUND-03: with H_r set, aere.pq.chainId must be the genesis chain id; inert without H_r (L1).
|
|
+ * </ul>
|
|
+ */
|
|
+class PqCommitRoundGuardTest {
|
|
+
|
|
+ private static final long NEVER = AerePqIdentity.NEVER;
|
|
+ private static final long TESTNET = 28_001L;
|
|
+
|
|
+ @AfterEach
|
|
+ void tearDown() {
|
|
+ System.clearProperty(PqFinalityLayersGuard.PROPERTY_ROUND_LATE_AFTER_FINALITY);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void round02RefusesHfinWithoutHrUnlessTheConfirmationNamesHfinExactly() {
|
|
+ assertThat(PqFinalityLayersGuard.roundRefusal(3_117_000L, NEVER, null, TESTNET))
|
|
+ .as("28001 shape: H_fin armed, H_r unset, no confirmation")
|
|
+ .hasValueSatisfying(r -> assertThat(r).startsWith(PqFinalityLayersGuard.CODE_ROUND_02).contains("unset"));
|
|
+ assertThat(PqFinalityLayersGuard.roundRefusal(3_117_000L, 3_200_032L, null, TESTNET))
|
|
+ .as("H_r above H_fin, no confirmation")
|
|
+ .hasValueSatisfying(r -> assertThat(r).startsWith(PqFinalityLayersGuard.CODE_ROUND_02).contains("above it"));
|
|
+ assertThat(PqFinalityLayersGuard.roundRefusal(3_117_000L, 3_200_032L, "3117000", TESTNET))
|
|
+ .as("the confirmation EQUAL to H_fin lets the node start")
|
|
+ .isEmpty();
|
|
+ assertThat(PqFinalityLayersGuard.roundLateConfirmed(3_117_000L, 3_200_032L, "3117000", TESTNET)).isTrue();
|
|
+ assertThat(PqFinalityLayersGuard.roundRefusal(3_117_000L, NEVER, "3117001", TESTNET))
|
|
+ .as("a confirmation that names another height (copied from another chain) is refused")
|
|
+ .hasValueSatisfying(r -> assertThat(r).contains("EQUAL"));
|
|
+ assertThat(PqFinalityLayersGuard.roundRefusal(3_117_000L, NEVER, "trei", TESTNET))
|
|
+ .hasValueSatisfying(r -> assertThat(r).contains("not a height"));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void round02RefusesTheConfirmationOn2800() {
|
|
+ assertThat(PqFinalityLayersGuard.roundRefusal(21_100_000L, NEVER, "21100000", 2_800L))
|
|
+ .as("H14: on 2800 H_r comes before H_fin; the confirmation is never history there")
|
|
+ .hasValueSatisfying(r -> assertThat(r).startsWith(PqFinalityLayersGuard.CODE_ROUND_02).contains("2800"));
|
|
+ assertThat(PqFinalityLayersGuard.roundLateConfirmed(21_100_000L, NEVER, "21100000", 2_800L)).isFalse();
|
|
+ assertThat(PqFinalityLayersGuard.roundRefusal(21_100_000L, NEVER, "21100000", TESTNET))
|
|
+ .as("control: the very same values pass on another chain")
|
|
+ .isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void round02IsInertWithoutHfinAndPassesWithHrAtOrBelowIt() {
|
|
+ assertThat(PqFinalityLayersGuard.roundRefusal(NEVER, NEVER, null, 2_800L)).as("L1: 2800 today").isEmpty();
|
|
+ assertThat(PqFinalityLayersGuard.roundRefusal(NEVER, 21_000_032L, null, 2_800L)).isEmpty();
|
|
+ assertThat(PqFinalityLayersGuard.roundRefusal(21_100_000L, 21_000_032L, null, 2_800L))
|
|
+ .as("2800's order (H_r before H_fin): nothing to confirm")
|
|
+ .isEmpty();
|
|
+ assertThat(PqFinalityLayersGuard.roundRefusal(21_100_000L, 21_100_000L, null, 2_800L)).isEmpty();
|
|
+ assertThat(PqFinalityLayersGuard.roundLateConfirmed(21_100_000L, 21_000_032L, "21100000", TESTNET))
|
|
+ .as("no history line when H_r already came first")
|
|
+ .isFalse();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void round02ThroughTheSystemConfiguration() {
|
|
+ // 2026-10-09 (1(b) step 11): verifyRoundOrAbort takes the anchor configuration itself; an ARMED one without H_r is
|
|
+ // the 28001 shape this probe always measured (H_r unset), so the guard is reached exactly as before
|
|
+ final PqAnchorConfig armedWithoutHr =
|
|
+ new PqAnchorConfig(TESTNET, 1_000L, Map.of(1_000L, 3), OptionalInt.empty(), false);
|
|
+ assertThat(armedWithoutHr.everActive()).as("control: the anchor is in force, so ROUND-02 is not lifted").isTrue();
|
|
+ assertThat(armedWithoutHr.commitRoundBlock()).isEqualTo(PqAnchorConfig.NEVER);
|
|
+ assertThatThrownBy(() -> PqFinalityLayersGuard.verifyRoundOrAbort(3_117_000L, armedWithoutHr, TESTNET))
|
|
+ .isInstanceOf(IllegalStateException.class)
|
|
+ .hasMessageStartingWith(PqFinalityLayersGuard.CODE_ROUND_02);
|
|
+ System.setProperty(PqFinalityLayersGuard.PROPERTY_ROUND_LATE_AFTER_FINALITY, "3117000");
|
|
+ PqFinalityLayersGuard.verifyRoundOrAbort(3_117_000L, armedWithoutHr, TESTNET);
|
|
+ assertThat(PqFinalityLayersGuard.lateAfterFinalityFromSystemConfig()).isEqualTo("3117000");
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void round03RefusesAPqChainIdOtherThanTheGenesisOnceHrIsSet() {
|
|
+ final PqAnchorConfig base =
|
|
+ new PqAnchorConfig(28_001L, 1_000L, Map.of(1_000L, 3), OptionalInt.empty(), false, OptionalInt.empty(), OptionalInt.empty(), 1_005L);
|
|
+ final PqAnchorConfig armed = base.withCommitRoundBlock(1_100L);
|
|
+ assertThat(armed.roundChainIdRefusal(28_001L)).as("the same chain id passes").isEmpty();
|
|
+ assertThat(armed.roundChainIdRefusal(2_800L))
|
|
+ .hasValueSatisfying(r -> assertThat(r).startsWith(PqAnchorConfig.REFUSAL_ROUND_03).contains("2800"));
|
|
+ assertThat(base.roundChainIdRefusal(2_800L))
|
|
+ .as("L1: without H_r the guard is inert, whatever the chain ids")
|
|
+ .isEmpty();
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/PqRoundBrakeStartupTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/PqRoundBrakeStartupTest.java
|
|
new file mode 100644
|
|
index 0000000000..db491fc17d
|
|
--- /dev/null
|
|
+++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/PqRoundBrakeStartupTest.java
|
|
@@ -0,0 +1,193 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft.core.validation;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.assertj.core.api.Assertions.assertThatCode;
|
|
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+
|
|
+import java.util.HashMap;
|
|
+import java.util.Map;
|
|
+
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), step 11 (2026-10-09), nm-consens-02, the Besu part: AERE-PQC-ROUND-02 under the anchor brake, measured on the
|
|
+ * STARTUP PATH and not on the configuration reader alone. The configuration is read by the reader the builder calls,
|
|
+ * {@link PqAnchorConfig#fromSystemConfiguration()}, from system properties as on a node, and the OBJECT it gives is handed
|
|
+ * to the guard the builder calls, {@link PqFinalityLayersGuard#verifyRoundOrAbort(long, PqAnchorConfig, long)}
|
|
+ * (QbftBesuControllerBuilder passes the object it read; the guard has no other form, so the builder cannot reach it
|
|
+ * without the brake).
|
|
+ *
|
|
+ * <p>The defect this measures: AereRoundBoundMessageTest proved the reader right ("the brake engages whatever H_r says"),
|
|
+ * and the startup still refused, because the braked configuration carries no H_r and ROUND-02 then saw "H_fin armed, H_r
|
|
+ * unset" on 2800 (from T4) and refused: the brake could not engage on a 2800 node after T4. Each case has its pair:
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>braked, H_fin armed, chain 2800: starts; the same node without the brake and without H_r: ROUND-02, with its
|
|
+ * reason;
|
|
+ * <li>braked over a configuration whose rest cannot be read (the reader carries it as "never", with the brake flag
|
|
+ * from 2026-10-10): starts;
|
|
+ * <li>not braked, H_r at or below H_fin (2800's order): starts; H_r above H_fin: ROUND-02;
|
|
+ * <li>(2026-10-10, review of consensus M1) no anchor name at all and no brake, H_fin armed: ROUND-02 (the exception is
|
|
+ * the brake only, as in the second client).
|
|
+ * </ul>
|
|
+ *
|
|
+ * <p>What this does not run: the builder. Its startup checks are one method, {@code
|
|
+ * QbftBesuControllerBuilder.verifyCommitRoundAtStartup}, measured by its own probe in the app module
|
|
+ * (AereCommitRoundStartupTest, the same cases through the builder's method and its log lines); build() itself with
|
|
+ * H_fin armed is run by neither (AerePqFinality needs the v3 identity and its epochs, process-wide singletons, the limit
|
|
+ * AereD412BuilderTest names for the armed-anchor branch).
|
|
+ */
|
|
+class PqRoundBrakeStartupTest {
|
|
+
|
|
+ private static final long MAINNET = 2_800L;
|
|
+ private static final long H_FIN = 21_100_000L;
|
|
+
|
|
+ /** The anchor names this probe sets (system property, environment twin), saved and put back around each case. */
|
|
+ private static final String[][] NAMES = {
|
|
+ {PqAnchorConfig.PROPERTY_CHAIN_ID, PqAnchorConfig.ENV_CHAIN_ID},
|
|
+ {PqAnchorConfig.PROPERTY_ANCHOR_BLOCK, PqAnchorConfig.ENV_ANCHOR_BLOCK},
|
|
+ {PqAnchorConfig.PROPERTY_MIN_SEALS, PqAnchorConfig.ENV_MIN_SEALS},
|
|
+ {PqAnchorConfig.PROPERTY_MIN_SEALS_CEILING, PqAnchorConfig.ENV_MIN_SEALS_CEILING},
|
|
+ {PqAnchorConfig.PROPERTY_DISABLE, PqAnchorConfig.ENV_DISABLE},
|
|
+ {PqAnchorConfig.PROPERTY_MAX_SEALS, PqAnchorConfig.ENV_MAX_SEALS},
|
|
+ {PqAnchorConfig.PROPERTY_ANCHOR_INTERVAL, PqAnchorConfig.ENV_ANCHOR_INTERVAL},
|
|
+ {PqAnchorConfig.PROPERTY_ANCHOR_INTERVAL_SCHEDULE, PqAnchorConfig.ENV_ANCHOR_INTERVAL_SCHEDULE},
|
|
+ {PqAnchorConfig.PROPERTY_ANCHOR_V2_BLOCK, PqAnchorConfig.ENV_ANCHOR_V2_BLOCK},
|
|
+ {PqAnchorConfig.PROPERTY_COMMIT_ROUND_BLOCK, PqAnchorConfig.ENV_COMMIT_ROUND_BLOCK},
|
|
+ {PqFinalityLayersGuard.PROPERTY_ROUND_LATE_AFTER_FINALITY, PqFinalityLayersGuard.ENV_ROUND_LATE_AFTER_FINALITY},
|
|
+ };
|
|
+
|
|
+ private final Map<String, String> before = new HashMap<>();
|
|
+
|
|
+ @BeforeEach
|
|
+ void save() {
|
|
+ for (final String[] n : NAMES) {
|
|
+ assertThat(System.getenv(n[1]))
|
|
+ .as("control: %s is not set in this JVM's environment (the probe sets the properties only)", n[1])
|
|
+ .isNull();
|
|
+ before.put(n[0], System.getProperty(n[0]));
|
|
+ System.clearProperty(n[0]);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ void putBack() {
|
|
+ for (final String[] n : NAMES) {
|
|
+ final String v = before.get(n[0]);
|
|
+ if (v == null) {
|
|
+ System.clearProperty(n[0]);
|
|
+ } else {
|
|
+ System.setProperty(n[0], v);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /** The 2800-shaped anchor of the reader's own probe (AereRoundBoundMessageTest), read at startup. */
|
|
+ private static PqAnchorConfig startupRead(final Map<String, String> extra) {
|
|
+ System.setProperty(PqAnchorConfig.PROPERTY_CHAIN_ID, "2800");
|
|
+ System.setProperty(PqAnchorConfig.PROPERTY_ANCHOR_BLOCK, "1000");
|
|
+ System.setProperty(PqAnchorConfig.PROPERTY_MIN_SEALS, "1000:0,8200:1,15400:3");
|
|
+ System.setProperty(PqAnchorConfig.PROPERTY_ANCHOR_V2_BLOCK, "1064");
|
|
+ for (final Map.Entry<String, String> e : extra.entrySet()) {
|
|
+ System.setProperty(e.getKey(), e.getValue());
|
|
+ }
|
|
+ return PqAnchorConfig.fromSystemConfiguration();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void theBrakeStartsA2800NodeWhoseHfinIsArmed() {
|
|
+ final PqAnchorConfig braked =
|
|
+ startupRead(
|
|
+ Map.of(
|
|
+ PqAnchorConfig.PROPERTY_COMMIT_ROUND_BLOCK, "2000",
|
|
+ PqAnchorConfig.PROPERTY_DISABLE, "true"));
|
|
+ assertThat(braked.disabled()).as("control: the reader braked").isTrue();
|
|
+ assertThat(braked.commitRoundBlock())
|
|
+ .as("control: the braked configuration carries no H_r (the cause of the refusal this probe measures)")
|
|
+ .isEqualTo(PqAnchorConfig.NEVER);
|
|
+ assertThatCode(() -> PqFinalityLayersGuard.verifyRoundOrAbort(H_FIN, braked, MAINNET))
|
|
+ .as("the brake engages on a 2800 node after T4: ROUND-02 must not refuse it")
|
|
+ .doesNotThrowAnyException();
|
|
+ assertThat(PqFinalityLayersGuard.roundRefusal(H_FIN, braked, null, MAINNET)).isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aBrakeOverAConfigurationThatCannotBeReadStillStarts() {
|
|
+ final PqAnchorConfig braked =
|
|
+ startupRead(
|
|
+ Map.of(
|
|
+ PqAnchorConfig.PROPERTY_ANCHOR_BLOCK, "nu-e-o-inaltime",
|
|
+ PqAnchorConfig.PROPERTY_DISABLE, "true"));
|
|
+ assertThat(braked.anchorConfigured())
|
|
+ .as("control: the reader could not read the rest and carries the node as never")
|
|
+ .isFalse();
|
|
+ // (2026-10-10, review of consensus M1) REVERSED: until this date the line read "control: so the brake flag itself is not
|
|
+ // carried either" (isFalse), and the ROUND-02 exception was widened to "no anchor at all" to cover it; the reader now
|
|
+ // carries the flag (PqAnchorConfig.brakedNever), so the exception can be the brake only
|
|
+ assertThat(braked.disabled())
|
|
+ .as("the brake flag is carried even when the rest cannot be read (brakedNever, not never)")
|
|
+ .isTrue();
|
|
+ assertThatCode(() -> PqFinalityLayersGuard.verifyRoundOrAbort(H_FIN, braked, MAINNET))
|
|
+ .as("the brake is absolute even when the rest cannot be read: ROUND-02 must not refuse it")
|
|
+ .doesNotThrowAnyException();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void withoutTheBrakeAndWithoutAnyAnchorNameHfinArmedIsRefusedByRound02() {
|
|
+ // (2026-10-10, review of consensus M1) THE EXCEPTION IS THE BRAKE ONLY: no aere.pq.* name at all (a node whose anchor names
|
|
+ // were LOST from its options, the family of the grep -v of 9 August) with H_fin armed is a configuration error. The step-11
|
|
+ // form of 2026-10-09 exempted it ("no anchor at all") and started such a node with a warning and no code; the second client
|
|
+ // refuses it with ROUND-02 (AereCommitRoundConfig.Round02Refusal, its probe R1bNM_BRAKE_ROUND02), and so does this one again.
|
|
+ final PqAnchorConfig none = PqAnchorConfig.fromSystemConfiguration();
|
|
+ assertThat(none.anchorConfigured()).as("control: no anchor name is set, the reader gives never").isFalse();
|
|
+ assertThat(none.disabled()).as("control: and no brake").isFalse();
|
|
+ assertThatThrownBy(() -> PqFinalityLayersGuard.verifyRoundOrAbort(H_FIN, none, MAINNET))
|
|
+ .as("no anchor and no brake with H_fin armed: ROUND-02 must refuse, the exception is the brake only")
|
|
+ .isInstanceOf(IllegalStateException.class)
|
|
+ .hasMessageStartingWith(PqFinalityLayersGuard.CODE_ROUND_02)
|
|
+ .hasMessageContaining("aere.pq.commitRoundBlock is unset");
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void withoutTheBrakeTheSameNodeWithoutHrIsRefusedByRound02() {
|
|
+ final PqAnchorConfig armed = startupRead(Map.of());
|
|
+ assertThat(armed.everActive()).as("control: the anchor is in force").isTrue();
|
|
+ assertThat(armed.commitRoundBlock()).isEqualTo(PqAnchorConfig.NEVER);
|
|
+ assertThatThrownBy(() -> PqFinalityLayersGuard.verifyRoundOrAbort(H_FIN, armed, MAINNET))
|
|
+ .as("the exception of the brake is not a hole: an armed 2800 node with H_fin and no H_r is refused")
|
|
+ .isInstanceOf(IllegalStateException.class)
|
|
+ .hasMessageStartingWith(PqFinalityLayersGuard.CODE_ROUND_02)
|
|
+ .hasMessageContaining("aere.pq.commitRoundBlock is unset");
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void withoutTheBrakeHrAtOrBelowHfinStartsAndAboveItIsRefused() {
|
|
+ final PqAnchorConfig armed = startupRead(Map.of(PqAnchorConfig.PROPERTY_COMMIT_ROUND_BLOCK, "2000"));
|
|
+ assertThat(armed.commitRoundBlock()).as("control: H_r read at startup").isEqualTo(2_000L);
|
|
+ assertThatCode(() -> PqFinalityLayersGuard.verifyRoundOrAbort(H_FIN, armed, MAINNET))
|
|
+ .as("2800's order, H_r before H_fin")
|
|
+ .doesNotThrowAnyException();
|
|
+ assertThatThrownBy(() -> PqFinalityLayersGuard.verifyRoundOrAbort(1_999L, armed, MAINNET))
|
|
+ .isInstanceOf(IllegalStateException.class)
|
|
+ .hasMessageStartingWith(PqFinalityLayersGuard.CODE_ROUND_02)
|
|
+ .hasMessageContaining("above it (2000)");
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/AereDecidedChainView.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/AereDecidedChainView.java
|
|
new file mode 100644
|
|
index 0000000000..287cc0838c
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/AereDecidedChainView.java
|
|
@@ -0,0 +1,271 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead;
|
|
+import org.hyperledger.besu.consensus.common.bft.network.ValidatorMulticaster;
|
|
+import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockAdaptor;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.AereDecidedConsensus;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.AereDecidedHook;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.PqCommitEnforcement;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData;
|
|
+
|
|
+import java.time.Clock;
|
|
+import java.util.Collection;
|
|
+import java.util.Objects;
|
|
+import java.util.Optional;
|
|
+import java.util.concurrent.Executor;
|
|
+import java.util.concurrent.ExecutorService;
|
|
+import java.util.concurrent.Executors;
|
|
+import java.util.function.Consumer;
|
|
+import java.util.function.Function;
|
|
+import java.util.function.LongPredicate;
|
|
+import java.util.function.LongSupplier;
|
|
+import java.util.function.ToLongFunction;
|
|
+
|
|
+import org.slf4j.Logger;
|
|
+import org.slf4j.LoggerFactory;
|
|
+
|
|
+/**
|
|
+ * AERE D-412 / the DECIDED HEAD (rule D), step 3: the Besu side of the wiring. It answers {@link
|
|
+ * AereDecidedConsensus.Chain} over the node's {@link MutableBlockchain}, its {@link AereDecidedHead},
|
|
+ * its {@link ValidatorProvider} and a multicaster WITHOUT the send-once filter (the echo re-sends
|
|
+ * messages the node already gossiped), and {@link #install} connects the pieces the way the builder
|
|
+ * needs them, in one place, so that the proofs build exactly what production builds:
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>every move of D posts a new chain head event for D (the QBFT controller starts D+1 from it);
|
|
+ * <li>every block added to the chain (canonical, fork, reorg) is told to the wiring;
|
|
+ * <li>the wiring is installed as the process hook ({@link AereDecidedHook#install}).
|
|
+ * </ul>
|
|
+ */
|
|
+public final class AereDecidedChainView implements AereDecidedConsensus.Chain {
|
|
+
|
|
+ private static final Logger LOG = LoggerFactory.getLogger(AereDecidedChainView.class);
|
|
+
|
|
+ private final MutableBlockchain blockchain;
|
|
+ private final AereDecidedHead head;
|
|
+ private final ValidatorProvider validatorProvider;
|
|
+ private final ValidatorMulticaster echoMulticaster;
|
|
+ private final LongPredicate anchorHeight;
|
|
+ private final Function<BlockHeader, Optional<AereDecidedHead.Decided>> certifiedDecision;
|
|
+ private final Clock clock;
|
|
+
|
|
+ /**
|
|
+ * The view.
|
|
+ *
|
|
+ * @param blockchain the node's chain
|
|
+ * @param head the node's decided head
|
|
+ * @param validatorProvider the node's validator provider
|
|
+ * @param echoMulticaster sends to every validator, without the send-once filter
|
|
+ * @param anchorHeight whether a height carries an anchor certificate
|
|
+ * @param certifiedDecision the block a stored anchor's certificate proves decided
|
|
+ * (AereCertifiedDecision; teza Q3, 2026-10-01), empty when it proves nothing
|
|
+ * @param clock the clock of the echo rate limit
|
|
+ */
|
|
+ public AereDecidedChainView(
|
|
+ final MutableBlockchain blockchain,
|
|
+ final AereDecidedHead head,
|
|
+ final ValidatorProvider validatorProvider,
|
|
+ final ValidatorMulticaster echoMulticaster,
|
|
+ final LongPredicate anchorHeight,
|
|
+ final Function<BlockHeader, Optional<AereDecidedHead.Decided>> certifiedDecision,
|
|
+ final Clock clock) {
|
|
+ this.blockchain = Objects.requireNonNull(blockchain, "blockchain");
|
|
+ this.head = Objects.requireNonNull(head, "head");
|
|
+ this.validatorProvider = Objects.requireNonNull(validatorProvider, "validatorProvider");
|
|
+ this.echoMulticaster = Objects.requireNonNull(echoMulticaster, "echoMulticaster");
|
|
+ this.anchorHeight = Objects.requireNonNull(anchorHeight, "anchorHeight");
|
|
+ this.certifiedDecision = Objects.requireNonNull(certifiedDecision, "certifiedDecision");
|
|
+ this.clock = Objects.requireNonNull(clock, "clock");
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The executor of production: one daemon thread, never the QBFT thread.
|
|
+ *
|
|
+ * @return the executor
|
|
+ */
|
|
+ public static ExecutorService singleThreadExecutor() {
|
|
+ return Executors.newSingleThreadExecutor(
|
|
+ r -> {
|
|
+ final Thread t = new Thread(r, "aere-decided-head");
|
|
+ t.setDaemon(true);
|
|
+ return t;
|
|
+ });
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Build the wiring of one validator and connect it: D's moves post the new chain head event, the
|
|
+ * chain's added blocks reach the wiring, and the wiring becomes the process hook.
|
|
+ *
|
|
+ * @param blockchain the node's chain
|
|
+ * @param head the node's decided head (already restored)
|
|
+ * @param validatorProvider the node's validator provider
|
|
+ * @param blockInterface the QBFT block interface
|
|
+ * @param echoMulticaster sends to every validator, without the send-once filter
|
|
+ * @param newHeadPoster posts a new chain head event for a header (production: the BFT event queue)
|
|
+ * @param anchorHeight whether a height carries an anchor certificate
|
|
+ * @param certifiedDecision the block a stored anchor's certificate proves decided
|
|
+ * (AereCertifiedDecision; teza Q3, 2026-10-01), empty when it proves nothing
|
|
+ * @param enforcement the node's PQ commit enforcement, or null
|
|
+ * @param verifierGeneration changes whenever the registry may have changed state
|
|
+ * @param sizeOf the bytes a proposed block is charged
|
|
+ * @param executor where evaluations run (production: {@link #singleThreadExecutor()})
|
|
+ * @param clock the clock of the echo rate limit
|
|
+ * @return the installed wiring
|
|
+ */
|
|
+ public static AereDecidedConsensus install(
|
|
+ final MutableBlockchain blockchain,
|
|
+ final AereDecidedHead head,
|
|
+ final ValidatorProvider validatorProvider,
|
|
+ final QbftBlockInterface blockInterface,
|
|
+ final ValidatorMulticaster echoMulticaster,
|
|
+ final Consumer<BlockHeader> newHeadPoster,
|
|
+ final LongPredicate anchorHeight,
|
|
+ final Function<BlockHeader, Optional<AereDecidedHead.Decided>> certifiedDecision,
|
|
+ final PqCommitEnforcement enforcement,
|
|
+ final LongSupplier verifierGeneration,
|
|
+ final ToLongFunction<QbftBlock> sizeOf,
|
|
+ final Executor executor,
|
|
+ final Clock clock) {
|
|
+ final AereDecidedChainView view =
|
|
+ new AereDecidedChainView(
|
|
+ blockchain,
|
|
+ head,
|
|
+ validatorProvider,
|
|
+ echoMulticaster,
|
|
+ anchorHeight,
|
|
+ certifiedDecision,
|
|
+ clock);
|
|
+ final AereDecidedConsensus wiring =
|
|
+ new AereDecidedConsensus(
|
|
+ view,
|
|
+ blockInterface,
|
|
+ enforcement,
|
|
+ verifierGeneration,
|
|
+ sizeOf,
|
|
+ executor,
|
|
+ AereDecidedHead.DEFAULT_MAX_WALK);
|
|
+ head.onAdvanced(
|
|
+ d -> {
|
|
+ final Optional<BlockHeader> header = blockchain.getBlockHeader(d.hash());
|
|
+ if (header.isPresent()) {
|
|
+ newHeadPoster.accept(header.get());
|
|
+ } else {
|
|
+ LOG.warn("AERE D-412: the decided head {} is not stored; no new chain head posted", d);
|
|
+ }
|
|
+ });
|
|
+ blockchain.observeBlockAdded(
|
|
+ event -> {
|
|
+ final BlockHeader h = event.getHeader();
|
|
+ if (h != null) {
|
|
+ wiring.blockStored(h.getHash(), h.getNumber(), h.getParentHash());
|
|
+ }
|
|
+ });
|
|
+ AereDecidedHook.install(wiring);
|
|
+ LOG.info(
|
|
+ "AERE D-412 rule D: wiring installed; H_ev={}, D={}, window={}",
|
|
+ head.activationHeight(),
|
|
+ head.decided(),
|
|
+ AereDecidedHead.DEFAULT_MAX_WALK);
|
|
+ return wiring;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean active(final long height) {
|
|
+ return head.active(height);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean provable(final long height) {
|
|
+ return head.provable(height);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public AereDecidedHead.Outcome resolveFloor() {
|
|
+ return head.resolveFloor();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public AereDecidedHead.Decided decided() {
|
|
+ return head.decided();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Optional<QbftBlock> storedBlock(final Hash onchainHash) {
|
|
+ return blockchain.getBlockByHash(onchainHash).map(QbftBlockAdaptor::new);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Optional<Hash> canonicalHash(final long height) {
|
|
+ return blockchain.getBlockHashByNumber(height);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public long canonicalHeadNumber() {
|
|
+ return blockchain.getChainHeadBlockNumber();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Optional<Collection<Address>> validatorsAfter(final Hash onchainHash) {
|
|
+ return blockchain.getBlockHeader(onchainHash).map(validatorProvider::getValidatorsAfterBlock);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Collection<Address> validatorsAtHead() {
|
|
+ return validatorProvider.getValidatorsAtHead();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Optional<Collection<Address>> validatorsDeciding(final long height) {
|
|
+ return blockchain.getBlockHeader(height).map(validatorProvider::getValidatorsForBlock);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public AereDecidedHead.Outcome advance(final Hash onchainHash, final AereDecidedHead.Proof proof) {
|
|
+ return head.advance(onchainHash, proof);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean anchorHeight(final long height) {
|
|
+ return anchorHeight.test(height);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Optional<AereDecidedHead.Decided> certifiedDecision(final Hash onchainHash) {
|
|
+ final Optional<BlockHeader> header = blockchain.getBlockHeader(onchainHash);
|
|
+ if (header.isEmpty() || !anchorHeight.test(header.get().getNumber())) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ return certifiedDecision.apply(header.get());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void multicast(final MessageData message) {
|
|
+ echoMulticaster.send(message);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public long nowMillis() {
|
|
+ return clock.millis();
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftExtraDataCodec.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftExtraDataCodec.java
|
|
index d4f6e2d8fc..1ca0748f83 100644
|
|
--- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftExtraDataCodec.java
|
|
+++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftExtraDataCodec.java
|
|
@@ -10,40 +10,41 @@
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
* found, as section 4(c) requires. The change itself is in patches/0003-aere-pq-anchor.patch.
|
|
*/
|
|
package org.hyperledger.besu.consensus.qbft;
|
|
|
|
import static org.hyperledger.besu.consensus.common.bft.Vote.ADD_BYTE_VALUE;
|
|
import static org.hyperledger.besu.consensus.common.bft.Vote.DROP_BYTE_VALUE;
|
|
|
|
import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec;
|
|
import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
import org.hyperledger.besu.consensus.common.bft.PqAnchorV2;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorV3;
|
|
import org.hyperledger.besu.consensus.common.bft.SchemeSeal;
|
|
import org.hyperledger.besu.consensus.common.bft.Vote;
|
|
import org.hyperledger.besu.consensus.common.validator.VoteType;
|
|
import org.hyperledger.besu.crypto.SECPSignature;
|
|
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
|
import org.hyperledger.besu.datatypes.Address;
|
|
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput;
|
|
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
|
|
import org.hyperledger.besu.ethereum.rlp.RLPException;
|
|
import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
|
import org.hyperledger.besu.ethereum.rlp.RLPOutput;
|
|
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
|
|
import com.google.common.collect.ImmutableBiMap;
|
|
import org.apache.tuweni.bytes.Bytes;
|
|
|
|
@@ -79,40 +80,73 @@ public class QbftExtraDataCodec extends BftExtraDataCodec {
|
|
return new QbftExtraDataCodec()
|
|
.encode(
|
|
new BftExtraData(
|
|
Bytes.wrap(new byte[EXTRA_VANITY_LENGTH]),
|
|
Collections.emptyList(),
|
|
Optional.empty(),
|
|
0,
|
|
addresses));
|
|
}
|
|
|
|
/**
|
|
* Create genesis extra data string.
|
|
*
|
|
* @param validators the validators
|
|
* @return the string
|
|
*/
|
|
public static String createGenesisExtraDataString(final List<Address> validators) {
|
|
return encodeFromAddresses(validators).toString();
|
|
}
|
|
|
|
+ /**
|
|
+ * AERE 1(b) (2026-10-01): whether element 6 of this extraData is a v3 certificate, a list whose first item is the
|
|
+ * scalar 3, read structurally without decoding anything else. A binary without v3 refused such bytes at ANY height
|
|
+ * (its v2 decoder says "unknown certificate version 3"), while this codec decodes them; R1 asks this question at
|
|
+ * every height, so a v3 is refused wherever the form is not v3, exactly as before (L1). Malformed bytes answer
|
|
+ * false: the decode refuses them anyway.
|
|
+ *
|
|
+ * @param extraData the header's extraData
|
|
+ * @return true when element 6 opens with the version scalar 3
|
|
+ */
|
|
+ public static boolean carriesV3Certificate(final Bytes extraData) {
|
|
+ try {
|
|
+ final RLPInput in = new BytesValueRLPInput(extraData, false);
|
|
+ in.enterList();
|
|
+ for (int i = 0; i < 5; i++) {
|
|
+ if (in.isEndOfCurrentList()) {
|
|
+ return false;
|
|
+ }
|
|
+ in.skipNext();
|
|
+ }
|
|
+ if (in.isEndOfCurrentList() || !in.nextIsList()) {
|
|
+ return false;
|
|
+ }
|
|
+ in.enterList();
|
|
+ if (in.isEndOfCurrentList() || in.nextIsList()) {
|
|
+ return false;
|
|
+ }
|
|
+ return in.readIntScalar() == PqAnchorV3.VERSION;
|
|
+ } catch (final RuntimeException e) {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
@Override
|
|
public BftExtraData decodeRaw(final Bytes input) {
|
|
if (input.isEmpty()) {
|
|
throw new IllegalArgumentException("Invalid Bytes supplied - Bft Extra Data required.");
|
|
}
|
|
|
|
final RLPInput rlpInput = new BytesValueRLPInput(input, false);
|
|
|
|
rlpInput.enterList(); // This accounts for the "root node" which contains BFT data items.
|
|
final Bytes vanityData = rlpInput.readBytes();
|
|
// AERE-D415 (2026-09-25): the vanity field is exactly 32 bytes at EVERY height, not only where
|
|
// the anchor rule looks (PqAnchorDigestRule checks it at anchor heights alone). The second
|
|
// client's decoder has required 32 from the start, so every header of chains 2800 and 28001,
|
|
// both geneses included, satisfies it; the differential fuzzer of the stage-5 header rule found
|
|
// the two clients judging a 0-, 31-, 33- or 64-byte vanity between anchors differently (this
|
|
// codec admitted it, the second client refused it). One rule, in the codec, for both clients.
|
|
if (vanityData.size() != EXTRA_VANITY_LENGTH) {
|
|
throw new RLPException(
|
|
"AERE-D415: QBFT vanity must be exactly "
|
|
+ EXTRA_VANITY_LENGTH
|
|
@@ -122,60 +156,96 @@ public class QbftExtraDataCodec extends BftExtraDataCodec {
|
|
final List<Address> validators = rlpInput.readList(Address::readFrom);
|
|
|
|
final Optional<Vote> vote;
|
|
if (rlpInput.nextIsList() && rlpInput.nextSize() == 0) {
|
|
vote = Optional.empty();
|
|
rlpInput.skipNext();
|
|
} else {
|
|
vote = Optional.of(decodeVote(rlpInput));
|
|
}
|
|
|
|
final int round = rlpInput.readIntScalar();
|
|
final List<SECPSignature> seals =
|
|
rlpInput.readList(
|
|
rlp -> SignatureAlgorithmFactory.getInstance().decodeSignature(rlp.readBytes()));
|
|
|
|
// AERE hybrid PQC: an OPTIONAL parallel Falcon-512 seal list may follow the ECDSA seals.
|
|
// Backward-tolerant: older/exclude/no-certificate encodings without this element decode to an
|
|
// empty list.
|
|
final List<FalconSeal> falconSeals;
|
|
final List<SchemeSeal> hybridSeals;
|
|
+ // AERE 1(b) (2026-10-01): the round of a v3 certificate, or NO_CERTIFICATE_ROUND
|
|
+ int certificateRound = BftExtraData.NO_CERTIFICATE_ROUND;
|
|
if (!rlpInput.isEndOfCurrentList()) {
|
|
// AERE ANCHOR V2 (2026-09-03): the sixth element is EITHER the v1 Falcon list
|
|
// RLP[[idx,sig],...] OR the scheme-tagged v2 certificate RLP[2,[[scheme,idx,sig],...]].
|
|
// They cannot be confused: v1 opens with a LIST, v2 with the SCALAR 2. The raw bytes are
|
|
// taken first so the v2 decoder can enforce its canonical round trip on exactly what the
|
|
// header carried; the codec's own round trip (gate 2 below) then covers both forms.
|
|
final Bytes certificateRaw = rlpInput.readAsRlp().raw();
|
|
final RLPInput probe = new BytesValueRLPInput(certificateRaw, false);
|
|
probe.enterList();
|
|
- final boolean v2 = !probe.isEndOfCurrentList() && !probe.nextIsList();
|
|
- if (v2) {
|
|
- falconSeals = Collections.emptyList();
|
|
+ final boolean tagged = !probe.isEndOfCurrentList() && !probe.nextIsList();
|
|
+ if (tagged) {
|
|
+ // AERE 1(b): a DISPATCHER on the version scalar, named both ways. The scalar 2 is v2 (exactly
|
|
+ // two elements, which PqAnchorV2.decode enforces), the scalar 3 is v3 (exactly three, enforced by
|
|
+ // PqAnchorV3.decode, which also checks the round explicitly and the canonical round trip); any
|
|
+ // other version is refused here by name, never handed to a decoder that might misread it. The
|
|
+ // height decides which of them is VALID (rules R1/R2, codes AERE-PQ-V3-01/02); this codec only
|
|
+ // decides which of them is WELL-FORMED, and its refusal is the AERE-PQ-V3-03 verdict.
|
|
+ final int version;
|
|
try {
|
|
- hybridSeals = PqAnchorV2.decode(certificateRaw);
|
|
+ version = probe.readIntScalar();
|
|
} catch (final RuntimeException e) {
|
|
throw new RLPException(
|
|
- "AERE ANCHOR V2: the header's certificate does not decode as a canonical v2"
|
|
- + " certificate: "
|
|
+ "AERE ANCHOR: the header's certificate opens with an unreadable version scalar: "
|
|
+ e.getMessage());
|
|
}
|
|
+ falconSeals = Collections.emptyList();
|
|
+ if (version == PqAnchorV2.VERSION) {
|
|
+ try {
|
|
+ hybridSeals = PqAnchorV2.decode(certificateRaw);
|
|
+ } catch (final RuntimeException e) {
|
|
+ throw new RLPException(
|
|
+ "AERE ANCHOR V2: the header's certificate does not decode as a canonical v2"
|
|
+ + " certificate: "
|
|
+ + e.getMessage());
|
|
+ }
|
|
+ } else if (version == PqAnchorV3.VERSION) {
|
|
+ final PqAnchorV3.Certificate v3;
|
|
+ try {
|
|
+ v3 = PqAnchorV3.decode(certificateRaw);
|
|
+ } catch (final RuntimeException e) {
|
|
+ throw new RLPException(
|
|
+ "AERE ANCHOR V3: the header's certificate does not decode as a canonical v3"
|
|
+ + " certificate: "
|
|
+ + e.getMessage());
|
|
+ }
|
|
+ hybridSeals = v3.seals();
|
|
+ certificateRound = v3.round();
|
|
+ } else {
|
|
+ throw new RLPException(
|
|
+ PqAnchorV3.V3_03
|
|
+ + ": the header's certificate names version "
|
|
+ + version
|
|
+ + "; this build understands the v1 list, 2 and 3");
|
|
+ }
|
|
} else {
|
|
hybridSeals = Collections.emptyList();
|
|
falconSeals =
|
|
new BytesValueRLPInput(certificateRaw, false)
|
|
.readList(
|
|
rlp -> {
|
|
rlp.enterList();
|
|
final int idx = rlp.readIntScalar();
|
|
final Bytes sig = rlp.readBytes();
|
|
rlp.leaveList();
|
|
return new FalconSeal(idx, sig);
|
|
});
|
|
}
|
|
} else {
|
|
falconSeals = Collections.emptyList();
|
|
hybridSeals = Collections.emptyList();
|
|
}
|
|
|
|
// AERE AIP-22 stage 5: an OPTIONAL seventh element, the proposer's seal [index, signature], after
|
|
// the certificate slot. When it is present the certificate slot is ALWAYS written (an empty list
|
|
@@ -188,41 +258,49 @@ public class QbftExtraDataCodec extends BftExtraDataCodec {
|
|
final int idx = rlpInput.readIntScalar();
|
|
final Bytes sig = rlpInput.readBytes();
|
|
rlpInput.leaveList();
|
|
proposerSeal = Optional.of(new FalconSeal(idx, sig));
|
|
}
|
|
|
|
// AERE FIX-MALEABILITATE-BLOC (2026-08-01), gate 1 of 2: the leave is STRICT.
|
|
//
|
|
// Upstream ends this decode with leaveListLenient(), which silently discards anything still
|
|
// left in the outer list. That is not survivable here, because the QBFT block hash and the
|
|
// committed-seal pre-image are BOTH computed from a RE-ENCODE of the decoded BftExtraData
|
|
// (BftBlockHashing.calculateHashOfBftBlockOnchain line 84-91, calculateDataHashForCommittedSeal
|
|
// line 53-75). Anything the decoder discards is therefore dropped before hashing, so two
|
|
// different header byte strings carry the same block hash and the same genuine validator
|
|
// seals. leaveList() rejects exactly the inputs that have content left over, and is
|
|
// byte-for-byte identical to the lenient leave on every input that has not.
|
|
rlpInput.leaveList();
|
|
|
|
final BftExtraData decoded =
|
|
new BftExtraData(
|
|
- vanityData, seals, vote, round, validators, falconSeals, hybridSeals, proposerSeal);
|
|
+ vanityData,
|
|
+ seals,
|
|
+ vote,
|
|
+ round,
|
|
+ validators,
|
|
+ falconSeals,
|
|
+ hybridSeals,
|
|
+ certificateRound,
|
|
+ proposerSeal);
|
|
|
|
// AERE FIX-MALEABILITATE-BLOC (2026-08-01), gate 2 of 2: CANONICAL ROUND TRIP.
|
|
//
|
|
// The strict leave alone does not close the hole. The Falcon element is OPTIONAL on the wire
|
|
// and the encoder omits it when the certificate is empty, so a header carrying an explicit
|
|
// EMPTY Falcon list decodes to exactly the same value as a header carrying no Falcon element
|
|
// at all: the trailing 0xc0 is CONSUMED, not left over, so no leave, strict or lenient, can
|
|
// see it. Requiring the full re-encode to reproduce the received bytes makes the accepted
|
|
// encoding unique by construction, and closes every present and future shape of this defect
|
|
// rather than the one instance of it we happened to look for.
|
|
//
|
|
// Backward compatibility: the re-encode used here is the same EncodingType.ALL the block
|
|
// producer uses, so every header any Aere or stock Besu node has ever produced round trips
|
|
// unchanged. Headers with no Falcon element re-encode with no Falcon element, which is why
|
|
// the whole pre-Falcon history of the chain still decodes.
|
|
final Bytes canonical = encode(decoded, EncodingType.ALL);
|
|
if (!canonical.equals(input)) {
|
|
throw new RLPException(
|
|
"Non-canonical BFT extra data: the header's extraData is "
|
|
+ input.size()
|
|
@@ -242,41 +320,50 @@ public class QbftExtraDataCodec extends BftExtraDataCodec {
|
|
encoder.writeBytes(bftExtraData.getVanityData());
|
|
encoder.writeList(
|
|
bftExtraData.getValidators(), (validator, rlp) -> rlp.writeBytes(validator.getBytes()));
|
|
|
|
if (bftExtraData.getVote().isPresent()) {
|
|
encodeVote(encoder, bftExtraData.getVote().get());
|
|
} else {
|
|
encoder.writeList(Collections.emptyList(), (o, rlpOutput) -> {});
|
|
}
|
|
|
|
if (encodingType != EncodingType.EXCLUDE_COMMIT_SEALS_AND_ROUND_NUMBER) {
|
|
encoder.writeIntScalar(bftExtraData.getRound());
|
|
if (encodingType != EncodingType.EXCLUDE_COMMIT_SEALS) {
|
|
encoder.writeList(
|
|
bftExtraData.getSeals(), (committer, rlp) -> rlp.writeBytes(committer.encodedBytes()));
|
|
// AERE hybrid PQC: only the full (stored-header) encoding carries the parallel Falcon
|
|
// quorum certificate, and only when it is non-empty. The exclude encodings omit it so the
|
|
// committed-seal hash and the on-chain block hash are byte-identical to upstream Besu, and a
|
|
// header with no certificate is byte-identical to upstream too, so the Falcon seals are
|
|
// never part of any signed pre-image and never disturb the block hash.
|
|
- if (!bftExtraData.getHybridSeals().isEmpty()) {
|
|
+ if (bftExtraData.getCertificateRound().isPresent()) {
|
|
+ // AERE 1(b): the v3 certificate, canonical bytes, in the same slot. Written whenever a round is
|
|
+ // named, EMPTY included ([3, 0, []] at K_eff = 0, decision H5), so the slot is never omitted
|
|
+ // for a v3 and the round trip stays unique.
|
|
+ encoder.writeRaw(
|
|
+ PqAnchorV3.encode(
|
|
+ new PqAnchorV3.Certificate(
|
|
+ bftExtraData.getCertificateRound().getAsInt(),
|
|
+ bftExtraData.getHybridSeals())));
|
|
+ } else if (!bftExtraData.getHybridSeals().isEmpty()) {
|
|
// AERE ANCHOR V2: the scheme-tagged certificate, canonical bytes, in the same slot.
|
|
encoder.writeRaw(PqAnchorV2.encode(bftExtraData.getHybridSeals()));
|
|
} else if (!bftExtraData.getFalconSeals().isEmpty()) {
|
|
encoder.writeList(
|
|
bftExtraData.getFalconSeals(),
|
|
(falconSeal, rlp) -> {
|
|
rlp.startList();
|
|
rlp.writeIntScalar(falconSeal.getValidatorIndex());
|
|
rlp.writeBytes(falconSeal.getSignature());
|
|
rlp.endList();
|
|
});
|
|
} else if (bftExtraData.getPqProposerSeal().isPresent()) {
|
|
// AERE AIP-22 stage 5: the certificate slot stays in place, empty, so the seal is element 6
|
|
encoder.writeEmptyList();
|
|
}
|
|
if (bftExtraData.getPqProposerSeal().isPresent()) {
|
|
final FalconSeal ps = bftExtraData.getPqProposerSeal().get();
|
|
encoder.startList();
|
|
encoder.writeIntScalar(ps.getValidatorIndex());
|
|
encoder.writeBytes(ps.getSignature());
|
|
diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/adaptor/QbftBlockCreatorAdaptor.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/adaptor/QbftBlockCreatorAdaptor.java
|
|
index 24769c3472..34826f64fe 100644
|
|
--- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/adaptor/QbftBlockCreatorAdaptor.java
|
|
+++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/adaptor/QbftBlockCreatorAdaptor.java
|
|
@@ -92,40 +92,42 @@ public class QbftBlockCreatorAdaptor implements QbftBlockCreator {
|
|
* whole (vanity with the anchor digest, validators, vote, the anchor certificate verbatim) through
|
|
* {@link BftExtraData#withSeals}, so nothing the proposer chose can be dropped here; only the round
|
|
* is set to the commit round, the ECDSA committed seals are EMPTY and element 6 is the proposal's
|
|
* post-quantum seal. Every node seals the same bytes: the header is no longer assembled from what
|
|
* each node heard.
|
|
*/
|
|
@Override
|
|
public QbftBlock createSealedBlockWithProposerSeal(
|
|
final QbftBlock block, final int roundNumber, final FalconSeal proposerSeal) {
|
|
final Block besuBlock = AdaptorUtil.toBesuBlock(block);
|
|
final BftExtraData initial = bftExtraDataCodec.decode(AdaptorUtil.toBesuBlockHeader(block.getHeader()));
|
|
final BftExtraData withRound =
|
|
new BftExtraData(
|
|
initial.getVanityData(),
|
|
Collections.emptyList(),
|
|
initial.getVote(),
|
|
roundNumber,
|
|
initial.getValidators(),
|
|
initial.getFalconSeals(),
|
|
initial.getHybridSeals(),
|
|
+ // AERE 1(b): the v3 round rides along (D-328 discipline: every rebuild carries every field)
|
|
+ initial.getCertificateRound().orElse(BftExtraData.NO_CERTIFICATE_ROUND),
|
|
initial.getPqProposerSeal());
|
|
final BftExtraData sealed = withRound.withSeals(Collections.emptyList(), Optional.of(proposerSeal));
|
|
final BlockHeader header =
|
|
BlockHeaderBuilder.fromHeader(AdaptorUtil.toBesuBlockHeader(block.getHeader()))
|
|
.extraData(bftExtraDataCodec.encode(sealed))
|
|
.blockHeaderFunctions(BftBlockHeaderFunctions.forOnchainBlock(bftExtraDataCodec))
|
|
.buildBlockHeader();
|
|
return new QbftBlockAdaptor(new Block(header, besuBlock.getBody()));
|
|
}
|
|
|
|
@Override
|
|
public QbftBlock createSealedBlock(
|
|
final QbftBlock block,
|
|
final int roundNumber,
|
|
final Collection<SECPSignature> commitSeals,
|
|
final Collection<FalconSeal> collectedFalconSeals) {
|
|
final Block besuBlock = AdaptorUtil.toBesuBlock(block);
|
|
final QbftBlockHeader initialHeader = block.getHeader();
|
|
final BftExtraData initialExtraData =
|
|
bftExtraDataCodec.decode(AdaptorUtil.toBesuBlockHeader(initialHeader));
|
|
@@ -136,41 +138,43 @@ public class QbftBlockCreatorAdaptor implements QbftBlockCreator {
|
|
// must therefore carry the proposer's bytes across UNCHANGED. The legacy assembly below would
|
|
// overwrite them with what this node heard for the current block, which would leave a header
|
|
// whose vanity D no longer matches its own element 6, i.e. a header this node's own digest rule
|
|
// rejects. So above the activation height the assembler is skipped outright.
|
|
//
|
|
// Note what is NOT done here: no re-verification, no re-selection, no comparison against what
|
|
// this node heard. That is the whole point of V2. The proposer's certificate has already been
|
|
// checked by the header rules on the proposal, and re-deriving it locally is exactly the
|
|
// dependency on "what I heard" that killed the earlier design.
|
|
if (PqAnchorProducer.config().activeAt(initialHeader.getNumber())) {
|
|
final BftExtraData anchoredExtraData =
|
|
new BftExtraData(
|
|
initialExtraData.getVanityData(),
|
|
commitSeals,
|
|
initialExtraData.getVote(),
|
|
roundNumber,
|
|
initialExtraData.getValidators(),
|
|
initialExtraData.getFalconSeals(),
|
|
// AERE ANCHOR V2 (2026-09-03, D-328): the sealed block keeps the proposer's v2 certificate
|
|
// verbatim, exactly as it keeps the v1 one; dropping it here is what stalled the testnet.
|
|
- initialExtraData.getHybridSeals());
|
|
+ initialExtraData.getHybridSeals(),
|
|
+ // AERE 1(b): and the round of a v3 certificate, which D3 binds
|
|
+ initialExtraData.getCertificateRound().orElse(BftExtraData.NO_CERTIFICATE_ROUND));
|
|
final BlockHeader anchoredHeader =
|
|
BlockHeaderBuilder.fromHeader(AdaptorUtil.toBesuBlockHeader(initialHeader))
|
|
.extraData(bftExtraDataCodec.encode(anchoredExtraData))
|
|
.blockHeaderFunctions(BftBlockHeaderFunctions.forOnchainBlock(bftExtraDataCodec))
|
|
.buildBlockHeader();
|
|
LOG.debug(
|
|
"AERE PQ-ANCHOR: sealed block {} keeping the proposer's {}-seal parent certificate "
|
|
+ "verbatim ({} seal(s) heard locally for this block were deliberately ignored)",
|
|
anchoredHeader.getNumber(),
|
|
initialExtraData.getFalconSeals().size(),
|
|
collectedFalconSeals == null ? 0 : collectedFalconSeals.size());
|
|
return new QbftBlockAdaptor(new Block(anchoredHeader, besuBlock.getBody()));
|
|
}
|
|
|
|
// Step 1: build the sealed header exactly as upstream, with the decisive ECDSA committed seals
|
|
// and (for now) no Falcon seals. The ECDSA path is byte-for-byte unchanged.
|
|
final BftExtraData sealedExtraData =
|
|
new BftExtraData(
|
|
initialExtraData.getVanityData(),
|
|
commitSeals,
|
|
@@ -242,41 +246,44 @@ public class QbftBlockCreatorAdaptor implements QbftBlockCreator {
|
|
// "am I, right now, an eligible signer", asked before signing with the single private key
|
|
// this process holds. It gets its own name rather than a fabricated height, so that no
|
|
// future reader mistakes it for a verification path. See FalconSealSupport#localSigningAddress.
|
|
final Address self = pqc.localSigningAddress();
|
|
if (self != null && eligible.contains(self)) {
|
|
// AERE FIX-OPRIRE-CONSENS (b): height-gated like every other attachment point.
|
|
final Optional<FalconSeal> selfSeal =
|
|
pqc.sign(sealedHeader.getNumber(), Bytes32.wrap(commitHash.getBytes()));
|
|
selfSeal.ifPresent(quorumCert::add);
|
|
}
|
|
}
|
|
|
|
if (!quorumCert.isEmpty()) {
|
|
final BftExtraData hybridExtraData =
|
|
new BftExtraData(
|
|
initialExtraData.getVanityData(),
|
|
commitSeals,
|
|
initialExtraData.getVote(),
|
|
roundNumber,
|
|
initialExtraData.getValidators(),
|
|
- quorumCert);
|
|
+ quorumCert,
|
|
+ // the legacy v1 per-block path (history): no scheme-tagged rows, no v3 round
|
|
+ Collections.emptyList(),
|
|
+ BftExtraData.NO_CERTIFICATE_ROUND);
|
|
sealedHeader =
|
|
BlockHeaderBuilder.fromHeader(AdaptorUtil.toBesuBlockHeader(initialHeader))
|
|
.extraData(bftExtraDataCodec.encode(hybridExtraData))
|
|
.blockHeaderFunctions(BftBlockHeaderFunctions.forOnchainBlock(bftExtraDataCodec))
|
|
.buildBlockHeader();
|
|
LOG.debug(
|
|
"AERE PQC: attached Falcon-512 quorum certificate ({} distinct valid seal(s)) to block {}",
|
|
quorumCert.size(),
|
|
sealedHeader.getNumber());
|
|
}
|
|
} catch (final RuntimeException e) {
|
|
LOG.warn(
|
|
"AERE PQC: failed to attach Falcon quorum certificate; keeping ECDSA-only sealed block "
|
|
+ "(block still valid and final): {}",
|
|
e.toString());
|
|
}
|
|
|
|
final Block sealedBesuBlock = new Block(sealedHeader, besuBlock.getBody());
|
|
return new QbftBlockAdaptor(sealedBesuBlock);
|
|
}
|
|
diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/adaptor/QbftBlockHeaderAdaptor.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/adaptor/QbftBlockHeaderAdaptor.java
|
|
index 09215c69e8..07500be404 100644
|
|
--- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/adaptor/QbftBlockHeaderAdaptor.java
|
|
+++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/adaptor/QbftBlockHeaderAdaptor.java
|
|
@@ -1,33 +1,39 @@
|
|
/*
|
|
* Copyright contributors to Besu.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
+ *
|
|
+ * Modifications Copyright contributors to the Aere Network.
|
|
+ *
|
|
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0010-aere-pq-round-bound-commit-seal.patch.
|
|
*/
|
|
package org.hyperledger.besu.consensus.qbft.adaptor;
|
|
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockHeader;
|
|
import org.hyperledger.besu.datatypes.Address;
|
|
import org.hyperledger.besu.datatypes.Hash;
|
|
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
|
|
import java.util.Objects;
|
|
|
|
/** Adaptor class to allow a {@link BlockHeader} to be used as a {@link QbftBlockHeader}. */
|
|
public class QbftBlockHeaderAdaptor implements QbftBlockHeader {
|
|
|
|
private final BlockHeader blockHeader;
|
|
|
|
/**
|
|
* Construct a new QbftBlockHeader
|
|
*
|
|
* @param blockHeader the Besu block header
|
|
*/
|
|
@@ -38,40 +44,45 @@ public class QbftBlockHeaderAdaptor implements QbftBlockHeader {
|
|
@Override
|
|
public long getNumber() {
|
|
return blockHeader.getNumber();
|
|
}
|
|
|
|
@Override
|
|
public long getTimestamp() {
|
|
return blockHeader.getTimestamp();
|
|
}
|
|
|
|
@Override
|
|
public Address getCoinbase() {
|
|
return blockHeader.getCoinbase();
|
|
}
|
|
|
|
@Override
|
|
public Hash getHash() {
|
|
return blockHeader.getHash();
|
|
}
|
|
|
|
+ @Override
|
|
+ public Hash getParentHash() {
|
|
+ return blockHeader.getParentHash();
|
|
+ }
|
|
+
|
|
/**
|
|
* Returns the Besu block header.
|
|
*
|
|
* @return the Besu block header.
|
|
*/
|
|
public BlockHeader getBesuBlockHeader() {
|
|
return blockHeader;
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(final Object o) {
|
|
if (!(o instanceof QbftBlockHeaderAdaptor that)) return false;
|
|
return Objects.equals(blockHeader, that.blockHeader);
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return Objects.hashCode(blockHeader);
|
|
}
|
|
|
|
diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/adaptor/QbftBlockchainAdaptor.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/adaptor/QbftBlockchainAdaptor.java
|
|
index fa01732a99..f380218241 100644
|
|
--- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/adaptor/QbftBlockchainAdaptor.java
|
|
+++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/adaptor/QbftBlockchainAdaptor.java
|
|
@@ -1,45 +1,87 @@
|
|
/*
|
|
* Copyright contributors to Besu.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
+ *
|
|
+ * Modifications Copyright contributors to the Aere Network.
|
|
+ *
|
|
+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0010-aere-pq-round-bound-commit-seal.patch.
|
|
*/
|
|
package org.hyperledger.besu.consensus.qbft.adaptor;
|
|
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockHeader;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockchain;
|
|
import org.hyperledger.besu.ethereum.chain.Blockchain;
|
|
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
|
|
+import java.util.Optional;
|
|
+
|
|
/** Adaptor class to allow a {@link Blockchain} to be used as a {@link QbftBlockchain}. */
|
|
public class QbftBlockchainAdaptor implements QbftBlockchain {
|
|
private final Blockchain blockchain;
|
|
+ private final AereDecidedHead aereDecided;
|
|
|
|
/**
|
|
* Create a new instance of the adaptor.
|
|
*
|
|
* @param blockchain The {@link Blockchain} to adapt.
|
|
*/
|
|
public QbftBlockchainAdaptor(final Blockchain blockchain) {
|
|
+ this(blockchain, null);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Create a new instance of the adaptor for a validator with AERE rule D (D-412, the decided head).
|
|
+ * While the next height's decided block needs a proof (D + 1 >= max(1, H_ev - 1), the proof height:
|
|
+ * the parent of H_ev must be proved too), the head the QBFT state machine runs on is the decided head
|
|
+ * D, not the canonical head: the canonical head above D is provisional. This moves, at once, start(),
|
|
+ * stop(), the height guard of consumeMessage, the late-seal salvage (D-227), and the guards of the
|
|
+ * block timer and of the round expiry.
|
|
+ *
|
|
+ * @param blockchain The {@link Blockchain} to adapt.
|
|
+ * @param aereDecided the node's decided head, or null for upstream behaviour
|
|
+ */
|
|
+ public QbftBlockchainAdaptor(final Blockchain blockchain, final AereDecidedHead aereDecided) {
|
|
this.blockchain = blockchain;
|
|
+ this.aereDecided = aereDecided;
|
|
}
|
|
|
|
@Override
|
|
public QbftBlockHeader getChainHeadHeader() {
|
|
+ final Optional<BlockHeader> aereHead = aereGoverningHead();
|
|
+ if (aereHead.isPresent()) {
|
|
+ return new QbftBlockHeaderAdaptor(aereHead.get());
|
|
+ }
|
|
BlockHeader chainHeadHeader = blockchain.getChainHeadHeader();
|
|
return new QbftBlockHeaderAdaptor(chainHeadHeader);
|
|
}
|
|
|
|
@Override
|
|
public long getChainHeadBlockNumber() {
|
|
+ final Optional<BlockHeader> aereHead = aereGoverningHead();
|
|
+ if (aereHead.isPresent()) {
|
|
+ return aereHead.get().getNumber();
|
|
+ }
|
|
return blockchain.getChainHeadBlockNumber();
|
|
}
|
|
+
|
|
+ /** AERE D-412: D's header when the next height's decided block needs a proof, empty otherwise. */
|
|
+ private Optional<BlockHeader> aereGoverningHead() {
|
|
+ if (aereDecided == null || !aereDecided.provable(aereDecided.decided().number() + 1)) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ return aereDecided.decidedHeader();
|
|
+ }
|
|
}
|
|
diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/adaptor/QbftFinalStateImpl.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/adaptor/QbftFinalStateImpl.java
|
|
index 03d2c64c9c..35f7dc7724 100644
|
|
--- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/adaptor/QbftFinalStateImpl.java
|
|
+++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/adaptor/QbftFinalStateImpl.java
|
|
@@ -1,151 +1,209 @@
|
|
/*
|
|
* Copyright contributors to Besu.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
- * found, as section 4(c) requires. The change itself is in patches/0008-aere-pq-aip22.patch.
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0010-aere-pq-round-bound-commit-seal.patch.
|
|
*/
|
|
package org.hyperledger.besu.consensus.qbft.adaptor;
|
|
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead;
|
|
import org.hyperledger.besu.consensus.common.bft.AerePqIdentity;
|
|
import org.hyperledger.besu.consensus.common.bft.BftHelpers;
|
|
import org.hyperledger.besu.consensus.common.bft.BlockTimer;
|
|
import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
|
import org.hyperledger.besu.consensus.common.bft.RoundTimer;
|
|
import org.hyperledger.besu.consensus.common.bft.blockcreation.ProposerSelector;
|
|
import org.hyperledger.besu.consensus.common.bft.network.ValidatorMulticaster;
|
|
import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCreatorFactory;
|
|
import org.hyperledger.besu.consensus.qbft.core.types.QbftFinalState;
|
|
import org.hyperledger.besu.cryptoservices.NodeKey;
|
|
import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
|
|
import java.time.Clock;
|
|
import java.util.Collection;
|
|
+import java.util.Optional;
|
|
|
|
/** Besu implementation of QbftFinalState for maintaining the state of a QBFT network. */
|
|
public class QbftFinalStateImpl implements QbftFinalState {
|
|
private final ValidatorProvider validatorProvider;
|
|
private final NodeKey nodeKey;
|
|
private final Address localAddress;
|
|
private final ProposerSelector proposerSelector;
|
|
private final ValidatorMulticaster validatorMulticaster;
|
|
private final RoundTimer roundTimer;
|
|
private final BlockTimer blockTimer;
|
|
private final QbftBlockCreatorFactory blockCreatorFactory;
|
|
private final Clock clock;
|
|
+ private final AereDecidedHead aereDecided;
|
|
|
|
/**
|
|
* Constructs a new QBFT final state.
|
|
*
|
|
* @param validatorProvider the validator provider
|
|
* @param nodeKey the node key
|
|
* @param localAddress the local address
|
|
* @param proposerSelector the proposer selector
|
|
* @param validatorMulticaster the validator multicaster
|
|
* @param roundTimer the round timer
|
|
* @param blockTimer the block timer
|
|
* @param blockCreatorFactory the block creator factory
|
|
* @param clock the clock
|
|
*/
|
|
public QbftFinalStateImpl(
|
|
final ValidatorProvider validatorProvider,
|
|
final NodeKey nodeKey,
|
|
final Address localAddress,
|
|
final ProposerSelector proposerSelector,
|
|
final ValidatorMulticaster validatorMulticaster,
|
|
final RoundTimer roundTimer,
|
|
final BlockTimer blockTimer,
|
|
final QbftBlockCreatorFactory blockCreatorFactory,
|
|
final Clock clock) {
|
|
+ this(
|
|
+ validatorProvider,
|
|
+ nodeKey,
|
|
+ localAddress,
|
|
+ proposerSelector,
|
|
+ validatorMulticaster,
|
|
+ roundTimer,
|
|
+ blockTimer,
|
|
+ blockCreatorFactory,
|
|
+ clock,
|
|
+ null);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Constructs a new QBFT final state for a validator with AERE rule D (D-412, the decided head):
|
|
+ * while the next height's decided block needs a proof (D + 1 >= max(1, H_ev - 1)), the validator set
|
|
+ * is the set AFTER the decided head D, the set that decides D + 1, not the set at the provisional
|
|
+ * canonical head; and below the durable floor of the decided head this node is no voter.
|
|
+ *
|
|
+ * @param validatorProvider the validator provider
|
|
+ * @param nodeKey the node key
|
|
+ * @param localAddress the local address
|
|
+ * @param proposerSelector the proposer selector
|
|
+ * @param validatorMulticaster the validator multicaster
|
|
+ * @param roundTimer the round timer
|
|
+ * @param blockTimer the block timer
|
|
+ * @param blockCreatorFactory the block creator factory
|
|
+ * @param clock the clock
|
|
+ * @param aereDecided the node's decided head, or null for upstream behaviour
|
|
+ */
|
|
+ public QbftFinalStateImpl(
|
|
+ final ValidatorProvider validatorProvider,
|
|
+ final NodeKey nodeKey,
|
|
+ final Address localAddress,
|
|
+ final ProposerSelector proposerSelector,
|
|
+ final ValidatorMulticaster validatorMulticaster,
|
|
+ final RoundTimer roundTimer,
|
|
+ final BlockTimer blockTimer,
|
|
+ final QbftBlockCreatorFactory blockCreatorFactory,
|
|
+ final Clock clock,
|
|
+ final AereDecidedHead aereDecided) {
|
|
this.validatorProvider = validatorProvider;
|
|
this.nodeKey = nodeKey;
|
|
this.localAddress = localAddress;
|
|
this.proposerSelector = proposerSelector;
|
|
this.validatorMulticaster = validatorMulticaster;
|
|
this.roundTimer = roundTimer;
|
|
this.blockTimer = blockTimer;
|
|
this.blockCreatorFactory = blockCreatorFactory;
|
|
this.clock = clock;
|
|
+ this.aereDecided = aereDecided;
|
|
}
|
|
|
|
/**
|
|
* Gets validators.
|
|
*
|
|
* @return the validators
|
|
*/
|
|
@Override
|
|
public Collection<Address> getValidators() {
|
|
+ // AERE D-412 rule D: the set that decides D + 1 is the set after D, not the set at the canonical head
|
|
+ if (aereDecided != null && aereDecided.provable(aereDecided.decided().number() + 1)) {
|
|
+ final Optional<BlockHeader> aereHead = aereDecided.decidedHeader();
|
|
+ if (aereHead.isPresent()) {
|
|
+ return validatorProvider.getValidatorsAfterBlock(aereHead.get());
|
|
+ }
|
|
+ }
|
|
return validatorProvider.getValidatorsAtHead();
|
|
}
|
|
|
|
/**
|
|
* Gets the validator multicaster.
|
|
*
|
|
* @return the validator multicaster
|
|
*/
|
|
@Override
|
|
public ValidatorMulticaster getValidatorMulticaster() {
|
|
return validatorMulticaster;
|
|
}
|
|
|
|
/**
|
|
* Gets node key.
|
|
*
|
|
* @return the node key
|
|
*/
|
|
@Override
|
|
public NodeKey getNodeKey() {
|
|
return nodeKey;
|
|
}
|
|
|
|
/**
|
|
* Gets local address.
|
|
*
|
|
* @return the local address
|
|
*/
|
|
@Override
|
|
public Address getLocalAddress() {
|
|
return localAddress;
|
|
}
|
|
|
|
/**
|
|
* Is local node validator.
|
|
*
|
|
* @return the boolean
|
|
*/
|
|
@Override
|
|
public boolean isLocalNodeValidator() {
|
|
+ // AERE D-412 rule D: below the durable floor (a decision this node wrote durably and whose block it does
|
|
+ // not hold since its restart) it neither proposes nor votes, so it can never decide those heights twice
|
|
+ if (aereDecided != null && aereDecided.belowFloor()) {
|
|
+ return false;
|
|
+ }
|
|
return getValidators().stream().anyMatch(a -> AerePqIdentity.isLocal(a, localAddress));
|
|
}
|
|
|
|
/**
|
|
* Gets round timer.
|
|
*
|
|
* @return the round timer
|
|
*/
|
|
@Override
|
|
public RoundTimer getRoundTimer() {
|
|
return roundTimer;
|
|
}
|
|
|
|
/**
|
|
* Gets block creator factory.
|
|
*
|
|
* @return the block creator factory
|
|
*/
|
|
@Override
|
|
public QbftBlockCreatorFactory getBlockCreatorFactory() {
|
|
diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorDigestRule.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorDigestRule.java
|
|
index a9ba7a2ef3..78eae86e81 100644
|
|
--- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorDigestRule.java
|
|
+++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorDigestRule.java
|
|
@@ -4,40 +4,41 @@
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
package org.hyperledger.besu.consensus.qbft.headervalidationrules;
|
|
|
|
import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec;
|
|
import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
import org.hyperledger.besu.consensus.common.bft.PqAnchorLapse;
|
|
import org.hyperledger.besu.consensus.common.bft.PqAnchorV2;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorV3;
|
|
import org.hyperledger.besu.consensus.common.bft.SchemeSeal;
|
|
import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec;
|
|
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
import org.hyperledger.besu.ethereum.mainnet.DetachedBlockHeaderValidationRule;
|
|
|
|
import java.util.List;
|
|
|
|
import org.apache.tuweni.bytes.Bytes;
|
|
import org.apache.tuweni.bytes.Bytes32;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
/**
|
|
* R1: the anchor DIGEST rule. DETACHED, and deliberately part of LIGHT validation.
|
|
*
|
|
* <p>This rule is the whole point of the V2 scheme. It is what makes the sentence "the post-quantum
|
|
* signature protects the block" true rather than decorative: the block's own vanityData, which IS in
|
|
* the block-hash pre-image, carries the digest of the certificate the block carries for its parent.
|
|
* Strip the certificate, swap it for a different but equally valid one, or reorder it, and the digest
|
|
* no longer matches and the header is refused.
|
|
@@ -69,112 +70,157 @@ import org.slf4j.LoggerFactory;
|
|
* DownloadHeadersStep} now applying the same validation policy to OPEN-ENDED ranges that it already
|
|
* applied to closed ones, and {@link PqAnchorDigestAttachedRule}, which carries the identical verdict
|
|
* on the ATTACHED side so that it survives {@code SKIP_DETACHED} at import. Before those two existed
|
|
* an honest node with its data directory deleted imported stripped-certificate headers in silence and
|
|
* reached head 350 with ZERO occurrences of this rule. [MEASURED:
|
|
* {@code dovezi-sincronizare-2026-08-02/evidence/OBS-BEFORE.txt}; and the negative control
|
|
* {@code OBS-CONTROL-STUBBED.txt} reproduces exactly that silence once the two guards are stubbed.]
|
|
*
|
|
* <p><b>includeInLightValidation, measured.</b> Both {@code DetachedBlockHeaderValidationRule} and
|
|
* {@code AttachedBlockHeaderValidationRule} declare {@code includeInLightValidation()} with a DEFAULT
|
|
* of {@code true}. {@code BlockHeaderValidator.Builder.addRule(DetachedBlockHeaderValidationRule)}
|
|
* snapshots that value at build time into the wrapping {@code Rule}, and the modes {@code
|
|
* LIGHT_DETACHED_ONLY}, {@code LIGHT} and {@code DETACHED_ONLY} all admit a detached rule whose flag
|
|
* is true. This rule overrides the method anyway, explicitly returning true, so the property is
|
|
* asserted by this file rather than inherited silently from an upstream default that a Besu rebase
|
|
* could change under us.
|
|
*
|
|
* <p><b>Inactive below H.</b> The height gate is the FIRST statement, before any decode. Below H this
|
|
* rule does not even parse the header, so a binary carrying it behaves exactly as today on the whole
|
|
* existing chain. That is the condition under which such a binary can be warmed on a live node.
|
|
+ * CORRECTED 2026-10-01 (1(b)): one structural look now comes before the gate, at every height: does
|
|
+ * element 6 open with the v3 version scalar? A binary without v3 refused such bytes everywhere, at the
|
|
+ * decode, so refusing them wherever the form is not v3 is what keeps the verdict of today on every
|
|
+ * header; no real header carries one, and nothing else is decoded.
|
|
*
|
|
* <p><b>Fail-closed above H.</b> At or above H, anything that prevents the digest from being computed
|
|
* and matched is a REJECT: a non-canonical or undecodable extraData, a vanity field that is not 32
|
|
* bytes, a certificate whose indices are not strictly increasing, or a mismatching digest. Never an
|
|
* implicit accept, and specifically never "true on exception", which is the defect that made the
|
|
* legacy {@code FalconSealValidationRule} unable to catch anything.
|
|
*
|
|
* <p>The residual exposure this does NOT close, stated plainly: the certificate is outside the
|
|
* block-hash pre-image, so a hostile peer can serve a header with the certificate mangled and that
|
|
* header becomes unimportable although its block hash is unchanged. That is denial of service at
|
|
* header service, not forgery, and it is the same exposure the ECDSA committed seals already carry
|
|
* today.
|
|
*/
|
|
public class PqAnchorDigestRule implements DetachedBlockHeaderValidationRule {
|
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(PqAnchorDigestRule.class);
|
|
|
|
private final PqAnchorConfig config;
|
|
private final QbftExtraDataCodec extraDataCodec = new QbftExtraDataCodec();
|
|
|
|
/**
|
|
* Instantiates the anchor digest rule.
|
|
*
|
|
* @param config the height-indexed activation configuration
|
|
*/
|
|
public PqAnchorDigestRule(final PqAnchorConfig config) {
|
|
this.config = config;
|
|
}
|
|
|
|
@Override
|
|
public boolean validate(final BlockHeader header, final BlockHeader parent) {
|
|
final long number = header.getNumber();
|
|
|
|
+ // AERE 1(b) (2026-10-01): A v3 CERTIFICATE IS VALID ONLY AT A v3 ANCHOR HEIGHT, and this is asked at EVERY height,
|
|
+ // BEFORE the height gate. Why here and not only below: a binary without v3 refused such bytes everywhere, at the
|
|
+ // decode, while this codec decodes them; without this line a v3 element 6 at a non-anchor height, below H, or in a
|
|
+ // lapse window would be accepted by the new binary and refused by the old one, a fork during a rolling deployment
|
|
+ // (found by the adversarial review of step 3). The cost is one structural look at element 6, nothing decoded. Inert
|
|
+ // only on a node under the emergency brake, where every anchor rule is inert by design and the brake is uniform.
|
|
+ if (!config.disabled()
|
|
+ && config.certificateFormAt(number) != PqAnchorConfig.CertificateForm.V3
|
|
+ && QbftExtraDataCodec.carriesV3Certificate(header.getExtraData())) {
|
|
+ LOG.warn(
|
|
+ "AERE PQ ANCHOR (R1): block {} REJECTED - {}: carries a v3 certificate where the form is {} (H_r={}).",
|
|
+ number,
|
|
+ PqAnchorV3.V3_01,
|
|
+ config.certificateFormAt(number),
|
|
+ config.commitRoundBlock() == PqAnchorConfig.NEVER ? "unset" : config.commitRoundBlock());
|
|
+ return false;
|
|
+ }
|
|
+
|
|
// HEIGHT GATE FIRST. Below H nothing at all happens: no decode, no allocation, no log. This is
|
|
// the property that lets a binary built from this code run on a live node before activation and
|
|
// behave bit-for-bit as today. From 2026-08-07 the gate also covers the interval: at a height
|
|
// that carries no certificate there is nothing to bind, so there is nothing to judge.
|
|
//
|
|
// THE SAME METHOD AS R2, and not two questions that merely resemble each other. See the note in
|
|
// PqAnchorSealsRule.
|
|
if (!config.anchorAppliesAt(number)) {
|
|
return true;
|
|
}
|
|
|
|
// SECOND GATE: the named historical windows in which these rules were not in force. Inside one
|
|
// of them vanityData carries the client's version string rather than a digest, so there is no
|
|
// digest to match and no recomputation can produce one; refusing would stop this node forever
|
|
// at a height the whole network holds. See PqAnchorLapse for what happened, how the bounds were
|
|
// measured, and why an exception written anywhere other than validation moves the error instead
|
|
// of ending it.
|
|
- if (PqAnchorLapse.isDisarmed(config.chainId(), number)) {
|
|
+ // AERE 1(b): the form this height demands, from the ONE method R2, the producer and decidedBy ask.
|
|
+ // The lapse windows are all historical, below any H_r: they never apply to a v3 height.
|
|
+ final PqAnchorConfig.CertificateForm form = config.certificateFormAt(number);
|
|
+ if (form != PqAnchorConfig.CertificateForm.V3
|
|
+ && PqAnchorLapse.isDisarmed(config.chainId(), number)) {
|
|
return acceptAsWrittenInsideLapse(header, number);
|
|
}
|
|
|
|
try {
|
|
final BftExtraData extraData = extraDataCodec.decodeRaw(header.getExtraData());
|
|
|
|
final Bytes vanity = extraData.getVanityData();
|
|
if (vanity.size() != BftExtraDataCodec.EXTRA_VANITY_LENGTH) {
|
|
LOG.warn(
|
|
"AERE PQ ANCHOR (R1): block {} REJECTED - vanityData is {} bytes, expected {}. From H "
|
|
+ "the whole vanity field is the anchor digest D.",
|
|
number,
|
|
vanity.size(),
|
|
BftExtraDataCodec.EXTRA_VANITY_LENGTH);
|
|
return false;
|
|
}
|
|
|
|
+ // AERE 1(b) (2026-10-01): the v3 form, both directions (01: a v3 below H_r; 02: no v3 from H_r),
|
|
+ // the shape (03) and D3 (04), judged by the one pure function the producer's self-check uses.
|
|
+ final PqAnchorV3.Verdict v3 =
|
|
+ PqAnchorV3.judgeForm(
|
|
+ form,
|
|
+ extraData.getCertificateRound(),
|
|
+ extraData.getHybridSeals(),
|
|
+ vanity,
|
|
+ config.chainId(),
|
|
+ number,
|
|
+ header.getParentHash().getBytes());
|
|
+ if (!v3.accepted()) {
|
|
+ LOG.warn("AERE PQ ANCHOR (R1): block {} REJECTED - {}", number, v3.describe());
|
|
+ return false;
|
|
+ }
|
|
+ if (form == PqAnchorConfig.CertificateForm.V3) {
|
|
+ return true;
|
|
+ }
|
|
+
|
|
// AERE ANCHOR V2 (2026-09-03): from the v2 height the ONLY accepted form is the scheme-tagged
|
|
// certificate under the v2 digest; below it a v2 certificate is refused. Both directions
|
|
// are checked so the switch is a clean fork and never a header two nodes read differently.
|
|
- if (config.anchorV2AppliesAt(number)) {
|
|
+ if (form == PqAnchorConfig.CertificateForm.V2) {
|
|
return judgeV2(number, header, extraData, vanity);
|
|
}
|
|
if (!extraData.getHybridSeals().isEmpty()) {
|
|
LOG.warn(
|
|
"AERE PQ ANCHOR (R1): block {} REJECTED - carries a v2 (scheme-tagged) certificate below"
|
|
+ " the v2 activation height {}.",
|
|
number,
|
|
config.anchorV2Block());
|
|
return false;
|
|
}
|
|
final List<FalconSeal> certificate = List.copyOf(extraData.getFalconSeals());
|
|
// Height aware since 2026-08-11. Inside the one measured historical window the ordering
|
|
// requirement relaxes from SORTED to DISTINCT, because 36 canonical headers were written
|
|
// unsorted during a production interruption and a node syncing from genesis would otherwise
|
|
// stop at the first of them and never pass it. Distinctness is not relaxed at any height, so a
|
|
// repeated index stays unrepresentable everywhere. See PqAnchor.hasAcceptableIndices.
|
|
if (!PqAnchor.hasAcceptableIndices(config.chainId(), certificate, number)) {
|
|
// Checked HERE, not only in the seals rule, so reordering and duplicate indices are caught
|
|
// in LIGHT validation too, and so that "the order given" and "sorted" are the same list for
|
|
// every header this rule accepts.
|
|
diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorSealsRule.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorSealsRule.java
|
|
index 3f58217d1f..9f316aefd1 100644
|
|
--- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorSealsRule.java
|
|
+++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorSealsRule.java
|
|
@@ -8,40 +8,42 @@
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
package org.hyperledger.besu.consensus.qbft.headervalidationrules;
|
|
|
|
import org.hyperledger.besu.consensus.common.bft.AerePqIdentity;
|
|
import org.hyperledger.besu.consensus.common.bft.BftContext;
|
|
import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
import org.hyperledger.besu.consensus.common.bft.FalconSealSupport;
|
|
import org.hyperledger.besu.consensus.common.bft.HybridSealSupport;
|
|
import org.hyperledger.besu.consensus.common.bft.HybridSignerRegistry;
|
|
import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
import org.hyperledger.besu.consensus.common.bft.PqAnchorLapse;
|
|
import org.hyperledger.besu.consensus.common.bft.PqAnchorV2;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorV3;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
import org.hyperledger.besu.consensus.common.bft.PqSignerRegistry;
|
|
import org.hyperledger.besu.consensus.common.bft.SchemeSeal;
|
|
import org.hyperledger.besu.consensus.common.bft.SealScheme;
|
|
import org.hyperledger.besu.consensus.common.bft.SealSchemes;
|
|
import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec;
|
|
import org.hyperledger.besu.datatypes.Address;
|
|
import org.hyperledger.besu.ethereum.ProtocolContext;
|
|
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
import org.hyperledger.besu.ethereum.mainnet.AttachedBlockHeaderValidationRule;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.Map;
|
|
import java.util.Optional;
|
|
import java.util.List;
|
|
import java.util.OptionalInt;
|
|
import java.util.Set;
|
|
|
|
@@ -126,81 +128,97 @@ public class PqAnchorSealsRule implements AttachedBlockHeaderValidationRule {
|
|
public boolean validate(
|
|
final BlockHeader header, final BlockHeader parent, final ProtocolContext protocolContext) {
|
|
final long number = header.getNumber();
|
|
|
|
// HEIGHT GATE FIRST, same contract as R1: below H this rule does nothing at all, and from
|
|
// 2026-08-07 it also does nothing at a height that carries no certificate.
|
|
//
|
|
// BOTH RULES ASK THE SAME QUESTION, THROUGH THE SAME METHOD, and that is deliberate.
|
|
// anchorAppliesAt() = activeAt() AND isAnchorHeight(). If R1 and R2 each asked it their own
|
|
// way, a header accepted by one and refused by the other would be a chain break, appearing at
|
|
// exactly the first height that is not an anchor height, i.e. the day after activation.
|
|
if (!config.anchorAppliesAt(number)) {
|
|
return true;
|
|
}
|
|
|
|
// SECOND GATE, and the SAME method R1 asks, for the same reason both rules share
|
|
// anchorAppliesAt: if the two rules each decided this boundary their own way, a header accepted
|
|
// by one and refused by the other would be a chain break. Inside a named window the threshold
|
|
// was not in force when the header was written and the indices were written in arrival order,
|
|
// so neither can be required of it now.
|
|
- if (PqAnchorLapse.isDisarmed(config.chainId(), number)) {
|
|
+ // AERE 1(b): the lapse windows are all historical, below any H_r; they never apply to a v3 height
|
|
+ final PqAnchorConfig.CertificateForm form = config.certificateFormAt(number);
|
|
+ if (form != PqAnchorConfig.CertificateForm.V3
|
|
+ && PqAnchorLapse.isDisarmed(config.chainId(), number)) {
|
|
return acceptAsWrittenInsideLapse(header, number);
|
|
}
|
|
|
|
try {
|
|
if (parent == null) {
|
|
LOG.warn(
|
|
"AERE PQ ANCHOR (R2): block {} REJECTED - no parent header available, so the "
|
|
+ "certificate cannot be checked against the parent it claims to attest to.",
|
|
number);
|
|
return false;
|
|
}
|
|
// The certificate attests to the parent by NUMBER and HASH, and R1 has already bound the
|
|
// digest to header.getParentHash(). If the parent handed to this rule were a different header,
|
|
// R1 and R2 would be talking about two different objects. Cheap, and it removes any dependence
|
|
// on rule ordering with AncestryValidationRule.
|
|
if (!parent.getHash().equals(header.getParentHash())
|
|
|| parent.getNumber() != number - 1L) {
|
|
LOG.warn(
|
|
"AERE PQ ANCHOR (R2): block {} REJECTED - the supplied parent (number {}, hash {}) is "
|
|
+ "not the parent this header names (number {}, hash {}).",
|
|
number,
|
|
parent.getNumber(),
|
|
parent.getHash(),
|
|
number - 1L,
|
|
header.getParentHash());
|
|
return false;
|
|
}
|
|
|
|
// AERE D-078 (2026-08-02). DIAGNOSTIC ONLY, and deliberately before every early return below
|
|
// so it runs at every height from H, including the warm-up where K is 0 and the certificate is
|
|
// empty. It feeds FalconSealSupport's registry-coverage report, whose only previous source was
|
|
// FalconSealValidationRule - a rule that stands down at exactly the height THIS rule takes
|
|
// over. Above H nothing updated it, so the coverage report was either frozen at a set from
|
|
// below H or, on a node whose process started above H, never set at all. Nothing here can
|
|
// change this rule's verdict: the call cannot throw and its result is not read.
|
|
observeValidatorsForDiagnostics(parent, protocolContext);
|
|
|
|
final BftExtraData extraData = extraDataCodec.decodeRaw(header.getExtraData());
|
|
+ // AERE 1(b) (2026-10-01): the v3 form. A v3 below H_r is refused here too (R1 refuses it first,
|
|
+ // with the same code), so the two rules never read one header two ways.
|
|
+ if (form == PqAnchorConfig.CertificateForm.V3) {
|
|
+ return judgeV3(number, parent, extraData, protocolContext);
|
|
+ }
|
|
+ if (extraData.getCertificateRound().isPresent()) {
|
|
+ LOG.warn(
|
|
+ "AERE PQ ANCHOR (R2): block {} REJECTED - {}: carries a v3 certificate below H_r ({}).",
|
|
+ number,
|
|
+ PqAnchorV3.V3_01,
|
|
+ config.commitRoundBlock() == PqAnchorConfig.NEVER ? "unset" : config.commitRoundBlock());
|
|
+ return false;
|
|
+ }
|
|
// AERE ANCHOR V2 (2026-09-03): one form per height, both directions refused (see R1).
|
|
- if (config.anchorV2AppliesAt(number)) {
|
|
+ if (form == PqAnchorConfig.CertificateForm.V2) {
|
|
return judgeV2(number, parent, extraData, protocolContext);
|
|
}
|
|
if (!extraData.getHybridSeals().isEmpty()) {
|
|
LOG.warn(
|
|
"AERE PQ ANCHOR (R2): block {} REJECTED - carries a v2 (scheme-tagged) certificate below"
|
|
+ " the v2 activation height {}.",
|
|
number,
|
|
config.anchorV2Block());
|
|
return false;
|
|
}
|
|
final List<FalconSeal> certificate = List.copyOf(extraData.getFalconSeals());
|
|
final int k = certificate.size();
|
|
|
|
// THE THRESHOLD THIS HEIGHT WAS ACTUALLY JUDGED BY. Normally the configured schedule. Inside
|
|
// a named historical range it is the LOWER of the schedule and the emergency ceiling that was
|
|
// in force when these headers were written, which is the same lever the fleet itself used at
|
|
// the time, replayed from a fixed range instead of from a runtime option. Asking a header for
|
|
// more than was asked of the proposer that wrote it refuses history that no node can
|
|
// reproduce; asking for the ceiling rather than for nothing keeps the strongest claim the
|
|
// range supports, and the ceiling is a measured floor, never zero. See PqAnchorLapse.
|
|
@@ -246,43 +264,42 @@ public class PqAnchorSealsRule implements AttachedBlockHeaderValidationRule {
|
|
LOG.debug(
|
|
"AERE PQ ANCHOR (R2): block {} carries an empty certificate and K={} at this height.",
|
|
number,
|
|
required);
|
|
return true;
|
|
}
|
|
|
|
final BftContext bftContext = protocolContext.getConsensusContext(BftContext.class);
|
|
final Collection<Address> parentValidators =
|
|
bftContext.getValidatorProvider().getValidatorsForBlock(parent);
|
|
if (parentValidators == null || parentValidators.isEmpty()) {
|
|
LOG.warn(
|
|
"AERE PQ ANCHOR (R2): block {} REJECTED - the validator set of the parent block {} "
|
|
+ "could not be resolved, so seal eligibility cannot be decided.",
|
|
number,
|
|
parent.getNumber());
|
|
return false;
|
|
}
|
|
final Set<Address> eligible = new HashSet<>(parentValidators);
|
|
|
|
- final Bytes32 message =
|
|
- PqAnchor.commitMessage(
|
|
- config.chainId(), parent.getNumber(), parent.getHash().getBytes());
|
|
+ // 1(b): through the one place; below H_r this is COMMIT-1, byte for byte
|
|
+ final Bytes32 message = roundFreeMessage(parent);
|
|
|
|
if (!falconSealsVerify(number, parent, eligible, message, certificate)) {
|
|
return false;
|
|
}
|
|
LOG.debug(
|
|
"AERE PQ ANCHOR (R2): block {} accepted with {} verified Falcon seal(s) over parent {} "
|
|
+ "(threshold K={}, |parent validators|={}).",
|
|
number,
|
|
k,
|
|
parent.getNumber(),
|
|
required,
|
|
eligible.size());
|
|
return true;
|
|
} catch (final Exception e) {
|
|
LOG.warn(
|
|
"AERE PQ ANCHOR (R2): block {} REJECTED - the certificate could not be checked: {}",
|
|
number,
|
|
e.toString());
|
|
return false;
|
|
}
|
|
@@ -401,42 +418,42 @@ public class PqAnchorSealsRule implements AttachedBlockHeaderValidationRule {
|
|
LOG.warn(
|
|
"AERE PQ ANCHOR (R2): block {} REJECTED - the v2 certificate has {} Falcon seal(s), below"
|
|
+ " the threshold K={} in force at this height.",
|
|
number,
|
|
falcon.size(),
|
|
required);
|
|
return false;
|
|
}
|
|
final BftContext bftContext = protocolContext.getConsensusContext(BftContext.class);
|
|
final Collection<Address> parentValidators =
|
|
bftContext.getValidatorProvider().getValidatorsForBlock(parent);
|
|
if (parentValidators == null || parentValidators.isEmpty()) {
|
|
LOG.warn(
|
|
"AERE PQ ANCHOR (R2): block {} REJECTED - the validator set of the parent block {} could"
|
|
+ " not be resolved, so seal eligibility cannot be decided.",
|
|
number,
|
|
parent.getNumber());
|
|
return false;
|
|
}
|
|
final Set<Address> eligible = new HashSet<>(parentValidators);
|
|
- final Bytes32 message =
|
|
- PqAnchor.commitMessage(config.chainId(), parent.getNumber(), parent.getHash().getBytes());
|
|
+ // 1(b): through the one place; below H_r this is COMMIT-1, byte for byte
|
|
+ final Bytes32 message = roundFreeMessage(parent);
|
|
if (!falcon.isEmpty() && !falconSealsVerify(number, parent, eligible, message, falcon)) {
|
|
return false;
|
|
}
|
|
final HybridSealSupport hybrid = HybridSealSupport.instance();
|
|
// Two sets, and they differ only with per-scheme intervals (AIP-22 stage 2). NAMED: every scheme
|
|
// the step at the parent height names; a seal of any other scheme is refused as today. REQUIRED:
|
|
// the named schemes whose grid THIS anchor height sits on, counted from the chain's anchor
|
|
// activation height; each must reach K. A seal of a named-but-not-required scheme is a surplus:
|
|
// verified and counted like any surplus seal, never ignored, never a reason to refuse.
|
|
final Set<String> namedSchemes = new HashSet<>();
|
|
final Set<String> requiredSchemes = new HashSet<>();
|
|
hybrid
|
|
.schedule()
|
|
.ifPresent(
|
|
sch -> {
|
|
namedSchemes.addAll(sch.schemesAt(parent.getNumber()));
|
|
requiredSchemes.addAll(sch.schemesRequiredForAnchor(number, config.anchorBlock()));
|
|
});
|
|
namedSchemes.remove(SealSchemes.FALCON_512.id());
|
|
requiredSchemes.remove(SealSchemes.FALCON_512.id());
|
|
@@ -509,40 +526,129 @@ public class PqAnchorSealsRule implements AttachedBlockHeaderValidationRule {
|
|
"AERE PQ ANCHOR (R2): block {} REJECTED - the v2 certificate has {} valid {} seal(s), below"
|
|
+ " the threshold K={} the schedule demands of every named scheme.",
|
|
number,
|
|
have,
|
|
schemeId,
|
|
required);
|
|
return false;
|
|
}
|
|
}
|
|
LOG.debug(
|
|
"AERE PQ ANCHOR (R2): block {} accepted with a {}-seal scheme-tagged certificate over parent"
|
|
+ " {} (K={} per scheme, schemes={}).",
|
|
number,
|
|
seals.size(),
|
|
parent.getNumber(),
|
|
required,
|
|
requiredSchemes);
|
|
return true;
|
|
}
|
|
|
|
+ /**
|
|
+ * The message a v1 or v2 certificate's seals sign (COMMIT-1 over the parent), from the one place.
|
|
+ * Only reached at v1/v2 anchors, whose parent is in the round-free anchor form; an empty answer
|
|
+ * there would be a configuration this rule cannot judge, and it refuses (fail closed) by throwing
|
|
+ * into the rule's own catch.
|
|
+ */
|
|
+ private Bytes32 roundFreeMessage(final BlockHeader parent) {
|
|
+ return PqAnchorProducer.anchorSealMessage(
|
|
+ config, parent.getNumber(), parent.getHash().getBytes(), 0)
|
|
+ .orElseThrow(
|
|
+ () ->
|
|
+ new IllegalStateException(
|
|
+ "no anchor-form commit message for parent " + parent.getNumber()));
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * AERE 1(b) (2026-10-01): R2 for the v3 (one-round) certificate, through {@link
|
|
+ * PqAnchorV3#judgeSeals}, the same pure function the producer's self-check and decidedBy call. R2
|
|
+ * demands K_eff from the schedule (decision H6: not Q; Q is asked by the consumers that claim
|
|
+ * "decided"). The empty v3 is valid only where K_eff = 0 (H5). The round is not compared with
|
|
+ * element 3 of the parent or of this header: it is bound by the message (M_r).
|
|
+ */
|
|
+ private boolean judgeV3(
|
|
+ final long number,
|
|
+ final BlockHeader parent,
|
|
+ final BftExtraData extraData,
|
|
+ final ProtocolContext protocolContext) {
|
|
+ if (extraData.getCertificateRound().isEmpty()) {
|
|
+ LOG.warn(
|
|
+ "AERE PQ ANCHOR (R2): block {} REJECTED - {}: at or above H_r={} the header carries no v3"
|
|
+ + " certificate.",
|
|
+ number,
|
|
+ PqAnchorV3.V3_02,
|
|
+ config.commitRoundBlock());
|
|
+ return false;
|
|
+ }
|
|
+ final PqAnchorV3.Certificate certificate =
|
|
+ new PqAnchorV3.Certificate(
|
|
+ extraData.getCertificateRound().getAsInt(), extraData.getHybridSeals());
|
|
+ final HybridSealSupport hybrid = HybridSealSupport.instance();
|
|
+ final Set<String> namedSchemes = new HashSet<>();
|
|
+ final Set<String> requiredSchemes = new HashSet<>();
|
|
+ hybrid
|
|
+ .schedule()
|
|
+ .ifPresent(
|
|
+ sch -> {
|
|
+ namedSchemes.addAll(sch.schemesAt(parent.getNumber()));
|
|
+ requiredSchemes.addAll(sch.schemesRequiredForAnchor(number, config.anchorBlock()));
|
|
+ });
|
|
+ namedSchemes.remove(SealSchemes.FALCON_512.id());
|
|
+ requiredSchemes.remove(SealSchemes.FALCON_512.id());
|
|
+ final long p = parent.getNumber();
|
|
+ // D2: the HISTORY doors at the parent's height, as in v1 and v2; one factory shared with the producer's
|
|
+ // self-check and with decidedBy (1(b), review of step 4)
|
|
+ final PqAnchorV3.Signers signers =
|
|
+ PqAnchorV3.historicSigners(
|
|
+ registry,
|
|
+ p,
|
|
+ () ->
|
|
+ protocolContext
|
|
+ .getConsensusContext(BftContext.class)
|
|
+ .getValidatorProvider()
|
|
+ .getValidatorsForBlock(parent));
|
|
+ final PqAnchorV3.Verdict verdict =
|
|
+ PqAnchorV3.judgeSeals(
|
|
+ config,
|
|
+ number,
|
|
+ parent.getHash().getBytes(),
|
|
+ certificate,
|
|
+ config.minSealsAt(number),
|
|
+ namedSchemes,
|
|
+ requiredSchemes,
|
|
+ signers);
|
|
+ if (!verdict.accepted()) {
|
|
+ LOG.warn("AERE PQ ANCHOR (R2): block {} REJECTED - {}", number, verdict.describe());
|
|
+ return false;
|
|
+ }
|
|
+ LOG.debug(
|
|
+ "AERE PQ ANCHOR (R2): block {} accepted with a v3 certificate of round {} over parent {}"
|
|
+ + " ({} verified Falcon member(s), K={}, schemes={}).",
|
|
+ number,
|
|
+ certificate.round(),
|
|
+ p,
|
|
+ verdict.falconMembers(),
|
|
+ config.minSealsAt(number),
|
|
+ requiredSchemes);
|
|
+ return true;
|
|
+ }
|
|
+
|
|
private boolean acceptAsWrittenInsideLapse(final BlockHeader header, final long number) {
|
|
try {
|
|
final BftExtraData extraData = extraDataCodec.decodeRaw(header.getExtraData());
|
|
final List<FalconSeal> certificate = List.copyOf(extraData.getFalconSeals());
|
|
if (!PqAnchor.hasDistinctNonNegativeIndices(certificate)) {
|
|
LOG.warn(
|
|
"AERE PQ ANCHOR (R2): block {} REJECTED - it falls inside the historical range {} in "
|
|
+ "which the anchor rules were not in force, but its certificate repeats a "
|
|
+ "validator index or carries a negative one, which no header of that range does.",
|
|
number,
|
|
PqAnchorLapse.windowCovering(config.chainId(), number).orElse(null));
|
|
return false;
|
|
}
|
|
LOG.debug(
|
|
"AERE PQ ANCHOR (R2): block {} accepted as written with {} seal(s); it falls inside the "
|
|
+ "historical range {} in which neither the threshold nor the ordering was in force.",
|
|
number,
|
|
certificate.size(),
|
|
PqAnchorLapse.windowCovering(config.chainId(), number).orElse(null));
|
|
return true;
|
|
diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/AereGetPqFinality.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/AereGetPqFinality.java
|
|
index 7fc5d24a5e..d693a8c223 100755
|
|
--- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/AereGetPqFinality.java
|
|
+++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/AereGetPqFinality.java
|
|
@@ -79,126 +79,228 @@ public class AereGetPqFinality extends AbstractBlockParameterMethod {
|
|
* @param message the message that was signed
|
|
* @param signature the Falcon signature
|
|
* @return true iff it verifies against the key bound at that height
|
|
*/
|
|
boolean verify(long blockNumber, int validatorIndex, Bytes message, Bytes signature);
|
|
}
|
|
|
|
/** Rebuilds the message the seals of a block signed, when that is possible from the header. */
|
|
@FunctionalInterface
|
|
public interface MessageBuilder {
|
|
/**
|
|
* The signed message.
|
|
*
|
|
* @param blockNumber the height
|
|
* @param onchainHash the round-independent on-chain hash
|
|
* @return the message, or empty when the form at that height cannot be rebuilt from the header
|
|
*/
|
|
Optional<Bytes> messageFor(long blockNumber, Hash onchainHash);
|
|
}
|
|
|
|
+ /**
|
|
+ * 1(b) (2026-10-01): rebuilds the message the seals of a block signed IN A ROUND, from H_r - 1 (M_r).
|
|
+ */
|
|
+ @FunctionalInterface
|
|
+ public interface RoundMessageBuilder {
|
|
+ /**
|
|
+ * The signed message of round r.
|
|
+ *
|
|
+ * @param blockNumber the height
|
|
+ * @param onchainHash the round-independent on-chain hash
|
|
+ * @param round the round
|
|
+ * @return the message, or empty when none exists for that round
|
|
+ */
|
|
+ Optional<Bytes> messageFor(long blockNumber, Hash onchainHash, int round);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * 1(b), review of step 4 (2026-10-01): the member the registry binds an index to at a height (the HISTORY door), so
|
|
+ * that from H_r - 1 a round counts distinct eligible members, not indices.
|
|
+ */
|
|
+ @FunctionalInterface
|
|
+ public interface MemberResolver {
|
|
+ /**
|
|
+ * The member bound to this index.
|
|
+ *
|
|
+ * @param blockNumber the height
|
|
+ * @param validatorIndex the registry index
|
|
+ * @return the member, or null when the index is bound to nobody
|
|
+ */
|
|
+ org.hyperledger.besu.datatypes.Address memberAt(long blockNumber, int validatorIndex);
|
|
+ }
|
|
+
|
|
private final ValidatorProvider validatorProvider;
|
|
private final PqSealCache cache;
|
|
private final SealVerifier verifier;
|
|
private final MessageBuilder messageBuilder;
|
|
+ private final RoundMessageBuilder roundMessageBuilder;
|
|
+ private final MemberResolver memberResolver;
|
|
|
|
/**
|
|
* Production wiring: the process-wide seal cache, the anchored Falcon registry at the block's
|
|
* height, and the anchor-form commit message.
|
|
*
|
|
* @param blockchainQueries the blockchain queries
|
|
* @param validatorProvider the read-only validator provider
|
|
*/
|
|
public AereGetPqFinality(
|
|
final BlockchainQueries blockchainQueries, final ValidatorProvider validatorProvider) {
|
|
this(
|
|
blockchainQueries,
|
|
validatorProvider,
|
|
PqSealCache.instance(),
|
|
(n, i, m, s) -> PqSignerRegistry.falconSealSupport().verifyAtHistoric(n, i, m, s),
|
|
+ // 1(b) (2026-10-01): through the one place. Below H_r COMMIT-1 exactly as before (ROUND_FREE: the round is
|
|
+ // ignored), empty below the anchor form, as before; from H_r - 1 this record is not used (the per-round
|
|
+ // record below is, with M_r of each round from the same place)
|
|
(n, h) ->
|
|
- PqAnchorProducer.sealMessageIsAnchorForm(n)
|
|
- ? Optional.of(PqAnchorProducer.commitSealMessage(n, h.getBytes(), Hash.ZERO))
|
|
- : Optional.empty());
|
|
+ PqAnchorProducer.commitSealFormAt(PqAnchorProducer.config(), n)
|
|
+ == PqAnchorProducer.CommitSealForm.ROUND_FREE
|
|
+ ? PqAnchorProducer.anchorSealMessage(PqAnchorProducer.config(), n, h.getBytes(), 0)
|
|
+ .<Bytes>map(m -> m)
|
|
+ : Optional.empty(),
|
|
+ (n, h, r) ->
|
|
+ PqAnchorProducer.anchorSealMessage(PqAnchorProducer.config(), n, h.getBytes(), r)
|
|
+ .<Bytes>map(m -> m));
|
|
}
|
|
|
|
/**
|
|
* Full wiring, for tests.
|
|
*
|
|
* @param blockchainQueries the blockchain queries
|
|
* @param validatorProvider the validator provider
|
|
* @param cache the seal cache to read
|
|
* @param verifier the seal verifier
|
|
* @param messageBuilder the signed-message builder
|
|
*/
|
|
public AereGetPqFinality(
|
|
final BlockchainQueries blockchainQueries,
|
|
final ValidatorProvider validatorProvider,
|
|
final PqSealCache cache,
|
|
final SealVerifier verifier,
|
|
final MessageBuilder messageBuilder) {
|
|
+ this(blockchainQueries, validatorProvider, cache, verifier, messageBuilder, (n, h, r) -> messageBuilder.messageFor(n, h));
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Full wiring with the per-round message (1(b)), for tests.
|
|
+ *
|
|
+ * @param blockchainQueries the blockchain queries
|
|
+ * @param validatorProvider the validator provider
|
|
+ * @param cache the seal cache to read
|
|
+ * @param verifier the seal verifier
|
|
+ * @param messageBuilder the signed-message builder below H_r
|
|
+ * @param roundMessageBuilder the signed-message builder of a round, from H_r - 1
|
|
+ */
|
|
+ public AereGetPqFinality(
|
|
+ final BlockchainQueries blockchainQueries,
|
|
+ final ValidatorProvider validatorProvider,
|
|
+ final PqSealCache cache,
|
|
+ final SealVerifier verifier,
|
|
+ final MessageBuilder messageBuilder,
|
|
+ final RoundMessageBuilder roundMessageBuilder) {
|
|
+ this(
|
|
+ blockchainQueries,
|
|
+ validatorProvider,
|
|
+ cache,
|
|
+ verifier,
|
|
+ messageBuilder,
|
|
+ roundMessageBuilder,
|
|
+ (n, i) -> PqSignerRegistry.falconSealSupport().addressForIndexAtHistoric(n, i));
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Full wiring with the per-round message and the member door (1(b)), for tests.
|
|
+ *
|
|
+ * @param blockchainQueries the blockchain queries
|
|
+ * @param validatorProvider the validator provider
|
|
+ * @param cache the seal cache to read
|
|
+ * @param verifier the seal verifier
|
|
+ * @param messageBuilder the signed-message builder below H_r
|
|
+ * @param roundMessageBuilder the signed-message builder of a round, from H_r - 1
|
|
+ * @param memberResolver the member an index is bound to, from H_r - 1
|
|
+ */
|
|
+ public AereGetPqFinality(
|
|
+ final BlockchainQueries blockchainQueries,
|
|
+ final ValidatorProvider validatorProvider,
|
|
+ final PqSealCache cache,
|
|
+ final SealVerifier verifier,
|
|
+ final MessageBuilder messageBuilder,
|
|
+ final RoundMessageBuilder roundMessageBuilder,
|
|
+ final MemberResolver memberResolver) {
|
|
super(blockchainQueries);
|
|
this.validatorProvider = validatorProvider;
|
|
this.cache = cache;
|
|
this.verifier = verifier;
|
|
this.messageBuilder = messageBuilder;
|
|
+ this.roundMessageBuilder = roundMessageBuilder;
|
|
+ this.memberResolver = memberResolver;
|
|
}
|
|
|
|
@Override
|
|
public String getName() {
|
|
return RpcMethod.AERE_GET_PQ_FINALITY.getMethodName();
|
|
}
|
|
|
|
@Override
|
|
protected BlockParameter blockParameter(final JsonRpcRequestContext request) {
|
|
try {
|
|
return request.getOptionalParameter(0, BlockParameter.class).orElse(BlockParameter.LATEST);
|
|
} catch (final JsonRpcParameterException e) {
|
|
throw new InvalidJsonRpcParameters(
|
|
"Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected Object pendingResult(final JsonRpcRequestContext request) {
|
|
return describe(getBlockchainQueries().headBlockHeader());
|
|
}
|
|
|
|
@Override
|
|
protected Object resultByBlockNumber(final JsonRpcRequestContext request, final long blockNumber) {
|
|
return getBlockchainQueries().getBlockHeaderByNumber(blockNumber).map(this::describe).orElse(null);
|
|
}
|
|
|
|
/**
|
|
* The finality record of one block.
|
|
*
|
|
* @param header the block's header
|
|
* @return the JSON-shaped record
|
|
*/
|
|
public Map<String, Object> describe(final BlockHeader header) {
|
|
final long number = header.getNumber();
|
|
final Hash hash = header.getHash();
|
|
- final int validators = validatorProvider.getValidatorsForBlock(header).size();
|
|
+ final java.util.Collection<org.hyperledger.besu.datatypes.Address> set =
|
|
+ validatorProvider.getValidatorsForBlock(header);
|
|
+ final int validators = set.size();
|
|
final int quorum = validators == 0 ? 0 : BftHelpers.calculateRequiredValidatorQuorum(validators);
|
|
+ if (PqAnchorProducer.commitSealFormAt(PqAnchorProducer.config(), number)
|
|
+ == PqAnchorProducer.CommitSealForm.ROUND_BOUND) {
|
|
+ // review of step 4: the Commits of rounds r > 0 heard without the proposal wait under their digest; they are
|
|
+ // moved under their round before the record is read (the node's own import never runs in that case)
|
|
+ PqAnchorProducer.resolvePendingFor(header);
|
|
+ return describeRounds(number, hash, validators, quorum, set);
|
|
+ }
|
|
final Optional<Bytes> message = messageBuilder.messageFor(number, hash);
|
|
- final List<FalconSeal> heard = cache.sealsFor(number, hash);
|
|
- final List<SchemeSeal> extras = cache.extrasFor(number, hash);
|
|
+ final List<FalconSeal> heard = cache.sealsFor(number, hash, PqSealCache.ANY_ROUND);
|
|
+ final List<SchemeSeal> extras = cache.extrasFor(number, hash, PqSealCache.ANY_ROUND);
|
|
|
|
final List<Map<String, Object>> seals = new ArrayList<>();
|
|
final TreeSet<Integer> verifiedSigners = new TreeSet<>();
|
|
for (final FalconSeal seal : heard) {
|
|
final boolean ok =
|
|
message.isPresent()
|
|
&& verifier.verify(number, seal.getValidatorIndex(), message.get(), seal.getSignature());
|
|
if (ok) {
|
|
verifiedSigners.add(seal.getValidatorIndex());
|
|
}
|
|
final Map<String, Object> s = new LinkedHashMap<>();
|
|
s.put("scheme", "falcon-512");
|
|
s.put("index", seal.getValidatorIndex());
|
|
s.put("verified", ok);
|
|
s.put("signature", seal.getSignature().toHexString());
|
|
seals.add(s);
|
|
}
|
|
final List<Map<String, Object>> hybrid = new ArrayList<>();
|
|
for (final SchemeSeal seal : extras) {
|
|
final Map<String, Object> s = new LinkedHashMap<>();
|
|
@@ -234,21 +336,156 @@ public class AereGetPqFinality extends AbstractBlockParameterMethod {
|
|
note = "seals were heard but none verifies against the anchored registry at this height";
|
|
}
|
|
|
|
final Map<String, Object> out = new LinkedHashMap<>();
|
|
out.put("blockNumber", number);
|
|
out.put("blockHash", hash.getBytes().toHexString());
|
|
out.put("validators", validators);
|
|
out.put("quorum", quorum);
|
|
out.put("sealForm", message.isPresent() ? "anchor" : "commit-digest");
|
|
out.put("signedMessage", message.map(Bytes::toHexString).orElse(null));
|
|
out.put("falconSealsHeard", heard.size());
|
|
out.put("falconSealsVerified", verifiedSigners.size());
|
|
out.put("verifiedIndexes", new ArrayList<>(verifiedSigners));
|
|
out.put("falconSeals", seals);
|
|
out.put("hybridSeals", hybrid);
|
|
out.put("finality", finality);
|
|
out.put("retentionBlocks", cache.retentionBlocks());
|
|
out.put("note", note);
|
|
return out;
|
|
}
|
|
+
|
|
+ /**
|
|
+ * AERE 1(b), section 3.1 H: the record of a block whose commit seals are ROUND-BOUND (from H_r - 1). Each round
|
|
+ * is verified over its own M_r and counted on its own; the block is "post-quantum" iff ONE round reaches the
|
|
+ * quorum of verified distinct signers ({@code decidedRound}, the smallest such round). A sum over rounds never
|
|
+ * counts: seals of different rounds are different statements. The fields of the record below H_r stay, and speak
|
|
+ * about {@code decidedRound} or, when there is none, about the round with the most verified signers (the smaller
|
|
+ * round on a tie), named in {@code recordRound}.
|
|
+ */
|
|
+ private Map<String, Object> describeRounds(
|
|
+ final long number,
|
|
+ final Hash hash,
|
|
+ final int validators,
|
|
+ final int quorum,
|
|
+ final java.util.Collection<org.hyperledger.besu.datatypes.Address> set) {
|
|
+ final java.util.NavigableMap<Integer, PqSealCache.RoundSeals> held = cache.roundsFor(number, hash);
|
|
+ final List<Map<String, Object>> rounds = new ArrayList<>();
|
|
+ final List<Map<String, Object>> seals = new ArrayList<>();
|
|
+ final List<Map<String, Object>> hybrid = new ArrayList<>();
|
|
+ Integer decidedRound = null;
|
|
+ Integer recordRound = null;
|
|
+ int recordVerified = -1;
|
|
+ final Map<Integer, Optional<Bytes>> messages = new LinkedHashMap<>();
|
|
+ final Map<Integer, TreeSet<Integer>> verifiedByRound = new LinkedHashMap<>();
|
|
+ int heardTotal = 0;
|
|
+ for (final Map.Entry<Integer, PqSealCache.RoundSeals> e : held.entrySet()) {
|
|
+ final int r = e.getKey();
|
|
+ final Optional<Bytes> message = roundMessageBuilder.messageFor(number, hash, r);
|
|
+ messages.put(r, message);
|
|
+ final TreeSet<Integer> verified = new TreeSet<>();
|
|
+ // review of step 4 (2026-10-01): from H_r - 1 a seal counts only for a DISTINCT ELIGIBLE MEMBER of the set that
|
|
+ // decides the block (section 0 point 4), as R2 and decidedBy count; an index bound to nobody, to a non-member,
|
|
+ // or a second index of a member counted already, verifies nothing here
|
|
+ final java.util.Set<org.hyperledger.besu.datatypes.Address> members = new java.util.HashSet<>();
|
|
+ for (final FalconSeal seal : e.getValue().falcon()) {
|
|
+ org.hyperledger.besu.datatypes.Address who;
|
|
+ try {
|
|
+ who = memberResolver.memberAt(number, seal.getValidatorIndex());
|
|
+ } catch (final RuntimeException ex) {
|
|
+ who = null;
|
|
+ }
|
|
+ final boolean ok =
|
|
+ message.isPresent()
|
|
+ && who != null
|
|
+ && set.contains(who)
|
|
+ && !members.contains(who)
|
|
+ && verifier.verify(number, seal.getValidatorIndex(), message.get(), seal.getSignature());
|
|
+ if (ok) {
|
|
+ members.add(who);
|
|
+ verified.add(seal.getValidatorIndex());
|
|
+ }
|
|
+ final Map<String, Object> s = new LinkedHashMap<>();
|
|
+ s.put("scheme", "falcon-512");
|
|
+ s.put("round", r);
|
|
+ s.put("index", seal.getValidatorIndex());
|
|
+ s.put("verified", ok);
|
|
+ s.put("signature", seal.getSignature().toHexString());
|
|
+ seals.add(s);
|
|
+ }
|
|
+ for (final SchemeSeal seal : e.getValue().extras()) {
|
|
+ final Map<String, Object> s = new LinkedHashMap<>();
|
|
+ s.put(
|
|
+ "scheme",
|
|
+ SealSchemes.byWireId(seal.getSchemeWireId()).map(x -> x.id()).orElse("wire-" + (seal.getSchemeWireId() & 0xff)));
|
|
+ s.put("round", r);
|
|
+ s.put("index", seal.getValidatorIndex());
|
|
+ s.put("verified", null);
|
|
+ s.put("signature", seal.getSignature().toHexString());
|
|
+ hybrid.add(s);
|
|
+ }
|
|
+ heardTotal += e.getValue().falcon().size();
|
|
+ verifiedByRound.put(r, verified);
|
|
+ final Map<String, Object> ro = new LinkedHashMap<>();
|
|
+ ro.put("round", r);
|
|
+ ro.put("signedMessage", message.map(Bytes::toHexString).orElse(null));
|
|
+ ro.put("falconSealsHeard", e.getValue().falcon().size());
|
|
+ ro.put("falconSealsVerified", verified.size());
|
|
+ ro.put("verifiedIndexes", new ArrayList<>(verified));
|
|
+ rounds.add(ro);
|
|
+ if (decidedRound == null && quorum > 0 && verified.size() >= quorum) {
|
|
+ decidedRound = r;
|
|
+ }
|
|
+ if (verified.size() > recordVerified) {
|
|
+ recordVerified = verified.size();
|
|
+ recordRound = r;
|
|
+ }
|
|
+ }
|
|
+ if (decidedRound != null) {
|
|
+ recordRound = decidedRound;
|
|
+ }
|
|
+ final TreeSet<Integer> recordSigners =
|
|
+ recordRound == null ? new TreeSet<>() : verifiedByRound.get(recordRound);
|
|
+ final String finality;
|
|
+ final String note;
|
|
+ if (heardTotal == 0) {
|
|
+ finality = "unavailable";
|
|
+ note =
|
|
+ "no seal heard for this block: seals travel on Commit messages between validators, so a reader node hears none, and a validator keeps only the last "
|
|
+ + cache.retentionBlocks()
|
|
+ + " blocks; the permanent record for older blocks is the anchor certificate";
|
|
+ } else if (decidedRound != null) {
|
|
+ finality = "post-quantum";
|
|
+ note =
|
|
+ "in ONE round at least the commit quorum of distinct validators sealed this block with Falcon-512 over the message of that round, and every counted seal verifies now; seals of different rounds are never added up";
|
|
+ } else if (verifiedByRound.values().stream().anyMatch(v -> !v.isEmpty())) {
|
|
+ finality = "partial";
|
|
+ note =
|
|
+ "no single round reaches the commit quorum of verified distinct signers (seals of different rounds are never added up): this node did not hear enough seals of one round, or some no longer verify";
|
|
+ } else {
|
|
+ finality = "none";
|
|
+ note = "seals were heard but none verifies, over the message of its round, against the anchored registry at this height";
|
|
+ }
|
|
+ final Map<String, Object> out = new LinkedHashMap<>();
|
|
+ out.put("blockNumber", number);
|
|
+ out.put("blockHash", hash.getBytes().toHexString());
|
|
+ out.put("validators", validators);
|
|
+ out.put("quorum", quorum);
|
|
+ out.put("sealForm", "anchor-round");
|
|
+ out.put("commitRoundBlock", PqAnchorProducer.config().commitRoundBlock());
|
|
+ out.put("decidedRound", decidedRound);
|
|
+ out.put("recordRound", recordRound);
|
|
+ out.put(
|
|
+ "signedMessage",
|
|
+ recordRound == null ? null : messages.get(recordRound).map(Bytes::toHexString).orElse(null));
|
|
+ out.put("falconSealsHeard", heardTotal);
|
|
+ out.put("falconSealsVerified", recordSigners.size());
|
|
+ out.put("verifiedIndexes", new ArrayList<>(recordSigners));
|
|
+ out.put("rounds", rounds);
|
|
+ out.put("falconSeals", seals);
|
|
+ out.put("hybridSeals", hybrid);
|
|
+ out.put("finality", finality);
|
|
+ out.put("retentionBlocks", cache.retentionBlocks());
|
|
+ out.put("note", note);
|
|
+ return out;
|
|
+ }
|
|
}
|
|
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereC1DecisionVectorsTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereC1DecisionVectorsTest.java
|
|
new file mode 100644
|
|
index 0000000000..ec8114f7ac
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereC1DecisionVectorsTest.java
|
|
@@ -0,0 +1,508 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.mockito.Mockito.mock;
|
|
+import static org.mockito.Mockito.when;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AereCertifiedDecision;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorLapse;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSignerRegistry;
|
|
+import org.hyperledger.besu.consensus.common.bft.SchemeSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealScheme;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealSchemes;
|
|
+import org.hyperledger.besu.crypto.SecureRandomProvider;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.BlobGas;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.datatypes.LogsBloomFilter;
|
|
+import org.hyperledger.besu.datatypes.Wei;
|
|
+import org.hyperledger.besu.ethereum.chain.Blockchain;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+import org.hyperledger.besu.ethereum.core.Difficulty;
|
|
+
|
|
+import java.io.InputStream;
|
|
+import java.nio.charset.StandardCharsets;
|
|
+import java.nio.file.Files;
|
|
+import java.nio.file.Path;
|
|
+import java.security.SecureRandom;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Comparator;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+
|
|
+import com.fasterxml.jackson.databind.JsonNode;
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
+import com.fasterxml.jackson.databind.node.ArrayNode;
|
|
+import com.fasterxml.jackson.databind.node.ObjectNode;
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+/**
|
|
+ * AERE teza Q3 / D-470 (2026-10-01), project 1(a), part B: the C1 VECTORS. The one answer "which block does this anchor's
|
|
+ * certificate prove decided?" must be the same in both clients, so this class computes it with the production
|
|
+ * {@link AereCertifiedDecision} of this client over vectors built with REAL Falcon-512 keys (and over the real anchors of 2800 on
|
|
+ * this laptop), checks each answer against the label written below BEFORE the run, and, when {@code AERE_C1_OUT} names a file,
|
|
+ * writes the whole corpus there: the headers as the chain would serve them (each rebuilt here to its own hash), the key set, the
|
|
+ * regime (H_hdr, H_ev, the anchor grid) and the answer. The second client reads the same file
|
|
+ * (AereC1DecisionVectorsNmTests) and must give the same answer on every vector.
|
|
+ *
|
|
+ * <p>The set that decides p is read the way production reads it, from p's own extraData (getValidatorsForBlock).
|
|
+ */
|
|
+public class AereC1DecisionVectorsTest {
|
|
+
|
|
+ private static final long CHAIN = 220_883L;
|
|
+ private static final int VALIDATORS = 10;
|
|
+ private static final int OUTSIDER = 10;
|
|
+ private static final int SECOND_OF_ZERO = 11;
|
|
+ private static final long NEVER = Long.MAX_VALUE;
|
|
+
|
|
+ private static final QbftExtraDataCodec CODEC = new QbftExtraDataCodec();
|
|
+ private static final ObjectMapper JSON = new ObjectMapper();
|
|
+ private final SecureRandom random = SecureRandomProvider.createSecureRandom();
|
|
+ private final List<Address> validators = new ArrayList<>();
|
|
+ private final Address outsider = Address.fromHexString("0x" + "0".repeat(38) + "ee");
|
|
+ private final List<byte[]> falconPublic = new ArrayList<>();
|
|
+ private final List<SealScheme.PrivateHandle> falconPrivate = new ArrayList<>();
|
|
+ private long tag;
|
|
+
|
|
+ /** One synthetic vector: the regime, the headers the chain holds, the anchor, and the label written before the run. */
|
|
+ private record Case(
|
|
+ String id,
|
|
+ long chainId,
|
|
+ PqAnchorConfig config,
|
|
+ long hHdr,
|
|
+ long hEv,
|
|
+ List<BlockHeader> held,
|
|
+ BlockHeader anchor,
|
|
+ String expected) {}
|
|
+
|
|
+ private PqAnchorConfig config(final long chain, final long anchorBlock, final int k, final int interval) {
|
|
+ return new PqAnchorConfig(
|
|
+ chain, anchorBlock, Map.of(anchorBlock, k), OptionalInt.empty(), false, OptionalInt.empty(), OptionalInt.of(interval));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theDecisionOfThisClientOnEveryC1VectorIsTheLabelWrittenBeforeTheRun() throws Exception {
|
|
+ for (int i = 0; i < VALIDATORS; i++) {
|
|
+ validators.add(Address.fromHexString("0x" + "0".repeat(38) + "d" + i));
|
|
+ }
|
|
+ for (int i = 0; i <= SECOND_OF_ZERO; i++) {
|
|
+ final SealScheme.GeneratedPair pair = SealSchemes.FALCON_512.generate(random);
|
|
+ assertThat(pair.publicRegistryForm()).as("control: the registry form of a Falcon-512 key is 896 bytes").hasSize(896);
|
|
+ falconPublic.add(pair.publicRegistryForm());
|
|
+ falconPrivate.add(pair.privateKey());
|
|
+ }
|
|
+ final List<Address> wide = new ArrayList<>(validators);
|
|
+ for (final String last : new String[] {"e0", "e1", "e2"}) {
|
|
+ wide.add(Address.fromHexString("0x" + "0".repeat(38) + last));
|
|
+ }
|
|
+ wide.sort(Comparator.comparing(Address::toHexString));
|
|
+
|
|
+ final BlockHeader g = header(0, Hash.ZERO, validators, null, List.of(), List.of());
|
|
+ final BlockHeader b1 = header(1, g.getHash(), validators, null, List.of(), List.of());
|
|
+ final BlockHeader b2 = header(2, b1.getHash(), validators, null, List.of(), List.of());
|
|
+ final BlockHeader p = header(3, b2.getHash(), validators, null, List.of(), List.of());
|
|
+ final BlockHeader pWide = header(3, b2.getHash(), wide, null, List.of(), List.of());
|
|
+ final List<BlockHeader> chain = List.of(g, b1, b2, p);
|
|
+ final List<BlockHeader> chainWide = List.of(g, b1, b2, pWide);
|
|
+ final PqAnchorConfig cfg = config(CHAIN, 4L, 7, 4);
|
|
+
|
|
+ final List<Case> cases = new ArrayList<>();
|
|
+ cases.add(c("c01-below-hhdr-f-plus-one", cfg, 5L, 3L, chain, v1(p, 0, 1, 2, 3), "parent"));
|
|
+ cases.add(c("c02-below-hhdr-one-seal", cfg, 5L, 3L, chain, v1(p, 0), "parent"));
|
|
+ cases.add(c("c03-below-hhdr-never", cfg, NEVER, NEVER, chain, v1(p, 0, 1, 2, 3), "parent"));
|
|
+ cases.add(c("c04-from-hhdr-f-plus-one", cfg, 4L, 3L, chain, v1(p, 0, 1, 2, 3), "grandparent"));
|
|
+ cases.add(c("c05-from-hhdr-f", cfg, 4L, 3L, chain, v1(p, 0, 1, 2), "none"));
|
|
+ final List<FalconSeal> bad = sealsOver(CHAIN, p, 0, 1, 2);
|
|
+ bad.addAll(sealsOver(CHAIN, b2, 3));
|
|
+ cases.add(c("c06-a-seal-that-does-not-verify", cfg, 4L, 3L, chain, anchorV1(p, bad, true), "none"));
|
|
+ cases.add(c("c07-parent-below-hev", cfg, 4L, 4L, chain, v1(p, 0, 1, 2, 3), "none"));
|
|
+ cases.add(c("c08-hev-never", cfg, 4L, NEVER, chain, v1(p, 0, 1, 2, 3), "none"));
|
|
+ cases.add(c("c09-non-member", cfg, 4L, 3L, chain, v1(p, 0, 1, 2, OUTSIDER), "none"));
|
|
+ cases.add(c("c10-second-index-of-one-member", cfg, 4L, 3L, chain, v1(p, 0, 1, 2, SECOND_OF_ZERO), "none"));
|
|
+ cases.add(c("c11-rf1-seven-seals-from-hhdr", cfg, 4L, 3L, chain, v1(p, 0, 1, 2, 4, 5, 6, 9), "grandparent"));
|
|
+ cases.add(c("c12-rf1-seven-seals-below-hhdr", cfg, 5L, 3L, chain, v1(p, 0, 1, 2, 4, 5, 6, 9), "parent"));
|
|
+ cases.add(c("c13-set-of-thirteen-four-seals", cfg, 4L, 3L, chainWide, v1(pWide, 0, 1, 2, 3), "none"));
|
|
+ cases.add(c("c14-set-of-thirteen-five-seals", cfg, 4L, 3L, chainWide, v1(pWide, 0, 1, 2, 3, 4), "grandparent"));
|
|
+ final PqAnchorConfig live = config(PqAnchorLapse.CHAIN_ID, 13_014_000L, 3, 32);
|
|
+ final long inside = 13_014_000L + 32L * 9_000L;
|
|
+ final long outside = 13_014_000L + 32L * 30_000L;
|
|
+ assertThat(PqAnchorLapse.windowCovering(PqAnchorLapse.CHAIN_ID, inside)).as("control: inside a named window").isPresent();
|
|
+ assertThat(PqAnchorLapse.windowCovering(PqAnchorLapse.CHAIN_ID, outside)).as("control: outside every window").isEmpty();
|
|
+ cases.add(lapse("c15-inside-a-lapse-window-of-2800", live, inside, "none"));
|
|
+ cases.add(lapse("c16-outside-the-lapse-windows-of-2800", live, outside, "grandparent"));
|
|
+ final BlockHeader noCert = header(4, p.getHash(), validators, null, List.of(), List.of());
|
|
+ cases.add(c("c17-no-certificate-from-hhdr", cfg, 4L, 3L, chain, noCert, "none"));
|
|
+ cases.add(c("c18-no-certificate-below-hhdr", cfg, 5L, 3L, chain, noCert, "none"));
|
|
+ cases.add(c("c19-parent-not-held", cfg, 4L, 3L, List.of(g, b1, b2), v1(p, 0, 1, 2, 3), "none"));
|
|
+ cases.add(c("c20-not-an-anchor-height", config(CHAIN, 8L, 7, 4), 4L, 3L, chain, v1(p, 0, 1, 2, 3), "none"));
|
|
+ cases.add(c("c21-v2-falcon-rows-from-hhdr", cfg, 4L, 3L, chain, v2(p, 0, 1, 2, 3), "grandparent"));
|
|
+ cases.add(c("c22-v2-falcon-rows-f", cfg, 4L, 3L, chain, v2(p, 0, 1, 2), "none"));
|
|
+ cases.add(c("c23-v2-below-hhdr", cfg, 5L, 3L, chain, v2(p, 0), "parent"));
|
|
+ // the v1 list as this client's codec reads it: indices in arrival order, a repeated index, an empty signature (window E of 2800
|
|
+ // carried arrival order; the codec refuses none of the three, the decision counts distinct verified members)
|
|
+ final List<FalconSeal> arrival = sealsOver(CHAIN, p, 3, 0, 2, 1);
|
|
+ cases.add(c("c24-v1-arrival-order-from-hhdr", cfg, 4L, 3L, chain, anchorV1(p, arrival, false), "grandparent"));
|
|
+ final List<FalconSeal> repeated = sealsOver(CHAIN, p, 0, 1, 2, 3);
|
|
+ repeated.add(1, sealsOver(CHAIN, p, 0).get(0));
|
|
+ cases.add(c("c25-v1-repeated-index-from-hhdr", cfg, 4L, 3L, chain, anchorV1(p, repeated, false), "grandparent"));
|
|
+ cases.add(c("c26-v1-repeated-index-below-hhdr", cfg, 5L, 3L, chain, anchorV1(p, repeated, false), "parent"));
|
|
+ final List<FalconSeal> withEmpty = sealsOver(CHAIN, p, 0, 1, 2, 3);
|
|
+ withEmpty.add(new FalconSeal(4, Bytes.EMPTY));
|
|
+ cases.add(c("c27-v1-empty-signature-from-hhdr", cfg, 4L, 3L, chain, anchorV1(p, withEmpty, false), "grandparent"));
|
|
+ final List<FalconSeal> onlyEmpty = new ArrayList<>(List.of(new FalconSeal(0, Bytes.EMPTY)));
|
|
+ cases.add(c("c28-v1-only-an-empty-signature-below-hhdr", cfg, 5L, 3L, chain, anchorV1(p, onlyEmpty, false), "parent"));
|
|
+
|
|
+ final ObjectNode root = JSON.createObjectNode();
|
|
+ root.put("schema", "aere-c1-decizie-1");
|
|
+ root.put(
|
|
+ "descriere",
|
|
+ "AERE D-470 / 1(a), vectorii C1: ce decide certificatul unei ancore, calculat de clientul derivat din Besu"
|
|
+ + " (AereCertifiedDecision) pe chei Falcon-512 reale; al doilea client trebuie sa dea acelasi raspuns pe fiecare vector");
|
|
+ root.set("registry", registryJson());
|
|
+ final ArrayNode out = root.putArray("cases");
|
|
+ final List<String> wrong = new ArrayList<>();
|
|
+ for (final Case k : cases) {
|
|
+ final Optional<AereDecidedHead.Decided> got = decide(k);
|
|
+ final Optional<AereDecidedHead.Decided> want = labelled(k);
|
|
+ if (!got.equals(want)) {
|
|
+ wrong.add(k.id() + ": label " + k.expected() + " " + want + ", decision " + got);
|
|
+ }
|
|
+ out.add(caseJson(k, got));
|
|
+ }
|
|
+ assertThat(wrong).as("C1 on the Besu-derived client: decisions that are not the label written before the run").isEmpty();
|
|
+
|
|
+ // the real anchors of 2800 on this laptop, below H_hdr (the regime of 2800 today): the decision is B1 of before 1(a)
|
|
+ final PqAnchorConfig c2800 = config(2800L, 13_014_000L, 6, 32);
|
|
+ final ArrayNode real = root.putArray("real");
|
|
+ final ObjectNode realCfg = root.putObject("realConfig");
|
|
+ realCfg.put("chainId", 2800L);
|
|
+ realCfg.put("anchorBlock", 13_014_000L);
|
|
+ realCfg.put("interval", 32);
|
|
+ realCfg.put("k", 6);
|
|
+ int certified = 0;
|
|
+ for (final JsonNode v : realCorpus().path("vectori")) {
|
|
+ final BlockHeader parent = rpcHeader(v.path("blocks").get(0));
|
|
+ final BlockHeader anchor = rpcHeader(v.path("blocks").get(1));
|
|
+ assertThat(parent.getHash().toHexString()).isEqualToIgnoringCase(v.path("blocks").get(0).path("hash").asText());
|
|
+ assertThat(anchor.getHash().toHexString()).isEqualToIgnoringCase(v.path("blocks").get(1).path("hash").asText());
|
|
+ final Blockchain bc = mock(Blockchain.class);
|
|
+ when(bc.getBlockHeader(parent.getHash())).thenReturn(Optional.of(parent));
|
|
+ final Optional<AereDecidedHead.Decided> below =
|
|
+ new AereCertifiedDecision(c2800, CODEC, registry(), h -> CODEC.decodeRaw(h.getExtraData()).getValidators(), h -> false, NEVER)
|
|
+ .decidedBy(bc, anchor);
|
|
+ if (below.isPresent()) {
|
|
+ certified++;
|
|
+ assertThat(below.get().hash()).as("%s: below H_hdr the decision is the parent", v.path("id").asText()).isEqualTo(parent.getHash());
|
|
+ }
|
|
+ final ObjectNode r = real.addObject();
|
|
+ r.put("id", v.path("id").asText());
|
|
+ r.set("parent", v.path("blocks").get(0));
|
|
+ r.set("anchor", v.path("blocks").get(1));
|
|
+ r.put("expected", below.isPresent() ? "parent" : "none");
|
|
+ r.put("expectedNumber", below.map(AereDecidedHead.Decided::number).orElse(-1L));
|
|
+ r.put("expectedHash", below.map(d -> d.hash().toHexString()).orElse(""));
|
|
+ }
|
|
+ assertThat(real.size()).as("control: the real corpus of 2800 is here").isGreaterThan(0);
|
|
+ assertThat(certified).as("control: it holds certified anchors").isGreaterThan(0);
|
|
+
|
|
+ final String path = System.getenv("AERE_C1_OUT");
|
|
+ if (path != null && !path.isBlank()) {
|
|
+ Files.writeString(Path.of(path), JSON.writerWithDefaultPrettyPrinter().writeValueAsString(root), StandardCharsets.UTF_8);
|
|
+ System.out.println("AERE C1: " + cases.size() + " synthetic vectors and " + real.size() + " real anchors of 2800 ("
|
|
+ + certified + " certified) written to " + path);
|
|
+ }
|
|
+ System.out.println("AERE C1 on the Besu-derived client: " + cases.size() + " synthetic vectors, " + wrong.size()
|
|
+ + " not the label; " + real.size() + " real anchors, " + certified + " decide their parent");
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // the decision, as production computes it
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ private Optional<AereDecidedHead.Decided> decide(final Case k) {
|
|
+ final Blockchain bc = mock(Blockchain.class);
|
|
+ for (final BlockHeader h : k.held()) {
|
|
+ when(bc.getBlockHeader(h.getHash())).thenReturn(Optional.of(h));
|
|
+ }
|
|
+ final long hHdr = k.hHdr();
|
|
+ return new AereCertifiedDecision(
|
|
+ k.config(), CODEC, registry(), h -> CODEC.decodeRaw(h.getExtraData()).getValidators(), a -> a >= hHdr, k.hEv())
|
|
+ .decidedBy(bc, k.anchor());
|
|
+ }
|
|
+
|
|
+ /** The label written before the run, as a decided block of this vector. */
|
|
+ private static Optional<AereDecidedHead.Decided> labelled(final Case k) {
|
|
+ final BlockHeader a = k.anchor();
|
|
+ if ("parent".equals(k.expected())) {
|
|
+ return Optional.of(new AereDecidedHead.Decided(a.getNumber() - 1L, a.getParentHash()));
|
|
+ }
|
|
+ if ("grandparent".equals(k.expected())) {
|
|
+ for (final BlockHeader h : k.held()) {
|
|
+ if (h.getHash().equals(a.getParentHash())) {
|
|
+ return Optional.of(new AereDecidedHead.Decided(h.getNumber() - 1L, h.getParentHash()));
|
|
+ }
|
|
+ }
|
|
+ throw new IllegalStateException(k.id() + ": labelled grandparent but the parent is not held");
|
|
+ }
|
|
+ return Optional.empty();
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // fixture
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ private Case c(
|
|
+ final String id,
|
|
+ final PqAnchorConfig cfg,
|
|
+ final long hHdr,
|
|
+ final long hEv,
|
|
+ final List<BlockHeader> held,
|
|
+ final BlockHeader anchor,
|
|
+ final String expected) {
|
|
+ return new Case(id, cfg.chainId(), cfg, hHdr, hEv, held, anchor, expected);
|
|
+ }
|
|
+
|
|
+ private Case lapse(final String id, final PqAnchorConfig live, final long a, final String expected) {
|
|
+ final BlockHeader grand = header(a - 2L, Hash.ZERO, validators, null, List.of(), List.of());
|
|
+ final BlockHeader parent = header(a - 1L, grand.getHash(), validators, null, List.of(), List.of());
|
|
+ final List<FalconSeal> seals = sealsOver(PqAnchorLapse.CHAIN_ID, parent, 0, 1, 2, 3);
|
|
+ final BlockHeader anchor =
|
|
+ header(a, parent.getHash(), validators, PqAnchor.anchorDigest(PqAnchorLapse.CHAIN_ID, a - 1L, parent.getHash().getBytes(), seals), seals, List.of());
|
|
+ return new Case(id, PqAnchorLapse.CHAIN_ID, live, 0L, 0L, List.of(grand, parent), anchor, expected);
|
|
+ }
|
|
+
|
|
+ private List<FalconSeal> sealsOver(final long chain, final BlockHeader b, final int... indexes) {
|
|
+ final Bytes32 message = PqAnchor.commitMessage(chain, b.getNumber(), b.getHash().getBytes());
|
|
+ final List<FalconSeal> out = new ArrayList<>();
|
|
+ for (final int i : indexes) {
|
|
+ out.add(new FalconSeal(i, Bytes.wrap(SealSchemes.FALCON_512.sign(falconPrivate.get(i), message.toArray()).orElseThrow())));
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ /** A v1 anchor over p (sorted, its digest in vanityData). */
|
|
+ private BlockHeader v1(final BlockHeader p, final int... indexes) {
|
|
+ return anchorV1(p, sealsOver(CHAIN, p, indexes), true);
|
|
+ }
|
|
+
|
|
+ private BlockHeader anchorV1(final BlockHeader p, final List<FalconSeal> seals, final boolean sortAndDigest) {
|
|
+ final List<FalconSeal> carried = sortAndDigest ? PqAnchor.sortedByIndex(seals) : seals;
|
|
+ final Bytes32 vanity = sortAndDigest ? PqAnchor.anchorDigest(CHAIN, p.getNumber(), p.getHash().getBytes(), carried) : null;
|
|
+ return header(p.getNumber() + 1L, p.getHash(), validators, vanity, carried, List.of());
|
|
+ }
|
|
+
|
|
+ /** A v2 (scheme-tagged) anchor over p whose rows are Falcon-512 seals. */
|
|
+ private BlockHeader v2(final BlockHeader p, final int... indexes) {
|
|
+ final List<SchemeSeal> rows = new ArrayList<>();
|
|
+ for (final FalconSeal s : sealsOver(CHAIN, p, indexes)) {
|
|
+ rows.add(new SchemeSeal(SealSchemes.FALCON_512.wireId(), s.getValidatorIndex(), s.getSignature()));
|
|
+ }
|
|
+ return header(p.getNumber() + 1L, p.getHash(), validators, null, List.of(), rows);
|
|
+ }
|
|
+
|
|
+ private BlockHeader header(
|
|
+ final long number,
|
|
+ final Hash parentHash,
|
|
+ final List<Address> list,
|
|
+ final Bytes32 vanity,
|
|
+ final List<FalconSeal> falcon,
|
|
+ final List<SchemeSeal> rows) {
|
|
+ tag++;
|
|
+ final BftExtraData extra =
|
|
+ new BftExtraData(
|
|
+ vanity != null ? vanity : Bytes32.leftPad(Bytes.ofUnsignedLong(tag)),
|
|
+ List.of(),
|
|
+ Optional.empty(),
|
|
+ 0,
|
|
+ list,
|
|
+ falcon,
|
|
+ rows, BftExtraData.NO_CERTIFICATE_ROUND);
|
|
+ return new BlockHeaderTestFixture()
|
|
+ .number(number)
|
|
+ .parentHash(parentHash)
|
|
+ .difficulty(Difficulty.ONE)
|
|
+ .extraData(CODEC.encode(extra))
|
|
+ .timestamp(number)
|
|
+ .coinbase(list.get(0))
|
|
+ .blockHeaderFunctions(BftBlockHeaderFunctions.forOnchainBlock(CODEC))
|
|
+ .buildHeader();
|
|
+ }
|
|
+
|
|
+ /** Index i bound to validator i (10 to an outsider, 11 to validator 0), verified with index i's key. */
|
|
+ private PqSignerRegistry registry() {
|
|
+ return new PqSignerRegistry() {
|
|
+ @Override
|
|
+ public Address addressForIndexAtHistoric(final long blockNumber, final int validatorIndex) {
|
|
+ if (validatorIndex == OUTSIDER) {
|
|
+ return outsider;
|
|
+ }
|
|
+ if (validatorIndex == SECOND_OF_ZERO) {
|
|
+ return validators.get(0);
|
|
+ }
|
|
+ return validatorIndex >= 0 && validatorIndex < VALIDATORS ? validators.get(validatorIndex) : null;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Address addressForIndexAtOwnHead(final long blockNumber, final int validatorIndex) {
|
|
+ return addressForIndexAtHistoric(blockNumber, validatorIndex);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtHistoric(
|
|
+ final long blockNumber, final int validatorIndex, final Bytes message, final Bytes signature) {
|
|
+ return validatorIndex >= 0
|
|
+ && validatorIndex <= SECOND_OF_ZERO
|
|
+ && SealSchemes.FALCON_512.verifyRaw(falconPublic.get(validatorIndex), message.toArray(), signature.toArray());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtOwnHead(
|
|
+ final long blockNumber, final int validatorIndex, final Bytes message, final Bytes signature) {
|
|
+ return verifyAtHistoric(blockNumber, validatorIndex, message, signature);
|
|
+ }
|
|
+ };
|
|
+ }
|
|
+
|
|
+ /** The key set in the form the second client's loader reads (AereFalconRegistry.Load). */
|
|
+ private ObjectNode registryJson() {
|
|
+ final ObjectNode r = JSON.createObjectNode();
|
|
+ r.put("count", SECOND_OF_ZERO + 1);
|
|
+ r.put("chainId", CHAIN);
|
|
+ r.put("bindHeight", 0);
|
|
+ for (int i = 0; i <= SECOND_OF_ZERO; i++) {
|
|
+ final Address bound = i == OUTSIDER ? outsider : i == SECOND_OF_ZERO ? validators.get(0) : validators.get(i);
|
|
+ final ObjectNode row = r.putObject(Integer.toString(i));
|
|
+ row.put("addr", bound.toHexString());
|
|
+ row.put("pk", Bytes.wrap(falconPublic.get(i)).toHexString());
|
|
+ row.put("alg", "falcon-512");
|
|
+ }
|
|
+ return r;
|
|
+ }
|
|
+
|
|
+ private ObjectNode caseJson(final Case k, final Optional<AereDecidedHead.Decided> got) {
|
|
+ final ObjectNode o = JSON.createObjectNode();
|
|
+ o.put("id", k.id());
|
|
+ o.put("chainId", k.chainId());
|
|
+ o.put("anchorBlock", k.config().anchorBlock());
|
|
+ o.put("interval", k.config().intervalAt(k.anchor().getNumber()));
|
|
+ o.put("k", k.config().minSealsAt(k.config().anchorBlock()));
|
|
+ o.put("hHdr", k.hHdr());
|
|
+ o.put("hEv", k.hEv());
|
|
+ final ArrayNode held = o.putArray("held");
|
|
+ for (final BlockHeader h : k.held()) {
|
|
+ held.add(rpc(h));
|
|
+ }
|
|
+ o.set("anchor", rpc(k.anchor()));
|
|
+ o.put("expected", k.expected());
|
|
+ o.put("expectedNumber", got.map(AereDecidedHead.Decided::number).orElse(-1L));
|
|
+ o.put("expectedHash", got.map(d -> d.hash().toHexString()).orElse(""));
|
|
+ return o;
|
|
+ }
|
|
+
|
|
+ /** The header in the form a JSON-RPC node serves it (and the real corpus carries). */
|
|
+ private static ObjectNode rpc(final BlockHeader h) {
|
|
+ final ObjectNode b = JSON.createObjectNode();
|
|
+ b.put("number", "0x" + Long.toHexString(h.getNumber()));
|
|
+ b.put("hash", h.getHash().toHexString());
|
|
+ b.put("parentHash", h.getParentHash().toHexString());
|
|
+ b.put("sha3Uncles", h.getOmmersHash().toHexString());
|
|
+ b.put("miner", h.getCoinbase().toHexString());
|
|
+ b.put("stateRoot", h.getStateRoot().toHexString());
|
|
+ b.put("transactionsRoot", h.getTransactionsRoot().toHexString());
|
|
+ b.put("receiptsRoot", h.getReceiptsRoot().toHexString());
|
|
+ b.put("logsBloom", h.getLogsBloom().toHexString());
|
|
+ b.put("difficulty", "0x" + h.getDifficulty().toBigInteger().toString(16));
|
|
+ b.put("gasLimit", "0x" + Long.toHexString(h.getGasLimit()));
|
|
+ b.put("gasUsed", "0x" + Long.toHexString(h.getGasUsed()));
|
|
+ b.put("timestamp", "0x" + Long.toHexString(h.getTimestamp()));
|
|
+ b.put("extraData", h.getExtraData().toHexString());
|
|
+ b.put("mixHash", h.getMixHash().toHexString());
|
|
+ b.put("nonce", Bytes.ofUnsignedLong(h.getNonce()).toHexString());
|
|
+ h.getBaseFee().ifPresent(f -> b.put("baseFeePerGas", f.toShortHexString()));
|
|
+ h.getWithdrawalsRoot().ifPresent(w -> b.put("withdrawalsRoot", w.toHexString()));
|
|
+ h.getBlobGasUsed().ifPresent(u -> b.put("blobGasUsed", "0x" + Long.toHexString(u)));
|
|
+ h.getExcessBlobGas().ifPresent(x -> b.put("excessBlobGas", x.toShortHexString()));
|
|
+ h.getParentBeaconBlockRoot().ifPresent(r -> b.put("parentBeaconBlockRoot", r.toHexString()));
|
|
+ h.getRequestsHash().ifPresent(r -> b.put("requestsHash", r.toHexString()));
|
|
+ final BlockHeader back = rpcHeader(b);
|
|
+ assertThat(back.getHash()).as("control: the served form of header %s rebuilds to its own hash", h.getNumber()).isEqualTo(h.getHash());
|
|
+ return b;
|
|
+ }
|
|
+
|
|
+ private static JsonNode realCorpus() throws Exception {
|
|
+ try (InputStream in = AereC1DecisionVectorsTest.class.getResourceAsStream("/aere-d412/ancore-2800-diferential.json")) {
|
|
+ assertThat(in).as("the real corpus of 2800").isNotNull();
|
|
+ return JSON.readTree(in);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static long hexLong(final JsonNode b, final String field) {
|
|
+ return Long.decode(b.path(field).asText());
|
|
+ }
|
|
+
|
|
+ /** The header as the chain served it (the parser of AereCertifiedDecisionRealAnchorsTest). */
|
|
+ private static BlockHeader rpcHeader(final JsonNode b) {
|
|
+ final BlockHeaderTestFixture f =
|
|
+ new BlockHeaderTestFixture()
|
|
+ .blockHeaderFunctions(BftBlockHeaderFunctions.forOnchainBlock(CODEC))
|
|
+ .parentHash(Hash.fromHexString(b.path("parentHash").asText()))
|
|
+ .ommersHash(Hash.fromHexString(b.path("sha3Uncles").asText()))
|
|
+ .coinbase(Address.fromHexString(b.path("miner").asText()))
|
|
+ .stateRoot(Hash.fromHexString(b.path("stateRoot").asText()))
|
|
+ .transactionsRoot(Hash.fromHexString(b.path("transactionsRoot").asText()))
|
|
+ .receiptsRoot(Hash.fromHexString(b.path("receiptsRoot").asText()))
|
|
+ .logsBloom(new LogsBloomFilter(Bytes.fromHexString(b.path("logsBloom").asText())))
|
|
+ .difficulty(Difficulty.of(hexLong(b, "difficulty")))
|
|
+ .number(hexLong(b, "number"))
|
|
+ .gasLimit(hexLong(b, "gasLimit"))
|
|
+ .gasUsed(hexLong(b, "gasUsed"))
|
|
+ .timestamp(hexLong(b, "timestamp"))
|
|
+ .extraData(Bytes.fromHexString(b.path("extraData").asText()))
|
|
+ .mixHash(Hash.fromHexString(b.path("mixHash").asText()))
|
|
+ .nonce(Bytes.fromHexString(b.path("nonce").asText()).toLong());
|
|
+ if (b.hasNonNull("baseFeePerGas")) {
|
|
+ f.baseFeePerGas(Wei.fromHexString(b.path("baseFeePerGas").asText()));
|
|
+ }
|
|
+ if (b.hasNonNull("withdrawalsRoot")) {
|
|
+ f.withdrawalsRoot(Hash.fromHexString(b.path("withdrawalsRoot").asText()));
|
|
+ }
|
|
+ if (b.hasNonNull("blobGasUsed")) {
|
|
+ f.blobGasUsed(hexLong(b, "blobGasUsed"));
|
|
+ }
|
|
+ if (b.hasNonNull("excessBlobGas")) {
|
|
+ f.excessBlobGas(BlobGas.fromHexString(b.path("excessBlobGas").asText()));
|
|
+ }
|
|
+ if (b.hasNonNull("parentBeaconBlockRoot")) {
|
|
+ f.parentBeaconBlockRoot(Optional.of(Bytes32.fromHexString(b.path("parentBeaconBlockRoot").asText())));
|
|
+ }
|
|
+ if (b.hasNonNull("requestsHash")) {
|
|
+ f.requestsHash(Hash.fromHexString(b.path("requestsHash").asText()));
|
|
+ }
|
|
+ return f.buildHeader();
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereCertifiedDecisionRealAnchorsTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereCertifiedDecisionRealAnchorsTest.java
|
|
new file mode 100644
|
|
index 0000000000..7541aa1f75
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereCertifiedDecisionRealAnchorsTest.java
|
|
@@ -0,0 +1,248 @@
|
|
+/*
|
|
+ * AERE teza Q3 / D-470 (2026-10-01), proiectul 1(a): DIFERENTIALUL SUB H_hdr, pe anteturi REALE de pe 2800.
|
|
+ *
|
|
+ * DE CE EXISTA. AereCertifiedDecision schimba ce numesc Q3, tagul finalized (B1) si repornirea, dar numai de la H_hdr; sub H_hdr
|
|
+ * (azi, pe 2800, peste tot) trebuie sa dea EXACT ce da B1 de pana acum: parintele unei ancore canonice care poarta un certificat.
|
|
+ * Se masoara pe toate perechile [parinte, ancora] reale de pe 2800 aflate pe laptop (ancore-2800-diferential.json, extras de
|
|
+ * cap-decis-besu/extrage-ancore-diferential.py: v1 de la 13,1 milioane, fereastra E inclusa, v2 hibrid la 20,4 milioane), cu
|
|
+ * codecul real si cu configuratia ancorei lui 2800 (H = 13.014.000, grila de 32, pe care sta si grila de 128).
|
|
+ *
|
|
+ * CE MASOARA, fiecare cu controlul lui:
|
|
+ * - anteturile se refac fiecare la propria amprenta (altfel restul nu masoara nimic);
|
|
+ * - pe fiecare ancora: decizia de sub H_hdr == forma lui B1 de pana acum (parintele, daca poarta certificat), 0 divergente,
|
|
+ * si fara nicio intrebare catre registru sau catre lant (sub H_hdr nu se verifica nimic: costul e zero);
|
|
+ * - control al metodei: aceleasi ancore cu regimul de DE LA H_hdr si cu un registru fara chei nu decid nimic (deci proba ar
|
|
+ * vedea o decizie care nu tine cont de H_hdr).
|
|
+ * CE NU MASOARA: 1000 de ancore (proiectul le cerea; corpusul local are cate spune proba, restul ar cere o extragere de pe lant,
|
|
+ * adica o gazda) si regimul de la H_hdr pe anteturi reale (pe 2800 nu exista; pe 28001 H_ev nu e setat, deci nu ar decide nimic).
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.mockito.Mockito.mock;
|
|
+import static org.mockito.Mockito.verifyNoInteractions;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AereCertifiedDecision;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead;
|
|
+import org.hyperledger.besu.consensus.common.bft.AerePqFinalityTags;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSignerRegistry;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.BlobGas;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.datatypes.LogsBloomFilter;
|
|
+import org.hyperledger.besu.datatypes.Wei;
|
|
+import org.hyperledger.besu.ethereum.chain.Blockchain;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+import org.hyperledger.besu.ethereum.core.Difficulty;
|
|
+
|
|
+import java.io.InputStream;
|
|
+import java.util.ArrayList;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+
|
|
+import com.fasterxml.jackson.databind.JsonNode;
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+public class AereCertifiedDecisionRealAnchorsTest {
|
|
+
|
|
+ private static final String RESOURCE = "/aere-d412/ancore-2800-diferential.json";
|
|
+ private static final QbftExtraDataCodec CODEC = new QbftExtraDataCodec();
|
|
+ private static final long CHAIN_2800 = 2800L;
|
|
+ private static final long ANCHOR_2800 = 13_014_000L;
|
|
+ // the configuration of the anchor on 2800 that the corpus needs: H, the base grid of 32 (the grid of 128 from 17.225.968 sits
|
|
+ // on it), K as it stands; Keff plays no part in the decision
|
|
+ private static final PqAnchorConfig CONFIG_2800 =
|
|
+ new PqAnchorConfig(
|
|
+ CHAIN_2800,
|
|
+ ANCHOR_2800,
|
|
+ Map.of(ANCHOR_2800, 6),
|
|
+ OptionalInt.empty(),
|
|
+ false,
|
|
+ OptionalInt.empty(),
|
|
+ OptionalInt.of(32));
|
|
+
|
|
+ /** One vector: the parent and the anchor, as the chain served them. */
|
|
+ private static final class Pair {
|
|
+ private final String id;
|
|
+ private final BlockHeader parent;
|
|
+ private final BlockHeader anchor;
|
|
+
|
|
+ Pair(final String id, final BlockHeader parent, final BlockHeader anchor) {
|
|
+ this.id = id;
|
|
+ this.parent = parent;
|
|
+ this.anchor = anchor;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static JsonNode corpus() throws Exception {
|
|
+ try (InputStream in = AereCertifiedDecisionRealAnchorsTest.class.getResourceAsStream(RESOURCE)) {
|
|
+ assertThat(in).as("resource %s", RESOURCE).isNotNull();
|
|
+ return new ObjectMapper().readTree(in);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static List<Pair> pairs() throws Exception {
|
|
+ final List<Pair> out = new ArrayList<>();
|
|
+ for (final JsonNode v : corpus().path("vectori")) {
|
|
+ final JsonNode b = v.path("blocks");
|
|
+ out.add(new Pair(v.path("id").asText(), header(b.get(0)), header(b.get(1))));
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ /** A registry that refuses everything and counts nothing: below H_hdr nothing may ask it. */
|
|
+ private static PqSignerRegistry emptyRegistry() {
|
|
+ return new PqSignerRegistry() {
|
|
+ @Override
|
|
+ public Address addressForIndexAtHistoric(final long blockNumber, final int validatorIndex) {
|
|
+ return null;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Address addressForIndexAtOwnHead(final long blockNumber, final int validatorIndex) {
|
|
+ return null;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtHistoric(
|
|
+ final long blockNumber, final int validatorIndex, final Bytes message, final Bytes signature) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtOwnHead(
|
|
+ final long blockNumber, final int validatorIndex, final Bytes message, final Bytes signature) {
|
|
+ return false;
|
|
+ }
|
|
+ };
|
|
+ }
|
|
+
|
|
+ /** What B1 named until 2026-10-01: the parent of an anchor height that carries a certificate. */
|
|
+ private static Optional<AereDecidedHead.Decided> b1Today(final BlockHeader anchor) {
|
|
+ if (!CONFIG_2800.anchorAppliesAt(anchor.getNumber())
|
|
+ || !AerePqFinalityTags.carriesCertificate(CODEC.decodeRaw(anchor.getExtraData()))) {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+ return Optional.of(new AereDecidedHead.Decided(anchor.getNumber() - 1L, anchor.getParentHash()));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theRealHeadersRebuildToTheChainsHashes() throws Exception {
|
|
+ int n = 0;
|
|
+ for (final JsonNode v : corpus().path("vectori")) {
|
|
+ for (final JsonNode b : v.path("blocks")) {
|
|
+ assertThat(header(b).getHash().toHexString())
|
|
+ .as("%s block %s", v.path("id").asText(), b.path("number").asText())
|
|
+ .isEqualToIgnoringCase(b.path("hash").asText());
|
|
+ n++;
|
|
+ }
|
|
+ }
|
|
+ assertThat(n).as("two headers per vector, the whole local corpus of 2800").isEqualTo(2 * pairs().size());
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void belowHhdrTheDecisionIsTheParentOnEveryRealAnchorOf2800() throws Exception {
|
|
+ final List<Pair> pairs = pairs();
|
|
+ final Blockchain chain = mock(Blockchain.class);
|
|
+ final AereCertifiedDecision decision =
|
|
+ new AereCertifiedDecision(
|
|
+ CONFIG_2800, CODEC, emptyRegistry(), h -> List.of(), h -> false, Long.MAX_VALUE);
|
|
+ int parents = 0;
|
|
+ int certified = 0;
|
|
+ final List<String> divergent = new ArrayList<>();
|
|
+ for (final Pair p : pairs) {
|
|
+ assertThat(p.anchor.getParentHash()).as("%s: the anchor is the parent's child", p.id).isEqualTo(p.parent.getHash());
|
|
+ final Optional<AereDecidedHead.Decided> expected = b1Today(p.anchor);
|
|
+ if (expected.isPresent()) {
|
|
+ certified++;
|
|
+ }
|
|
+ final Optional<AereDecidedHead.Decided> got = decision.decidedBy(chain, p.anchor);
|
|
+ if (!got.equals(expected)) {
|
|
+ divergent.add(p.id + ": B1 " + expected + ", decision " + got);
|
|
+ }
|
|
+ if (got.isPresent() && got.get().hash().equals(p.parent.getHash())) {
|
|
+ parents++;
|
|
+ }
|
|
+ }
|
|
+ assertThat(divergent).as("AERE D-470 differential below H_hdr: divergences on %s real anchors", pairs.size()).isEmpty();
|
|
+ assertThat(certified).as("control: the corpus holds certified anchors").isGreaterThan(0);
|
|
+ assertThat(parents)
|
|
+ .as("control: on every certified real anchor the decision is the parent of the vector")
|
|
+ .isEqualTo(certified);
|
|
+ verifyNoInteractions(chain);
|
|
+ System.out.println(
|
|
+ "AERE D-470 differential below H_hdr: " + pairs.size() + " real anchors of 2800, " + certified
|
|
+ + " certified, " + parents + " decide their parent, divergences " + divergent.size());
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void controlFromHhdrTheSameAnchorsWithoutKeysDecideNothing() throws Exception {
|
|
+ final Blockchain chain = mock(Blockchain.class);
|
|
+ final AereCertifiedDecision decision =
|
|
+ new AereCertifiedDecision(CONFIG_2800, CODEC, emptyRegistry(), h -> List.of(), h -> true, 0L);
|
|
+ int decided = 0;
|
|
+ final List<Pair> pairs = pairs();
|
|
+ for (final Pair p : pairs) {
|
|
+ if (decision.decidedBy(chain, p.anchor).isPresent()) {
|
|
+ decided++;
|
|
+ }
|
|
+ }
|
|
+ assertThat(pairs).as("control: the corpus is not empty").isNotEmpty();
|
|
+ assertThat(decided)
|
|
+ .as("control: in the regime from H_hdr, with no key and no parent to look up, nothing is decided")
|
|
+ .isZero();
|
|
+ }
|
|
+
|
|
+ private static long hexLong(final JsonNode b, final String field) {
|
|
+ return Long.decode(b.path(field).asText());
|
|
+ }
|
|
+
|
|
+ /** The header as the chain served it (the parser of AereD412RealHeadersTest). */
|
|
+ private static BlockHeader header(final JsonNode b) {
|
|
+ final BlockHeaderTestFixture f =
|
|
+ new BlockHeaderTestFixture()
|
|
+ .blockHeaderFunctions(BftBlockHeaderFunctions.forOnchainBlock(CODEC))
|
|
+ .parentHash(Hash.fromHexString(b.path("parentHash").asText()))
|
|
+ .ommersHash(Hash.fromHexString(b.path("sha3Uncles").asText()))
|
|
+ .coinbase(Address.fromHexString(b.path("miner").asText()))
|
|
+ .stateRoot(Hash.fromHexString(b.path("stateRoot").asText()))
|
|
+ .transactionsRoot(Hash.fromHexString(b.path("transactionsRoot").asText()))
|
|
+ .receiptsRoot(Hash.fromHexString(b.path("receiptsRoot").asText()))
|
|
+ .logsBloom(new LogsBloomFilter(Bytes.fromHexString(b.path("logsBloom").asText())))
|
|
+ .difficulty(Difficulty.of(hexLong(b, "difficulty")))
|
|
+ .number(hexLong(b, "number"))
|
|
+ .gasLimit(hexLong(b, "gasLimit"))
|
|
+ .gasUsed(hexLong(b, "gasUsed"))
|
|
+ .timestamp(hexLong(b, "timestamp"))
|
|
+ .extraData(Bytes.fromHexString(b.path("extraData").asText()))
|
|
+ .mixHash(Hash.fromHexString(b.path("mixHash").asText()))
|
|
+ .nonce(Bytes.fromHexString(b.path("nonce").asText()).toLong());
|
|
+ if (b.hasNonNull("baseFeePerGas")) {
|
|
+ f.baseFeePerGas(Wei.fromHexString(b.path("baseFeePerGas").asText()));
|
|
+ }
|
|
+ if (b.hasNonNull("withdrawalsRoot")) {
|
|
+ f.withdrawalsRoot(Hash.fromHexString(b.path("withdrawalsRoot").asText()));
|
|
+ }
|
|
+ if (b.hasNonNull("blobGasUsed")) {
|
|
+ f.blobGasUsed(hexLong(b, "blobGasUsed"));
|
|
+ }
|
|
+ if (b.hasNonNull("excessBlobGas")) {
|
|
+ f.excessBlobGas(BlobGas.fromHexString(b.path("excessBlobGas").asText()));
|
|
+ }
|
|
+ if (b.hasNonNull("parentBeaconBlockRoot")) {
|
|
+ f.parentBeaconBlockRoot(Optional.of(Bytes32.fromHexString(b.path("parentBeaconBlockRoot").asText())));
|
|
+ }
|
|
+ if (b.hasNonNull("requestsHash")) {
|
|
+ f.requestsHash(Hash.fromHexString(b.path("requestsHash").asText()));
|
|
+ }
|
|
+ return f.buildHeader();
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereCertifiedDecisionTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereCertifiedDecisionTest.java
|
|
new file mode 100644
|
|
index 0000000000..990152038c
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereCertifiedDecisionTest.java
|
|
@@ -0,0 +1,385 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.mockito.Mockito.mock;
|
|
+import static org.mockito.Mockito.when;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AereCertifiedDecision;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorLapse;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSignerRegistry;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealScheme;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealSchemes;
|
|
+import org.hyperledger.besu.crypto.SecureRandomProvider;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.chain.Blockchain;
|
|
+import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
+import org.hyperledger.besu.ethereum.core.Block;
|
|
+import org.hyperledger.besu.ethereum.core.BlockBody;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+import org.hyperledger.besu.ethereum.core.Difficulty;
|
|
+import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider;
|
|
+
|
|
+import java.security.SecureRandom;
|
|
+import java.util.ArrayList;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+import java.util.concurrent.atomic.AtomicInteger;
|
|
+import java.util.function.LongPredicate;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+/**
|
|
+ * AERE teza Q3 / D-470 (2026-10-01), project 1(a): {@link AereCertifiedDecision}, the ONE answer to
|
|
+ * "which block does this anchor's certificate prove decided?" (Q3, the finalized tags B1, the restart),
|
|
+ * measured with real Falcon-512 keys at N = 10 (f + 1 = 4) on a chain genesis, 1, 2, p = 3, anchor A = 4.
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>below H_hdr: the PARENT, whatever the seals (the anchor's header carries the ECDSA quorum of one
|
|
+ * round), and the registry is not even asked;
|
|
+ * <li>from H_hdr: the GRANDPARENT on f + 1 verified seals of distinct members of the set that decides p,
|
|
+ * nothing on f;
|
|
+ * <li>a seal that does not verify NOW counts for nothing (the seals are re-verified, never trusted from
|
|
+ * the import);
|
|
+ * <li>the number that proves is the count of verified members, not the threshold the configuration asks
|
|
+ * for (Keff);
|
|
+ * <li>a parent below H_ev decides nothing (rule D does not govern the commits on it);
|
|
+ * <li>a non-member and a second index of one member count for nothing;
|
|
+ * <li>an anchor inside a named lapse window of 2800 decides nothing.
|
|
+ * </ul>
|
|
+ *
|
|
+ * Each property has a control on the same fixture with one thing changed, and a plantation in the class
|
|
+ * (planteaza-1a.py) that turns its proof RED.
|
|
+ */
|
|
+public class AereCertifiedDecisionTest {
|
|
+
|
|
+ private static final long CHAIN = 220_881L;
|
|
+ private static final long H_EV = 3L;
|
|
+ private static final long ANCHOR_HEIGHT = 4L;
|
|
+ private static final int VALIDATORS = 10;
|
|
+ // index 10 is bound to an address outside the set, index 11 to validator 0 (a second index of one member)
|
|
+ private static final int OUTSIDER = 10;
|
|
+ private static final int SECOND_OF_ZERO = 11;
|
|
+
|
|
+ private final QbftExtraDataCodec codec = new QbftExtraDataCodec();
|
|
+ private final PqAnchorConfig config =
|
|
+ new PqAnchorConfig(
|
|
+ CHAIN,
|
|
+ ANCHOR_HEIGHT,
|
|
+ Map.of(ANCHOR_HEIGHT, 7),
|
|
+ OptionalInt.empty(),
|
|
+ false,
|
|
+ OptionalInt.empty(),
|
|
+ OptionalInt.of(4));
|
|
+ private final SecureRandom random = SecureRandomProvider.createSecureRandom();
|
|
+ private final List<Address> validators = new ArrayList<>();
|
|
+ private final Address outsider = Address.fromHexString("0x" + "0".repeat(38) + "ee");
|
|
+ private final List<byte[]> falconPublic = new ArrayList<>();
|
|
+ private final List<SealScheme.PrivateHandle> falconPrivate = new ArrayList<>();
|
|
+ private final AtomicInteger registryCalls = new AtomicInteger();
|
|
+ private long tag;
|
|
+
|
|
+ private Block genesis;
|
|
+ private Block b1;
|
|
+ private Block b2;
|
|
+ private Block p;
|
|
+
|
|
+ @BeforeEach
|
|
+ public void setUp() {
|
|
+ for (int i = 0; i < VALIDATORS; i++) {
|
|
+ validators.add(Address.fromHexString("0x" + "0".repeat(38) + "d" + i));
|
|
+ }
|
|
+ for (int i = 0; i <= SECOND_OF_ZERO; i++) {
|
|
+ final SealScheme.GeneratedPair pair = SealSchemes.FALCON_512.generate(random);
|
|
+ falconPublic.add(pair.publicRegistryForm());
|
|
+ falconPrivate.add(pair.privateKey());
|
|
+ }
|
|
+ genesis = block(null, List.of());
|
|
+ b1 = block(genesis, List.of());
|
|
+ b2 = block(b1, List.of());
|
|
+ p = block(b2, List.of());
|
|
+ }
|
|
+
|
|
+ private static boolean aboveHhdr(final long height) {
|
|
+ return height >= ANCHOR_HEIGHT;
|
|
+ }
|
|
+
|
|
+ private AereCertifiedDecision decision(final LongPredicate headerSealActive, final long hEv) {
|
|
+ return new AereCertifiedDecision(config, codec, registry(), h -> validators, headerSealActive, hEv);
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // below H_hdr: the parent
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void belowHhdrTheCertificateDecidesTheParentAndNoSealIsAsked() {
|
|
+ final Block four = anchor(sealsOver(p, 0, 1, 2, 3));
|
|
+ final Block one = anchor(sealsOver(p, 0));
|
|
+ final MutableBlockchain chain = chainWith(four);
|
|
+ assertThat(decision(h -> false, H_EV).decidedBy(chain, four.getHeader()))
|
|
+ .as("below H_hdr: the anchor's parent p")
|
|
+ .contains(new AereDecidedHead.Decided(3L, p.getHash()));
|
|
+ assertThat(decision(h -> false, H_EV).decidedBy(chain, one.getHeader()))
|
|
+ .as("below H_hdr the count of seals plays no part: one seal, still the parent")
|
|
+ .contains(new AereDecidedHead.Decided(3L, p.getHash()));
|
|
+ assertThat(registryCalls.get()).as("below H_hdr the registry is not asked").isZero();
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // from H_hdr: the grandparent, on f + 1 verified members
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void fromHhdrTheGrandparentNeedsFPlusOneVerifiedMembers() {
|
|
+ final Block four = anchor(sealsOver(p, 0, 1, 2, 3));
|
|
+ final Block three = anchor(sealsOver(p, 0, 1, 2));
|
|
+ final MutableBlockchain chain = chainWith(four);
|
|
+ assertThat(decision(AereCertifiedDecisionTest::aboveHhdr, H_EV).decidedBy(chain, four.getHeader()))
|
|
+ .as("f + 1 = 4 verified members of the ten: the grandparent, block 2, never the parent p")
|
|
+ .contains(new AereDecidedHead.Decided(2L, b2.getHash()));
|
|
+ assertThat(decision(AereCertifiedDecisionTest::aboveHhdr, H_EV).decidedBy(chain, three.getHeader()))
|
|
+ .as("control: f = 3 verified members prove nothing")
|
|
+ .isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aSealThatDoesNotVerifyCountsForNothing() {
|
|
+ final List<FalconSeal> seals = sealsOver(p, 0, 1, 2);
|
|
+ // index 3 signs the message of ANOTHER block (b2): a seal of the right shape that does not verify over M(p)
|
|
+ seals.addAll(sealsOver(b2, 3));
|
|
+ final Block anchor = anchor(seals);
|
|
+ final MutableBlockchain chain = chainWith(anchor);
|
|
+ assertThat(decision(AereCertifiedDecisionTest::aboveHhdr, H_EV).decidedBy(chain, anchor.getHeader()))
|
|
+ .as("three verified members and one seal that does not verify over M(p): nothing is decided")
|
|
+ .isEmpty();
|
|
+ assertThat(registryCalls.get())
|
|
+ .as("control: the seals were checked against the registry")
|
|
+ .isGreaterThan(0);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theNumberThatProvesIsTheVerifiedCountNotTheConfiguredThreshold() {
|
|
+ assertThat(config.minSealsAt(ANCHOR_HEIGHT)).as("control: the configuration asks for K = 7").isEqualTo(7);
|
|
+ final Block three = anchor(sealsOver(p, 0, 1, 2));
|
|
+ final MutableBlockchain chain = chainWith(three);
|
|
+ assertThat(decision(AereCertifiedDecisionTest::aboveHhdr, H_EV).decidedBy(chain, three.getHeader()))
|
|
+ .as("K = 7 is asked, three seals verify: three is not f + 1, nothing is decided")
|
|
+ .isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aParentBelowHevDecidesNothing() {
|
|
+ final Block four = anchor(sealsOver(p, 0, 1, 2, 3));
|
|
+ final MutableBlockchain chain = chainWith(four);
|
|
+ assertThat(decision(AereCertifiedDecisionTest::aboveHhdr, 4L).decidedBy(chain, four.getHeader()))
|
|
+ .as("H_ev = 4: rule D does not govern the commits on p (3), so its seals prove nothing")
|
|
+ .isEmpty();
|
|
+ assertThat(decision(AereCertifiedDecisionTest::aboveHhdr, 3L).decidedBy(chain, four.getHeader()))
|
|
+ .as("control: H_ev = 3, the same certificate decides the grandparent")
|
|
+ .contains(new AereDecidedHead.Decided(2L, b2.getHash()));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aNonMemberAndASecondIndexOfOneMemberCountForNothing() {
|
|
+ final Block withOutsider = anchor(sealsOver(p, 0, 1, 2, OUTSIDER));
|
|
+ final Block withSecond = anchor(sealsOver(p, 0, 1, 2, SECOND_OF_ZERO));
|
|
+ final MutableBlockchain chain = chainWith(withOutsider);
|
|
+ assertThat(
|
|
+ decision(AereCertifiedDecisionTest::aboveHhdr, H_EV)
|
|
+ .decidedBy(chain, withOutsider.getHeader()))
|
|
+ .as("a valid seal of an index bound outside the set is no member: three, nothing is decided")
|
|
+ .isEmpty();
|
|
+ assertThat(
|
|
+ decision(AereCertifiedDecisionTest::aboveHhdr, H_EV)
|
|
+ .decidedBy(chain, withSecond.getHeader()))
|
|
+ .as("a valid seal of a second index of validator 0 is the same member: three, nothing is decided")
|
|
+ .isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void anAnchorInsideALapseWindowOf2800DecidesNothing() {
|
|
+ final PqAnchorConfig live =
|
|
+ new PqAnchorConfig(
|
|
+ PqAnchorLapse.CHAIN_ID,
|
|
+ 13_014_000L,
|
|
+ Map.of(13_014_000L, 3),
|
|
+ OptionalInt.empty(),
|
|
+ false,
|
|
+ OptionalInt.empty(),
|
|
+ OptionalInt.of(32));
|
|
+ final long inside = 13_014_000L + 32L * 9_000L;
|
|
+ final long outside = 13_014_000L + 32L * 30_000L;
|
|
+ assertThat(PqAnchorLapse.windowCovering(PqAnchorLapse.CHAIN_ID, inside))
|
|
+ .as("control: the first height is inside a named window")
|
|
+ .isPresent();
|
|
+ assertThat(PqAnchorLapse.windowCovering(PqAnchorLapse.CHAIN_ID, outside))
|
|
+ .as("control: the second is not")
|
|
+ .isEmpty();
|
|
+ assertThat(decideAt(live, inside)).as("inside a lapse window: nothing is decided").isEmpty();
|
|
+ assertThat(decideAt(live, outside))
|
|
+ .as("control: the same construction outside it decides the grandparent")
|
|
+ .isPresent();
|
|
+ }
|
|
+
|
|
+ /** An anchor of 2800 at {@code a} over a parent with f + 1 verified seals, headers served by a mock chain. */
|
|
+ private Optional<AereDecidedHead.Decided> decideAt(final PqAnchorConfig live, final long a) {
|
|
+ final BlockHeader grand = header(a - 2L, Hash.ZERO, List.of());
|
|
+ final BlockHeader parent = header(a - 1L, grand.getHash(), List.of());
|
|
+ final Bytes32 message =
|
|
+ PqAnchor.commitMessage(PqAnchorLapse.CHAIN_ID, a - 1L, parent.getHash().getBytes());
|
|
+ final List<FalconSeal> seals = new ArrayList<>();
|
|
+ for (final int i : new int[] {0, 1, 2, 3}) {
|
|
+ seals.add(
|
|
+ new FalconSeal(
|
|
+ i,
|
|
+ Bytes.wrap(SealSchemes.FALCON_512.sign(falconPrivate.get(i), message.toArray()).orElseThrow())));
|
|
+ }
|
|
+ final BlockHeader anchor = header(a, parent.getHash(), seals);
|
|
+ final Blockchain chain = mock(Blockchain.class);
|
|
+ when(chain.getBlockHeader(parent.getHash())).thenReturn(Optional.of(parent));
|
|
+ return new AereCertifiedDecision(
|
|
+ live, codec, registry(), h -> validators, AereCertifiedDecisionTest::aboveHhdr, 0L)
|
|
+ .decidedBy(chain, anchor);
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // fixture
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /** The seals of the given indexes over M(b), each signed with that index's real Falcon key. */
|
|
+ private List<FalconSeal> sealsOver(final Block b, final int... indexes) {
|
|
+ final Bytes32 message = PqAnchor.commitMessage(CHAIN, b.getHeader().getNumber(), b.getHash().getBytes());
|
|
+ final List<FalconSeal> out = new ArrayList<>();
|
|
+ for (final int i : indexes) {
|
|
+ out.add(
|
|
+ new FalconSeal(
|
|
+ i,
|
|
+ Bytes.wrap(SealSchemes.FALCON_512.sign(falconPrivate.get(i), message.toArray()).orElseThrow())));
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ /** Index i bound to validator i (10 to an outsider, 11 to validator 0), verified with index i's key. */
|
|
+ private PqSignerRegistry registry() {
|
|
+ return new PqSignerRegistry() {
|
|
+ @Override
|
|
+ public Address addressForIndexAtHistoric(final long blockNumber, final int validatorIndex) {
|
|
+ registryCalls.incrementAndGet();
|
|
+ if (validatorIndex == OUTSIDER) {
|
|
+ return outsider;
|
|
+ }
|
|
+ if (validatorIndex == SECOND_OF_ZERO) {
|
|
+ return validators.get(0);
|
|
+ }
|
|
+ return validatorIndex >= 0 && validatorIndex < VALIDATORS
|
|
+ ? validators.get(validatorIndex)
|
|
+ : null;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Address addressForIndexAtOwnHead(final long blockNumber, final int validatorIndex) {
|
|
+ return addressForIndexAtHistoric(blockNumber, validatorIndex);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtHistoric(
|
|
+ final long blockNumber,
|
|
+ final int validatorIndex,
|
|
+ final Bytes message,
|
|
+ final Bytes signature) {
|
|
+ registryCalls.incrementAndGet();
|
|
+ return validatorIndex >= 0
|
|
+ && validatorIndex <= SECOND_OF_ZERO
|
|
+ && SealSchemes.FALCON_512.verifyRaw(
|
|
+ falconPublic.get(validatorIndex), message.toArray(), signature.toArray());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtOwnHead(
|
|
+ final long blockNumber,
|
|
+ final int validatorIndex,
|
|
+ final Bytes message,
|
|
+ final Bytes signature) {
|
|
+ return verifyAtHistoric(blockNumber, validatorIndex, message, signature);
|
|
+ }
|
|
+ };
|
|
+ }
|
|
+
|
|
+ private MutableBlockchain chainWith(final Block anchor) {
|
|
+ final MutableBlockchain chain =
|
|
+ InMemoryKeyValueStorageProvider.createInMemoryBlockchain(
|
|
+ genesis, BftBlockHeaderFunctions.forOnchainBlock(codec));
|
|
+ chain.appendBlock(b1, List.of());
|
|
+ chain.appendBlock(b2, List.of());
|
|
+ chain.appendBlock(p, List.of());
|
|
+ chain.appendBlock(anchor, List.of());
|
|
+ return chain;
|
|
+ }
|
|
+
|
|
+ /** An anchor over p carrying {@code certificate} (sorted, its digest in vanityData). */
|
|
+ private Block anchor(final List<FalconSeal> certificate) {
|
|
+ return block(p, certificate);
|
|
+ }
|
|
+
|
|
+ private Block block(final Block parent, final List<FalconSeal> certificate) {
|
|
+ final long number = parent == null ? 0L : parent.getHeader().getNumber() + 1;
|
|
+ return new Block(
|
|
+ header(number, parent == null ? Hash.ZERO : parent.getHash(), certificate), BlockBody.empty());
|
|
+ }
|
|
+
|
|
+ private BlockHeader header(final long number, final Hash parentHash, final List<FalconSeal> certificate) {
|
|
+ tag++;
|
|
+ final BftExtraData extra;
|
|
+ if (certificate.isEmpty()) {
|
|
+ extra =
|
|
+ new BftExtraData(
|
|
+ Bytes32.leftPad(Bytes.ofUnsignedLong(tag)), List.of(), Optional.empty(), 0, validators);
|
|
+ } else {
|
|
+ final List<FalconSeal> sorted = PqAnchor.sortedByIndex(certificate);
|
|
+ extra =
|
|
+ new BftExtraData(
|
|
+ PqAnchor.anchorDigest(CHAIN, number - 1L, parentHash.getBytes(), sorted),
|
|
+ List.of(),
|
|
+ Optional.empty(),
|
|
+ 0,
|
|
+ validators,
|
|
+ sorted, java.util.List.of(), BftExtraData.NO_CERTIFICATE_ROUND);
|
|
+ }
|
|
+ return new BlockHeaderTestFixture()
|
|
+ .number(number)
|
|
+ .parentHash(parentHash)
|
|
+ .difficulty(Difficulty.ONE)
|
|
+ .extraData(codec.encode(extra))
|
|
+ .timestamp(number)
|
|
+ .coinbase(validators.get(0))
|
|
+ .blockHeaderFunctions(BftBlockHeaderFunctions.forOnchainBlock(codec))
|
|
+ .buildHeader();
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereCertifiedDecisionV3Test.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereCertifiedDecisionV3Test.java
|
|
new file mode 100644
|
|
index 0000000000..0906cd4923
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereCertifiedDecisionV3Test.java
|
|
@@ -0,0 +1,377 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AereCertifiedDecision;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead;
|
|
+import org.hyperledger.besu.consensus.common.bft.AerePqFinalityTags;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorV2;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorV3;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSignerRegistry;
|
|
+import org.hyperledger.besu.consensus.common.bft.SchemeSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealScheme;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealSchemes;
|
|
+import org.hyperledger.besu.crypto.SecureRandomProvider;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
+import org.hyperledger.besu.ethereum.core.Block;
|
|
+import org.hyperledger.besu.ethereum.core.BlockBody;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+import org.hyperledger.besu.ethereum.core.Difficulty;
|
|
+import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider;
|
|
+
|
|
+import java.security.SecureRandom;
|
|
+import java.util.ArrayList;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+import java.util.function.LongPredicate;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), D-470, pasul 4 (2026-10-01): {@link AereCertifiedDecision} at a v3 anchor (project section 3.1 B, marker
|
|
+ * AERE-R1B-PARINTE-Q; vector class VDEC). Real Falcon-512 keys, N = 10 (Q = 7, f + 1 = 4), chain genesis, 1, 2, p = 3,
|
|
+ * anchor A = 4 = H_r (so p = H_r - 1 is round-bound: decision H3).
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>Q verified distinct members of ONE round over M_r(p): the PARENT, below H_hdr and above, with no H_ev;
|
|
+ * <li>Q - 1 of them below H_hdr: NOTHING. No ECDSA branch from H_r (RF-C3): control, the same headers with H_r unset give
|
|
+ * the parent through the old rule;
|
|
+ * <li>from H_hdr, f + 1 .. Q - 1 with p >= H_ev: the GRANDPARENT; with p below H_ev: nothing;
|
|
+ * <li>seals over ANOTHER round's message count for nothing (no sum over rounds), nor a non-member, nor a second index;
|
|
+ * <li>what proves the parent is the quorum of the set, never the configured K (here K = 3);
|
|
+ * <li>the empty v3 certificate (K_eff = 0) proves nothing, and B1's predicate says it carries no certificate.
|
|
+ * </ul>
|
|
+ */
|
|
+public class AereCertifiedDecisionV3Test {
|
|
+
|
|
+ private static final long CHAIN = 220_883L;
|
|
+ private static final long ANCHOR_BLOCK = 2L;
|
|
+ private static final long V2 = 3L;
|
|
+ private static final long HR = 4L;
|
|
+ private static final int VALIDATORS = 10;
|
|
+ private static final int OUTSIDER = 10;
|
|
+ private static final int SECOND_OF_ZERO = 11;
|
|
+ private static final int ROUND = 2;
|
|
+
|
|
+ private final QbftExtraDataCodec codec = new QbftExtraDataCodec();
|
|
+ private final PqAnchorConfig withHr = config(true);
|
|
+ private final PqAnchorConfig withoutHr = config(false);
|
|
+ private final SecureRandom random = SecureRandomProvider.createSecureRandom();
|
|
+ private final List<Address> validators = new ArrayList<>();
|
|
+ private final Address outsider = Address.fromHexString("0x" + "0".repeat(38) + "ee");
|
|
+ private final List<byte[]> falconPublic = new ArrayList<>();
|
|
+ private final List<SealScheme.PrivateHandle> falconPrivate = new ArrayList<>();
|
|
+ private long tag;
|
|
+
|
|
+ private Block genesis;
|
|
+ private Block b1;
|
|
+ private Block b2;
|
|
+ private Block p;
|
|
+
|
|
+ @BeforeEach
|
|
+ public void setUp() {
|
|
+ for (int i = 0; i < VALIDATORS; i++) {
|
|
+ validators.add(Address.fromHexString("0x" + "0".repeat(38) + "d" + i));
|
|
+ }
|
|
+ for (int i = 0; i <= SECOND_OF_ZERO; i++) {
|
|
+ final SealScheme.GeneratedPair pair = SealSchemes.FALCON_512.generate(random);
|
|
+ falconPublic.add(pair.publicRegistryForm());
|
|
+ falconPrivate.add(pair.privateKey());
|
|
+ }
|
|
+ genesis = block(null, null, 0);
|
|
+ b1 = block(genesis, null, 0);
|
|
+ b2 = block(b1, null, 0);
|
|
+ p = block(b2, null, 0);
|
|
+ }
|
|
+
|
|
+ private static PqAnchorConfig config(final boolean armHr) {
|
|
+ final PqAnchorConfig c =
|
|
+ new PqAnchorConfig(
|
|
+ CHAIN,
|
|
+ ANCHOR_BLOCK,
|
|
+ Map.of(ANCHOR_BLOCK, 3),
|
|
+ OptionalInt.empty(),
|
|
+ false,
|
|
+ OptionalInt.empty(),
|
|
+ OptionalInt.empty())
|
|
+ .withAnchorV2Block(V2);
|
|
+ return armHr ? c.withCommitRoundBlock(HR) : c;
|
|
+ }
|
|
+
|
|
+ private AereCertifiedDecision decision(
|
|
+ final PqAnchorConfig cfg, final LongPredicate headerSealActive, final long hEv) {
|
|
+ return new AereCertifiedDecision(cfg, codec, registry(), h -> validators, headerSealActive, hEv);
|
|
+ }
|
|
+
|
|
+ private static boolean belowHhdr(final long h) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ private static boolean fromHhdr(final long h) {
|
|
+ return h >= HR;
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aQuorumOfOneRoundDecidesTheParentWithoutHev() {
|
|
+ final Block anchor = anchor(ROUND, sealsOver(p, ROUND, 0, 1, 2, 3, 4, 5, 6));
|
|
+ final MutableBlockchain chain = chainWith(anchor);
|
|
+ final AereDecidedHead.Decided parent = new AereDecidedHead.Decided(3L, p.getHash());
|
|
+ assertThat(decision(withHr, AereCertifiedDecisionV3Test::belowHhdr, Long.MAX_VALUE).decidedBy(chain, anchor.getHeader()))
|
|
+ .as("Q = 7 verified members of round 2 over M_2(p): the PARENT, with H_ev never reached")
|
|
+ .contains(parent);
|
|
+ assertThat(decision(withHr, AereCertifiedDecisionV3Test::fromHhdr, Long.MAX_VALUE).decidedBy(chain, anchor.getHeader()))
|
|
+ .as("and from H_hdr too: the parent, never only the grandparent")
|
|
+ .contains(parent);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void belowTheQuorumBelowHhdrNothingIsDecidedThereIsNoEcdsaBranch() {
|
|
+ final Block anchor = anchor(ROUND, sealsOver(p, ROUND, 0, 1, 2, 3, 4, 5));
|
|
+ final MutableBlockchain chain = chainWith(anchor);
|
|
+ assertThat(decision(withHr, AereCertifiedDecisionV3Test::belowHhdr, 0L).decidedBy(chain, anchor.getHeader()))
|
|
+ .as("RF-C3: Q - 1 of one round, below H_hdr, at a >= H_r: NOTHING (no ECDSA branch from H_r)")
|
|
+ .isEmpty();
|
|
+ assertThat(decision(withoutHr, AereCertifiedDecisionV3Test::belowHhdr, 0L).decidedBy(chain, anchor.getHeader()))
|
|
+ .as("control: with H_r unset the same header is judged by the old rule, which below H_hdr names the parent")
|
|
+ .contains(new AereDecidedHead.Decided(3L, p.getHash()));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void fromHhdrFPlusOneOfOneRoundDecidesTheGrandparentWhenThePArentIsAtOrAboveHev() {
|
|
+ final Block anchor = anchor(ROUND, sealsOver(p, ROUND, 0, 1, 2, 3));
|
|
+ final MutableBlockchain chain = chainWith(anchor);
|
|
+ assertThat(decision(withHr, AereCertifiedDecisionV3Test::fromHhdr, 3L).decidedBy(chain, anchor.getHeader()))
|
|
+ .as("f + 1 = 4 of round 2, from H_hdr, p = H_ev: the GRANDPARENT (Teorema 3 with M_r)")
|
|
+ .contains(new AereDecidedHead.Decided(2L, b2.getHash()));
|
|
+ assertThat(decision(withHr, AereCertifiedDecisionV3Test::fromHhdr, 4L).decidedBy(chain, anchor.getHeader()))
|
|
+ .as("control: p below H_ev decides nothing")
|
|
+ .isEmpty();
|
|
+ final Block three = anchor(ROUND, sealsOver(p, ROUND, 0, 1, 2));
|
|
+ assertThat(decision(withHr, AereCertifiedDecisionV3Test::fromHhdr, 3L).decidedBy(chainWith(three), three.getHeader()))
|
|
+ .as("control: f = 3 proves nothing")
|
|
+ .isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void sealsOverAnotherRoundsMessageCountForNothing() {
|
|
+ // seven rows under round 2: four signed over M_2(p), three over M_0(p) (the same block, another round)
|
|
+ final List<SchemeSeal> rows = new ArrayList<>(sealsOver(p, ROUND, 0, 1, 2, 3));
|
|
+ rows.addAll(sealsOver(p, 0, 4, 5, 6));
|
|
+ final Block anchor = anchor(ROUND, rows);
|
|
+ final MutableBlockchain chain = chainWith(anchor);
|
|
+ assertThat(decision(withHr, AereCertifiedDecisionV3Test::belowHhdr, 0L).decidedBy(chain, anchor.getHeader()))
|
|
+ .as("4 + 3 from two rounds is never 7: below H_hdr nothing")
|
|
+ .isEmpty();
|
|
+ assertThat(decision(withHr, AereCertifiedDecisionV3Test::fromHhdr, 3L).decidedBy(chain, anchor.getHeader()))
|
|
+ .as("and from H_hdr only the grandparent, on the four of round 2")
|
|
+ .contains(new AereDecidedHead.Decided(2L, b2.getHash()));
|
|
+ final AereCertifiedDecision d = decision(withHr, AereCertifiedDecisionV3Test::fromHhdr, 3L);
|
|
+ final BftExtraData extra = codec.decodeRaw(anchor.getHeader().getExtraData());
|
|
+ assertThat(d.verifiedMembersOfRound(p.getHeader(), extra, validators, ROUND)).isEqualTo(4);
|
|
+ assertThat(d.verifiedMembersOfRound(p.getHeader(), extra, validators, 0))
|
|
+ .as("control of the metric: the same rows counted over M_0 give the other three")
|
|
+ .isEqualTo(3);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aNonMemberAndASecondIndexOfOneMemberCountForNothing() {
|
|
+ final Block anchor = anchor(ROUND, sealsOver(p, ROUND, 0, 1, 2, 3, 4, 5, OUTSIDER, SECOND_OF_ZERO));
|
|
+ final MutableBlockchain chain = chainWith(anchor);
|
|
+ assertThat(decision(withHr, AereCertifiedDecisionV3Test::belowHhdr, 0L).decidedBy(chain, anchor.getHeader()))
|
|
+ .as("six members, an outsider and a second index of validator 0: six, not the quorum of seven")
|
|
+ .isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theParentNeedsTheQuorumOfTheSetNotTheConfiguredK() {
|
|
+ assertThat(withHr.minSealsAt(HR)).as("control: the configuration asks for K = 3").isEqualTo(3);
|
|
+ final Block five = anchor(ROUND, sealsOver(p, ROUND, 0, 1, 2, 3, 4));
|
|
+ assertThat(decision(withHr, AereCertifiedDecisionV3Test::belowHhdr, 0L).decidedBy(chainWith(five), five.getHeader()))
|
|
+ .as("five verified members are above K = 3 and below Q = 7: not the parent")
|
|
+ .isEmpty();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theEmptyV3CertificateProvesNothing() {
|
|
+ final Block empty = anchor(0, List.of());
|
|
+ final BftExtraData extra = codec.decodeRaw(empty.getHeader().getExtraData());
|
|
+ assertThat(extra.getCertificateRound()).as("control: the header carries the empty v3, round 0").hasValue(0);
|
|
+ assertThat(AerePqFinalityTags.carriesCertificate(extra))
|
|
+ .as("B1's predicate: the empty v3 carries no certificate (decision H5)")
|
|
+ .isFalse();
|
|
+ assertThat(decision(withHr, AereCertifiedDecisionV3Test::belowHhdr, 0L).decidedBy(chainWith(empty), empty.getHeader()))
|
|
+ .isEmpty();
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // B1 (the finalized and safe tags) on a v3 anchor: AerePqFinalityTags reads the same answer
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void b1MovesTheTagsToTheParentOnAV3AnchorWithAQuorumOfOneRound() {
|
|
+ final MutableBlockchain chain = chainUpToP();
|
|
+ AerePqFinalityTags.installDecided(
|
|
+ withHr, chain, decision(withHr, AereCertifiedDecisionV3Test::belowHhdr, Long.MAX_VALUE).over(chain));
|
|
+ assertThat(chain.getFinalized()).as("control: no tag before the anchor").isEmpty();
|
|
+ chain.appendBlock(anchor(ROUND, sealsOver(p, ROUND, 0, 1, 2, 3, 4, 5, 6)), List.of());
|
|
+ assertThat(chain.getFinalized())
|
|
+ .as("a v3 anchor with Q of round 2 over p: finalized names p, the PARENT (1(b), 3.1 B)")
|
|
+ .contains(p.getHash());
|
|
+ assertThat(chain.getSafeBlock()).contains(p.getHash());
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void b1DoesNotMoveOnTheEmptyV3NorOnAMixOfRounds() {
|
|
+ final MutableBlockchain chain = chainUpToP();
|
|
+ AerePqFinalityTags.installDecided(
|
|
+ withHr, chain, decision(withHr, AereCertifiedDecisionV3Test::belowHhdr, Long.MAX_VALUE).over(chain));
|
|
+ chain.appendBlock(anchor(0, List.of()), List.of());
|
|
+ assertThat(chain.getFinalized()).as("the empty v3 (K_eff = 0) proves nothing").isEmpty();
|
|
+ final MutableBlockchain mixed = chainUpToP();
|
|
+ AerePqFinalityTags.installDecided(
|
|
+ withHr, mixed, decision(withHr, AereCertifiedDecisionV3Test::belowHhdr, Long.MAX_VALUE).over(mixed));
|
|
+ final List<SchemeSeal> rows = new ArrayList<>(sealsOver(p, ROUND, 0, 1, 2, 3));
|
|
+ rows.addAll(sealsOver(p, 0, 4, 5, 6));
|
|
+ mixed.appendBlock(anchor(ROUND, rows), List.of());
|
|
+ assertThat(mixed.getFinalized()).as("4 of round 2 and 3 of round 0 are never a quorum").isEmpty();
|
|
+ }
|
|
+
|
|
+ private MutableBlockchain chainUpToP() {
|
|
+ final MutableBlockchain chain =
|
|
+ InMemoryKeyValueStorageProvider.createInMemoryBlockchain(genesis, BftBlockHeaderFunctions.forOnchainBlock(codec));
|
|
+ chain.appendBlock(b1, List.of());
|
|
+ chain.appendBlock(b2, List.of());
|
|
+ chain.appendBlock(p, List.of());
|
|
+ return chain;
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // fixture
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /** Rows of the given indexes over M_round(b) (COMMIT-2, computed with the primitive), each signed with its real key. */
|
|
+ private List<SchemeSeal> sealsOver(final Block b, final int round, final int... indexes) {
|
|
+ final Bytes32 message =
|
|
+ PqAnchor.commitMessageRound(CHAIN, b.getHeader().getNumber(), round, b.getHash().getBytes());
|
|
+ final List<SchemeSeal> out = new ArrayList<>();
|
|
+ for (final int i : indexes) {
|
|
+ out.add(
|
|
+ new SchemeSeal(
|
|
+ SealSchemes.FALCON_512.wireId(),
|
|
+ i,
|
|
+ Bytes.wrap(SealSchemes.FALCON_512.sign(falconPrivate.get(i), message.toArray()).orElseThrow())));
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ private PqSignerRegistry registry() {
|
|
+ return new PqSignerRegistry() {
|
|
+ @Override
|
|
+ public Address addressForIndexAtHistoric(final long blockNumber, final int validatorIndex) {
|
|
+ if (validatorIndex == OUTSIDER) {
|
|
+ return outsider;
|
|
+ }
|
|
+ if (validatorIndex == SECOND_OF_ZERO) {
|
|
+ return validators.get(0);
|
|
+ }
|
|
+ return validatorIndex >= 0 && validatorIndex < VALIDATORS ? validators.get(validatorIndex) : null;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Address addressForIndexAtOwnHead(final long blockNumber, final int validatorIndex) {
|
|
+ return addressForIndexAtHistoric(blockNumber, validatorIndex);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtHistoric(
|
|
+ final long blockNumber, final int validatorIndex, final Bytes message, final Bytes signature) {
|
|
+ return validatorIndex >= 0
|
|
+ && validatorIndex <= SECOND_OF_ZERO
|
|
+ && SealSchemes.FALCON_512.verifyRaw(falconPublic.get(validatorIndex), message.toArray(), signature.toArray());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtOwnHead(
|
|
+ final long blockNumber, final int validatorIndex, final Bytes message, final Bytes signature) {
|
|
+ return verifyAtHistoric(blockNumber, validatorIndex, message, signature);
|
|
+ }
|
|
+ };
|
|
+ }
|
|
+
|
|
+ private MutableBlockchain chainWith(final Block anchor) {
|
|
+ final MutableBlockchain chain =
|
|
+ InMemoryKeyValueStorageProvider.createInMemoryBlockchain(genesis, BftBlockHeaderFunctions.forOnchainBlock(codec));
|
|
+ chain.appendBlock(b1, List.of());
|
|
+ chain.appendBlock(b2, List.of());
|
|
+ chain.appendBlock(p, List.of());
|
|
+ chain.appendBlock(anchor, List.of());
|
|
+ return chain;
|
|
+ }
|
|
+
|
|
+ /** A v3 anchor over p of round {@code round} carrying {@code rows} (canonical; D3 in vanityData). */
|
|
+ private Block anchor(final int round, final List<SchemeSeal> rows) {
|
|
+ return block(p, rows, round);
|
|
+ }
|
|
+
|
|
+ private Block block(final Block parent, final List<SchemeSeal> rows, final int round) {
|
|
+ final long number = parent == null ? 0L : parent.getHeader().getNumber() + 1;
|
|
+ return new Block(header(number, parent == null ? Hash.ZERO : parent.getHash(), rows, round), BlockBody.empty());
|
|
+ }
|
|
+
|
|
+ private BlockHeader header(final long number, final Hash parentHash, final List<SchemeSeal> rows, final int round) {
|
|
+ tag++;
|
|
+ final BftExtraData extra;
|
|
+ if (rows == null) {
|
|
+ extra = new BftExtraData(Bytes32.leftPad(Bytes.ofUnsignedLong(tag)), List.of(), Optional.empty(), 0, validators);
|
|
+ } else {
|
|
+ final List<SchemeSeal> sorted = new ArrayList<>(rows);
|
|
+ sorted.sort(PqAnchorV2.CANONICAL);
|
|
+ extra =
|
|
+ new BftExtraData(
|
|
+ PqAnchorV3.anchorDigestV3(
|
|
+ CHAIN, number - 1L, parentHash.getBytes(), new PqAnchorV3.Certificate(round, sorted)),
|
|
+ List.of(),
|
|
+ Optional.empty(),
|
|
+ 0,
|
|
+ validators,
|
|
+ List.of(),
|
|
+ sorted,
|
|
+ round);
|
|
+ }
|
|
+ return new BlockHeaderTestFixture()
|
|
+ .number(number)
|
|
+ .parentHash(parentHash)
|
|
+ .difficulty(Difficulty.ONE)
|
|
+ .extraData(codec.encode(extra))
|
|
+ .timestamp(number)
|
|
+ .coinbase(validators.get(0))
|
|
+ .blockHeaderFunctions(BftBlockHeaderFunctions.forOnchainBlock(codec))
|
|
+ .buildHeader();
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereD412RealHeadersTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereD412RealHeadersTest.java
|
|
new file mode 100644
|
|
index 0000000000..e48c6962fa
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereD412RealHeadersTest.java
|
|
@@ -0,0 +1,420 @@
|
|
+/*
|
|
+ * AERE D-412 / capul decis, pasul 1 (2026-09-30, dupa revizuire): tinta colectorului pe anteturi REALE de pe 2800 si 28001.
|
|
+ *
|
|
+ * DE CE EXISTA. Colectorul cauta voturile unui bloc STOCAT sub AereVoteCounts.Target.atRound(bloc, n, r): digestul si digestul
|
|
+ * sigiliului ECDSA ale rundei r si mesajul pe care il semneaza sigiliul post-cuantic. Probele pe unitate folosesc un model de
|
|
+ * bloc, deci egalitatea cu ce au semnat validatorii ADEVARATI era presupusa (revizuirea: "PRESUPUSA, nu masurata"). Aici se
|
|
+ * masoara pe semnaturile lor, fara nicio cheie privata: perechi [parinte, ancora] luate de pe lanturile vii pe 28 sept
|
|
+ * (corpusul fuzzerului de ancore, extras de cap-decis-besu/extrage-blocuri-reale.py, amprentele surselor in
|
|
+ * rezultate/extragere-blocuri-reale.txt), cu adaptorul si codecul reale ale lui Besu.
|
|
+ *
|
|
+ * CE MASOARA, fiecare cu controlul lui (aceeasi metoda trebuie sa poata iesi rosie):
|
|
+ * - anteturile se refac fiecare la propria amprenta (altfel restul nu masoara nimic);
|
|
+ * - SIGILIILE ECDSA din anteturile lui 2800 (sigiliile commit-urilor care au decis blocul, copiate in antet) se recupereaza peste
|
|
+ * Target.atRound(bloc stocat, n, runda din element 3).commitDigest() la validatori din set, cel putin Q; INCLUSIV trei ancore
|
|
+ * decise la RUNDA 1. Control: la alta runda nicio recuperare nu cade in set;
|
|
+ * - CERTIFICATELE ancorelor (v1 la 13,2 milioane, v2 hibrid la 20,4 milioane pe 2800, v2 hibrid peste H_hdr pe 28001) poarta
|
|
+ * sigiliile post-cuantice ale COMMIT-urilor pe parinte; fiecare se verifica peste Target.atRound(parintele stocat, ...)
|
|
+ * .pqSealMessage(), cu ancora armata ca pe lant: Falcon cu cheile publice ale registrului, iar pe 28001 si SLH-DSA cu cheile
|
|
+ * epocii v3. Control: peste mesajul de dinainte de ancora (digestul sigiliului) niciun sigiliu nu se verifica;
|
|
+ * - RUNDA > 0 si mesajul PQ: ancora 13.267.824 e din fereastra E a lui 2800 (10 aug, ancora DEZARMATA, atasarea pornita). Masurat
|
|
+ * in pre-zborul din 30 sept (cu o cautare pe toate cheile si toate formele): certificatul ei e cel VECHI, pe bloc, adica
|
|
+ * sigiliile Falcon ale commit-urilor pe blocul INSUSI, peste digestul lui de commit la runda lui, runda 1. Deci acolo se cere
|
|
+ * ca Target.atRound(blocul stocat, n, 1).pqSealMessage(), cu ancora dezarmata, sa fie exact ce au semnat validatorii; control:
|
|
+ * runda 0 si forma de ancora a parintelui;
|
|
+ * - peste H_hdr (28001, treapta 5, fara sigilii ECDSA in antet): sigiliul propunatorului din elementul 6 se verifica peste
|
|
+ * mesajul de propunere construit din Target.atRound(bloc stocat, n, r).digest(). Control: la runda r+1 nu se verifica; si
|
|
+ * (a doua revizuire, 30 sept) doua controale care schimba fiecare UN singur lucru: alt digest la aceeasi runda, alta runda
|
|
+ * peste acelasi digest (controlul r+1 le schimba pe amandoua deodata, deci nu izola digestul).
|
|
+ * CE NU MASOARA: mesajele Commit capturate de pe retea (nu le avem; sigiliile din antet si din certificat sunt semnaturile lor),
|
|
+ * sigiliile SLH-DSA de pe 2800 (cheile hibride ale lui 2800 nu sunt in resurse) si niciun bloc de runda > 0 peste H_hdr. Toti
|
|
+ * parintii din corpus si ambele anteturi ale lui 28001 sunt de runda 0 (numarat pe elementul 3, 30 sept), deci nicio plantare pe
|
|
+ * drumul rundei din Target nu poate inrosi proba de peste H_hdr si nici certificatele peste parinte; certificatul vechi al
|
|
+ * ferestrei E (runda 1, blocul insusi) e singurul mesaj PQ real la o runda > 0.
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AerePqIdentity;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftHelpers;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.SchemeSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealScheme;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealSchemes;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockAdaptor;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockInterfaceAdaptor;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.AereVoteCounts;
|
|
+import org.hyperledger.besu.crypto.SECPSignature;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.BlobGas;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.datatypes.LogsBloomFilter;
|
|
+import org.hyperledger.besu.datatypes.Wei;
|
|
+import org.hyperledger.besu.ethereum.core.Block;
|
|
+import org.hyperledger.besu.ethereum.core.BlockBody;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+import org.hyperledger.besu.ethereum.core.Difficulty;
|
|
+import org.hyperledger.besu.ethereum.core.Util;
|
|
+
|
|
+import java.io.InputStream;
|
|
+import java.net.URL;
|
|
+import java.nio.file.Path;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collection;
|
|
+import java.util.Collections;
|
|
+import java.util.HashSet;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+import java.util.Set;
|
|
+
|
|
+import com.fasterxml.jackson.databind.JsonNode;
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+public class AereD412RealHeadersTest {
|
|
+
|
|
+ private static final String DIR = "/aere-d412/";
|
|
+ private static final QbftExtraDataCodec CODEC = new QbftExtraDataCodec();
|
|
+ private static final QbftBlockInterface BLOCK_INTERFACE =
|
|
+ new QbftBlockInterfaceAdaptor(new BftBlockInterface(CODEC));
|
|
+ private static final long CHAIN_2800 = 2800L;
|
|
+ private static final long ANCHOR_2800 = 13014000L;
|
|
+ private static final long CHAIN_28001 = 28001L;
|
|
+ private static final long ANCHOR_28001 = 64L;
|
|
+ private static final long H_ID_28001 = 3080010L;
|
|
+ // the pins the published epochs are loaded with (the same as aips/aip22-conformitate/besu/ruleaza-harness-besu.sh)
|
|
+ private static final String PINS_28001 =
|
|
+ "3080010:0xd19eef4a2d0db81b71d856e7c7dfa27825711f299c4f0b692f2549e6db32635b,"
|
|
+ + "3097600:0xb5847f46f5a6ce3eb9dc1dc0f0c48eefd98d835e7bd4b27398879807ac26a678";
|
|
+ private static final SealScheme FALCON = SealSchemes.FALCON_512;
|
|
+
|
|
+ /** One vector: the parent and the anchor, as the chain served them. */
|
|
+ private static final class Pair {
|
|
+ private final String id;
|
|
+ private final long chain;
|
|
+ private final BlockHeader parent;
|
|
+ private final BlockHeader anchor;
|
|
+
|
|
+ Pair(final String id, final long chain, final BlockHeader parent, final BlockHeader anchor) {
|
|
+ this.id = id;
|
|
+ this.chain = chain;
|
|
+ this.parent = parent;
|
|
+ this.anchor = anchor;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ public void disarm() {
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ AerePqIdentity.uninstall();
|
|
+ for (final String k :
|
|
+ List.of(
|
|
+ AerePqIdentity.PROPERTY_BLOCK,
|
|
+ AerePqIdentity.PROPERTY_REGISTRIES,
|
|
+ AerePqIdentity.PROPERTY_HASHES,
|
|
+ AerePqIdentity.PROPERTY_KEYS_FROM)) {
|
|
+ System.clearProperty(k);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static JsonNode json(final String name) throws Exception {
|
|
+ try (InputStream in = AereD412RealHeadersTest.class.getResourceAsStream(DIR + name)) {
|
|
+ assertThat(in).as("resource %s", name).isNotNull();
|
|
+ return new ObjectMapper().readTree(in);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static List<Pair> pairs() throws Exception {
|
|
+ final List<Pair> out = new ArrayList<>();
|
|
+ for (final JsonNode v : json("blocuri-reale.json").path("vectori")) {
|
|
+ final JsonNode b = v.path("blocks");
|
|
+ out.add(new Pair(v.path("id").asText(), v.path("chainId").asLong(), header(b.get(0)), header(b.get(1))));
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ private static QbftBlock block(final BlockHeader h) {
|
|
+ return new QbftBlockAdaptor(new Block(h, new BlockBody(Collections.emptyList(), Collections.emptyList())));
|
|
+ }
|
|
+
|
|
+ private static BftExtraData extra(final BlockHeader h) {
|
|
+ return CODEC.decodeRaw(h.getExtraData());
|
|
+ }
|
|
+
|
|
+ private static AereVoteCounts.Target targetOf(final BlockHeader h, final int round) {
|
|
+ return AereVoteCounts.Target.atRound(BLOCK_INTERFACE, block(h), h.getNumber(), round);
|
|
+ }
|
|
+
|
|
+ private static Set<Address> recovered(final BlockHeader h, final Hash commitDigest) {
|
|
+ final Set<Address> out = new HashSet<>();
|
|
+ for (final SECPSignature s : extra(h).getSeals()) {
|
|
+ out.add(Util.signatureToAddress(s, commitDigest));
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ /** The Falcon keys of a 2800 manifest, by index. */
|
|
+ private static Map<Integer, byte[]> manifest2800(final long height) throws Exception {
|
|
+ final JsonNode m = json(height < 18082816L ? "2800-manifest-13014000.json" : "2800-manifest-18082816.json");
|
|
+ final Map<Integer, byte[]> keys = new java.util.HashMap<>();
|
|
+ for (int i = 0; i < m.path("count").asInt(); i++) {
|
|
+ keys.put(i, Bytes.fromHexString(m.path(Integer.toString(i)).path("pk").asText()).toArrayUnsafe());
|
|
+ }
|
|
+ return keys;
|
|
+ }
|
|
+
|
|
+ private static void install28001Identity() throws Exception {
|
|
+ final URL a = AereD412RealHeadersTest.class.getResource(DIR + "28001-registry-v3-3080010.json");
|
|
+ final URL b = AereD412RealHeadersTest.class.getResource(DIR + "28001-registry-v3-3097600.json");
|
|
+ assertThat(a).isNotNull();
|
|
+ assertThat(b).isNotNull();
|
|
+ System.setProperty(AerePqIdentity.PROPERTY_BLOCK, Long.toString(H_ID_28001));
|
|
+ System.setProperty(
|
|
+ AerePqIdentity.PROPERTY_REGISTRIES, Path.of(a.toURI()) + "," + Path.of(b.toURI()));
|
|
+ System.setProperty(AerePqIdentity.PROPERTY_HASHES, PINS_28001);
|
|
+ System.setProperty(AerePqIdentity.PROPERTY_KEYS_FROM, Long.toString(H_ID_28001));
|
|
+ AerePqIdentity.uninstall();
|
|
+ AerePqIdentity.installFromSystemProperties(CHAIN_28001, h -> List.of("falcon-512", "slh-dsa-sha2-128s"));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theHeadersRebuildToTheChainsHashes() throws Exception {
|
|
+ int n = 0;
|
|
+ for (final JsonNode v : json("blocuri-reale.json").path("vectori")) {
|
|
+ for (final JsonNode b : v.path("blocks")) {
|
|
+ assertThat(header(b).getHash().toHexString())
|
|
+ .as("%s block %s", v.path("id").asText(), b.path("number").asText())
|
|
+ .isEqualToIgnoringCase(b.path("hash").asText());
|
|
+ n++;
|
|
+ }
|
|
+ }
|
|
+ assertThat(n).isEqualTo(10);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theCommittedSealsSignTheCollectorsCommitDigest() throws Exception {
|
|
+ int roundAboveZero = 0;
|
|
+ int judged = 0;
|
|
+ for (final Pair p : pairs()) {
|
|
+ if (p.chain != CHAIN_2800) {
|
|
+ continue;
|
|
+ }
|
|
+ final Collection<Address> setOfAnchor = extra(p.parent).getValidators();
|
|
+ for (final boolean isAnchor : new boolean[] {false, true}) {
|
|
+ final BlockHeader h = isAnchor ? p.anchor : p.parent;
|
|
+ // the set that decides h: the validators after its parent (the parent's list for the anchor; the block's own list for
|
|
+ // the parent, whose own parent is not in the vector, at heights where the set did not change)
|
|
+ final Collection<Address> set = isAnchor ? setOfAnchor : extra(h).getValidators();
|
|
+ final int r = extra(h).getRound();
|
|
+ final Set<Address> signers = recovered(h, targetOf(h, r).commitDigest());
|
|
+ // the collector looks a vote up by the MESSAGE digest; for a block proposed with its own round (what an honest proposer
|
|
+ // builds) that is the very digest the commit seals sign
|
|
+ assertThat(targetOf(h, r).digest())
|
|
+ .as("%s %s: digest_r of the stored block is its commit digest at r", p.id, h.getNumber())
|
|
+ .isEqualTo(targetOf(h, r).commitDigest());
|
|
+ assertThat(set).as("%s %s: every committed seal is a validator's", p.id, h.getNumber()).containsAll(signers);
|
|
+ assertThat(signers.size())
|
|
+ .as("%s %s: a quorum of distinct validators", p.id, h.getNumber())
|
|
+ .isGreaterThanOrEqualTo(BftHelpers.calculateRequiredValidatorQuorum(set.size()));
|
|
+ final Set<Address> wrongRound = recovered(h, targetOf(h, r == 0 ? 1 : 0).commitDigest());
|
|
+ wrongRound.retainAll(set);
|
|
+ assertThat(wrongRound).as("%s %s: control, at another round no seal is a validator's", p.id, h.getNumber()).isEmpty();
|
|
+ if (r > 0) {
|
|
+ roundAboveZero++;
|
|
+ }
|
|
+ judged++;
|
|
+ }
|
|
+ }
|
|
+ assertThat(judged).isEqualTo(8);
|
|
+ assertThat(roundAboveZero).as("the corpus carries the three anchors decided at round 1").isEqualTo(3);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theCertificatesSignTheCollectorsPqMessageOfTheParent() throws Exception {
|
|
+ int falcon = 0;
|
|
+ int slh = 0;
|
|
+ int skipped = 0;
|
|
+ int ownRoundOne = 0;
|
|
+ for (final Pair p : pairs()) {
|
|
+ // window E of 2800 (10 Aug): the anchor DISABLED on the nodes, the seal attachment on. Measured in the pre-flight of
|
|
+ // 30 Sept: its certificate is the LEGACY per-block one, the commits' Falcon seals over the block's OWN commit digest at its
|
|
+ // round (round 1 here), not the anchor form over the parent. There the collector's message is the one of the stored block
|
|
+ // itself at round 1 under a disabled anchor configuration, and the controls are round 0 and the anchor form of the parent.
|
|
+ final boolean ownBlock = p.id.contains("reguli-oprite");
|
|
+ final List<SchemeSeal> seals = new ArrayList<>(extra(p.anchor).getHybridSeals());
|
|
+ for (final FalconSeal f : extra(p.anchor).getFalconSeals()) {
|
|
+ seals.add(new SchemeSeal(FALCON.wireId(), f.getValidatorIndex(), f.getSignature()));
|
|
+ }
|
|
+ assertThat(seals).as("%s: the anchor carries a certificate", p.id).isNotEmpty();
|
|
+ final long np = p.parent.getNumber();
|
|
+ final int rp = extra(p.parent).getRound();
|
|
+ final int ra = extra(p.anchor).getRound();
|
|
+ final Map<Integer, byte[]> keys2800 = p.chain == CHAIN_2800 ? manifest2800(np) : Map.of();
|
|
+ if (p.chain == CHAIN_28001) {
|
|
+ install28001Identity();
|
|
+ }
|
|
+ PqAnchorProducer.useConfigForTesting(PqAnchorConfig.never(p.chain));
|
|
+ final Bytes32 preAnchor = Bytes32.wrap(targetOf(p.parent, rp).pqSealMessage().orElseThrow().getBytes());
|
|
+ final Bytes32 ownRound = Bytes32.wrap(targetOf(p.anchor, ra).pqSealMessage().orElseThrow().getBytes());
|
|
+ final Bytes32 ownOtherRound = Bytes32.wrap(targetOf(p.anchor, ra == 0 ? 1 : 0).pqSealMessage().orElseThrow().getBytes());
|
|
+ PqAnchorProducer.useConfigForTesting(
|
|
+ new PqAnchorConfig(
|
|
+ p.chain,
|
|
+ p.chain == CHAIN_2800 ? ANCHOR_2800 : ANCHOR_28001,
|
|
+ Map.of(p.chain == CHAIN_2800 ? ANCHOR_2800 : ANCHOR_28001, 0),
|
|
+ OptionalInt.empty(),
|
|
+ false));
|
|
+ final Bytes32 message = Bytes32.wrap(targetOf(p.parent, rp).pqSealMessage().orElseThrow().getBytes());
|
|
+ assertThat(message).as("%s: control, the anchor form differs from the pre-anchor form", p.id).isNotEqualTo(preAnchor);
|
|
+ assertThat(message)
|
|
+ .as("%s: the anchor form over the parent's chain hash", p.id)
|
|
+ .isEqualTo(PqAnchor.commitMessage(p.chain, np, p.parent.getHash().getBytes()));
|
|
+ if (ownBlock) {
|
|
+ assertThat(ra).as("%s: the window E vector is a block decided at round 1", p.id).isEqualTo(1);
|
|
+ }
|
|
+ final Bytes32 expected = ownBlock ? ownRound : message;
|
|
+ final List<Bytes32> controls = ownBlock ? List.of(ownOtherRound, message) : List.of(preAnchor);
|
|
+ for (final SchemeSeal s : seals) {
|
|
+ final SealScheme scheme = SealSchemes.byWireId(s.getSchemeWireId()).orElseThrow();
|
|
+ final Optional<byte[]> key =
|
|
+ p.chain == CHAIN_2800
|
|
+ ? (scheme.wireId() == FALCON.wireId()
|
|
+ ? Optional.ofNullable(keys2800.get(s.getValidatorIndex()))
|
|
+ : Optional.empty())
|
|
+ : AerePqIdentity.v3KeyAt(np, s.getValidatorIndex(), scheme.id());
|
|
+ if (key.isEmpty()) {
|
|
+ assertThat(p.chain).as("%s: only the 2800 SLH-DSA keys are not in the resources", p.id).isEqualTo(CHAIN_2800);
|
|
+ skipped++;
|
|
+ continue;
|
|
+ }
|
|
+ assertThat(scheme.verifyRaw(key.get(), expected.toArrayUnsafe(), s.getSignature().toArrayUnsafe()))
|
|
+ .as("%s: %s seal of index %s over the collector's message", p.id, scheme.id(), s.getValidatorIndex())
|
|
+ .isTrue();
|
|
+ for (final Bytes32 control : controls) {
|
|
+ assertThat(scheme.verifyRaw(key.get(), control.toArrayUnsafe(), s.getSignature().toArrayUnsafe()))
|
|
+ .as("%s: control, index %s not over another message", p.id, s.getValidatorIndex())
|
|
+ .isFalse();
|
|
+ }
|
|
+ if (scheme.wireId() == FALCON.wireId()) {
|
|
+ falcon++;
|
|
+ } else {
|
|
+ slh++;
|
|
+ }
|
|
+ if (ownBlock) {
|
|
+ ownRoundOne++;
|
|
+ }
|
|
+ }
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ AerePqIdentity.uninstall();
|
|
+ }
|
|
+ // counted in the corpus (rezultate/extragere-blocuri-reale.txt): 3 v1 certificates of 3, 9 + 9 on 2800 at 20.4M, 5 + 5 on 28001
|
|
+ assertThat(ownRoundOne).as("window E: the three seals over the stored block's own round-1 message").isEqualTo(3);
|
|
+ assertThat(falcon).as("Falcon seals verified over the collector's message").isEqualTo(3 * 3 + 9 + 5);
|
|
+ assertThat(slh).as("SLH-DSA seals verified (28001)").isEqualTo(5);
|
|
+ assertThat(skipped).as("SLH-DSA seals of 2800 not judged (keys not in the resources)").isEqualTo(9);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aboveHhdrTheProposerSealSignsTheCollectorsDigest() throws Exception {
|
|
+ install28001Identity();
|
|
+ int judged = 0;
|
|
+ for (final Pair p : pairs()) {
|
|
+ if (p.chain != CHAIN_28001) {
|
|
+ continue;
|
|
+ }
|
|
+ for (final BlockHeader h : List.of(p.parent, p.anchor)) {
|
|
+ final BftExtraData e = extra(h);
|
|
+ assertThat(e.getSeals()).as("%s %s: from H_hdr the header carries no ECDSA seals", p.id, h.getNumber()).isEmpty();
|
|
+ final FalconSeal ps = e.getPqProposerSeal().orElseThrow();
|
|
+ final byte[] key = AerePqIdentity.v3KeyAt(h.getNumber(), ps.getValidatorIndex(), FALCON.id()).orElseThrow();
|
|
+ final int r = e.getRound();
|
|
+ final Bytes32 message =
|
|
+ PqAnchor.proposalMessage(CHAIN_28001, h.getNumber(), r, targetOf(h, r).digest().getBytes());
|
|
+ assertThat(FALCON.verifyRaw(key, message.toArrayUnsafe(), ps.getSignature().toArrayUnsafe()))
|
|
+ .as("%s %s: element 6 over the proposal message of the collector's digest", p.id, h.getNumber())
|
|
+ .isTrue();
|
|
+ final Bytes32 otherRound =
|
|
+ PqAnchor.proposalMessage(CHAIN_28001, h.getNumber(), r + 1, targetOf(h, r + 1).digest().getBytes());
|
|
+ assertThat(FALCON.verifyRaw(key, otherRound.toArrayUnsafe(), ps.getSignature().toArrayUnsafe()))
|
|
+ .as("%s %s: control, not at another round", p.id, h.getNumber())
|
|
+ .isFalse();
|
|
+ // 2026-09-30, second review: the control above changes the round of the message AND the digest together, so it does not
|
|
+ // isolate the digest. These change one thing each: the seal binds the collector's digest, and the round, separately.
|
|
+ assertThat(targetOf(h, r + 1).digest()).as("%s %s: digest_r+1 differs from digest_r", p.id, h.getNumber())
|
|
+ .isNotEqualTo(targetOf(h, r).digest());
|
|
+ final Bytes32 otherDigestSameRound =
|
|
+ PqAnchor.proposalMessage(CHAIN_28001, h.getNumber(), r, targetOf(h, r + 1).digest().getBytes());
|
|
+ assertThat(FALCON.verifyRaw(key, otherDigestSameRound.toArrayUnsafe(), ps.getSignature().toArrayUnsafe()))
|
|
+ .as("%s %s: control, not over another digest at the same round", p.id, h.getNumber())
|
|
+ .isFalse();
|
|
+ final Bytes32 sameDigestOtherRound =
|
|
+ PqAnchor.proposalMessage(CHAIN_28001, h.getNumber(), r + 1, targetOf(h, r).digest().getBytes());
|
|
+ assertThat(FALCON.verifyRaw(key, sameDigestOtherRound.toArrayUnsafe(), ps.getSignature().toArrayUnsafe()))
|
|
+ .as("%s %s: control, not at another round over the same digest", p.id, h.getNumber())
|
|
+ .isFalse();
|
|
+ judged++;
|
|
+ }
|
|
+ }
|
|
+ assertThat(judged).isEqualTo(2);
|
|
+ }
|
|
+
|
|
+ private static long hexLong(final JsonNode b, final String field) {
|
|
+ return Long.decode(b.path(field).asText());
|
|
+ }
|
|
+
|
|
+ /** The header as the chain served it (the parser of aips/aip22-conformitate/besu/Aip22AnchorVectorsConformanceTest). */
|
|
+ private static BlockHeader header(final JsonNode b) {
|
|
+ final BlockHeaderTestFixture f =
|
|
+ new BlockHeaderTestFixture()
|
|
+ .blockHeaderFunctions(BftBlockHeaderFunctions.forOnchainBlock(CODEC))
|
|
+ .parentHash(Hash.fromHexString(b.path("parentHash").asText()))
|
|
+ .ommersHash(Hash.fromHexString(b.path("sha3Uncles").asText()))
|
|
+ .coinbase(Address.fromHexString(b.path("miner").asText()))
|
|
+ .stateRoot(Hash.fromHexString(b.path("stateRoot").asText()))
|
|
+ .transactionsRoot(Hash.fromHexString(b.path("transactionsRoot").asText()))
|
|
+ .receiptsRoot(Hash.fromHexString(b.path("receiptsRoot").asText()))
|
|
+ .logsBloom(new LogsBloomFilter(Bytes.fromHexString(b.path("logsBloom").asText())))
|
|
+ .difficulty(Difficulty.of(hexLong(b, "difficulty")))
|
|
+ .number(hexLong(b, "number"))
|
|
+ .gasLimit(hexLong(b, "gasLimit"))
|
|
+ .gasUsed(hexLong(b, "gasUsed"))
|
|
+ .timestamp(hexLong(b, "timestamp"))
|
|
+ .extraData(Bytes.fromHexString(b.path("extraData").asText()))
|
|
+ .mixHash(Hash.fromHexString(b.path("mixHash").asText()))
|
|
+ .nonce(Bytes.fromHexString(b.path("nonce").asText()).toLong());
|
|
+ if (b.hasNonNull("baseFeePerGas")) {
|
|
+ f.baseFeePerGas(Wei.fromHexString(b.path("baseFeePerGas").asText()));
|
|
+ }
|
|
+ if (b.hasNonNull("withdrawalsRoot")) {
|
|
+ f.withdrawalsRoot(Hash.fromHexString(b.path("withdrawalsRoot").asText()));
|
|
+ }
|
|
+ if (b.hasNonNull("blobGasUsed")) {
|
|
+ f.blobGasUsed(hexLong(b, "blobGasUsed"));
|
|
+ }
|
|
+ if (b.hasNonNull("excessBlobGas")) {
|
|
+ f.excessBlobGas(BlobGas.fromHexString(b.path("excessBlobGas").asText()));
|
|
+ }
|
|
+ if (b.hasNonNull("parentBeaconBlockRoot")) {
|
|
+ f.parentBeaconBlockRoot(Optional.of(Bytes32.fromHexString(b.path("parentBeaconBlockRoot").asText())));
|
|
+ }
|
|
+ if (b.hasNonNull("requestsHash")) {
|
|
+ f.requestsHash(Hash.fromHexString(b.path("requestsHash").asText()));
|
|
+ }
|
|
+ return f.buildHeader();
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereProducerPendingRoundTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereProducerPendingRoundTest.java
|
|
new file mode 100644
|
|
index 0000000000..d7751f3512
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereProducerPendingRoundTest.java
|
|
@@ -0,0 +1,231 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
+import static org.mockito.Mockito.mock;
|
|
+import static org.mockito.Mockito.when;
|
|
+import static org.mockito.Mockito.withSettings;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftContext;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSealSupport;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorNotReadyException;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqRegistryHash;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSealCache;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqV2Fixture;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.ProtocolContext;
|
|
+import org.hyperledger.besu.ethereum.core.Block;
|
|
+import org.hyperledger.besu.ethereum.core.BlockBody;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+
|
|
+import java.lang.reflect.Field;
|
|
+import java.nio.file.Files;
|
|
+import java.nio.file.Path;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collection;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.bouncycastle.crypto.digests.KeccakDigest;
|
|
+import org.bouncycastle.pqc.crypto.falcon.FalconPrivateKeyParameters;
|
|
+import org.bouncycastle.pqc.crypto.falcon.FalconSigner;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.junit.jupiter.api.io.TempDir;
|
|
+import org.mockito.quality.Strictness;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), D-470, pasul 4 (2026-10-01): the PENDING seals of a round r > 0 (D-339 / D-227: Commits heard without the
|
|
+ * proposal, held under the digest they name) are moved under their round by the producer of the next anchor, which
|
|
+ * rebuilds the parent's digest at each round from its header with the chain's QBFT codec, and then make the certificate.
|
|
+ * The review of step 4 found this drive untested: the store's own probe fed it a fake digest function. Here the parent is
|
|
+ * a real QBFT header, the Commit's digest is the one a Commit of round 2 names (the header at round 2, committed-seal
|
|
+ * form), and the codec is the production one. Pairs: without the codec installed nothing resolves and the proposer is
|
|
+ * not ready; a pending entry that names the on-chain hash under round 2 is not this block's round-2 digest and stays.
|
|
+ */
|
|
+public class AereProducerPendingRoundTest {
|
|
+
|
|
+ private static final long CHAIN_ID = 220_891L;
|
|
+ private static final long H = 1_000L;
|
|
+ private static final long V2 = 1_005L;
|
|
+ private static final long HR = 1_100L;
|
|
+ private static final int N = 10;
|
|
+ private static final int Q = 7;
|
|
+
|
|
+ @TempDir private Path tmp;
|
|
+
|
|
+ private final QbftExtraDataCodec codec = new QbftExtraDataCodec();
|
|
+ private final List<FalconPrivateKeyParameters> keys = new ArrayList<>();
|
|
+ private final List<Address> validators = new ArrayList<>();
|
|
+
|
|
+ @BeforeEach
|
|
+ void setUp() throws Exception {
|
|
+ final KeccakDigest kd = new KeccakDigest(256);
|
|
+ final StringBuilder manifest = new StringBuilder();
|
|
+ manifest.append("{\"config\":{\"aereFalconRegistry\":{").append(PqV2Fixture.manifestHeader(N, CHAIN_ID, H));
|
|
+ for (int i = 0; i < N; i++) {
|
|
+ keys.add(PqV2Fixture.privateKey(i));
|
|
+ validators.add(PqV2Fixture.address(i));
|
|
+ final byte[] row = PqV2Fixture.anchorPreimageRow(i);
|
|
+ kd.update(row, 0, row.length);
|
|
+ manifest.append(',').append(PqV2Fixture.manifestEntry(i, N, CHAIN_ID, H));
|
|
+ }
|
|
+ manifest
|
|
+ .append("}},\"alloc\":{\"0000000000000000000000000000000000000fa1\":{\"storage\":{\"0x")
|
|
+ .append("0".repeat(64))
|
|
+ .append("\":\"0x");
|
|
+ final byte[] anchoredHash = new byte[32];
|
|
+ kd.doFinal(anchoredHash, 0);
|
|
+ manifest.append(Bytes.wrap(anchoredHash).toUnprefixedHexString()).append("\"}}}}");
|
|
+ final Path genesis = tmp.resolve("genesis-registry.json");
|
|
+ Files.writeString(genesis, manifest.toString());
|
|
+ System.setProperty("aere.falcon.genesis", genesis.toAbsolutePath().toString());
|
|
+ System.setProperty("aere.falcon.attachBlock", Long.toString(H - 100L));
|
|
+ resetFalconSingleton();
|
|
+ final PqRegistryHash.Registry held = PqRegistryHash.loadAuto(genesis);
|
|
+ String hash = PqRegistryHash.hashFor(held, CHAIN_ID);
|
|
+ if (!hash.startsWith("0x")) {
|
|
+ hash = "0x" + hash;
|
|
+ }
|
|
+ final Path schedule = tmp.resolve("genesis-schedule.json");
|
|
+ Files.writeString(schedule, "{\"config\":{\"pqRegistryHash\":[{\"block\":" + H + ",\"hash\":\"" + hash + "\"}]}}");
|
|
+ FalconSealSupport.instance()
|
|
+ .verifyRegistryBindingOrAbort(0L, CHAIN_ID, PqRegistryHash.loadScheduleFromGenesis(schedule));
|
|
+ PqSealCache.instance().clear();
|
|
+ PqAnchorProducer.useConfigForTesting(
|
|
+ new PqAnchorConfig(CHAIN_ID, H, Map.of(H, Q), OptionalInt.empty(), false, OptionalInt.empty(), OptionalInt.empty(), V2)
|
|
+ .withCommitRoundBlock(HR));
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ void tearDown() throws Exception {
|
|
+ PqAnchorProducer.useExtraDataCodec(null);
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ PqSealCache.instance().clear();
|
|
+ System.clearProperty("aere.falcon.genesis");
|
|
+ System.clearProperty("aere.falcon.attachBlock");
|
|
+ resetFalconSingleton();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void theProducerMovesThePendingSealsOfRoundTwoUnderItAndCertifiesThatRound() {
|
|
+ PqAnchorProducer.useExtraDataCodec(codec);
|
|
+ final BlockHeader parent = parentAt(HR + 49L);
|
|
+ final Hash digestAtTwo = digestAt(parent, 2);
|
|
+ assertThat(digestAtTwo).as("control: the round-2 digest is not the on-chain hash").isNotEqualTo(parent.getHash());
|
|
+ PqSealCache.instance()
|
|
+ .recordPendingRound(parent.getNumber(), digestAtTwo, 2, validators.get(0), sealsOver(parent, 2, 0, Q), List.of());
|
|
+ final BftExtraData produced = PqAnchorProducer.apply(base(), parent, contextWith(validators));
|
|
+ assertThat(produced.getCertificateRound()).hasValue(2);
|
|
+ assertThat(produced.getHybridSeals()).hasSize(Q);
|
|
+ assertThat(PqSealCache.instance().pendingCount()).isZero();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void withoutTheCodecNothingResolvesAndTheProposerIsNotReady() {
|
|
+ final BlockHeader parent = parentAt(HR + 49L);
|
|
+ PqSealCache.instance()
|
|
+ .recordPendingRound(
|
|
+ parent.getNumber(), digestAt(parent, 2), 2, validators.get(0), sealsOver(parent, 2, 0, Q), List.of());
|
|
+ assertThatThrownBy(() -> PqAnchorProducer.apply(base(), parent, contextWith(validators)))
|
|
+ .isInstanceOf(PqAnchorNotReadyException.class);
|
|
+ assertThat(PqSealCache.instance().pendingCount()).isEqualTo(1);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ void aPendingEntryThatNamesTheOnchainHashUnderRoundTwoStays() {
|
|
+ PqAnchorProducer.useExtraDataCodec(codec);
|
|
+ final BlockHeader parent = parentAt(HR + 49L);
|
|
+ PqSealCache.instance()
|
|
+ .recordPendingRound(parent.getNumber(), parent.getHash(), 2, validators.get(0), sealsOver(parent, 2, 0, Q), List.of());
|
|
+ assertThatThrownBy(() -> PqAnchorProducer.apply(base(), parent, contextWith(validators)))
|
|
+ .isInstanceOf(PqAnchorNotReadyException.class);
|
|
+ assertThat(PqSealCache.instance().pendingCount())
|
|
+ .as("the on-chain hash is the round-0 digest, never the round-2 one: the entry is not this block's")
|
|
+ .isEqualTo(1);
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------------------------------
|
|
+
|
|
+ /** A stored QBFT header (round 0, on-chain header functions), as the chain holds the anchor's parent. */
|
|
+ private BlockHeader parentAt(final long number) {
|
|
+ final BftExtraData extra =
|
|
+ new BftExtraData(Bytes32.leftPad(Bytes.of(0x77)), List.of(), Optional.empty(), 0, validators);
|
|
+ return new BlockHeaderTestFixture()
|
|
+ .number(number)
|
|
+ .extraData(codec.encode(extra))
|
|
+ .coinbase(validators.get(0))
|
|
+ .blockHeaderFunctions(BftBlockHeaderFunctions.forOnchainBlock(codec))
|
|
+ .buildHeader();
|
|
+ }
|
|
+
|
|
+ /** The digest a Commit of round r names for this block: its header at round r, committed-seal form. */
|
|
+ private Hash digestAt(final BlockHeader parent, final int round) {
|
|
+ return new BftBlockInterface(codec)
|
|
+ .replaceRoundInBlock(new Block(parent, BlockBody.empty()), round, BftBlockHeaderFunctions.forCommittedSeal(codec))
|
|
+ .getHash();
|
|
+ }
|
|
+
|
|
+ private List<FalconSeal> sealsOver(final BlockHeader parent, final int round, final int from, final int to) {
|
|
+ final Bytes32 m = PqAnchor.commitMessageRound(CHAIN_ID, parent.getNumber(), round, parent.getHash().getBytes());
|
|
+ final List<FalconSeal> out = new ArrayList<>();
|
|
+ for (int i = from; i < to; i++) {
|
|
+ final FalconSigner signer = new FalconSigner();
|
|
+ signer.init(true, keys.get(i));
|
|
+ out.add(new FalconSeal(i, Bytes.wrap(signer.generateSignature(m.toArray()))));
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ private BftExtraData base() {
|
|
+ return new BftExtraData(
|
|
+ Bytes32.ZERO, List.of(), Optional.empty(), 0, validators, List.of(), List.of(), BftExtraData.NO_CERTIFICATE_ROUND);
|
|
+ }
|
|
+
|
|
+ private static ProtocolContext contextWith(final Collection<Address> vs) {
|
|
+ final ValidatorProvider validatorProvider =
|
|
+ mock(ValidatorProvider.class, withSettings().strictness(Strictness.LENIENT));
|
|
+ when(validatorProvider.getValidatorsForBlock(any())).thenReturn(vs);
|
|
+ when(validatorProvider.getValidatorsAfterBlock(any())).thenReturn(vs);
|
|
+ final BftContext bftContext = mock(BftContext.class, withSettings().strictness(Strictness.LENIENT));
|
|
+ when(bftContext.getValidatorProvider()).thenReturn(validatorProvider);
|
|
+ when(bftContext.as(any())).thenReturn(bftContext);
|
|
+ return new ProtocolContext.Builder().withConsensusContext(bftContext).build();
|
|
+ }
|
|
+
|
|
+ private static void resetFalconSingleton() throws Exception {
|
|
+ final Field f = FalconSealSupport.class.getDeclaredField("instance");
|
|
+ f.setAccessible(true);
|
|
+ f.set(null, null);
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereRoundBoundCertificateTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereRoundBoundCertificateTest.java
|
|
new file mode 100644
|
|
index 0000000000..b4a0567180
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereRoundBoundCertificateTest.java
|
|
@@ -0,0 +1,524 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
+import static org.mockito.Mockito.mock;
|
|
+import static org.mockito.Mockito.when;
|
|
+import static org.mockito.Mockito.withSettings;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AereCertifiedDecision;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead;
|
|
+import org.hyperledger.besu.consensus.common.bft.AerePqFinalityTags;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftContext;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorV2;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorV3;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSignerRegistry;
|
|
+import org.hyperledger.besu.consensus.common.bft.SchemeSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealScheme;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealSchemes;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockAdaptor;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockInterfaceAdaptor;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.qbft.headervalidationrules.PqAnchorDigestRule;
|
|
+import org.hyperledger.besu.consensus.qbft.headervalidationrules.PqAnchorSealsRule;
|
|
+import org.hyperledger.besu.crypto.SecureRandomProvider;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.ProtocolContext;
|
|
+import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
+import org.hyperledger.besu.ethereum.core.Block;
|
|
+import org.hyperledger.besu.ethereum.core.BlockBody;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+import org.hyperledger.besu.ethereum.core.Difficulty;
|
|
+import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider;
|
|
+
|
|
+import java.security.SecureRandom;
|
|
+import java.util.ArrayList;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+import java.util.Set;
|
|
+import java.util.function.LongPredicate;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.mockito.quality.Strictness;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), D-470, pasul 5 (2026-10-02): RF1 REDONE ON THE NEW FORM (project 5.4, marker AERE-Q3-RF1-V3). The execution
|
|
+ * of {@link AereRoundFreeCertificateTest}, at N = 10 (Q = 7, f = 3), validators 0..8 honest, X = 9 the single bad key,
|
|
+ * height 3: round 0, validators 0, 1, 2 (and X) commit p; round 2, validators 4, 5, 6 (and X) commit p; round 3, 0..6
|
|
+ * commit p', which is DECIDED. Here every seal is produced on the EMITTER's path (PqAnchorProducer.commitSealMessage, the
|
|
+ * one place, under the configuration in force), so below H_r the seals are COMMIT-1 (one message for every round) and
|
|
+ * from H_r - 1 they are M_r (one message per round). The anchor of X is at 4 = H_r.
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>below H_r (the control that the fixture can express the attack; if it fails the verdict is STRICAT, never green):
|
|
+ * X's v2 anchor over p with the seven seals of rounds 0 and 2 passes R1 and R2;
|
|
+ * <li>from H_r: X's best one-round v3 (r = 0 or r = 2, four seals) is refused with V3-05; the v3 that carries all seven
|
|
+ * under r = 2 is refused with V3-07, naming a round-0 index; decidedBy and B1 never name p; the honest v3 of round 3
|
|
+ * over p' is accepted and decides p', the PARENT; K lowered to 4 by the ceiling lets R2 accept four round-0 seals,
|
|
+ * and still nothing decides p.
|
|
+ * </ul>
|
|
+ *
|
|
+ * <p>The restart half (SEALSTORE-2 and the finalized tag) is the app module's AereRoundBoundRestartTest.
|
|
+ */
|
|
+public class AereRoundBoundCertificateTest {
|
|
+
|
|
+ private static final long CHAIN = 220_891L;
|
|
+ private static final long ANCHOR_BLOCK = 2L;
|
|
+ private static final long V2 = 3L;
|
|
+ private static final long HR = 4L;
|
|
+ private static final long H_EV = 3L;
|
|
+ private static final int VALIDATORS = 10;
|
|
+ private static final int X = 9;
|
|
+ private static final int K = 7;
|
|
+ private static final byte FALCON = SealSchemes.FALCON_512.wireId();
|
|
+
|
|
+ private final QbftExtraDataCodec codec = new QbftExtraDataCodec();
|
|
+ private final QbftBlockInterface blockInterface =
|
|
+ new QbftBlockInterfaceAdaptor(new BftBlockInterface(codec));
|
|
+ private final SecureRandom random = SecureRandomProvider.createSecureRandom();
|
|
+ private final List<Address> validators = new ArrayList<>();
|
|
+ private final List<byte[]> falconPublic = new ArrayList<>();
|
|
+ private final List<SealScheme.PrivateHandle> falconPrivate = new ArrayList<>();
|
|
+ private long tag;
|
|
+
|
|
+ private Block genesis;
|
|
+ private Block b1;
|
|
+ private Block b2;
|
|
+ private Block p;
|
|
+ private Block pPrime;
|
|
+
|
|
+ // round-free (COMMIT-1) seals, made under the configuration without H_r
|
|
+ private final List<SchemeSeal> freeRoundZeroOnP = new ArrayList<>();
|
|
+ private final List<SchemeSeal> freeRoundTwoOnP = new ArrayList<>();
|
|
+ // round-bound (M_r) seals, made under the configuration with H_r
|
|
+ private final List<SchemeSeal> boundRoundZeroOnP = new ArrayList<>();
|
|
+ private final List<SchemeSeal> boundRoundTwoOnP = new ArrayList<>();
|
|
+ private final List<SchemeSeal> boundRoundThreeOnPPrime = new ArrayList<>();
|
|
+
|
|
+ private static PqAnchorConfig config(final boolean armHr, final OptionalInt ceiling) {
|
|
+ final PqAnchorConfig c =
|
|
+ new PqAnchorConfig(
|
|
+ CHAIN,
|
|
+ ANCHOR_BLOCK,
|
|
+ Map.of(ANCHOR_BLOCK, K),
|
|
+ ceiling,
|
|
+ false,
|
|
+ OptionalInt.empty(),
|
|
+ OptionalInt.empty())
|
|
+ .withAnchorV2Block(V2);
|
|
+ return armHr ? c.withCommitRoundBlock(HR) : c;
|
|
+ }
|
|
+
|
|
+ private static final PqAnchorConfig WITHOUT_HR = config(false, OptionalInt.empty());
|
|
+ private static final PqAnchorConfig WITH_HR = config(true, OptionalInt.empty());
|
|
+ private static final PqAnchorConfig WITH_HR_CEILING_4 = config(true, OptionalInt.of(4));
|
|
+
|
|
+ @BeforeEach
|
|
+ public void setUp() {
|
|
+ for (int i = 0; i < VALIDATORS; i++) {
|
|
+ validators.add(Address.fromHexString("0x" + "0".repeat(38) + "c" + i));
|
|
+ final SealScheme.GeneratedPair pair = SealSchemes.FALCON_512.generate(random);
|
|
+ falconPublic.add(pair.publicRegistryForm());
|
|
+ falconPrivate.add(pair.privateKey());
|
|
+ }
|
|
+ genesis = block(null);
|
|
+ b1 = block(genesis);
|
|
+ b2 = block(b1);
|
|
+ p = block(b2);
|
|
+ pPrime = block(b2);
|
|
+ PqAnchorProducer.useConfigForTesting(WITHOUT_HR);
|
|
+ for (final int i : new int[] {0, 1, 2, X}) {
|
|
+ freeRoundZeroOnP.add(seal(i, p, 0));
|
|
+ }
|
|
+ for (final int i : new int[] {4, 5, 6, X}) {
|
|
+ freeRoundTwoOnP.add(seal(i, p, 2));
|
|
+ }
|
|
+ PqAnchorProducer.useConfigForTesting(WITH_HR);
|
|
+ for (final int i : new int[] {0, 1, 2, X}) {
|
|
+ boundRoundZeroOnP.add(seal(i, p, 0));
|
|
+ }
|
|
+ for (final int i : new int[] {4, 5, 6, X}) {
|
|
+ boundRoundTwoOnP.add(seal(i, p, 2));
|
|
+ }
|
|
+ for (int i = 0; i <= 6; i++) {
|
|
+ boundRoundThreeOnPPrime.add(seal(i, pPrime, 3));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ public void tearDown() {
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // the fixture
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void controlTheEmitterSignsCommitOneBelowHrAndMrFromHrMinusOne() {
|
|
+ PqAnchorProducer.useConfigForTesting(WITHOUT_HR);
|
|
+ final Bytes32 free = message(p, 2);
|
|
+ assertThat(free)
|
|
+ .as("control: below H_r the emitter's message is COMMIT-1, the same for every round")
|
|
+ .isEqualTo(PqAnchor.commitMessage(CHAIN, 3L, p.getHash().getBytes()))
|
|
+ .isEqualTo(message(p, 0));
|
|
+ PqAnchorProducer.useConfigForTesting(WITH_HR);
|
|
+ assertThat(message(p, 2))
|
|
+ .as("control: from H_r - 1 it is M_2 over the on-chain hash of p (the primitive of 1.1)")
|
|
+ .isEqualTo(PqAnchor.commitMessageRound(CHAIN, 3L, 2, p.getHash().getBytes()))
|
|
+ .isNotEqualTo(message(p, 0))
|
|
+ .isNotEqualTo(free);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void belowHrTheMixedAnchorOverTheUndecidedSiblingPassesR1AndR2() {
|
|
+ PqAnchorProducer.useConfigForTesting(WITHOUT_HR);
|
|
+ final List<SchemeSeal> seven = new ArrayList<>(freeRoundZeroOnP);
|
|
+ seven.addAll(withoutX(freeRoundTwoOnP));
|
|
+ final Block anchor = v2AnchorOver(p, seven);
|
|
+ assertThat(indexes(anchor)).as("control: the seals of rounds 0 and 2 and X's").containsExactly(0, 1, 2, 4, 5, 6, X);
|
|
+ assertThat(new PqAnchorDigestRule(WITHOUT_HR).validate(anchor.getHeader(), p.getHeader()))
|
|
+ .as("control (sub H_r): R1 accepts X's anchor over p")
|
|
+ .isTrue();
|
|
+ assertThat(new PqAnchorSealsRule(WITHOUT_HR, registry()).validate(anchor.getHeader(), p.getHeader(), context()))
|
|
+ .as("control (sub H_r): R2 accepts X's anchor over p, seven seals of rounds 0 and 2 over COMMIT-1(p): the gap")
|
|
+ .isTrue();
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // from H_r: the rules
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void fromHrXsBestOneRoundCertificateIsRefusedWithV305() {
|
|
+ PqAnchorProducer.useConfigForTesting(WITH_HR);
|
|
+ for (final int round : new int[] {0, 2}) {
|
|
+ final List<SchemeSeal> rows = round == 0 ? boundRoundZeroOnP : boundRoundTwoOnP;
|
|
+ final Block anchor = v3AnchorOver(p, round, rows);
|
|
+ assertThat(new PqAnchorDigestRule(WITH_HR).validate(anchor.getHeader(), p.getHeader()))
|
|
+ .as("control: R1 accepts the form and the digest of X's v3 of round %s (so the refusal is R2's)", round)
|
|
+ .isTrue();
|
|
+ assertThat(new PqAnchorSealsRule(WITH_HR, registry()).validate(anchor.getHeader(), p.getHeader(), context()))
|
|
+ .as("AERE-Q3-RF1-V3: R2 refuses X's best v3 of round %s, four seals of one round", round)
|
|
+ .isFalse();
|
|
+ assertThat(judge(WITH_HR, anchor).code())
|
|
+ .as("the code: 4 < K = 7 (V3-05), round %s", round)
|
|
+ .isEqualTo(PqAnchorV3.V3_05);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void fromHrTheSevenSealsOfTwoRoundsUnderOneRoundAreRefusedWithV307NamingTheOtherRound() {
|
|
+ PqAnchorProducer.useConfigForTesting(WITH_HR);
|
|
+ final List<SchemeSeal> underTwo = new ArrayList<>(withoutX(boundRoundZeroOnP));
|
|
+ underTwo.addAll(boundRoundTwoOnP);
|
|
+ final Block anchorTwo = v3AnchorOver(p, 2, underTwo);
|
|
+ assertThat(indexes(anchorTwo)).as("control: seven distinct members").containsExactly(0, 1, 2, 4, 5, 6, X);
|
|
+ assertThat(new PqAnchorSealsRule(WITH_HR, registry()).validate(anchorTwo.getHeader(), p.getHeader(), context()))
|
|
+ .as("AERE-Q3-RF1-V3: R2 refuses the seven seals of rounds 0 and 2 under one round")
|
|
+ .isFalse();
|
|
+ final PqAnchorV3.Verdict two = judge(WITH_HR, anchorTwo);
|
|
+ assertThat(two.code()).isEqualTo(PqAnchorV3.V3_07);
|
|
+ assertThat(two.reason())
|
|
+ .as("project 5.4: the refusal names the first index whose seal is of round 0 (index 0)")
|
|
+ .contains("seal of index 0 does not verify");
|
|
+ final List<SchemeSeal> underZero = new ArrayList<>(boundRoundZeroOnP);
|
|
+ underZero.addAll(withoutX(boundRoundTwoOnP));
|
|
+ final PqAnchorV3.Verdict zero = judge(WITH_HR, v3AnchorOver(p, 0, underZero));
|
|
+ assertThat(zero.code()).as("the same seven under round 0").isEqualTo(PqAnchorV3.V3_07);
|
|
+ assertThat(zero.reason()).as("names the first round-2 index (4)").contains("seal of index 4 does not verify");
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void fromHrTheHonestRoundThreeCertificateOverTheDecidedSiblingIsAcceptedAndDecidesTheParent() {
|
|
+ PqAnchorProducer.useConfigForTesting(WITH_HR);
|
|
+ final Block honest = v3AnchorOver(pPrime, 3, boundRoundThreeOnPPrime);
|
|
+ assertThat(new PqAnchorDigestRule(WITH_HR).validate(honest.getHeader(), pPrime.getHeader())).isTrue();
|
|
+ assertThat(new PqAnchorSealsRule(WITH_HR, registry()).validate(honest.getHeader(), pPrime.getHeader(), context()))
|
|
+ .as("the honest v3 of round 3 with Q = 7 over p' is accepted by R2")
|
|
+ .isTrue();
|
|
+ final MutableBlockchain chain = chain(List.of(b1, b2, pPrime, honest));
|
|
+ final AereDecidedHead.Decided parent = new AereDecidedHead.Decided(3L, pPrime.getHash());
|
|
+ assertThat(decision(WITH_HR, h -> false).decidedBy(chain, honest.getHeader()))
|
|
+ .as("Q of round 3 over M_3(p'): the PARENT p', below H_hdr")
|
|
+ .contains(parent);
|
|
+ assertThat(decision(WITH_HR, h -> h >= HR).decidedBy(chain, honest.getHeader()))
|
|
+ .as("and from H_hdr")
|
|
+ .contains(parent);
|
|
+ final MutableBlockchain reader = chain(List.of(b1, b2, pPrime));
|
|
+ AerePqFinalityTags.installDecided(WITH_HR, reader, decision(WITH_HR, h -> false).over(reader));
|
|
+ reader.appendBlock(honest, List.of());
|
|
+ assertThat(reader.getFinalized()).as("B1 names p'").contains(pPrime.getHash());
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // from H_r: decidedBy and B1 never name p
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void fromHrDecidedByNeverNamesTheUndecidedSibling() {
|
|
+ PqAnchorProducer.useConfigForTesting(WITH_HR);
|
|
+ // every certificate X can write over p: one round alone (four rows), or all seven members under round 2 or 0 (X's
|
|
+ // own seal taken from the named round, so four rows of that round verify in each)
|
|
+ final List<SchemeSeal> sevenUnderTwo = new ArrayList<>(withoutX(boundRoundZeroOnP));
|
|
+ sevenUnderTwo.addAll(boundRoundTwoOnP);
|
|
+ final List<SchemeSeal> sevenUnderZero = new ArrayList<>(boundRoundZeroOnP);
|
|
+ sevenUnderZero.addAll(withoutX(boundRoundTwoOnP));
|
|
+ final List<Block> anchors =
|
|
+ List.of(
|
|
+ v3AnchorOver(p, 0, boundRoundZeroOnP),
|
|
+ v3AnchorOver(p, 2, boundRoundTwoOnP),
|
|
+ v3AnchorOver(p, 2, sevenUnderTwo),
|
|
+ v3AnchorOver(p, 0, sevenUnderZero));
|
|
+ for (final Block anchor : anchors) {
|
|
+ final MutableBlockchain chain = chain(List.of(b1, b2, pPrime, p, anchor));
|
|
+ final int round = codec.decodeRaw(anchor.getHeader().getExtraData()).getCertificateRound().getAsInt();
|
|
+ assertThat(decision(WITH_HR, h -> false).decidedBy(chain, anchor.getHeader()))
|
|
+ .as("AERE-Q3-RF1-V3: below H_hdr nothing (4 of a round < Q, no ECDSA branch), round %s", round)
|
|
+ .isEmpty();
|
|
+ assertThat(decision(WITH_HR, h -> h >= HR).decidedBy(chain, anchor.getHeader()))
|
|
+ .as(
|
|
+ "AERE-Q3-RF1-V3: from H_hdr never p; four members of round %s (f + 1) give the grandparent, block 2",
|
|
+ round)
|
|
+ .contains(new AereDecidedHead.Decided(2L, b2.getHash()));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void fromHrTheFinalizedTagNeverNamesTheUndecidedSibling() {
|
|
+ PqAnchorProducer.useConfigForTesting(WITH_HR);
|
|
+ final List<SchemeSeal> seven = new ArrayList<>(withoutX(boundRoundZeroOnP));
|
|
+ seven.addAll(boundRoundTwoOnP);
|
|
+ final Block anchor = v3AnchorOver(p, 2, seven);
|
|
+ for (final boolean fromHhdr : new boolean[] {false, true}) {
|
|
+ final MutableBlockchain reader = chain(List.of(b1, b2, pPrime));
|
|
+ final LongPredicate hhdr = fromHhdr ? h -> h >= HR : h -> false;
|
|
+ AerePqFinalityTags.installDecided(WITH_HR, reader, decision(WITH_HR, hhdr).over(reader));
|
|
+ reader.appendBlock(p, List.of());
|
|
+ reader.appendBlock(anchor, List.of());
|
|
+ assertThat(reader.getChainHeadHeader().getHash())
|
|
+ .as("control: the reader follows the heavier branch p <- A")
|
|
+ .isEqualTo(anchor.getHash());
|
|
+ assertThat(reader.getFinalized())
|
|
+ .as("AERE-Q3-RF1-V3: B1 never names p (from H_hdr: %s)", fromHhdr)
|
|
+ .isNotEqualTo(Optional.of(p.getHash()));
|
|
+ if (fromHhdr) {
|
|
+ assertThat(reader.getFinalized())
|
|
+ .as("control: the tag did move, onto block 2, the grandparent the four seals of round 2 decide")
|
|
+ .contains(b2.getHash());
|
|
+ } else {
|
|
+ assertThat(reader.getFinalized()).as("below H_hdr nothing moves it").isEmpty();
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void fromHrACeilingOfFourLetsR2AcceptFourSealsOfOneRoundButNothingDecidesP() {
|
|
+ PqAnchorProducer.useConfigForTesting(WITH_HR_CEILING_4);
|
|
+ assertThat(WITH_HR_CEILING_4.minSealsAt(HR)).as("control: the ceiling lowers K to 4").isEqualTo(4);
|
|
+ final Block anchor = v3AnchorOver(p, 0, boundRoundZeroOnP);
|
|
+ assertThat(
|
|
+ new PqAnchorSealsRule(WITH_HR_CEILING_4, registry())
|
|
+ .validate(anchor.getHeader(), p.getHeader(), context()))
|
|
+ .as("control: at K = 4 R2 accepts X's four seals of round 0 over p (K is the rule's floor, H6)")
|
|
+ .isTrue();
|
|
+ final MutableBlockchain chain = chain(List.of(b1, b2, pPrime, p, anchor));
|
|
+ assertThat(decision(WITH_HR_CEILING_4, h -> false).decidedBy(chain, anchor.getHeader()))
|
|
+ .as("AERE-Q3-RF1-V3: what R2 accepts at K = 4 does not decide p: the parent needs Q = 7")
|
|
+ .isEmpty();
|
|
+ assertThat(decision(WITH_HR_CEILING_4, h -> h >= HR).decidedBy(chain, anchor.getHeader()))
|
|
+ .as("and from H_hdr only the grandparent")
|
|
+ .contains(new AereDecidedHead.Decided(2L, b2.getHash()));
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // fixture
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ private AereCertifiedDecision decision(final PqAnchorConfig cfg, final LongPredicate headerSealActive) {
|
|
+ return new AereCertifiedDecision(cfg, codec, registry(), h -> validators, headerSealActive, H_EV);
|
|
+ }
|
|
+
|
|
+ private PqAnchorV3.Verdict judge(final PqAnchorConfig cfg, final Block anchor) {
|
|
+ final BftExtraData extra = codec.decodeRaw(anchor.getHeader().getExtraData());
|
|
+ return PqAnchorV3.judgeSeals(
|
|
+ cfg,
|
|
+ anchor.getHeader().getNumber(),
|
|
+ anchor.getHeader().getParentHash().getBytes(),
|
|
+ new PqAnchorV3.Certificate(extra.getCertificateRound().getAsInt(), extra.getHybridSeals()),
|
|
+ cfg.minSealsAt(anchor.getHeader().getNumber()),
|
|
+ Set.of(),
|
|
+ Set.of(),
|
|
+ PqAnchorV3.historicSigners(registry(), anchor.getHeader().getNumber() - 1L, () -> validators));
|
|
+ }
|
|
+
|
|
+ /** The emitter's post-quantum message for {@code b} at {@code round}, under the configuration in force. */
|
|
+ private Bytes32 message(final Block b, final int round) {
|
|
+ final QbftBlock qb = new QbftBlockAdaptor(b);
|
|
+ final Hash commitHash = blockInterface.replaceRoundForCommitBlock(qb, round).getHash();
|
|
+ return PqAnchorProducer.commitSealMessage(
|
|
+ b.getHeader().getNumber(),
|
|
+ () -> blockInterface.replaceRoundForCommitBlock(qb, 0).getHash().getBytes(),
|
|
+ commitHash,
|
|
+ round)
|
|
+ .orElseThrow();
|
|
+ }
|
|
+
|
|
+ /** Validator {@code who}'s Falcon seal on {@code b} at {@code round}, over the emitter's message. */
|
|
+ private SchemeSeal seal(final int who, final Block b, final int round) {
|
|
+ final byte[] signature =
|
|
+ SealSchemes.FALCON_512.sign(falconPrivate.get(who), message(b, round).toArray()).orElseThrow();
|
|
+ return new SchemeSeal(FALCON, who, Bytes.wrap(signature));
|
|
+ }
|
|
+
|
|
+ private List<SchemeSeal> withoutX(final List<SchemeSeal> rows) {
|
|
+ return rows.stream().filter(s -> s.getValidatorIndex() != X).toList();
|
|
+ }
|
|
+
|
|
+ private Set<Integer> indexes(final Block anchor) {
|
|
+ final Set<Integer> out = new java.util.TreeSet<>();
|
|
+ for (final SchemeSeal s : codec.decodeRaw(anchor.getHeader().getExtraData()).getHybridSeals()) {
|
|
+ out.add(s.getValidatorIndex());
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ private PqSignerRegistry registry() {
|
|
+ return new PqSignerRegistry() {
|
|
+ @Override
|
|
+ public Address addressForIndexAtHistoric(final long blockNumber, final int validatorIndex) {
|
|
+ return validatorIndex >= 0 && validatorIndex < VALIDATORS ? validators.get(validatorIndex) : null;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Address addressForIndexAtOwnHead(final long blockNumber, final int validatorIndex) {
|
|
+ return addressForIndexAtHistoric(blockNumber, validatorIndex);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtHistoric(
|
|
+ final long blockNumber, final int validatorIndex, final Bytes message, final Bytes signature) {
|
|
+ return validatorIndex >= 0
|
|
+ && validatorIndex < VALIDATORS
|
|
+ && SealSchemes.FALCON_512.verifyRaw(falconPublic.get(validatorIndex), message.toArray(), signature.toArray());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtOwnHead(
|
|
+ final long blockNumber, final int validatorIndex, final Bytes message, final Bytes signature) {
|
|
+ return verifyAtHistoric(blockNumber, validatorIndex, message, signature);
|
|
+ }
|
|
+ };
|
|
+ }
|
|
+
|
|
+ private ProtocolContext context() {
|
|
+ final ValidatorProvider vp = mock(ValidatorProvider.class, withSettings().strictness(Strictness.LENIENT));
|
|
+ when(vp.getValidatorsForBlock(any())).thenReturn(validators);
|
|
+ when(vp.getValidatorsAfterBlock(any())).thenReturn(validators);
|
|
+ final BftContext bft = mock(BftContext.class, withSettings().strictness(Strictness.LENIENT));
|
|
+ when(bft.getValidatorProvider()).thenReturn(vp);
|
|
+ when(bft.as(any())).thenReturn(bft);
|
|
+ return new ProtocolContext.Builder().withConsensusContext(bft).build();
|
|
+ }
|
|
+
|
|
+ private MutableBlockchain chain(final List<Block> blocks) {
|
|
+ final MutableBlockchain chain =
|
|
+ InMemoryKeyValueStorageProvider.createInMemoryBlockchain(genesis, BftBlockHeaderFunctions.forOnchainBlock(codec));
|
|
+ for (final Block b : blocks) {
|
|
+ chain.appendBlock(b, List.of());
|
|
+ }
|
|
+ return chain;
|
|
+ }
|
|
+
|
|
+ private Block block(final Block parent) {
|
|
+ tag++;
|
|
+ final BftExtraData extra =
|
|
+ new BftExtraData(Bytes32.leftPad(Bytes.ofUnsignedLong(tag)), List.of(), Optional.empty(), 0, validators);
|
|
+ return new Block(header(parent, extra, validators.get(0)), BlockBody.empty());
|
|
+ }
|
|
+
|
|
+ private static List<SchemeSeal> canonical(final List<SchemeSeal> rows) {
|
|
+ final List<SchemeSeal> sorted = new ArrayList<>(rows);
|
|
+ sorted.sort(PqAnchorV2.CANONICAL);
|
|
+ return sorted;
|
|
+ }
|
|
+
|
|
+ /** X's v2 anchor (the form below H_r): the rows canonical, their D2 in vanityData. */
|
|
+ private Block v2AnchorOver(final Block parent, final List<SchemeSeal> rows) {
|
|
+ final List<SchemeSeal> sorted = canonical(rows);
|
|
+ final BftExtraData extra =
|
|
+ new BftExtraData(
|
|
+ PqAnchorV2.anchorDigestV2(CHAIN, parent.getHeader().getNumber(), parent.getHash().getBytes(), sorted),
|
|
+ List.of(),
|
|
+ Optional.empty(),
|
|
+ X,
|
|
+ validators,
|
|
+ List.of(),
|
|
+ sorted,
|
|
+ BftExtraData.NO_CERTIFICATE_ROUND);
|
|
+ return new Block(header(parent, extra, validators.get(X)), BlockBody.empty());
|
|
+ }
|
|
+
|
|
+ /** A v3 anchor of round {@code round} over {@code parent}: the rows canonical, D3 in vanityData. */
|
|
+ private Block v3AnchorOver(final Block parent, final int round, final List<SchemeSeal> rows) {
|
|
+ final List<SchemeSeal> sorted = canonical(rows);
|
|
+ final BftExtraData extra =
|
|
+ new BftExtraData(
|
|
+ PqAnchorV3.anchorDigestV3(
|
|
+ CHAIN,
|
|
+ parent.getHeader().getNumber(),
|
|
+ parent.getHash().getBytes(),
|
|
+ new PqAnchorV3.Certificate(round, sorted)),
|
|
+ List.of(),
|
|
+ Optional.empty(),
|
|
+ X,
|
|
+ validators,
|
|
+ List.of(),
|
|
+ sorted,
|
|
+ round);
|
|
+ return new Block(header(parent, extra, validators.get(X)), BlockBody.empty());
|
|
+ }
|
|
+
|
|
+ private BlockHeader header(final Block parent, final BftExtraData extra, final Address coinbase) {
|
|
+ final long number = parent == null ? 0L : parent.getHeader().getNumber() + 1;
|
|
+ return new BlockHeaderTestFixture()
|
|
+ .number(number)
|
|
+ .parentHash(parent == null ? Hash.ZERO : parent.getHash())
|
|
+ .difficulty(Difficulty.ONE)
|
|
+ .extraData(codec.encode(extra))
|
|
+ .timestamp(number)
|
|
+ .coinbase(coinbase)
|
|
+ .blockHeaderFunctions(BftBlockHeaderFunctions.forOnchainBlock(codec))
|
|
+ .buildHeader();
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereRoundBoundL1DifferentialTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereRoundBoundL1DifferentialTest.java
|
|
new file mode 100644
|
|
index 0000000000..e7a2f6fb52
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereRoundBoundL1DifferentialTest.java
|
|
@@ -0,0 +1,469 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
+import static org.mockito.Mockito.mock;
|
|
+import static org.mockito.Mockito.when;
|
|
+import static org.mockito.Mockito.withSettings;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AereCertifiedDecision;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftContext;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.HybridSealSupport;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSealCache;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSealStore;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSignerRegistry;
|
|
+import org.hyperledger.besu.consensus.common.bft.SchemeSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealSchemes;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
|
+import org.hyperledger.besu.consensus.qbft.headervalidationrules.PqAnchorDigestRule;
|
|
+import org.hyperledger.besu.consensus.qbft.headervalidationrules.PqAnchorSealsRule;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.BlobGas;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.datatypes.LogsBloomFilter;
|
|
+import org.hyperledger.besu.datatypes.Wei;
|
|
+import org.hyperledger.besu.ethereum.ProtocolContext;
|
|
+import org.hyperledger.besu.ethereum.chain.Blockchain;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+import org.hyperledger.besu.ethereum.core.Difficulty;
|
|
+
|
|
+import java.io.InputStream;
|
|
+import java.net.URL;
|
|
+import java.nio.file.Files;
|
|
+import java.nio.file.Path;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collection;
|
|
+import java.util.HashMap;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+
|
|
+import com.fasterxml.jackson.databind.JsonNode;
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.junit.jupiter.api.io.TempDir;
|
|
+import org.mockito.quality.Strictness;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), D-470, pasul 5 (2026-10-02): THE L1 DIFFERENTIAL ON REAL ANCHORS OF 2800 (project 5.6, marker AERE-R1B-L1). Below H_r
|
|
+ * nothing changes, byte for byte: the 1(b) code with H_r UNSET (A) and with H_r set in the FUTURE (B, above every anchor of the
|
|
+ * corpus) must give the same answer on every real pair [parent, anchor] of 2800 on the laptop (ancore-2800-diferential.json, the
|
|
+ * corpus of 1(a): v1 from 13,1 million, v2 hybrid at 20,4 million), with the configuration of the fleet (H = 13.014.000, K
|
|
+ * 0/3/6, grid 32 then 128 from 17.225.968, v2 from 17.047.600) and the Falcon keys of the three published 2800 epochs:
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>the commit seal form and the certificate form at every height of the corpus;
|
|
+ * <li>the message a seal over the parent signs, for several rounds (COMMIT-1: the round ignored);
|
|
+ * <li>the verdicts of R1 and R2 (the real rules, a real context with the parent's set, the real keys);
|
|
+ * <li>the decision of the anchor below H_hdr (the parent) and from H_hdr (the branch that COUNTS verified seals);
|
|
+ * <li>the seal store: one record per block, the round ignored, and the SEALSTORE-1 head file written and restored as a node
|
|
+ * does at startup.
|
|
+ * </ul>
|
|
+ *
|
|
+ * <p>Controls: every header rebuilds to the chain's hash; every real Falcon seal outside window E verifies with the key of its
|
|
+ * epoch; R1 and R2 accept EVERY real anchor (the fleet did), the 20 hybrid v2 ones included, with the fleet's hybrid support as a
|
|
+ * reader runs it; the counting branch and the file restore actually ran.
|
|
+ *
|
|
+ * <p>What this probe compares is A against B in the 1(b) code: "setting H_r in the future changes nothing below it". The
|
|
+ * comparison AGAINST TODAY'S BINARY (review of step 5, point 2) is the judge AereL1Judecator (d412-reparatie/r1b), compiled once
|
|
+ * against the fleet's distribution (wt1b675449) and once against the 1(b) distribution, in the dist5 mode of the harness: the
|
|
+ * same answers, byte for byte, from the fleet with A, from 1(b) with A and from 1(b) with B.
|
|
+ *
|
|
+ * <p>CE NU MASOARA: 1000 + 1000 anchors (the corpus holds what the probe prints; the rest needs an extraction from a host);
|
|
+ * 28001 (no v1/v2 corpus of it on the laptop); the producer's output on the recorded seals, SEALWINDOW-1 and the AIP-21 answer
|
|
+ * on real data. The plantation diferenta-sub-hr (round-bound wherever H_r is set) must make this probe RED.
|
|
+ */
|
|
+public class AereRoundBoundL1DifferentialTest {
|
|
+
|
|
+ private static final String DIR = "/aere-d412/";
|
|
+ private static final QbftExtraDataCodec CODEC = new QbftExtraDataCodec();
|
|
+ private static final long CHAIN = 2800L;
|
|
+ private static final long H = 13_014_000L;
|
|
+ private static final long V2 = 17_047_600L;
|
|
+ private static final long HR_FUTURE = 30_000_112L;
|
|
+ private static final PqAnchorConfig A =
|
|
+ new PqAnchorConfig(
|
|
+ CHAIN,
|
|
+ H,
|
|
+ Map.of(H, 0, 13_034_000L, 3, 14_961_456L, 6),
|
|
+ OptionalInt.empty(),
|
|
+ false,
|
|
+ OptionalInt.empty(),
|
|
+ OptionalInt.of(32))
|
|
+ .withAnchorIntervalSchedule(Map.of(17_225_968L, 128))
|
|
+ .withAnchorV2Block(V2);
|
|
+ private static final PqAnchorConfig B = A.withCommitRoundBlock(HR_FUTURE);
|
|
+
|
|
+ private static final class Pair {
|
|
+ private final String id;
|
|
+ private final BlockHeader parent;
|
|
+ private final BlockHeader anchor;
|
|
+
|
|
+ Pair(final String id, final BlockHeader parent, final BlockHeader anchor) {
|
|
+ this.id = id;
|
|
+ this.parent = parent;
|
|
+ this.anchor = anchor;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @TempDir Path tmp;
|
|
+
|
|
+ /**
|
|
+ * The hybrid support of the fleet as a READER runs it (aere.pq.schemeSchedule and aere.pq.hybridRegistry of 2800), so R2
|
|
+ * judges the 20 hybrid v2 anchors of the corpus as the fleet did. Review of step 5, point 3: without
|
|
+ * it R2 refused all 20 (no scheme named for their SLH-DSA rows) and the differential compared two refusals of the fixture.
|
|
+ */
|
|
+ @BeforeEach
|
|
+ public void armHybridAsTheFleet() throws Exception {
|
|
+ final URL hib = AereRoundBoundL1DifferentialTest.class.getResource(DIR + "2800-hibrid-10.properties");
|
|
+ assertThat(hib).as("resource 2800-hibrid-10.properties").isNotNull();
|
|
+ System.setProperty(HybridSealSupport.PROPERTY_SCHEDULE, "17047568:falcon-512+slh-dsa-sha2-128s");
|
|
+ System.setProperty(HybridSealSupport.PROPERTY_REGISTRY, Path.of(hib.toURI()).toString());
|
|
+ // NOT aere.pq.hybrid.attachBlock: that arms EMISSION and asks for this node's own hybrid keys (a validator's), while the
|
|
+ // rules here are the ones every reader runs (measured 2026-10-02: with it, R2 threw HYBRID-CONF-04 on all 20 v2 anchors)
|
|
+ HybridSealSupport.resetForTesting();
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ public void disarm() {
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ PqSealCache.instance().disablePersistence();
|
|
+ PqSealCache.instance().clear();
|
|
+ System.clearProperty(HybridSealSupport.PROPERTY_SCHEDULE);
|
|
+ System.clearProperty(HybridSealSupport.PROPERTY_REGISTRY);
|
|
+ System.clearProperty(HybridSealSupport.PROPERTY_ATTACH_BLOCK);
|
|
+ HybridSealSupport.resetForTesting();
|
|
+ }
|
|
+
|
|
+ private static JsonNode json(final String name) throws Exception {
|
|
+ try (InputStream in = AereRoundBoundL1DifferentialTest.class.getResourceAsStream(DIR + name)) {
|
|
+ assertThat(in).as("resource %s", name).isNotNull();
|
|
+ return new ObjectMapper().readTree(in);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static List<Pair> pairs() throws Exception {
|
|
+ final List<Pair> out = new ArrayList<>();
|
|
+ for (final JsonNode v : json("ancore-2800-diferential.json").path("vectori")) {
|
|
+ final JsonNode b = v.path("blocks");
|
|
+ out.add(new Pair(v.path("id").asText(), header(b.get(0)), header(b.get(1))));
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The three published Falcon epochs of 2800 (registry.history of the fleet: manifest-13014000, registru-v2-13600000, then the
|
|
+ * epoch of ten from 18.082.816): index to {address, Falcon key}, chosen by the height of the parent. First run of this probe
|
|
+ * (2026-10-02 23:47Z) had only the two JSON manifests: 309 of 358 real seals verified, the 49 others were the seals of the
|
|
+ * epoch of nine (13,6 to 18,08 million) judged with the keys of seven. The control below is what showed it.
|
|
+ */
|
|
+ private static final Map<String, Map<Integer, String[]>> EPOCHS = new HashMap<>();
|
|
+
|
|
+ private static Map<Integer, String[]> keysAt(final long parentHeight) throws Exception {
|
|
+ final String name =
|
|
+ parentHeight < 13_600_000L
|
|
+ ? "2800-manifest-13014000.json"
|
|
+ : parentHeight < 18_082_816L ? "2800-registru-v2-13600000.properties" : "2800-manifest-18082816.json";
|
|
+ if (!EPOCHS.containsKey(name)) {
|
|
+ final Map<Integer, String[]> keys = new HashMap<>();
|
|
+ if (name.endsWith(".json")) {
|
|
+ final JsonNode m = json(name);
|
|
+ for (int i = 0; i < m.path("count").asInt(); i++) {
|
|
+ final JsonNode e = m.path(Integer.toString(i));
|
|
+ keys.put(i, new String[] {e.path("addr").asText(), e.path("pk").asText()});
|
|
+ }
|
|
+ } else {
|
|
+ final java.util.Properties p = new java.util.Properties();
|
|
+ try (InputStream in = AereRoundBoundL1DifferentialTest.class.getResourceAsStream(DIR + name)) {
|
|
+ assertThat(in).as("resource %s", name).isNotNull();
|
|
+ p.load(in);
|
|
+ }
|
|
+ for (int i = 0; i < Integer.parseInt(p.getProperty("count").trim()); i++) {
|
|
+ keys.put(i, new String[] {p.getProperty(i + ".addr").trim(), p.getProperty(Integer.toString(i)).trim()});
|
|
+ }
|
|
+ }
|
|
+ EPOCHS.put(name, keys);
|
|
+ }
|
|
+ return EPOCHS.get(name);
|
|
+ }
|
|
+
|
|
+ private static PqSignerRegistry registry() {
|
|
+ return new PqSignerRegistry() {
|
|
+ @Override
|
|
+ public Address addressForIndexAtHistoric(final long blockNumber, final int validatorIndex) {
|
|
+ try {
|
|
+ final String[] e = keysAt(blockNumber).get(validatorIndex);
|
|
+ return e == null ? null : Address.fromHexString(e[0]);
|
|
+ } catch (final Exception ex) {
|
|
+ return null;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Address addressForIndexAtOwnHead(final long blockNumber, final int validatorIndex) {
|
|
+ return addressForIndexAtHistoric(blockNumber, validatorIndex);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtHistoric(
|
|
+ final long blockNumber, final int validatorIndex, final Bytes message, final Bytes signature) {
|
|
+ try {
|
|
+ final String[] e = keysAt(blockNumber).get(validatorIndex);
|
|
+ return e != null
|
|
+ && SealSchemes.FALCON_512.verifyRaw(
|
|
+ Bytes.fromHexString(e[1]).toArrayUnsafe(), message.toArray(), signature.toArray());
|
|
+ } catch (final Exception ex) {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtOwnHead(
|
|
+ final long blockNumber, final int validatorIndex, final Bytes message, final Bytes signature) {
|
|
+ return verifyAtHistoric(blockNumber, validatorIndex, message, signature);
|
|
+ }
|
|
+ };
|
|
+ }
|
|
+
|
|
+ private static ProtocolContext context(final Collection<Address> set) {
|
|
+ final ValidatorProvider vp = mock(ValidatorProvider.class, withSettings().strictness(Strictness.LENIENT));
|
|
+ when(vp.getValidatorsForBlock(any())).thenReturn(set);
|
|
+ when(vp.getValidatorsAfterBlock(any())).thenReturn(set);
|
|
+ final BftContext bft = mock(BftContext.class, withSettings().strictness(Strictness.LENIENT));
|
|
+ when(bft.getValidatorProvider()).thenReturn(vp);
|
|
+ when(bft.as(any())).thenReturn(bft);
|
|
+ return new ProtocolContext.Builder().withConsensusContext(bft).build();
|
|
+ }
|
|
+
|
|
+ /** Every Falcon seal an anchor carries: the v1 list and the Falcon rows of the v2 list. */
|
|
+ private static List<FalconSeal> falconSeals(final BlockHeader anchor) {
|
|
+ final BftExtraData extra = CODEC.decodeRaw(anchor.getExtraData());
|
|
+ final List<FalconSeal> out = new ArrayList<>(extra.getFalconSeals());
|
|
+ for (final SchemeSeal s : extra.getHybridSeals()) {
|
|
+ if (s.getSchemeWireId() == SealSchemes.FALCON_512.wireId()) {
|
|
+ out.add(new FalconSeal(s.getValidatorIndex(), s.getSignature()));
|
|
+ }
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // controls: the corpus and the configuration can show a difference
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void controlTheCorpusRebuildsTheConfigurationIsTheFleetsAndTheRealSealsVerify() throws Exception {
|
|
+ final List<Pair> pairs = pairs();
|
|
+ assertThat(pairs).as("control: the corpus is not empty").isNotEmpty();
|
|
+ long maxAnchor = 0L;
|
|
+ int seals = 0;
|
|
+ int verified = 0;
|
|
+ int windowE = 0;
|
|
+ for (final Pair p : pairs) {
|
|
+ // window E of 2800 (10 Aug, "reguli-oprite"): the anchor rules were OFF on the nodes and the certificate is the LEGACY per-block
|
|
+ // one, over the block's own commit digest at its round, not COMMIT-1 of the parent (AereD412RealHeadersTest). Second run of
|
|
+ // this probe (2026-10-01 23:54Z): exactly its 31 seals were the ones not verifying over COMMIT-1. They stay in the
|
|
+ // differential (A and B must agree on them too) and are counted apart here.
|
|
+ if (p.id.contains("reguli-oprite")) {
|
|
+ windowE += falconSeals(p.anchor).size();
|
|
+ maxAnchor = Math.max(maxAnchor, p.anchor.getNumber());
|
|
+ continue;
|
|
+ }
|
|
+ assertThat(p.anchor.getParentHash()).as("%s: the anchor is the parent's child", p.id).isEqualTo(p.parent.getHash());
|
|
+ assertThat(A.anchorAppliesAt(p.anchor.getNumber()))
|
|
+ .as("%s: control, the configuration of the fleet puts an anchor at %s", p.id, p.anchor.getNumber())
|
|
+ .isTrue();
|
|
+ maxAnchor = Math.max(maxAnchor, p.anchor.getNumber());
|
|
+ final long np = p.parent.getNumber();
|
|
+ final Bytes32 m = PqAnchor.commitMessage(CHAIN, np, p.parent.getHash().getBytes());
|
|
+ for (final FalconSeal s : falconSeals(p.anchor)) {
|
|
+ seals++;
|
|
+ if (registry().verifyAtHistoric(np, s.getValidatorIndex(), m, s.getSignature())) {
|
|
+ verified++;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ assertThat(B.commitRoundBlock()).as("control: H_r of B").isEqualTo(HR_FUTURE);
|
|
+ assertThat(A.anchorAppliesAt(HR_FUTURE)).as("control: H_r of B is an anchor height of the fleet's grid").isTrue();
|
|
+ assertThat(HR_FUTURE).as("control: H_r of B is above every anchor of the corpus").isGreaterThan(maxAnchor + 1L);
|
|
+ assertThat(seals).as("control: the corpus carries Falcon seals").isGreaterThan(0);
|
|
+ assertThat(verified)
|
|
+ .as(
|
|
+ "control of the method: every real Falcon seal outside window E verifies over COMMIT-1 of its parent with the key of"
|
|
+ + " its epoch")
|
|
+ .isEqualTo(seals);
|
|
+ assertThat(windowE).as("control: the corpus carries window E (rules off), judged in the differential too").isGreaterThan(0);
|
|
+ System.out.println(
|
|
+ "AERE-R1B-L1 control: " + pairs.size() + " real anchors of 2800, " + seals + " Falcon seals outside window E, "
|
|
+ + verified + " verify; window E " + windowE + " legacy seals");
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // the differential
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void belowHrSettingHrInTheFutureChangesNothingOnAnyRealAnchorOf2800() throws Exception {
|
|
+ final List<Pair> pairs = pairs();
|
|
+ final List<String> divergent = new ArrayList<>();
|
|
+ final PqSignerRegistry registry = registry();
|
|
+ final Blockchain chain = mock(Blockchain.class);
|
|
+ int r1Accepted = 0;
|
|
+ int r2Accepted = 0;
|
|
+ int decided = 0;
|
|
+ int counted = 0;
|
|
+ int restored = 0;
|
|
+ for (final Pair p : pairs) {
|
|
+ final long np = p.parent.getNumber();
|
|
+ final long a = p.anchor.getNumber();
|
|
+ final Bytes ph = p.parent.getHash().getBytes();
|
|
+ final Collection<Address> set = CODEC.decodeRaw(p.parent.getExtraData()).getValidators();
|
|
+ // the counting branch reads the parent from the chain (its number and its parent hash)
|
|
+ when(chain.getBlockHeader(p.parent.getHash())).thenReturn(Optional.of(p.parent));
|
|
+ final Map<String, Object> answers = new HashMap<>();
|
|
+ for (final PqAnchorConfig cfg : List.of(A, B)) {
|
|
+ PqAnchorProducer.useConfigForTesting(cfg);
|
|
+ final String k = cfg == A ? "A" : "B";
|
|
+ answers.put(k + ".form-commit", PqAnchorProducer.commitSealFormAt(cfg, np));
|
|
+ answers.put(k + ".form-certificate", cfg.certificateFormAt(a));
|
|
+ for (final int r : new int[] {0, 1, 3, 1024}) {
|
|
+ answers.put(k + ".message-" + r, PqAnchorProducer.anchorSealMessage(cfg, np, ph, r));
|
|
+ }
|
|
+ answers.put(k + ".r1", new PqAnchorDigestRule(cfg).validate(p.anchor, p.parent));
|
|
+ answers.put(k + ".r2", new PqAnchorSealsRule(cfg, registry).validate(p.anchor, p.parent, context(set)));
|
|
+ final Optional<AereDecidedHead.Decided> d =
|
|
+ new AereCertifiedDecision(cfg, CODEC, registry, h -> set, h -> false, Long.MAX_VALUE).decidedBy(chain, p.anchor);
|
|
+ answers.put(k + ".decision", d);
|
|
+ // review of step 5, point 4: the branch that COUNTS seals (from H_hdr, H_ev = 0, the regime of 28001 below H_r): the
|
|
+ // verified members of the round-free certificate over COMMIT-1 of the parent, with the real keys
|
|
+ final Optional<AereDecidedHead.Decided> dc =
|
|
+ new AereCertifiedDecision(cfg, CODEC, registry, h -> set, h -> true, 0L).decidedBy(chain, p.anchor);
|
|
+ answers.put(k + ".decision-counted", dc);
|
|
+ final List<FalconSeal> seals = falconSeals(p.anchor);
|
|
+ PqSealCache.instance().clear();
|
|
+ PqSealCache.instance().record(np, p.parent.getHash(), 3, seals);
|
|
+ answers.put(k + ".store-rounds", PqSealCache.instance().roundsFor(np, p.parent.getHash()).keySet().toString());
|
|
+ answers.put(k + ".store-round0", PqSealCache.instance().sealsFor(np, p.parent.getHash(), 0).size());
|
|
+ // and the head FILE below H_r: SEALSTORE-1 written as a node writes it, restored as a node restores it at startup
|
|
+ final Path data = tmp.resolve(k + "-" + a);
|
|
+ Files.createDirectories(data);
|
|
+ PqSealStore.writeAtomically(PqSealStore.fileIn(data), PqSealStore.encode(CHAIN, np, ph, seals));
|
|
+ PqSealCache.instance().clear();
|
|
+ PqSealCache.instance().enablePersistence(data, CHAIN);
|
|
+ answers.put(k + ".file-restored", PqSealCache.instance().restoreFromDisk(np, p.parent.getHash(), registry));
|
|
+ answers.put(k + ".file-round0", PqSealCache.instance().sealsFor(np, p.parent.getHash(), 0).toString());
|
|
+ PqSealCache.instance().disablePersistence();
|
|
+ PqSealCache.instance().clear();
|
|
+ }
|
|
+ for (final String field :
|
|
+ List.of(
|
|
+ "form-commit", "form-certificate", "message-0", "message-1", "message-3", "message-1024", "r1", "r2",
|
|
+ "decision", "decision-counted", "store-rounds", "store-round0", "file-restored", "file-round0")) {
|
|
+ if (!answers.get("A." + field).equals(answers.get("B." + field))) {
|
|
+ divergent.add(p.id + " " + field + ": A " + answers.get("A." + field) + ", B " + answers.get("B." + field));
|
|
+ }
|
|
+ }
|
|
+ if (Boolean.TRUE.equals(answers.get("A.r1"))) {
|
|
+ r1Accepted++;
|
|
+ }
|
|
+ if (Boolean.TRUE.equals(answers.get("A.r2"))) {
|
|
+ r2Accepted++;
|
|
+ }
|
|
+ if (((Optional<?>) answers.get("A.decision")).isPresent()) {
|
|
+ decided++;
|
|
+ }
|
|
+ if (((Optional<?>) answers.get("A.decision-counted")).isPresent()) {
|
|
+ counted++;
|
|
+ }
|
|
+ if ((Integer) answers.get("A.file-restored") > 0) {
|
|
+ restored++;
|
|
+ }
|
|
+ }
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ System.out.println(
|
|
+ "AERE-R1B-L1: " + pairs.size() + " real anchors of 2800, R1 accepts " + r1Accepted + ", R2 accepts " + r2Accepted
|
|
+ + ", decided " + decided + ", decided by counting " + counted + ", head file restored " + restored
|
|
+ + " (A); divergences A/B " + divergent.size());
|
|
+ assertThat(divergent)
|
|
+ .as("AERE-R1B-L1: with H_r in the future nothing below it changes, on %s real anchors", pairs.size())
|
|
+ .isEmpty();
|
|
+ // controls (review of step 5, point 3): the fleet accepted every one of these anchors, so R1 and R2 must accept all of them
|
|
+ // here too, with the fleet's configuration; otherwise the differential compares refusals of the fixture
|
|
+ assertThat(r1Accepted).as("control: R1 accepts every real anchor").isEqualTo(pairs.size());
|
|
+ assertThat(r2Accepted).as("control: R2 accepts every real anchor, the 20 hybrid v2 ones included").isEqualTo(pairs.size());
|
|
+ assertThat(counted).as("control: the counting branch decides on real anchors (it ran)").isGreaterThan(0);
|
|
+ assertThat(restored).as("control: the SEALSTORE-1 head file restores on real anchors (it ran)").isGreaterThan(0);
|
|
+ }
|
|
+
|
|
+ private static long hexLong(final JsonNode b, final String field) {
|
|
+ return Long.decode(b.path(field).asText());
|
|
+ }
|
|
+
|
|
+ /** The header as the chain served it (the parser of AereD412RealHeadersTest). */
|
|
+ private static BlockHeader header(final JsonNode b) {
|
|
+ final BlockHeaderTestFixture f =
|
|
+ new BlockHeaderTestFixture()
|
|
+ .blockHeaderFunctions(BftBlockHeaderFunctions.forOnchainBlock(CODEC))
|
|
+ .parentHash(Hash.fromHexString(b.path("parentHash").asText()))
|
|
+ .ommersHash(Hash.fromHexString(b.path("sha3Uncles").asText()))
|
|
+ .coinbase(Address.fromHexString(b.path("miner").asText()))
|
|
+ .stateRoot(Hash.fromHexString(b.path("stateRoot").asText()))
|
|
+ .transactionsRoot(Hash.fromHexString(b.path("transactionsRoot").asText()))
|
|
+ .receiptsRoot(Hash.fromHexString(b.path("receiptsRoot").asText()))
|
|
+ .logsBloom(new LogsBloomFilter(Bytes.fromHexString(b.path("logsBloom").asText())))
|
|
+ .difficulty(Difficulty.of(hexLong(b, "difficulty")))
|
|
+ .number(hexLong(b, "number"))
|
|
+ .gasLimit(hexLong(b, "gasLimit"))
|
|
+ .gasUsed(hexLong(b, "gasUsed"))
|
|
+ .timestamp(hexLong(b, "timestamp"))
|
|
+ .extraData(Bytes.fromHexString(b.path("extraData").asText()))
|
|
+ .mixHash(Hash.fromHexString(b.path("mixHash").asText()))
|
|
+ .nonce(Bytes.fromHexString(b.path("nonce").asText()).toLong());
|
|
+ if (b.hasNonNull("baseFeePerGas")) {
|
|
+ f.baseFeePerGas(Wei.fromHexString(b.path("baseFeePerGas").asText()));
|
|
+ }
|
|
+ if (b.hasNonNull("withdrawalsRoot")) {
|
|
+ f.withdrawalsRoot(Hash.fromHexString(b.path("withdrawalsRoot").asText()));
|
|
+ }
|
|
+ if (b.hasNonNull("blobGasUsed")) {
|
|
+ f.blobGasUsed(hexLong(b, "blobGasUsed"));
|
|
+ }
|
|
+ if (b.hasNonNull("excessBlobGas")) {
|
|
+ f.excessBlobGas(BlobGas.fromHexString(b.path("excessBlobGas").asText()));
|
|
+ }
|
|
+ if (b.hasNonNull("parentBeaconBlockRoot")) {
|
|
+ f.parentBeaconBlockRoot(Optional.of(Bytes32.fromHexString(b.path("parentBeaconBlockRoot").asText())));
|
|
+ }
|
|
+ if (b.hasNonNull("requestsHash")) {
|
|
+ f.requestsHash(Hash.fromHexString(b.path("requestsHash").asText()));
|
|
+ }
|
|
+ return f.buildHeader();
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereRoundFreeCertificateTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereRoundFreeCertificateTest.java
|
|
new file mode 100644
|
|
index 0000000000..be683a3f4b
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/AereRoundFreeCertificateTest.java
|
|
@@ -0,0 +1,526 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
+import static org.mockito.Mockito.mock;
|
|
+import static org.mockito.Mockito.when;
|
|
+import static org.mockito.Mockito.withSettings;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AereCertifiedDecision;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedBlockChoiceRule;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead;
|
|
+import org.hyperledger.besu.consensus.common.bft.AerePqFinalityTags;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftContext;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
+import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSignerRegistry;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealScheme;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealSchemes;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.common.bft.network.ValidatorMulticaster;
|
|
+import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockAdaptor;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockCodecAdaptor;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockInterfaceAdaptor;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagedata.CommitMessageData;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit;
|
|
+import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.AereDecidedConsensus;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.AereDecidedHook;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCodec;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.qbft.headervalidationrules.PqAnchorDigestRule;
|
|
+import org.hyperledger.besu.consensus.qbft.headervalidationrules.PqAnchorSealsRule;
|
|
+import org.hyperledger.besu.crypto.SECPSignature;
|
|
+import org.hyperledger.besu.crypto.SecureRandomProvider;
|
|
+import org.hyperledger.besu.cryptoservices.NodeKey;
|
|
+import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.ProtocolContext;
|
|
+import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
+import org.hyperledger.besu.ethereum.core.Block;
|
|
+import org.hyperledger.besu.ethereum.core.BlockBody;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+import org.hyperledger.besu.ethereum.core.Difficulty;
|
|
+import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider;
|
|
+import org.hyperledger.besu.ethereum.core.Util;
|
|
+
|
|
+import java.io.IOException;
|
|
+import java.nio.file.Files;
|
|
+import java.nio.file.Path;
|
|
+import java.security.SecureRandom;
|
|
+import java.time.Clock;
|
|
+import java.time.Instant;
|
|
+import java.time.ZoneOffset;
|
|
+import java.util.ArrayDeque;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Deque;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+import java.util.Set;
|
|
+import java.util.TreeSet;
|
|
+import java.util.function.Function;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.junit.jupiter.api.io.TempDir;
|
|
+import org.mockito.quality.Strictness;
|
|
+
|
|
+/**
|
|
+ * AERE teza Q3, proba RF1 (marcaj AERE-Q3-RF1; PROIECT-PASUL3-BLOCANTE-2026-10-01.md, sectiunile 2.2
|
|
+ * si 3.2): Teorema 1 made executable. The post-quantum commit seal signs M(b) =
|
|
+ * keccak(RLP["AERE-PQ-COMMIT-1", chainId, n, hash(b)]), which carries no round, and an honest QBFT
|
|
+ * validator may commit the same block in two rounds and another block later. So a certificate of K
|
|
+ * seals over b does not show that b was decided, for any K.
|
|
+ *
|
|
+ * <p>The execution, at N = 10 (Q = 7, f = 3), validators 0..8 honest, X = 9 the single bad key, height
|
|
+ * 3, written as the commits it leaves behind: round 0, validators 0, 1, 2 (and X) commit p; round 1,
|
|
+ * p' is proposed fresh and validator 3 locks it; round 2, p is re-proposed (the highest lock in the
|
|
+ * round-change quorum) and validators 4, 5, 6 (and X) commit it; round 3, p' is re-proposed (the lock of
|
|
+ * round 1 is now the highest) and validators 0..6 commit it: p' is DECIDED, p never had Q commits in one
|
|
+ * round. X takes the seven seals over M(p) from those commits, adds its own, and builds the anchor A at
|
|
+ * height 4 over p.
|
|
+ *
|
|
+ * <ul>
|
|
+ * <li>(1) control: R1 and R2 accept A over p (the fixture can express the attack; if not, the run is
|
|
+ * STRICAT, never green);
|
|
+ * <li>(2) control: a node that heard round 3 decides p' and A raises no conflict on it;
|
|
+ * <li>(3) RF1-3: a laggard that heard rounds 0 and 2 (not 3) and received p and A does not take p as
|
|
+ * its decided head;
|
|
+ * <li>(5) RF1-5: on a reader, the finalized tag (B1) never names p.
|
|
+ * </ul>
|
|
+ *
|
|
+ * <p>(4) and (4b), the restart, need the builder's functions and live in the app module
|
|
+ * (AereRoundFreeRestartTest). On the code of 2026-10-01 morning (Q3 and B1 on the anchor's PARENT, with
|
|
+ * Keff >= f + 1) (3) and (5) came out RED, each with its marker (RAPORT-RF1.md). Since project 1(a)
|
|
+ * (teza Q3, D-470, AERE-Q3-BUNIC) the wiring and the tags are handed the production
|
|
+ * AereCertifiedDecision over this chain, the regime from H_hdr injected (the anchor at 4 is above it):
|
|
+ * it answers the GRANDPARENT, block 2, on the seven seals re-verified with the real Falcon keys, so (3)
|
|
+ * and (5) are expected GREEN, each followed by a control that the decision did move (D and the tag on
|
|
+ * block 2), so an answer that proved nothing could not pass them.
|
|
+ */
|
|
+public class AereRoundFreeCertificateTest {
|
|
+
|
|
+ private static final long CHAIN = 220_879L;
|
|
+ private static final long H_EV = 3L;
|
|
+ private static final long ANCHOR_HEIGHT = 4L;
|
|
+ private static final int VALIDATORS = 10;
|
|
+ private static final int X = 9;
|
|
+ private static final int K = 7;
|
|
+
|
|
+ private final QbftExtraDataCodec codec = new QbftExtraDataCodec();
|
|
+ private final QbftBlockInterface blockInterface =
|
|
+ new QbftBlockInterfaceAdaptor(new BftBlockInterface(codec));
|
|
+ private final QbftBlockCodec blockCodec = new QbftBlockCodecAdaptor(codec);
|
|
+ private final PqAnchorConfig config =
|
|
+ new PqAnchorConfig(
|
|
+ CHAIN,
|
|
+ ANCHOR_HEIGHT,
|
|
+ Map.of(ANCHOR_HEIGHT, K),
|
|
+ OptionalInt.empty(),
|
|
+ false,
|
|
+ OptionalInt.empty(),
|
|
+ OptionalInt.of(4));
|
|
+ private final SecureRandom random = SecureRandomProvider.createSecureRandom();
|
|
+ private final List<NodeKey> keys = new ArrayList<>();
|
|
+ private final List<Address> validators = new ArrayList<>();
|
|
+ private final List<byte[]> falconPublic = new ArrayList<>();
|
|
+ private final List<SealScheme.PrivateHandle> falconPrivate = new ArrayList<>();
|
|
+ private long tag;
|
|
+
|
|
+ private Block genesis;
|
|
+ private Block b1;
|
|
+ private Block b2;
|
|
+ private Block p;
|
|
+ private Block pPrime;
|
|
+ private Block anchor;
|
|
+ private final List<Commit> commitsOnB2 = new ArrayList<>();
|
|
+ private final List<Commit> commitsOnPRoundZero = new ArrayList<>();
|
|
+ private final List<Commit> commitsOnPRoundTwo = new ArrayList<>();
|
|
+ private final List<Commit> commitsOnPPrimeRoundThree = new ArrayList<>();
|
|
+
|
|
+ /** H_hdr of this fixture: the anchor at 4 is in the regime where the header carries no ECDSA quorum. */
|
|
+ private static boolean aboveHhdr(final long height) {
|
|
+ return height >= ANCHOR_HEIGHT;
|
|
+ }
|
|
+
|
|
+ /** The production answer of what a stored anchor's certificate decides, over {@code chain}. */
|
|
+ private Function<BlockHeader, Optional<AereDecidedHead.Decided>> decision(
|
|
+ final MutableBlockchain chain) {
|
|
+ return new AereCertifiedDecision(
|
|
+ config, codec, registry(), h -> validators, AereRoundFreeCertificateTest::aboveHhdr, H_EV)
|
|
+ .over(chain);
|
|
+ }
|
|
+
|
|
+ @TempDir Path tmp;
|
|
+
|
|
+ @BeforeEach
|
|
+ public void setUp() {
|
|
+ AereDecidedHook.reset();
|
|
+ PqAnchorProducer.useConfigForTesting(config);
|
|
+ for (int i = 0; i < VALIDATORS; i++) {
|
|
+ final NodeKey k = NodeKeyUtils.generate();
|
|
+ keys.add(k);
|
|
+ validators.add(Util.publicKeyToAddress(k.getPublicKey()));
|
|
+ final SealScheme.GeneratedPair pair = SealSchemes.FALCON_512.generate(random);
|
|
+ falconPublic.add(pair.publicRegistryForm());
|
|
+ falconPrivate.add(pair.privateKey());
|
|
+ }
|
|
+ genesis = block(null);
|
|
+ b1 = block(genesis);
|
|
+ b2 = block(b1);
|
|
+ p = block(b2);
|
|
+ pPrime = block(b2);
|
|
+ for (int i = 0; i < K; i++) {
|
|
+ commitsOnB2.add(commit(i, b2, 0));
|
|
+ }
|
|
+ for (final int i : new int[] {0, 1, 2, X}) {
|
|
+ commitsOnPRoundZero.add(commit(i, p, 0));
|
|
+ }
|
|
+ for (final int i : new int[] {4, 5, 6, X}) {
|
|
+ commitsOnPRoundTwo.add(commit(i, p, 2));
|
|
+ }
|
|
+ for (int i = 0; i <= 6; i++) {
|
|
+ commitsOnPPrimeRoundThree.add(commit(i, pPrime, 3));
|
|
+ }
|
|
+ // X's certificate: the post-quantum seals the honest commits of rounds 0 and 2 carried (X heard them), and its own
|
|
+ final List<FalconSeal> certificate = new ArrayList<>();
|
|
+ for (final Commit c : commitsOnPRoundZero) {
|
|
+ certificate.add(c.getFalconSeal().orElseThrow());
|
|
+ }
|
|
+ for (final Commit c : commitsOnPRoundTwo) {
|
|
+ if (!c.getAuthor().equals(validators.get(X))) {
|
|
+ certificate.add(c.getFalconSeal().orElseThrow());
|
|
+ }
|
|
+ }
|
|
+ anchor = anchorOver(p, certificate);
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ public void tearDown() {
|
|
+ AereDecidedHook.reset();
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // (1) control: the fixture can express the attack
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void forgedAnchorOverTheUndecidedSiblingPassesR1AndR2() {
|
|
+ final BftExtraData extra = codec.decodeRaw(anchor.getHeader().getExtraData());
|
|
+ final Set<Integer> indexes = new TreeSet<>();
|
|
+ for (final FalconSeal s : extra.getFalconSeals()) {
|
|
+ indexes.add(s.getValidatorIndex());
|
|
+ }
|
|
+ assertThat(indexes)
|
|
+ .as("control: the certificate carries the seals of rounds 0 (0, 1, 2) and 2 (4, 5, 6) and X's")
|
|
+ .containsExactly(0, 1, 2, 4, 5, 6, X);
|
|
+ assertThat(new PqAnchorDigestRule(config).validate(anchor.getHeader(), p.getHeader()))
|
|
+ .as("control (1): R1 accepts the anchor over p")
|
|
+ .isTrue();
|
|
+ assertThat(
|
|
+ new PqAnchorSealsRule(config, registry())
|
|
+ .validate(anchor.getHeader(), p.getHeader(), context()))
|
|
+ .as("control (1): R2 accepts the anchor over p: seven valid seals of distinct members over M(p), K = 7")
|
|
+ .isTrue();
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // (2) control: the node that heard round 3 decides p', and the anchor over p is no conflict for it
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void theNodeThatHeardRoundThreeDecidesTheDecidedSiblingWithoutConflict() {
|
|
+ final Node decider = new Node("decider");
|
|
+ decider.store(b2);
|
|
+ decider.hearAll(commitsOnB2);
|
|
+ decider.drain();
|
|
+ assertThat(decider.head.decided().hash())
|
|
+ .as("control: D = block 2, on the quorum the decider heard at the proof height")
|
|
+ .isEqualTo(b2.getHash());
|
|
+ decider.store(pPrime);
|
|
+ decider.hearAll(commitsOnPRoundZero);
|
|
+ decider.hearAll(commitsOnPRoundTwo);
|
|
+ decider.drain();
|
|
+ assertThat(decider.wiring.evidence().quorumFor(new QbftBlockAdaptor(p)))
|
|
+ .as("control: no round holds Q commits on p (rounds 0 and 2 hold 4 each)")
|
|
+ .isEmpty();
|
|
+ assertThat(decider.wiring.evidence().countedAuthors(3L))
|
|
+ .as("control: yet the collector counted seven distinct authors' commits on p, across rounds 0 and 2")
|
|
+ .hasSize(K);
|
|
+ decider.hearAll(commitsOnPPrimeRoundThree);
|
|
+ decider.drain();
|
|
+ assertThat(decider.head.decided().hash())
|
|
+ .as("control (2): the decider decides p' on the round-3 quorum")
|
|
+ .isEqualTo(pPrime.getHash());
|
|
+ decider.store(p);
|
|
+ decider.store(anchor);
|
|
+ decider.wiring.evaluate();
|
|
+ decider.drain();
|
|
+ assertThat(decider.head.decided().hash())
|
|
+ .as("control (2): after p and the anchor over it, D is still p'")
|
|
+ .isEqualTo(pPrime.getHash());
|
|
+ assertThat(decider.head.conflicts()).as("control (2): and no conflict was raised").isZero();
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // (3) RF1-3: the laggard
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void aLaggardDoesNotTakeTheUndecidedSiblingFromTheCertifiedAnchor() {
|
|
+ final Node laggard = new Node("laggard");
|
|
+ laggard.store(b2);
|
|
+ laggard.hearAll(commitsOnB2);
|
|
+ laggard.hearAll(commitsOnPRoundZero);
|
|
+ laggard.hearAll(commitsOnPRoundTwo);
|
|
+ laggard.drain();
|
|
+ assertThat(laggard.head.decided().hash())
|
|
+ .as("control: the laggard decided block 2 and did not hear round 3")
|
|
+ .isEqualTo(b2.getHash());
|
|
+ laggard.store(p);
|
|
+ laggard.drain();
|
|
+ assertThat(laggard.wiring.evidence().quorumFor(new QbftBlockAdaptor(p)))
|
|
+ .as("control: with p stored, still no round holds Q commits on p")
|
|
+ .isEmpty();
|
|
+ laggard.store(anchor);
|
|
+ laggard.wiring.evaluate();
|
|
+ laggard.drain();
|
|
+ assertThat(laggard.head.decided().hash())
|
|
+ .as(
|
|
+ "RF1-3: the laggard must not take p as decided from the anchor's certificate (seven seals of"
|
|
+ + " rounds 0 and 2 over M(p)) while p' is decided at round 3")
|
|
+ .isNotEqualTo(p.getHash());
|
|
+ assertThat(decision(laggard.chain).apply(anchor.getHeader()))
|
|
+ .as("control (3): the certificate does decide something, block 2, which the laggard holds as D")
|
|
+ .contains(new AereDecidedHead.Decided(2L, b2.getHash()));
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // (5) RF1-5: the finalized tag on a reader
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void theFinalizedTagNeverNamesTheUndecidedSibling() {
|
|
+ final MutableBlockchain reader = chain(List.of(b1, b2, pPrime));
|
|
+ AerePqFinalityTags.installDecided(config, reader, decision(reader));
|
|
+ assertThat(reader.getFinalized()).as("control: no tag before an anchor").isEmpty();
|
|
+ reader.appendBlock(p, List.of());
|
|
+ reader.appendBlock(anchor, List.of());
|
|
+ assertThat(reader.getChainHeadHeader().getHash())
|
|
+ .as("control: the reader follows the heavier branch p <- A")
|
|
+ .isEqualTo(anchor.getHash());
|
|
+ assertThat(reader.getFinalized())
|
|
+ .as("RF1-5: the finalized tag must never name p, which no round decided (p' is decided)")
|
|
+ .isNotEqualTo(Optional.of(p.getHash()));
|
|
+ assertThat(reader.getFinalized())
|
|
+ .as("control (5): the tag did move, onto block 2, the grandparent the certificate decides")
|
|
+ .contains(b2.getHash());
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // fixture
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /** One validator with rule D: its chain (genesis, block 1), decided head, wiring. */
|
|
+ private final class Node {
|
|
+ private final MutableBlockchain chain;
|
|
+ private final AereDecidedHead head;
|
|
+ private final AereDecidedConsensus wiring;
|
|
+ private final Deque<Runnable> tasks = new ArrayDeque<>();
|
|
+
|
|
+ Node(final String name) {
|
|
+ chain = chain(List.of(b1));
|
|
+ final ValidatorProvider vp = mock(ValidatorProvider.class);
|
|
+ when(vp.getValidatorsAtHead()).thenReturn(validators);
|
|
+ when(vp.getValidatorsAfterBlock(any())).thenReturn(validators);
|
|
+ when(vp.getValidatorsForBlock(any())).thenReturn(validators);
|
|
+ final Path dir;
|
|
+ try {
|
|
+ dir = Files.createTempDirectory(tmp, name);
|
|
+ } catch (final IOException e) {
|
|
+ throw new IllegalStateException(e);
|
|
+ }
|
|
+ head = new AereDecidedHead(chain, H_EV, dir.resolve(AereDecidedHead.FILE_NAME), 256, m -> {});
|
|
+ AereDecidedBlockChoiceRule.install(chain, head);
|
|
+ head.restore(List.of());
|
|
+ wiring =
|
|
+ AereDecidedChainView.install(
|
|
+ chain,
|
|
+ head,
|
|
+ vp,
|
|
+ blockInterface,
|
|
+ mock(ValidatorMulticaster.class),
|
|
+ h -> {},
|
|
+ config::anchorAppliesAt,
|
|
+ decision(chain),
|
|
+ null,
|
|
+ chain::getChainHeadBlockNumber,
|
|
+ b -> 100L,
|
|
+ tasks::add,
|
|
+ Clock.fixed(Instant.ofEpochMilli(1_000_000L), ZoneOffset.UTC));
|
|
+ }
|
|
+
|
|
+ void store(final Block b) {
|
|
+ chain.appendBlock(b, List.of());
|
|
+ }
|
|
+
|
|
+ void hearAll(final List<Commit> commits) {
|
|
+ for (final Commit c : commits) {
|
|
+ wiring.observe(c, () -> CommitMessageData.create(c));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ void drain() {
|
|
+ Runnable r;
|
|
+ while ((r = tasks.poll()) != null) {
|
|
+ r.run();
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /** Index i bound to validator i, verified by the real Falcon-512 scheme with validator i's key. */
|
|
+ private PqSignerRegistry registry() {
|
|
+ return new PqSignerRegistry() {
|
|
+ @Override
|
|
+ public Address addressForIndexAtHistoric(final long blockNumber, final int validatorIndex) {
|
|
+ return addressForIndexAtOwnHead(blockNumber, validatorIndex);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Address addressForIndexAtOwnHead(final long blockNumber, final int validatorIndex) {
|
|
+ return validatorIndex >= 0 && validatorIndex < VALIDATORS
|
|
+ ? validators.get(validatorIndex)
|
|
+ : null;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtHistoric(
|
|
+ final long blockNumber,
|
|
+ final int validatorIndex,
|
|
+ final Bytes message,
|
|
+ final Bytes signature) {
|
|
+ return verifyAtOwnHead(blockNumber, validatorIndex, message, signature);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtOwnHead(
|
|
+ final long blockNumber,
|
|
+ final int validatorIndex,
|
|
+ final Bytes message,
|
|
+ final Bytes signature) {
|
|
+ return validatorIndex >= 0
|
|
+ && validatorIndex < VALIDATORS
|
|
+ && SealSchemes.FALCON_512.verifyRaw(
|
|
+ falconPublic.get(validatorIndex), message.toArray(), signature.toArray());
|
|
+ }
|
|
+ };
|
|
+ }
|
|
+
|
|
+ private ProtocolContext context() {
|
|
+ final ValidatorProvider vp =
|
|
+ mock(ValidatorProvider.class, withSettings().strictness(Strictness.LENIENT));
|
|
+ when(vp.getValidatorsForBlock(any())).thenReturn(validators);
|
|
+ when(vp.getValidatorsAfterBlock(any())).thenReturn(validators);
|
|
+ final BftContext bft = mock(BftContext.class, withSettings().strictness(Strictness.LENIENT));
|
|
+ when(bft.getValidatorProvider()).thenReturn(vp);
|
|
+ when(bft.as(any())).thenReturn(bft);
|
|
+ return new ProtocolContext.Builder().withConsensusContext(bft).build();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Validator {@code who}'s commit on {@code b} at {@code round}, on the emitter's path (QbftRound):
|
|
+ * the ECDSA commit seal over the round's commit hash, the Falcon seal over
|
|
+ * PqAnchorProducer.commitSealMessage (the anchor form from height 3, the round-0 hash).
|
|
+ */
|
|
+ private Commit commit(final int who, final Block b, final int round) {
|
|
+ final QbftBlock qb = new QbftBlockAdaptor(b);
|
|
+ final Hash commitHash = blockInterface.replaceRoundForCommitBlock(qb, round).getHash();
|
|
+ final SECPSignature ecdsa = keys.get(who).sign(Bytes32.wrap(commitHash.getBytes()));
|
|
+ final Bytes32 pqMessage =
|
|
+ PqAnchorProducer.commitSealMessage(
|
|
+ b.getHeader().getNumber(),
|
|
+ () -> blockInterface.replaceRoundForCommitBlock(qb, 0).getHash().getBytes(),
|
|
+ commitHash,
|
|
+ round).orElseThrow();
|
|
+ final byte[] signature =
|
|
+ SealSchemes.FALCON_512.sign(falconPrivate.get(who), pqMessage.toArray()).orElseThrow();
|
|
+ return new MessageFactory(keys.get(who), blockCodec)
|
|
+ .createCommit(
|
|
+ new ConsensusRoundIdentifier(b.getHeader().getNumber(), round),
|
|
+ commitHash,
|
|
+ ecdsa,
|
|
+ Optional.of(new FalconSeal(who, Bytes.wrap(signature))));
|
|
+ }
|
|
+
|
|
+ private MutableBlockchain chain(final List<Block> blocks) {
|
|
+ final MutableBlockchain chain =
|
|
+ InMemoryKeyValueStorageProvider.createInMemoryBlockchain(
|
|
+ genesis, BftBlockHeaderFunctions.forOnchainBlock(codec));
|
|
+ for (final Block b : blocks) {
|
|
+ chain.appendBlock(b, List.of());
|
|
+ }
|
|
+ return chain;
|
|
+ }
|
|
+
|
|
+ /** A block with real QBFT extra data (the ten validators, round 0, a distinct vanity tag). */
|
|
+ private Block block(final Block parent) {
|
|
+ tag++;
|
|
+ final BftExtraData extra =
|
|
+ new BftExtraData(
|
|
+ Bytes32.leftPad(Bytes.ofUnsignedLong(tag)), List.of(), Optional.empty(), 0, validators);
|
|
+ return new Block(header(parent, extra, validators.get(0)), BlockBody.empty());
|
|
+ }
|
|
+
|
|
+ /** X's anchor over {@code parent}: the certificate, sorted, and its digest in vanityData (R1's form). */
|
|
+ private Block anchorOver(final Block parent, final List<FalconSeal> certificate) {
|
|
+ final List<FalconSeal> sorted = PqAnchor.sortedByIndex(certificate);
|
|
+ final Bytes32 digest =
|
|
+ PqAnchor.anchorDigest(
|
|
+ CHAIN, parent.getHeader().getNumber(), parent.getHash().getBytes(), sorted);
|
|
+ final BftExtraData extra =
|
|
+ new BftExtraData(digest, List.of(), Optional.empty(), X, validators, sorted, java.util.List.of(), BftExtraData.NO_CERTIFICATE_ROUND);
|
|
+ return new Block(header(parent, extra, validators.get(X)), BlockBody.empty());
|
|
+ }
|
|
+
|
|
+ private BlockHeader header(final Block parent, final BftExtraData extra, final Address coinbase) {
|
|
+ final long number = parent == null ? 0L : parent.getHeader().getNumber() + 1;
|
|
+ return new BlockHeaderTestFixture()
|
|
+ .number(number)
|
|
+ .parentHash(parent == null ? Hash.ZERO : parent.getHash())
|
|
+ .difficulty(Difficulty.ONE)
|
|
+ .extraData(codec.encode(extra))
|
|
+ .timestamp(number)
|
|
+ .coinbase(coinbase)
|
|
+ .blockHeaderFunctions(BftBlockHeaderFunctions.forOnchainBlock(codec))
|
|
+ .buildHeader();
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftControllerDecidedHeadTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftControllerDecidedHeadTest.java
|
|
new file mode 100644
|
|
index 0000000000..b9357ccb7c
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftControllerDecidedHeadTest.java
|
|
@@ -0,0 +1,1364 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
+import static org.mockito.Mockito.mock;
|
|
+import static org.mockito.Mockito.when;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedBlockChoiceRule;
|
|
+import org.hyperledger.besu.consensus.common.bft.AereDecidedHead;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
+import org.hyperledger.besu.consensus.common.bft.BlockTimer;
|
|
+import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
|
+import org.hyperledger.besu.consensus.common.bft.MessageTracker;
|
|
+import org.hyperledger.besu.consensus.common.bft.RoundTimer;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.ProposerSelector;
|
|
+import org.hyperledger.besu.consensus.common.bft.events.BftEvents;
|
|
+import org.hyperledger.besu.consensus.common.bft.events.BlockTimerExpiry;
|
|
+import org.hyperledger.besu.consensus.common.bft.events.RoundExpiry;
|
|
+import org.hyperledger.besu.consensus.common.bft.network.ValidatorMulticaster;
|
|
+import org.hyperledger.besu.consensus.common.bft.statemachine.FutureMessageBuffer;
|
|
+import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockAdaptor;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockCodecAdaptor;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockHeaderAdaptor;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockInterfaceAdaptor;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockchainAdaptor;
|
|
+import org.hyperledger.besu.consensus.qbft.adaptor.QbftFinalStateImpl;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagedata.CommitMessageData;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagedata.PrepareMessageData;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagedata.ProposalMessageData;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagedata.RoundChangeMessageData;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal;
|
|
+import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange;
|
|
+import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.AereDecidedConsensus;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.AereDecidedHook;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.AereDecisionEvidence;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.BaseQbftBlockHeightManager;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.QbftBlockHeightManagerFactory;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.QbftController;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.QbftRound;
|
|
+import org.hyperledger.besu.consensus.qbft.core.statemachine.RoundChangeManager;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCodec;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCreatorFactory;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockHeader;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftMessage;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftNewChainHead;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftReceivedMessageEvent;
|
|
+import org.hyperledger.besu.crypto.SECPSignature;
|
|
+import org.hyperledger.besu.cryptoservices.NodeKey;
|
|
+import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
+import org.hyperledger.besu.ethereum.core.Block;
|
|
+import org.hyperledger.besu.ethereum.core.BlockBody;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
|
+import org.hyperledger.besu.ethereum.core.Difficulty;
|
|
+import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider;
|
|
+import org.hyperledger.besu.ethereum.core.Util;
|
|
+import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData;
|
|
+
|
|
+import java.io.IOException;
|
|
+import java.nio.file.Files;
|
|
+import java.nio.file.Path;
|
|
+import java.time.Clock;
|
|
+import java.time.Instant;
|
|
+import java.time.ZoneId;
|
|
+import java.time.ZoneOffset;
|
|
+import java.util.ArrayDeque;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collection;
|
|
+import java.util.Deque;
|
|
+import java.util.List;
|
|
+import java.util.Optional;
|
|
+import java.util.Random;
|
|
+import java.util.concurrent.atomic.AtomicLong;
|
|
+import java.util.function.Function;
|
|
+import java.util.function.LongPredicate;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.junit.jupiter.api.io.TempDir;
|
|
+
|
|
+/**
|
|
+ * AERE D-412 / the DECIDED HEAD (rule D), step 3, proof P3 of PROIECT-CAP-DECIS-2026-09-29.md: the
|
|
+ * UPSTREAM {@link QbftController} with the patched adaptor ({@link QbftBlockchainAdaptor} with D), the
|
|
+ * patched final state ({@link QbftFinalStateImpl} with D) and the wiring ({@link AereDecidedConsensus}
|
|
+ * through {@link AereDecidedChainView#install}, exactly what the builder calls), over a REAL in-memory
|
|
+ * DefaultBlockchain carrying real QBFT extra data, with the decided head's block choice rule installed.
|
|
+ * Commits, proposals, prepares and round changes are signed by real node keys with the upstream
|
|
+ * MessageFactory. Only the height managers are recorded stand-ins (what the controller hands them is
|
|
+ * the measurement), and the wiring's executor is a queue the proof drains, so "not on the QBFT thread"
|
|
+ * is visible.
|
|
+ *
|
|
+ * <p>Four validators: Q = 3, f = 1, f + 1 = 2. H_ev = 3, so the PROOF height is H_ev - 1 = 2 (the
|
|
+ * second review of step 3, 2026-10-01: the parent of H_ev must be a proved block): with the chain at
|
|
+ * 1 or above, the decided head is block 1 (Q5 stops below the proof height) and the node runs height
|
|
+ * 2 over it, the way rule D runs every later height (one proof builds its wiring far below H_ev =
|
|
+ * 300). Until 2026-10-01 these proofs ran with H_ev = 2 and Q5 up to H_ev - 1 = 1: the same heights,
|
|
+ * with the boundary one height lower.
|
|
+ *
|
|
+ * <p>Four proofs answer the adversarial review of step 3 (2026-09-30): the collector's D from one
|
|
+ * source across H_ev, a validator more than W behind coming back on a live quorum with Q3 off, only
|
|
+ * the committing round's own commit as a vote, and a proof retained when the collector already
|
|
+ * follows its height. Four answer the second review (2026-10-01): a one-key sibling at the proof
|
|
+ * height neither starts H_ev nor splits the nodes, a proof at the proof height overrides an unproved
|
|
+ * line below it, and the durable floor (no vote below it; a proof against it is a conflict).
|
|
+ *
|
|
+ * <p>Teza Q3 (D-470, 2026-10-01): the wiring hands Q3 the answer of ONE function, AereCertifiedDecision
|
|
+ * (the block a certified anchor's certificate decides), not a Keff; the proof of Q3 here measures the
|
|
+ * WIRING (the view moves D onto exactly what that function answers), and AereCertifiedDecisionTest
|
|
+ * measures the function.
|
|
+ */
|
|
+public class QbftControllerDecidedHeadTest {
|
|
+
|
|
+ private static final long H_EV = 3L;
|
|
+
|
|
+ private final QbftExtraDataCodec codec = new QbftExtraDataCodec();
|
|
+ private final QbftBlockInterface blockInterface =
|
|
+ new QbftBlockInterfaceAdaptor(new BftBlockInterface(codec));
|
|
+ private final QbftBlockCodec blockCodec = new QbftBlockCodecAdaptor(codec);
|
|
+ private final List<NodeKey> keys = new ArrayList<>();
|
|
+ private final List<Address> validators = new ArrayList<>();
|
|
+ private NodeKey outsider;
|
|
+ private long tag;
|
|
+
|
|
+ @TempDir Path tmp;
|
|
+
|
|
+ @BeforeEach
|
|
+ public void setUp() {
|
|
+ AereDecidedHook.reset();
|
|
+ for (int i = 0; i < 4; i++) {
|
|
+ final NodeKey k = NodeKeyUtils.generate();
|
|
+ keys.add(k);
|
|
+ validators.add(Util.publicKeyToAddress(k.getPublicKey()));
|
|
+ }
|
|
+ outsider = NodeKeyUtils.generate();
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ public void tearDown() {
|
|
+ AereDecidedHook.reset();
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // P3 (a): a provisional head does not start the next height; D does, posted off the QBFT thread
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void aProvisionalHeadDoesNotStartTheNextHeightTheDecidedHeadDoes() {
|
|
+ final Block g = block(null, 1);
|
|
+ final Block b1 = block(g, 1);
|
|
+ final Block b2 = block(b1, 1);
|
|
+ final World w = new World(g, List.of(b1, b2), H_EV, true);
|
|
+ assertThat(w.head.decided().hash()).as("D is block 1 (Q5)").isEqualTo(b1.getHash());
|
|
+ assertThat(w.chain.getChainHeadHeader().getHash())
|
|
+ .as("the canonical head is the provisional block 2")
|
|
+ .isEqualTo(b2.getHash());
|
|
+ assertThat(w.createdParents()).as("start() runs on D, not on the canonical head").containsExactly(1L);
|
|
+
|
|
+ w.controller.handleNewBlockEvent(newHead(b2.getHeader()));
|
|
+ assertThat(w.createdParents())
|
|
+ .as("a new chain head that is not D starts nothing")
|
|
+ .containsExactly(1L);
|
|
+
|
|
+ w.wiring.ownRoundDecided(new QbftBlockAdaptor(b2), 0);
|
|
+ assertThat(w.head.decided().hash())
|
|
+ .as("the own-round decision is handed to the wiring's executor, not done on this thread")
|
|
+ .isEqualTo(b1.getHash());
|
|
+ w.drain();
|
|
+ assertThat(w.head.decided().hash()).as("Q1 of the own round moved D").isEqualTo(b2.getHash());
|
|
+ assertThat(w.posted)
|
|
+ .as("the move of D posts exactly one new chain head, D's")
|
|
+ .extracting(BlockHeader::getHash)
|
|
+ .containsExactly(b2.getHash());
|
|
+
|
|
+ w.controller.handleNewBlockEvent(newHead(w.posted.get(0)));
|
|
+ assertThat(w.createdParents()).as("D starts the next height").containsExactly(1L, 2L);
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // P3 (b): the height guard runs on D, so messages of D+1 are handled while the canonical head is ahead
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void messagesOfTheNextHeightAreHandledWhileTheCanonicalHeadIsAhead() {
|
|
+ final Block g = block(null, 1);
|
|
+ final Block b1 = block(g, 1);
|
|
+ final Block b2 = block(b1, 1);
|
|
+ final World w = new World(g, List.of(b1, b2), H_EV, true);
|
|
+ w.deliver(prepare(1, 2, b2.getHash()));
|
|
+ w.deliver(commit(2, b2, 0));
|
|
+ assertThat(w.handled())
|
|
+ .as("a prepare and a commit of height 2 reach the height manager of height 2")
|
|
+ .contains("prepare 2/0 " + validators.get(1), "commit 2/0 " + validators.get(2));
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // P3 (c): the echo
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void aRoundChangeForADecidedHeightIsEchoedOnceAndTheLaggardAdvancesOnTheEcho() {
|
|
+ final Block g = block(null, 1);
|
|
+ final Block b1 = block(g, 1);
|
|
+ final Block b2 = block(b1, 1);
|
|
+ final Block b3 = block(b2, 1);
|
|
+ final World decider = new World(g, List.of(b1, b2, b3), H_EV, true);
|
|
+ for (int i = 1; i <= 3; i++) {
|
|
+ decider.deliver(commit(i, b2, 0));
|
|
+ }
|
|
+ decider.drain();
|
|
+ assertThat(decider.head.decided().hash())
|
|
+ .as("the decider decided block 2 by Q1 from the commits it heard")
|
|
+ .isEqualTo(b2.getHash());
|
|
+ for (int i = 1; i <= 3; i++) {
|
|
+ decider.deliver(commit(i, b3, 0));
|
|
+ }
|
|
+ decider.drain();
|
|
+ assertThat(decider.head.decided().hash()).as("and then block 3").isEqualTo(b3.getHash());
|
|
+ assertThat(decider.wiring.evidence().retainedProof(2)).as("the proofs are retained for the echo").isPresent();
|
|
+ assertThat(decider.wiring.evidence().retainedProof(3)).isPresent();
|
|
+
|
|
+ decider.deliver(roundChange(keys.get(3), 2, 1));
|
|
+ assertThat(decider.echoed)
|
|
+ .as("a RoundChange at a decided height from a member of its set: the three commits, once")
|
|
+ .hasSize(3);
|
|
+ decider.deliver(roundChange(keys.get(3), 2, 2));
|
|
+ assertThat(decider.echoed).as("the same author again within 10 s: no second echo").hasSize(3);
|
|
+ decider.deliver(roundChange(keys.get(3), 3, 1));
|
|
+ assertThat(decider.echoed)
|
|
+ .as("the same author within 10 s at ANOTHER decided height: no echo either (one per author)")
|
|
+ .hasSize(3);
|
|
+ decider.deliver(roundChange(outsider, 2, 1));
|
|
+ assertThat(decider.echoed).as("an author outside the set: no echo").hasSize(3);
|
|
+ decider.deliver(roundChange(keys.get(2), 3, 1));
|
|
+ assertThat(decider.echoed).as("another member: its own echo").hasSize(6);
|
|
+ decider.time.set(decider.time.get() + AereDecidedConsensus.ECHO_INTERVAL_MILLIS + 1);
|
|
+ decider.deliver(roundChange(keys.get(3), 2, 3));
|
|
+ assertThat(decider.echoed).as("the first author after 10 s: echoed again").hasSize(9);
|
|
+ assertThat(decider.wiring.echoes()).isEqualTo(3);
|
|
+
|
|
+ final World laggard = new World(g, List.of(b1, b2), H_EV, false);
|
|
+ assertThat(laggard.head.decided().hash()).as("control: the laggard is still at 1").isEqualTo(b1.getHash());
|
|
+ for (final MessageData m : decider.echoed.subList(0, 3)) {
|
|
+ final Commit c = CommitMessageData.fromMessageData(m).decode();
|
|
+ laggard.wiring.observe(c, () -> m);
|
|
+ }
|
|
+ laggard.drain();
|
|
+ assertThat(laggard.head.decided().hash())
|
|
+ .as("the laggard decided block 2 on the echoed commits alone")
|
|
+ .isEqualTo(b2.getHash());
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // P3 (d): replay from the collector beyond the future-message buffer
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void startingAHeightReplaysTheMessagesTheFutureBufferCouldNotKeep() {
|
|
+ final Block g = block(null, 1);
|
|
+ final List<Block> line = new ArrayList<>();
|
|
+ Block p = g;
|
|
+ for (int i = 1; i <= 24; i++) {
|
|
+ p = block(p, 1);
|
|
+ line.add(p);
|
|
+ }
|
|
+ final World w = new World(g, line, H_EV, true);
|
|
+ assertThat(w.createdParents()).containsExactly(1L);
|
|
+ w.deliver(prepare(1, 25, Hash.hash(Bytes.of(25))));
|
|
+ assertThat(w.log).as("height 25 is beyond the future buffer (10): nothing reaches a manager").isEmpty();
|
|
+ assertThat(w.wiring.rawAt(25)).as("the collector keeps it (window 256)").isEqualTo(1);
|
|
+
|
|
+ assertThat(w.head.advance(line.get(23).getHash(), AereDecidedHead.Proof.Q3))
|
|
+ .isEqualTo(AereDecidedHead.Outcome.ADVANCED);
|
|
+ assertThat(w.posted).extracting(BlockHeader::getNumber).containsExactly(24L);
|
|
+ w.controller.handleNewBlockEvent(newHead(w.posted.get(0)));
|
|
+ assertThat(w.createdParents()).containsExactly(1L, 24L);
|
|
+ assertThat(w.handled())
|
|
+ .as("the manager of height 25 receives the kept prepare exactly once")
|
|
+ .containsExactly("prepare 25/0 " + validators.get(1));
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // the raw store for the replay: validators only, bounded per (height, author)
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void theRawStoreKeepsValidatorsOnlyAndBoundsEachAuthor() {
|
|
+ final Block g = block(null, 1);
|
|
+ final Block b1 = block(g, 1);
|
|
+ final World w = new World(g, List.of(b1), H_EV, true);
|
|
+ w.deliver(prepareBy(outsider, 20, Hash.hash(Bytes.of(1))));
|
|
+ assertThat(w.wiring.rawAt(20)).as("a non-validator's message is not kept").isZero();
|
|
+ for (int i = 0; i < 100; i++) {
|
|
+ w.deliver(prepare(1, 20, Hash.hash(Bytes.ofUnsignedInt(1000 + i))));
|
|
+ }
|
|
+ assertThat(w.wiring.rawAt(20))
|
|
+ .as("one validator floods height 20: it keeps its quota")
|
|
+ .isEqualTo(AereDecidedConsensus.MAX_RAW_PER_AUTHOR_HEIGHT);
|
|
+ w.deliver(prepare(2, 20, Hash.hash(Bytes.of(2))));
|
|
+ assertThat(w.wiring.rawAt(20))
|
|
+ .as("and another validator's message at the same height is still kept")
|
|
+ .isEqualTo(AereDecidedConsensus.MAX_RAW_PER_AUTHOR_HEIGHT + 1);
|
|
+ assertThat(w.wiring.rawRefused()).isEqualTo(100L - AereDecidedConsensus.MAX_RAW_PER_AUTHOR_HEIGHT);
|
|
+ assertThat(w.wiring.rawBytesOf(validators.get(1))).isPositive();
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // observe-first: a laggard (D-419) leaves its height on f+1 commits of the next height
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void aLaggardLeavesItsHeightOnFPlusOneCommitsOfTheNextHeight() {
|
|
+ final Block g = block(null, 1);
|
|
+ final Block b1 = block(g, 1);
|
|
+ final Block b2 = block(b1, 1);
|
|
+ final Block c3 = block(b2, 1);
|
|
+ final World w = new World(g, List.of(b1, b2), H_EV, true);
|
|
+ w.deliver(proposal(1, c3));
|
|
+ w.deliver(commit(1, c3, 0));
|
|
+ w.deliver(commit(2, c3, 0));
|
|
+ w.drain();
|
|
+ assertThat(w.head.decided().hash())
|
|
+ .as("Q2: f+1 = 2 commits of height 3 on a child of block 2 decide block 2")
|
|
+ .isEqualTo(b2.getHash());
|
|
+ w.controller.handleNewBlockEvent(newHead(w.posted.get(0)));
|
|
+ assertThat(w.createdParents()).containsExactly(1L, 2L);
|
|
+ assertThat(w.handled())
|
|
+ .as("the buffered messages of height 3 reach its manager once each, not twice")
|
|
+ .containsExactly(
|
|
+ "proposal 3/0 " + validators.get(1),
|
|
+ "commit 3/0 " + validators.get(1),
|
|
+ "commit 3/0 " + validators.get(2));
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // the final state: the set after D
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void theValidatorSetIsTheSetAfterTheDecidedHead() {
|
|
+ final Block g = block(null, 1);
|
|
+ final Block b1 = block(g, 1);
|
|
+ final Block b2 = block(b1, 1);
|
|
+ final List<Address> atHead = List.of(validators.get(1), validators.get(2), validators.get(3), outsiderAddress());
|
|
+ final ValidatorProvider vp = mock(ValidatorProvider.class);
|
|
+ when(vp.getValidatorsAtHead()).thenReturn(atHead);
|
|
+ when(vp.getValidatorsAfterBlock(any())).thenReturn(validators);
|
|
+ when(vp.getValidatorsForBlock(any())).thenReturn(validators);
|
|
+ final MutableBlockchain chain = chain(g, List.of(b1, b2));
|
|
+ final AereDecidedHead head = new AereDecidedHead(chain, H_EV, tmp.resolve("fs-head"), 256, m -> {});
|
|
+ head.restore(List.of());
|
|
+ final QbftFinalStateImpl fs = finalState(vp, head);
|
|
+ assertThat(fs.getValidators()).as("the set after D (block 1), not the set at the provisional head").isEqualTo(validators);
|
|
+ assertThat(fs.isLocalNodeValidator()).isTrue();
|
|
+ assertThat(fs.getQuorum()).isEqualTo(3);
|
|
+ final QbftFinalStateImpl upstream = finalState(vp, null);
|
|
+ assertThat(upstream.getValidators()).as("control: without D the set at the head").isEqualTo(atHead);
|
|
+ assertThat(upstream.isLocalNodeValidator()).isFalse();
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // below H_ev: the controller with rule D wired behaves exactly as upstream
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void belowTheActivationHeightTheControllerBehavesAsUpstreamOnRandomScripts() throws Exception {
|
|
+ final int scripts = 300;
|
|
+ long events = 0;
|
|
+ long entries = 0;
|
|
+ long starts = 0;
|
|
+ int divergent = 0;
|
|
+ for (int s = 0; s < scripts; s++) {
|
|
+ final Random rnd = new Random(0xD412L * 1000 + s);
|
|
+ final Block g = block(null, 1);
|
|
+ final List<Block> base = new ArrayList<>();
|
|
+ Block p = g;
|
|
+ for (int i = 0; i < 3; i++) {
|
|
+ p = block(p, 1);
|
|
+ base.add(p);
|
|
+ }
|
|
+ final List<Object> script = script(rnd, base);
|
|
+ events += script.size();
|
|
+ AereDecidedHook.reset();
|
|
+ final World a = new World(g, base, AereDecidedHead.DEFAULT_MAX_WALK, false, true);
|
|
+ final List<String> la = a.run(script);
|
|
+ final World b = new World(g, base, 1_000_000L, true, false);
|
|
+ final List<String> lb = b.run(script);
|
|
+ AereDecidedHook.reset();
|
|
+ entries += la.size();
|
|
+ starts += la.stream().filter(x -> x.startsWith("start ")).count();
|
|
+ if (!la.equals(lb)) {
|
|
+ divergent++;
|
|
+ }
|
|
+ }
|
|
+ System.out.println(
|
|
+ "AERE D-412 step3 differential below H_ev: scripts="
|
|
+ + scripts
|
|
+ + " events="
|
|
+ + events
|
|
+ + " recorded="
|
|
+ + entries
|
|
+ + " heightStarts="
|
|
+ + starts
|
|
+ + " divergent="
|
|
+ + divergent);
|
|
+ assertThat(starts).as("control: the scripts start new heights").isGreaterThan(scripts);
|
|
+ assertThat(divergent).as("scripts whose recorded behaviour differs").isZero();
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // the own round: Q1, the own commit only at the decision, the proof retained with it
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void theOwnRoundDecidesWithTheOwnCommitCountedOnlyAtTheDecision() {
|
|
+ final Block g = block(null, 1);
|
|
+ final Block b1 = block(g, 1);
|
|
+ final Block b2 = block(b1, 1);
|
|
+ final World w = new World(g, List.of(b1, b2), H_EV, true);
|
|
+ final QbftBlock qb2 = new QbftBlockAdaptor(b2);
|
|
+ final Hash digest = blockInterface.replaceRoundForCommitBlock(qb2, 0).getHash();
|
|
+ final Commit own =
|
|
+ new MessageFactory(keys.get(0), blockCodec)
|
|
+ .createCommit(new ConsensusRoundIdentifier(2, 0), digest, seal(0, digest));
|
|
+ w.wiring.ownCommit(own);
|
|
+ w.deliver(commit(1, b2, 0));
|
|
+ w.deliver(commit(2, b2, 0));
|
|
+ w.drain();
|
|
+ assertThat(w.wiring.evidence().countedAuthors(2))
|
|
+ .as("before its round commits, the own commit is not counted (2 of Q = 3)")
|
|
+ .containsExactlyInAnyOrder(validators.get(1), validators.get(2));
|
|
+ assertThat(w.head.decided().hash()).isEqualTo(b1.getHash());
|
|
+ w.wiring.ownRoundDecided(qb2, 0);
|
|
+ w.drain();
|
|
+ assertThat(w.head.decided().hash()).as("Q1 of the own round").isEqualTo(b2.getHash());
|
|
+ final Optional<AereDecisionEvidence.Proof> proof = w.wiring.evidence().retainedProof(2);
|
|
+ assertThat(proof).as("the echo proof is retained").isPresent();
|
|
+ assertThat(proof.get().authors())
|
|
+ .as("with the own commit in it")
|
|
+ .containsExactlyInAnyOrder(validators.get(0), validators.get(1), validators.get(2));
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // Q3 wired: a stored certified anchor moves D onto exactly the block its certificate decides
|
|
+ // (renamed 2026-10-01 from aStoredCertifiedAnchorDecidesItsParentOnlyWithKeffAtLeastFPlusOne, teza Q3:
|
|
+ // the view no longer reads a Keff; what the certificate decides is AereCertifiedDecision's)
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void aStoredCertifiedAnchorMovesDOntoTheBlockItsCertificateDecides() {
|
|
+ final Block g = block(null, 1);
|
|
+ final Block b1 = block(g, 1);
|
|
+ final Block b2 = block(b1, 1);
|
|
+ final Block b3 = block(b2, 1);
|
|
+ final Block b4 = block(b3, 1);
|
|
+ // the certificate of the anchor at 4 decides its GRANDPARENT 2 (the form from H_hdr)
|
|
+ final World on =
|
|
+ new World(
|
|
+ g,
|
|
+ List.of(b1),
|
|
+ H_EV,
|
|
+ true,
|
|
+ h -> h % 4 == 0,
|
|
+ h ->
|
|
+ h.getNumber() == 4L
|
|
+ ? Optional.of(new AereDecidedHead.Decided(2L, b2.getHash()))
|
|
+ : Optional.empty());
|
|
+ on.appendAll(List.of(b2, b3, b4));
|
|
+ on.drain();
|
|
+ assertThat(on.head.decided().hash())
|
|
+ .as("anchor 4 moves D onto 2, the block its certificate decides, and not onto its parent 3")
|
|
+ .isEqualTo(b2.getHash());
|
|
+ AereDecidedHook.reset();
|
|
+ final World off = new World(g, List.of(b1), H_EV, true, h -> h % 4 == 0, h -> Optional.empty());
|
|
+ off.appendAll(List.of(b2, b3, b4));
|
|
+ off.drain();
|
|
+ assertThat(off.head.decided().hash())
|
|
+ .as("control: a certificate that decides nothing moves nothing")
|
|
+ .isEqualTo(b1.getHash());
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // review of step 3 (2026-09-30), BLOCKING 1: the collector's D comes from the chain, one source
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /**
|
|
+ * A validator whose wiring is built with the chain far below H_ev - W (the activation path planned
|
|
+ * for 28001 and 2800): below the proof height H_ev - 1 its D is moved by the canonical head (Q5),
|
|
+ * never by the wiring. Above it the collector must work above THAT D, or it drops every commit of
|
|
+ * H_ev. The decider decides H_ev on commits it HEARD (no own round) and retains the proof; the
|
|
+ * laggard, whose canonical head is already ten blocks past H_ev (so H_ev is not a live height for
|
|
+ * it), decides H_ev on the echo. (2026-10-01: Q5 now stops at H_ev - 2, so the proof of H_ev also
|
|
+ * decides H_ev - 1 as its ancestor.)
|
|
+ */
|
|
+ @Test
|
|
+ public void aCollectorBuiltFarBelowHevFollowsTheDecidedHeadAcrossHev() {
|
|
+ final long hEv = 300L;
|
|
+ final Block g = block(null, 1);
|
|
+ final Block b1 = block(g, 1);
|
|
+ final List<Block> line = new ArrayList<>();
|
|
+ Block p = b1;
|
|
+ for (long n = 2; n <= hEv + 10; n++) {
|
|
+ p = block(p, 1);
|
|
+ line.add(p);
|
|
+ }
|
|
+ final Block atHev = line.get((int) (hEv - 2));
|
|
+ assertThat(atHev.getHeader().getNumber()).isEqualTo(hEv);
|
|
+
|
|
+ final World decider = new World(g, List.of(b1), hEv, true);
|
|
+ assertThat(decider.wiring.evidence().decidedHeight())
|
|
+ .as("control: the collector is built at D = 1, more than W below H_ev")
|
|
+ .isEqualTo(1L);
|
|
+ decider.appendAll(line.subList(0, (int) (hEv - 1)));
|
|
+ decider.drain();
|
|
+ assertThat(decider.head.decided().number())
|
|
+ .as("control: D = H_ev - 2, moved by the canonical head (Q5, which stops below the proof height), not by the wiring")
|
|
+ .isEqualTo(hEv - 2);
|
|
+ for (int i = 1; i <= 3; i++) {
|
|
+ decider.deliver(commit(i, atHev, 0));
|
|
+ }
|
|
+ decider.drain();
|
|
+ assertThat(decider.head.decided().hash())
|
|
+ .as("Q1 of H_ev from the commits the decider heard (no own round)")
|
|
+ .isEqualTo(atHev.getHash());
|
|
+ final Optional<AereDecisionEvidence.Proof> proof =
|
|
+ decider.wiring.evidence().retainedProof(hEv);
|
|
+ assertThat(proof).as("the proof of H_ev is retained for the echo").isPresent();
|
|
+ assertThat(proof.get().authors())
|
|
+ .containsExactlyInAnyOrder(validators.get(1), validators.get(2), validators.get(3));
|
|
+ decider.deliver(roundChange(keys.get(3), hEv, 1));
|
|
+ assertThat(decider.echoed).as("a RoundChange at H_ev is answered with the three commits").hasSize(3);
|
|
+
|
|
+ final World laggard = new World(g, List.of(b1), hEv, false);
|
|
+ laggard.appendAll(line);
|
|
+ laggard.drain();
|
|
+ assertThat(laggard.head.decided().number()).as("control: the laggard's D is H_ev - 2 (Q5)").isEqualTo(hEv - 2);
|
|
+ assertThat(laggard.chain.getChainHeadBlockNumber())
|
|
+ .as("control: its canonical head is past the live heights of H_ev")
|
|
+ .isEqualTo(hEv + 10);
|
|
+ for (final MessageData m : decider.echoed) {
|
|
+ final Commit c = CommitMessageData.fromMessageData(m).decode();
|
|
+ laggard.wiring.observe(c, () -> m);
|
|
+ }
|
|
+ laggard.drain();
|
|
+ assertThat(laggard.head.decided().hash())
|
|
+ .as("the laggard decided H_ev on the echoed commits")
|
|
+ .isEqualTo(atHev.getHash());
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // review of step 3, MAJOR: a validator more than W behind comes back on a LIVE quorum, Q3 off
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ @Test
|
|
+ public void aValidatorMoreThanWBehindComesBackOnALiveQuorumWithQ3Off() {
|
|
+ final Block g = block(null, 1);
|
|
+ final List<Block> line = new ArrayList<>();
|
|
+ Block p = g;
|
|
+ for (int i = 1; i <= AereDecidedHead.DEFAULT_MAX_WALK + 51; i++) {
|
|
+ p = block(p, 1);
|
|
+ line.add(p);
|
|
+ }
|
|
+ final World w = new World(g, line, H_EV, true, h -> h % 4 == 0, h -> Optional.empty());
|
|
+ w.wiring.evaluate();
|
|
+ w.drain();
|
|
+ assertThat(w.head.decided().number())
|
|
+ .as("control: Q3 is OFF (the certificates decide nothing), the anchors of the window move nothing")
|
|
+ .isEqualTo(1L);
|
|
+ assertThat(w.chain.getChainHeadBlockNumber() - w.head.decided().number())
|
|
+ .as("control: D is more than W behind the canonical head")
|
|
+ .isGreaterThan(AereDecidedHead.DEFAULT_MAX_WALK);
|
|
+ final Block live = block(line.get(line.size() - 1), 1);
|
|
+ w.deliver(proposal(1, live));
|
|
+ for (int i = 1; i <= 3; i++) {
|
|
+ w.deliver(commit(i, live, 0));
|
|
+ }
|
|
+ w.appendAll(List.of(live));
|
|
+ w.drain();
|
|
+ assertThat(w.head.decided().hash())
|
|
+ .as("a full quorum of the live height moves D over the gap, on the canonical line")
|
|
+ .isEqualTo(live.getHash());
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // review of step 3, MAJOR: only the committing round's own commit is a vote
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /**
|
|
+ * The node accepted b0 at round 0 but never got prepared (its round-0 commit was created at the
|
|
+ * proposal and never sent); round 0 still gathered Q - 1 = 2 real commits on b0. Round 1 committed b.
|
|
+ * If the unsent round-0 commit became a vote, the collector would hold a quorum on b0 that never
|
|
+ * existed on the network, and the evaluation would move D onto b0 when the advance onto b fails (a
|
|
+ * full disk, D-388): here every durable write fails, so D cannot move and the collector is read.
|
|
+ */
|
|
+ @Test
|
|
+ public void theOwnCommitOfARoundThatDidNotCommitIsNeverAVote() throws IOException {
|
|
+ final Block g = block(null, 1);
|
|
+ final Block b1 = block(g, 1);
|
|
+ final Block b = block(b1, 1);
|
|
+ final Block b0 = block(b1, 1);
|
|
+ final World w = new World(g, List.of(b1, b), H_EV, true);
|
|
+ w.appendAll(List.of(b0));
|
|
+ assertThat(w.chain.getChainHeadHeader().getHash())
|
|
+ .as("control: b is the head, b0 a stored fork")
|
|
+ .isEqualTo(b.getHash());
|
|
+ assertThat(w.chain.getBlockHeader(b0.getHash())).isPresent();
|
|
+ Files.createDirectories(w.head.file().resolve("blocked"));
|
|
+ final QbftBlock qb = new QbftBlockAdaptor(b);
|
|
+ final QbftBlock qb0 = new QbftBlockAdaptor(b0);
|
|
+ w.deliver(commit(1, b0, 0));
|
|
+ w.deliver(commit(2, b0, 0));
|
|
+ w.wiring.ownCommit(ownCommit(b0, 0));
|
|
+ w.wiring.ownCommit(ownCommit(b, 1));
|
|
+ w.deliver(commit(2, b, 1));
|
|
+ w.deliver(commit(3, b, 1));
|
|
+ w.wiring.ownRoundDecided(qb, 1);
|
|
+ w.drain();
|
|
+ assertThat(w.head.notDurableCount())
|
|
+ .as("control: the advance was asked for and could not be written")
|
|
+ .isPositive();
|
|
+ assertThat(w.head.decided().hash()).isEqualTo(b1.getHash());
|
|
+ assertThat(w.wiring.evidence().quorumFor(qb0))
|
|
+ .as("no quorum on b0: its 2 real commits and the UNSENT own commit of round 0 are not Q = 3")
|
|
+ .isEmpty();
|
|
+ final Optional<AereDecisionEvidence.Proof> onB = w.wiring.evidence().quorumFor(qb);
|
|
+ assertThat(onB)
|
|
+ .as("control: the own commit of the committing round IS a vote (Q on b at round 1)")
|
|
+ .isPresent();
|
|
+ assertThat(onB.get().round()).isEqualTo(1);
|
|
+ assertThat(onB.get().authors()).contains(validators.get(0));
|
|
+ assertThat(w.wiring.ownCommitsNotCounted())
|
|
+ .as("the own commit of round 0 was dropped at the decision")
|
|
+ .isEqualTo(1L);
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // review of step 3: the proof is retained when the collector already follows D at its height
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /**
|
|
+ * The interleaving of production: the wiring's executor moves D on the chain, and before it tells
|
|
+ * the collector, the QBFT thread handles a message and brings the collector up to the chain's D. The
|
|
+ * proof must still be retained for the echo.
|
|
+ */
|
|
+ @Test
|
|
+ public void aProofIsRetainedEvenWhenTheCollectorAlreadyFollowsItsHeight() {
|
|
+ final Block g = block(null, 1);
|
|
+ final Block b1 = block(g, 1);
|
|
+ final Block b2 = block(b1, 1);
|
|
+ final World w = new World(g, List.of(b1, b2), H_EV, true);
|
|
+ for (int i = 1; i <= 3; i++) {
|
|
+ w.deliver(commit(i, b2, 0));
|
|
+ }
|
|
+ final MessageData next = prepare(1, 3, Hash.hash(Bytes.of(3)));
|
|
+ w.head.onAdvanced(
|
|
+ d -> {
|
|
+ w.chain.getBlockHeader(d.hash()).ifPresent(w.posted::add);
|
|
+ w.wiring.observe(PrepareMessageData.fromMessageData(next).decode(), () -> next);
|
|
+ });
|
|
+ w.drain();
|
|
+ assertThat(w.head.decided().hash()).isEqualTo(b2.getHash());
|
|
+ assertThat(w.wiring.rawAt(3))
|
|
+ .as("control: the QBFT-thread message was handled between the move of D and the collector")
|
|
+ .isEqualTo(1);
|
|
+ assertThat(w.wiring.evidence().retainedProof(2))
|
|
+ .as("the proof of 2 is retained for the echo all the same")
|
|
+ .isPresent();
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // second review of step 3 (2026-10-01), MAJOR: the boundary. The parent of H_ev must be PROVED
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /**
|
|
+ * Below H_ev a single key can still make a node adopt a sibling of the block the fleet decides at
|
|
+ * H_ev - 1 (C1 is upstream behaviour there). If the canonical block at H_ev - 1 were D (Q5), node A
|
|
+ * would start H_ev over the forged sibling, its comparator would then hold the honest chain as a
|
|
+ * fork for good and every proof of it would be a CONFLICT: the honest nodes split, for ever. Rule D
|
|
+ * asks a PROOF for H_ev - 1 instead: A keeps running height 2 over block 1, the forged sibling does
|
|
+ * not start H_ev, A takes the messages of height 2, and on the quorum it hears it decides B* (the
|
|
+ * chain rewound onto it) and starts H_ev over B*. Control: B, whose canonical block at 2 was B*,
|
|
+ * decides the same block.
|
|
+ */
|
|
+ @Test
|
|
+ public void aOneKeySiblingAtTheProofHeightNeitherStartsHevNorSplitsTheNodes() {
|
|
+ final Block g = block(null, 1);
|
|
+ final Block b1 = block(g, 1);
|
|
+ final Block bStar = block(b1, 1);
|
|
+ final Block bForged = block(b1, 1);
|
|
+ final World a = new World(g, List.of(b1, bForged), H_EV, true);
|
|
+ assertThat(a.chain.getChainHeadHeader().getHash())
|
|
+ .as("control: A adopted the forged sibling at H_ev - 1 = 2")
|
|
+ .isEqualTo(bForged.getHash());
|
|
+ assertThat(a.head.decided().hash())
|
|
+ .as("D is block 1: Q5 stops below the proof height, the canonical block at 2 is no proof")
|
|
+ .isEqualTo(b1.getHash());
|
|
+ assertThat(a.createdParents()).as("A runs height 2 over block 1").containsExactly(1L);
|
|
+ a.controller.handleNewBlockEvent(newHead(bForged.getHeader()));
|
|
+ assertThat(a.createdParents())
|
|
+ .as("the forged sibling at H_ev - 1 does not start H_ev")
|
|
+ .containsExactly(1L);
|
|
+ a.deliver(prepare(1, 2, bStar.getHash()));
|
|
+ assertThat(a.handled())
|
|
+ .as("A still takes the messages of height 2")
|
|
+ .containsExactly("prepare 2/0 " + validators.get(1));
|
|
+ assertThat(a.wiring.rawAt(2))
|
|
+ .as("the raw store keeps nothing below H_ev: the replay runs only from H_ev")
|
|
+ .isZero();
|
|
+ a.appendAll(List.of(bStar));
|
|
+ assertThat(a.chain.getChainHeadHeader().getHash())
|
|
+ .as("control: B* is stored as a fork, the forged sibling stays canonical")
|
|
+ .isEqualTo(bForged.getHash());
|
|
+ for (int i = 1; i <= 3; i++) {
|
|
+ a.deliver(commit(i, bStar, 0));
|
|
+ }
|
|
+ a.drain();
|
|
+ assertThat(a.head.decided().hash()).as("A decides B* on the quorum it heard").isEqualTo(bStar.getHash());
|
|
+ assertThat(a.chain.getBlockHashByNumber(2L)).as("and the chain is rewound onto B*").contains(bStar.getHash());
|
|
+ assertThat(a.posted).extracting(BlockHeader::getHash).containsExactly(bStar.getHash());
|
|
+ a.controller.handleNewBlockEvent(newHead(a.posted.get(0)));
|
|
+ assertThat(a.created.get(a.created.size() - 1).getHash())
|
|
+ .as("H_ev starts over B*, the proved parent")
|
|
+ .isEqualTo(bStar.getHash());
|
|
+ AereDecidedHook.reset();
|
|
+ final World b = new World(g, List.of(b1, bStar), H_EV, true);
|
|
+ for (int i = 1; i <= 3; i++) {
|
|
+ b.deliver(commit(i, bStar, 0));
|
|
+ }
|
|
+ b.drain();
|
|
+ assertThat(b.head.decided().hash())
|
|
+ .as("control: B, whose canonical block at 2 was B*, decides the same block: no split")
|
|
+ .isEqualTo(a.head.decided().hash());
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Q5 is no proof: a node whose canonical line below the proof height went through a forged block 1
|
|
+ * (and a forged block 2 above it) has a Q5 D that a single key chose. A quorum at the proof height
|
|
+ * on B* (over the honest block 1) moves D onto B* all the same, rewinding the chain, and raises no
|
|
+ * conflict. Once a proof has moved D, a block off its line is a CONFLICT again (step 2's proofs).
|
|
+ */
|
|
+ @Test
|
|
+ public void aProofAtTheProofHeightOverridesAnUnprovedLineBelowIt() {
|
|
+ final Block g = block(null, 1);
|
|
+ final Block b1 = block(g, 1);
|
|
+ final Block b1Forged = block(g, 1);
|
|
+ final Block b2Forged = block(b1Forged, 1);
|
|
+ final Block bStar = block(b1, 1);
|
|
+ final World c = new World(g, List.of(b1Forged, b2Forged), H_EV, true);
|
|
+ c.appendAll(List.of(b1, bStar));
|
|
+ assertThat(c.chain.getBlockHashByNumber(1L))
|
|
+ .as("control: the canonical line below the proof height is the forged one")
|
|
+ .contains(b1Forged.getHash());
|
|
+ assertThat(c.head.decided().hash())
|
|
+ .as("control: so the Q5 D is the forged block 1")
|
|
+ .isEqualTo(b1Forged.getHash());
|
|
+ for (int i = 1; i <= 3; i++) {
|
|
+ c.deliver(commit(i, bStar, 0));
|
|
+ }
|
|
+ c.drain();
|
|
+ assertThat(c.head.decided().hash())
|
|
+ .as("a quorum on B* at the proof height moves D off the unproved line")
|
|
+ .isEqualTo(bStar.getHash());
|
|
+ assertThat(c.chain.getBlockHashByNumber(1L))
|
|
+ .as("and the chain is rewound onto B*'s line")
|
|
+ .contains(b1.getHash());
|
|
+ assertThat(c.head.conflicts()).isZero();
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // second review of step 3 (2026-10-01), MAJOR: the durable floor
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /**
|
|
+ * The durable D names block 3, and the chain lost the tail (a power cut): the node holds blocks 1
|
|
+ * and 2 only. Dropping the file would let it run heights 2 and 3 again; with enough such nodes a
|
|
+ * height already decided would get a second block. The file stays a FLOOR instead: announced on the
|
|
+ * alarm path, the node is no voter (no proposal, no vote, no message of its height handled) until D
|
|
+ * reaches the floor, which it does as soon as block 3 is stored again; then it votes again and the
|
|
+ * alarm path is told so.
|
|
+ */
|
|
+ @Test
|
|
+ public void belowItsDurableFloorTheNodeNeitherProposesNorVotesUntilTheBlockIsStoredAgain() {
|
|
+ final Block g = block(null, 1);
|
|
+ final Block b1 = block(g, 1);
|
|
+ final Block b2 = block(b1, 1);
|
|
+ final Block b3 = block(b2, 1);
|
|
+ final AereDecidedHead.Decided recorded = new AereDecidedHead.Decided(3L, b3.getHash());
|
|
+ final World w = new World(g, List.of(b1, b2), H_EV, true, recorded);
|
|
+ assertThat(w.head.floor())
|
|
+ .as("the durable D names block 3, which the chain lost: it stays a floor")
|
|
+ .contains(recorded);
|
|
+ assertThat(w.alarms).as("announced on the path a human reads").hasSize(1);
|
|
+ assertThat(w.alarms.get(0)).startsWith("CRIT " + AereDecidedHead.CODE_FLOOR);
|
|
+ final QbftFinalStateImpl fs = finalState(w.vp, w.head);
|
|
+ assertThat(fs.isLocalNodeValidator()).as("below its floor the node is no voter").isFalse();
|
|
+ w.deliver(prepare(1, 2, b2.getHash()));
|
|
+ assertThat(w.handled())
|
|
+ .as("and its controller handles no message of the height it may already have decided")
|
|
+ .isEmpty();
|
|
+ w.appendAll(List.of(b3));
|
|
+ w.drain();
|
|
+ assertThat(w.head.decided())
|
|
+ .as("block 3 is stored again: D is the floor's block")
|
|
+ .isEqualTo(recorded);
|
|
+ assertThat(w.head.floor()).isEmpty();
|
|
+ assertThat(fs.isLocalNodeValidator()).as("at its floor the node votes again").isTrue();
|
|
+ assertThat(w.alarms.get(w.alarms.size() - 1))
|
|
+ .as("and the alarm path is told it is over")
|
|
+ .contains(AereDecidedHead.CODE_FLOOR + " RESOLVED");
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * A quorum on a block 3 other than the one this node wrote durably as decided (more than f faulty,
|
|
+ * or a corrupted record) must not move D: it is a CONFLICT. What lies below it still moves D (Q2 of
|
|
+ * block 2, on f + 1 commits of its child), and the recorded block, once stored, becomes D.
|
|
+ */
|
|
+ @Test
|
|
+ public void aProofAgainstTheBlockTheNodeRecordedAsDecidedIsAConflict() {
|
|
+ final Block g = block(null, 1);
|
|
+ final Block b1 = block(g, 1);
|
|
+ final Block b2 = block(b1, 1);
|
|
+ final Block b3 = block(b2, 1);
|
|
+ final Block b3Other = block(b2, 1);
|
|
+ final World w =
|
|
+ new World(g, List.of(b1, b2), H_EV, true, new AereDecidedHead.Decided(3L, b3.getHash()));
|
|
+ w.appendAll(List.of(b3Other));
|
|
+ for (int i = 1; i <= 3; i++) {
|
|
+ w.deliver(commit(i, b3Other, 0));
|
|
+ }
|
|
+ w.drain();
|
|
+ assertThat(w.head.decided().number())
|
|
+ .as("control: Q2 of block 2 (f + 1 commits of its child) moved D, below the floor")
|
|
+ .isEqualTo(2L);
|
|
+ assertThat(w.head.conflicts())
|
|
+ .as("the quorum on another block 3 than the recorded one is a conflict")
|
|
+ .isPositive();
|
|
+ w.appendAll(List.of(b3));
|
|
+ w.drain();
|
|
+ assertThat(w.head.decided().hash())
|
|
+ .as("the recorded block, once stored, is D (the chain rewound onto it)")
|
|
+ .isEqualTo(b3.getHash());
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+ // fixtures
|
|
+ // ------------------------------------------------------------------------------------------
|
|
+
|
|
+ /** One node: its chain, decided head, wiring, controller and recorded height managers. */
|
|
+ private final class World {
|
|
+ private final MutableBlockchain chain;
|
|
+ private final AereDecidedHead head;
|
|
+ private final ValidatorProvider vp;
|
|
+ private final Deque<Runnable> tasks = new ArrayDeque<>();
|
|
+ private final List<BlockHeader> posted = new ArrayList<>();
|
|
+ private final List<MessageData> echoed = new ArrayList<>();
|
|
+ private final AtomicLong time = new AtomicLong(1_000_000L);
|
|
+ private final List<String> log = new ArrayList<>();
|
|
+ private final List<QbftBlockHeader> created = new ArrayList<>();
|
|
+ private final List<String> alarms = new ArrayList<>();
|
|
+ private final AereDecidedConsensus wiring;
|
|
+ private final QbftController controller;
|
|
+
|
|
+ World(final Block genesis, final List<Block> blocks, final long hEv, final boolean install) {
|
|
+ this(genesis, blocks, hEv, install, h -> false, h -> Optional.empty(), install, false, null);
|
|
+ }
|
|
+
|
|
+ /** A node whose durable D file already names {@code persisted} when it starts (a restart). */
|
|
+ World(
|
|
+ final Block genesis,
|
|
+ final List<Block> blocks,
|
|
+ final long hEv,
|
|
+ final boolean install,
|
|
+ final AereDecidedHead.Decided persisted) {
|
|
+ this(genesis, blocks, hEv, install, h -> false, h -> Optional.empty(), install, false, persisted);
|
|
+ }
|
|
+
|
|
+ World(
|
|
+ final Block genesis,
|
|
+ final List<Block> blocks,
|
|
+ final long hEv,
|
|
+ final boolean install,
|
|
+ final boolean upstream) {
|
|
+ this(genesis, blocks, hEv, install, h -> false, h -> Optional.empty(), install, upstream, null);
|
|
+ }
|
|
+
|
|
+ World(
|
|
+ final Block genesis,
|
|
+ final List<Block> blocks,
|
|
+ final long hEv,
|
|
+ final boolean install,
|
|
+ final LongPredicate anchor,
|
|
+ final Function<BlockHeader, Optional<AereDecidedHead.Decided>> decision) {
|
|
+ this(genesis, blocks, hEv, install, anchor, decision, install, false, null);
|
|
+ }
|
|
+
|
|
+ World(
|
|
+ final Block genesis,
|
|
+ final List<Block> blocks,
|
|
+ final long hEv,
|
|
+ final boolean install,
|
|
+ final LongPredicate anchor,
|
|
+ final Function<BlockHeader, Optional<AereDecidedHead.Decided>> decision,
|
|
+ final boolean withController,
|
|
+ final boolean upstream,
|
|
+ final AereDecidedHead.Decided persisted) {
|
|
+ chain = chain(genesis, blocks);
|
|
+ vp = mock(ValidatorProvider.class);
|
|
+ when(vp.getValidatorsAtHead()).thenReturn(validators);
|
|
+ when(vp.getValidatorsAfterBlock(any())).thenReturn(validators);
|
|
+ when(vp.getValidatorsForBlock(any())).thenReturn(validators);
|
|
+ final Path dir;
|
|
+ try {
|
|
+ dir = Files.createTempDirectory(tmp, "node");
|
|
+ } catch (final IOException e) {
|
|
+ throw new IllegalStateException(e);
|
|
+ }
|
|
+ head =
|
|
+ new AereDecidedHead(chain, hEv, dir.resolve(AereDecidedHead.FILE_NAME), 256, alarms::add);
|
|
+ if (persisted != null) {
|
|
+ try {
|
|
+ AereDecidedHead.writeDurably(head.file(), persisted, AereDecidedHead.Proof.Q1);
|
|
+ } catch (final IOException e) {
|
|
+ throw new IllegalStateException(e);
|
|
+ }
|
|
+ }
|
|
+ final Clock clock =
|
|
+ new Clock() {
|
|
+ @Override
|
|
+ public ZoneId getZone() {
|
|
+ return ZoneOffset.UTC;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Clock withZone(final ZoneId zone) {
|
|
+ return this;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Instant instant() {
|
|
+ return Instant.ofEpochMilli(time.get());
|
|
+ }
|
|
+ };
|
|
+ final ValidatorMulticaster echo =
|
|
+ new ValidatorMulticaster() {
|
|
+ @Override
|
|
+ public void send(final MessageData message) {
|
|
+ echoed.add(message);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void send(final MessageData message, final Collection<Address> denylist) {
|
|
+ echoed.add(message);
|
|
+ }
|
|
+ };
|
|
+ if (upstream) {
|
|
+ wiring = null;
|
|
+ } else {
|
|
+ AereDecidedBlockChoiceRule.install(chain, head);
|
|
+ head.restore(List.of());
|
|
+ if (install) {
|
|
+ wiring =
|
|
+ AereDecidedChainView.install(
|
|
+ chain,
|
|
+ head,
|
|
+ vp,
|
|
+ blockInterface,
|
|
+ echo,
|
|
+ posted::add,
|
|
+ anchor,
|
|
+ decision,
|
|
+ null,
|
|
+ chain::getChainHeadBlockNumber,
|
|
+ b -> 100L,
|
|
+ tasks::add,
|
|
+ clock);
|
|
+ } else {
|
|
+ wiring =
|
|
+ new AereDecidedConsensus(
|
|
+ new AereDecidedChainView(chain, head, vp, echo, anchor, decision, clock),
|
|
+ blockInterface,
|
|
+ null,
|
|
+ chain::getChainHeadBlockNumber,
|
|
+ b -> 100L,
|
|
+ tasks::add,
|
|
+ AereDecidedHead.DEFAULT_MAX_WALK);
|
|
+ head.onAdvanced(
|
|
+ d -> chain.getBlockHeader(d.hash()).ifPresent(posted::add));
|
|
+ }
|
|
+ }
|
|
+ if (withController || upstream) {
|
|
+ final QbftBlockHeightManagerFactory factory = mock(QbftBlockHeightManagerFactory.class);
|
|
+ when(factory.create(any()))
|
|
+ .thenAnswer(
|
|
+ inv -> {
|
|
+ final QbftBlockHeader parent = inv.getArgument(0);
|
|
+ created.add(parent);
|
|
+ log.add("start " + parent.getNumber() + " " + parent.getHash());
|
|
+ return new RecordingManager(parent, log);
|
|
+ });
|
|
+ controller =
|
|
+ new QbftController(
|
|
+ upstream ? new QbftBlockchainAdaptor(chain) : new QbftBlockchainAdaptor(chain, head),
|
|
+ upstream ? finalState(vp, null) : finalState(vp, head),
|
|
+ factory,
|
|
+ (message, replay) ->
|
|
+ log.add("gossip " + fingerprint(message.getData()) + " " + replay),
|
|
+ new MessageTracker(10_000),
|
|
+ new FutureMessageBuffer<>(10, 1000, chain.getChainHeadBlockNumber()),
|
|
+ blockCodec);
|
|
+ controller.start();
|
|
+ // the start is not part of what a script measures
|
|
+ log.clear();
|
|
+ final QbftBlockHeader first = created.get(0);
|
|
+ created.clear();
|
|
+ created.add(first);
|
|
+ } else {
|
|
+ controller = null;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ List<String> handled() {
|
|
+ final List<String> out = new ArrayList<>();
|
|
+ for (final String e : log) {
|
|
+ if (e.startsWith("proposal ")
|
|
+ || e.startsWith("prepare ")
|
|
+ || e.startsWith("commit ")
|
|
+ || e.startsWith("roundchange ")) {
|
|
+ out.add(e);
|
|
+ }
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ List<Long> createdParents() {
|
|
+ final List<Long> out = new ArrayList<>();
|
|
+ for (final QbftBlockHeader h : created) {
|
|
+ out.add(h.getNumber());
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ void deliver(final MessageData data) {
|
|
+ controller.handleMessageEvent(
|
|
+ new QbftReceivedMessageEvent() {
|
|
+ @Override
|
|
+ public QbftMessage getMessage() {
|
|
+ return () -> data;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public BftEvents.Type getType() {
|
|
+ return BftEvents.Type.MESSAGE;
|
|
+ }
|
|
+ });
|
|
+ }
|
|
+
|
|
+ void drain() {
|
|
+ Runnable r;
|
|
+ while ((r = tasks.poll()) != null) {
|
|
+ r.run();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ void appendAll(final List<Block> blocks) {
|
|
+ for (final Block b : blocks) {
|
|
+ chain.appendBlock(b, List.of());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /** Apply a script and return what the controller did with it. */
|
|
+ List<String> run(final List<Object> script) {
|
|
+ for (final Object e : script) {
|
|
+ if (e instanceof Block b) {
|
|
+ final Hash before = chain.getChainHeadHeader().getHash();
|
|
+ chain.appendBlock(b, List.of());
|
|
+ final BlockHeader after = chain.getChainHeadHeader();
|
|
+ if (!after.getHash().equals(before)) {
|
|
+ // what BftMiningCoordinator.onBlockAdded does for a new canonical head
|
|
+ controller.handleNewBlockEvent(newHead(after));
|
|
+ }
|
|
+ } else if (e instanceof MessageData m) {
|
|
+ deliver(m);
|
|
+ } else if (e instanceof BlockTimerExpiry t) {
|
|
+ controller.handleBlockTimerExpiry(t);
|
|
+ } else if (e instanceof RoundExpiry r) {
|
|
+ controller.handleRoundExpiry(r);
|
|
+ }
|
|
+ }
|
|
+ return log;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /** A height manager that records what the controller hands it. */
|
|
+ private static final class RecordingManager implements BaseQbftBlockHeightManager {
|
|
+ private final QbftBlockHeader parent;
|
|
+ private final List<String> log;
|
|
+
|
|
+ RecordingManager(final QbftBlockHeader parent, final List<String> log) {
|
|
+ this.parent = parent;
|
|
+ this.log = log;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void handleBlockTimerExpiry(final ConsensusRoundIdentifier roundIdentifier) {
|
|
+ log.add("timer " + roundIdentifier.getSequenceNumber() + "/" + roundIdentifier.getRoundNumber());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void roundExpired(final RoundExpiry expire) {
|
|
+ log.add(
|
|
+ "expiry "
|
|
+ + expire.getView().getSequenceNumber()
|
|
+ + "/"
|
|
+ + expire.getView().getRoundNumber());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public long getChainHeight() {
|
|
+ return parent.getNumber() + 1;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public QbftBlockHeader getParentBlockHeader() {
|
|
+ return parent;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void handleProposalPayload(final Proposal proposal) {
|
|
+ log.add(entry("proposal", proposal.getRoundIdentifier(), proposal.getAuthor()));
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void handlePreparePayload(final Prepare prepare) {
|
|
+ log.add(entry("prepare", prepare.getRoundIdentifier(), prepare.getAuthor()));
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void handleCommitPayload(final Commit commit) {
|
|
+ log.add(entry("commit", commit.getRoundIdentifier(), commit.getAuthor()));
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void handleRoundChangePayload(final RoundChange roundChange) {
|
|
+ log.add(entry("roundchange", roundChange.getRoundIdentifier(), roundChange.getAuthor()));
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Optional<QbftRound> getCurrentRound() {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Optional<RoundChangeManager> getRoundChangeManager() {
|
|
+ return Optional.empty();
|
|
+ }
|
|
+
|
|
+ private static String entry(
|
|
+ final String kind, final ConsensusRoundIdentifier id, final Address author) {
|
|
+ return kind + " " + id.getSequenceNumber() + "/" + id.getRoundNumber() + " " + author;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * A random script: blocks (extensions and forks), messages from one height below the head to far
|
|
+ * beyond the future-message buffer (so that a hook active below H_ev would replay something), and
|
|
+ * timer events.
|
|
+ */
|
|
+ private List<Object> script(final Random rnd, final List<Block> base) {
|
|
+ final List<Object> out = new ArrayList<>();
|
|
+ final List<Block> known = new ArrayList<>(base);
|
|
+ Block tip = base.get(base.size() - 1);
|
|
+ for (int i = 0; i < 60; i++) {
|
|
+ final int kind = rnd.nextInt(10);
|
|
+ final long n = tip.getHeader().getNumber();
|
|
+ if (kind < 4) {
|
|
+ final Block b = block(tip, 1);
|
|
+ known.add(b);
|
|
+ out.add(b);
|
|
+ tip = b;
|
|
+ } else if (kind == 4) {
|
|
+ final Block parent = known.get(Math.max(0, known.size() - 2));
|
|
+ final Block b = block(parent, 1 + rnd.nextInt(3));
|
|
+ known.add(b);
|
|
+ out.add(b);
|
|
+ if (b.getHeader().getNumber() > n || rnd.nextBoolean()) {
|
|
+ tip = b;
|
|
+ }
|
|
+ } else if (kind < 9) {
|
|
+ final long h = Math.max(1, n - 1 + rnd.nextInt(26));
|
|
+ final int r = rnd.nextInt(3);
|
|
+ final int who = rnd.nextInt(5);
|
|
+ final NodeKey k = who == 4 ? outsider : keys.get(who);
|
|
+ final Hash digest = Hash.hash(Bytes.ofUnsignedLong(rnd.nextLong()));
|
|
+ final MessageFactory mf = new MessageFactory(k, blockCodec);
|
|
+ final ConsensusRoundIdentifier id = new ConsensusRoundIdentifier(h, r);
|
|
+ switch (rnd.nextInt(4)) {
|
|
+ case 0 -> out.add(PrepareMessageData.create(mf.createPrepare(id, digest)));
|
|
+ case 1 ->
|
|
+ out.add(
|
|
+ CommitMessageData.create(
|
|
+ mf.createCommit(id, digest, k.sign(Bytes32.wrap(digest.getBytes())))));
|
|
+ case 2 -> out.add(RoundChangeMessageData.create(mf.createRoundChange(id, Optional.empty())));
|
|
+ default -> {
|
|
+ final Block pb = block(tip, 1);
|
|
+ out.add(
|
|
+ ProposalMessageData.create(
|
|
+ mf.createProposal(id, new QbftBlockAdaptor(pb), List.of(), List.of())));
|
|
+ }
|
|
+ }
|
|
+ } else if (rnd.nextBoolean()) {
|
|
+ out.add(new BlockTimerExpiry(new ConsensusRoundIdentifier(n + 1, rnd.nextInt(2))));
|
|
+ } else {
|
|
+ out.add(new RoundExpiry(new ConsensusRoundIdentifier(n + rnd.nextInt(2), rnd.nextInt(3))));
|
|
+ }
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ private QbftFinalStateImpl finalState(final ValidatorProvider vp, final AereDecidedHead head) {
|
|
+ return head == null
|
|
+ ? new QbftFinalStateImpl(
|
|
+ vp,
|
|
+ keys.get(0),
|
|
+ validators.get(0),
|
|
+ mock(ProposerSelector.class),
|
|
+ mock(ValidatorMulticaster.class),
|
|
+ mock(RoundTimer.class),
|
|
+ mock(BlockTimer.class),
|
|
+ mock(QbftBlockCreatorFactory.class),
|
|
+ Clock.systemUTC())
|
|
+ : new QbftFinalStateImpl(
|
|
+ vp,
|
|
+ keys.get(0),
|
|
+ validators.get(0),
|
|
+ mock(ProposerSelector.class),
|
|
+ mock(ValidatorMulticaster.class),
|
|
+ mock(RoundTimer.class),
|
|
+ mock(BlockTimer.class),
|
|
+ mock(QbftBlockCreatorFactory.class),
|
|
+ Clock.systemUTC(),
|
|
+ head);
|
|
+ }
|
|
+
|
|
+ private MutableBlockchain chain(final Block genesis, final List<Block> blocks) {
|
|
+ final MutableBlockchain chain =
|
|
+ InMemoryKeyValueStorageProvider.createInMemoryBlockchain(
|
|
+ genesis, BftBlockHeaderFunctions.forOnchainBlock(codec));
|
|
+ for (final Block b : blocks) {
|
|
+ chain.appendBlock(b, List.of());
|
|
+ }
|
|
+ return chain;
|
|
+ }
|
|
+
|
|
+ /** A block with real QBFT extra data (the four validators, round 0, a distinct vanity tag). */
|
|
+ private Block block(final Block parent, final long difficulty) {
|
|
+ tag++;
|
|
+ final long number = parent == null ? 0L : parent.getHeader().getNumber() + 1;
|
|
+ final BftExtraData extra =
|
|
+ new BftExtraData(
|
|
+ Bytes32.leftPad(Bytes.ofUnsignedLong(tag)), List.of(), Optional.empty(), 0, validators);
|
|
+ final BlockHeader header =
|
|
+ new BlockHeaderTestFixture()
|
|
+ .number(number)
|
|
+ .parentHash(parent == null ? Hash.ZERO : parent.getHash())
|
|
+ .difficulty(Difficulty.of(difficulty))
|
|
+ .extraData(codec.encode(extra))
|
|
+ .timestamp(number)
|
|
+ .coinbase(validators.get(0))
|
|
+ .blockHeaderFunctions(BftBlockHeaderFunctions.forOnchainBlock(codec))
|
|
+ .buildHeader();
|
|
+ return new Block(header, BlockBody.empty());
|
|
+ }
|
|
+
|
|
+ private SECPSignature seal(final int who, final Hash digest) {
|
|
+ return keys.get(who).sign(Bytes32.wrap(digest.getBytes()));
|
|
+ }
|
|
+
|
|
+ /** This node's (key 0) own commit on a block at a round, as QbftRound creates it at the proposal. */
|
|
+ private Commit ownCommit(final Block b, final int round) {
|
|
+ final QbftBlock qb = new QbftBlockAdaptor(b);
|
|
+ final Hash digest = blockInterface.replaceRoundForCommitBlock(qb, round).getHash();
|
|
+ return new MessageFactory(keys.get(0), blockCodec)
|
|
+ .createCommit(
|
|
+ new ConsensusRoundIdentifier(b.getHeader().getNumber(), round), digest, seal(0, digest));
|
|
+ }
|
|
+
|
|
+ private MessageData commit(final int who, final Block b, final int round) {
|
|
+ final QbftBlock qb = new QbftBlockAdaptor(b);
|
|
+ final Hash digest = blockInterface.replaceRoundForCommitBlock(qb, round).getHash();
|
|
+ return CommitMessageData.create(
|
|
+ new MessageFactory(keys.get(who), blockCodec)
|
|
+ .createCommit(
|
|
+ new ConsensusRoundIdentifier(b.getHeader().getNumber(), round),
|
|
+ digest,
|
|
+ seal(who, digest)));
|
|
+ }
|
|
+
|
|
+ private MessageData prepare(final int who, final long height, final Hash digest) {
|
|
+ return prepareBy(keys.get(who), height, digest);
|
|
+ }
|
|
+
|
|
+ private MessageData prepareBy(final NodeKey k, final long height, final Hash digest) {
|
|
+ return PrepareMessageData.create(
|
|
+ new MessageFactory(k, blockCodec)
|
|
+ .createPrepare(new ConsensusRoundIdentifier(height, 0), digest));
|
|
+ }
|
|
+
|
|
+ private MessageData proposal(final int who, final Block b) {
|
|
+ return ProposalMessageData.create(
|
|
+ new MessageFactory(keys.get(who), blockCodec)
|
|
+ .createProposal(
|
|
+ new ConsensusRoundIdentifier(b.getHeader().getNumber(), 0),
|
|
+ new QbftBlockAdaptor(b),
|
|
+ List.of(),
|
|
+ List.of()));
|
|
+ }
|
|
+
|
|
+ private MessageData roundChange(final NodeKey k, final long height, final int round) {
|
|
+ return RoundChangeMessageData.create(
|
|
+ new MessageFactory(k, blockCodec)
|
|
+ .createRoundChange(new ConsensusRoundIdentifier(height, round), Optional.empty()));
|
|
+ }
|
|
+
|
|
+ private Address outsiderAddress() {
|
|
+ return Util.publicKeyToAddress(outsider.getPublicKey());
|
|
+ }
|
|
+
|
|
+ private static QbftNewChainHead newHead(final BlockHeader header) {
|
|
+ return new QbftNewChainHead(new QbftBlockHeaderAdaptor(header));
|
|
+ }
|
|
+
|
|
+ private static String fingerprint(final MessageData data) {
|
|
+ return Hash.hash(Bytes.concatenate(Bytes.ofUnsignedInt(data.getCode()), data.getData()))
|
|
+ .toHexString()
|
|
+ .substring(0, 18);
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/adaptor/AereV3ReconstructionTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/adaptor/AereV3ReconstructionTest.java
|
|
new file mode 100644
|
|
index 0000000000..657e620a06
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/adaptor/AereV3ReconstructionTest.java
|
|
@@ -0,0 +1,125 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft.adaptor;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftBlockInterface;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorV3;
|
|
+import org.hyperledger.besu.consensus.common.bft.SchemeSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealSchemes;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec;
|
|
+import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
|
|
+import org.hyperledger.besu.consensus.qbft.headervalidationrules.PqAnchorDigestRule;
|
|
+import org.hyperledger.besu.consensus.qbft.headervalidationrules.PqAnchorTestSupport;
|
|
+import org.hyperledger.besu.ethereum.core.Block;
|
|
+import org.hyperledger.besu.ethereum.core.BlockBody;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), step 3 (2026-10-01), the D-328 discipline: a header carrying a v3 certificate of round 3 goes through every
|
|
+ * place that REBUILDS an extraData on the way to the chain (the round substitution, the sealing with commit seals on the
|
|
+ * anchored path, the stage-5 sealing with the proposer's seal) and comes out with the SAME round, the same rows and the
|
|
+ * same D3, still accepted by R1. One place that dropped the round (wrote NO_CERTIFICATE_ROUND) would turn the v3 into a
|
|
+ * v2 under a D3 vanity and stop the chain at the first v3 anchor, exactly as the v2 certificate did on 28001 on
|
|
+ * 2026-09-03; the three plantations of that kind must turn this probe red. Added after the adversarial review of step 3.
|
|
+ */
|
|
+public class AereV3ReconstructionTest {
|
|
+
|
|
+ private static final long CHAIN = PqAnchorTestSupport.CHAIN_ID;
|
|
+ private static final long H = PqAnchorTestSupport.H;
|
|
+ private static final long HR = 1_100L;
|
|
+ private static final int ROUND = 3;
|
|
+ private static final QbftExtraDataCodec CODEC = new QbftExtraDataCodec();
|
|
+ private static final List<SchemeSeal> ROWS =
|
|
+ List.of(
|
|
+ new SchemeSeal(SealSchemes.FALCON_512.wireId(), 0, PqAnchorTestSupport.signature(0, 0)),
|
|
+ new SchemeSeal(SealSchemes.FALCON_512.wireId(), 2, PqAnchorTestSupport.signature(2, 0)));
|
|
+
|
|
+ private final PqAnchorConfig cfg =
|
|
+ new PqAnchorConfig(CHAIN, H, Map.of(H, 0), OptionalInt.empty(), false)
|
|
+ .withAnchorV2Block(H)
|
|
+ .withCommitRoundBlock(HR);
|
|
+ private final BlockHeader parent = PqAnchorTestSupport.parentHeader(HR - 1L);
|
|
+ private final Bytes32 d3 =
|
|
+ PqAnchorV3.anchorDigestV3(CHAIN, HR - 1L, parent.getHash().getBytes(), new PqAnchorV3.Certificate(ROUND, ROWS));
|
|
+
|
|
+ @AfterEach
|
|
+ public void forget() {
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ }
|
|
+
|
|
+ private Block proposal() {
|
|
+ final Bytes extra =
|
|
+ CODEC.encode(new BftExtraData(d3, List.of(), Optional.empty(), 0, PqAnchorTestSupport.VALIDATORS, List.of(), ROWS, ROUND));
|
|
+ return new Block(PqAnchorTestSupport.header(HR, parent.getHash(), extra), BlockBody.empty());
|
|
+ }
|
|
+
|
|
+ private void sameCertificate(final BlockHeader h, final String where) {
|
|
+ final BftExtraData d = CODEC.decodeRaw(h.getExtraData());
|
|
+ assertThat(d.getCertificateRound()).as("AERE-R1B-RECONSTRUCTIE %s: the round", where).hasValue(ROUND);
|
|
+ assertThat(d.getHybridSeals()).as("AERE-R1B-RECONSTRUCTIE %s: the rows", where).isEqualTo(ROWS);
|
|
+ assertThat(d.getVanityData()).as("AERE-R1B-RECONSTRUCTIE %s: D3", where).isEqualTo(d3);
|
|
+ assertThat(new PqAnchorDigestRule(cfg).validate(h, parent)).as("AERE-R1B-RECONSTRUCTIE %s: R1 still accepts it", where).isTrue();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theProposalItselfCarriesTheV3() {
|
|
+ sameCertificate(proposal().getHeader(), "proposal");
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theRoundSubstitutionKeepsTheRound() {
|
|
+ final Block replaced =
|
|
+ new BftBlockInterface(CODEC).replaceRoundInBlock(proposal(), 5, BftBlockHeaderFunctions.forCommittedSeal(CODEC));
|
|
+ assertThat(CODEC.decodeRaw(replaced.getHeader().getExtraData()).getRound()).isEqualTo(5);
|
|
+ sameCertificate(replaced.getHeader(), "BftBlockInterface.replaceRoundInBlock");
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theSealingOnTheAnchoredPathKeepsTheRound() {
|
|
+ PqAnchorProducer.useConfigForTesting(cfg);
|
|
+ final QbftBlock sealed =
|
|
+ new QbftBlockCreatorAdaptor(null, CODEC).createSealedBlock(new QbftBlockAdaptor(proposal()), 5, List.of());
|
|
+ sameCertificate(AdaptorUtil.toBesuBlockHeader(sealed.getHeader()), "QbftBlockCreatorAdaptor.createSealedBlock");
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theStageFiveSealingWithTheProposerSealKeepsTheRound() {
|
|
+ PqAnchorProducer.useConfigForTesting(cfg);
|
|
+ final FalconSeal ps = new FalconSeal(1, PqAnchorTestSupport.signature(1, 7));
|
|
+ final QbftBlock sealed =
|
|
+ new QbftBlockCreatorAdaptor(null, CODEC)
|
|
+ .createSealedBlockWithProposerSeal(new QbftBlockAdaptor(proposal()), 5, ps);
|
|
+ final BlockHeader h = AdaptorUtil.toBesuBlockHeader(sealed.getHeader());
|
|
+ assertThat(CODEC.decodeRaw(h.getExtraData()).getPqProposerSeal()).hasValue(ps);
|
|
+ sameCertificate(h, "QbftBlockCreatorAdaptor.createSealedBlockWithProposerSeal");
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorDigestRuleTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorDigestRuleTest.java
|
|
index 64ba7f3072..a2bfac6fd6 100755
|
|
--- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorDigestRuleTest.java
|
|
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorDigestRuleTest.java
|
|
@@ -336,24 +336,24 @@ public class PqAnchorDigestRuleTest {
|
|
.withFailMessage("tampered header should be rejected in mode %s", mode)
|
|
.isFalse();
|
|
}
|
|
}
|
|
|
|
private BlockHeader stripCertificate(final BlockHeader honest) {
|
|
return replaceCertificate(honest, Collections.emptyList());
|
|
}
|
|
|
|
private BlockHeader replaceCertificate(
|
|
final BlockHeader honest, final List<FalconSeal> certificate) {
|
|
final BftExtraData original = codec.decodeRaw(honest.getExtraData());
|
|
final Bytes tampered =
|
|
codec.encode(
|
|
new BftExtraData(
|
|
original.getVanityData(),
|
|
original.getSeals(),
|
|
Optional.empty(),
|
|
original.getRound(),
|
|
original.getValidators(),
|
|
- certificate));
|
|
+ certificate, java.util.List.of(), BftExtraData.NO_CERTIFICATE_ROUND));
|
|
return header(honest.getNumber(), honest.getParentHash(), tampered);
|
|
}
|
|
}
|
|
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorDisarmedWindowTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorDisarmedWindowTest.java
|
|
index e7604a4fca..6e12537b90 100644
|
|
--- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorDisarmedWindowTest.java
|
|
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorDisarmedWindowTest.java
|
|
@@ -507,41 +507,43 @@ public class PqAnchorDisarmedWindowTest {
|
|
private BlockHeader digestBoundButUnsorted(
|
|
final long number, final BlockHeader parent, final List<Integer> indicesInArrivalOrder) {
|
|
final List<FalconSeal> seals = sealsFor(parent, indicesInArrivalOrder);
|
|
final Bytes32 digest =
|
|
PqAnchor.anchorDigest(CHAIN_ID, parent.getNumber(), parent.getHash().getBytes(), seals);
|
|
return header(number, parent.getHash(), extraData(digest, seals));
|
|
}
|
|
|
|
/** A header an honest proposer under the armed rules writes: digest bound, indices sorted. */
|
|
private BlockHeader honestBlock(
|
|
final long number, final BlockHeader parent, final List<Integer> indices) {
|
|
final List<FalconSeal> sorted = PqAnchor.sortedByIndex(sealsFor(parent, indices));
|
|
final Bytes32 digest =
|
|
PqAnchor.anchorDigest(CHAIN_ID, parent.getNumber(), parent.getHash().getBytes(), sorted);
|
|
return header(number, parent.getHash(), extraData(digest, sorted));
|
|
}
|
|
|
|
/** An honest header for ANY chain: the digest and the seals are computed for that chain (D-428). */
|
|
private BlockHeader honestBlockOn(
|
|
final long chain, final long number, final BlockHeader parent, final List<Integer> indices) {
|
|
- final Bytes32 message = PqAnchor.commitMessage(chain, parent.getNumber(), parent.getHash().getBytes());
|
|
+ final Bytes32 message =
|
|
+ org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer.roundFreeMessage(
|
|
+ chain, parent.getNumber(), parent.getHash().getBytes());
|
|
final List<FalconSeal> seals = new ArrayList<>();
|
|
for (final int index : indices) {
|
|
seals.add(new FalconSeal(index, LocalRegistry.sign(index, message)));
|
|
}
|
|
final List<FalconSeal> sorted = PqAnchor.sortedByIndex(seals);
|
|
final Bytes32 digest = PqAnchor.anchorDigest(chain, parent.getNumber(), parent.getHash().getBytes(), sorted);
|
|
return header(number, parent.getHash(), extraData(digest, sorted));
|
|
}
|
|
|
|
private List<FalconSeal> sealsFor(final BlockHeader parent, final List<Integer> indices) {
|
|
// One return, one mutability. An early return of an immutable empty list here is what
|
|
// errorprone's MixedMutabilityReturnType refuses, and it is refusing something real: the empty
|
|
// case is not special, it is the case where the loop runs zero times.
|
|
final Bytes32 message =
|
|
PqAnchor.commitMessage(CHAIN_ID, parent.getNumber(), parent.getHash().getBytes());
|
|
final List<FalconSeal> seals = new ArrayList<>();
|
|
for (final int index : indices) {
|
|
seals.add(new FalconSeal(index, LocalRegistry.sign(index, message)));
|
|
}
|
|
return seals;
|
|
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorTestSupport.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorTestSupport.java
|
|
index f7961bcd3e..df609d6ed2 100755
|
|
--- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorTestSupport.java
|
|
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorTestSupport.java
|
|
@@ -75,41 +75,41 @@ public final class PqAnchorTestSupport {
|
|
/**
|
|
* A seal for a validator index.
|
|
*
|
|
* @param index the validator index
|
|
* @return the seal
|
|
*/
|
|
public static FalconSeal seal(final int index) {
|
|
return new FalconSeal(index, signature(index, 0));
|
|
}
|
|
|
|
/**
|
|
* Build the extraData bytes of a header carrying a given certificate and a given vanity field.
|
|
*
|
|
* @param vanity the 32-byte vanity field, which from H is the anchor digest D
|
|
* @param certificate the carried certificate C, in the order it is to be written
|
|
* @return canonical extraData bytes
|
|
*/
|
|
public static Bytes extraData(final Bytes vanity, final Collection<FalconSeal> certificate) {
|
|
return CODEC.encode(
|
|
new BftExtraData(
|
|
- vanity, Collections.emptyList(), Optional.empty(), 0, VALIDATORS, certificate));
|
|
+ vanity, Collections.emptyList(), Optional.empty(), 0, VALIDATORS, certificate, java.util.List.of(), BftExtraData.NO_CERTIFICATE_ROUND));
|
|
}
|
|
|
|
/**
|
|
* Build a header at a height, over a parent hash, carrying a certificate whose anchor digest is
|
|
* written into vanityData. This is what an HONEST proposer produces.
|
|
*
|
|
* @param number the height of the header
|
|
* @param parentHash the parent hash the header names
|
|
* @param certificate the certificate over the parent
|
|
* @return the header
|
|
*/
|
|
public static BlockHeader honestHeader(
|
|
final long number, final Hash parentHash, final List<FalconSeal> certificate) {
|
|
final List<FalconSeal> sorted = PqAnchor.sortedByIndex(certificate);
|
|
final Bytes32 digest = PqAnchor.anchorDigest(CHAIN_ID, number - 1L, parentHash.getBytes(), sorted);
|
|
return header(number, parentHash, extraData(digest, sorted));
|
|
}
|
|
|
|
/**
|
|
* Build a header with explicit extraData bytes, so a test can tamper with the certificate while
|
|
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorV2RulesTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorV2RulesTest.java
|
|
index 867b46b6f6..4c8a67e6b9 100755
|
|
--- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorV2RulesTest.java
|
|
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorV2RulesTest.java
|
|
@@ -135,41 +135,41 @@ public class PqAnchorV2RulesTest {
|
|
|
|
// ------------------------------------------------------------------------------ certificates
|
|
|
|
/** Falcon seals for indices 0..falconCount-1 and SLH-DSA seals for 0..slhCount-1, canonical. */
|
|
private List<SchemeSeal> certificate(final BlockHeader parent, final int falconCount, final int slhCount) {
|
|
final Bytes32 m = PqAnchor.commitMessage(CHAIN_ID, parent.getNumber(), parent.getHash().getBytes());
|
|
final List<SchemeSeal> out = new ArrayList<>();
|
|
for (int i = 0; i < falconCount; i++) {
|
|
out.add(new SchemeSeal(SealSchemes.FALCON_512.wireId(), i, FakeFalconRegistry.sign(i, m)));
|
|
}
|
|
for (int i = 0; i < slhCount; i++) {
|
|
out.add(new SchemeSeal(SealSchemes.SLH_DSA_128S.wireId(), i,
|
|
Bytes.wrap(SealSchemes.SLH_DSA_128S.sign(slhKeys.get(i).privateKey(), m.toArray()).orElseThrow())));
|
|
}
|
|
out.sort(PqAnchorV2.CANONICAL);
|
|
return out;
|
|
}
|
|
|
|
private static Bytes extraDataV2(final Bytes vanity, final List<SchemeSeal> tagged) {
|
|
return CODEC.encode(new BftExtraData(
|
|
- vanity, Collections.emptyList(), Optional.empty(), 0, VALIDATORS, Collections.emptyList(), tagged));
|
|
+ vanity, Collections.emptyList(), Optional.empty(), 0, VALIDATORS, Collections.emptyList(), tagged, BftExtraData.NO_CERTIFICATE_ROUND));
|
|
}
|
|
|
|
private static BlockHeader honestV2(final long number, final BlockHeader parent, final List<SchemeSeal> tagged) {
|
|
final Bytes32 d = PqAnchorV2.anchorDigestV2(CHAIN_ID, number - 1L, parent.getHash().getBytes(), tagged);
|
|
return header(number, parent.getHash(), extraDataV2(d, tagged));
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------------- R1
|
|
|
|
@Test
|
|
public void r1AcceptsTheHonestV2HeaderAndRefusesAStrippedCertificate() {
|
|
final BlockHeader parent = parentHeader(V2 + 4L);
|
|
final List<SchemeSeal> tagged = certificate(parent, 5, 5);
|
|
final BlockHeader honest = honestV2(V2 + 5L, parent, tagged);
|
|
assertThat(r1.validate(honest, parent)).isTrue();
|
|
// one SLH-DSA seal stripped under the ORIGINAL digest
|
|
final List<SchemeSeal> stripped = new ArrayList<>(tagged);
|
|
stripped.removeIf(s -> s.getSchemeWireId() == SealSchemes.SLH_DSA_128S.wireId() && s.getValidatorIndex() == 4);
|
|
final BftExtraData decoded = CODEC.decodeRaw(honest.getExtraData());
|
|
final BlockHeader strippedHeader =
|
|
@@ -288,46 +288,46 @@ public class PqAnchorV2RulesTest {
|
|
|
|
@Test
|
|
public void theCodecRoundTripsBothFormsAndRefusesANonCanonicalV2Certificate() {
|
|
final BlockHeader parent = parentHeader(V2 + 4L);
|
|
final List<SchemeSeal> tagged = certificate(parent, 2, 2);
|
|
final Bytes v2 = extraDataV2(Bytes32.ZERO, tagged);
|
|
final BftExtraData back = CODEC.decodeRaw(v2);
|
|
assertThat(back.getHybridSeals()).isEqualTo(tagged);
|
|
assertThat(back.getFalconSeals()).isEmpty();
|
|
// the v1 form still round-trips through the same slot
|
|
final List<FalconSeal> v1 = List.of(PqAnchorTestSupport.seal(0), PqAnchorTestSupport.seal(1));
|
|
final BftExtraData backV1 = CODEC.decodeRaw(PqAnchorTestSupport.extraData(Bytes32.ZERO, v1));
|
|
assertThat(backV1.getFalconSeals()).containsExactlyElementsOf(v1);
|
|
assertThat(backV1.getHybridSeals()).isEmpty();
|
|
// a v2 certificate written out of canonical order is refused at decode, not silently reordered
|
|
final List<SchemeSeal> unsorted = new ArrayList<>(tagged);
|
|
Collections.reverse(unsorted);
|
|
// the holder accepts any list; it is the ENCODER that refuses, so no header can carry it
|
|
assertThatThrownBy(() -> CODEC.encode(new BftExtraData(
|
|
Bytes32.ZERO, Collections.emptyList(), Optional.empty(), 0, VALIDATORS,
|
|
- Collections.emptyList(), unsorted)))
|
|
+ Collections.emptyList(), unsorted, BftExtraData.NO_CERTIFICATE_ROUND)))
|
|
.isInstanceOf(RuntimeException.class);
|
|
// hand-built non-canonical bytes: the same seals, encoded by hand out of order, do not decode
|
|
final Bytes canonical = PqAnchorV2.encode(tagged);
|
|
final BftExtraData holder = new BftExtraData(
|
|
- Bytes32.ZERO, Collections.emptyList(), Optional.empty(), 0, VALIDATORS, Collections.emptyList(), tagged);
|
|
+ Bytes32.ZERO, Collections.emptyList(), Optional.empty(), 0, VALIDATORS, Collections.emptyList(), tagged, BftExtraData.NO_CERTIFICATE_ROUND);
|
|
final Bytes good = CODEC.encode(holder);
|
|
assertThat(good.toHexString()).contains(canonical.toUnprefixedHexString());
|
|
final Bytes swapped = Bytes.fromHexString(good.toHexString().replace(
|
|
canonical.toUnprefixedHexString(), PqAnchorV2.encode(List.of(tagged.get(0))).toUnprefixedHexString()));
|
|
assertThatThrownBy(() -> CODEC.decodeRaw(swapped)).isInstanceOf(RLPException.class);
|
|
}
|
|
|
|
// ------------------------------------------------------------------- D-328: the round substitution
|
|
|
|
@Test
|
|
public void replacingTheRoundInABlockKeepsTheV2Certificate() {
|
|
// 2026-09-03, testnet 28001: every sealed v2 header lost its certificate at replaceRoundInBlock,
|
|
// because that copy went through the v1 constructor; R1 then refused block 168032 for 3 hours.
|
|
final BlockHeader parent = parentHeader(V2 + 4L);
|
|
final List<SchemeSeal> tagged = certificate(parent, K, K);
|
|
final BlockHeader honest = honestV2(V2 + 5L, parent, tagged);
|
|
final org.hyperledger.besu.ethereum.core.Block block =
|
|
new org.hyperledger.besu.ethereum.core.Block(honest, org.hyperledger.besu.ethereum.core.BlockBody.empty());
|
|
final org.hyperledger.besu.ethereum.core.Block substituted =
|
|
new org.hyperledger.besu.consensus.common.bft.BftBlockInterface(CODEC)
|
|
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorV3SealsRuleTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorV3SealsRuleTest.java
|
|
new file mode 100644
|
|
index 0000000000..b352a74468
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorV3SealsRuleTest.java
|
|
@@ -0,0 +1,248 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft.headervalidationrules;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
+import static org.mockito.Mockito.mock;
|
|
+import static org.mockito.Mockito.when;
|
|
+import static org.mockito.Mockito.withSettings;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.BftContext;
|
|
+import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorV2;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorV3;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSignerRegistry;
|
|
+import org.hyperledger.besu.consensus.common.bft.SchemeSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealScheme;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealSchemes;
|
|
+import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
|
+import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec;
|
|
+import org.hyperledger.besu.crypto.SecureRandomProvider;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.ethereum.ProtocolContext;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+
|
|
+import java.security.SecureRandom;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collection;
|
|
+import java.util.HashMap;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.mockito.quality.Strictness;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), step 3 (2026-10-01): R2 on a v3 certificate through the REAL rule, with a real protocol context (the
|
|
+ * parent's set from the validator provider) and a registry of real Falcon-512 keys, generated per run. Every negative
|
|
+ * differs from the accepted header in one field and is refused for the reason named; the R2-only refusal of a v3 below
|
|
+ * H_r is built so that, without its own check, the v2 judgement WOULD accept it (its rows are valid COMMIT-1 seals over
|
|
+ * the parent), so the probe cannot pass on a refusal that comes from somewhere else. Added after the adversarial review
|
|
+ * of step 3, which found the null-context version vacuous.
|
|
+ */
|
|
+public class PqAnchorV3SealsRuleTest {
|
|
+
|
|
+ private static final long CHAIN = PqAnchorTestSupport.CHAIN_ID;
|
|
+ private static final long H = PqAnchorTestSupport.H;
|
|
+ private static final long HR = 1_100L;
|
|
+ private static final QbftExtraDataCodec CODEC = new QbftExtraDataCodec();
|
|
+ private static final byte FALCON = SealSchemes.FALCON_512.wireId();
|
|
+ private static final Address OUTSIDER = Address.fromHexString("0x00000000000000000000000000000000000000ff");
|
|
+
|
|
+ private final Map<Integer, SealScheme.PrivateHandle> secret = new HashMap<>();
|
|
+ private final Map<Integer, byte[]> publicKeys = new HashMap<>();
|
|
+ private final Map<Integer, Address> bindings = new HashMap<>();
|
|
+
|
|
+ private final PqSignerRegistry registry =
|
|
+ new PqSignerRegistry() {
|
|
+ @Override
|
|
+ public Address addressForIndexAtHistoric(final long blockNumber, final int validatorIndex) {
|
|
+ return bindings.get(validatorIndex);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Address addressForIndexAtOwnHead(final long blockNumber, final int validatorIndex) {
|
|
+ return bindings.get(validatorIndex);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtHistoric(
|
|
+ final long blockNumber, final int validatorIndex, final Bytes message, final Bytes signature) {
|
|
+ final byte[] pk = publicKeys.get(validatorIndex);
|
|
+ return pk != null && SealSchemes.FALCON_512.verifyRaw(pk, message.toArray(), signature.toArray());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyAtOwnHead(
|
|
+ final long blockNumber, final int validatorIndex, final Bytes message, final Bytes signature) {
|
|
+ return verifyAtHistoric(blockNumber, validatorIndex, message, signature);
|
|
+ }
|
|
+ };
|
|
+
|
|
+ public PqAnchorV3SealsRuleTest() {
|
|
+ final SecureRandom random = SecureRandomProvider.createSecureRandom();
|
|
+ for (int i = 0; i < 4; i++) {
|
|
+ final SealScheme.GeneratedPair pair = SealSchemes.FALCON_512.generate(random);
|
|
+ secret.put(i, pair.privateKey());
|
|
+ publicKeys.put(i, pair.publicRegistryForm());
|
|
+ bindings.put(i, PqAnchorTestSupport.VALIDATORS.get(i));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static ProtocolContext context(final Collection<Address> set) {
|
|
+ final ValidatorProvider vp = mock(ValidatorProvider.class, withSettings().strictness(Strictness.LENIENT));
|
|
+ when(vp.getValidatorsForBlock(any())).thenReturn(set);
|
|
+ when(vp.getValidatorsAfterBlock(any())).thenReturn(set);
|
|
+ final BftContext bft = mock(BftContext.class, withSettings().strictness(Strictness.LENIENT));
|
|
+ when(bft.getValidatorProvider()).thenReturn(vp);
|
|
+ when(bft.as(any())).thenReturn(bft);
|
|
+ return new ProtocolContext.Builder().withConsensusContext(bft).build();
|
|
+ }
|
|
+
|
|
+ private static PqAnchorConfig cfg(final int k) {
|
|
+ return new PqAnchorConfig(CHAIN, H, Map.of(H, k), OptionalInt.empty(), false)
|
|
+ .withAnchorV2Block(H)
|
|
+ .withCommitRoundBlock(HR);
|
|
+ }
|
|
+
|
|
+ private SchemeSeal seal(final int i, final Bytes32 message) {
|
|
+ return new SchemeSeal(FALCON, i, Bytes.wrap(SealSchemes.FALCON_512.sign(secret.get(i), message.toArray()).orElseThrow()));
|
|
+ }
|
|
+
|
|
+ private List<SchemeSeal> seals(final Bytes32 message, final int... idx) {
|
|
+ final List<SchemeSeal> out = new ArrayList<>();
|
|
+ for (final int i : idx) {
|
|
+ out.add(seal(i, message));
|
|
+ }
|
|
+ out.sort(PqAnchorV2.CANONICAL);
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ private static Bytes32 mR(final BlockHeader parent, final int r) {
|
|
+ return PqAnchor.commitMessageRound(CHAIN, parent.getNumber(), r, parent.getHash().getBytes());
|
|
+ }
|
|
+
|
|
+ /** A v3 header over the parent: certificate round r, its rows, D3 in the vanity, element 3 = headerRound. */
|
|
+ private static BlockHeader v3(final BlockHeader parent, final int r, final List<SchemeSeal> rows, final int headerRound) {
|
|
+ final Bytes32 d3 =
|
|
+ PqAnchorV3.anchorDigestV3(CHAIN, parent.getNumber(), parent.getHash().getBytes(), new PqAnchorV3.Certificate(r, rows));
|
|
+ final Bytes extra =
|
|
+ CODEC.encode(new BftExtraData(d3, List.of(), Optional.empty(), headerRound, PqAnchorTestSupport.VALIDATORS, List.of(), rows, r));
|
|
+ return PqAnchorTestSupport.header(parent.getNumber() + 1L, parent.getHash(), extra);
|
|
+ }
|
|
+
|
|
+ private static BlockHeader v2(final BlockHeader parent, final List<SchemeSeal> rows) {
|
|
+ final Bytes32 d2 = PqAnchorV2.anchorDigestV2(CHAIN, parent.getNumber(), parent.getHash().getBytes(), rows);
|
|
+ final Bytes extra =
|
|
+ CODEC.encode(new BftExtraData(d2, List.of(), Optional.empty(), 0, PqAnchorTestSupport.VALIDATORS, List.of(), rows, BftExtraData.NO_CERTIFICATE_ROUND));
|
|
+ return PqAnchorTestSupport.header(parent.getNumber() + 1L, parent.getHash(), extra);
|
|
+ }
|
|
+
|
|
+ private boolean r2(final int k, final BlockHeader h, final BlockHeader parent) {
|
|
+ return new PqAnchorSealsRule(cfg(k), registry).validate(h, parent, context(PqAnchorTestSupport.VALIDATORS));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void anHonestV3OfRoundThreeIsAcceptedByBothRules() {
|
|
+ final BlockHeader p = PqAnchorTestSupport.parentHeader(HR - 1L);
|
|
+ final BlockHeader h = v3(p, 3, seals(mR(p, 3), 0, 1, 2), 0);
|
|
+ assertThat(new PqAnchorDigestRule(cfg(3)).validate(h, p)).isTrue();
|
|
+ assertThat(r2(3, h, p)).as("three seals of round 3 over M_3, K = 3").isTrue();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theSealsOfRoundZeroUnderARoundThreeCertificateAreRefused() {
|
|
+ final BlockHeader p = PqAnchorTestSupport.parentHeader(HR - 1L);
|
|
+ final List<SchemeSeal> r0 = seals(mR(p, 0), 0, 1, 2);
|
|
+ assertThat(r2(3, v3(p, 0, r0, 0), p)).as("control: the same seals under round 0").isTrue();
|
|
+ assertThat(r2(3, v3(p, 3, r0, 0), p)).as("the round-0 seals named as round 3").isFalse();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void belowTheThresholdIsRefused() {
|
|
+ final BlockHeader p = PqAnchorTestSupport.parentHeader(HR - 1L);
|
|
+ final BlockHeader h = v3(p, 3, seals(mR(p, 3), 0, 1, 2), 0);
|
|
+ assertThat(r2(3, h, p)).isTrue();
|
|
+ assertThat(r2(4, h, p)).as("three seals, K = 4").isFalse();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void anIndexBoundOutsideTheParentsSetIsRefused() {
|
|
+ final BlockHeader p = PqAnchorTestSupport.parentHeader(HR - 1L);
|
|
+ final BlockHeader h = v3(p, 3, seals(mR(p, 3), 0, 1, 2), 0);
|
|
+ assertThat(r2(3, h, p)).isTrue();
|
|
+ bindings.put(2, OUTSIDER);
|
|
+ assertThat(r2(3, h, p)).as("index 2 bound to an address outside set(p)").isFalse();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void theRoundOfElementThreeIsNotComparedWithTheCertificate() {
|
|
+ final BlockHeader p = PqAnchorTestSupport.parentHeader(HR - 1L);
|
|
+ assertThat(r2(3, v3(p, 3, seals(mR(p, 3), 0, 1, 2), 5), p))
|
|
+ .as("the header was decided in round 5, the parent's certificate is of round 3")
|
|
+ .isTrue();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void anEmptyV3IsValidOnlyAtKZero() {
|
|
+ final BlockHeader p = PqAnchorTestSupport.parentHeader(HR - 1L);
|
|
+ final BlockHeader empty = v3(p, 0, List.of(), 0);
|
|
+ assertThat(r2(0, empty, p)).isTrue();
|
|
+ assertThat(r2(1, empty, p)).isFalse();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aV3BelowHrIsRefusedByR2ItselfEvenWhenItsRowsWouldPassAsV2() {
|
|
+ final BlockHeader p = PqAnchorTestSupport.parentHeader(HR - 51L);
|
|
+ final Bytes32 commitOne = PqAnchor.commitMessage(CHAIN, p.getNumber(), p.getHash().getBytes());
|
|
+ final List<SchemeSeal> rows = seals(commitOne, 0, 1, 2);
|
|
+ assertThat(r2(3, v2(p, rows), p)).as("control: the rows are a valid v2 certificate at this height").isTrue();
|
|
+ assertThat(r2(3, v3(p, 0, rows, 0), p)).as("the same rows as a v3 below H_r").isFalse();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void r1RefusesAV3WhereverTheFormIsNotV3AndOnlyTheBrakeLetsItThrough() {
|
|
+ // a grid of 32 from H, so a NON-anchor height exists above H_r: H_r = H + 32 * 5
|
|
+ final long hr = H + 32L * 5;
|
|
+ final PqAnchorConfig grid =
|
|
+ new PqAnchorConfig(CHAIN, H, Map.of(H, 0), OptionalInt.empty(), false)
|
|
+ .withAnchorInterval(OptionalInt.of(32))
|
|
+ .withAnchorV2Block(H + 32L * 2)
|
|
+ .withCommitRoundBlock(hr);
|
|
+ final PqAnchorDigestRule r1 = new PqAnchorDigestRule(grid);
|
|
+ final BlockHeader atHr = PqAnchorTestSupport.parentHeader(hr - 1L);
|
|
+ assertThat(r1.validate(v3(atHr, 0, seals(mR(atHr, 0), 0), 0), atHr)).as("control: a v3 at H_r").isTrue();
|
|
+ final BlockHeader off = PqAnchorTestSupport.parentHeader(hr + 9L);
|
|
+ assertThat(grid.certificateFormAt(hr + 10L)).isEqualTo(PqAnchorConfig.CertificateForm.NONE);
|
|
+ assertThat(r1.validate(v3(off, 0, seals(mR(off, 0), 0), 0), off)).as("a v3 at a non-anchor height above H_r").isFalse();
|
|
+ final BlockHeader belowH = PqAnchorTestSupport.parentHeader(H - 11L);
|
|
+ assertThat(r1.validate(v3(belowH, 0, seals(mR(belowH, 0), 0), 0), belowH)).as("a v3 below H").isFalse();
|
|
+ final PqAnchorDigestRule noHr =
|
|
+ new PqAnchorDigestRule(new PqAnchorConfig(CHAIN, H, Map.of(H, 0), OptionalInt.empty(), false).withAnchorV2Block(H));
|
|
+ assertThat(noHr.validate(v3(off, 0, seals(mR(off, 0), 0), 0), off)).as("H_r unset: refused at every height (L1)").isFalse();
|
|
+ final PqAnchorDigestRule braked =
|
|
+ new PqAnchorDigestRule(new PqAnchorConfig(CHAIN, H, Map.of(H, 0), OptionalInt.empty(), true));
|
|
+ assertThat(braked.validate(v3(off, 0, seals(mR(off, 0), 0), 0), off)).as("under the brake every anchor rule is inert").isTrue();
|
|
+ assertThat(QbftExtraDataCodec.carriesV3Certificate(v3(off, 0, List.of(), 0).getExtraData())).isTrue();
|
|
+ assertThat(QbftExtraDataCodec.carriesV3Certificate(v2(off, seals(mR(off, 0), 0)).getExtraData())).isFalse();
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorV3Test.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorV3Test.java
|
|
new file mode 100644
|
|
index 0000000000..1a2d55b3d7
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorV3Test.java
|
|
@@ -0,0 +1,467 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft.headervalidationrules;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
+import static org.assertj.core.api.Assertions.fail;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchor;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorV2;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorV3;
|
|
+import org.hyperledger.besu.consensus.common.bft.SchemeSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealScheme;
|
|
+import org.hyperledger.besu.consensus.common.bft.SealSchemes;
|
|
+import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec;
|
|
+import org.hyperledger.besu.consensus.qbft.core.validation.RoundChangePayloadValidator;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
|
|
+
|
|
+import java.io.InputStream;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collection;
|
|
+import java.util.Collections;
|
|
+import java.util.HashMap;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+import java.util.Set;
|
|
+
|
|
+import com.fasterxml.jackson.databind.JsonNode;
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), step 3 (2026-10-01): the v3 certificate (PROIECT-1B 1.3, 1.4) on the Besu side, against the COMMON
|
|
+ * vectors (classes VC, VD, and the per-round seals of VS, signed by a third implementation with synthetic keys):
|
|
+ * the codec, D3, the form codes of R1 and R2 through the real rules, and the seal codes through {@link
|
|
+ * PqAnchorV3#judgeSeals}, the function R2, the producer and decidedBy share. Every negative differs from an accepted
|
|
+ * case in ONE field and asks for the CODE. The full rules on real anchors (VR) come from the rehearsal (steps 5, 7).
|
|
+ */
|
|
+public class PqAnchorV3Test {
|
|
+
|
|
+ private static final String RES = "/aere-r1b/VECTORI-R1B.json";
|
|
+ private static final QbftExtraDataCodec CODEC = new QbftExtraDataCodec();
|
|
+ private static final byte FALCON = SealSchemes.FALCON_512.wireId();
|
|
+ private static final byte SLH = SealSchemes.SLH_DSA_128S.wireId();
|
|
+
|
|
+ private static JsonNode vectors() {
|
|
+ try (InputStream in = PqAnchorV3Test.class.getResourceAsStream(RES)) {
|
|
+ if (in == null) {
|
|
+ fail("AERE-R1B-VECTORI: the resource " + RES + " is missing; the harness copies it, a run without it measures nothing");
|
|
+ }
|
|
+ return new ObjectMapper().readTree(in);
|
|
+ } catch (final java.io.IOException e) {
|
|
+ throw new IllegalStateException("AERE-R1B-VECTORI: " + e.getMessage(), e);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static List<SchemeSeal> rows(final JsonNode arr) {
|
|
+ final List<SchemeSeal> out = new ArrayList<>();
|
|
+ for (final JsonNode r : arr) {
|
|
+ out.add(new SchemeSeal((byte) r.get("scheme").asInt(), r.get("index").asInt(), Bytes.fromHexString(r.get("signature").asText())));
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ /** extraData written by hand, with the certificate bytes as given, and an optional proposer seal after it. */
|
|
+ private static Bytes extraWith(final Bytes certificate, final Optional<FalconSeal> proposerSeal) {
|
|
+ final BytesValueRLPOutput o = new BytesValueRLPOutput();
|
|
+ o.startList();
|
|
+ o.writeBytes(Bytes32.ZERO);
|
|
+ o.writeList(PqAnchorTestSupport.VALIDATORS, (a, rlp) -> rlp.writeBytes(a.getBytes()));
|
|
+ o.writeEmptyList();
|
|
+ o.writeIntScalar(0);
|
|
+ o.writeEmptyList();
|
|
+ o.writeRaw(certificate);
|
|
+ proposerSeal.ifPresent(
|
|
+ ps -> {
|
|
+ o.startList();
|
|
+ o.writeIntScalar(ps.getValidatorIndex());
|
|
+ o.writeBytes(ps.getSignature());
|
|
+ o.endList();
|
|
+ });
|
|
+ o.endList();
|
|
+ return o.encoded();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void vcEveryValidVectorRoundTripsAndEveryInvalidOneIsRefusedWithV303() {
|
|
+ final JsonNode vc = vectors().get("VC");
|
|
+ assertThat(vc.size()).as("AERE-R1B-VC: the class is present").isEqualTo(25);
|
|
+ int valid = 0;
|
|
+ int refused = 0;
|
|
+ for (final JsonNode x : vc) {
|
|
+ final String id = x.get("id").asText();
|
|
+ final Bytes bytes = Bytes.fromHexString(x.get("bytes").asText());
|
|
+ if (x.get("valid").asBoolean()) {
|
|
+ final PqAnchorV3.Certificate c = PqAnchorV3.decode(bytes);
|
|
+ assertThat(c.round()).as("AERE-R1B-VC %s: round", id).isEqualTo(x.get("round").asInt());
|
|
+ assertThat(c.seals()).as("AERE-R1B-VC %s: rows", id).isEqualTo(rows(x.get("rows")));
|
|
+ assertThat(PqAnchorV3.encode(c)).as("AERE-R1B-VC %s: canonical re-encoding", id).isEqualTo(bytes);
|
|
+ valid++;
|
|
+ } else {
|
|
+ assertThat(x.get("code").asText()).isEqualTo(PqAnchorV3.V3_03);
|
|
+ assertThatThrownBy(() -> PqAnchorV3.decode(bytes))
|
|
+ .as("AERE-R1B-VC %s: refused with the code", id)
|
|
+ .isInstanceOf(IllegalArgumentException.class)
|
|
+ .hasMessageStartingWith(PqAnchorV3.V3_03);
|
|
+ refused++;
|
|
+ }
|
|
+ }
|
|
+ assertThat(valid).isEqualTo(8);
|
|
+ assertThat(refused).isEqualTo(17);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void vcInsideAHeaderTheCodecCarriesTheRoundBeforeTheProposerSealAndRefusesEveryInvalidForm() {
|
|
+ final FalconSeal ps = new FalconSeal(2, PqAnchorTestSupport.signature(2, 9));
|
|
+ for (final JsonNode x : vectors().get("VC")) {
|
|
+ final String id = x.get("id").asText();
|
|
+ final Bytes cert = Bytes.fromHexString(x.get("bytes").asText());
|
|
+ for (final Optional<FalconSeal> seal : List.of(Optional.<FalconSeal>empty(), Optional.of(ps))) {
|
|
+ final Bytes extra = extraWith(cert, seal);
|
|
+ if (x.get("valid").asBoolean()) {
|
|
+ final BftExtraData d = CODEC.decodeRaw(extra);
|
|
+ assertThat(d.getCertificateRound()).as("AERE-R1B-VC %s: round in the header", id).hasValue(x.get("round").asInt());
|
|
+ assertThat(d.getHybridSeals()).isEqualTo(rows(x.get("rows")));
|
|
+ assertThat(d.getFalconSeals()).isEmpty();
|
|
+ assertThat(d.getPqProposerSeal()).isEqualTo(seal);
|
|
+ assertThat(CODEC.encode(d)).as("AERE-R1B-VC %s: the header round-trips", id).isEqualTo(extra);
|
|
+ assertThat(CODEC.encode(d.withSeals(Collections.emptyList(), seal)))
|
|
+ .as("AERE-R1B-VC %s: withSeals keeps the round (D-328)", id)
|
|
+ .isEqualTo(extra);
|
|
+ } else {
|
|
+ assertThatThrownBy(() -> CODEC.decodeRaw(extra))
|
|
+ .as("AERE-R1B-VC %s: the codec refuses it inside a header", id)
|
|
+ .isInstanceOf(RuntimeException.class);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ // an empty v3 is written even without a proposer seal: the slot is never omitted for a v3
|
|
+ final BftExtraData empty =
|
|
+ new BftExtraData(Bytes32.ZERO, List.of(), Optional.empty(), 0, PqAnchorTestSupport.VALIDATORS, List.of(), List.of(), 0);
|
|
+ assertThat(CODEC.encode(empty)).isEqualTo(extraWith(Bytes.fromHexString("0xc30380c0"), Optional.empty()));
|
|
+ assertThat(CODEC.decodeRaw(CODEC.encode(empty)).getCertificateRound()).hasValue(0);
|
|
+ // and the v2 of the same rows still decodes as v2 (no round)
|
|
+ final List<SchemeSeal> two = List.of(new SchemeSeal(FALCON, 0, Bytes.fromHexString("0xaaaaaaaa")));
|
|
+ final BftExtraData v2 =
|
|
+ new BftExtraData(Bytes32.ZERO, List.of(), Optional.empty(), 0, PqAnchorTestSupport.VALIDATORS, List.of(), two, BftExtraData.NO_CERTIFICATE_ROUND);
|
|
+ assertThat(CODEC.decodeRaw(CODEC.encode(v2)).getCertificateRound()).isEmpty();
|
|
+ assertThat(CODEC.decodeRaw(CODEC.encode(v2)).getHybridSeals()).isEqualTo(two);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void vdTheDigestDependsOnTheRoundAndDiffersFromV2() {
|
|
+ final JsonNode vd = vectors().get("VD");
|
|
+ assertThat(vd.size()).isEqualTo(6);
|
|
+ for (final JsonNode x : vd) {
|
|
+ final String id = x.get("id").asText();
|
|
+ final long chain = x.get("chainId").asLong();
|
|
+ final long p = x.get("parentNumber").asLong();
|
|
+ final Bytes32 hp = Bytes32.fromHexString(x.get("parentHash").asText());
|
|
+ if (x.has("certificate")) {
|
|
+ final PqAnchorV3.Certificate c = PqAnchorV3.decode(Bytes.fromHexString(x.get("certificate").asText()));
|
|
+ assertThat(PqAnchorV3.anchorDigestV3(chain, p, hp, c)).as("AERE-R1B-VD %s", id).isEqualTo(Bytes32.fromHexString(x.get("d3").asText()));
|
|
+ } else {
|
|
+ final List<SchemeSeal> v2 = PqAnchorV2.decode(Bytes.fromHexString(x.get("certificateV2").asText()));
|
|
+ assertThat(PqAnchorV2.anchorDigestV2(chain, p, hp, v2)).as("AERE-R1B-VD %s (control D2)", id).isEqualTo(Bytes32.fromHexString(x.get("d2").asText()));
|
|
+ final Bytes32 d3r0 = PqAnchorV3.anchorDigestV3(chain, p, hp, new PqAnchorV3.Certificate(0, v2));
|
|
+ final Bytes32 d3r3 = PqAnchorV3.anchorDigestV3(chain, p, hp, new PqAnchorV3.Certificate(3, v2));
|
|
+ assertThat(d3r0).isNotEqualTo(d3r3).isNotEqualTo(Bytes32.fromHexString(x.get("d2").asText()));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void maxRoundIsOneConstantAcrossTheStageFiveRuleAndTheRoundChangeCap() {
|
|
+ assertThat(PqAnchorV3.MAX_ROUND).isEqualTo(PqHeaderSealRule.MAX_ROUND);
|
|
+ assertThat(PqAnchorV3.MAX_ROUND).isGreaterThanOrEqualTo(RoundChangePayloadValidator.MAX_ALLOWED_ROUND);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void bftExtraDataKeepsTheV3Invariants() {
|
|
+ final List<SchemeSeal> one = List.of(new SchemeSeal(FALCON, 0, Bytes.fromHexString("0xaa")));
|
|
+ final List<FalconSeal> v1 = List.of(new FalconSeal(0, Bytes.fromHexString("0xaa")));
|
|
+ assertThatThrownBy(() -> new BftExtraData(Bytes32.ZERO, List.of(), Optional.empty(), 0, List.of(), v1, List.of(), 0))
|
|
+ .isInstanceOf(IllegalArgumentException.class);
|
|
+ assertThatThrownBy(() -> new BftExtraData(Bytes32.ZERO, List.of(), Optional.empty(), 0, List.of(), List.of(), List.of(), 3))
|
|
+ .isInstanceOf(IllegalArgumentException.class);
|
|
+ assertThatThrownBy(() -> new BftExtraData(Bytes32.ZERO, List.of(), Optional.empty(), 0, List.of(), List.of(), one, 1025))
|
|
+ .isInstanceOf(IllegalArgumentException.class);
|
|
+ assertThatThrownBy(() -> new BftExtraData(Bytes32.ZERO, List.of(), Optional.empty(), 0, List.of(), List.of(), one, -2))
|
|
+ .isInstanceOf(IllegalArgumentException.class);
|
|
+ final BftExtraData ok = new BftExtraData(Bytes32.ZERO, List.of(), Optional.empty(), 0, List.of(), List.of(), one, 7);
|
|
+ assertThat(ok.getCertificateRound()).hasValue(7);
|
|
+ assertThat(ok.withSeals(List.of(), Optional.empty()).getCertificateRound()).hasValue(7);
|
|
+ assertThat(new BftExtraData(Bytes32.ZERO, List.of(), Optional.empty(), 0, List.of()).getCertificateRound()).isEmpty();
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------------
|
|
+ // R1 and R2 through the REAL rules: the form by height, both directions (01, 02), the digest (04)
|
|
+ // ------------------------------------------------------------------------------------------------
|
|
+
|
|
+ private static final long HR = 1_100L;
|
|
+
|
|
+ private static PqAnchorConfig cfg() {
|
|
+ return new PqAnchorConfig(PqAnchorTestSupport.CHAIN_ID, PqAnchorTestSupport.H, Map.of(PqAnchorTestSupport.H, 0), OptionalInt.empty(), false)
|
|
+ .withAnchorV2Block(PqAnchorTestSupport.H)
|
|
+ .withCommitRoundBlock(HR);
|
|
+ }
|
|
+
|
|
+ private static final List<SchemeSeal> ROWS =
|
|
+ List.of(
|
|
+ new SchemeSeal(FALCON, 0, PqAnchorTestSupport.signature(0, 0)),
|
|
+ new SchemeSeal(FALCON, 2, PqAnchorTestSupport.signature(2, 0)));
|
|
+
|
|
+ /** A header at a over parent, with the given certificate round (or none: v2) and the vanity it names. */
|
|
+ private static BlockHeader header(final BlockHeader parent, final int round, final int digestRound) {
|
|
+ final long a = parent.getNumber() + 1L;
|
|
+ final Bytes32 vanity =
|
|
+ digestRound < 0
|
|
+ ? PqAnchorV2.anchorDigestV2(PqAnchorTestSupport.CHAIN_ID, parent.getNumber(), parent.getHash().getBytes(), ROWS)
|
|
+ : PqAnchorV3.anchorDigestV3(PqAnchorTestSupport.CHAIN_ID, parent.getNumber(), parent.getHash().getBytes(), new PqAnchorV3.Certificate(digestRound, ROWS));
|
|
+ final Bytes extra =
|
|
+ CODEC.encode(new BftExtraData(vanity, List.of(), Optional.empty(), 0, PqAnchorTestSupport.VALIDATORS, List.of(), ROWS, round));
|
|
+ return PqAnchorTestSupport.header(a, parent.getHash(), extra);
|
|
+ }
|
|
+
|
|
+ private static String r1Code(final BlockHeader h) {
|
|
+ final BftExtraData d = CODEC.decodeRaw(h.getExtraData());
|
|
+ final PqAnchorV3.Verdict v =
|
|
+ PqAnchorV3.judgeForm(cfg().certificateFormAt(h.getNumber()), d.getCertificateRound(), d.getHybridSeals(), d.getVanityData(), PqAnchorTestSupport.CHAIN_ID, h.getNumber(), h.getParentHash().getBytes());
|
|
+ return v.accepted() ? "accepted" : v.code();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void r1TheFormByHeightBothDirectionsAndTheDigest() {
|
|
+ final PqAnchorDigestRule r1 = new PqAnchorDigestRule(cfg());
|
|
+ final BlockHeader pAtHr = PqAnchorTestSupport.parentHeader(HR - 1L);
|
|
+ final BlockHeader pBelow = PqAnchorTestSupport.parentHeader(HR - 51L);
|
|
+ final BlockHeader honest = header(pAtHr, 3, 3);
|
|
+ assertThat(r1Code(honest)).isEqualTo("accepted");
|
|
+ assertThat(r1.validate(honest, pAtHr)).as("an honest v3 at H_r").isTrue();
|
|
+ final BlockHeader otherRound = header(pAtHr, 3, 2);
|
|
+ assertThat(r1Code(otherRound)).isEqualTo(PqAnchorV3.V3_04);
|
|
+ assertThat(r1.validate(otherRound, pAtHr)).as("D3 of another round in the vanity").isFalse();
|
|
+ final BlockHeader v2AtHr = header(pAtHr, BftExtraData.NO_CERTIFICATE_ROUND, -1);
|
|
+ assertThat(r1Code(v2AtHr)).isEqualTo(PqAnchorV3.V3_02);
|
|
+ assertThat(r1.validate(v2AtHr, pAtHr)).as("a v2 at H_r").isFalse();
|
|
+ final BlockHeader v3Below = header(pBelow, 3, 3);
|
|
+ assertThat(r1Code(v3Below)).isEqualTo(PqAnchorV3.V3_01);
|
|
+ assertThat(r1.validate(v3Below, pBelow)).as("a v3 below H_r").isFalse();
|
|
+ final BlockHeader v2Below = header(pBelow, BftExtraData.NO_CERTIFICATE_ROUND, -1);
|
|
+ assertThat(r1Code(v2Below)).isEqualTo("accepted");
|
|
+ assertThat(r1.validate(v2Below, pBelow)).as("control: the v2 below H_r is still accepted").isTrue();
|
|
+ final BlockHeader v1AtHr =
|
|
+ PqAnchorTestSupport.header(
|
|
+ HR, pAtHr.getHash(),
|
|
+ PqAnchorTestSupport.extraData(
|
|
+ PqAnchor.anchorDigest(PqAnchorTestSupport.CHAIN_ID, HR - 1L, pAtHr.getHash().getBytes(), List.of(PqAnchorTestSupport.seal(0))),
|
|
+ List.of(PqAnchorTestSupport.seal(0))));
|
|
+ assertThat(r1Code(v1AtHr)).isEqualTo(PqAnchorV3.V3_02);
|
|
+ assertThat(r1.validate(v1AtHr, pAtHr)).as("a v1 at H_r").isFalse();
|
|
+ // without H_r the same honest v3 header is refused and the v2 accepted: below H_r nothing changes (L1)
|
|
+ final PqAnchorDigestRule noHr =
|
|
+ new PqAnchorDigestRule(
|
|
+ new PqAnchorConfig(PqAnchorTestSupport.CHAIN_ID, PqAnchorTestSupport.H, Map.of(PqAnchorTestSupport.H, 0), OptionalInt.empty(), false)
|
|
+ .withAnchorV2Block(PqAnchorTestSupport.H));
|
|
+ assertThat(noHr.validate(honest, pAtHr)).isFalse();
|
|
+ assertThat(noHr.validate(v2AtHr, pAtHr)).isTrue();
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------------
|
|
+ // The seal codes (05, 06, 07, 08) through judgeSeals, with the synthetic keys and per-round seals of VS
|
|
+ // ------------------------------------------------------------------------------------------------
|
|
+
|
|
+ private static class Keys implements PqAnchorV3.Signers {
|
|
+ final Map<Integer, Address> members = new HashMap<>();
|
|
+ final Map<Integer, byte[]> falcon = new HashMap<>();
|
|
+ final Map<Integer, byte[]> slh = new HashMap<>();
|
|
+ Collection<Address> set;
|
|
+
|
|
+ @Override
|
|
+ public Collection<Address> parentSet() {
|
|
+ return set;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Address memberAt(final int index) {
|
|
+ return members.get(index);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean verifyFalcon(final int index, final Bytes32 message, final Bytes signature) {
|
|
+ final byte[] pk = falcon.get(index);
|
|
+ return pk != null && SealSchemes.FALCON_512.verifyRaw(pk, message.toArray(), signature.toArray());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Optional<byte[]> extraKey(final int index, final SealScheme scheme) {
|
|
+ return SealSchemes.SLH_DSA_128S.id().equals(scheme.id()) ? Optional.ofNullable(slh.get(index)) : Optional.empty();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static Keys keys(final JsonNode v) {
|
|
+ final Keys k = new Keys();
|
|
+ final List<Address> set = new ArrayList<>();
|
|
+ for (final JsonNode key : v.get("keys")) {
|
|
+ final int i = key.get("index").asInt();
|
|
+ final Address a = Address.fromHexString(key.get("address").asText());
|
|
+ k.members.put(i, a);
|
|
+ set.add(a);
|
|
+ k.falcon.put(i, Bytes.fromHexString(key.get("falcon-512").get("publicKeyRegistry").asText()).toArray());
|
|
+ final JsonNode s = key.get("slh-dsa-sha2-128s");
|
|
+ if (s != null && s.has("publicKey")) {
|
|
+ k.slh.put(i, Bytes.fromHexString(s.get("publicKey").asText()).toArray());
|
|
+ }
|
|
+ }
|
|
+ k.set = set;
|
|
+ return k;
|
|
+ }
|
|
+
|
|
+ private static List<SchemeSeal> sortedCopy(final List<SchemeSeal> rows) {
|
|
+ final List<SchemeSeal> sorted = new ArrayList<>(rows);
|
|
+ sorted.sort(PqAnchorV2.CANONICAL);
|
|
+ return sorted;
|
|
+ }
|
|
+
|
|
+ private static PqAnchorConfig vsCfg() {
|
|
+ return new PqAnchorConfig(28001L, 64L, Map.of(64L, 0), OptionalInt.empty(), false).withAnchorV2Block(64L).withCommitRoundBlock(1000L);
|
|
+ }
|
|
+
|
|
+ private static String seals(final Keys k, final int round, final List<SchemeSeal> rows, final int kEff, final Set<String> named, final Set<String> required) {
|
|
+ final List<SchemeSeal> sorted = new ArrayList<>(rows);
|
|
+ sorted.sort(PqAnchorV2.CANONICAL);
|
|
+ final PqAnchorV3.Verdict v =
|
|
+ PqAnchorV3.judgeSeals(vsCfg(), 1001L, Bytes32.fromHexString("0x" + "33".repeat(32)), new PqAnchorV3.Certificate(round, sorted), kEff, named, required, k);
|
|
+ return v.accepted() ? "accepted:" + v.falconMembers() : v.code();
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void judgeSealsGivesTheCodeOfTheFirstFailureInTheFixedOrder() {
|
|
+ final JsonNode v = vectors();
|
|
+ final JsonNode vs = v.get("VS").get(0);
|
|
+ assertThat(vs.get("n").asLong()).isEqualTo(1000L);
|
|
+ final List<SchemeSeal> r0 = rows(vs.get("groups").get(0).get("rows"));
|
|
+ final List<SchemeSeal> r2 = rows(vs.get("groups").get(1).get("rows"));
|
|
+ assertThat(vs.get("groups").get(0).get("round").asInt()).isEqualTo(0);
|
|
+ assertThat(vs.get("groups").get(1).get("round").asInt()).isEqualTo(2);
|
|
+ final Keys k = keys(v);
|
|
+ final String slh = SealSchemes.SLH_DSA_128S.id();
|
|
+ // positive control of the METHOD: a Falcon row of round 0 verifies over M_0 and not over M_2
|
|
+ final Bytes32 hash = Bytes32.fromHexString("0x" + "33".repeat(32));
|
|
+ final SchemeSeal f0 = r0.stream().filter(s -> s.getSchemeWireId() == FALCON && s.getValidatorIndex() == 0).findFirst().orElseThrow();
|
|
+ assertThat(k.verifyFalcon(0, PqAnchor.commitMessageRound(28001L, 1000L, 0, hash), f0.getSignature())).isTrue();
|
|
+ assertThat(k.verifyFalcon(0, PqAnchor.commitMessageRound(28001L, 1000L, 2, hash), f0.getSignature())).isFalse();
|
|
+
|
|
+ // accepted: round 0, two Falcon members, its SLH seal over the same M_0
|
|
+ assertThat(seals(k, 0, r0, 2, Set.of(slh), Set.of())).isEqualTo("accepted:2");
|
|
+ assertThat(seals(k, 0, r0, 1, Set.of(slh), Set.of(slh))).isEqualTo("accepted:2");
|
|
+ assertThat(seals(k, 2, r2, 2, Set.of(slh), Set.of())).as("round 2 with its own seals").isEqualTo("accepted:2");
|
|
+ assertThat(seals(k, 2, r2, 1, Set.of(slh), Set.of(slh))).as("round 2, its one SLH seal required at K=1").isEqualTo("accepted:2");
|
|
+ // 05: below K, and a required scheme below K
|
|
+ assertThat(seals(k, 0, r0, 3, Set.of(slh), Set.of())).isEqualTo(PqAnchorV3.V3_05);
|
|
+ assertThat(seals(k, 0, r0, 2, Set.of(slh), Set.of(slh))).isEqualTo(PqAnchorV3.V3_05);
|
|
+ // 07: the seals of round 0 under a certificate that names round 2; a mix of the two rounds
|
|
+ assertThat(seals(k, 2, r0, 2, Set.of(slh), Set.of())).isEqualTo(PqAnchorV3.V3_07);
|
|
+ final List<SchemeSeal> mixed = List.of(r0.get(0), r2.stream().filter(s -> s.getSchemeWireId() == FALCON && s.getValidatorIndex() == 1).findFirst().orElseThrow());
|
|
+ assertThat(seals(k, 0, mixed, 2, Set.of(slh), Set.of())).as("a seal of round 2 in a round-0 certificate").isEqualTo(PqAnchorV3.V3_07);
|
|
+ // 06: unbound, a non-member, two indices on one member, an unresolvable set, no key for the extra
|
|
+ final Keys unbound = keys(v);
|
|
+ unbound.members.remove(2);
|
|
+ assertThat(seals(unbound, 0, r0, 2, Set.of(slh), Set.of())).isEqualTo(PqAnchorV3.V3_06);
|
|
+ final Keys outsider = keys(v);
|
|
+ outsider.set = List.of(outsider.members.get(0), outsider.members.get(1), outsider.members.get(3));
|
|
+ assertThat(seals(outsider, 0, r0, 2, Set.of(slh), Set.of())).isEqualTo(PqAnchorV3.V3_06);
|
|
+ final Keys twice = keys(v);
|
|
+ twice.members.put(2, twice.members.get(0));
|
|
+ assertThat(seals(twice, 0, r0, 2, Set.of(slh), Set.of())).isEqualTo(PqAnchorV3.V3_06);
|
|
+ final Keys noSet = keys(v);
|
|
+ noSet.set = List.of();
|
|
+ assertThat(seals(noSet, 0, r0, 2, Set.of(slh), Set.of())).isEqualTo(PqAnchorV3.V3_06);
|
|
+ final Keys noSlhKey = keys(v);
|
|
+ noSlhKey.slh.clear();
|
|
+ assertThat(seals(noSlhKey, 0, r0, 2, Set.of(slh), Set.of())).isEqualTo(PqAnchorV3.V3_06);
|
|
+ // 08: an extra of a scheme not named, an extra without the Falcon of its index
|
|
+ assertThat(seals(k, 0, r0, 2, Set.of(), Set.of())).isEqualTo(PqAnchorV3.V3_08);
|
|
+ final List<SchemeSeal> noFalconZero = r0.stream().filter(s -> !(s.getSchemeWireId() == FALCON && s.getValidatorIndex() == 0)).toList();
|
|
+ assertThat(seals(k, 0, noFalconZero, 1, Set.of(slh), Set.of())).isEqualTo(PqAnchorV3.V3_08);
|
|
+ // 07 for an extra: the round-0 SLH seal of index 0 with one byte changed, beside valid Falcon seals
|
|
+ final List<SchemeSeal> badExtra = new ArrayList<>();
|
|
+ for (final SchemeSeal s : r0) {
|
|
+ if (s.getSchemeWireId() == SLH) {
|
|
+ final byte[] sig = s.getSignature().toArray();
|
|
+ sig[100] ^= 1;
|
|
+ badExtra.add(new SchemeSeal(SLH, s.getValidatorIndex(), Bytes.wrap(sig)));
|
|
+ } else {
|
|
+ badExtra.add(s);
|
|
+ }
|
|
+ }
|
|
+ assertThat(seals(k, 0, badExtra, 2, Set.of(slh), Set.of())).isEqualTo(PqAnchorV3.V3_07);
|
|
+ // the order is fixed, Falcon rows before extras: an unbound Falcon index (06) AND a bad extra (07) give 06
|
|
+ final Keys unboundAndBadExtra = keys(v);
|
|
+ unboundAndBadExtra.members.remove(2);
|
|
+ assertThat(seals(unboundAndBadExtra, 0, badExtra, 2, Set.of(slh), Set.of()))
|
|
+ .as("the Falcon rows are judged before the extras")
|
|
+ .isEqualTo(PqAnchorV3.V3_06);
|
|
+ // and the count before any row: 2 Falcon of K = 3 with an unbound index gives 05, not 06
|
|
+ assertThat(seals(unboundAndBadExtra, 0, r0, 3, Set.of(slh), Set.of())).isEqualTo(PqAnchorV3.V3_05);
|
|
+ // TOTAL (H11): a door that throws gives the code of what it was asked, never an exception out of the judge
|
|
+ final Keys throwing =
|
|
+ new Keys() {
|
|
+ @Override
|
|
+ public Collection<Address> parentSet() {
|
|
+ throw new IllegalStateException("AERE-R1B-PROBA: the set cannot be read");
|
|
+ }
|
|
+ };
|
|
+ throwing.members.putAll(k.members);
|
|
+ throwing.falcon.putAll(k.falcon);
|
|
+ throwing.slh.putAll(k.slh);
|
|
+ assertThat(seals(throwing, 0, r0, 2, Set.of(slh), Set.of())).isEqualTo(PqAnchorV3.V3_06);
|
|
+ final Keys throwingMember =
|
|
+ new Keys() {
|
|
+ @Override
|
|
+ public Address memberAt(final int index) {
|
|
+ throw new IllegalStateException("AERE-R1B-PROBA: no binding at this height");
|
|
+ }
|
|
+ };
|
|
+ throwingMember.set = k.set;
|
|
+ assertThat(seals(throwingMember, 0, r0, 2, Set.of(slh), Set.of())).isEqualTo(PqAnchorV3.V3_06);
|
|
+ // the precondition: over a parent that is NOT round-bound (H_r unset) the judge refuses by name (01) instead of
|
|
+ // judging the seals over COMMIT-1
|
|
+ final PqAnchorV3.Verdict roundFree =
|
|
+ PqAnchorV3.judgeSeals(
|
|
+ new PqAnchorConfig(28001L, 64L, Map.of(64L, 0), OptionalInt.empty(), false).withAnchorV2Block(64L),
|
|
+ 1001L,
|
|
+ hash,
|
|
+ new PqAnchorV3.Certificate(0, sortedCopy(r0)),
|
|
+ 2,
|
|
+ Set.of(slh),
|
|
+ Set.of(),
|
|
+ k);
|
|
+ assertThat(roundFree.code()).isEqualTo(PqAnchorV3.V3_01);
|
|
+ // H5: the empty certificate is valid only at K_eff = 0, and proves nothing (0 members)
|
|
+ assertThat(seals(k, 0, List.of(), 0, Set.of(slh), Set.of())).isEqualTo("accepted:0");
|
|
+ assertThat(seals(k, 0, List.of(), 1, Set.of(slh), Set.of())).isEqualTo(PqAnchorV3.V3_05);
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqHeaderSealStage5Test.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqHeaderSealStage5Test.java
|
|
index 2a928bda7c..3f0d4691c1 100644
|
|
--- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqHeaderSealStage5Test.java
|
|
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqHeaderSealStage5Test.java
|
|
@@ -119,41 +119,41 @@ public class PqHeaderSealStage5Test {
|
|
.map(k -> FALCON.verifyRaw(k, m.toArrayUnsafe(), s.toArrayUnsafe()))
|
|
.orElse(false);
|
|
AerePqFinality.install(H_FIN, CHAIN, v);
|
|
AerePqHeaderSeal.install(H_HDR);
|
|
rule = new PqHeaderSealRule(sentinel(false), CODEC, CHAIN, v);
|
|
}
|
|
|
|
@AfterEach
|
|
public void disarm() {
|
|
AerePqHeaderSeal.uninstall();
|
|
AerePqFinality.uninstall();
|
|
AerePqIdentity.uninstall();
|
|
}
|
|
|
|
private static AttachedBlockHeaderValidationRule sentinel(final boolean answer) {
|
|
return (header, parent, ctx) -> answer;
|
|
}
|
|
|
|
private BftExtraData extra(final int round, final List<SECPSignature> seals, final Optional<FalconSeal> ps) {
|
|
return new BftExtraData(
|
|
- Bytes.wrap(new byte[32]), seals, Optional.empty(), round, ids, Collections.emptyList(), Collections.emptyList(), ps);
|
|
+ Bytes.wrap(new byte[32]), seals, Optional.empty(), round, ids, Collections.emptyList(), Collections.emptyList(), BftExtraData.NO_CERTIFICATE_ROUND, ps);
|
|
}
|
|
|
|
private static BlockHeader header(final long h, final Address coinbase, final BftExtraData ed) {
|
|
return new BlockHeaderTestFixture().number(h).coinbase(coinbase).extraData(CODEC.encode(ed)).buildHeader();
|
|
}
|
|
|
|
/** The proposer seal of {@code signer} over the header's own proposal message (for the index {@code index}). */
|
|
private Optional<FalconSeal> sealOver(final BlockHeader unsealed, final int round, final int index, final int signer) {
|
|
final Bytes32 m =
|
|
PqAnchor.proposalMessage(
|
|
CHAIN, unsealed.getNumber(), round, new BftBlockHashing(CODEC).calculateDataHashForCommittedSeal(unsealed).getBytes());
|
|
return Optional.of(new FalconSeal(index, Bytes.wrap(FALCON.sign(falcon.get(signer), m.toArrayUnsafe()).orElseThrow())));
|
|
}
|
|
|
|
private BlockHeader sealedHeader(final long h, final int round, final int coinbase, final int index, final int signer) {
|
|
final BlockHeader unsealed = header(h, ids.get(coinbase), extra(round, List.of(), Optional.empty()));
|
|
return header(h, ids.get(coinbase), extra(round, List.of(), sealOver(unsealed, round, index, signer)));
|
|
}
|
|
|
|
@Test
|
|
@@ -239,46 +239,46 @@ public class PqHeaderSealStage5Test {
|
|
int seed = 0;
|
|
for (int k = 0; k < n; k++) {
|
|
if (sorted.get(k).compareTo(prev) > 0) {
|
|
seed = k;
|
|
break;
|
|
}
|
|
}
|
|
return sorted.get((seed + r) % n);
|
|
}
|
|
|
|
private BlockHeader parentWithCoinbase(final long h, final Address coinbase) {
|
|
return new BlockHeaderTestFixture().number(h - 1).coinbase(coinbase).buildHeader();
|
|
}
|
|
|
|
/** A header at h, round r, built by {@code coinbase}, sealed as index {@code index} by key {@code signer}. */
|
|
private BlockHeader reproposed(final long h, final int round, final Address coinbase, final int index, final int signer) {
|
|
final List<Address> sorted = sortedIds();
|
|
final BftExtraData bare =
|
|
new BftExtraData(
|
|
Bytes.wrap(new byte[32]), List.of(), Optional.empty(), round, sorted, Collections.emptyList(),
|
|
- Collections.emptyList(), Optional.empty());
|
|
+ Collections.emptyList(), BftExtraData.NO_CERTIFICATE_ROUND, Optional.empty());
|
|
final BlockHeader unsealed = header(h, coinbase, bare);
|
|
final BftExtraData sealed =
|
|
new BftExtraData(
|
|
Bytes.wrap(new byte[32]), List.of(), Optional.empty(), round, sorted, Collections.emptyList(),
|
|
- Collections.emptyList(), sealOver(unsealed, round, index, signer));
|
|
+ Collections.emptyList(), BftExtraData.NO_CERTIFICATE_ROUND, sealOver(unsealed, round, index, signer));
|
|
return header(h, coinbase, sealed);
|
|
}
|
|
|
|
@Test
|
|
public void aReProposedHeaderSealedByTheProposerOfItsRoundIsAdmittedOnlyWithItsParent() {
|
|
final List<Address> sorted = sortedIds();
|
|
final long h = H_HDR + 5;
|
|
int judged = 0;
|
|
for (int p = 0; p < N; p++) {
|
|
final Address prev = sorted.get(p);
|
|
final Address builder = expectedProposer(sorted, prev, 0);
|
|
for (int r = 1; r < 2 * N; r++) {
|
|
final Address roundProposer = expectedProposer(sorted, prev, r);
|
|
if (roundProposer.equals(builder)) {
|
|
continue;
|
|
}
|
|
final int idx = ids.indexOf(roundProposer);
|
|
final BlockHeader hd = reproposed(h, r, builder, idx, idx);
|
|
final BlockHeader parent = parentWithCoinbase(h, prev);
|
|
assertThat(rule.refusal(hd, parent)).as("prev %s round %s", p, r).isEmpty();
|
|
@@ -301,44 +301,44 @@ public class PqHeaderSealStage5Test {
|
|
final Address builder = expectedProposer(sorted, prev, 0);
|
|
final int r = 1;
|
|
final Address roundProposer = expectedProposer(sorted, prev, r);
|
|
Address third = null;
|
|
for (final Address a : sorted) {
|
|
if (!a.equals(builder) && !a.equals(roundProposer)) {
|
|
third = a;
|
|
break;
|
|
}
|
|
}
|
|
final int idx = ids.indexOf(third);
|
|
final Optional<String> why = rule.refusal(reproposed(h, r, builder, idx, idx), parentWithCoinbase(h, prev));
|
|
assertThat(why).get().asString()
|
|
.contains("cannot vouch")
|
|
.contains("the proposer of round " + r + " is " + roundProposer);
|
|
// the round proposer's key over ANOTHER round than element 3: the id passes, the signature does not
|
|
final int rp = ids.indexOf(roundProposer);
|
|
final List<Address> s2 = sortedIds();
|
|
final BlockHeader atRound0 =
|
|
header(h, builder, new BftExtraData(Bytes.wrap(new byte[32]), List.of(), Optional.empty(), 0, s2,
|
|
- Collections.emptyList(), Collections.emptyList(), Optional.empty()));
|
|
+ Collections.emptyList(), Collections.emptyList(), BftExtraData.NO_CERTIFICATE_ROUND, Optional.empty()));
|
|
final BlockHeader wrongRound =
|
|
header(h, builder, new BftExtraData(Bytes.wrap(new byte[32]), List.of(), Optional.empty(), r, s2,
|
|
- Collections.emptyList(), Collections.emptyList(), sealOver(atRound0, 0, rp, rp)));
|
|
+ Collections.emptyList(), Collections.emptyList(), BftExtraData.NO_CERTIFICATE_ROUND, sealOver(atRound0, 0, rp, rp)));
|
|
assertThat(rule.refusal(wrongRound, parentWithCoinbase(h, prev))).get().asString().contains("does not verify");
|
|
}
|
|
|
|
@Test
|
|
public void theSealMustBeExactlyTheProposerOfRoundRNotOfAnEarlierRound() {
|
|
// found by the adversarial review of 2026-09-25: an implementation admitting ANY P(r') with r' <= r passed every probe above
|
|
final List<Address> sorted = sortedIds();
|
|
final long h = H_HDR + 9;
|
|
final Address prev = sorted.get(0);
|
|
final Address builder = expectedProposer(sorted, prev, 0);
|
|
final Address p1 = expectedProposer(sorted, prev, 1);
|
|
final Address p2 = expectedProposer(sorted, prev, 2);
|
|
assertThat(p1).isNotEqualTo(p2);
|
|
final int i1 = ids.indexOf(p1);
|
|
assertThat(rule.refusal(reproposed(h, 2, builder, i1, i1), parentWithCoinbase(h, prev))).get().asString()
|
|
.contains("cannot vouch").contains("the proposer of round 2 is " + p2);
|
|
final int i2 = ids.indexOf(p2);
|
|
assertThat(rule.refusal(reproposed(h, 2, builder, i2, i2), parentWithCoinbase(h, prev))).isEmpty();
|
|
}
|
|
|
|
@@ -426,41 +426,41 @@ public class PqHeaderSealStage5Test {
|
|
assertThat(rule.refusal(reproposed(h, r, builder, idx, idx), parentWithCoinbase(h, prev)))
|
|
.as("prev %s round %s", prev, r).isEmpty();
|
|
judged++;
|
|
}
|
|
}
|
|
assertThat(judged).isEqualTo(3 * (N - 1));
|
|
}
|
|
|
|
// ---- AERE D-415 (2026-09-25): the vanity field is exactly 32 bytes at EVERY height, in the codec, as in the second client ----
|
|
|
|
/** The genesis extraData of chains 2800 and 28001 (both a 32-zero vanity), as published. */
|
|
private static final String GENESIS_2800_EXTRA =
|
|
"0xf865a00000000000000000000000000000000000000000000000000000000000000000f83f94b5e768cb3117ea25175f51aa956b48691025c2a894f73bbbd26a82dbc769066550d8d4585eab2fc00d944bf6f91d84b37454544279cba152581ed6820044c080c0";
|
|
private static final String GENESIS_28001_EXTRA =
|
|
"0xf87aa00000000000000000000000000000000000000000000000000000000000000000f8549404211fd71c1eae94f560e7e173399c91c15fd9b394070d5e1534a367430307a6e56bef29ddff79c0e394b84ec13c5811264f60a8bc392634709558223ea694fb6be1504acf8262cf98669f7833b9cf1cbfabb9c080c0";
|
|
/** A real 32-byte vanity between anchors on 28001 today: the client version string, not a digest. */
|
|
private static final String VANITY_VERSIUNE = "0x626573752032362e342e302d616572652e312d643230333230312d7774396239";
|
|
|
|
private BlockHeader cuVanity(final long h, final Bytes vanity) {
|
|
final BftExtraData ed =
|
|
- new BftExtraData(vanity, List.of(), Optional.empty(), 0, ids, Collections.emptyList(), Collections.emptyList(), Optional.empty());
|
|
+ new BftExtraData(vanity, List.of(), Optional.empty(), 0, ids, Collections.emptyList(), Collections.emptyList(), BftExtraData.NO_CERTIFICATE_ROUND, Optional.empty());
|
|
return new BlockHeaderTestFixture().number(h).coinbase(ids.get(0)).extraData(CODEC.encode(ed)).buildHeader();
|
|
}
|
|
|
|
@Test
|
|
public void theVanityFieldIsExactly32BytesAtEveryHeightAndBothGenesesStillDecode() {
|
|
// the two real geneses and a real between-anchors vanity decode as before (the check cannot touch the chain)
|
|
for (final String g : List.of(GENESIS_2800_EXTRA, GENESIS_28001_EXTRA)) {
|
|
assertThat(CODEC.decodeRaw(Bytes.fromHexString(g)).getVanityData().size()).as("genesis").isEqualTo(32);
|
|
}
|
|
assertThat(CODEC.decode(cuVanity(H_HDR - 5, Bytes.fromHexString(VANITY_VERSIUNE))).getVanityData().size()).isEqualTo(32);
|
|
// found by the differential fuzzer: a 0-, 31-, 33- or 64-byte vanity between anchors was admitted here and refused by the
|
|
// second client; now the codec refuses it at any height, above and below H_hdr, and the header rule reports the reason
|
|
for (final int n : new int[] {0, 31, 33, 64}) {
|
|
final Bytes v = Bytes.wrap(new byte[n]);
|
|
assertThatThrownBy(() -> CODEC.decode(cuVanity(H_HDR + 12, v))).as("vanity %s above H_hdr", n)
|
|
.isInstanceOf(RLPException.class).hasMessageContaining("AERE-D415");
|
|
assertThatThrownBy(() -> CODEC.decode(cuVanity(H_HDR - 5, v))).as("vanity %s below H_hdr", n)
|
|
.isInstanceOf(RLPException.class).hasMessageContaining("AERE-D415");
|
|
assertThat(rule.refusal(cuVanity(H_HDR + 12, v))).get().asString().contains("does not decode").contains("AERE-D415");
|
|
}
|
|
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/AereGetPqFinalityRoundTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/AereGetPqFinalityRoundTest.java
|
|
new file mode 100644
|
|
index 0000000000..f149e04b9d
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/AereGetPqFinalityRoundTest.java
|
|
@@ -0,0 +1,211 @@
|
|
+/*
|
|
+ * Copyright contributors to Besu / AERE Network.
|
|
+ *
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
+ * the License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
+ * specific language governing permissions and limitations under the License.
|
|
+ *
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
+ */
|
|
+package org.hyperledger.besu.consensus.qbft.jsonrpc.methods;
|
|
+
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
+import static org.mockito.Mockito.lenient;
|
|
+import static org.mockito.Mockito.when;
|
|
+
|
|
+import org.hyperledger.besu.consensus.common.bft.FalconSeal;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqAnchorConfig;
|
|
+import org.hyperledger.besu.consensus.common.bft.PqSealCache;
|
|
+import org.hyperledger.besu.consensus.common.bft.blockcreation.PqAnchorProducer;
|
|
+import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
|
|
+import org.hyperledger.besu.datatypes.Address;
|
|
+import org.hyperledger.besu.datatypes.Hash;
|
|
+import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest;
|
|
+import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
|
|
+import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
|
|
+import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
|
|
+import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
+
|
|
+import java.util.ArrayList;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+
|
|
+import org.apache.tuweni.bytes.Bytes;
|
|
+import org.apache.tuweni.bytes.Bytes32;
|
|
+import org.junit.jupiter.api.AfterEach;
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
+import org.junit.jupiter.api.Test;
|
|
+import org.junit.jupiter.api.extension.ExtendWith;
|
|
+import org.mockito.Mock;
|
|
+import org.mockito.junit.jupiter.MockitoExtension;
|
|
+
|
|
+/**
|
|
+ * AERE 1(b), D-470, pasul 4 (2026-10-01): the AIP-21 record from H_r - 1 (project section 3.1 H; vector class VF). Each
|
|
+ * round is verified over its own M_r and counted on its own; "post-quantum" iff ONE round reaches the quorum of verified
|
|
+ * distinct signers. r0 = 4 and r2 = 3 verified at Q = 7 is "partial" (a sum over rounds would say 7); r2 brought to 7 is
|
|
+ * "post-quantum" with decidedRound = 2. Below H_r the record is today's, field for field (L1).
|
|
+ */
|
|
+@ExtendWith(MockitoExtension.class)
|
|
+public class AereGetPqFinalityRoundTest {
|
|
+
|
|
+ private static final long CHAIN = 220_885L;
|
|
+ private static final long H = 1_000L;
|
|
+ private static final long V2 = 1_005L;
|
|
+ private static final long HR = 1_100L;
|
|
+ private static final long NUMBER = HR + 40L;
|
|
+ private static final long BELOW = HR - 40L;
|
|
+ private static final Hash HASH = Hash.fromHexString("0x" + "ab".repeat(32));
|
|
+
|
|
+ @Mock private BlockchainQueries blockchainQueries;
|
|
+ @Mock private BlockHeader header;
|
|
+ @Mock private ValidatorProvider validatorProvider;
|
|
+
|
|
+ private final PqSealCache cache = PqSealCache.instance();
|
|
+ private final List<Object[]> verifierCalls = new ArrayList<>();
|
|
+
|
|
+ @BeforeEach
|
|
+ public void setUp() {
|
|
+ cache.clear();
|
|
+ PqAnchorProducer.useConfigForTesting(
|
|
+ new PqAnchorConfig(CHAIN, H, Map.of(H, 3), OptionalInt.empty(), false, OptionalInt.empty(), OptionalInt.empty(), V2)
|
|
+ .withCommitRoundBlock(HR));
|
|
+ lenient().when(header.getHash()).thenReturn(HASH);
|
|
+ lenient().when(validatorProvider.getValidatorsForBlock(any())).thenReturn(validators(10));
|
|
+ }
|
|
+
|
|
+ @AfterEach
|
|
+ public void tearDown() {
|
|
+ cache.clear();
|
|
+ PqAnchorProducer.useConfigForTesting(null);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void sealsOfDifferentRoundsAreNeverAddedUp() {
|
|
+ at(NUMBER);
|
|
+ hear(NUMBER, 0, 0, 4);
|
|
+ hear(NUMBER, 2, 4, 7);
|
|
+ final Map<String, Object> r = call(method(), NUMBER);
|
|
+ assertThat(r.get("sealForm")).isEqualTo("anchor-round");
|
|
+ assertThat(r.get("quorum")).isEqualTo(7);
|
|
+ assertThat(r.get("falconSealsHeard")).isEqualTo(7);
|
|
+ assertThat(r.get("finality"))
|
|
+ .as("VF: r0 = 4 and r2 = 3 verified, Q = 7: partial, never post-quantum (4 + 3 is no quorum of one round)")
|
|
+ .isEqualTo("partial");
|
|
+ assertThat(r.get("decidedRound")).isNull();
|
|
+ assertThat(r.get("recordRound")).as("the round with the most verified signers").isEqualTo(0);
|
|
+ assertThat(r.get("falconSealsVerified")).isEqualTo(4);
|
|
+ assertThat(r.get("commitRoundBlock")).isEqualTo(HR);
|
|
+ @SuppressWarnings("unchecked")
|
|
+ final List<Map<String, Object>> rounds = (List<Map<String, Object>>) r.get("rounds");
|
|
+ assertThat(rounds).extracting(m -> m.get("round")).containsExactly(0, 2);
|
|
+ assertThat(rounds).extracting(m -> m.get("falconSealsVerified")).containsExactly(4, 3);
|
|
+ assertThat(rounds.get(1).get("signedMessage"))
|
|
+ .as("each round carries ITS message")
|
|
+ .isEqualTo(message(2).toHexString());
|
|
+ // every seal was verified over the message of its own round
|
|
+ for (final Object[] call : verifierCalls) {
|
|
+ final int index = (int) call[1];
|
|
+ assertThat(call[2]).isEqualTo(message(index < 4 ? 0 : 2));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aQuorumOfOneRoundIsPostQuantumAndNamesItsRound() {
|
|
+ at(NUMBER);
|
|
+ hear(NUMBER, 0, 0, 4);
|
|
+ hear(NUMBER, 2, 0, 7);
|
|
+ final Map<String, Object> r = call(method(), NUMBER);
|
|
+ assertThat(r.get("finality")).isEqualTo("post-quantum");
|
|
+ assertThat(r.get("decidedRound")).isEqualTo(2);
|
|
+ assertThat(r.get("recordRound")).isEqualTo(2);
|
|
+ assertThat(r.get("falconSealsVerified")).isEqualTo(7);
|
|
+ assertThat(r.get("signedMessage")).isEqualTo(message(2).toHexString());
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void aNonMemberAndASecondIndexOfAMemberCountForNothing() {
|
|
+ at(NUMBER);
|
|
+ hear(NUMBER, 2, 0, 6);
|
|
+ hear(NUMBER, 2, 10, 12);
|
|
+ final Map<String, Object> r = call(method(), NUMBER);
|
|
+ assertThat(r.get("falconSealsHeard")).isEqualTo(8);
|
|
+ assertThat(r.get("finality"))
|
|
+ .as("six members, an outsider and a second index of member 0: six distinct members, not the quorum of seven")
|
|
+ .isEqualTo("partial");
|
|
+ assertThat(r.get("falconSealsVerified")).isEqualTo(6);
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void belowHrTheRecordIsTodays() {
|
|
+ at(BELOW);
|
|
+ final List<FalconSeal> seals = new ArrayList<>();
|
|
+ for (int i = 0; i < 7; i++) {
|
|
+ seals.add(new FalconSeal(i, Bytes.of(0x29, i, 0)));
|
|
+ }
|
|
+ cache.record(BELOW, HASH, 0, seals);
|
|
+ final Map<String, Object> r = call(method(), BELOW);
|
|
+ assertThat(r.get("sealForm")).as("L1: below H_r - 1 the record keeps today's form").isEqualTo("anchor");
|
|
+ assertThat(r).doesNotContainKeys("rounds", "decidedRound", "commitRoundBlock");
|
|
+ assertThat(r.get("finality")).isEqualTo("post-quantum");
|
|
+ }
|
|
+
|
|
+ // ------------------------------------------------------------------------------------------------------------------
|
|
+
|
|
+ private void at(final long n) {
|
|
+ lenient().when(header.getNumber()).thenReturn(n);
|
|
+ when(blockchainQueries.getBlockHeaderByNumber(n)).thenReturn(Optional.of(header));
|
|
+ }
|
|
+
|
|
+ private static Bytes32 message(final int round) {
|
|
+ return Bytes32.leftPad(Bytes.of(0x5e, round));
|
|
+ }
|
|
+
|
|
+ private void hear(final long n, final int round, final int from, final int to) {
|
|
+ final List<FalconSeal> seals = new ArrayList<>();
|
|
+ for (int i = from; i < to; i++) {
|
|
+ seals.add(new FalconSeal(i, Bytes.of(0x29, i, round)));
|
|
+ }
|
|
+ cache.record(n, HASH, round, seals);
|
|
+ }
|
|
+
|
|
+ private AereGetPqFinality method() {
|
|
+ return new AereGetPqFinality(
|
|
+ blockchainQueries,
|
|
+ validatorProvider,
|
|
+ cache,
|
|
+ (n, i, m, s) -> {
|
|
+ verifierCalls.add(new Object[] {n, i, m, s});
|
|
+ // a seal verifies only over the message of the round it was made in (its third byte)
|
|
+ return m.equals(message(s.get(2)));
|
|
+ },
|
|
+ (n, h) -> Optional.of(message(0)),
|
|
+ (n, h, r) -> Optional.of(message(r)),
|
|
+ // index i is member i of the ten; 10 is bound outside the set, 11 is a second index of member 0
|
|
+ (n, i) -> i == 10 ? Address.fromHexString(String.format("0x%040x", 0xEEEE)) : i == 11 ? validators(10).get(0)
|
|
+ : i >= 0 && i < 10 ? validators(10).get(i) : null);
|
|
+ }
|
|
+
|
|
+ private static List<Address> validators(final int n) {
|
|
+ final List<Address> out = new ArrayList<>();
|
|
+ for (int i = 0; i < n; i++) {
|
|
+ out.add(Address.fromHexString(String.format("0x%040x", 0xA000 + i)));
|
|
+ }
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ @SuppressWarnings("unchecked")
|
|
+ private Map<String, Object> call(final AereGetPqFinality method, final long n) {
|
|
+ final JsonRpcRequestContext request =
|
|
+ new JsonRpcRequestContext(new JsonRpcRequest("2.0", method.getName(), new Object[] {"0x" + Long.toHexString(n)}));
|
|
+ final JsonRpcSuccessResponse response = (JsonRpcSuccessResponse) method.response(request);
|
|
+ return (Map<String, Object>) response.getResult();
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/AereGetPqFinalityTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/AereGetPqFinalityTest.java
|
|
index b3b6d95ae9..40365e0d79 100755
|
|
--- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/AereGetPqFinalityTest.java
|
|
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/AereGetPqFinalityTest.java
|
|
@@ -73,41 +73,41 @@ public class AereGetPqFinalityTest {
|
|
}
|
|
|
|
@AfterEach
|
|
public void tearDown() {
|
|
cache.clear();
|
|
}
|
|
|
|
private static List<Address> validators(final int n) {
|
|
final List<Address> out = new ArrayList<>();
|
|
for (int i = 0; i < n; i++) {
|
|
out.add(Address.fromHexString(String.format("0x%040x", 0xA000 + i)));
|
|
}
|
|
return out;
|
|
}
|
|
|
|
private void heard(final int count) {
|
|
final List<FalconSeal> seals = new ArrayList<>();
|
|
for (int i = 0; i < count; i++) {
|
|
seals.add(new FalconSeal(i, Bytes.of(0x29, i, 7, 7, 7)));
|
|
}
|
|
- cache.record(NUMBER, HASH, seals);
|
|
+ cache.record(NUMBER, HASH, 0, seals);
|
|
}
|
|
|
|
private AereGetPqFinality method(final int verifyBelowIndex, final Optional<Bytes> message) {
|
|
return new AereGetPqFinality(
|
|
blockchainQueries,
|
|
validatorProvider,
|
|
cache,
|
|
(n, i, m, s) -> {
|
|
verifierCalls.add(new Object[] {n, i, m, s});
|
|
return i < verifyBelowIndex;
|
|
},
|
|
(n, h) -> message);
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
private Map<String, Object> call(final AereGetPqFinality method, final Object... params) {
|
|
final JsonRpcRequestContext request =
|
|
new JsonRpcRequestContext(new JsonRpcRequest("2.0", method.getName(), params));
|
|
final JsonRpcSuccessResponse response = (JsonRpcSuccessResponse) method.response(request);
|
|
return (Map<String, Object>) response.getResult();
|
|
diff --git a/consensus/qbft/src/test/resources/aere-d412/2800-hibrid-10.properties b/consensus/qbft/src/test/resources/aere-d412/2800-hibrid-10.properties
|
|
new file mode 100644
|
|
index 0000000000..4db607b41f
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/resources/aere-d412/2800-hibrid-10.properties
|
|
@@ -0,0 +1,23 @@
|
|
+formatVersion=hybrid-1
|
|
+chainId=2800
|
|
+count=10
|
|
+0.addr=0x4bf6f91d84b37454544279cba152581ed6820044
|
|
+0.key.slh-dsa-sha2-128s=0x5a223b6ccd6991221265ed715c0d0656a5f14aa3820624d21f044a9fe480f427
|
|
+1.addr=0x5f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb0
|
|
+1.key.slh-dsa-sha2-128s=0x73e76257c40876cd9fa2d08060b1be9a8ed216cee06daa351f35ff6d985c34db
|
|
+2.addr=0x97473985d04723299559f49b856effb47d7abfad
|
|
+2.key.slh-dsa-sha2-128s=0x30faf2e4626a0fffd74369c1c1f1c9ef795526677dc9b1a53807f7d2d255a44a
|
|
+3.addr=0xb5e768cb3117ea25175f51aa956b48691025c2a8
|
|
+3.key.slh-dsa-sha2-128s=0xf04aca3422194bae6cf9cecf8214215f4c72b5728479f4789fc0bf9a47bcefa7
|
|
+4.addr=0xc3314fd768bb68b986e80c0a14175f6f72630d7a
|
|
+4.key.slh-dsa-sha2-128s=0xffc690bb8feb463cc359c0dd64f017f6af77e3fdca17864d562010a1bd058687
|
|
+5.addr=0xe13aa491abbc1252dd714e7ca0e55717a2143eaf
|
|
+5.key.slh-dsa-sha2-128s=0xe4e78e33faf1538665753136783ce1cfcd7ac20d29473b7079905d2859bccf4e
|
|
+6.addr=0xf73bbbd26a82dbc769066550d8d4585eab2fc00d
|
|
+6.key.slh-dsa-sha2-128s=0x4d64e902943d4a78d5dec0ab0f9ab7271ca34b1bb94d84b6e867698b33e03c0f
|
|
+7.addr=0xdf09b32c761620c5be77da398b97a64f03c3980c
|
|
+7.key.slh-dsa-sha2-128s=0x4680b2ae637453f4d28a4092489884f89488fa0df7a95a9f68aa3aaa22112f86
|
|
+8.addr=0x1bd5514286f5602a6762b0075266379d29af1c9d
|
|
+8.key.slh-dsa-sha2-128s=0x9de25aee7a187dc2d82c60792f70b6ad71a90d744f89b0baf70639af4c682a20
|
|
+9.addr=0xd38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa2
|
|
+9.key.slh-dsa-sha2-128s=0xd54598af717e15dd28cda15d7603d9423246c1d97411c0173c3673ecc02f530e
|
|
diff --git a/consensus/qbft/src/test/resources/aere-d412/2800-manifest-13014000.json b/consensus/qbft/src/test/resources/aere-d412/2800-manifest-13014000.json
|
|
new file mode 100644
|
|
index 0000000000..994e7eeaf4
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/resources/aere-d412/2800-manifest-13014000.json
|
|
@@ -0,0 +1,48 @@
|
|
+{
|
|
+ "count": 7,
|
|
+ "formatVersion": "2",
|
|
+ "chainId": "2800",
|
|
+ "bindHeight": "13014000",
|
|
+ "0": {
|
|
+ "addr": "0x4bf6f91d84b37454544279cba152581ed6820044",
|
|
+ "pk": "3b946f7ac3adbb6b49eb1426d60f07725a1b9409d472c9e8ea47a8e4ba38bfc773de905f06c51860d4e83eecf5f5621329634c3d9061816305c1fc89d55ba937f97b6482cd055895c8b4864b549ca4bb197244771d0635828882718142fb6800cbac04bd6005e3ae582f7e3ab704471877faec7aa6e1e96d1912a6e763f74dae69c2ccee323c06e5515fcc6880a2d96935220f50ac5bb02343fd2985a1b3b78f0a8548abd6702adc2e298bc113dd37411454286c29ec5592b963fae4bd7042fa6877e2363fd03c9a95e97da50144f02690d0b97ca332d14f9332edc0b0c5e5b27279569526523034d65b618147d267fdc5a35220091cca00b7456ed9bb1def448f4105bded1e79e1e34a6de8bed08a24383b954d47b3df5d1d8ae8b5e8592a92bc80b4220a7c0bb123cba55ae14371ca1716282276416c82772795ab0191c2562f189700469714ca5500b94beb23ad45a41ddef1184eda4d06f4286da21c0fdcb450e760d84401968a4e0fd19dc49bb1fa0bd79be005d781a4f19d5c40e71a4e6ab3ccf4413bd7f922799d28554f19609d7e4746e6519c8d029a1a1a548d369498feef77438051dbc2e024ac08220934dd42264acc038beebb5314f198589b211a81d8f1ef97e41af8d9b0de9fcc7b645cd80fc72c8c255e34495c51a060628205d48a11f9992b3865d59e692879a9ea9c6af9b831986e852c2583f35b1ef9aa55d41b1d18dd7162aab0ff4931476092f9d7e2f078f44ea2d0da699d362b8a0de3f140640826788faf7c7d4c0aee4b88a14cde9300a7253ac6c9b8de188515720f130a94673465e0f1e84a501b6c390b2ae84ba44a449320de37b26520e12988a11911465afdd2fc9b161965d3ccc15a0559930810104a6e40d17f629cacb8fb3973af0967c679a7d8c93b8aa833a28d6ae975913d0096a1416d79779c00052b2f19f479251a76264084552e99a76d42cc8572dd2573de7497472bc096e29cd7b81a2c1e8c20688e84245a46e159080bc976d98581b7a1023f94a5947cd244ad487b0193a62cb799afd30a8bfebb6a23ead4da7d2c7993919913583deef2311da82a924594d11f1e337b1ebd4364405c0cc88f57254261441d7a0b416492af894a9920e2c34cddcae506e16581b977e978150402663246b709bf9a4a0264050c4c972d86258d40eb8a046755ab187663109ad0aeab371f798b503c2ae73da67c5b8069dbaf06c0b6af28e0007dc22a766fdc3e1a87439258e65a701d8098d474",
|
|
+ "pop": "391116f21d1c25632456dc07484168b582e8404245936ff15409b34fcbce6b80c17c229d64c444d05b117eedd10408a7549e06cb505ae75026bf85f4bcd1b9450b98a0f19c62046b8cfcfa129ec55a2860481842a1b35dff45ef49b4747129690bdcfc3046a745a4e7679def13b50fe499375e093952a01a818f4193e757f512a2434ed76b68ba6a2d26d1b4891062b5915ab46ece68ec1a95216aa1e848ae260694a779e7a8c2f8677f9b5a2d14c28d7472e39b988f0b0b986c95180bbdbb9ab5c419084ebdf77ff32d058be7e20d9bccbcd410741539b744d158746d85b546fe58618640d18e1959e32c0e1bcb31588cfe7749855da0e98f6af3a4fd5291169a14b39e0d36818821590a2a62c0cbcb64553bb1fc3d908b5d67fdce94957d174d21d21ca8ec526ace28a6f90163b094edbd0676bfc4ca4c9b90dadf123f3c83c73f91edbac73197a329e9395db561d0d685ca98e72eadcb5fa28448a73a1fd5474be8c3949d9556c18aa2395cc5534ec3f3cb86fcdf49f11076d52435f5b6699aa86bd45695416e64f56e36783b3d7937d1a06626884a2f44241a94a76eb8eb9764b8abf02629121936276ba938703ddb67a74d0a468b452a6678146f228b9ad2b58c4370cd4de9fcb9366e2f20a61cf72e67132dace761356d7f583da14844141afb2ed0a10c448e098cb961d60afa6d299bb81942f8e6f27556bd66dfdf0db194247ca6bee40baacf634d92cf6c2f4686dd5a84308b863616f7c4caf41d0b815da5092d7b1f20cf8f66c62ab7e9158eb5d3d8cd217b4a9b19356850e41263e8ef2dd88d6c54b5ead803432ca94206de0b7f68c90b0c9df7744f1e30c4160c08e1e9a899f279c4c9436b52d6279b5c4a983a5a536d9cf5bd177467e28026cf677a11e1f46e6db218eccd9f57dde8",
|
|
+ "claim": "2a3a676d7e9f0cf99770e9b42923b7e4d64244b015cf166df453a8b1e07a01e14eeba6397d2d8e83071775b42631d4e9d205a0d49e0344fd3ed4cf33ee31217501"
|
|
+ },
|
|
+ "1": {
|
|
+ "addr": "0x5f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb0",
|
|
+ "pk": "1125a8c8ceab68078dadd35101e64ac8fff297aec01181732a50ed24098c5106cc1acebc7ab349380a595c7207f93e8cc96aec66e74a5ad73c0d9658e450776448d8b7f6901e8799525b6bafdc0401bda562c5a42e7e66f67ba1645c70f9473769ec01d01239f9d26b6134abe28fd2cc361852138c657455657bba806c37a1eca1b5ef42f4a498a987b7614f41a99752be9e640804d4fb74db16be5e9b3b101f20b37264a31b5efe4b5d2388cc92dab1c82218e24de139ea69e51b9d7f5e190691e6d20626806686939b7d2e593409532d4c465af2b5c8848f298ea7601fdddf2f5c2420b7e02f8bac6273da2b2c91b24e4329dc1c42640b00455ddd4c040b9accd0a90d993062de6e1f82618d523ac0d5b80d407689cdf05c100a758702f60e395df0525a7d0421b1e2bc60c612b89b945765f0b251adc824d9a6a7c4ff48761f36350de36bc7de94900ce4e91486424d1a1901c45abaa1188acb4e45f4bf61753b41287e73ea33213c153b661032e1e158db1d12d5532a0387870ec896e5267e6d290d53850cbe3e4d12ab5f0ef223b6e307c34c9285c122f75090439d152d466f49012bf9135860468886c954a574212d438c99013a878e9295b44686187b92783ef22c53aa95e2ac84d143a1b20e1ef74fc5ac39f2e03566871a42e67b340455da2922ebd9e4400b17a4f1965764039bd864e278d7b5a5a1ab600ea6edb0512a932acc47186db7f0cc5d429e984ec1b4af06747e1e09374d372d65b9c9c9540731d6e5e9f54005011570d3525eabb3c0c6056aa3522b9d3246f818834fa18cdb069807270ee3e6b30e945d0d9009444b303a50f7313d800f11020d49b80d27696a3519e1145b62f678d0206dc6be78cd321459dba0f444e96ea529be49b0d864d56ea2368b60661bc259184154722c1332de5593a5e29235569936210ca761cd9518de96855c328a517c8f4a6a3cbb75ac1f0a6834e9e6ff4d426d22b547ecc88e1ab45d3678481585e1ecba71a54421c0fd83dccc39ad0e4764366e740a482ae8ee05f22f541ac79c48c57eda102288836b3b6242334e96ed85ca3790d3e40ebc859778b844503c5c8a97980ee347294bd9606f226831db0aa40250bdb073312baaa92a86a31770469b7fe041e33f85a40a34f1071aa3ad4af426619fda690e6e60a3b8534c63e080438a123f97fab6f0b66c677de4ed35b65db81fca0521dc99b20e5474466412ca5151f6497893988970d3684f90d95b8283e8d040a5",
|
|
+ "pop": "39f5000f94992d07037c37b518e89cec504a9e67255380bae96fbadea56523ee3e09d98702d629d6d76945921801e63ee50d514aa1dbb81c065c9c409356d216942b1ddcf486a66d354aed7721fcf3de3312bd4c0be7144a73673574b8b0b11479a3c19984558ecc9b36ecac270791ae6d93279a429d5da76e35253941d5ae0c19c1ceb4283366d45ae93d920f3df5b916477b7f922f3c7b1288dac5e832e9035befb6a00aacd6238cb3ba0dd75f29c64a4db221b593e051ba7e5f788164e29bfb19d88be9135d966f050b71a854bd1a1d83ab304eaec12f7092220b4a287999379ebbd28ca10c122ad525b5e952d85ea7723779d087ca94346dc452124ecb78f7b1f25ecc510a47d32abd53ed7ce05427c308dcfaf7e6e2ffb6c6f09019032cba5539f1e23da526e3051e5a50568b5323a56f2c5cb39d5a41ab6ecdd725e5450f4fd30bc89cbab506015e61a7261eeba0731c8bd93c668308b742a1c75670f6c1310c4217b97c5350b5e711254f112dc6bb4558b34014a6757dc89bf9c44a371edba3b78b059f53a4a2cc5a44eb3f54ea161a9be11ee73d3a54059891a776845ed518d470358df661944b1c9787c1ac20aaffb2b71c7b2518547ecac6687148d34ab4b05cff5f8f7a4487c3655d451749c766ffb2fa5fe9ab86ef42a461b18213cfa3fffecbca15911b081a790253e41aad5c54bd31a4efcb12f660130582deef3ae53f64f955a688395ef8a1d82d634daa593c0c734d203a98aca4f14c8351b9297354bff45686ec54d0358a43dacdf3c9077eb0c9e1abba02828ea52d92a8a8458e4d05085214866d22605a24c05b2e2a8c29108861ecd33c01f08d1e78eb132511e9ab14c56914c9618e5e1eca4648df334961ea8f067c8c40ea5b6a7d4c8f2b2e535e8da19796262997ffdbde78",
|
|
+ "claim": "0af001cacd0d40b367c39c151b2d205d230b9fbaff7c6440a185e915d7e050947509b0a987d3114b09d7122945cfd0010ca34473199eae0289b6fa0e1f3ecfc901"
|
|
+ },
|
|
+ "2": {
|
|
+ "addr": "0x97473985d04723299559f49b856effb47d7abfad",
|
|
+ "pk": "8cf6831a6196601d69c0db2725e6b0c2ddf4179d8c2eed5bc1e46528a7f9cd046199a53e8e6c127d6dbc35d1a0d0450f6f660dd0a22debe45654788a5b8ec849aafcb2a0ed8345bae07a262769b1a8ee57ac92f496b8ad4082ea0d8f7cdbb9a52040b59dd0f69a9206bd9e48aa41d1852c217cb885a4238e6234b5bd2ee5771a3eb2e70010056438744fd85b4a74d5f080256d65789967c0e0c835a12a36f7e12c32f42107514374220d3a19fd9bf6570c6a53596cfc035024bb9fd1aa67182060f2e8c115a66376d445d840b92b44105d376af967528561cdb18d9492d15c6d7dc2562b310fca6cd1d7da395fb6684467b5451afd1a485aab16af8540247df46be18a78d9840526e7b84bb48c45fe8bbe2f8a43149c04403326ae48b99e684d1d30201fe904226cc3c453dbf407ca84344e882f47c1d32b93597f958c1642d39b23402d8ec498a529534eabf50365f4845e68b34d89d8910c5024dac2208e8610e5aa536a0048d0c62b5364233e96b690124dbdca104adfe8217e3472127c15a8a0ee55a99a29af316ee18460e9440f6192664fe0a36b191d5048eded163ef0e0b32a1b81767672bf13d6b881ad6833500c2418d2f65c530b100689b5f368956a92175425cdb0b2fdcd0346c73f148545d463c99128a859e64f0028447286e7965b58374023b94804bf26a56b88b55feb0b0de8243cd3c1aad0b12affd69a9661829bbbc823264edb8084ea4a71212cc34209af973efb92d0d591838695b91b44da5a88a71a1b0b2c583951584a13c872b007167edaac130aa9fb2386a66f7c83a887af6a7100e9c80e2770bd4d9a535ac7c40b78ffbb148bdead7a6631824bff5da6d781a50310bd827cf0345d8c2d15060995824f98ca752154da4441f17e0739999854eaa6474067ceb026fe705aacfe0c1cb23a192f4d38404b7651a9d416b139a4ba0e7191289999fb41127e2937997fe39f83a090a1d15fb27e689ab7fa9254b79d0321966cd4253c50c197886a7f35209421038d81bc8b66d124066f78ac80936dad17c0cd653244e80771abe442d2f0905da80ad50a3a994cfd282cd7b727097fa444aa384e090668ff174b86e8b072b0c938bbbd9f416b0d9f1a742421a7443eab4a0d66298764016168f5630f2f840a3744d4dce2af0c41f094a3ff6bb57c6af71c03a255939be159379c66fb0bda9a5bb47ee375aa6f9943447ee2cb1b916c0458bbdbc4dca2497c166e586c70b9d47a53ca74a5793537430dc7",
|
|
+ "pop": "39e2035ce0cd76c333e8583aaad397344cc4566aaaf5a708e509042738fcd97041b98f323319d164c600c6f177de968cd1272671c1dd9b434efd6fb8f894c91f4a312543b78a431f9b6439d628dc1a024f5fea521f9b124b50e05b21bd62219cce1e1f7630d4d31ac8eb7fcb7fa8fd49a2648021b4584395474f99766bf2d3b812d26fe45d23a44102766c3483bf6191b2e55539c5dcb0c479747e9246998b489cd6858d254b1a725e1d0823e396aa3c12d9925f3b6c55357d8662d824a85af3aceb05549e23112c3ce35ee833da7cbe7fe3834ed068545108c18abc269ea6e8d504315fd06a26ca1eed458110c2e7b00f9b491ce9c2f9302cb44af34eb83a1f747d4e7f19dcebfed8a449a65945c17cb6ba0778f5c6dc0d153919583332c8a42ca6f5de56ff81509b359134a22e6b9a07290879930f1b9d7c9bd6d6550cd1fb193fed7ea246707f1ea7ceb9af9bf4a5c4ddc1d3bf084247aadef35c9b1495d7c6d86e4c1319b7cc3bdd2d9c5cbdecb64ac5c7edb156530519baada04692a06beb397a41297df5de4b42418ba93a1cbcdc525cc9dd30747bdea941dd61bd7cfb879e819ba3c5ab3af35d15ccf729988c7528c36258d389ad6bb7293e44d39a5ae108e4ce2486206625c3d3bce12f9cb4e4d6c978baf7c1eb2ac96f4b9fed43680cae0c4f71cbbae8f5f109bb70a308b9052831a51746f4bb359e531cfc37f4244a878f7bd0135b9a30ea2642a5585272143601f8f23e16c6e68a9c89fe8f7ba2546b3a967e8948b2b0eb13196d9db1c4c31f0e6b9e6c28d130e904895a8463b4cbc3aafb9ec7b367e8577f94edcbc472da0553058374f00c9a4bef7633555ed93ddbc0ee9074d29175cdb73c7d16a59cb47ebb85d775b1fde962e154b0d5184ebae65e98a6812b72150727f5c75a5324",
|
|
+ "claim": "c6cd8cb888cce26c8f4726270be52138430a4a1583972509ec8980105bfe604a55469ddee595607faa64391f0c7348a5fe5effec367870697e5f101589f8131601"
|
|
+ },
|
|
+ "3": {
|
|
+ "addr": "0xb5e768cb3117ea25175f51aa956b48691025c2a8",
|
|
+ "pk": "b991d68a909506b5ec27a59c86a2b0b815f1fc8d60a9224f75f40b8b4fd0a73885821d9982e7f829dbf24a824b1a85292145807041d10005944d107b70cf9636a15765096ed8a5320797415fc709456a85bb47037279d692bcefee14ca4284b9495e0eb80353461c10304d8ac592d665aea90f30b2ca0331e84b0139a4c98e3e47bb48d616198ea14b8b2dfd77453b4065c33a2d4daa44976ecc4d440b772f43700e341c22e146026e75de104be7fdbe4d95a52cd40997eda2a0092a299b44d4274ceff272c05abb0bc59607249be4a58a0093f2fa34c14957250d5bc4ed23339d3a2d0750a77e14e8d107324ed12938c592071335bcc165ea62009145885bca6e2a6937ec815af86c670d2abb119488e2056689090623578b9ec28108654c93806ee0d664e2b7c53146fd981b65b177e8de61fd8f3a47987e6ae66221241a68e64534ca22351c8990641210851fe997b669f848a891337bfeb0faa42e88bc406741cd943685512ef7bfc65440e86340dd96b57408cec4d1648550129fe838e201a86164b081055926b6fae0b6e5f65a65eef5061d6d40681c648c9aad426927134bcb2e38ac7b63e2120a97b21007d553db0dc64be0b2ca1a2c6449c6f9873496b49973af9ca1514e3217fb0608aa3d82246f55dd6504a8c8ae0ad1a634d54bc1c1f0bdd008332817f25ddd700244d68c0b6a8f480cdf90ae1ef1a3a619961bf67c7208697151c2af54fad43471de38739cd6c4067a056587542782a422325a174db998c552d5c48095a0ad555d8b784d32c3645ac4d099165071d662ec365587d954e7128db6cedbc3172621d58c1b242d4a202841374c126c2e80a8830d570301717936b2c328ac7ec61379a7bf1b06be385162ae0c8139d25b010bbe166f1899299862acc316ba59a6313a6bc6a10f590248b2575e243f66be6d62b851bd685413535894e2ab09f2519290bc3f701d52e2518276621df409172f3695e628580432ba096327ce4efb170ead3701c899a7e84f00ac926e21564cf0a78eb662f5df31c2c57540423039b12f402ea20135a62d3c4d90fac5ad8096bf7ec667e919a006ba518a49187744122f783d12ce69a1bcdbbcc486b4e9d2f81c6bd09839a5902e575aba9ec4c81629e6b3e480d74f81aa245c546185542d8a2c1c39942a6e1c6a32f94a8d201eb85b6230e9dd16cd03827eedda829e8f35e6049e9725fce18066a77dae2456c62c82790629494b699a8d648a853eea8d322dd869005025",
|
|
+ "pop": "3901b22ed9771f20c0b0828c879b5416bc214762fb8e3b25ab145898fa86c5a5e44ff04e59189a3b1e979619281f050e6f8d434872250a0af1313252b613f89fa21ddc9ef73c9eb3b8ac64db2989256b0d25a66a5503e2a6ddb34a156519afba73091e14de350d0147b16939538eccbb42f86499c3ab1f87563fd75cf4344de505d25042c4ad0c615152e2feb3041725799d7438c41a3b23cda81b4c1da3db8c29875f7d30cf4ee006dd62b4af44776f85ccdc718adb7d58565fd4e6f8ec6bc61ddce2aeba19971122c21a92b9c4476d0f3f01b9e697c32ec93315847ab5f0c7a9ad1c45c26a139cedd1d69743ab6aaf86c7c8c412a7e3d685f71cf204f2ae505e12deac2dd219bf4d8c1ab5e1b44326abacb0a0d6acba1f2a079a90fbc9f1e957564d53450766c75c8f954cbb379c27269e3b719bc112029f7eb76e2abee4f90a39e98e1cd13169f4299d35667a2ac8240e8631cc5f9cbc8101fe40ba919e314ff047ae0d3e1cb2c861d0f427a8c94d4c679696bb2f85c27f7a8ce72babdc5a08ebe11c3e5e99c8a152e30e948b18a847a2582f564e3c5469e8fae986e72658397b78bfc4e7192d4116cb44d908eeaf755388780912090e290dbb74c2761b554d1da3d77c12c839166d8832c53b9855ca9da086a315bf2482fdb7df4b9d29cb5fa2d52909d7751c8fb458684915ce7335ce93bb4794b0492efddc33566c470a353f85cde5e5fd505e2f75edac69b9789bd21c43a033c35bc3e02ce6df20a045252c8c2e5752d8c46ed26c7a3648dc5d6e0e3e853d57e7e5a47efcd54dd7e581f9530948a3cd2d709425216f5be49e5ea71c7dcc66eb4db86e4ec40a4442dbd69e12fe663e0e9b004a5bd70f0ae14c4ced9c89d7208648a161469342dd62a8eea47666f3229916e968c8189479e4a0a204",
|
|
+ "claim": "7520fa7a23d424aa47c467adf4c55725a3a64209b206f67000e73ca069819d1b5aae39f959584134d6ef8ee85bcb7f143007cc83e9f4fb0f186be99d0d65a12f00"
|
|
+ },
|
|
+ "4": {
|
|
+ "addr": "0xc3314fd768bb68b986e80c0a14175f6f72630d7a",
|
|
+ "pk": "6e9ada38d7da61bb7062c6812dba3954f433ad08157ce4e9d340c3bb80d6b9b1d1027cbfe1514b2a9e5266da4757f9536a3efccfe15255baa4f48fd442d9c2731d8c63a29f936c1a6908f96fdd393dcda5ad19b81b1ca5c4472cfca358bf1566eecd9e3082dac612c158cc3788681f5f0868ec68a06cb04621465a4fca948f7e118352813e5d2138366c97296dc15649c99394b1bdd0e7969f913c255d694a989d75b6499a7c19bb1ce46f313e6a2fb6f4faa7ba63e4814e3348f7ee68bef4b823486dd6baf6f5b847a48b78bc1003bb125d3b26aaa9694a026c75da351064ff868061a78543677db940eb33a4636baa3e756948d61845dc43c04595427a6e9568a216b50eeea2428d82887931632a5a1d33803b392ed142bbd5cea9f619ce563a3c7b35d2f0a7709ed1e20edf0754f3f60aec60b329c0f51b2ecea714d079d2d4ed5f58a737feabee9c26a0320157147a3295a0eb00399eec3bb82d0a33a9e18789496f4e4d6dd6f29f106eab227336b49f688f95b33398c5489f5c32033cab2176749445c208500778e3955bafb2521628740896a9525d85d61aa2220379f8bbe8a16c44b45652d9ae7b2bfd3664a2a64133edae4b4edc930c64e6d99f97d707fcca1242467c9d0c71c441e59073e0d879e3af0529fdaf99eecc7c5219ec66d2c61c8294bd90dd53a21ffc0b230c6f6a89142336478c1179d6ecd91881d85e1e6535c1692979f217883feafc45b9a539834f0b9d74554901a8b83835c983fc43fe41141281c5234f02d50ea5f7a774a5d4dd9b8aabe902d2d0659bd1773bb62a5b1750a75f24ae7ae492cf2a5469563ad5062b4592037401ac334d8f6b2beb46a8aee678c11e98503e0be846dc5992e43b2019085e2872baa217547855e2d5b9984073b020b5224b577352c1a4bb900d8f5fd974c2c027cd633ec0c08ccae82134453b720a67b78e5d01f617343d81fa0864d6b0b1be09d35f1d707b688d134c4b82af9eaeb8908f40b259a8334c04a5223074638a82046cfaeba392c21f58f0be565492958f6282baf64d98a0d6af810490705136d1d1fc16e43b4668c9cb4fbfbf58d943ce5de56fbc5e44a684990b7df050981e559dd9d34a3fc4962b1282a15e63ac0e85d8d5794cf15a94c9409be98e9652e59176689d153214f2c6d011aa41f5709e536e267a9c897a10dc61081e012c51a2467464023c1dd870091db16b54665070a4db581cca14bd3843c3d42e907ef1f7c053d0a535a4d4f92752",
|
|
+ "pop": "392621a1e2bb24f4a12c64e2b2335e1e18b8ade582d7d1e4005fdf355e105460dd837b7a6c5f51088a9940f0368be61b35064616fea62a4deffd3f79d6b8ab20fbb2e1ed88acd794f4ee4a31752ae71708ca3c8d746af586092c72c537e078246d7eaad0cf121376689c749cfec403188ce2b9bda552652459936f04a5c4aae608ce3e68bc377f77371794a0c790ba1e7f49539a9f6397d93b262489bc7718245510b1552f16fb3ea95d943fdc5926d614e173b965c6a35f19f45322e039e790c0c0e55ead714dba312d22b19e46aa8c159b5b2adaf891fcbad7babec30661107173eb552cba31ad7c8104c7a519835f73fdc657a725533b7ec986304e2cffb7425dc04cf92ed0a2e7ad9ffb44695183612f9256fdbea092e56ac1fd60a1967d6afb05fdb6ad5992549c1443d1084a50bbeb47f59fc4c8e9c0ab110e7b3dbdeed9748ed3d679599ca387b2f620939e0398c9895dee21ab47d0cc3dc73e637d786a3adbc8991de5cb577990f11af48a0754b6a635c9a910afa1be52a25ba08e014cc870623e19d97db0bf4c623c70875f28d93730b2006d598d4f04dafb71ff443df89ba1abdc4f64600f8ae93a494ec664ef2e70aa4b7f9cb1f2593af373c056fa5c8bb4b70784c5426448645dab67bdca57330ed82bf503e2c8cfd1e2c7f76bb0980104487b35f571e55bf73993b8500a321053743759142133bb71f84ac2c59ef666384f4262de5f7c537eb27dd4e746ed9f146e695fadc82c0a638b0b7daa69bbace33312b588639672e6d8febc8a258f3ab321068337e7e6681a34c4bee35fc8f193d2dd34c50b797142a2cb7ec94353a108efe7b3727c2791e7c8b876ba1332958d53d16481ece11b35c3f9d2f1f1b00dce0cc74a566204c79c52e39c4d31703b299ce74d38d2fcdc3a324c0659",
|
|
+ "claim": "9cf806af0ec3d002e2023064b245a9c77b84a1d1d5e2fbf69eb0353ab48a432f0d6554a4cbab6ed3e715164e33791cf5305cb2010bd85e66991444fe2d11232101"
|
|
+ },
|
|
+ "5": {
|
|
+ "addr": "0xe13aa491abbc1252dd714e7ca0e55717a2143eaf",
|
|
+ "pk": "a2b859c229911277f188666a63981fc25ea2b38df500cc8851ccee2f467d0fb1f8aaf84f9e757b7b5db61479c1a6a196677ff6d46779ef8d910a78604f04d8591c5de80ad1c32422ccbb3bc71914cd159001a2c78a9a00480fda69321a6ef54104bd0d1a1b8764d537b5909c107dde111786d5c6b943f52a06bebae81ed7168066aa0723ed5de103d0880994341828d3bbc78546b5e602cd842baeb162c8c099bf1112bff3f3ccaea4cec0ab5b4cc276a81351cc692d463cb6e1c4573036f1d07adad56f0210ee755c474614cd7ac618afa673197716ce24cb041225e4c72062873c8da49d13d11b70e05a71a35b384a90e95290735d9cf1ba9d0eb0abc5aabb728ad13d6cfa3ac2819411684629ff07db9306d6f5c52ac680ba31a2e1e41b1cf0f1b6d190ed3ad00470cbaeff956e7da446016360b515d2da9dad49f26a274957e45a6948843b0ea49c7995403667885a86f6f116e52eb7701615b75dc75801f5a5855c5e1b262746ed991aaeca6f3b9b59ab0406baa1e74a33617dfb6b54afb796c1d2299be9aa68b9bbd71c212f23909466471f8b04a5801408929474ce5304cd87801d01e1e8ff1d2b0842f727bfc3611138a3431e12867bcc000147238d659c7e241703444c26eaa6a161883a91e4e0afdaf39cc57d38615fccb1edf56a2adf1e401df1d5100467ac261772d695f29be1b3113a2a6f8e48f1b47380b97651a852b2c5da942a3ce92d17db15a669a4eaad2f116a25c4beaf1f9d72bfe1d665411c28041761d0960f5d3995e86fa15906195b2a1d163dae8e750b1a5c06b5fb32092b0ea47501da5e6d9a5941d82b5704299ff56e49299ec82c62fee9828ae56bdd2a90eadcdb94fcf2963d02349909dcf27e02224120d6b66747dbafec302bbc6b166e5eb3692b55a35495b15af063bb746d8c99c5c81719d42efb8d851537f875f6deab96b5860f26d6d0b036aa62d8f744692f256093f61f9e2e669f87feda1b60ded5d0574c521860665472ea9d44b1ba317d12e7b5480aa449c6d55f70d7a4341c22560a037b30df071f36573793efd2b098a6138cd74265e0493b71a228463c00a0260e0cbddc7905795261980edafbd3d30a0102ed9bd9e99630116341ef583f387e9ec5f9a6ba035e33d6b6c96faa9e27f6420a952496b540badfed26ceead61d590a5eba9f329ca9a5a0d562f4d0137f643128e6ee270e175c0ee0f5e68c03cc05338f2dc481723857fdc42d9134b908ae43367fb2601355a326",
|
|
+ "pop": "39ace3d53e6e33b8523abf6d522515bdae29a971d44d2a7a21f4ea0d9494eca5ccec4c92988b8d77636bd5bba397e64c704a9bab445c5b141508dc6ceb30ff967f74b96a244fa13c432d1f7247e63cf17719e7731de904393e45d7fb6700591de6fe9e99e9326809c393306361f4b3c806663337e11c3f3d751b51a9db171f7334189feae7c02c0b090965f576dd9d108274a10a6134c76fa44a2e1b191f475a8d24e7225063c7218ccd674d2433c372f771b867611d329bdd3b829f2a7c5895b568acb4cf3e9e7d4192c431acdf1713e69f962c9b00d0aefec906bf43753071affa6cc022e841d1afac056da74c22bd18ecb12fe96f943d3cf1f4acb61de43e41089632e9b45d60609a358229d7dab4b4bcdb0570418a8f1a3dc8cb7ea6162db2b17ad0deca36a18f94a099352559e68b3d6246956a99aa8bd4eba13fbf3e1696ab9956116b65f066222d49aaece015afae6f7eb66e3349fa048b9dfbea34b75357db7a6b3f21ae07ae0899a0b1bd5fada38cbdc91c36ce230d07cb0eb1c6524d342340a4b58ba7a5c1bee2859e307998147a8d9afeff6d15ea65e2f6c4c9b63278f51ba7d6f8a16eaa73f9a5b7db9e4c8214270c9109657f5d9d7d0fb4ced4c81287c74c9d1f1af978cfa5598d8db55b201f86b5ac3979f6405d04c697bb2ea91246f920ae2607bd844512c3a988829f43370de1597dcc21a8df355235aa2ac09c5ca330c61dd4f31e18261daa88b330fc5a479daacefbb93c03d982f6363a6396fa407b8efe5d3c7238c84cccdee5e6f8f503090e578d0d8d0e4e50f95acf28b1182cfb4c9773654dc9914706c19977135631c589ceae237d9b20d9c6254ce8902a8372e3c3d55a140b53af8053f5ff7c319a24cce917cee66ea6751612fa663f0b2972d179fc1fa6d0b44b0b34e020",
|
|
+ "claim": "a2b999cf24a5bd218daa1a606b1acce6835cec77e673222220ecb83c09d734bc236b7c3057d313bf834370300afbebb41aa5424c316b21e27612e158b7ea022a01"
|
|
+ },
|
|
+ "6": {
|
|
+ "addr": "0xf73bbbd26a82dbc769066550d8d4585eab2fc00d",
|
|
+ "pk": "ae79ca93fae11c333ca673090a4b548553614bc1ce7f6aa2773e17b972caf48a07efb416581422605f12400494db84accd432c148168db7794ecff419e83d4738d98f6b0de8f0d742902359aed104a1582cb8ef976965502c28bf4466efdd9ae0350021542a563c9ad2c22b7b0da1f5cb832c5a54d58284ed0f172091dee7be8f94bbae38a4ec0a7c1dca67ca50de962ca09ecae9a66d227841b2c66cb8600a1f01fe2d48be3c64999d1f8236762983a80c3a58fedaa0bd09e3912223b4415cde3fe63d70a62acb564cae57b3ab760780ff26c422d6675920eac389b91659aa3738a5055a76a9046f443ca1c101da8fcca37fe0be18fc9c6851706367cb65f035615d3150acbb738c66eb6eacd7b9a1b03b06e4f046f8615754d85e69d262d8674e8e82052bdbf753591474488488c714a066592718dbfe08d0b91bf387d2b9ee6a86bd0bdf96082fa523e5b6851c27723b99af0aa0722b185d52440c9c82a2a61d6729ec27999f9019f071e9852e813c0ab9318e2cc791a6e7203c27ad48a68ed1385319985aace0112e17999c80662b12a135b5e1a2c9067d5e06d0b33f5a691b65e2181b8b7f389a364543a058268a97c20928b490ceffe1520fa52d143a495941996b527712beecb17786f982425a8ea6cea000f191226855eca65f069782bd777baf11ac781a5b77492e2b69c039903c991259b92a93d18fe6ac74e064370f3dbbbc5ad82b478648ccff8ab45d133b1853a1d21d2e7d525027b2d9740bc82fa16201fb16318da37ec6494c9ddd1af864ef8b50b266f1227134a99c40d8571879b8a660964f6217ca41c6c0435056e5aafb494f4763984a55b196ba4e6691c57a66ec82b886e3e9da601acd9a2ac3584975255ae13c2781abb2a089e423c36cea35126fca8728a82a9bb8dfbf1ed0795a46a83c22945b08f6c7048e3d5f3bc7874164ca39b05ea81d9f75e778cea8b01b1c19a8a5e89991419cea779aa49ae6d562d38be70784def475ca78a3ee40e86de917557d716b008a0819410625ba6d3603b53ce821d1cbc0009dc4d518e025c246e5b6904196e22667a9df22192d22195ccb2694e0cba7fd011553081520d24f53344d5da90299c150b968f7412d51a638bb853d52065e49ae471b5cd979b11953eed2ea89c2d1366a48a664502a96dbad1d8e527d2064d5885cd510898880110cfc7ec002de2029e02516682b953a88fa72b00c55632415e9b52eae8640d866d4074880443ac6f791270a208d2",
|
|
+ "pop": "39a25eeb486016683ed131f7bb6601c5382d88ba69ff982d0d9b5283f753d6dac3b905a443828b414743d25461c8a6d969cac62b8b0452e9b4a8e1b0f5fc3e8ea6cca853999bb4754877714a484a1c4189de5e303f12a72283ef954e11be46f61693f551b7507f18ecb19f6a73d0d77b54de4d357337a21f4380792384d1261cf4b71bd6668685f4515daca6e49836283659204c6e9085f7b93dca234a892699f21f44d6fdfad5d81aee142689217c99ef5edd42957a70c77dda7f6591ad2de937836b61d4bc631b42c090e2aec11fcc51f0f226ae79bd529291d2aee52227e226a05a3f307618401f2598a0ccfd1c496305b9bc366db2637e6a76e86b52f3c19b179f30d694c9a697692a904509daa8adc418a2f345a54392beea878c6c330f945f70a4313b69d22ed62d931294781e57bf1500a1e05e7f7634f0289bd4f165329724b338c570b2a7b1d6fd8866e643097d94445aad0e4ac42214b92d3b9a2b356530a62916f3a2c6995b64da3f6ff6879850b9e2d9bae15c30a8a2931fddaab589aa9b607f505fcee713955930e64ece44ddeef6e5488cbccf41b8bd64bd4d12113587e7d3184185a32ad4dc2f4b0e7d50ece40090e4759d4a40907772fdecbb3ac799e53db1b3cbe51cf21ee491c48a1bc8e166ab0793db8a4458fc98e9ea1a27ef80ae6063cbc73f17a332e46d208edc3aba796b893da849f24ccf691394c970464e0e388c12a912471ab3896751ffbb6a9945e43e8c554b4ba64bf672dd02e497c57f91556fba62aa89652d7065e64b4c3e1b914ece5c49a55af2b00a9e84d476bcbcac155a6883db6b694bcd4d7dbb4c8aadee3b63d3726bd8d474b4cf6ad01426408619d435ce2ed0a846ccd73b68ecaa8374983f184f429883bad814e0a825f0e9bc5141d9491198210e6aa0",
|
|
+ "claim": "544c3943786f34719faee1a3a5253af26a6c746b643a546dd625fabc8dad992b61dc05d59d72e581bef313be7843c919acee98a383f61305d0bae30f6574c53700"
|
|
+ }
|
|
+}
|
|
\ No newline at end of file
|
|
diff --git a/consensus/qbft/src/test/resources/aere-d412/2800-manifest-18082816.json b/consensus/qbft/src/test/resources/aere-d412/2800-manifest-18082816.json
|
|
new file mode 100644
|
|
index 0000000000..ae1d3dc921
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/resources/aere-d412/2800-manifest-18082816.json
|
|
@@ -0,0 +1,66 @@
|
|
+{
|
|
+ "count": 10,
|
|
+ "formatVersion": "2",
|
|
+ "chainId": "2800",
|
|
+ "bindHeight": "18082816",
|
|
+ "0": {
|
|
+ "addr": "0x4bf6f91d84b37454544279cba152581ed6820044",
|
|
+ "pk": "3b946f7ac3adbb6b49eb1426d60f07725a1b9409d472c9e8ea47a8e4ba38bfc773de905f06c51860d4e83eecf5f5621329634c3d9061816305c1fc89d55ba937f97b6482cd055895c8b4864b549ca4bb197244771d0635828882718142fb6800cbac04bd6005e3ae582f7e3ab704471877faec7aa6e1e96d1912a6e763f74dae69c2ccee323c06e5515fcc6880a2d96935220f50ac5bb02343fd2985a1b3b78f0a8548abd6702adc2e298bc113dd37411454286c29ec5592b963fae4bd7042fa6877e2363fd03c9a95e97da50144f02690d0b97ca332d14f9332edc0b0c5e5b27279569526523034d65b618147d267fdc5a35220091cca00b7456ed9bb1def448f4105bded1e79e1e34a6de8bed08a24383b954d47b3df5d1d8ae8b5e8592a92bc80b4220a7c0bb123cba55ae14371ca1716282276416c82772795ab0191c2562f189700469714ca5500b94beb23ad45a41ddef1184eda4d06f4286da21c0fdcb450e760d84401968a4e0fd19dc49bb1fa0bd79be005d781a4f19d5c40e71a4e6ab3ccf4413bd7f922799d28554f19609d7e4746e6519c8d029a1a1a548d369498feef77438051dbc2e024ac08220934dd42264acc038beebb5314f198589b211a81d8f1ef97e41af8d9b0de9fcc7b645cd80fc72c8c255e34495c51a060628205d48a11f9992b3865d59e692879a9ea9c6af9b831986e852c2583f35b1ef9aa55d41b1d18dd7162aab0ff4931476092f9d7e2f078f44ea2d0da699d362b8a0de3f140640826788faf7c7d4c0aee4b88a14cde9300a7253ac6c9b8de188515720f130a94673465e0f1e84a501b6c390b2ae84ba44a449320de37b26520e12988a11911465afdd2fc9b161965d3ccc15a0559930810104a6e40d17f629cacb8fb3973af0967c679a7d8c93b8aa833a28d6ae975913d0096a1416d79779c00052b2f19f479251a76264084552e99a76d42cc8572dd2573de7497472bc096e29cd7b81a2c1e8c20688e84245a46e159080bc976d98581b7a1023f94a5947cd244ad487b0193a62cb799afd30a8bfebb6a23ead4da7d2c7993919913583deef2311da82a924594d11f1e337b1ebd4364405c0cc88f57254261441d7a0b416492af894a9920e2c34cddcae506e16581b977e978150402663246b709bf9a4a0264050c4c972d86258d40eb8a046755ab187663109ad0aeab371f798b503c2ae73da67c5b8069dbaf06c0b6af28e0007dc22a766fdc3e1a87439258e65a701d8098d474",
|
|
+ "pop": "39efab635b14eff1911054489bb69b23eac37901ead8f121a58fb8b713dbbd1a1d52beb987c77a061f9040190f626e35be5e2b545ab547816949a418442c4b98efe467fbecc77a68cdc43dd4d03968a6292e622a09bcbae491d45275324c415ef5f2ad7bda6b99be7e2b1e2a3da36a4832bcef4a1aa355ee4c56fb4197f9e7963db2f7f7dc493c0ed58578604d8a69effd44ec05f5db331c984ca02329089bf57206cfa57e53dc8c7acd127e8b82996424bc6a3e7699ed9ca50e4ed8caa529bb48ffb639c65889f820ec35e5878b931ead2e4784a452e52849cf89281205a8487489034ea1315bcbd1f611ce2ffbaeb8fc68cf6f82007add599403fd2b944c1fe43700c82e74de41c23ebf9bb4650da17ab36c5b07336f4b8347807dfd64d657694890b4258e12dc89bec29803ab2a8e22591a623dead9abde7edf5d321a1b7c5d43c768db7ca5877bf9af4aca0fc55757940706aad34c19b761c695a91bbc9b495a8edef30816b381f2b0cefab22de3c1c08e29069bfdc896985412b0711a0e2527177883d11d0a0160cf4a214bf4518d490cfb91bfbba1bad40286a6330e5a8295a45afcb4075048ae0e1b9353b8e84767325b3495180b9d9bcb31986f6ea97bc2ed205218597e83f1e8386d16a0c88aa636833cb14e34d58cab5e78a32533c3158cf1b50440bd32745dfab9367ba53849199ce227d3fd5c1455b9ac5f1904d43f781f7baec4dfacf71600f0a46d49209b629336452c39757f3d3f77d73f330632b667a0655e7914c0c47f714f657de98e1cffe48f9c94c5b2597673618a8dc799ec6b8ee870289076cb7933ace352e6111c875f9d29513d45bf54fd05f0cb652496d719c465da799f128d4062908392cb63e6121dbddbbfa6689d04cd284cfa680c27c798a02507160a56dc78",
|
|
+ "claim": "4eb7bad0f5cb7a9f33151adb12591b8df8eb7b8003be628cb07dd3bde5da37ef3994908b1c10b80ce280023c219e743c6e582f5cc425543b9ea49ee34f85e7a400"
|
|
+ },
|
|
+ "1": {
|
|
+ "addr": "0x5f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb0",
|
|
+ "pk": "1125a8c8ceab68078dadd35101e64ac8fff297aec01181732a50ed24098c5106cc1acebc7ab349380a595c7207f93e8cc96aec66e74a5ad73c0d9658e450776448d8b7f6901e8799525b6bafdc0401bda562c5a42e7e66f67ba1645c70f9473769ec01d01239f9d26b6134abe28fd2cc361852138c657455657bba806c37a1eca1b5ef42f4a498a987b7614f41a99752be9e640804d4fb74db16be5e9b3b101f20b37264a31b5efe4b5d2388cc92dab1c82218e24de139ea69e51b9d7f5e190691e6d20626806686939b7d2e593409532d4c465af2b5c8848f298ea7601fdddf2f5c2420b7e02f8bac6273da2b2c91b24e4329dc1c42640b00455ddd4c040b9accd0a90d993062de6e1f82618d523ac0d5b80d407689cdf05c100a758702f60e395df0525a7d0421b1e2bc60c612b89b945765f0b251adc824d9a6a7c4ff48761f36350de36bc7de94900ce4e91486424d1a1901c45abaa1188acb4e45f4bf61753b41287e73ea33213c153b661032e1e158db1d12d5532a0387870ec896e5267e6d290d53850cbe3e4d12ab5f0ef223b6e307c34c9285c122f75090439d152d466f49012bf9135860468886c954a574212d438c99013a878e9295b44686187b92783ef22c53aa95e2ac84d143a1b20e1ef74fc5ac39f2e03566871a42e67b340455da2922ebd9e4400b17a4f1965764039bd864e278d7b5a5a1ab600ea6edb0512a932acc47186db7f0cc5d429e984ec1b4af06747e1e09374d372d65b9c9c9540731d6e5e9f54005011570d3525eabb3c0c6056aa3522b9d3246f818834fa18cdb069807270ee3e6b30e945d0d9009444b303a50f7313d800f11020d49b80d27696a3519e1145b62f678d0206dc6be78cd321459dba0f444e96ea529be49b0d864d56ea2368b60661bc259184154722c1332de5593a5e29235569936210ca761cd9518de96855c328a517c8f4a6a3cbb75ac1f0a6834e9e6ff4d426d22b547ecc88e1ab45d3678481585e1ecba71a54421c0fd83dccc39ad0e4764366e740a482ae8ee05f22f541ac79c48c57eda102288836b3b6242334e96ed85ca3790d3e40ebc859778b844503c5c8a97980ee347294bd9606f226831db0aa40250bdb073312baaa92a86a31770469b7fe041e33f85a40a34f1071aa3ad4af426619fda690e6e60a3b8534c63e080438a123f97fab6f0b66c677de4ed35b65db81fca0521dc99b20e5474466412ca5151f6497893988970d3684f90d95b8283e8d040a5",
|
|
+ "pop": "398ec121892baf26be6baabf4533d4e4cf825e98fe43849ffad44c7ba50718327f4805fb972fabf50b05a995b9734d4d71a7300af9d3d0bf955d03db536beec8b912286f27b68b84455545762c9595d65b4b6c5961922300a4606b0e0b08fe4e4be14fa9a3d6e97a636c965d76cb9c118dc53374455b16a731d0d61cd360de03f7919c210edacd38d9241bdd6f5ef1ace845b7886665c3cda2acd31aeaa23d050f09cca6baef6a0fc969f08d9ad34afa46f11cc94e50aaa4d0e8a1bd4e1c514749b512f44640d94f4ca329b84357b6409b392f5b6bdf24bcf9cb4a613e8ade0e54ff635e5c03c9adc1a49963913fe25d20ea27357c5534c89b33435a7c244ba71ff65fa9de1d0a8ccd4bb44485178ab9721fcd2d18cca90d1d15ec883fccea8d2b8df460dc16a554bbf2312f0d939d9a725e8e9663c50f4b62ebb4eb554161f5b14a72848f19cdf597ceeef895f9647affd293a9d363ece234ee3f8d533997e4c11a4f5c3c75c94ac87cbbe4671736f067ffdb0456094beeca260512ae6cacaa46cd21d1cfd7078dc0b0b40a679bc7011003dcb6ee65ae0b1fee6b4a471352b0a46674c77dbdd28cce3e87d45aa72deaaa8aa098bcd58b743816a5826283ca6834a4ac86fdb75b9e1cdaea4d75f15953b1438df9fb94998cb904841a3b9d0a4f8c4d2b493b535c66a7ec8987b24e7a7869b186eeca9dc28cd2181720cf26b4471ef51ce190b6c94568582769ee7067ce3cea64633bdf52b0b7c6bdae5e7221478aef060686d2886e213d62bab0586616b0f0222c8f19e56213540519fdc6f2148482b7ee5a559bea6f3a3329924fdff27c313b158583ed631007221eea64dec34dc7e5521dce1fef2a4ab80dbb447de58a490b38cfbd5792b8c789224f2ccfa1fc354f06d3b7bf4f9d395383d6a0",
|
|
+ "claim": "03409cb1260adf9b529c62ab1ed51f84459b065f3c00bc8e4aa52ee9df0e0219747be4dc1a9ffbe1f15d223cc66ea607a6a01521cd08c47649dfa049bd2ae3d001"
|
|
+ },
|
|
+ "2": {
|
|
+ "addr": "0x97473985d04723299559f49b856effb47d7abfad",
|
|
+ "pk": "8cf6831a6196601d69c0db2725e6b0c2ddf4179d8c2eed5bc1e46528a7f9cd046199a53e8e6c127d6dbc35d1a0d0450f6f660dd0a22debe45654788a5b8ec849aafcb2a0ed8345bae07a262769b1a8ee57ac92f496b8ad4082ea0d8f7cdbb9a52040b59dd0f69a9206bd9e48aa41d1852c217cb885a4238e6234b5bd2ee5771a3eb2e70010056438744fd85b4a74d5f080256d65789967c0e0c835a12a36f7e12c32f42107514374220d3a19fd9bf6570c6a53596cfc035024bb9fd1aa67182060f2e8c115a66376d445d840b92b44105d376af967528561cdb18d9492d15c6d7dc2562b310fca6cd1d7da395fb6684467b5451afd1a485aab16af8540247df46be18a78d9840526e7b84bb48c45fe8bbe2f8a43149c04403326ae48b99e684d1d30201fe904226cc3c453dbf407ca84344e882f47c1d32b93597f958c1642d39b23402d8ec498a529534eabf50365f4845e68b34d89d8910c5024dac2208e8610e5aa536a0048d0c62b5364233e96b690124dbdca104adfe8217e3472127c15a8a0ee55a99a29af316ee18460e9440f6192664fe0a36b191d5048eded163ef0e0b32a1b81767672bf13d6b881ad6833500c2418d2f65c530b100689b5f368956a92175425cdb0b2fdcd0346c73f148545d463c99128a859e64f0028447286e7965b58374023b94804bf26a56b88b55feb0b0de8243cd3c1aad0b12affd69a9661829bbbc823264edb8084ea4a71212cc34209af973efb92d0d591838695b91b44da5a88a71a1b0b2c583951584a13c872b007167edaac130aa9fb2386a66f7c83a887af6a7100e9c80e2770bd4d9a535ac7c40b78ffbb148bdead7a6631824bff5da6d781a50310bd827cf0345d8c2d15060995824f98ca752154da4441f17e0739999854eaa6474067ceb026fe705aacfe0c1cb23a192f4d38404b7651a9d416b139a4ba0e7191289999fb41127e2937997fe39f83a090a1d15fb27e689ab7fa9254b79d0321966cd4253c50c197886a7f35209421038d81bc8b66d124066f78ac80936dad17c0cd653244e80771abe442d2f0905da80ad50a3a994cfd282cd7b727097fa444aa384e090668ff174b86e8b072b0c938bbbd9f416b0d9f1a742421a7443eab4a0d66298764016168f5630f2f840a3744d4dce2af0c41f094a3ff6bb57c6af71c03a255939be159379c66fb0bda9a5bb47ee375aa6f9943447ee2cb1b916c0458bbdbc4dca2497c166e586c70b9d47a53ca74a5793537430dc7",
|
|
+ "pop": "399d5f5ec68a10b4fd548f37c4ff387187ddd41929151084ddbb978058a84ec85ecea2b4bb6961614440e7dcf39861d2c6b0a912135888e90e37e10e77f1089be0ae70bc165e55f23e46337b9723e70d895538388ee664c2e4a2f9ed15ce8da74e35950b8c02382c340824a9b639b0cfdb694fa94efdc6d251973b1544f547287bbd3148c9244565efcb438a6a4b0e7ee4d79e06369889db941b7d9113277ec944e31550aec797435e5798c423e1805425a8536b0c745e93c8e9cfdbfc9d5e1247738970ae4a21aca901fcd5f89328de730517bff6a8f5edfe7118d365b80c6c215d37d8c53448f4126d5f9670c45195a8522694c1d7a9ef7ff85ed66b6c8110e2e0103939e26245d7ed7460d9551a63ad46ddb66ea17e93363eed773632caa7a709d24605c6426aa170126f5dc39edf327ef0d260ef06ec81bf10c7a8a0b4cdaa7a8336f27e6a1069c74706629a3282b35fde2d070f3891f8bb5ca866133367f3f4fb15545dc692a9444a9792c16a105268b5c5dbb610782c707cfa7b14d7ce11a844e5d143594b92fda654e4db9f0b81bd9c9e2a1397af31e69d8f32b71ae63f28e2b2043ee5013ab1e951011d8b53f3eb8d72386e010bef31df7fb089b151e81c893e7e788fa3c9d0eaa3bf7db336b473b1043aaac835a79e8bbf4798852495bbeced93a9066b76bc745b24eb19dc9931c5efbc2e861de4af9e5a5d1616f54253b507e4a4be2c6b3ce2e36bd33de453ca459ea47746aebe9e39b45ba6cdd457d8914a4cba88f290c230fc2b7bdd10defbefba385fb32e6fbb95bbf7be86df3376d79397cc4027b69407fb756e1463c160fee3bdecb1909f726213ec52aaba2358c67d498e7c9b925221548721a954a49bf63a196821f12954928d1d776f98a6c541f765372813f08cb3389735",
|
|
+ "claim": "006257bc26cc7d1b0099af9cafbdc5f60d696b419e28329487e0227be30d66cf4868002d57361e2c8da1c193a60c2a09ce78b15c20f5f3da0fb8315d7778140c00"
|
|
+ },
|
|
+ "3": {
|
|
+ "addr": "0xb5e768cb3117ea25175f51aa956b48691025c2a8",
|
|
+ "pk": "b991d68a909506b5ec27a59c86a2b0b815f1fc8d60a9224f75f40b8b4fd0a73885821d9982e7f829dbf24a824b1a85292145807041d10005944d107b70cf9636a15765096ed8a5320797415fc709456a85bb47037279d692bcefee14ca4284b9495e0eb80353461c10304d8ac592d665aea90f30b2ca0331e84b0139a4c98e3e47bb48d616198ea14b8b2dfd77453b4065c33a2d4daa44976ecc4d440b772f43700e341c22e146026e75de104be7fdbe4d95a52cd40997eda2a0092a299b44d4274ceff272c05abb0bc59607249be4a58a0093f2fa34c14957250d5bc4ed23339d3a2d0750a77e14e8d107324ed12938c592071335bcc165ea62009145885bca6e2a6937ec815af86c670d2abb119488e2056689090623578b9ec28108654c93806ee0d664e2b7c53146fd981b65b177e8de61fd8f3a47987e6ae66221241a68e64534ca22351c8990641210851fe997b669f848a891337bfeb0faa42e88bc406741cd943685512ef7bfc65440e86340dd96b57408cec4d1648550129fe838e201a86164b081055926b6fae0b6e5f65a65eef5061d6d40681c648c9aad426927134bcb2e38ac7b63e2120a97b21007d553db0dc64be0b2ca1a2c6449c6f9873496b49973af9ca1514e3217fb0608aa3d82246f55dd6504a8c8ae0ad1a634d54bc1c1f0bdd008332817f25ddd700244d68c0b6a8f480cdf90ae1ef1a3a619961bf67c7208697151c2af54fad43471de38739cd6c4067a056587542782a422325a174db998c552d5c48095a0ad555d8b784d32c3645ac4d099165071d662ec365587d954e7128db6cedbc3172621d58c1b242d4a202841374c126c2e80a8830d570301717936b2c328ac7ec61379a7bf1b06be385162ae0c8139d25b010bbe166f1899299862acc316ba59a6313a6bc6a10f590248b2575e243f66be6d62b851bd685413535894e2ab09f2519290bc3f701d52e2518276621df409172f3695e628580432ba096327ce4efb170ead3701c899a7e84f00ac926e21564cf0a78eb662f5df31c2c57540423039b12f402ea20135a62d3c4d90fac5ad8096bf7ec667e919a006ba518a49187744122f783d12ce69a1bcdbbcc486b4e9d2f81c6bd09839a5902e575aba9ec4c81629e6b3e480d74f81aa245c546185542d8a2c1c39942a6e1c6a32f94a8d201eb85b6230e9dd16cd03827eedda829e8f35e6049e9725fce18066a77dae2456c62c82790629494b699a8d648a853eea8d322dd869005025",
|
|
+ "pop": "3955f003a87405c557945470279f9124af6d868a78bb9e327383e76bba8fe4a2df71bb4062ededa3b467c09005c74e992d4544bf326f9beaab3b49f6a3510ade3368f23b9ba3d0228d810aac9a3cf41fb93ecde264f69dea6c47dbc730a9dda8fbd686419f6c3d3a8de6fec48def614cc913c43205d6dfd86d73e9f5b6f0462a55354a2049369b1d355d2f35ad6bd3835f3a78e5c16ceeeda0c47b10f13c6d47b1405814aaefe709d678acd6af8c9ca41f146108ccd6d9fccf87fd51971a262189dbe625bbc5bb06b561a9baed7eaacad16ea5ab12cd51c839196e820523d137591907b12ffc725c0498977dfa1ef6525a779414b7588d5a60b9a3e950ce324e5f8729af2c0dcf5d4679e5c28442a939c63b6cfceeb174ab9fb915e76a67886522d16263fe5ee777e0d9ae367c87a190fc698a55bfa2db7039682782908f68ba1ac9ea4adb12e97a7cb599a4c13f815b656576775d88c1d0272e14462651692ae5b6d4accbae4cf154db58269996e2e6ec0965062ed86b9584df0f1447739c9b6b5ae14f1624830a624e0469d0a6c8311267c92a312723af0deeb2672a0674ee52a511599a48b91ca60a69516f4b6c0fb9484614180290eab0a67572adc610bde3e0c3f4b372c3bcbd7b3e1294b20de2809bad05a9c7e0b20b41d1697a5b8dee2653287068da7496678372d9567f631b13e8bb4136e413998678b8354935bfa2ac1cde6f1b54baa2678708b3fe2471c430bd6ee06eb6d289e3819998ce73464d4f0cd9cb3f1b3fe1a4439b17a1b0d8fbb294984d112d3d4c1aaf35c1a80934e131cb13c34ab5d2dd7a57498063fdf9a2f773baa6483ebd794cd1f49fcb105099de2c5a5a4386fdfc6b10d8e647530b2614b68385da36141ff79237334da76b83eba9c3c3cd8a8d0a300e6c4ea3",
|
|
+ "claim": "06cad9490a31b14faa3327eb39c9e1fcde38d5f5b3b3b2f8f41f32484ff827041b3aa98a8c837a0545ca57774d65958f2a44c270fe3c478248ae119eb22f3dff01"
|
|
+ },
|
|
+ "4": {
|
|
+ "addr": "0xc3314fd768bb68b986e80c0a14175f6f72630d7a",
|
|
+ "pk": "6e9ada38d7da61bb7062c6812dba3954f433ad08157ce4e9d340c3bb80d6b9b1d1027cbfe1514b2a9e5266da4757f9536a3efccfe15255baa4f48fd442d9c2731d8c63a29f936c1a6908f96fdd393dcda5ad19b81b1ca5c4472cfca358bf1566eecd9e3082dac612c158cc3788681f5f0868ec68a06cb04621465a4fca948f7e118352813e5d2138366c97296dc15649c99394b1bdd0e7969f913c255d694a989d75b6499a7c19bb1ce46f313e6a2fb6f4faa7ba63e4814e3348f7ee68bef4b823486dd6baf6f5b847a48b78bc1003bb125d3b26aaa9694a026c75da351064ff868061a78543677db940eb33a4636baa3e756948d61845dc43c04595427a6e9568a216b50eeea2428d82887931632a5a1d33803b392ed142bbd5cea9f619ce563a3c7b35d2f0a7709ed1e20edf0754f3f60aec60b329c0f51b2ecea714d079d2d4ed5f58a737feabee9c26a0320157147a3295a0eb00399eec3bb82d0a33a9e18789496f4e4d6dd6f29f106eab227336b49f688f95b33398c5489f5c32033cab2176749445c208500778e3955bafb2521628740896a9525d85d61aa2220379f8bbe8a16c44b45652d9ae7b2bfd3664a2a64133edae4b4edc930c64e6d99f97d707fcca1242467c9d0c71c441e59073e0d879e3af0529fdaf99eecc7c5219ec66d2c61c8294bd90dd53a21ffc0b230c6f6a89142336478c1179d6ecd91881d85e1e6535c1692979f217883feafc45b9a539834f0b9d74554901a8b83835c983fc43fe41141281c5234f02d50ea5f7a774a5d4dd9b8aabe902d2d0659bd1773bb62a5b1750a75f24ae7ae492cf2a5469563ad5062b4592037401ac334d8f6b2beb46a8aee678c11e98503e0be846dc5992e43b2019085e2872baa217547855e2d5b9984073b020b5224b577352c1a4bb900d8f5fd974c2c027cd633ec0c08ccae82134453b720a67b78e5d01f617343d81fa0864d6b0b1be09d35f1d707b688d134c4b82af9eaeb8908f40b259a8334c04a5223074638a82046cfaeba392c21f58f0be565492958f6282baf64d98a0d6af810490705136d1d1fc16e43b4668c9cb4fbfbf58d943ce5de56fbc5e44a684990b7df050981e559dd9d34a3fc4962b1282a15e63ac0e85d8d5794cf15a94c9409be98e9652e59176689d153214f2c6d011aa41f5709e536e267a9c897a10dc61081e012c51a2467464023c1dd870091db16b54665070a4db581cca14bd3843c3d42e907ef1f7c053d0a535a4d4f92752",
|
|
+ "pop": "3916fe2130b3682018bffb2f7f230a13b4752186677177a473da8da5a8d63af28c0fe8a4ad9bfa487cba7e246d40e33198b4758833146b8286da281e5b578f33948be197d938b1ffe5da8aac4d5e8dc1f20baf960d9e8b894e1d8fce9b970f06f86733cf660fc6a922cd2d32998197b5f99b3477916adf7e1af657210b4562b3127b5339bb7ce9194c78e40feeaeed1fe3128275319f7c99815156644f62d349887779548e2284f1b280b5ab35ee2bbdad6f93c4c21957c11e395ee13c8dca7388feb20a4087c2b48739f9cd3578de59fd251236d0a1928afb9971d5d2306dc8c1eee1da7fc491944fe836e82474465e160df7dcc05a14f7e91167d92a714d8f48ec1694ddca87d88d5b9593623cbe9c8d39836b9b14b2284752d80abbdf4a4adbe46395fac90167b7d66c2a568420a5e2a1c01e892b9f5bd90cb668ccabe8134c507ecc5f82c3b0a451b2e29c6110860cdc60dd57979a523e0fbe9efaf69dea6aa334439824a991f13b52bf5a9bf65b6be2a5f166bdd5e9a47f6b904ff8ed112067702c3ab5b1aea12fd37f50f442b06dc3672732da1bbf2cc7902198dbec591c132c96e5d20e1e25a5f26dfd696334a2d525dbcb94af8f558caa39baaa290f98bb2a0fb9ca853e05b517469b0430d38852e174566031e61a8ea258f57aca6e48e4a38887e374f3a9a82948a3d3e4863eb7b1e1969373f19ea3f33c7e2febdf9f44279a0252daf9128d0389168da47688ab33ef9b1835aec663bb97c4171da7a1b8c7b12798cb151f1e09e848643d164247858ce31438263582dbc037d7d3d25bf0cb8d99cd26d1f19d6206b98aa0d8b492466d7d80e43bbc8fe586c4a91da6b147e9e95068f41edf1466bac80cf4906619df258f617982ffe92963daee3dbeed16698ab654e929196498d02f6c6c",
|
|
+ "claim": "c923a8b28832878c3daa04e6ff989434d7054fb065e2776e16db7f2485e7f98a22a85a94d887694c453c9a1c1f34c4eeccfccdf52adea7b7b4e7da2a5ede842e01"
|
|
+ },
|
|
+ "5": {
|
|
+ "addr": "0xe13aa491abbc1252dd714e7ca0e55717a2143eaf",
|
|
+ "pk": "a2b859c229911277f188666a63981fc25ea2b38df500cc8851ccee2f467d0fb1f8aaf84f9e757b7b5db61479c1a6a196677ff6d46779ef8d910a78604f04d8591c5de80ad1c32422ccbb3bc71914cd159001a2c78a9a00480fda69321a6ef54104bd0d1a1b8764d537b5909c107dde111786d5c6b943f52a06bebae81ed7168066aa0723ed5de103d0880994341828d3bbc78546b5e602cd842baeb162c8c099bf1112bff3f3ccaea4cec0ab5b4cc276a81351cc692d463cb6e1c4573036f1d07adad56f0210ee755c474614cd7ac618afa673197716ce24cb041225e4c72062873c8da49d13d11b70e05a71a35b384a90e95290735d9cf1ba9d0eb0abc5aabb728ad13d6cfa3ac2819411684629ff07db9306d6f5c52ac680ba31a2e1e41b1cf0f1b6d190ed3ad00470cbaeff956e7da446016360b515d2da9dad49f26a274957e45a6948843b0ea49c7995403667885a86f6f116e52eb7701615b75dc75801f5a5855c5e1b262746ed991aaeca6f3b9b59ab0406baa1e74a33617dfb6b54afb796c1d2299be9aa68b9bbd71c212f23909466471f8b04a5801408929474ce5304cd87801d01e1e8ff1d2b0842f727bfc3611138a3431e12867bcc000147238d659c7e241703444c26eaa6a161883a91e4e0afdaf39cc57d38615fccb1edf56a2adf1e401df1d5100467ac261772d695f29be1b3113a2a6f8e48f1b47380b97651a852b2c5da942a3ce92d17db15a669a4eaad2f116a25c4beaf1f9d72bfe1d665411c28041761d0960f5d3995e86fa15906195b2a1d163dae8e750b1a5c06b5fb32092b0ea47501da5e6d9a5941d82b5704299ff56e49299ec82c62fee9828ae56bdd2a90eadcdb94fcf2963d02349909dcf27e02224120d6b66747dbafec302bbc6b166e5eb3692b55a35495b15af063bb746d8c99c5c81719d42efb8d851537f875f6deab96b5860f26d6d0b036aa62d8f744692f256093f61f9e2e669f87feda1b60ded5d0574c521860665472ea9d44b1ba317d12e7b5480aa449c6d55f70d7a4341c22560a037b30df071f36573793efd2b098a6138cd74265e0493b71a228463c00a0260e0cbddc7905795261980edafbd3d30a0102ed9bd9e99630116341ef583f387e9ec5f9a6ba035e33d6b6c96faa9e27f6420a952496b540badfed26ceead61d590a5eba9f329ca9a5a0d562f4d0137f643128e6ee270e175c0ee0f5e68c03cc05338f2dc481723857fdc42d9134b908ae43367fb2601355a326",
|
|
+ "pop": "39dd9d598a70876df50cb2671f76c9e4bc690d156806ca16c4c8fbaaa8ec924d58a21499975c35bb846ea2fe99973919e596ddc4b5978b3e0a44fa3b9e21290a16d1bf2ded923261f9cf5b1a8468b173a6433aa86f5868ece33279facf219bf0d65f3ad554e5dbf7275587c9c9ffb17f2dbd9097c51e57550ec520aea9e7df252cb53a7db74bd7bb6c0d9094f7b0ae55ea70bd639ba71eb5bf5b53d6e73ee3440ad3dadc352c89aefe7279cf641baecaad76e4f5c8ed374bec0d806eaf9d3db46232da65cc16564d8c3e1cf605e29ab428d7250ab7f47d77b6e54089a128fe4d3624b71b2f65852951583f0a333725c9dffc99e874f43689bbd3b6e8bf821a99a8d613272674ddac1a5952da9878b44bbf9664345d579bee8699354b0f91e324e43a30854dde8a5126298bebfbd79b9f4ecfed165774fb2db23c6c79aa47d9738dedbce91d81d3f5b6d9ef895f393ecf5b7326d64e92d95ecb3c40de0431746cb55b3d81e8d5ae5136aba93d21b068577ec56bdde99ed996ef3c8a3d8a34d105e7faa486161ae42f13d3d59efc3dd7f7912b8fd0332854f65a9cce993248fa5165bfcd7532a3648e9e477dcd2313f7a673a4459ff69d89c125af2c425b579ecebbfdf3d07ba70d4bb98773e13417767b68effb5a72a2b379f864bb2c8ef6921876c93fe971a85b4549f5c91ace8a797ee61196bbf58a8e8bac3dc87021f25c8952d0b0accd850f9baeed02629063617119c55b25f248aa7663188b9067c6a2e294539595306a141571a2eb3afa244dc0d929271bcbe8a4a884f1694220b86d5709acacc9b4b1b51bbd4cb3b07b12abc9aec450f2cdddae2ef9199411719538da9304e0310579bd6594da42dbc344976b0e76227d26b8ef81d658a17e650b31ecb5c8f1c81312d241912a47c93a20",
|
|
+ "claim": "80204bce4d2129b72d9fade5453543e25e859b16e7885273a618f7523ee70c5012b231f49d9db11a3a248bc997352f510926488064c7c0e1b6e79f99f01a59c800"
|
|
+ },
|
|
+ "6": {
|
|
+ "addr": "0xf73bbbd26a82dbc769066550d8d4585eab2fc00d",
|
|
+ "pk": "ae79ca93fae11c333ca673090a4b548553614bc1ce7f6aa2773e17b972caf48a07efb416581422605f12400494db84accd432c148168db7794ecff419e83d4738d98f6b0de8f0d742902359aed104a1582cb8ef976965502c28bf4466efdd9ae0350021542a563c9ad2c22b7b0da1f5cb832c5a54d58284ed0f172091dee7be8f94bbae38a4ec0a7c1dca67ca50de962ca09ecae9a66d227841b2c66cb8600a1f01fe2d48be3c64999d1f8236762983a80c3a58fedaa0bd09e3912223b4415cde3fe63d70a62acb564cae57b3ab760780ff26c422d6675920eac389b91659aa3738a5055a76a9046f443ca1c101da8fcca37fe0be18fc9c6851706367cb65f035615d3150acbb738c66eb6eacd7b9a1b03b06e4f046f8615754d85e69d262d8674e8e82052bdbf753591474488488c714a066592718dbfe08d0b91bf387d2b9ee6a86bd0bdf96082fa523e5b6851c27723b99af0aa0722b185d52440c9c82a2a61d6729ec27999f9019f071e9852e813c0ab9318e2cc791a6e7203c27ad48a68ed1385319985aace0112e17999c80662b12a135b5e1a2c9067d5e06d0b33f5a691b65e2181b8b7f389a364543a058268a97c20928b490ceffe1520fa52d143a495941996b527712beecb17786f982425a8ea6cea000f191226855eca65f069782bd777baf11ac781a5b77492e2b69c039903c991259b92a93d18fe6ac74e064370f3dbbbc5ad82b478648ccff8ab45d133b1853a1d21d2e7d525027b2d9740bc82fa16201fb16318da37ec6494c9ddd1af864ef8b50b266f1227134a99c40d8571879b8a660964f6217ca41c6c0435056e5aafb494f4763984a55b196ba4e6691c57a66ec82b886e3e9da601acd9a2ac3584975255ae13c2781abb2a089e423c36cea35126fca8728a82a9bb8dfbf1ed0795a46a83c22945b08f6c7048e3d5f3bc7874164ca39b05ea81d9f75e778cea8b01b1c19a8a5e89991419cea779aa49ae6d562d38be70784def475ca78a3ee40e86de917557d716b008a0819410625ba6d3603b53ce821d1cbc0009dc4d518e025c246e5b6904196e22667a9df22192d22195ccb2694e0cba7fd011553081520d24f53344d5da90299c150b968f7412d51a638bb853d52065e49ae471b5cd979b11953eed2ea89c2d1366a48a664502a96dbad1d8e527d2064d5885cd510898880110cfc7ec002de2029e02516682b953a88fa72b00c55632415e9b52eae8640d866d4074880443ac6f791270a208d2",
|
|
+ "pop": "39b7d0c43c000dae00ccfdf9ff77990ea1b3e586066129f2c1504c4a7e61d19e600a06e25a974fa8a31a7a4ba11bdab472929ac01d9dee4e28413b9ca6a22648ea3e8d2b0ced5b50ee043e3c2a3a7e36d1e45511c21f066413896df7b563ea94af027d243ef079dcaaaa71365d4d525955966b3991e9f7cdd669b8e48a5e787070e87250bcee6bce8fb9b79cd392731d1c911a844bc4d2e00c2a1788c01f4c3bff98eeb8bdc913f5297418dc9f7a8a8331925806bd9b2b383c3357af46b2ef87263057f719531e53e0332681edfed9bcd3848cb0d15917d221b0db183acdb7da8e34b4e4e0783bffd8b323929261c490833be6687c2bc8866f76b7ba88267de7cf1bbbce8ca4f032db37aa02e510a4ad80633125ee5b8279e6bfc48d3f796a26ad99ea76e25f5fee686a34d18991ee8a93d6ae57ab4dd24f336ebf755ca7ae9548c4bbbdb517773587b4536d1e1363956c6132c4a10931f81d0a309226193cb34a5bf2c4bbcb2f7e2fcf29568e94acfb92dab4ecd4a106de1d1c2900fd126cdb95b3e17595f6459b63a3700234926992a8450f4ffefbbf3ee83ad589915a56ef89513ff90ebcfefa214dd27350e15f970d71e2d8ea1adec8dd6791072657fb2e5082578b636d11277b603152d4359bbe69f0ebef1f9c526c3ab911d6d0b1d2cf4659f0557a72b1fe9178e84e223b2d582cd22a2e7251d27a4e0c161574d6415e0f35b59e58d83ae2b279ab30e68fe515329b58ae2cc1d55d1ffedb3672d2ca510e826d8f96b67968eb92341105464739c0348ae4f6810c82e970267155248661cb3e536677358d66f04976ce3b23c9689d8337c18de39ee42fb353df4e13376924a9fc9105df7df533789dc62113dd7a08919db0acd90e5d1b458e64cf7c9e25dafdff38b6843e02995519518f1b9a52",
|
|
+ "claim": "1bfac8072d4bb5a8e190a46c9d412f038bc2e4ed22bc47410f9ce795af3ee70b7dffecd9dee523f350fb6bcbd01aedc13c2357c399d3a40690d389dc5596ee3800"
|
|
+ },
|
|
+ "7": {
|
|
+ "addr": "0xdf09b32c761620c5be77da398b97a64f03c3980c",
|
|
+ "pk": "b3e68f6854452ead92a798ea4db7116c6fb4f249d222909490f1837648185d207752134d8830bb9949597b70e7fa8297be87eafd8b7d116d1fece81701e0924d6a745bb64e884a54e1e949238e497868d2bd2960918a07a3cb1100364043d3218d2e76ceae07859de4182c85f7080a6baec87cd2235e908b2ca1a5c2e903bb387c067f2c514aec16c42f1ecf45b2eba63dad3b08a2da6bb6ae485156735261194cb8426fb8d10686527c4567a64195891acd62ba2c368152d2d36c5c24bbfea36412a74830c00135dc21941cea0010dc6d5c14ea61d1181f2db9ece691f151f1976e9a4a375d75964dc3363699f030ca842572c8e322854209f796268bd831e2975bb26f0c43332c2e7c5f5a959a50e7697e218f968e0039664e585a8fd5204261d6d29c287f13dc874122a3c3649169b0e6a2aa3dc93d70dfeefba3aa2970a788112f1c8085802174759594f33fadea69a413e5dee35f8dd13841f29234393a59052787cd8bf4b5f51b8ec26185ef65b788306f317121386a23456a1a64b1abc415d4b4f6281a8074526a19e8dd51b8317342e1de9f4c86a4c7fc90f64d628a909f5b0a2c146fd0b6861165487a75f606536a7abb9aec8571984a90b9b254447df27945cfec9f01ad1e82e54ab3617d22d38d912a4fc93c8bd4154648129bd17818892004605a7a6980b2a54842c5c6be2ca0071527a5b279156983ceea138ed86d93808b732fb492a036088c8864b7e1daa6b589982aca418d73358adb00aad06da91845f80723b4b3903f79f18fca2e3a49e31a21253bb6fae64f08a3350951a454d0fc84cece51f9ca3504d8665933088ca47c2345a744410ada4b41c29639299127c5a38ec701aeccb82a1caa59c0abf4be05bf4d10b119cadb9382f5e785900b70578a3de5659d2c1dee6a5338df1d0b90c293084620b9bacd2602839f75e83aa4258e03be9e541437d0481af11535d4e049b2568190f6cfaf2ed6b2e4d48e8979168299bf96fb192112e99a4589855ad9470a5a8f451e8a61f3eb4a51885865080c8dbc98e71bae8f0c4ab1e15247c79d207a5ad11796c85e6e62733a483e0f022cb05097243e1e61143805cd3ede3cb2640aea3300829821276803d1ab1898401e0196e070b89cfcbbc194e86f49108a45e01bb4a3dc4bbc73a05b5d1a674a9d28b16958812d4ca7bcd475b5e99957e9ee4236506d33f5179e6f804b59db5bb81f0a94500a668302599121fb67a62a4dc56048029c907d226bfcdbf3",
|
|
+ "pop": "39d8afb377da50cc8d5abac6c5df2c8efa90968762947d5b4b7799824a23490a2c1aa0785d5cc9ef3991dbc8561f09d4adfb245f5aeafba320cf03bd76ec645b6cbc318d2619548f7a29d8c6a134e0208b3c8b0cc2f85a79a2239a57908b249bddd8b01b542b49918439bdb4aa3c88d7d7faa10556a8d2f686c1a8e29aa94df718e4c8d368b978b5c25a2e8a2c841865990148117273196cd1c9bcb90741625b2515ab3e1ede76991fc51614f7317a8120a968b4094c4ab9924cf8fe274f62e969b02e1d8b5993f8f26d91dbb6fbc342e9f42c9ecf0ba5d23c1bda6fb204c9a0598d4b0f8292d5d66a9920a229919c94f62efd61b03cc6a9e99852d01576ad827796dad706fd82a2f3e15056f60cc9449fb3bac5ad126503e17b64184579c4d68c6174c96212ac44820b262eef7f9391c48c6bf89ae4232466f6888604abe71936953975b9ff04aee1c8268d5926c226834520ce9249e5b0f915f89bef30696b784689493fbe481bd975bad86339aa4e33a0fdb006ce1aa4cfae7ee3410088a5cddfda96de112954232ae356a23f355f3ada54a069a64754c6515d6b5c4f075380fd48cb3ac03c8418cd2269e607e9b07ae544fb336794c35857193da02377592bb19ca1354964d60ab2abb4771f9ac8455ca32053ed566e844e9063fd31929f2cc6a8eef4ca22c2e31ec6e635be61552957b30066b3441231d2ec7e6f5edda37e9f775229637f5457b77fef0a8103d8e20a6bf6bba6489ef95b9cd588aaeb997cb22c39dde8147e9ba293436f2f83fee593fa5eab4966672024508fc6a0cce75eb9988c7b20f16949a68bc2ce9ddfd16b4985198319bc823384afcb4fb5497c413d3f47ff198e22f4550c9359763d5f4628e42679cc7c89bd9fdae0abb4c2d362ce07670097fab4aba9569a40",
|
|
+ "claim": "67b38f20558e39a874581e0304f0b78a08f670a2328331b97a55525370568d4f153e26e8425c06ee738753fb20f282aac80698ed3841da9dba74e91f0609221001"
|
|
+ },
|
|
+ "8": {
|
|
+ "addr": "0x1bd5514286f5602a6762b0075266379d29af1c9d",
|
|
+ "pk": "820cdb49fa91e522cafe7550a586b94132cae78b762b166f6bd819a1a25409c534a0846a6173d047cfbc67f518518f1fef1c0ed22a006ec77175f78b1ba5240ec600a721e7c8444a770bba44fe186a5edb2a8078bd55b823ab4fd0b6991748d142dc710691d574d4f64768167776ed9559de1dc6a466c5103585602f0bb21f2a85b1a76fe9a27ef5d5e6eef099d255c841ee8a12481d9bac050955e049398e228a8bf63013ee4a504a7c50573e65193872fa271f58cb848205112b29592d9222c6242e581ca10bb10ad04852f276182a1db822d63e66926b9b2229b8551a06520f9c89828d053864dc6717d107b9660ac6f5ccdc5696e013774f28a050ba02b787c4801139f33445231b87d44bb0ae5a8b5b16dd08ff174221f51e00bc4ca26712d6d2bbc03aa918cb95f999b23a4d71c1846ad5ab887f71ac294f42359d33b9aa6421d604b1e81eccaaa9ea7787469a68541103cf0a3b8234efc146cab85f4900f9188eddb6e00d68eb04debe0afe14572b1f924de61b610daebc7e7c20b18c97787448e199a79d5316e9b8c2e695b3b030335dcc60927d8d62d6526a4fba58763992605508ae16e3efd27a861d1796c0a6b746d4479c4fbea6f51597c9aa2062e2b8538dd1e85cd5350095472852e15d09b68ba1572c466555616134c8caa3330974244d3d31d00d256b654f92bb5bad3d75f668e69567263c1ae2e5ce6a2a218468b1c02c89f971e474efb8b59283578443f79e425a06e3ed7c344176db59e899a180eef9e0a5440ff4570b385ac700cd7fa290940b9201c56aad19e584ee08a19b4e38bdca2c38ebee649c404495df9ea22cae49b48767eca88e9e784319598688df4223ef1890450c597b2519044230a209488a56856cd1890045967e12006acdb128e4121614a1fd5996df927b6d3d60a84bc362cf4044b5243569639c19821adad4c4e09839a1789b82e9051cec285e611d0ea0170703e5f317496dd0ba0a330ef00bc7e70911463c534be4c1e8296ad5a05256a72712b9cb31d5adb0b4e8c5f89255211d1d41c121ce7d80f1132ec33b91494cd7c22378b3bce21b689d24a9bd933b68aaa917a8df5bf9513014897fd66d9451b62e30fa7c09d5116a11c5f2a9bd21ba718362a40484fe6b93f76c1008316d552bda724634edf50b184eba5a0c1413c17e5b82b16762629746fa5302b352c525e97bc189593e93adcd4430684d2c0237117611f615edfe21c8a4b531354925e7638570bacbc3868ae7",
|
|
+ "pop": "39734597f635fcd82c95d109fac4083ee6c5eca3e660a6b96dca98affbde81f942b937c64fb0332f792aa7f6622b7f0791c83a18446f857cd2ae7f39f92758a34f6e43dd2fdfeae6fddf1b4f1d969fdc317c8b2364dde6cd26e84e2937b51b6649c7c95df207e7b937f25856620f01453464567cae3338666a3cd6dae26a1c2e50dfef58b33a9677d4aa6f5c43cd5cb6a9515e98d61bce9bcafdc81c6d0e71e90bf3bbd0712b3df4e1877c30f8ff69fdb13a3d6236ce2d6696344b50134ce57be824a3d9502a7a941267b1c546c584befddaac53b7d4c02c1f72a5ad5d5a8b72f8a157d1bc2999c3635ba4b9a5e0d5f8d8bd1a12ffc00fae52752dad43632b7cda82aa6158dcd9b0af4d19b409b0d838a713931b255d76e34fc582c3cc5469abfe9a0a5515f16678fa7192327a9ceb6bdb39d5fda27784b7ee287a3dfab93172e23ec5527455715d492968a421321ae390cbce20d5a724f672fda93696468f9ed46ec0ea6ae222821b0c3f424bb4eb38188e67a9bd9d7f92cca3ff3cd16db2e41bb25c65684ba1a2653041e18fc1b8b975168e9e50cc1a4ba59567d1ae3e432b1ef79ff78597cb13a26136213e8f97349fd0fff754e69b57d23bc8c2454aadb7084cb88e186ae459abe4978de22c687c33bd9d496b42308d120a4c57bf9d8ac272e7c52e0702d91f1f7c1a4495c651966081f5f267ca0b022ef404f5c4dc319b9e5db24bcff0ccb64ab41bb91429f3b631c2fee30bd137e0be387ce340966a17ae9d076d7d82f8ff5cab16dee1193b8a761c8b2009fc448ae056e6978f998ee36a49664d2c7e1f36d904e725e8356ad0d122862d2763935610ce10cdddfdab65b0367fde39e5662d7a86b192cb48aaf52e2c2f1298aa28427e601a546c9ee478f35eeb54e67b7b6b455afa4d6c9752",
|
|
+ "claim": "a90d28ebfd369081b233b0814d8d0597dd11a20415fe9d398d8dc62c1c75f7265068c65e6a9252eda43eab486890d03689a3f68deca95d1e41a9cd98f1ef0ad400"
|
|
+ },
|
|
+ "9": {
|
|
+ "addr": "0xd38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa2",
|
|
+ "pk": "1e74b3ebfee790a83ceb68a02712b5ee6d45b8a32e89580a793b1bb4b2b244b32f19311d307dc8e85ffeb516adf81e989a59c9f8b133e0b1a7203783ee645d214554207c93a37bbdbc46cddbec39f86a8b2e84de31551094cdd8de2c5e688baf695d4c68746b532f7a8726ae68a4ce092698dee27a4d3912292d52288cdc2f1223b6224fcc9b89336935e022be58de01e4aba3b5b53e0b4343a6af054974ae6c1f8cb9c35860442324b18b493d9bce9ac104153012061d141ce6381c154d50cf49f25722228c7f6b90aca65e09c590f6a868715ec10478dc341a41c475b8ef7d69daaa9704252e4b21d3710e0be0144e5fd45c11ec5dc0718bb02fd78eb86df829946f301ca778a91fa91f4a98b2cc1050751109c05fc698b10d9580211f560102082003872d5aea25ca5323664e8a03bb71e22d7aec1e0377546b0b95ae9a1b2dcfa42ea2d2e51fee82a4b2eb95e8a908266ff4cd561d89a53cb0541f434c25ba0a02ac14579eb4964801c07d3d1886fa6dcca95dd7d88c00fd43f20079eb991e0aece37345ea0f70b858650dcfa960c0c4f2205c692ed2edb1fcc5a454fc9c671c47ee06793f05f1e7101c88055603e1657a4d1606bbe8f543985df306cf9d3d446c4188ad8d5e2a67b922d9fa029938b2f5c7a90b3966232682c92b1c0408c5e0e89b51b764d4aad660a4c01698560da631e225db479ba0615e28c54ff474e18e48352b4b4afe1b605d968143729b8ac7a6888858adebfc20b34768730aafceca2d88dbcbf9ca116fc8ed56bc2e768e1afb04c4a2c55fae42987b98c355e6de4378e93c3e7287d581a3d22a6894a1a888ad4815d6d23256808335a4f1f51fdf1ee68b8582c03457c69f5887991030a63f031249aa7784bd07209a3213323af4ebccbf11edb2e73451745e7cc207584dcd0b2837274e40114ad064f8e3cb1dafbd9ea6cf200c212616a9674b4bb436e225d4624c570c284818c9028d7d855112e1dbbf068155924c817a213257fcdd0f310a0c0196a34629de2ca2982e0350b88b844e2c31120ce346321e86a92124b256dce0bb6c2d944be784a835757436a8a09920d8101a864083ba5fc70043442e2e6250a0255d93a9264b3254320b327149c8c61d047eeb136399f86fb6dd78000b063086f0b2efafc16d06feb03beac5bc323d1844633258a1c908bfc9d985a69812ebaed174143f48e2ca2bbb92ce37678b8e3fadd424612a100bf090582588230421f2a98e9ed75e298eca9c8374",
|
|
+ "pop": "39db5bf26600166c824167a356a8bedda227c8f6c541a690ac73f5cdbc6327d33e5bde14d7dc6a10b7e9ed7ccd679f1b3c661422fbe3aab173467a85a76530daac90aaa1ec849dbf3639b4f90858d86fdc619245a469049bb8685de9c4cd9c97a0040eb7a9758d2e6083a0da1abe4e0f5589981351eb6c580292c1ee8e374bd12cef22f4055504dd2706a3d0fc94a9ff05947fd1d43e98e424ae8e71aa565b998b61a02536b328a7dfbdea1e6f368709eb58b1d1d38b03bd569fd9953ceb5fa87453560898b1c8ae3fa5d25205bf151ae2d8d36448b85490653b291f6cf64792afaf44a8e8178138e53e86afce84fbac96094b768ca52d2df92a56a0cb1e0b232a340605882cca3a7b2b625b642171903774b8cc00e3efaf5ec52881526ab7754cf2c44fbc6d4047216979a47aac69dfade0cbfc709b6f3358e253977c717491f77e8c0de62b01e26daa0e6a76eef776caa4bdb4e9e96987f7e521646b6fdff6cbf790220a53ca54de05b52755b18fba87c9999d98010679b364587cc80d22a36c5c9c95913eaca6111b7222c535a34307638aaf81476499841fee7eb9927e54692bb3cb638611a4e0ffe86e5629f0abd50908c3bba73cc76c515541a2f6f4b97cc6bdbc7014b79ee98c27be96b1c5fd1f390cb65d30761183a462d1f431c7ac73a358c95964c5115cd450b017cb4b2f34216cf664cfc189db862e482e5cf3a08c2c97bfc3fc2459d74e1ced2adf345f24a5f17407c3b5b4f81c37d358b7ff61bb444545ff1b63c87f250ae40f59354e7c6a4fbd4c93c0562779f9d6cb09b226d72ab47b3e0d54119f49e253b0076f4b16effd56ecba5fd64d93873234781b0c2e3288837f5989556d87aaeefee5dbae523729eecf75a2e820b0bf540c822d3a830d2754891beea5cf5ea3e16185c8d1b497225910",
|
|
+ "claim": "44837b28b10bc2bc01c49fd48bb561fe12ff763f366c9a3321357f35597cbdec7bccf3b359629e4253c3a083cb2727fd89996f0e0ad9e2a4ee0cd0684833355b01"
|
|
+ }
|
|
+}
|
|
diff --git a/consensus/qbft/src/test/resources/aere-d412/2800-registru-v2-13600000.properties b/consensus/qbft/src/test/resources/aere-d412/2800-registru-v2-13600000.properties
|
|
new file mode 100644
|
|
index 0000000000..1120200053
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/resources/aere-d412/2800-registru-v2-13600000.properties
|
|
@@ -0,0 +1,63 @@
|
|
+# AERE - registrul Falcon al validatorilor. ADDRESS-BOUND si LEGAT (v2, D-146).
|
|
+# eticheta : REAL
|
|
+# construit : 2026-08-10T17:31:28.615510515Z
|
|
+# chain-id : 2800
|
|
+# bindHeight : 13600000
|
|
+#
|
|
+# Fiecare rand poarta DOUA dovezi peste aceeasi pre-imagine canonica:
|
|
+# .pop Falcon, semnata de cheia randului -> cineva TINE cheia
|
|
+# .claim ECDSA, semnata de validatorul randului -> validatorul A CERUT cheia
|
|
+# Fara a doua, oricine scrie fisierul decide cui i se crediteaza un sigiliu, si
|
|
+# aceeasi cheie pusa la doua indexuri satisface singura pragul de cvorum.
|
|
+#
|
|
+# index adresa validator amprenta_pk
|
|
+# 0 0x4bf6f91d84b37454544279cba152581ed6820044 fd07f92c9e3260f1
|
|
+# 1 0x5f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb0 d46510fa0bb7a9a4
|
|
+# 2 0x97473985d04723299559f49b856effb47d7abfad e959ac2a6209a4b9
|
|
+# 3 0xb5e768cb3117ea25175f51aa956b48691025c2a8 6c8d2be5c3a2ae33
|
|
+# 4 0xc3314fd768bb68b986e80c0a14175f6f72630d7a f719af63d9296c18
|
|
+# 5 0xe13aa491abbc1252dd714e7ca0e55717a2143eaf 05991af0f4c8d8dd
|
|
+# 6 0xf73bbbd26a82dbc769066550d8d4585eab2fc00d 075bc8630e79658c
|
|
+# 7 0xdf09b32c761620c5be77da398b97a64f03c3980c 949d1b4777391fc7
|
|
+# 8 0x1bd5514286f5602a6762b0075266379d29af1c9d be91e6d03b9b66f8
|
|
+
|
|
+formatVersion=2
|
|
+chainId=2800
|
|
+bindHeight=13600000
|
|
+count=9
|
|
+0=3b946f7ac3adbb6b49eb1426d60f07725a1b9409d472c9e8ea47a8e4ba38bfc773de905f06c51860d4e83eecf5f5621329634c3d9061816305c1fc89d55ba937f97b6482cd055895c8b4864b549ca4bb197244771d0635828882718142fb6800cbac04bd6005e3ae582f7e3ab704471877faec7aa6e1e96d1912a6e763f74dae69c2ccee323c06e5515fcc6880a2d96935220f50ac5bb02343fd2985a1b3b78f0a8548abd6702adc2e298bc113dd37411454286c29ec5592b963fae4bd7042fa6877e2363fd03c9a95e97da50144f02690d0b97ca332d14f9332edc0b0c5e5b27279569526523034d65b618147d267fdc5a35220091cca00b7456ed9bb1def448f4105bded1e79e1e34a6de8bed08a24383b954d47b3df5d1d8ae8b5e8592a92bc80b4220a7c0bb123cba55ae14371ca1716282276416c82772795ab0191c2562f189700469714ca5500b94beb23ad45a41ddef1184eda4d06f4286da21c0fdcb450e760d84401968a4e0fd19dc49bb1fa0bd79be005d781a4f19d5c40e71a4e6ab3ccf4413bd7f922799d28554f19609d7e4746e6519c8d029a1a1a548d369498feef77438051dbc2e024ac08220934dd42264acc038beebb5314f198589b211a81d8f1ef97e41af8d9b0de9fcc7b645cd80fc72c8c255e34495c51a060628205d48a11f9992b3865d59e692879a9ea9c6af9b831986e852c2583f35b1ef9aa55d41b1d18dd7162aab0ff4931476092f9d7e2f078f44ea2d0da699d362b8a0de3f140640826788faf7c7d4c0aee4b88a14cde9300a7253ac6c9b8de188515720f130a94673465e0f1e84a501b6c390b2ae84ba44a449320de37b26520e12988a11911465afdd2fc9b161965d3ccc15a0559930810104a6e40d17f629cacb8fb3973af0967c679a7d8c93b8aa833a28d6ae975913d0096a1416d79779c00052b2f19f479251a76264084552e99a76d42cc8572dd2573de7497472bc096e29cd7b81a2c1e8c20688e84245a46e159080bc976d98581b7a1023f94a5947cd244ad487b0193a62cb799afd30a8bfebb6a23ead4da7d2c7993919913583deef2311da82a924594d11f1e337b1ebd4364405c0cc88f57254261441d7a0b416492af894a9920e2c34cddcae506e16581b977e978150402663246b709bf9a4a0264050c4c972d86258d40eb8a046755ab187663109ad0aeab371f798b503c2ae73da67c5b8069dbaf06c0b6af28e0007dc22a766fdc3e1a87439258e65a701d8098d474
|
|
+0.addr=0x4bf6f91d84b37454544279cba152581ed6820044
|
|
+0.pop=396e2664ccd6ca94f76fff588a59dadacc08cb9215a90a0d9220bb260e80e1dad4d10acd3b29253f3e06f33390f58d1ed78f3e9d4a363a060a7cfb43318b6c2157f03e70173b054a6fd14fcb8f98b2e9e1a65caac4694c2cbbbea5e9281a3c34f1e5feebac690ddbf76ca5b3fde81b8f2a601c047feb69a714cf74da3eb1b3edff7afd2b8d0c015991134a6425c63aeb39ce298bcd927cadc47f7ec7a113cf9223b0b1a2272daa8f6505ffc387d0f58cfebdcc48b9edc144373abcfc8dd6bbc4119adb9b0272dbe696bd2fe79335f750c5933d07f23b6864993f565748edb929592e73fdaa56212472e4274e22a6657ccbeb56cadaebf69a221326abe9a0acbb618c4d29d89af1b6552cb1126b1d611046b2fb05a94b395d6468ffcd272f254be05baede5c4a53c9cbc91746a748fcefafc8d1909320ed8a47345b9045fdb575f76e451999519996522f53423cca2b245272ddfbbca77b4a32475d56506d090461c2c9f79104070d682cb1ec9279ced0c9ccacc896e1d20956793947068758c21a3f618f902488ce3f35022b6f3e46e89e51b71e4c496520f9063993133e255754d71a1635769c25fb1351b2a4a5b28f3979e3f1d15dc08c57e4ceba14b860c867e5b09a08377fd32bb3a39b4600db7c6068059f104bda82aa44ed6b515cee321ce95e3d6ed462191eebb0a0eff3880b3d0a54503c0b626ca2a8d3170575a5e77a1ee99ec8392ee95b66aa0efa3aa46d0bfb61182c5e5571a05967ba89ff3e2c87e59947dd14204c3cce9d82f9db9fff9caf1ae6c80a6f29d1d0b50ea49e0e85c288827a9554c9aed550e8d4ae2fa70f332acd94ebd8f24f315a72a37d48364d4b1edbc455be63f5b848a2a9aaefe64faf32569e06d3d52b83ff377d98d802819993dbf1d76ef21288b4be6d7a2745b8a0
|
|
+0.claim=368969e111970b8772d0b85540de5497ac036e4e1b30e6dda7e8778ea26ed2640519161648722b974dd94063e7fa14d351bf906d7ee99a721355aa30f206ae5f01
|
|
+1=1125a8c8ceab68078dadd35101e64ac8fff297aec01181732a50ed24098c5106cc1acebc7ab349380a595c7207f93e8cc96aec66e74a5ad73c0d9658e450776448d8b7f6901e8799525b6bafdc0401bda562c5a42e7e66f67ba1645c70f9473769ec01d01239f9d26b6134abe28fd2cc361852138c657455657bba806c37a1eca1b5ef42f4a498a987b7614f41a99752be9e640804d4fb74db16be5e9b3b101f20b37264a31b5efe4b5d2388cc92dab1c82218e24de139ea69e51b9d7f5e190691e6d20626806686939b7d2e593409532d4c465af2b5c8848f298ea7601fdddf2f5c2420b7e02f8bac6273da2b2c91b24e4329dc1c42640b00455ddd4c040b9accd0a90d993062de6e1f82618d523ac0d5b80d407689cdf05c100a758702f60e395df0525a7d0421b1e2bc60c612b89b945765f0b251adc824d9a6a7c4ff48761f36350de36bc7de94900ce4e91486424d1a1901c45abaa1188acb4e45f4bf61753b41287e73ea33213c153b661032e1e158db1d12d5532a0387870ec896e5267e6d290d53850cbe3e4d12ab5f0ef223b6e307c34c9285c122f75090439d152d466f49012bf9135860468886c954a574212d438c99013a878e9295b44686187b92783ef22c53aa95e2ac84d143a1b20e1ef74fc5ac39f2e03566871a42e67b340455da2922ebd9e4400b17a4f1965764039bd864e278d7b5a5a1ab600ea6edb0512a932acc47186db7f0cc5d429e984ec1b4af06747e1e09374d372d65b9c9c9540731d6e5e9f54005011570d3525eabb3c0c6056aa3522b9d3246f818834fa18cdb069807270ee3e6b30e945d0d9009444b303a50f7313d800f11020d49b80d27696a3519e1145b62f678d0206dc6be78cd321459dba0f444e96ea529be49b0d864d56ea2368b60661bc259184154722c1332de5593a5e29235569936210ca761cd9518de96855c328a517c8f4a6a3cbb75ac1f0a6834e9e6ff4d426d22b547ecc88e1ab45d3678481585e1ecba71a54421c0fd83dccc39ad0e4764366e740a482ae8ee05f22f541ac79c48c57eda102288836b3b6242334e96ed85ca3790d3e40ebc859778b844503c5c8a97980ee347294bd9606f226831db0aa40250bdb073312baaa92a86a31770469b7fe041e33f85a40a34f1071aa3ad4af426619fda690e6e60a3b8534c63e080438a123f97fab6f0b66c677de4ed35b65db81fca0521dc99b20e5474466412ca5151f6497893988970d3684f90d95b8283e8d040a5
|
|
+1.addr=0x5f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb0
|
|
+1.pop=39ec0d61382825bb96a0facd4dd5b7b3961fac490c9cacb7344c44e33ca00950bc02eecd992b31eb8194760cdc157a7013c54facf5b6087a9e91f3eb9926663bcda5c6b2e93dd362cf99b9d452336cca60502c868b9384a0cb7ca72796baa707829b3579e606fd0e218d8619e9facd14071deef1e5dcb943d2b25c258a4ce52e8396c3b39842a90ae4bdd3839b952573c69754b612d92c34a88d3486269b592dde368598d6e69f99d4c04c3208d160bcbfc97a8148e9b1e41ba9a02592197eff95e7a54faf860d662e5dc67d39c3c4c9fa5fed47993af66b65a0399a490907e92af60688cfe9df09e64afea5c9cd6a4cab445a0220c219b9aa7689dd3c4a1d9a2e8fd17eef466bc95a6e5054655af0c29c671a8c736d555eca6266388deee11a739a78cf0516701f7ee7d7e08b67465f80620fc37490930e2ad6356570d00993e1cf531cf8df0633c18d47e48767e19acd9b3758ca55fd7356498763261727c70f824e530532efffaab0022a3e48ef9b924fd6a7db746f0c157d79cef31125b27316952a8e475ecc88d00bac7a1f9f181e3ce9a87f2b318f444d823a1354311c723f0af09a14c83df27ec8bc31f5cb4e64ad1c683aaedb5d931f922b2c53d8b5fe8909f22d8783387c66fd561e3fc28ff7f94c195a7d7dec02a0bacdf5cfe3fc58d3641c83a9538bba295aee11b6ba3b4f93e71563c6f7679f4cb9b7410d4f9141f412faeb32b045fbca33f240d78e2e0976acfbb7bb77057aeec872da9dc40a77b9e260de5e2753cb96ca221c136326b7bc3c1fc45702a56bf6cd83296c4b67082f558de9c9ee747ada1ac7f3a5da1636b92baf4c5e3aa4694793a765b0e744f1496c69163c133c2373ff7a7c7abcb2ba477edc34d7bfa570a8e752022837dd0d6b7b8a27d1479e38f74c6184ae00ab88
|
|
+1.claim=a2fda63d2ea63808adbb89c1a095b929372ca456ce4cef1b60924861988feea302b38d827f3f82bd5c1eccb6da44653eb4321908dbdb543ea54d968d1104beb301
|
|
+2=8cf6831a6196601d69c0db2725e6b0c2ddf4179d8c2eed5bc1e46528a7f9cd046199a53e8e6c127d6dbc35d1a0d0450f6f660dd0a22debe45654788a5b8ec849aafcb2a0ed8345bae07a262769b1a8ee57ac92f496b8ad4082ea0d8f7cdbb9a52040b59dd0f69a9206bd9e48aa41d1852c217cb885a4238e6234b5bd2ee5771a3eb2e70010056438744fd85b4a74d5f080256d65789967c0e0c835a12a36f7e12c32f42107514374220d3a19fd9bf6570c6a53596cfc035024bb9fd1aa67182060f2e8c115a66376d445d840b92b44105d376af967528561cdb18d9492d15c6d7dc2562b310fca6cd1d7da395fb6684467b5451afd1a485aab16af8540247df46be18a78d9840526e7b84bb48c45fe8bbe2f8a43149c04403326ae48b99e684d1d30201fe904226cc3c453dbf407ca84344e882f47c1d32b93597f958c1642d39b23402d8ec498a529534eabf50365f4845e68b34d89d8910c5024dac2208e8610e5aa536a0048d0c62b5364233e96b690124dbdca104adfe8217e3472127c15a8a0ee55a99a29af316ee18460e9440f6192664fe0a36b191d5048eded163ef0e0b32a1b81767672bf13d6b881ad6833500c2418d2f65c530b100689b5f368956a92175425cdb0b2fdcd0346c73f148545d463c99128a859e64f0028447286e7965b58374023b94804bf26a56b88b55feb0b0de8243cd3c1aad0b12affd69a9661829bbbc823264edb8084ea4a71212cc34209af973efb92d0d591838695b91b44da5a88a71a1b0b2c583951584a13c872b007167edaac130aa9fb2386a66f7c83a887af6a7100e9c80e2770bd4d9a535ac7c40b78ffbb148bdead7a6631824bff5da6d781a50310bd827cf0345d8c2d15060995824f98ca752154da4441f17e0739999854eaa6474067ceb026fe705aacfe0c1cb23a192f4d38404b7651a9d416b139a4ba0e7191289999fb41127e2937997fe39f83a090a1d15fb27e689ab7fa9254b79d0321966cd4253c50c197886a7f35209421038d81bc8b66d124066f78ac80936dad17c0cd653244e80771abe442d2f0905da80ad50a3a994cfd282cd7b727097fa444aa384e090668ff174b86e8b072b0c938bbbd9f416b0d9f1a742421a7443eab4a0d66298764016168f5630f2f840a3744d4dce2af0c41f094a3ff6bb57c6af71c03a255939be159379c66fb0bda9a5bb47ee375aa6f9943447ee2cb1b916c0458bbdbc4dca2497c166e586c70b9d47a53ca74a5793537430dc7
|
|
+2.addr=0x97473985d04723299559f49b856effb47d7abfad
|
|
+2.pop=39be1ee617d60e058ae6d51566dd8d4651d339979c574fe8fe28991aafb30c294a95b7954830445237bb4344a57061997d26e8a42a3d2d01846b09a0e113364abb8b13a926e6e5d35154cda3662d5043a917f2200c2ce5a04473d76683b2a6f41f86eebd29c82632066e3f35a035882b22282bdcf99c7b1166d5b65fa0d435f6eba3a556bfd13e141baefb48a6f8acdc4dba8f5148e282407796280119cd5ea0aa6a8902d0b46a4ce8b3422c543ed2630bc16249723c86f9f8d822b8a9df90b911ef4af4715f9a91537d328951cdebe4552819019f293364cf6f2f1091d3c4c83c9255947b288fb275000c8dd2f27e745e8916b78da521cf4c53c7899793453b5faa4c1976e8de749b8627bf8b9ca644261b20b1d0157a6e60fb542611e678e991baeb07a61d29619fc39a2e5bc56a520e96756a3bf9643678c132ca32c51946626e6613759749ccb31aa3ce7e10f90745af28d31dbe31d669d427422ea0fc19a1055418df64e9eb37fc866f168c119c735950bb47dba6bbe5726d31e8735ca4f988a2026b2370a7937b71436affe64d004fe7079518a2f462397f641de74824deb6e345024e92b553b34c5819c84b0552ed4f5f9d45ca4e8057687c98643ea6cfb9e9691a5527e816a517600c3c7d87146d7afda1298ad1df49d006c865d645013bc9d6514c8edd1e9f4a88620f959a3a3ea61ecf7d5c509cdfd7c2ebe313d95f38ccf1d84472b3f397098c576091ef65f228658f4ba6d6becfcc4d78962b10d5468a90a1d0a8da87d9c9b9079e4b8a70b87bf6575f87e530528306a579112748c248e4290152762af82d526cb026703736c2b4bfd2f96a5fa84afe37cc14d34ec5389157166f1bd1c7a56405238df7180324d6bd9e7f1f56e5b9525964120ac5d061c7891b9593e8452608bfd63a63d040
|
|
+2.claim=4629ab23b0d3e559e9beddd8e37671d1993c7d0f07b29be638fb92886269eb123384e5cd5ab18fa3c9828daa6aa99396f1c5ac3ae9f51be80155f2dc9ad7301e01
|
|
+3=b991d68a909506b5ec27a59c86a2b0b815f1fc8d60a9224f75f40b8b4fd0a73885821d9982e7f829dbf24a824b1a85292145807041d10005944d107b70cf9636a15765096ed8a5320797415fc709456a85bb47037279d692bcefee14ca4284b9495e0eb80353461c10304d8ac592d665aea90f30b2ca0331e84b0139a4c98e3e47bb48d616198ea14b8b2dfd77453b4065c33a2d4daa44976ecc4d440b772f43700e341c22e146026e75de104be7fdbe4d95a52cd40997eda2a0092a299b44d4274ceff272c05abb0bc59607249be4a58a0093f2fa34c14957250d5bc4ed23339d3a2d0750a77e14e8d107324ed12938c592071335bcc165ea62009145885bca6e2a6937ec815af86c670d2abb119488e2056689090623578b9ec28108654c93806ee0d664e2b7c53146fd981b65b177e8de61fd8f3a47987e6ae66221241a68e64534ca22351c8990641210851fe997b669f848a891337bfeb0faa42e88bc406741cd943685512ef7bfc65440e86340dd96b57408cec4d1648550129fe838e201a86164b081055926b6fae0b6e5f65a65eef5061d6d40681c648c9aad426927134bcb2e38ac7b63e2120a97b21007d553db0dc64be0b2ca1a2c6449c6f9873496b49973af9ca1514e3217fb0608aa3d82246f55dd6504a8c8ae0ad1a634d54bc1c1f0bdd008332817f25ddd700244d68c0b6a8f480cdf90ae1ef1a3a619961bf67c7208697151c2af54fad43471de38739cd6c4067a056587542782a422325a174db998c552d5c48095a0ad555d8b784d32c3645ac4d099165071d662ec365587d954e7128db6cedbc3172621d58c1b242d4a202841374c126c2e80a8830d570301717936b2c328ac7ec61379a7bf1b06be385162ae0c8139d25b010bbe166f1899299862acc316ba59a6313a6bc6a10f590248b2575e243f66be6d62b851bd685413535894e2ab09f2519290bc3f701d52e2518276621df409172f3695e628580432ba096327ce4efb170ead3701c899a7e84f00ac926e21564cf0a78eb662f5df31c2c57540423039b12f402ea20135a62d3c4d90fac5ad8096bf7ec667e919a006ba518a49187744122f783d12ce69a1bcdbbcc486b4e9d2f81c6bd09839a5902e575aba9ec4c81629e6b3e480d74f81aa245c546185542d8a2c1c39942a6e1c6a32f94a8d201eb85b6230e9dd16cd03827eedda829e8f35e6049e9725fce18066a77dae2456c62c82790629494b699a8d648a853eea8d322dd869005025
|
|
+3.addr=0xb5e768cb3117ea25175f51aa956b48691025c2a8
|
|
+3.pop=39b4602846b08ca6db8d14b399980769d05f8523772390259518a06255d76e4a4b35f117f8b3ae5b9b1b9eb97d8ed40b382e31120a355d56092ea5c928ae244f9295ca576763a51621867c62b6689b06896fca866dbd5af5d854e1f6f334d253f760ca7bdce42353ea6cf8528e86e582b0c57e10585366932664b1af9a155a0a18aab48c4cf1458e22adbc3a44d6343e76299d3178e8d0d574313d6be57746623331150b398450d38d89289cc473db21bffde60fe3b7535636ac1cc4ff51e7883df896cb2635e71bcd9b90a4c3704a20a4a57d5b3c8d9e91013c5559bda6feb15db2a6ed894d21680d79209f9cba2f6eb3f06baf1e49e958c191af84cbae23187876ea85e2f4ba713a278ac2e13a0b3e624c287e370e9b39cb7fdd9acc1e5ded9252566f03b172350e01698e5af6f8372dfd754eb41cc2c3dd8cba465636fb79870de5d657b6b37dc2dbb6ea3098151b304110a58d9a73dff5614faadefc33caf682768e71734e74610beda1fdc435bed2fa726bc78f08de9be93cc1c9d67410b1a5824f18f4ba2d39d0463299c2632e81280e1effc15575a0ac91defae5d08fdd625b7171cd213467b4b9725d96195cf78f3b4dd5d85106254bb86adc55016ff34fc40622cd38107b7e30e662f25351e28f31483109c8a0664d9fe97c72285be366b0cd6791e7674ecc69e0b185c91149a0d3295bead53e95ecb4bf5bd529057e23a0515c0aaec189852939d8bd6b4d0a8146d48b2fa76fbc6a3f0426cf2f50a87a1a9f1d099f59ef2f2c17f183e630a7cb87017fb65b1b4f6daca87865d72c49f29094c966d9198dbdc8679d416cf4eedecf9a885c6ff3168ac3dac512d8622e9553712e113c86caa16b4dfd61d01e6abd0177eac951838de45979e8c73a02d66a53ad6416c999c2f7dc38
|
|
+3.claim=4e6ce5501d4754a03f1288deed8cd22ac25451a564ca20e43b2776c9b4ae77374ad67cf6459b2a3e8e31bfa38f83cf5bfbcf3afa91f9db157ff65f2342a061e800
|
|
+4=6e9ada38d7da61bb7062c6812dba3954f433ad08157ce4e9d340c3bb80d6b9b1d1027cbfe1514b2a9e5266da4757f9536a3efccfe15255baa4f48fd442d9c2731d8c63a29f936c1a6908f96fdd393dcda5ad19b81b1ca5c4472cfca358bf1566eecd9e3082dac612c158cc3788681f5f0868ec68a06cb04621465a4fca948f7e118352813e5d2138366c97296dc15649c99394b1bdd0e7969f913c255d694a989d75b6499a7c19bb1ce46f313e6a2fb6f4faa7ba63e4814e3348f7ee68bef4b823486dd6baf6f5b847a48b78bc1003bb125d3b26aaa9694a026c75da351064ff868061a78543677db940eb33a4636baa3e756948d61845dc43c04595427a6e9568a216b50eeea2428d82887931632a5a1d33803b392ed142bbd5cea9f619ce563a3c7b35d2f0a7709ed1e20edf0754f3f60aec60b329c0f51b2ecea714d079d2d4ed5f58a737feabee9c26a0320157147a3295a0eb00399eec3bb82d0a33a9e18789496f4e4d6dd6f29f106eab227336b49f688f95b33398c5489f5c32033cab2176749445c208500778e3955bafb2521628740896a9525d85d61aa2220379f8bbe8a16c44b45652d9ae7b2bfd3664a2a64133edae4b4edc930c64e6d99f97d707fcca1242467c9d0c71c441e59073e0d879e3af0529fdaf99eecc7c5219ec66d2c61c8294bd90dd53a21ffc0b230c6f6a89142336478c1179d6ecd91881d85e1e6535c1692979f217883feafc45b9a539834f0b9d74554901a8b83835c983fc43fe41141281c5234f02d50ea5f7a774a5d4dd9b8aabe902d2d0659bd1773bb62a5b1750a75f24ae7ae492cf2a5469563ad5062b4592037401ac334d8f6b2beb46a8aee678c11e98503e0be846dc5992e43b2019085e2872baa217547855e2d5b9984073b020b5224b577352c1a4bb900d8f5fd974c2c027cd633ec0c08ccae82134453b720a67b78e5d01f617343d81fa0864d6b0b1be09d35f1d707b688d134c4b82af9eaeb8908f40b259a8334c04a5223074638a82046cfaeba392c21f58f0be565492958f6282baf64d98a0d6af810490705136d1d1fc16e43b4668c9cb4fbfbf58d943ce5de56fbc5e44a684990b7df050981e559dd9d34a3fc4962b1282a15e63ac0e85d8d5794cf15a94c9409be98e9652e59176689d153214f2c6d011aa41f5709e536e267a9c897a10dc61081e012c51a2467464023c1dd870091db16b54665070a4db581cca14bd3843c3d42e907ef1f7c053d0a535a4d4f92752
|
|
+4.addr=0xc3314fd768bb68b986e80c0a14175f6f72630d7a
|
|
+4.pop=3931edae48178015ea9ae47ac7914b8a18807ba47b01c97594f93a525872b1890de7dbf73aa6d65046899f7a2a051079a6dce8e8ee918d1e80742ab18c8659a03fb333109bb337daecdbe6e9bf2d9b18c550e955ef8fba133fb399b928eed422978de91d88212d8a8531e9be4e0a142d52a65a11a2344c4a6712d874736c10aa73507322487d14bb9340c9a87d2559172b169f3e1137b0f0914e29eb89246e86e7f956718f66baebb95b8a9ae505cf6dd2cdccab85606488739884b94a8ee7d7892fba94d73b5b3412e27d25cadea735059964b4410b46ea2f7a85a7340320fff120ceb132b77a11f46d99de2e0640a794b6af0de8f6d064dc1a8e81b6b8b6b21680d58cf9d3c8d01e120e4e131c769f348d5d6d88fcecc71f9400c261eb35420f41cf669286b4f32f9c34fee5b09ed1737a241f37299bb155cca1906d0812f3786b2190faa0f0d2780dbeaa07d1639e442eea5411293762cda58c4cf72da77fc5b9dacaae853a765c37cfc401d5abe5c8e23ac95b29adb6ca34e433a9848a0c228791c82fd366775d897aa2aedebb23e967fb7badc340ad78fecdd6830b018f3a32342d36525b49c49ef111cca9779d01549d2be4911e63c8d4391989495b0ec3c1cb536b6f6a19ee8cc90c85414161d63364e65529486906df20bdd1266a568259cde459e28a17456790281668ab89dffb4f8b6dd92eb6505719548a43758023fa7bb328ecf675ccdb2a7d9545ad428aa2bbc236d055d30c0e069b3ad05c15a9db4838fc56060feb54154f9d09b3641fc4f25b3060886d23cf33689e98eef168eaa619398e45e260e807b9b8407572cd170df1c25f0884471ff251ec318fa26ae7330e1dae034ac1b8d6d69a8d1163beaa078d475e25a816894cd0903ce4c338ff7072316c2e20d15fd5721bd9aca0
|
|
+4.claim=9924a7ae89127f8d98563bb87bce744f4e4175c9fe8216814702cd109b1058a01245d7330ad19d18ba96bb745b24350119279735a28db0c948f6b4c093af2df000
|
|
+5=a2b859c229911277f188666a63981fc25ea2b38df500cc8851ccee2f467d0fb1f8aaf84f9e757b7b5db61479c1a6a196677ff6d46779ef8d910a78604f04d8591c5de80ad1c32422ccbb3bc71914cd159001a2c78a9a00480fda69321a6ef54104bd0d1a1b8764d537b5909c107dde111786d5c6b943f52a06bebae81ed7168066aa0723ed5de103d0880994341828d3bbc78546b5e602cd842baeb162c8c099bf1112bff3f3ccaea4cec0ab5b4cc276a81351cc692d463cb6e1c4573036f1d07adad56f0210ee755c474614cd7ac618afa673197716ce24cb041225e4c72062873c8da49d13d11b70e05a71a35b384a90e95290735d9cf1ba9d0eb0abc5aabb728ad13d6cfa3ac2819411684629ff07db9306d6f5c52ac680ba31a2e1e41b1cf0f1b6d190ed3ad00470cbaeff956e7da446016360b515d2da9dad49f26a274957e45a6948843b0ea49c7995403667885a86f6f116e52eb7701615b75dc75801f5a5855c5e1b262746ed991aaeca6f3b9b59ab0406baa1e74a33617dfb6b54afb796c1d2299be9aa68b9bbd71c212f23909466471f8b04a5801408929474ce5304cd87801d01e1e8ff1d2b0842f727bfc3611138a3431e12867bcc000147238d659c7e241703444c26eaa6a161883a91e4e0afdaf39cc57d38615fccb1edf56a2adf1e401df1d5100467ac261772d695f29be1b3113a2a6f8e48f1b47380b97651a852b2c5da942a3ce92d17db15a669a4eaad2f116a25c4beaf1f9d72bfe1d665411c28041761d0960f5d3995e86fa15906195b2a1d163dae8e750b1a5c06b5fb32092b0ea47501da5e6d9a5941d82b5704299ff56e49299ec82c62fee9828ae56bdd2a90eadcdb94fcf2963d02349909dcf27e02224120d6b66747dbafec302bbc6b166e5eb3692b55a35495b15af063bb746d8c99c5c81719d42efb8d851537f875f6deab96b5860f26d6d0b036aa62d8f744692f256093f61f9e2e669f87feda1b60ded5d0574c521860665472ea9d44b1ba317d12e7b5480aa449c6d55f70d7a4341c22560a037b30df071f36573793efd2b098a6138cd74265e0493b71a228463c00a0260e0cbddc7905795261980edafbd3d30a0102ed9bd9e99630116341ef583f387e9ec5f9a6ba035e33d6b6c96faa9e27f6420a952496b540badfed26ceead61d590a5eba9f329ca9a5a0d562f4d0137f643128e6ee270e175c0ee0f5e68c03cc05338f2dc481723857fdc42d9134b908ae43367fb2601355a326
|
|
+5.addr=0xe13aa491abbc1252dd714e7ca0e55717a2143eaf
|
|
+5.pop=3947bc4a7a6698d2b7889b89b6ccc1bd89b468001e7f27a031a2fbc557afd233937be4df7a2cf67db99ab234796ae4658ab7b62e3c5dbe613313139b4d63db75d900f5fbdd48bf43211155eb17f5f7be91764ee35915c39d0f4c5bf4beccc8ce8aa59683716dae362fce8fd19dc8c48a59a09a888c990754ee96263a22b9497353e4c6a68dd16b8c839ddfca50bc90f38193ea475e8de7455188d166a9e77eb06d66096674c9abd95473d4ce20b2c409bb86d0f00624efcfcbc3f3737da5128486d3045e8a93a7e34a7ba8b4d1f091292c5469a98799e26ed1eaf3c8ca3da56ce05ff84a39d18d65a2cee3f931d1f65cdf2e9b93ac6171698a6466d42f6a96aaba9092d15de72776fd3f44e399b96f1f875dee2a05a24289412e8d0d9e3e9642d6025b7ba34e163a9fb6204499bf066f27a1df9a4c23573e4f6c3b1e36cb3329fcb184b1dccbb3f6879268b753d357863784bb35f09bcf9dd08a71af8d4a5a4c7573181b299a185b864f9b9377ba6e1db2bb6985d7fc8a9e8107972bb813530a66b5565a3328ccd61416208a10d39a8736ac9c5394b6e168b46ce9adb0f634d762d7d2232f4fbe54e079285c85c19d21bac4af9ada96d56fa4fa392c8e1dcfec51dd28a8c1fa176ff571b9596aa9aa65fb6436ca57f72bab21742362954e6224da557ff2929a078e6ccd3cb755c3cbb55670999ae457513ef85abf07ccf3f4a78de9d4ffce5a647f1e78288d98e43893b421de5165a7310ad77930eac3bb718842bd76473fcf2d683b555cf0bc747cdee76d6fcbcc96e59f2e7d502afa74dcc07047699e79f1cae5762ed5632956e1c175ed5ed47893302c8601859ec0d049a52b08cbb97d46373f1183b724cf76aebc469ba3a0a7c0d9756ac32b51544fece178b9a41b4d25bf49b2d03af0
|
|
+5.claim=681a9c3746716b58ed54085ff394131920e0fee87a8970f1395c9a0e61636915580b7828973de824cad866d3aa35e02ea820cf8d2595e6184be077da78090d7101
|
|
+6=ae79ca93fae11c333ca673090a4b548553614bc1ce7f6aa2773e17b972caf48a07efb416581422605f12400494db84accd432c148168db7794ecff419e83d4738d98f6b0de8f0d742902359aed104a1582cb8ef976965502c28bf4466efdd9ae0350021542a563c9ad2c22b7b0da1f5cb832c5a54d58284ed0f172091dee7be8f94bbae38a4ec0a7c1dca67ca50de962ca09ecae9a66d227841b2c66cb8600a1f01fe2d48be3c64999d1f8236762983a80c3a58fedaa0bd09e3912223b4415cde3fe63d70a62acb564cae57b3ab760780ff26c422d6675920eac389b91659aa3738a5055a76a9046f443ca1c101da8fcca37fe0be18fc9c6851706367cb65f035615d3150acbb738c66eb6eacd7b9a1b03b06e4f046f8615754d85e69d262d8674e8e82052bdbf753591474488488c714a066592718dbfe08d0b91bf387d2b9ee6a86bd0bdf96082fa523e5b6851c27723b99af0aa0722b185d52440c9c82a2a61d6729ec27999f9019f071e9852e813c0ab9318e2cc791a6e7203c27ad48a68ed1385319985aace0112e17999c80662b12a135b5e1a2c9067d5e06d0b33f5a691b65e2181b8b7f389a364543a058268a97c20928b490ceffe1520fa52d143a495941996b527712beecb17786f982425a8ea6cea000f191226855eca65f069782bd777baf11ac781a5b77492e2b69c039903c991259b92a93d18fe6ac74e064370f3dbbbc5ad82b478648ccff8ab45d133b1853a1d21d2e7d525027b2d9740bc82fa16201fb16318da37ec6494c9ddd1af864ef8b50b266f1227134a99c40d8571879b8a660964f6217ca41c6c0435056e5aafb494f4763984a55b196ba4e6691c57a66ec82b886e3e9da601acd9a2ac3584975255ae13c2781abb2a089e423c36cea35126fca8728a82a9bb8dfbf1ed0795a46a83c22945b08f6c7048e3d5f3bc7874164ca39b05ea81d9f75e778cea8b01b1c19a8a5e89991419cea779aa49ae6d562d38be70784def475ca78a3ee40e86de917557d716b008a0819410625ba6d3603b53ce821d1cbc0009dc4d518e025c246e5b6904196e22667a9df22192d22195ccb2694e0cba7fd011553081520d24f53344d5da90299c150b968f7412d51a638bb853d52065e49ae471b5cd979b11953eed2ea89c2d1366a48a664502a96dbad1d8e527d2064d5885cd510898880110cfc7ec002de2029e02516682b953a88fa72b00c55632415e9b52eae8640d866d4074880443ac6f791270a208d2
|
|
+6.addr=0xf73bbbd26a82dbc769066550d8d4585eab2fc00d
|
|
+6.pop=3922660f4804b28323dce5ab01be86754742cacb2d2a29ae578cad568ce0c36a069af8c3b1525d82fe6fe92e26ff2924515b9c4ed33e50b43dfdaba15e3c0e9384336cdffb39ab440c818c3afae4c4e92968e76efa5473ad33162589ad02f710f7500e109240d83eb24c2ed33f6f9685ed7a94fdc9a595c3166b17da66b45193d4cd0bae4aa9cef7ba0a8a54da786462cd85a0759ca4220ab034dad855838b53c228edce15398ba1acf1586ade9a041387d0553b4d7eb36b46e1229f9cb2a1d05a3478e7775ecf24cc1355fd813f9a3cc666517bb7a8aafa119ec67406e2950b8fe99b56af2eb729957cce6a6677fea49930bdc4f715041d17eae29cd7062867f20d0f74999489bac62fa215cffe0a8a4c93d2210c79cdd8a6497aa4d44becd86178eaa612e5c7bda995eeb938adadd1d1e54b9820d8f76748b7cd92c1f4dbf163f2bd968f2f3a2c91491424221bf7f5f796da2ce48919b7c525202418a56b5befe5bd42cb13cdd7edb856b70cb397c653931875deb6c5c7e0ff08811cd8763edd9a8f4c91340ae6e5a74b1b2cdd95dc7f24e44e2d6551ae3adbdec15b6b1bf54e1f88b9eebebc736d6182d6ad3a0c77d38e86397449dfb266cfaa33caa7c20a9a417ebdc7cba31d6f1986c4985ce1d96c4fc1aa24957543f0c93b64b0731b2efb25ca3a593a764c2006c0feebd599cdc72299e390db05ccc55cef9c7debd0baf5d3fee5ea3f1abda2958b6d0f90ea95892a2990aaa6f7da0666a53598214600829c09ceccf9378e6fabd346268ae702853661dbe3719057fb514587ecd063911fda42fada8f64ba9a6e1c27f954e2b0d9691b7146a16c78927f0202ebfc750815038111a8189dc26be8cf419229457e789132589a6c65dffccd36300f345ddfbacbe37d49dd357bd8590badb480
|
|
+6.claim=6a5f446db8033ce9d9d20a26405ed248c85593ce317a49d7a7cd6e3e94639ad678523869098e091dd6900eff856f4d29e1b1e29f456e2d290503ff3853d8c5a700
|
|
+7=b3e68f6854452ead92a798ea4db7116c6fb4f249d222909490f1837648185d207752134d8830bb9949597b70e7fa8297be87eafd8b7d116d1fece81701e0924d6a745bb64e884a54e1e949238e497868d2bd2960918a07a3cb1100364043d3218d2e76ceae07859de4182c85f7080a6baec87cd2235e908b2ca1a5c2e903bb387c067f2c514aec16c42f1ecf45b2eba63dad3b08a2da6bb6ae485156735261194cb8426fb8d10686527c4567a64195891acd62ba2c368152d2d36c5c24bbfea36412a74830c00135dc21941cea0010dc6d5c14ea61d1181f2db9ece691f151f1976e9a4a375d75964dc3363699f030ca842572c8e322854209f796268bd831e2975bb26f0c43332c2e7c5f5a959a50e7697e218f968e0039664e585a8fd5204261d6d29c287f13dc874122a3c3649169b0e6a2aa3dc93d70dfeefba3aa2970a788112f1c8085802174759594f33fadea69a413e5dee35f8dd13841f29234393a59052787cd8bf4b5f51b8ec26185ef65b788306f317121386a23456a1a64b1abc415d4b4f6281a8074526a19e8dd51b8317342e1de9f4c86a4c7fc90f64d628a909f5b0a2c146fd0b6861165487a75f606536a7abb9aec8571984a90b9b254447df27945cfec9f01ad1e82e54ab3617d22d38d912a4fc93c8bd4154648129bd17818892004605a7a6980b2a54842c5c6be2ca0071527a5b279156983ceea138ed86d93808b732fb492a036088c8864b7e1daa6b589982aca418d73358adb00aad06da91845f80723b4b3903f79f18fca2e3a49e31a21253bb6fae64f08a3350951a454d0fc84cece51f9ca3504d8665933088ca47c2345a744410ada4b41c29639299127c5a38ec701aeccb82a1caa59c0abf4be05bf4d10b119cadb9382f5e785900b70578a3de5659d2c1dee6a5338df1d0b90c293084620b9bacd2602839f75e83aa4258e03be9e541437d0481af11535d4e049b2568190f6cfaf2ed6b2e4d48e8979168299bf96fb192112e99a4589855ad9470a5a8f451e8a61f3eb4a51885865080c8dbc98e71bae8f0c4ab1e15247c79d207a5ad11796c85e6e62733a483e0f022cb05097243e1e61143805cd3ede3cb2640aea3300829821276803d1ab1898401e0196e070b89cfcbbc194e86f49108a45e01bb4a3dc4bbc73a05b5d1a674a9d28b16958812d4ca7bcd475b5e99957e9ee4236506d33f5179e6f804b59db5bb81f0a94500a668302599121fb67a62a4dc56048029c907d226bfcdbf3
|
|
+7.addr=0xdf09b32c761620c5be77da398b97a64f03c3980c
|
|
+7.pop=398f3d3900e8f3360dc56b9c672ff214b90694d4517b3eada26d2dee11314490adbe600759bbe186542c8fc27b6b56e36b28376d98e0b96bdbe0bf28f7937068fedd82690e5e384b9705f2fc47b5ce632a92aa48222e843b798809c2cae6a2854a0913476fa68281482d3c5c928742afe84a2ff29338eeee528814ed7d6f4d1b50d8de39fb0ef6f3252047287dc4fbe0b236d7472e11128479eb2c148e331ca72af9fd3192e3a13a36565ab2f2724ade7524280928e6b0fb6bb492d4b1eea78fcce25abf5519f76e22e56ed0a186c331113d63bf1d3a8f220246f2fcd60094ddbf9a2c444ab1a789a8ba9f1f4f567511860d6d4ed8737683d20835de947f9b96d6827824abdec344e00d7418e7b2bdd58b711ed2e226d23d926cc6626f579ce214f950223b34f628689aedd45ae0cb1fc914b50bbc2451246dd8be412e9a1d20b6d4d3b6e989d2d00475fadf15f496675cc021b8ecefd71a4d8ec451a1cf772bb31f4320569c565134bbb48ff7ddd15311be25e30733fd244d666abcc6ee4ce2bf30494a268f17b69d5c1a16b67f16dfd8f0b6661c6048caf394a7860a576ee790ee66dfc138833ab9199f12268b509776cfb587cd9de8b4fa66a86ab197bc9366cab16e6f29b57ba02fd7223aa2cc579b7515d3bdb33cff7ce5d4a98c121db7361909391d2dc656247ba31071bd62088cab454fe65d715db188775e66bdfc3bf339ea3a76598521fec00f2a0eef651a2d11044ef8ce66b948e970fa293d2b8d02c11cf58f0aebfd3c7ed22eb146b1ddfeab7110ba3338ec5782e1bc8cc70a10cc1e1f4a15eca6334cf6b35fa26d32da9bdcd471b50d461c80238c91dfc99f8a1bcaa16c9c643f253c943ebf497e63cf6acf5b6f7b967139d3c8345f9a97d5ef8365b44739e7493106d8801091a7f5c0
|
|
+7.claim=feeab3b9960c07f94214c6e1b7e93752d777c5b70b54a4f397b4fcd08b9bb3145a8adbe7191e449054dacbc624e81cfd55327bd8ff1a63589465c2c3a42ec1ed00
|
|
+8=820cdb49fa91e522cafe7550a586b94132cae78b762b166f6bd819a1a25409c534a0846a6173d047cfbc67f518518f1fef1c0ed22a006ec77175f78b1ba5240ec600a721e7c8444a770bba44fe186a5edb2a8078bd55b823ab4fd0b6991748d142dc710691d574d4f64768167776ed9559de1dc6a466c5103585602f0bb21f2a85b1a76fe9a27ef5d5e6eef099d255c841ee8a12481d9bac050955e049398e228a8bf63013ee4a504a7c50573e65193872fa271f58cb848205112b29592d9222c6242e581ca10bb10ad04852f276182a1db822d63e66926b9b2229b8551a06520f9c89828d053864dc6717d107b9660ac6f5ccdc5696e013774f28a050ba02b787c4801139f33445231b87d44bb0ae5a8b5b16dd08ff174221f51e00bc4ca26712d6d2bbc03aa918cb95f999b23a4d71c1846ad5ab887f71ac294f42359d33b9aa6421d604b1e81eccaaa9ea7787469a68541103cf0a3b8234efc146cab85f4900f9188eddb6e00d68eb04debe0afe14572b1f924de61b610daebc7e7c20b18c97787448e199a79d5316e9b8c2e695b3b030335dcc60927d8d62d6526a4fba58763992605508ae16e3efd27a861d1796c0a6b746d4479c4fbea6f51597c9aa2062e2b8538dd1e85cd5350095472852e15d09b68ba1572c466555616134c8caa3330974244d3d31d00d256b654f92bb5bad3d75f668e69567263c1ae2e5ce6a2a218468b1c02c89f971e474efb8b59283578443f79e425a06e3ed7c344176db59e899a180eef9e0a5440ff4570b385ac700cd7fa290940b9201c56aad19e584ee08a19b4e38bdca2c38ebee649c404495df9ea22cae49b48767eca88e9e784319598688df4223ef1890450c597b2519044230a209488a56856cd1890045967e12006acdb128e4121614a1fd5996df927b6d3d60a84bc362cf4044b5243569639c19821adad4c4e09839a1789b82e9051cec285e611d0ea0170703e5f317496dd0ba0a330ef00bc7e70911463c534be4c1e8296ad5a05256a72712b9cb31d5adb0b4e8c5f89255211d1d41c121ce7d80f1132ec33b91494cd7c22378b3bce21b689d24a9bd933b68aaa917a8df5bf9513014897fd66d9451b62e30fa7c09d5116a11c5f2a9bd21ba718362a40484fe6b93f76c1008316d552bda724634edf50b184eba5a0c1413c17e5b82b16762629746fa5302b352c525e97bc189593e93adcd4430684d2c0237117611f615edfe21c8a4b531354925e7638570bacbc3868ae7
|
|
+8.addr=0x1bd5514286f5602a6762b0075266379d29af1c9d
|
|
+8.pop=399c665dfc4c5a84e8660b229cfe2a8161e7affdd52ccca8ebbc9d191ac3f11e6540419176f45b2f5e02fe61ec33d485c555e399e197340758845032713cdae695629f8ed40b8372b89c1ed629d0e136b39670412b7b42699a6fe6455312edb7b18daa07fcc9d20d9a5fd2671f25bd5ab0912472c1c3819059ed37b8d7f85b88a0edc2ae55850893929bd5533840741abe7d31358a775242a17272fb71f5e3db158f66ba58d650f0c3fbff7a4726455624c4e58c364e2a3aaed4b94b0d2f3a8a757f4daf7faa6e79b9c9414e5e4c818c71cbf6d7cd1cb92cedd94693c08c312bd3e2a29b49fd8fd16448572ac61706f1cb936a1f29d87d1bd1b1d92dffa5152f428ca77f5ac672e65c210fd52e08e2ae48327f6591037c20d02c9a39855a273e36667bd0d3be9306293888e625343e9c4b23615d389c4160569d652f41b666e1ca690742d05aa405b5bc6f628f13c18b67219fec8cdf90c3d27547719ddab4d4cde7ad8ac09a895c0693689bc5529c0c41b41f8f33fdcef4e765e24754a425914b7ea2684eca04ce678d46fccc768109c107baabd7cea3f88843a14fb20cb6ae0a13dcf25bd37c210cd5aa1e63cc5cd582326ac3a53fa2e3c693529bbe4ba470ffe5124222b8c33aa60f74f85ca177f207e975dacc770b4c9911b87c15caca406c91af7faf41103a2d31aaf2d5644dc77aadded8689aaf723499d3abf76de284c3d0b2ccbe78fd4dcd23779988facc290b452496b45908aa16a5498b6c5858a27da36d25ca977255d9dac15548ce0dc21da2238c15245e7ac973653241f290def8abea530b855644d23d1f6548a4ee76cb975988235d97d518de6b9b266d8c6451ba75c7e74811f7c9652e0e56a48fa44cf2f6eb159ad4b21d8ad91078d251bbfaf7bf2864d5ad25bd9c14e1d1e171d184
|
|
+8.claim=022736cb764b88fee04dc13d648b88e9763c6f68197ff114d8a6127b279248f01ab20c20e680d35540ccc30d07aa33328c800187d96a88f8389113fa1807e70600
|
|
diff --git a/consensus/qbft/src/test/resources/aere-d412/28001-registry-v3-3080010.json b/consensus/qbft/src/test/resources/aere-d412/28001-registry-v3-3080010.json
|
|
new file mode 100644
|
|
index 0000000000..761fc5c58b
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/resources/aere-d412/28001-registry-v3-3080010.json
|
|
@@ -0,0 +1,97 @@
|
|
+{
|
|
+ "formatVersion" : 3,
|
|
+ "chainId" : 28001,
|
|
+ "bindHeight" : 3080010,
|
|
+ "count" : 5,
|
|
+ "0" : {
|
|
+ "id" : "0xa0a55ee6109da671e0ab8e10e4e7de58ad26bc37",
|
|
+ "keys" : {
|
|
+ "falcon-512" : "0x09ae40aeb815c52a815d8ea5ab69752bf982b434610d10b0fb48d28e1831051d900e87a90128f64a089c8e477abea339aacc3242ff74509989510e69e176131d9afe7bd7015fe651ad75d67f8cbc0b54cb1afa57e11ae4c8112bad04325d6ae3e59f304f7cdb62850af55cf6f3652b5a477f0c4e58a32d750c46187b2d92ca4932de3408ab764845355862453755f41599c3e9a019c6b730090135bdc4fd348ae4851d9cb123bc8a68604862b7a288837a38a511bc1f736daabbfbf39b6742286f2af80c5875f544c765d5fd0bd934a39aa3c23544c6e2c566c048d64bf811807523322e24495e2e86288704d6e2f2617981d863558c2fec3fc83ac37e7baed5759228d4306c0d57c1e9bc7038623b1e19d4b268b50adc51de58daae077b8468275ec54b6f84a14d09ac10bcc4c8702e28f7659468472d7cf340462b03a6e9b65446b26f10466a47537d85415f3a1f1ee878142cbb4a4fbf74e5a17727e7ecb07d287197a7ab314d37599359a37aa6915adadff87d0c9c46f011e15b3ef1828984443670614681a88a7ba6215228d1837804ce79636fa721421594fb97768b697b23d7c8a2635db03a97d94430e2aa347928aa07863cd184919f11b22119b24b90352dc2362d57da7030725ac850bab0a139c2c9af74472a3b49be8f5bb4297dc7c58fce8551f25574eedbad0256fb2516014ff4dc823d9090ac426c13f9e9205f5e023ac3c9756e2c3892b24367549185090b4ab254ca505b6a2c5aaf860afa166b3658d06e7b1ce6cb825dbcd05b0491750dc626fda7dc8b28e8433a8f9b6c1de1c9ac03ea7ab40d4ab81f6a3e91bb6607e9074d3427e1354aea46d9766316d3484bbe1c77c488afb1d643e10f40566da44b47b0eb94b15ecf00aa899a7df905599c6fb73ab88b8968dcee8aaa7b56e56f8278e448784e69b2a28289b40128410edc418b97e5047d2da2181221aa8d6899e810e87d9b210195b156f2260a4909d11bd5926aee369a10a907c1be275527c81d9c5df874460ea89830422695500aed2bf70dd895186085394487ef31c09f0bca0979259530c3a9546660e49708632dac6a6e0f4320443e1f1eb055472bd20aad65b4da621778d606daa4a8db19d818c93b1af13d087c131622d73038e46b60cf1c00c070b1abe245105c7f841fad070e9dff939b17232cd1b66382985f1cf24b0bf76a1f78096a929254371d7a0e6432d2d21360bd9233c33bbd2e45f548a09f4da1dac60b96f19591f43bc05328",
|
|
+ "slh-dsa-sha2-128s" : "0x194a33b4b82c061956d397a3d100e5031eebbc11bc1718aff682e2847c823258"
|
|
+ },
|
|
+ "pop" : {
|
|
+ "falcon-512" : "0x39c2ac638cfc3fd83565acdb439d9c19c39f58b81a2de8b94eaefe8a1240c0d3fb3f225c3f8823f6aa019dc397aaf6810a3ebef8eda6caecb4c85bbea37b74a4c5006cbab215bfad958e1a5eced57b158d1dd99fd24288bb6b84ad6c5d133536e2a18a8f035b9f42515f85054ca1cf263b6610c792e619a9fba2796ed6a44f98288e78e6cf597cfc45ff55b20f29f46ad5d61d9782b46d9c8f6edbc6697b7cf1e9c4d85d58812b6424d669a95bb6ee89e26945d7de6d331aefc95fe7e2622ebdcd9e75e499f732c0a0addb383202a2cec4b2fd185e73ca7eff9564366c81c4c733b9384a789ca1b1a210c63dd0b60a3139207018725e9e3e7e0d97435b5a5ee4184f5c5f487da999fa953b508cbed5224564c8a8b0271dc446e0ab0150424f9adfaee7f47024dae9859e19ea6a128cb9ea3251cde2ca5980c82f04c3cf748b48855b24e9b57e256495ef0aa4a4e64cdf1cc292ccc133122421d029b1855e0c46e9683e77b5af7beb9e7458e86760cbac793e620b9c63a19f1e4d95514bcacd9a09ebfea3b117355630571a648dffe812177f80e153109360d9ac1b130d3b1abbff73ec70c48d4da068f684298ef44a616437852f94a419e916bca92f2310dcc6a410d46d842d849e8f5feced18fdf895099e0af93762ad745bc61cbbe8857fd30a62ce4aae8c406ac916ff38648d0646628bcf241317fd04b3d6fafa47d15c41319e0f3d189a6162e8a6ee7f229738cb67c182a932d8864c8b641a0d9e1bded5d3f7d98c6247172c8228311f7bf2f51bff4bba059b37858fc7550f264ba7b9f5b386c239c45447a732d1b5092d27d2c1c9fb55cdf322d7ee6fb0e497cca96b9046c9595a3719f24658b638abeff138c7bb26095f6656984526de827fb169d37c6d2d6b0cceb890d993bec48c667d07572b",
|
|
+ "slh-dsa-sha2-128s" : "0x296154dff61693febc3131f0d9202eb15af3607833eaa76489c4207395b310fae767ad17e303e2ce258842b01a6178cee1bc87f78cd332fd7511b393bff82daccb729e102a6fe537a9140b772ff1708a8f175659441241954507fe5d8e4d9ee3e64f490728f693ded8b12850d88bbf5bea693aeb0083afd949557a609be95a7d9820f2d5aa234b729a235515c0faec6c6a050c894ea0cb357b832b38f6db77baa6e1dd2d6de5dfa1274b0c7879ee66c93dbdb2cc7d53186489a4e0849a5e6433fdc945cb6d6993f51d0c7e81572c6c11f410675eece61142316cd7530c42fb2c42fc98eb115d428b27e97f5f1944628d04c7e9396f8e396ec763475d508878c1a2a6d3d1a0757ea4cb5fc51b07c8e9a2e5bc05916e4e3bfea8dfce9d36fc8c9a29f2c333b94b00a1a7a51893182431a436fed92338490e7949b27e8b97671ba49a21d83180dfc981d0dc116e6f0c5bdc8c825434e9bbe3cabcda4fab8a5d706dbf2802d0a5bb7e56ff2ecefc8ed5bbc226dc23fddf7bcb29c59e2a3443b01e77ac984432af3ba3cc518b297a730c0a4a7e6fdde9c46461b0ffcf1eb7b5e99c9df3e468b28eb202ab7e687d760f540017ad310a5787316777d3d0749d56f50a9b9eb2dd732abdabba3f2251eb006f93b6cf7d071a23ed47f42e10027f82f39610781f60dee5c14f23d8c310ec8d72161d2570b9c6d1c6868d436608aeec72cb11a56840828c449b8eceae068948b44451fc71cbcde6df81e58eb60cc25ccbc9c1d2928090f9b6373d7f5b6ecbe97883c38c8e9faecb3835576bdfc99429b55031b08f5bc4e71c45d4fc67704e39532fa41c7ec68cadc83473dcdc6560c82bd0ddb9b04f610757a38b39b68aeda8a3b120ae886cb11708656ce27891148bb1452a8d7daba35d7230e0d9d7d08ff3379a92287721ce7aa1f504050b91953f7b0273b544a844b95411c635af6113f42a4465334565b54cd69133e7b5b362b4e8ea3af15e34abaac1c65ed3692c2e7e4fb53a9b30317db8fc6258fd3d26a051d583c593335a7fa29335d28d5a7825dc51b338341c668c026ea747a2d10fbd95c4cffe6929fbededea1be2ca1a3ff2f59d309887353e172b6b3bdf6368aded2ee40ced6ea6bddf360149ecc448c15db1eddd8d85ed2135562862790ce56f4f5a6b7f632fd848e2b64b8ef8b94c298fb57b3abd88510f18ec4cccffa0723266a69fbd73a18f20d4718bbbac39ae8cd3ff2d1952203bd470292beb46e4b3226cc77b1b46c7df5e4d0c739b38ea8237fa488cc4a39d4e357d71ee609e5f9678a6feb33308445b6d4ef6c9221766c6b8b3f6cacac9d3932909ba8f47ccde1c0e5649d1348607cd4099c1a396683e0facb26a252f6a210ac2cdb72bf5c67929bf8d276a83018d94ee9102bce61dd675f124fede9a5a1c0c95600a7607aa01335ce728d5889954a6516ccc65f9a8cf4aa162d96eb27717c5ee43912a7c877359534dc8cae333fafe66d685e741b88372c81ce71abcb5df74bf3e7f731cc17a719790cc56cc7397339743a3010f8b0f092aa8f3f73432f9b2df552388d00bd8caa350998d32f8b393e063378d74d90d02929787876d081a6922a584cd4c11c49ee76f04753fd5a3bea7ab96f07ccde2a6f54e8799d58d096d99ce170a4fb7efee1c89bc403c77c8438aedf65cd5fa62346f366189ac9d2e732d282888aeb2aec004fb3c01384c97f227b64c749299ab301c0a11f321e127bec6e5a12641745210f59c5600dfebddf3ec9d0648d845907d06b62f9ae1ee88218940f675058bce88531c5ad7ecef046a6a45797557a868e7985a035ea55e01d8ee0251b7fdc270c391e4ca9732e1b9e37a429bde2817ebbd17387bc5ae5615fa735f07de0fe393762b9c8b3832d6e938ccdfec5d29a534ac8634ba147b0e68616eab64e82c5af71c64bc5c8fca9c3d62c570687cba806a8e2b762479648dd562dbbb727e75f65f40605df77466984058a3569b47388e7bc096f097eb4facdf88a8d55ae5f28a17f1f748a552fd0e552f76db1e644370bd0506885b3882bf4c4ed8f9e969ddebe5b66598104e6713482f0b8b28956ff59fa84f65ea23edd46f20d53bbf04d6de6936c18506c867a1a97c47c42239b82f799cbff1e0e60a1b5cefdbe61f17ca999b3712a49011bae98038d4a5c39f7d14b62488e22bb560b4c75306ee750b0ed3251d5f9ada93fbc78ffb6b7c1f54d1b8af4d6973a59e9d2e22b726eec58fc2f6bef614d90b4af7a4847a7ed36a4a04419df878ebaef09a733ea07e41c95c0c0d0ffa0f76df9a38eb0e2e7f51f10dcef432c4f9b884e02af36047c3de8e6f7fc926e1a4ded2e7a4ffe2a5b95f6ac99cb054edf4554189353aa02cb8a547d013c121faf7de45812fd9143b66486730d6b944f2a56cb66ca40e003c3a0b78536053a3fc9cd3cbdbab566ee5140e29cc6eb68c8c11c79018213b80111e5d5b1ba07ec3f1f02eb7976a1f1629e6dc21f6e909f319ab39dd7b8856af996aeab71a61b8cb90b1cbfbeb987255fdec4283898a6070a8431ac52bbb4537ac0ca5dc7cc30bf02c405193ffa000f3453013cbabe436fce040764845ce61883ca92d9ee742050d8fe16dd7495e8b22d822bf0f9de54289039ee827b01783c36091590038254ad0018a48a8650c5653fedf84121fd8e6b916c086faae7220347e91460271b1b56f25a3d3002f4abb2488f84c33e89b0156c7ac0687b9309569d22fc7279cccd10f006323126e1dff63134236173b7713e02df389866021c3384fa6b5ddf135fdc3e9b8230b85c0c70decf1ed811ab7c0a3a63cd662a5de98809a87fadffe8018bdd24e9babd15193994ff50bef814d7195531f456731503be47d83d52ab110a1755c43700620e9bc295b90ce8bd6680b63d8ccf861f7f9e60ab9c92573906e20fd57a0b628381b5e06fd0c4338920502db37c6e490294f1d0804a4765f3604e2d28828a2cbbdd24dcb2183e9b867000b7fe7e4158fbbe248f60c6fd125493df39bac12fb42003d00f94d6b59ea233635e46ecac111e1c7f987ed1df1d270aeeb512857244f21e071a6755abae2064b87bcc9a3e7081b2133796d5dafbc214747e5e59af441466ef6fd9ab309c7b5aa2ef4bad33083016d0596e0d80ade58122930ea6996d9636b3bd6cbac37bed256f17eb3e336e15ada4a547411f3b529e19a1c8d130777a556ac0b64753718662e7d772fc544911a0083be4b2eccad1201c81ee2b31201ccaa840aabd1aa81f1285a15aa0548db8e3177a46af4d0948ece7e6094f0e5cd7e8722df5827e14a1cb4a1f6b342d86c841196b6a2351852d48a2be37b182741b696d120bbd576cbf995fabaa9c00bb376505389d65146f4ef93ea08ba203afb40437949210dca728d4cb44709390efe3c44f53d50aadac47f920159e37d44bb1a9d8b332a1f6c606945deeb06b1cf47e33d146ccf4576fb5aee668725d2fcdf8cea746c4c5ce735064e412fb51957d26619fb30c8d0be4280d1dde9b8414aacb1844068f3fc980bf90c40deca9004fa1a5243b8d82cbbbfa2950c0c17b9dc315e69fc4aa8461d68fc7ea29ce0d56a4036e14cbe28c333c7338cab56a51010767d576ed6548c4ceda2eed30a9ff664e9174709cda6426453db7f320ac113a016b59ebcddc5c0a62ef43b9602c9e25273d10e5d1dcf2e708e0aa3e64968c9f36c165a3bcf2eae5bafa76f071a8d8e1c9d74b59a902b3a22eef0b19c8778f354b46512055ee8c015d429f8c9543dc993f80d6eb62e111711e88f5b9e4acf8050239a328bf7f412601822c0afe4286a5fae76260d58e0cc05cff53942ea47e8f6d419c7cd8c3d203eb98b9a07dd2c85826cad9196c33557d34aa7819201970dc4d964113cd77f6f38078aa524792e6742cde5088ddd0b1307aaff567760d0f9ff5f3bc564db04b1de645eaeda067f37c8bb6b2b779b5c9a3824db68b57aea881f445072d83ce809a9a66a67bfba866724db96009bed961506360e9a1cf731fb97b07b6b98e946ffa024f89bcc4b470d1adc77610bcdc137995f912f4fbb4fc5da8d91fa2088b19bcac98856c795506f5106dabd341df297730cdd76b1e0ad0ae0bd485914f69d1961395a77777b80ca7b52df11b528f3c60879900bcfdc2f0e8d7464b4b73d7c252029f7f031072eb909011a1454f1f7bb02eaf0b5a90685638060960a8403407243d2dd36b0d3633be144808e8a296ffc65e305929f8c111fbab40d94b071bff03dfb38bdd34fc11e72bb338f2d797a012baae1b15b7dae5a37d0efebf4816618934304b40a61b68d907ff58b75c18472d5bf30eca48f21728adfe9ae7ae321d8e96414bb3ffaddeb63446d9beb8ae660a2c608b1b78246ad46cd863b23eb0aeb4843415bc679ba271bc92e5be2b936a6755f86a7b0ecc030dd6696515e84d9f9b618c574315b0075fb846716d1b3b74c3a71c277947ca26f566aff28b27aebef71213dab7f25fdd83671f1b5f6e14e2b85a652910bca3a4f229fd8d9f8ed30389726fc13add6de5ca1611bbdf054ac65ba477e5ff8df90de7754e83a4f542b7472f6f6c03e86b1cda4f3860866b2780dc7fac815eae50682875dca698063fe610ecd21cd0ec5f05a6b22c0c3117eb5ea956b9394b04666bb3e2a7bf7059a2b9671c6ccd62fc32f437d18f48b25ee765627441a1dbb3ad87afebb653e42860e9238ca7965add9c80f3816d8c8201bd0a8dd3afc230e0bd24fef5655fb24dde7139c3cb6e1f8410130b079a57ecd3667c7eb4344ee546ff079e41752769c5ab7fc78793663e980531e324b129fd112bf47edbd538bdfe36295eaac33115a676ad178fd145e7127d4423a3ca97bc695a9884ef01f5fb16d82c23a75fe6c8f7077569639ce2ba02adeb611945fe5d6421fc6c2fd5cc33862832e2bb9293f74986b6f0d47282fc735b85ae8556cc575472416aa036c019575828b3e095193ae45458e53aa753ad9fc80a22ebf90f153da47c3d3ab429400d63e09b0b4186eaa2603e53a21d34bcfc416edf14b86258f6a448db35d27bfb78c5f08e2233d6048166936fab12aec694a57fe5928ce26a1cd3ed99afb910621b1411307bf50df4db1a4cf25fc234e9fa4d0ef6f83fd578f9fcfc0e16272c14ac046e6bad30cc9dd8304281aa548fb6668d4456990fa6c5480b65820d4e334dea96f7e1551e13ebcc0df14ab1dc4b731ab2e5dece8843c50bd3c556cde751d98027ac22716c81b1a7b7af0070f46c412f9ba1332a6d922c4e4071764a25210cd650568dbd18c1ffb87c100372b06acbd359fdbbd0f969303fcfbc21dc086169d4f64d6602a0477b70280b1d1354e44bdfbbfaf656567421038d52ccd6ebb5e642dfdf782e9dfd1577eb5dde72db9d579fe6ae1d1a470e80e50bcbdd31f5ba6efbac9f12e603e477d25d2e1a9b8af27074be492f8583ff6bc9d1846740ae8da14c06246ad0b22f68b0340e1f7189fe5b1e585e5807242cb847800c61a1659e5ee17bcaf8ef040667107f385d52c2219bd3b2475ea0a106f8426f3daa64044343fa5690614fe71e34591c6945024676a97009aeb62aac3c8257bf540e0ca23b50bee332038b1b13f0e2533a2d81289fdd7f08ecabed357f0ae450eda64d6d2b2172d128a9356da065ea17bb39e71f85b06da8980890990d95f0c1a4b2659b8b416fd4e465719b1046dc841384393a1483f5c40a2bdba1a6f6eb793464360ca95039c9a738b6ba9924a17ae4e0d43b8017db9886148168ecfbf8942e0558a7d658b6c16cd99d26099756d36c866e8ec994a7bd2d505cd25f6731d506da579f29beb730ddd0086b19a8b5fad8e589106aef57ed8a4f672ad4a00ab8bc8b2ae1f05cb449e3abb8799868560d7e597a2d2209ceb035c79cdd1aba301fa05e7175d0876c177a83e4a12b86d039bacb03d6ccb9aec3967ac2d103b41567e98ccf7b152b23a8eeec6f7d4c08d821e5b6669f28edf58c3a28bd355c6380179a285961d2675a59ad0a115662cda18b91d10503fc9b3df174de95b32cace5008fb2d2c91d99983cd6387782d15aa08a6c644acf3cd06d0d401f755bb10772c5c8cea7cc6d8486d879d8887fc2aeb8a158b96d7410c1f5fc9302adda563271a06790080da6c640f0fe6c0e37ba863b710e648207fd405aea49a119515c658c25f414af88b2952c5b82c7c81bd161648a6bc178f274498ad61feec773ea87239ae022e4b99f7062a6b1301a17f417c99cc8a01b9f922527541cbfe4be8957610043e5f05de99410cc2073a02877f610e6df16f3f6b0917fd24727515414ae047317c37d058f99ec3fdb664c5b8eb6567f7c025a36a167d34dcc049402a1e5ee84ba2076d0c3ddd256b3a5d5c9a57770ede389b19af1e0bb84b565a6b8e011d2fa48db39f5ac6405ed621cc516acfa942967a3dbdd5ccd170abfbd95e6b676eb208809afd07164bb61cffc78cd997e9bfd5f8a67addd125fb204960748f6bfb326bc6d9dacaefaaf817aa66f2399c7babda37777adb50ff692c217a1b59fcf43567b791884bcef66681e04aac4e02739024bfd23f6aba4c07022dee7ff77954630d09d3d5fb0608ae8c45b0d0d8db1f0aaef951f0071095faa668b6aea040ddb5d20c7806114672ea3c530ea2358762c2091fb97ce47d81a9b0211094694bc1ce72f4d080330c6cf785066d15da05eeabd3d93e827f5b0071d646b645ad7a58aad06f4d3584211e6f8a1a006380de89adf274aad5163b25850d4c9cf3dac50ba18d693d9eebda2a0eb33c8a7e79d299394ac41ff3e8c238e2f81c1fa2afc69b9e4c6c7754dbb32c21aea977c63a013c37c67da95b06e966888187c9a709d7fbaf6e4fc12c847781ef1d5b31fd2f4b6078c8de9a827fc14ac7db889322da356d919058fbfa963291fc82b789c86e56fab9a17734ffaba0c50c3e93ebe5d1c841c810712b7ed1e6dd6a9c6fa27409c4dd31648f3bc584dc2cbeb087efc12976e8b3714024facb9b8d5a53d1207d9608a9a0e724706b640cfdbaefeb4219e54520d61df89bf0f20595b7dff6952f2d7a007cc352bff3227628e22904b524d2b95e215a2540bf72f9a2fe4f8b6eaf6db06231ac3de87809a72d3c79970a6c530fdbfbd1d572f9feaa7775c08d452e8127cd64456a13ead0927cd5dc86cbd5011f35657032949798f427a3bf28b72f5438a0afbbc3f615976ecd27726765b70d3da0bb4a179a9b94ffdbdb2f0fd000a1fdcfaaaf02bbaa1da176fdea19ce525a635660e81376f3942c83ee18aa53ef8c081d5b5f59a6d0f9e593411de46c6aa5efa4f35a3cc614d532d40de70f4bbcfb048dde00bdfb2d9122f9b1c7b57c4eae9ed8e66f92b82e96309fd2b3520c91baffae3945cdaa1eaf4feb7d627e8904005a33d7564ff1ac75a43c5d56ce3f7888c644829809c899c58dfb4389c1be4673b6ebc350979c8138b5fa29bd9e125a3b16f44de25b164b4f13d215cbfc8f704e271581f2d19ceb73578b6f94689f127046c497723a730cf0001a450fec1737c5a69d809eef2e8b20ffa2ff1fc6386d4b4e6a7104f7bfbb8b9475ad24c73c943a6a177c09e8244a9a65ef71a8e6f35df956c779bee1212b8130a0ce2e5b527162c750cf995eb44cbd377f503b9a81eedb8e29d385f1189659fc4834e6175468bb64362ef55aecad326efdac361c7326fc817a9c782c61c1660a94c6a2a5d2f89b504caaa9e7d93a846258adfc52b67b56a29cc8a96687bd560c95466c6876327c238eb24b3b3500788d9bd6285ecd0e9b95905ba0eb1c35c564a9de7c48478c38112162043f87dc937ec5b791b5f746c0109be860d6e207a67a136dfca82926c9ae6891d0317f7a595ccf016b846188d03e20507d4355848a32eb77cf3f7f12005838f20a93320617b6cb96a5d66f2c315f9b47a87dea95742e03469dc956a988f16a5f4c8c56c6fa19b305c153324afe116bd4646274f19b02e7fcbbb34dc9ae560cc857287e9cc6372fc95ef81c721e8ece928a41b12a6d798c106beff3658fe01ea2f7d071222a30aa3c76a87a3938a7b724ae5df2f66ce8e17d73b84dc5f6283e41bcd4f701eaef6ce7c2977f63b7bbc7977ed1230f31fa092b280916403a146564fdb9a9883adb81e0419e529a5dbf78a29fad976523c8438230142c186fc7a2424277300bd28ce954c644b0f4036980f615df94dd3320e8f132b2f25963a0276d56e2a35e4a5daa32c59c461f7bfe161a10d88fd0ac071466da2e5ac4a152b67a3c7243959e04c43f34217b3d0b1bf43f4d5f0f0e57203ca18e84825208b667d0025749e10a9ebd17947b773d71f221e08e44a438277283351bce584723dc4e52227a89b377d6d8d6ea40ab3bd3d9bc63ae8a5611c5662a7d1ae09dde5ef6326f0d9bb423a81e81653eb8dfa5b31af6e8f4c72c2d589e6d8c9eb5839886801d89eea7dc2d72cfb96b319e057112ab27b9ac8476a8227d83cc2953d502d97739bbce6557295c0b3c8737ac5925b8e00ba2c98926fa130e826bc52ea61002b0a01fedd1a569878883438d9f6d1190fa84ab29980d47174b9d0afcdcf4ee6d2050e0b1442a4cdde0f2d398ce27a56679f507233e7339d8d5442cd3b6fbc0944ec67555205f027333864083247606f64daff787e3ad25dfca4a6bea8be03ebadcc90c454029bc91466f535bc1381ab828f612d70dc9da6cdc631f020b50f4263b2b07e5dfccef03c9cc8fb47375ebc663bca55f7e9421f0fd4dcb1178afa8580a6d3ee84a23dcb86b542d7d1ce5025b32196b524cd147bf68cf9823cedf2d210b4721b9f68fcdef1fdaf14ac5ecd18349aed3c139b8619ae751f13fe4f042ce1a338efdd81d8e65596fde9ff22dc9ea8c0e11ddde407e797a6c88a6e39887ec41794c96283e6e58d0449acd88ee7626d7f022b5ebc549c0f4eb0e98938132244d8d1cd0d5cfd0f0e3caa236ab70ba76a45de39d80dcc87cfdf5e9c15b4a642926a7fc6c5f3a2d337faf8978924aabf72b3e441e3656e47be8ed9bc52fba555c9496543836c11abdf8759bee0f16408beae32178b7a259857adfed320c79a50bce63215b9185cd4088e1ca2bb0e2c0f2de1768e9fb48b9b30542403789a30a3851c10692ec1b33d84bdbef1d3dde0ed4079ea3f9971a2f4ca065c6674f1b5c729daca703203ef66357ce57752d468b31bbd86fd44426d22d43e4308166fbe2f002a02d26ad3c61a9fce1b3c73df6c6e9a8e2d59b8bfceb686b6c79cfb2149b6a97f554bda7fdc765f679e57c5ce43995129610cb7e0b0809c257863c6f5b3af120d6ac8b49aa2a467cdf3906939f0b334172bd9d99ff1763de49ee588b9d9738d6f66e9dd35543b887b8d8fa4ceb0d9487ab2731c435cfb1b184a71f7a83072ad7c1d22827cb31b48d1002a9007a0262234560723a8134a5aad597f20b269b416d624b1e7fc11e77b4be61bb3a7316827093b69f67f73ccb54a119ccd6c370cd8f2d9efdc5a9c308b108b5ccef485acedb664e7cbe5feb7b5fc6dcb0f13a65155e99af84beed45e990a5860ac0433326bd908e075d46c2f77c3d852278d72ccb35d1985cfdbe068ee804fc22e5e5662b54337d3bb4431f8477bdb3e47c669ecce49ce99351fc63ee279cc2070b3b8b09297866e36013028edec21b35d690bfcd7e0e3729403fb83a3fa755c429621da1967e012a4e0168ee29b04b0660948c4a1074de934be67ee3f9d5d6a45b7855d8751e75981658f3efcfbe783395e8de65ad392a9912787929bbea44b78c42946742e73f51bb1f0877d216b6a773f010da16b598c205a185d07bb5552ea4cfe82b0da004385d65add2948b3a72e0987bae7cbfbd71ed9137e53d8671b469634e9dce73cf28965027a5f2fce76ff1f2b6d38e8ad1fe523d240115a6da8dccef2381f6c7d23747c27c7fe153a208293af131ff547f55146b5e82e32ed286630eb5515bf6d2aac04b17207e6532145dc175ff25e2aa2e85c771b7c75b096b0b2d65622d03254ceca836afd026e41c7131fa492164ee0cd01d0fefea2489369b3b345720de10cd77e07ddc27768724de300ada16bc4e8756ffc70dd9a0543bf1a217e707ba195359b54aa8c2e5da9f57059211541c1fbf97fe5f168a3b95c08370e557d445bd1cc19af126155013d90ee71ef73306ece507066218dfa81b90088be37630afc1702cb0283545d08df4569c2d3012326c0b68d356976636a139b5d4d519ab7752edfc1f5a54e2930abc7e148604b4b88595b5de3391874fd3ccdc83c68567971d4e4003957b30e46937e3f68d601f698618d3f9c5824a8299967cf8c29fd4988bee64d4f3773888d692e3ec9f0e1ca77385645cb53b891d7a59ba1301750bc625cce67a8c8f2ee1c2a3c80a5ef5082bfca36f3f4ff8d03e2c904f2bbfbbec988c524b84a371ab39399d083e9962265daecfc4ea1bc9324ae124d785a885c907452a6cd6c229efa0038416b4e1760fd2972246fb0bd73042b6a740166c8e0da2b92b3159e81651d64554b764977684a9426d447d55ca3a7a5ae7b621f163cfb060d6577c094b44ffe524fa6aa48a21132660853a65399b862f7cba738be7d4a5000a699106e3d6927651b683b46177caffcd0f23429c78317d27cad884076bfceb785b52cbd3c22db191ddafa170bdcdf52fcdd7f5a1195e33ba084cc8fdccaa3ac47dc24382e07e7bd0f6679162d883592f4f1b06536337f9db864ac01efd01ebb495fc8db6e8b83d765f3f4adb3d8b6d4960c3b82ac799725f26b78ef808cf7e01d517a89e3230e770b5712cf8df1f6847a4b78d2c845d9eb5d9dc123d8edfec8b2989dd4533345df13582167cdcde3dfc4deab38052640bed679a4c80b258a274f129e3d3104d4e96e21960ba9569e631b1e6f80bfa8fe3a8806cc9d66693038f380db948ee1c5748e938c083ab32bcacbe7c85bdd988a7091d65a0a1de090a2b512bce5e87250b5a41ce287c0b707f051602658c543478ed451f63d6b48013239314a98765b742406cf187900719b1c738c87b38668061896b6687f9921aa6999c11d1c2b76bf3337ccd1418b9958ee7271ab163e75e3ba0c4d31b5d6201193109ed265e69ce163e71bb74442507"
|
|
+ },
|
|
+ "transport" : {
|
|
+ "secp256k1Address" : "0x070d5e1534a367430307a6e56bef29ddff79c0e3"
|
|
+ },
|
|
+ "ecdsa" : {
|
|
+ "addr" : "0x070d5e1534a367430307a6e56bef29ddff79c0e3",
|
|
+ "claim" : "0xbe331f029d64c18573f1ad767b382fd3df52f882baaf32c55e5f47ea12a3ceb848b9cf448d6a9327d1922dc6a5113b64408ca1e65b414b104b3f894f1758239d00"
|
|
+ }
|
|
+ },
|
|
+ "1" : {
|
|
+ "id" : "0xd15fe33d96494a36ff79aa4817f9618c14b67b8b",
|
|
+ "keys" : {
|
|
+ "falcon-512" : "0x098cc6958451c05c23b92e012c1fc0865a5653ed89b391feefc3b8d79b34be0f035fa6d192ce7ecba92415bd86a7d8586fef7810f8a71a803e8d086382fc0a407e4c02285400d1938de51657d03f95c63bb1e726b92064bb213c4ce201be8b809c44b32ae03278dc11bf8978ac208daa0fa4ca7972558be022b4cb453e6be94bf624207d09e418d8985a8edc2347aac04b6a04a0547ee2e27ce5cf59fa6e307fc59f2ebdcb68dd5586b5f830b41d5e973426f92b44c8559a6af242839cfe72022d3321cb5b3d6d03e7d391c206124d11d4dea003e22509726cde6ec90b8389508d1bf64d01d25fdd999ad1911da4c30eb5271648a75202f8592af522ce4e5043652ed6476ea6c2c2936aa516a9f776e2d9beaecabee6a9cf5b5d108640aa6c0104e2d1b2a12213776937925a5c984891ea668462021b101e373f90342d95cec9085e43a41a91e83bda6e19f62e86a268b23534b37285289091fd118a084e787e387391a718999dd854c93d04dd97fde27700cc2e4bfcd59565934a814636cbd3479da3d4ab30bf065876d65766f7d9afbe91777ab2067f3110a925dda843244e809a0a96f12e5a5f3520dcf08dfaf62427a21011dede06ef5eaa4b814e591f60b0b05e3325b6296c8845b7fab34e62352e156030d66b5cb1fa60f0987e413dc3cbe380c217b6169680a2768b38f6a181ca93acdc82dad1ee31ad8cabeaf558234df2b806af8ad18ee66893f5113b823a85806f09f55db4aa9570dcc991aca67be0ce7557a26d1a6395c47b654533c50e358fcadc7257c2d18dea8f6487e156987001c587ce996c10afc99a4ea0bb9ad2cb4a63f2a4308dd27c8ea8048a8d1111d05575989aa3e4e49425316ee90027d7859d6d047f5bca5d02c1d65552f8accd06706554e76665de01714e2940181a77d7daa29816f8b3fe92a6045077420e8a17099c8eb621107f14e88567d4a72478d90b732047169a9489724214ddab4a9c12ffa8bb03513fb516d692262d2bf9209240a8f0545a8f2c3f7d8ccbc93861df01667d31eacef011711d79ea5ee0575117c190c9a20844dcc292e2526c51b018a368ed3274015050814a55f8e5f15c970b698889846307f49f70d219d328665f4033e6fb888d7d88bb7b1381178ccaf77b90e3360240c8e73645f2682a7ac37790ac4b10ab559bce0314783d6101152a9348f6b8df16af973449023002023f258fa6ba81c50314b72807284b567200766c49d1827912623614b1752076d9dc87cd",
|
|
+ "slh-dsa-sha2-128s" : "0x60d27185321422cf2886c8beb14eccb7b5179f406055751eb2dea19888441086"
|
|
+ },
|
|
+ "pop" : {
|
|
+ "falcon-512" : "0x39d8e0d1ce993e3239c790b361b84423ac7facea4bcdf18d6c92508879b0c9122bef42991d1c48756cc05561129c9db2b170715e8c225771fcf67041766d960d6671afc2742b7f98caa2dca8071235f69dfa9336508e7b3d7f8e3cc5394bca8bc951df3d2ef56d57c57077b3241fd28a73101d5d7d2e4366441798696c48b59ba9f857665e3f01c9f04ad20cca2fc7542cf3a8f563654aff23cd94fa5369c6e7318967efd360aaf367bab9b481cc82a2ecf52113174fdaa5b54f23d56b5badc5a3b52d0abbbe44990f21f364a912d6815e456408e3789fb82460e06adbdedda8617c2c94b9d8e2cb211a6a819677f18d7f4b65494ee0064aab73d6f3d3f4989cb1ecc6b9cebf5cbb780634fc1b6776dfb1e62956354631c8bdd20aae0cc7ea197e1b3d9669d40ba5b840e92afd8a9ef66ac9b7c650e09875392e58bea6bd5862e3f123c5ea4ae82c33d9a3d60d1405a940a1b877820ad0379fad57a8bf92cb0ca5925c103beee1aa80cc9abcb20e781848cbcee3f1a70c5e738d23b635398dc6c6ff03695c04113fa84dd2d27f814c5e2d9bd5c1da6acf9254f1333b239b59b7de7d9f280342f7fe21fe636517c826e8c92c8b2994b32ac1b54e498c455ad4d4495af32cf84c9d1a367efbfb4e3bf29b56be4508a4da913f6ee66547ec30931aa52f3a9e42bb45418d6ff137bf1ed53f5ba1057b6f176ffe9b684bb5a98025290b5ad5cc1c1afd7923a01f28f9b5b7fc13366116c0ecf57a7a83a8b2af8cdc151f9ad1128559cf5a9236de09bb60f9abaaef1bd4da39adbf4bb057f06c8d5fbb29a5f6fa4cca9733ebb126009eeabe5438f40126c718fac414921b28a2a38b56770526b35c831759cfb8802bb015bd0889b32c7a37856de4f78cdb87ff50bcde45b900c4ac2d510e932675f452",
|
|
+ "slh-dsa-sha2-128s" : "0x499f63fa78767f11737ad36fe768d41bb2aa68758653aa96298b97143715d0aac5af18b2e2d99b6248f6b448682f7394d3520cedce383d56caf8eb86b8fec5c9a811b0f2682236384b6a3e63d06f18f13aa94ea7cc0c3348c112b03dc582ca0a9e75321abbd55667cd0b7acf7d01bb554354907df36833bd5de7f17e6aa6bad15f2984188b8078b08f5d450015a3acbaa0933b63d2b14c094597f6861cec4110fa915b48a6e4db064bb74619391bce58a6ea47bdcfa341e83ac6fd67b21c5234890a1bf7309bffcadae4e0b90b5dbd405dec21a8356c31bc64185e4b194e884bfc025cbf2e9b1dccefa664d1d9f240e1fa667fd560d14a6d04aeed5e61ad6d34b070ffe90887105483132f48cf7e9c61ef757270f0b3bfcfd0f22ba00990092dcdffdef46ea1ea1a0c18a4f7d56328c0f080c1770c3de93c7337d0dbfd0c752fba87f4f7ed1fa259d97b442cd872044757ae0789371422bd65c68a3e8d4abd3665064495c8226e3ebbe153cc628d2f460910d20638d228de916ad7e2284e925f8a72b173b3e96819862cc56b137349bdda78dc0bcfebfcdb441d1925e3e9f39702a87ac3b7d800ff9df6a97fa14fd9b8790feeb120ef523bcad2bdd38ef9b9d17321d794ae378cc1334512854e72e3f47e9d4b123775321360242ebef17ec3ade9bbeaebb7c8d0b0b2aefaf4ffa5fe01d7b68d3ed51b8f7127e6d9481ae5b6e7ad6e473c518c8a2a858af6a77c1f7e45afd6019445170cd6dc002cd16bdbc750c306417db76ef68ad7df88944c9a7336fd1399b3c884c1c196f6fd7c1c69ba170212cd63086dede03866f3c67a643c88ab17a5e21d5bf11440798578aedb76c15ab80c1958c892222b3fa076af88809f75ed3ce9ab29f5698f0ecff6c989678b22fd026f49bd856b3343bbf4ec61aae89b1e057216f1822243d32c78fd55307a515e34dc3ec06388647dd44fe0ace511430ebf015e6eb1083df582f825581b48e875cbdd55d2d253d08ebbda4647d01133bab227f56f1dd2f6c1f03f3b3ce91f4b4c47d36098bce545a9d8562e7cc41f28c0f53683bb2b0cc3f221b2f62370b6e8b5bf8eaad1f69166eb3acf5628f0be7586e19888a9e55cf0168d21ded7b6124df38403e139c30d779b50e3f1c25fbb5aaff556a95358a2f5b7e47fc820bf10074cbfea88353820e162421307be8090b1c143c4f7a4f66182f07a46e86706e1966f11486a0017733aa4c87a410b7ff0ca614c5ff2ee668c04fe16355c75a47485eacf384977882fbdc8106201c52acc9123380268ce6cb534e79b3d0a08ba4355755dfc220f8f2dbf807f2aa6f5ffd59d2a454c00c31ff6f6418d984de6757a3e6a79b7f9ba5d3721fe2e16d3cc27efcd0cbb5493dca865fcab9fece781a25b62176a659d9419aaf3f3f2c76ad5262c11883f8ad6de060cbe437e9acc9c989ecf02fc39428f052294cc72399f7f011e60a47275d784e46f98f8b0b44d31420a2ef6cebf516d8a333e780c63722bd2eadfc71ca3c20af3b209468ad58d54afc912ca77d500f75933a00f29711328d4fbc7f409ab8f13836442adaffb0458db456f96b5c7bba71250059fa79859368a06ca88b8c8688e5ab3826529051a9155abe22f9d98226abfc525a85395096df6523f0e7027c074a70768b46e647190fd7077d65f143b00db30ad928620166601a88ec63571d711ff45418da859b5e379d78f0756e8956c7ec783740e943848fc2e2f29efd052585f88024f3315f4139eed9df71fd8ff57e0275ca8e84db88ac021b32ec865bf35416e960c9a6aee978c48052dbe1ee06f642543762e0f3f7ac7fe878d6a515f1db9e9c117a684a2b78907c36ae249c7985166410440c463e2d8f5714325bdbd0fc3d3d6ca9e6ed4c44232652b900b9c324cc3acea3d4110d79bfd778a94a51554f54250643844be160082fefbcc53a713c6f4aa79515d340e513579c6778892e3a7472853ecf9b9bc514fd37361a9eefbff76b53fad3b84f4076af6f8e1fa2bc4e4c2908a4e92ab7b43d4a61273259a14dc85c9b5d591293f23deded5d8bc9a5c6a96eeae99eeabc8b6765e313365a32f97a9f52d4c10983ba04d0fdfcbcb015c44c9212a9b7a2a3ef6fdee002e6941648196b23c04380b6b733d4a6900d70311e270181e933044e1a5ebad9370ab15975d47bcbbf03d5c6e8dfebbc032eb4e62e11f6e24d32f3816d8270d276485ddd0ca1641aee5468423d9f389b59477306a06ef2be7b2076f6021295ef6b079c70f6571918acd7cc0b0dd88ce1f1150082a5513db9d1d5ed068b064a7de1341a9a53db9027a3fb19b18093db9a20bc3ce88cd1d0031d0a9e78b464bff2e3373f32aa3b1c50403aa58ed5dd82e8344c24be1499a6d3c88731cba21b88894c8956dfeeed63f6633ee749afe2364e78925082de868668b5fe6e186dc44f9519e3e983762fcc9ff260dd10261c39814eb5b9a9eeb9badad3d5deb66ee8c53caa39236a84f79189272f54fb986b72924bdceee03eaee9ac536c63163ded669dda08d215adc9bb5369d891fc31a1a014d79e73317f6079164b0cf37d77e5efb0daf3c668d95a5ea55f6d6db420508cc96b19f9c991613568e858102bd2541729bab4a49c6209a78ab86cc0929506c7e94f8517fe2202ef286ede2bcca03269f21af327de389fbb43503e21e30442f700feb58a21fef6ceff9a93deab1bd80e4cb067496c644a7ea34d6034ab13abfb1ac8966e9f3f04e7013f524b6893c121eef9f9e71bedceb95aa08086a60607adb21bebe9ec92ca6fb386088c649ff88be869bf102355799f6b1da36f607ec776b3881bbdcd851a0f8c812d814ddc5575831f7b1daa901803867ddd76fdb0d646fb80cc171949aee6fc54c3a22fa8978c932e9ca282588113022521a3c05352497de8beb0c2f39997a1a01104b1d8196415384fdd429e0b903f08bc3fddb8d497bbd885701a8db29be969ed5d48e932c3bbd888a212b904ebe4047e2df56a6b2091a5027a4dad8fab23025141762fb79fbc17f0aba511d7cd5df41d7ab91aa817589817676104adda295b26b4db40e85046c6f22d7db9f6151e9b80235d3177f445243ad57ca28791de7bff855e7a01f457e5d969a583b36873116811937067264d5932b8e6146aaef0a28c914bd138758799adea87f064d280f02a7666db937f83c7d90ddf6d20a820d4615518283e64d0f24191e30aec6efe5438d778b258cb906308e023701c681e2cf84ec540beca15f4f56f3a8dbe96c24a5aae3fd1892e44ce5039653232958f01bcee8b3ea83e1b80bce5434e08373d6c6ffa50b7549c61f8f7a6583c88476c581522d50c1184ba8e0cbcc7d307cd98447832d6afffb557c01a0fa088885d05d88c37011aea3205ae7aa2bd17ba8f784810b9d5f2c90f7b3c290c0625e15c8d1bd57b74360824e67ecd630a3c6cad74c6ffe080bf5bf9c8f107e7f251be9f21fbf7d66f6cde8d2fc585bc7444771210e35d2c26f277ac9682dc557fd17affecf955e117b38f7f26ac147d801cc9622628aa0a48908bfb9bba36c319c6505d68f925307cfd05d990c09a6447afd26ba2a1dc65dfd847b72c891f4159c17805fbcb73228bd50890b6231a5891a15559bf388fa4405f055215661e4e31770042fc25ac46b605bf82d89544d2239f2f5fed3bce69be1814fe34a24df9e4d1e7e17eae8090d28a45c1aaf4b74ec50729fb0de9f6b9bdbeeac852e5994777d839974047bb6df98bbf8c8bf13ebf7bbbc57a480c57ca7c54d82e7a6a52dcb7793816a88d5df7dcbbab45dbab1a3d390e1faa4e9269c13a1da08846fbf91c937944ef612fd06fa4e0bbdd72988c9497a772a4e6428f69aad77fb200289aa7645443ba703575d015e28c02e2e6a48d3f289c6dae25d0a6d775af10dcf7d77a64547d5aaa23f07f3e4c9eb5ff680af06add6460c9168d241c143f0ec13baaa70a675775e5059df80a4b15cc59774ea8bde8da6672e35391035ebfcf6f84f322f37c3998aee672f07fe36e6cc6d2ef9be5de238009684116b2ce81fd1e46b7b8a3e67cbb3af59964d067c86ae94244e910d87eb5c338c16ad8a52e1771a6d665c982fef3458e59ae499fe652071328dcea9837652791c39fbc67bb89c01f2bc865a26e7a12484e3ed980d9615d3ba76d8fb7df335aa784d3059aea84d0be9fed2a1e8ad6f4b4610659f1f7126a55ab59b828ce78f2519c73fe95dc4cb4f75e99c8f17f055735e32c85b0748b6a13b2177f907e45842e8479f0b4081fde471a715eafe9aa7267bc626b2cd2aa39c7811bc91524ffdcc6643cb2a500a1e725ffcb5baecdbdb2bbae2e127243e3210d3c71be910c84d63f0de5fba29db351c0a743f45f054850582b50156be9a84bb48eeac4153705e23de76be04baa34b67227a3f4c48ae7b37c375933c5da3215aa5a1955ac3f3021449531abba03ae14523a3916435449d41b5ff07bc6f60b931941643ac8b57da66bf5e17377b2aa3585565a6790bf9b3cad7d3f18e43e21f31a11fc07c0d9628cdab77eb97e63ee922a6b82ef73affc26cbaa3419394f01935e894ec2b066a281cf760ab1cdf55a2650e9328e7f425b79458d60c16edcf67ca79d92607e1cd851edec620623840f193ac14ac93fb033bb9545de27b4dece857c5374097b0a6d816eb8832e8b829e56647e000a1816d502d8d1c47ea8caddd555de735c0b22a60c9a5645c355db2039eaa19961c10d660a4f6ee113cbe90505333e53991d9262d0d03917e9eec8ada96d924815ed5d332b48cb9b1935af96b97382ab6d89bc0766396b2798c6460f97744d4046ded63e93322f12ceef139aa67628f077d6670a0f3312a1fe9ef7ef519ed5ba973e7e7a8320f7d596343458b9beec32e149d589f7f65e3cd9432eeee95ebb5481004745f15de87532e5ab828153245a8b6bf74e7b0fd9bd4528b61c8d02f691ce12bd903a0ce55028dc428a56bc003770fc9b75ef27fa34532f65692ea6bfd19d6d678c5890ba446de260528f9c67a2eb28010117715c2b472d8507a2e2de543e874a1dd1bde9666ad73439deb70968b402250c231c1e7be02fed35b4f5984403e210726e815722da2e36afc76b8eb712bec1fcd5cf8ea0a2a9c101459300471d012473507acd6a18774acb10108f89889b1a9976978643ac7f0236e2161f62c35feec2e2ba21c3a72a9a91477fc4dfca9f805a4f2a432a6f5aa45f75b403600d466553736d36cae1ea0d80f69e1dc13014c99484275a3d3123443720d9e9de9236a7aecc1026f6b655eb236048157157794e82f838168b891bc6e7aee6d43dc44f25cca34d45bf20966ec0df0ed93b780ed77ca7b7fb2910f9ff33348e807fea0652d74dbe03105be37e05be5d4cf25a6d8b8fadf547b76770d34c62fdae28376ca413814ba93552b1a1b3d3fbf945309e3d76333ad1d16e9bbe175f5cf4cc69e65955fb258fa92eb6c5c86584fb401c8cffdad26306a4fb7f1d57f1fba52682825e59cb3ac7f0e8f2a6dd1d24d38c9e92248bc789ed81534c89ea3206bd566282bd7c6a9470e7dfbdb36076ad03d554d5a36b915024b0262dcec4f20cb76868abd9bfdd51c32249f4fb2337c9c7e824cddd8fa950c243af0a36bd5f5131e7ac72eba89a96d235e39bebc25f37f936381b8805f7fff2395e0fb3806dea2b26c2207e859af8b95dcb073df315a56f09f5d33213431f8a3d1ae1a465b217e7be98a6a2fd427aeccaa313c215241e262e4b5eb00031cad37f0fe2ed723fd8eb701bac646a90ee5cbd0fd28b4f15b0cbc2911dae427375ed66e316efad734169f0448ba34b8b3fa6e8ab5070c365a39c1f092eb0e4269fc0cd1f5b7dd3cb2235a38dbb144b7d87f4b70532e8da40be86b888d35a54b5b84da8c26c9d60c72aaf1b19d1ee8fde8a1bd9af6252058ff1d04c014750d8b8cb940af3ca74ba4a12eb7c541d1042b5bb786093074f5ebadda59ba2b77e2db04f3d32433306c90fc06e04dd69a28dbec758d6165cbe9c20a20effabc7e0fabeda077ca72e73befd6794e0d101e6f70822eeeeb7e3954ebfebd29739fa0b8caa399f495dd9a2e5a9fd2edafafefc3a072a1d6ffa8fa2299a0a294b7887e6b8dfd0fa4279498a9f509cf12c79a5510c3e07bc7c93323169ddfc9e46d9e91a9d45764eee6b0bcef24185120a99ca46edd67e2f3fdba55bc85499d5c4e90bc4df982e7a24d3af53b63250ebb246f0bde46072961a57304bc59b37b7779ffcd55e39d6ea2123d111ae794293773c66955b30fa89b30a8006255a883af822c6260830fa40444e1222bfdd37756a3a41296f3da8843abebf39489934915fbdc47d567fd2840f3c386c360cb10a24ddb5be6ed735b1f1ee9df95e2e01ba60bf3b3196865cb496089948427736a060c5ca1d0ac8c85987be15828d8bad56020f2b38116a5a5e2e16137b2e83fd483adb9d46916dcc6ef3fc50f325e90703c5a24810983477c230686c155571cc1ddccb6cb6ce3911742503ed3e1312473fc07d4563128c654462e4ddd033097bd5e6b3c7f1db01fc9aee006bcb5a17fbe8d8953a1b465ebd12e26450dc21ffcb73c7bacfb37019979b880444651911dec58fe0d5913c20f58e9f7f6c274408b4217b90c35666758bd9cf7bf1d37f77b59e38c08d76dc8ed139b6e99d6a509c00d03c5a68143701336d44cbb02cceaed220b06ccbf15448bd3259c6a8af24845ca52095f90b6f50f357c77dea1b22fe61109a5f2b3a50a468975ebb1f418e95023812cdd5d92aebebd3b0630a253aa9febb8ee35e0438b4ed1742238ceb15d23674425377b00ecc53066423852b272ffe578f0bb59e31127ef48a521f18d4e14e90ca695e424cbdc751e614790f07a585632949a7fd50dcf19629ac7d2467710c3ff8735f83b9fba4e48d554797439060a32910bafbf1167a782b683ab67ed82dac43e706ac540ab72a78f5a53adff3e3f83ebe7844e2d62fb6ce64aa2311abd6f9832bb995ea1c2eeb052b4a8195ed249c3a425ea7b936fc6ac644383527e69c24171d6914d253514bec7432be8fb15a0d63a697e35282d33e862629fcece1c196f393718b9d4c8aaf5b321d508c07b1289172ba290a8ca2ae58d8d77c1bc9dafbd4026c2e40cb18e1117d1f7aaf8893dcdb53dea67a6bd100b6706a395f5f876906d2d01aefab4b6cd16fcbab55397eb0b4233e62a0c157e140c1fcbd3b9b96738d68001e6aee72d966bc0d75917437a23536476d12e8de496eadb3b650c6029f9035ca0a77c67b77c7ad635cbc920b2f6c6d5d86ab307f3c295497896b0dee08bc1fb618ae4dad5028a7fda2b1fbbea22672e2311fd10ffaf0ff0c41a88ac7207204d45d58ae82033a168823612a88be3db1656d08335505390e0b47e0aace452758a0e81dbc22dc96319c54eb18b1d2533d904103c38f9f242b3bf6685c9d24d830b07a42d88f020b615b96d2c825ce7a2b316b44ba7f83bfe3c74599ee0e38942e3dc1e68d31c6830ce66b10c5e288411c791534b7d29eb3ed76cc8df571cbee9c5c0f049e4cd5f6bb3f941f92bbe4407c0186d622a2e4b1fb989ee637a4d5d3573a1d3f02cae495517051b10a7c374e947cd3b570aa941157bf1161d84f69477c1d1e0f9eee6e2c3f2400f664f0e3b8891032fb3e004ee65d7b7e10a29c2e6d9444b05147d448ac655961cd2a303e9102909b63b37219cfaa3368b9e93d35d6165609872c31a05f86a06e80fa29b7d91925e90d00ddd5f9e50105be2b1797c1c4989daed18a2a8dd2b530e3cfd06485952e5aa5fbcb0b1f5c7b095b24058602028e92156accc7204e2c8d1a475e25db56dacaf63fd0fe9b5908469fc99af188bab81ecfc3a44a7069298d18c785275dc30e62b41588767fcdf0ac30282f6eda6fdeed0ff286277420cf3bf675654d59c6a724ccb15b5c310304b4841699b7d9138fadac315eca4bbde8e2fa7b2bb27f0557c324dac2e902e9214c5d3d442818041beec3c67a7343acf9da4d222ff7da7da2af7e922941e7f7163c763a498c104981211c698711a04f8382fb9bb3bad97123df5732869c3dd7d3358839747f67196c06c9b747c729bebd53406336146dddc9da154535144ca6d1f4ae97d13cb61abf139cb8aca8d4a0b382a7b250aa2278204fb8614062272d68114728bdba4b8176719346b14bb26f9145aac5de87bc2b798282bc5a844ba8cdd6f840924a8c20430d75ebffceae7bed2945db014d3d1f2a6531d94c7944632acceb82c1b388f0b72cb120e80768e4b205f9344e073125a521092f4ab6a4b5a273757efc30ffe2143eb5fe157f2c92fae60d01c0a2b5892ef6b800609f66953d51e95b69657e898e04d96cc6ea461c446524cb83e6d73b68c58d688481c710da6b0dca85d5e398728cf27b808446c657ddec2b437d8d9db33762f8b3d0b66334ea2e98c7849f5c3032cea446dad35ce0f75d27eb17a114ef911c0d132991b53c9feb85111fbc9b45c69e4d733f357f3cfcef08bb89452c3a1115d846c9d7dd8ffb44451fd4cb82d23ddd64b59c5c905cdb2ad91578f6fe2c8d95ca1e21512bb8d64990de8deeefaf3bf99c8c5b3de2a18fd7c633034e57053ff3cefa5f6e6ef55e2d996066a5a0414bbf19a299cff94366c26f572809e4f6fcc3fe76854a725b1a8d9a895a31e83bab50643f0866e5829a84ba56d5b8e888d48b51a514891e8cdf61594ed179ef75a06bf92d5d4f52fbd15b938f63ea077cec7c2cd809971174eb4558f8a328e4121c40f513b39d2ceffa6131485fc6944e8a4be0281178eeaa75fff62b0908f953d5efe1f434053c77e5d0eafa94e251d4aa1da51d27bf21f0b9946cd2bd0c0248dd722526cb5f230153bd11ee7098bbf3250ae1cadf708275c3ced6b8c9fca2b0212415328ab2efcc92a9e0c860c166296d98acfe57af8834ef33a7bc61af4741bb9974f6b864e9d163d103ece242e5e301e9250d6f12a4dc3aa7e80249c2c8caee40f209bdf42fd7584747feed3defe73e5f22b13b954863920bb8ba9f86517961d1f2143c0d7a7656e46eb9ac31a9286d3a9bf93fe8f7a803e7e2bded0ed7d439cf58e21409e895fb2b6a093fb3dba482c727a08818c52926b926228388d8547dc4d22a908ba010f3062ba82c195d2e579f0ccd907f4672bc7d547b6d2b3c1b536fe5fd87ce0964d0eb2a1c4ffe2986a10f7476e82d0d69ad43a93536e8849cc1a90e642712fedf66ad89d33a3111d583dd290ee0ba3625e3344e1dbebf7054a33097babaf27678bb96c632cf61b88c75e4b7aec96531e6806e9472411cdbc20c2c83bb22acc7618e3c36e4994596e439837701d3577a5be94c58184a3d8e4f1ee943285487a8563bee3958eedfb6ac67cf71278a84045eeb8cc4eaf18b7c0916f5c13191e9b45916d6471b3fd9e4afa16d1fcc53d2924ff990b863834ca741b0567161158e539abffceb5cb50993f6d6c3bb29e1da9a5279fc090f3aaf2a44abd5482d8c1da5c967d9ab3ac71cdabfacb8c6ba87ce7bc9714d8d9b7824fe200a9a0a0baec5c3cac1bcd1e48871ac86c987b7bef0642c5c33f1ba8405f8c459f80367fdb835ee4d1dc813d5269ea365d544043db7557c431b2207324f88c94bb9e4e5565f9f3fe54ad1f287db1e1e93f4dc33eef04d0487c540ea39e96dc43ae6953db7b3d503bdd097b5492cf2e1899341dd1d0f1261f8b2dd01e07a207654aed22579c88897243eb2fa3f974c439dab9b8bed79be2c84b0686a44a77e9e4e2624d64d26b9ef033ee0d1a3e60014b162cd08668c0bfaf47e83a6ece33210d501b23ecdf3ee6755ec3257554d2a86cabb20191709aa573086e1b7af91a65bbfd4e3b8402ac11d155ee20e0afdb29ef1815909f4afda16a896034e7827a82a5fa11c662c62a391e6f65cefaaa2b683d3c31182476935d80675931500c0f032525143e81ed242add864d3f62198086d24d83b58d16e0c6d9a95b2c67bf9ea4515d8b9c903be342ae3c077c94450611938ee9c304219700d342db6649f82eff184c9a74dd6af7f0b15f2c34efc07ac760db90b787fc1d4f71e51f034758bd3de024ae4e47e948fe0010d591c6d3a897c3e3e13f8f8766d0a15f455af2a153451a269cba07e34b386ce2d06c6c12c02c0a3460c956a2b25e38ddd23bb6f2191585aef751eba22cbe2daca5d44e48784797f44c289827a8361b19e98f48d7ac0f23248160be537f6f9e8405a08fe2f7c52a2afbfe83b380088afdbbdea43a2abc820d3b7e2f027a29908c6aac47814922a10eca9455c6d58418fd01a37879f1f3366d5ef6cc5867a900fc5fda628aeb6b5ea8607edbbb012941bed40833a667ceaf518888a9836e16107cedbd732e564ae202e2f0463027f9a2e7fa12797e9b622fe21e2e38a98afa0427b8cfa200aadd355001b3cfa08d071c4228d74b00242c0160b2d731c6d226a1e5c5fcc61daaf2a7c4e740c0e8cc1b6a6e60276d63b857a87aa1deeb0c059f65c0f7b9c3a1c239e704432dfcd59f5e9a6be0527850be3e4be4c3fbad4d14c5499d0794bb0598916370985b568673188d789df42d3bd58fc965c6feaae423ca5ec0a818dc2c0915f42a3dacf3705c2e6dd2857a649cfdd8e98c48fd51191e218df75377a59749fb3f7336a36c8c269685a74c4e99f00fec7aa05af46ad6a34d9e10f4b84fc63694828d3af921982b03983d497dcb0587753c33f20acfe9ac1f92c313e66a6fa69bf10963fcb8231c4305b22871e7313ffca1ee5f58bb5bb3964a69be0b8efed8a33c9dcdf54f45ba30e6421225db4f0cb788989e1df6290d87c6cbf0ea218ae94b9998c5dc949537427a506b6a1797556ca76f5e394b7ae7aa3931e9749b9497c4926f18a51730c79ebcf7a92452fbc63b0333683c1f2d6662e813c041e361e020d62cd9d00ffb88dd24345d79ae6187632a126949bf4d244042b277525d450ce3c0247e28c28207c2000e022a08a263614e41772d72be6bff533394e5fffd5e58222e3321fb9a21870cf53fa6dbe005abe5d12b251c7450f438c5c879fdfb452c4e3e479f4ffc2bc1c2a6aa80eb39968dc268c92eec938efd1b71e3c915dd4ecb4e092128b625251504c1f6"
|
|
+ },
|
|
+ "transport" : {
|
|
+ "secp256k1Address" : "0xfb6be1504acf8262cf98669f7833b9cf1cbfabb9"
|
|
+ },
|
|
+ "ecdsa" : {
|
|
+ "addr" : "0xfb6be1504acf8262cf98669f7833b9cf1cbfabb9",
|
|
+ "claim" : "0x11ada655e5fee0a8bd99d9f9cccfccef052f0ebb97fe7a996096bde11bb31aec3d1978ca99b3d58ecd8b9638178479a25e4ae66c06dc6163a58e9ff2ddeaf54700"
|
|
+ }
|
|
+ },
|
|
+ "2" : {
|
|
+ "id" : "0xe7e6b4d336121966dba59a9dbe640a888c69c6a3",
|
|
+ "keys" : {
|
|
+ "falcon-512" : "0x09759c7daa5c5ec1230a0da6b221041eba22c8b4c380bed9f1c79cc6849a8e77eaeaad59438ce22599c5ce0b0ccda691c14a9a2eab17fb4886a4da08f9aa48a92448201514663156f63be99595261c21d3833520181eb4fbf89b4bebb7e2f754ca9a7b4fa63b2686555671623219ea134152fdcec214527bb34c24c2f1a391ba268588c488bb469abd36195a698c2ee829a09b2001c1bedbbbeee53fd28b091846cd0290f2c7eac0d9189abd1180e68969d294871acc0d5d26d2b2d86f1b45f10696c1471142114c0b8dd4269e44f1112f421360d267b87e9563398890019e1baf63204c9a3f09ce00a28576829d894dd8332b47d6f49d552077a2cab130727f886e8345a95c6f7575676088fef5943020585b42ab55304d2c000a604752e3c35ca26d09c3a8873fec5802c7d6951279da6afb113467a943c03bc910b31196f945293396acc88430a1c6af35d151306ab341b8510677c9efba29c889e16266155c6ce88c5572a629740085a936316ef14094c06eb06194450263452a4836029aced916888f08cce36f59381b86262a7e960d83ca5baef8791d65c34a4781bf049e9bd5cb6e3321ccd3b5c97b7661e330c84c6fb81813125d2caf59588ca7ae6c6f5750b2b04d0d9c18acf539b42b7f395069a4881a5ca12d69878099ad769da6f8d3634f4666fa53d3c8c73f4c10704a4367481685b4c70d022c417508e662f6905dea254e5e93819ca50755ebdf5f691371aa84ea72644e97fd8da83aae2e68cc5cc894f4d0e404af4b88069772f389ba6a2afe5a164fb72a3df800fb48385b155920ab15d25e3a2a76fdd8d19b126d6921e4758f0e36789ba7799094ab78ef58149e045a8b319c615de425e872435b593cca95f36bbdaea0c7b581c67abe4dd45ba40aed24ced9f3f527845565da941a21e14f12263aef44b471e4464a761de64386d156361dca9cd9305b22131f00099fc0462cd76630250ad52b3173b6c767434823ae2e769b1e48e87601689b8d17fe0196c69b2e603ebe9aa8c0191b1abdb8e91285cf2ab170bbd47192e4aad1c550901af38749dd946a2dfb43ce217ab504bc52098f4361c1dc3c70bb5a8b58d119781699ecdd9f53fccae56596c95d0ad2906c5e0398766ca9c88ba8062aa0e18dc07820ed8c36efa5b4446cb8c61ce64a01cdd31883e4ee7aa1b2664c8985673106088653342ee417339882ab2dada70a4760db65da95c09688574d60b5c40c0f26b79699646c08d45c311902ce616e",
|
|
+ "slh-dsa-sha2-128s" : "0xa7c13898844216ffceb386f10483a567223afc9605c91e848d38abd4a0ffeb67"
|
|
+ },
|
|
+ "pop" : {
|
|
+ "falcon-512" : "0x391a14e5b3677bac15cc47b63366257ea50badac7d752562a5a6afa5ff711a91bd54dec6e7e5837c143c262a1d6214e75fb1043468b77c4f6ce3a309d9f76b1829336b9564a1f039da697a563d2db4b84959f835ada466b4d8c81d0752a7fe762cf2aca8b37974c8c3ca4b145f0eefca4f1aff6d4a3ef2369f0b31c1b48fab226791c287823312ac418162a4985fae526db8dd36589630b24fbe3a3bdb192d78e770af9e86b17a71a2e402a7a475b3f0a4ad3bec7068cfedc249facdc5a091c356f6ee6aff1ddd15cbd6f327b3e24695481c0df52be15ad63c1cc9262c9364d964dd8ba8dde6b9df2fc39716d5c1dd45a69b495c9ba65b49eab35dd52d2d8116e24ca8871b075ae272d93cadfd2d78b14ff302b5227f6eff463390268921567118055a0b409dd038f4de45429910c1ff9c893c4cb8256805b9fcdea47c8e1d275f4b9476b7595c959e6f0eaf29ef99c247931e9a45c7e1b59f94471aa88e9250846348430ed73129256be3593d8c1bdb19dad2bf50534c2087a9263dd00eaf9e9c70a21e12abbc7afe92a61d18835152b348d174d3f47f1b38676756fc598bddee620a26439e7a70df440c8d941e1629044aa3597aac152243d9648f18a7282a3615dd6948f62b22cc340b24a494fc6434ed0fea54a6a71afdba06d0279e5b4ddc61f6e64ec1e65c30073e6547601376e505437a1146cf9fa8682c72e175ca1b8c8737ceb66c10e85a69dc95e758196d2f409ab45dc2764d3fa8d2746ed61567c30d762d587f2e07a32de0b0d8e143ccf0d528a901ea2053257fdd0af2a313e29ac4bc049ed6aa41ba9d6dbc658155b78f962892b2c25ce9f933d36a7e3987877d4fcabdb1ed21861d1548dc28c2304a8a72047de20816f2a57b8d63b03d144a2ba30a0727d447da75c96c9320",
|
|
+ "slh-dsa-sha2-128s" : "0xc5f92902ab559e6fde0432bdafb0deb2158f541813bbbf66742ef063d8d61e5bead214051c06442eb7b22837a35cef97fce268117259f99687c0c73e3df26109350825d638ac24ab0839e252fc9bed86b1ff19c2d6e47519981fa57f48007c79940f6919964fc924314852ff526981f31d37be854da518a795c661ccbc3712411302aeb186ff1bda6a59f93022b394f23f176f907482f7c26ffd0525d7a130f1f638b8631324f6edddb307e258a936dd71815ed22da1974cfbb6ef189c4e15efb7a17c59648c2959ee2491d752420a2891207a678f29860357017341be2ed9c7f75df12ee9a47fbcc2a59d434e26f0506868d168e754ab1e5eaace470c32a075ee317f480aee7b2836db2bb63fa9356daa21b4f182d9e02c03274bdf3770951b303856fc7a4e0b37ec8b6d47426491d28bc9da0f1720f81e897f86e24b01bc4b2846ed15b89dbae6c397e63d54d042476bbf206bf268610dedf6c2c55fde1320a484bc47a86e8568b9e6c13e19969fbea7ad0bcb6f0af9a2944ff0a3ef95f2dbdeb3e1930d7c5b65d1521cc2e024a4bc991c66970c69cca019a3ac14e8051b94105b661467313bcc92da3864ebb7a66449a67abcf1409e46936f6193efb45a2102033ad72c9d2900cac64c55f31a4bddbed1171cafdcb63881fc5006dd963734c0d16f6460d6108cad039cf9957991d37f42dc489b6a30cc8884b0010ac9f9457be24a2ee76b3e44f83a1c23230b512a8efba547819e9018836b298c3ce569423053afba3a33e82fbe41a31546c12c8f8f700f68b63e6f2a4511be2be777cb8e05bbe568ceedab514f3004b634335001b2f3e907a0b56d416dbf12fda4e4c0c9697ab7512613fea679caa682f2caf2d24835b6c392d83c27dd95bbcc88962fb77b98960ebc88caed1511065381fdbb1a66aa8c2b6137521fe5b2a79bf89cac4a9595a83707eda171b86ec497adcc06134c7ee7715b6316b817c78021f3cab0134de0f9de03cc2143b871f3b1d97c0c3f993f4ab712a638dc053d3fac8453ca142422fb1693686762c050764671a4b973b9065f604a8b0458bc02be83281f4b23225f18a8dba19554090c33e5a8f20a3db8f8e7856c5e6dde98b2c271bab1ae3513f1d1ab555f909ddafc2eed38a601f9886c3dbd97844296b1ec97d4f059ede10c883504854f0f1ff88e008c56fae4bce7afb0f9811c6427b162e421373c2cf22216a495a0360b50f8eb31118fde7f2c4a62da1065c9d3f2501c089e76fc941546228cd3f753cf37a825b625bfae3d1ebc1697ac3f0fb94f86a1134ba91e3544f8a3fd7707f86ffb12233feed4d8994c806915686fda90121ef66c4cb477fb6d4280ed1c53e11396d90aca0b1cdd3ab73a1d59e264bad03a159da7a0b4816500aacc2c5fb47f07e5295c3134d306c8b0a0d2be4b311d52fc8213320ed35c2338fc9a86862bbadd6560283d26cd282872ad7263b408f68001bf82af6f39017fa174b20eba3f474730d9908eea94b69fba5f8809c4c5f49b57ce4a35b8eff42360e3f30a0133fba43e0ade7033efe9ea3e8c283d155ef8d3628a23b478afe05897810bee5a245c135ceb58c48778a6f7c6df5115f8fe15dab72b0cf0740874015c99567ef143f3e55aa3f670d24981380487cb8db343f13a14a2973fd675b1afcfbbbd7b23b9ba603256e47c40f1a909ab45756ae8ff88d6f40766c5d80147e2ab94b3dd8c561b42c391d4f28a748f8634aff32c76d05af6fee0b36b8c0904218730721d613c68ea8e137c97bfd74c227c73e274189868468f5f96302da3ad73bf92f80712ca70dedefb93ef7aee4ff0bd32c379d694512548b7e3d551c16e3a313d31d6bc7576c2e3cc08cfd8c6ea4beb4ffcaff971c53c0b220d4645a6dff8bff1a165ab8342ef577819b4bb141a4230a6990c3c0f3dd5fef09611c65eff6ba1636066b805ea1ffa7cd03c3a43412a55464a19e8161ebbaf55d95c11a0b9242294cdb1f8119b023753c4f8ada1b8881edf1a3c6bcb3f6e49cd97aac5fcb745031991260d6352d49d2eafd472edf3c8375576d5d666095aa90441898479cf8a6d41aa5928a2d5e71fe7baa975aecf8edf476a4b36b3a92f6044fcbe676e79a2a2c4a67ca51dd60f7707b3d23d5ccb585c4858d75f7b573e82022a963d0b66f77f314a00c0b169abd88c518fd6adb65a24fd186f8331e92d6b905ec1abafaaaefa9e5670e2b5726c6dd0f95130b56fc0fb738c312c9d6f588feff98d84ee90ad3d285be90bc3c4a7d2056965cd971d8ce136e35139debedd41894891df7a26f82f47dcc2d2a9f1fb52800f5d016cd35f0aedda35dc0187dd962e07d36da455fda0ee4d54f72e500400b56f249a73c5db217a8329d7e99eb4a810bb11400ba1df9cf0aa806d9eb1c6afc46c010ac906709ebb573463d508589ba3dcf74c749a554c75cf2dc9db7292b5ab4f939a41819355ccc48d533f8a0f5841f4d328bc754a3bc22ee9ef34d4e1ffc351c7e8cf4cbe3be7a02ee5aa7836147c328da32f748a2a9973d18db9f85767ac4442ee056c6927ff20ddd45df2769c03e3beb73cc91c3802e5c55f49cd56f7c962283bfe7e6374459b81ea39fd1590e4a6b68e883eb62920b05e9031c5800f75782b34e000eacc4b0c5f9264411b07213a6409bc5bc4c469ba33c93ec3ab4260194c445e489cd87d723c45baa5da6e845230ed9c08ba7bbf7e1c7cb78cda9546c7c1f24867c02a3150b034cd0c006c4f95dff5fb53e30bca4195acf5fbfa21611f6ae55ad6899609f157f6c280db7eb473dc3f6e39eb856029eb251adee20f9c2377188f53a4bb66c979daa9471ca5569d57e7fca5d08b7af2165277c60649110f66950062b74931cf8e5a7ed45bba48668eca0887bac514c47e1eb1f12755aad81c5e297277f8156f212bfc4ae923c76f4826a976adb7982c0366771abb0f4b137612b58871090ae06697f5d975d659b82c720f2b27bd027f532f1e1ae3b2b66208a027a2d4eceda8188bf79823de4e4cfcebbdf0d0feb1e4b3896d758c79a655c64557af82150647697673bbc77f6288841c043c63ef6c5ae5eea8b0b51f05f9d690e39416d57047b87310aab88c2b9b10faabd6eb703168d9099606a49c51b5ea7795efdeded3a2b336fdfee0fcb5143eac8ab81aa60b5d81cd493ce00cdd2036f9328f6024f0d584f967375d3d7b1cbb8cde327adb52b94da5ba26c507916404d13177fa1cbc4a434c7991fed3d9cd54a130a8de20bb0cd44d8327b61ed9a46c6ea77b7eeb52a8eb74a4d378b763b49cf85c900cedff88bee81d99368a701b9aaeba74a8e09f1bf847ba6911228365071678eba9802a3c914f51a35eb715c0dd18969c1fe1f858f02c3853bbe4205fd45582dde78cdbcb95e2e435a55d4d6bf9172d15e7f4b496ddc08a028524b983c2cee98d04cfdc703bc73d76ba5d494be6684a6c94a5c64974849bce898b35a765634833d1c007af1d52650eee6b9832d9981125edbbc7f79ae596a366c92f85e34909b544dc5bb4425db60cbbfe0d81734f804c2ce4e91a445bf08740513d85742ad04963ac02fc906c8cacd0c25a20ff016cedcf6e3e4b4efd51058939cb90fad0463c77faf8f39e317df8689c5d256edec4c60a165c9d2719e96a1df0bcf60fc5f6b26ad9eabc1653247fb697ec3a6829a1f9ce1b7e2a87f903a0ef7f28c1dc6e09c6d352de2aeb0d22e72e7528fa9d09c98474ea161d8c2436fdc75dc754bc09b9d221d26e46bc683a910d8d4f7fe2e819611bf24559564b8401526b54cf2a5500643bbf8b967cb6b88418b6f124c3595526afdefa0038620cc179bc37a43806f772d667f3f25222d42022ca0dd634b6e567d1cb35211586c88e961ad38ace38186b8a7b968dea9a0d1826e86036e1dc890bd381de583c9c41706eb4b743bb210fc01b972c1a175954f13c8cc7ab760efeb94817057ee72e9ca23509cb85e8c2a2abf9a61175ce0ac9a354a52f43599abb7e2a72f18fed0ed76e6d58c1338fd0d5a1db58dcf332d74dd993ef0cc58d65a5f226520d663ab5d17a2d4010d6ffea4e7652acda9a3329b7df7027d173aa4f27748f8482bf7f540aa72d083cc6e126704188a54c86feb03d883d161dd1a398bab32b5b9a2dd9a5f041ecd94fcabecfa11fc0ad0e1c648fd1838660e9cfa0892740f8a4f617d795c0e2701d688a3b6d9892125ac7a48baafd29967e09ff9b4ae517bb9de9b9c931062b9c95aac9cbf0288c17ce74242575579585968079fa78a57d0cbd09a891c47c2163ce5a5aaa202557d5960e68b1ae00604b319b6c8bc07d38be77e9433d6a568f409773c1b24035a38c5df816c641eee0c1c005e5eabd06e34b05d4fcd95bd9cab610074bde699d19df4c458acb4dba5b488b7009b2f97778f1b7de8b19e8d35b45a41ea8b357db74cee09fea30e61bd15893e588c07bc579a5cf3bce4274a05b71ce85be4100206d740d534c58d3bc09945f517d0beafb41a6f8f872692c9778be0ecaf374be2c47d203a5c35c355e7a01d65a8e54b40e64dcb7db0e718260627887e4d8b2a3af5c0cd5c45203e00385226b0090784a7d74d05136334c0b27bfc69888a69198fc82f4596acebcbaff9f4cf3a0349dcd358004b8eed8162c213d8036ffa7abf009099e598e708abd58c955b66fcf3c44eff8702c04a2df2d795cb72bb366ad21866d81605ce0f3795d020d49138269a30cb33ed0045b676928daae2512b5d85bd9487a9f7e5d0887ae634be7395cee5aa9c581ddc0c94112719c8d4163d35780ceab170984b16c58212934cf0b61fe7c36eceacd10e47399cfc0493678ac9c586d5428582ebab0be3299f0afa03d8833dc3fff5d2a3fb69c76714f81034cea7d60cae87af6857dab1cad4daa91880f4f5342c182feb8bd082ddeeff3903370dc20b32d3fe8c98173a01d2c12e3cae66443b0f6dba91e9748a2c827f646859ab59e81c897d59099207fd5ad3585556adde00370544adb52ac25bc9d2e6776cde546705aa568948f34231f5c35b01b0e3d0d44f598f64196fff393dbc2fb1a400dc4aeae664d125cbb82289623cd0cd62c6db3c4e4dc28e173a047d2911e4319f3edbe4c8b8d03cecc4b3b33b97e2839c74a317c6cb9cfbc2caff761185268ec74d6853ecc47e22dbfeb2bb0b190165409fb33fca801882d13c737576d04d528f0425bcfb0d25ca63a9fcb9dcf389271c58eb19dd6757f6b77996c089c33444e34f729f35ffb19f130aa9c17b66952cb3912401c46ed11b2df097ed4fbfaea20061061312dc214010387edc0dad670ba6d329311ab49eeefda21763d24ac183c5131b966dc4cf5de88588c680e659d73c37c3f860abf689c9635a4ec2503002a7dd8255c858964216df760046c421dba6e02b9b5805b2ef4882a4ddd7a3a6692dbf25465217bb0d55577ee026cc6dd5e2e53f83a4beceede8222eb23f49aa014ef1e7f4d39125dd894a9769e7a694bbce88017f4073b551cda1c9dc4efa5dec70ae55975af1c0cd16fed174ea3ba33fdaad5607799137fd32d2936623a1adcb7bf50a0f0d7df6f046a5d6861df1ac17c47263f3c888331007c45e73f41534e34566f38b8a2ccb5039718d1be91d9bb7e45c8bda1acd8438fc1b07f120bbf19e9478dd7b68d414a8eb66a18ce0b18070adece2b171a68d819680cada4b1a403401b90604ff4d3b12070d16a6a9ef72a023aa926167a17eafbdc63ff0c6d5ff7fbad22bedbbef04c184dcdaf35ac02f25c6032c141e8eb2537f3fabc44f65f17d9b01bb7e63f7474c2b11bea164275352e73804ad89a07cbe6addf9e4226c9b0c1ef5e6119885d00788b1af5dda7da3270bd401aff076e14e1fcd7ca6edd6c1e8d2395b396a666cb4229d6dafa7935d2a47e570c7dfa266e3e3b7b9dd5f1e2f15277876ec5d3f3c90c4fe1da5427541831de52ae7b1bd9c8afe95747b3781c87d009c0f676b945c425c88e0ceeee7284882a7d32721db686e508271056dba07dbf5127981230650010cc44483fa924cba9941d0cd6dca2b7cab6b292568b60cad722731c64d73ad94504d7a8e9c49d4aa2d3afc4e4bdd03bd1ec2bdc85797a654ede215b6a70f8c80be57c477fe79069a21ee30de12d00e7294503d821842674f7eaa15b411e536ec5505df64fc16138cca54ae2d3ca7346e8dde6a4fdc46b315b6b4ef702523aff1123d1a29e5ac81356da7a31fcf0c2fc83022b9a265e1193b747be2c86e249bef82b31012b5eb6586d9787032241ef6a030914b5549076a523f902dfd1be17cb05ee17042cf5e29e548af4982f6bbd2a15e3c58264c9c70f0c17c702d672e5701e168927ed794222552cd81a9ce26828996bd87fe8d1eac6536b06d589fee60f680e657689203dd92ce2d0aec0e5135badb805a407efb692d6a73066711242962eeaf918b8bb3bb09ef45011793739b374b76fee3be0f0238499698cfc9489cbb20a60136117b7674b5ba344bfefe562b905bdf0e959deeafdc63719a36e5d79234828cbe72d0b2908efc02a77678c1daeaa267c52222dc581420d3e500bd7ca27c2e68ed209a263783be89de125ca399a588a40bebc0b37cfc06aa5bc754b7bda94389c165f1dcf06cf98a672b2ed93d5fb4fb59ee8c7fe3e3d6bd615d2764cc0751e16f627d7eadff50a866a78fd6044afa7f8a7f43c874fdefae40c0384f88b2c8e16fd7649bc517fd83c66ea039dac7046d913008084390bb5f858d17b2d46cb5cda8bc390e0856083f482f305230dd0e4aae03efb12085119a8b9c5967ecb62f1be5675378a46b38fa4afea0617ed0361a1b0ee2aa0c4cf3ab88935c75b610cfe36af1276dde72e4361b788e3ea935602f4a265136f15e3ec659c18804dcf864379e93229ae198b22b125abd3c463883a21fb9a219a23c81a5d2cb6b9a1c75c7ec0e412de22e96e4eed4573aeaf911105f13e312551c387966b4481ae8ad92edcfd96adb90cbf1051b28c1a5018c510a23c0373fa30d6850b46fa0ab4fb1e2538a7d0ffb0fc1c3641009df67e2ea4caa141da66ec86c18a6b5745a1279a66c83888396642a7ea4dfca12eee073a04b5a4c1ffae875f6b87fb1cd79b4e9ae473f1cfbef6b8523a795e6dbd7b3ddeb0449593e1d10286977d43f5236c015eb62b288a054d04ba1adeb391caef62a76b4a454ebdb270ddcdb35849f0ea9c7349a3f0cafc2061a012ac0a877c6fd253794a8111b967ea880562f8be1a28bee3a28a95eb1dc82244b1d967bda97d2477cfd083e39908feaadb0ad15631b9d0df00da2c46edafc35a2055c95cbbe5e8479688ebdb606227512797bd645ac6a43240799077d948f565c4d4f514baebd107bea8f04ae936f1ddbd2992556142e8843afbf22c35c54f49c3be20c4fc1e63d44b6077d848038231263a003ebd075a24770eac8d7f995872277a2db0844030974c979871fe20722d255bdc54263a6fb64c1a20ceb5913eeb5e0651ea88b8cd5ad7086c18354220b3a576507d5c26a9a0f3c4915a6cbfecca6edcadad8c331f2b63555d6f09497a244d99ee8360b1a86dad7c531f96428676ce9685be3730f16ed951d578f49f5424be220f914246609cc8d892f3ae42bc1e927a569764312773a6bc8ec183666a3aba1c75fcf56108aaf7dc368768045703ed5d615c365b6cad73dcd24b3406ee553650d1a7ffd056a4c26c47d20a12935b0e923b0318d6229f62a332223c910b1e1d9f2ba676e87f5b79b63b5500f9b3c4e11c12d52c80769cef99c648a2b061bc90a215df74d485669c49940436488847148016d7be6397d44a4f915658bf30f77d84ac8e7ff918658df21e79aa6f53c97ab5127bbd8a8fc3d77bee7b044f8d74b4282171fc11a2f3ee290136215b98bc814b86ac41f8e6736d2680043c07fcd1eccab82187a39f697c4df2fa6397635bd9515d3b8dc9e44061473bed7fab86a7c2fd3f53df2d4cac543a2d1a686d5f568b061effea9607e3e3cf729aa2b23615b0fbd5d6cb03ae161dd4e27c83f68e76ba8e9225d61e1a558c6dbf5a2e326104424acf320c60ab3e5ac07ff830c286289c8c38090b40880080eb2fbde41d1b648e99544c6dc42ad24ce599ed8e644ede5acb79fe7f7400f030bbc00de8508643b08d0f6b0b204af1c4880ecf377596bb45e7dbb72cdd4f68c046578c0f554ac63aa3007c52ddf1dd1d95cdff771d2eb42f8a263c4959a9f98127074c8c26de456d101e6ed84e75ad249333730b5dc5d154605323a755b246bf1587630a1c4f2594732b9ab5e4ff6f509fd48e0f84c05b7b014a5b0aeef7633649009bd93b74cade4cb3dd77729e5795dbadcb57d1eb8ff0fb3b6baca69073814b0ea7838d2ee2923e4a945a9d88125fbfe5f5f980d230df80948759dcd41e532e642b10d14ac97cc76c217994ccde0b6d1dacd029c1638a70bc9520d39712789cf69440e81de167517479ff7027ad4e840baad6e30be1514472344e5be1dca2f9dd9074266ae904b9ff042e83d44133471e856210c2ffb08024b39a547aac63d2b7b9555c2489ab3aac14f0c382915df8595b100aeae81d942f2dc898e22825cfc27692732c743bccdcb98bcf0ca8abe82f65049d483a62ad1728534d0d110d07d176cf93a3bdb8e930f598d2e234e54f1345aa26a2f9122cda2eb2096ed52ba16852de8ee5c0506519988b010c9f87104dbd5eca24dbbe08dacefe0ca884d1e9958767617a68cce56ac405859debf5b616392e4b2cab2d8cd832050ddcfbca9384608d3c21b5f143bb795b13f8db9cbe35d5b295ea327105fe369773397cdca7107514ee1fccd4b0f71ca23e357b297ff0dbe872715cc5f7ab653c68723b6dbe1ed3336e12428df5204297024c7132019f4d3958fdce3d2ec737c9e4c97c0a6e5d15d888601326b8533c15f39271d85d39ab63a092f9378ab2a9fb15742d4e959f80903c2819c2474679dbc5ae74e24a80a73ccf6e020f083ab23267bcce7c120ec5808abce8f9767b8aed75b3978d617d29b0b6eaf4c3629212cfbec434910ac538b9cb7d3ceb61311572ec5dc41571d95ebb506a8163c31b15fca8fe64d04a01e87974dbab2b140d04399bf0626db12cab947c29470e45da6c2dbf8987cd24208e1e68d0ebdca946b8e1a62f7a299641142cfda6940a36fb1586c3fcff4c207ce3f4891a386314b223aa292ab825b703451aca99de7d07c1d97c08f6a27d640caa99b0d52cfdb08859337e5615d475dde4680fbdeeb4526cc95fb35c869aa79dd2da52db6df2a9a0663558339cb03c2adea58d47a039bfc77730c6e6fa918a181a6894f875a6f473d503222c470d94eed7f157fbd64e23956ff8827ec4d8e60b1f3c95d3a9a0e65165bc1d1f217ed63b27cf78732278c750b78b4b84815c011ff6305de67c5869b81b63c3ef6be0ce22c3b7660aae1600e91c220fa8e0c1977c2ed063dbc6aca36187748b72c39afd1e93a74b7ecff456063fbab7af1124c3b7c3019288af24c8e65444b7b82f582e1074097654192a44e066d36a7a9502af8e45083be2c1bd0ce7fe6e4df7d5e4cfa7fdf622fdc52639f4f4592c84dc53d2508a4454611ac8b7c193d793e76c00ae119982edf4a548a018d99980982291f2e7fa41f54bb0586866ed11999eb044d73e0a89930746fccf48a285ae89a9b87bd1781081fce25507816dabff979bfc7adf71ea02a514be0aae7d6c060fbf1e84074d30211fcd3b3940a74d8658f72e6bc187e7419fce5a654f8170d2082fb4c1ac30b0e33dcd29edb5189d8e70cf2a03eb18756dded805007114683cc8e874a26a346fcc189b60562b3a88825fcf8ccedc520df171b231f323e085cd2c2c1381c1f30cfd3a9c0ec9613d72a3be9bf76253696bc387de07e08fc12ca66f29f00abdb10a278b395b0cc4259b2e7a42ba41e52e8fe59e2c9fb4c999702b1c16f605997496f6828de470c97e8552aa30e757d8733d0ae6d7bb5b542391f6c7d4296b792d7dc0ea363edd6ba9c0a88c10baaa862d8dfcd1cd2ea7bc04a24518550b1ed90fb1be9d4c05b083bf0d7881818ab2d09a43efacaef943d9dbd60bcdee0d7a226f73a114a79e4719aea40bd59cf557cbcd65c3618c5f611330fc4207fc2d8c0efe4f480e5cbe5498fc410cad3527738299fd28e4b0394ffd0e66d1d8780bc5963dc63b2da95224c5373062a75cb09e715f530c1d4da7bc4c053985c1b1c99094bda96239609d9895ca6ffee8d56f80d7aa7a144296df5525876263a433854e0c56476874b69c94a1115e861b53f17d9efe0ec358ef0ead5da0aeb44f196160ce4a03a66921bd461cf9f3c270a45a0d468897f3b12ff15633bd2e03dc81bfec5cb2398573adce7c99946f633f98363b8b70e0cd7ff3ae30671e240e051cbd262f77cbf85ba58a770e9da2ad43ca713a20ff6402a54acc377c4fd4a13316f0551f794d23c5e51daeebfad74bbebaca3af9e4a93a2b7c44cf142ef473c449345b2ada3a07bfe132dde58ed8037963fe9819eabe8213a5c58b6f1b916a40ca344e90ccdab50103894ce2bda2248ff22e9d6866dfd28d3871eecf160d15d88db2f91dd61905b8ef9c7ee1d10594249d6e09c2b935d153409bc36fafe6d26563e61548898ee854201621d9fe67dd5206378954ac2b79dfe46e6a9ce031af2a5938ffaf6109d09e249c9c4c5935918a65ffb673fde2bf893e86c32b658f049f1e40cdf631400726fdc37d9606e5f730f5a72e2550eaa244ca320eaa1eaad7a83d474cf03ab43f8099be3d98b3b403ad074955f999cffccb4cbc781a89baa6a570627c3d39168f586efd44fb82a86ad66acffd7d3f1f30f3a138afdfafe8637ff67a7135ceb96b19dd6b1b0a5c9bb3e0bdb298b02c0513bf29dd5363a53c1cb3c06c1bf39ceffb542a0836c1264d46995ebd9238aa5eda7ba6887572479e9b5decab4eedeee5a87c86d1bd07f724b8e250db6a72ef5141c0dd32068ca1a82c5f222e3ddad24c65c1133a13ee0e8804422a7d5dfb1546ca24359f1c331f73969aa10ba3faed3b1735d70b481da0ab5b6e7d731d830332c49859e518acd5b4c9cf9eaa2be436be01a1a7b354082f3bb0c6b96fcbdf742231f474bd4da4725e5a"
|
|
+ },
|
|
+ "transport" : {
|
|
+ "secp256k1Address" : "0xb84ec13c5811264f60a8bc392634709558223ea6"
|
|
+ },
|
|
+ "ecdsa" : {
|
|
+ "addr" : "0xb84ec13c5811264f60a8bc392634709558223ea6",
|
|
+ "claim" : "0x72ca5b8aed7f5886303f0228b03bfa645864597ef3c7081d75ff03d29931031924309478668c7e75f4eb04a9f1f9afa61a6cfd15ba362f1012e440e6556a161f01"
|
|
+ }
|
|
+ },
|
|
+ "3" : {
|
|
+ "id" : "0x5fb56304084a625a9a0eac9686c07cf2f9aba446",
|
|
+ "keys" : {
|
|
+ "falcon-512" : "0x09ad2ebf1313260c40f22071ee1fbcb0e154d4bcc90b6cb9aa19cfc95fb5a2af7379950b4e4ab5651392d73d06a6ba2a192a670939c10ae85c84c024a4140d83b7c9b1a349dc586ac9f138d9d5f64624fa632d67d521e6a37ac14c987705702580d6031dc5f2d8c662cc27ec0b9a52afe650cea811dd9cab6190784875eb68582d434197c6386639ade78408fda7baa8cb2fd3916819c9d174e50000c9e89bcce89f20bd99f12085f76f4cceb96758f6352ae3019ac290037ecad880de3e0ce4a31bf6dcc402c0cdf7442360a9a4bcf947085cb452d431b0c2739c8833c6d04e595b6224954666630e5e2ceaac0a775c3953b71f4ee4ace262a394672799ae8347c0a05d3c24c6355898334e5195d13f4e652c824015d805e33f3675f76fca6bb701e2264cad3072aab446f5165c0ad81195cf4671708d27dbdd87027382ee43aeed3fa18da5e0d7a23514208e88502e9c986d0dd747893c7151fbf191a04d53b2964380a1fe8b751978341e3557d81502c48eb36d66390ab06743235922e08bcdf99f258e0abcac179bd10c2b718c736a849067fa069cbdac00d3bc9a7561e698dbe1ab73ab2e7ac0799816829940929e863169e82ea7dc87a96b29dcbb392e6f4aee0e41ea512849629ab126966561d4d0c149c14c3871136b8289d6626932f51629061a02c50a2c9bc8a27d9067f7d273012e1152e8e17246ee818227938482188d521ee99b582d3657a8c6a14c50e9c822271daf4eff480786ccb23ea785dac600b7c13c32ef983c6fb12635b80fab8ef85ff4d5ab5f3dde22f48d630f26edf680bb1677948ec09073960032252cf45b62bf5300327622de5a17c4e6617e27b6acea8262c74bd27936008943075138bc5d61ec03a3491939d6ed67ac21229ba550547f71d83399f38df6bfa0dac01be7507dbe62d9e76c7a7d54feb32ead736a2c4cb9eaefe8b6e26e55fea850b06aef59235de45f80e662edcd6dba6ed620d34f7c3b34a03a782fff46c216cafd9ead38f5d963e8061b08c6d9e2c7e70691915ea99dd96604f52605921e9718c0f637300ccb6be842f1c29ddf4fae72313f20a5bd09df65d2da0240f1a3828f6edeb9fef819d713fd35ee5116c7913912283ae53266548c483495481f59589cfc99158c189b358f26949b19a43cd676509ca47bf1b1e449c11c462dbf48ef4cbc5bcea219184bb428445b5b609973437de3ab0ba62ebdd6f6d888666f6c3d05a81dc1bc08b6f7516a1e7c9909a2a76148ef",
|
|
+ "slh-dsa-sha2-128s" : "0x6c2fba92712689037e0aca0290f246d7cc727407006ad3f95e5a5db8a588e588"
|
|
+ },
|
|
+ "pop" : {
|
|
+ "falcon-512" : "0x39fe8f5205396d5711c256a86e648362e0bb19be4c7b42858d71d3479c884cf100364a31eea3238498135a67ec3377c64d19cf3b82d741d517223fa762f99fc9d1a66bb61878d739a8d4d491090dd3adea6112890ac9c9df895a1dabc3b85d442b8ccb69b0cfb2af801024173edbbb8579cfc8c821bda69a08cdf2a594e9457369e54f20ea4254f0b91688db42a4b0909e5d8343eae05e72698424fe6e54a866071cc55ef7f989be46e520f5b5915a7a23796cbe9799fe2db386f5b086249ceb2cb82e541f554384477d8314d1565864372890de717b1ade9d558da1c78e44e155f15ddeb229963ea923c9293cb8e687c6d7ef1ab3968cb2b58be4f996d41f69dfe0f8cde98bdea72990a8c2d94f7430983b0b270a078fc4b56b6358fce0cd874f1f1723cf4439acd926b37cb53538dfd8788d2ee15ab96ebd11b48a0ade3369b9161c156722a14564f115fb1470ae9dbe3c23406355774a854fd8c7f437893bd3f5203193316dfc43ce3f0752d8ec3feb5b86d050bf185a890d575c7dd5edb85af43f1fcdaf8cc5245d1f2c3542d47059885270f3e5edd0410548dd3cebff41ce3955fe90f8dfa047dce1e9a4729892294a8352221816ebbed819a4ee0993c1069938d9c7fc8ffc7ae8f5b13aa5db6b4dc332a963a50f355032faa7904de40f65c3fcb45538fc9b2df76f102cd1455e3d8d5efe3f5d571ac43db9e321b2659edfed285425d661c5b942558aa67a574bceba892d7b5547c37a9c481b45616372cc3f9f7c9f723b891455dddbe39727120899b4174f562d9c4926d65fbbab1b806d73cd59253767a73e904ed6368bbb236251bd47df5709b0edeed8ebeafd4addcc24922de5ebd8c276fe6d6cc98f8434aa56e515367d756fc8fccc514ff74e379e6535da58da15a280",
|
|
+ "slh-dsa-sha2-128s" : "0x479404ca8a6d0e5afc9302c665661405501529c579400d179cd108b887f06f67a49531e9a404f5918851cfcb40c1f6981b15d9683bfbcbfed4263b8ca491c0836ef07169fb1c9b726e7d4f53687fa5cf6e676a3c47b72f17b907ff7167cb9c40a2cd79b4204335a21e450c0020183f9841c64cbe7dcf6839711620cb47d883a826fc5c5cd1733e2d04d39bba4cd1a4970efcdf1ebdddce9326c77ace52e0f5adcf64d6e9d88fbb5b0475a4c9f352ba04512e6f02411fbab6ef758b1eba7c0101f4e102536a6041726af10bd239bc82d02535c9bc56bd38930646f915de872773c61d82be657072e1b9417633f206323363fdde40f1b55d3c908d832af3f7d36460875f2ce1a8b8b4fbf663c7506142eb81e25e15d1339f579bc6074e42bf567b55510f55e159b975defa192b8db0b13eac4fbe909e8ce67e17f8248cdabd1b9f1eabe0227fcc960051d5a0dda5383980ae287169f94ba69bdb9d6097e1d3730cf5929650317b0b4e26e8440e7e0567d6cfe24dd4ebbcec348b4f67d39c4f54afbb162b19c89ff00dfc252fdc7955eaa3f1b731dceddf0f7d1c0c9c601fd135b6fa13f970457d353a051d0fc76b5e788d6d1809925172236ebb7283dbd2f6ed681cd460ee6a2b3eca9436cf8ead6e58141f9c562c684ce1a51d31303f7c0ff3bb059b7a45764f78cd77156201691493ffc51e792a13e35372488d91e4baafab692ff4e5985d9910af4d4cc1a1849aab2f0b4c0c45a89a1310c517853f95a9e50770ecbdf7143f487b69f89864044c7a1f4f6a939421db174bae57575368a08b219e66e0aff1e33325dbf88e7ad625b413b54c9a6700a8cb7322d1ca8ed1cb9b69a4034e6993772dd12a21fa3c7ed82ffe175c77d749097cc75e7458aa9d7cf387cb7af687a8e60ff19e32de46077ed037baacbaeba596c2665a1c22d2870910b70f0ecf3695d137b5271e08696bb9bb9b70226182eb30243aa6946c6b31b2f703319faa7479b2ab0f6d4d5a3512e19392fb02a55e9a4d5d5e1a46df95ea1830e462eea4c33e8bb69fd562d9ca21c34bf431eda3ac5ec4660048bb7f0aee9b22eea561444c6b0494651d52cfd6857e1f09698b4a73e67272b670222fa77d77715b64f1342c0512b277d310539a58f8a1f17a11e3adb9f31234088464d8b2d1a74c0d33f133ef4de48e28be45b3f8884dbd788e5f7b846ee71663e9fc34692dabe7da0dea6a6ba2e80187b1ee01e44f38073c9b9cf15c83c049a93c62f6ca226b73e0d738576962c862beb1dd7b9280ae7fddceb507faad9848abf772cf2d1f9c714d886bc82ecb86961bc0deb67bc17148edbdc10e82d4859bfac934b343165f0264cc9d458c7d64aecfe6313ebf2b9adb74469e4ef56334b4127f1e8901cf184682c05077d9552ff78b33e59212889d25289d98e980127186de0fdff00c285f7f5f7ec4af64d42b119237c62948badf5b4382156a32fd1d3a3fc4f68712a6aac29759d4e37a1296ccc4d6900adea0ff3376afd4b4827009c6423da3c0c9a05b12ffd4468afeffa15cf8f2566a692d9eb336610f641cbaaaf1ff1d9f32a4320844d926c0273311ee888f5ea5e81a295405d8437b478235a86fac534974dda508b54f797837b8845873462cfcf243dd4e17653572230c7ee5b7322a6465868771446ddf9453720be29caa8fcf04b5d9e39a338ebef6f0bde702c433fe97e84af71da0427354f0da0966a4775477285bdea5650e6c45fe9b0a5a5f229dc82e6db78d153a52c81bfd850ea6fc2a35f45741e6f3c8f8c435d0a53f55cc105b319089ad4cb7f7f95367277abdd6e572c2ad414c08591a3d310e32ab6a7774d6845610428a0fc4eb21dcb9b03b91baef9be1e283f63561f8282015568f1e5064b8f2adfd6435388dfc9df51b90e204d3a9ce8f1587138fb8f759b993564c820607dc6baa0db7c1f55b406038e43fb970c7d956b35155346b346577a7ec02518146fdcbe98970c3a04d2da35d2dc429eea19e929d8ea052c1ee599ce2a54378eef202351b982f457729fa507438cb8cc55ecfa2362fa7261902734693c980f9a8e009003ff9df87a0174777753ce1625857b4e446cbc4b9ea639ceb1ee6cbf04306852f6fd5664a33b1e62a7c876ba371e81df54a09eb3f678c7b0fbbce35c54a3b46170b2b7ea75a1c4fe36b7536cc480846fe80d20c937d3cc53eb65be17c2c09c66afcb509bbd25d192929f394414b4244e3a0f40f1c8c93b2014e59fcec041bfbdf3edc0d354291842038caad2a49eda7db8d7ea4c8cb331790b67ba304542a98192199fed5ffee132670c1fdaa7148a1b59f268670565700743930392062d2b4dc19b2d98d0d522613c23986b8fd29fd76e822eb091d14f012526ab6e3f5a2f0f71b2aae8453092431a389be53b85a077ae9c21e2ffbd7fe6ddf1837b4f4b06a3f5fd11d0cfc34961cc2af3b7cf59299fdc52712169b26b5c35dc69127ff129536e3f4c7c4aaa7ea042e068b1174c5f64637998d44f4a598b0b68a6c7ecbbf08218d6503df80ab61514d479fd44b8c9530ff5fb96881b2b0549ffca395caa2498e5699b6cb5a313037f8a74373758565cd6224271f22e7b01e13100f7a1e62f6ee1f956c438a66e298e6f5419078e1468b5ae66bdf6cf7b3ba69dd9919e0a754751ff219de7cdf4dc09889f11f18552b3f225aa345f6db6b65f5be0a6d6c8cad06b3205cae2a42ec0d08cd8044120d602a520aa4875c49ad566c06792bc33f7ebab5b8259e31fa3bd001e4fcaf3ace4854c259c747b130111b1a2eaf8ed79327c856f8428049faad8e3c2f3abbe88b86558582d92ff19d5ab8c0fd50e4f80a82c46453d621bf00d3b4cb3a75a988d4b6ea9fb11039450a8cba1eef7496fa7e3a0ed52da10d0d1bece53c9390bc7d40b6cdbb2846692872334098ebb45af849ffb768e822f04cfc3adb79bef664b573989441414e1f2b6225273d2278784f3b11ffba827ba82a9d69fabcda1283df70043c28230496ff2b95e71bf1fbb93e77ea410ee4a9f28e473c920a51a467fd11b48995855806cf734db87814aee3dfac2f77e3cee49843edba0f34eabc45f10f6d797179ab1af54c7b6853e7ed81e4669c98ad178325fbe4d1fefc15b7bfd57a483a8092ab6f76dfd44766453d09a468a55ad025436f7fb8ca4e82633129d6e4c2b15cef1270bab5037eaee145cf64a2066ca1b26f18dfe5b579b2228b14b2be24fb77603be8e9c7a6653c10df00aba4a0a3f01057ed3fe2e92589437c74d163199b9d685eed64378ed48432fe6f74af78b4f9ef7a679ca958695172e74e2218c3202e61fcaa5a205dab14fe417aec870cfacf59250a11ad3f42e35c8049f4622799faf724dc9ec2a6781705659091eb19dc72f516c6c0728a43d10530d6bfcf2699b243c0da5a936ef7932ef5aeb586bc370db451ae8905a04f77ff68b1a00a49c1cd9f7b360e83fb7c9b0b7810e7ff6d7d93b3cde79a7e6354e7ad235381ec173bfea8fa88abf931cb25b5d7355774e510355af59e8fce0577e4987af4b090e98b332a42d8938f628d0a0abf7dc6c1378e0a118132eef456b6a01a5efb30ff0554822860b4975159beb5a1544c9b34e9b5e9ccb528035144a59a059a175016a4625e3dcfc256e62289104da7080ff6993b0926736c3be63b90008db720a575e5d61523186b22c15e2ef6f86380eb6b59fd42bc0f722712bc516f920f337c1ddf5df8bfa955f987cee43e74e88836dcfcf7335e4a592bff7fb60c3bede31ef5c9d5b5a396302afc5f0dff745f886d4122972765d1f9ea8df422e0c7a1fb5ad6c63b6330c9530a1cc585b721e70216383d9e2b7c8bce6a601dfa7ba35068f42e7554f0c9b6f04fe954854f1e17747a01ae0404c7ba8679e525e5dd0a6842bb3913a3fcd2e77a33e1f62fb85f8180bf8d9fa25f218b28fef0434be67ef1b97e4016c144db21bbfc681d79f159487477d5f250a259be1fa2dd41cbdcf85597b95c1cea1c6ca35f8bfb4b821e1b2718e91f44eccfcc7f085b67f1f8f34af942e799c2875a1723f9971e4e997f7ef3c2a318b2979c77a8f02a1ea492ad75e8b647f63dac07eae9e4e237c9db38a02de72ef8eac8c7e4b0e45e954366dd71aa9a1ce0ffe8da715a598edf0b943ce6b6ae3bd6930ebf7a52a194d750c90b80c94cbb8a63fafbef90e5118a78b24beef359d69335e1300157e93af085f44f93e3ed09de122c486138124fb77fe72ca5e09d90eff56e18326980e45b665933c2b9436ace5dcb39c08aa5c6d0272ef65744b5cd7863f257ebcc56ca5ada6dba5da776e2e1acc0bcab628239c235392f2e49e5cd31c3443169c03434410f615af838237e0a01c55a2be92604cd9235fb11a768b362a87e6c317651bb9866be5a9b0154ef00913f5f03c34cd2ad97b22ce2d262f3223c0621e8af7b3ccccf7fa46ead24b92fa827120779742015ed14709f410b363da1b59a50240e4e7779b380838369a466e6d4115021e576896d0beaa02d597cd95c87b7d1a2a98b0a44f2a3b2cdcdea2a500cad0855924a1332363250a45407385c0d0f148a26dbd16dfe3ce12ced6ce9a88651a1ec17e2949f65b8681d7dd884a298b5e004d9217e3a66753828faeade2347347f28b4e99feb93d92f1db22d88f63f04c1e464445b4e636939af8dbca42fa01100211168adbb4aa8c1c01f0906185cd5cdd48261cc0bccc8fa41c32af7bf924e0a09afedb1411fb4c76471a72c307f7b93371c567750ff9999a39cec3b05c5c4ff974a99ff3206df2df08a90ad181bcbe2e738cc33f08c0e68dca366193934f00188b2dfa7b01fb96627143f1d6195eef35ac7e5ecb8b85d0ab55b956c3344516ccb1ecfa43bdfbbdb69ff24540a52d45c3d64daf6a452f47fd0030d3a1de43a27d0e7f0c05c1abf25d5cb020792435a9105fbcbe8f0f5d00269f42b29a61508b706f54d7cf01bb3dfa018d10309698dd1a4ab15e4782811fc4756bfb2a3a37d25b6b101f0bdf99d298627fd6612f47c76381c70a0de6c7a47b4ff0f97bb720286859e12e3176c960bf3ce58b1397d6a8a4991e64b7e1a9f74c275159fbbecfff74b535da3a262f5b2fa65381c7812ad8d9a5195e7a994083cdb9e0ef269a3f7c18da42768c8d2337118a12e0ab451f3c9eb5b5fc65e947bbcdf7f6e00b070c5b6086ee7931c6d1f9aa40d546020baf026beeff80bd8a9279d3653c27aaa1c120ce999cc8871a3b431c84c86abfef29fd7f7ba885aaf7530945114f8049a06f4ef5e212aae9e9846663cc11ab2c2358ededb100b8a4f4c6f3a00ae57b344d75768a0593e14825d1a1f5a90866943cd94949e799d7874e26d000e1210bdced4f993a45ded6159ad2bde805b5d2888f9add9491d97714ea16403410dc75b75706c04235f52de5c9c7beb27162f4ddd0206f5a33e03a92369a37eab3005d5a7a6945a58026e3752dc7fc06b7fdd7d0b1eda6d656385bb889782e0564058ea2381c4569ad90a10db752f7284f466d2eba5595a673b4f8849650230d954a31d07e4ed5407f120fd54342eb126354b48ff5b83b76fb409dab5fdcc5f3cba5a2b0b4a5b53aadb951cdb271d996e5f04ae97675b960c73121a392d73e4153ac53140e4d55f4a92135fd329c07bea4f90422176f15d253a298b82427a3c81c67c32900f346e049ffbb00c084253bb57733e9799a1627770e6ffba9847d7274359ccc8a3c4731b7248dc258e629a64c2c8f4f4fb4cbdce2274934e601eb318235f2fea64c661398dcd704fe759fe172c234a8acea950d282e03e8b8533ce96bf51493e18c504138170dcc7271ebff12040a6810be8f9238c4e6122a731866f3e18e334de1089ca5522eb9f97502d1b0fd934cbb7a1f8e2104ac98007f6060cd9b54984d7953b2a39ad3a93eb952bcb59beae19e5d2cc4adb637ae7a22c44aa68ce3fac8a15fdff7c422a3c95ac15756b08359d496f806ad8f7264d16ddd067a0231b82e4055a32e9b841d08546f01ea8775c8e39d24fa5c3fa8eee4be10467f739e4ce6a83ff441dba6a581f3d92dfd833b556fe5a4a4b6d5603403cbc6a1287ff922f257c0bfba8f185d9f710b85b3dde65441736737cc8abe4714ec2d85b861e3775d7e32b3ff4bd4e0b93d2bb1c40e4b696587adb2a59b993da354febad8f0dea4da5f842902137ace8ee5c518b53e2907f8619ec0b490e250cfa2f27f43e02588200daeb47931d289fadbd9f199ffdb84d4a17f2b4c92e061b8a08a99739f2ff0cfeef12d2fedc01d993672d7e43068b311a20c5b8687d5a97fb0eddf696ad34cdfd7fa82b304af726840d325cead97bfe777ad62fc9de984aa493d549f1fbf45b71b946098ea5e0ccb5d14a8509c9039d4eb602c98a0c79904b6b2d54b639c55940e3cc5b4773ee40d699229c6e066fa5e9a2a62b4c62a8c95b499e8d8b74960d7a7dd43f5fa55f0e74180c08b6b22f99cd2f500abc41612285d9de84222fa81f0394c5aeff353feaefe99d98b0cc8ffb7284d96ea1cd6c30c983a93c465d15044b2d47a19f5d1aedd6f046a9d7154a6add04de3a94644744f892839229bd7ce75885e4a0ac37ea3aee4f91e1d85b118cb61cb101b1de0bba1f62784956233199a5e45d4087836c92f778f5211dca4f45a2a9b2c28df98d18219f20eb3bfcfe339ed058c52e064fe10249e8c7e9faf2fe27ae625116f42aa9c4d08273461e8475ee7bc42a501ee348a230205dc5cb6d2d0923e76ed270c84341ba4c3bdb5a85386a43ae7bc52ce56d79f599a8d4c1755885c2629f5f626c3a2838c2240b8f157cd2f139cba7050cc5c077daf54a5b3bd6f2bdbbae5ed52cb9e02492952f3877e4fa0076e08285e26402cb09e42a065a8657abbf6b9dd3a217fdc0c20bd553424b73e2233338068ec8e41a98a03142c5544bbc112d70584297ea9481bdc820fe6aaf52bed40328c17412b7df363ed3fdeab5906b00c814477a5d93421615688e5b888968c1c37035a67b24c8534d694796a450c3ced1348510fb18432fb82f2d53ef3dd66b6646fc7ab07deec868a21036632bc641d2b6e9957cad833cdb7a740b5dbf4235ff080973cb38c0c1eb5a09732b5d2cd1bc6ca333c07a9c7b0a7cef75161adef399a2279e48bc7daf5736db7f5145f98e86fff535fae6c29587b0067dde8949a71e9c9ea7e2ebed7fb1a8af3bff17c8319ff9f439776126339e1fe40741013ecf9b78b0ca8f873d1cf2ca9fde7dc08950a9c67e666e27c655355802cfa34d3c4fbf474923ca44869ae0ba60160d349939e0f837f2cc06e14eaffd274c2182c7c492e60d287e7de495c7eafb6e51f5abc976ec8ef1638543d9adde59f4c798ff1520c096d4768c4294f20b44e67708a36a6de5e593dbabb74961a5fe0b4b727ad0a8297c05927b39cee25996259e0250a10cdc5f41297d4ff3d821e52dd1049e91d7642cef38b2bbfcf7085bd07a0ac058236c958b835da439a29414de72d0cda1664a17d9eb0da444b086b0d74c35f8341f4b684a5e6fdee330733acd0408b436df408a3f9d142a565b20aded423095c22264eaa8f83f257889cfece55b45615e7a9164cbda9448d01248017503c6d5706786744c52fdb39b3bfa2999dc469a8dae635a414845bbc79e5dadcf5958c4bd7e676fe19714d7b50b6192e2c934533a3b93fb1e01c5d9d2372f5b569bb872dee1a72db20610f7c8f0e6f901581094f73ae82bc86bae3048c79245f42f22a9232c2ca87d4dca0c24c11b3711ea86eca4498dc2fcda44742f4a90232e8b29c7ab6a94d3d855b9a5edde1a5a683af774b0e20d7a94f8cc1abe56432f3c03c6dfdbf25edd4bd902d1ddf557c0ef09fd343fc4733ab13ec4ed75cfb281a012736d0308f5c84cd66575eeaa54e10198a6f1b234725c7755771a57c827a8acbce42762f15dbfb21d04f15d8b5ee73b2bde2db086fec7ed94506554edcf5ea223fcfe28dc932e2568cb96c0eca9be4e144a3db66c66b68700ef916e2321d525a7d1b8ed383bf8fe2fb04f11c1b1a3c6fbaea628157a62892dbe9784b1f12cbd57c21079a2ab414c2cf304925eea7421352d1b620ec9d1373c923bc1a84e1f46a8bba6abb1a4c1cc928598f94d378956175b42a2b2b3ce8eb407a1f21853d130ffb1d4d3f0163a9963e99b5dbf45cc6e9bef9499949b8e8f0c9224ac4c42bad98826bc4ccd755893da4211fd7748fd5383c512d4c80af8cceb794b50dd591e3de9b0892349a42c6a87601574c746ce86c5d9658bd79b7201348eabc6c79bfca52e8eec3b79293e207b012dd7b78f84b927738e3453e3427bd68a925897bbedf8f55537593102531058de53aa5fee687bda87f5b13f835c8fd0d75c575c0b8d0e35e7e441be247895863d6eafcd75e0043bf5451aaf9cf549ff038b061cb38cdf6b48d494040b8e9cf49623eb35d0cd2d8f4a003cbfba807d878ebf6728ef0aa019221e72bc09f79a8a1e004ff747007bb8a44bf09ba4dff31c62f0de25cf8252c1858287223485a57b21fd93a9f7b870ecdeb482aa39b5eac5ca63fd80ad61e3bffdcf7e4aa6bfccea90f00854568bf0df67341823bb4a404dd46beb0ba7bef2484996e9f6a07f84f0b0891bfb8b25ec6801f881050e56458f2b3bb16b1f343d9f8fb34030dc9cebff405d1e07328f557fef3dd32191a19585a4a5a8641d8a8679ce61e10c5d5846455e350af941dac9fbb4161e94d47796e2afd0e940698c347d8193a0cbe67303772930d659272fc898cd9b574d37bf0471bcc96a48fefe663573135f2bf9a50cba94d42809c9605622c5b45e029ef25bac538c99e50b4521a1fda504ab062f0973bd69495c6c278eeb631e35a1750944f35f9b530fad7677b9cf6ac29c5a4060a320f15449636adbc0f040859dcd188130657953420bb663af63006c51bbcf04c4f2fd7bf8315bf98364bacbd910edd3a3ab69518e18c55b8052aa94b17f1533cfeaa1b1f68db257b0f03a0129d7190ef6f246dc650ddd1c6298b1e837962dffc9c9b36e515e96f9c6d9591df8d82884d1f2fcd4bc166ca4cf0078392dcc770cd4ce1099ca34dd02dc0744c6aa8752e64d0b5af66407e01ed3d2911b93dc58449002f80afe752e3300e4210947d725d7a39092167789b21254a638b0057d04c7da7fed4120614f02fea06ca951aab4f53f1fa15cacfbaaf9389782c6233cdd8a450c720ed07308e1ce8da9d95697a80e9d63514a82e9cea0fc81426be83cc1e8685831ab428d1a8d67850ed08e2a2b61a8db778f67d42bf7b43bd3b033987e4e7c96ff2cf2dc066878ad1aaba860fc1f581275353907469912f87e7efb0b8ad7db66890336772bfa8f69ae1c7c159e865768510def0d08375be99e197e26ab5cf9248b59ed3f0dc2007cbc0863712378300d9f2ef1b45e45c4e9e6ce74756679f409604774a91fad8de2f054dd361f5098a1f9836fa31b0063ff3d7404f830ff58ffb4048205c435973de70751e710135c16f6c1e6c2c1ffaf533b84f2313f878ddd72ba17604bf335994d4d1dd6e5060aae19ec7695f9687c484b367e20b277a35259203210e2a14c44f983dcb67b030d38641bfd9b04e7a0422768f9fe8d22f91d0b5f0cb03ebe534c2dbfda17d0e9b6aea1e0b56a9f464907d58c63e3545b3e18a5bb03215efd9f9b0ebdd86c4be32f0319b4318e699f4bd07328a731e1009d24c8eb995409cb3a1a943f16e1039fbfa35261a936fc58911c5f96fa5def854f052eb85c11d726552328f9fdb3f0cc5d1be223f2260c42f5efbd7824b10e7cfeaf99868e0f0753ebfa3fa0f95ff1adb8d16f41d8e74b1d52f574d25d98ef9e3dcd2ea49aeb4e4652565e1c4750a42e81a33bddf11db22ce4cc3742549bf72df17e2f34dc31d464a3be1ed0a1eeeb7bfc92f2b58e427986779f44363ce637feb0b19be0ee48e62f783d5e62363281092c27ce070c4f5bf538415e3e8550e11baf809b5778ecd9d4e76d39405bd7734c42cba298e43456099fb1120bda22122c7c7461889fcedd3be27f1dd4931d51cf0c9681b3811f3a042613fb748016c63a10436931a830d14e269e913628074ec3b24923de90a61d4546c830fb547adc92ea12ce9e12100e149679fb6c522fab35a8fd07b23ea083775570c535ecdf8ffae2772a6ff0f8e7e183a81754438704c63745f1419a54ee7e5adf23f85d52c6032d313a88eebc89b32087c0ac917841b3bab27a160b3a3b0946f3ac765ac96880cada17f2f6f9daef8ed7844c395cbdeeb2d960f969cd2ac56aadae457bcbe2c3e335330e2856a95e0078a7149821973061dc2c1918aa4c66072946e6ec562630e45161f287fdd45e3ba543b55d2ef9399db6a0fb70b8d96ba67127184124326cd5e6ad1716e5871cc3d66b13d46a67d2f591e88d063fa990fd1169c89b3808cf8b387613b79bec4e386aebab5b94c7bac982a143fd4b6b5c13f149c98a462a8346a56b5ccd053be6f0357809b5f578819ac6fb5d95aa51246e296326c47d24a6d70c8f6eba7164d7d656de193fca5deeafd1a56a2308829153689e4f2e826e9a65874e631cb6b42b77c61ef4708011ac16445b5ea6e7b86e14d4ae22e8dd3fedc06d3a4300d55245ceaad97b6154e37bebb6983bc9d7403bc469bb69472a67707f24f174c6d24069d982e176dc38849b0e21d74be6e01786b69cca7e03c9b48f72cf682c484075c3af2c841c714ddf6a736a77764aa398338f3461d0386aefde8f9acd31740ceb73739300ed7700080741b98f2d1d0341b8dbbb7ce712fc009455717ea8dcaab14df8a3e1f5b3a976f043d56f5a23738443438f3362b58a909fe1efb3ef6b70f74576c346cfe9ae6dac5b7b8a1c50e6d0cd14e11179a79e63b33160d87af9bd59e8d9987f09c517b46eff47740dbbfd7b916ec01d5581b941d9c7b4212cc56e22d54f9e43c28aa9665dd940aa189f85dcc68afcd07625395264cf434df28b79fa0a9a8b083e140811ff538ff8e102b7ff63b9c25fd85f3efc8c2224706b58c0a97a2cef9e37549f927610f3fd4ebb5a7282cb6fe199855a871ee6e54dce2b154211ab7c6980abb050226205981754322190df166a2f137822db294674edae26e5835f37"
|
|
+ },
|
|
+ "transport" : {
|
|
+ "secp256k1Address" : "0x04211fd71c1eae94f560e7e173399c91c15fd9b3"
|
|
+ },
|
|
+ "ecdsa" : {
|
|
+ "addr" : "0x04211fd71c1eae94f560e7e173399c91c15fd9b3",
|
|
+ "claim" : "0xe689ffbbd832e3e259ff749c598a7b971551703b977a9dbe151eca33cc546a8057150d83ff6a2e1ee96e6831b0f85d478f22daf45e37a34a9a0726ada45f2f9200"
|
|
+ }
|
|
+ },
|
|
+ "4" : {
|
|
+ "id" : "0xac23c7e741af9bcc42e82729e3abaa64c809ae57",
|
|
+ "keys" : {
|
|
+ "falcon-512" : "0x09ad185ff14b2fdc6a15b035c294d3a55e2da69cc17113553c587469f88ae5e7362843608d88fe34bd99486a3c492451536f82d084d2196649b0e69a60f60e3d7bc450909f2e926d8d362a94aa778b35baf0e14b8eb960e27b10ceb0403c60aa5610d6636921a06ececfa399dd5a2fa0edb66c36f5ae61af528d8b3ad78454a20ce0920bdbe45445cc1a6646e445c092951487b4949df9b8ddd68058c0a318420cb9203e95718e2fb76e60b816bfc7066336d4073099a2251a3b72548afc4eb9e98085da7a0bd4bd01c793e7406ad1d4a7d1667e26f872e012df95220809e2a01d0c40df86a50c527bd4e4f73220c16ee822845d4ccf0866abb515e1f65006522a5ad75b1bf643db51879c86e4af5013ef8c4b440b29c4639cadd1bbfb5596660886b0e30d5684121811e08694e20e5ea253a65c44246c4cab89cb16a42456d675e3ec5f8ee86a76adaf8aa4fc745a48aa826d05b9ef4dda1b0a7113d76860468084a6adc942755e4b17531b8f7d75038b96047f0a82e1e89926384630de8a7f2fc7a4ad3794b89b1123f5b590d9095c6a08d3aba855e26a25a7303e47f87a445025278ebda0cd95d6f70efe61709a561f95817116bcab6e4af068b2dcf98f64d358f458cb6e1e453308cbfa7a4ef83e6838e921d6d64ae009c0336aa694ca882542e8e2a7cac0bb4f48f6067c4894382533bf286a1b2e4d205a5c2faacd87564678c17062105b41749bf0920f883021dbf91c8f1ca876d9f05fa3efad6d6bba2380f88d6eeb249fe5188996cccbff928230f0d0c011171c184c188a88506b16099ae8142ce82b754fe0cc08456fe4cd946fcbd1b24dc389c1c024a6d0b2cbcd12ab4146722195a9af8890f8f8ad80384ce4d409b72ec2ab2a0394194e1708143bb9e929cc65040f042866fc0f48a60038c7559a757906760d7031195920fe41888c8660215a2bedb0640042c0aa618155c79b4be15c8ac22d80b9e64b41b140c702e9e10b9064dafd81b01a0d368a9e2346954840e2700962af2419a0b8eb51651044b5c3074968523d3095505b56b0aa99d15334668ae838c1e7cd5e6e9d8b802a46bde018d1a457bd1f81fb559682ac22b20edb5251084285d3ea919091035a1ad1b80ff5a5121af743e74552b454e4fe1c0d1c8e5a6276d2e7767437ab1d835a95647bc6710e201c5e6c1ab9a8aa09941de1970c56a5557aa66b10be1f3281348943bd1a5c5385b349fe547df1d84cefb0525e040b90810cad711be71ce468",
|
|
+ "slh-dsa-sha2-128s" : "0x2abb37ac3e01bf424e6eee2948dd1479f77e0eb20523e320e8cda908025a0ee4"
|
|
+ },
|
|
+ "pop" : {
|
|
+ "falcon-512" : "0x397da68e7bd49dca187adfaf4dccd1819cfb03eb7a5503f9ab4f1153707216b7e512b08dd5321db592b353b4fbe229f0aed36218e84a87f753da68dea90f971207317055dde516394a51958bb4f11c305efcffba70936864fa6bf58d11d11e583aa16c98eb18f6514cb84ccb11f80e469b273eee4dbe1f2437168af5a34655c473957d8e93c95ee4b77a566725a8817db65d7655cbc0911243cdc4934e8edf2b8c7bfbe699f8d54d6fd3332ee71feb8475a76a734d34c22f5140da334ddf31e792f747555c9d43be90cd9b4ce25933f7ccf48a720bc410778a23f297c92ae54a4d5ab3a14648ea7b9ca82a5e2768ce5bf2d63d0cd33c46646f1f3e4fc2de4b5ca71fec9718360b7b1f68ad4fa46b3085af6a654b26843c9a760dc8d332ea251a0a60d49f0d8b846a093e53d6cf3b2c86b8e5986588a8b20e6922d68be26f88c4920bc3227c54ada2dae35112d4ce86e92da5e37db2b2e0db0203b58e25d5c66755217bd06479398fcd243a44051ab846b8da133b037eb7570924e51ce0ee283a6cd1bc860edc3ef78b63d7cb67a8492e4f9e559cec7d9af49990539316ceb83536cca20a85b26c2e0a2da3cf95565e8c7a0a9d27e2745968ae3c64ecb35efd5d8ccc4cf6eb0d95bde7e064a68dd0627a6df2fce224e4d8d277ac17a8da81dd6050150e211318c37ae1d06ab556f723b6acb665727d3fa933483c87bfd2253163024e548cbb9710cfe0a89c2ee9c0593b8902d365ca7cfd1c5ad4a6c5d3c23a6d3de7473ce15232e44f6c86584aadeb87d6ae3c2ab77a376445535aed0e95404b6a2c3b135230344414b3f795446267ebe6c012f4998a5eb4ee0c761cb27b5c58435292e5671d3e94ae4a6c1ae50b40646071b7858ef5c532784307b0f524efef19c233748a10a09eff1e12af0579b888",
|
|
+ "slh-dsa-sha2-128s" : "0x5d83ace043ddf691631e892283f919e166a78c32d4a0662aa00d9ac619b3ef5aa52bafbab299ab9b47c7446189aeb94b4ed81161023608f4551660d6b925cf32ac1f348b27d567e957dd2d22b2cdaf4800816cd55bfa66476cb38550bfbebf66400f82e0eeb1365f23f2b161dfc96258167440e0a647d02b96e00eb8eb35c35f2e3b6eab1d5400b22778fcef490b98053d903cd73ba264a0686ad9e4c155ddef23a69304e9946573ba8dff62cc04d996b372b3d07e6193ed82e503d3798daf24bc72b333c1a536bc1bdecd3c0e8c513587c4c0871d446787b3479ec06f114ec39bfd4a24734023223d462d8c3fe601ecf1223708361492c67607fd150bfc099f292b6aff1d1c7420489869007dd19c5da7bf48775bf44d9183f4abfbe05557672efdf2a8c67dc021ec676eb7bded67ef733c2680875b5a9efd53f85fe6176b09b7e862aed2651015f09ff158190625c08d40326689696dffab5be3f1b0d7f8eaf017d473ff4e61b6d858dccf097c0e7083e86385ea852a20798cd3754c0759c7cc75dddcef27822e93ca5b4590517edb5b4562be83d0325ae2f198be33ed2f9dd2d1fe9e22f81c2d738de9ec1fac4cb3913d79441e3966bc6f7977caf53482a441a337a0227f64c5dc3e3b786504def3d395d82774ca1e83685734ebfcf2d0ef4de71c87953bba2a46c5f12c3ff8e1d58b94af03210f09a998384faa71e603e392830b9c235d1387d6df8d1379b389715ff13746cf8b28146aea4aeedbb9f03ac1729facf8a907aaeef410568f5808c0db0d59a00828acbbf5f5882040de0f2de18d8bec38871d7513d62b920b1913566355e4975a818bb900da9a6f7b9d03cc486059405947f3255993136a03a4d70aeddd1e9b7921af1a2141a0655d03a90e7137797ecf82d5b771576c1e12ffa811c843c377ae792aafbb30a75e0fffe0ab0df29dd173a3c1fd642d0beeb5a38a069b24d4767b0f90b18bf97b4f9c65a3bab287cea0c551e21fb85a79e1ddc94ad6366b609c5ebd43c3751aab786308e25b5a30ce2ecf5fd76f936afd40f9eb980bc60a76cc4133c57c4e2a8a8b6d397cc6d4e72e66ba171d6cf6cfab6878249ca6008f8121282b06e72d8a2e3129a374669dd3ed301a31049f11b7e63a9ed64f533581a1cde479fb687898281e2da48e9d3aec90910b50ba20b786c184ce669f5016d72fc5d181de6e88ac51c2a46fb2db9a7fb0683a6cf52dc185a1c36f537112e3991e368f98fde18ed447e82ac5e200ccf058e904a6b2d82e94ec40ef40279f926780556134acf7dc4562a327ce6676beb95c6a0a3f3dd275579fc3f324748ffc35e83befefa4549580626f5658762da1528979fa83fb7a285a47a579355fd70e7dc4eae755e83eb73e3965b2caf8bbc668625bdc8d8d1758c99d35897b6b750f7dcec0899ba1ab607bf79df2a4ceee67fdc5ef61f3b3fb2e91a38d9009faad65c0fdf1b838f4a5d5df396d5d90d7195a394299a6f273ebd58bd4731cf1cd57f75264048e7a7ba45df5c0658f97957a4a06559a2e447c67959833f61256ed768700fa915aabd65b2586af84650b34121a45b2dc7e928fdca8d85ae81b97ce0ab7f52fc08905f8de89f03025eeb76e2894a0cc4784153f2a3e468c77908a26ce3f72d1388deae2f89b9d6765dca6b2495d1f6cc6ecfd3dad67c0c386efda652fa2f17746a1bb9efc167683dc6922637c88e81db02bd1e27bdd14cb148e56993621e77eecbe615d91d57148b457cdc04cd8c12edbc437f51bf06e1b0a7eafaa62bdc476823a14d028e4c1dcde5896786631ad1f0f828097131789028f1ab08d20a241999a4dbfdb979ffbdd433fe4ede34f5737fae114edeb95fde3dc247a9a1b43b555c9f51e677cdb37baecd59be7b1d6afd059f960f75c17af39947ad4d13a4204743191edee6974c127e653761ea51d306dc40696ed4077aefcb58830b4c93a11b6c9391de64a0601fe4667581a4d26a9e549be6cffafc09eb1c872ec90d243609ac0f27648fb05a650785b07b09067ae9367b7dfc90b40f96a43b83c4ccd6352a38f024ae06ab9ca09dfdad62f55d1ec11d9e72d6458fda7f215935c9c095d1a5ef76bb609635e14ac7c941bbbeb6e86cd59c5854c41f53cf8aecd999077855c6ce880841639af7d8fc02d3cbeeea8d0b3d31841b9506679d583cb7ce8b187d9c8381c3ea1325214e9401bbc622c6bf077596478e54b2dc4fd988585507428524de069c0ff9eae9f3229e98ee3d288b4abf8c846124e35d456535dbe11d4fa380f1bc51167dd531efe6ccfdce5eb1835bf7c7cce9989b6b0e8f956351dfc4acd330d90f1c8958ae644a5a2f275096749d6a77ec22e22532f6ff29d4de13bb2c122db654a25932666aa88657f049f5037e9f70ae6555319ccdcd68b0170ef61aef7827ee1c48b5e0d8145a5c744ad84e6637c502b05fa012195c4afa352fadfd88701faf6b6702a491c365a10546b581c1aa6d05ae7ca6d480a93a8d6dad34895e30518da89009e138b2cba57c9284b8830ab7b805dbbf102f1d5e007e1ebfafae25bbf5b6a3bf7c998fc9ebff38ecc4d882e451f521c888c0ecf7cdc1b4995ee2630d5b8495bf7b5c9cc8d537ad103c887599b4bec52781537334e86e1f28e63cbf47a8af66066331f0d57e49ea2abb19960703bc36e60f78fd44bd3ab0f37e6dd8749d45fbc871ad1bf857e7b457a88aaa40fe1c10683918261bbe5528fcec62a7b2bc5bebcc7c4131429781a1996ae29e85285d255b12848fd320728d5ed8e6c8d8da208c10fb3906434a6d49467acefaec54d485ff45052448b2295d8173241792eac09822aa19384688befa5643a0c8599eaf0553a9391453a7dc6caf1daff68a75caf8de5a677f858e946cd8e11aa56ee6dbebdea8565c7177722856380d610a5166a416da1a5eec79344fed0220f310b82290f0ccc06fb84e6bbef5465520d12144ca2fe2284a227deb32ea07d4de802b15e1c49b9ae0182bdaf6982779fa8de6b9fa5ac0c2dec5b4a85cc00c0a6f9bb66117cd35558bc2b80d36d111bad129161b944d6ef4a07d224a69b80bf1fa91c1f4644f60026b1384ca50e0dad96a8e1e887e057280828ed9bb7ca0ec9e6a92900352679584a835bdde96704d7aabad5dd1fc85dddf678d529d38cfd3c76e80820d2204df89dab5f09f60f07e3978c0efaac66217ed40f86dfd20bcd8ea02d0a9b59991ee340a2eeb19201d8b66901fb06e51e222ad92f6f8231c76506870bee2a18781f257f365454f6a9aef2d4d0018842241a7f172a096062ff7547efc6b8884fdb804c0bd851210b974628dc6d2bd2c42bd6c08c59bbb09ff778a9a2b51420fa7db69d6f4640161a3bad4bad8dfdfefa37410b813f14bcabe2bccd365d13d37dad40981ce0cc374efdde2961ca222fc5174cebcceb7828b39a02a344828b501191c7d38dabe3dedcd85d48744a8107517345133297fff5f26ae0fd037e212e05b59bb5c78bd58b23d801d3f5410607e5c255d55db38447fe0f1a8b4ccd5eeb7da87f9769473c9028b0bd159fa5d35903d88b3515103206b0e9b7ada05a5060f40334fab83101dcba1f865910631b2051bd6ce598be048cc4c6e37322cc344afc030fa7ab5c0f4b65cb883a383d486ad3fd2871e039989b12646730a69b7e1df841f35a49e36526d3798e9341ba6fce1b25d9f1c0ef11c152f2b946e2eeef19fc1429fe3cc0ac1e652f43ba40f262365a8e9a9b40121d1ea9fc91b070c2d1e25f52735726a1167bec3d2242ce2f69e6ceb2e871a77e22c8b4af1c32bce7ae670611f968841b9b34bf393785969ba311814d90f65bf263dca523d0fdbb6405a15c2b3b150613f307cdb0f169fc541593dfbf62a7a585d73d3617edbca50678a28c5a72970da60b556d57922223c4886c3c6ddd61681e6c2c0d13f0c4319e4e638ee68ce7c4aa7aa7b7ba59c8304f4a76552fdccabe006d94dc5e6faf425ef512f70d15a600335a2998881f1b53d2cd81b5e9dd1aa0f81ca5ac21db4a4a39fdd81d3a47004f4044d65e3c2bd41d9f61f67b796576c0de9149294966916365978d61f8b9a4fba20a340a9fa95172e82e48f4cbdad243c9b7bf7f94129c4ab61eed4204def9bbae2c5e23146de3466322502a257afd94ac4af43889fb3892e894f7b56deba44b8003b2e79ca63f8f3c28d3c746ef5897d91f343015602597b80e24962fc236b929708da7059662c2442ebf3be0b8cece9db0411048a90b1beb70b99016de9169085286531d51615332fde0e18934c6c6ab680f61ddd0920e300756dcc72e8d5a98123957164ceaabce02a4dca76773ffd5d6fc91be0e3f5230b2f687e41afb14ffbc8a2cab4c3e134bd1e778ceda7cef569276655de02c553cdcebebf74f9f2e098ffc5c4ebabc0daee7f58f7659040b6e6dbd7f4c18e4f102c805c7e5ad522b2f13cee6a4c8bdc2892fef6473d6a6e1148bfa430ad1c66753b79ebd514dfd4915f512406f97badec32c0549f8d830080ce764ef5ab2311b703b63c4a01041a7ff66b81f8bd7a54821b79bd0a690e21f929cd46739c18e7d97229153c75f6f455be2904d556a51bb8f04c38b2d3b4c77090817eb62fd1a6078e1597c144a3f61e0e54f6f60a77ab02d3bd3a755441659a86bdabd6214b18eb5ed37f73862ab47dbfb28a8e7f62967a35e276a9f3023c2e425ef77463cfd6d8d563902abec875fafcc23b52d50d65e4353858f57acc73371ba43bd5990f2cf23e587571d477b4a5345c02c7a8655b3c9e38c25f01d93ef3678d51d57c596da9decb0a1ee3da6bde03eab2507cd190782dd9e860d84829f8e68fe96add7301b89a6e4bad1095f6f9dff8fd362a114f2708bd36fb48c87b5721940f85a680385e066b034a03d84bc1ca90f319bb9e05c3f9bb8c3a882c53205cebd25e4c4271cb468cdd43c3e581bc30417525990c73b321555ba83d3c93105e3fc3e17a8cd211d13b248b65c093b56bd7dd082aed575463c8d98a4a932f90142e41af169dac961b47349b337afa528f8144fab6a04976c2fc28d6a36d3c696c536220ca492014eaf4b7a75921bd759de9fec38dbbb0d3db23a3145d4d33d1a252b462078d960c05a5a153e5efdc3e8ed624648a8e5b87736741d357e5bd863c694e1e0a73efdfa04773113d5f61c8e301eb94d267df0871e7a4266ede25aa2da40483b52b53d63d6856295ac46239656f04087b61c472025dfc76c7cb55b32a3776a370684558524a75dbed0a367d85c64c73497b4c3f585a133980134f3e7988802b16b87695412ec4000fceab17e2f734a605fd973f20dea319a6b2e013460acf8cd8ef0e638a74f618492058b7ee84f7789ab20e7ed631883d20b54b8658a39e2767a161947ad9c158352b2d71919d82f4e0418e96603a3a7137117b14109f6f4756db5bb2e2b2e1c7731ae44da2265aefae84594f25b0e251d6d25a798f9992c774cd0122017ef1b94d1b92f9f1da9011ffd367d9aba3eecc6561690068d9c8c576e46f6bc03f2a3c1f4c49aec965ca1a730f41b1e62452595365e991da7eb51083bac9f7dab6b2cc0d9b4b0deaf8dd6c7d1419d90a4bc32672816793fdcbb40777b918dec48c017092555cb08686122eac37975781b5e37fb00b16a202f6beab31ff9a7d56383526edfbdc48b6d6d5cc77457c0ae232c3e1454bc0ef2031c36d1844a0b85791a18c6452d1fbd044dcece65c3d2dfad05fc14ae79d0fe16f33f5c78d7f21db1f3baa50869a09e777826a3b7e08c7aae79d1b62c2406a9d5405761209e3b8dbcfe4b2c6bbb48f925e322b98182fd20d48335027f5586cccfaf686b0dd560efe462ac61d752d168e572f21ff7fbb5033fd89ebb1f99dcf476c853777bd5dbe6f9e30e049004c8c7692e97d451016b0e179ced7a84d8a9fcafb715c76321ab9839b554de68c408710dc82644a011d7e826f5ec6718f5ae1cc4e6aa37e1cd7f2406119cda3dbdb690aa33c6f764e37255f192a26c58c7dc915c56aed40fd4f9c75289c3940118169e4814e545c896edad11495a75b188d231e6cda5e1f251fb94b67c3c07b898c3cfc94a5438ff8da9704a4ef44e23759c4a8253d4949511f5cf3ed60fc1762f6d9097e477a03084fa40b70391939dfbcd3a8c63ae432af9c34c319f00dbba2902437a88d50746618db8af7ac3a74154dc4015650aab05da65a681180b5f21ac03481c3d6558bcbce81a9b766da3de95acf54c8fc446e2de190189aa5019d4ed4bee79ab36c8509d9aa82e28e565c9014c0a2cd5d2db49dad1a6d6a74236c6f10aec3b155d727077342536cad9da8bec68682334f2bbe633e9c838aeb71b31da5540a8725ccdd0bd0b3b04e0feca6667769eaeb10a1cfd4d7a8fcc8a89f8a4b792a55ee022b68b44eb0cd4a382d31326b63112d8659793b1fde8698295198fb8847f612e0136401714b81675072b9d331e117f4ece617dbea1f351914a1229a07804816c01c71142ff96f9b5972192d5c89bc11606e30f6daad1c8c7115cd38de21c9fee412d1d7e58303be61ee65f97e103957607b16d41e3aa26f74d78cff33cea3b74e4935e037eee5c11ce8e16abe91dc1973e47d1b144d8b1792eb49837d833c1fda440e0e89db54024e6ac9ecc856d21e5f57ac0755982fb7631b5ae76c0453dc744d55b391a961733729f83eae9dc2ce588b88116b161c853e06bdc9895814f5af287f2eaa7771d6678fbf1f4fe798cee07c1178b5822ada90d99d96289ede6822627b39ff42a13fda83de59acbd4a01df8c2102cf65cca9668c29b9bb03ef1270d8a7c103dba4116c40f22507ea5de60e03676685de528461dd6814ddb3eb36f035f47282f4b790e4fee21423881fd036b5b91cd2c390cf2348c48d3cdd2e8210464a6a13d3bc59f2d36c2bda89535cfc43dc9bf69288370334d137a589d1986b8fc635077fc736e227a59c210d75d6b51f68328ce0fce9a17f90fa1e1b3c4a7c85e6643144ff257bdffac5f82afc751992660c24ec88f40c6096bae6a4eb4fe43217006be99be9ccc0ab3c03d28fbf16720b87fae22fde61ff066af57715dc821a62fcdbd690c12db39e5ffbf8564ea128550c1dab3e22278fa79068119a02db4b7284cbc957a9569b9dc5516271b26bd7f7fff39bddfd1b25a0b131b75f58d783087123a181b9dc178804a10fac0c812a07a57b79cd332018a35413e0a5510ae1ac8f9500e1e2f512ff0bf8408e7a6702e9684b25fd856a3413bd2d6cbfb6410f291b0d2cc9488003e0b919bd6059bacb4690c58d3d37459733f2859f485f916911e3d23f9cd0da5aa3cdc934036a289d19c40afd7a227e6af9c1feda53b4e8a84f6143f57a8c0c024f6f0d1f9f18a44bae8f898325330eab4a66a241e7154d45a3b06aabba19f67fb30734b065594ced26e82acf460d62b4d15e49e3f4d9aff558db9ae7ed6dc88ba93550c83060fd872e424610dfceb1a79c76972884fdd0e8b056b7b982117fb46273a0b93247ac14db28e5d3cf1b0b071615198b7dece6067608299de2812ed0b00239abf949323da7949a4991146ee1eabcca09c020b73ff85fc78191c5602c9f6e5d0cb42f4c77e1ee0c372b006b74a9c4b96455b9b16eeb41a766147fcc286253c972a46b5d8d00e3f1fd770eefa11811f46e34fb7176084ad800db61ab66f3ad0c7a87f948adca1613f7ab5d4b9466e3d13ccd561c612847152b24d7478fccb03691a742ba01ad2a490eef4d91726b40a6fc6baff94147341cf71c7674a57dfd6c664b1afd3ebb2f618ce5247a757ddd86040d7784209d6603f443fdb0f915f943f40291646d5569b5f883401eeffa0183816e97e29a84d2c3657350cb3ef7abfbb588ac6cd93d1772262aee5091d77016a4fae723a74e92fe694980007b0a2e5c45e0191f4150c326ab1c29f3996a4e2fc62423ea5267d9513400f02d3f276aec67f1c81db5d4895181978e8224cb7d6c885466f41c5f0ea5a6b67f6fc88aebfcab44929dc95d9de2ba7aa7a97d03d340adb6dc2baa54563bcd838c78911eb2c9a5d5a9ac44e54f03c2cbcb0c483bf6c2e52bfb4af4e91ad00e2cd4a9a465521b3d01bd8e308ae2d332a0cfdede8de7e7490dd73d3f83b745082cf13b91fb228f3d629a0d53fc5a246277545bdbd124d9256ba8adb9e67935b63174212e783742e423590e20f538bdcba3bd7b059074ebbfaf907827499321f8f3704d08085b662b65ab298f2474df6f991c00ececa0c1bb0ee03ca20412f630eb0e228c340b4fb6f264eec3fc120073cbbfafd13474f93d3d7373be2949289c2e476705008f256fff38363ffca8859709b7e6be111f0c17639a837b76662c0b36474999bca76a41b2e08413ce89b0fdfaa1680aa5cf5698d6c29a2585892570b35cb8401517d29fd4c14f2ed139f26562480dd0b7e7234d63546feb1651fc99fb374fa2a125e1f5e6f26302f9308b01826d49651cbceecb6941f39f2bf8bcf22a9d6d7058c98f4e7ad756c17ff1a5afdcf10aba6430d312c9aeff6005604c98e9b6dea32aa322bac03197d5635814f044467fc5733305519c1b178541adeaa584c5209f4f4c449eaff167d469520b702533e864635c360507fa502f5ed404d3868830731e7d1ce1c6e06ab875281194ccd9c830bc609d98fb18c968680b7038a848cf3dd9a6077b74e215af039baabfc3e6c53d10de0ca4e335ee5b9480cf310ea427cde699509643116c8a1ce7678add8979633d011de500a27c1393ede1f1fb42ff4fb736ecb7fa9693bf89cdeffddbcdafcdf389c4d368a2416547d79ce8843b728f49f0387a56e770a21aca887b87007a6fe2df81f6d1ab4748bd943b1335b6add82018e7e9ece894e1e06ced2ee358e46c91e74a5119fef317269b785451e03dea3709a10f864da85f5c5b50c97cd90ddf47969f63f3c0991854508c5886a1b381bf507e51503b494014deae660aa705c99c6893a17ab7ff8060a6708a72552af3c9266ec6835b1a94996b0bf8c777a30dbb18a435cce8773e0663f74c2bf46ba1a163bdb63f740e89289adfbf4f7cdf2fc94988b6bd5d4a6671f2ae7b4b39f837e89ad568e3e5ff564b0f56c121911574bc578fbaf31bf7397bb36a5b36859e66f0ed4b9647eed052c44ec1794a38b7d1497f56fb37f2a18d9b964159aed46146a63125754f7fa74e8d1014585bdc8de7549402731cbad2563eb94ed0a85f03af39ba357960a470043842782324e85bd7a8efeeda99fba76696a72011f8a5b69273ecdb39081fb9d4075ff2cfa9224dbd642a1fb3ee465e20072803a260d2de4a750b7bf4f583562c7469a5c3f33ab85be9d4486449579cf6212a01ed371684b55af7e1191836308e35ae4e2b941d5669bee4fb489423248cfd1929c72f4a0e56ca437d7e033a71d69c01419b6062cca7f15d074ace345fc2daa66b523239e9fb6975182fb47d96daee16935feed985925e487262cf90da0932fd9d28beff509f82309525c2acfd9944759cb4d9ca25485296a3a1510bdfd1d0ab2103731739fd485af5fc105eba0cbc1074520cf9163afc90c6a5054795db956bcdb73c7ad8fcb8acd6f106139d05d64861ef5a57f66cfe05f075de3bb920ea6192b8d3f832891988374da0059f06b69666341414293adb07e822f83941baa430706f25b549a596d7d8121271b1c3db25787093553ee9a056112b72fdf7138c98af16d671813b39ae401c6beec139ecd8b9e5619e61c38aa54334e21be6d73737cfee967b16d0282a2a021e8d2eb88b01d92b704fa0fc090c1b2f211a533edc2579dcab9705450ba52191b56678626a2df9d29efca766f0b247fabacdf7f420269760ddd7b9b2ccc5e768491ef23b6f4337b1366755ab7d343a6d86a320a1c1451a07d3e9d26b080bf06dee88d70db985da0a7e312547e90dd8082287195327d1beec9dc13820678bc26cd5890f16324f80e1a7282408632c84691d627a7d75d6d279948cbe90c4593c6e3413d4cf5ba5f4496041794228f0701fb1d71226b4bb07885854d3d802e98beec201d4a4c684c089061a155edd4762ca2c9f6c3faff67f092c59f2e97dabf9bacfec74db3f50f64a27c17a5b292537155a087956a8d2fad87d6784168ba21c9805ef6051fcb1787f55aa40bad6c1bb23e3bcf4314fc5c3e72b81ba1b81c34099bcf4cf5ab030bd2d9f8439c9e39616d164bdbd8f1f182435b9d0116599ac5a3998eb51edcb48d10ec2ca481071e28fbd9bfdc29a8d42a1fcdcd0a1974bb5933b2db1860d8935b525ff9f1717b185d599ea3207e0ec755b13d1e264227ad1dc1a39de2295397f7eed47541c6a2820fb4f4e7afab55aa237ec94ff150289fd8ba405591d86a2a9329a8b6d933f62e53b5e0752ea1a22524d006afc29c03b5182d1ee6007e04f7f119f124c7ff7020bf8045234e947453eb867a57d8b211b654e54e29faf1e963eeba1d0ff789277297b9a8ee1593f95b1ed4c6b8abf36181bd2297ea569d03d3ea4ad22509cb39818b96a68f23edf4f4cf45fd4db97ab22265107314f9e0e5540f6fe877baa560980f8e300776a7f611a57f796544b4bd6a958901032937e345e685d3ba03b04dd32cb926af49dd6d9adab84f9281dd585e707849c188ebdf27c48f4d4b523cd16e0394511329a2fe14f97b9a7bde17ce6ff5c2ca5474f4cf5810b00f98d5de10aa592fb367a9bff8fb7cf68d2dd783fbc14c69da10e2a1bb233d897a41595da41654de75938a847be778a8d9562dd8224efd074be138c362dfa38af531d3a4783d71be96f9c262c7b2bf10b9557bc9ba5c82c562d0615168249a46bbb1a75d65d9dadb087f707844cf7201af36b880dcc39dc0f3917497febd4fbc753f8d9e98f92d27a8032b942efaf1b6507211509d4e7aa1c19563ff668bae09f3b64c514b528ff37acab71dc5c8cb7d6b1bdcec715068da0ea689355cf427e0b977bc15c1d2d1cf1307c2cac82feb5bb56b246991b5cb6f4e6c19b4706a63ea4b5376a9e5934d90ce0bf6938d949a0ee55ba089787163335217f291903afb19ffa0095daac40d8d58ef7dd207289a81e35313d8b547fa34857e997a208b498e7fab7e7930b2a87cc6fbb29cb1"
|
|
+ },
|
|
+ "transport" : {
|
|
+ "secp256k1Address" : "0x47dac6434214ec9792effdac6f52062c2171fdfc"
|
|
+ },
|
|
+ "ecdsa" : {
|
|
+ "addr" : "0x47dac6434214ec9792effdac6f52062c2171fdfc",
|
|
+ "claim" : "0x24bd1ec9e5c5e866e8fd02894e2f1bfbb36025c74d416d1da935f1292ee6200d25a08650a5a5228dd2c6a2094ac4409d385f41d3ea325dd6ceefc5f3bbbab0ae00"
|
|
+ }
|
|
+ },
|
|
+ "registryHash" : "0xd19eef4a2d0db81b71d856e7c7dfa27825711f299c4f0b692f2549e6db32635b"
|
|
+}
|
|
diff --git a/consensus/qbft/src/test/resources/aere-d412/28001-registry-v3-3097600.json b/consensus/qbft/src/test/resources/aere-d412/28001-registry-v3-3097600.json
|
|
new file mode 100644
|
|
index 0000000000..7e3c54e2a4
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/resources/aere-d412/28001-registry-v3-3097600.json
|
|
@@ -0,0 +1,101 @@
|
|
+{
|
|
+ "formatVersion" : 3,
|
|
+ "chainId" : 28001,
|
|
+ "bindHeight" : 3097600,
|
|
+ "count" : 5,
|
|
+ "0" : {
|
|
+ "id" : "0xa0a55ee6109da671e0ab8e10e4e7de58ad26bc37",
|
|
+ "keys" : {
|
|
+ "falcon-512" : "0x09ae40aeb815c52a815d8ea5ab69752bf982b434610d10b0fb48d28e1831051d900e87a90128f64a089c8e477abea339aacc3242ff74509989510e69e176131d9afe7bd7015fe651ad75d67f8cbc0b54cb1afa57e11ae4c8112bad04325d6ae3e59f304f7cdb62850af55cf6f3652b5a477f0c4e58a32d750c46187b2d92ca4932de3408ab764845355862453755f41599c3e9a019c6b730090135bdc4fd348ae4851d9cb123bc8a68604862b7a288837a38a511bc1f736daabbfbf39b6742286f2af80c5875f544c765d5fd0bd934a39aa3c23544c6e2c566c048d64bf811807523322e24495e2e86288704d6e2f2617981d863558c2fec3fc83ac37e7baed5759228d4306c0d57c1e9bc7038623b1e19d4b268b50adc51de58daae077b8468275ec54b6f84a14d09ac10bcc4c8702e28f7659468472d7cf340462b03a6e9b65446b26f10466a47537d85415f3a1f1ee878142cbb4a4fbf74e5a17727e7ecb07d287197a7ab314d37599359a37aa6915adadff87d0c9c46f011e15b3ef1828984443670614681a88a7ba6215228d1837804ce79636fa721421594fb97768b697b23d7c8a2635db03a97d94430e2aa347928aa07863cd184919f11b22119b24b90352dc2362d57da7030725ac850bab0a139c2c9af74472a3b49be8f5bb4297dc7c58fce8551f25574eedbad0256fb2516014ff4dc823d9090ac426c13f9e9205f5e023ac3c9756e2c3892b24367549185090b4ab254ca505b6a2c5aaf860afa166b3658d06e7b1ce6cb825dbcd05b0491750dc626fda7dc8b28e8433a8f9b6c1de1c9ac03ea7ab40d4ab81f6a3e91bb6607e9074d3427e1354aea46d9766316d3484bbe1c77c488afb1d643e10f40566da44b47b0eb94b15ecf00aa899a7df905599c6fb73ab88b8968dcee8aaa7b56e56f8278e448784e69b2a28289b40128410edc418b97e5047d2da2181221aa8d6899e810e87d9b210195b156f2260a4909d11bd5926aee369a10a907c1be275527c81d9c5df874460ea89830422695500aed2bf70dd895186085394487ef31c09f0bca0979259530c3a9546660e49708632dac6a6e0f4320443e1f1eb055472bd20aad65b4da621778d606daa4a8db19d818c93b1af13d087c131622d73038e46b60cf1c00c070b1abe245105c7f841fad070e9dff939b17232cd1b66382985f1cf24b0bf76a1f78096a929254371d7a0e6432d2d21360bd9233c33bbd2e45f548a09f4da1dac60b96f19591f43bc05328",
|
|
+ "slh-dsa-sha2-128s" : "0x194a33b4b82c061956d397a3d100e5031eebbc11bc1718aff682e2847c823258"
|
|
+ },
|
|
+ "pop" : {
|
|
+ "falcon-512" : "0x397073491013eb48d31332266074edc728007e7235a3f2bb5f91ed5448f95cf7c87fcea3ae971e1ec2d4ca388204d4a4b2786af2816cbe5f073d0e28112164a3766ea811994e91fccea29b9ba7c221edca66aa352538cb3279a5c123bfbaaece792be99dea2e90e8e84a86c39beb478c22595d489828339daead649c8d1a6305ab537be9ddbdc076fc1872dce74b12266ac4c80c2b9e465d06659f43660e3f35129d5025af66052d4805c64f7db6ba7bf79e6929efbceb2caadd3dccfaacb95923f4d43cfc3cdba0d852ef7a3751d054af18ff5add9d43be2feaedbd6d15b42c5d107c86f527c43ac8bba4a625eb5c89819aee6bf9f257ba42b68b435a691d384bb98c8c346705e250e9b23b57899e6669a4c70d44bfc40e9552029795f76b28b118939bd6b7429c9471d8e5635d020150ebbcd3da6e70e86ef63b7ef399b0c439292ee184aa5a9524418d5f4f9d19fd69a79ae6a1914730ff4478b1fdf9120801b676d386fb1781674bbc9af8816d19f43cd2320c8b03da2eed3a6be37d2e769b448e28caa56c5782f921bfcd1d48889ccc683ae4fd2af9ce34731191a65f2d3ccf099761dea8aafb599bb046eb088739d9ad8c1db6922bd94dc3574cce6bf292b37ed39a25fe57a3a09f0735d9c4f691363cf57e8db4d116a94a7189a62888af877a28c1b6f8521c4f76ae2d4b06195869968e4afa1d96ff5cdd77678854ffe7018373b767652b553671d5368d08e269684dcc15f08f1694df66f04c12e2a08b403729c69334c6a85b084e938f70f266a44bf6b673c4a267a7dd1d5de79e4ff1dc38c6a6307cfb9f69cd423ee5ae10663f48407ab59492f6c351910cf2ad78812751d27a8ba8516cca1763a2a3ea2237a5617b3ac461176cee8c817b56e4e41cc0353549c52b6d7c434e8612155d80",
|
|
+ "slh-dsa-sha2-128s" : "0x3985f3208126ec1690a13bdd7dd7d2489ac6cc8d5b10acc93675851ffcd2e1fee67eb81d74178ebad7d3d32defd3314e4755423a4b68322c7fa7552ff49151d5efba3b4194b17237e9a3744ae5c849f8972434f4bd87f1e4e8efdf17d0515896eb030794c7343e495f2061462503b1669a013c78cec527ea77b8ba2a202365ba80528d198f1bd9802995b01f44d23c96950d64a5807d34e2f724dd35ba1b0d3513f5fba155f81c61eb5ded41ce3833844437a0d0906dfecde7b51a6784116f9d47c7ed8139628c4f3b6ed12e0ac3f429ecfed002d50ae58af04a19a4451a07153b5e4b7069c6eea1d288cfa034e323cb59256483d53f7d90f367a2fdb93506f43088dda0aba8f625c06425a6dd89203f1919fb913a1ad27c065c8059517bc10143764af5abe4eb1ed341e9ee61d700fbb414add691915f2cfa3af511ad0d3ace7b895e2e73bf78ca2bcd09b7f0d2ba356bde63f338ab5ed40542b4f5a98c005615dd167bfc7dd83de2b7b113b2123eb0642df7af06f7ef4349c2e87a41cf1c01da97206f42b99e988ba413b65ff6cc7b0f17ff59aa171f6b1e295f5b1062786c3a5e198166f3584e496a8d2e1232e8a7e391304d30dcf241f4e7043535164556905dcb76029a2e6d931275678b449617c18dad77966aebbedbd47ada89da5715e1bdc6be4b634ae514e69650977e998eefb7966bcee8a1eb9f9e5fc24965cf507145d919ea069c02b3b5220cd0287b93d4c42d76b1616d70d78faafed232f3aff54763cb3ce57d04fc9434b4c75a519ac0ca45902f23f827bca0cf4cd7cb444afdcf42b7f8d395f7c225d196148e84df19a02fc05b7121a15fef2a3c9eb7a4e0782bcb3fcf77c6402ac2cbf2035296733c94570fd62c0aee3f0d081fc8724601445c58b53b07bfe9afe96e54d1b2dcfd1bb00b1be91af448969302eb794910517f32c5640a9f353dc40380fd12307e70d5be92f34eb8a5e70b0806a0d4f4f455536b8070861b6fbb82c85ea03ca484aa5a2bac21452adc94ba04e98fc2974d1dca3bb89e80b1a222143406444a05a0751ba98015d5ca8b865d19efed21a3251ab6407bf0c3d1ce20087e576f07c614343e5aae5de00cf08c46011681f7033699d349c04a0a70e96679d64394da031b8ef2058034f07fcc0fcb4fd6a05c04462bcfbcbf56fbb0fe17cc1384df5f4db7cb8ce1211339fd887b2e849821462d743ba9600f9e777d511b867a10aa1a97ae5bb4859a7fdf0feed041f97a80606178d1ad37893e42199297d24f872589763b93ff3a6fc9b82572dfbf77eccd7a82b8dbc38a3449bd85935e6745ce160d2bb2e555ce7b475e5801a26ad2d8daacd3dc029c989ca0b799aab4aec4608d94a04440d9b7e72dc018a4087b04fbca43211ed6be4836f94a2281c39bda2c23cfce3730997fefe2d3709f623185d209e69967b0269e8ade2e8fb40b4be2cf1c87e8359869962f0161fa60a2251129945a29dcdcddaa49f075a716d898f1f25991084534ed706efe8cf8a990f4b44bb11ce87e489257b11e206513a2f52c6ac045aeee0f5262a382c27007ff4757115f3078d7765d80b45abb7b3e8aafe71d7fd3e23a93e34091eb62389bd5ac6afb704c2968dad65a5002d6ce5e08910b0f03d16359c4f7c1ecc64eda9f6b8e56ab6298dd7ec924f5f35bfe834f895cdc8b2a5a50d1e8a344f684e8958e935293c55b0c772d3835d0749cc2d25fb0b20d9eceba53a1148b30305124ed94a7621b5d932703acd0df27a761ea315a28e5062b0369439505230de3b6f87de296f3dc2166fb85813045244b809d6a8be8da3d079b6e5eeaa5a14f196316f55082528b5109a9005d7490445202b4af509824b22de47c778816e245fcf12bad3df6f1f9a3b44aa78bd979a110b7dfde3646e73b50e277b400dbdcb12d238d4fdd8ed0d71935122bb5911a500ce27ba8ec4bcfee1d967f976f98e5d8aa890782271a52db0be1408d343852fbfa123f76953b0b67f18456a5b13dfd3fbee4edb876a9bb761ba26af7263726b76db027604c17e04428f938b849c71d746108a648c4a4081e6c49bfe7ccaab3f60769be298f7e0044b4e4e4a88e0608091d047c09d98859a1a4cf134d0a8c783757dffff8ba078a3de75af5733f2ff725890008b3ed1e2ede4d877bde7bcec6c97b03b4f96b21e82cdd03942df5002ca91e42be897c13b9084a03fd052a9ad90949b8c880d5e0e8df532e92c5a25d991b15864a93cfbe2ff8399188ef170e68c0ea23c645ad6108951657a1ad001a4a162525bde333bcf43a0c24e9d2179fde9ed4fb311f46a5c3b67fce647bf24a24bf18471d39f327910dd2a40c5e3749be735921ba72b9b48fdabaf5dc0de17fe0e1530f91a07d4d8eb733f84d74fb5262d3e3442a56c2f2515738463b43d1ffb5c43c770ca88b14e200a7adfbcd35180a5cb76c99a6e2634b31b6de522c0cfe6e44a704cff0016d7d97675d8c05b02862940468b17163cfbd839611b53072f3c956e9459bd4596f4bb99879a6911b767371ae8ff56f18cfbc22ce1c52fef6a123cf90fbf410d69b589cd782e691ca784dd43206247e101625a1e646e3d3ebfff66af27fca3c9f574b8cb055d35f3804c098298cff7adc025de4806d2fc04172b87bd7291aecf5547821aade02381abfd3755febcd508c95a01e709f105cf889e0b91989d3babe4cb0a5784df65fad75c782a07b99be7ec106cf36b40258da54e4fa97883fb4078988c3c29324286018be19b5dae60988dfa6cefa06b2bc996ec174c69c5c45078da19b2195d6a2c821f22b5f576386954821edb796ade86f1d3d298ad78fc944f0383b0f897027f608b0572e0a2b5fdfec545846fa67e422a91b7c1609da79761eb33896e4dd7319dde2a408aa1e8fe92936d527e9e09fd1601a09d8c4da9fd41514720b3f2b6172cae8fdc1f6fcfe39a5de7e58fa95d9e1a5bfcc3c342393b0db37881bb04332f5e0abfdfa9c3d80d34f7d685ed92d7a08fda7b98d00b036ad97abcd02baf4b70e6601c6582e9aed63a48a891b52e1c5d3606704820972282672a7ba2a2c00064e5492dde1e2ba1ae4029702de2005f51e5a7e2a01a2fe951448ccf3ec7aec307f68bd7450c8f82b3f7e08e6a638455940e27d332f0f8d82eebba3960b0b28cc4425f475a07a4b45250a0828539b11e6666edec4c93bd0f8b380ab4d478f9e54c583bfe6b12b75a789f9436a6e0a6723df01ef45f290b47069ea1cf1d15e95fd378ea4d6485339a46c2841f683f427dc1f1c57f30c72abcffe624782b2f8dd85e2849003ab35e7ae4d86369d30de25c270c448947b9ee8ce3129eeb20c889f757409098a4682b0fb775076b84c9cd8e3afe9e7557b67b7e97a89e3b69afed7a985452c30745a2333a3c70daea5c4be9afb269729b24429918e8c1ed14d06c164c76de5c5786c1f2994c943ab2dfe34d5e7e9cd0d422f162b948a701c59964ba7e7d829779230f7c9d48c6426cd2549c148f87c35c717eb1cb9c1804a34da9b8b63e8fd727f69b8bfd59a678ab406ea99318cbca60cc6a438d1a60fb054e79f5ebd165b13f5279e7e70f7637c4ca216e8f732f691bf199ccb7d17bf28af735c3fdffb305e7c35c9091383ed148ca1c2ec99a382537cf078968b1e4a51ef0e82e275216d00f1aeac3483ec428b26a0f8b7c72f1f25f3c5d7c05ffc1061292bef3c53384ba78f45d8926c344de580afbcb68e8fe1f70ceecc7eaa4fe39c6a002776a713e30d682f8d7a207ca7da8ca512678349de01a2812993eba9bd81e82f4b380cad041622f13baf4b5f9f612656ab8d3baaad39205ff6c54c1f87fd7dc18db1ee7acdb890c507b746aa5eebfaf0711d41d10b7c9fad2864041b5d7e36e089e7770a28a64228c7f2d2f95bbb8398113884fd417b33efd84947b21990481ce2b70179e2e41b011c853a53f1dc44bb1a16780b32bfe428aef7b23bbff932d3d704bb8a0417d35a5e8c2282ff404020caadaa648426de303e60a209a9170f3a5dc4e66239fd244bbcc4836dd4620ec9c7e9b291f2920974995e385c9a71b0974c8f355480ad594c757e4a86785d5d5a174678d2b7280c589ffe0a5075a5648e917887639be79c8bfb84bc441b6a79126942a7138d63342cb91d911a488e22577e87b74974f75b7e9a818a4ac6d91dc977c3d44bdac288da56d00de407ec5d1350d94071547ea8c7a9555bf50a2f10ffcca4132a12fc2598f36cc9eef5dab8bb966c7b0c4e8f180c80dbf89fc06a9c8ba5be4e420caf751140f3d16297149daac2015e47ad2bea11e6f29ba19f8ff014f44adce5594e035d4d3f85628153ab96a0cea2cfa453a46671554fe5b0b035974c700d27255ab0c178439061c4321099ab54597c4ca344f0aa2f8299e9707e3ab690a0a28adcab39870aec09054e7b085b7da6bf263491e0f3fbf51e915ca91a037fb208432d4729f5e5967eeb0dfe95dcdba11a2e30768b4c28923ba64c66beb0cc39fe8392aaa4e76a0e78c65c20664a74822b626d55a82b017d9694af5784767fa023c3d1aba4cec8f6cb0ea62d8cb15b9bebdc8ac794805111bdd15734b86cfbd5f5e390e03dd2f6928e219c9af79cab94e5fad8ad71f1bb604fe4ca31170ab05c81075c60ac299dd1e9966fa3f0769d3971514c0cf32626476068c7cebf36028490d258e7283ce535de57afd264fab553cd3e6ebb4890282d7271b75f410ed636988b881d49caccdba1d32f7a7c72d605c8c269d3f0b7289d28e62ed30200ba95d2438ed0ac90df381ecd906be058d59353e50e82fbfaca600560223dd861b836c2c1947297b3991adfc30e6c0ed0ae51a3d5a18bcc250a3021629bb200fe2f47d557d011836234e355c89e10f170ef5078371b3df978f8a3ba88af257e8f64e9e70a376c3016c82921652fe4294e0a0c9cb774bb13411a64b112da9ff32805b244cb081afabfc3b9a12f1f2d99f33f2ae152d4647a2b642b7b02ec3b86580c612c3686f655f840f8acb9838d1a386c3f1fd036e89db137f82e2c571cfc9f6b5acd2f215ea9b3d86c4454c09d767eca558f42113d6bf3d7fc2cd78c2e335c46cef228dd6b23ec3d5884a99d720d6027b3ff037c06c6b74830ddf5866da0aa5f9352df8192a61a91c09196686e041db482bb0a8e374d1d08fd23498f40fba86f125662b580e4223ca6975157c09d52c6aa926a4ab3f55899547b37fb1b64abc5f839694bf8b965914b9ef1abae0fe42af247e43c9685046a5bd1a8273d3f745e5059b5cf6cd4f38de42eb92ce974f15d2f7b702838003bbf246ebc235a43ebee803fa430aa371f314b71636ec6c0f2e0d454f837a4144fffc9b074a1a1bfd2caca53dc72748b37e295ac82bd0e33dcd808d7823e3019e47bb4b04a7183fa5b3bfc7522677c6a3f1f341b901b6cdf8698af351ce33ba44fe3faa749cff4c321c8cb725789a2e7cd3c595bab65ef9dda8711ec9cf8437b0ab245ac72272d14984a35b9db6dd9952656633c8a59df229e9da4775ef922c13d1ae58339b2eb73836804d898fabddfe50e5841dc977b91db098dbbe5c0911188f4c58fbc18968ffc27f5335f1c3d21f89a7c22c5635f78563067ed1739c3a939a80a7c07b366c23c0589e7ab40219657382c17d407ebc18a600616e10bc745cdd2ee0f9024dbfabcd3691f29bed441bd797ca35f7e03a3a4ae6f490be539908cdea4fb0ceac015e34759a2f47ad032e86d568e5c0c0e211dbaea339988101a880dc0ca0100b0636141426ef430d6ef3edaf1a115e23dc798eb47dd7aed6ef8d1953d5c92ad5ef51f8c6366b4b65f54a745d090038db6b1964faa8f136a2d9845e3d1b66dfca13dce4653afd228b32978a8db91a70298b20a1ddde39692d9c222c6c55566d5c2ebc64bee064e9a02a4dc91601709a9cc7928afffa24b8724fdf4777f77071f43cf76b355f1af44f44d63b8b8c92dfbcb8047b3a9f56f8c19774aaf014225ea6e961084abdebf3e007b4214780c4ba1ec58f8173f40fc846a5c2047ca3e87c9ae72819f582db0db57a3a630343dc954fd1c7872016850c2e6195b58e97e6ee5456eec886b9f137e70b558279c64d82c4b7070ae6543a271f079418b482569a9970b9df76c6426bfeb2fbfc80f14adc18010ebe26f3889414c1c983f03d65b32d445645ee56cc5c79575c2cab24aded3e2addb74180f27509f4253a504d66a7d1e1b8d5d9d5bff7126d28dd3d40720a517b2296b04d7a651a8653f57967e3fd78ed19bb82c49b2806efc2b9675141e36af4709aba14108f3da943e6ec822948dcaad93af7c46249e41685585dbdfea7b43ea5261c04e9aeea1500aa5dd9808615fd5544104ddfcd467a5dae3d3ea35d8be164047e5e682b76517262e0bcd9f4a5f471c63b89cbbb8de3d0a12fe645596cb6b760805d461c9f3527b29f83e3f4545cd3eedc18127e0b4c139e2bca078432a21b0918bc175e50b0d807eb7ec95c540907fe1f4fcf87a00ec2904babbc5a1d06245d67f5282fbcdaa134034ef02200cc060076bce89e1f1f88101873632fca2b7d1c447f70c5435551a307620b87f3411fddb1138781e5c01967c5452b15439ddceeeaf738f33bc4b67e3921ac393ed4a2065e30d6fb1321fc0126b79efa80169cc9ec29e6245dff418e0d488a20d7b51676cc49bfb1348b283770a67537a55ebecbacdcd192f63818ffcea272ef04cc5957c987c9fab25ea3759fed6e9ab73b9a4685306d2126bd7a848c8b02981e47b783e0c449529e2505dc736bf59d9ad684610b8ac86ca2f7ebe8ba121ed7adf38ecb4ef983457241f3095eb2cdc5fd87c13447ddcffce41ca1dfe25aaae39181dd8a2a17093c8223332211c51cb969449fa83aaba8953e12030deffe9ef81d09631b28875f494644db6e899fa471b018b5e582f02a6685ec87445c52d00f005a6c9a41e1389347930c9f32d2db737fff4802e6c95f1781104311076bcb3066a963d61f8b33944ea4be7f06068f18c50c80e9d938c06683d763eb3b39ff410a6aadb61365fde77409e6a164e53fab83712e6adde6aa445b61043d7b87aa994dd9d640361f44372c037a7d8e640dadef2478f783e0b319b340cd1bba8402781854906986e2481630f8ef5d66d4fa9a64c857ebe0c97cda49bdc6bbd069db7622a1b2c51e6b444648d1e4a8f8676da99716d0ab81ae7cb4daf950b5525836b31d486fb3b753a2286e00816bc29022036d1b2aec208267b2a0b0f2db92f8948f22751c3c53e8afac03b5ea4da1d329d44880cad9684e2461a487b6e323a41cd94e5e14baaa324c09804aa53725d441a83c29703a276df1b82d27926074922a4588eb67ddf984430f8536bb1b1ef4a81c452b892e5961b781f1c937be83ecf209fe5c95bc7f28fb88a6e18a778baaba57d35364f0efc56191b23d15d027d81fa5547e0a921ade0846621590205917566cd2197b571ea94a2edc5e76ce766c47ab54ee56cfc20bf63342197ef21130207ddf62bc0846b0cb372aec9b8a671da3bdc2beb8482067e9c82fef9047fcff45e9edf436c1f968b998531038590839b1cf6b78da0993b80c4067777f72f913c13866351ea7a719969bfb0104cd92d9d8b2ee23651458047692c491814ebd05dbd0a8687d5f3b6302acceb85d6a99018bab4a96c9a4ca47da53e4395251aa210876fd1b560b47c3ffd520a3364c696d2b6730319cf2cf0ff2025e63555ec93fe77cd6c9453b5f50d8e5c8a181f3df756632765e8d33166dfa9bb653e19b31fb7ca74a58967b4590f8b69edec2ba36f89c550b8e1d0af17b77a0e16357d29983bff23da7c4b3fd0d75960bcc2708fcc5d9fd42b2cea8ed50a8d77e09e972f1adf01cf43ff2e4f119dc9606986c6ab9f2cf860a7826a6cee710740b262c3427f0f27940142ec3ab2e157a247ab2441aa1200e63a4584ef751311f2cd152ccd5d1b4095f52478d5c25717c306e6829e5b94c054f78981cb1c37192a4e6bfb13e60f471e4014f9b9752757a02aa0830e093809bd2c49fed718a0574c40f0bed0dfe345545fd6759d338fcf370448268a162482ba336ad48a05a3f4eff6eb38a3b88a573a6113e145c06e68f65a75371d1f3a2c3e0c23e50b55bebda2edad2a14b07eef02f169a6e9bf5f6ded721c8844ecdf18b72a6825c71be518948ee32f21c99ff8166e718f7d8eb14206d91f1e0343ede633003ca90df79bea7e045357bb87ca608e01c65abd9173c2a97556de9b993df0344a2eaae050f4b32917ddc67a0b01973a318d05d50247f53d94ee36a9c702f8ecdb317e062955ed8232d5c7e5d50c3e1644c23f455867d8467c21c2c513aef34e707a6b2f8696fd077beaa42737981f10053780786e8f7156689743a2e5c863fc5d1477eccedf30e9c19022e996988370b6f97c3b25c675be0d115d08d263cd2f4c34536799ce1c49674fdd1c8c0c219b752ba064b148010214fefa8fb275fd2ce6066bb3d0086544f004d181ca934e2f4e94ce58e68549036af51da1c58d253903d1070db81d6dcaba47cc29ad489f42ca3d737431f16e056189883702289d603711aaaf03cb05429e92325f7ce56bea389a05562bdb61d664f1b8d4566c9dedce5f502fc17bd4be231e8b4d4aacb91baecd0ff0d531cc0ab9fa50762058ba99c17e3d06e371c2a02a5dd324046a5d64c6c02d244171eca8738f642f6d68ce8f214395dcca9cf31774d7c0679f807acb01bebc9639ef12a5e56001dd978c98865622119439c0abc068f31a8be949f1b147839ee3407108211ddff60a0a0e7264719e114fce9084eefeb5e7a3ecb5136d1f5b1e1be119b25d184217e19e2f3e8cbce3f248de3f3024423a0b8cbf13225b09f4504cc85cde885c19778b812e45c58c25a5904f3f18d126fafa3b627266957095cfe099d813955d9d03f9718abf93af77111f98ea667c7457c48fb3b58b108ad96f37b36a725245b6a1fe4e8179f9a1c9697fa87c9667ef3eb5b0bedec5a67f5f06a11825e5186fee946fb9661cf0fe32dd1770a6b3b7af5d56abfc457fb642126d72f9b11f93db6b354ab22c407256e0eef19e6f73773a636da5e3f76e5d8285ade79b8d2c6976be8375ad074bf5e8b76f4e88717876be76dae804381e719defac11c644ba78d9ea0e632749201422cb5a6b81057fb9fe351e79f7bd16e26e812aaca89f160d20689a1728576545a343afb4551d0a1192c0e77aa2e043968a56bf720afd449e38cf2c589e3da38354446c0206dea4b34bf7bed711a3c0de5a5d461985427d19755d455b564fc186657723f02e2b6bc3a706cb0e10a73190f1eb3afadc31e47a62596ae0d0ff36de172479e7c071dafc0631a17a95db13252ed66dbd9fa6a1bdd39667a802b5c3c240843060b0ad030b583dc6f0ed75139a0c5f1d1f2554c3679824f071e61a61203129380f87fcd76c909fa3beb5180a570e6650ad1861296b00c447a752d660520d6f906238ea2e22ad59961f5fc9f8ee4d60f6622ce165a79d9be84929c5f935f9dd4261141bb0a842f0bb6b22903c8551d6b41615ef2df2c1a78f600b78c2febf09f8722a1411d3ccb73b8a871a8b14e8e16dea8af13d0d206a4e622dc95544d0fb85ebc71e3f9a67060bfb82423cf3622632f2a4fab184f71032e0e41bb44d38fe848523f7bb1450dafe986df33510ea3b9ffd4e28be0990436d7f9bcd0bcaeceaf7666069dd96eeca54bc8a7bc8628cd0f75d2ac8d684ef67692c92d61cf6718c9b233523630817260082832c42adc4f404d691908b76c3a21baa876a99619a3e78038a44d507ae2b59bb6af0ba43e7d6c453e8e5736efac9ec1113a357d46e0a4ef00a8df6b1738a4b98545ccb40c24953e44a1115e1b25f66b6b9a4db7ff14fe981266f7fd0a197498af37642a61050e234fd20b18be435cec9804520cad9ab93738f0ab4becb62a23f16fe618986516ae078a4ffb2efd0ce643ca5d06f0c9f9b275c673013461c34e83cfa5b19e601256b73b575f841800011499005ce3363594f24c035dc07d268f6ababaca8621b189652a8d3f54be44cd7291da4d23367c5b994203ae6582525a3393a35201eb4e2d8b860b214220a713d4d9cb24b0ab36d4a2a0cc086085f7115ac748b2e0c1d9e18b76acd0af1cc35f282ce3945e51cb26c6ce1a8d960ffa5d6111e724b5178670a10112dc7cd4e522cc4d8d7bfc03ae8db6594d4167fb7af8d033bbfebe61dc567abf7d9bc864e118ce9688757c0b11b08f6aff177d40ad7c6dfcc91d1ef435c174d976b88de692fb4b6b36ab644b1223c08256e0cc0cb89e697d17f676d982aafa9e992d07dd1e38b465b11b1a86892837aa0599255d914a4ab204361c82338cb8820e3d364d3d45f8a312f9515773cf0b18197ca5c7b8e21fb7fa9a795ac6aaf564f1ad06cdfd6040f24decd28cc74dd58e7ca390e66ea7d66c589447ac77ace3bddb312c2aac4726d3599ff1016e4cc74d1a02b1b2fb627b5f5102dd44ac6f43f5ac82b25c54f5fb211eeaa6881634e28a81a5837ee683bc4dc8466af2f98ed0bf08d07add6ce746057ce9216a27f163f90ba5e294582360452cf46b6defc62cc031c5b55be10b4d93d601497e6d408256fa62e53da0674d32fc4836029b23928d21962d03b832cd393c462d1f0d02208658e9c16e26609d5f62d5e937f3dda5be059f679a2efaba4a9dcb169e8064fec898b4c8085680857060aaacd7c5ade2c784c0fd8c33f215ee44fe95155a64f9b5fd4c3de60922436b1a8b6c96299235049ccc34508d4ff13819fd3b0bd981e6cd96aed4ea0ff932d360c545169520d33a10c58d6e6ab2688893718bf73cc55ea5691c64f7c39e876633db06c4014d42831274f21954d2df671175ba98b6f756dcdcee15c2b9a0468eb901cce55e50c5d5b112ef10efad6295e7dab7fc10e0aca81f61f325cc3ac332a79dde22683557bfa7ccdd0c70eb330f58a46da8fe0fc70396fd94b83837874f7592d17aa8e269093683c5bd4e45fce87437ad5d00a26e1d5227af75ee0a893582e478a4cc8a1684a277071b6ff5cd0e7e0816079c8c95dea03c9a56fc8c5b2a9bb6d81f186d9cb6f0ef24b34f209c91d97299a4815d5fe8e"
|
|
+ },
|
|
+ "transport" : {
|
|
+ "secp256k1Address" : "0x070d5e1534a367430307a6e56bef29ddff79c0e3"
|
|
+ },
|
|
+ "ecdsa" : {
|
|
+ "addr" : "0x070d5e1534a367430307a6e56bef29ddff79c0e3",
|
|
+ "claim" : "0x5a024cad5022d9f91eb45399f817eb26901a68833814497e993fff6e022d063e43c63e6efc438897b6cc4248f21bce31b3817b820b93ce5f1d6df8eb4b28f27400"
|
|
+ }
|
|
+ },
|
|
+ "1" : {
|
|
+ "id" : "0xd15fe33d96494a36ff79aa4817f9618c14b67b8b",
|
|
+ "keys" : {
|
|
+ "falcon-512" : "0x098cc6958451c05c23b92e012c1fc0865a5653ed89b391feefc3b8d79b34be0f035fa6d192ce7ecba92415bd86a7d8586fef7810f8a71a803e8d086382fc0a407e4c02285400d1938de51657d03f95c63bb1e726b92064bb213c4ce201be8b809c44b32ae03278dc11bf8978ac208daa0fa4ca7972558be022b4cb453e6be94bf624207d09e418d8985a8edc2347aac04b6a04a0547ee2e27ce5cf59fa6e307fc59f2ebdcb68dd5586b5f830b41d5e973426f92b44c8559a6af242839cfe72022d3321cb5b3d6d03e7d391c206124d11d4dea003e22509726cde6ec90b8389508d1bf64d01d25fdd999ad1911da4c30eb5271648a75202f8592af522ce4e5043652ed6476ea6c2c2936aa516a9f776e2d9beaecabee6a9cf5b5d108640aa6c0104e2d1b2a12213776937925a5c984891ea668462021b101e373f90342d95cec9085e43a41a91e83bda6e19f62e86a268b23534b37285289091fd118a084e787e387391a718999dd854c93d04dd97fde27700cc2e4bfcd59565934a814636cbd3479da3d4ab30bf065876d65766f7d9afbe91777ab2067f3110a925dda843244e809a0a96f12e5a5f3520dcf08dfaf62427a21011dede06ef5eaa4b814e591f60b0b05e3325b6296c8845b7fab34e62352e156030d66b5cb1fa60f0987e413dc3cbe380c217b6169680a2768b38f6a181ca93acdc82dad1ee31ad8cabeaf558234df2b806af8ad18ee66893f5113b823a85806f09f55db4aa9570dcc991aca67be0ce7557a26d1a6395c47b654533c50e358fcadc7257c2d18dea8f6487e156987001c587ce996c10afc99a4ea0bb9ad2cb4a63f2a4308dd27c8ea8048a8d1111d05575989aa3e4e49425316ee90027d7859d6d047f5bca5d02c1d65552f8accd06706554e76665de01714e2940181a77d7daa29816f8b3fe92a6045077420e8a17099c8eb621107f14e88567d4a72478d90b732047169a9489724214ddab4a9c12ffa8bb03513fb516d692262d2bf9209240a8f0545a8f2c3f7d8ccbc93861df01667d31eacef011711d79ea5ee0575117c190c9a20844dcc292e2526c51b018a368ed3274015050814a55f8e5f15c970b698889846307f49f70d219d328665f4033e6fb888d7d88bb7b1381178ccaf77b90e3360240c8e73645f2682a7ac37790ac4b10ab559bce0314783d6101152a9348f6b8df16af973449023002023f258fa6ba81c50314b72807284b567200766c49d1827912623614b1752076d9dc87cd",
|
|
+ "slh-dsa-sha2-128s" : "0x60d27185321422cf2886c8beb14eccb7b5179f406055751eb2dea19888441086"
|
|
+ },
|
|
+ "pop" : {
|
|
+ "falcon-512" : "0x39c7cac306076eed1524f56c06af507e125862136f343134a7a856811895ac1650f1c2be28d349741d1c859a575f8b00626213691b7d96b21d4b9441b58db836a3c1af9839f23f3732cd96c0adfe1d3bd165c6ee2537d3455b61a11ede9595d8809a8e942642ca8425abaed92252e3fd896e5606f6a70a6f5356c6337eff4e31ede58520f3404d43cda97337397a32f9a986f8321309a235d0dff967456905c394c446e708464d0726a9d933fc7f7ffff7524198ea1c154f9b2a1fdf254fd94bca0cc4b220a0d16e4d0355d49fa1a70ab6cde0f055265c9620f713b966e1cad908eb0fd4729288b129e3e33e6fbc40ceb88ac5169c961dda215967137939ae80d14c9385162284f306d7157a9d798e9e68bc1b3bec2882c4d3056b06b7d2328b4e3b6bc395692d5cc85901c8a6ddffa26b7b87c85ff7ddfb38731e712927d8612bf2e699074125c825262094695bec1666d1df53907492c8fc3c0ecec8a1f88cda65b18b6a10b397f6d74692dc3bdc9f5af84eb7ad961b14d7864913f99bcd00ed4ccf06d9ded61a954911e6677a97267b8dba75541f23c7a1fb4e2a7f84f0cfa9db581a885b6d3ce8363f8515761174ef20abb36d1bb386321f9e8e515f8d7c71b487218f2cda39db9ce74292abd5a0d61a4728e0715b8f6e6953ea290630dfe93c9c8e79ca70cca40a375c56ea4b251cc71c2c539067504668ac4b8b0eda172b8635849add83542a869a6532c131c5be7b14e352d4768c847caf7ca8b3bd196d913dd91891249d48fbc25e539acb5199f198d23c6f55ec28f067952a867f6cc293fb2a858b10e9a5423d6084a69588fa0ad1d1e98e1e908043ae10d31ae2e412ad0c090541f5ac3f4367ba7e248f4a3620ba8615d5ca393db846a540c0e657b4b75d4b56a1c8437309ca59291178",
|
|
+ "slh-dsa-sha2-128s" : "0xcc9289454f22d36abd835ad05f7b8586aaab1bbca32d14a15a48d934a383db36601dc96de9d3efb0c134c01381adeebb23281a3b36a06f22a51eca0efda0b354fa48a8c64463bc7b55ef52f6130e988be2778cdeeecc859426bc7e68dda1f27edf0d28a9f4e73023fe8f8cd644a95224dba5b55154b722369c1e4720ef501c896b0ed1d955a437bfd2bb69a164f0405bdc293dbe4b8782876a15a976a468aaacaf590f9bacbf4f57367af82a50d001ab6f3817f42de24b16a66ad3d6f22898275886115d84719671871424565ff4e3db3385157b8bee09dea4b9f8f630ba5aa5218667178073def9af988514f4bee8b87c8a4f9e9d00bda471ce92f95c57dd136e2d4b6e87e4086276b8096dc6b29d9dfaff5373665fca74d8e05a2d84e0743bfc612676f74c7d123c1307f5902a1e4b304958c7db2a87311dfcd3e2636b91a81782c132397df72902a2b4e73c8d28c58dcf5cf52b65e9644108062295358a6d4b5a7c6e38fd03ff13641197d5d24b3f93bc22771017ac2060c5ba0e384d7c3df20c20b48e16b77af7494ed3d16e344a51c7af53df65ca133d40acd708f0dd5666e4ecd0027c8c0bc81fe90eb79f9fdd56d5b22bbb4667a52e9f73afaf974a8fdb4477b47138f32e13350c5f75b688f20f81c4a6333044682e912fb08ce4a932decdd8cc78640d36fc1c1f2994af55082297678b7c694ec34b22080b86ea9c2bbf4e7affa769f05f45a3f50429932a09fae77ab55124842e102aa2806f8313cc2eb684209c549632b1e04798dccbcc243052227550087d5431f2d78deee041b4f6943ddddd0c30482e5bca91e1f23606ea1fed8bf4910ae991dc39f7ba35a3dbfd7ee75c5471e38f80639896a6f324ae689bcd0be5bc882961a2f88716b41c2d788e1220dcaf8dc32be6422ca38756288ed75a5a2e767ad48fc825394889903892805aec7732876d24215f211ef406f69fd14c735e41935495f3054394624af51b17906419ea9722983f6540cb7e584557d07bae3658295b29089deb30076818dee835d7651b0a1e30be32fae058b65b8a880e3a45593f0690527b89361253c77404493adf00816e8808fd050e45c5271ce6f4b6b559f4485d5420fd874be6326411960ae57c73b616dee713d46034083776150e311cb016bd6862c5b2427270e13af8de79a675cdebd95a7d75412e57a37a69f49fa69ea4f3c96de99218d700eba65c6c6294fe421b9f378bc837000b1875957236b60868501ce030c9bd128401af874d9dc528ed6c9df3695dc350204f1c33e6f75658f905e91a050013d0a7f7460f4b491486b3e7b25149408f744e5c9d2b9e17948bf3b1547f4f2c3d0afe6459b0f11bac4c9b63cca05ec856d0463ce46d4209a827d550bae38dbd633d7040531a2fdc7d1eb9043ab58d983b1784bad8d582cf4bc18ca25ea7f739bd027407a03144f03eed342bbba3f2a206863244cae89e0ab180f94589494cb10274d729947e37cbd67e15fd681c0b96c62b63de20133abb151e1b578dc7b7d81c6be87f2bcaa07b87794de4b92d38ad9842f703b428ee7babb1cc07610f330d361ba7f9ceb000b08a3f8a0654c45c5090222dcbcf985e34c363b9ed048da3c49ab1b1d2f0995f650ed31514bd35bc4034075c77b63494be354b5ea229fb355db517a780fb26f673e92f2387c03894ade60156bb8957e147f1e17bfacff1205748ae04f6c72037652db57e4829d743d5ed1a07fb955bdba7e863fbd346a0894c58224d2247af2f7e26ae38d3bf3072f2df0f6896acc884ad54c37a341bb9439c998d704b6aad0c5f0f7464ba85c890354aa91688dc168a5dd5524336b7539db6174f2f5097f134f3c4354b427d6c6b661fd1b1c1a969317c3fd7e564f4cbf789ba3eb15c5fac346287c1d7733deae73243836c33f717cb36eb62ba29ed3e2e306e5a2a78c0d2ad0b4ae3752372a5ae7bbd029fbbb208beb2e473c86cc56bde66ed67048ab60ee2e7288e4a1f04f9cbea78f1c127d09a5f465dabd41b4f79ca469743972df8c88f8309f55ddf7045598ec3a739b8dbe674df24c0c47c6fcb8765275f4700f286207ae2ae525b67e074c916bc4e7a27942346b2427e43f8c07b4177e88219d2aa655a0eb4e13f5d0e3cdedd053f5d515e6d59f12924e3a7a4016e0723a0d2a7d269967213fc32eaaddcfa26628d66c68a91561ee05a54a4a2b7e1cb53bb41de65efcb9ce890f28936cc67bb62facad4f6c3390c054b49e0c52126f14318b8994979585217000d6243d90c27ad4cf9d45c9f911e93b91324bb8e4e6f174a2bf4da6b00f065633c35f06f4c9f59c4214c2906cb12e79b60d2583748a305f387d6890f1c664bb727e4359ebf7b8d0f1ecd075674b02415d82d63ba163ca563fddc159f6a2a3bb6bd198fa1c0accd1007969c0394351cf5cf72a79ada97237975a666131c8b4927735c60eab8b2795287b026b422c1b469f2a1340fc8173ca9a88f393857588e2cbd950bddcead86ea2e3f65cdf9cb250de66cdead9c646fcecb24dc10ad54a7b37a7ed0e63266dd5f0c031d38338eda2a536fd1cff76bcb5e9a257c74c133352bb1f7ee48e7afeebeb0661a4d647ebc1188c111eaa7b627736dbdc880252dcadbe9cbef28fcef3aa4484fafdca6597ee6dccede8f0a1fe87110c337631475d157a44fc2a25143a7507d9dea00856f564c12ae529f4985c73c49113c241404ced01ac572bb3530fd177859c9ce9da2e2e33f5e8116499f279cbd00524bd63871e8e8ac21a434746ca99679dd27c298b58815992326333b36f007885e2aea73a22e992705c1ab38820c2ff918ad38a97bf229f748900310cbc22aa359aca2135b3df4aabc301d559bbb0442cd266620eb86569790d52d59dd302ce2cb6e93e7a20e9b559210bbd9659b1a4357a62393299f3b920c15ad83fd2927a5f3e9238d2a0b25e4c1fd37fc00b6cdc0ff2a0e49dee6265af158b08e27d68f8c5f7bd5b053e08e86f911795b3a949f090a29fe21e61acf2f4bdcd69a050b8037c80d4b52f2606d282b5bcafc515afa352157c4487abc289bab36b534d9aef418fec0e2e32331832adb43ac3138310c42bfe3143311f6319e2bf89adf9e810540aedeff845d9b552ce24a44b946aeac3c03ad5dbae04bbe8e95be4ca28f9c42a2062d721477f613c83bbfaf5b8aeea83540fd8a2321f1dc8ac71cb73ca52a38afce246ea8d2c60465c8ca9b2fe122b61b7941fb2d35748912ba128d8d18103845fd1352ab7bbd8faf621c26237797051a9ead8a15c26381a21cb82211a1833c0222cb8fd9aad2430217df152baa9b46756f6091f3f74dbdbb40e40cd1e7c9acdefac5461257ebdc5a3f92b31d13bbf97e3b33031906d50f1084247147663e9c57114208a3fd76cd973d6e07cad59d86744e87279d5da1737e3399fd2c33e652a842bbe331914ac04bc2e9d1083483dadae91397e2bae2febe880580868717d9c0f8a31ad9dcc2022b496d7e7327b09cddaaffc039e17c67dffb5adb4b7084892390398fb19d340283e910d5913c22e2c2693504be3cfca5070207cab6ceb73325cee4ae49329bd682ad2265263d9242522ccf9b716f7a639cca274d1f67c357fe011582a5f1dbc7254e687dd96b1bd83ff1cab635a5543364357a4bd8af5bb07de97f9f2e6b10cd5eef149e01220d6837c1d4ec45a98dbe472fca137f07588f12ebb8b7b35beace32693f06168e471896a092ac2cf0c24e4376058684cd1540dce708832c473ee25769e97e17f4fae4f8afce97b50740961c458452c5806d448a7503e0919a9ff3f85018b372326f555cf32a898686d978c4e12e16c042303e91ca05f8132573b531644d401cb34e54b41bc079142e8efe1c21831459f653c9202a3523fe1caf667445767416e4feced49189508ce594968bcc307c0bce81c86aa17165dba07a499f7b17414a461d6f949b413a114f37577340c7236512c41c6d6eb7dea3fbd031729fa64dc8d4b5b5563c0ddabe2936e439b1ff28d5ff62786af0ef84ffe08ba0771af7bb5bc49d75e75955fdd2c1daa1dabcb67236de7006743a121f1fde3cf04718360bc51095690e28b598021043b4449773b767ca596e333a8f4896af4f5b2bb67c8102443dfb74cc2925606b8c569111ef6af07c452faea242e0d95031e02e58f5ac45154d4904ea00a91337a6792fae27e34b7633537974781c7ecea808e82cffc33fe48d4c20e255e5a0e50af4e8251dd00887c4551922eece916f435d449bde1243a36d72ce5d40d1005eb88368854d008c5406b0e2c6eeae75060fc3e337b341541b8f6cb5167c3a5312523651cf6ae277b9b19c84e61fe059766e23741564154f0aaf6b701a893f05ba10777a98191644d5c9912c72c5e6990f9f2aa249a8b89c2e7de3050c062c2d74fbc9e81dda206238f3386dd7f361753bffc66f100cc61fcbf863c5c915397f67ac217904ee637fe9d9adba7be07fdb67b38fbc277de20b8a6f9babe1d0e475daab64e7b6911b5d12536390e7ef7716711b969c4660a9a8460e1b3507f487d9c443d55ea8ea60f8bcd75dbefa8b1503f9c7778bad1ea41540316d544ce9c0e803f77e88b30054064231fa91f4bd91a1f31e005b8c73eaf630e6f2b8f95c3db350d24bac4498cf9418f81309c32b852a017bfeb140d4db579d9c9031ece38314d12fd6103bb2a1c78f6f5f0d79e20093c5da97a19fd852a800595997f63e21c70f54a642d15f9f854d7a540dfc569a08bdf5bb370083966f10cb08fca16b17aa0892aad88a810c8ed719f166a03568fa53bd3d30d447f2e233b67806094938743a5c8f28df717d6fc819186ee2c0be46ec42b98d98df6fafd6e71cb77d87e1ad7d60d114063f28d0e6d599e52208c4778a7d9f96f371b48cf566035a572d56be72cc35359311d3682b23a04864c3d67fecbbdd7a658184acd8fb1a1b0f2ff2012406b313c83000764d75ba79e7edab6966a74adf28214ae4f7480e7c6a954a51a3400bde3fa31816a670a463eaedb6739df9ed31a72a4e39590f2b73b3fa4fe2a8ff8dcc57a2301ef215d33bb1366ca73c036d54857b6e2a7dc5c9e79da211a031893ecf7e6aa9b18b6a135ded921b214936972c5e943b2696d3f2851c7a494ad22721592eb91785a9d41ca8b98ba8c055aa2c4cb1e562746bf422b1b2aa74df0a69bb05228e5121058d562572fee086d129228673ad3675576455286db0501465386c6bb8c5195f89d098382b41f7d53d3617162dcf76f873373f626b15b050e3f70aa39160f25514c760dc7ea6d7fec0f6d14e978f35fad3dca7b70d91b3387684109395e91b79e68e27dcf04c7e227d199d57bb10540f75cbb994feab5d01b58f4a7fc4416e561590d3119b87791fc0f743e606da3712105d8f078b6eb7683362d939626553d266486e167070128a9385e78f580e1a8727a24075df2aba70e199a67d45e8712c43f279f847a4c963dc6491c42369c16d4bcc3a1161d92ee6deb5134a1cca98d7a596b29005fc0470db7b8be838ed18144a36c9fd401d077559b8c543c7fea76206c2a579949f2de6bc490a3cf4725239259e542279d67162a69ba6f0eac3d36a436a9a03d2fd8cbd1cfeb82d7a0ab9892feb62d58eebc32d881028c2b828d0986acab6c7631ec98d372f97b238a6a9c0d66ed1ffac33e83489a1df7324875bbcece33f17d7bbe52739d98d4b0e7f5ba9e462b9d005eb3e9ecb59e146cfeec8b5b78020d94e23c7a7ee16d427e87abe5d6f01b116f59ab876497af4d0d890c3af0eca01e31fe2e0fcbb30f1aa63d2ad8c5c880a8f3315b70ea56296cb2dba4b0209a68c19b7195854238a71a93df04e531eb72fd289ab30c4de04aef1e35b2dd03e21a7fae4d2d1a9e2a3ead60e304a5bb64a7441a5b6217c59e6d318fa16a339f7895548b9223157e52741f506996442d0abd8e07e273b6380ab0e0d318f4ee17ecc56ffab28a9fe93473d8c02d52be61eb7bd33c3881ee8c1b739d4b10674440654c743a0ee4c9cd7798520939e882cbb4e05cf65b4a0b13ef2274720617dc4950b58d3557fa822a3b5738144c0778de451aa083367863de69ea51037b217d5420921fe3c66718bca96b40453421827991659a7a3139b7053ed204ef415074d4b0fcb480705e3cd132bcc7e676947aab38b328867cdac132100ff7ce2944d5ced5a699a5f34ad7ef3307835c1ed787c5b4c502cc3e976ec661a4c5c0f4638dd855769726a625b58ed0fdaa21228dc4702033d2de3ab4789c9e1129511a3191f7b6b6c332d452e2a38f26e237df1f737259d60d16569dd189bb0aac06a0dc03f27aacf166511e65f1d2f1ba4d5ea5635d2c1b09d524cd527c298590c156d8701070d43198e2fab2318c147442ef1b78c9a3ca73131d8ab237075bee1972798486698db87b9e4dbb7266a9b85ec94cf51cf5e598e1f0bd139c12518253663f9bc5ce928cbd5daba71099fb2b928b51f198817cf6dff917886bcb9654f32e782d3b4cc078f83686f2f4b856c3530ff3982824a7650fc6fef8fc884c22fc7d84de615bb9f2a026d78d5aafe5d7ae89e152dc1d6babc05f6a254d37a14c568610d192f4ac5a7fb40556caeef2f329aa0cd9d019b0a4db5c5499586687df3a4b3957e4299c6160fbabb86b0f9b0faf2a5436dd7a71430d69cbbd4307418aa12db8d173e75275fab11b2d0dacf82e7f9068faab37654336a0d9ea491c66bb04fc68efa2f71413d1f304965e307a4d461a42c32addc717d32321da3b6a6ff2c5341e829d9f9c7113c2a6ea8a7860a4595346171528e8ec5064c82ca8e3d38a28a4a09058cc75454fd660ad6b6e9d86fc0f00dd6083da084fdb9b95b247e7eedf31824aa9c6fb41026823e080b7061af6cb776deef4f97f20b955e9ac01b11f358b6088a6ce9c8584a139760d5c3f9c533f9479d9fa9dd60024f644a1362d79915ccacba9aeaa918c08327ae38bdf4faa1ead81de8db26d3d47687a0955095cb3f71c428c835ac7d2e12fe4f61f723e1b887fbe8e34062a4a36419a247a1cf955ac461f73f96b2822fec1f2307cbec21956028ba4eb610743bac0e90af13985d41530167e1fc5fc7dc1a8febc067f85af0f9fba2f7156403a9de04fdcfc97b2fbcb90e893d90defd4bfeabd57d03a187956d877d728bc38fc5a78e4659510fba30d174db85938023ff584a6f7523944ff886f380fd47ddec4e955edfadd4d6f09c65ddbdd1146082f52bd7ae4894362d1336fd2c506f511654b8cac6074d62f5aad0086f84ea5b88617135a59a03af6fb0e80e36a60102d567e102dfcaafe1a5f6763b7e3efa98fb9bd62222bcd6793303b9afdd6f90edab8e8fba4976023ead5d7c19c7cdc097a51a134adcb3fa8da4c7ed9c00bd4e7c14d106979069806662644b96271fe277c892cad5344e72fae3f5f0c4d0efebe1caa5b7ab1193b9143fef983517445290bd23128db6364c019e61f19415f06f3353994b9e1dafda35f10dbca90ca0dc7762524f88867f3a3b8d3f2dbd3ef3a330c0bb9e71f022bd3d5b80315aa4c8d0c7a73caa3c9d8fe822846735e161229a0618d8b68b094c9a677f22305989d2a61155083c0a1a3c01852b2ecda587d8d7f8e9a741ce0782025cd509e90c3032adc1a0b47b414722baf97158e02a5f5886e437e42d973d0f0df512d0aa2032a367bc0375302a539b99379942e4335ed69ac1f197d0fff497360a36ed5c8356a72783f1e478a544544b362df873edf8c386a1b845b1fdb2cbe95199ecd73e2cf1d8b5d84c9353bb70ce44010e3fbc3de2c1e87455d88d15bb820d0e858ff37e1c191a810d7dfcb712339702604b1999243b9ef8d45b6bb719b86a4d8a8402f90c6709683883f7854ebb5cbe1434a3b2f486eb253c309ce13ec2fe29e5030fd94bc27bae5e4f076b27095802b169e90e6311e84478f1a2a16f7930c02f6d17bc23321c01647855f779e101391ecf58d56cd38b1dd48706ea3c9a679c501ec62cb31c39ae8f5b8cca56836cce58ef9e27bc1574ac8368547e2fb95ae885610ed34ac82c438cfa7b94284e50692f2673838c181ffeb1108aa90fadeaa9e34485792cf6cdbbe1234a10b5b8282fedb0608c6abbcd1721dd8b3423d1381105d0c8ef973214fd22d9d71d0e7bfc52277e846214b64bbebdaa5f60889271ade970e08541609ea58e34b423614052fd89335916895b2ef568938aae9e74212545955d8d3ded7040bec9330470afa422ad33e12224a0a1b95901046a5254ca76b9fff4ef6c450ac7cf4d3ef13d57b849bf8ab3eda57b33af794079efadcc09dacf535fc9883b706828e06b4f4519cd58131e1e6a00aa29b9e11c091cac3d68563ef8c0e1d2664038b08377517eeb9204250f55e3435aa91e15f41fa898998bd1114757dd1a412a85d0434594e39024f3ed6f38fc5cc53bfd7f0fbc99fd18bf1e579b319a75b1dbf9d7aac87a089b534d1ff549e9dc61fb79249acbcf1ddb86eaa9844363ec5a2e2369185b33e2e0b4951381abe749de28c6c00d05f2c73836bdf1c672953ebeb9094cce7cb059c75a5e86f5827a4133bfccd1ee4ccea27f8352f68b5083a628138df52612c454699a5edbd5572ce482e0a335e3be5d4f9fba6b2271fcbcc1acaea4e955d686815630b66bd7df32debc0f706079d9270d245d93d77316d610373972e072ef2bcbd3a3cff4b95e50b4aa658957a4cc372894320ff5844c24c8d1d450a96e149e0866bba044bcacc3116825b633b42aa0ba2a8a795f437c956f0d29d032f21200cbada3db1f86f1d69ce6c906ce530bdce4283fafe92dd156789bec1035a745355a4af9a8717d131ee92551647acd592853c23ad4cdd6750310800290a68724a8757741966acbffecead4ab4f4b6e6ca9d66a850b2ca0247c1a1b366d5b9ef994ea41ba86514eb263a1f78a9d57d776866f4e173d423fd1242b83c3dd8940a3508a1ddb94ce3336488448da483b93c66b2280fa3b4d56df1405a191ea972562d53e157790e69b4aad471735cda8d1f01b09b89a476e6c0344df67db7d70b2eec3741671b6e2689c3ea4a6663d2dd6182271801c4d1cea0f102e8656d276100178555f50e3b83b88aaab83e4a2302cff55994002327d9ffa8b5aa50c5286c84405ad76631b294dccac8d62d5c13f4c9b27b699e8a105c224f2923b06f2a13c6a9b82d63a7416e9326d21265b9b6361ef2ecbe173b47b2ca0b4e053128273f67db8041966cb0252ea3052d3e43663a7918019a49f78ba3290693d0856171e59feaded159e21ae9d4c231083cadd8f91126a12c6d89a47bf67a6d32f96eed953639f3a9277fdba19ca1cbf8e2e4f8088a29ca33378f65d2c70d4e89d0879d55672592895fa1877c4b76f109de54cb8cec376c28512923fbcde81e3322626d965d27f15ac3ce20769c3071a1c34c71821b0d7b9774aa24ec319b3244884b625286ba4518cb1ee5ad6c63f189ba7f5fffadbda136f45026ba36d06c481b52511a40a40a9d38977b80f79ec1daf97a67608325019748fc819ee0f026ddde0240693f7b0ef6d65acb2ccc3740b65ae1337dd0a3c0e41c896575578884266f963df6c6707290646aa7f20b004f309f924a1cd9b467785130a8ee6b413cd99192cec9d2f96b09f9083ea9002184069ad0c17b9b44427f0c109435b4197af636f8928e86a588a6831abdc40e4bb9e53375322a8577d972473ee35cd2b79153863a3cc212f7b805002282a326bfaca196d83b8744cc0a01405697a1c24f2e9680c4403b97dec09afd304144db8a356b5cfd3b1c7ace3ff2cda6918297ada606cf2ff886ad13b5319d7a78baee4b7348cca874ae2cd64479e333f81a4bd734b2b6a21662353228c8a5943efe9ff0c2383d371a7cda2a9207fec342c9afe80323a9b7a778ed2c5a3d3b1fe553c1e78574249c16b94e11c82569321a023c791ab4a066856a81a27a184c054e63e29cef645c7b66edfc73cdaadb85055ede159d8f7fbc559148eb1ad2eb9dd71bb66cc5f3680de2beba690f30647eb1fdf5a02c15ddc1113a70d5e95b7f8004538530d81001ec087c844be3c147d796cacabf84101bdf9a0cb0e08cf16d3d99130e678a6b6cb6ee46769960285332fc5f0f3c6734760dcd011a9ddff240de0e04b1170753c8283024966983cb4870803c6529f2e22edcff93ced2a9e279bf8e2d3839da1cdc757e661f6fdd1c69d47acd8c797b51e41a39ad5cf0eb665d4ba75556e21b1c56b13cff861c1be807ef2bb85f01a1087e620afd0c2ef85c6376730cdf1926106d0933de6ee05f27920300831f276c9ae49e595eaf7cc3ca0916526d92d1baca2d26d70289d64a2bb27c8c0c5fe0d9bff8f9ac242e184e104a2e9c0a6a666b312b3e57c04560688fde6d9214cd8af4ce147ee8b008d25d63151b02fe22831d38891c334034dc9913d832f43e4ef71c00bfab048e38b777d20009406d9d1e4e9610db89c736f2042e988d8753cc1b7d2ced4a0ea92d34edc53ffd53e25570e8f534abb93511071241844aaa48d16995daba8f97a57dfbb67ccc7cb226ce702fdfe96ebfdc1aea512af4004561856e1ae05cffa401813b52a223e6d0f3cef0d0857a08f3c764c12918e21dbae0c856c7cd16785fbc3d9635387c3ead8455beef891971105e7560f60f5b26835a2913473943fb318a8b1b0c3340c973d6eb93b21db02a6c5d3602221064169b7f54f0296422b317e5edc0520df04ab0061ae37284369f5607acc2a0a27f756b91034f3e359d2589f05b2a3c7c508d1c09fc15f8f39b481dc4ca3f6d96a540f6dec80b40063f125a3accb8181302c681fcd0f873660e103074df423dd7adc99f2b86e169c22016e554f1f58416ff3a472d7605049e728b96603c7afbbfafb3cc214ccfc343f934d37457637e61191214e326c0f016616ed2b05e2c747a913ab1dbb551c069997445c5e08624ab2b1a0648dbe1a4a7078ad482901a897b40610afe63cd0e0c1cf31a8effdab6dcd3c9fa42526a77f739789f057bfa66532842f0a92277dddbe79fdfb452c4e3e479f4ffc2bc1c2a6aa80eb39968dc268c92eec938efd1b71e3c915dd4ecb4e092128b625251504c1f6"
|
|
+ },
|
|
+ "transport" : {
|
|
+ "secp256k1Address" : "0xfb6be1504acf8262cf98669f7833b9cf1cbfabb9"
|
|
+ },
|
|
+ "ecdsa" : {
|
|
+ "addr" : "0xfb6be1504acf8262cf98669f7833b9cf1cbfabb9",
|
|
+ "claim" : "0x93226518f2f96577f65afd1fa29a6ce9ae009993a5c33edc62c10f32cf06509d5329050d4b4102982eb5999faf68b0a2ff14c6bb56b20a5b1b6e3b995aba012f00"
|
|
+ }
|
|
+ },
|
|
+ "2" : {
|
|
+ "id" : "0xe7e6b4d336121966dba59a9dbe640a888c69c6a3",
|
|
+ "keys" : {
|
|
+ "falcon-512" : "0x099389548152e1d13032882405cc079e58cad02ca0cf4ba2614183ec672652f1b650295317eaf41485d53120c0ebc106d930a5644659becfb3762a9307d1453baf6520d7e541af4172e8e15812cc8b105fd0752f6b46103e8ac45fe724196ad5c313577de66dda8203873d56c53a832b0150ee2066afec88066c16f4bd2e3034e92cf3b78be948f25538190a3714218c1b640e6e072279142392189c12c5287c21e043800203485a71036af5659f457452a05506e3cf63ac15b4341ee0327cc548359e6a2103a20ae599470a62689f9b85a3f0039e48674d01689581669b54263b0bf98cf4308c40b8495b562c4c0540cc8b84a6e3c60dd202e9f3d38a1d1e1ea8e72a59704d8c3aa007fd64605032e0a77463d8f9c781d7ca6478673a82c3f59d4df4d74b63bfb91916b0011e6b2d66b402864629bbe48846ea2a1486302c6441c5be779ea295fcd5db313c9d5401e7978aca0ab78f5bf649347a93bf436869a2a784c729d8537e76384a4e17b934aea8a990224e8a1560a388968cc1d78aa345029884fb248611332034dcd69b0beb0654fc2a6ac8026fb48133e4c2886408cbf89dd400043ee99394eefb1280e1cb07af291f191153119eb625d1332a884d930f941cdbd30699b568124400260ca7660366778a5ba60d93868d4c438be93b55422e2cb2fc1481895fad9ed68aa573e3fa375df7f585242aa2a4afcbd36ee9837545d439a3843ffc470ab868ec3a48c4419f4db0b9f8b174b808951c70df56e88716128ed0b1f443039bf6a6c32ccd300cc57f23fb18da19dc3861c5210909014a32f92e15460265f4fe556053e6c3ca96d458b2b1ae956392ceb9616f228a48ec30a0eef82c2bcd4309ee388de6ed44791309be05ed1dc810bb5642978e6297311258a25e24eaf05305e204dc66e47cadc639159f08ecc4b5609d44912bc6b439b8dd2098e95625353e9b7e490b2889cd71dd009e8dd0ec2b0fdbfa251deb381ae76db5881f90ea06301819751b4c14686cd1ccdaffef6e183917e09a931882d8a6c12dc1fab1d16fc0091d5c224588a7d36bfb598e5a653b9820838d6d427023518d80fb7ba49c5c113e22d75321fc40e0f2d9a9827892f00b9710aac47d596a77f8dbc3987ac18360e65f22a5449a4be2f597cdcb124397c1663c85113c48f3b088336a8890c1ac60dd6039de70bc86b9a40d07aa4a8e1f401d43e36cae0997cb82a5a09d37036babba73d27bf36428bf462466270604be03ed885a3050d5",
|
|
+ "slh-dsa-sha2-128s" : "0xa7084ed6d1f93fc7a8712d009312b5c048b5d500527fceab1be02c98327239c3"
|
|
+ },
|
|
+ "pop" : {
|
|
+ "falcon-512" : "0x393005e44d31a4eb11a4ff4c3b6b1b9bcd79ccfa8cc73b5d8d844768a0be60280dd67ee41f416e5998042d190d2472f8c72b1fb943a383e338ce77ce954fd270922e9cee7aced8ca190c3c724c7f690c72dd87f34485295efe7de62667e9c86b5fc2f7480fcb5625f9b35f8b5a6d79cedbc97e86b78ae294eae0f67a86bb6aa0df7eb8af9227986bd8dc1c37534f50b1af7292a790785c6d1f3b95c939ac523d65912bec20c4c7c91465120086eddc74c79e67ec5acda341b7839cb96fa216b2ceb0ef0266e764c8f14a48cd1b6ea91b640bc70d78da353fa47a9fb4c302729aae0134726812bdd1885a1308ab47b1e9b7bd9571564391e50d5ee4f0db499ce709596e3653c864b703ca99ad7ee601992f9674ef75b47b3c098755d0c8b553dc8ae2a7c9056de17bb7aa45499f8f5b338efb74ce2f7bc3b787aae2d1735e4d909eeecdc4ea5356f55b9d32c1d6b1b33d9ecaba5d72f1a5225665bffe89189edb95e6bd1d37b50bae8a7a822e9c729fb7443a9eb8ce392a682db0e835f3db946aafb4db6f74b9e3497408d2a945551e227aabfe970eda2152662eb78b8a21defe027b2e489716d5374763ae44d2fa8d284d16a8fb18efad26ae50e2902796b3385a189dbaa51044d13377d546ea6cdbd6a364ef50c6f1b4543971eaa4e850e916a7389e2c737a46bb473e7c735439dafc9199d6bfa48c7efc49f34161f9cf2eb152346ad11cf2412cdd1329077f6be5d527f59c9d4f4e6d650bea40cdfaeb846adb27b9a57ae96b531f6551aaa5d6fb5a741781e4c8a386b92967b09ade0af9b0f538f1a62b239c6a09f7b4db576cc7f66164cb30f672dcc953d329e3304e5755296ba4204b24b8c295a48303b746a1e7aea29453122ca313c1eaf058316623c9b1c3e9fa95ddd3ea4757470f18bf789148",
|
|
+ "slh-dsa-sha2-128s" : "0x2d99178a59e6149c65e2ac8201ad1cd8d140dd49664b91074094a315906ba1092862c259b8d96953f9cb8f7a765a8508624dbdf2c4227349fa709511567c584ec2231f2f39ff2653775fd3472114442f3ad75936945ea684fd6e4d281f3bda6bfc3a5458a6aa60745348c3637a4aac2c5eb7c5960c85c272583b713d512b701ce822ebda1ad2b5325d4ec0f3acc6646373f3f7b1f6c541b5fe4d083d618249c343453d2dfba81feb884253488476623c0bde3e074471e515f6945918278c045a79d3ab0cce98c6a4d3c725d6fc9bd40fe8ebccd4fbc878611a9f0f0d1aaf5f8eeff9e7104ba63a5302e5465d088f821725f6a5101b7f1b3d787c044364e114b899bc918c88d1e1854adc822c061d1a42f02a9479484b5d1af921322afbdfe93fed7e85c2f55cbaf0be31b6c89fc21f369e452a5ff8e32fdcb963dc5a3526e8794eab291d13939e969e57df7e51d94ed210f3eced5fc8b6690d621f66140bf8d78e34dd1bb641e4c90748807acbd461502a0398e40754e406b3e869889e52578ff255fd28469a92168abff97d8d42b1917dca9ecd2d4e1524e3b9c3d5edaf2c7305c9185b163d6228d0b032f16998fb36a5c609ab7e10e5354c9ec313cc3cf113c023196513b2da8a1b19aef1ef48123c086bcefdf3ada4ac6004223f92fc466108b58d55188b352d734ae4d5e42ca4121d9f6ef8cd0351e76901f6c72a79c7f34ac4092a012fe50a0b74f97ccef1efd7e1496f6113ac886331a71f7f3cef890946892d6684c1efb35537bdf4a596c7960ce6299e9637c5982fea74868b86ee9380d69cdcea4ce63771073825ca89b348c1603103d26e1d92234d2d31dda4c7e204cc5b5c915fc71af2aa8c268bf0f72cb787d6ab206873bf4946a24f98e66ad2457044ac730326066c7648f398bfccab6d4a2cb68d9852260728c84bdf8033858cf7f88525b3269bd60204e2eb9a34925ae694581265800ee4c6202fa9ab88083e631cba05b55d051f6986e505a5d6880b949540670f4049009695b13aa26e3d39a732d23205413205deda93a244c393087b2bb178218fc5766924ac8e0a5572bbff0bd3b71d185ce3a123db4aa027eb93d107fc9a7b185fca721b1e7a213c73b59e0ffe893371cfb8593807273d6438444825dac7411e4bc0236c1ecf7054ae1083b6169b9e1f098b6b5cdfd369f120eab330ea6b98c12fa159f0d567558a937a88612328cb06df452af15053c981c765ffa1c38dd89ee8835acf7a170f0ee2950c5b3bdaadf904aee8688e636bc55e3ec638e3693da6422373ffcdb20dc4a648d5bf810fb63e7fa0ebb69ccf8ca6c6cd423b4826113f0a4dcd3bd37e4fc06ed3597192d42d37625e1596cadccffa7f53aeb4edcbee2bb26dc7ad46d35671d1439aee460903ba6d41928e35ef09b4062bbe408b6c0ab5e18e71b8615c6b0220b911ef028a39b9410a87ccb477ff28b8a256580f28a5a9f5b7aa9e43b29e009ae49175d053c294424ccb20cfafc31266d4e52e33ffc02706d1de6eabae599354ddb320f54cfc7d17cf88b9fa43dac5857ac44132d8be8a9ec34db6e444c6d453abe8fd48f1cd7c5244f01e49bf1df919e9c5acb22c9f066e80b885a52d579e05b853b979707e7de64c316519538bd464c580e5e829cef1c5de3f9e947baaed5c00e38aff0631dba1c7c418d5b03ff07d830218828c51fa306d27696e1e57b5b3ef3d1a12e3dfd1e9ddea3bca2057cba7fd6576c38057d22fb9b919875c1a53b3c40b8a8625a70f73a5bfa16d0b26f838298ff620efe4c68ade8736f0d7910d9577534287a7ae098dfc3e61a54f0f5a00e0a242542e793d0bde26243a1cbbacf8d4eefe6d011f51b23a883f628bd24e9ecbe0a118ecea5251b8278fdc4ac1405f12397ec5889b84f3722f4986b7115e9bddf01dbecb296c1a4a4b1fc72a47ae5ff1e60cab5ce656df125c0e790e54fe1f264e5da99f979ec5f6a1c032d4ac05e6326e76b6c0192181c59bb389467624c258e6619d945334e2a5050f115fd0d33d90e99b7974cea332d9b9fc63b94f127fd68e8f6478c4ea1a5e9b7f8c9fc33f2b008978328383226fc1cb393ac1c0d50e203f00dd34d121f081ca3feffd917294eba38b919dcb37370e2b438dacba9d2ccd0df58efdfb9a39c5782f79cc10907b090b3d9a855494399aabbb464df83310b0381dc95ec6ddafe675a07df7302ac7cd12689f65d59da9d8fe3a11e8d1aba2a638694621afb4d6e31bde3cc1f352b99931fe1067ff11880c3ee417d7e66ad5f0489ed562b234978cb7190a55560fcb30853c3b64babf6625821e8077a306a38a1477a6620c379cde5b7fd36f52a18ca076d844a7a2ed68b458b160004d994e9039c0e4231637be8cb4a77ea8ea0b39a45f4802a26321086cc2022ef9050e9cb4692aa39fe6bc9d0df69269b4515414cba3d67e830b623ece8b918df893db18357c45dfa2ea9283c315e545688878f2c9ee4cf5b9b91385b550815361d49b374d823a535c24d159a4b21a9d4fd5b4ae8ad52bd86b84a6bcb5c4b7e8571331f8ad1a915002ba8afcadffd031343cda9c76a092d77958f0fdf49d197b2f080f872b44c2be572b5c96646642bec7addb2b4ba344b0b2f699fe79846b30fe1d7d4536e84b594cdc78c618be77ee5f2ff5e3e7202c509db3de56f2b697d638f8ec7b86129619f1ed1cc30df9b187e03e207e812b89fe28174b25cd1972f6f7e1c97da583a27eb1a6029bad9b7196c00a643c92658665f51520431eca91513bd86daa5f2e7c4922c1ba715b57be08477ea6da97cf0b19f743c68abc2fa5015cca396fe29002c8e4598f38b8eeac768ca281644c5d521028bcec37ad991fae5bd3a2f6b5daa7fa31e6173786adb2c3ba157ff44a4babdf13b21836e95054f2cc752bf17a4e0fd20ab58ad0beea608eb80df3169e11f3940508d86c1674e2ac616e29336e17d00a0a2ae2cce75ff0aeeea230516a61c8a1f64d53b3be591c690d7f07bf7274b46f4cf7a378bb365e939bba071390eca4345216dac3662a5879c29e3d64c642e1435944db48984c8af80952f017bda9a9230df0e8866f854fffa3900f19e4476b8b6918d2d57053f0fdea90b5b08c47d736d3e8295dad9f5d04fa5562480486ec163db6fad58347b0d2d9a594d18a60876d6a32e667870e999d178e685b68f49967f4709e615ba3935730eea3a6052b38e56b34ec48936c7fff066ce4999ecbc7e092966c7d4bc84139bce4f2760d870349221c471517eac0d3558965417b82d28dae7741bcbca4dd11a990b133b2dea8dd9eff67d6e36b2a068bf3e9265e013a3c5dba7cf3259ba2ffa44bd5b24ff7fcd32cb989627ae48b38c354495bc6171ef38baf147b125c1c0ee440c619995ed9c32ba0b2d7c4e139fcf5c214c2bb51cd999cae3b8b48be39b3203987bde51fbc0aec16778622ff544e4896b011de73a105135be02f38fcfbee55f615295beb131b7a775816d3f55a298dbc0850b0e1e2ba53bda719cdc5ae08379f8e48cc957f946d38fa4ab2889dd62103bc1c7acf4a0e51415fcba4ca1a1ed6be80110ff61638d895e76d6aad1ae8c9c80dcc4037ad90d25be3c1e5fc6e59579df3941d87f006629c0c85fbf04fa4cc26a8036d81adcbf4b1247fa1b41ec95af958f73dba9505d43da67b2fc1d3c8ffb71f518cbd087e159005eab5df23f771a43348534153d6f89e531f2c9be02031d30faf6caff6c08d53b4f0c0c42da1c9549b21cb0f534378b9764f02a018fe7a25fe70b4400343fac5c0a72ad305912d0f4a365f7be8902144cfb32ad20101267e474c89507e53521548685932a03c31d1c0f381c5f88181a7a5c1e006b8752618cbe93444a90b7002a54d8dab6ac15cc3d1b7fc4be25f28044a098b75b02a3a4ced4a217c205344ed0fb714657028423ed6faae6aba0f5d64f4b90af69c8bf13a9a46809ccd05f32ac274606ddf5adedaa6927d1c4b6eda36cd46facfd6853e435d7a00c46347764b3269f7ab8c90a8e5a66a430c41416850eba25f14bc86beed06c0c31dc96a1db7a55fc4588e86d514535dd962bbacae06363b42eb4ecb4bbe546abd1ebc6854c3213a9b1dd964f3067c84c5c4dd687ea6c5b8911f1e6f4825076fc59c8ac9a702bc8abec08ac995beeb081c53294a8e656579e5f783820f9f69a2ad82857cb18a17cdf36ee18bcb0b68e5e9b07efdaa73dd5f30bf3fad6914a7e8f698c24f2fb3dc90ee38cf38584f4d49c0dc5e7c447495f02f1321f39e3291d73212b7e492b22a288cfab7722e8ba34bbbb78f5b2357c82291438577178e56da891297294a1f0334429c0e26d3aeb6e0d6282f18b2d51bf967e28978651becb8b847299092b02c6d5fe594fa639e94a17e2c1afd91363945648268885b390121b61d5600e9b95f1d1a2a28a058ae545da33a2a7bce06482ffed7485a9d83038ef24c2467bf2aa34814548fc55dcb67d28cbbe9b1d2e51707c50ae696bea54841b200b074e43b15c7a5e3b52ff2d809f15a845216050f37b7748c85e6f7e722cc7d8b49bfec1c9ec22d88300571dc2d882fe61455c7c656590839ebbb93362942af003f4d8a877c4025ba82a8a88bbeb8571f2685d8f2caf98fe32dc6d2c11305b45c69cda34fd2c19b645e1ba216f6c593aa69bca8b55c677a05ec4a83f3607131e3861bd5390e303555b340b6ab1c8d0c35d11cf0f13a6eb74677bfea48b7f07d32cdb226eb261862c7c3f7509ecb6416d81dca07ed2799d96adeae27e8ea254fa6bc0e4c36f4311445d4bd9d201f48aa92017e604e75b1e04cc558e42c0e6e58ecaccd02c59400073df4f47f2d25dcd2f727758837c201095858fe0a764697c20c571948128c78ce3cf2c089201d59205904ecddf8658633bc0c4fb4e4f79daf1b651741d1bde5b6c7fa608cfa694a898bff200fc91e40347b7d2e124b38853de3388d43108579dbd68870620f507e6a234555dcf263c5c0ae149b6bf9ad6b3ac9fa15f27937e7e9a2be3e8b1b7be7e19a884e57cf30f5c1b1ac5c96a781092d17143fd893025719b09e6cb7498373551f56d337cd18dbddb7fe3755b7e1ecfe93a180f12433ffb66056bfc1132003e6a1677990db9e58a5907289c0e0b15566a1743d997b01238c7b71415e39756d2f5d75cde0bb2952de2563cff3c92649d07d60c22840503f09c232e50985d2a061964b0de1cae948a88f0b3884ad57f791227c053db3fce320472f3d6ac1645c2c4adf9586d29f6b175d9a63d2c7e23181c333c61fad7156d385dec0fad4fe85ec5cefe656b949bbdbee9bec6ed6fa52cc43b9c6daf7579c3f156f436a6a21eba6bed34a6b85d9b35264eab9d0cde259782f6a1175c9b085f820df1daceed672b43b7c73a73cf6d3ad32565001df09575b92bfd0ba15be0248a1093b15f40376c59c450b9fe0dec4c4a9a2e12e25d85910fea3fe22168a3b085f8cd097f18838c75e1fff0b0681889588d002f822d8313d99de724e0d2cc02c96007f48072e23977b4401d7170a4a7ea807b6b90888150a700cb8fb3923ac7511fdd33cf2726786257985ff211ee5fd30d115023e6e63015d72eeceac88a63f10c8ca572fa92446f8a318793133a5053cd68332fd7efbc6b8df69c1742c4ea8367cb671b3daa6dc8d5133d1c68284cec6078eee0561545a9f8616ec08b9b82589e39665bd7b38965d90990fda2e1f0fb2799e4f6981c6dae4b1cc99fa6e55fbea740dcccffd019c79657f6082a1e45910c75952c754e3225fa0f072619fda1df5627d560a196ed812570c2b9496e4fc19d0843e701ba7148e540635bc2858a299f59b389b275103708a74c8f4b106a832bf05c8384846541a447ddbeb12620dcbae6d2de0bbc385ead45f2e8806a5cc6ede4aad23a4863b919cc2b78ffecdbb4acba2181b7c52c129212b8b4e45f17099873b8a513c63a3a21dded19380c23ef350790a94089acbf673894546663b978359518023d3e3bd73c0ea4755e45ed37a5058af6aa52f0344dbc293a5a2c02f3d4309dc40d29e6a6eec15970b572f0b34788ad6ed05f98ebcf06417c09e61030100390029b2d726363e4d0d2eb2442855ca77eb94b7fb2d7f3f614530177682d8aa351bc4b24d866325b8437c0d33b18c6269bf1da4edd394a15db3ca462db6bf5eb337fff5d775e05316568cab84bccc49d9bfdf9ca548b7281ee3f5158c1e4c50e7d4b50f1f4ce8617f2525aed8b60e1acd36d7e702341704e932dc294f33c0cf47eeecc67645b411c675fa39bc01fa13c5dc1abb956d3bbb3a5ebd5ff9243ab58f82c8b2b3ffeed8064c28a383771e4281ae900f6ff4a9b4a4fff0f861349795f43b8ac1361c9c074db43f97ef4db42d45639765d5a087f6eb3abf4307533e021402b9f81b1cd97de2f6a13b7b1ff7adc0644a54ee820bd3f593562ce9b70fb793ac715d6dc1e0021d20c5e502b0702c18157dc48a0e5f9acb2995366e33143dbaff767ac60312a62cc65020817b02301b82842f424dd362d26f86835925b18331b2de2466a76ec2a011f8e7b48eb8111e0c35995299917d0021a60c5c1b1bba6cfc6910b7a10d264ee4a87cea656a80aafe4169e5c968e9eb4528aa9ec04e0902dcb2fd9307176b922b878d1b263320a5e8cb1461edd1ad87374cb8695aec47ef182725f8cd2b95380a4073a06a3c9684fc4596f45c53e8ffacde54f69f111e1cd973e32fc82f21a4e202b6f1545154e5a2d4a9d2770debd751e09a3d8d476ee5d4071be4aa823caba92fd2fe2f6621d786234e88fb439491d9aa1cc58cccacc82b0fc76a1efc8bd934942021e5c441426c31982a4459cd47b3cbe94686cd2bea1b20c7412d2287293203f5d2d60a181fa1b7dd7a5908ecbff18dec2d4f060bb3a4e41df1147bbcfdd1f4421e4f3c04b07ec5ca7187dab62e6624704dbf0c529c95fffd924eac744b7f3574417259e99dc9be39e49ba8346913a6f961750241600a22eca4c3cc0840451e7a3012b0d9d9f0ec95a7bd057db68ca9ec4a976ab307accb813cc37e0f51d40ba7362a319b86ca1e53e12b5af29ade7768d0e643d1136ee797b030d1d09cc431f5dcd865bb0cd135041d633791c2c131ab691de4dbfcb928ce2e8b7ae00da9d34283f3f3fd394ec69a9d2a3015a9cd3a33c507596c1c96a8d85b99627af7efded653d5dc41cc0317bc20e83e24445b0569e2e5d1da0c9e4788968269a1b383cc81362e02ddd69b3bda45662695c47be29e28ce426ee7f37e0875832aff3f9a215ec61012e1e5185716c351012c7b62af279caf45cc222c83638fd549b8e7e20a30e1cc1ae697c0b1a9bcc065c90bbbffdcf22b375a6d66a5265a739a34f9a4f6879a7e01c3ea99441e8bb0d883e90ab34faaf39f3e9d9246927172a1e0f11ef07b6e4e7d265fdbe17d33a95da86da67e30bb9702f4042679aacfacf0c5399a5b7fdeba24f97f4b0eeceee23d111de63d7c9178680bdf13f5c2d969b45efc2dde042a0f81c725a6017058bd67ada6a0ebf4c737eb8a9097d203d7b8d45e5cfac21de4bb6d4055fae9dbc7e880937ebbc6727463b000dcd07926d0ee29224310315e8781b850ad7364496acb61ad747b06526c133d991703f5fd42c12311f003a84609db864522a4cae1e960ce702942dc3ef8219da4229fe74359ae320b95dcbcf68daa949568762becba5dca08dbe20d88db54d96658bf4f7fa0dd61f808c872d0a1fe4ddbc8e1de96c5a1af3c6d69d13a3d119ceb02f6d862954ed7745e7ebb3a5bccf8a1f176ef877e6ef4db81e24c6fd112b1a22400878e75100ce85e4838eb26dd2911029b92be935f4c39679abb0f60e39ba63939f5d57c7eab38f40c2a06f8ead33809743a07602f5f345ebb4b2cd12a4695b83d65f24a508f64f34d74d79faa60a693221bdc6fbf45f1fa1427f954517bcde925942ff14935f4a1443fadadf940874d5b482b61f44d8610f3b98737ccdae4c4b5b732fd6173c2c5840e3bbcac0aa8cb1a49d0a4610f1bc98be90d8509d38006b76ee62b88683a5f7794699a7bb05d4fa772694faf7bfd2dd9f61aeb009863d8690f86e5becaa13dca4f256f7a418f5b98fecd37613de99f32832d62586b27f1ce60a18cc39e8c480cf5f59f527ff62a552300628f0a6935ad9d8d1d0093c3d5a90289d71fbad53cf4ff672d39a66eda73440205d6d21c0ff5f4880a3758f38b66b42f37c1cf3e2157557ec90648a0d21b838cc43269dbb5cee852d51aaa8be5cb6e58143e3cbdfa47304cefd4aa8459deef958ef1657705b12911e9fb01d5eb9ff66c748e9de044a31a30e5c5bf98171528787106b1c56829e695af6ebb170132ea08ee0b33ccef38efdd6b5cbaed6ea512a6041fce1d18f60911033d60fa7bbfd57261734a161b0752486e63a513638c4f4cf50f336863546d075bfbea1e8bd23b17ce3eb33f30fea696a0fa112c9f4284319341c6c37f2e9e118bb0dbdccc9d9b247c6884f31a19776bc4deed56bfcb937f935bd398c25083db218d22ae7bc23e8f1e243e400f629edbea5c8c6d044d0cbc918d358eff69381117a595d1645e72e05250ca9816830c0b0d3b29e5f49660ff41337ac9e0a2b5974a18d9623fb8f7d75ce668f0519ca0f81ee8690437177da9df6bf59ff3d53a7b25ce61c7fc22e6a84046db5c8356b04bbf055dd959ad41470d18d95d7c7a90c7a5814135bcbfd079f469f11fa02b1fd3a6536ee4cfd28c87a5eaa8cfb348ce9bc6e369820d7e42d5156a2e37a5007a2c0bf40f6c74b1be80363fba2d5bbf591bddb5e911d934c249f34e68047635dff0e7730a3d9988077f225844c2313b34610c6e6610e69b20afb3ebe81720a4f47789587e5c4ea3ecab1366ca9a74d51d1fb6a87b15427382c5c0e25341e9a4d2d2cf42d139f543185a801a98ee444c22a5f555fd96adcea8225c380433d676fba670d06b6ea1cc7b630cfe05f864bab3ca6854506c102cb0e6ea51654ba1969a8b54d3a125d0445aa83019379f0e0946f0db34c9f247962adf07c6e1ab3d19c58b680cc0aff48e3ee17786c93f85ed9926008dba4e2138e04c09bc6f147d39691783e60beb493e87f328bacb7bd485b0ae4b2a0b740b238bd6e64050f73284b94e5c284d5975316380e11aad615fe53eabf3d708a73eac2ae0e5a9bd31cfec01ca8a56048836183a5ebd2e1b1c0116eecf3a1749e5b531b2e295c92469520bc2f51913f2b8c02254085b38457e8f2a5c21e516abf9c9e60fcf0bf5cd03cb27cb209d2e885a4c44c028fcc1964c559ab87383becb41801d1142bd025d81d48cafc1ceea128168f80c59ec11d89f6b9ae5126880bb54f2d2c306a1c7a66b67be75652f79f3d08f44b9e9aea0640c9ba0434ef9bc96d7bb79a716461b330079ec8692d25ff2c3529bbb28d14efd7d076a2a9f7806c84c6b5670855cd13d49c135ab8d461c75b2e4fbe7efbec2d5a01ac2818249ae1ad874535a2c9a4d7c15f6cb224567b29c9bf43425ba91e1854767ca1bd04092fd1efff7f2c13f5980738fccba9855ea2e1223d3c2ed3be1d6c852efea7c81d2285399386a1614db14c2c8158a1d6244dd1aa4205ee47c3d12d1354795e15e8b5ab81f30a249375c39d141ddf9c84b95461a5e0f236ccdec097831431c938ae7106ca6c4c75f238dc0a7cbc802c74289fab9cff24d2e8ba217215fb8a8e4e033f5a19a1fe2f518c2c29bf9c9fcd316241d4f8ad3570e680a099c505757aa8efe6935ecfbbd3af6dc3eaa910bbf18d8fd2ba2877a0c966b4c207871d0691cd235eba11c5175b8acb4578ec920e23b7ae4eb075af5db7b81a3103c17da0c2fc7de04f40374ac7bea64c5fbe396f9c6efb3f390418c1e03c5717d761cc063d02954f9dd6336cd661ce36267641aa0abd47ff0f556c81a4761a9214a344c4da8e77cfd02cd6a0b39f1aac68a3ede4afc56b7674b82790dbe7d6fc21674f079ffc4343e3e15f0e90835c4e3c41ef2a5f4f96da69ba06b24ad96507c9e5c6ac1ad37b089a32b441c5905aa05dc05469f002bcc02302f7905c1ae0a06846c92d0424e503aa8d42b4e3f60c5935eb059ee714bfc0bc68bce5d83626599f68dd2d6b08167be94e3629d1dd62d36b696e3cd27d1e71bee141f1e69adbd26e2f9010a433dd74b00637ab84a3275c8097eee6a0dd54a784562dba68a82c651d211151ad33540c99e61b81d9774545c6b346c676d0699ac4a375ce31b95d45966466c7d3719d187e450d9f6ab5f5f2733045719a0b5c52db2d07eb593d9a16f4e8bf88684c90ac2e928612056d0dd3377cb38d7883d455295fe7bcefb32111024e75ca3ca4107ceb188b11a4f4bbe964487a797859152945a63cfbcb22cf04dd2e110fe01eb9b97bb4c8402a44d831811957ebdafa10e684914cd4eb291ac87e61942f80756716f4157ae8c15a140c4e685c759cfe39c1a7cde039a3581d8a4f2f456b4d56e407b83c96d9ab7d602d35c8562c84e0db3200d0842ac2db1813561142cf57401f5492965b36dd3f449c11801e3299fb17844c52ef2393fe49cc1eabc90a46832242dae0336b884a97e5e99db9d5803ed517ae597fed378f3ec6ec8ce409034bf9cf8fbfaad88fb9edd79ee19cc5036456826bc8a3f8bfd0030db0a9138130dcfa1ea26b3db752b65e67b77a900307fdba1e747bf32192c01fb67244282206c4d93364f1b74d82bcd41ff60cde5e0aab192e5ffd0d39b6121c361730b8487387f74f1dba11be5ce74c73ac2145c747e83b3fd76c82237b60826254a6759a4157cd09da41bb6abd27102ee4950ca68bafc01e12d11b840497f0ebf9bde865a31c4c43785558752c5b4b7c5a315c46e5be99b0eaad9c378aefb9eda4d1a79346b15b9987bc16fe2d668d5ff9e486a04b986b6db2a85a29c3d9ae0b51cba67b1c8773f6bc26bfba2f8d7e8a51c3d35d7f11b8bd5560faaf8801b4959e5b11ecfe67e606c147d4f02ddfde4db9fae8e618c1ce76db126f8b3698c38be86e3501e739697c2dabd72ae672a838a349f008c4b24a791ee09012a3ff6cfc4e2b1e152132d9c33c00497fd7475f9bf0f8e5df1cc7a0075f8ae77a02818decc62383f0f3a2b66781d5ee35d77ce"
|
|
+ },
|
|
+ "transport" : {
|
|
+ "secp256k1Address" : "0xb84ec13c5811264f60a8bc392634709558223ea6"
|
|
+ },
|
|
+ "ecdsa" : {
|
|
+ "addr" : "0xb84ec13c5811264f60a8bc392634709558223ea6",
|
|
+ "claim" : "0xddabaee4c80ffe71ee9d54ce4a7afa28ba2433b5fa403e357f1927fa8e254a7d68a1bf2cf36adc19d251194828146d7a0647fe9910ee41d87d4bfde3f212d83901"
|
|
+ },
|
|
+ "rotation" : {
|
|
+ "falcon-512" : "0x391d3a903910eaa6bf05a1353e88b7f8414fac5a61515860b26ee418f8acf630e312911356a698f90b52ad913238611018c4cb59fa980fef337b955fb7396adf03a4a37820257565cfe2ebfa9c440c6113d42a3d55df32a856aaf1f6dbe68f144b2a91b2de996b2ce1e2889c6db384d2f7ab0b3daa94a6da5cd277d855d76afc3b6715a731359362e57fe86813daf1ec36cb04e393866a236848baecb415251a6e5522bd244188f27f19b893c1729f6c51167512feeff96f9d9348deeafd22b7b666b2aad2849832da429b90d63199e7e6dcbcfb85a916e49c1e5f7392c3fde888ee6cdfe21e1625aa73560caf7593ab35664a0f1cd36c93a7de97bbdc31187d0fa0ca47eadbddddaa7b194ce5d44c1b1b0b43362868c47baecb72789b3211271289ca669ad69161d66bdb0d2f4b3736dd5db5892cd218b0e9db67128dfe9c6e9f1d1f0ae33c9fcb33a92e23211796e7d436b7d5d69672d30bdeb0f6c689540632ee9b4c3c7969b0add9a467f5976004f04653d31a5e60b24edd417985e990288343559c91e6b57c9e508d27f9f22ab126958c438d8d739ad2e4b9709b55f4a6234e2bac462c4c9fbabce5baaca7438eb3bff6f95e9a346dfffd6149fa70f73dbc6591e7992f594cae9ac4f9ad1c9f1a3b467cf2a8c21508e3f9f18eb3c3347563df39c4acc369a105a5b8ca0554c1fa5044e59e797e4f020b1aabe72d19c22c8e64bbbc6421b57cf7cd950d05e23ebe7f37895d9c384efc90816758e6909971b97089c65a279f439952a1e93437cc3c6a5ffc63751fba593f37ac7391278ec712ea74b29aad92f99d9effe187ef2f5bdd5be3199f473ba6f3a16df6e239af8df621399ee8134d5bf70f6daeb833797978e0572266c1bdb8883d711030ff08bdc64fae679aacd35dfd8b40",
|
|
+ "slh-dsa-sha2-128s" : "0x02faf5264502ba946f835d9c3d9920dfe53a0897d2c6c199692958125d8152dcf7d008c90ae295a0f1149eb24f4a6fb0489371e7aff6dde74278bf487c4c99a89b19f5d5ecb1a682c17642b7b5c79bbf9a700bbb0213c132649cd936faa870fdb5e43125b87fb3200889237beae69a7e2af6434049f9bdc30151ceeb3415bb46bd51d5d14616369a414ca5ee59eb5b5d8d49ec56a342c0ed85d98c65e21502e4c486186e8a289e4097914709bf32a97836c53270d21a1e27a4d748645ba1a142ce0769c4615df1bec03dd1cb4bfc2013b7b4a606057ee873eeada724d5f0c900870f6fcd00ae6b9831c002f4dfd3bf1a313a35dc8bea7c8b983dc2b40286c2cbc453c2a2d743d344ce0ebcdafc523cfc76071543cd4fdd375fc6e0629863792bf632165265b7ec16e2f9a3ae4f75a373fd1dee0b49c62cfa8fd325686224adfdc8c71be6f8531e07edd16da8b86ca7b3348a95395b3421a4f4d3151d6d501b9b29f7ff55953e7946ff69e21fcbc971da4a2579e93c2be448e3bba52310c9bb209d4e3521afaa3f476ea0e35cd30ef9288a6514173d91cc6f7b6f7aca8ad18d905de8a043cbc7936f44cf03cde671d17f7a1f5b2be38020e55246a7091a369f03cda5f4102a95c177025ef6ffd9f29efd1a8f4c9358a5f7409d47bab2678ad5e9010d5b2be2290f001f8aef2240a2a82d52a3e45d523b817920cfa34e4e209106a1a2de81f965218bd74c26a51432b4c082148eb53b8b826f8f73b89ae4e2131b8c672ac9e3b2884eccf1393958cd7af454d22e3d90bb5903b216c18577a22867543f185a071063c70f6804008ffe59c500bf61599e098d478e061bc2b44289369bd3291574b713d0d563441fbc7523b3ec3bf72acbdabd17dfa8330d9f427088ed1bfe47b108d74faec3f68c8f8f31209baec675bc5bb9b5f832a43e2526c1f7024fd8c051e5d88fe9f37c49b7544a30943970f43ecfb1e47c343cf9e9f2e039e934e782716b636f1d87651c112db3ce25237749850bb0f6e2763fa85b6eebfffea3e9cc8ee4dd059ec61471b41169d2d754169e5cc93fadf3c328b3808932b8ac7a7c70fe5d2567303bf8ace1f466ce439f049e9abb7bb8c97ea2051c006377b8e2f1728ff63242c272c9f48bf24825794ec3253d9e108c5551926302277ad328b668bb2414fb6b73cd974b117546ccfdf9ce436168af61e603ebadda11620750b50375033824e862cdadf575315d2f22a85648be0b0ff1618bdc3cb80890d9838e69938cb6b90f85ba454b15f5a19f3aea082e4ff2712d500de4328f495e11b26645998a8717d957be2ab443ff65dea2ef1d6be791ecf7dbfb075ef5437906dd6d5dd8a8b0fb93d7e9df445a270ed84e810b2636d0fd92716fbd81633b0b35402259e20bf2c1d9b3c7ef25c03137b7e49b2b5e6886deca66aceca716d7139e1d9f4db82b5f7731892ffbcb5ac5b238f89dfa29f9cf9bf36728530ba9ac1cd965053a4fdd8141338164bb4ab850ee4f89fe6c7025052887b4a25ce7b808349007cb7f3e8c12a2bf887afdf30e4bfca4e61793089438ae4430432c789897f8451565af66c206cdd2480a92ae12c1960b2868a4a0e11bdf02bfe2f22cda4fbbaed19a3fae28b9035dc6e054cb9b4680c117797ec53b59f506dd1b8c235ba87abd42281f4717c32267e834eb8a0fe01284756c719ac847f0eb0fac3aca20ccfc065d156ea0f889fe756f50c7cfd0c36c08ac2ec004e7e70f413a1b06ba42049913287126371edc87f8b9f11d29f5c46e47543624cb1e3381e4684b22ab08f7c55d3b2817833dfa2095718f5df5178fb411733e8cab46bd343edc8f5775d88c0f5855ab8c72cfef9530829d939e4c9592e4bfbac519bdaf3a3e3b46331e52207d73d48ceeb9e857dfd491048e50f02f64fa5da2c9ba995ab05b80638a25a171272c414c46ebf281fb4321632387bf867ce6414a9deff0e144eabc7d80c5ca72fcb3b9bca97930df48a28adec63ae3eb50690ad6058f195ae0e79875cca73bf6814027085b2f2fb6aa41003ac3a6ab3796ece656ab38681ca032e9daed9744b64e5e2672e939975fc6ee29b5717e183ec63b20aa830929c970a06bcdbf750f456326a5042a3c5dd215e968879470e5b7849c94e31d1d4f2bdc7edbd87ae4300ff5a3728c3715c2b87283ae27793820d0fe7a4aa1c72aaf5c6de1c15d25736be7f12f024f9873a22704775221dd1e1543dd1debf2563120c56879466e6a1280c4f672db7918fa82613cdc58afd15e8109d27a9f3bde548a756594df99861a7fe02047193392687a3ae45f2d966df57bc7a77e422771c9c32f85811258015507a19988a73945e970c6cb04a3f3507bf96270d176c57de83b3bbbff41947ac07f26e044980c5fe809fc3f4ac3408ef2a00dcf34661724e25f397e1789cf344c6a8fd84f64f9007700117f9a7a90dfa66d4d2cab2ea718f0e7c0975b027e1aefef3025dc34f0b751c527913d0c76c16b07d33daae19b9d5746a84a877853a4d66b477e57474a0ec83e44834297ecdc0da5c70d9b867061dc9dffc775c574bfc870640d7bf2d0fda97bc341a2574d74f538d99f9aae18652dcee2bd2872d6d0c24ef723a2c4f2eed2c9cbf49eb6012b107c1d5824d041143f2b5a2367d8fa1c94d30677615752b5a22f4aa9092172161c663d6a39ac2b20bc0dced4d47a2aa0c6103c888e4c2fb315cbea462f56ed25fea393bd1c714c532b9da7bb7e3bf637828f0444de119fdf1a0cc1f9180cb1677501d2b8a50915d5fb01c2828cea7468ce80e07df700a43a845cce951d48a55e9672f756a8b8e702e25ccfaeb13f8b1ddb4736e76502df3afb2dcfc0e21a56d0272146b95a78858b032d3474991c0e750883226b10573486da8e6c18481378fd6e2c7c839a80fe19194ffeef1c91adf92c9ca7d6b82525063d8b2b281844d87150064fb6e7cf133d53049aaa15aeef65adb1ea5b42b96ef88be0f1a69dfa70b7e4b9ade3206c259b9c0a09ad725e80dd4bfd4ce53ca347b95487337134e8c0bb0c6c2156859c32ff8d939ae2c86c6ab47fc73edcab59b60c4524771916bc5b3c3e8b69d816fe433459132dad4077bcf246f25d3fc58ccedec808003c73e60030968b1f72040a00f7b0efe9ef7a2679b84cf2d638de189a8b059ae17b2ea83d496d1b9db83090832b58158e1bab989ee1b4a3ea0dab674c953f8ee772135618b6f4181e0208ddd920d03a8a70059ed08485d41d8a15680ad0778f79bb9d5e13f4a8f886f6be93b5e233565c9ffe2462913fa3677d8ab2c348c1b44011ca2b769a4648b8fd65060df95d4deb08305c76156108ebb47c2b9e0824bdc9ba9c53408e7ae8d6f893cc3fe15ac97cdabb104864dd38b46a3765615d675e55be7affce770eb11fed73bf703944d453933e216e16fbcf8911acc2550d46898b0c427f25f96df5ed8600a74ddc234cc9712fde38f39cb87ebda98477cea4fdbb9457c748f35e9fc39433e48ad44001fcb5f8e55d72958243a1f18520e090816a44b25014c6e34e5e1b1b192182f2a9d8e0d76187a57449c53fbe8abc080bc383608ea4547170a879c1ba92f5033d113d241c821e8dd49bd3b95ef5af1f52b532290c02c06081aff7c24fa07218064b093d7444095dfb1647febea753088e12439e0dfb8368bc4890ed1e209991532f83a88ccdd3e12b49b4694699ee33241b15a9168e2f7d56e3077d918e387babdffc289ad7f9cefc4013bfbe0e7dafad7d9fa532c5442b22c5178587d83df171a98d87240cf4fe7c2b13f6cc3b5146ac17b0276b39b3ac0c76eab454a1e8005eebbf66d22fa4b01c35d76b1e51643596c329a94326eff3551880cab5a94b5cf7add6b5b8f005af2449696be7dea382b5f3f76dd24711fe7c014fa415de1964bd39cedc5df818be45f95f997e24bd76748cdea58708824da72245d717e36dbcbe3752f9f4bccc0bc930828b10ed74644dad87dafe2e5d36250b799b5dca3952fcf07720a2bd051cefca7718f20fac59dd0ca874ade17113d87ccb032d6eb90d9d30b6cf106a6687c690596c0657e3c1d91dfb72f30f040ddbeab89017773d4522fbd0d555a28997533a3ec763c934020940d2c56e40b23f5dbdbbd0d6d1d702f9e389d31d091660077c458a5ae521ed228bfc7299242544f72de236fb01b29669e5470cff12f11b74eecc5784898cc6a03ac8ef45d34efc43be202230935d69a6b66be3f076a4ae5eb436ef8cb887d5a92a7bbf7bf05ea61d49ec2380fb872148ab4e1a36057b3561d268026c992e32df9bee508adc998591e7d9890594585d1fac77900a9628b73119518994a3bb85cbbd3ffd719dad64a98b1449d645c9666364bebd40e26635cc31867fc0aafa8478190d5994e4f1884fb726c8dc27373868098b3aad2655299bdb7d1b1443104a6a29811720ec05c24501a4355f4d2bae3dbd32912c2563957e0eb72d5f4f1c81b7371aeaf5ec37638885e23b89da79ec594d8835bf2f5cb4a8bb9fe991161f17f14a8d23c005df1116a176b31462553b21f700f910d8af49d3a19c1d244fa7d8932ab24447a9383001f57e54e4bd40ec7d14d6662f7810c1b2560959b1d409406c12caa14692099deb644b886769e0f55dbab4182d7ce900b4209ed45e4e11bc8fa576322bd953305407b6257da987722b2686dea42449692e6252c91cc9d3edfc2a9cb2fb0c5f4d23eb22753c8503a8a05146480f3bfb40d5b724e6c075965b9296235daaea666d1acc350966b6c35a18f8713db5d2a06a191d59d972d7a2accd5e4dfb462164e0855040ea376b9569378e2d4655ce452bad396c56f195451286e3f50ccf4cffbb8d19c09a67d7d61d570402791a0bb7bb35f318d65c77552bdae14a5efe87e18faaf374e3f7c9ebe4bec1401911f5ca685f8805aeee21943427cb387055507b85916bf91fa3a06aa209bbdec4f2d9b29364ef12b3afa805a27e3a307c7090f5d9d60c666f643915869dde4a9d3a56e76e05631ea4b565a00ac3bd4eba9b28d99289b4de8b34ee7a5aed235bb641ab190738872e1559507daee317ccf82f9c855d86043fc4a14d4d8dbe52e4c044e6c670f42c0bd95e59692e43baf48b1b1bf7cbd6a22bd32539554ad219d566f65c03eb016cb311d0a31b2ec80bcd2b97966091463f668d098c5db71ee1344b1b33344783b86d101fc388c8b19d57f0a6b43e06360199a25b58c8d0fe36b6239ea5b50857c5d602749341593dd13315973598be3540178be39bb257c9c0355636a6d1f22304cf2c4ea66655dac1d7f0a2805c0fe73af07fd6e68a6d299e01a11349b2fd6c13eaa1ab710ae2b77763a4cc9e3aa452b74751b2f4cbed248f57d6653538766490531c88f9336aff045a4007224dad1dda1bdb412c65b893db3ef411caa1a6f5170ace8b48888e491997c6af30ef428425f0fcd58ead5e252c738147d9ea5b79f5f817b8652fb47961fd56238ac9f7fba00410343ad00c68de56add92856e3f4d2d561e9dd5f8570678591c115c03faf0d9b830719f0d534552e15efc2abc17bc1bb2628e9dcdb7442dd4dccd4d3410ad948d8ab48c22c9805e9b78d57fdefc1fe312f7f01a57fd2217f47594f4929038218c563b897dcfaafb167fef1d153ec454638246c835524995041ef339e0ce23dbe4b9a39df733511c49efd3a0edad48803ea7e82d7fed7742b044e0e1541d4594b840451fc2eae7daae9b80f496742525b63361c268eeb1d16b71e89e4abae1a74baedcee36a121e55442d4de973bcdf0b2d1b16e43bd41b774a659bced9cb1917e39c37b92cfc7e0fea12d0c057f55866a7e673799e189cdac918788e88d2354f929f842a31bd307e19620583fe8b53a4974009a42469581f50ee39a70b568fa291e479103bb8ac0b8d43bf4b5c744a070e3b1082be7648cbad8b4445f8c543702e9d92946661af796b9a8e9c2c02eb24a80baaf0b8d0baa7c4682f51e8ff2c1f5088b906a6bad9ac3345109de1d139fcdcbf80051601c4c3c6107e727451a6aed51998427e3f039b2ed69c99c01532bfd6001da1a0355f750bf5181bacabd7d03389d754718da8432fb20e75d5cbe54bc5c794ca30fba8811986e44915fae1388f235d6747fda8e8610f7df6dfa47fdd806201b11fbd8a8cbf809619561df688e4032e6e210a026a03e22a1b937892aea721100ee9d5bf5fbe6b02568b10c150ffa5f15295feb268ef8f2f1578daa29d148336a443bb24d85cbdb503911181c6cd4b734984048ba5a0570316bd1c683c6e27b68551bbd25a36f4c77520af4362767b69fe3f3e580eff82eceacd0df1d6dc66b69d1136366a4c45bb1f3a3b2cc82c2810487b845699cc1df2dede728023bf033db487e331ae51990403f5c13af28ee7978fc11f6f56fc5f0ad968999e412b2525c1aa5b58da722c8e8824cb117fab727b831ce79b4f537e1514acfc820c0bdfa358a7f2ba860f9fa5c76cd7d56c8e869b68b9e3127a8dc4389433475a09078f9ebfc071742cddb79b29defd132bab19cf34f587c1aa2121ba78b87de600496bf0a1e7a8f278aae8418f5bc609e60140e45a4b3008f4ea637bbe41c0c55717542c356f003dca5094229da5d572e6ea2709cd61bee06919bb5948605d9b0c8a3cf8c0ed1931eb384077aa89b2e6837888521fc7caef6fbe8a79878b292033cc268e476bba736f482f8288489b6628c500cb2197d222d9adcb74a0f7e82292feb402368b103cf644d8b1e1be9574c0fdc02f56ac16631f79e435c6e5a4dcfee0273a8b3547089e6abf711b137263f8f5a5a602df2d8542d5d4cab6abc0ed5eb259ae6e1166f22b488e615e3c279e6c8faa434e11873c5408153d1181fd36bb715bce2015a5dd3bbe32e41ca5b963add8744c8d3b708c593f6912a058d9cce65994efffb7626916962766f899aeb3a70e93ba101e01ce68e77da39bdac6b456aca20f54f0437473bb67ca2f728fbc3e26805d1c1a92356d51ed769b259ee3f9e821a0be830c9d38adabc86137d8e5b7b842f9defe88fa2423b7148eb7e89b6581e3dc8af1838159cf804a096f9c6bfc8049d444b2d48c37e9db040530c0632cb9389f54c05b681e3539bb447799ebc3bec4789f4177bebe5410b70b3a66e10a17c3f08ba74aeb8a706dabe947f4cf1341ae767e0bd3547a1918cb42fd2b63ccca4fcca84cc82ad2825b8bd40b766bf9a4d2500572bc9058084b53b456470643d6cc14c418c6c0d2ee501a307ca299af6c54d8f86ac7471cdd77f6aea3d3b4e8926e31fda02d2873e6279421d836fe4d74244c140bd83bf6bf6249aa72e25a95e04c2e918e1adcedd2a3c8479614dbc5967a93943dabcc3a2f306ed9d9fc564009c1ef576ac5850bc25d798e138d05243a6a69f84d96cfd44e7c0f8c9c9d2d13dc29d09c50a936fe3b602609d3bc85076763e1b96d9f0681a82baf7c6c42b1a67e9d2c7bc886bc8e9f3224bab5b46986d1a6dbf9a23519b53cab5f6f3ab74d371678298c7b6c624829fedb2ab3ab974ec760d04c96fcc6e6daa2d9f664cbf22a7cd2e5dee4ab8ffaac664f03113ffe2253505fe5f52b9554e1a5d0088975a0d13fb8a012758c91b52113b196c822a6e16226535d59f6d085a52e0fce1f92bff34ab53bff870e03b6fce306a7d08e8068e2e37258e5b25aa79b6f4d901153df00c495e35802d3fb9063677ecb946d07c906c8c13569ca8459cf27e2b91e263d38412d71a2f698f05928ad0ba596b305e6c291e7a95ea5e062dae6c7753c3496ff5fa59a11bd6a1220a7a57a86d95dba1c63857bbe4026ca8171c33e9ab367d1905f474b150b513af177d8155365c907d75883ffcdf3c4f7f027ee459f56cff4020d20ac4efbaf94eaeea4d8043d464b00bdaa3d673c76355acf0e696d89b0d278b3560a74492c16b3631af0c805f86726e287b0f4c6d1e4d18df58fa4d4a9030197d0bc7b3e172210f69e33e084b2943a9fa80dc11ffe1f3a1b9f9148b575db3a2c8fa1825fb20c4efd3336dff46135aa415a81094fb09466cdc88d413c2fe41efcd351e6d0a7b3f38cc7782badfaf911faaebafb142ecef20a8c7d28687185049ed177798efa68c69aa58f68d878240a83c30f413e1ac3586bf4abb7f058cd5a1c0f35d645910c71d7757c7f9f4b8afbd2c95cb87d713d85586696dddd2d292ddb1a901ee985290caaae933e339a0a3ecd50eeac573a3adb9beeb1aa114f7176bfdfa4e57d32b4d7ec1d86c81728797c5e7ec35b35b711de140746a10dec1cd40af0b56ba3aa46df3c4b4a65c20a58d86c5f1c9d7a423311335c19ba9a0662a4fc25bd7d69bae34eefee6f058cf20b0382fe9f89fa3807d904911f6e266a3d43312e11d56cce57c06f5db1dd2fc17a01c5ddc32bd9b58c4aa2938e904a91ecae49073f475c72cdf0c296156a56ba9e5ba620957569e9874490f6fdd8c0ec929c260051f00b21081b7df9176f1f21079662f65c1a75c0938be7bd5dd29d52c2b172637e335f148515ff6c7dbad7b725d8aa79c8dff4b436bf26b2176cdd008bd62a249d15933d96b97443b348b631258d7fa075130d46adc35df8d1513cecb301ccf095a9981f2f77095b18bdc556e27d7735e92aa7893984532362165bb5dd3419d795bdad136e95cc26ca6f418ab61960a3470e6707e8aac0d92ef37a45bd727ef8a3d34dc5c11bed2af86e73a33817abc768163411b8a0fbfee12b57e1a8ecd98acc2ac130f698b087a738016b7b3280aeaaf857b5ab8ddeb02dd4727347456ebeded68e7d39c3e9bf4485658291060b05d527b3d445a96d0e4abace2ca4ecc318a4b64f3ee2a20b81473c7639251407b20817811030e5db9aa107026a274ed98c22240e0d5e5019409d5b762fa0cd2d8e7b8bd11a4d4d2ccd1730cbfd3c5b8e4bf99d2ce784901e7cec5707d2704e869df15ef19b5bd0127660772373c6477a9eb24ed4c91a22ec95750014dd9da74c608be3a89f5c01ec1ef323108f739ece6c2b63280d31904f672e6cd16c1f8a82784fedcad3124157469dfe65e49a5efd8b2d84828b64a5e7e83cec9daa613252f24f0a9125b67a3fa00443643834dd208999c0ddc462a544e2715a5b7303b39c23c94c7dbe1922554927eaca6b044f0c662247ac9a0d552bdfa95b9032fcd4a47fe1487837d6b10fea08856698d3a2b1bcde2ae1c66f660ec0e3de9912dedc55696b42873ed762670995bbc459f83cb81f40c1da58ae79c9bd4d4a35f16d109e3f609e99f6145c9832d0748c30e2e944c7e5de314d56d15f17527464b7f53165289825040374b4ba0e99423bf84df587c795de9ea67c2bb6af059eec5e6f6aeb08666ca878881a408f3aa0e1437206f3a86e1e1112efbc86e5769f14f4d57e76655dccb645c708b89a04bc369b2b129f3532b575222353f2ebc621eb0fb16faad44ce8bfa9ba79f18be1d8ce376b2e4160e42a8b28e81f445b6f015d44717ae6c40120983177039c668356db27c25d1edfd09136c1b3e077eb89052dd39d87d7fe3aeceb9ed7f7f84eead25bf4a6055b9081827c3eeba0ad9bd0054a1c26abeae2d0069ac76edbd4e3499f537ede7e1f0f845bfec24786eb0e888deb6a50852c77ffdf4af0ffe25583bce26ff6b3767421ca9aaaa650ffa49b0ce6a676c148689cfe713adbeb528ff024d26a1ea20e6739d441ae5b83441d5560573cb40b3d89642413d33ecc78b04a63d247dc008f1bc8fa50bd53ca05c4ad747450a50c8281fa0d54e6ae707300947d4dbfcfca2e4087ea4b302fd0546b496f9100d5b432cf95ba13a9c5f850afa9c243a6ee418e61a6a71cfd21f92aede28072ddef70351708255d7c06e05a47a66d87b264821dff7dda2f82a93361dfa6d15fde2d208684f25f464d82ead10e0c9033bf5f1665a3502f817fd71bf25fea23b7775ad5fa06ce2a16962b6acc6f63c84f902aa584c7685d34b472af53d1e6d8a6bfe1539926b8735c0a3ae2d1974e93c1a36de1734a75768234a1a0484d5dad87ea2a2175d1d40ae29c910e054602fd719fe581102b2d7cb33741c98e8ebdac732ce7d86f710b1d1059a0468f87fd2d4d34465112811818bea573fa4cdec47c3983c8a27e9c29fb2aced8985b83a2f7cbaca173a6f71e74d87da4392cab734ab16d49c9c7693f6a3f46457323b49a2e196912ee3a66dad4f7d949c0b8ea1bb2c33311a16bafcf0577419dfc0afe1a36e3e1b01b22039f91dd40e2f62a451c14bfb63d8021277a615381a8eccf08149fe036987ef9bbf978a732b3c9f9c377b542d869e51e8440b1e2ec2ad80493853f0d1241345745541262005ab753537b8e553cb10f5cdb7bff9ef22dc156dfcc369400d91a896a4e5e4e6dd4372850d0e505ea9aff5d5c2c65568d10b758478a7664c7fcf61bec2358efd31670124611e24d937cf705b45a1b566f7a4ee9351370a2009857fafd09540bb56ca691d5e6416bf2e8968dca659ca16a605a67ad7703537b76408a6da3e1eecf4510a613bc5c63413d64d0d8f91107c0d0cbb61b3c1e7ae4dd065aceac3b72f4e45bd8f5e0ffb96cb4d73351ff9720234870c426255542f6ba2572410d739a97c85560a269f03bb02a39be6a26ecb71372157b4872896b94506f8098321027110ffba3fd348dd43b3d908e7601932cedb024ea030dd4b9a7316a38473ec55ad9ec78cef36bbc658785e870af55b127b34c8446583931929a162c02d131fc733e7d50ae907096055e35bee1830b1ee7bb03364644d740beab30a6f74b4cbf3516bed93a31f25c778f5deab5abdcdc1cdf80ecda8d333e33d808f511b53e446f2c10caca5ff9a71b72452de9344f3b8986983eed8905470ea7978dc3f80cf4e2dbd9db2c88c8a17e1491686410ec534366972046ce4b00c915ad99b533c5c51eb223b4b64674d67b9bf1588f02ec487d9c50e2800cb9a647d3b9fd2aa5faf781f4fada625308b9c3f3292c0feaf340e9b9bb33861577d98c574deb5ff032034774cdd77a5124abd37bd87235bbfcc0e117fcb25848232f64692aa1b6a4c25b0af1917dd7bb3f36d8093f23f5cf95cf9eaa2be436be01a1a7b354082f3bb0c6b96fcbdf742231f474bd4da4725e5a"
|
|
+ }
|
|
+ },
|
|
+ "3" : {
|
|
+ "id" : "0x5fb56304084a625a9a0eac9686c07cf2f9aba446",
|
|
+ "keys" : {
|
|
+ "falcon-512" : "0x09ad2ebf1313260c40f22071ee1fbcb0e154d4bcc90b6cb9aa19cfc95fb5a2af7379950b4e4ab5651392d73d06a6ba2a192a670939c10ae85c84c024a4140d83b7c9b1a349dc586ac9f138d9d5f64624fa632d67d521e6a37ac14c987705702580d6031dc5f2d8c662cc27ec0b9a52afe650cea811dd9cab6190784875eb68582d434197c6386639ade78408fda7baa8cb2fd3916819c9d174e50000c9e89bcce89f20bd99f12085f76f4cceb96758f6352ae3019ac290037ecad880de3e0ce4a31bf6dcc402c0cdf7442360a9a4bcf947085cb452d431b0c2739c8833c6d04e595b6224954666630e5e2ceaac0a775c3953b71f4ee4ace262a394672799ae8347c0a05d3c24c6355898334e5195d13f4e652c824015d805e33f3675f76fca6bb701e2264cad3072aab446f5165c0ad81195cf4671708d27dbdd87027382ee43aeed3fa18da5e0d7a23514208e88502e9c986d0dd747893c7151fbf191a04d53b2964380a1fe8b751978341e3557d81502c48eb36d66390ab06743235922e08bcdf99f258e0abcac179bd10c2b718c736a849067fa069cbdac00d3bc9a7561e698dbe1ab73ab2e7ac0799816829940929e863169e82ea7dc87a96b29dcbb392e6f4aee0e41ea512849629ab126966561d4d0c149c14c3871136b8289d6626932f51629061a02c50a2c9bc8a27d9067f7d273012e1152e8e17246ee818227938482188d521ee99b582d3657a8c6a14c50e9c822271daf4eff480786ccb23ea785dac600b7c13c32ef983c6fb12635b80fab8ef85ff4d5ab5f3dde22f48d630f26edf680bb1677948ec09073960032252cf45b62bf5300327622de5a17c4e6617e27b6acea8262c74bd27936008943075138bc5d61ec03a3491939d6ed67ac21229ba550547f71d83399f38df6bfa0dac01be7507dbe62d9e76c7a7d54feb32ead736a2c4cb9eaefe8b6e26e55fea850b06aef59235de45f80e662edcd6dba6ed620d34f7c3b34a03a782fff46c216cafd9ead38f5d963e8061b08c6d9e2c7e70691915ea99dd96604f52605921e9718c0f637300ccb6be842f1c29ddf4fae72313f20a5bd09df65d2da0240f1a3828f6edeb9fef819d713fd35ee5116c7913912283ae53266548c483495481f59589cfc99158c189b358f26949b19a43cd676509ca47bf1b1e449c11c462dbf48ef4cbc5bcea219184bb428445b5b609973437de3ab0ba62ebdd6f6d888666f6c3d05a81dc1bc08b6f7516a1e7c9909a2a76148ef",
|
|
+ "slh-dsa-sha2-128s" : "0x6c2fba92712689037e0aca0290f246d7cc727407006ad3f95e5a5db8a588e588"
|
|
+ },
|
|
+ "pop" : {
|
|
+ "falcon-512" : "0x3941cade1e8a700729e8e4d2921d252e29be4751cf88e86b907014d431ad39c657fa2c225ab2a3bedab02ad104bfb2620460feb138382e399430a9a4154c857fc9556f2cc5c327fa337076b835849be7d995b02ea911cfbef5d304a64d2f3196edcc5a73e8e6ae42cdfda932e39fbeaec25122cbe141d9741841ddade5ca8e7f4bfc150bf14d27089af6b6f826d08d7af4c3e6504eb3c3505d1535d3cf1ec8c79d8da14941d0af8ee714f3342c6d932ad0b2f0ce26095845ddb346e63c3d9cc0be4d2392271447d3b82eea00fea617dd1ddbf582822cbf1475057d1d990f01d7c4e5889195cb139e19abdee4110f6f496c72d546aaf117d318bd2b4a843409829851a4aa132465b16797c530370fdf323bc8b053613e9854910bea56153ca3337d74bad05ebf7d53b713df374087e38df7cbd5835ea77fecbc79699cbe1b0627b75fefd3f361ebe7c0722a949d16601b22155ff7d88cfbd97c4e4d13a9dc8ff37731d55f91ae4bb4ddb955d6bf82c153a10853f579a9272ffee5cab24b22210d66dc18b275dcc9d975b66a16151851be1fbc4c270d4fcc2733474b18a617a8661ca10475317e16394a7d5be25954d2c6975323a65e66947c1eecdc63d91fe72ed82c4ec66bd37cb8a5c235a59435465c8db1ca377aac7ce5e50b1c61a890278fa561c66de008a4bb28f592227d78f56be909aef32f38d1d2bf96ed55f5d4d6b16db693629518f294db0ddb55db26e55508e3d51bfc9407032c362fcd22d3c249f0683231ee9836c9b377698aa205b51af64c44bb4fd6a5fb525b8c28914b1558524a62d474e775d20898ab5429b1e1a8511557850d2a753f94a48edd346d7588f820adecc1a56ed413146b2534df62cdad9740bdb5280a4dee87cb946aab5a691ea49a2ddb1c27a8a4a2166c2e7de74208",
|
|
+ "slh-dsa-sha2-128s" : "0x63b0d4503e4c4e47f749c70d9948bd57125954bb48808c43afac0d63c780645c80137eb8e8f5134b114dab9d3d49eea4cc4c9c8c2fd3e65c5b74d44eb0d472f86089bfd2c8a1f93c5d29b7e08dfaf423941f8740454bbfc4104bac6291e224eb9e91675b7ed462c00f5ca529eca2fcbd34a7390de68ba9add73dae1e3ce1e74d1b44cb0069fe44bc78414ee46870bb6c89d11822abc49a4ed48ae1440190ca327163abe185c358d0c9e9abefac9aadbdb41dcdddde5884b3dbbd12988563a38a38460746ab0ac6a8bf30283bdc7326408e1001e8a8d1a515dff4ab02d6ff88e29e01dead5417dc1e8a9fb4d28df43500517098db524ca91a950e6299285f092ab11f7ceb95a31d9881443087eb810583fca40ea9d13240c338724bbebb90ef6529b8e2bfe4cfa76dec66a04e1c48556aedb29cdde98f49a44954f2bac9ab36883444b65a0e3450bdc865ccf3125ad1967230b44ec0b113c8bcb09f15d419586819297923d481a572c45ec135cc1b4b8b6971e05009ef9ae2c2767bb26eea03e662b96b9d0d3cae91568a8535ee985ac01bf6e396de6ee0a3c45beda21232d7b13c1526b407032925aadd1f4d8760f9bc27c6fd4d06f4b274c038a295aa875b7811fc1fbf418126be578c7e27b920240a4ce667cbc80fd70255136d7bed9179277a64441dab4b177ff7b1413f4ee7edf0ad84be0c3af8b36e79d37814fc8be5f2282a99d86d29b187f3a6ac2821d19648e3c17a65dd5aa0b2c0f4ddbfb6eee18019097caebddb2ce666f65dff1b784cfc7b10f03eaef90306b95ae53bdfdbbd4ca78d5d21de82b420bbfe140e90c239e290daef389e5cfe3f993b365820dd2e2b72e147b136ebf3833be512416f211e2f513b72a63d9cb74029a708e0a65b9f9304b3f275818ba35dcc277d6304b37aaf102c9c3128e289f785e1b06b0fdddfbaa9911c9e486654c82694cfa35b23a2ccd4b0b9e1521e94207f237ea8c4ec3fdebc00652614eba4c55181e198e259ae22afbc28cada31969b00898c6dec40182a4a45d949f02ce475f7e5ae041570e802ff8566ad7144c6766f210ecac6e74c32c527a20b24b09d353da31081497fb7f4a24b4fb74d459ec9d5da1b08871885738b1d7a2cf0d9312e384b7bf5b768a03d792650b0c5017a1b0c7719152875eedf00a6f92d91e7b3af3231f166215023b4fe243567e1ffd8ec681d1323893b20847ce869c6daa489206261cb4728e63155fa1f71100ed3e54a0f2609479c51ca5e3e5e6fdea9bedf750f6a29dafb6123332654a924f0cacf639d4e23bfa173c2d8b70cb5db6398047de482155984c0fb549db89a73ac41fa70ad2e63838a0ef74b41ea29336a886708edc2dd9cd457ea291abbf00ade63826f49185a5d240169aaba772eb3f2860822dfb61a59ba391449c9e174582518f6116cb5f5e2b437ed35de95b95eb5a96bcec718b7d0b43e660cf7de0dbd0d9539e4bcedee8130f867970a2582c34b0eb08536a95a496d78b6527710cc60ce7534a2cb3e8aeb21ffdf5743cded32a60f15c8969f12769dccaf1927b88b1529bfc6d8b64807097057bd987e871c2ab78e3fe721b54bae93a4eec52fcd9530926e3e69f52075a73a085d41df91662adc0e37de52a8acc3037e23ba7b51ed6646852b02a0c424bbdf67b7199bc3ee4233af5be5daed08468feaf8553fa41ebfb0a553b2cfc2b2ee16f887f7d6a1e9564b877e1b9bb6aa82ca4629d16d6565e758ca53153cc4bbd474f9e770556e81e2bbeb3b621271193a2ac3bc477a9d1122de73264b6865918218a0f7bc568a7eb5d779abff5f76ce2241a3e7f51ebc1f2614ea07cbd470a0a9989c7938ca89715773bed09165b5598cff794bb3a14ca91aed942cc5d9acc5dc71105a71bddc752667872a0229382463a37b4dfdc71d3a536962ac77966d7884ddc654b52cb75b415a468c1e18661f9ee11309fe639f9e2426909ee9d64e3d6d221faac5da1a2fddd4730a0c19e7cbb4857723dd694769861af2d6f0934fafef0afb95d234e81692a72914c3ece5dd58d06b277bc683633dfe0afa29436d395f32f9b1c4528e9909779eb5f2aa990d765d8cd0613ffa4e8967433984e40cad9edff1c3da739060ca73c1f122ee50d172899b8cd01629e0b602e874f2549ab9284ce6544ae481fc8b4cc1be07a64a5cab2777f618afaa062aafb54b0ffbb10db94a26ec6adf6db40fe014d582e9c995588f42bf91c44dc57710aee85ad5f2a22af3dc5d8246c0e5706209efc9adafc5fa03b7ed3dec2666f1a9ecf7311734252d28ab7f44a9dadc61669c796af176d36dc3048bf205693f79b75d9446ae34e8e84e76ac4fdedf1c021a6d658fa5cfd9b2b3750f3aa28a1cade4178539ecdc736a04aad70e47ae3033ae3527c24ad0c10df1383510e49b7c99a234fe803626e5c827ed781db90e76cc9b6abd86eea854376472faeced185698d020bd5a45c82b14e5667775c471cac8f12575a78bc995ccf42d9f707e2c959e9987f1e84c8396e73a96a7c25c6b76391fa40b1e8cb77c68e2497b6a02f49e520d782d9a79c2e6220c617a4497369f5e213d9790f3cf12b40e5cbb8256f1077d780346a3cda5bf63b398ba55d4ba2893c08299935cd07d20c902c6d219a15179501001decbf85aaf303efb4f909e1445467f7e8615e9110460499f570577b2f4e540bcea3d5ad52b7b08149bb127d03d8b70924da51fd0a684334f3087cba976d8e73f2b62f476363b41db7541402a163fc72941dded23a969e5ad7b3be45fd5cb7e36ee7fd3a5c0c28f2369d445f2ffe725b1dfd247556fa38cc2501b88fbd9a38a2daf6630ba594e3efa951d31f309080fc7f8376f019b4a43aa278738b0fbcedd088769780b90a18bc7605fa7e0f8fc11a0b2a39953bd4c017810f97b721ad290858ea304d1c4a5b7bb18ad995368b50794251fc7a4c76efa8124e12c9d0e6f2fe6bdc9bb4f06c98cc58c103d73bbad7aa35e3f6b3f99bb651534c04ec184e1d4f697a55aeb9c43bb90cc42d08783b44f9fc4a3234376741fbceb988ffda3eb9588bf2ae1e4ab9a7de26ce9626e7f2bc873718f659b67e9237ede2fd5d5f6716ea0dc9251cb430b59cfc7df3315a09afece4f42cbc53ae7768dfc0a29ed14b8077cf45cb18188ecec9f90d6f66bf1814fb26b1cfcd0301a3bad5ce99bc9e8c296cc6dc721cbcecd32d6f9240aee0750ec02620be5b5416c2777983b77a9855fdf3461b930c30ba4a1f50dfa5e62fa4310c003278380e5e7f328de154771101587af515b5d1cb908f548f1dcbc9dec702f25f21555cbab0df1d0a5de4613b4a8ac6c2f576b92932ab3bb0e02d0c4c4b215aba46c41bec3f3b830152e48797bc831655f6c5d8905f55d68602eeefc1513ac190c7a5ba41e95b7706d1de73fe965a8ed25d6f9438737a6321c043e2550cc39514fd6c44047ed414cb3b969f963847a2f3e364da6cd82fdb602391ed8c6cebdf23c43360c7c03fe8aa638a07487dcbef52d62598838a2d01d26ba61466216e32f9766459d27f42167641a41745a77e506b5850ba3a298792721de3b2e2d3b77cdfa3451a833028755c8a346d2ebb5d28a166fbd17516055cec0fa48c9a2b8c9a9c0ee00e8aed9014ad5acafb4318fac07f2b01d84d697c3e3d9d47ce31f836f4a706da2b32db8b611d02b3b3fbdb76256ab304e71c911210a37b0ff0356c0d23a64eb71f5615fea903fc3db488cfbe24483c72b3f6e66f3a10b0fcdaf9f7c2f1b624b4b8d94346cdf356ac0ed1e69378b0075c4f6fc2e5f79be9d3b6bc9e3c9c94373dfe9d1a3f7faeda23f8fb4df3550dd7dc63341665267777c33b795e2f6ce27939f0b77e1d4c4aa854c602c668c64f13c659d8cfa2f7380f1e16e679f7ea641d6ae9162adcbd117e2e728d6a468647d3c9c2f52e3e0be4b587d55f89a785784071c9646891084c0d68004f647b46e281502bec9998e4f254eec2afa011fb06759297913eb2c00f96d55a3f5feeaae3e12751c36b76ba3793a150f1b5748fbda316a15b57c5902bee51439695b0d5b1b162533366adb7dde911a125e63aaf59b11755fe7077d4e17945810fbaf92336d553290173325d18fa03bd170e1764910e0b4222d45eaf93c38a38fe053f71a826749173568812bfcb37f6b3074bec2b38a34d6ef0de6a80b019bef18a04ba8056e21d94cf808d7a190146f5daacd355d9af26f5bd71e91461b57641e50629f528254acb96ae075a0572c85ba14507cca09319a08f94f7afe5fe5c6f89a52a37477fefc9bca0f5496814609ed920e8daeb096a9d7a9655979459bb2a72cd46024430f7636edcae93be87463a465ea92c8d9d96eb5998bf5751ad2eaa324b4c1bc5c732d9f395afa9920e0f99ffbf9e798a5bdf8f151212730f66df14052ac1e68a2b285ec22d9fe72051828eff7afff7bcfa00f3048bb769b08b205ac54dac9b330098a61a96ef78792dc5601af594e03469c8e0c7f3a32602860d108fcb1f1d44d6d0386525016dc8cfabdabb126f9e5ec85f2a6fb602c88e9c7139f4256d6c644b78ab8f1863978dfcc7965e3aea98cd79a82811b0d95c4605de03c7984dcfe7f900817c050a5300df053ce7c32c5688bc4abad72f16b4b12500c90c2df37849dc0745866ce5458d7358e24968c93da2aea2485ff256f260d467e7d3d1fc217a7e3361a31ce3625071c79c6b0944585bd4123054315629deab241fdd7a738baf8b1ddcf92f688ad33445c25eea9e3b51e549485ece83314e943be9941882dd044667505fccd894a000b8b77797d89c19ea9f8e768e9b3ff4aa8e3edb5132f852138a2f2ab52c13069a2486f9aeac7dc1386fa1e0b9a77209a1440416f50f81832402b7806e7b4c894cc4cbbdbdc8e363825c8a07ee31a0c4d6059c5aaacbff86f69765d8854f6368e80d0eeb4c48c44d3cf03d5600a2e862e2816ac4082911ad5e8dcac5e4b4e403ecfae8701ab49ab9278bc519a52318afd6f5d80d996a6d158f38a3034c5371d6a04102b9d597eca7dbfec88fc441e51c36ed4ce4dc2bde9c3874a9eba2f2d9911ca21c87188b8cd27859f137b5709b88a777ece903f27163cbf0195aaa64b832b1ccad1a3e72d988e1a29d0b39111b7becae267039bfea637ed4377500f18e7e4390fec7d452414f1b486b149fcdeb8bfb0d4486d58e10b05199be1e9161d275debbc93b135f05b3c4f1c3007f49f410244c17cf63d8f3b7b9e7328762800e78c6fbdb95153515cc495aedb75f4191a4fbdfc524bafbf619058840542d72984a284237f669b1754ceec72cfac60bf723ac048035d22a59c156f69c8acab63a58e68674107e7e1d54db9b027f867349141dc78bcbc688100843f4123eff0574d561fcaba39e5f2d4deb87cdca7c2efa558bda9b773eefc629487b7dc51277d8743aa07bedffa3e18bc1354260ac11c41d5ba2de2de572531971530641fde0e607de834dda6ad6d6a3ec0ca9824263405b27917f6ac26eb4c6db9775a51c389b37218bcee588d731e3de3d8e93c61adf3df2ca58d7654180ad7924ae4abaf9192daf10b087088d8ed8be4d4327a79cc8bfeadf4a3a941496eba29741669eb57484679fc18c3a2db8824b6e6a79149fa1fea732504fa4a1ffa95f230eba72024cf7d7263e7221bb6768ee5a8c1ab0987a5640a48d409629f9a296415d6279239a4b881176855f1fa12d9ebeb2ed5fc59fb8359767db5e1ba313124a3af73bfca08ac0fcf6d9015518a5721f4e5eb3fd59eef819116b49d10df4ed0f5857e255f2b971eef42ef78dd659e8c02c1e0f6eb591e8a8438bbc36bd0c19ddb456029b88043e556f5690e66baad58c7a7806d32a60e76265e01cda8ee0da24d074133ba6ed85635c42aca89580538b2805275e46a950ab3cb6f3098964650768ff4180024d91b4158ff8f0f1f49a0c86028d9a7cf9efa5498e285caa3b005a36b6b234bf48da02b65d11dbd276285ea7937dc8a1c49407925e0471a69f397e2faa79e6d260c349da49f9f2d7e448f3f14b638eacfabb66b8af36f08ac5d06cac255635a4f1ad955500de2da27872f8d10b2ff0fd790f2ac4c3c426df02588be21a14fb3928fef061f2a4fbfdcfb43cc6abb521397b9167e2cfb2df9c23944abeebe4e352d8a1cb7aec5e9d814be9297c28e5f7d5301836dc449109c03d4499e5f83712f5fe2f6dd9303ff96e7f641a009e4bb19fbeaa44a7eb9fb7c21e1b9b583433cb152677a5afa7959b98ba58bdc06967b19d2bc09bd512493dabd6b9f8680dba255d48acd0bf0c07296f346abe38114a1da25675ef9779745c318f64c1086a2d168d900ee6344bb34fac891d6a01ef12643201609619f9a2afd67b3cb62aadfc1cc7c84c7a599c33e72023352e0ac922bf9ef9d847b7103df0aaff9854f8b09e42239eff1b876a04d11a584a17313eb89752720bccaba87fbf81b2cef0f9ce0ec0d46dd282cd33672b93753a6d4a87a4e2af92c0cb6e86b485d2f09b4d99ca0d0c63d3a186481a75138f8b708bf2a5fd8e6ed1b27edd39b68cfac45467fa1ec7398d614a77885a9a45fe63b5baa1285dba83e7d1fc47299cc567354685bd586074ce45fdf1e97e16a22a4b9e08c836c9827ae68a1c305286db3270a8f266f2cf017ee9c02503aead42722f8419998f40b15505bb46c47f9a56ede76d1e635221db22828bc4a569792f51ab52d6db4dbb911888f4c2339cf9891c34064311a55aa11dcbe5f75cda6709d950a4b4baa597c46b92fd4ca87f6991ed4e81b68b98dd0a2ba48fd1bffa6258585461a38dd823600e8c032c1cb73d4bab0fdd97d4e6c74f23adf6469ed154eef163fa5ee076675ecec64aabc270e670e8fbe0c2d5e93bde59e605689a720ce4c54922280555915387e27f11ec5e55007a3955d5b102ef4d4d662363b556ec03a9f4dd1ccda925df3fb8966523dd077b483b7107331be8c880dde4906102676a9557f7a2b493cad44303f6ec74d5f5b77a5e05a4c9415475b69b1ec7caeedcc2c759bb23b1deaecca49e420981b68659fd45fc5f80ad914afa22e1b1902da37530529a6178e156357035b7271448330cfb450f8214f04f64749514d77bc8f8ab5fc467285e1d0e2188a0d6259f33329a5f11bda75c7f033dcbdf2587a2a12fa4a96123e0471982be76c884d6276fbd0c787e0014e97e756b34e14b360419c110a7baa0431a6d571620e2543d22bc91b2a25f626684714d044ee6b06958c5cd006ff1af45d5335b846076e9b815d90261fa7433c9a0c87d51319e36b2f303377b4ae0ff7355b6f420f85af1b8e67c1826e214e2a0457e78a47c8f3c3a6430de263c45874d07cc54c9ba1af179bf354fc5397b577936d4efc7f88f2b0d1375a7e2e2026ac50a955fa0ac20eb59f93fe5eb3ec8f02ad8ce28395d6a9aab30932774d03bef1da9de62b33ceddb42e1d61f27630d5a21580eadbaa0a90625b8f7e4ed371c615db19efd71aa6904ed2e1ddb713065266388d1e4fcf992f48ec98ec4186dcb236f434a3adb6556f60b33f5e65e8d3e09540003e21c716e07a6bce041110cb7864493cd950b1f3f2b3c3219790d2582d63f8fa3d0d4d9b02e24b221a62bc68d465ce2a82e4fbf8765172036990a6c62337ce5202c0da0b8c3ea559efaf4c57891fd82df6815b8b3e6c2215d29b868fb80342acf657e7447bac074ac1a0eb103d833a3399188dab2eb3b80cc569589092ac7225c1a4d3871f061cbfd59ae56f91d00d1c334fadcc1b503d2245c088ec803d2bbb3e144c40317bfeefe619671e076b988796d9cc11af12dca3b382a31b4837018457bdd72e436358b75990835739bf30e3d0436b7d86db54141618586545afdec01b7d13bf47ef72d88211e20cb5e8729909a1406cb0e81271237096feb1bd257d1ac73e04088da28f5002a00532d03ccd77fc10fca257b06c73da5064d557055d6a2eb570c4519bc780048d7b06839c95961da61b898fd731f8779f32000c507e25be161627cf8687d65b4bac160393a9bb5ac24c4ed2c51adb2acda6238025cef342d2f36cf1970f7c32ee070462e70d1b363b14aae8cc6b9e0e3bfd180e711d6a86d322249608b4e4c5cfa376e5b76cc32c7365e3468ec0e34cdd8ce85c557cb09ca2295662cc926c609bae9ef0a814e8e92fdebf490881c70c1225f3c96bc946a69371c6819717a42ffa0f5e16fbc9339066a8db604a9174fffd120b0b27d03f34c122b9b4cbf0184625183bf734c5caed905c1a739377700c66f43b0170d8e7947cc3aeae531695311b5851b622a264a681ef8432246a9e569f1920b6c4b1872f3fdcd5ff20cff2dcc6fbcede2dd68fc546e7ac8a882d092a8b87b0660ad4859e64bba3b8f7212ca841aae163b3adb6efa347639852b3d1c08541df7c51ed92ad1cfe1caa5f34fd8bdc336e23ca0a5d5b4a50e848bdc9d0471928b84723694459dbbe8322b952176ecec7d4ade8950cb3c4a94f07d686975c6b7fe202f173b0dc610ffbf1c8ae9d4cc68d4d7b2bec7aa3e015e6ef270ab8fa397f4674cef002caf96555d4dee0ad1b034a53cf6cc1af398774932752d501bfde60eaa9db9d162d8192a33d9aeaae63ff61c5b99ba788bc53713913b1b668b77786e7a5f05e2836ee47c3e6cb797a1d5e136435eb3cb211872b7268e71991544f7ee8dffbb0f001f3d7ffd13710a229a21d0d5e64c1f41cf53f8b5bd47fd0b766bab5ac75127a2b1f4c8797f559c78d90d43b530dcb5299ffabb518e2cb7b568fa7f5bce4dbeed98e4458ce66e38aed41353585a7fa72acb915aeed6abc46475a0ae4b6db3d0f95031d2870fe9d5f6e24d76b1de1cbba433737be607539168136456afafefdc30a500957d13f14e4a616894a6ec851e8286e75b904ba078fa2789b5e5350b5562e591387d295b39f77ef9bde975340956739f1e7f426ebdb6d0696bbe9edcbc527b80395c41bc06a7f09e6e7326d1af538894c4771acee2084f980af6d53d9c466443b65c16ed7c8e691734d4eae478001bcc8ddc6f665a09ab01049e7d14dbacf19729754d8830414c7a19f09ff32b556720b58da07ecaa84a263721fe77511b0b1318deea238c134900af0fa57b00924ac2506203bd8290e5d25e3d43a719bb7c011eceecbc4c141b278ae7b748295878de87b91f486b8aeadc1e9abbd6c5b5187087e51d252dc02f097a8700c677dabcd6d603d68b6e7f15f2da16c63dd6dca80ca6f9d21f20edb921f55f6b7f12a73855dd599480726ea454af9943ed7f636acdcf23743a5460ea1092069114871ae5be8a7082b04d44eedacadd18c530e032edc6ec1ec4f46d39018f55d8e0005e040ca18c7ce5447c5f75a315c22885e76c645f7ff59ffcebbcfe818f112fd224765f65291ded353101b2ff802b4629ffb740f0e1dc80acc628cda604ca9270a92f284eca843e2b2ca1f30c5c57defc3206f1ff1c2b665680efb0ee8bc84c9ba49d1c147bce32837697f1908e9f5573327b8f9e87d330095717e788cdd60f33ba1d146376d888befd5ced8f909567aeea48718b82fb53e15ddb4a456af9cadd7d9e7ec475bf63fef74ea512e3df2dec8e1d533618b0ef9eafd18fa2d158ac87a3a99339dcc71dcc76d5a82b705fa6b0b25d4c33851d83e2fe5c887941692bfa641f333c827f103042e575f3c6707a7455db8b6540142a6ae660a4be3ca683eb512feff8fec2d40fc6e0fcd556556dd6786fa9b3c2652503c9a13734a0402d98e2b8f2dfcfc5b7bc1c5854cff1f4c0186fe8fef95691250f4a89871720499543eeeb2d7e7f97a46f7ffa65ad9ad9e6d7f8d393f5fde9df5d4c1c1f990c120fa36104c113dd80bb6df3ea96d497cd19c6ce07625fa2dac481e157ffda973d52ee0c2670b2232b42fa857f00fd6ba1a45625782707185872b6e67c78b726f29b1d78d6572dcc6155c0229795bc9caf4267929c8bf22784232020b519bd0589578ca1c8fd1b2a67dcbf1c494bcd3017bc3ed4da40bf5d9d2f5c4b30120231b1517a16d31d0922f65bd4229457ba7bb18365757455f74498662b5043a032652c49ccd00775a559b7ee0fb031082106749b33f5c194fec5d814dd6a7fc3fd06810973472b3c842b3a6db9b519cc58b80596a03880f40dcacee3f4d8ee0e5d423151b1febaa1d6f17797f2dc1ea460ee279664c627252fc4a1d1079410268ea312f0e108ec928a6e3ac103a918097aa0076817c2275dfce56b13f618e1607702a8eb11cb0520521d70ce7413ad4b9040ed2d82c9192760a3e438e94c1c1bae92042aedfeb97c2ad684a47609f183c466d69f1756233fe9b438f2720e41bc693bab236d18488d43af5e664491386543fc27025509c0517d1292a2cdd65f9a77a1fe6c676facbad48fa4493bcf45359269bccd6e012662a09218583de70e8d582a6cf8474bdf4d7ae31b9f22093ca1d5749e4f97d626e15cc1c6bc41a87eb0b7202a14285a4322c4fd86dbe27fec0c125eb5b061556e80e6f579c82b7f3561cfa6a693b6595635407ff49092172fcdb753f66274c1a1331c94c97c0b73c543cd00380b9c95bd5402bcdddd1791e04bf4730fe05fe3c311bfa6dc4d3222329ded92c12a85fbc26a7c7c68fa8fae46b4273b84f55d87d8957e326095684415cdd3fd00fc558a0479a470bc152c7a3b999a2a9d6da0c1d819f0f8dfab3afc2fb818ce01e4ab33ebac2d31f410a3b26092fe46414d04dbff09dea0e7e7e746674b6c60a538f14a30003973a323f613eb9e7cc944bbf34c3b364de6430a18bafd36c5e4f887d3f83c70216d05f979bfe8117d3395612f9eb42efee28023638d77d2cebd038ca8ea66b07a9847a101ce2017265cc6f828508c9118b97687a484e87c1514f172f111c41b31c131a846ef90e6dddedfa18b3cd522755c7962077046db69181b62cb09dc5fe4537a07a2873b6817cc5420e6d6d1ec905d9c3c86c86c190d03f0d6e085e3c477f2c025627c018547ecaa9ee6b1599373059a0eb4d6832c531ad025807c0b431ac8e659aae827fef076937d7c383532b88b2e972e72ae419d9f34d368c551038c3b5ad3bed531173002677cfad2befaf6a2f137822db294674edae26e5835f37"
|
|
+ },
|
|
+ "transport" : {
|
|
+ "secp256k1Address" : "0x04211fd71c1eae94f560e7e173399c91c15fd9b3"
|
|
+ },
|
|
+ "ecdsa" : {
|
|
+ "addr" : "0x04211fd71c1eae94f560e7e173399c91c15fd9b3",
|
|
+ "claim" : "0x790d81887948a118924f9cfde4fbd1d22adc053913e857955f655b88e05ea9eb22038162e3f7eb3117da0919a77fc1108650254098940969f585974082c9216d00"
|
|
+ }
|
|
+ },
|
|
+ "4" : {
|
|
+ "id" : "0xac23c7e741af9bcc42e82729e3abaa64c809ae57",
|
|
+ "keys" : {
|
|
+ "falcon-512" : "0x09ad185ff14b2fdc6a15b035c294d3a55e2da69cc17113553c587469f88ae5e7362843608d88fe34bd99486a3c492451536f82d084d2196649b0e69a60f60e3d7bc450909f2e926d8d362a94aa778b35baf0e14b8eb960e27b10ceb0403c60aa5610d6636921a06ececfa399dd5a2fa0edb66c36f5ae61af528d8b3ad78454a20ce0920bdbe45445cc1a6646e445c092951487b4949df9b8ddd68058c0a318420cb9203e95718e2fb76e60b816bfc7066336d4073099a2251a3b72548afc4eb9e98085da7a0bd4bd01c793e7406ad1d4a7d1667e26f872e012df95220809e2a01d0c40df86a50c527bd4e4f73220c16ee822845d4ccf0866abb515e1f65006522a5ad75b1bf643db51879c86e4af5013ef8c4b440b29c4639cadd1bbfb5596660886b0e30d5684121811e08694e20e5ea253a65c44246c4cab89cb16a42456d675e3ec5f8ee86a76adaf8aa4fc745a48aa826d05b9ef4dda1b0a7113d76860468084a6adc942755e4b17531b8f7d75038b96047f0a82e1e89926384630de8a7f2fc7a4ad3794b89b1123f5b590d9095c6a08d3aba855e26a25a7303e47f87a445025278ebda0cd95d6f70efe61709a561f95817116bcab6e4af068b2dcf98f64d358f458cb6e1e453308cbfa7a4ef83e6838e921d6d64ae009c0336aa694ca882542e8e2a7cac0bb4f48f6067c4894382533bf286a1b2e4d205a5c2faacd87564678c17062105b41749bf0920f883021dbf91c8f1ca876d9f05fa3efad6d6bba2380f88d6eeb249fe5188996cccbff928230f0d0c011171c184c188a88506b16099ae8142ce82b754fe0cc08456fe4cd946fcbd1b24dc389c1c024a6d0b2cbcd12ab4146722195a9af8890f8f8ad80384ce4d409b72ec2ab2a0394194e1708143bb9e929cc65040f042866fc0f48a60038c7559a757906760d7031195920fe41888c8660215a2bedb0640042c0aa618155c79b4be15c8ac22d80b9e64b41b140c702e9e10b9064dafd81b01a0d368a9e2346954840e2700962af2419a0b8eb51651044b5c3074968523d3095505b56b0aa99d15334668ae838c1e7cd5e6e9d8b802a46bde018d1a457bd1f81fb559682ac22b20edb5251084285d3ea919091035a1ad1b80ff5a5121af743e74552b454e4fe1c0d1c8e5a6276d2e7767437ab1d835a95647bc6710e201c5e6c1ab9a8aa09941de1970c56a5557aa66b10be1f3281348943bd1a5c5385b349fe547df1d84cefb0525e040b90810cad711be71ce468",
|
|
+ "slh-dsa-sha2-128s" : "0x2abb37ac3e01bf424e6eee2948dd1479f77e0eb20523e320e8cda908025a0ee4"
|
|
+ },
|
|
+ "pop" : {
|
|
+ "falcon-512" : "0x394a1cd77f56cd20666cefe824fc97a9a5873f556016b7c240ace70fcaddf4fe32eaa72461b3a9b2adf75793dc461575d9f4de5bdc55ccd2ed96e79ebba5e3f1e22c2612a661be4482f8d3e40efc1decb7348dd477969031720c4e88eb34ca93eb56ec27e90555eeaefd54ac32d0c7887429106418539f0b87e9b17484d664e9d46e79faf7b755f8bc6de96c41eba433ce8ad193eaa2fc398c3cc2b06ca92a45e610ed423aedb9f0ff03c9bca7612bfa9107d3649d681218dc28deeb43614d36a4db398be659a84992e3d64cf619891362fee11bcb4a8148455fc2adb6ee92aaad5164628c1164651eb40edf97dcd8f110a89c19ac84cb7813782e2312bf949cd3991ddcd9d9060db1bdc2cb338cd8a2b5a9cd63a2727f590d8257473614633a4957fe136f299ec335f65933abac6c64d23fa9f3d227cd836d4fe09654bac8c0e5d83341e084b12bec4241eb91f34f01518fcf939ed6d9826779775cb7ff1ae81001bf80624596c4fdf518b517a9814a1ea9de3389ea732ee844758cd6404dda2bd2efbb9844557aa42f5af677ded2472914340cf4ae2df4619b248eccbb2ca7b727298337b217973ec90eae4feceb181b425bf3ed4438ccfe4de45efb913d3b4a434949c858bbf9a946c0836f1ced47a570e6c2340cca5e819d08df5677abdeeedb6d4c8b429f60c8572d1174675f754d42e33c125d20a8c4f970f974bd821dfd04d1fb6138a53bc3fad7e368ecbd12712ebd3406fac1c6cea79df743b65009c46ba86bd1455ed183540fbe10e34151fcea5e8dcf3cfb76060ac359b8d206cd995dd9cfab8b16de6bd343149e665e26dc8bbc1c66e70c871b866542475aba2126975acc5414b547b7b339f4c9d486c7e3b39281c9421ed713d2c51e69124d918c4035a6390d9cf1da8a3631004c88",
|
|
+ "slh-dsa-sha2-128s" : "0x8b796a55758c9ca56484e22c2e0e8b4e9a9fda31a24ce5ca85889f47a0cbaa590562ef0f73a9b77e3a293c1f9ef45e242462f4fb4a329b8fd5650deb4990de9b4ce82aded98b691d0e36f1f78b1c4f52839afd301ed3b885e006ed074c2a71bb21eb3a07bed8e9dc5075ed668a3779c8722ad68988807ea06f96485c550a3e714d29700827e9a0f0a395e2281e3992f896060e7924ece183badf2864d825d3d621c45e4c6c7603ae5ebbe860758584f07781d3e039edf0308c4dd5e2651b72981c04995bd8946646dccc957d8815c41696bcba98f9240501577e1fbf843a01740846b3c26610c01891075f6c55425c24c7acc9c9f58f4ac3d8445d3b020ea1b8e685f419377e5cc33810078c4e81812f8e368a0d25ac84b64ddeada211b7a91e5103368ea4a41d8ee3c1827ddbd262515c552fc98404fffc6ca21269c0659a4528b925c24939461296ef43dd0a182b360781eef9bca17850edc394afce4bfc4313e2f22c4ae8a99a58515692e114466b3f986441b7bdc857e5b410133d5d44efdb8303f1274e5813fa2164279e378ccb4ebb84eb6b3b78106b7b4453b8b82b8b8181880ff1aa6c6fe3e292d65d79b40380b1b0b54a8ce8595d97365aaea509ba7f3398fc02221f2a800fa4a0f5f9ce083fee1dec5b408969e06d960c006ca0e02556be1d81ba677836a0785ed40fed7f001cde4474fbf7725177a55a68e8f0f83006b85c8661ca2eb9e5bb25c8e4aed9d1a64685fc02cd12af25febdf2cd6c3f8684845dfd7bd48d6df1461c61752fe32c73fd6be5fe025312ca829acc77f455a60a24ed12eb3819914c0da7f142f5c1ec74ecb20d3c04ebf99e67cb1803575b0801ac5fda467579dece5076d568f6d5c67363401c5c02f27d4fdfdd3d3dd9d9cb865824e4cd9a245ac31879c99f4370d653bc1f9dc57408856d951acd5bb6ec9f1df55a23b1702694187bcd21fc57ad7f44ca0159b521b30f1af60cce06583e9104ebd762171e036c7b698179f71b92df4bc46003dceeb8c60b17fb581d672c326f84b93158a254952128d5f170ab0bda82c930d01c5ec63f2fa5ef3c434c40936dc9294f9d7f049ebb2129931f55ceb4e7e6d7244b974cbb1cd3f7da038e8f70f171799176b2125725ff459e05dca5d60f3b0620b933ed39c1281d55adeef79a01ef6dafe201688cc6e6289440dbabc1964ffd9b37b9c375c95183088416ed49e0d26ba7e303ab5170f8e2656cf8f251db65c47bb910f63d4df0a96c7edadf332e102ac31c752887c753f71d91430ee01a7367cc6a70dc1cafde9891db8bd6d00fd289ec562b8c1be8e2dd6973df9f3fee2f977461ac18503205923bc835daccecfa8f150ad18dc1368e92ee72455255a3ac1e872a438cae6fe629501c07a0106b92738ff68847f21506ef886ec6a607a18adc4d95318d95e5f40867a78e1b733d4e2d4408246e0f3da7e577affc78e4e2e2f8f17528856ee8ed594012808f7d8311551850f7b2014a475484fbee4e1f58c85adb9f7199505de5b0960f869f7db4628f61c68ae5d2f082c0d91fea1617a1613f02dce33a1be180c08aef890385426495bd16c5202594817b02997a6a671716f7ff36300b0f2fb21e00f318c1abe0485f33fadae0470134370848b6eecd8e6d131ccf141d2ac4de235c6a42d286a4cb048142c8a21fa8c666b95f38034906474e4dddf8cb8482174ec8df465122faa6c790639e527bdc1acb36d749452c7f695f0615754c983badca890ea3ef3863fa0adc48b165bdd213d96c342a56a9b96d17ce7c90b9ab41a6bfb8ee763b96989a1c07d08545a6dba140243bb6fc5940e7a208248203eb4133cf66e9d26bb526d6feb0bb968a0ba472007edf3db76f37a8dc4740d53eaf3cb9bdb27ce0483283d905522dff8d47b16a090a96820fb4dab172cb5c07cc16af865ef70220db7c0fe3d3575b48cef14a8dbd55266f1b1c4f6cb6c165de75c3ae1fa45b86f219417c623219af7cfd4f9c7365450b44bf6643e096cb523d783f7fa1e577d3ec7b347e36b3c1233403eb1080ed8bc6c03731bf6683cb5481573b4e91549ba042304b60f1c8889af181422b89076f6c8ddd4a686309953be61732fbcfb25c58ad9859820089bbbd56dc10724d01b56120d50d566f3cc03e1c5de2c1113d4dba0a1abb0afdb6e0704ca07dd1d4fc02d2b9002bbd1ad46eb9d144c752318b98c1041dd79b01927263468209f972540bd835e7e673c0c57c3f8796ddcd4c6a783866b258451170d945c2ad988f442915c60807f023bc1e95fbc5ba5c19143aad4e7ef1bec4e44110759b7e8ec41cc417213df075a954e20244b1cdf56b41accbdc743203b1248abb38ab1139e5817e352f4fc181f5ded58b7bbf1729511eabc54178b605f5e4746a6ffe6f3bc263bd0de2958e41d39953aaf7e04c530501e271c4581f00e4971b6e22124eb1813b0697bbb700d5e15b005a99c7df3b95962450090b6c0de1ea8fccb8f1d0962bc7fd7c6bad5e3238e0b95adb0732e77e1d6a39581ce7e38ad6b1edb57071c176bdb43190a59605790c7d1de3b1293a801f9d3fd871d18afd4fd932512994afe4c3f70670854b736e3b0a365714aee0f1f569489e272a971fde3e836a05aefd88321fa8768469336e23fd08713b992649811e1c075ef4a47e0a599b5b28f52551097bcad00d00fd20ea6841820fff24416c9fa65c27613e6c8c34bab6c8fadf6286a73f7a9c1518177ff45769e2f58db82c5bb0b73ffeffdbfdba6b935918151fdbcd1da616ff935196eb384e1ea1b833fba20ec624ad2d994973054cd593c6fa6ac3d92d4b11fa9d4dc73c19f5e34c128e0aa570446c83c4b7598a2af516a9276fd3fa53b2e7af08eab9500ea7b86a9b363b4cf31f82d118017275208016f822a867fb00ab2d0e657a2609a8fb2fe14d84d668ab0e650f8041348865e06e02dd4ddb363cd05a7dc79cf79eb986428d6ca251c282df09a0e21e632e558375305316d1238bb02ccb74ac732749cf2e07a096b528127fa085e5eb182f26b99721269c3546f75ecafdc39c4e1ad07c568fd99667de6198b005f758e3675a7089d0efbe631ec9fdfb53b4cacdddf07758c601951791f3822760cf6da48dc4acbbe322d3384042ffaf4bdccf6b818cf5e8636a634e9d6b16876df5ff1fb9f062350489700d0b6ff67c5bafae64b06ee07ff8660fff4d53564fcefcd91638c0f02ae86018355febeb74e414eb090634422e7bda429f98bba46b0c1329310b76f33f8e33d0bbadea9b9ce8b080fe441e667c813ae87a4563f144480dc2113220aea01a5165dc56c9c80b3c99b3cb429a0bafcbec3ca0c0e030ed9e2110b62f15685a5be0236deda18fdde95cab06c50c3a927c3cddbb8bd11d26c3bdc4ecaba13b7d9ba87c621c5152b2ff8da903a5d61bb9fc9f402af74de66c84f3a19725ed6e91a81e7b05a9964f38b71678bb86e8a7b63d92646be7087ba993247c90e2faa16eb6ad4f082ce4e20fcec4dcbfdf72f149851f8e3efcc7a8c3196722cc4a1e811956147704bcf40c5fccb1a1c7a434aa82cd8f619773bab7cc6cf9d9f0a6136aabcb16ff78575c6cbca3589b9ffc8978f803d8af8d10b834a2e89968290ec35b62cfa43f2ff33b645df3413b6ceb4fa75eb8dde38a65ee0397c202e548461213ad5effdfd2d3933ac69872f27d7e8fb21b8a42d7a14a34f9a496cde486d2e09b7399e0ff027da2a98cfb6158d6dd7eefd4f6c2b1ce51395c71e5c8c987eec8b32b213aebb237d4152da84589c056b71c54f3ee01804c2f11c163794f89be61cea482f68214d7edc4a99d5f674195c2f1599e429b80bd3917ac8e7003d7c41978315a80f8e2ed9e44210a8c12f72e2afafb693503fff8d9d72a49e57de67b42803f2a4e94cdfe32f1d27c4b47a42ee3a0ba62d22d5d8bff952d6f8aadf7ddec2daf827ff502af66e5652f94e4851765f79a71a060dcb4490448f511cf7fb9000754332f67b9a7c92561f260cfbc160a445da6413320f1bd02d7a06485a25925b0e996681949412d3b04b5ad3eb8804b28c3d96a1d3ff5f5e59aec1e7c08af86d67dc12a5980d965e3ff8eb5236579940efa38e50edc11168fe76b51d16be0bb728c91aee3f2fff47f776e05b131b29882cbc41d6b82e5e21ecdb5e4734ad368a273d33504f69c36bc0da258f464c3bd73e4e9b00d0bc31c94b6a05166fb002b381132ffa63ae5c2b8e6d2d08f49fa6a98efbd3b0b1bdd40f5420a27065de432a876f9a44cf3b1235725227d10533dc2b9562b56689b03591a2b8991cf0c659415e823d301346acbbae0fe9dd47717e763256e98aa802e6b7bef696fe8fb88b841c76e22df7128794382b732d434b48a27453c287762645bf8ef040ad022451d0269349bb70c023dc6d854e516d3e5f097f412cccf53410408c08dada7802f8d1b03954d1e8faa2d0b11f3d114541a739283b43b54361330d3f91c4b13936199a63171d3cd6794a3bc69cfa5604f9c619eb168e169aac84c0732804a7fe657fc2d78c29e4319623eafc571598bac55c4997cdd4062d495b0f517ad0deef39d1b2ae2a38ad90603e41f801627a24a356e4cbb671c9fdd4c950ea664b0795447d948f20e4e0287fd4677e77deaca881496b1a3e9287c5cf963e7845f9a9c477d5fd93ad40bc07d92044ea0b01da9c99f429d45b376189f2def621c754513bead13d50c693c434b17d05cf3e8055a6466464e08545e9e6bae2ac2aeda4b89cefab0f07b4945279295bc7896bc4561ccfee0bae9023174811b30df96bafc36f289b2222386bf8a8667ca2d262ac9bb9dfd5541f49b3f9f138f5ec91e401692fe8154ffbef8d3ea0849ff8a0b4d89ba7e53554e749d0c56aa66ee67ccd0aa727ecb11313c1d21c94aaf4437eca11d12c78a43dec9b936e8be9d50044135b5e53b2fbb627d74b290418db2a9a3a1be8d2d734041ddc1ce847a58638094a7e396c725bc7dee19556bc87fd26f3e3d1e02a0e901b3e8931dc68a45a5242d250927403d368c3d5cc7a86fc8ee1462de2e3b5659f6c541bdb7bcf5b889daf7def2432d4caaa245c6313041d3eafd3880aa0571528cebf1977452e6d3fd85b61bfba25f5368b6894308836df1382078aec969db515f9e10a1a9c48e914de707f59926eea0d7c491d32c8bcae3eaae71409c5cca45c42d9276751678cf66871a48f9a28250945529367dcceab1e77d72064bbc6d77ab5fa9dfc1063b8094d0296c93829f5dfa4981a6f9a3fe4adbe2d99a18b733d82c5952bf235bff408ae263d366057bbae11bbdf3aed32d8f101d7c70fe94db0b4a8c3d07934cb8ebd6c96a25abda668f06996ab50cf695a4bf8dfb7d1ed92dbcc7a6b6b0230cf0c0b6c9910a7e7065029184c1e2724dc5415662c3f756410155f18a27c3f8cc302e6cc1cd1b2194faea68d55e1e5fcfa5ac8fbad66173670c2c70f9db9d4a505f167ee323285b5a562570d9e7241549754cab5231e1a87ea585132ed9e1ca472a3b3ec48b524d44fd12826bda6896569c53065f9016bf18b8d9b8937dac9a6e834732478bc62723875fb6109605a5e5079cdfbeb3b896a62e67978fe7be531d1bd41ced9152ec41961f6fab225021bcda83bff802a58083372cf597564820dd25b70130d9dc725e26a019a551ffcb0b607015082e475bdcd54da2ada52c3f730f8d6fe6d708675c68c664086627e0602eed80b20a85b32a26199957a5aee3978402e027bd06be418a58f094f187c9cb692d91847a3ccfb92cca33423a70a1c847a172fecb950d245d979434fae0e0de3dfde7207eedca86c7cf634af7a035c3db312f138cbbfe1e929ed433fd7ca8dd5422313e9a9a591b63aa938ddafaa528e6ffd84967a9c7ffa7f56b0718f0979dbffec035f10f69810c1f453aa1699787df913fa59852afdc22fb9ea5119088d9ace8edc94731aee61cf199a5b7a99ec30499d719ed320375472d810f289ad6063785d7a8daf3841ac6425830887cb8e8ff899a174b958c681f008682e9c577f548bce144accdc2539b7d7e339ddbe3d417e50903852479a91c5d8d4f1fe5478e34072b710260de3b6b8bff4b5591b1f659bb61690b51460c470b7b6703d8c60e694290029e5e0f3fe3837007ebbaa3d475fa8b7a44fc24f224723ccdb93089b04400ff23ceb5f95fa0b62d405480c9abf48fa95a7b93c527a924682147b957dae81400cb1f24456ee42d7595a2f95a93bdb0cd01274c755242077fe4e91b08549a0011166ed01838ffda86181bd2942927f90b922543ed20cc990eb295eb4ea7ad58d8f062cc0e252c7c49df368beaf75e772c67345465ded5abd128a7d14169bf3ba0ec7c073f0c2b64b44442236b53700568c87a19caad0afd533501825405140cbe443e8f1399f5767086da8d047a1b37c2038721eca505bb1e8088503ab9aad0e9133ac8a30c0dc2aab7c41b946349a696ca08448f31d770865d6cbffee6fee8b4db5043a332cf2b9a33bde1a6c057e05781b913101af24a328e16dc2dfeaa72d82282566772371a3bf87e4f7f757c20532b8f8afd79f09d7be5c47e72d2c9ae864ca7f51aa20090d6838ca1e49c1f1b109f2f9c0ef15caffea45bd07dc43af2765a3f15c5443a78441e336dfb2740d3bc6cd2246b0c0259736b8fe673eca3c71e31a728a99f2af73ed4230ec47ef893f44e6916ce0e0da6322996f8b9590f0be3f75d920f2943298089ff29d58a742b9c0e6978e3ff73aa7e38645e093c2ea0ae9a7d05dcbee4a95b20df85fc46a8a9106eb433ef1e3f51baf7762fa236d70029e5048e5c61ce63ec3d94478f50ede7a0b92ba02ca55635d8786a45999ad2d983bcb232c6ea2b9e16bce5738db7ab2bb527e8a9dfe7177aaef9e014b55727c9365ca81ccf8052c58993fbd0ddd80ffb8695fcbc601a4be3c5578d47cdb37e43a4e4bc5e99d84cd3c511d155917d9819986772fb78863c851970d6677adbcf17fc1479185723ede97a326a339b442fcd70e18cfeb157bab2800dd323ff9be15c1364a164d2b508b88bba4ea7a907083ba1c20ed31c894a40306655c97ad948523c54f9483f63c5377ad79ec49c32e443bfcc71de7a285645f72be66a50c34282df04ff7adc1d5a09aba25be3e10ebd85c1738001b9134db0911d8fb4e09f52208f2bcc8d09aaa326c3f36522019fe5bfbb4e03e838bbbef9e17870dd6cf7b2c7d7f4ad0fb08d283a46e62ff66350ffbdf1ed1f66d2b56c8cbf102bd17c64af899f1bc6bddcef055e9c461d2ddf998f1dfdc2a685e8976154b9fa985054161796556b096174a5ecba9aa7948685e82c49de24aff8acc50905437a30aaf07bc444853b0909546e8c7a7a6ce6760b625bc763738eb418bd84b79461a7ad28f3775ada273195d285d619b1c1c829b1bae38ab9213b7b9f7c5bf9176e008986e2dd5003ec6d5697a8e12b8b23c96d59c6c3bfb6f9f6058c3fbe86435ee2f235c0d0edd3d821784a99081470c5f567dbb961c3af693529a03b5624341d1d3ce1fb06c186aa88b720ad0c988cb08c99daafd6eddc2e3d9378004c1de7ea475fb733a2d4d09cef7139e0bbe211f28c06349ef5a55fdbd2dbb8181cf46b000d143b3e83007945c61142e71e61ee1d4309ad913dc6fce0c82794606cc8414293a5f28744967a1aa18c414d57d1d3339db72502ff4e11239c5901fbb7cdc118d896d5eb52bd6fceb195db17448d672c6453b854c29cfc1ec0ad0a281f78615beed3165f2f1f70b0eaae3297a4969893df3934453397c999deeeb3708a282926e7898ffea30773b83351ead39260332e4b9105206f8ff488e7de6c74df624342893d31492538594ee2c4c3dfd90f201a5502a3d742062702b56017f2094acb633361665306086709c9e0dbf660e4bafaa196349c184e0bed6409f5d103dd301b6ea5750312a48da80567c10168c28046ff16cb6fbefac5fa1d6d713fa721f257d5fc081376f4966e66987a1e8646b468276f23f4332d8f32eb1060ffe4bc57398a02daa82e19ecc59b1f6685e8b3ef16fb52037f6c5d40175861f16408d73788f3da86867e39197d7db9909d5f9eadd5e7801c1485d96c8bf9cdc6be770a4459acbdb3a1190366d9ae6f22d50d0466e82744f4a6707d900e2e243664fec66aaa5991e02a4d64ca90a411804ca2089109a2c036e0ef2c425e73daf3a1d7711bd15bbf9782f8c7cea62d9936b3e630ee88c6d3add299adb1eb98e1e8681c06c7000b5f9905a5042256e1f1e8d0cb460e69a55d07a974d61d34700dc2b58b79451b138c9ba2d5737b877b05ff0f3390fe411cf54cec15699e29067e2c1961870cff07675ce1d7a7cbd608f1a65023ea2eddc6565cd29362e4e45c91f55dbb768a382ae257d6b32a6c829982b8fdb3dfae5a4dd252d06a153fdf66c1b87f0fccebd582c49a5af4abbf17f6a6d561ca5c30feede4d5bba65584a295dde2a8e9522ec49757563c0ab1c31d06ee294df5e80f3f54c13c67b9f35ce66c4d53e251f39491e40dd971131c4a7c1c73cc80ee58d7b2605f75d8f89e209b4390500613ecc0479acdde2481213f3b2ef34798217dab48ff787d8d9e0ca7bdc0647932f1977ecb4e2996de2073acc133f63e9c2d490166267f21385c79fd36753e7815d7d6fccd4561dc78705f1c45fec1c9d7c5aae6485c19822d21628dc6ec02744407889734b97f6219c4964917cb1d74ff31d9a731adeee90e90f6fdc1150f2278f4b688b5a1a5894660c5fde3e6281be6debbd6492d357158b3f2cf0e000c674927c77d362d56bbb37bc57b4811ddbaf604ed2603b4df35c565f7e1f965718a5830f4c9b5cdee62d88e7c9c7734ea0415a723daa8499aec98bf1b6648ac2da9db52a9c4d77a721cb1914c0c0ede3829a6438e4073faef715ca302a1f7d714f6bca663b7722050a9b1350906a42653f43253f4d8b984b8f2343c327f3bba71fb1dce007f22de0fdceced72c3ae9e0fb58df5354b44709a77bfee960ad227d6a479b1217bcb65b13dda85f9fd02928732e64f3cfd06142bf3d75b86c3813d14463d282fa65a662fea847fb67e86bea2c40ce096c2ffac4ca949a0bc583366f630f548b3510308383d744538169aa953a09dd30ee300047b4b9cd3958c02e00fe1f40a1fa7e4416a723a125be5cd925d1c25a840a9a37c77dbbb92c033b4c8851d30df70e719acd233e76b9a7421ca987cc987b2cdba7ce61275637a108ebe5b25cb31ad2ad3f994f77a910a23670c3f93ddc94feb1e4f8a2099d3c6d0cfabd729aced59caff2f737e7adfc2df161af033d3ff824895816bd7513e3576d049eb85a6f5e2d3090b684eb7e8925b0a9f13c97297e986569b9243aed69807a0ca3529ae34c851817c5d647073e972df8a0c68ddb80ec8fd65614165070b9ba0f0814fb63726ddb1f5a4f2286aa6c72e3331b490bf1eed4dd13bd709859e8d31755b53c1ed50d13780835bb2ba638668998ea0a754490b84c019e1c600fb39d4e940abf7c60ef936b594579eaec6d25944190f1cdd089abe7285882e5ac12216ccedc35ea289fd83d47b3168fa38149e7cec13101eff7ac5451b963c340347c9c1036eef805b3697ae3a98dc46d1dfd9c701f425481129cddd1df129c03387098531d15af0fe8ee3229e7c80177b74c4ef2b8ccdb4652c4d8b5e3002d0633ace934d871cf4b98e2de54a2ff6c96f843a203a43b4e59b2890da4f43dbbea3c5281b5dc5d335fa0f3c0114185d3ee9947a108ee4d2b8883295c3de3a4826f88c9616f1559b6456ab14bcc4bd42d487517db196571022fc9e78961b04fe4ccac764c82326426d319ac4a892bf5e890f147d1abd54766504bfb9732f96a76d99d8edb2b3ab36b840bbef4cddecf0b715014e4e2d877c214c8d5393145c0808611eaef99f376cea6481aacaa0961a89ba45718d42906c79bd3a25b625b96242a0e8140588b6fcfda4271f49bab60394c9cd6b8d270af2632b4b0b6f7bdefa3136967cc1e6f3f519157db74c145dd74b7d30673d4214beb9a8e343958d846cf0c8a0a90927b3c727ed9cf1976cc65eb5bb3069c0431146e3daa7a1445a93895ef1fdaeb3f7642e4112c3d20eb597e1be5d3f2a6d10ca662d4e26832d64d4aa3c6378b6853e0f75771e4b809f65831f3157949e2f7d6179fcc2a1d96c4be53eefd8bcd2e90990fb275737f3dd6f5aea47c05b1391dfadf4e3c6995a08543d00c491e5b9796e6d0d89bcfba49315d988bd80223cf5daaae064374d14f6a0f5a1e6b4827a491370c0186d6b0a046af01a7c19ef40845e6382fc4143c5629876071a78efd40609296aa9c703cfcbc925dc4b700f7560b8aef8e837754267f375154ea70c4a55732d664e75ba1f5aae8ac2f570c969c195126288be5526e61fccb61150e680dd577d370bc0436e90728317234b09522dc49d875984978a859f8a59908dc1b9fd4584fc134ba6c7cffbc131284d9c9416e5c9d56e7010a7883c21482809f3b09ca89032bb295c7c8b79f93c49f93bf42cb9500ccb1d8892826456d8616bd33798f574859a20e0a2319c18ee8cf8110b5bfc08ab31e2def3033d5135d356b2dec0a28a29a4e0c4622812be06fa16bf8bfee085d519d219072292e728b2418c3467011d050ad9d2eddb9d95248234ce64a22b24cedcfd3a25545255449488899d31fc0f713c78aab4e544695bfc860eb2b1ad1908af3660e6d8d8ae8781c24960b55c4e6a018a2974d852081ce2b233ece50dd1677c8bdfd57697b65cd6a25d64eddf85733988ae1c14f50e2729e8f37891d7a66c78d698cc5d23c94062b4f79e7ef07f82bba31ea92a1f65b66665438afae26d55f3a31dbad3f47d8303f4a0755a494411fb66d9c1ff7077f8e26988cb4e5e228ee061661efb00ae1d42060c4766006457c4ccb0ba538f4b7e8d046f68a98f25fa808ac8063f0502d681ed746a4418b13b441c19bf5b55ec98da3360cfd052c5d074e3dc0adea4e2386f54e101d73edc42045b2d419388bd098ae8823c17450fdd5facdb3592c4fc7e4764acc621c9e665bcb3de0ae76ced84b8f82865288a23ce3e4ddb5d711ac0b868e38293d58b498e7fab7e7930b2a87cc6fbb29cb1"
|
|
+ },
|
|
+ "transport" : {
|
|
+ "secp256k1Address" : "0x47dac6434214ec9792effdac6f52062c2171fdfc"
|
|
+ },
|
|
+ "ecdsa" : {
|
|
+ "addr" : "0x47dac6434214ec9792effdac6f52062c2171fdfc",
|
|
+ "claim" : "0x1ac8964bd13e8d37663e58776ce24bf06dea99e482c722cd25e2e0cac9231f09464dcfb9f5bdb61d5ec77565a075dec9d862ede5ab90475df463d5d0c30d75a700"
|
|
+ }
|
|
+ },
|
|
+ "registryHash" : "0xb5847f46f5a6ce3eb9dc1dc0f0c48eefd98d835e7bd4b27398879807ac26a678"
|
|
+}
|
|
diff --git a/consensus/qbft/src/test/resources/aere-d412/ancore-2800-diferential.json b/consensus/qbft/src/test/resources/aere-d412/ancore-2800-diferential.json
|
|
new file mode 100644
|
|
index 0000000000..0c39ee7b4a
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/resources/aere-d412/ancore-2800-diferential.json
|
|
@@ -0,0 +1,3197 @@
|
|
+{
|
|
+ "descriere": "perechi [parinte, ancora] reale de pe 2800, tot corpusul local (D-470, diferentialul sub H_hdr)",
|
|
+ "surse": {
|
|
+ "aere-d412/blocuri-reale.json": "dc26a88501032040e78eb1108948c6b99fecd73511a5f5441cd15cb9caee40b1",
|
|
+ "fuzz-ancore/iesiri/2800-1/vectori.json": "f0560d679f7dc2ba60cbbaf19e1b4d1cc3f299d488332b45e72e665fb16d7028",
|
|
+ "fuzz-ancore/iesiri/2800v1-1/vectori.json": "985e9fe50243ce8dc6184c285eb935f0f912eddcb42be626ce62d944ca6ec239",
|
|
+ "fuzz-ancore/iesiri/2800v1-trunchiere/vectori.json": "9ea706fd64fde66c16ae7dbbe2911bd26e7cccdff03703823f811a812e716f46"
|
|
+ },
|
|
+ "vectori": [
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841f303a5463b2b2cdc75a041aee6d28f8a7ae9114b06ae0b46d48c2b9cdb46c38e1e659408bac78e4bb270d81a38bab8a721f791bdf891765941f7991139d6129d01b8410683376eb72cc91693697daac126ee557a5fb80fdee314d89fb8127b62b7eede21ce4a875211b4e03e3a8409eb52a03d2050ffd66fdb7bcfeba514a6c789b08c01b8415a5075d944272eaabb1804df696415c72b08777d409d388fcfacd7b7eee2a01d744abf575a55595c8398e6b586274eed55ed79100f027cd5f02ea36d777397d900b8419bfb310a07925c235365ca749de7a9fb61de74c51a0735f7f50954b3f8cbd46a3b2e52274c0af827d3f9afa4c3f535d88686356d7c6ba303a4de5a8a96f0625f01b841f377bc775ed6f3a5184a0f5277d4fa3310fb73066b6e92be8c686c30da98f728761d112d5bf142068c1c3d26fe95e6b2bf3e0ef4558ff4168992c4c1c27f522d00b8415f5bf85d2789f34461ed41aa8fb40738c3db9d1612acd2cd9e105e525c56fa532098f012f5370ff18ca2d6ecdbfd4c60c359e613936a5ccd4b7110e68816a77600",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x42a0ed78c50bd85c82fa8ce282c3444880700fbc430f268bc6c44335bb29b60f",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xf73bbbd26a82dbc769066550d8d4585eab2fc00d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xc7e3ef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xdbacd4b38a39b8f5f78a26876e016cecd06c4c2e774dc4d2323f5ad738c38b3d",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xf647d34c7d3bdfbda0c81f26aa265c21ef1f18a0a86ee42f616b48da952bc252",
|
|
+ "timestamp": "0x6a78be7d",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a3fa0d08818ab450c2848315bc0723052f187db5760284bd1a015e3582a287590710df8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b84129efc5839f0a831495936bb6395b8ad2d9bb14298ad70a8897f134a66a82d339792da63cdbc962f4fc769b69286368985686a116e971f9851eb2bbae441b9b9500b84131f0a705c21b27652cf26d900f402fb8e101a499be3a2eb2206e6f5fef69db2b7fd8aff388af071c16f9b75aa44ac7eda3b69b723d488f73c357a280a399902f00b8415d4faa7c506647337438953e3ef62944766d8c868ad34a70174a6847cc3798002c822ff7c7337f839141c74d1725acba4649de2942674cfd8dbfbd9c37c873c401b8410070d4ad972511aadaa7c399179fa1da1009c366faa8304f8b2ce642c3317238745a36d7dd3b357ebcae119f48c877e268241fbf7258353d357c594c52215cd501b841e0245e37ec860483a9740e0bd2ca5ec948e7e80730ad7268872fc05395bf1108585f50bac18b9f192a5b2c4ba68959efa0d7349fef3954b83ee13ea5cf6801fc01b8418bb40bce8075e0fcbdd7cf206461593317d4abe46dc7d4f7694a529b1fa7ed1e075a1a702af20aef52e79c408e04b5b999cd5103c68debe2854a01226e1d221101f907c5f9029480b90290398581a1615f175f22548f9ebad5bf422e7322644613168de101095f41af1968fc6b295654bc00892be7f4471cd746aa92be91a2ba52a84fa579bf418ac6fd8681649902d08bf395ec2ed5972aa6c1e099a6bac2d5bae8c0889e8c9cf2d93521833109f9d7cf38852679a9685015557c86606787fbb7128e9d6efaa866f505be6ba02b068757c9fd1292198d98ab4aab0dcda41ec8f1faa1c066d59fdc792aa81c3b9b4715c5cc730836d90b5124a6092192bbef63a4d9324303fd8532935b53090a310c72d37e265a2de372b2f8b6f4099a72b5c9effa242686a66436c91591b992c1249ad6224492c7911b756f39f4686d5804cf4d2038faae0f1d174cb00d22c1eb8c21a8728137338c8619a33f4e84b7508a9b55d77f3a4e674c76ee2558f3a25a6329a1ac2529f63911d45d2d3d4931ad201aa92e1b84b5590d0fe6114033256cc2a89934b20108e6c0f817c94cb2c48dbe2de881fe614d661d3ad0dbb9b84ed66a32fa3d3ed3fd2e7a1a5607231c78f28b918e69c699573fe875f957ee2fb9696152c626d2c63216935d8fc2df58d6dd6a3daa431d5f4852c6563e82214e3e050d81c5114854977c62a8b6f52e6f4733cda2108f6e18dc3b49141b44692cd4b5099f8640787b99a214c5cf76bc1d4f8187bbc8ed984f6711abddf2cc364333438f52d6637a9946354f89d244978e7758cde576d3e9bbfd298d6d33ad692e69e6868112d3d5522f27224a833d0f2261d56bed3e2ba35e91a6f98bd12f8deae873281dc3cb76645c7d2aff51586eb8671ee912168954b35aa0f59f59d727029deb4bce10dfb35688ed628f2c2c1adc2a0508eb6d71d73f3b6e9c24e9be3318400ca61134a052fbf877eb4798eeb9ed5aa323a69cc22ac230b86562a65fa97d77b7e0d1447ae898b6ed1967945150f9029204b9028e3970525fae8b6271668c0680737658ed9e9199788e4c29a46af53e188b7141e20fb2d870fa8f5c72f2c5cc58d634499926dbfc59888c5bd41bdee6869746aaff7b48a8287e7ce2010c562bbe1862c4dd7d6391d63658ab4e6a71faec337f132bae734ed3b78ebf45fab42765325c9147738cf7cf9424864a8ed32a8ede61034a77f42ead2f43656ad6d77718e07823a61ad18dd6f05ac365af774e8671b9f81866d65f1feae714c5b6ce495f7d34bea0bca9c90c27718654b0482f20efb8cd17fcdca4f1237d345c2dc45d928be3b466568dad72228711b34025c42d9aa3da484cba0f892a9a97bf4eb34d9bb6a767c9dd450cfb805f33165bc3c30bc50ce964c3667e301c3d27a335936d182a45c28e4113382a18f00e3fc342d5b0888a814baf40d835da9923858a2bbb91df76a59b221c9c6e5a232fa841accf5ffe47e2348e0745017b188d8c69e68443501ca1078246e5d9b25cd5d695bd84a7a5639b61253516e52522ba0c1a965529ffaffeaf8da0e7947741b7cd6fb7cc1f35d5c4a1cb74754625464715c4509bb207109bb5ae5c3f2abedae2fbacc3479ccccea26e6d53a1b1316d1aad8c86160c99f54b18e22b47802297c991dd63f46e7e09496c7484413e716d7f54630526c1f32d59e8f4e77559423d93b57acda0bf5ad04bf1d3773eb36a652f88c1c133e6508fc8ea11561740a7d0ea89560079901c72c0f9dd4a1cfb1447713b7f66fdb05d1d2743f2757266c77902eb3955adf307f44a4b922fe470a1684dab2ead9ac36cbddeebbbfa9c39f7b260ad46651467c8a1f6b1e113fa245f7a985ad66364aade12fafef4cbb42d2c39acef3d4bc2f8bcbf2d7f893c8fa819047dd03d7206afebd4f92d974ef74ee5b1fe595f6362872910ba9ebbad0d219b69c548996ff09aace4f9029605b902923975ae0e4473a1ae56b46dfa28090aca06bda9ccc3ee9a73043398e8acbda43b9d2db79f3e3c15a8ea22b73b327321cc823cf97c94f2815a75d2b4572daced4b50f6d66f8a8f60f705a336d4f5aecf3b38471c3769c6205dc228f02672d4914e7f642e211e9a55142d5d74873fba751b309995f76cdcb5753a7aba7a21ad147a2ec29557d618f4ba0c4458a1e7e2d60d47c7008d96270b1ee47316ea848dae48e246a39268d90eb7022d9debf13b2cccab549cc0546263b76d902c1307502a4c8b3cdb9f4f1b03b33056c634e74a24ec46417b932cc6ee08b73c3ee5ae64cdbb654a9ae6572b8620eff654fe4fe9db85f41b6cd21d4666d6efd6161f018e65f09209a1358bdf633563589fb1db5733dbc88229f83763f7e5759ada92cead5367d18d6be18b62a175941551fc19495e7e6ab58d62490f59a22a450560f9e8254a230dbc707031d8521a90b410293b168a080e20cf3a39cf8e8317a8286d4b50983ec2686170042da57173930c0bf46b24584ae697cde320dbdafc06faa1ad96e6427ab259bd9b8d6d9d1d77eee8f99829a8c1d3443752ef1a616b6ea41278be58f520e6a34dea7b8d336e719dc3f718be900125e2b688694c7b34bbb7c165893a69a6ed468ea18f01f4d14621a8b5636d2454ae39596f716d8bdd176316d0edaa0e911a95ff5a6114c8ac6aea26491f4e9ba0b0901ce18ee0569e9ee42f54bad727298a37a8c8b5af05ae4f05914dc85a82c4b57899a1c31499a9b680fa5d9cc505488ee19a7ecf1fb5346cf2a4e5e9b5a9d8de0221a5bd924b05da693bc63b5ff9ab7243b4881d6d21b62190f20c4c534451cb7e25466550c5715126fee555c790d6ef2bfb9e243f445994a5c7ecf56fe7464c5051a68f1dcb288f7ac7ca3466f30b16492cbd79191b371fe56feb013a3b38",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x42ce20d6b831fd804819c1470db7b6d4cdb12ea406b5b0ca9f09518aa606e51b",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x1bd5514286f5602a6762b0075266379d29af1c9d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xc7e3f0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x42a0ed78c50bd85c82fa8ce282c3444880700fbc430f268bc6c44335bb29b60f",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xa01b8df348e4fa19c074c0f2dd3c6cf3863db939ad0a69da96a2cbd16f2a90b4",
|
|
+ "timestamp": "0x6a78be7e",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-A-7chei-anchor-13100016-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8412bdfeaeb345d3b6ba09b88e7c387ce2b1d3d4f256a8e82eb5546f5bd2a9ef2c51a1dbd91c73c15c9f9cb1b50bddfd40ea3f7d3ce80386c6c8c56d0effc4496a700b8414e4b6e34d36eabf786f2d45773bdd15d6a85f289364b8f5c30a671032424d61464f13ecf58324edac2f207608e1df5dbb6c699200f72bdd9d308c7d13a0c852800b8416aa2a20c8b8442f022072c810a920a796d4116eec719803a043d9b3486f4f3790629b740ee20ec3bc93282c59cc2a5d8e50019f6f4044c9af6485aa6a081e8ea00b841e968f9282a8456d0d1843023d5bfa0110e6441116041969fcae2042c8ae00b946939caa92668b0c444a6271161a3267d8db70991478afeac732dd91d5c5cad3701b841df6e9af25284f079f34faaf4e1ee71d8f573021e40c3ee6d6557489ff7759c33509cb08e8eacb8aea14dd7ef306e6bc89c7f87e4601ae3defccdeba729b5b63f01b84159058b897fb2d6e2b3ec99cffc273f5e69aa7810bf4e392ca63bf6497f1a82941800f1e3c361982e402047163c3602b9908cbc26b197395964a5b8c0078d79c000",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x2721a6a64df76c06c27ed14eae523c4e46106a0a5e08020420a72a9901c2590c",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x4bf6f91d84b37454544279cba152581ed6820044",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xc823ef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x8042ad11de2107f8e3c4af2162052fa9cbb681156c44ba6732f53944d93a6c2e",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x9d90a17d0daa200d6607ae6535c92cce6159d5cdad10fd1703ba0eeeb60ca930",
|
|
+ "timestamp": "0x6a78e227",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a41a0676268828dae366814e70842560d532fbb450f999a172d954c8ca32cc0b38ca9f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841fe0aab6ef2ac3f9fa7aec7f1ee0e7b293ed3f31ebb2344e9919d93ae0e9394eb169c5231d7fe5ef88ddbdc517f76c83665d53fc25cd8070cc5c5c2bcbabf188000b841060e91a8277d4a2a943245377b29f6129b67f5c5112ac079bf68625c3dbde74c3cb1f08e74df3ec98709c12a4e5c1a626a1fe617670a4d18f022c50dfab1ab2701b841fd8dc97ccdad3af87745c72db74d25b15e400ff3d5238841b38bd25be51f00c42f97f54ba47373a9b245d31f7d7b1391921e022c52d1287c2ad1ed56119808ae00b8416186ae63ee914fe9ba0a0c323170a37ace6b0837fb46bb4667e47c826e434e9f097d54d213e91d8051db73edcff79f92a4e9ff15fe094586f3a6b4b04735725200b841fb9f70836e3271487b77fc8579d964c29a0e7d2745d31cd498cca92c948d44b01d6f8b3005469d3663f2530ce784599583e328e00e17f8e950b2444c59e587f801b8410637695a40b1b49ffebcae4019e2fe40d891d5a5c581fcc2a3c5203f8d7bd4991bd15641cf99709f8ef36662acf5845e94a9bc0d6ab30e766d470611822f00cf01f907c7f9029580b9029139d66af24c0f7310c3f849c65f4b19fe65ec7f93b213661c93656aa9a96b93b2835839009c9b3e5e31a9d5f8f50c6689b5b26852257302c7a0c33464fab58b0c39d537752e035a96aa49a5018c4d9d7ff278c79ac28dd5eff764537f0a6186766c1bd42d10db3d4a0ededd276a36f30a04984751294c7f6ea152a3a25494506896867773c362756d331f90b0ed50f338ac324ef5619d4edaf439ecbdcb59d49a0784957990354fad8b4bdde69d5790428c29035b6d2489d193a2625b61efa72a46613bf212d592378a399bda0b08ac2c3a2ebea970b21218ad862fde336409854cbc1456ea46b6a4ad3b31e64b485328a66177c298257a4117c10f46bafc4671df8ba323c5fa4d081dcdadcf6100e236b9f460ede9dcc43e86f69774feef6c32fddbdfef99d8bde9526d49d8aae088918d60d0c876a48a10463bd16c63144ee683bd851b075db860b2ae0bdf6f612866dbbcf4f3248e06c3c32a525637599aebb09bdccaaf1781eeead18ece92346c698ebb218730c9ec61af4a661be803fde9b65dd3be2f5d87bbc1f58eebe938a73146908b9fac6fd3035979e1cf23ff0f6f6214da0e4197be76d1fdb35fd19bc5b5cd47073f2d9d44e6cdedcd2e2c30766e42792fb937b3c3a08cca8be7269a54df261d2845c94a6f9a37c992c4e33269b1bee6296ce6e0a225fd26ad2a8c716ccd677586e35a3dec7ae6a5735682295627e85cbe26dfec1fb753616bd3141873a311296834bb5ed666094ce917afcaa7987e542c9b599cd59e430e96be4b2acd3549f1ab34f51521bb0747a981ecd39985baa66136b93d7436d99869f0b13d1c016383c154eb4a88966ee8dc79026ea4f2d1590fc7b961ceaf92acaa58b6746c38a79ec7786e189a4f61ea281e39bc155b21be39f429f1de91aca9dc7dd9917c8ca0f9029501b9029139d26f441eeb383c6f319fe66922b3df3c79fb43331532f844a22d3489a41dc1690f0a6043f5b28e1a9280676630f733857df16ebf75f562151bd5d19bbfb62eedfb67a7e24b41e54d50e10b2011ebe28a5d60ac999710f720804e68d6ed4425e4c109bb605238ddec829ad3c8d5f6c5aa68081b2632043c68e46829a0f0a113ce29f08a2b29faa3fadb9066c9245a6f49bdb263e46953b83ee7130ed42d115387e5afd232ff2bfab5198ced740ddfb5d8f14795c8daf9338db1a4118d41d74581b927dcbc64d68f273abbdfbe5727f2cc32548e62a4cdd7d0feebc150ce2adf9eaf352c949cc8940d68fe3ec4311c2394a812f0927f736c7dbaf48c60505690f561d54b7220a17433ada6c851caf1d550cc5bdee96d659a294bc9974b9c42d5d1fb8f5f5e2c3bb0cce4de92d16b2e680f831c43ddf4c55c6f90294406cc6452237086219845be4ab72a94f9d7e59a4526116cd5aad106214cba1965bda7b89d1c6d664d7dcc65ef5daa6e227e27baa591d87790e8b73e2ab39bacb3238f5073fe256f9a926d8a05ce7fe2ed3db0969b57eee0ffbe2421df4f2c53762d32881b6b23c6d8a485213ebda2c9e46e74707fd60c51dafab08a2e411aee1f027b76acbf350d23fd488f50361bbb1bc7f36b17cad50531e16a327037eb529a20681335b6445e68327e90777f89992631ea7efc891f2844f266bff69d0c6ccbebf8ce3699cbbe5ff5db938d05bf53d2625c9e02dd8831de38f764daae0bcfc52f64b3669cbfce1e570251a61a46e60d84604f2c84e13c168eb7022aa6363ad43ebd953b878344df35b4fcb6898f6ea10b535080f49e8f772e7f0e6e572d3c54fafb15eeb618da59dc14e0f268cc6431a7b0a0c795b69f9d5d30c84821ae86ff038442165b94a67f802673179d6e9e39d05881e080f9029403b902903939ca1844b9ceae27f1469250ab3f40245bbda9b918575f5d6354b59adfdfd4830263065975b0c785facb47fdac02b3d59e7f3c33f71a959beb499deb79065add4f5abef0d37673c6233f62b5edb6e7d7426ae6d6a41c7a32b7fb0e658a7eb1c9ca93abae50396dd796f2b3d16b70c49cdbd237520e4a6253527cb127a7a7bbc93577207d21ca337ccab7fa84474f023139576ba50d34adde9c50b6fa969154545ce49798a54522f9b4ddfe4f69681577c77d787978d9b9a09d4555baa5d6ad8ad9796ab8740afd34da305b7a6133f271f078de332ed6c6b5701401ef6c9a2581c313063d4776aa56a63ce3be0509d4c419d51d0369a30aa422226a09e6db8372f91256be7e5038cf4b223cde9b5648f129136b1b9680a831f7e536796429662dcc30b8f82e2042bd4a031eb6394d81146aceb6daea8f48a20c9c2d8960cd99bee8333a0abaa7d0b87312feec2340f91af6673477e27b64906a601c4be24a7299848ba0a7d8fcb75232f30be65e0525a9da67bdb9b9e130a759c2dbc60cc5bef1966e97af7cae5118dda604f7ad1ca51a4f6b6d8dc55c9aa76de2bf4bd6075bbf0d35acee820f0145a21ba7df1b1c470ce5112f75db12af3a493006b063e4b9460cb83d1283f682481e2cf79cabc9b5f11261aea35860f3e8c9e47de89d6c2b1d07e4ea34b0399a4d07c940cc83e071e02ae0a851ce3c5db685e42d9708373a18c2d41237662d9db4c3cf5c725dbf7ac84ec68b3cfc60f49b67290467f99349a3eca224f592bdd38fb5c84a713285b3c92f7a36f821ef6ce5c4d8a504e722df28e316b8a90c537f85294a7f6f05e4ceb254968a54d3493437658336f09736fa4c7fb2840f48fc42191502fca152d2c5cba3b1a6bc9d18861499d7a2c5a1ae4f568edbbd4da9e1b115f65a1ad96fe008",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x2f969426d6a0b677372bde3e3414650cb6e3fa13267c4dbbb9d4f318ab4c409a",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x5f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb0",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xc823f0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x2721a6a64df76c06c27ed14eae523c4e46106a0a5e08020420a72a9901c2590c",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x0762b5d1b4a8b1783465e259eefae45f12f93932866022568988c029bb4ca108",
|
|
+ "timestamp": "0x6a78e227",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-A-7chei-anchor-13116400-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8419a82ee524258144901f86af949d04833a72837bb351cffcdbc76d8aa83ead06417ec03db943ef03f8dc29982550978f792b47c30cb80c4c7172639bc8b49fe5901b841b7196f014563439ebffd2d068ec15054eb333582fcb6183178771d034db4c2e07914da846a2a9fb5139c61f54bfa7be751efc60ee7d368e05e50f7819539e88a00b841994947fcb229d3ad29b05e7facb137fee354e720b9909fbc5dce348fa0fbd40b7730ef7925dfa5b8c012bb2c75672dfcdee325e03d66c38c432f5d1016b3f9fa00b841619f1852aaffa0d5a9d2cb03c9390576f69cacaa3838fe9468715c10d90fbe010d20851f946ada86298eab9682bd15e909f32ee3336633aedbd88d1995742fd000b841185b121c3e7f51c9c501186395316d1b3203ab607a6f8e55148ef717f96e4cdd1fc7907f06cbc6a1b7059457c1324bb733460b52b9abe00f1696d7f36b13622501b841339ec9c1786f88f82c95ad494bbff117f6306c152680a37aea280952d2fc3b8230360619e09dfb41e97bcea1bbf06abff0fc65e3592f4577a0c9fe100ac3f59400",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xdb5c57cdf156facb314c206f44c50ab98bf6249acec059a87f76dc5dad98ed2e",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xdf09b32c761620c5be77da398b97a64f03c3980c",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xc863ef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x5e86b7d258e2ebdba17ed093ee3071d3b814460f7f86473e2255a6d38996a8eb",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xec176b63c22ab0574ba4394e731e5908409bead5e9e22afce81225f525832403",
|
|
+ "timestamp": "0x6a7905d3",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a3aa024ac78da532b841322d750f32cf486443f4fa16579ad12d13fcdf2f335fac7bbf8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8414274e0e957c9ceccc481eb9cf60530b7c2cafb0829df08cbcb94bace44e369e66dc5361e1ed7e795d53c71b1ccacd9cb3c22a6b53b322886d57388047e08a06500b8414bef8e3dd9c47138a9c7b82f2db2c05cd1c739b21c0ee513303440cc53818be37457a5bce48e83c9d55be6ebc758506fa02b9d396af2ba3e61e1b8107449633101b84121b9f800905b8978931aef6d5fdf0d25edd9830fe84961f926c6b94c203fc25b5d3b2c097a67f4b204325820a0bbb9984682d8c2f89038e57f8bfb38c471c93201b841dc6dee887d2b9c9e0839fccced15d205035c0e8c1613fbe0d19cb0412709c3702a52e539ade17421a4c709ba190df07d3fc199b26cac444b1b17333b51928bf201b841afcfc241c73aef79094b7ce7881fcf3c8f54f19d4421747a16f92630462709a729e6c49c178d5978dbb43fd4e2e6c4e6081ba82bb8694d5117d3e1047b1d380f00b8417e2a8db7ea793cfe514a06ec42692353cfb01264cd97a324fa211c4843d6c1d839228536e596433666bda12c9ff1aa5b9e8b9b29eb98199eca78fab211d2723e00f907c0f9029480b90290393333af26c18411890976443a49b320023bac486285175957c20d33a3d89365d3e4aa3af807af26ffe5e3251b46ba07dfbeaf884459cacb92a85f0378db559b1eb795604295e8a62c83b468156b2f79bfa62a6c5ae6c718eb5e4efd5ec2918edccb2362fb57339422125390bd9b2e323e593ab3277c3d12970a2ac97fb34cf5d38dae89641838498cd549bf7ac64b4fb4994ae536842775fe2e83d969f57f9ddc35c02d1fbbe41daaccedab30e46e3f9a23ffadb3aa2f9fddfd9f6ac80c5fef159047558923e6ebb87c1acf390339f08f0ff5a24ca1ead480aeb67a864c4d92968a0cd626137bc4bd66b9ca5960b06d09df2df9a19833955febabcd11b47539022539727718f61d9822f7c6d1e844586e0a52edbd4854e9e3c8c27b36e5054a8ce5d1d566232c4c4a0997903ece8c016742139e043fd277d0631f454813a6f572355a2cf5ce0172fdc24379eb1875912a73b47f5c3e2dc667e7b8c71e8b46ae6a98eb84a62ce3eda1a9bca91c5a122a6e74d4ee791468ff4221f4c8ad181c8c2e892b7058cdd7c1876d472fecc823cdd33164fd5fb02c3d2a9381250d66de170a23f9399e196d6c29261702d212bccc817cda4ccb8cad8b9591953ccea0f055a51b79e2983f9ce6cf1071cd415f83ad154a7913a9b1f1de162b0e9542934da2cb2a4524099721e46c6c0d86e0d3233149b92742f3293b8c989a940e42d7912460b0cd2fed620c45d09e8b9a2e844ed6dabb4bdd028fb04dd8442b4f804421be3945ff844cd6a40d1d44787b696d3d1a8788d43524b7ef5075cb78dc49bcc38155aa20259f3468a468e4a9c966c89f798a7ae2eae6fc5f2d53aedf4265bcd0bb3c2f6a9971c5b3f913999a41721b365daf70f15836934b3393c8b89fc5ebd10c54617126c2f7004124e885f6a354d3a0f9029203b9028e39f8f14e82049124032d151a85d1c708f9777c9fbef70789b7fdcb8d683db8cad7a2ae6df7d9e2276f3950b4690da775b54991545e2f1c9621ce221943fca2b1fa9a75db8ba2f137e3ae8aa366dc8de15af23fb595c91e3582c326b24223f53ce6c90cf7e7309c9bb258c4105cfe9354cda75a326a5e7b502705ca67c4ab50e79fa8d308caa7597f4c8108b0318a97ded7f0c3d4a92422744b9348b74a2c85a6a989aa1fa4aef1448ae7edd1953fd50733f05f22fb5bfd3f984a00bb7d9c69974f37c58bd1bb5b37e6ce8e2a3ca1978da13d7a4ef66b6b80776476a7fb43f72afc5fcd36bcc1f3ab58435ed3a19cbbadeee8c7a6e4b5133b0a5def472afe67fa3108a520c5a386e67724658f7b04956c1d0a40c1de34e4fb9def7450e4b1387cd255050245c89267a7c43a1996852799f4e45d9d1c42ea831d269df0f9fcd5a46a2e242a82a1f0c552cd67ea0bc47a559449851acecd59e249199a7abdbaf219968550dabeb08b1fbc90a11ceaf797649e64d573505563d2ba43a4ae2734d8644214e77d6310d2966be877280eedc452601277b226470dab8b8ccaa04dda4c4da1936d5cae39b8765311a7a493db439241b1550d499c94a759dcfe27c1e4527bc3351081354a948238757bac76420ac23c2d457def8df52848e26cd4e433bd38acd7a51e28cf378632de79d624db872f641f3b43a79bd44aab31c41ec4913b5b7982bc986a0c13ba82761b17bcc4c733762e9f7244c0ae92abd5cfb3e8b3a386f356d33472f6d6c2a46510565bf908a56e0ab13051393f1cdb80c87fb124bf7843664509e04e24eaa6135317e3cfb9ddb58f80d12d900dc1ced2d760ba0fb2f784f0413ef8c75b652fdd45b54d6143c0c91e5ceb6ed95850f459cbbd675387c7ec699ec3290c55d5a6f90bb95020f9029104b9028d3907adb369d17b85c568db67e5603edffcb827f058ad8bb907cf5e35b5091fd689e720d01c8184066466b9f7f3a937777d0cd0b74ea6b74a4c9d12a7e1e52289e4493e6097285d6a146c129bb7ab479543ea77fbad0748825fade4d5378b3b8821004e6269c31661781a0e4b330a2f91ea1d7910fddb5f17a7775852644e70c1e45143c466eed2bea4990180e0d0e9f74aa5d39467f948ed6a93089110018d73a75bf4796f99a451453a232caca01f75a9203d5959e776fda2e95073fc2bbcd59c6dcfbe20902cdedd50ec217356b3e54b83be5b64de9b9d78e03a42a36562b14d6eb9a25aefcf0db125d3ca4f672ecc4af0f6ad674d0872a6b73d520787bdce5bc916f4bd2ca7f79ce0b16a34c5d378470a25572507a345f945563635344cd1d9b68a1cc4e81af983ae69a1680fb93ba9d9b042556eca73e326d965b35c212438d24f64f956df572a91372a74ff9cc1b2275be136fd318eaa2e99be5a3adc49539738dbc60b2af4616250d4773d99d94a131c22b303652508e320e51ebd6911bbce9c3ae3f4d8e5d77f2c0b22a242f1e93c16ffcceb72f778ef77473ca01335a3ddbc66991f2a5953e5409b7cedb36959bcb9990f8f42ebd5ae493bb56343b79f71b7ac80e54032866b928a6d2b112e278b4d148b2879685410b1eed847a2fbd0a7a6583681591c161b8ac63191db16dc4251fdbedd17b0e7d299ec8d10b848f3aecd363fe0409dd66ce9b2c891ae8afe76e558287d459a338da5467f1679fdfa25ab8051da594ece9f55d7a2e2ff85ce55169f06430c24320332d32d9f67bba59068eb4aec209f2d4c2f76f0b05a5758513fcebfcd7597b5d8f42a0d09e4d50da6c620ce246ac78d5d42da1d719b458d6ca0983ef21ae95648a5f43feb0cddcb48a6e3fd2af96e4bbf19ac80",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x81246ed1b93f99a3710449866201e485c81d97bf42107f4d994ca6598c27a843",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xe13aa491abbc1252dd714e7ca0e55717a2143eaf",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xc863f0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xdb5c57cdf156facb314c206f44c50ab98bf6249acec059a87f76dc5dad98ed2e",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x2ffaac92fe1b069571f5ad46407c4a8d850806754a3829b6d02108a001c98fce",
|
|
+ "timestamp": "0x6a7905d4",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-A-7chei-anchor-13132784-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8417f88f32f66130ac45c33efcae08c3527e0deb80a20586ef2bf61b866fe34f2a24230d422250ef3f8a741eb4bd0914005f2bbc877d75b020183c868dada21427700b8412e3ab7c874e4f24e59fdd7f02d6483d72cf6ddc73b8c0a3a7ddacaec7a9996863e83721c94778c759c7bafd77b9ac454b274e9e0fbb7953eea86a3b4018558b600b8418b8397fefcb33ec1c595de9b02c8e52f67ee219d85e38fe8e2773b136413d9016a44d5328e701eb3c6cb1cdbe4d478ae54f1ac0ef66cfbcedcca7e6db9e396f901b8414c29b2318ee805e7474823a65553f0aa70552dec0bc5e73ed1ffbe53c33d66b702da20c6ae826748a402b5ce8ff6a3f648971b7a3d4faa9a14c9a51d3b3f5cdc01b84198c487b7be1d6e5eb54fa32a16c67179a1d0d6d0435cda0f72f47a3170006ba70272ef6ea4ecf3fc9dc9b51bf345f8fe750a2ff3bb4fd6fa384880dcbb049ce401b8415967136de40f7f2629b025a6ec1733fc6016f8a75a65a6b9b276678e10ff99b10d706f4aed1f8f90d521ebe46976de12efd68f984b78b16611bde758aedb8e5d00",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xea2aeb23161259932273165c0afd21532970c3a1a7be405f1878202aa8692a3e",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xe13aa491abbc1252dd714e7ca0e55717a2143eaf",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xc8a3ef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x4a9ceb2ec6ef3531696c1159e8fa9c99129872b033953dc38977185107a37760",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xf04a70ad3d227ffb35647d5da509cb8f94929f11c2a75d8df84baa9bdafded9e",
|
|
+ "timestamp": "0x6a79299e",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a39a029977c855ae5b64a7b79f80398bce6cc57e8bec18ad276506e6af04545f85abaf8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841e812b75c6f3bce5ee98e2d468e29b2144fb93d6e0f3a2d7ee6f27c4b4ddb6b8d65a5789fda411d32d37252697bc2f9d63a093deb64b0aab39669344ab69ce58801b8412ebdf89e8316a9aca3c357ed2203a7744ce06043af6189f05ac1dd882bca7b290220ac3c0755c4c903ac15502cfcf899da1ec8942b56180dc53fa7ff56d9bfba01b841e87d3b8626b73c6ccd92559a27f844bce0ec81f03c40b4c3ea867979b49d4d6c01fd02cbe6fec65f96b61133c95c9379211292a92eab1d885901490be482768000b8418538def9d4ee09a2873ee7e0d02667659f537308acded3638bb944b18f12609d26baaeac235125ce09062bb693f4fa414f3811e5ad58a6db946179e3c086198701b841223be9b904d90ecdf1126b8f5aff93216610694b88e497c84557fa0ff5d5cc006a87bdb86abd5b417a221ac9c2111aca49afe14849a764fbc7c41d5bea0bdbf100b8417997a41ea3e1eee315cfb0d9140d7889365a16be61e99e6721d3f6c856330843321560d6f99ed032d8e8ab273aa74b3f8667928818518df50a8ed9fbe7f6993400f907bff9028e80b9028a395253cc11aa4c4dd8622c97dc50f8a97ffb36ec59d85476fbe6c3105695661bca50cae079f7ed87d256e93f8f1cf9c5bb26eb26a79ca5e9bb72f72bedd863264655109c18460fa552e899b63a756e5218123f59a1612af56c6cee658269352982e5ee908ad607469cec66d04aeeea4cd5eaa2aa093e9ca3e4dd4299111a36b4f15a1d8a7db142f6743bf4a3cfcde625abb4009d432408e36177eacd97be63fefbf0db863cd13185376ce0e61a8b22efa7d0ca59d6636984b4d7b48c2f7f6944a23fa962bb06a3b9f6e4f71acd5a4526d0c4150eac77367ca06feb7cddfadd1a6dc2f3739643f1949f6b6964b86d136c1db4882a308da346ab7b583e0fe15c9e2ddc88427f24a1eb622a9e275393957ecd23911ab56b4c1f12158a33cbadd38a94a6510d8cfa790a2971d9525085a3d069e2b0d5293c14763307cc263c0c4167ce8d89abaac7b4be89a5370bb0d5468c3316f1399c4b650933dc361e7430c21df839117cb4978ab499296896e42b7392c8848f535d97e337a4a733849bfa6354b9a63cd6ab9b7345747549bc9197c9fc1a95f31d4076bfdf2231fc94ca1c538388704faa53a4a14f705c7e5c4263bec959cafd6a575d9e61db145c963d9273aec7c9acbdff6459921078adbfed274eeb1e1ea10979e83d34b67325bdb48fc48921eae5976fdf0686eed4710a4cacdfb0ae2b98cd16eb3d9f17237a93629dbd5555bd8f4fcee6650c762b6f12e553f9b4cd85ee77b77a641bca1b4b0b497e18722f70dc9f56829facd1664de453a3027127b68c43a2dc106a2ad1ed11396a933e9e4350398d9b3c8fd070e81124915710bebf46f48a13494776bd994bf297888af5004f4432b70de636f278f24c555a7cb2b5a4f8ebd14cdb4c86b8b217ea06ab353e822bca4a2cc9b281f9029504b902913909f3f3764a124d207278831fd78e95608760a0918146bb2f894f6893a56e512a122f2fcf246536095854c95419678db8d793bf38956e96dd391c9bc3cf7333e4945b99253ac0ce9c8793f91241e3093212bdf28f54b3083aed5a2a6199d34e88b4306f87ff86bbe4f04a435e8af7376dd3fcd2ac7d662b34cc4e8cc2366f5119c625e2e4557644f0c59e4fcd4a6488f1f1eb6320eb3fb6271179cb329266a6d4da7d3f7a0f2a31a889a7a6ddceed5d2cdeb89a2bbc96ef36a991c9eab1b177c4a053dfeabd4764db1f98fe2f343d84c8234a3cf233c42cf348badaee41e10fb6c0a21b5ee2464bb932ae02edc653dc064b17c79f5c704b311847e0af5f1dfbba783cf120a0287a897ce55bbfbe93ab0f9f941214490e5859ba53e895a2af1e2d348ee8441e66f6b6d1c41692bee7584730d551120349362d9a5bacebfac2d952cae3ca825933f99f1d720f072f2c32b8eb2a4cf1948430286a1fed99fa6d918778a7d64833858a2cd1a9ae00e3e29e39a3651859f205bd297bb60f7c4383766f969e6223b78edfb8ebaa298247d68a5203ef4c7ff52dea47124a26b1aabab7c97af6af0b4357941e564a9d743610fa832d9b1184f706f3230dba4363c1ce50843312854c2487cd223a5aa81df19090f21bc4bbf8d9c0130c576e03de61e2ef73e2dddd1b036bad45d638bf4358ca5288934f3275d68d169d24a6c8cb0ecfe31e244e918a9129cca7f2e1b8e6aa98185a8cfde6f83c3d24d2ab661e2f5a175e50b5642b55da716aedddb969d3e1de25566b23f3a1fe9604682f2c1ecdc3b3d532ca0c7385e69d28f3d88b0eca4f957844de14e3b3b960ee93e771b58f274d7369ae627ab46ce5e0a7d5085d35a02b358f0d51112b108cd43c884cb31aa6ee888c7e56590e6ff8835ff6b34c22b7dc9340f9029306b9028f39388bbc290271b028fbd66b0133d350d2d735e9dabab22bb7cdffff4512690e51677c1b3b28e1f29abadc209ac3871dd73907b57493df6330246e3b8eda70b02552559198a2d0673d163224cfcf4f7f6f97fd6cdf52435288a6d1958ac8529eaeb922473e730c1462afc940fb45078b69c4d1bb77af39167709de4493cbf2901b8e9bdb07f3b02484d3400fbf26b5fc26e40ae11d95b13366a99786fc294c2f0b5ced42e0fe89d3005af2cdd768f745342d68d32e9fe4b16e5350e5d5cd47dd5c86459654328e7703ef835a93ad016d84b2ac6b5530704e8566a843e5053bdbe2ed272981de5fbdb1a448f0fcb2a4090c82d5f9acda793b8c3d397ddfc762fea8f8448a45813128707f6671edaa048678f9f8bff1c1685e66bd92dc2d1e29ba5faee2b6ad088bb2896253d9d2bb55241ca4369ee54bcb37aca7252a72cf5a3a5bf60101a12f8d45631a4ce0ad9369a564d2b8740122cd6eed5eba8a41e47df3c92bfb06943bd26b1c06f7094bae91f2cb339bf073d6ccbeaa9d214ef44ea3269126b677312b89a131cc3573c539e9fe30247d738823aa8c7184c03936d4a4a5759f19b9ac6547bf415bc6928d260863fee436ebbdcf18392191a763ca84ae1186357292718a9dbe14d451a3f3ff266d824c88f28ebf690d37b06c4a082bb38be412d0f3a7bafc0d6d88f54b53da967a149f74f088be55e9c6adabbabe8466f31a1233aad5e2958120dd24bb2b7b5505192535e0b090a46d85d84f53bd75c248e8ba476f0530cee43b27e0f7af9b1e2f937ca459f225f56186d3db3e5bb96fa52b3d841f404563056143801e0cf15052e2b16886d38ee5a41cd922763968dc2b6154dc433f04a4f4ae0448bbd734969cada19ba0386e46fb24d162ffb07f0a14e24566e320d5baf5b54593be59b1c4",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xa2a3d4b68e12b6150bdd6c7996b1503ffd674477629bdf0ad3f0d2aef848cfb0",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xf73bbbd26a82dbc769066550d8d4585eab2fc00d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xc8a3f0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xea2aeb23161259932273165c0afd21532970c3a1a7be405f1878202aa8692a3e",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x360430c93ffcc3b79c05b5b9e7e72b2ef14f5cceb5fcddfecf0211287bc6832a",
|
|
+ "timestamp": "0x6a79299f",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-A-7chei-anchor-13149168-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b84191255633054f28af742e09c348d337ca895094f64fb0f1a899ce454d1d6975766a1ef7fb2d0393ee8335f56c05c125d6fbe3a17bff9429c85a96c8b2010f898f01b84146b894f56839a0a826e4a53f43bdf0f2887906aa7f699482ca4e420a8207d49f3502ac69ac3203e130fb8cf739e46dbad3538cb011f3fba4ab86e7d95fa9285501b8419fe4a9a11f8630e06c75b9a3cb21847a49ac5dd984e0a99e3160d5b640f915a1463961fd2efc7514d00c357967f758778e73127525b70e1382c228851b0fe8fc01b84110b9ee9743f97e774dd569ce0f544dd240c1621350336c2c1193056974c06336616e43d2360261d147e103fc31a55a8a2e58e280806869c765b7d826f692e1a000b8416f2757eb5d22163a44eaaa2aa6eb287c24ed58177f63368b2aa2c1163bd1ab1d631941fe773dbc642aebd3fd88b1733d9f75aae05a50f0e5edaef5b382050e9200b841e4f77018e3115bb83f4d1cb0bbeab2ab10712a2824b171556597dd51c67722a6534582138fe88c55f132d20185740fe7fe6422dbc84effc5af7ad5b88f45847501",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x5938e141c31d6ef2228fb226d18c9012eedcb396ad02fd9128a2831131371f42",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x1bd5514286f5602a6762b0075266379d29af1c9d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xc8e3ef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x088e983ca2eb38df0ed6536bc331b8dd2fa6b3ac7ff8f6da6f03c0515b2e72d5",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x3bc1c28a61484d877122ba6a46c19097718e906a609e68c9c69484b63b6b8046",
|
|
+ "timestamp": "0x6a794d40",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a36a057c422c0c9f83822cbd4108b463023919bece95fb057242da52a01eb715c450bf8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b84175a64197d8cc24380886a5e6e265fd8c895afc06f1ee4d8ddebc2df1896ef1a157faf5574084441ec29e27a20e75411373ac7bc1a98ec831f8042d8b49db510300b8412a2000427c64c0c4a6317ecc6c34c948aa073edc03d7c28761714f9f2b7a2545116708df3456c57af3d2848d006595512429953e372dac8b9fcf8ae217517bf800b8416d0552f865f26b10cf7f3e09e67b2caf943a2a698e8c94561aa644c0b7b7ffca4d75fd36300919721dd8e0539aa1d5805a6b6d165ea6e5a9be61fa5782df996f01b8411d72ff764845dc063671157c85bf4da5c0d00f0ee9674e86ec91f406b7b7183a212bdafab35324fa6e07b9af22b11e7d19cada8c911db74baaf54a9be0b427f000b841122b3b00153896f265f3a73735df5c54546eef50899ea55525e3feede0e9105807120f6484ef5b97dc50621e658537c4aa85c55354daac4e8b3edc093b0259a501b8418a94d150ddcc758168277f8a024604d323e6f5d4646daeb3e5b5e385c65f94116f8fa26f5f482ef8bdff0f629a1cf2bb5b76b18517563661188180f873032f3601f907bcf9028f80b9028b3914a0b7aa2d0eeda15e4675c9276e0c8a965c547ac8d558511f53bb4569255dada85a9e004d44acc2a470527ba2ad7371adb02abc6b5da3db346eb44fe9b3c81cc8a5e9043afbfb1d27b5725bffd19fc43f824fbc1f9f7d3ae3b885a3d8ab4a518bd2bd71cfb65eae8c91c4e0bf5fd7abdb57189bb8f242c1335aa8b376358da233b3bd5dad3774db88c5ea6cc75b30a675fccf9def3b426be8972804c90931ee02a784e0d3e27aef7d0689a137dbe49e7a6156fede5a8ec505468b2b7c2ac85c9732fed3343b61099d63551ce627af1d876eeb8cfc179f2e762cb782fc2226564999e6d858eae360bf614916367ea85a11e7f1beda63111b0d824a9d63482a6084c4f2a76e672cc165d545a334d2f3531daebb3b7b8ce6131d5d67532e347e48523510dde130abdea1118ac93b8817f3912892ee2cc9053e3e2955d9d3ec8457aa243a52e278fa245eb6894c8c518e630e217db159ec11010a9c61e41eb5854661e53607135823bc7ec4497c7b4d14cba24def58aa8e9f7394753fbb88311819191a2d3411989b5e81b06e3b91eb58e47adb37baed8446e50d3e2ff79fccf9d8ceb7b6d473183cacb71ef7b96afa7ead69526c3d15421a1df70d6d7ce648b20a8cdf5a6ea99375287b98b3e9241c8a66568b56b1ec514a44d24ecc57b228f675369724e6e603df61d846662125ef2e9639e601aff0a388be6b448f661426a3aed1ff998e5ea7f10e43543d417183b03a5b3b9eafaacb04dd8b1047222557596eb906e9186fae17cf3edac9d24e2098556d5ddda754478228e1ac711770543d8c30fdc1aa5be69e76c78b17d3b917b7f5371c6d9bf4ec7ea8d0f5be64edbfd9270e5340a670fc9a5868e5791e74f629c24218d5bf9b1129411ec6b10836858e492908dfd919e4f0fbaad9f9029501b902913969ce0fa6500992718921931b3db76cbc89e66ce8cc9747ffee9e8392fa1630e7abde9095e718bd5de77920188a1e4710a3c389cc576b5cefb00d4f1d50e17ae0ecbfa5108513a39efea9f8370ac4d8e973c8f6eed3dbc6c146cc97d05696fa428c2173ba2ed213f1c9904c6c0f76eb35def34119507bda99ec9cada4e85ba301f2749d8b65c5d5c21403950011afd6c8a147f60697e3ac479f2ca3672ec895b7255024dfd81237cd9fa69126c69e6d797aedfa66f9a74ffe5ce14611bbb606676d61b1733ad4c34fa8368f621f4cdc2bf8540fa17dd19958bd0d47a133b944fc457cbf4d9a2ccbe6b248acd1cbb64e64852dbd956015286cca7a6c74ccd3d55aae90c9cd579e5a700a2bbb1e74621e2843f6a3fbb7c59fd7803e7bbe6245a83f7016d3bb71541c32d28aad8ecd96bb7348a73fd8f6398abcdd1a8ac6e70a949f2e14d6bb9660cd84aa15427fa29a6d9d3a6ed623c4f5ec5bf2afb18adb7da9cd4b966a497c37ce90e1b14daa4e562c5a45071cb3933a6a12686955bd415665d9a9d5e2e0ef49448d938967e338e2496654abf458ac6dd38d03b05dcd86c34e41ce4e24a01057689daacb991caba579caaa0c9c3f72796f43652eabaf9044f05aa97c395c2b2d8448d0ab5c024bb690a10c2b66ca12040f7688a34f42f751dd9545e142435f14f63131410dea3893cf2132cca62326d4862943238de877ba4d0bd344ea2bdd38e6b62bf3b7c7e0ca1b4cd11b88fb18493ff9e7117d6274cd390225c69ab399222f0b996b6c1cecaf820f1cbc54222c4af18af8a1bf59f69768b9be8bb39a49dcba4457a01c88f4c5df70260a87d515638851749323cc76c757ea94c40954462485e52d0a3c4508dc6a3cbd0b8ed227a74c4c1ab9d965122ea3527d3aaf67130881f20ddfe585481b0efaf9028f04b9028b39d6242006ecc8abed622c449849cfa3daba68c39a0d1d08f368c2275091c12af163e0e6109e88c1329067ce9ea8fed7d7ebd24f42dfc3dd594b71c4478d15b1fd9f68dc1765054b397fc555926ad23679b4cc1e97f3610582e6a2197839cfc3ff79ba66c21c9671ad131d0c528b8671314c11f8755b7e3c96148728b6df268223396999c9eb2d21b5e4a8d33310ea4da5446297fa4abbecf326917762f9ee3d8a27b9c3cdb04ad64e71ed60ce4e659687491916d33f90c6c7218a9eae9283a01b89fa29d9d5fc734f75d8cab8909bff5f34a8d8f5b9181a1c9fd91a6ef6379626ee5416713c629f0e12d89f676673c8595fca8c8634dc9c72855c92aab0a42ed4d447dc49870beed5fce5d7c4ae030782bd0b730569dbd5d64d06855b4e5045f2e965299b86eb3f4276983f119aa059ba391386dab7f06447e78bc78cfbf8b57a5eeba71eb925a7f6aaa76125934cb89eb648919627e56a908a46df1940c3c16fde7ecd1acdb3eb2f331c64c22a552cd8bdb5494f2ccb36386752558bb834c33f13685978dc32c9bde346d104376a8cc463f9e44d2e42ab6b360162aef692f7fd43a7ca8a5d1be3a460fa3375a9e6d0c751dc39495798397b11649eff2270797a3f675c6adb8858cdb110ceea5e5f18d84377e14056dd43ed3cd96fa7705df2bceed0dc24e895d0de6663485236118e6761d7fa75244faef714997c321fd60104f71f2da26052f43578dd26b8e123869aff066d05950a5275560a33724aa912441fcef26f60c609e74d3d7bdde5deb4c922991d1c1b159bfbd370950792175ce1e52b6b4a72ab4b19229b1150b497e99bbf42fc90939b29973486ba9ade1b69223753b078e8e7dd335aecb39857e22d20b7ee1b4ccb84666978f69afd60bfc35884ea69566098e6665e80",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x5b74210e3fe00aefb20bea77f2c539919340b059144d4ebee478462c6a59cd6b",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x4bf6f91d84b37454544279cba152581ed6820044",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xc8e3f0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x5938e141c31d6ef2228fb226d18c9012eedcb396ad02fd9128a2831131371f42",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x3395b5400aa641d15aff9148cf1c90c54671109c9ba4e48489430fc6fdec1cec",
|
|
+ "timestamp": "0x6a794d40",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-A-7chei-anchor-13165552-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841c06c764ded093b066f3968d83f2a280cc4d9377283e3beb4690d34a64d1f980559a2b097366995146d277778c3754653aa2432ec33d964c1b011b593a9afac3101b8416f27018ba6e536f830638e0926480bfd27f97c3af445b701e8aee8a8297c43f36199f6fcb07a9cce60fe0b48b4a7078895e32420013f3a0de4d85070db16de2601b84116f95766fa5ac1a6d190dbaf47450024152aac4198deb85242424a5840c5812a665a24d91dcc1f3d9f64b8c31696e5473f9eb976418518bcfbd5c5436142a71801b841bbf15fccb23fdaf794dbd34752d586e618215bf4b43685db775b14f2d718dd0540f7294acd0473391dd0de1fddeb9d27b4097706ea47c7b64def7b957162571900b84113d3dafd24a8df1fc22a332a3fb2cf3b6c7575a7788b25639270ced5459395db154339208fb25a8f903fc2cd79a5bb5709cbbadaeb16c62c4742c98d7ae42bed00b8411c04d9740014aa7752ea56abed30828bb85a12242d9c989119346db3e80c0721388ba7e61aaf33532a6258c1700061ee51a33ac359076724a7864ed80ef6427f00",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xb8c61b7f24c2c29301808129b6632a1348c0d696232d7c1153484ed323ac6c1a",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x1bd5514286f5602a6762b0075266379d29af1c9d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xc923ef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x44ce68add94379d01515516104d53fd1a56d1ac27c0deaf887e0b537d583cc1d",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x2954d1fd1f2074ba570090e99eba274ebc5545344f30e9028a456e6497395782",
|
|
+ "timestamp": "0x6a797185",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a38a041ecd78243e201b1234578e66c96a6ee74d26ab43b1161c147d109687f19477cf8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8410140b07b9c2e24cbdb6c9df15cb2f0c4800016cf9e1c7ec48b056af3d587b6996192cc9e3b71a3fe3fca98c3596ffa026d2245e88ce58846a15edb30dc4a635500b841f57c6535e899a61aa222b021d6a61988618adfba4f6226a13af1eaf703eb81f35eb2a37011997040dba43c4bca52a0b16670e2328351e591a3f73ae494da736f01b841d61aec777b07c599f05edb677fb43ded0cc922e2a7ea56609fd4e157ff08451e3472faf3ba0673bae4409c083263da7879925df402e6b23fad8e236a724cac1a01b841f0a8202283c4db30b5c5ebf41b2bac916de6ce7f468562a64985e4feb7bc526b0a5bf30cdc2e550e3f48b03ed3cd178b528dd853890f28e56a423a8c6c25a32901b841d01963441f9e5cb51ce4e7239b4a6e65f0ed1d1c0ad77e6253279c54e2904d3571ee8b441994cce982ce6e078905bfa00fc39d44ffa88ef08cccd997e88236af01b841339a25e3a2ae1649a11238db9f6c5d5b43f601fbed550efdd8155a568a0375a03409ae7d92161dfbd4c7201ee99be2d64870248e89d1980c901cbba17270641001f907bef9029280b9028e3919872f36eb6297113a83a729874ab21c1b9de17ced80068c1e34a1536879b5bede6fc551a4237175fae2258c691a42918d9c81b78e5434686b50b327a995409766b3089a617da7ba68cd020c66dd158d003bf5c75fd9377a16155eb78e2ad9ed340a1f76ef1262b0ec10edc466cb0f3f5ff2216c1328c5889a75d1e3ebbfaa2bf91d2ae294ae072ac2d656311074e9c9507b8ed6c5034474d8e9fb1cd52c6f5350d72331299412bb6f6cd004ccacacb83eda0ae07f48c3f169c9c4d98204525dbe3d5ba9576dbc34d93382e1b89c154361d95b2f3efb0a6f283c97f4a509972fe4838fa0eb117bbb3142f6cede8c0e9d8f9c64d3cc1eb135ad9416f6dfe942b6b3f78d8a123463d716cc2d67d25ba6dd222226c3706813bf448f9b7bf774d76a1f6b884295281977d8a62ee3e8b562217f7c7b7bc7e2eda18d84f6874379dace0c4db75598ba57aaaaabd7c943ad6b1f58ca2e526be5b9a646a0f041eea64d7550ba7af912d4964fc683abd5a138085ad8e8d6d0787e952be978e17903f11142a1d03a8ebaf59cd7c3117ca4561860df361a6b6288ba1c6ebcde34b123d15b9caffb4bb3d1cf6654d9e116193499a49a9c992b2940a2a4b8d235cd691e99232f1ff2ed982796cf8d6c29dc26a57f94181832ab524688e172cdf59bfd9fd3a643d62a1a45b2549e885376d03991a67a3e8f99ee2fb3d657e0eb4a91cdbefb98349ba652db76225b009a355f2ce1386bd2d90d6d1acfa997e782b2db4e71d30e96319a73378ecd3ec9faa736ef9408aec35a6546b4b244de5efb6dad6ed483535b83aa5b2645a1c6c9702b3aaa5fd90c27795621c9ce3ccac99f34e243f0f0125bf4cf27bb47763a6c1f7cfad4d5638deaa8dc3879f41abd1fc432931688ceae197e0bcd1ce4639a2c437fce71e0f9029101b9028d39571a4c27eb2a8976752bac4e48a8c5e7f3af03ed963badd01c2f16a1e54d3e5db183e513a2954ffa1b6e2c722b31c95479924cf4f38e342671b0e354da829df751a76deb23cf81ed0ceaa489f4bd30f2810323c99feb5b56df4e73ac23a6f52d5a9465b84fd3e91c1d066f34cbc732f2e2acb7e5952121cfe6cd398a8cd158c328ad8239cff0358bccbbadb75097441354c81fa8ea42909aca4b972154e30fc33cc2a4be6c627e9d6d565a9b42b46ff364564b8a8ba132a16987bfb2cd02878d106202ef67520d6cc8ba43083f6fe9e8c35d7128060fab66c822d94b4237dfe54fb17cdb31c781723056ea01b84a2c6a31b22491589096e9510a2165f761d7da817fa267ecb95bf35d59ff5bfb099a7ea8d892d54bb14e8cb404d79bbd7b12c9f241bdf6a8f56de4b9b3b9441b7208413aad49b7cf6be2eb1c08e821f9f355156be20d4a0b43d49248d9e39eb9f863f928af2139288456c51664e99144490f5e3b584b2a236cbbed73c26f20c4a7356f66ec72a157c8ffd13172bcef62918b8062f20e2ea5b57dd2335c36e876863f4cd6415dbda6df2e6d67c9ce5f00ce41d54cfbecd9e569f96d7a929af43b1b38e26723d635ff7770a978678f045a3831493e2b0a479dfd768da57333b7840be6dd63230cbe6d0042dd852f43a6198e3429f7ac3bb8c5ad216b9e7843ccf6aa18c455c230f49b7251e5984ad5e7514880e1d7bc5639104a7a57bbbca2c69deb7b104e43bdb7f5a88d7aa0e370745dce0bf1aff6476504e6465bfdd5775e3c87c019f73e3bf966335d549c6a7f1836e188d808d7c909d76439898ae47067ff793a2b0ea599f71fef9853544def253ccf6fe9f05629812746cfe2d771a64a5e091b9f7d21f113d9cac5d86f52e29961e261ef30e5c669e8c1f86518cc3c56f9029203b9028e3988a5028f759eb3232de372408383d0f95a52753c6042e9f585394cfd456e946c45fdb120453ce3c6bb72ba1a042b4597e6433e3d2db7de1ba5c850f5f13c9f8f2581407f1594421ccb9325a11f49d35c1752a8f2aaf3bc61fc49cdf320ea92d8e9e9fc906d7268d5fca9f31a0210481ad5075344c6a38edf7d36ba7c4c1376ca309b07858846535f951a733e90a3b12a545f4afa71db2f031af37e60db06a6cdcf760a4cbb2e987518736b46f0cbba28eab7a9c0f625893409d861a5097c57f6a0401cc6fbca63cc238e62842733225528a90e8f579e63dd8a45bd4184e4095af54020dc1f26014dc678bc2ff57b0e6c139d6f6e00446d57dce373bcdf14095a85767157e53312e37cd9774b4edc0e5b5c81a36ef28b3495f9d825551262f0a9817a4f531f2d5a86b0210c92edc65cb0080a2d49d4994c6523a44de5c4e34507f1aebbaae2e987fdd632e9f4063d3c4e18132a96411169a56b7ce9fb949244fd9e2eef4a91098f23a914523598c84a138eeee287e222b2256a658520ad9f5a5be999b9d323aba341d88587f889b4eaea46a2a5bb051bb3a27bafea9c45a0e164d334562b15c178f9f42eb2270d17eaa17f87e32c38683201babaaee9a23b1336f0e81759e04c23ba2fc553b1cfbf3a343c42b044552887ae4e4bb79b4f4369a2b2ae0e7a6497233392c9d3fa99b8b138fbd6781498b798cc6ed3c40d0d30c6c0c827f0839f676f09cd1a03f69d23ec131cacdbe9b705e652eb3f44894af31aa7ba3fd4f5631477973b939db61a3822efd45af5e73a1c68f93acf6b459d2a1fdd9c1f771625f9c252e1bfd878ae5c8f65b352c203b486ba3b8d052f2d8669d2e23dfd5b989915777fd4a95692ca870d8430fe68973a916edea5834c2ad9042b5ff2b8d1b1a9332ca82544adf780",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x7513d23377c9c0d36f65aa4cac4a41122fa437bafe26e91a2147a7f00c01f55f",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x4bf6f91d84b37454544279cba152581ed6820044",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xc923f0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xb8c61b7f24c2c29301808129b6632a1348c0d696232d7c1153484ed323ac6c1a",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xffdb80d83591fce3dfc3e5583d9220d7f132c73d1d4b9b6dc154b9e0f5b2f480",
|
|
+ "timestamp": "0x6a797185",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-A-7chei-anchor-13181936-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8417636dabe242530ce2a9eeaf6be8b2e6705505af33e856782fa6a9cfcb9c6dd785065c0a28dc1e34854670ff35a70c5d42bc366cadc1158f28d0703d67411227300b84157856b19c2393e821061fb187ebfa8d60bfc68cf78f4ef713a7517602a84f5a2500e3b7f87d72251e531d071cf61fa3fe960f03d2bd39b41ee0f0dfc44dc880a01b841317eab78431aaf2c539311de0451705ba9847d278808f36edbeead9a9fd6dd2d544282b048db70456b69e4fc84f3626ab589b208efbd96de8aeb555951cb065b00b8411555c7f50977885afa3ad1c28f91d9068277f634777572ccafb3f9735f0e5e3e6d746e9cf3019ee993e6403fa45229af7e385bf5ca704c36301222d215ab80c300b841b8d89a47059b0776ad66e75094d586af765f876740f2f0cf853edf4635c1d0cb1b3a95526eeb4127e18922b3f02ced4d77ebff0009d20bb85eae4825703f34e001b84138b3d2b115351b6712c921f525470be4f3ae17c75fabee27a87291caa105974047920a73514e11309153d9cbfba54b0fcdba43adc2bb6653676ba34103d6357100",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xe8902485a0173e52d9a07c1c8bc3478b9d28cb6216e66de78d2511caf0126025",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xf73bbbd26a82dbc769066550d8d4585eab2fc00d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xc963ef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x426020a53fbaed4fe1c2459862eb748bf99daced172c81961e6cc53959a1c653",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x1cf655c2b96bb2ae1698476761439aab62fbbb3fe94934731b19be187b137077",
|
|
+ "timestamp": "0x6a799509",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a3da03756393f9debb8719a967a67fb99a0a7e20e46dd4e3386850268ee8541e099b6f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b84102a61b5e727fa126d6d280ca8725245e24fd3b206394f0deb00e15cd85d87567446111668bcd8c99686d83f75d24e8dc91a3083b362986dc3a2258fc981910d501b8417fe68d0aa84f043c4e77143420b7c62f69c1c83ce514fb642ca7b5cf9aae2f8f7920a59405beda026016fb8244d62c843f63d304cb09d7eb63638a87a312f3d401b84152705249ebfd8f133bc595391229fcf77ff027c4991df738f3e096bcb7bced7a1e57376ee1c921f47b7695ecbc57b265d964832c48dc873aeba6db0b5e9daac901b84122374beb57edb868e48d5ed926e13ae349b87d68d4dc8d51323c8b8612ef199225b4a4d8ce51e9f4b907171287fda612f91a154291fde8599e5fc651fbe5f89001b841b09e379ca033f96a9a9d3a918bf75581c2329a8b2363c845792347ecc05ac717622d272295e15bed65866436c231ffe0846d6154d053cbf28e53e11549c3122200b841658b438a0785beeaf7787255df72ae96ac127af5f30563471214829ddb6e9bbb761504cade639d2240f8667aa3adb184f88ab447528719fba4b356d93b03440901f907c3f9029503b90291398a4b0acd6f839978f46d54bf400aee9fe1b86c647fc000d8d62a5dae167bd97ee6081f33997a1a2c1beb2f748593138ecf0f629d668c691c0d574d6058e794eca6db47a8994e16e55dedb0da91c50730f83da8d9ba35f4e9745fd066206309695ba0c96cc504259aec6538d592a5909ab1a438749212da99425798e26486c29006277aaf5045915bf6b06214c7231f7cd95a74f8ec2173673ab4a5aacb1e65281f7a725c9a582d6f350b78eabfd1adebf35acea3e9fb0ed33684371e8f1527916a605a08b355d3e8fcfa122d5dba73df479c7e0cca9568cc7f29c508cd2c3b42499391351f820f269a178d8ab79df78a3d35be84e0de0d4f2b58d6090b0aea41de2a6f15f5ceb65aa862ac893667b52ffbc65169ba89064d732d82b76e607a921d9b39c9354a9a2f3d7dd3553f20c9d7375fe6aa5c43fcbc4e9c4ec28c18aebe0f2f12f6759be8a6e25924b11b9de67cedef5213f496990cb6e3590a4d4de35e46517a9b244d2188c3808b33bd59f42b498b9fa4845a1db4283b76da02aca28a796fd231f0f29b4af5261709b60e53a518999ac2c879de467779f8720ce1c6c3c63238caccbb34cd6154b70bf9e583f3e7474cf2368c96c13db4b7bbbe0f0b8cb24dd59217fc94dbd853555f2b5d79fa373f7e79dca23bb5f925cc55c5ebd4d5ff55ca7fabaeefddf5cfa74628113831f2206661fed6a272d31242b20ddb3b61e75c763ff819b7415fee87255bc551f834d83529bd6bd7946902c172e2b6b4755cb2f8483900709060926cf225419021454bca7b66be72a9a3e761144934439caeaebdbef641b6c02473341252bf49a7eb5aab9a719c54ff6fd37112c335c3b46196bf161c9640bf5ade6f234da8a6c765f1cb3222fbc0db99330c1c1c17bed31b7e26e8da3ca324eb4e1a784cd0acdcf9029404b90290392ac476ee4928430da55245e364906b1028ebcab1ba0f5096574cc189df1abf94163c18dbda7aa4dd81c99333b1996ff8cdc2f9a5dce3113d6a5971ccac9f6b57f76199956e6559c9f5a987d522bcbfbc81c65620e336d7a32ebc850a768e8bf3166e902654d04e3a93296932d66b9104a68d5f2d934221ee2e1e6ba20f90b370974ee230cff09213b519cce723170b4958410d6c27c39d58345b2feba4a139e20509b1a68e8a146d724bb729c575f5d1757eaff5cc22d8b6d4ab46731c5d7e19d4caaa5a438898a2f56a292bb0a3e4767465e3c9a4a2a7ee8a6dd6d861c49e4833b810d0dc7e1848793af9a2195a64a69249d83e61a4ef418fcc13bd11fc6b882c9564e24be96cbce947516b362e2447613180b4385c4b39b496408ae94dded32aedb2550821fd0210a2bd71ba3e65ca616d3266052fcd49673d46b96ec01972619c66e30764cf1bd7ddb1a7ed76319e91814d2373cc3e898c49a67dcae440ffa3957e12659f6f13498a5dd98aefac589a3654c57dae0d76b656f665e07bf90a2480f356ecf15493a749a235ef90e918235ce33bf76b28cf36e70a22f62535895db934b97f302fb389a84653350d07b06e1483e350d75a5b5ed7399028d52402abc632ebf6126a9aeedee6f147dbe1b0edf24981f45c306994e60e7390e587f512c3b50c518a7aba0d0dbf570d65bc4ca05de7d9061ee70f7073e618c5c4f85b7119cf47b52fa4b8d06ce50323d7b9cb34ba1e9409bed5ab9618a270f73b52680e25fb5b6aeb061cc39d0b02c24b48fe6f5ad939ef7d2db320aefed0ff931904de59063aedc2db6e679d96d3d3dd6755f4510040b7840d3044e8c4cbfd325115e4348379124601137a24794d7fafa4abcca29ae5dd3de125564e6e6ca6b159c4bdaed738aade5cd337b9f47a7e8740f9029105b9028d391ed87d5008d3dd5c3b25426a958fa73ffd244ecd350ca982d4c0b1c9fa6cda63688cf6ca10d9145ebbda0bec7c61da855543c271b570330b86526ab3360e108c9bcc16ff83b4ed4a304ee20fb07f19a5d267c8a4343679b6b9a67cc939c25a6caec2fe604b67e18b2b7894569264892e77af165058cb030ba9e0c01c7c6d66a54c8f936c32528ee06a070fc16952e9d02cd9b46698abd492dca0cefb9118458213f4b07f184aca878996dee78d9223ed9c0d15df628c4c7bb3136ab34098e6313ab5b87104b28e5f1c5fcc25d3a9c21aae041adda6f12be87ee463904a6a12bf53b17cfc911d67b5f3869ccc61596e0dcb64344c918f93f14cbaa7ab59174dd55a46dcfe38778349ac917f172985658d44101e34a71dadc5617df24d944d88f94f78ac17462a7bd8984238afd85d448ce437cacb937b47bb1c2c6ecbc56bec47fcb76b5432a49c4a1ae8bfad60c02394076a7043e81031653a2a9ad84a6af81e05c22821ab076f826a900a9df7efb1c6b8c4fcd87d28718f9b5ca6791481c967588b54ae16a498f21b10474f2a6d2aa9a2d9de4f4faab3687166ec85e519e694f862a70856319f475a0463cf83d119ad790baee879cc55d272fd5723ad762c55a4d16f49ff4f7da9a50d2fa6eadff5e3f9a5eabf058566e5f3fe1149844336796ab84ea4891b9b79eb598c942937d4df3446c13dbfee67c9fa5be17471070f404c7b55c9ac849cf5b82996199e6e8f758a2389d025f59625bc80c7765a473ebab2c388eb2cc2a5eef421dc28ec957b493fb7a73737330c91cb333e4ba27504abc44a5c4353865d59350f85dae050a29ebf41f664516deb68d0865d7fd6a999f7fec5a36c1eddac6f328df5687bf526a88a6474bfc63e1b2f78647dd216f1e2a77dddc7fe18444895a1bda4c0",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x44f01123427df8a3149e1590ea7ad288423beb3a88bd6a9c9db3fda52d6f52da",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x1bd5514286f5602a6762b0075266379d29af1c9d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xc963f0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xe8902485a0173e52d9a07c1c8bc3478b9d28cb6216e66de78d2511caf0126025",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x1a764c7a30b6d6188dd7e555a5a186f77cb1563098487ba9f52cac7ff849d485",
|
|
+ "timestamp": "0x6a79950a",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-A-7chei-anchor-13198320-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8411af02cc55bd0e772e5df15c9d67f79b97597c1ac75d08bd1a87ed3dbec36b5d51295b9d0ce2642ab30e06dc37367bad1c02dfcf2f70090ec20ddc3b9c0f9c09f01b841f75e8dd26a796eb48621f62d7c2b8fa4d713b5d4cf977338e74bfbc73c3bf10619a88addfda8c65b6e0ad70da3de156d3ea7a17169691e9a4da096708bca3cc401b8411922222fa2dd031e905a65c026a4c66199c3098518570ec5659b32fab40798f6483c6b6c5e69089ab7e102abda4a8aa758eb63a7af7660d2a297e44bff87c99400b84106c90416f15a7d0ab002a7fafbd315d208eabad1b6e799355cb72b86b3456a09732d710ef8bc9cfbd115419366705cc9143ac2278ec4536cecd8c7ba4c6fe51501b841c1d20b0ce4174fe39251407a5df20adb182e57c406e9ad038b4c5eaa2eeff01f00a19e9c6579d3e0ce2308c1ce843e5d9b65bec6c2d611132a721840e112b18d01b841f74919a73ec63f74aa96fd5360d8b8930741f0eced86c4bdec66fbfd3941888c56458af43af6ab9e7a11532b9b796cd4441f88ccdd1c8fc699f1bc816fb0b6e000",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x3a085dfdb2982b745cb942f694727afd942916c83db1b57dd212e53905a3b318",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xb5e768cb3117ea25175f51aa956b48691025c2a8",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xc9a3ef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xe776b86d416bb82c28b1debdef92c4f4d35713f6b256c37e89ea02673b2958b3",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xea4ef19ef4c271edb79cff29daab3574a91dac3df8d605473732c4703eff9774",
|
|
+ "timestamp": "0x6a79b83d",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a42a0ac4583e43b7e13cf2d8b5b49f336f0f220e7001ca2d383524da6462ec5e506eaf8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc001f90192b841bf2fff34f92158a0dff81a0e946d33210ee848b994c1beeb0fb6e21969aaea8c7058d926385085117202ffd075c019fcb469221d997a864fdbd38945260f2d2a00b8416b3ea238105ae82c8d9fc5c49c946c2ebc4c5cad22918cbb9f036a621a629ae70acec9bad3f76943165e8b88f8def9653da3b6a3399add22e34226cd206eca6101b8411ff321917e140d1b9bb7d0b57506158a4ee638f49b028a44043371996963363d5547f9dfe2df7199a5e70da580e8aa20d6ed468a759ffe2fe6cdef47c27d64fb01b84100eb390dd7d9188d7f4578803103f9bae4bfba0206a17a6b42479ea596af81ce22872e92cd6a16292462aa86a4a5276e34bcc7ca83e5e1cb2204d5f84ddf673301b8417a2fc817a4e22c35622be123662b1b220a7ad9dcb25c3931830f67f129a25d25701cf85e2112fb7e3127a03aa810e046fe66ae2452d22c7c6f109c3662bd9cc500b8418db00c79fb5c3d1ae0d33dbff8f3ccdbb2c68475598413a4d3b8fa27f3d46375147a963834476165e9a817e993a4bb8e0f5b89c86be13cb7b692cc413ebe541400f907c8f9029480b90290395d78a75713f5fe1ce496ad7a1047e4ceffbc85844135552a1d580ecbe7cccf299c17268835e4884ae2703dfe044b0bef8c19cbeeae89044c14138bb35ab944669b079cd4f84605e764e76450c3c2c8ef00c0f2334b7fa6977d9b3b9ee489b5f5e6bb1c941d4e4a5408db9874c8a9be22e66c8ef6bb755544e46a488533511cef703fc8ab64d7f95ccf4ce5097eef4b52fcaac55335bf3b959af73894c7289bf2510a7513c7f1749644038ed4b133d6a17e6951c6113a8da9923712498f1599cab5fb89383146fd5c8f4f10d2c12c567fb9c8cd959fb2e48d1443738c3ef038268e58617cadb45e15c0a5e7e45c178f25bf199832ddabb9776bf4b52adb2e688be4bdae6098068318d46fab0da683483e3469f31b3c79969824e7c65ea14537589773e3ca6473538d8f92a2d55e92e770d88ca35c4d54dc891170250ee331984f5022b258aa0d9e20961ee446f5075568c8ce9688fb63385b8806cb14a21f930c492b26aa5d433d0ee42f28bac47f6d0378ad55a0e35c74f2546c1b8131ae64201f9cca6895b074b4b1fac029ee93c38967a7247d926292c854c1943977899b15a54eb07ed9bc43788a5bd718ca1232b5a9d2931b59ac4b55125a9dfc100545d6feeca29c5cae9f618077998448a64f087ee9f04032d7ad129cda4459da594a83455b521bb6cde67aa58e4ba56fc824398a32b42dc7115a38bd1499a374b4b48685b06270ea45677e95946bff6ea38297665f0a46251ce7cf107daf37257cb1c1ae48de11897136cc926ea248590498e1a82392f841ef17656914d233d61e1da634bafd278befbaac811bec84f265c74eb71a5e775d1478203d4fab48e1b5f716a8cb48612293d07ee907db304735e1a3bfd4d0e5b7cfd12ce8aed793f0628332b12f1bee4d57f0a230ef6d96138780f9029301b9028f39ef3590d883b44bb4ddee8970b19e323bba7753f9a75089af0db85ba5cad927b43ccb991143a96c7eac974c24c5223ad3f6a33db2d9c68843a0d9b81de7af8cbbe499562949eb9eecec950ac39f24368cc8228ded099d2b214475d373b1a9f55ea5053baac33087969ccdf3d1e46700f043310ff37f7cb5ea677af5d6a18b377935e619dc49f411bf439047b791136846cd28aa5ab118d551949021347694601e0a9afc22ef77b798ae64191a32f9853738d7dd3edcb0c71138a6564e221db785cd99068b34a91754619868a1d87435f3e7b096af360a1660cda43e1df46d6b0f496e97c8ee764a5b1779b3df364d37264be9ae40fa6d6273a484371e4d15e075a637795c373f0539ddc7de706b7799d7a9e58346ed68775ba10d69e6b97f15020191d0d7a49b3a9674e3ecd5b456fdce34d1e9f51512ab16a56b4a9fa31a683996658e70b5543bfd063052dd897f631542f4611b2b34dd9e92b89158831dd8b228901a27ce8ad4abba2b540cf19baafb0ab31c1d0e31196e94462621f345d8e79dd3499c8bfc7e1097d07e3da6f91ee172bb8a7ff9cd66fcda0185ad468d9df7eeae354688c2a7782afa909996153d976b74f839b7acd1a87c5ce12a4a0ea22fa1687bc4814382642ec8f23a40985afd8fcafb3b2f9e21b5e21055a7715b3c2a771a3dc7f9bd3a8e4e613b831cb39dd1baabc281dd90a9281d3aeb342114994f4291a9618c45cfb7317bf058fd36e5070f637931c371f5d0159e55c79eb3cd8581012e0fdc00c4d371a96d8a4055b176e7727b57f522340afaa790c940722d5312e845288c15471d0057ec79bd5b64d86f04a2c59886678c166aa575792e8e9750b059265f9eff4e2ccaf42e19ef553584c836666d7832efd14e413786275886ec680e41b562624a8a33eafecb08f9029803b90294398517f1331027aff6bca3cfccd10513f85a3396c5a98aee3932ff3312011acdc0260b03e42830e161b5586d8d6214e23bc90b1287c4c5a8982ab0494b93e6828e8a616f9a40263926911b535eee25906952c6999ac2f29186a23bae56221b4c7c2eeecf58a912bc1cc0e0465b8270654561c67a6034c568d73c3018445ee4788c367d2f66150f6ba70032db2cbebd12c79677ae4c889008353de7e56cf0ecf1538fb96181b3248cb4763344cdf8e15c65ffb2242c62ef308e42dc01aad9e1758af42fd9fdecded57cea76dc26b0cf01b54349230230822142460fad637f7ecc55b11853e585664fb5efe5e78560b8d9b28def94e075db7b9b4d20b570b990829366de3094b367e859a2cf5db73d56abb7735f236b14e73a0b7484b73ccb566dffa468a486dc8f95062527a7b0ac4948eed026f3996ffb4caa1bdcf9f9cd364bfa7142cbe95e04758850b246a3a090b5bb66cc9c46910a6e50dd307947c11e7f352d627db072b97baefd77c1c7358f0c98dbee0d2219b5a32ab96d749d8886bde76ed3d418d9c29596c840eb7c45875bbec6635259ee21ab37f0137f9b49e46a2915a44fbe1dfefb2a1c29b926ad7f74bb2664fe3bc8a988843228b8faa5869bbd0756f13b0f1cf9704018024488f87acaf4a0ab563ed30c1b82696fac7709bc844631688b89200ab374d11cbef5f610fa31d875b9d5d7d56bece4971ae94c39fb6f3e4b0a438732768eb66c2c4475ac59bcde1959b07e9de334678b5df70acbb3b954a38b183090bbaf5cd567e4e6b73242185a3ef7cce2c72f13b5d0caea7ab457470257d92437d088b38ce35f97246f6136b1c1d64945fae091ec6c3d19010098743fb2a7dd965015a59529240d3efcbecc7563ceed29b4b5f3b6d61dadd53d7787e57718ca4f136c655656850e674dd9e580",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x8341",
|
|
+ "hash": "0xf187f539f65388b0642161a7bf10d4385736b37f0c5cd88a6d39218e7c1bc6df",
|
|
+ "logsBloom": "0x00000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000010000000000000000000000000000000400002000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000200000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000002000000000100000000000000000000000000000000000000000000000000100000000000",
|
|
+ "miner": "0xdf09b32c761620c5be77da398b97a64f03c3980c",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xc9a3f0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x3a085dfdb2982b745cb942f694727afd942916c83db1b57dd212e53905a3b318",
|
|
+ "receiptsRoot": "0x45e6e2ae5301eff0f18e76b695c6d5cc8a4578cf2f3b979c2d28452e21827674",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x4c792d46b0bb21b03599d01808b00d78ab623571a3d620159f21e48f5e8ef651",
|
|
+ "timestamp": "0x6a79b841",
|
|
+ "transactionsRoot": "0x2adb39fcbbdb4e69fb434c86ca332863b793355aff396329b839b5cb0d66fe41",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-A-7chei-anchor-13214704-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b84102599cc71035c7d4222de8d75a8b6b55ce7debea976ecf681588b1921d01533332dcc72eede37d30fdb898f654b693fbbafaa157381cc9f0df6aadd9924648d700b841e21e21f081eaac8e6afa66eb3eeb0a4eeeea2c470e9043c8c915025673dffa5553ecb6000ddcdfd9b252a9b9b25f497c8188430cfbc76ea3907cbbcf586fe18b00b841c43db1be0b01d45923ad624d74046a6499bf1f29450f31f97a78d85d07776d53359d2787c68609dce2727680660d869f5c298722f220fb1157b116ae0b27d7c101b841377ac264a7d2fd04af3953705269ee7e78c53fdc3d9c71e5d410a1ac2d3aa4792baad00901ec2244776483e18a4107a7e986429cf189b9ef2ef63b8bacded8aa01b8415a30ace89269a382e63980e9a2ea62c8b0f75f9c98d732ccabc11a75b76c28b9698d5a9b5fee800a431b2d36c5cd1d247be0b2afe93ff5499f3088cae78acafe01b841ea649c2c6695c6cfd236b055d0485d7bfc98e1eaa78ffa66b2efdfd04eca9af011d743e34223a370a2ec580436266558c0e5366578e0ca8c1cd0da7f69dba4f000",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x616db5d0bf14efb43a1a123683e3332acfb3bf3b4185361b6e321797df217235",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xb5e768cb3117ea25175f51aa956b48691025c2a8",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xc9e3ef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x5972eff91d310417c29b09602125b84e99511464d658b990b25c2f328634d923",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xf9ce55e7cb28beb44b486a83645e7a99353bcdf0fbb94890b1532be7f88b8089",
|
|
+ "timestamp": "0x6a79dbb7",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a33a02e3ffa2696a8f89f37e84f9ee1a865eee00962890e3283fd42152efad29b6896f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8412160bd5316ce90f4f41fdf73ce4a6382b307dcd5fa51386ec60d13acd815f1773bd64371f65f0de58f89ba385488f8677adc5ae946fe34d3e546012966b71fa501b84150302e53ea09c4d86d58e4b30d26c7440382f36d4d072e7c57bc655c1d52e74b2d720bd99a98c21b7d3c5b5fdd2af18e572524f4502cfe6ee3b405cd677a7d2e00b841e246d3f3667ef086fda8bd3c676c7047caa51a86deb016ab9b62741f4eea12e627c71042eeaff198314c479d5f114b2220399b0d0a1b88c75ddc00b9c5b22f7800b8415b86c9ef27cf8d86cd28813e9e879a7e7a257a50806073ffe80be5d32baaeada38dceaf9cd08f1dbbb893b025c057ad36e01a18b3aa8a5cd13bd429faad5842700b841be7223918bf7716c5201d49b4d7d4184c855590848cfabaffe297ba3ba7d7bcf2abedf490a2de32aa7e1cd3b3511619284fa6c80cfb665c554e20fa6b0a945ed00b841398978bab1bd8f6d3a22329b9802339ed3eaed2006087008058609c11a22b540144626d6e6e7ebcf60988aaccdabfc954e656683bec6170e56fc7a558674c2a200f907b9f9028f03b9028b397bcdefbc58a8551ebee198fa2858f3cdbf319ac008ddf983ec89f1b3a83c96c47ccc94bfb8f64cc99464059f07d6abc012bf34ba2fc6b27964fb84291e6e740919458225fb982e8f1bf25ffebc5ad70f5b2fe07830d452a7e4d1e1bdada2ec5abb0fd7ded5272858472f6cf326fec8423f14f1aa0a2549d7478a83adb772ea91baf9e5cfc26457e44b0e7dd057e172d729d4568148b3e0ac3e780287634aae0c5c812c98b369fa3c296aa5c6494e133da687b7274c115de68fbf107a240c937aa06763572f01f0c0da93e33736c5b3144d6b12b70bc61585f95c64647259ffb4c14404f2e97895d209bfbc54f78a17a53fc364f10438e873ffff6aba0ed6bc13dc913e3503532ad5a0f99c3232b12bd21a4d1d9fa85de3b31404ae466cf102d7cb996faa5af769902ef64c2de6388637dffd030fe9df503cf4eb1b56c0c108834e8dd8a292e583c8cd9ab4fd0a9c77932b4c15dccd4e8f1dab952561bef946a23f054d2ae96fff6b58c5472a5028fb5fa2c5e8eb6e3edab32f2a52c41350ca33b998c7927fa647b8f8b388d11e2ddfe65094ef517185812508189540c66a16a772e49b570f6d0955258b5249b756b05f1b8ad35d498bed8fcf8ed52d1357c209257373ca742335faf4a7664b9733751c88aa75948a16871e709062e606f27ab4f455ed641f498d63ec5802118a24abceae402c1b5c5f3228cc335accd9a28059f3c6af2bc8826a50cb5e064047888c026c796a51527da130aa5ec392c76ad5b337ffce971d296c5b2146828fda85b31c6abcc5739913ec5cbaf5cdd5c469843657e03bcc2f2dace23eb9b38cd3dd70cf542308ebd56632175cd36e61891adbf6c4b176a40215817a1a0a4dca030a91ba745f8c7dbe5669959a3773c69871b1165207511d94de319fdf90f9029204b9028e39cf204686cb0db78c331c3d5e2b94b353a47ab76b1f18830d992b3c5a006c34dda768187ea6b0fd4e00803148bae128abbaf44ffd2708c82a3a952dee955b6c506830b56595b594cbc6dc162243e9612617e96d3add9177f4851536e9f0f7d6574d1bd8ad6e455ffba0380d36fcbca36dacd43348d2869a2292364b950e8533a5bf3849aabadc2d9db068737b4445c9494f1fb920dcd5a5f01de7da1be7eae8eef345e4542bf8281469b0883bce9c21fb661cb6814d8d777a5234ff3c82ee9ae21ab6f5ea3163b6eab9d5eeaf68ebf2b3156b24054798e1e069fa95e273e172b67de08bfb28e5431e8626952805d3296dc9cd531c6b7240579a426e7b474f324e1a18d533ecef24090a7082a5ef85da8ea8fd175ddce0a11cc845ea012f3a5e4fcd0a65ff630d5db4c25c2f3da83bce5f5b4dcd2310bc72dc564ce644e48bd411f0736d65434855f7d9cbff46529f457a4832224f91d775373d9a9c6a3f1162efdfecf52cc3130492f8f7dad8b983234bd839f44a1cbde445785dd9113149d29acb996f83582990cac5ce7154511a4ed6ace346564e9c375588546e2e2e64caa57debe22188487a7db841668ff275adefc70504e0b810f23aa8f4ba0d3303e6762a7f36fd55cfb86d02a1b9b7f96c50e3653d92661609e2076a4f77f142dfa74c516fa59e1eee1b0398efb1714abf3bbf2f7e91a70a802d0f4c267837d224d90dc9b39309738b859e339935cf713ef0459a9a32b4a01189b765caac4d21c6f52e98e706753fe895e9f346ce29759f0b374ba8cf96ba4286c1d6a3ed2958ff69eefc6460cd69d3bc25474fbd49163a95cbb9777d98cafea64043baad07e8b1447f7e6ff66785dc6b2d495566153724a5af2ca2a8a987be2f386ce3c678a1e90c9e112033e9da506a49534f13c3c0f9028f05b9028b394bbe84075c0ed411ddcea6c70ec3af8788224218832aa40764fccad9aeb1d79f1855e7f29d807421d554511612a2efcc60e2708a2434ba2a1efda216e6791058eb6a3b85e7bcdf69cd0c952a3f50c372d5f6f1ac5b9bf9785717fb5788ed21fdfc1c8ea7d1f7cadcfb0b1ec29a98e3b0c3f91c5d8b7b337b4a640928c2a4f1fce908c395d6a6ead9c1753db2f4ff58ad3cf61f937a71d0c17b3e5dad13833830facd452b109dcab6ae13a36ac153269b0c2973f4c2564e9ba6ad621a4e2f1a3cfee8e4a9de6d77ac513ab8de41d9d17419a926b17564249efc1cd7bf776fd12ed21584475a48bc17738eb7a6552bd511806345f937d53ff024529aa84b2bde9ed33a8161234a5e9d87fadb6dfaf2c9039e5ee9d8dac5ab1b4a386452d6bbc657cb1a53505f58ec6c59186105462e3b1ae57dbb6d1d89c9e57bfaa9cb0d5190b3b89ceba3ddc19b1ce65e9512332ddb717afef0da56793549ea4619cbc736fa39977a1b52cc635068162b4aa0776014591469f6cd4cabb8d82f627902964098c49d8a6ca4ef0f4a54cc489eeb49a66e28b7ee43db83c7e09c57e15184335dbd437e57049395067f2b194db749d4d12bd74beee59b313279ecff03f2cdeb5f3b0ded4347d8d6512f597549f403cbbba5892c1df564e2ec3d149e6aad6ed5195482b8d867c6b791bec925730403698ad93a57dd2eab2863a859c5bc81f19769b3b7a345982633697db973d9698c77bf69a12ceeaba721d254a211e5d9fb954a0da5ea9c8663511510a4bedc9da7f1538f041df24cd474591057c82a3ab5b49c99e2155285c8a26da8fcd2fe6b94879ba394be167429b3e75c39b167d3ff9a3e35ac57a741ca361f8d17530ad0425f1e72106224ce1cde5ab150e62aa36f4abf6a2ecdc0a0a45dceb7791780",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x8022b49f6792555a6663b0d006849b06792b842a37fa6d95b3bef01a73513a23",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xc3314fd768bb68b986e80c0a14175f6f72630d7a",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xc9e3f0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x616db5d0bf14efb43a1a123683e3332acfb3bf3b4185361b6e321797df217235",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x4958e0953632f2286c76d834183899a80693950ff176882ec62901d7b5e1b8da",
|
|
+ "timestamp": "0x6a79dbb8",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-A-7chei-anchor-13231088-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8415067d6ac795ab9e5af35a56bfe70ebb2193312a52d84f0989ac933ec6aa3613f5caea07b519c15e5013795c72239ad16f0886e478f91ca205ed04de53737817300b84182e0ff371b382e95c8070135f12f60c92981846f3f1da57daf1e275a29bcce0a63f27435db23fb4d79db549083282ec7ac44fb73cfb575931d3367e0ce3c6d7f00b8416d501b227059b9fe3a1905fe6a75e8712e397c6d8e575657df57c62b97b17dba5b70f7b63d9444ef17cfe6c4291b300e66576876d46da73aa3c1d3e55080a6bc00b84139b02a86852b69035fcca72205c4b35790fa27a1537bf7a61497da9fce47aa7e2cfd3d07b6139e033a74b65802db94a84796c3b184d68c37ed45ee69cb432e0e01b841ff51677f8e9100c4819ad07f0568249e5582f01109500dd98abbe611fc2ab76c1acfc7a0a17724b8d556c194c91e0e3c5297079736c2debf5c909abc2d55368100b84107b3aae736c24fd4cde08ed9ff9c7a58376ea71defdb9cac8144610a1ea03ee70e1683c0e1c332dd23ad9f9af95ebeeae05f666126e2a7959a4b846376ef95b400",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x226af30db5c1c8b324396dd10c04b7fb2d94dfb501d30ae0aa4ea3738137e6d0",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x4bf6f91d84b37454544279cba152581ed6820044",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca23ef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x01262d7b74756134019d6fc54b6046aa3690ff50d1655a884f08b550d4e470d3",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x569d3bada071fb866ecaf82d29db4e3fbf6bb0ab78393219006affadd55dd050",
|
|
+ "timestamp": "0x6a79ff57",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a3ea0d0b7b4dd8d3c80e8fb4476491deccf85dceb305db891b5e58f6ce2d9feb84138f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc001f90192b84178924bf012503d351d86f3dfd2d976356137cd75b7fe92b1e9f9bc5959496686366a4c4963576f209a1837a98ee128d8270c463210f1608c8544090c7f869c1700b84184a38e80e2a83bd1c5762e2793cd4ce5d56c48ed0ebbf828d8df747f844d757429b568e926e819804117d492d250ab40d77e662b2a85b7b056e3a62985cd399e01b841ab158db610e8c6c1c6f5e0f557af4e898e09213c774fe6f81c8290d733fdc83c24dd1946a98d067327d94dbb4703a5b82b0a1abbcd17cbaffdd35388906ad09900b841467ec28b4a6c7ea3e79091cf6154f9318fd109a736afd132d5ff15ab9e6041eb565dd022862b47bd329f6ad8e3e53416c9c25ad03ff556a89e11aa974db6fd6101b84116fd1a14e97fcee9a8cf0979cef52b9740e50bd2e78109c519b312bbe0cd5d9c387aa94ca73bf4649a67aba22a3e260a71c150aad0b65d282c66135c162efab101b84102881bdf70a8136012e7d77801f2222163188dce8e25a68073671fce51dcb4b527f9805ce4054730e560120d824fa4407da3ba576157e2c91c18ced364393a8c00f907c4f9029402b9029039fa7564a578254c3b878d3873d2bf49309c53fb823b7e6cb8a5bf29c8cc6c36ed8d4b8e2c446d69beae502ada93559e90a2126e7ebb43852765e375b39747e0fbe253b12536fdc6aa756f4216ddafdd126b3588911cedaf541a37b123ec96844b3c7411a40d218c09cc2d7a9cfedc924362c1531e2830be545a1c75a89290df76476a449b38a6e1c9d99aca23d50ecc770e0b8efe2276d345f666a7e6c71f06b669207802af85183b0cffdf03e4ccf26a9c0e8bb9c112087acb07a1499904d3b74d4551964379b61fd98779a14038f8db745e946e59b894d7ef98819b68f52aea88b44b533a8f49e78fa533cef1919e7a7aa2f6a21c1a5491de2fc97e61b9a6aa0f7a18d7364aa6cf075ccbb666ad16cb47a531b591901c7acaf6594aee6bb15df332c3204cda5c3e13c4d66354ea1789ecfac565a84145a6a69c3b9e4d28786eb20532698b6da19bb5bcb649a257f098323a756d1317ab9c5c8cb1091b6724e02727f5342c7604678bd0784f209eca9a6122fa726e09f71914f968756e3c3a16d3b0c6e5fc60129d47e66ebe2618db26959ff65c728e3601f8a4b567f6a93fc43116669641b04f90482ab5a69853eeaea658c526e9eb05c4f08513cd18cc45a737dcf6faca8144927d04826acbf557c863a4dda8d99b6dce1ce32ed519b334e07d2e90463dde57a552eba27c947ee8994b3c1726891236ea0277b706e52f81428b3ea7d8e1f112d91429d5409e8d47f52164f3c9da660bdbfd4b97b070c245ae5e0b5e07c4fde1b43e0d98daa733eb5ed9b29fb46398c2f61975e5b3eb6569df01aba72397243f31779dd5f5b48274d52dc9bc6ed5d3300e85f4b7a231b7db11ff746f71ae4b61ac98a5d9d83bdee03809168ca21d88c9468eb81663668e4c1023a4f033d304570b4186cef41589b4f9029704b9029339f400cf85dee3378512242991713b9d01a5e530509258cb14b48677f26cbe437b0241ec51c60cfe24f3e545957c97fe38d1fbed6d8da7f89ac8d658e93d398a243712fe303f88d1a7b5de92b9aea95e7ecad272ead3d510b6e496dc118cb2e7e9ba46a95ed3b6b4266d23d55d6d594d924acc6818faf7831a4273be0ebd538d3d9614beb29ebea84acfde3752667772da0257958938df68624d17a5e2042f0adac718bdb2a8bc69eff7efec05b1bf6c73597b14ca9450f6329f92645c66ebbda52640e24404eaea7132de229fd68ad93489ab5883d27667ce4856154849284795a67d802fcfd1505521e48a278b620c950fb43643893cdba1524c020226cc633e82c59d8ee6c133476531556d3d94ad942280c41ba28c82a101be8b1a66a48c539dfdf2cf07b6dc29d172d787b0a4c2733823ac8333558e4d0e33e9e3e36875e73f15c3c51ec4618e532dc71a94e120a26f392d90ea5c7911cd2f3b63775756fcef0b885bb1759b2f71209affe928124e4f1fd70fabd5b5cb23c85a396e306cb72ec1d5cf8e65bd1520c9ba0bc19563711f587d15b596324d7cb19b48c98f38481ce36c8f304d5d0dd3bad8202f5687b136ed40a1b2a4f0b8514d3c309d1ef5591480d458596632d942d24eaf37d802eadf1e25037554bd297ec63f498b9d5e31c9977a79f16650643ed79410c5ef16daf7ebe626b3159560da924258a0e8ae01abd0b25e22185fd1bae4a2ff955bde0f14173e2f53d5bd1f33cb147b81b0a9491bd94c3308cfbdd2f6d558e5137a02312667634720d72f7bd690408c8e30cd45d678ddeb38300a424f4266df8914a2d4d1a1c53b8516e15c582441089abe7190a9ec0f5680e1f64cf64c812d5e992b4e6e7c71d77f3719ce4ea23ae67d0f35390627f9428fa24f1bad8581ef1ce7cd85c940f9029005b9028c3958711fb42cf820de73be9d4192034c57883948fb53fec18c26c2a3a0886af159e82872607e1c81543d8443605c9410dec68cd40d43acd61efc9ebfe5329776a1fdf8a61f6c5dedb82375dcd5a0167deac0f2b9621f57f4dc25f4a97a45e2bfff184f4ee2eddcc52c5e024ddcb0432fa6e8c0d7f0b97dad417ad3aa7e3ca1b697781bff459ed5cb8d6537d877f51bdbb68ce4cbd2d313fdbaab9c67b1f37353ca1a9c171335a760d807da66ce49e3130ebc3e09f65ad2ed95bf498b9fe673abada370924cb2250fa5818540b6cc3c6f7293c91ab784a13704c911c276952f0b4291e75f0a62a19e9a6c3f33140a00d621ee4be34fa449c92b0a5812156b201b4db35afb6927c992ffb06373e6866c9d493d2d6990e2625dc4614184fcb66e1764a8eab634cc63349018ae85697dd02727a644be528e3b158dab3a9293128ff1e99756a0f95c37040c8344dbe6318c7f37cffd25c44eb23682788431ea6727f1f34f27ee87f184cf2b7198e35a9eed322d2e132d68e330ba94ba2d37f63eee6f76cbf4d4b6b188dcb6a0d97bf96473d7cd66b7b0e9aa4ffb68b0d88557725e7074658ef518bfda60251a97573c4d84b03f0ca3679644684d442a1104d8155756a9cee9d0d635ed34a95bbc7be257b19b4de88d970512140cdeb2a6ed43eb8f9a933122e49a8c799a5c739778402290caa3bd7cb9c0706c3acbde3297be43831c655ef84d1274f5e059d6df20f92b3d97ef717e515a88914a595e94af334e619b3bb694f5177b07126cfb519e6df4c92fe4d05baa58975ab699ea5cf11c248353533e1b99f46f97919db8bad433c1613dc789f429a89930aefa7d69d7972cbefc7982a520e646b2d3d90f0282707ae5ba3cd1996da2ca8f4eaff901ad4090eb93369fc17a7e5dbc7f759eaea0",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x68171aa479019708e5e62ba9855aeab8ee8c76440b5c9765fa4bfb097bcf1db0",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x97473985d04723299559f49b856effb47d7abfad",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca23f0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x226af30db5c1c8b324396dd10c04b7fb2d94dfb501d30ae0aa4ea3738137e6d0",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xf7dad77291ba6d2ee81e0222b1bbbda94de8a9de6819f0ae298972bc1d0e229a",
|
|
+ "timestamp": "0x6a79ff5b",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-A-7chei-anchor-13247472-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8417c3fde9ff7d4342e27cb063247f82a99e42d21fc529ab685d5f3dda040d3897b51b1db1fe29c81d4da8c25a26e1f46ce34bfa81d54eb859c3e3fe93fe76dd68c00b841fdaf3d94429317423c74bf4b514ab858ca3571fde06e29c359a4c57041d79606796e792139dac07f7dac1e744400c9ed9bc28d440abdc1fe008e9a3de4665dad01b8418d465c6013284fda736a62a10bbf59941fb6c688e7ccfd87a7181af9da8a36db515235d892331146f49579563059ffeddc2211096eaeacda1bc7ca53343857dc00b841ba6965c9cef9f6aa8588f42a2384fd31c6e951a81dbac6c0315cd21db536bb2a7387e15a567b7fba44775d008ed07e26f2d8a4604b60822f33abdedeae9a2fd301b841397a695c6305c7eca63d13de07692032268e93c5ba3be484401daebda70fed1230eec24c334c9c31476d1fec4aef249ecd2ba8bd888315476b7918954804f97000b8413b8735c7eb1cb795ab1ad33e31a69e85b92f24bcb36f2894f22cedf65e5c3bcb5badd071ed2500c706d0b23414ead650df186de37c212f8f94abc3ec0747b1b700",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x0c6249cc8c2696fedc258c9fe25031c309a69ff5a98afe0d75f462f84892f944",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xf73bbbd26a82dbc769066550d8d4585eab2fc00d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca736f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x579eb58c0e30d394a5c24c7af542427036c36aea26b0f612e7e9df722ce3558e",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xe3c6f8322bbf555693b48960f29263c9e2fb1b5d54866e69d55b956e9aff5ddf",
|
|
+ "timestamp": "0x6a7a2bf5",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a39a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc001f90192b8415f08d982ed0b0a5b9c06e803b60bbc65a604f53b008c4c0ed7d38a9a9b9c63eb3ef11bb3067af2b2a75232e3d7fb83fc7f2915bd58193181448977a1d1426e0b01b841f64b1f24665600f6f79c8636d6bba2aa293c69e1de9fc37cb0a17e25bba939c248bcf986a91a6ea5bab5b3708095931dcb1c0aebd535f3c574f1601e5a5aed7201b841671fd4be7450fc9181f0f90a28f9a0be1da6c1a49b1d985fd1f7deb4745560c728fd599a8aa83891ec32fa1691f159141c9d68b44f714fe0fa4317834128b97800b8414c178a0fb8854d5cec142b0a38f1e119212c2704dadd0b861e7f2822befa9bc97295fa77e96517cdeebb37687bdeafcacebc1e62f43e1cf89c8715922c2baf1801b8415580797691984bd03c96fc6f1c2523a6fdb58f5f5ffde735e7c86e8b849ba37541eadecfc95da24a8185ea27327b5c2e23e8ebc63aaebcb59c611c14eeab2a0d00b8410c1e0e35bb3725bb480e9858e8de56b5756de22b104b09abff0a6489bd13b2af78aab70352a267ceca41e8279b6f5596f4d104f3f9fcb857e38c58803d09c54401f907bff9029302b9028f397e46d850639fe02d5a580ba06aba3f344f932b7ecbd962a20d758af765c80b98534a52d1be2de10aa583a71714d32ade22fcd7e759eb3129f5407712ee999419b4a7390aac9e06b8e851cd2eae32df7b50ee53a90b75b55d3856008c7493646a15e76476906292e7b33b463250841836a17db54690158b9133f46a94add1aa8b6da08719c4849b552e1a72555de9c7f9ab3212b28872f137cb9edfa9b5f8e9d0ca66bceff699748dc0aec2d71936896e42b30d8cf90e3ef982c58b428a047d1a43b93ca6d118585bb31c6112f9264504936937bbcfd52d4760cb3b31a0b44a61265f7c7bb3a5111847639f5c510d395f996d99b5966b2e148e7d21de8e768bef2789dde9a618d527152c85c049a4c771c9b2c378b026313ed67ae7572b5753da5fe235a663b37564b70561bf82283b9c9b8731ca40a059362f50beb4e7129afbb33ebbdc3b68c5e719c76a97484e3475b3ab264de66adbc8591c8482051ccda0e667e8c81949beef22b0564dac77c1f59f69e0b3d5ee5f81628496eda2cef2a6fb28a99cb6efb7ba5b1e12739a7d37ac416d6ee49788d0f6e112864a08cfd755ff86da0530520c2fae75b8448e052587a1abb06e76973965aa791f938d0845a9174e855dfa8fb053cd7c00ce891667d7a99c61ca137ecbb9f16862a86b5d34abff5a349eda6dce53466aa3afd65b168471f96492dd9f539eb6a31a9775ad0a5ed768239c68e60bf085bf7b336c40d5b6afc591c67adedcb95c5a7ae96af1c347d7f48d4b779dd29f52a6723db558ef6a7772447abc38f1966b669599b0abe108cb289aa37dbdff37b04d0da2a95c5d9ffe368a1f8112227ea1a5c30ab4aafaa7ed4b5e94eba76dedf12bf85e6d57e7579daed3ed3f7cd3a9dbd11b937e9eb5510e3a9478a383b4749a27226f1c40f9028f06b9028b397a93d74d3c71de9e34f9bea196cf8b7f5e571d325e28590acd4974dd3f8fa373076ba4ce2577460a1d7a13395ad7e7a9d118d7ef756e55a9e993a3ebb5bef2fe678b93e2abe4d39285349d4df70c26235357a5a0bdfaba8d9a61089e697f942bf779f547d7936e9c6aba58f09b76a05a35ac1f2b33c263f25c7b02d94a23cd0dcaef0c582990defdba1795f51903cf1722ad15af50dad6789508cf8283ab215004dbbfaacb0a0ef3bda8c158a469ed3f1b128ceae0cfdc292985ef53553d5e85bf6a9f0ea587da2a98b4bdb3309fc96c599d5bd0d4348aa249cd27ef8cc2d54d12eb70a317621291b674086f5d01a7c94649c54d64524a59eda8b00ec259e9c639cbc135c8d93ff36e25111db4e7ffb9881f3a19618146d0764aa283c6b7b4769a81afe5caa4dc4e45f34eb66c3712694f38c6a167cdd7cc7088231fb8d7dbf5f31401174825af34309f736b923bccadbc24578f8f151e648f95ee1d45cad0740396472777dcf4bd3b5a7bba798ee538313d33233927b59b3bb0f0b24bc652f9f851a34a8a773e505c6ea44f74bbc1f62a910428504ff615459d63d1c21483a6ec1a06bb6352c797d024547d2d2c905bf5ca32a3a39d1132a8e4f1cc1683ed8778b03cd9f9cfeadbaf0c6601fbd85828bb613cd0a49af20177c0a6b3aa46cddf206fe3dec42190b6af1ebb617afe7a3bce2a950f773f4dc6c7d45bdb0a2296ebf21123936464203013f48214021cb5e3eacd796ad0a5d24ed5b53b232a7bddf1ba62481aa7ed8e4bf9c2ea43ddeca258a0e82a129864ecb47f7e6a1d5a82c03c8d54594f9568639b138d9a2c1014e99ed17a75ef021fb8d355bf3392ed09a97a1bef54e75b1bbac1c97b3bff6eb9f5dd365299e2b0347fdd611b6496c6c1f4de11df5aebac6d7944d6b9f9029401b90290395b67bbe1dce532045160eb78703d7ded3a0f9f44d7679c47f8d5f743fb3237a3d87fc456b19db03a49f865934b29b46e8761849f26665488c232b886f4f811e532651978d8e7bd2eb1dd0b7c694539afb34f219927c9c29f04df371cf8632fe4673c79fa1495a74010fe0994409eabb578dbee738db55174f4c8ef889edf4b3315de05770d7dfc25ac9df9c14110d57651b36070556a0ed9089b6779f92af53d996416aed1ca433b0ae0ea6e7ea9eb0ea2bfbc5abb6aa36beee86b039b7be932e59b4530a84e0cf5b60edb507087077cc23045967ee7e5e3332cc6a312f9b1c69ea6cd90e2474ce0d25ef5e15c6ce67df82b58dd5cde64cd8a408e56293edbd97d935ba52c82372c96075e92f2d0bd42468e2a99da4b9dfad5c5b2f2e2224a3e1d3ba64c6a3e0b6e1b831e18352af53fac347d4cfc01ac545315293b2b05504fe6a9f323c93248fe493763b04d3a0a709f5ba405cd40ea7e5c6348c1db27191c9286d81dfa71fd67fca4cf7b48645007637ee87289bd3d41f021f17a725ce409fa3f87afac7ba4cf6b14a71b1ab57bc123d14bcb6200eb12e401b19e8902f498321c9e0429705fa5991682fb8747cd3cd5e0b4a0dfa83133a4c3c6e0d54aecaa578c83c9a8f02df48572fb9168d457f8d4f0314cbfd7da45eb0ea6403a576a7d362b8bde647619ed3262f85258960a50eac4570a7c64ed662434442a0383f25b6b398cf21ced2624979df319730e6dfd3af6790362bdb21c3d4744be67de0f07ab0d1caabbb7c46f02c018a8cd365c8c674ee49594ef64373ad81f7d27acf30d421bb9dc4768acb6b979f96c545356833f1a7ef2d1838519847ae7a65dda28e909cf936bc3ebc64eb9872e6b65bb6aec95031d40d117ac2b4b32cfc0761fdd04e52cffe62a874a2dcebf3f52057880",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x2e80f",
|
|
+ "hash": "0x5048e837440f072ce6e0c1be04370abb62a2bfd2f5612c0704eeef46b64d6ad5",
|
|
+ "logsBloom": "0x00000000040000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000400400100000000000001000000000000000000000000000000000000000000000000000000000000000000800000000000000000200000000000000000002000000000000008000000000000400000000000000000000000000000000000000000200000000000002000000000000000000000000000000000800000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000100100000000000",
|
|
+ "miner": "0x4bf6f91d84b37454544279cba152581ed6820044",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca7370",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x0c6249cc8c2696fedc258c9fe25031c309a69ff5a98afe0d75f462f84892f944",
|
|
+ "receiptsRoot": "0x680d21685cda7bfba14ea6b1313d7409149b4ef07668a55b4850274128829bea",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x9e9f7bd15dcd563a30fbe250c899870086522be81189f0de04593534012a9058",
|
|
+ "timestamp": "0x6a7a2e13",
|
|
+ "transactionsRoot": "0x31254d9e400993f1e37c31b8c695715d66ae26bea46b7f6148c7ffe8b2620629",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-E-reguli-oprite-anchor-13267824-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8410991e3c72541d8494161f43a2a7c129f4f02c515148c0a8e645d30dd4feb238b1464871108b8eb4c6d813d9d821bd9c13a6b2015ccfc90eda04c94e7828c618801b841db0d227904d8889625c920fdc50a57d763a45b4b50da79c1bfb8d44b69cd72910139560f865576a0aa52bf61d942b493339ac1c3599c16f57cbdaf83fde7182200b841adf883e0572d499f5f2cfc5b027e8447ccfb3b093b1f9153a23c6ae9cc3f6804135777f1c5e7eab6e0e8d66fe93b252bef361940e4867e736eeda4f28bff697c00b84107dd68ea5db54e7270914fd19200167d62f0e35f4351ff90eb3dbf9914d952b616cbd52a5f3ddc6df69ccd6678a6c9b0b1c8ed7cd1870c0f63245c7ed51b14b101b841f050f8291781345e5d4d58f9aa4017a722d36174dc810f18e1425da42acf93f53894ca9fd0dee69f4fc851cee49253ec1295ca02f5b5c7ca3d31df4689bdec4700b841874dd2bcfc69489f54261863aa569c837dc0b87d2c414bb9eadc974de3a62faa3705f5130a37ad13fd7e0545bc272212f1799b44622e9ede096995f9afe253a500",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xa451975687b58df5435cb25a3320530baecf7f14f8f566149216f739cc9c6837",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x5f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb0",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca73ef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xcf1b1b0f13cfd06b8eee35c84cecfad52e7c39ec479ed956c228346d370be80e",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x3d4d13b2b11d76d9707bd424f7998fc583b5e92383d704d9a88496452b3bf6e1",
|
|
+ "timestamp": "0x6a7a2e5c",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a3ea000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8411078f6ac915e2b0d59be25a971931e511b95639e267bb94d3933702c2ec424da4c34bedcbf12b85b78426ca12b715e29b50bee126ffea67fe446e159123200c800b841f512907ef84daf54d10a9c8e110c5ac41acf438f51ca1e6041f2d0d5e13ed94114c6bdfea23dc45db6db97304b789d3ddd0e9c2ef6a1bcc63a68e0d9891ce8b500b8419e94113c80365426293ef8d03db56a5c68cc313f5d63984908f8c3e6a4fbe30b0a93e34d73ea8e6a136bdceff915e1fee87288ecfdc7f1dbb16918d7cd7481b901b841251adf2c53ddb70771675966cbe1dc6ee77682c44fb3de569a5defc97b07203573bb5e124345c4845173a2f97e604f30f91e72623fd069c452c28e5aad27ce1600b84106e3dda41e3766449acafab09df03e35c101b402eb64712220de34d0c166cfee12982e822a60e0fb56a94e810c50745c4ced83b528a74bac023a853081383d6c00b841c002fb9fb73a346da78414dd4615bc248689a22c77b2ea1643a465af53e3227f733aafa4e096fbffd93f1a1b38a616c66276ebded369cc3519af6bb87a34e4d301f907c4f9029606b9029239eceeff3f19b9ad3a5fc44f8b8e836a6bb302abe465884f94cef3f7c6643dae951dd4f1de019c623c93e1171a6d115dd7bdb72f56e0dda9ed5618c525465fb2f413349cdcb57fae9fc3ff3354550d5526a7938a76106362d528f9d712b8e71b959d57932751f6bf7defc0c8f28700eb4c71bf265b07b0bad0b35372db56cb252afecb3fc5c4dde52409a6399026a33cfeff6bac69f298b8a834fc80bb6e935cf3d652250924413d0366e61a0429d4ccf663abd7623193af971ecc956a63b056361df09f34a27e83c550efdc0bcf9d610d4e4d9ab8e6e11b9cc2568f2912164ab26866ac32899560ff4c43982cb838273771dac0292c46349034114fcbc751cc5894c86f0a53a584cc2e1da87bb53db2a54afc68f02a28f9fe63eb0dca1fa0ee429365497333b0ccaf35492d184eabdfb25bd7e53e22fa5ba64c5a4c92c00a44d2707e2df024b6a5c9475b433d05cbe90c7cc70a906f05ef9365d0542f44ad6eb54a0859c5923e67f4748c7c9fd2b3389907b3c89b2952baf370629aec2e3f6326d465dbb9e5446aec0d0415d2cdb174e58ecd9e36eef9b275e1559f67b97340963be72d2eeac5328cb139ba2854514543b80a449b397b4391440097769dec7ba7182a0bf7c2e965e2cf36e6ae71df559a769147c46650d360cf8f0a7ba5f5fd7774c8279a51a0644f43ba9d3d18d7e9699ea631781b0a416734b96206c8b84990a014e82fb63aa2bb4b47876e344b2cee36d13a5cde26699d21ac3bbdc38b258b2ea5892e48545219076109cfabd514e0d270292dbb51a05292965d2bb82975bff6f6750fbbec9001541c18f9fa89274c3e157a8e250459a4793bed47774e51da15d30ff6f2b0bda6d9a7d72f5631c0893f945eafe09364f427b6608192b4f705a43d31c586e79341f395e82163735664a9f9029080b9028c391162d6af9811a66fe30e351e3520c68c78c1e6a80cf6ff242ee8ae4ef557ab284fd456bf8f32c3b0461223b71b71bb96b9044ac50d62db0ada6a8d7221cee2148ad69e6d8618e1435e9b2a518d89f08fce991598c8102d830f9c9e363466c3ab83517bdbac9c3891bcb5cc35a1edcd0a7293f4feb3d87ff79f0091bfac82a23c02944c09dd798488c6e69a48adefd8b724d4467dd659fdbdecfa3d1380951ed499fb846f23713e3f3e2559eb933f2eeb8dc554e10d6d6e72a9cfab560b271be17fdc98e28eda6c38642f379894304f40cb36672e8a43724e5a03f394e5e24e3a65936ef5881fc736c7109f2d475a7ca9c632fd85b6b1880446304a07dfb6ecc24a9a2554c6d36a1aa762eb81df2eaf32368a7e1b13accc35fc1ceb20e26acd11ca619053bc37d53e520940d95a20b7b2e33a621d4ba538c2a066e95cc2ba0c76d7bca2a619832a1d742d22cc71ca79b047265cfa54f540ec7a266918cde249cf9925ee291cc9625feedbd560e85c95fc395298a97c6512e95df625535b2f7688b5afe59e4b9835a91a28199c975cc723f48e1247c076895792baff557c33cea3ae9f3431d2d5a55c251dab771e378e723113f78e2d7fa3227c6d2731e7df20ae3df225b6b160d6afd317d0a26c7759a84e9657d66e1cabe699b796e56b0a035d3b8378b5ec860f4a97a5bd8ac61e02879ad60fc19064600a9c8d3e953b38c58bd2da29db463f9f8a44b0b67ef701451b38e7b65111d1318b9c16e0ae753bda65e5e283e3a1f10e820d262531073557250c4956b3cc712e55e89fa4793c597b6a5871d56c75048aa324e7d820224746adeee494ebfe29d6a125df2d12c69ba4665723de8beb64378ae795969db254c8910efabe1da43aaaccef245c1caceb63938bccfeb1a27f3043d5c892f9029504b90291394972b8cc804173e19f2865a5f1ccb732a733428a34adb04949703b93dfb070527134905c1f63598e42d34e730fea653f40c5ce66ee299c030ac17dd41e0ea357d4ca7c5ea98c564cecf56a47ad36a95b78684c3f8eb53124225aa44307c6ddcc47184b9e5487d69d0a0e53d6af7f6a4dd74ad043ac2954f5c66ba4cda4ea9f28e65ae08cb178ce0c5542f69d6223de8b1a1aa2b991245f3cf976e544a6e4cfa48972391441d9253a9afe3105c4c49238e1e582b0c94157f8d9a2c54731b1f27632936abc218662d96c6e9651844919520bd0c1f055e884850d9808afcb60c0d159c0dab15e5dc2fcd9d710a629af72dd2947223a8a141c774efc8d37a6bb67ca42968741d3cfec956aef11e7542b597f64152562f549a3fd80418629e8d19f286a8d089768a211c1a34de15fd7f3b4b79674dcd55e3139d82b58f5b91ae222c950b279c524a3d9b85d1ed5934edeb13af68f9f8fbe1634279315d739593f96d20ba73c86ee12eb397af13eeae5a15f6b93fb0bab1d3fb9f4d695b7dd0facbd5ab27eb8f7b5b8f1ee9efae41fac766cbbfada86de6f43a83a642d84b057eebaaceaa995be18845a268bcb3794f766d524474c6e0f25dd90a2ce3c26542a3e18c9c39567bc2b29ad9cfccc9bc0961ac28f807f3e11cf24aaf7f784a2a84e548959ab1012ce33eebae55f9b5b8439a02b64020cab92981bcfe2b2f83e982f0c112c862a59a361acd636bf5e2b89cd26d1a9ad658ba198bbd536f4ac233f0850965e7cb8d6311524c812d3d2ed5eee78d7470350cff9634d713d907f9e5e3d668d2fa7a4b8f1f343a7bbbe2be680c993010e5cd1d8168b1ea3b6c4505761477f1ec575eadec99b7ed6e168e31edd3353c628c761a7e94c7b3a9d79314e4aeeb530712eee4bda5a7ffa94ede3675db46b3040",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xcfca3b51ec277251f4d11b65915160741dc6296728af2d79973f8d90249634b4",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x97473985d04723299559f49b856effb47d7abfad",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca73f0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xa451975687b58df5435cb25a3320530baecf7f14f8f566149216f739cc9c6837",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x3eeacab2f86f1acd9142acc53c3e8c427a33b45c3c60d26c3b89256295e25717",
|
|
+ "timestamp": "0x6a7a2e5d",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-E-reguli-oprite-anchor-13267952-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841cdbf549d3e978785bea8cc79dbb9c78698481a499fb56c76059974bd0fc250315618cadd3d92849c973f84f5d51b5e77fe4936e72c79ca9d833653ae77a49b0c00b8411551dfa4b431c626ac66f0288dfb4d0147eb3f94c3ac1568e34936a9aa030d39604b5e08fbd8087255ec6ea8abd6abebfeb5fe1cf8b8e9f186cbb012039b9cf100b84119a6742634db7a932e8099ee6ec9aa300b17ba1d54a9b0195b504d1a12fb101c20b805e2796e7a9702c480f9414885c04cce4513e07ebf13b0b4b8e01610387101b841b06051480cddfda29db6e0fa0375e27e9f3080dd51fda25233b3b513162a7c7168e0d0fc62ea578c71b032aa20707dc92d6ca0239ef027687253256340760d9601b84151802cf159a8616366645ea5990e9afdf19a58a6c2719b4173366aad51da7c5f1d47af227f9824a50f767b56e59e1ac62b1a2e2be73d6038cc12812ce7b5408600b8417fe6c5f07c03f97fe60b7e5049e72b267d39291ac1281bf1b938e73e6009f6b508a90e002e6cb87012113f242733269128546b8350fe6064ed4bab09e6d64f0d01",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xe674d766374bd77e6a44926e073a20ac3f0649813cdb0fb7531615f98feed309",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xb5e768cb3117ea25175f51aa956b48691025c2a8",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca746f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x19ae10c9ee500893e51f52aa9462045be3abe52465ec8af1fabecb3fddd0a035",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xd7787accdf5ce51e21f681886be9287d673f8dcb7b19c7bf270b8141d491f2d2",
|
|
+ "timestamp": "0x6a7a2ea2",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90cd3a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841c124614d98b6faf2c2f7be82bcabf298801819f4981d58083522fa441be5c6e53ad1f1e231a5f0352e0a563e341832694132f6642019b0cb6f93e38a6188334a01b841c2463780b63011b5f97bfae5d5fd42beedbd9e6587f21c2d3bf54cf0446455af4c2630696124b9e8fd1596421ab8647acc062b5650f8c745c88140689e42445301b8417b6b9080ffeb05eeba3bf2dd8f3fdcd00471c6a74e97d86b4c8390b9aeb449215bfdd8c71ee6dd71484953aef00c677f4afc570b10274522062cb3049c91e1ab00b8412f8b15941b8098effa4f681d258636e972dca58954555349c746b2378d1735ad73781a76adabe5d4bd9c80dcdfcdc46cac434bd656c2f0f941a3e2a0b50e26e800b841d1ee9fc21efd156a0494758c2111cd5dcc77aa24fda732e838a91fb72ff2f0ee5fce4ba5258de2c20694f771513bc0b6760eeeeaca5e9cdfb1b12518827a873901b8412451212118baf95bf31f6ed070e7c0f78acf90b164605300de3f76388ff6a26c3007e39866544a64f7a51db7ad022b0ffecd289d9c95a41bfae57fe1602bbd1800f90a59f9029306b9028f3911e63ecd719c5243114c06994e4f2eb338cb1bd237b81fb6877f4896defb848c38bfa87ae8ecd78588a746b06d0a752320f6d89157eacf7170057cb1fa18458a58c69055dc6557cc545f78bc68a76948cc6eacaa1c29a154320c3d05002e1a669bbd4ca172666c797d752caaa5bfece5a38c9d0b0cbabff1b4b9f3bde208841d40a531536b5cf768abf97af3810cde54cb6be537fb26afed89004488a57a2a8e799c2c2b44c8132cdf6360a0598d4a711d178ca923bb6b9dcad165e7a11e846f5af84a0d61d853fb1a86431a893ebabaf685b36717d8ea42f3adf1a1f2b2c910412b2c097b2347de6b3119fdc6c5465221b486e8b31db88e1f0a65d727f3fac4e457feed7e6d977bdc6d862692b73aca4e7ce0eff1aabc3fc1fcda39937b0cf50d73ac953d1e3a28cd12af9ebdc691bd2d374ebbc3e74eaca7cf177077f968843fa65469daac7765848a13440c6a64739b7a39e38e9af58beb5cf4a932ef1a4a4e72cc150af76de0236861172469343e769a467770a804fd3a4edb0607a8d46a6649847d66d25fa1469b94c542e9293a1fdcc84846095c843345771930a34b561b9d0b0c903c98cbc4555fd137f8d8645249ebd7d2d8263bc7cda3c5d3c304b61efc3295b1da3d188404e7d6187d760f651650d8ffee9a06b731549764c98fb3ff3c2b1728b0206f06279eb546fcf5830906f3210c9584ff5a3a94efd6629ac63f368c89a0609118fa0d70d2b20476bf67b171b333388e8e313de267e0908a1e0d2f1528036d1b6df9bd269e4ba1f744d8a3b79344f38aae2e70de30982b21152b2decf9055bed4ac28decd1e57bf04c7a2a3f500f97e76b11f91b2c8c00f34a13afb7bffba3d4cd5a04b4559f65b65884b5862063530af44153ade44d9a452845625204376ed7f1f8d57324e520f9029304b9028f39c20a3315da69a621b7d14670fa48eb77cc97a1100ad49532709787e1e3f32ad1cced097fe7398470494f9dcd7e5202ce0a2a3370553063a79da1cdfbace5ed28b778a74d3b31cac224f35d8970cc459287a7c78adb27d786331c81b41f44b8c4be8b114fa8b8c5a5c593a0459e81e0758d947a7fdb3b9bfcf544b360d3e20656faaa1ee38f3560509ce260a796d23e7f272b16f924cc78e1b9cbe57ba91b24e8f5d27cc52470fd24cbb9a4f59e2c5183dbdbe9ca4cc143cfde642b1a7b0a82b394cdbff1eb63f3101e89e6f4629211a484b99a031dd34653f609c1e72e183659ef987064f7dd8c168ec747ebe5489fc0284e0259dd74b29e3417b52b63210616070c5376f0e6f93087a4c51786daa75e3892e3493b537542ca5f273c89b9476d7138633947821bd4292d47740873d9be8f47d89771948dc892c14d47d025a56fb0570b630c862c16662560691fe336fcd96f51e4ba574aaf71e79f044108d1eaf8151be3bcbac2dfd79e8683fdd33d4b692a43ca52d70b48ffb4ad2200d830cfe34a9d412117e82eed6685976b1ab1b68f0b06b9578a9976be6ed76e59681c9e198b3148dd5f052260f269b4b23281c4251d544f4c95a56aaaeb9a825bb31af8d219928a3a50e1e5fb761c28b34c4aba5159064968f29e8c0e25981998aee743f333503665e327798726b07d47350d8bbffb267d13f8def38c56745836da3531769e351e565dd35bf270a4637e5df46c84e6895ac2c2a19214a53d9f44ceab4edfe15a6ac7f57cec308d5ae6704c429931af52a355eabe37456262b2f97f6ced26986730d619dd2952d1d1b9cc6baee5390478a14338052aa8b4fafb6f9b10b13bcf0218a8237c6c76ae7fa9c0202ded3d98ff5e25bcdcfe103704bd0b62729714c324bbde69d359ac8388906850f9029403b902903985555e82be9e4097b9073e3f3ccdfcfa131bbbef3538e510aced10a446304910c20367e48758f21c82535c1ed3668220cf9152c5c5e679978232f7514906f21e3804748b4922a83e3f37013206b90df0a06b85dd4d8c38fd6bac2b9e4230944ee7e2e29edb5801c0dba1ffac7a8db6c411826f74a9f75837ddb1b4d11545856e421e48c9e0d846545d83b5308a902d2cb6f4a4e84b63b947ac64604ee28e44f59b5c1646aadee05aeac7ae3252374eb5ef1ad7ffd2972b1160cb930b17b69e8a2fbd6c713a46f9987e0fe54ace4df6978841b95911680b5cf2dfdc4c953513e5a1b3b652ebb9ade4e399546f1b81ddb74e970a6cbffb6dca3b2556e53deea33f231ba9bad09467b0ea3413397abc493f06d53099112f3edc7114477579b8ec62c4096f8c22fbe2c09af7e4d436160248ef33d953e48f7367c74f1702690cfbeba9d8d59d3dd29cc16f508a70ae4f603e6fd0c6b63fec154dec41ab084b63fce6ed23244e7eeb4a6c9669af1562d9224cb2690b50c9043b89adc81be2211469b752a3d0872a98a3dcc7c7d5e9df8d9b93f1e7fc27e1a24b2d0ea317b5468d25a108a92b990cb2697d64a0c6163dab662f3a6b7c8e02dc6fba30189aa377cd9b338ee5552cecd9ff489fae2786fbf07b7b7b0d13fb8cb697054f44f8c3665389b155f33ac833b98041c93b809d4f868dd2c1b3b983a84e9b6c9bef0660938af57250a21aac75b9767f753bacb1057c285898bc05b46408fc5af3d8c535b2bd6775fdd82290d6a7baaa6dfd771fdc33468ca26dfba5d3ce6b9486df1cf3489e936b843203ab4fdadc99a712305bdcab01f65abee4f55ee98df16c9f9d18e1bf62a49b5fae6f6362d4b4437beb834a98e203fc5564be772e691f3cce320ac84e08221f5346e428de9d812f2ea67597db20f9029380b9028f3944c6a44f24a00f125100eb68071b4a651d647c525458fd74359f80c2f694a9d3b71700b3fa993343f19e4fb1e3c3338832d5741506729268e105ee509b07952773f1788aea90fb5a697bc9a8f1f30b568362fdc229bf16d9936544d4fdc34bddf158ba4ee61f036f935b1f494a6f4c59d1470ab9afedebccb93fcce7e4ee339b8d7d6e7824c068c8649f0e5e511d3d714c72b9ba9452baa3f065307ca2c98d4c306dcac78221da085e6b7eb5fcd825d95bea5fa2d5859e8adea0bbfd95d75581c5389a7762c8caecd267bfb770e4c9346e4c3a7a91ff52964c9bbf8b7f5174e8abee2a7da9ab130691f47c3df1f885276a459c2e0c11246f96a62dfe6f92493cf79f39ffbc993bcc1adfc6db4bd453cfeffd18e805651c1314e9a49a1186950e7a2e67caabc775116a63379b3269e477b5bccab5cf7b95ef8451fbf01281719dc9de79bcd25352920c03c88dcfb557f879fb942610ae3eee0ca0ba33fdc4fe559e1766257ec728468a4dbdd6425817ab4355a23c0ab6a7c091c56b5e983a42c9a4d9573b3516db6e6f2519d1c83a4d7440a2d4880b337191a9e824fad09d5120369452a5af5329c433a8d19e9fbae39a24e53662d7a64b8d1ba7d7fa47d93604d24df02f6b47a1c772df6d1ef91d604f8791868dae36b2e75998415397b6816b36d45d3282ed5957bf8f15a673fe89d944716185116ec16085a2e04888aa75b88c71cbe0da2791689b254b52d00ebefa42d4caa427631a735fb9ebc4cf61e0a88b57c8517328b37f0d6892c9122ea0c0119556aa9c32a82a24dda10c4c9cecddbc1e4cfa4d32ae9ac642cf3f8972f79b79b4c7365fad484e09e3421a5854fb207cb194c5b64792c29d1edb0566b49f2cac7b6874c6fa7b31eb26f79a628ffb9a8994e7f7f088fd89c52e8dcbb8c0",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x30cbe999bd9fd11dd1349e8a0c14b9deb079fe9166e9778d6a3b75650bddf239",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xc3314fd768bb68b986e80c0a14175f6f72630d7a",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca7470",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xe674d766374bd77e6a44926e073a20ac3f0649813cdb0fb7531615f98feed309",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x547436dfdcb1595783bddab571f214c0d383d832180d70d747a1f4436f50c116",
|
|
+ "timestamp": "0x6a7a2ea2",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-E-reguli-oprite-anchor-13268080-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90cd5a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841dc56140fc1d80140c5ad7aac91e07341442e815f2da5d85fb5986244b7860e7a09241554a472c46b8e499f28f285aadce475fce17decd3d2f5451d728fe9b37000b841ea0a4ae2dea48464609f281027d964af567eff8f11f7f2daa8d2a1cc75c8c4a7306be9820d491b586427ebcd2e1f7a76038a2c8653319e1f0f979eb69869d02d01b841f0dfdaf376632629d3c9d7d09d73a17dcea6c957c56a8e97b1bdf28bff0c45f97aed939f6659e9fd9757dd02d846bf82d7081eed3ee9d887fa2788a505fa0c7d01b8419e12d0a58331de1bf63ed291531d89ccf5fb883cbf9c3d30455a3e0798ef44546c6c1a71bfe3c25d278163b86cdac428067db687ed63526eae5ffce95f8decfe00b841bf011e6d248b2a0391ff1521b4514d8158a8bb106b51af0b168b1a99fb5255a915d45be1596299c1ee32c8e2cdf2c02474fc04eb9c22442ef2e29c02604154ac00b841ea79023afdf8262411a9821e05779044d397f0d120a944cf55d88452be9c4dd864b247a789a85821889cac9a0047ccca2586d8ef76454b0e7b0f4b0e98ab7b0500f90a5bf9029406b902903981bda9676e2f202a205246eac1bfebdd27077d948e11fbd117c3c042b4eb43409cde95100fbba34a14d12ff252a442a6f0a81a83dea0428effbf59163c267d48280ffc1927962465855c444e2a011060f8738e6a428fd790531a4e23c995676900618ad77af8bbcd4d43f45094450e95b634dd76c33b6fa01245b556af6abc09c343de8a3584fb616e75d6bc41ac6d1d27dbbf6df5efb3b380c892ba6a511ce5ea638c1c11fd6b8f53a8a64adaa8cc17a86914f5e6b34da1411b836437284e6e7187cf9aaec521b763952582777a468c6cfe4b5de1e0f427aafcb3e993356de9cb955965456b3ad31476e35589a93efa56dae32d4a32e68f3aa18edd20c09e2fbd6936ad2b9d6da679b68adfb22b54868cbdab9564fe0b6324bad86daf542e6b0fe31dec91dc6b98c691cfe041a4bcbd9a892fcfa6722439f5f5b17a16f1d28a6c9a9c5246baa088a606da957d9d5b74c7d6e9a631ea8946bfff10da4d960edff8227a2de22bc937aa3b9b991b15d8e6f517a96f93cf1d57e64be6d307917738289eb77c7708570604ccab9d9ce753a0dfe7d01f0b4376fc3e5753aae01c750ce9d1764d6daf2776e83179cb02621bd98da33069b9f8a6d1a56b4efe439b1b5d29462ad131a744447d8850f606ff1c6e76ecdb9b9a713e0d8280a7f3316dc68d8f3e90165e3f52c359b504c3a088d1a1cef277a5713f2bb24fd4ca259a4376aeac92c34dce8a7ba48d2a61b9673e38464e7179e052f60725ba5b942941d6ccf220c76606563456e98e771a8b7c35b5a8dbea823915266888a2bd16a9cd59ae6c10516229b6caaee09c63ffde97c4188ccc50a63124105f2cb5f9247bc093d6a073c6efeefe65b4eba95c9d0d3a7e9027fda86391d99fdd36f57edec7b182d04236b23696ed39b4a39a5e0db1fa8dc0f9029401b90290391c75274f2aa6d67944d79893bc63a1b455ae4a44b3c271c2e9eb076cd45f69b99bf948ab9863b9680d7e49e9aa4a38fbd37ac91114bb7934ee69901ecb052d2b4d4e13056d6726ac59aec6d6ac4a4c61fc254e961fcd9c9a65eef929dab7049bdb2047ea47962dac1944cca14b83f790c62822c8d4fd361bbabf335cadd6d4dcee12c6df2ef6c99b7ec29f47158eda317a5208477cdbffb257184f3455b6108760d1e82dcae36acebcf8cf3eb165baa0dd0c361b46fac2efb1063def5c72926eeb15b447ad3ce6bd649ed35acdd373a0877b1724c38eff749f0ee4fd8f45b20a6e9753ccc0bb1304946991229eaa6cb30acb1fbdd614a474932e1e7db213b514dd8d34a24c44ebc91b8747fe34ec43abd4519104693f839b0dc5ed136399c69d3b280c132ced3247aaa4536acd967d1cca991212d555abab12242c0f166ff0c7b8325fbb2d2f39da6d2b3ae4430e2b6a8e31759dca3d486129193eaa5295cd232cc492c9cbd3346c69fc6999bbd95f9bc421da7acb3a712eba29fcf7577bf642119f55aa4875fbcd5aa1a2f44f9cefb10fcc5b606aa33f84d4b71637ae491cc40e3aa9cd7cf1e8ca32b846abd3a476069336690eb9fe77b54947e23aad42a62432cbd1b5f19f2edcd555d918e415906ebbcdb38ed6cf145e491c7218f91efe5fb049dbc75222776759f300e8f77c3636f95048dcfba2551349a489ea3fec498aa57f55dd8f310423c79dc1c594956fbb65b96a67fb7458a8524d7548d190e36d34b1b06c93f9c793a6e7db726a7c6f2c80af2426bde03899fb0d58ebea99154a896b249c493103abf82755071287f6665bcfa7bf32ac48b6c79c83f2f4b7695d1fff0363a68e7cb74d9a648a9c66233c65e45d6c7bf8d63876520f98b3aa6d6b88c348d2fa559df967c7d644353854f9029402b90290396973afa1037a3adbeec93272b4a6a02ff52614fcf19d2b2857b28588116d96c5c7ca11ea47ef6aa6706a1534112f29aa3b3694925cf60573d6a06521b5912d2220c5b4983523eee89d0fbf56c9a641174892c7d6924935043f0b3a914124ac6d49906a93fcb9dc94b775573551b660d5665fb097421f2ccd4e7713eeda1f949b4685a0b0aa7ed0e9e12993c82acc89f30f8943acb22a5eccbe669815b35fb8449dc90b6ac92c0a40aea64f24515686e351c97cb5266b4ffc8acf3e4b5c2ffcad74f3a2ba2a7327f058f0bb24855ae6ad0a2cfd729732886497d8977657ed59f784384b3c771cd97da0c6ca374c63643c2c86423ae3b051783272dd128c833e97aa8c9e078c77ae54a3ff16716c8ac48e4329942a7ae62b72d0cf7410e457f18387b4655ea880d920acd4d7d8df31af84a4ef52ae4a6746e71bfc5262305ae9155127042e11aacc4fa2f716fe0cc57ca5874ac95d26f073e93ffe6f884b2545e6f5db049524250e967efe9bf8a2e4169df6e7a6b03f1bdde7605f1e17918d3bf6345a006f16269f34a66821c8ad609dc922958969737f999c20cf08dcc24dc055a7cde283df9f75f75bc218c30e627eccf2f00e943e08ab5a1d770bc9e630f9ae0b5961dbe090f4ceb0da40e7db6b9c2a5bd6d98d6796b16462e5883ea5cb420adc7eaadfa1fc1e055ea7819f2888510399d10c0b995e84ef8cbbb39487ff10361e8eb5645062205223be5dfd9bfc55f42b141e1ac314cf5fafef1798116d83bd4f295cf8991b6750f22ba86d1498c93f71dcaff6991c54204b9f44c960988d861cdf0b78edc53dfb652495132859cc4e3bec0e8e8ad820e142c3dde656787b4e264863fee4d712863d4e94a51b335b72dc93752358d0e1dbf6770f55c56261d8fbde1f3b98d1f8d2bb16362ed371a0f9029380b9028f391cf683bc6788763811328b6f8b1763ea907b605e794c2b0021e94c7dac7c905ed5c12f2578b23670d4a05611edf4b529fea274d69768410c433fd860fa7d4ec289af47a44d3765d987e04ca9cfdf42a371cd64cb12ce6673cf0b46e450f0ca03a389a57c18ee79e2231246d9c693303b97cb2f9a48bf564c4db73a9c10024fa0c1b35c45bc89faf71abc119f875c6cc7ce5098a2d8d786e57d8e243fce5dfeaf94ca613f9c0d07b6190d68e85bcda1b32ffa2a1f3d73eaf0e05a84f570c19d7d86ae48dc438e96722ecdf2633a28b8d2191fc11ee3e2bdc533c9098159dbe3b68e8815bb5597353ef6aa9c8df0d9f6f7e194694e5c4dd1c1357a36f1a5c3dcb83a8df3bd576190c27e733c51ed239ac7683519716cdddb26512156f6b1ecdb55279d670c7cce5d3075953752f0e0e7f2db1641c5705772e18d64d31ac6d9359c96a4a1bddca3cb0fd77f518a198f75aaedad92462a9fcfa49c559d8a0e8e09cc24e51ff9aeb441ce9c29c34717e418fb39af14fd55cd24f01342e46254496f40841925f19d771d594232812b7822b8e0946dd42c93af91dfe283913f118c572c479762404554e7f2f7612d6d589430022b995e9d38f494c37959f229b973b9c8371dc049b550edcc9ec6a5a1f3f4f75974fb1f9d0347e1e47e5d0bf4710c6fbb9738e7b2d394eab4901ef36b8dc1ab39ec4736833165156b6dd19ad11354bb708aa0493895e5dd1cc4d12c9f5b6131e469a0a78e2b73a9f172fc159ebb7d90abcb704b9167a853152344a9545d9570a99d75c740bbcbd6a4ad8ad7f0d20c09ac6b8c0f452148afce653e77156c38ca6ab972ee4b50e33a8cde0c89486b30f465332715cc66b96d9a03ccd2455dfdd77152452bf29466018dcfc3a06c1a9f7b14ae4d8ab9bf892570ae43576b8440",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x1eeae9229ccfe7e298aebce2f2728fc0d9a3ded0897bba8c32b6fca35c5af092",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xdf09b32c761620c5be77da398b97a64f03c3980c",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca74ef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x434a6726ec46a010850712ffa18b09e5339facd6c5cd842dd0efd414b9d88b53",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xbc8269dabd10eb74714b942c415610e8632eeed835cac5b938a2b6df903ca5a4",
|
|
+ "timestamp": "0x6a7a2ee7",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a3ca000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841ff2714f0d601a9cd582917bc35f71bd38f3d5f5225b9048846e37f717ee1fd2532eff93c08a4731e0f13eb396d29573c984d9ea861733ea83676a0cf46801f3100b841db32844c3d8442f038d27554cafa4940bb5f3d2c946e58030a40b609ca8fc52b03a925eba1566bb697a1758c8213890a8836479a3779271d660c4a46b318949700b841e7b931a1200630fc468a77487a28ed776b0a991ab5eb7a1428fccae908b4abdd6d1aa2c917f281bdca9941c327b1b47b6717ab4c9b8a2a42767b25ef9a4a30dc00b8416c0e2e3980bad7d1c51b780a5ea4796d3c078086152140666192ea7951658737336133476baf15f8de8a15d9c4fe90d83473ccc428dcaa5809dd21a0366abd4a01b841c24cd445c0eb3daca0caf40513f6c8620f3494951dc40528e97890245d0f132f10b21d6e1ab9c5ea8e0636a0efe76eaea8cad66f256bc53ea99a696c4772631401b841f1150d524c6083e3f4c02a1418045c350bf182cef68c39da3678a33c97c1a226339bee5e8f04d9cda37aae29cb5fab49bf707eaecc112433aebe61457703527e01f907c2f9029206b9028e3926c84d9038d599311ae19d26d8cf57b6bd6e2c542fbcbadd1a1b6cb602ccbd22387784f0644d6d6964826e3cb0b3e93a984dbce8d1a4a3480db38d2ebce309848be0ae68202aceff7041993db698c0daac85fc85f6d3f67f4fa47efb69d75ab55084bbef4536c72f83b5e86ed1ac2b647377bbe459a32c21c6508f9c98fe69917642fd9d58ee55c6f2a3b6b6d2ab5065d167739965251bad40f7c36f8933bd59eb3c229b0df9c24c1bfa01a0863faa64d6658ba220d262631ad97ac9f76fc0a419cc4c4ae97ba77450e533a34031cca4c5d6a9b16f6307b9f7c097e57fd076d829034b48220e44998bd2b278191b6c32685cdfab8c3bc87fb79c56c66a2166fcf3f0d1d26d386f284f2e3daeff3a0a38507235ce06d710cf49dbf85e97b598af36b33559baab6c25ddcb73cda0419fb94d158f8bc7d64f951df4b54f65c8f51780e3a4e4393678dfe5c77d2f43a3df6c1359b44ad2f2d789d6e6fa3f7a07c189fda691745df863b5da94178b7b40b43e473dc584207da6cfd04cf9fcdec42911e740615818a32fedf0c599a3124b3a087c8e179b53e910c19dd1c2844520c964fd87bda381cfaf72975d9c9ecfbb5b8f43c72b623ace67cf2642938ad499f290f971ec01563b4a873b9767ff1090ec61de7206c563cab67d2aa714f8143946a72012753d411906f7c6e4ea63f54c45c63c81e2dcd69082cdadcb4370947d34d066c7c4fb4c483e53c9f0f56f2298a444e1f92136fd65052d1bb80a40ac274e7b53cf45f7999613bc640cac11b7b5be52cd6edf5494cde7f1972e14d9fdd4aa6b86e65bdf28893969dda6db299135bb56d22cd8473f37245283e982940e9c408130f8d45518f726b564e3e719b9a3dc77c669765e99eccd69a7530c1331546914da553d8f65b068bcdb9d9368a0f9029305b9028f397d03f645d4c5cf9a8b69a5dc072dc91f74bbde0132d6687b2a83086165b37b8a1f535b055560a0e6245fbf562d56ba3e742475364f3f28dbf0b60816edeb50d1014cc562b5549bb4e71abb5e90a3d68a9e452cd31a0244ac6ddaa261438d510ad5e6156e859a87278b5fa3ac3ee70f053250b798e79638bf27090aaa4d789ca4f1009ec7cbc655c69334ac7980663868f66d2dc2c920582629588026351533b588f2b837fadffe0f91e8e610f98cd268acb2bd794e2128e4f2dec57d8e59b45f45608fb551c6d9989f935505b6dcdd2a08e654c634580223fb838c87db137ef3414d6d7609a89541cb896e5c7f18563ed194e4aa10aee6228c8aef1419b0f43df8d586a1d2ccb9aa0dbeaec0389267ab1528dfa7f67cb92c660e33c1244be5acaf039ceaea57c97f7b12fec4a36872bd896622f72e7413db108b5dbef894f6bf100769448a33c896b52acd2a88a6d60d17dc64d88cf2599b8a34fa0dec8a6ecf2c7fbd2f38a4b9e96dfdbe9fbbbd3f31fec925de6c1493d7e9c9e1ba4feab18334bbade1eaccfd6265cf6398be4ad69d5ce1639f60b493ef1f0e66d2231a19b8c94a39d83f27a59c36ccfa167ca54a826863f6024e682d90a6f5a44fd85951c0c2acca0f138a77d9110fce29a62c8ab88995c6fd4040258c679322c95ef4c4275a4d8d0e1108c128daa5ae56cea4b78a59d4c0e7d10a8d491db0f46198e9b3a396271e03772e2d11291cd560f267710241bac26107c094c5d736762837f499d4f708735182893c63e558ce0c96bac2a56f218923f8e2c122ada0b4353e1423d80204675019d31c5dfc0ebeab4330eae13674edcd2372c25712f8bd813af47b38ba743988865efc0e73193227844aa38423bd83873153981dc70d3d6e5889e163db69272ccbc74cb11e055d4aa040f9029401b9029039cd9151ec822b7f1e18c60b47807297b363364903ec4f512c8b5c0294c571ab3fa2507a579f858d46b181fe56cf8bf0d4b1b119b7f6a9d3ed5bffcc87237c63f1a8132a2a75f9cfc7c9f8afb27574395e6f6cba0292a665c9e2a16be856e2508977a74e98132617d0cad024a69199983b242b7b8756748afc9652ea0d07c95d309489df205861ba28e35ce4954cec6b29b75d9062355dd3a0ca6557406290427b30c1f02167128c3471032cf24f4c4257378914cfe1d7c3a6743e54114cbced1be9dc95c884c3a711faeebf5918d532453a99e0ebe91ccf8f86192be239ed14bdd8582f32465d126d6891c3b3324bdb8f1bc2c6b8e842365497e89b70af6a58c3331248ac91f267408c6b77687b6da1e6f17439f2bb984521145af53b00f6206cee84d4759026149d5df7d7cdf445ccda3092986d49ed45de46977d2ddfcb2a2b496554797aac28e8698d79acd32fea819c4f641c37bab9f5830aa7f70a9bb8d360bb2ad4b0dc6a540e5cc5c150ae4b3d7128ec425e950353208a3b1729c21f8ca7b5aded049b7e8c8639c844ed94145770470851ce6a8546259d214862a7a544b78713aaddaaeff2d38769d765376b77671e8e653b5d0f4c2a9389d31a63f0ced739e3e5723768521182ab8c2c6380adecb5dbd7335841dd17922d7650fd10680695d59b21c6bbac69ce0fc08fab54163cfb5963281fd225fd4cb592f34eec75f8b39ca6c121685bb284b09e84296e59bbbc0a442fef364e13274384a0290e5ee7555b48e0b7358bedfe91a50449d07cb0cda28d8eec3c27da17a3471e23d486cc9de5f30be14af6c98302884ae9bd86c26ad5e3f07b9b76dd5166de39a2bed03e0e6d89a5cce296850752b69236c53f7535b88e8f9fc9ec44091c77ef24438d39408eb83276aee5e3a2d759ebde1a",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xfe2b08b2029c963c10b3e3ecb352705fc23c5c2ffe1ab0b555c4790340f91f87",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xe13aa491abbc1252dd714e7ca0e55717a2143eaf",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca74f0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x1eeae9229ccfe7e298aebce2f2728fc0d9a3ded0897bba8c32b6fca35c5af092",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x91c81fb963e6019c1750478bdce9ca2189ceeb8014793eda15573e57a224c302",
|
|
+ "timestamp": "0x6a7a2ee7",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-E-reguli-oprite-anchor-13268208-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90cd0a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841b2776407b8dcce9c1d7f3da5a389b35b1804570ac9b12aa14793ae938ec6a5842f96721b2767b9b1f7f326b857cb82b80b141b07bda4f4cc1136956d5f39474b00b841ee8fa8c58b1e9243360a31e97dc0deada6c2088a10154cc76ce9e15eca8fe9ff7da1a14e3dd94e989d9455bc62a528d7c54ad68db17a380d94b8bff9f14c48a301b841726e0a78a2d95888dae9f1a0de0c9bace25d1c6d0168a38703962b23f7ba09c967dbd21120f61e0831cbf4b09f1ac2badf2b549f1470631e04f1afb62981a9a701b841b5a5987fd80dc393f228ca4b60d275b8691bea2230defbc4a5886b4e6ab8668460fbe6bc3f99593a68e60a1e27d07bacdb0be72098c2644fd3d4eb046f9191c601b841186b0fd20dfebd02baf2de55bc5dba183a1d5d84e1913f44174db9a8ef56471216060268f2bab936afd6bec4a3f11368874cb5b57d87c74d7b6ee6576883758a01b841bad200c77ae776ef453408c2999ae607c51ce497ad6320ee195c07cfb7c2b1ac40e4607a8b744f811f5e426142d4244d8a661d2d67088ac24bfccc6874ce780500f90a56f9029080b9028c398da7c767355c2ff1826efdccc2bc516a6ed9d40c3c0e7fef297984729f3283e1abfb558cbf5d375a043218abc5a573c11e4856ccf7f0bb7be3c36998e7df6d9b62c10bf63a44c762716ae4d1efb2738a8a7353d0626495f5e543d9783bb2f8c778de49524ffad8c9b10c6be4b1ed64be4d2b18c6e29fe4dedf893c3a2abc1adf67eae64a9aeb59d841cb4a35bf30458f41c2daa0c88b5d3b5a7ceb41fdbad7f06e4419cc99da6df8d8b92488535e628cce731367f1a94d7c26120e227beab3afb1c56877d84328d3c5bc09ebe1b984121f1e2980655368f63551d5e1e62d5e3f91a8785dcb6cb1b431dc5c490e9692523cc0319c2dba33dfd15daa3f78cc759d8cba0a4e765d2e56d26b47928c152a094753ea496bad994f5481ff3a51cd9aff3ee1663ee635f9f46ab8aeb5df268da0a8aae8a6fb777544a4ada097378fd69ccaaca771e67aecd896ad006efcb5885d17af3697fcd13c29a284385249421f3680e85b270313da8f95bc8dd5147c2eb60c46a650a7cc3a785dd647475a555cfcbdddf263a0b3dd6f690542c27e896f9db7f3e28b1049e249023aa801634527b0f4b26aae502c2d1f056d6d31068d8f41d28ab632bb88985ef2b3c209458934ed1c35c8473e330b6a30ebf21827668dbfe7ca1a9d055e75f09c7019e73b11bc78a990f4202f8e64f1908f39f63c4c1da59eca1f98c523b0fcc963999461434a7672e7ca690221366b0239e5ca3e194bc3cd1383b4341ff6e98a97bd3c87f394857f654f57e72d9241e3ae8a679f6168367cab085bd26a2a64651cc59a29afd95dd3d54bc31bf4532f994cf3ee84b50317f0d41ee644d2115ea2db7fdbdd11f9d40aeb339e358311f3ce196eef2f4387c23a33ee7da7059b831108ada33081ca5185773bc8957f0879f3d7a0f9029506b9029139d73b29e1371f6a8aba2c0a12da94737b5af0714172f84614dc52a0dc26acedf832a845c95098fee4cc8321f9d2145808d28de39861b70c096730503ca695426c6ad00ab23ae65d51776740a820a87408e62b1b7a5cc7b8848ddc48b67a23296b3c5d2f54984be7958c0ddf43345c6257090d4d1e9deadbe6e2d0eba88da0d3eb1ae9cc52398863b3145635d1bc27eabfb77ace47cccb86a9b90c033df1c9a9cbdd113c8dfa7945b3748a4be6680b8d73c7af76d971e14c737efed43927eae9ff2befda5360673b4a40fc466ba8d5c5f29c463f9a49392150e988b65344c36d58bb823195296d3ee721f8becfdfbf5d02169b4fdfcb633775b4a6445326accab74b21bb80a1bb58330e269799e64a154eaa1c789b34d868fdd9ad4226657b1bb6df8bae91f22f6b410d57eab754a7acb2b137da4aa85965287e6f970f226e518e3032ecca20645044f37d6d3a4e3a228b382c2e85fcdc49f3c418f1ee07c5cd5b7b778c760a8d9fae4c64486771851dd4da293b9aec62b33a1b3068dfaebfe0be42d5b742bf386dcde31a87278b9214c68b318bba78a09f95f91c321fececd11639d9bb2372a8610a1204d8b5c59312c8f43192640158e2d2e470efa615c1d52c8ef33cc717d9272a00f761256ae9774c9d3b8e15cf4c883ec34471302c34af36f3c9c8e2198a38b34a92992f9b1f13bea92bcd87bbbdb476a730a53b169ecd069200e96192156224832c3a92aeabf2109c3337b0444c2b504e7ae9bd15b8abc1941a258ee6ebe79bf7a2909b6d5c5d10834b5c22f1013da9d7431368d1451f2765d9b5b0491f46e7d1c85a3eed665b5eb056d1e885076099b4fa0c73708a1592491abff374ad2b4240ad1114a51eb56b6b190e67dfbf41e3db185fb964fa3fd8a8b7099bc39d84bb96d4a6015a2b30d8f9029204b9028e397c30adbf7dbe96cfc597b196d225271fa38cad2132b96c7ba4ac9e01edd9cdb6e73e71e80dadf71bb58571ddf849fad0245aec821b377b5c1d052ff723864831fab53b7afd365a954aefe84c7c706249f26d0aafcfef955d4da300d7f6504d2f63306863d7ca8960eba0bc375b5faf1bae6c3ab08bd1aad5034cfa22733d2bc2ea32961d9adfcf4b990139aaa918d8ac15938976aaf626f9e32a09ef6b3316f3363ca8d36a626fa755a0ba5ba502c799d360d38daba741fbe957f4de1b0e909d256e1111ce31c282c461aabb751a7e435e09d93ed39118f936bbd0aa516dc495afc4ae8887371842e3642f14b8a26ffcaec2dc5ff43d2deade8818a12569704adbdf103246e619b981d1127d2b634d826554fc8494b77d9d7f13cc96388c4fa7c71039181242e27c3d138d4c9d8f7dfd6f8e1d22e1c667bcea3e248ea4154682b5a364306c94fb7a64915ec6e39261b5d0664117573112c90b7bcde9f5a75a3e5241d84c90ae03afa0675902dd9ec7322852ff9d4b9d8db4737686fcf36e974a424ef87e2a5cdc6dc51787c177a425bcc9ca59e819ad93b8fa8535a71bb70b9edabe933b7a332ec81c7b122ce45524ce9eb210202a6619da80a591d234efb38b7d0fa19c3adb26b9c9596d36d84bc39e503189bb45bae1d386e2a3fcceb93439f7b0da6770b184099df3487be81fcfe3c437a95def8d0e409667061affd661fbb4eda46698ca5427ba572bf54bc12da6db51782fd67e826b48b27bff6962ef4e5f69eb5c763e3775b09ea777b61367b1b4ad6be7c59e59f8d8111480ed609ad6b66865aaf547710759221a2ca6f328c9ebb590153dc54c1ed8e14185b38cb676e49f09e66e69965eb7aa5893f27bd0a20f2987467ff83612c3a095ebfd2c67d98a72605810a83e32382ce22280f9029305b9028f39259d01514fb00315231f535737ccf1c36ae0a124237b30496ae43f989990a14280709bcd5bd805fac62db9bceec0bc4f13f9f393b2b2e3ae4683c2e349ab0827c9dcc4b51c5d50a2c14c17596ab51ced67662f83833167a757dc9245e4f9f45bd2c599a3c2428e0479338fa7ea44b1bd5ea6f4ddb652e799ed4b10437f2c6a62a9b3192cbbabb1d10353bab7a85253ed7068c8de3666c0a7ad33ac6b5c987f88fce446691a33b3967e692220cfa0f92689453ff4a8e8991f99844c2b4d5cd295c3315464354749c8171f61b3e545988a36fedfc0363b3a0dbb0f50926f0e4659205491b844886b9264d4f798bad377614d5e9846552afe211cdc0ac26123b1b31d89f4f7a1c3b1d2d2124eed2da05ae18785806217878f136ad5c6a818a4037d4c51ebdfaa5c2b8eeaed224224d95f5be58b06cf9014f78463a2bf79e22a4829a4e9a6c2a88f4f68f34ab3a5b7df8ecab70e8e5d2955199607864f2b45fb3304938c0359795fb6bbbbdecaa349dbb9d617373cf02d584c421cb5c43d79c6d45a63e28fd65466e245c4d054e06edd93d5bf745c05e6a62c6b3448c6fff5b5886c6cf19689d3c5cf45556e3d3a14d169bf741cdffdd4e569d869e55252a17863d0ad4bd5626c8fcd138aaebd12e65d2aab1a9481b052be4ef6ddba4ff1783d9b7b289138f81e7a45c29e685ebc5220a5f55def8703e59de459e490287a0c817ad2a882b10de75e6d7049d92b451c2d11364a883585f06a9908f2ed2dd1fc7dd54d6ccb7fbbd3e859e6922fe699a62e9a348e10dd3183f631f4dab60d9e7a6fdf8992b4d735ee5d57b76ba226cc00801dcd965567c9275f95c94a4cc9464a22c190e36929a5ea32b79b89119e21c70b610d644ccee9f397eb1dbb561b277351137b74e7f0b56bd97d5b8ce7b9a79761",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x0b864f6f4529a7168ceb4b1bbbbc2293f56bbfbb606f88f8c6f948994d10d161",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xf73bbbd26a82dbc769066550d8d4585eab2fc00d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca756f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xd8f00ab3efeda00bc3c24280b7cc8d03168aa718047c3f32a0267dadfb594520",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xdb676b36288cbccdfb0354db9926c8767cbccf9f01b941698f912f848309a6fc",
|
|
+ "timestamp": "0x6a7a2f2c",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a40a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b84115b1e00bc17ec2cb01ca10e16a2e7f12b51b7cab8311d3614370196de4efcb0202b7360cbaa170e3aefaa613604286f3790014ec1a363f275f399c45add58fd800b84141c98d66b62fa98bc2b4a569643f06a815508a3af967179afc112e97eed1bdfc396bb8aae69f3744112251738a2ad967dd10a0ec1aa5fff7efec052915be21f000b841b64744ecce9dfc11c5b0b4b0d769fc34fef9fdd216b314ef2abd39c97a54a26842c414380448d511d5c65afb87519203ed41e024d4acdd693b908c15237d858e01b841d06787a02fdfee8b34eb169e92a3ee46d1ffbe2a742153a64ff0298b1dd1dedd32f42b950aee4a0dea9b0b0cc2be2f2b7315ddf902d0e78ce590b7f5f8dc2f3e01b841b27bb4442cac94a3791f50ab4f3d4bae1c51104e316a87c16bbc800192f81b8208b7d2f5b4969bf5da198d24cc9475a0effdcc0ac052cd6a3f9276ef2bd8352a01b8412231ae15afae2f4f52716e0c9128b8f6538148baecf18f3c9674bbebc4d3ba1c301b64cf56ac8052c0a8c6b112dd6dd400d8ca40dd3422596f0c8aecb94966f400f907c6f9029104b9028d39dfc1498fdb24454afa909ab80bd19f4dc767a6cafe8f34de533019e8751cab39e8bda3b1d676acac14645a790fd51953e9e53e0ef7fda72b1fbfb13c7021a97aa264865e5aa438b9172641c2fbed7b92f701f2fa559266620333da6eaa08348956a7cca630248b78bc44a00d76eb428d24c49a3456399cbf863dc68759f39282e8ca4412087c5655c073e335a7e8763a8c6d45fd94f33a71664fb749943144e67ef16e132b07b6b9b833c8d37e4990b5f3a5cb551b56c670a625542a73afdc66e3020a8c50385e567d21f1c990e800c4adf4dae91041dcdba402dafdea265dbcf60e1a945de3fc943a0498a0ca4bfafa61a002773cc357b5dd95659bcf98d5cadf7948ffe7f9cc494aef698ba4f311e736fe3c9971a946b088776693556cf487a6a486f1f5916342eb5f3ff58acd939851b5cda448e743dd4c8182d9a3888b2bcaf1425a69af22a339b3cbb149728dc3e77292557aab0adcaa6be5d2e10a8fb99496060b888d103a1251ece5227c346a2caadfe1ae747982f61e24e12ececf11c87d253655b348f53a1e4979a63577cf9c9536711f595268db1f55d0252906e26623b7a2d569d52df29d6a7c3d2d4aab8158a39f054958c26658839f80482c5a05b9fed09a45dbd8fbe39bbd793f64ce638fdacba1ad92f1bccbee2107b2dcf8bfbb9d7aab8ec1627255b751168ae23bec56da4acf59374a0a827d96d817cf03effe55162eaa365562acf26f394da66de3daca1a69c9055b13971fb6c1917b1113f0a8ed755fddbb729abddc496fbd5e30ad0b9a8550d2b545ced235122efe960641ce1746c12b36f6b995db11c8864ad95582c48ca87724ad74c5fe5cf29bd0b04b617afb31fcdeba9658090ea2bbcabb8ae4c021ba24048ec7b79969cafbf190fbb3a966e9d0d0b6ff8902f9029680b90292399cc107fc13657c5b1a21a4ba94f53626fe5f0761f3f4321e5fe15489bf9a0576cb6a3ff4ea14c6970d78717e182d7704d860d87eaea25a929844315a52ac6a7448c715a93b1c8dba2408cd9b5c209330e9c6f659c27bd0e5dd8731868638a820b44ced513dc955575de3164cd6b5f2bfd18feeb9b0a41c2b5fc7012fccfa74b8b9314072958f4f225ea66b511565ac52e3456e33f869523acb4fae9ba9ccbe10f5f5d864e795a6e54716bca699cda0349fdcbe23e1b181c69d3485be735718d0ceb724b79b90122e391553d87799c89419c6d5f9aec228734e0b5bdcd09c511d5e5b4cfb53b7d754327d0cb63140310aae9dd796f96b7a4cd71ff66d1fea57847f211c875540861062bd9a6ec61b43b3c9782245597dabcc137d7c7f805dfab9642bceb12a1dbfe6611a431bd6c328ac1454d2719866ea895f02b4b648cbe646c53ea329755fba858366c69b24685f5d21bffab553d27c9331b0240885e52f11ccd789129a436cb2ae010077507700fab54dc4e08e28e5a95bd543dd1156cae796fd35b11c9e96e8b74e34b72da44938d02411aacf0a85517b243a2bd36aa08bf7039d9d2ccc11c1d699e9f95fb59a6a9e3a009029f90290abff370bfcee8d2b5bbd3a96517dd7cce837a4ed8859f607de46501f9d26fdd2cf456ed7751b20729ebfd3064a6158e9eb6fc1487cc9485d7c36095d563f6361542aefdf974db351e3250a3c4f327e05a1fdd771941ce6132eb429fca7afa79499e009d9f1515fd2f25352a686f709651eac82dfff53cf6ba12ff71af216a723e93aed8ba4f7f03479098eb6b322828b9bf825fd3952b489d62ea6acda321b5741d238a9bc474ddfc42d39c2c99185f44d9af99cb22425fec7d491745ccdd501657131642a7187a1242c4e3cb561e1ec2e39a04dfbeebdb38ff9029606b90292399c6c77cfa155a03416d66650e620b393d00cb65514224efc8bb68682e107749efca6eeb62b0bb219f9da5acb549d6bf2984614b2605c277a18b1b83b96d59dad5896dd0c39438a2eb0b27f51d2725a16a6208d4527ee3e4b6715435a34c5ecf746f73a56277b54d92da8da68d490bc4921fa4bd08e7c8d909ed9f454d76a0c5534b5e5b3f4f0497d69ff1e41e64f60c5cd4bb85c514c22142bea44c1935508e472bde497b65ea0e595074a5a616441258e732ef0db2cab22c8c1458d65a153bca96b0623840a788d974c3c5ac78fe7ce92c4924d34bcde6f8caee8468f2766084a45190c777cad616eda313c8c1122a965550450dfb78a0c20f1c5446da5757e58c678d19ec35caec3b9cc7272e31d8bf4bb5514fedb453b6dcbaeeb261a9ab7ed1b411b4880d177cdc899483d8afa94ee5f29f22369e753549c8c4a4a7c52134e633cd8641dfec96e91165d7245f30b1f8a731b311fb9e7d51daf15998479dda25e4bb7b7e152dec49d389c462f19db33362d1dd95acf97c3209ff7ce1fb2c8976415e9b2d55d7614fdc54adbba21c68fd79b76a52a47af48b647a16e67ce5469ca5442529cf35c5c8635022c97ae3e59aef7a6623d60252a0231cde9469a9a2c45859aef3212a48447882aaaf24253adfb024269f6aca9448611194c791dc1143310f752be7bb8944718f353a9b11cf58a270817347625795a65ea4ff7299e881c99d739b19829f13d0c1b5cf9f532f209138cd295ca0165db6017e758b699063b12489d07aa5bb3f2a5322f43bf3a4018e7b23b22d975766b1d8912a7ea7eafe716110872f3c26a85ad0e8f9440cffccb40cdf83190e61638d514533796ca110f9c44d1ad1fcf2b839068a85c5d916af5c9dada87732cf5f647cb7eaa27b7eb8444a2debacd8a0fb87bf884efb7ae20",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x71d74d144db3c5a994ef61e2b0a4dad8084dc0c18af43bf07e12050f821810b5",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x1bd5514286f5602a6762b0075266379d29af1c9d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca7570",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x0b864f6f4529a7168ceb4b1bbbbc2293f56bbfbb606f88f8c6f948994d10d161",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x74a6e48d1e4ca6924150806268dbfbb61cd9391339ebae979ac792ca3924066e",
|
|
+ "timestamp": "0x6a7a2f2c",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-E-reguli-oprite-anchor-13268336-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90cd4a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b84170cbc357f37455f267e089e6b70b4ee29ceef958bc7d70b216cccd845824f5aa6ad6013019382568038f360bb53076069f64c8df685a7d57d7bf0e541469c45e00b841c0798534a7b5864161e362ad3d0345474995812ad495886196977a2241b9a1a43c972405875027246fafcb09a328084554af2b672225ed8d59f9253b9caeb1af00b84162395402094ebab46705a390836f266deffee1a8b636a4e2d65025f5931919214e61856775907e74c47d367eba77780d127a7d84b9deda09a3158d5529f2686400b841d721a46be9c9632ce3b8ceadc283c03bbe5774dde0da43a3724228fea90e0c5a6a50aa3d8cb1aa8d0391a6c280042ea89e180588576b195089918a41b78d556700b84142409d413f987682e5152c3e01ddadec84dc96880f5a4295f9a3bc4dd13414de4008b8efdeb45d8bdf02ba75ef526f0f608f6bca41eaaf108a66c0242da0505300b841e16c49bd7bdc47c64e892c350d5d25433e4cc68b076b0a0889c05269fba228bf64f06cdf6ffbe7193ff8cf32693932626fb6c65f80ab8350c73adc476e5fc8b201f90a5af9029305b9028f3967c65ab1ba3c2cbf4a723cb3f9ca1f51011f245ab02e36fa992fdfb4101e677808a389f955b87889a68761ef74995aabdbe4702b128f3ff6476158d92a96f4cf4a658a58a764374d5a2b137c3159251a96db1858dfddf46930a5862dfbffb306ce052047887ad915108c893e20147b5b02b51c1db954cc769a7d93538461dc4624cbc836cb4a56a1427008bb638a984f3a97dfbc3e3b1d9eda7baf951a7a7d21dd3f0f82a2be4a35044f07d5a277bfd6bc4ca6e525526990bcc224a76f57da2b5fdb9f687add0a5173a035f48c9a3db8f1e83b866e61f6a92dd11b11fd4fa3d73b674347918faeb66a2e08d5d773d2946126414822c34d7fccdba1e8e0f162c5c97f5aa38b6b32b737a8af86d23f0479b7c7e29a4cacbab71b54f573c8912585c7882b1da8e9949c648b35a469fbc6238679d962043cad5c33ff53ca4315394b9a8c8a0eaeb2d5e059678707c0b8fc8cc23f103b28cf24930c5f44e5cea8b10429249cbabf5c7985357d25897fdac18b89dad19124fcf6cd96bc5517fd7063ebf0fc3a5049e0fd3cc3ab7fefc8e8ad6e15334433d234e9f0ffe0e770720a9bbd9226c673e63273e995673e4790d6326500bf4d64bf75f2bd00a9158c7aede930faa97a104c13854e72b7561f04cea79b57d9f75710dd9b362d3aeb667d894e17170337da2f552cbc6c4e86606abb2de893d3aed47966c5a429d3a29d4ef0a7dd84a7347ed3a2a2f7aadb082e5ab8beeb6e9a28038a496b930749f02e6a6a5b8b277c32f7368ac46d127eddc51d42d05677e4b2d10c56dd21111a84a88eb73bd38f2032559163b0a23871b1f47f6469fe446b576981789fc93efb9d51bc9a6c6b340dcb9f0f68e5fe931e7a8c9772c328e8309a4cbe537bab6328f2ea6e88d6e5ec3788ae3765a4fe306c00d0f950f9029306b9028f3904ed35a869708d977667e0ec5bce83db83e41e4d014820a15a24c07731be4e6944dccd4b6144d3a1a6961f2df6584710b3db286a8c41f08b3afb962d198fa79d1b4200af54b224cded911c92a1c12337e93ab7e5f553313182ef18dbdddae5a35b4546d48b2e792ecaf23cf7fa775b041c080b624116d5699ed5c44e29094226bbbd39b766dae7f9c2699287513b5225071685123b3bacbafd32cd3d99c52769e044cc95518e560d770717078cd9208b57df76cce7616c31d960dd1696892cda12427b8b670995128742b07bf5d4797f1d1fbf6ab5f0ecb8b5767b7616c0f06f11b9c7f6c28ccc1004e26d2c787b5bf4c20a8eab58a4e227175c54ccf4f9064e7498256fcac23678f47f8b5b49e075388bede6d20fa381beb722eb44429701874cf2bc0bad06b947b5e350f66e87f9cfad576f9735d1cf3eb203eef0bc2b34fba852a25a4c64fbc8f6b26ef33d2d727ddf5ed3a9a3790cab3da941f679a8ba18ba32fb6d0c133ab2a0f176fbb74b9e1a8ceab35ff5c765ee69c96a790523f5f15296c62842ab55266952335ab8d2122b97dc1342c5ef5cf8471e41a622ce8f0f037de492ac2ad6c7f19b794cad85317a9d323db87361849d34bd72bc5ef57aba7c5bf39333be4ca178f512595c2d6e44d13b932c3c853996c722e3170f760656426f395b1884a929d6c194650223eb999bcda62709fec71f1b145bb8eed01e631877d83338a1e21f7b6118f3c21a18630a44d0255e1178592208fd1dcabc245657678d493a3603c3385d645b1ee3c12449e739328098f4a32e3fb12fda7e32a646251ea6bc376f74f7387a21329b82137a89a98511d38238c5e7e1552ff577455cc69f0f945499270e0c460c66e3a627468dac495c7b97139336aee4959f5134b5f6f61392b325af3c8d30c35e50f9029480b902903976043fe8fbd656064392e21507b7d8bf071145d4ed3a61cb8b933d134659f7c11ff4b43f81d51e9d6a8bad647dac38ef4ef2250dd2656046434c691c5d841f06788628ab52a73c4267629ca63cba3eb7794dd636ead169c5ad89a22a8efb31e93a40439c2efdd3792d662ab434261f8f6f48732a863ccae736eef7e291654951ce5faee97df4aa649d3c1a3cf946f36fab783e3a33356c9156636d72450b2be92b0b98336c4c8aa2dbe1e391b932249a361e530cfd692811d251dbc6d82c8ce35cb1611e7604fec2654e5ae24264b8f456d58254910ee300cc2142c2923190d30d89d7c7fa706186cfa9531f3d9da3846ad907f9012c9c67fd4fed6b31ecf342d5316473402e4cc2429b1c7c42095c8cf09f78f999615dab977e926e9c87bb61a6324fd34c9a4a883c1218c0880dee268f5861a95e3320fdc158264c61b1f9e7774e675935aeed86b4904f57038743b95011372a0167b6e59679eec201b9be3a54a7b9aa254853a73c1dcaf610ef7f1d255dd1dfd8d8361221fa7d51db1c1b34b1e2281db4b0fbf594281f97a7578fe71bae6109e1f5a92ed2f7918cfc6cb516a051bbbada83bb5690ce12063f81ef9fe4b9f2068511551193575942550425be96405964c118493a6e7b5bd5833e6a7fe21a9c4fec269d3ad7c6b45e0742517bb2cbfef1dee71a48c3e0a86f932290629901e5c11fef446e30923f5be449d723cdd34ad8ad51949df8a128f07166c7bfdb99095d314d8e6fb3e7b6f87993d8f48ad549d24a3667877fc39f54af673e9ab9269c061216cbc29d19630dc8fd52d3b886aa0f6a9f2dd61d3b33ab5bf5d3630e4ddbc54e95aed0526b876999320af229a7230c6da753a3f232d90485b36e353756a68daddddb63156a5d412062ef4cd25e939d533724a1fa188615afe820f9029404b9029039137eb5005536310c219c20de2e0ff3968aefb7fefdf7c7abe34a80446ddf314ffc075c35fa4b8320141ba8cf16679678d4bebd53054d41c6d64db4e247e4b5ca0accee43fd8a5de6829cad51b87dee78851ac849fb6ab34de4217df94c313e434483243cc7abb726532344fde4b8a290493b16cce9954d765b2fadd7bd2b7f8489b1d07f2dbf8b89b6ff9b2f19dba0663a1365b38594ecd2e94d3489ebfe48b332467b87355ba4c382edaafa3456a26a710851a9ae340bcafdc2255775c3877bbde1e7aa7b6d19c4c76359d897a51e208376e53dad7b3c6c93428a91c2e99e04c3f4cc66673a8f7c0ca09275820ba818b381fad34a5dd4d3a4c4a407d73f863f5abd6d163b517769fa56762731f9ef362e2914384d53dcc4904fcf8b550675e20b2728d4b00ab3d533adf81c9618ca3189cf7d74e823d0bdc67921cae2f84f3e303b2cdbccda2c9ced8c7fe770b7542444e105e4d89afd515d73a1fa5483a722429fc65dd0724faf7548c0bdf294b69c66830ab52829b10fb06dabf2e441ab54ccef8ae3a855dc28b4f693c7448c995b8add2d6dc60065f8cc660dc082bcd69c53d673a32a4a13a7c7c237341b4e04c7b2db9d8a0107a04a1d6c120f5686b4bb8c7fb9b3b638aa193cb1a0a83e8c879df74fd9af219e11584156c706112b34d04873109e9e2c5eefeea566dd99848312532a51f51302d3a287663d39c6eb4d55ba2278746c8699f1374fc29d403025cd23c437cd6ac1df7857ccded2c09f2a4831a186a68b1ac6ceaced38a4c979483f7213527da1fca68789b59c49279989db03e49e2613b64e330b8a3aa8f1e79ada95891bdab376d1e841bbefa3d84e3eb594a9cfb41806ab98643d5c5f67c3a48198c56218ffcdf83076529b965c19feba5d14664fcfa976342d490f31ed7c66",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xebb32dc02f33c18af3af5f3e16bacb7752708a77c7869f20aef17df0c25372ee",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x4bf6f91d84b37454544279cba152581ed6820044",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca75ef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xe3be96aea2d3d7b08496cfdd1e91a8c1e831861f97b5d8c40164d16ae8146dbc",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x774b84a0e54696656abcd904df81b164ea22121f0a6db71e68f41282ac472f9c",
|
|
+ "timestamp": "0x6a7a2f70",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a44a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8416810aa5d6cb30dd1fa4382cf16515a398ddb1c95e5b2b3cf1439a33cc0340d3178adf076cade5ddc49cad677962ed7f95283e974fa78f126472c4444f6623ffb01b84105a3b792c020199d4ab35cd2636dc8b7770b62653fe783743ab49b39894de311614c224362918779709a31221448a537e1157dfdc69970d8cf542aef6c9401d701b841adabef623129ab05fbd7f12b29b552e1ab3671e16d67e05ba5637467c01616ff6eea994175519baa9387ef6f1e35001fae7d34cae34f6ff60e2cdf94efa0cd1b00b841b305f2a7a677d43dfffa5354fa061abe553b1c0e443f6d7391621a80043331c6194aad393b1ae8dbca93649a756b2ff5d2a44425436a16597a419a2ecf20f83c00b8410e09fcbe3c488a7e7af9c5b12a106376f5fbc8d45c36a5077383ced37f41518b21817522c6a17147f4d824a505f9a9d75bbea4f7b21e9153606a4754b7d057ed00b841aaae9357f74d7d8b903ca88b6cc08761699c11ed40449993d40db3bb1b4a5b4e3918acc6e5d9451ed5094cf40a65911efa0f7e6c0810bf543d10699bd094fcfc01f907caf9029106b9028d3933c7bf1c57493212ec1ca8f072360ff73b9d8645cd3c108cd533e4177f208f27089ce5c275265f35fb486fcec4161434730d32dbc9ce9e76614e9ec0870596bacae87d364137bf75f2e8eeb697d4ecaab28c5c6aa7a921528b375b399e575bdabb99af32c8c34cec6b0dab7ba446a672b84620b46693a4e4c6fb880515ef9f311ef771f8869c64778688c1eaf1aeda7d0c4226ecfbda9695f874eb849e28fdfde0eb54156f42ad88eec8e6739ad25329c99f1f6a3d96d8b3748a3319aba2bfbced0b3b8f552444793d2cf028a25dc3c85fa5cf6350dd224c7493e68cb979669e06f7dd61f62e465302f028b90a6d97cfb5431b14f338db25eade8ebac4a6646e44fd7912ab1ce6fb4c93f5af1e580a31953a9eea3d6fae53f1f3a751c825ccae97a92ec9bf7038b74f1281b67a04aa355535198e26fe5d51bfc5c7626b3162430fc2c090941e5c852af098bdf1f9439f9f5e218f65f0f254a7d994ded9fb519d6f6ff3319362b1667246a4b4d97ccb2c455795c33f3a6356eb4366550f724aa3298626ebd9e1fff3a55656dcaa07234d8569fd3bc5d49a9f457740cb146c4a3abdb585c221f2327d3ec998468d125867953c3ce77ad0f9940a32c140ed7428cc1e19f188573315c8c16accf0bcaf147c939d1a2662a3e862f8bf6601907a69dafd3e574ce1e9d915f9178d7f120e43a29895398203cce26698f3358b62d235d89b377e6d0bd4e4a08a9b3cf16c1d7dae2076788aba44645be5b9a8bde3a5cc3bafa4f964d32e3c9ed530472dd12ff4450c558de13151ac5cfc6257ca77472747bbd068bb8d97b7b28c7be5564d553dbd4b3675179a6ca5cd5519cb03fbb49b42d8fa2bfb4d9684a317228d948ce329a84cdb9a8f919b2e37a8c4461c46be0705e220157f12bdb0636f134814f9029804b9029439028b05706a1ddd801ced71a36f7a63738b44800dbef980110cf886704fa1e346fb2191cb6fa39eddc5c419c633bf5cd2400c11072d6769d0423936ccf405906a49b510fff36033f2df618bee91d796556240da0c41c77ae1a9d1518884ed57cf66151ec24e24499f709d226e1081581d3f2ad648525d2d33fe840b6b8f9568d8328d519c7339726b9a4699eaa6271e42ab7ad18649257452dcf9b167138bd2073eb8ca09199f82643ab7944b8ccea77eb8d5767f1e2d59f19245e6ccc441bc38f3aaa405e8ba907cd44c86522cffff217dca4de9502401838e3d331d55c28f26274c19366f97cdd1f3996163d8fb0f52b4294cd62c238b12d19457e42e3d2b5b3fffe9fe507d4ce6f8f3e369b9e57304fda5d535efbfc4538be52b158f436bff8c129ba0e7206a7c19666a9213e55c5634982b94c0a4380e957d3b7425e52f5980322c0a5b50976759570f10e7c25e24910f7f5f6852d6b74cbab0ba02decf30d42ab374f43768721d9d910b17ebccef892baf28274985409e9df85e9509a8ca103e1c2141a35ef5b4147131606c18a493da6461cbbe109631ee9f456a7663e487e870d9453f63a8a333cc1928bc171c54526e55bd7669126574d2f0ef48fb3ae7d346f720729186ef95b66853b2edccee71e2b9e624a143e8f77e270e8af6c4f5cdb2cbae4355b7ed68822ffc86092961486f67a3956890ea9adbbc93ed6793d411c82349f17fdcf05364b5fede6bbe42a7921af19d6f260d033267d8e12e4b248b73a678a59e7605ac78b4722c731284526acb3e99af91e1a00d0e330c81fbb407c53b60760bfd262d1e18868065d24f5588e4bcd6cb72228196e70a4f4bbd4d91e6c48e7a9eaa4112204b0633b58068d88bbd56eedbb8b8d88ca508c030d51d977312e94423faeba4fb894313aced19e540f9029801b902943931132f06519aaee98296d5ca9955f1fac088bfd01e05a40ee8da91a8dab3fbb854529a2d2612d62538318b0b4ee1495b851326806252cc01778d8bfe8da3ba62069bbfc6afe1088eda4362829cd4b35afdbe760cbeff19ac299aa2555da484fa97b95f635b760f40e1a4a97976c098d6332ee2dabd5ccc888a4209829e8ef7f71d0bcb21d751f1713b091629b22efe18fcb8ca6ea0a7d80a5e1b844394c23c8034e30f845f6345da079845bbf0e732b28a276cbb96c6e9a41fbb678d8924cea6bd12f41aa5e1edc50b0d0d686f99f94925ce5539ef4742858a84a80e0e50b2c95b4dd64989753e5119ac27d8f6dfd4ec53fdbef0e751bc3918813b920c4c4fcef57bdb875902f153250be58ec0635124f2639c4392c86f22a27defcd865f968324a71f9ed8c10c69bf52f7af7908edf8ebbb8d198fe7f0b22b675a919d802e1ad4ae5075a1fa8e933fd37ff0f0bf7a2869e7a76390e428779fc408a868687dac9be7a7790d448cf979974698dc7a70f75623a38821b103e280b432a268ed4ad04169bfac9129a4cf88de6a3ed8e72d1510ccc1deaa1f7d546940883f7c04b07b9152aa5c738bcc4f2d1254a315e695afddaa7d4ba5c94b8a0874eda2832f3cd9a1ae2c2e11ed416d177904d6106912a6f5ff436cb518a3d3238e5db64ceac4624a8b9375e8215094edbd600c4d232bf6f8e58643e1a3205696667932803813c300ef45d19e9e79abceafac831148e74be137675ebf124b08e5ab50ca40e4a961f50b47bff2566dfc5be2953d8558d94c50ca4e7e7e43418558132a27829d7ead4b65cc62275de2ad3b48138955e9e338598531f7d83703c09fa9bed4086a0a7eb7aa431e365f39465572490a02d1e5b9f287acacb3294c64c4902aec04cfd5bad1c644e593acea44406888ae3dfc15e6096580",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x8cd29176090e259a55dc9b3fd493ac2dd9a28637b59370ff0d153959a034cb73",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x5f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb0",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca75f0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xebb32dc02f33c18af3af5f3e16bacb7752708a77c7869f20aef17df0c25372ee",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x8cdc6a0694c53cf91e7359ec1b8c4de03c4e3e31b29f7ee45238bcdaa190cae1",
|
|
+ "timestamp": "0x6a7a2f71",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-E-reguli-oprite-anchor-13268464-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841f97080a295e96af0d6daeb391343e34e890ad9bd64ae4c31cd8d4bf08aaf26757b53c23784238b6f8b8669fa137834f18e2ae8b24ef1410ed727bc32899fa2c001b84160040bd4b4287258e661411d9b651da1b0251f617079548dfe5e08ed989bd1f802e856d3780ab6a622e70808a447a06fe60187092e29c69f5beee9b4108059d301b841c0371798735adab3c144964ce3eb6605ee357e8c684dda3144b034753028c50e5438229dd212df3c79ef0d1b4e64129340118ac9a9123afc533cf95b05ea507201b841a78497a21564c37ecb9eb523e68dadabf35aceef638d5bcc587b7abc9c8b208d7fa21f536b500efecccc3f8bcde444a938784a7b558d8eb32afa66d69aedcaf500b841ca0528a6492f36c516fb83defeeb0a6914c3e9f7538a16aee00801a8ea8ca1c60b2b3ec8fbb038c1671d28917ec9b7a6e655a20411915ff07ff390c0ed87942900b841b49d9649985c4905b79fb8aa44c625366335f4d10aa439d5988a4fcd678f99023ff39f8c5461ebb3dea4a2294c2633979f9bbe72d363b2161d72d96fd8c2899d00",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x485a0d19a5c42674ead28a8b1cd228f69259083e407d5ba12d69d65094a94998",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x97473985d04723299559f49b856effb47d7abfad",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca766f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xe4894bd7e96e0449592d9936b0c0c4c67a7bb5c3ee11ae9d24fd7e28f86d1846",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x1b8701af3dbae71fece2b7c126fa133d19de9a99793347fd1a5c53fd7f66eb4a",
|
|
+ "timestamp": "0x6a7a2fb5",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90f66a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8414cf381ce47cadcd233ae919ce6d9ee0c9d32f094c2bab57398b5db96c640ae703e6c4e697a081fccccb71e5391b402446c82329d5c9ae3fb6a2d142938eed9e101b841dedb7ff2e8dfa5423c0a2da81799e7c5f899b273cb9f833015f38ea8ae6f82064e7a46158ad61f46e97af43bdea6935efd5526facaa4a52feb31e84bb880beb301b841e3f0ac86c19b6bb7eeea51c7f317413911797f1b12f6d4db8bfdd1dea9551d27414af37a40e75712cd00a9e05ec85930598d3dbc7cc6f5e703564fd9e891a94600b841b69120ac403e5228299c7a91541e85596666d87d80a2095b3b52a53fdac45f977c692f2f3f5e180a2dfea8f3685217d24e05367c6dec5f30a803fb8d1f24738400b8414db4530ac6c38354866991652936ac4e2e11de60f232057b7826a8946f4cd13d0b2dbf4bcc5491dd0e58eb378124b16620bf5580a6fd5b649c366df78efdddf801b8410c31d3859a10c44cf0a7b863e2604847895121f5110aed49b27b7b933345b2af0bccbcb963c085a7529bf454e170ec402eab8808fb0e9333ff46f8853931cd8601f90cecf9029403b902903957834fc1bdb667e4aa01a66562a40d2b79ce93bcc2127fffb1ba229233088ae9d83b68bcd76f508daef83e3e9ce186469952b75d9c47d8eb3874db1a34ba759a5065fcdcfecfe445aee62611ab6593788247c8791bf667d4f86f7c14b39b2ccb31ac853e3ffa547ac85392cb951bb9c6fb4860d81ad973dbbefc1bba3f158a405dac99816d9c060ce71f4ace01c1429c1767ce92dddf2e1e0a1e8ad22a199df335c2951696fed93bec34f1b84ff914d32d4c9cdb9747994ba7cffd8b8322fed411870b7377ca2d8421ea6d9d8a4ac970bc489ef41b268ab6a54aed932a8d475dfacd9bec36b32f262cd5df3cca068db9891b276e6747d72933288bdebf333d38fc781569501b793d97ec6b984913c99a717ccf5e2f2bd1adcf9424e538183476f59a234d42065cbc4dc1bc7b70e56556977ff37e2c166599f20a72e08b4092b150e02f4d3ef3919726471afcbdeebcf40681d064c50f968860ea9103ca373a295d5f7f7c90fc25ba515f60dd34cd64d89bb13bc829e9240873e0de03b1836b50242a92be64d75bbe9b6d937bbc296af16e9c2298eec38747710d9232a13b8527a3db743e42a7ee64a5527492b1a0a68a2f09e1e794b6578fa0b6e379773cfbad6743b39319d2ddc6e4a30409ca387af590a86521afd7551480736307acb7409f7f83effed53bb05d115539375641be7493dcdf2592843d7e6afbf6c44230973ac46eef3cd1b5f1686eef0df6d47dd6b83a1868ec54b6b93b989f388ae6fbd7cc5d8e0ba771bbba78aa3b51c2e7e173e300e81e093d66b48eb226c05ed6672d4e916fbfd20809bb584c6b84e5721259af9698233388e625444e50b25238729e148fb6e9dab17bf23cf346de7d8dfe13fe3b308740b4959c963102eaf06f0dac3f0b12d6dc30d2babe6fadc7704dfa85f9029405b9029039c2fdfaca0ec659675e1ace559bf73e777dbbc3e5ebab7b8e9af4d818fdb7c3ef9b1a7bd9349a13aa7170e816aeef5f9ae2bce7ab5e415672a48f4d938e6ee9c7f82e48c7712472f469f6e8e4c85cfc6e114ff8eaa9930b52a3ece358bdca793440a0a85ea1ec9a198b3b2c9d6c865f06455a843d5f6cdd637cde52c483767f2cb5edbb375ae27f73683057a098cc84472f7e7bba73236320c76ab1da8aba145ee774bfc65a6da96a1af932092e2e3c74d729ee308c5ea528c6e4e45af25912e55d9b2c75ada0702e132896dd0da34b563d7a6e8b590ce2bf4388a03074bb0bcf47aded0341d281ae50ccd75ad4df22119b7372d769921add6a5b57f4acb3c73648ba79f2c8258a6ea0b47f0ba305c943915f832f576b1a7c4b0ec4dda9ec82aa78a3973e0d57959464babb51dfe62269153666ff3c4a15516b8a7f227153ed0e9cb27deecb6dd35135a4ef149717747596fe7f959da28f244b9dea11b93a08b4d0afc2da8870c20ffaeba395149981b734e599257214d872fdd1434993494ec8306a8a7af26dd3d80d2650b434a8f46f87bacb7b2b4d4066b8325670c43b8faec6bb99985c556566cef3b5b843a4c34fc816f3443b78857604cb3dec36610e9339f78d3b7d99eaee71334e212473eb7b8756450525dd335f1c9e27d899a6f4c7c912ad16590d2cc8e536026876ac0bbbcb9b423c6c693237bb99a6dde26cb150f4a18268d3225db6b2783e39b5b9105ccbae4bbf9d47d81314aac7d18b77dec3505e66a637e101376a73ae551bfc15136445fa858711d18fca7852e94ecccf9f55963f5671db78363d4ab23fdb4f225d44401a587994e2a3ae2d4e6aa04925eabc6b53e3ef541f3e2403444b5265b1ffee4952feb90e9f421974845ae0e62482ad0d94d2976924fcd93cffcb6cebc0f9029201b9028e3958c1da2deeb34942289db3a4fdeaf6b9a09acadeffc1a2950aed29e1366e423b7b8159086b044c47a9eb7a220d27a54533dda46d62e0e71f9895e6e31795de60ff0b4e414ca0ed676a820a40ab584edc7e33dc4724c771afa1ec452d11261d9ebc51bb9ba0f516ad915ae4933a121b5cf37ad397a646415c63b7b42eb54418a8b95e7a123d4344a771ffa407beb0bbccc3fc9149a6787b6cc3eeaf64d0946799913275fd7e8daacb1fbe525889cf0d0c7a64b1ae7bc9ad694e9ace7ce4f38ce73e28749c20a97c5fdb448f256ac593a5335c8d4bf30355b5533607c18fe072a793ac2b4139181c91325209553a48424e84c2a046cc2c4b53d7381cc58d8b20fdbc2b184020c6eeb99b8bb7aa964c845b6572ab1732d9fe20dc06f7028c485b4acbe4d8da1ac7f4a4383044ef9e9b632a4a2b10336d03b3c837e2f8a029f9f76aefa1cbe64c649557e8a44d64f57cdeb94dcff2ac8145bdc4ef37b089982522a1ab21eafaa1fdc12c1e6c94e782e0f0f767f0ad2416d67ea7dbeecdfe6e8c1b61ad8f951795c55b630f0dcaa55e8d72cef7a58773fafb0d61e9e1372be914893eec856e93cf66c8a6712e9379f60a66a16a4dae28abd69b610399c7cad864b5839dd3d249fc0ef774fbea65973e5a8a62d11b8d2f77d9b20dfbfddecdcd7fb23fa5a617206914b7f246aa31a4aac8709da45dd426c9e776657babe7300cb58af6ebf0fcb2ced5a5a933d1a8dcb2414c21b57c2baf3bc1248a3c63ba9e12be1d1f41255075187c4d7f95bef044b0c6c6d4ba4d0e227f5f5e2efe2804fb1dad594dadcb5e6063043f18f2bfb318137beb60e1a2438046764849e14d672d9aa58d95a056f8b397849f2fac20ecc2b3dbd56e2c7c7373674d148ca011e16f49199233f094af10dba241cf276ef69acdf9029080b9028c391b8404e152f9c4ce1916fc694b03c963cc4e1b9b292405d8a77650e927c1bbd564f484d08132e0dea7c8c5af7114373aa58f82084674d4261d6b67dcec1923ab439439025fb0876565989ca637b325d9ee7dd4f617ed912d6ce432a3bb45c9dc463451b337d48759a39a2654a7c5e7ae6ae98e8ce3b771b4a6f83e03412f50d5fa26f709dba3faa11aada3a1a3597ff85d4b57b34e93f53fb66e78cbb46a43677fe08409053eb8b604cd7316bc589123cb7de4f4c15a01d5e4a086cfeab56afdf46c1730db65de7a559ed8a8bc6e978124ddf22bb1d16a9067bb15c5eb8536c4448fb33453e21c6d749b826e148eed2f40ee1a89d9ac50742df907cbd44d3b114a67dd4d32690f409b3baa60c4b21af2c39a6164877e3d8c4475baa6421f9911a6518588ea210def4767895136d3aac277a97758d8ab210268dfda6c9b9b35fccb9fb493570234896b4f873ea98b534747b00c6b87dec2948a11dd3488e6a62b2e60dffacfd34d0a11ec0b3086afdd6a6542af9d5231cc097e82b14713a72d5930c4cf4cb9cc9635389a929ed93bc340ad552e34ce59a788ba080e7ef7e6b3b7bdea0c271b19203a274e0caf2925df6824098e73df03eb2d99adc20f81e19884e660e4a70b3c189de2a26243bfb85549669a3ddaf04d93011ca42e306ae7216d694f0d07366dd938c0c63918cb198b28d86666ed97e416e4734de8b5216be65a02d39adacf5f282848ae5ee5d9427b9be47377a9d164763954da5aa16965745c27a245e5a4c34e5287769f3344bf83934e7811f88dbf7fe2773df30e5abfc4fe55170b4cfdbd6730c5bfd0a1aeb90897bb2b7aace2cd42176ad0aaeff27303c333be1d744ac28e4694e882acd1bf72c48210d3386b2fbbc2892c8dc6a99545e2d62f5ac68e53e51836e2d5f9029304b9028f39680fa735aa76def00cc1687b4045fb948b7f4df485a0168b7b8b83bd452548c16ec29f10228994b2b8bc507bed62ed9ce748d1b4abd1947e9ae18524f81d5482f28eb2a839559970e8c557b35511189a38c952e5c870a2658cb261de48aff42cb1d39243b74aab8bbefb459b736ebb25f936c74b3e65e2d917130b71dd741f24d5e9f8b4ce3c834cc3673d9dba1e5d3937ad860b3d3fb8ac5abc4211f9d961e5a861a77d89824cea5612ec25bbd5485a6b15c8bf99c31b44864d45dec2c8eb68f7b4b6acd26699cd66acab8904b8c231d85a6ef9b670a00475137166b44c913376d2151088b3b40755807ca7899dfd981a32cdafb6922ff7af8ef730eaf708b86f60af20ef434b6304415e3b5682b682e178f6bd549cabb8545dcc41c1a4e874982c9bb0d3a3769171b4b308ce4d00d7288e031655e24771fc803e308ed94a9470fe3edd3b2dc15234cd856398d7db2d5b584b8e5a758f51caa0acd096b27e75b6e2513d5896374c926ba75c85d654f379e1ce177ffdfbcfb2b7f54ef30155a0ed2e832ab6b7855347228f326f120ce45aea289c8b57a76a069dbf4859ba8d39fbdcfc7c398586c5a6659b44213866c5f372fab36e7a2fec49add0650d914392f30af79b1c7bdacbdbf30ccc5691b5b3f3e3accecfa6de3cca1caf753125b82a5edf064e90bce1bf853693bdf30fa97244893ae5ebe4b4c628e0d9e397e3faea2150868a44ed3d386422cf9b4cdc3a3bbc6cdc6c449f755ed73f907d37158d7fe757c90b9732eeecd975ab8e4fd0ed848496a0e6e74799dbbeb78907731e8ce7b66a7f0fc597d7a3531c0c21dd94aa5b0d74bf1517594e8e406390491f2de2415fed847e3d993b0424773ff30d02ef7866b32fdc7719b1b559f1a81ed7a26b77cbcdc235a4fd156a92b0791cb3ff",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x05d6f35007095e754d1bf8a0f7ab7bfe29d764de1b19db0828f2dff33220e880",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xb5e768cb3117ea25175f51aa956b48691025c2a8",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca7670",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x485a0d19a5c42674ead28a8b1cd228f69259083e407d5ba12d69d65094a94998",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xc8c8bd351e759f3f90493c412a80a983878324bd911a460bb0ce291885cb8e34",
|
|
+ "timestamp": "0x6a7a2fb5",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-E-reguli-oprite-anchor-13268592-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90cd0a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841996b4202057df1123c2074de52369901ff2571078f8823f2c2ffe52e0e651c867d439602acc32d691f4bd367aad2e44fe8789866c9febae5308296350b5c189f00b8413305ec15c09be5dcb14ddf0d02501553885aa35f1229ce2701aeeaabe3ff499c5c06588a844835dd195a9f666dc4de42946556126a6af75ccff5060dd43f7f1601b841825693edef530f4784a10b320a2f252907cc364fab51a65c6feb28edca3f10087e076af8012fc792cded2f05152e025b39b707d4174627d28ba1a30ad2ee835001b841136b3d7d0ee3757ca761ad9a1676d7115a1e3b9fe0cec244f8ed6850e08aae5e4ad1b987c0fa0b90a39df002ab3faac8ecb5327a9a2eda804b950aaae01c019601b841356c76e7b49bf4b63c4b41e69b0a99ae4b0125b65c7ad36725522b59640ed9465347e3639cfda9d519c45d962b57e7880bc33db8b2905db927797c85a982a67901b8416cb77981b3f555c96dc90b8a9214d9747971190ac0574fd4679dfe7a877a422951178c8f233ee61ecd663edbcf4dd7c0dcda98d97fcbec0e6dda120d4602684201f90a56f9029303b9028f39eaa63d17f4d58f455a198279cecde0311ffdb3a5662b4ea3074dfa2119ed901b331ad5a9c89373ec886ecdd6e8a05fbd1929f298c91e3e17335cc11a421241d195059854e0100cfaf9bbef58a254be5e98eff925487ac492e67db6d15a41a6c97281812cecf642097822ee92658765bc56baa4467c93a76accdb54f9cd542fcc0d5966eb16aaef23005d6d221249a74af40d14f498ad9f82cb00c0f43e3eb7a6fad3f12dd85a298aca068375ed9d41d53b92fd96271ed85b87716ad4e9bb89168c8a3e9ba5d97b3c5d2929244fa20e358e87d56250f6bf3259f79cb61189e34d1348ca5d4ecc5b9ab615bbca465b2cc552f3055832b7ce5412d852350a7246feddf14a64859fc32fb885b7526f65ac1aecb6d46e2a56da15fa7224ad4c0097450b4ec1b9fe45a346bb03657efa14cc19e4d4d45142e318ed3d9b640b7e96976dcf858a249b1cfa21547ece462620dfc763449cd41aeb0759afde25288481c74bf48463af81f24b8a9c5d2fd41655630c9b61ab1825557980b3d328bba1dae4c954fef636cb937f24701382ce778c3942f8a014cdde4f732d4fd1d6886430cab1ae4718f5e21bd36a571e913629c801bbc679f4d931b95465bc269903dfb0fbaf355d0c15fd45698986dfbc5c7a03d290f2390d0268c9242c239d1b6a6fb1134910ec13de9de5f87f98e927226bb4587078369f7e9047f35843f4a1310a9635e94294d61db966b27709cb26f57e27af444f2afded8842798a58ca1b1a9a42796c6d0669bc454832d132bac0dfa506ebc4d7220d930352d25d4addc7eb6be9e2ffeb8ff74b5f7d7bc42a2ca34cc95291206c766befd5dde4e30b42d0ec260b9ccf46b63b7c7bc4fbc0530d3613099e787a3c79966d8d46b0f0ec5b0e927d8e72064b94c9eb7acdb7ecb41562b2e3e0f9029106b9028d39dc1dcd80c395557972648b02de0739218e85e0d88b100977ee99129da0a415502f6bb6915c3fde4e448cac0d20ca4663b29ff67ebecef3c926fed9547222f39e1c3f959624450555a4e014696cace4b1ad4b7363f3690c5260ab6dbff5678e226136487ef3298accdef805e2db639f4e0ce68066f0ca325503813f08f218caddd9198b392f3c3433d0b1220829c68d376c956a274b6c5efcd3f7d06cb7f29a7bbb06cfeae9d127bd12442eab12cf2fac5d9d29851149eff19679f97bb8d358fcd252f0705ce494ffd1b25e8aedea1d9e4075b55c13b1c2c0152ae4de25439db22c17eb7a43b9b864b24066f0d7f6e2324ebf4d579c8571d594295ecb77654d7a1cf7cb1a12e11ed0459bf964a729c2519b4719d5428a889227ca8c638186e467313a1a0e8bb4d5cb52942a48816cc983453965dc278e15d7600821cc20e724c4556433582eb9154e0af48e3fc576589652deb792c7d30b3363f6ed3a0b9c682a12ad2bb091ce7c4d249fd4eedad47e461e41b46049d302423e33a9ac83415752a93d5fb3e93b4e78cec8c564f04fae1537d02f71183bf723e03992186aec85a60b4c24bcd61034abcab149d2be945d5b203b4e0cad5ac1e70d4ab1926fe87ad8a1484cacb31f3e6750baa393c4ea67aa7058fc2b4fbdb228db8c7c03964a102f9713c7c74fa3fb8ada7e83ad9d0cd40f10e835da9a33d083c913667504fe45a4ac0adc55ed5c959cb140f4e951956d46dff3a093366f14deaf2d9ad995c4236f5da0a10932bd3ea6dcbbf1c9591b319bef3d5677b06e298aaaa5132e10ccaaa6c6467fdf5a8bd8c8d094c4fbf9f3cc54934af3f8fe50f29ca4dcb3fc99aa8e3049b73315d26310e19d6a16b976be38edb9864ab548e247cf83172dde210533a87b63d1a0ab48e69de7cca722f9029380b9028f39b50debfae3e608ceb905f7522de1c23d464a83ffd1478de6a8c1499b63f9b265792673b16e1f0de65f8b1475e5203ddac499a02516cc6212bf60bdd964189cebe1f9b238cb758d4f75a1cf4ebbb134811ac799f6230c61ba0c0882a04d47636fa93434163491418cc6dd13b9ed6efbe418a4e2e195fe4fd765d33345018395c6b6768b94f8bbf5dbd4c221b26de6592dfa9d0d20308c27acf6472f13443e8b9992ca1db862dde318fbedb912d8d621b3be6ee4fbbba64a112e479209989bc9531bd43a384da7bfc408441b0e52672d7a2b4bfc451aa948a977c91e4d03f96af739771727a9854d58566a8d239937a7b9bc293863834e179c7d51a5664e0283459d1504307aa3b11838e3302b83437e7b74708ebce4fa7dbbf2e52a8937ca9519a611bd5bf7a97d9baaa777bf3a7debcf384115e71723ad959c38050facf541a3af2d6643e2a8335b7bc53f54345892332347ddc6d4661b520a9e2a6a0afd328238f5c7b8811b6a3d466f30451dab36758a2a347d72a5573b1ced19944c12b35069903e4e4f099362ecf14df3dadef348d4db6c202bf33fdb8c942bd2c1adf354741a6ab75684ae58154afd9d67a2e4d2569a499e29e95a88c9ebb9f645bb066b2fd936cc53e0cb43e7d4c3632eec93b7ab57b15f1c9ef5a58614fa1e74e8a35cb92bb2e9cdb0eeb578e872e6f3f1d16feab82e9d1125f235dc5d1627d9b87b6c532495654f65b1c8640a63042b74e89541ed945a66abf19cdce93ad95db4cf22a4f151d6561f00c5329c53adc7c7c6b93059747d04af3e55a2953676d13686788692be4a31a731668f4282143b8e5bc681b097ab03a688b0be93be442e11774b4b1d8dc12e7c62a68b48adaaa38d2dbca788f190c8a358d23baf2c526b030fc2c4ad946630bc59b4881a9755da40f9029304b9028f391f6127f1d597d61ad218df994ac57205ffe86c542b1c0d4a73e0cecfee6caa933cc0d2c358943482a762f452d64bc481ee19c3150ef9b57ab513bcc1f4b636991f438ed217471f9493de608df6f4e2f22ac922af918b3a9a2329ac816ca65698d1a9f5e0a8cd1c72a9079da1f979274593b67d0b2fd2e89db07ca985579b4d9a971639b998ee394d114058b6f0dcf954570d5e0d5782741d182cf9eabb1a04c20bd75b730f2fc64624cb989c351626010985538d3a40cdbb9e7f7cf7ad1a67a5e431f1e5ffd77933e58e64723f566480bad322ca527ee21ce9670ad2eecad0bcfc4ed4247299e310c659ad8e63038d56248a7d725d2c24eb3cbbd46762867a99fde551a08e7a387a99446ea866fcf04a818442d45d66271ba85123318dd14afd71e50638ebc209260acf9eceade5115c8213bd6c8dc081a6e54f676ca446b1aebb42231fed9e55458eab8c6afba4e0f71aed7b5dc664903a474d0dceae8aec77a591c456bdb79f2ff587f15ea124c9d958871e89898439d51aa4cff91465b0991487bdfd70f4f9dd2a9e4ba0539ef776c4b48e93535da6d1d9362992609c47c9216be21c56846eb2261bbfa35121f78666050b6a5a0c214fefbb1016794d7ad65c64d8e4eef9c3ad7cee506aba4a40d1627e5d893dc5c1ba2a7e4ce73f8e8717185376b3f5467a50c137527f8f614290a04bf4524651356e02336dbef38de2bdfbc456df6d5a2f103b84469496b936ce495a9c5e78056aece8f1680d5400c9e8af2eabdd3458bc84635d8cbf6ebe0771efbc24e6e9ccbba4ea2316e79096958ba1f73aa8919839062b3fceedb57a04ee9eca3d782c3f8a46f0610f7c1b56546d1f93099cbbc8248a9c235a5d6a3c1c1242c0c0f7d9afe7abbfed65876cb0e25094b1f54e111e76feeb14d6d21358",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x7366c8d740c101a72e159e82b3d1e7bec7cf3b4f39775b65b21af459e8a9bd8a",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xc3314fd768bb68b986e80c0a14175f6f72630d7a",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca76ef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x83f18974cffb9b902ca18d325e7dbc82a95b43dc76c75d4a5ba5c1c4f729eaa2",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xad3963e842299f16d7956324a1f6344138c9ae6faed8de6fe99291721e3f0acb",
|
|
+ "timestamp": "0x6a7a2ff9",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a37a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841e688eddd2e0ec0c0285544e4c69cac851e81862ca54d81c19e5c07f8097fa52762236b97f0ae4e8608602d751c171da84598346657211e85e10d883067b8a55301b84162d991dd813ba748d63b2e893de5475d09ece9ea7c58c2098e00fb72c4abefc31b85e3fe2c9487305c22592b8b44ac0b0a4161155de2dfc80fb79cc81190382f01b84121ea707ed3d1587439c29ea4b0c4ede9e5a968c563df1ca148509b93c0e51c614ebdb50cb72ee6c650d1ebae4d0bce5aee96b6bb270b0cd03ba2785535f08b3401b8418689f070f1f2cc08e02f2e974f0cf6a9a5771f8f07f07ae139636ab7641a26d666e908bb3f57ff422238bc8381d683151d32ddc3ac30f76e26c917eca88bbb4900b8411dbd29f07842173df0d929ea7001dde8d78b369a256305017f4cbd55b053c9e13e33954165df322cb818ca2930ca6659444a8bda29b9ae625fc1cea87f7b339701b8415495407eb10f9a039b3138da48ae6e6c94dfa53a8067cdc9532761d4d64da92b5c4dd4ab9631a462c1fe82d66d48225dc0d10c49638efdbc9b11a4906507af4200f907bdf9028f06b9028b39f1b913245f50ef5cf59d073e176734ac32f482efe545b57236c84bf5277da26a29cc5bf7a8d76cc37bc1567a6e811d68ced7b62d97dab1d0e9a6251082e26e70b5829ab0234863950b57933c91a262ffbe060e510059663c4435d370a489f68787fa54aa3364ea1d18516f70751ccee06e0eca670b7e7a9d695cfdbb8fd7b5be6f07bf06663769b4fd19e28d7b2fc780727d74393b5c1aaf5764aee6f9b322793ca2dbdeb6521eff241bea9d5bffded5531bbe5f8fc2d4bd5d9f4c5cd0a3f8737d70a7500c10cd330fd48dbbc2229d1b1f8e1b96494e813829159664904ae6628f3d1c52e10a42b3709460b4f9378c36cd9b6eba753d26469fae6e16367f8173743a6ba58dcdfa449945da94f7e432ac75239d9dee44c537a0da5791e18ea354ae10446b7bed47777a9d4a7fbb86a50e24b71a69b37bc9be8294c235f02509ad9d25b17ab3ad9ea16dfb6cf4986ee2888544aa6a96ce662826026b2bfe5891541d8163626d120f248f13efb5ed1ccb6336ae92b1329b66549752cbd86a9408b254822f11bd9feab39fdf20f5a8bd6f59c3a05c1a9c035500a8d569382278888f2738c343bff85d028ccf523a2824c26e4dcc74f577775f030267a256149ffd9a6a2b9af645d29df2b2b068912ec01ddecfb621f09e24b5d87b4dac2d9311f98aef5f6ddd9b6115c32dd80405a3fcf7197cfdba1060b47f27512dda5da9713abf95cd56a4916e1f3591a45a76f956c73f3a51a08cba472b66491210e95b2d8e625f09801988541d5b71a1845ed702d72bdf7c5fa308a6e707e3c6a12088232b167029be49a21646543d353b12ca491b1ab666710bc375fae58b452466671d666131fec2a22cde19cdfc5a8d2ec344b97620d1388e1970acc10e3ca19c45384b8288a9146d5933ee657e08f9029280b9028e391ce0b05a8ea8e7ffa6f5eb6562f3252556f3bdb606b74ee9a3ec41578aab5ec5fdd32032fee84719ca4e192c4d5b672b4e5ceadbaa83cb113cc2a5b8a551f6d2e20aec46a6d00682ce90232853fe8b9201a7e97adc3483069443f63c3695f4af911e19f7e3a598bc4a5d843437a6e8810d93909a3848c44946650c9f816d75787cdd1c57e8b4eab4bb3b5a234e463c5159256f3bc84a97adbfb1cd9630482c250acb198f36bd30dbc928556fe1254fe38a9e421d9df6c3aba54578416dd29231a71b9c313f7b599a4c72daf7333f1528a85451a6c998cfa3af949949ad6a0b4f4f226dde36f1436489bfddaf218739cf8b3b5f0a1ecb328895ab5de68f06865cd107632f3e5cf4e45f0cf9c5cbcecfbb91d3dd4a7e518b2e91c8fa2adfd57728ee76a1be6e253bcfdb6b86934a53965e6ff5c1c7b6a8543e96c2304a31eb540de2b187b124885ace9ba8b06a4cc55ac74a1a36aed05ad8f6e8d3eda2546bb1574795b44a189ad6f72c7a1fa2f09ca954c9559f1ae226c5abb3b666cb66b963db381a70ca38b32cf17ef047abfaee0e920ecc31f023326e744c968194903b9e8e338ce363ceeb1cb0ec9be5753f5b1ab79b8ebbbb6a850b31b8cd99ed06d4bc48579451b2e190c4de2458dbea936928686c2f03eb17ea717342613ab13c9ef4236da4e629f1d264e7e091aefa2e9741cd33d9eba9f4ae34f64f1485aa562a6fa745aad57a9ca20983d45e27efe645854be7b33a7d432309a3b698692b3a68520c3526ac2e68076676d2f76f1cec0b34b9f7305a223900e736efeb6ec622ba060b869c27df39be92d3d5a1d3d688821ed24ca9f4cd1d0a785ae5d67f2c5b31b084a6b23f6366c08d236d21f6fe3ad81e3aa371932a6ebb79d66be1f59c9b5b85f06e3a59a325f04ce60b54bb3c80f9029303b9028f39b52b415954ad267c83ae222c0f14ba28727560656bdf64845034b64a56a223a71557b8336d40ebda28761313e38ec2570a4918e342b056cfa50cceec24df645111d52a5845e13cd144a131fd454283a95391f9ba12f8db2e14971be7d8cab478c9de6e5fc02dbd8b24d8eb480f0cf34734b5d9e32ecbad8aa862d5749d61f5a15a0c7337fd575b4a0e5a64e8fa26d5054613938ab96ef7b565cde6b1a81cc576a473ba053a56abb27add51cd9659aba84b0305650d54372bc49a92b9e3fdbf1ac20ee0a35dc6ad91b8af6ba57700d1f264ce2f2eaede74bb2c5e8fc36a9dd3350d03edb02ecb8d03b4dcefbb5e2af62938c4a502fe67c8ac08440f072107b2bd770fb76d46bf6079bd5753066558960ca294af1d5f8eabe1f351824b744ad8edc4b9ed9cf2f1068d3b8344697993754bbd66389112b123ce594dc7258c9aa2f9e8d1984ab88a9ab34dc13ced7bfd0f83a7aeca86e16253dd6ed9b6c2d06691ce8ce27a638f8a9ca82caeeec242dfc2946f265148765b868b6d8b71a8f40614f5430df286c27f25487238832c29120a8430bdd895d6e9021364fd5fea4bd1b4c11b33734cb159bec31cd6671e1a06abee912c8918e8c399198c1346f1d620ea6cce2fef8bb2d2beca2e8eb3810d29ece696bd2a896b11de372ad29c6861e9dc0a7f3af4277c9263c53c3da83bedb268a9071347be147660c71af3e0ff3ba81cea9500ded7340768a11f9db28ff99f3c3947118d547c0c8aafff6d3f0b69378da5f12ea2b0c1e175934458d47958dd3a2d9c32665944517b5e22e4ccb47bc84b2500642adc5fb1356211b467c74d6ff8502c1da57fb1de74929da6d4b92a875da8648f76bd5a77fcd16c5703e08826992cb1c3b76b13f7b968c933ae7e2205c0855e24ed5ef75fdcee22cd098cd0a0",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xafea52ccfea11ef0d90fe07784314b16129858f44b0345977b6e5aa0c525c8e8",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xdf09b32c761620c5be77da398b97a64f03c3980c",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca76f0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x7366c8d740c101a72e159e82b3d1e7bec7cf3b4f39775b65b21af459e8a9bd8a",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xab6e11e54408040e6bc37eced65a5a7e6d4e939fc7067c76c9c4698835d57af5",
|
|
+ "timestamp": "0x6a7a2ffa",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-E-reguli-oprite-anchor-13268720-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841d2174868e0baaf5931795b6f0bdce434249a2bbfa367789a4eb21a8089b24c3e0cce6d79a03d51f4a822526ddbe36458cc021c7545f5a386965dd634639fbecd01b8410f941e79f95114221f00344fc13244be5a020ead3a2055b9d1a3751ade9ee96c32626c8dbdb4f90f3a72d8fef64f38686c00a716164f2426021c4713e3e3992501b841d38fa949d8f73c5b3dd0744891c03a809a42a97d0ae5df62ba74563885752d554ade746e8e688dfe6c2cc2185ef77270fbec14d9d0a007637c41f3f2d6b5c9e201b84195ccdab88547124b6bc1a79cca5484c731733838940941329fda1e242478fbd0238101c90bb64284c292b29b8271ba51c9eace3764682ad10293ba81dd501a0301b841ec520965987aa7875bf616069302113eb82d7aa870e4e06c4eaa50a7d69175de650682dc0bb2976110d510f6c8f9fc21f538c4aa24586d95c362683d3004db2200b8418e6686cf067ef5da16e998f3343c159b7871a2e67d8626d1188d8f478ebef5ed2d5704b641d4f3148702e096db3f8be7549079c2e05ac0fd54686a5dba713fc000",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x5cdb09e86a424ae0ed9494adf6e7273485deb6eb497e713f3df2b924fc772a03",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xe13aa491abbc1252dd714e7ca0e55717a2143eaf",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca776f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x175cfca9d483f2dd840186d85ea7343b615401b68684658847d04790930c61b7",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xdfa95eb92df701da44aed3e9590303ab844b28dc292861c57055990bcaf2a77d",
|
|
+ "timestamp": "0x6a7a303e",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90cd6a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841e15c20208eb76774cc584f0b795d0ebb727097b522882ef752efdbb29afeb282545baf99437220656caa0cdfaafec462375241ff7f2caa00eec696a801470a0301b841e3cb786d9ee1aa9bc79406bbdec51bdb1c27f43001fb27212c8b342d3febae470b058c98c16a0a847e66216a500e754ba9e2a5b86ac0a413c63807cd20c315d901b84143b92a28629d81225209affd92ddd7804fe26a11cbbf69ce7015b68b0e0cf8481db673ee1cf1157ba97d8fb5031be9b3391a9a9054d06d248e9e6bffafc0a44301b841dcee0991a5542c0542dd08b7d7d391bd35b09258fbc01663843906ea6e5f2ae90c1b8819a9fd6dec3bd6d0840aeaa666f94c30aad6614b9050aa4890451692b201b841f766466119dcb8bd46b8efdee86e4d7c194c1027c2c0dac471ea8802fb7244e940012b2b17533ab00803cfb13df9619bdafb0512f55c6de6afb2f9b251cb995301b841fb4f79f2862372391a23a01070ff9339f76ebe235a62d3e426878ce036fe3c47216573e331fee110026bb464687c7a685a9e5531b6d661256f26b3b10cf2454200f90a5cf9029580b90291394c134221c49484a568babbc8be5b831f3d4a5523739e274c675ff487849b767d65d3efb0c1779b3d8b420c56bad488a247db3c94af680a1713d30f44fcbf425a7228b2aacc17ff2b7cba415104a99056e0d0670290aced65a67e4640eaecc34d0bfb52fe9eca430f19d0c0d27f041d7056a0166e624a966fa9681b430d95bed5813a556b1216052238b4bce3eaa1b8d59ab5ef3aa7ffa371daffc37cafb3d2f7bf09c770ef39d886add9d773136ff606ab6ed30cf1dd9e35b0aa932966bf280dc606692e252c43d4d7c184c074b7321a6e55ec85fbf5a5174923880a925ad63390d8d34a873ee2cd223aae349e71c2337d955706e94508ceeaa506b140624d9889a38d34d196807fe528219474189e0c37c89a6c31665469d23b52892310771295376d766b5d725d3941522f9282ff991b90fe407e3b91274facfde5246b89c4dd81f0b92df85772c57962ec205c1e23439a31142516a0e83533a7aeb6467709cc27b9294523ea0ec0eba3ef4d0d568a6166065b2973c57b8f9401cb7ee754f879899ebe3f45794f476b88132c8ae2638bfd0f5c8199387b95912eef8d4f3f8b5a69f3a71696c79f72869f62bae71eae2f548ccc955e46e40d2efd86cdbc2bea4b0747f203226b697004b7ae9112748d84241c94888a41cf26f6d0832a924a861c8393999b27bbaacd945d2e389b448a8b15e18cfb287798b2e7012d687ba5ed677d92b400cb5a330f5495334e2b18b6235da79a1d9cf5258dc9b5a4a38679a63bf409dfa5afa22d04d9a43c1d5c7b32c7fab8cf974e1d31e6efbd1c363ab829e569a7f2c59a1c43b9a643938d765d6184cc152d937cf86a9e3d26169b7dbd32ab5b1f25ec43159dfb997491f5ad864ccc9ee752729ecda7b4ce6e5e356c93b2726571dc43383d6fd3af2557edacdc22f9029604b90292395be128ca5f81b869d08390ff31d0830cb9c11d89f04d04708a9cfe1f918d19417f196420420476560644d7081e0b2a2290fc4d4de57418cea2656ef9704575daf7e37859516e685b35a966f5c618474716b4e8b1bff387084c94964ea9b6b5543e88e259ce5891a9121a63592599b994fb90460779376c5b849d4f907088a94c6baafbc61717b2642158e52b579839d183308b52dda49e4ece100848c873662d8a2d1c27449c38733ccfbeedc4113b36012e770fae1f0cfa11e4fe76d1a78cb9eadba522aada53f3277fe09ed5989d642042671ae6465b872f075d235e947c225af9455da5b31adb28f654ca73c2158cbf3d3853530312e5e5e0df7d59e6e454ba372daba3b8699a176c83a7c9cab851b0fe43db78438bf6368072a95b3d39188c791cbd38fbcaaff30b2cbdadae283256f67041ebb06202fdcf39ac9ffe1082fedd09b3b79be5cf6f89691a5ed1fa329bdaa27aa3b0cfccea298887e0894ad1434bbff0fc4fcf5f106f1149bffb99d361dbbd4c0a9724ba77b442de42a39f95cd66dcd8d4f6d6ceb8d718c378cc439a065dd4663bfb1c82a98394a0adfcd53c827dfa5c6b1d251e86a34cb3f7d365d5f16a5b51a884437bb023b9732b0e55ee1852fbc8aadd987e57bf4264752720c9d611892640d35812e67f62fc66a545c4e63db44a8b16bcfe9f37de4be07ab34b8eb9e223574defb98048ad5b1c44eb9bd5de2d34aac36cb9f2d3130a6497459afaa0cf316ef25f7aeae5390a1af3e95696ad719c9c463eba326988659e55472aa5d1d2c900d545d149e8d244a5ae8475ef4139a8d70700ddfc3715a314762ddbed254fc11c2971edd12191a3497f7d4afaedd1b2f1205da33ff4da56b397ef0714d46a71474269a9e138d2a8c9c49d775b4dc459b966c849079f459a6af460e390f9029306b9028f39f410eed3ea3432f36b7e6623a72a50e55563a9dc5d38f772e945cf6aeb7862105ca7b8eb2caee1521aa5c6ec5b26cce0645046be1f2dc954a9d8e4355a779a78111fdf333acd8f61504bfbbb1c636cb6e7d836ef02e510c45cb0c5c8fc74c73c2a5cfb51e752311dce324f4bb9c6a53566dcc53cf17eed15ab93951cbbcf9674bc2b22aca7de3453d6231524c3156779f9b31ff3cd955a6fb2ca0445008315bfec3a31ba26f098d6fa3b24c5cb74493f065aab65295d4feb5dfa563313ec5f3583fb5bbdcd261e5ae43dfa9d6c9bc18a8d6217776a9581d46d7b463a7b21c6671d1c2b0aba9c66326d8af0654e6c1cde5d4c6b0b8aa84d58d75ddac14aa8aa3a6b689e426b1813598653e59ad5db83c131159bb2339147b7990c8ee7abccea57e5cea6fb29ec7be48c25e9d163bebd1c429ebfa0c6b128e1f5d249819b46158e1e83b8f4b507563f90d7c3e102919a624feec215b08911a43e9c52629861c67a8dea02b7aff33f2eb392b4e8264b3fed95455a78996ad3333d3c0d43dd2cca9993fff5cc42a5fac4f96fc785e4dec5d0711b9de9b3d3d364d27e306b6353397df7d574159e78531609efc1c918e1046293b71a9d5351659aa6cd85089b8cb8da9f94432689e1cd5a796d1f08935f3695b81a0ec29ccac7dab8c6948d6cdf776e8538478ce102ef288619a8af233624199ee024e41f3f1ee1255e5b149b0593d7c38a9aeaa6c0a9b35e5b1ff8d772d845a8c2b275bc1f939dc1894d96c657de965f4f6a2312aad1ed462f1895ae1b44adaa2fd54722026653061fa0a4ac295dac975fb80cad02b8947d44e70640c62494345aae76513f8e3feab3dda97b2a45c602b8d9dece1d4527baa3652cfc4173b118f262ae234dbee7d627482be9957d909aa242f4a0fb742b4ec33b68b475f9029201b9028e390e3ddc6e787d78bec6895343020b82762ff06c55292505bfb0d0ff65677e1dcfc097b1615f75837cb243a0559f0e9e5cbeb6cc0c3bc0729cd49d2de5a71ada7bd391608a7985ae629f4b15c3593697b244567c415f75bfeb2fe0a7735419c89eb35bd5652e4daad209e5837b78912b1b981aa730a3c521125b6a74ccb05d5d56a62db79dec3b29079f0a309a0272f1c8f805de5ef0408a551a36d4494e27a37509c14d773a458b8cd4e0febccd63713a7aa68310b1eb4b6a2d8485ee92e711d9c25493cad6c06aab393744e299ce658d94600b34df1caccef8e9ebabf49c5f6a2bfcecacc72e6b13106c7eac241a70d0b039b818987c2edaee571e3d8be6cbaafc8e46f38ba6be237eb9ac3872de0c11a899a74bcc4080a798373688ed2cd0c2728daa1c57b4f8c7913fd3078ec3397c79f656d9ab3b7cfa13fd50525bf98e0d01a64a3b6f2571b8b4ec3936de836b7bab408954ceb96ce494aaab13c36b60480cd501cf108656b30d86bc456d3c72e7b13729875a12f57656cf4819370591c6937b7fe768557757b5750cd4233d98561f42c227d1af7f4bbd6b83b2f5876f5fec24e2072ceb110d4d9672cb8c61edc48ea94a9f64f828cc24e4b9b08708ef26da5c09f1b236904a316f364a52b4b21b7f122ef2b3cb25177650f62b1c4299c1d1b23dfa13110686c2dd57d2e69ac0e56401505bb202ad47ce28ef39befc2614832e59d08905466be76977ee453b42a4ace8aa399be52f9524e73fe640dd862d4a9665cbbd5b3a54e7375c2ae5a5c68a44e448a2961c92328a41e1b63520ceca57dc5dd6610a487566a09263a18430a9f524596a569fbedeb8c8e363525dd7ce616065ed99b52f850189d27bbbc668aafdf1f30b79b5e8a4c5ba21f9b6c271df7a2b1c82e9458a39aebb58de78",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xb4ca9861ef00486df253bfaef906e5ae712bbc993c7ae1b616183b97b40e260d",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xf73bbbd26a82dbc769066550d8d4585eab2fc00d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca7770",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x5cdb09e86a424ae0ed9494adf6e7273485deb6eb497e713f3df2b924fc772a03",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x1aa8400a596cbf1bf24164c21ed31eda02497af5b2243bab16fe4b9fbba17f22",
|
|
+ "timestamp": "0x6a7a303e",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-E-reguli-oprite-anchor-13268848-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841443ea47bb0a76d098838667eae40f22034c53416a7c61f42e060f4185ee152f14ec2b9e525d1e9a0723d6ad0acb41cbbbdad7c3653f9b8a156a8e0640203a24e00b841f1c60304651dbe0c157f160463e67fdb2be9149fd0917638f92571c7e33b61e155a2f9081029c88b12930914d0f2f80fcd618a0e06f6aa51fb96fbfdbff035c201b841c3dc6e89c450d5d5b84cf01820e0585fb0b72a3c90a82be0e629f552975be11c2b06ffd60379ba2eb0bba36c2b27a0d36b9320d5812bb92dbda57586dcce4e7501b84181af139d5500dcb5e600680b18c5b202803cafc0cddd0eb4e14b1e4d4afc03b0057ee1349874f10bec1fc38c31da8ee7cd43eed679f8a70c1c0f0c07ab7709bf00b841922187c65715eb033eadfa9a7f9a7503e17ff077abfc90aae0bea255c53749aa236c4184f71badbf2daf5fccaf241ac1acc85116ae5d259729609e0dd75b6b8c01b841b9edc72ced142dc06f9b40e4f7d206e43296ef628456cbd8ccecd02453c676f63d8fa975ab2c99026e664eb5c8b19c8a45b711f03aab4ff290d55e80d6cf857800",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xc57bae68261dcf33683eb1fbc0077c2880b6c7d70ef1bbbfbe350ceb54c4949a",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xb5e768cb3117ea25175f51aa956b48691025c2a8",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xd10baf",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x7794d671f2cd61dabfa2c3dbb80c6fdfc366aa1a994de0421ebef875ae5bcff9",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x8bfbf3471009ba8ec426d71663907f4710ad63a7897cf0987421977d2168c145",
|
|
+ "timestamp": "0x6a7dbd14",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90514a05dd1b940658c0580e3ac377d127a3281b0aa98cfe34f41e51faab328270f54e7f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8416b3589ecbac63d9a71390cb3f03b9aee9d47f902de0a23e61c168f9ba59fdaa54361e353c432a74674b88b902d4b1509c507f85c551d2157e39925cdcc383db300b84189f1573c0dc18891c9922367207020dd7002928284bfd479a48baa398f4fbeef3369a290f1af6437ea673069d6e60598b3ecf652fa5c37c990cf265c421ced1901b841b0d9b3962c99eec8fb6987601d875ba86f6187e1fb0ba50c90f8dee44739ce70382e4bc64d86254534baeb3cb4bfe6a7973bc8a53b24a067198cce10b175ae1600b841bc1e00b90a33957e579628fea759c16e88f5a304a66ffd8bd5de945e907a6b726a7bd518ffb15ef3964189901d902306cf4ac3cdc161a83e781c2cd7f7c3b34000b841f7d9422eb12fb8377fa0cd135d9955f4fbbe2c8ba3608c82de904c4faadb762761860aba1205460623290af34c653840e592a2f749bb5573e3b7462983db7d9b00b841d09170fe05c0342bd43f02c76a55b9b21e12e51c61dacf4df4ad6d1d88a93f1a64016ebb1f064b235f79ac4d51fab0908dd07c4239eef80c9f42316e0ca9030b01f9029af9029704b9029339446671cb0333de8d82391ced99751f36c6bc51f651418f16be44561e9a739f7988e78c60eb56cfdbb7ad79b6b494d90ed0600d5d02ea6e0dba84d59e8cdebb30c9f01ac82e8ba74565ff74224ee67ba05781f9b642094a2df64466183953008215182f0944c754b709e9519a4c2aefc684a2fc7d703820c89577634840e2358e6fb120a7fa1207b736acfa0c4e0eb8541f39ab835e9067f937340c5c6355526f8b6e5877bd8653ac79c119ede82fa4391c4038683414dfd297860aec751a8d3371a9c87fef99c9da544958e90e05ab6b8f7edaa539b1c33cf00fdec0be3ae478fa2464fab145e79ccac7df7796592ecbddf3185b3348afd2dc483f789a214d46af90510cdd23487a6eb2682b680a12a4641baa0e0b4285a36b9ed66688bf51e5c37c395a66ce18901ab4757b88c9da94f697973f59c3229cc96df35c8d8de047973ba71161d43b8d9660f86a1fa43935f153904cbf0d36c9f271341676b5ebef2567205ba9f19873c285345d82939a45db9f8a3b359e73a92f47ab68c130ff63b71045251346265d1b9eabf194093397ddda7dd381d362e58cb3f48286428d017a54e9546b50545e17425d21d6cfed52e706cb7d42c92b3ecf29fb79b78512c496a8c3bb4a4d36eccdb1174c9b27669f9322874b0e95c0161a9122db9c3a1a2737a4310e1b89189555cdbdae22bae0182eae3456ae6b1a201e85d1192d3334fd30f5981cb92cabd3369ff98b7d8439f2a6dfe125a71e5b3e7e85c48cc84409af3832df868d8a449ccd2a645e5bcaa6fa146b942eff2498307f4efb41de6dca6f10c1cca02e8a18e24d4edcb6dfd5acbbb22983a8c6a6036c22c25597429904a9845584034c81228f5fc5eb4f5537fe40b1044273a675b04ad4c1c6600c9b88a94fb36eb526fbf4c69fa955d598517b73e47d",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x9a2626bd576d8aba4c257052d113f8d6625f9638ba428dc94d8d41794fdd7ccc",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xc3314fd768bb68b986e80c0a14175f6f72630d7a",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xd10bb0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xc57bae68261dcf33683eb1fbc0077c2880b6c7d70ef1bbbfbe350ceb54c4949a",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xbd4fd5c7bdb315419549a13fd6e6af46d204c1dbe50566d6898c15ce1bb05a69",
|
|
+ "timestamp": "0x6a7dbd15",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-L-prag-relaxat-anchor-13700016-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b84184c2e9b88a8c51eca569154636bd5da2aacbb180d74cc0ee14c9c56c13117a2959213df1c682477914e6cf6519112176183079b693dd69860571416200a91f1301b841bea5faea6f69d9e390e105390df0bd7464575b56c55f24da755576df9f694c670e497b9abac43b553aeec9bb0aa2d2692585f97cce7eaa965582d9993daf03cf00b84186502d6b8ee019df71c5c34a6b673acea972ad7c2dc408a043fdf8c95341468f21ab36f0030a92daa72ed02ecfa38314262557fe90f7c0e53163059755b48c7901b841f30c8b6b58e91f7c40b94b5caa30c56deadc08dad84b427483a49afba8b2e25564ed16e6300b8f8ef77d44f291f2e28cb459249fe6055a114c186c69d67096f800b8412a388c5a802d61d0b8bdcd0ae9080a39c97ecd57b770acd438c936162816ce801542145be530ec7125a2e4a91524a49d01107cfd370e9c40a7fc289e9bbb44c600b841e462d85cd529df788df3355c95562d74c01056f7fe6b65ec5aa8472bd48cc5056cb3a54a348089bc364e332879121ceb361839b8ce98674b8b2993a70e3f63c701",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x4bbfc448c6f978988e0ff22fab97891b04792867b2f3450cb7d83f968bfc941f",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xf73bbbd26a82dbc769066550d8d4585eab2fc00d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xd14baf",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x0b906aa2505bfc82e4d980caba5d9087720b582e796a7863297172559213c455",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x11d6092eb0a615aa921705931e7de41c99b4207fa6d6de90379a515df0bc2dbf",
|
|
+ "timestamp": "0x6a7ddf27",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a3aa017c00529dfca459f724e5df14145f2e40de7a9d3c2c104cf3259aba04f4d66a1f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8418597eb42fcf99f9d3062bc3fa89cbda2d0e4258edbf069d0a1c2bfe06f54a3e16d4da488efbd0226ec50d218fa7afac0739b233ddeaf7e1459f6e54c1511d30d00b841d032389bbc7aaf93eac15366fe4048f9076510c6a3b0d3c96e6e3a904bee742c1ffb27dace3f51ce76e7455b8b19ebab5ca991644d12c1a468aad2eefe9e31f900b841bf77efe5170998d534facdbd4ff811d37befa4c377f5e9d2a82874643e0c9d1a4f7bfc40342f9d1fe0ca3947d29fe0ee9b31d3b636706b55c18fac3846dc3f4c00b8413061b52748413ffb2d6d891986d80838f5f1a32dd114cf978c5fb5cfee9fff1c4ed12b5051198c2c348145e451729324b21965b9376481ce5c1dcfa0595376bd00b8415741f86877ae4508a21ce7ecdf110b380627d3689f4d4faa2ebbb179cf0deccd74ce7fa34c9a898f6dc16e5e1486b4454282a411fc376fb257b2fe085f83466f00b8416d3e8ab2971d2cbdb2eea66dfc582604ddb95035f7952867b1e0c070139c32733db6bd034c9754a3e99cfa470c426edf92ae0b1f37bbc6af23112ad5456a8a1601f907c0f9029080b9028c391436a5c643157962e95e74ee5e763f6dca2f9a5308e546fee7ef416d132fcbf7acc259afab2e45358ecc66ac0c34b743368a919f3c90cd99c944df770280d3d0781a6fb765356eb6ed9552a37f263d8b2b1dfae4e98dfca69e37f9b8fdb96c5c8d3c4fa85b3729a95bcdaddce565e67b9dbada86b23b2e563efc403f3ca562efdc317738f7c94a9d53f76d53b72b4fae72089834f8da3aa494b2c7da4326c8e62e84c992c128015a48d79b92249e253264759242ac93063accb259d2f63f5f5d939461a780afcc3ae74282795fac96064ca5671fe8a5bc99d5792db3a9736cd38f89ddd15d116862290bf03bbc4517a3a580ede5fb262219d65c724218febe5744d4c0d933cc3386e0b6bc2e9978d19d6c6f293f9162d735bbbb4692484c2cd1905f56da977af76d933773e62bc4e93b4b0b0d8066ecb28986cbb9baeee876f16969688fe1b48aec0e8e91ea9376555580beaf32d758d470ec3d7d5fd7b367ed674bf36d5ff2e1f89964cd88f5b0298346a3fd1c19afdbf5797153a7f2c94ba7328bae9b63f12d6fbeab40ebe1e1c847628959f36ed24c1d21a2e5b9b55a8270c4c28f7a1b9b7af13f1bf5ad72ddcdae164de76bd316d3388ae7ea03178f79f458b300478f1eb6527aba9a42adede3bc99feb17323495987ecd2b73ccefbd8c908adc9ff811d58717ca7d509eb1ec1e99b9516f72699b44c68efb81a55cce3f867cc826add110b5d2a34b9b29f286a5769125636b90e3c7b9870820f3d890ca3949a3b8681a13e069e1085401b376b439ed92dee6d1b0de9d251f2f32e896a30dc6a973ed4fe41ec69536345265a1a6eaa5f2ae544959f6be2cfa8bc9a1e3527f0c02b0fbf135d0b5ff57a29ded57681729da8ce7a1d3c66518115c133261572adb2d971d7487219994442f9029205b9028e39009f57d14023bed25f0ce28a6ad7e68b9f8ad8b9ea6d12785b44cf1c8c369e3fa49e5fcf4a93e9b9aa70dd26398d655f78133f7930dc7745bb6edca73a47e7442141a8a8e0d046a0947e679a7518ba334e226058b13aa9a3004e362c4e52fbaf4a1ce8510e32c466413e4e254f0d5d0d586e704f544581eb60f54cc2a25cb5db2e3c1eb7845677bc34189b8cc1845c9b478117c2c3d8077637d74a5e59075dd24df9b41aafe52d4b0c9113762a4956585f6db1ac925905424f259bcee82ab968fb149bc920ae7db6d6576e2440abfe798ecf3ef06110d83a9f8cc6e85923494299e7332d6c46c7a38da977b6332ca8b38c92e9a46578f8ff24b6fda256f278fa439574d030f77accc3cea91db5e74bad8f5cb06608ed775b4c8741768d6ff3f01b498ccae7bc319b4e99b38d289def679a6447e6a8eb1f7bb5b30ec432aad5f64ddf15a4cd6e11b636918af8cf713ac4ccb27f1869257b26adf474055d89933f14ffb935c7f0ba0c52bb45637c79ecb1f3ff493e6c824fce98f02f11cc15a632323d2a3d42425ef42d6eedaa50bbc4335ab1387c8913025dbd1aebf18268166a0d1ea93848d3565639a727f3ad8b33568a6912fb3fda95f1630ca6cd635963de04bd1bb8a648cd490d23862f878ef76874c43f198a9fc6dbe32d246049318b90e0fd0bdae8da77fd318e6b9f857d85955484ca513deeb71572f8d4849e8135d96f1cfc46da2fc67760e1311c5d5d7edb2aa97a329846e08d6ce74f96260efca4893d61b661e8e82a7c5de0faa9267fc10272127af4c3cd70e1931b8b4b3375581911b67a0831241a4cbcbabb9aaec7e848a66dcd20bace5272b8ae59155722b341a3fbf6c7a96e28ea3796b6a99b58748f6b02bec85a1b5f9d214c584b0128cd94db7e13f9af89a1b2153f3880f9029506b90291399f7d8a869a57371593325c7c8ea8d7e578ba287ff541c4276d7e00ca5bcea378b9e69abc14f0adfe423173a6872fbe6b064b22c12dfb86fa8307a0fc505358eb9bca4d131ea74b21fff3b33f7522c302745e8a35edf7d4a14aaeeb2cca1d7f25223f01e1b80e1e4547654e94c722cb6777b136eea99697be3a74a5b9dfc128b24d9369e499c8ff19331b26c4c092b7964991f6a1106357e7c6c77e33199f025367ba6fb451180d30978db5af2b5bb66b2a8e86e699478472326dd611f657e5fd74dfbbec9851f43cf99317a23b0874fb59038b36ec56cf0bb8aabf44f72c998ccbcffac4599dd4b74d9421294ab1cfc828d2d2aecf0aeca362431d1b92027514fdca9bddaba6ee22199656d81692c2cfac4d7c333e5cbd503884e7a07a656e97cbd33744a695c51feb0b2f7f68721ed6d7f5afea4998450c15c4c2c7db9846052240e20b976beb13d028ff98363594626005138c82880a4057d3a31f2dcfc30e04f9f246afbdfc4cde8bf6ae9c742d8dac2c3e0942335219c711a41a2c2b97896fa357288f090ccae0aa690491299134ca5324e9d3964a94cffb7f999b8dab8931c466af89028f4c5b517e044df1ca070a479ae51b87c1ebddfe902e72e8f5b513a4ada67858c1fb5b53793336caea605ea7694e8596be4e5a30bdc42d6c4fd24509c3aadb39c9e15131d27696c9bcc26bd3bc518c929cb2f89ba0452904fea22a7134f51d9690b8a32679efe11dee44e6649353f145c86ca4d2baf604e246cc7a3aba484a7c8c64fc5ff94b976586c6a664b90fec3ca219a048f071528bb58d6573ecd26a37f4569d3ebd3e1278ea18b8496e4302926a87b9afc020cd314933bac92e90a42658e77ba2e75cea87111164a7c5d3259b651079fcdce4ce98598a4345709aec649d6d7e1152aa90e6bdb0",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xe325097512fade024fa8599004282f92d519cb7b6cae3986497bf31d594bcda7",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x1bd5514286f5602a6762b0075266379d29af1c9d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xd14bb0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x4bbfc448c6f978988e0ff22fab97891b04792867b2f3450cb7d83f968bfc941f",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x83e5c7c90875139f4fbfb5d11f547c5fd82ab1baf83c7f3ad4e87535beb6c491",
|
|
+ "timestamp": "0x6a7ddf27",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-L-prag-relaxat-anchor-13716400-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841000903e47e0403e776d5b79883bcc8a98dfa262f3d5dfb7a1d9f1ebec235ceb83f540331b6066060c9726f243e8bfd898ddeb49407384471351eeb03df65412900b841995eaa1bf3b837294c927be629658e70243a4913d81759853b62ee13a07f16de66955a56229745d15e322724d3c58f4fd166123ecea860d17510a7aff60ab96501b84160c0b58857914ba4eae5bdcdaa11d22f6e2eaafe9cf2302d9c5d0b2a386e609b2628030abea9411c6e98f0b523c25dbb0f4f8c04baee180221bbd40e24c6f96601b8412d17825bb39f30112435f4db05b5d4fe9548ccfa2f5a8109cf78c6fd7c7924835fb2bf899b577417fa1fc49ca4f9e2efaedb7f82db76e5aba7a52c2c851fee8c01b8414f3d6308a9133ebe6b0f98610d116d806d955b54eb246f495ef898cd149686995be9d7506df9e7a8b065531cd86cfdee58ab92b5a5aaad73b6c5afac8c465d2201b841cae511df3a7542355c7324beea6fbb6b3a06bf1953e523556a6de206621edd7f136fc5609c8d627f6e0f9a12d43956a746761f81815ebe42b3afd122d98dd0d601",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x1e90ba3c921e65406b21e8f83af56dbf5e1465b592f5067d6b2d7eadb36c02b7",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xb5e768cb3117ea25175f51aa956b48691025c2a8",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xd18baf",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x3b933d9e82e0e95420511f61d83b84b7127d59ee20b3b280e1976aca4d3309e3",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x83559aada520f4d134b1010989e0327e232bb3c03fffee6cb38ec82431a6b2d9",
|
|
+ "timestamp": "0x6a7e013e",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a35a002abcf3f2f986df5d787a2d8a653eb1401621bbe429237583e43d794548f0771f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b84181679e4f086ae12ffb6d4cacaae4fb61ea590594a5e2110079ab6b8e66b19f962c99800d4b66e090d924dac93fee03de252c40ce37eda572212928e6defda93501b841b37e8ec726fbc613833df65421c5b5b8cbf95e67611919a436ab48fda030bbf60e945d7df0cbd4c0e79b468ba2d3d2c7428de7c5ec2e538967e282d715e2b2bc00b841881b7a9e127e781986225088802e04e918f7cc952be7781206c2fb5f51a8cf415443477d5727f84c33c47a4d92ebd51bd2d9a07cdff3f02ee2abf53fdae11fb000b841f5cc6b0829cc52f23f5fba9179d69991a01b308a32f1f20d42b805e7318f8bd33052554fbbdd4955930f4f2d01c1e8347fc87762d3f5fc3099007a7935859e0b00b841f9d78b7aa91256f82382846acb544a71d1f1746528f4ab4f777485ad8c32723d02e8c9f41c72a4e460e00ddd81f3854883eb669be9d9fef1d100530cac38492e00b84113a033c80d7ec659b3b516a8397553f9b1924610451a2ac5d9fa0f9cd3567a534a92d01636f7c0c1d85b1bfc14c635f74b69462761f0e2a2cd63cb569101b9d900f907bbf9029203b9028e39f5432284677916a7f566fbbfc28d7e6e784650c396d5a8008820154686866896c6371f54fc846feff1c1b6e91274ce3ccdbf315dca4e6dec6e9376891a5947255cf476520859e474d9c12bda79e0564a854a07b2480b1b4770fbafd597d72939863b5de6f88530f5dde62b72719d3471b1cd30bc52512586e7e5977b72ee7eec3efc9337cb9e7fad12199347b73df2185ad5f3ede70dd27381269ad36ee3132736c941cf755ec9568fef63cbbdef9f7232d2c5905a6d310a70a734661a8ae635b3d6a25b8692230f321b082b8bbec9ef279bf4550b725bf51177a74c20de2e3cfad57ea6295a33733dbd2fb35ca5a2eb3349e3c4231af06ef7c5d923875e76778c2174921daf6c522dd3e4266c5966810c76fda361b2acda4280fad50a77659adff730937881d1de7fb8b9c4f62118def06e92a30465628dbcea5b5598b9a9b561c9a53577fab29322d4c6a2f12d6155ba23fa98ce0fc7a94ba5a22186ce560acf060ab3c0fcf5cf5285462b5ae4597fc624f988d70b32a9c13864312c33925c12c85d5a11016cbed5e24753b5743aacb153ece623df565e67d8613e7ad6a47311abe4d1d49840c435818626ac4d799080f72f7856f65125567af047f248d919f747339e4a73ef17ab35c2926450b7839d0823c3bf482407778c919e0f8f27794bce34128f3af6ffcad5a81b7a9448c8f7a098aca41abdc0d1a7f9ae9c6bb4cc66b15456d0ab606dff426f54ca3b5c1cfb5e4a5a6f1d22a5998dea86ee57e9e02295467f6f9fb062b3487425087f140bb2f8731100dc879110c4b9ca142d446ff22ade3ab3c74cf21c437696d258a72f20516b983250837529fb8725d04b50dcccace2e57b8d8d2e2f45c6b4297a7b0bf63d4680d5622add193489cee08ece34a269766724d3ff380235757ae0f9028f04b9028b39369fb847d89466760c2b6fa2ea7cfed6e450b9edb629ee604b4478c75be49f0500959b739c10f5982adaf23e4923fb6aee5aed4bbfad14eef36ab984664eac36d536eed6c4a22c621d9cba7d1d1b4651188bc2071eb543c744afd76b74d732f49ad4890229b486f93a885da1972a16de0f9de3449116df2686c4ce7aa0c238cb1215846d7d99a91f4eacc6f3e82d5365d794cbd27b2a13c2833258840618f7453f3ba34cf0a2ea5150c13dfb779f16fa63dd6fa56558d3e66814e9fba3c3e1f0798ba3d7c85660c9268715c35966fea8c524cfe99073cf8a7a1c4e078f35c3fa26181ece0e668a5a6ec33498537c0973646210a6d8a32a33a2d1159322f9b833e90611f79333abdfdca614a9bdbd28bcb6fb44bb18477959572d6ee3ae71db4f4a3a8c9ac81a1ca1f2a0f738bebf18dc56efcb1ff9b64df106cca148f48d7fc7f5126b728844f90d54efe5639aab543216f459d1817a9e0a444604c2143efea6fadf5f76dba9fd7da28ae777c9c08f22cc777b724d627c6aa19c665141c6c8988a0c0937c035ad5ec673e450f1fc441500967934f1b224fb6c75f811a9635c6a1af37fcc2bb17b6efd0eedc40fd6e1b868db6541f56934c72e977e637f5ad2d566937a6b08f56a6c82e6e34e4b94963db95c87de8841080cbde59a6dfe5ccc7606b4f6c03cf17eb626d5a4fb953cab12a17f623a7ca223de84b5bafc6dba0acbc4b828e7a6a6e9401d78852601a08dbe1c7a2b5aa02f3c168e724e5f3b49dabd2ab168b201d0671028471a3cd73688dcf998350db25543bee172037cac37899b5ede2f0fc651c9f5bac9f7e9067e8e9b1b2522f043b1bedeb29d1485a9caabbdd85a88c953665f4ba3a7dcb06e60ac5a86c3d4169853b4de50313fc6b588cdbbeee2784b60e4acd8f560f9029106b9028d39dddb45b5eccb6f89897561031466ee14688ca2f2a3790c5862b31028108980cf226fde95c9fefdfdd976f6ff1f5644a467102410cde7d282527ae298dc990fd0b039f1628caf9c55d2ce73e5cc3f01877fef13b791908d10d6d352d6e4f8c3c09991af6b39aec72f2cfb5702888af3498ea5c263c9a2048bcda2f6124e88b8f9f49bb3d6cf38f7e80273a0ac69679001fcfdff7a9bc469e7bd069ef79779626877353adfb935181f938b83dbcbf2d9b0c83d3039b544e2429d0c136161a3b51d4e990b61350bf4abfb2fce45711b54433455e473fc9b3b40b762a45e486098a05916a5c68967dc2dc1836c0479f848fabde3108673ba1141208436908826e95acb370cc12da0fcbc7282bf2d8f4cf3b8e57f805ce39b1e4459393c68e2ebbd80bcf84b713c621a988d098ac6769035250ee041e8d32525ff4ab4863720afe5dda5ddae573a8e6f65c1c523890d7a38f9eee83f1c1a56a3d854296e860aebf4f9213270a4c27bf0d6d63c2c7390dc7865e4f9ad8c75322db467f88ae5f71c361e392c696a4ca57a374ea42e1eb553757e94ac6e8b69c6d19f7975d25b24a136ac660fd93aa8a8bf9b6c1279579a26aa765952b9622ceb6c269aa0311dead7a9b84a90f8dde212cdd63313c9a2a32f2a706d76092325475e6fb79b30b3a49726cc9a59a228a4de120db312d57c537d9f20d7465099c73d834f37bc96da91015ff7142291f6bd9f232692ea15a67e3faba66777f0c3dbb2a2ac4c6bcb6be72c10a215fc64d1bd233d2f95170c7f623d23fa4bf90bb28f639ea8ba0d3c6e8b3626e57b4a9af8993a3f337a371eb56d9454229086aa5f8540fa26d16bacd4a379a1b4fee8318a5256492578a35d62a425b65e9dcfaad2360ebc346e223c5657b9af6ad63dacc523cc6b9c97b8a0c0",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xbff97a941f6653f8ba0d30fedf80f0d237900ca66b1bff3c8ad2c90e81fbfd23",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xc3314fd768bb68b986e80c0a14175f6f72630d7a",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xd18bb0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x1e90ba3c921e65406b21e8f83af56dbf5e1465b592f5067d6b2d7eadb36c02b7",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xe9433a55741232463a3e4c376349673376090f0dc9cbb6517c0dc7f40a02ad7f",
|
|
+ "timestamp": "0x6a7e013e",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-L-prag-relaxat-anchor-13732784-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841c9303d99808948e3f47c6e749e34fb7e7833569a5069a187428603c5350d7e222b07ec4e5ec22a4b9889c628f1eaf3d060d54d25e40c651413753a7b1ee8d3e801b8411f1654d3e44055d2fe5b9981a996531337669b9f83bafcf10c24a1b897babefb596597396fd6aaaa25b7c2fb18e675491e7ce2ebacf4019aea0b8b6e23bdac9501b8416f448a00a24a570ccdedb6052d0750e42f59a905af9c88b5bfe3cc89474f8f63359c637016cfbde5fe6bd70c42bd5243716111f132a0766b928d676759de37a700b841103dc7dd41f606def6a32402b88de7a3d4f2e36f223368751ba0c43df5c3c9994b6fb343235fd056b32eff85abe9adbfaebd7e645ea2c6bee32f0956bb3d824900b841718ea977d45c1c86f59d2fcfb6c0a52156afe259424a8f5d6691532614e859f519e38ccb254d8f7a85cd56acfb2ebcd482833ff940719546e7490b3b24ec50e401b84100ec80522b96ca561075ea98c82863db20657747bcbc0c3edce7b6a72f14916d18ac0b5e35c9cb301b41766792c56461d27219b01e488d03a803e2514ab3d08100",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x4eda46578a20bbe19d12594a61e475b02616365994033b2659cee51c0a816970",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x97473985d04723299559f49b856effb47d7abfad",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xd1cbaf",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xe83ec523c402ff88186a14e5bfc4b6ccdb0aa07df6cfc4d6f1120769b7643540",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x209f93fc24d65733f55d2fc6a698480cb3b626dd5301c84ac6cdf5069231c810",
|
|
+ "timestamp": "0x6a7e2364",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a39a09df3fa561f0fb3865b65be3308f2ecbaf183ab8fa054b20ebbbf75cde5700340f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b84110a4b168cd5e8cb8b18ab14d7a833264d84a6abb6062d7c75fc6f3dbe945e54a57ee7fc9b134a578eb3106664343fcc581fb6675f6790c1908388410e3ae0f3b01b8410739dc059514e2ae0f7527030e46bb10db240b420cdb162aaf73426d961e4af657b611fc3a1f07c6d7236b30ad7cb6e916eccb9e371896a5e1ca4ba6a0f5494701b84169f78934a923f44b0a616df5a15eb62a167e5066a8593f38cd17ee05c13305ac1bd402258287241ccfd20e186d766f7db2b80bdb43ab603cff72b925cc9bcc6801b8414ffb665700f7f3cac31cb1ad11ffe65b4cfb7ac92d43bb41a7f3b2fcbd6d59327a6a97b5a03e64ba5b30c91fabc2a416bf73fb19225a2f8386eee88e0b9dce9800b84140ec8dac8b44ceafa915db4855e82f7c1b388e146cbfea9c3cc58bae2ece7ef127fedf2845d6b5ae607b187b3a94d327952223e179381d79add4fb873968f64a00b841c042f5e05eb58d86b9bde8d2b408b8024cf2170b56bf6b7c5b6efc9d48fc89ac2803b1abf850d837739f8c7cef3639f172cb15fe850592f2d831873c4e91444001f907bff9029280b9028e39b3d52fbc6f8180d189788369c7b1d66a099f244c1e2544d89762af8595ec1b40e6148aed25d9fadfaed7ca4798fa7b5e9ce3e0fc2f55fc6a7934e5e06179d81b4924b0f331b1465e6e5417cd5e74a6b50d2c32c733cd21854e6c846e50b50e30c689ab34dd688efab35465524429a8ceb5b5761a0ba8c6b8982474efa219b2f18c864d8ec99e933f8836513119c423c8a8d4eacebb6b79fcc65c4c954b8276d5b7a7d937250f0c910f265937394fb47f502b233afc355cc732ed3d6739343561141225364ebd184a2314d930ab7680fbce76a84fb367295ea3d5d4fd9672e34a7185b34ca865d6974d4720479dbef0b3084e398e5e2e361f9dd1b34b593d34e0f56ccf0605e64267b3de16d4b2fd97bb18abd47494a7f25e86627efdd66c5f3ecfc73fad51a55fe6e8c3a7126c288ec30893416ca8de97b591555c9768f45770d889fa6d2db84bbd4dd761eee49cb53ad5d8c652130bfe47c724f7bcfced4c1a24538cbdf70c44e7d9f70515b959e9a53506ed467bf44695a53969321504196c4c9680d94aae9cca5535a08be40a2bdbf5bf4e50a57bcb104258a134f9412e78463e1090c4dddc1be3f2285dd52b3a9263e5068cf9adaae663ed976faf70c8ef71069da9b088233e9fa79e4c326f442969ad35bc7b660aad2b0041b2b9b8fb12c67ca09dc421cf2d7433b75ee570e1ef42568fc37cd64c13d181cba4a7b5257dd32c2e24904ab8453d2d60ec74ccd18c457164f3408be76730bb368e776da1c6b42ccf4b5b6dd2bb557ceccb79afbbb7f935dfdd543ebbe7afd4d76de1438c87d162161e4bf6e15b9b8cdefe7473b128c4ae24831a5bcc3b62e51f7d4ca7031caf91537e43a32f291e50ae38227c4da2dd0441bd5d524fc53d4f6cd62921dff542f2bb1dc75f735544ff4cc54af9029303b9028f39fc53ea523542baead933603c0a2df0b2ae90df7fc54324830feda0e39ad61b967919a6d322a27c57a6471a9c55dd9bd0fd7bed43f2cbe14b3405e56a7f3466e31bcd366ed433a2fa3bdae7c9208c5269d54df51e8dd06b6b6c3585a9abc7777cc65b422a74dcadfbb32c808b7b98cefe275f3cc8815458a6250ee6f921e70dcb357154316b73b604b765085de73f396247e48d2cdc2b05918685e77198e61e53ab8dbe954833506478c795d1ef58bf10cfb9bcd9e9dcb6adf68a6af12ae37a98584ceb3736cce517c79eeaccbabf94e251f6c9d5d27368bdb2f952eb73f26698f408ad6fe23029fa57b5525a06e0ebe85a77b33d507361391c122347273249c46ac703429fa79dbc272e122ff4a0adabba4296158ad49ab6ef4fb6f092939bf0b372b72e773d5551b80cc5729dc3554e04818e5b610750c7d19cc0bd26db4d8be6f0346bdcf3b1161b5ce218ccc9be78ad2267f8694db44de24a2f5548d3b09d788c8ea2790c64e5d13b6a389638848db142dc940b7499b43e95726a909bbdf319dfb598de3e47290de93b4c5a6d24639cac0970f022cade85c5f5d97a329af59f2ba5f139f2c71edcd4db5b59923737d6670b137506d791f35500b54fe2bf74d294ec131671455193ad2d273deb35503fee13e1924008c632214812f53dcac27d7a12f3686abc1827bb953ab947272cda0c61eaf537d7f13e83f299e426cfd292eeb73205c7d441b8ab526923d0a7cbf7ad1785dab28b520af3b249d524f44d6fd128e1a0e54ab54ebcbf4c4694a8cee15f983d1875bd89804aa61777144192feadceb518465d385bfd01853ea84f5965abaa5ad95bf721127a3c084edb66697e280ceadf4769f6bd3ff4d9a241da3a2e5c75afe52575a11e164bc4cd637e98241a26b70d4f6ce0c15ca6253f20f9029104b9028d391afa11138b6c15a71c22755f43b143a65f16c0bc39fabce4a78b7cad51e3430658515f789caf7ce6ac300afa0db56238711b67a288a4d2792565794e1ee8e60a8bb7bade924ed7a9d33c33bb7a9ec8b238ec52c49f4033adbbc95fd9f1e0e89300d1d01b78ed70ad188259823472a6a98f4b51fc253dee47369b8c434351a44935363aee69e5a866d9a48efb32fda7715d03b14b7050248b0aca5aed9b8e020683c0bd315aee7f3dc961344d009ea7cc0a25f3500c9e8cc4eb08f28e80ee231cbcde0e7093408568d7c6a776a7577d2cc0d0162cd1811238821ccca11f0be51eb5e7f7a5edf2f9404f1b584d8133bb28f9faa3b7a96371e9123fe499d564e66f04d84d98be6d8b44ed76aed2a717c7d8a245528de6d2a68c4deff3e672dd18da90be541625e34e51bd3bb2648d7b147926f6bc25b911af571b9c4c953e4d79deb7ee6cf47c7f49fe4e688b65b324f9319bb1189aa688e5ca712a71218a34a90363954cb052c94729365e95d66a5db2737f354ca25f785ee0ad062dfa77b73e08ee53bee8bcf236513a6d4d87332064c7f4e16bedd7eeb479c824aeadb91c60a92c5747889e36467841a62d6249a1a9e114e9ee4898af88e285d2773848d604dad3eaf4ea379968c2f237b01d8f6eb2963913168c85afad2c3a70878a41035fb6d2d7cf9288f0a6557a49bdf6de1883304fe2b8883e16085bfb1957b2f7ef64fd9d86a728afa242b31a629fb4d2a6a145d8649f4f93b1247fec6394539b1f53cf9fa0f77a0afcc54fd3e0138c4badd6567909fb05f9f7ced2249a8de520063b759670d147c37de26d1d06363df1e0c3d09274e9361e3949089ccd596d97c76743c5197947120aad57653036488ea3ed5b228ca9480b0aadcfdd197af32031e761a347a24a3f5f0284f5cded06",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x11764f7a624e3f20ef6ae3ddcabd06a2457e05e7bb13a6daf48996fbf073ec0f",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xb5e768cb3117ea25175f51aa956b48691025c2a8",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xd1cbb0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x4eda46578a20bbe19d12594a61e475b02616365994033b2659cee51c0a816970",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x03d352014d030249a873dd0f066c66ecafb10796d7631895e034689f79da130a",
|
|
+ "timestamp": "0x6a7e2364",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-L-prag-relaxat-anchor-13749168-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b84123650288e8d1eff62a4a480fd689b96910300facbcebc3a5104bea5370940bee3189d7bc3592aeeacbda70adcbcb0119bbea7aa6e62f1d0265234fb999b95c2101b841a221fcd8e14945d85edc9139a4785a02ebce161b76958d539fda36ffe1f5df1963b1ccc42d96c00c152fd5d8613e653e3de7b0e160dad08706e3c62236cf5b7300b8414d9067d304574ff1cc775359a27bde0a465c410063f4bb537dffb314410c0cfc1cade830dafb97e612edb4a973f6b7e3fd1619523ad8591e5d2cecf355215ab201b8412a8232d59982a2e2e04e08bfbe3e3215141c4226b4ac94bfa88766bf533ada9a782f9351ae269bc270526caebd44364b41309e851f24c0e84892a84c322b68b501b84196d29583cafe32da27c7a819656420557ad505f55c2b9aa560af2698802552da3497bc6aaf6bd3f0926a73951de392fe2eabab86b1fe62508e66db6b37421ac201b841a774aa575b798ddc89bbe224e1b40eb90b6e7018351d5d92385f19a0b5d5bbbb3acf367c72b022ceaf8a27dec178b24230ff51cea61454b1199097571d693a4401",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xbe9d8802426fd2a658d2a7e9ad4273b1f5cf001c0903abcacfcc649f1a72fdff",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xf73bbbd26a82dbc769066550d8d4585eab2fc00d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xd20baf",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x32ec2818c381fc2e6298e27d580db9ac443c93fc756303a4ffc8a07f2177502a",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x7e358369dc6d7a22ea1a1149b4fbd9cd57cf8c1ccb6bdcbc78c406751e06d1c9",
|
|
+ "timestamp": "0x6a7e457d",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a39a04b28d2eb417e2b793d55b226bfa421fcb79ccb9087ecdb7fc52dca88de762805f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841cfc3323741309a75add8cf784847a6a2f6013cd8ff522a148437f10af4a5fcda37142d67f61394ac70d9dcd1efc1996c5280ae0609926e39436e8fca3c1f399d01b84118f2e78feb0bf89b28ffc6e033034b675598a5e68bceed6491e031e829ad35773d8dcdb0b0488836f695b2b600351f81be3bd1027efcee325a339f71c9a326ba00b841ad37e62c4dc387233d102a58e9ede21eaac73df2348c76743ba4ced1564795ad18787106a9e3dbc198ee08fa767df70875c15d9fc40a4cdde6023132dfedf75200b8413f16e5a745ff3a2ca8ec078d18163c3b9c0af4a7597dc22fe726926da8d03a057e775595b83ca5039cf3ed890d3048f8122e63d80d347de81b3a8595bb52b93f00b84120c8854d9703ed8ae607c805656c1751fc5b5030ac0d6fecd86ef5edd00ba06e7836e8d1e8ea008e2b89ad407d8471d8b58d58ee7d87ca3dbf2863e024108ae600b84184d50282d11b302183aa166a14e40123ddb7099d643d30fff076918fed5759734a2ddc77991a0b643d72f1ff1bfe8f42108214a1c1536945ba61d8260842997701f907bff9029180b9028d39004802010441276e7a58d5e5ada5a857942bc4a95d9c8e676ddd3fc514c5492bf2928fc9a7f4043b4d4992f208d2c23276d14899f5f5315d7d4d9f499388adad00785ba3111482bdb3aa9225d14c13226114a5621d096d7e3488cbf299149d1b9cc1bb4eaab1b1dc2a129bdc68b519b5c20151a6386f6f4daaf94cb0ed3289507ce44e0e71f3f9213f3c59c1da4c711d96fbe5a99928e88b2678bd1bea74395d7513d22280e8333ba50146c4d9626fb627516e55f7ec5dba571654da9c59e5992770a4edcc78226e7d6f4f8a1d19dff1edc6c222a60fb50b2997460985afbf881c3af883b7732d37cfd3f06bee78bd8e10f6f30eeebeccdcd64738e057da02edc72ecd337d0549d409c7f15a393ea7d5c8b45aba11c4a33ccdae8c3acaf95db868668f1664a705e78aa9451d451fcb528a49add1f9c79f0a8fe513c84ff0afa0240717eefe682f91b521a774d49d921aabac3b08d43d41b4c59520e0992706f8e5f95742d586785173a742fa2eb82b3416d2fcb9467b7082e81a0c027f38f8f20c22279c385315616879a94c3a0092b1f0ed3f3f60ef272905ea332d757e27cf2ae1d6a07033179a49281c2713319af8f2f1de43bc627536c8d5b9b782a931b23f5f9bc1fe2ffe5fd68d36aed4769735eae5249ccbbcc358add2d6bd71db522758ec569384b3afd006b9d954db78b90455c262d8aa289b7b316d77f2b475d5f2fc7bea1ec2916e48e58a518ac2a40aaafdd9c94318225b46a7c1cf92c8dc6233b8122d9183bcb3be8cd36db45efcfd497c3115ae64b25295f96f74ebb8e4c1ac53aa8698935ccdbce5b6b465b3272dd6a079bc4796c7c482d856dd74bce54999942274c7a4affcd09f47114a7d119140897c16eeba69d8981fda278643d86eef2ff5d13c2cf25d24f7ebb9c8f9029505b902913939064f2f4b45a79921aae84b63f8b39542d12dc1a8671b7f6c476bbbd86debb034cd83845cf6d02d7577d58492f791370972404a71a5e9a1df3bf4debcffc7b620bd188b02f9e674cd154d3134114c26158d32a90f0b62c099621df34468b4228f10f6a859f713bccd457e486974a705911a220ae4214349ad7dba57d54f65083c01545e1ac37ac64f31952c31bb4b4f0a3b1464c6369b4b6c7cae2f4a107bdd262562613910ada495167016ed64b337a0bc4292852f8752ff1639fa3bb929a405a39611cbe35f608edd36cee7b6cd84197f3690b5287db4fd3cd2ca2839ef6b52bbea395c3d15ce1056203e7ad9b4daa189155e309f74d374459cfff47299b110cd31cbe568ba4ca0d7da7eab5bba33e942aa95a733b4793e4d75d06532b48c58e4b38514b3dbf90f4a9460c879f6a364a8b16bee16051ff2e95127eb27305d305765bca89b57b51d5ee8798ebfd1727289b357d6885285edd7e42decd486b6d0dbd4ae00853dfa884ea3151c61b79569eb1264c8d2d4817e560f535d298022c6b11b2cfc4e5ea9824b1b9ac93997545f1b51c153d40cb5f3973d8936704cfc46ea69e83ba3f371f2dfe0ff0d3238334995eef8ccb84f2498f1b66ee5a2a2f9c63eaa5795a89fb19f0e8aebba3813739025b26846f4ed78b5dcd5166c99e413f31c932415f64f5fd556aaf8287b4db59ddd34c972356c95f425fa443dfeead4e3ef5e2d22814215aacc189fd1118f7adb7982a948b7d1a9d852a5c2b18a267d0c264d89b4b219c2164c2d9234358841a66c19ea6f093791144b11ed776591dd9c28a91b6b300ca999dc5f95a4c96ab2e4885dd9bd95eeead2e87a16b338fc2de7090bd718a2ebc8d86b70d5b4ca7ab0f3a370d31e99712cfa3edddf7b43f4349fe87150e2123705a75ce3ee1b9281a0f9029006b9028c39e1e62f85bf0821dfe03f746d68e79061d28944b98e230861345db0b469e975a41cd584f40a890353638050639ac4fbd329d52d9a9518b9537e30c454c0bf6b1a4b33452c48cf589bb95ce345dedd564ee3b15b906f9b09e12ea3b915f690995b1bb46532430932c7b5edfeacbcf879a3c3a5f728f169f6eb4a8b2ed661d4e461c3c71d69c93d429419f71930f8dbf4ec8253a03ea4d28716606b2d26816bc86d2506b389d74de674a6113b717d42ab51a6a090c40999197e247565a1cdb933b48dd0c39358696819b661164f50c2fbb1cc5b55d712b6c9682a3c787bb34b31b95cee4d42303b9c65ead1945ba1264dbd8131f87e9ec6ff7b6be18b35f8894e69fabf7d8ac131cf22eda1bea3bf890aabbbb89cd41f2d8bf369a435c4da8aa8e7e7c909b8995b3e9ef91deec7ffc4b6064f7d23fa4964cb51318c587078163b16d562da28c3410f3b4f9c5242fa63dabe3f85277aadcc1a9950638c655361c7621b799b1fe9893273a622d6d3adbb889e4f203322b04a91996377bdb2028fa5fb5f7003870b26f1b90223038df9f09866214fae1b16bea179aff5b49958b75959bbfa6723312240e7b4b4f09dc79f180d7e1f557fb57e9b630fb34fbf3e7ac3f778ee743cc674f07149eddf0042be3c9cf57785aeedca05052dc2f7217514c6f0fe1b77ca3d585e0b3de6779b39b0f5a6fd20551563ccf2ae10ddbdfe228a6488cf964b2e2233fcb624daaa93810447602e110995f312af1641e251f7cb6d4086a89d7e9cb20491712b341cbc88b1f1b1eca5cd18876a9b354a37153112fd8d3b712522897b5f90fda86816089fbf331b56cf777b99f169e2038fc655542c2365f5ff61e30f2f2b3793af757132aa8dcbd08a1b482fae5f97aba568ecb21499ca29d3dfdb15c09fac158dcc",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xdae8d34f01f62fbc67f9c201700de9ca5c23171b58e0aa72819333471be9cd37",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x1bd5514286f5602a6762b0075266379d29af1c9d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xd20bb0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xbe9d8802426fd2a658d2a7e9ad4273b1f5cf001c0903abcacfcc649f1a72fdff",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xfa458dd3c48cb8830fd9b88e70c03040442126f3bee1cdcef39d8ee6763611e0",
|
|
+ "timestamp": "0x6a7e457e",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-L-prag-relaxat-anchor-13765552-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841567ad7719d01f5ef5d2625a60c7a5405843233243145975ff6abd6d664fd9cc93bd088f014f0c0c2ca452149959ccb5111e1f321d6e6f6b1e57c3b0f23080d7200b841386f0664e4c0aff297ac928b4d9715377759b6294f3be83f091ec62cb3e759ee164dc761225c50fe3dd8e727762a388c32a76d7778b1cdd061257b77458c533301b841f03aacd903c69f488e9617887c4cfb20dbc5858921c9b6b9119da147c1796b055aae6efa7fb980e3a87b6b93ca45d42fb835cb02f9d99d50ca880eeb21f07bf600b841b8adcfb9365c6ca0a4cd0ca10be9379379d8b329b61ffced564ae88abab4dd33424c33b7b63c04e375541b86c96c950f40725124328d80ad9e0c042e62cbcb7b00b8411b2db0a7c5e09c599066f0f5cf86164d8ae433a4a80d57f9971ea36f6ced01ef33814f2add1c760bbd24bf93e08e9a1c3307bcb466390abc0aadb2cafd17835701b8413919574d1306d8e24b57217fd67d1b42bcbfa2e6d98c0c471710efbf895cc0b45553a634e1cf1f582fe01b296a22981fd9e6a6d8821a9eba3aab835a0702190801",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x2ac0ce91d79ef3f0557a4e79671698f0f724973a144f89eab00aec83ec58f312",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xb5e768cb3117ea25175f51aa956b48691025c2a8",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xd24baf",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x83aa3b71184f7b2497f1b8bc179f77c2193e6efb2d3230abe5093553492c9d7e",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x2a6d36c94ee64793689878e35b50fed993e247f0bb015e196d84d6f5a4338529",
|
|
+ "timestamp": "0x6a7e6922",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90cd8a093cb238cd5be4d45b37923aa5c7579efda84116e6913fa9dc276c4533f9378ccf8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841da314d8fde7798cb449704e85a49f4b5ba725cb7d8fbb1df6fb70604e69a407134b66b9ea6fbf65fbd8abcee319c2cb58049e8504ebb8974b3fd80c7596e1b2301b841dc1df979b89877eae032c7c5728ffd00c68b887f6892d3973009c65a744ed1ff7a5983b79c0c8242dadc538f571290311e56de0ba0d9a8bc682c92083833bb8701b8412b33f981c2ea37ce872410a489dc0e55dd28b2141abe240aaf60b7b122a59bb961b0a7323a285385516275bada97414d74c53a93710f17af9cb4785211ab5b0001b841f038cdbd4378ab60963b01c35076f7dcf49ec3dbebae9bcedc2041508ef4c2761baad2042172f813a9309295c5fadccba6de539f49a8ef9dd5d5581785f7d81300b841a0fe13f1136c8537ce6899920dfa865dc161674ecd777105b86565d77c2ca48a1feee39433a0fd93ae2f6ea9e185bd53426712c7290a846117d9e75a2a8c050b00b841ff70f7c9f8beeafd8120ca9b14cea2af8193acf368e2a5be2378dfbd4d6fbd80500f61832d5e7373e94c9fedb76be94d9a173626df736b218d1d0d99fddf70b001f90a5ef9029480b902903923302fd512b21362187bd69b1b93de772c9993de932f6039cb470ab89b1bf511153168af313f212a9ffbe4508caa6f074c6a36036bccbe53f1ee5b263a4e0a1b1879f9a5f9c08aff749981b153e2c4992bc30dc6496ed6688bd4fed445e7f472b157c1a854472a8940e2fcece1a431bd567dac646330b58e17b59aa2abfcc10c78f1748bf1ae4ff366bf86a8952ebf733c5d696cd39b8b9f41650cd7c1d3dbe1e6567abf4e379452506a3f59a0ab4ffd9a8ea4f32133dad61d28ca1ca3a33e0bd474ceab36cac326d86c2afa1c422188623617a52a36f5ffa3d285e908927366d884d6686ab711f985204b90d473a5569bf5232f6592f086b71e1f1cbb3bd5a1a078292aa64b71188aaaace0378a7609978c9768ce5d62449856e35f0b4e3a8da33a881a63cdd128d0f1288a273028630f2644b40b0d51aa65a149dfb5267ba291fb4fc9582a70ec5a083ed0ee91d0bcff151760f8ae0eb6a1df533539c7938fde54ff66a8e7abf006009d231f3738efd072505d7b88926ea0be0c4a5d92696b3caaaa832266ef8ca9cdd29bba335ade23445085eb36b8c3b8d32fb6dd04591b5fb7e5c715c37566ff327d89bfea7faea519354aa27a6f0c8b558f7095018724e89da9859a69e50d0ca585ef68116a6c2542fdeb73f604c0cc9e67d771fc78a02923c0850e08869cebec969f9cbd346c2acb719f33b28aca894ab3cab364524bb95e69244c41337c7a188f5fbb7a771b353387238e90edb206be5d04efd79c778164cbdff8fff32da29b4c3ab6f983b9408646926c2baaa54865c8e62ab183db90dc83e09ab34a33cfbdb3d15d65f23e800bf65986d447eb57b33a83331effc5b3ce73c985652073a2376946d4b530a831354e34c4e67cb19d264542517ef6d5d75989ea391c15aa525709ddbd4480f9029603b902923964334e6d753fc1060abdd0599437ef50fd8ed3d9e2a4182647333b97d946150c2007110557ce542c9e3cda8fdbff84b447a1d1f36bc77a9743009651d01ae5eb44e3c4687c8e8b1a42dff844622075b04c814b6ed9b7883aeb2506ed0c2630b9f6fe3353abf3112b4dc347c5c3d8f7aca9a930e82c7b105af4ee3c09d739a9737c27d2a60e5cd65d5efca4dfa52b8772698f2423d117ac7a68de8b617cd2892cec94b7dcb95b3c8f14b6af34a43a072f2f2d484df6928cbb77e410f373d9ee61a94e249998ea4fe12aa322fb2d0b6ee5c9f7e5e5b418c438f9fd10b339ee727126c975c866d73f110dd3fa8e1c0145841a1d01cae7e8483aa91b8f3b53d776504a4bc3970c374df4fffbdaede65ada2f810edd916dbf18827109f75f5174c2645af203aa8bac5289a19c154973a5a3cadc75df14e75743411d48dcf9bea7b0ed4135ef1eed36a9f688384af7f4bd537efd269d1c6c2d9dcf2358f411ed0b7da3c243432fde703d9467dd1c7a567f752180516afd47d17b5725ec1e3e2ce5600b64dd2ed4c98e8d737ecc994cb2c95eaab8d82d7f2fa1d8bf271a1d163d2ead121836b102461b96a2afe8c88f45efa4ab65d1562fe8cd6309c75d9eedd1645f55ae43173f516cd1d6ca67d1991e8a252757fb79469da0151dcfa664c10bfa61d769229f89d30b084de3a4b9a0f4cb45571ca142dd66988c46db381f75534434a22d93f2b938d6d2cb9789705cad0de79a8d176401013d25e9f07cf0edbe26d1c6b44a5bd59a8d9848f20ed0afca629071cb6f0d24bb57d5c3b8d7d54ebbd574a1b1939e8b29a87d6ab52ff26d127f7a425da104f1376d067fb516ea25c7630c6bad351583851028aeb88710852e0ac4bcf798dc67b31218bea36f87fb44490f390470d84c1e5899a1a7c9f58911b463a620f9029304b9028f39321fabadb65b9daef51143f9321aebba2444c4884450a7a6dc56675fc160c17535d21858e4028a00e38fbe6d3c42f312e6bdccf9902aae141ba39c13aeb69669d74d7b36179518447bbad903713538ca93a106b3751ed932ba4a30825ff7b126dedc033e98359077635ccdc51464a8ef44d43ad246c46c8851367a8d2da2a5ccbb2bf243f70a6b542d77a261fc5593c835bd7733f3ac4b3c5bb2441704165796169195f41a5292a5d285d93b254cda839c5d26a93dd15398267a1869e19c7cf230c1aa23fe17aae0d2c96e9e7cf2f3b140e148ab90481eceba1bce7636ddc8118fc77f77ed4a044d370c44cb684df1fd17d206a5b8258e08f76c9ada953f78477d2ec4ca7989267a3f427cd01f2d51284c8cf7fb1c9d6d0b67e9dda7193d93a8f153bbd4e8de3a78df6bde995b970d4df4a660b0a5c48627ddee46d79e7f0f75bdbff5145a0e662d5083b004cd5ef321394d33a3a84ba4ae3568c94ec87381cabf6762e243a2e2ed2596296a2630f88dfd22768c2b9ccb72c9e2683b496c15a6f1366c9faa774551e8d1b78de4f53b508c9954bf0d51c381a1e77687f1685b47c3a75ec0c4f00c44cdee862abeb86f5bbef663e377ac3cd1fb322913bcfab77a0cf4b09025ec311eeef1a3bbc0f5f08a0c413f46f11d7dea57627cb253455b75ecde101d1360806674b10e16d3f536c99c582ac047cfc485dbb944688cacfdbfd7e6651d54b77721432fb0abeb93c074a617285b26fa7f7d731d6eeb0a4c178eff2a846ba5094f69693666dd4c4f8ac74e9a83f618bab60a48d61c051142f87d3df0b45c5930595ce115a48d9385a376f28c23e7183474a8ea15a7ccc5e2b59633e0a940ff3e1c5dca64fb3318033e8750748655c6c25e62ea2295cfc5ca56eea28319257b9f963245dee46ce608f9029506b9029139845b00c0190c96f55a63979dba269d7c1fd4ea0cd4e1dc69ef6c6c606d843ef3321213e0fb639b4e35665dbc6bde47d118a45bca9537a838d75f933883a038c66b46d236aa07167f9cc5a14afe77204799c851e2c24290a803bf0d2a2cfeaa938a99599cac97cc923968ccf4eadeac7bf209224ad18514d20e9483211cdda2b58d7ff603bbab2c8cfa8139d6cd140f46ecc8c54f9d327dcdb9c6893b1f17373035a95c9375f0702cc458c41918469167c5d5219162248cb86d2a26541de766d89b1826350954765a1a32630a437defec325d28742f544ddded03bf2c1934d51aa5c150eba9852c1414b941622bf1757a6343c3b33188723e38f1b84ac9968fa10a0b7aa83de90365d855bc0d2d55a0c4d04f83169e39bc7cbb4ae06e63b6ad9478cfb4cd24f26a444cf6be3adf7250acf3d119f1a4c4be5578675d744193ec4b6fd5fbeee5f3711e5be7da5460526c5ef5b9284a8b424cc9c6820fe79fc9218ac2414ddb7075cba697066b96ccd2bdcf393c590cb3c2629cd98262e6b452538a801321af78be5e2fb64f98899cee7251c2a6b718ffbb03b2556c0971b1e6fcaea7bf5e86e93af21ab4b5bbcdafb2616046dde1fc812b7b5bfc7b66fea21a099d81e3b5d2b79c64f37ad8ea21ee712d5c12a77b9a6eb048e64ebd3e71a1fa23eaa31a3a5312e7b69ffc9abf87648a1b6dc72c1219b78de6acb0c8b5430d611b09fdde712ca7cf7b58970233864098e6b5db3f294bdab633973ea671c6215f8f8a5ef234f66e5e86852a3952d3c123f3dba9cd49bb7bce04ef6bf89c7f27782d6b418395522a0b042de6482f12a80bcac26ba56a0d94dcfb43a385688dabe92a3afcfa9f22dc67a4dfae4b92a271e353679302c5d6c96951e820ad70e810c679d4c69098b5d339c8d849b472f4ba32efa0",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x6d32f6f1b2f4b9945c214e5b4433ba66ddc8523938ac1deddc88199bb647c117",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xc3314fd768bb68b986e80c0a14175f6f72630d7a",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xd24bb0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x2ac0ce91d79ef3f0557a4e79671698f0f724973a144f89eab00aec83ec58f312",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x524a228930fa1329cc6df866d5021728842ebbac2e166ad980ebbb8cc90c098b",
|
|
+ "timestamp": "0x6a7e6923",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-L-prag-relaxat-anchor-13781936-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841908ae07f7823f44d52b36cbcabf58f4a3e635e277143d959980156d5b5e5499d0e337f6bfcd59d23ca985986c702f0e628830a85ec36bc32081b61164fc6097e00b841f3ebff1a7e6212871a73918fb6ef07b3bfa3173c839827b0b4ff5fbab7b4ffd517c8e099908fdbc1843eb0d1bc21727605b599573a430fd4b38a493884e2284a00b84112a0d56d176338562b77b13e2bfc1ccd1a1e4f9141e4ad7d96b3395c23bb8e3e65916fb494d192995a6ff12544c7078d0985efe668dbcdf30c8f07ede8cc6fe400b841d41803b85ac74ba343b1cd2a7cb47198a16df569322d5d9418bf22ea5765b4636aa4473205cd2391d48793f8d561814efdce1067ee924220f2f9a417ee40eb8a01b841c844f30043b18c2a527752814b92aaef59dad37e6e3a4c498f39da3ced7f311f1d295859954bed1aa6fae159525034a9d64b7b0d581f0a9a826c06e616d0b40500b84115d87e9b8762412305d6a352ed243f4bedbee60e293a0e8acec089083a15e3b74b9bb7299d94fb9c9a16a54d659b1405a354721e7162423f031f367869e9f28800",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x2c0de9c14f75716c34e0c7bc035c1601f9f6e1c8a9781b74236f10a5c20f7210",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x4bf6f91d84b37454544279cba152581ed6820044",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xd28baf",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x1cb58ae4faffdc4f6d3e4aaa74e8c89aaa895df04377c65449f6d0a7c4f258ae",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xe621663e5ed79aaf4188fa9757144855b74b97b1ab8b6c1206be5b0e03c7e773",
|
|
+ "timestamp": "0x6a7e8b33",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a3aa020660e5fa811c581348441248060f5da7f8167d001159a7d5d11fa81863b8b11f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8415a5df8d196118a5076bb2670dc5a5d547d657718490ccc4a24835c2162448b91162f0627e2077782727cd7e44faae1d0709de0fd4ee4593021e0196da909c21e01b84101a2ba7cbf17a8758377f8d639eb1ff197933d8a252dbe6b8c12ac8fb5c61fbe5b86ec86d86aa402bef4a551462db2345807e69eabfe8ddb5d8c48d74449011b00b841bfd8d785117bbc6572aedbcd58f1443de3cde3a52bdc0e5ff16024a5abea93762b9e690236c7e178099062a23dc411d331bff6980559b86f65584200506e7e5700b841ddef5c406a11807a92a1ddc47ea3b1f8f1ff8f6caf02c5cc73b43c2eabf8386b1f9dfebffa10ebef84dfe0f1ced780774df373da214e310155daf736e5091a1801b8412a9f10c3bb5401ab5285a04b0e7af89342b3a465c70e33856e1b29d6fa57548b77cfba682144d1c7b980309abe067e5be86ecb84a236b960f7f35a76726547c600b84189f538f6d0fc980ab4e7ca1a62186e90806acffbf50767b13c83e885be51b206771d9d1e8c3970b800db103d98c4189e008d3d44ce4540f264fcea96b6a4c03600f907c0f9029180b9028d39837f41b0010baafa5c968158d62bf238eb25cc8253ab3da372f00a52d1dc0e9f7ef8f4bfabe128dfe8ed6db1a8ec56485cadf23745287f95a91522b70db9354f433aaab297a83aaaf775606bad8ca4c138cc3606c8809c8968b1c4ca7688cf7013076aaa64aa477e464530f4935c9ba0b5a9fb25c4223cd98758fde6ffbfaf43107324dab309035f90c823608ca133ae421dcd6d214faa088bcf69033f69cbb491aa9fbe7f8d680eac494081a75ae506b99e8ecea38ad549fb89b6505daf96f8a630081c764f8142154e76695cb7d530f3e1d6401b2d27a17a9548af91e34881606b38e8ffef809b2e287e313bb327fef815011f99a99b737be6d633135e029c4111ee6c560f878ce0ccb4095786d3a9849768c3b126f24d203bc49783358a9d1ef54eabb8cc9234ca7c551647c4aca309fc7315fa5f2fdc46c6a54ec110047d98fcabb8dde352c815d8a27be363f5b4d201a11ca35976a09f0c911f871c747ce09ab29a88a305fe7d067fa855184710de425c854b91fddabe0cabb93859f5988ae63b88c2705dc66182d77b629446934d17b05662f0a44710bd60973fb6b1334463ce35b395d3f2275d79071643278140d7ede6f11271a1b8d4ff8f27ad55b783e66771afbc223e567c4c6b4689a850dd3e0d17dfe80a81dff812993bfb25e9df2f7736290d7e9adcec21bb693b9b1688fae8d222fb5cfb6351f80cfd4ea39b9d836adffc9a8771da93d427587d5f3ac6e7e9f09c7c147e732888d0f0cc5ba958c127d2154a95e4f2a9b46d1ef3d745e8c854461113ec28c98b91028d7934d578d94d5871e44872e3e435e8e0453dd4be478e6fb56e1d867113ac1efdc6bac28935faf637934e69614b94661bdd3bc3fd5991c326242fd89c8cd102cf33ab2428e1b1523823639877bc1474f9029203b9028e39947a43aabd7e69ab07ca0d206c9bd82bc91bad3ad4fbee4a374ed3e41b997154f210c49a95f5f6788071b9bc3df753165c672659815c0fc393bfa23f88a21fed55d0381428e42a0836fee9a5ec7953f5563ff4350f0dc4d95036536f8d71f56d9ad42113f4afed238335901c873f5bad931014b6b1d8b24831c2003391a5d7b2b1ea5aae6e473301de1144c3579194e854432f5162f09ad67e9aa99f98432292ea62bd28e6991b5b505a6c7a68cd064dd0d26eb6cc9dbaef314bca9e0040740ca75a6d16ea1074af196d52a2e879f1c9a9ff6c4a574a98a3f4df41e3544c73054ada6fa47a4eaf09b5d7b4e4f36aaa6eba7ae1ace0fa6c0e722ad81b675c8b9bf93e0b939c6bce5cf73f64664c087a35e7a617d7b2525f2fc318ce20bcc4bd8d53bcc8716add62e6641dedadb1587b619a226c3e1ae7096a65b9461e178a486e50f4e26042e2870e09f08bd5aa37b9875e54c4f052cda588bfc08b5fd95de622e8044d2f426a0726ae86455276c1e872174fc771c3a244fcef2b30833613530b0d90c930e6176c40e0fdd841d3c8ba712b474616f1e4591db4f9b852e0744ca94a8d5660830dfb87e5cc63628e136a5c812395ce7eb29f7dbf24e962d28420ea5f9c9cce4f9b908372306ec6e618d3e8522beabf2bd6d2fb4d71216aa810487ee8c762918ef9a04bd5fedeaec74d99b129d276952512d609865e234c4adfdf49d5362da08806f35fc5183bbee67fefc8d6d287c3c9978aff1c1181795eb9e3b134cb6445a4dacb77198a2da9488ba846dd658fa6f45c038988c559e2518ddfbf34a83ab801a381b9752bebeb2c317944631cc930dd95c05de6d31bbc01f2baa00fd7d6034dfff19a7adc670a82e8b2b098f486c1334f2a555747668c23f9d54a0172cfa6ebb29beaebc62bb5d8f9029404b9029039b42775c5f4f26d01f3ed402e4b4556e68d8bbf28a065eeecd3e346f3f2878b339adf2a617828788dd7284e2d20661bad9ffb66c3996295c741bbbbeffeae111347e4e601b7619493730183f8f305b38a9877895b1fd99a9df92397c1b0ee919e3b186c682ec60eab2356e186136d917b5946264f648873d4187ae0a25a6146e0febbd7aa07ab832287ddf55d239ab43a68865645a8781a8e548feee299dcfc5e1b0c8599264115c92f4e47f347f3a365922222fc923b46d5f789bdb6693951c9613c5a020100e1747d2c6b06861f9d12afcb66ca4400f662ec5bed845d8d700e1a755c18d4688f36ac7174e1e9f28dc962e33932bc4db65bc6a0ecb26abbfd71f4a486d79f52c3b56d51d0e6ded2f4cffd92db213ea547cf1443ce169e3f797530ba28138b8641b769ce7303bcb8d8eeb9c657ef9f701033d9c1899ad33d00614791c0d96ff6ad394ba0f1586eedaaaa23cedffd39dc717dedfa168dbc2afb5ce233788a272f9138a46c2146cb8a49b3cd2625ade26d90768093b79e372fd36335783409c9e5586d3a4c238d9e520a2204f672bcac55cd1a7089ec23f3c26fcbb3592fd1f52ae9fcd1a53b70da0ce736f8a54afeabb702de3c4f4ee5684df5984f95935ae8f5b5cfe5573301381b386d0d0c304cc29f99382cfc1d0f17fe0d99cfc1b2f8d4f4e75a247ce8e3f6aca7d8167d0c912027529391882a4e44e0deece0a4eb919d7f13a70721fd8933af9ce8e2c356a9eea2d1fce8f8dea5212ab066346cabe6c78d43ae724c23825090cecbd3e0eff8bbc5f9d9abb38e972ccb356ecc1907491cac33a9b4a3f0d2ade90aaf4d719e9874e292af69a1d8c635b583c6e29eeb3febc4a82051f8fe8935246d52db772112dc295f4ec8015b7b533d95c54b76a179d4a6909a5d6d8f7bb71980",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x88e6a4497f65d730767c29509780d306f603a80ae1836715f8b6be6e449f6dda",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x5f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb0",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xd28bb0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x2c0de9c14f75716c34e0c7bc035c1601f9f6e1c8a9781b74236f10a5c20f7210",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xcca765b4485a30cb89477f71c9cab7f7409da7c29a3d7e98176522cb53518ba6",
|
|
+ "timestamp": "0x6a7e8b34",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-L-prag-relaxat-anchor-13798320-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841d5212bacb5123e189edcbdc7443ce73c69f531148497abf512d3c59f982dd3bf4031ea4550b1f9a4cec69e22cf50d22805b71a48c768135d4719f9b1892b61ca00b841730939904523891ef9adbbcfbe77bc51459aabacfc4e94821e028fd62e1b7cdf634162a20a0acbb85d554b619de75af5d4f3637e85698a32093d25805162023001b841883652a66f2f7f2b0b438acb11b44aef78004a549f398181c4b661296ee332232439538621640a5593edc097a66aa39f930f90b0bb90b9b3750af4cb18bec87c00b841411f7ecee92466e5a9ccfa9ec14a608581de61849272d9f110c0eaa131a873ea0fa4851c939ababe49a4e4ea8042c226a44aba25410a4965db5a5498b6bcd31b00b8417fa039879fb6b24e48bab780d975c78205288520511786712e8bd8af00fcb0655330c086b92205d5ab0bea5033cf34d49d7cb0397ce437b26133c9172dd04f5b00b8419f710a9dd81a2d8f9fe43c4e890b5e9e7a985c427f001335c826dd85af42698219bbe0f799341b3d313d0fcc2120fe4702ff3a0a367ac474e4adf3f0d099d5b400",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x7e0d972c8c9db5fd85ea27496624b3b82821c1b67476c88e1af28fe221bfc10b",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xc3314fd768bb68b986e80c0a14175f6f72630d7a",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xd2cbaf",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x1500808d369f3869f3d0cf35f8c24f8bfdb8469b7c49851ab0f5f06b41f44487",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xb00faca74b57f40c1f174d84f11c3c196b84ee474fbb7f70f562e95010997066",
|
|
+ "timestamp": "0x6a7ead3e",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a39a01894bb82b61e2a3decbd933ada4704ff2dda650370cf754cb364117213bd2745f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841128b391381593396acd80149ae7d4b73348fd1cac7b1cb2bccbb4ec876dbf04d7ecbb29b5bf0de4a13f8c8e69a942fd90bada6dcd560a698920f4a55123ffa4901b841682705277ebcc73ce15ce760ee82cb337f9e4a594b4cb5999c7e31e99f217ca34e70f1e2356e5118905307d39c5d8604b483b539094a3134e042d9d04f6eb07901b841187fa0f42e1ba7ff93686f7720e7abe03f66f46acf02e8e04f8ac52a8b77c93836deb8cf5262bc67e35d494b49f93772343cd3c8323f14fe1442b788b800c3bf00b8416e4d970eebbb98d74ddd0302fdda7521ddb9c68f885cdb803089639705abbde865fee9107cb04b22c68cc9a193fe8ee513c8013cda423033085fbecde858e8dc01b841aa58cd0a7cc80eca95e54a9b6ae45e3bbad8cd813ad68aeb209572e0617acb6f24b1553c6b8aee2e6a49b2a607ee85bc1ca53ede1127d53bc89e9c768b6a0d9d01b8416c97b3b0c533c6e81e639698ebff20865b289df1fb6f9663e5eb06d704d4a6837db4bc0607aa491cda42d6f89c1cae134771ecdcffe24066201ec4caa9c0a0f901f907bff9029303b9028f392d1df30d8e600716c8fd3e867024b8792924ea116ba0c1796235f0bbc5ca5893f60c3a5b453ed9cbcf68122f7d7b5d4ec5a9b31fe20888d7af374c8b61031d9a747f9b714e35a62e79f0d170630a242988b812d050ce8c45cef5babe7f67c77d4b84fcfec700a1198209735cf066fb64c894d35b1cfe902354eba2c6b915c3d0fe280d11fda866b831bf94f6828ac724e84b5142d37cdd197fdcc23bb50f1bfea063757e455f42b1f4507a643df49851b7137fba2ccba2250c99d39fd9318863334687b6c1be2b2468a2324541856f8e72afafc7ef150db595ccad293166b61c4864ef976f1151316d49a4baaee40a3a90a82d3b263af085dee13054e0a8026def466fb4ac5a9b017d90e6ef087d0c5c9a79bfb4e0e88b4d8090313f2f0657333597bcecfbd6ca6ad99b31bf62f1e7493ea8af89a47b60ee388c6dfa67474d8becf880a171892b4d595a643536cbcdf6d1b26b37632ea3187df5d611e9c5eda89b294c218924fd6c4175b9c51f864b7954f56d142d3421c8669181c283b498bf795475ea7d39fe8a8f7dd5a58a7b60b97a0cf8a074a96b239327db57fc5eb733766f64a8b37176e4321a3709f4b2ef49ac037fbdbae11a3f466392dd30887a6293aa2c473c8bfcd0468ad78c98481dfb7656d6649346a54ddd436b705c7ee48ce8e72b73c3aba791a47766766648edd575c8b7d8f8f468beb8e9c7a79123d53f982f75159b245063372ad35ee408c8d25858147975b2e953de8d2a0c445b62f6b0ac76762b40c9532f7495df1383715b1453e99179a14f7b63046111b9964e058a5922e86c328da48450d75a3b394485958343219ec311ce975ad0c2ff20a97545cc36875e8f1a57fcbcd9b47a5f294d1c46aa354181595e583589a3b9166b42cbea30fa0cab4c3974adeb3e77e0f9029204b9028e39bf9693b2c3785af09d545bbcfd707b99cff6b9fc4f0ee16742dc86d3bc21f595113cc80a00fbf783b8a64684af8d1761b0892889aa6d1d49adb96c30a951fe545ba4b74ccfb0f2240b7f04a153b2222fa3773496dabb76c84622fe39942230983f8bcb91d99936b488af5121fbf8608ebf4a1a33c4e6bfdf6e736b8e88bc6fa671195f31384836391f4cdef0e7c210872b1e625f7c994162a7cf3b4669be4523cb3d78ed7215cb4fa490238224669d9280bef8dc6c9e30aa7a668ffba497c57d59fc6a388c972e5229273598998aff73eae9391ca9c690c94791b9b5494751208541bf64ce0495e574fcbb69496439b6d4b161da97d45c519858d18cc4fc73d9f81dbf9fd497b0cb5a56675075e26f5b9afea362073af01506cee634b6663cc369bd3946f11c64afb27fdbe7907b124c13ddc9d3667078a80b7f1e5c38fed8d79131f5efd4f159c02f9d4a12917752a2d56f0e1dca84e272eb5cf38779e9cd9ebd0ada95e9396dfb3d0aaf19ff63811192ba1c25f3877899a0cfa39102d0acc8864f1a68e4970b0e59b0a0f79cd9798bf5adbca8f9d8d018e9121b88b8af0d35b7b7b0f65ed13704d327671a1fb8ebceaa0fbe3dd7dae6f15bec1517d663d34e69e6684b4c538f507c6fd79ff26d514bd072fcf3fa72ba73d9a839ed7c49a0e2d817f806f08ccc73d08eeeb0edec982aa9c76b987c72d893dc7df25bff58c5452378633922974df1bb7a3b1523ab886795bad08df6dbe71729e4e9fa8f60f645ea4ad4cf96232ef99154291bb64fe894568984ef6f75ef0246d30437d198802bcd7fbe1108eb6914a477189b1126ce0e8165483a44d4cc6df2b5990f676e2b1ede15d359a7d845eaaf124455de343e445e28eb964e6bb2d1a83d5afbbece8683a531509819222f45697273e76df9029106b9028d397ae36dd81ff6baf549cb5fad263d9f131dc669029ec4a923a893385323dddc11759a4e8803a8f7ffa9c7e6787e3a2e3599e729d8ce1c2df8eebe490771a472e9bb345bcf7cac24b58d9699dfa19f685102fc39c5b3f06fe636228a83cf1fa90d1d84bae1b965d283903f59e393d7232ed9993aef6e0082f4b52d6433f5282c6dec46c888efa2b3961115e020162c0af3024eaa297b4ea3af51749f20cabcd3e269217598c98b1cfc3796145de6f0d0d5365f24bb3408b78d3c93feebb5d86260f359a209d4e9e7db4bfb7dacdd5321a04bc871c2b5eb705b5b31745cdb682ae68cb002167792968248eb7119e47e235c76b1cd26a6e94ac6e0689169023e3c9c7136319e2c3b16c134ae01cbe39b4461503c78e61489982399db51ea9916933a7ad6543dd8c1d097c8094930a8144131feee585bbfb782c0bdc8ff85d668308caa71385bd5c90c8e23e9e09e58b2632ef8a3ce9aaa8da60f579f81594b33f1b30b7d5b7cc9c797d91e64db0afe4157e6f8f73ef2aceaec6c7eef9ce6551e79749d1ee2cf0a6ef7f8b6ba774aacc80623099e633a92086325a38beee6b87a7361ce44056d398a2a32864705c2c54233387321d3e117b98684cfcf0d5bf0c8e898591ffb98d24ebac27ce81adcd946b8d166ef8ad5b14cedb8af3af68f1f3dc4b1baf15925d34931ceb961b5eaf26084433c08b32dd42f9089ba2ff3fd4cf7570adef369d14e4fcdbda44591d421c3a6cefbec3df7bd4fff798fedab4ae2b75de82c7de371f238525f74eadafb1b95a73ea22f34a69a6af839559906392ac4cc9b941bc728c9134dabccb6749c1a7a79c28d9214cea8ac5d69de068e789f2af8b8957cd57973cd2411dffb2a8c65832c542cf0f436cb8540964a34833fce5239ee5b99904aed5da82e24df5e20",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x8fabd56662b60f03638c45ebd5a176d928a871471c343b1bffb7ef3660968ddd",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xdf09b32c761620c5be77da398b97a64f03c3980c",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xd2cbb0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x7e0d972c8c9db5fd85ea27496624b3b82821c1b67476c88e1af28fe221bfc10b",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x04c4ca145009057a55666c5cd2c78e06ba04634f037d3a98c6e84c102659d5e2",
|
|
+ "timestamp": "0x6a7ead3f",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-L-prag-relaxat-anchor-13814704-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b84132fd5d99e68fea004fe09b26574797e3cb5954ee3d7ae921f8c814017b893ebb163a520306a35f9b883bef6f4d29ebf6a996ad2e3b03a125a86797e0708f402900b841f96c093a389fd9929e9c51f316d78e0d3469ac975ba0c3cdc8d3a61eebdf86d573a8c3dc9931ed437ab645f949b65acf63ae54ace359b5565675af7bf5e02f5d00b84123426aff2396a50dd4df0837c575d569d7be7125432d2d1ff75d01c7d7f34e8731ad213fc0423cd409059c19f56752816430046cf3ff21e6ee165142a2a378f000b84194ef7b501a742395b7ae275fada5db7e4cab10d63f2b11246888d75a2b695f940e657c6ef17d764b03c4219507ed5ac98159e08a36300c3fb2e7fda281ab267900b841732e4d49af223fa1862f4521fd289842a1514f17032562da4b255fd9d0e1a2bf7b20b28e3de74313c4f7bcad18552eef4dc5730603c6323deb8a41131a1785f000b841f6f3e6b33f0b7268d3ee786439644aa7653794916074f53a7d6b01d4893dabd84cf1d46854b126bacedf912c86d9e8281518f5c8877cc60a90e9f5c5848ad42c00",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x460b4c62c8447355c53896d91e9ad678a2dbd313b7eb16a4f1ad901f8a3b1ecd",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xe13aa491abbc1252dd714e7ca0e55717a2143eaf",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xd30baf",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xf8aa07b3181b613a62eaa367d9c2e6cdfe3208ff33b2f633f0a4ff9956aef71b",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xeef494346cb353c6892d193991223e61f283a71355d13c42edc986f5b56abdd6",
|
|
+ "timestamp": "0x6a7ed194",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90cd1a00e89096356f2490464f9b29cd0eedaa24f55af5c2b8c88589a18b9f1ca365302f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841d07dab3dbb884c784366a65ba6ef402d0c268e353fa8b0520de5eca7993db6eb17f3e35e0b6163cecc7a914cf227afc9032b778766b8e179e432d4c158372cea00b841af4e938019f13973c3c10e4549352bcb07d3f519cb52435679087ec1cbeaf4f97e82a8284a6f99587f544a881a8f59b079a02c827b8cdf542916885c1058da9801b8412ac61393bbed0eb78453872dcb9d2ca007e47069f5d883126080f2d4ab332f880f68c8dd6b890dc2884e0d36387c08b4aa39a01ea81044077a58d1b5afbad92201b841cca799e747a8631511e25bbf4cb965c95e57b61da60d33388435c31d497f945d1c18f35951d396b09a64a455ed8723a9cf3ea5420915c66b3860bbf83735ca9901b841701ea625bd5e2319c1aee7fbca890b651ae4f8468ec70266b26a8ea788257f47119dd70650d56e9a0d91ae6704d0de6ea196374b87c756077280329f4faafc6a00b84154e62406148e014644c914a0089d48f55ce68a523dea30a8e2c0d6f4b487aba24d9922e8230d830cc676a5352d2bf104f2558b90184f00f749a158fefe86133b00f90a57f9029580b9029139a132d8081290ed6fcb74cdddb9b3a72962bc558a257ca9d39d3ef34cbd4842227de88ea1b5bf947b0f2265be30b7e35c6a05fbaf11f5639ae613a7974d9d677e3630a77699a6625a8e1bbf75eccffb9cffe67923dfed674d1b3785eaec48522f34c3522975d53dcceffc29fe3d2b86c176cc6c3a12b12e8e9a473fd525e595c576baac9e3537d522ec3e09115729faf92c13ea712f07724e6a0a139bb17cb427dab3cc96b1a4d14ad239f5bf73bd5f696014124382844465eb8a19e8671ac6618ae042bab88ac72a9779c8194b156365636c2835568eb30ce422c3053ac8200d3ea97c9ac68e432dde4c7c5b266d4bd333151a9b5a95ce21ff1b70cedbd5d84cc6d47d1ff2af8d1c9b2a2e345a23d44f339d7b51975eeae8ce958b400dc658bbd254faa727452b3255ccf2b2f865c4f2e14c87c9b3d91163d23ff63e0a987489064e00a4706bfbd4c495e8a3ac2d1953ce5aa9c7e6f0851f9a137ce1356fae558cd31b747d1662cafcf57c6f5fb39300e7296b043c9fb26456d5a9b24ad85628b5b529571f6015d95e63b266728c6a153aece35574ba3cf7c520cebcc7ff1427d977730946fbec61cc00803113a2d30a993f7fae85b7b39f6a62e965ed96dde57087d5ac47fb2a9243dcde34084e57558533926e737337f0e3ef6eeecdd1c7424d4621126354cd6eef429713fe3853f79b9cd23dafabe6d5dc3889f835f68b5f2240510c9c9441de3d11039fd81ae2d13d29b8cc3983e39d4c827f2e4de23d92e1f0c6a051dc9b4b36ffea39d1b9b235ab9d69f8a25856faea9745144463b90c62832ea87ce8d00f7cbdb1c97491832f416bdefe4673d0daabb46874c2059a4c688ca675f14030b95e8bb5777d9dbdc268881fee7e4c9b7b18343d031462e7d43324e9e292f262662b6a971e04953c40f9029203b9028e39212a4ad5f32c8faea5cc01148bd716c4eef77d5ba66fe74371a60ecd29af74e7dcfca987f8c95d0fb5e9283a145d91ae729bfc8d8e21f4bd3f7026b351fa9a9d85fec8af38090313d4fc6e2cfadb8c7f3af3c43bda1f548119340810c96f29bcb9ac360e895a58d7be05af467b347c7a5e66f865c68f28ac09c4c1a6cdd7dc96011b8733ce951f23a78423aed67929deb28207a45391b573646ab4bd196d31c9eed2a5f774a7c88a28ba477b32f0e1d0090a6f12cbbe2f2a17acc309dbbb9a9759087c9cfb4a3a6c6a1d428bc6739086135f92166b7c0d6baf89ca377d40422304c5c4ea48fa577f86a884b3848967ad58dd8b03a6a8b529463d5ec333779f2b089db7507e2d6b238e2418f7a72a3d6942160ac76dfcdc3426aaab8946da3adb893ed8fe37e9dc4f1444d33e6e0749a182a0906b542a2d9cc129cd433ca0413a0e0bca9b3c89dd9aa7b931e4a99e4c33283cbbc79198dc1afacc4b91435b6f4e4283fe6ed224021f6f475dc4269ee6f90f1206395c3f53d284409b8e33e599e70d0be33146556e7da715b31a56a27abab51eb8f55925dff6902c1345a95498da0cee3112d26f3523dbc6229e64cb189042235dfbba8ead5539692b4e553358a274e9ca5f8c0a3aa238686a70505c6a5dc77f7f310a452dd18e3adac8ad918cbf2bd4fd2e0652d6fc58f61270ca61b77c8e4696dbf66533f91affd230fcdc725fd41dcbd456cd933353f6b4c625e7ed5daa9a06c3b8c444188281c15e198239ba6e47fe8b49488a632d8746dd65c9abfc2c1a3787c26419539b5d93481a0699f421bcae1e2da1965094a76f1eefd0960ab38316435cfde9cbdfb3fa5e7aa295358c91e1caa08fb26649b1abecc8d3e12090826ad3523b11768904c8c4f275beeb89ad4c6d391c92abaef853f730f9029405b9029039a0f16a3e52b60e6e112c8c42364a9b60cdce4b091ded902f4de955f2844549eeaa97db06aac7833605b9a844aa54610dfbbe71e0a2183257dd03b08de8af705771fe6bb5145fa27174c1b3ece6390f87e05a0c295172bd38f5ad445cabbef874ff1f9511a36942cc553bacdec98b94493894edb50f83a921fc84e7134c2538e999b86a622862e3d032e6f1a97d7a1cd8c9a1bfdb2ab60303f2df46d6c6761269347525a6c9416cbcbb6d41063fa8471128b1edccd7eeedaf82d810b7ba118041382e4aab7489fdb3feae069e4a693f3514473cca21abdcd3ca5ad7bd4c13e5c3c9a09326d8c8b0c5c9a0c5666d0e5d6150c1985835af73b0e7a9afbb331867b296c8f216f675750d78a636f8b5614540dc576cc31001986664cbcf928985475be64f8d7b86ba9e2de485bdb642ed982ac53b4619434328e39a25e6adf1b4b7179d31fc58e4d684a7c9cf6813d4192d6158664f6e721c95288657326b4eaaf17ef039472bb87096d41db02bd3e1c4f0551c4d4201d5b35fe31b9a21f4de5d365e2ef7065196c6a72787f4bed27992195b2c54e38d56437d021503c0ccae72852b6732d9f872bc4f32d6b42e717443e3c628cabc79103483c5297f75ad99e0a3a7e6c54c24f6b1188741d8250e04291086117847b42c8fa59222d705ee98b5bb92231642a59ed8426e91c276af735d06d12a0f2441a9d55caad47a9c8746ac9336b26dfc8a5075d91752125df669e6fc8b54d564292583af15750d617277d00a0dbf197b69561aa79f22d9b3aef7ad7ccf183914b04cf67413d9643b126fc6670b0070e45e6b0b9f52661b56c71a8a60d2835edf36e8c1bb91f5b2ce74a916c41ea9eb445925b87493b5063338a52f118fdd72a1e17b8ce672110d2981f27312523f1c9affde984eb671c1eab7f2f67ef9029006b9028c3968f8ca56ef9c42760035a8b81ded72ab4e2e46bd3ccc4951f0fe5a1065ff903f958a76c5890f9bc909847575162712f138c9646df8159b3795c9e9f8190a6e7f20f4d0a9c8658afda4d2cf6805e560e5601e85f77104d3f723c6a10b891a0f89336333a8ee49b4404a3fdb37dcd4557a67b1bd90baae96ef48f642200b720c31d2380fb65eb5ecd41a8ff9d66450ceae5aa558749dbe5e2713b4a12cd445b341569e32f09d73f39667e853c4852feef962d9e9f8a12093da2b43a5bcf65fc970d5c0926884b39b1c68ccaa14fcb308dbabc026b64ca4bdb2fdf823bce5d52e346f12a2b695fa5c2720403ab22a647125ab3aadcde2a56f3c7a69aa393bf7687a5cef5a4c96c835ce37ae00314c78b0b591955728a8233c583c17bd60a2eb75a6b13ef120fbce5fddcc6410f349a86c0b09e25ffafdb58a06e8dbcf9e0b1f8ef2d75cfe43586405377699b41e49b2f9dac2317efab6ca9ad2a858eb1342872012a5ea8a874f915b345b6f91c6c79382cee194f9aa38d5bead44c783e4cd5398ad010bf1303e19e3f11521cd0af554d16794de324ede250e174b043a1bb89c398c84e29f360c654b3dfe619257b42afc3c96e9ec757d863d9ff79d0b32f06d63b9e2d75898b6f0f46a34fbb7586c2a21104094ee8b5e94da571a9c15b5b3f5d58544d14a9097c653aa935cdf8d333cc0fbf2fc0747a2815d77136e4c6d1928e4dfc77fc230f165653dd8e0531229abbfcde76d3c4648f36766d56622a9ef87fdbc690a3086c2b78af4d3e542ff2a5881bd9b68eaca7a151dc8674c1cca654ae1b4946296a19d2dad268ff743edf9c60538851b746d53ebb86c716a77e878c71efb7670577c1a69c7834e79ca7b9b8554885ec676ef2ce953106f3294c819a02564931939a5c529d99dba3080",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x1e95460f6d66cd4df4a9aec236b28b8605f7a40c54e37ae78a23bd1f855020ee",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xf73bbbd26a82dbc769066550d8d4585eab2fc00d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xd30bb0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x460b4c62c8447355c53896d91e9ad678a2dbd313b7eb16a4f1ad901f8a3b1ecd",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x9fdc0291bfed2d4a448c1616d57a43952e5ea8edb9383b736198d0699a163728",
|
|
+ "timestamp": "0x6a7ed194",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-L-prag-relaxat-anchor-13831088-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841395004fe82fb07d6c10766200d492bbb46ee6f1d484085aae0c218ce641a6a531944cb07c8a24561ef015515df11815b20b8dd90898e6947f074c34a65e84e2f00b8413bcba9ba755335c9e4465d3f92fa22d4e33bfe7fe2caf12387be99c5aff1043149e3d42de5c0ce907428555975ee271a178742947d0b470ee01a0300c7f0645b00b841237db71111f727bb4345d19f307ac4fa5f81057b10e6309d2cff9ce1507867be3170251e3f46d2ee57fabc5f2b4b0a0ab30584c80d5c9cce77a025cb5b215f3600b841e6ae64449361c739116b1ed5677ea04d7a2133b5de69bd7f52204fe39b276b2063166ac1c1fb78baaabcd8de52b460c681d1b72012183e11a2d2dffccfc7e4a300b841b555407e7d919e766dac07bb43b604f918f477183a612d194ddfb447431a098b555aec539dd245699f97e3a894a1bb342f3bf674d27b91e2bdf27b476ef2760a01b84154082f3fb2c1c7d33f27e1e5e03cda47a392c172cfff149711551146be63c50366d8e3c3c87d9ca7c59425a88a295e4fe599662ebda092c8c245e31260e78f8801",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xf70bb348c8f5a250b16620a8ba85c3e7a195fb914b0276c92e442ab734e408d7",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x5f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb0",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xd34baf",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x9116d6a4961dedd349c60d032286150dd101963560c49d1692825019211d6427",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x2e39dbcd5a6ac7590967a733bae47c565fdcaeea1ac88f1c32e054802ad56f07",
|
|
+ "timestamp": "0x6a7ef3ac",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf9050ea0cc531635a3c0d1e7bedf5170ef0973ba614d34402a203120a605074e148fd23cf8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8415e8a1d724aeefd70fae608be12894a567daf6cb1f84f9ae4cc3fcc70aa044ddf3faa908ae47c7bd286f1650b8d03fe88b644d7ccf2c3c011041a81c5c68d725e00b841cb863b5d185b50d33e197ee2d485f2be38370cfdb8020316f0c6a1449709d9a064e35f8aa26935e3f979e0efbb564f2e837bb56e1a0cb9bbae7c9fc1395037ea00b841c0614d0b7cfbe3e848c31d576afbc715568b5775e8fd3d1be23fa4458e6485203a23e343743cf04c55c002407607e521be3ab4c3c5aef576d7d9a6a142c75edf01b84126dedbcf208c646616f6b8a9d33f10fe10b3d7df095165a050b47a1046a1285929fa8a3cff26f958475cf5049788c587bc8de909987b0f30bc792a3f646c09c600b8414fc9c48870a6283e38af0cb8779194b21bc5d6f3759d0b4db1c28946e1738bf25e9e483add5589f970e6a307f39a66d997485ab4ac9e48a06772ad9ba32fe8d300b8415ddf2c8de0306446874dcc1ca19397ee3ba47fea02121bb6bb73150ab9a0d16f43e0a3333dc216687d109071c465ff39cd53b897ca9a8fd24c90b107acda7b2800f90294f9029102b9028d393c707f33eca46849d721eb5674f0f6b97a0a1980d3d8cb1666ea7ca70fb5320af7c2f2ad8d7efd685772b2094f2b1584d189c120cb3292dc7c4bf328af111a44ad1746c8f1a0cbe631576ac7c739a69eb31d633fbf406dd1175b7d829840e511f703f75a93f42835e9fe05e54cda611a4111589320644da564ba63750ae7f21a2193e75724810cc369bf4d607e4c296d8b7eb4fe7c1968c7add42cf659f54fb1ee4a2bb48f11391fe5b3e5ea5e64361cb9b3fbc3c16cd0b13ad5cb402671820112f22b46d485ac9ac83e884b1b6c59c159b826d4552e93412faba0246ae7bc89cfe4ef86af90cefae4f4fc21d6cedb70a4290720bd9d11ded2dcea1aa43f72c675685686fd156c1beaf7793042703ddeb47b0b873853d695a8b14f497c9fc34d3e86433b456595f9ac44efc50ad325b86aba7a6607c129c75c654d4997ec42a68dfca584b83bd2846de8cc1834451ee2e0509735ed377064d373de8c182866f76f0b29b1973dc98931073609379320ec932be7f969ab12b5c975c7fcb9cd8dfedbede6210e98ae589a3c6f376d2d4f63c49a30c2e05e086716d30f67d0287eaec16775105f6cc1f7a12967de976b82bf280e1b0fc050f37d88b1aabd45cacd0305f8c2d759362f1d154af57c4f0cd578f0e8ef6d76259cc160613ea89c5039b13cc47171f32196cd171e06fc354e1f2e174146982a13c939d0b8abdea7a7f66967b26c5af54960dab83acb2f27b5a9246297c6295cc63fb8eee8f5ecb3c277d5aaf419b5753953df5515966ebec8edd1dd4e71edc9c959f8d8c72eaccfd4d62f4ce968feb8b2d47345407d1d0590f3e513131689d7f650441083e01af53e9d3e13149beaab27ff25a26c9ffd32793b0a9dc059e18b4c46a1cd5a180611e4f3b3998653004c176c131adff5a0",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x2e2be0ec9fd621a380691091a2d3c45540be599b353ed7595f71bb79fb974bf9",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x97473985d04723299559f49b856effb47d7abfad",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xd34bb0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xf70bb348c8f5a250b16620a8ba85c3e7a195fb914b0276c92e442ab734e408d7",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xd67b11a261a8a8c7963532472d9c3631c872e809a78938a3c8985da826c7991c",
|
|
+ "timestamp": "0x6a7ef3ac",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-L-prag-relaxat-anchor-13847472-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e382d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b84161939dfa88465d91ff476dbee45f94626a33e89b30789c74df103628855459207c1469479374d01485b7b9470397b87cefeb0e3fb777a6ee048f68b5b889323701b8413c91e6d87de3396fd8d64d5fd462b93680173d323d15d94225d1b38901cb437618f847377ead81c778c7eafcdb2838eb8dbd510bd9b7ff95c29dea482a4035f700b84179d3a9129dcdca389b0f2de5d31783499ed56f7d1156c7252a6f0db41e7995f13663128a2d7154a2bfbd3109702b6311423d56ed8222d1a84f7f7a67674279e500b8411639f3960eed3d6b290f2d0ddc79593c6bbb9ab4b072fda7743693321688bd822bd614306067af36776602c93360b05b5089f53690886f7dab7c53e2ff72804c01b841a48b37da9e1b415da09f43109bc51ed1544dbcbec6bfe3d1cebd2952e07066d81f5f8955644327d8e42c810485c5118dfeda812dcc5baf613923737f50a1f51301b84166d71c0b1e83b803d66caa464ef682aebf072556672c5ee330ce2e90dd6b29b72e3b674281050acd27d9e912987c19ee6decd52ff9a387dc46e6a08f10344d2f01",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x64871980d7323657e04a38cb5d433ed3a26a809cac6f53fadfe6eda376f7fa32",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xf73bbbd26a82dbc769066550d8d4585eab2fc00d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xf4240f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x0352fcdb413cec32f3215f54581e9c6b77fcd79a0b868a15162b7bc6e114c35a",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x6ca9be344836d22df1746f0916d748509a7680fb1cf0b8be2f47739c6a936f6f",
|
|
+ "timestamp": "0x6a916c5f",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf919b7a043794b2dce1e460340f2821c5e4f54361e2547dec79998fb70235715d28a021cf8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b84178ba5cf50655ffb29a81e75c0ca57b18c37ec1794a6944381fbebc61afb4bf4c2fdbbf37c5969acf6a48fd125c600dbbc7e99481bbb16550a352f33eb08db1c201b841e29f969be846ce38408ded40d546a135d90f8705f59d0891cc1be380471165383342befb2bf816237e72caacf34029b69ea49779da06d7e25e9690b533d73e8f00b841893aef09c854973a6d22a96bd0c765f57a586129c5649fbf05a1367a970373e87280993abcb5e43231f55c8daa89a49c97074aa3f5b7a3504240a0d47da5f09b01b841e815f21715e47f86441c1dbb6be1a9b16ee19e95643a7673b116204b46149d4812720c078aa983bd19953963f2cce5f98a465224c2591918fdb0442989e6bca600b841af2f0a1f03628da4de47282def38cd86551a55a7f7c4fe02b4af7bf6a3108cb028fd5d5e0e6b5de8279b8acd38b9191dac6056883d075d4311246ef82bcbaf0900b841d64c6d27ebffd382545f0988657fe0980079bb7f4cd0669373211de232674c5c526a010e7d9d6df75e64cfc6596d74f50bff31f39a0f765b9d27d5252c02c63400f9173df9029180b9028d3911e364c6dfbc86c2b3de9a3dc54b3cb7050d11b20460bc70db372d81a3b88e7a9e4f7e1696dc2a065a6cd9842a256c1a5d0486cdcac9a0cb076bbf86d11fa4be8198595349c404b4e49a25fb43f6a03119a5d2790c814ee4e37949c8a15bab1273f8c7f91935d64dc3c8f8dbe7ab09663fccfa09397a7b134dcc6c656184210c76c892069f5a3be4137f89652fdbe9e224d559e238042268fab6a6532bc727789c0e9f9f1a438dd2629ae0aeec611d8e694d2ecb21e478fd513c99edf1fa5915ac92f9313abe1bac807c8ebf29f7a2f1f232542308bdf0214e61eca14fd95521926208746f3e96366c3fc7f156524f1a377ed71c830cd42212b9a7578cb1664e6ced4c5313467d5264e18e3f1e4f98c7c9ffbf9abb09a79d7ca730d67528e5fe5c170316a774c907fe24d14d8cdc2c82ac0a7f5936f94fe91cc54230bff4aeb688d3edcc37b00fee40c4a4db7eaf492a9a27bf925f92639c854682f6b2040b4e35f9cefddff5befb98a35691b3befe2ca20b122f76e91d095486333cc9573239e57a9c0520f3bc95ff6d2296eb274ce31379fcf13290649d53802d4841b4d6645df4c73976b4a2f286a18882d0192272762273188eba7220d19193c9496d59620ce1e21f2b5c192cc1b5cf2ef11ed4f554f58b3ca83255ddc3f5d0cf6a293d9d2363a7ec12a6a4679064edab4b36d33b6535a0e5981b45fd99b0893269c6a440aa49e26309c7e1fc1dac7b0505cf69a14d656109a1a0de07364c816125446a5cebd35ae26e635db5da099351a0ff1dfcc37e4e182eb47be0988eec490a8643feb2326968a5b8383acd917246deeca799ab705314b5efc7f452fe235e50dc28631465f9f74c3573cafe343f966b79677a1914131a88e9a8ba8531d5ba6d5ac9d197dfc6d082ef84325d6e6235f9029701b9029339a2bfdd9d162623cc2816fad7edbb7165a8fb009065d2875ba39680e8fbdb3d88f582706e1bcfd459d7928b58cc290589a76cd44e7d2538a1bcfd6a4e8ba3c4d9a49057860f8bc2ba95d94c60c5a33324b90e31ee497c766b30b9d147bc595f2ca9b76ae162b9bff17d25bd34b19745e0325b33307f58d53dbf450792eda2c9de63462d0465088a97f576eaef4c74ad1cb4b1ba470b0153d0d774fe7d7b6d3c228822ba8da445d1d2405b17d24035f17ddc1e4f007b1f1de893a36211a038d75528c0b285aff7ab814271142f0f879d2dd44aa8097c71eefa17696bd96ca92be89e53a34891410545b029ea672f9847ba339674ca23b292e92075fb51a6468645f1ec52c997935f34598bb3b19ceb5b18192b4cff79091f0653047f31d3942d46edf0a57cd6875d3ba862e2cd213393c11c536d922dbdadaf3656e4d79c29ee0a29fc341f0b8b17b2201a655f65edafb4536101fbf03c8d63d7d098a09c4acd53e8de195b34576114c3220866caf6b72331dde9389e110467795f784b0326a343f1fc364260e42b98379b1ed7781af66f084dfe3b0c331aa5b367c2f6bf2664f91442524db2d4d7c664ba24119541d9ed7f70a6f022b75bf7624968f15c36242636f6cd58416e7811ac6c5597cd0539aaa153511552af5641cdb9045c300956eb54423514bbfa1e76ddd4e4c7b811285ae0d9dff5ede61279bb2088fb2fefa6a2f92f2d9b10859845a959e7f5ebfb9738b6eee24c1a90b8a12dfda561a9917b5eaf38894ca1ad1366ac7609978a4f7f853cc270bfdadd44204c5f38d218606689ae193f08aee22cebaa28f78b1642a6eade4250eaed89bbbd29c4407d5bd6ffa5456adfcdd3977e65908d9e291687adaae5a28edee252a61238dd468d2178e33192033aaf8cc1858a2e5cd6d6dbddee29d1d8f9029202b9028e3940846e29d9e3b3e3c3b19d6aef82cd2fda00b7efa43ec9a8740cd4c565af8e9dc25c409b3e18ae540a115d37492174fb4cb7f28c702a54a26975331268efe638d0d3d334511678cf9271e074619956715798e7b9da4b0d2993b3d65e3812b341ebf9e30c7ac2867c7c99786ea5ce247e3b8bfbb7452f7ae2479dbb543f8d4752c5ffdcbc96223f48e533f6d4b57b5b658532450f9774a993f1ea44297834f3ab4f41f31b3c6a715013be9c4550f95d30fe563cf0280405d6330f3a61d4e2297d8942ae7a31a2b8ce2c64cfe4479fa88a0cf531f58d76b59064605072039d5be7b5d631a678377ab2688f8eec8b89b85db88f62ab4eb8f092b270a4741335f61cc0acbcd56fcad6eac9bbbdf3d7629124012942ac3c1f77e782aa268e577acc41259cb8a2c2f7bebeeb17277fb845a2dcd0cc9ea47b193db524bf1933b7ef8796bd5f0e46c1429a782b12f1fb31ccb33ce6a08945fb30f53dd2d4dfc1388c1a6c2b06a5b129544852392c8cc65ad72dd01c232667df98b671e49ae9643d2b1f894f6e15921888b47c278abf339559f5abb34996d3ddfbb1870261b7347efc6cb614b9316bb2f95f31ad8a0fc9d4caaf981250592efcdb7270da205885551e3611c9b410e66b0cfc8583390587549527bd661e229b2f5327d903cd5313dbb6ab7112df25dddb2d055c53bc7adb26fb6884a26cb5f9946c22bebe0fd6377e80f890b9fabecfc80f471acee3d81e386346682124fd72ebd3b95419fe04beca55cf0b5d3bb53da6e3fac76732ed4f3e6f1a883fb67a8e4f4b7499f1b043bbb4b0fe9fcd82eb8b5efcc9f243aa6ae3f8c761474f3bc84ca5de8fe1b26b43f6dabcdbac2c29e6c6ca289acec64df753e93bc59ef7e95c3a7ec51efcdbe3e0c71d404ab17a1a68818cdd49e04d0464a1c0f9028e03b9028a397a12916dadf33b5e72e2776bd2c868b99bfc0dbc4d1a1a487283812e7ca0fcf30f0ad5c434b8423063cb5b5ea690c4efa4aa7eb91c208c9d4a7cc9913fd7a78a9421540ef9d6f7303c082c6c5d2a551f52047211d8075346e318d94b086a0ec2e1524831f1bc32577f6da97f5a83912db1ee7473afc72f97ef9b732a45d2cf1895b6df3a62b8bece0fa447a9bf640c5cfd2fe7651bb388fa3d0b3732b2c43449f49744b9717b463d73a5c29dec1568be5130f4ca7d2e4f8283ecf7d66549a76849df01e6d179df77135cbff4e654b390c01124fbf344a755339caf45abc790cb4fb0240f6c6cdd63e8a37953239263140204ab4964d4d449e0f8b06fec9e29956dbc10c9838c6eedea9c43269193ce4ec331ff4b23ef679f39038c6693ac62ed7ac6c93abe6adf014ffdc3763b17c3e4a1c19fda1cc188d23a08ed3d9744748812f8bc52c9963321c08291675b6cb7b73d5a82f7a9dab5ee94b4d639bb983566684a25b31aaf3ba17a4fe2efff94e2c7bb1718248ed540a1ecf7fb8243def6cb181d4cd8d5ca0f4cca6dd47bac9554f75a4cd03675082a0bb4f95a64e9aa57ea256047db1297e85beefdbff3df8c7732d288f2f5ebfc54a1260f7fba5d6558d380dd66974c031682b9fc14cf6778a95b1a7b164ec9f7ad32973c4f9ad183f7c7c93b5eed70745be2b36b545ef541fec85abe97743e2eef73526ef5049ebacb4d37b2aa70606d157d13b2a4501e5b5d4194fad0a8796c8b64137fdb6548a32a644d20d4a249518fa4b099e8c8c3c252a74537bdc3c475dfd1a8993c9626b4dd91897e71a1428e0d3e1b87d59ce37104ce41164c3ab7b6a13cf56e639cc5e93d747f0d05d4f428e49b91e274d09200efd1b2e6d2492bbbdf3c4db383c77c28936976e3e99c6cee93a8baf9029304b9028f390db0844dceab0862a4a5f4ba16f4847afbc8ca55b7511daccbf2e237722b4a7b68d5ec346d816d49ad46fa14ad408d567f69ae4e1ab96b614d7f0e738354e20fab00e5f8ffef4fa0e041ab080f6bdf25683856b884115c3e15125d78c03911b6ad8b63fc8275a7bdf1c760c1b8675f418f5955ca6f2da9337ec40e45d2e1db62ad4b3e7a627fe8423ea1a8d20bb4c17f8975dc8eee4ce142c9bedec91e3d7067cf12a9d8f8aaa29e779cba2b348c2adb0bef02fd939b1bb14775d69836253497ec3f7baf1b2cccefede4d5e6a3a82470d05a26a8c2cb509e47a2fee718ca6313181cfe6286dca5a3d10e480965f34ef6f1e189099d50df36fbd71f8c761a46a8d0b375bcde494ceb459ba35081ad741c433c4f7ffcb8e77a08ce5b845f55af51eda5e62ba1d2d049d254418cc2f8b75471722674a16870d3ac9ee1529068730d5396cd608b4f7f7e4b235ab5f48ba23c395507da66df226cddf5562c3d1753959eae537e034098a66cfa4489a334ca5ddebacb6dab2da5a506d3a9fd24449269eeb858d90961b75d3c217fdeb36e6331b0933cfbad8758d9c572288ff1508eebd97c3e050c415325aabf045570ab5ccb673cc3a58cd75626b269b12911e4e9695f4e159f41c5c125d1a1796cd10a2f2f70d390654f26d34dd2db559fd30361a8c4f27da3517dedebf9caf65d68390451b26459e32d4b9e55c8930d8318d27ddb4ee2cd1a4724d7a2129b9d0dec8b7cd6b527298cf82088160156ac47980766f2fb5a246abb148f68f80dbffb534755d987e1203490f365af7420c803056876a4111a92126f6315c95f644611a60e3ee5efb3711e0d8238f6706f3ace7559507bb5836afe9cdb85921ac656d24c4941cb91fae6dd1ede1a56ee6d6520484ddea05336e8299ff25e6c45b32de02da4f9029405b90290398882c55d17ab106714a0ea084aa6d695af216bc300624101e67c0a68f011c0a778b510daf53945567ba53bc9b49638ee4d1909ba80bb5da364b18f32c58fe1b330a555cc23843099dc5908b14576a548e31c7ad81ecb7ff7b2b77e19b2af6bb64911de144aebd821aa76931f066463ca2b7fab7ea9ffd7e877b0939535c08ef8eb4d0c6c45d79821faf9abb0b5d2baabdd57c3929d2b7a4cbb68bcf7b4a5ed033db21b1f5e1514d56aee98793b5eeffc0f0bf9cce7b61a4ba6b25c946b6244d683d218bcbcfb7669a0b5cfd19f19bc5b059c38ea1e6a4693987c0e579d85c1f4f997a912a5ba497f7a147610e3a144f65a6f8acad8c921588a87db82f4e5a1d264721e42f178e11515c354d4788e2c5f59dd24d0a285cec1a4be757d0d72b84cb4d7255891ac6e19b875aa14edc4d3cf29acba4ad4162cb3117c2b46e9f22064ba744d89e71d488510227d0c83abe7fb69a44ecb033732c78d9c7dd2d2199481082ff1ec8a59f0f2d465d3897a5f2ac84bb85893e50962ca134552d82b5ae6fab5efae777c54bd7c99fcd108161a6a4f37f9a2fe819f0c19b05b31751b522afcb5927cf48ad39dc661532b2feaaba344941137de64b28a448740634965c10afe366fb64b519958f4f156fb6dd1d95bb72d74aa1c41765c6c560167856c5891ddfb649a81b3283983d0ac5639303afa5e8c7613fd71abb17e5bc56d8234fd6b5b85d7507c3527e6a6c3e3947c373502dca49b2c0b8da440e8f9248b1e8c42a8060b29246e267e4a8635c6675001a539bd980e45d8c876a2caff8218d3b6127ffe3f2f886ffedce5ba5292f636088af4eb6e6073a46d7b485e796f41189ebab3a793e94ab33273152273dfdcfbb2ed9f6468a63ba7531f10399af799ae6da1ec30b330716619e074793a1deed09879d0f9029406b9029039ed37b1d52927976e8f340c31bfad0394b873e199a28e171eeb3f1fddf022fb399ed0a47091d1f8eb89b3a666e737eac41d0d49c9a7273136262999272dc6ee8105dfb293c8ddf682573a12e9b4e71cc416fc34a6bd1d8e0687204e3ba5113eaf98b41b3f3e784bdaf6c9c2263067baf791701b79e63f6d6192c3ae36ad864b3fab3573faead7f6927dabee523b346b7f3d03d3bba1957ad290f642fb7f7e8b50c09faa5c0c56d2e7b3699817fc74747799dd7eda434988ccf8b6e4baa466f9dddd7e91b1e4ea9fc7f746c6bf1f576a969454faf966222b20881b5e5b163590ba14a13038aabf9f0a7e65c79393a827c485a24c8e0b484df22564ac4106b63beecba1708b23a0975a672c1beeb04c54965f04da17eb86b99664ffdeb6fce3cc92146e97a7d8abd9d993704f3851d9b9aa2e4db908c56992a35ad2234d07ad5fcc33e8cf9ab28671315274a5ca8be3ac1a9ffef5102c78d47f0c8a53a33d8c24679d499c6e640a74c96ca09e0dff30f71eb2048fca99de2ffe568b8c39da9d5da0c4ea30cabc744d067937d5b3627abe1a49ee15647823a445d1419f16955c6a11a4ef8d8525311c431c4d545258caf81ce51e6d498f26d59975b98f21de03593c61ab793c127f5358746c3ba399ce7270ed0beccd611087bbf7a97a1759762f24d89e3883bbbf33cd6a7be19cbe1c1c021e6f66ce910a3f917f7d149bece97aa4e198d0efd0c701e7b5dffb0e97a31fa178942ab5157f181b2a6ad824cabe755e2e723a3893af9194bdd28dc9f0eb264ebc9dea6f48ae2e6126d257ee0ddc0297247ff21106f652b274a0c941ba8e58ba4f1f19a54268fa8ddcf2bd1818f5e39ae8b5c94a309fb20e9c86717ea3a62e3238ce55e0c9f5a5c68c4ed74eafacfbe60c0a6c8ad79d3a5539d159f10b3ca1f9029007b9028c39240bc08031f2ad94ea94875a6ca99574e1b3ef0b52911217e7922108aefdbb13ca55bf1ad680243f4a34ec7be14ab35923b74a9423c136e85ace3b5db06fb969ea9afac6a52517c4e33779396b429fc73c91ce0f7a6da3d161552a59a65314fcdc7c67f5704532aac69ac2d3f4d207379ae22af9821c8fb1062bcfb9975af75fde546b3913911e29ff9b355f41cc762306386f0d220289a318cf922d1a58c9c7af65ff848981d697de9f0516f1d7eae7a1d5754a8963400c6334d1db77f6dafbb50a547bf2a4a74ce12f88b24f377f7589739668f69cdb3ba09bbfdeb45d4fd5de51ad86deb5aa94e6dc595aceed8fb1d4f3aab4647fcaa1c1f5088f59618eb97945909fb02405525c7a6d0cd6835db161d117f9bf5c18f535d68637b0efeec28f39242c24d289c575f9e6b2a6622a8d5e1b2ca943a1d737b56bc6e0d1170cd148773974df9123405cff277e7eaf3ccd3e95857d227609fba8b36a204f233d076b8244ef53bc5b3e025e61899277a651e3fa8495ca483ab0f3852279823743be619a362e9e9279200d84de0cda3b1c982a1a9931db64f5175399c6a78bbe4270d3059bed67a44c285c0f1c05a6383ffd025b1d4b9639f6b333c75ae9687abb488f7ea673d2b79121b577584776ad2a0dbf644b8ea10a5aea9a6dae852ac926ff45f08c44bc11ed93bf3a2534da5a818d5091e43ac5d470b459d2aff3db2c9c3c9b0ad42b964598c8201dd9cebe80489aa5ca1b1ab7da5ed3c9ba9f7875d407169056385b441e77ba646dd5b629a04f3e9575f5c6a5305b471156e21d49db80903f34a6ea41fd9e65ec9b7a27fe83b377f71a29bcdefd077233a823d3fed293c5be0762eae63efdba9c2d46d4ad8dd1097d29d479dcd6f54a8da59fafe4811a9a726228d17a85463749e72af9028f08b9028b3997fe5713a21a1cdae3e52b1d93f5491c4071a822dd367cc28bf373978c42423e1ff1bfd4fb4aa64718659f7f26539d6e8fc368ef3653c8ab48a3b83cb62967d028bbfdbbdbcccecaa6d58d57a1462ca4b3954299461bb93231c4be491d7743150dd5d63f2c766140c8cbc867bf1e59af9d86c46268fffe246ee6c86bf93cf9c4d21b8353d78c2e2bc69b8c6aaba86f2ac411a4c5abc9393835ecc5aa8d174f881afc6f736cc77cc9279125709c7836b2e395cae05a268938a2e9a8ea53d8f85721af7295632b89125d113fce3635979fd40dd0e9be6dbc5f72c54614481a74b17cf1b4c54b5d2249e98cfa028ba535ea028c8469a4c91a034f804b6fd7792632d77babcce3886211139141b6f6145f21b9ad53f36d4be994e0e9d4ab91aaf56bcf566a85badc512048fcaa6d47c6b168ea6c8acf1ab9dceec916eb6a19729f82c9aedf7f2b4a4559792902f6216892d1f3e4135705306a114c2bf6c96d0b1a0557c22488154d1d647a47e3b4c6a289ee2b44b1ca3b971f1fc7434fa03cba229dd1194eef3721f438f55fb20482da9f25d906267a6a42be4a98065728fe616352bb934c7d238d710fff3d54c87f232f4381e01e3b7441f696a7f9e7fdaed32ed178156a3307a2b3b6228c5f63e575abcc10d6a63c8ae4ddb7275ecd60de06412c3d58040b5d9bd061e79b4c956930d53dc541a94da212ab8a7e67ba75b72cb578a2ba58741040f4c95c528338e427c9cb6c8beed6bbda6b856cbdd7b6bbe642781af45d2068ea8606558bdb6c215884e7efe28ec75a5b3a7fbae06172a4818e75122b6e5b311eeaf0f76a16e87067ecd2b47fdde86faedb7ff2b869ba91a984f8ecd3d8a3dfbb8b9d88c69d3644bf5dfdf9cc4a90e8bedf595a8d144c736d8a449897eaa5116bd08ebc4d",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xbd088f7d59d71449a61eedf40761652193f247c8382c5679656f24b3b3e02f32",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x1bd5514286f5602a6762b0075266379d29af1c9d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xf42410",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x64871980d7323657e04a38cb5d433ed3a26a809cac6f53fadfe6eda376f7fa32",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xf90c6af5a03c7b8965a6bfb39df99d742597af717ce50251a84788e0ace76d25",
|
|
+ "timestamp": "0x6a916c60",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-B-9chei-anchor-16000016-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e382d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8412991f343bcc4fc96659056a70e72d73bd65a1964c49b035ddc5b395d69b1ef7c741e554ed34a0a4970e031351bdb8686fb2873696833f51a0074d8b665de96f201b84190948e0902e3e9360ceecd136034d977e6d8c9753511f56232a92e4aeacf284957ef5827f2806f6cf698dc858cff8fdefa6d0f86be1fa674bee213af1933e23701b841a8ef219830c92493c25a83ea3ac2cde4c5fb0176ae0e1eeecb36cee87f3b705b27aa6463f196fd043d73d04f48f7b894e59fd4e11d160148f35369a94e549b9601b8411bf1704be1b48db66deb457b7275e75ef186c7b497eb4bc9e5d319afc6d6968c1c47807660eeef80665298ca2f5468b7673f2e246875f0efb9a768339b9370fa01b841717c9ed9c515435c226f41840ec40725f383fe206a493ca5e83256ba875ad3a614103117548686b150028e1d357c1ed4c0e25ef2b4d5c2d98e40912a79c2c92f01b8415402bf5c33c2f63c2f7f7987dafb6cc57348c3607d17fa073d80248d657591142623627c66c40f742e225b1032c1ff18befe6ae949a7eb7aaff6b49f6d85482000",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x9857a675d7c45f63634616001ee98ab5e78db7dde042c22e6bfaa4ac9e0d9560",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x97473985d04723299559f49b856effb47d7abfad",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xf4640f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x18a47533b6c5803a7511b88af53146ea90433fcb769ca984a70dc68ecd16972d",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xf489e7d2c952288c5651452a00e12b6820721febad296f1d92363f60261fba21",
|
|
+ "timestamp": "0x6a91905b",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf91720a084a5585e6e71479436f13b64804e4c612eeab4343c466443178211a1c29d22b5f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841023187f5e98f7dc811b390067a9031ea2341b97ba919925ccfe310b172a1c1117b52fe0f2449d41464249797c0b4a0bbd57dd5f9ae92cbfd6a9b17aadedde0e500b841b59180c36e8dec128f4ff7976e46ecf633faf6c6295882b27517d0fccd72f888030028e67ca97027768f5344cf0dfca543f44d9e6be133087b31672589b206ab00b8419c0b68d7d691e119d58fe3ee1d7cb7719d9ae5119203c79646cbdfc7ed62b6b30bc50b7cd18e7f3ce0d310fac3a777474906a04e170899519d7c5dcf0c6e92b301b841bdade5b7f474362e82919ec3083f7ecf63784362c9d201a2cfb98f7b2782b7da24a19b512d69f7f0ab33b163ab6cd9fee3c0e4061adaed64f4753d21f3049f8900b8412afe5b35ddc9fc595e888a10a5225ef943ab3c839f239d92d92ca17f20829db154f01e8bc683e861e97c6592b1644a9c5061ed7497e9e258f36867172418ecd001b84143ceedd5687738db57c92705748d4e6c7ceeb83586917f68756f64209c8237793a554307f003639210e71c4a9958f99b1aec1f04fbec131ed404d58687f52d9301f914a6f9029380b9028f39200f9c3a65a6aecd110e0f805e1b738af10658c7b052476734e81bff2add287b68920ad6899e0298c9b4d3106d015d55d296c9078d264a5501ac92af55ae034730957e9929b9e6d9f8f66b3119873ff8885b506bd21d83f4c5e3da050dba9b41cd1f7e530d694f942f075f42d904e516eace641e15dfc71ccfbeecf3f4d820f01acd7f32c55e11a0e374d5bc24d7cd397252269e6fe8e7a72a6e65c64b28cff2024cff1764f633e871f4b3f91215229bc0cff4e88347e8d77cc24e59eb5bfed58923b5304413fd8f367eeaea22cd68106b6715a1157b0471f7afa653242639149cc76829b124d7a1c51e604849a996d56d058fa6c4e78f5abf8ffb1c6ff4fb5367ee632f45735f1346acebdd026af355f87955ffe29ec793f4c202b7f6a5c4dc82f75948cfec871e8fcd7a0ae656e83d33b6bed5e287a993258c196745fb7b9fd549fa7ebc73e7b1eaf4232bbdaffa5bd81739de4616cf4669aa40a991a3b37d942f375c93a8651043ddd1c7741fb70ebc9c99968588a9e29d4bfd8e65674065c86efea0895fd41211edaa2b3dd9d17d4c21260fe0e0a2dde83bf307886433ebab991fbac1d9798bb16436da95f5865e8cc503b4506013c51b69b26f7b7a41043c33084b2fabc24e97a65f7d82dba15e166c95ba3ca98330f27ea89218cd421a7858653a879e7b706337095ad5acb6dd28223e95e709822ff32df885356d121f9391285218bb0899d4330ec43cd234cabe351b4fc9a58f90f190853fe29facc80108d6c7e789ec92b25e8dc73e1a8cfa2eb75a329d2f9b30766edcdd0853261184d384ba77a5b6cead3108f615596ebae94ec8f86d2d17a210857522e52fd105c60bc57517b19c24f4bdec8b0ef97bce40875b3562381e5fdf17079450a80703c28eec105f243689e0833ef00ae9f9029601b9029239cd7fa7537bfdfc5d0d6c64a11d5a625f0500f806f97282be398462ea61f373f3b649fbc13f9e3cf8922aa9ddb99c37685abba02e4e5694ad7690c40868b6fc3ea70dc26d8ccefb9faf48901bc5e4e6357ad2e24ef3932393898b9e294fbd01641136b1ca22e8f6b1a79a67329c97b620c96b50473a5ba0e263ba39f18882deb40dc6c0af6b91e294986e7a05158279a26cf24a84551cc642f26ad76638d44e9958a3524c1236992b72a5f0d942c3f54fe38dbf04ccb3c4d6e4ebfda1b2152c5d73e9ae11487199f6b71332b845f2f4262d0e39ff686f16411c6ee2729c91fcfc8ee96eb6e44bdb365b17938ab1489bf69e2e814335afa5ede67261142b9cb72501c5b11156e10b6e5c065e1f40dae8113e4b271989947e0259359024b2bcb2ef98bcb90fe232893dba942f88c9c7d85f9a0f5c4820df9374cd587e5477a920b8b9d9cc44f8a86cbf9c39af12cd20a19a081d6af1959bc40540829e3b3e2c834a15c58a1cc424256f08dfe409bfc27d9a132e1b051be3c8e04d96d26d8cd96b1fd93fe2208c6f9599b474837519292e9d4e6523d69f1d612660a5d9bc7c9f66f5e1307607e7ac4413a5471188cce670df3ca263a150515ceb7390ff2fbace3f9f5835291558f5e70ce3efe9aab22971f5e2adc4fe62609b25fa5ea4b8cff5758fa56150954d07277a0a236a4a8e0f3ef089d8a5dcf219ee775bd726f30440499c1643fa1813828ac121e3cdb4cb9536239cf053d32c0e5753bc6e63d23c165cddbb3b64b099596c503f9be7a59ef53231e558b53310efd7855d8eb8d93e5d390168106fd47da368ead18178d99c5767f0e32347598a634453be3035cb1c4a3373f5d5f028ba3a214c19c5b442a04dab949aa335a575ae60e95582c7ae400cabdf274c20583ef6ed98d4b2ad7d3a47e18f20f9029002b9028c3977d484c83fd1550bbd2bc23002d422bc6a56bfae7cd4ecee54cd28c12a4f7a3fc87303024ec6af5785875f34fde7b67b87f1ca08d3612bd2b785efb30239f79cf4bf992be2d8cdf26deec79c08053ffaaec2b498186da5bb51adfbea815dada7b1d5d8f2f9e14a9222a073d5fbf3bb424adcf899bdfef8a2cd1f967cd1f366adb266caad127b645a32e6d8360c838eb09aadeb3fb73574d82ed18a61cb245503a7f41155f94fdc2d90085875348fd402b02bde282e170b3344f197eaef7ab2eefa1d1ca25153d34b8b57236447634ddf53165a91baeabb2ce6e336d8d1e97cd8d6fdb388ac286d167711fafe7a2512fda441fcab2f72c90c565747378885da2042ebb21806bc4e5aeab64d579fe3b067bda7726010660e6f4a8cac5748f7298c6bde983cc64c70f17f0ca7c658a259fbb17c3f2fcf4b8e2ab9ac51fa964b185aa661138c77ecfea4639d0fc7bdafc509ccccb024ff2120f6abf38b449d32f2e4dcd682308c2958cef9219e691117e35ae44e199e42bcbb69cadc1d38e77a13c525dbb253d6680ebd1765ad98be331f08d4b2892bd1b965c84a69805028bf19edab2b06153de389f35c6285bf438130853b325de289121a4d112c158a17a391ec6af30a011649f2f5a5be98f1487c4d1a131a4e73ff9c4c78651925fd56633ab45ce71100852294ea04489c6e896e45df6553a91d651f6e95f45d35ef6e60d8a687c0f0b8b44f89605ce11578fe351821edf467330ac21b1b144f98c6a6537f0e29392ad90f7a5b15df3a94694f476f3b604864b303cc2c0944d8ea4691dd61b56b0e077e96ab3135221e7462d175089bc19f526d83e0373b8d8a4c8fdba347c9a0d8bdccec799ff6e8182cc65d697d718b24a2e298b2d31ca6c3f38d25be2c01087cef884998ffeed17502f9029403b9029039e86e2b0fa668fd00f8eb047e04b43e381c963c7c3b08438a92dd5b4c7c4dff26eb0052804e15caac3f450ce694a730cbd4a8931054c0c5ee30e49c43aeaf231c56516a7caac2d24f500358ced2f5b7585be2df1777ad9a11ce352e1d56b0fd693326ea8b348736ef0729999ac7dc72f92b6070896a487ce5295c96511fd36f539474899c5c41cbd61b1ff8c768abf197bff1642c71d5f2258458f445ab1e471a8b79487090a45eb5d0a234337657b35874d278d0a02534e8617258765e16f8fa23de176758645249728ace436b0db22fbf690bd687b5bbf0e7a0e661c48a1022e577a8f45abce209d6a0ce9a690b3fe3ee3370a7231266f953735e46a709326ad1ae57575ae969cc9497dbf329b76a56ced32105c94c9078e1e39748a31c24c9dfbbcad96d3215a2cff239f72cc651a42dd2c45259c6fe3a8d1e609e926a5da769a594f0d4e5ef98e6d31afc7b0b41b4c7dbde1e847318f9a25b71159c5741cc9db08f3c2d877e93ee3c915cdc3ced836d66462d85cb39abf4229162caed98acac0ec1a47ac9cacf8b59d1c2cd1b364c4b71154c97983dbb303a28d4ca168a44b4d76d2789d5e0eb8326c7e4b923f30041e2d1f182f56f7169b5dd17327a7f5ed9b1d837fab697386154b2cb2e7ce2b6242f608f2da89ba39e4012b86467b6895b920d115be513754f1cbed3ceafeb5fa07c0c5d3eb8e72174fe9a04c7dba22d9b4e85e049634518b641190f8f969ebde7b6ba8d8426897c4b713e6993e29575918d0a8b946ae07a7b8cf6c5ecdb52e8fbecec6cb0b830da4ee30c8b33aea62d7d7fe10671016a2671e62e7f17a5353b6edd83c9bed9fe5b6c5e66adfac4ba7ab51399825599ad0cfd11eb2019517696a16f7fb504f075938c22a4b34316ac252a9e5198cb38d38eea08751c999f1ef9029204b9028e39fe457edb7e5a43b614033f5a20e5acea11499db43e9bb0f36fc407416cf39115d423827b0de5dea7a682452eb9c29c7a7bcc99267b17a94a2e9c4fb1535ba90e8fa49d25052c8a73a5248b4fda83abbc956ef916994ed835a131a7bc38243cebdcd1594bc3203cb2a7e4fa5610d8a6491da4a8caab5d4f86d3e0537c86732b33f1543e88c1869976ee1eb4774481c3b457ea61493a527e96fae8e7a518848bab5034d72867a730ec958f1a9ab6abaeab6fb0658f2c193c4ea4978f03fb85c9e1fcd75bb449339db1dcf38285f68ce5211c4472181a4549644edba83667009aeb54ea14012ec514e26a9dd03555dd8f776502c19dcf3b9bb0d7b44e460c4fa8067ee6a3c0d5288a10cc23bb9cab2bc7e6b94c7afb2f79248976954efbe2215a938da36fc3fef676b06c337119956bd71b4910da1e4fe2dfa054f829cf5dbf651d434abfa31005058338281a8bb5b19409434ad3f45ce439156fb1fe9bfdca1693ee6bdef9531870670f04ddada12e3f9875f5e7c0a151a67f6cac453453b669c2eed18dc9fde0e4b8b184391b4ab07ec48251d5d6c76b58cddd0ed3ebff2aa8dbd1f8fa7d105fb7a9b9625a3176baa1e8bad3cce2999e035881585dcd4f53bd277db45fca26419b50ac9ea2908d6b58a4a98223fdbd0e408921d2b1345b6039073e4fc88022cd31cd5d1a66bdccce8e1555ea7b6d985e4a70c56076593bc3dd0152f22c5f17a0c9b98917ab4fda9ac7a25a9742ebb13fb546093f5a676eca338f8fd0a79f4a160123cc318a196f8ebd0d56cf90c3e550febc411ecd2d936852a450a94625a2e3a45bb3af4b368b6c0b066fa1a38489703536e9d6a23eaeef114a44ae8a5c4d6eb0b49a68a1174f968801868ce55166826ea865abf33cf7245137497a69bdad79d43cddad9d2dc8f9028e05b9028a3937ae9948420714cd47246c430a7e02c2b5b5405f6e0592a9a66fa81b782625d32728107f49307193387a3d1dbace87ff3b40236fa209ac6c2efdcaf272e0c239b11aeedbff9cfb2914093b2eb45ae1716b7e1d802408fe8304f531594ca3692fa49b8c6d9e00e7d1a0c451bcd3a7ca516aad6e90d60f466c19e99f959dbdf5c985b0c3230696bbf7e8a65144fd6054a4de2c255cdd7bae517f9c1a00538cb66f51f4ec38db787eae919825febfcc67b62d5daa23bfb9fdb66b62bf694e5bc86c6de9c210673512e1537ac6e23f83451f9f069a0da7fcfaa2a51d157920481e6231da3d29eeaf8ff1faf8b8b4377589dbae6640a0717c452ae6c44de44e831525cb457d5aa488b5e1fd4b3e2e66ab78396cea81b498a78837abad98231e57f541c9e699c54d08dbd7ab5894fa8b851d5b25b50dcb4027096bf9d2b4c5a66cb387fc9e6a774d3aa345fb52486d0a1ad325faf84332c72d75ba6b2a55a2fbf867535cf53c1fdba9fc8ea30f5dbad194f5215a24bfc68d5c49a44f47c0a331f9fa6e44833e2a9471954a310e579c7520acb13f9ce3f206d9d7b3ea9f474b44add7f9f6ccf655d9f363d7055dab90f4780669194b9e0d6714b5d1bf8775d259bbcda442d34c4bd1b87371265426c96b35aaa1b2b8c469edb02157c769d9ea2912027500df2a6ed8c37ab1b6a9133e281484ff50450874db9d2d4b185863bebb6c9416f0b3edf6add4dd16efcc637857674cda4f95e9db0b3d50516a2644c7fb336a1988d57288dfaf9a99f07d5018763d7f8360a63f02af43e561cd369a9f0486230e4cafdda784bd995e0f1d22653e79ccd70567ce2dbed9a462faf06f3b3f7faa328276e1d6cdba30cc188a3a53596a3553dabb31f8be3618c7193d8a7be64b3b6892e558bb0e813fd4c0f9029006b9028c393f88e830c39d4baa9a41e2c604c1311b075416e8762a0bf1107ba3408fb0dae1c5b186b19f553fe47dffe5dc92d3a5e799cf2251b89a981becd6c2add1e61dbcbe49ec4ae438394e4a2c8f7e3669373bf0903355989425a04d9b47f73e947635591769fd486152b680ca9189ee6d857e99557607e625c629dc891417ea0759ef320b05af0ba049b0f4c503e3b94cbb1929a517038f72e6b7aa7d4b1b1188dd16e765bc393109fee483e9559c37861363c54a51d6f738cbfde829a966991b595a8066797a3174c96f219f2cc21549870d9bbf8386c75035efa5ab94b0cc799e7b7df24ec7d8cc3548c7cf27964d4bf462bd9acc2232e9662a65c0f2cf3391d624cdb2d26739a745e47cccc8d7121ca674cbdd656823dedc31486110f448cf69f8c4e2e231f35346a04a3e18a492518d93b538ade68385d47ebc91ee3a83ef874a0de106f82206e60826ae6589f43319f642d28c0d9a388b232666e130df2fc7a9f788f0899e20ca51082bbfb970dd78fc3147741d84efb6db5cea594d9f0aeead103a1922464c1c7f9b6841aa7b74e16fb08c932a5c5fb35d8acdeea43db9614cf436f3048914eac35b370f5b0984bc69c5c5ead9a69037ea464eb66df437fce8c87b28838a57f5fb880b70789faa0c097e8c989389badf16be171acdd0dd305c0428f7ddf239fe34bd91f33279a80e5a71d13790889a8f09cdd27c76d6ca48c012f24b6bedf4f1e64584398cfcf11686d171ab3e2490b49a7f2dbbc7d4a4c823e99c65a94306495c43f7ec7a5719a727f65fa14c26c92bd3083fb1bf0e938db5675839a453b1d2d95fa2dc1e1914476557dd7d1a09baa94c9add4a6d549d7fe89e06410349d19e86afd18699b494fb2c6257bc4dd1a8e22889a48b860b6370c3f4a056794ad35672787e38f9029107b9028d39d4ffee7aadbfec8a00f1e2b60fdb7928e2a802835798b2def1f7f3a11d7f8b0d80bad32e0b47c8459ca55a67d29758e29b568a9343bdc11195afc59ef8eb88b795dfe77b359e4f88458da7c68b9d83674867bf5c35cd440ed73c58a17c7f5de9053099f2ed122bbaa967d1299df7504c49b944b2f16b51ac9ae89ce44d29cdc672cb0ae74d8ec999e8e9726576de8ffabbe336ae2910e3ee3ed055a73b1f88b091615d4922dd74e203f493145594fe34cd5bdc365937ce3106c29885778930fbca36717824724c21777c98d0c11887658d22eb9a8e9f549558ec19578f8ff48dfaf74ae9c9db69abbae52386085e39e7ea2af1fa5a0e2e22854e264f2e9f1a512e8d1200aa6dcf27a723b55e5422172458573d0bb9afbb6510121c9459d02719576d250823e24971e9dc23b59dddd3a61d5f3cc84504a8c55af07849bdc2fb13735fdc3a1c84fa379abdd1bd67362c78c14ecd479a7ef5f43f966438d457a71539c2cfcb819d9ca3fbe7375539aa88f8464701cdb8cbe650b8bb968d9f43a32d44fdb2a40bc3164c90ae77c6869d10a4ebd5ee4bd0a4ff91042904f0c66b7c25c61a8923110ebd2d01166bd6b2498ca6c297c8340af15c83df8854379be57969d2191442b9ebcd4c7ccfbd558a8cb97f84bf21bd8cfaff967f3a1b06906415f9d4eff9c761989c26ca15c3a0d2615d55ff42c34666495a8f6eff3184c0edcdad6cf4156e41a1068fcf80674da5456b975a5a4ad4925d23821a24b89beca27668bcd1976631d41d1ac1e35a6395f99cf9c16ff64b1c2231efa0efd1d686b90437f0bbf934d8cad4970fcd07806c7389c4cb25b2dc0e551d85e6435ba7bddac5670c5a3d53ce524f1b7f428eb041f8712110674bad7ddd63935f52a28a4a09c22b11ac671b675dc1e940551ff4",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xc4e26a3c98e603142d0a7704dd7c0e1a2c8015c7f15d19912d59a7a941a9a2a6",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xb5e768cb3117ea25175f51aa956b48691025c2a8",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xf46410",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x9857a675d7c45f63634616001ee98ab5e78db7dde042c22e6bfaa4ac9e0d9560",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xbf1bbefa9421eb446f96e19a5f2ec100aae53432696d2171487ab025725c6275",
|
|
+ "timestamp": "0x6a91905b",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-B-9chei-anchor-16016400-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e382d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841f5ceba038bbeafa193f1dc179a0485dd4a611f5feebba5c41aaa48d18b3f2d6673072a1a503382a9e14394b252b3053494956e005da88f31366378513d2e2a1d00b841ceb9045b247e7497f606ccc7ec2c2ace9046741b32634d3c284a8df9009dc76b219f550088270ad034f8743023f1917a1c40c5ed1dd06e9ed39aa05c97881f5b00b841a3d58f6a79855bce0caa71cf46bcf21c8d00bb347b1273ee06855a450a0dde916a5b1c11c443d162b66c95b347af20f2a2e3da920d873c29b41d33eff9f64e0a00b8415a0af76d14753e0e9fb69115884e69ed27f8e0ccbb2a6ed9ab0ed299ea5838fb15450517608650f7d4d516ecde066c95db05b774459f0e03038f1aff4c7c470a00b841ca903e2864fa6a8117e1896af03bebd344f0c904c24e5ffcc2ff1c4db8eaf1f45fed578c98b4f76d9b744c4d2dc1b3104c8838b26ab5c85c41d53e815a35477000b841f5fc13ac57f41e36f56e7873c67cf0748731eb3a069fc67de658495c55dc737c303807f4c22799e9668d3b3c2efc976b484287435945e2d3900ecaf04a319d3b01",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x8e7c223b570d639add93fda6bbd446f3a96054cfbeba3fa09fdb2d442435b6e4",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xe13aa491abbc1252dd714e7ca0e55717a2143eaf",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xf4a40f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x03cc975a2cd114dce303c710b4a5a632b393109a3b309364baf35a1ce8efb39e",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x1e344a4459c45b1fd959041ba9a649a236e86b39b58249f9d3f2f522f0583ad4",
|
|
+ "timestamp": "0x6a91b479",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf919c7a050d9deaf019e1223dd23beb477abda0156dd1e8c25f761fba28e1847f539fee8f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841664ef94e288c42919224a1706c5cdff952b258101a79bce808843c494b6e2bf36166b1302eafdb3390ef5a7a2b5add104c5adaa54a4563ad5b8ee698ac60fc4b00b841f504b6648a6008e416b1c4ca969450c3eee73358d55a0216babca36b06da0c4428c5d5ab16ac458d34ed3237803c09ee7813dfea757c502074e27f037f574da800b841f3467b74a021cff4f85e91c1451954906915d06e1f2c65994dbc21cc39f580a52e5ea240c0c469375935bf714ebea2a0ebacefcb50268638b09e07a7fb55abbc00b841010813d20bd2a32a885afd93faeb81fb8b702ff2ab261285fba206a821be71b36c598a386244137bf6c08a6d6244b0df64ca30269dc76c3b5a32ceff555e74b600b84196090147d79c8727de7ab8ed6a3b93d109228b275d3ee46bd8dc9409495a569575022d81151292b0bbdec96e301593a5215e6879e3d69c7471fbafb143b8100400b841087b0cc132d6f48846fc44dda0ddac0f4f222d33a992439195c681e611ee74972b90ee22b7a6eb29441a1207e282bfd302f522b01d2c23f9af5961ee1f28f48c00f9174df9029580b90291399a4d9d4ca2092963a7a101b6658e4665936ace203cdce8c3076fc6c64bffa4f8de328053a2e48d6f81f3e059facb726b527983b4a2c932182811d6434ef77e3284ca3550ed9685e0df296f6687bc6d48844f1729415a0cca0920d2e60e2a7fbe74f50bc3878b1e38e29efcf783f53e97b08a46579d2850a4908ace2ffedee9fc8e0c1d8e90a5e8a309dd8b72d5369bab1a6b7091adc973273ea505e6a73368a95ea3cb6693a3df797663c88a178d6a2c93b7ef809ccc47477a80e115620f36c2e7c992d9de76045092d15c84052fb27e33ab93102d133451c89827250f1e81e83033bb4afbf59a6de1a949903632582d8dbc99cff0d0fc688af221162ab9da5de857bd2ee74f0af2445cf38b74c54a56bb050b837bc09526f2e0b9ad2b1efe08438f8a59cd1094366c551558820f3a58919ace5d2551074ca2701a4af3d38958198879eca5de927a64ceecc145488e2e595e8c4d1c7ca210e62f59834d0992f2e76de9737a74f0927dc859d64d5501a38f3cfb75a13b1962cd354d6692ecddd24fb7bb2887c340ca9a1512933a94644a2469a1b2b857a46395d0dbfda2c6099e667742e6bc33f3dc6b988d9acaf7553748e58f97b6967452f62d2f58ad0dbdad847e75778a5d2e089e3a099795dfd26b3f083c479a40963429f0e822f51a19b742745fdd2a3e767f7cf9ea3728964fbf9d3245ea9dd42d2c21b8d81a6b87c6308bb7d2cb62d5604e270e0b8d6891d670c5456ddee515ac890b62f021c48fabfb8d1b977d664c4d9e6b212214a6dbd5e6f4c48819c152a0c55116dce6372ed42c8c5571540a52f0ae298ebeadd1d17a39065616c14213224da4e866f7eb9154223dc9ded0dbd0b0c899c34d2bd8bc3c96bb4eb84b0bce32e3ade2997a3f3d9a77d1245195890c39345ba44bb218e374a0f9029301b9028f397de9704bda0824ad463262d509dddbc1ea70771b74ba84b351bc4f7d99ce3be42927557dd54691b0cf6dff061238c3ed1a5e765f26bbbcfaa20853b616a28160de25d0428d24e951f71a8495a5b2dfe8bcebfee1b33366424c5931333dc40f907459b6e93d8792423841b527174f9bb9679015b99b6770e4c3b90635bf561aded4aafafadd211ed585b6250f5fb13c244ca67fd06325cb60e27dffa4e1bf5f2214ea892d24329e2b63e06e89e4bb63a2b6d360da9aef2920f6f4263cf92f2e39fbe375fb4dd792af3b621128aa8061e6d93711dc7f1a74438895aa3344189927793253d0669dd8f7773cfa2bf5243d74aa4de33494d4c515046385a7e321e2c18f401776160ae94ea0749caf6d9f6475f2649517655c6d146c90b5c7c7314d4e68e7b560f77ee3acbabce6709a9e54698699984322972ded2a5e856d21e332f0219d6b077a303b759932073182273577629b91d064ecab2a5385973af54a46cb40f3509537d7d9d070ae4c9d8cdd409f8a6508891a5c5fd4884f3773e461c7e0561fcc9ddabd37f1185565335356064e03d3432084b4fb32ab876242deb411fcfaf3fb7c263eb8252f190077feb19bac0cbdcee391b5e6f7f55122d816311b4629edafb1b1fd4409ab999fce2588b7a126a097346ce06a0a5dc9fa4f98e9cb3b52b04bf044fb7b9780c19bbe4acab6aa9b3b84021cd947c5e3354189246bcbe89df299b4448455b279370f0b5ccba24ea1b26c2f3a75bff9708aa10ed3c51656910eeaadbac674dec9df1313a1c977537446d684b3f5cb3f564ddbc2455c9218fbc4a6abcbcf2832e4035ed7b83b557a8dbf6f442a7aeb6198bc6ec684354eaf5a9ca4115104803c69da9b2946b31a2df9c05054dd94bf4abbc0fc3b9730f0dfa64e27712b74a66487ea6835657af9029402b90290399f6d95d387e6497ec658912e0f7860f8cf834676221e8a84d13bd81b2a6c614149c45af23e27557e365db84ecb149d36c9a4e138a51d42ff445c31f1aa5e47628be0f13fcc7abde5ac6b7ebd1cb43166cc5270ae1a78df239323212c621f22b9a4407630ff195e886af9bd15cb6f1afcacba9b7e3197c8f3fb390945721b5ef5335d85bf0e4647854acc049a428cdca484c24eb6b2c2f98a5d0be44602d2232dd512e2d4b7526ee51773077179141cbd0a7d79ed4d67ebdbd357f8babbb68ad6dd7e23cff6337dbac3e937083c371ac971112f6f226bca62fdcafd5b4621525412a111901d9c2d6a9e50a3e8ba0f999ae53cf902827acdee3d0725736ac66e02c5b9340671caa8aed63d956b227a1c5982b0cbcf3c5293faa64ed5ba07fa8ec298c58710e6f126044a098145ddaeaffa5fbea81bebc9c65ba748dcbbba99fd7f10c67ac1f59be4d784629cc2bed57e7e6bf9a6795a55c9d670a87bf1a0e8bdbe5be234e76cfab6fabd3260cf665e549182499d4cc32cdd4651463045635f88eba8c85e198ebda935cf782b290b58ce4c9d8c7a08c4b62efdaa77b96a247dd70b299436ce42d8d04f46137dd79418d2f5bad0c6ee09922e2453b3e2830cbb2c8291e95eaa5f6343d857320e371d014c6c82eeb49a4f12889a22d87a0abbf0499af6a70cc2b07ab9fb065b198b4987c039c95e970a61681d069983664eeb36bfed3b68cb4c842cab56dd29615bdc4d66cda9c10a22984f112c5b3ac6c2d32496d2f5fc8a476f6ac294b43f852177a7ef9eaa08c644e7c9f403c83c9907c64f50b03b75ac6b8d4d281f2259e287fea7a50dc9dc3a1a7cb3f71178f96997a633e7ccc6af9ed62e1c7cb3adb872baae173abf13a4795c5cef8348ffb984413bdb0d3c969eaf6f3f3164e90a631707df8c80f9029503b902913960a471454a2b2a8fab4aa5e35ba0f07183c09eabb5cd319e3355ab8f4941f36b717c82fb7766d56b128fa6bb87795bcd4a0c3ec5ca236733808b612c04ead8b2c819f7253b94269e4e85de0b902323d5852c1b2e9f0d14e7e557b891f0c799c55199a5f0f190fb0984f3e0b184923b25e79d3862878f78cc428f86619af9ec6d60e0b050d8bb3daaa07122573a7fe36ebf3873f5e7efa0f25e567299c2c852b14b588f67335608974330e16fdc266b17ca82c92cf7e41f2bb583eeea2d07c8f7f2a4ede7fa4fbb450dc9fb56ea4c1a87f5eece9cfda9817055c3e192487344e4cd5e93add4926a40edbd5229847b56bc2b4c5d11eb0d8b269266a8d4341231df1424d9b6a7e9ead188ba6eda1205dfc19a538c73397056bb9cde3a0a31721441ff88200ed678a51cfd5eb94851ac74134364d255e7f2db932f14d1a9fc190b9b63456c53eb35b9f2816e77bef8f8b96d56ee07e4a8dedf021d61320e9abdc258b3c705189521590a129dc1744b75fa457eefdcf0a32384fcddf06ff66b60f3923f5451e28527982746c6cf4ef1f5f8b127829c7585beeecebaa65de5647847b93b2228625b35c83e18efde5094409c5e325533344a2db61d327a537646eaddc6d7fd6c719d7aeaedad412a6d09a943987e64b48213a161b0cfec74873adccd32482b155e08ecbc6c74590ee9cb61be3f1b439592b166a5a92663838f23bf41092ef8698ad72761cdae11e84111b3308325f36f9da21d085d639f561ce8b35ed1987cd1e2612de765192d6d023e21c7821068e54adac9dfa3579006eac71e60f88c5d2181ab7863d6da1deb359dbb0dc10f9553630f241b16eeebaad2251ce2781c2ebf2d843cee8f3c85279a3b5605b54c1dbd40a3136a04dac7933316ad9e9fa71868ce84a9d0863930af5d6da98340f9029304b9028f3981c7fbf6c057a764a1556c276a36ace9cc5b9b57ec3dd5821df4249ebf6c013c77255557dd32a2af4c7fe470144af9f8c40f64a48b4570268dc66e6544fd3f645f3448be2a5e564a213964f2cf57ded93176f46c7b3ab948e808197c458fb1599b5bb2fcc3658189df702f1e0626c36448699bf075f514657f3aaa264e693fff3dfbbeece1895b4a3f46369e3c634778a75713becc6283bec655bf9c0def1d1b53ee98bfdec2393eb13b244733eacbc1e7a6504f7f1eb751ed83dd79660c315c0f8fb59ac73a1bc4779d81b2f1b3192e7d01a77824eaef2d07e05bfb1284023a92b7ed14965ca8a52fb8aca0bb91ac3157de769669e5c426adbe85bda6a3cc9cf7ee86ddaeed86bb874293b249bd83dd1f84cb1e759128c8a666baa31c3599fab3fade24242a0f8d2c1b8709ad78af7806863a78163cea24a691430f2b699facd6a3bd8bf0aeb20b05790096669894ca1d1c5839294a18a44290dc4308709c54471245da6397ce8fae367fa97a8ba084c0cba952267cc0cf54c681fdd224d01a53a9838667f486f4b27cdbd8f989b647ebcd5201b078d0c5b279fa2d368b6475feeaf17368c9854bb064a78eb6c318442d51ab1a8a53ff09fca1465c44ca74167fc18d212f2a2c984e58e58a1263dc0a1a170ed03493fea4215322985e577fa304609d4bf32a91ed39db7f3f23d0e9314e26af2ebd636f504d7ba75b5da31ce5cd33f74c5b59264224a913b25fa483a815051f73bb65d58b2b4bf4d189bef893add0c6c67c86d47c4d659d944d23aa2a8df8738e87bb94f3e31579aeb3e1adcfa1b777d05abe9006625a8526d2560de630c5563961e419b72703e2eeeb3c4c8f1e4a7b3eb8ff1b49538a4f6bddb4a739f2a6e08e076a8b1da340feb9637af05cf25654cc93abf163f4e0a0d0c636f9029605b90292393068609b369c894ee7d018211365de02075271d79829e796431d3c541aaabbba57547b0e013f0cf9765cde9acf1b559b363c44fba6b3d4094aaebbc99fd511b51d4f975b5724548c7208b9c0e5a4e746dec6fa5bf74f0cfb312d5272d4b3ee977d90ee2854f91a0787132681e75750759b409f6cb0905aa599a5a2926992c824d9357a6794669dc9ab1ae0e89d791a77dbdd67cbfe767aefc44f1afbfbfd78738dcb71ef8f58be2a877999cf64b264e3274ba5fb9af3726b74940891f184189802e9ac492385678577d5e77714bfda20af7270650a171f6ea82fcfee12c18f46b4b2b849dcb34372c7feaad1a26549a970cbb22ff1a9f45c2f358ccac608c907b8d46d36c8cad3261c64838ad268206a4ad68b692a16385b526d3585c784b31a44badb0cd86f920d6f028f50e8c40620fc68bb1aab9c553d29d9788de9012bae9e5da1a7c382086bb1fd595e888c74dbb8d591a3409407ba08c1261c80b1e863c6e4d42219eac5ee3e414f5b24cd5575d30d0a568d2a79e40211c998c7f218657bab233370844d9dc76dc749837fab3d95dad79d334cb90cc6d9fb92b74e5f994df7bdf9da3e61190d85333731dca59aa5eff196de70c8f63df9a73615c69151f1cbd9a85a29ebde423d6e3b403ccd7e7e6efb74aaca061f4a862d3f9e4b471e91f7c6a3de7822c55041c30b41ffe1a44fe08d3313b8b4a0f8f6d584255c3c347922488d466fbadcecc2f6572cdace92117371670ae691016a905409229664c9a6d55d64e5499ced66ab6d1ff3705ba43cd260c9cd5ee408ce62220e564c6a67d03b9d58f73774448cb0dd720e4eb7eacab43afe0a1ba3b6b8b21a1ef144d937f3266bdac4d3d40ab1484492e859ff7a53324bbe93b6ebee27cbadde46ce72daf52399d414c53267fd4c7331ed696385a0f9029306b9028f394b6340a93a6e056aedbf847a8240c8f8e7b253d63b73c504596ed6dfd879c95ce5e01eaf43b9a567dee341fc860ddc658d6041e877a5252278cd5d7b4074f03a742d614fbdff0aaba4ee9639a9e965d09278f746995b5d56bedc53a52dbe8bcb8f679c73249428e96516e3fcbea3546d122d6d9b382cfbaaadc070708a7511043c8b7c16e7258dbfdd94631a91b16cbfc1e08d43d56d7d833e6c5654e563849b27408f34909437e1eb625348b2417374772dcc42998d5c20a6208041fc18b60abca5c04f0bc29ffd6434190884c509cd2b53bfc4ac76ff43819196a9884335bcb322c490c9e775ad9ce1a14aa3053b99d683f3e7329e12cc88e8753fcb34404a538a13d9f552d6174bd248326dc6beb299612ed5e7790e151f3d3a05cdde5f10e6e4c1dff32a3deb80837917dddc2dc9a0e65202f03de96dbdac881bb50775abc42aad3f2f7525f3b45bea8aef1c4b9f278a613968988c74cf5d86dcf6a25db9bd1f652766d68d7b52c0ad5ac4da7f2f600f84e7374483a51ed9839ed6ee60c5f38f86a85779a953eb058cf811ec135b0ba0499138f2b0a6fa5395bd002215e5fb7ac4ea4c4981fcaf2f6928785fc66f06894a124c99f44970eb7f920cc1231ff4b61cc4ac6c776202846d7b9a5e3e93bbd0251e8276d0d6b626ba4fd665499a1797bee0aa980746a6ac3c4c53bf6ee710bbf6f0f17ba2246d40b6c9e576cf096d83d19a2ddcf2f7936ea3ec1cd5458cbbcc4b6b8fd6b3eb4a20d98d6ebcdc7372e1b64652750578c8e656cef44cfaa4b8cc2b3ceef095c495997438693f1344d127ad9c355bc8ee527edc2c8598e8609237521296efeeb6abfc108160eac957d6e8bd27528453eb21cdd3ac14030d833b98ec975705b440a85b55f0b66626f094cf8a59d64811e8a1ba3f7aed2af9029307b9028f396526116f66ea5bbf787465685356f80888538533d0675424a70a51c0af0bd76205ff60c9d7052de6d37de2bea7aaf7d5cc116bd4c62339d8e5ac4d790ca4e1a0e80469dd9545da0f13ce4fbb087da885888c378f38cc4ab08323205292038042ab9098d8f77d235d1ec9262ed85f4c79ee87e650b97aa94280c233b47a0cf4cc2a055167506cb63505424b15cb83ff71ea542f951cfc7ed4f9e39624088dedba8e7cb3276084eb30c8c24c94d7b22a3337ed65b0296d153b518ad3bda89b4cd355ce7531564e3419c3ab2c04bbde9431d68ebed2f572569013dd4dd98a0b6305cd913d9ede125eb693c856cdc7c02632c538de1a7a9ecbc92bbc50740a74e1163e72254f23f4412b9c9419dfbf4ce1e86e1b4f6173c476aa943211824eddfefcf2f902608a4e5844e56654b4e91fb7c1116bddce33a276b8be5cbb4ac791d287acfaf16275746bd11466a1a8d7bc8f442baead72c1915ed35a3236c9a38c3b3375caaaddaf3e25335662fd2d8682842aa415b0cd9952251a99244e66932ce8406191379372987cb39ad30a78597fcc0b8f8bfc77517626708d63adda7af96e61bfb0471739e0752fda99635f037e982d09cc8925f36db789cc6cfb6dd9ba80629cfdff2d66d9a58b2b8ba59aab266a1943daa1587923531ff2f3dc55b59f64e408e5ffbff12d119b236a9a9c2fc666708ab64e814d7f3d8aea1ef9bbc4c501965cb5276849119743c19a275de6379cf4a67a4e82e51c440432ddea6d96c76675644deaae441ebf4cafd22ba8f2beda54b51e8cd3cbc2aaa08d877a2b3891d5fd59272d15ef96f12f348537a7784e1bb518fab891f64b50f0947e62eb0372fd79649b344234b3a88b24c29e6498c4b45855b47fa7dcbf842239779e498e2efb7d7a7a20fd5d7ec9452d6befdf2680f9029208b9028e3999754bbd3782463e1f854440289bb117192e261529e360a589f554bb47993c96e6ce3e842ab802b3afa821f55bd8e0bf3cdd253bac6d486a9f7f82f1de4e1d71e59f479bfbc5fe8cb4ec26f9f90f59cdf0b89db8d2d948dc2190045900da19e9b77b0259ed71e3c7442e16b35597976ebb8d12e94454cb7c426bd7d03dc62db274b71ef8c3925f280c0ce14c1cf3f2abc17df8efb747b7d4e1e977a9afbd31889ed40545fe92226d973022cb9ef43dcb2e8f0335d528f98f020525252a27f2992abaefbb6c32b7d3ee282b84d7319ea8ec27da8fed9b1b2751517212923142ddbdf4d0f66f6f066b33c532594efbf5faa0cd3bfc1ce1a3519b727567b45e4bafdca0789767571ecfa16416b7e3967e9638d6bd2bdc758f9f69afc023aafd6eafbe9625586778ccfbfd100cd2f6dbc659eca779354ee34e1c29d7aff8d13f498912281af737e7db58f922c3438066511b5d3878676afae79dd6e538ec022ec85c9d3809215f4dd942b1e8f16aa444710f1965f9acff8a3212e3e8652fa260405baf8e6f7081f69b95827befdfa69e1dac0cdae40e243b6c579494dd7a32a53e9c869cb9aabba8e4a18d25c67d848862b570bcaa02fee80a46774481264915889fe15bde33db5239ff0b6b6add23e6531aafd4eb247bc0f0f86af6de29798a4650210b6572b4a9f604adf81bec7cfa73fc85384d191e32959429c3b1b68a5a9d71aed598022894e5f9ee82a9886f5ee57787f271b0875bc3a4e7e57e2c815daaea0beef36af767721d22779de7c07b6f2d458eff7b9a74e99550387c8d0cb665c8d9769cab064965bac6b162425170771ab3694c9e421859b2cb709335eddabd96c6cad12a356db18e2399cc2fc240bb669b7a1bb9d346b2ed8e550771d09bdcf3cd0d7e2b83a8ca242d5eba1c80",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xd59fa9ea974ebd60dc96ab9afd71ad42ac2695801c9845d2d2e2b37925388712",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xf73bbbd26a82dbc769066550d8d4585eab2fc00d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xf4a410",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x8e7c223b570d639add93fda6bbd446f3a96054cfbeba3fa09fdb2d442435b6e4",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x249eca70633247f122a1739c1baf3a076f0514c8ea2a81b0ca970b3d08f07ae5",
|
|
+ "timestamp": "0x6a91b47a",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-B-9chei-anchor-16032784-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e382d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8416baf776cfc441d94c0623eb85fcc1a33e446b5b2f968a31ef7449eb69110fa222ed5bf45bfb84d181f8a01fffdc41f4c854353fb3be6826a360eb35b295fcb8c00b8418b7423dbd8960ff0649aceead988da18824a775da258d6626c99435ba6deed5517cd9bbb56ee695766927cfbc01c8181de7eb189032c5a12102412772348a5b700b84151493a7d9018e5a6f04a645bdc2309c8e4917c946ab3c00c0745ccb78812d9bb27bf5db1a0bc9954a2d0aa75044e4902a40480b602c31e3f81b27b6b069ec54401b841d364a7e45b5771c4a24cc87c9e15a4f9878b857dbaa0d4c468aa331620575c883af00c54106a98c11e6b7fc90ad57c95b14e6749dfe42b7571db761d56bf695b01b8412470cb2e7cbce9e47043c0fc8962debedcf1cc61ea9576f5bddf3444ca96855b4a2adbeea199ab82d9efbcdc8795a66f78df00d8bd959d116d0dec2f730f8e2700b8417fbbbf957e8d0b0ae5bfe469da51c76f8c9385af6058b118fac22c6d99f845fe41947207642c0001b5ff5c35720904f1fee2f937c40da8b8409d05e51d1c42dc00",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xc9d610bc077dd2cff3f54604cdefe04e2353b4bbd92e146576e8107e30c7ad19",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x5f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb0",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xf4e40f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x664229281314fefc4fee2090cec5dd4276d0d77f516d2dbcf9b52bc9a44aac74",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xfef3ee370c8a8753286685129edb58aaa665b6c41f70bab6a25baf84a559ca18",
|
|
+ "timestamp": "0x6a91d885",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf91730a09b7e2a1bc84653c04d66871eee97bbdad4d880d9d6beac5c23ce067a697bbbf1f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8415afa53022146871cddd7c9d6fd7a0502870232b35823fb305969332ec18243c73d912fe120cd2d726ad59178d685cbeb62aea9a828dd45ff040c6bf1210e5ac001b841cd1dd58a3144dfa35d96f87c7332665919f2a4c014934f6a0027dcab5c9ce7b7570dbafde6887ef7280cca386d19e857982f2f25b18eae067fd5f4a7773178af00b8411b407035379ece4e921e27cf55e86057fef4fef301155e52c145a5c940523143315be6ba3b29f54f6738df1db33760f57af5e5333007ebf3ac3c949d0ecfde9d01b8414eeb145df8550800f358b82e8094dff6fb81f717fe8e90a9c60b62c2b448f19614ebe7863b658443247f3334a91633d9218db33e977ac22349d41539c0fdbfde01b841e0e9f356d08676ef1aa5b3a4fd110d12ac3604275ccdb97cd643bfefff6618772a5f3b9c51d4ab7e512e5061f31af7adfd995719ec7b6dad56bb8f566ea6bb9a01b84159430bed44a1f04acdf28b4dacd7eaffd29864af06307cc62ef36db60e39c0b219dc15e19860634a4a527d6a3088f872b70c5262c96a3e641dcd53833b7f3d4501f914b6f9029480b9029039f9e60538035a2f9796ffb03102f01c5bcfe0fd5a0619bb2f2bba826b2a2da766813b71348521b28d87222833378624fbf22cd73b38b3a7213d579744b2a0ddfd6f53eae6e4f0fcb94f0549af742f7638e284481ed8aa8e822586a3d451c8110df7ad1bd503112969958e6ee8ac409fe9fd3799715a9a58131756f36eee5dccbc4a56cc78d021cdf2ece6cd7e792e244dd593a19fec6cf8b8a9afd309223df48bca631ec94106015289fe62ed55798183402373de7421bb42e8d427174749feb624649ea55c9790c9181cd9e7d4c58a09b966c8af159ee4f16ad623b4f3b0877b1d99f9277d3e044f2afc6661573c643d2024d3f1cb5593792b71ed6e78fbbd56c50ca7268d224ec475ea3b2ba1ab6494ba6a3255138da4adae74356c6a635eb171f56cf2988425d9ca53ebbeb03ca9e6dc5c355d8428e45646dd41260572c8b04557357bc12d5b900519c972dc84b58a7c4e0a28e4382a5b173667bbfeb7bda8b466d12484aa6fb4b43962cbf8d22f7b52d927b953208eaccd05311065ed903b463503731864cb145b354dc6c9fd409aaa34e38490ae7172543ef746462f989038fdaeb6099a4fb85c5f046134bc6f0cf3b8bce923f33d913c8dfc509d0beb65c0267eb8da3ad9254cf5237dfec1a199d6289264d67b4916201e1215b229b6770dfb42a9fd85488235af6e35cf9eabbdd5de03ac5e5fc25b3545399a19b1daaf3b8d714a885c78f8f6918911c7f6a28e67db5401587f71d2523b2f8788853d0ca2a094e9beba1828b3ae24390437e55bc5278ca5ef346a7088e45b830df5a2fabcf12c72e49f6c66d0fa3b458e7354bc752d99e42adc77d9f473268663d9ddd078b28ae5328b70a37e3efc4ac55528dc2c7f19641e24ed5ef756ac464653345e530196cfc9779165c19e91a6dfd994f9029501b90291393abf3c4cec397f05ba05cae9e58b6565331af3d7118fda145350c2c99b014c500346fd21ffcedf03895e90460ad535e3a227a76fa66da0cb7a145539c9332e9fa0052e16e7449876a857cccd3953f3fce31c04690d36848755c984885d25ad5b69ea6e20cafc30c9824ade4ca191d8a671bd6d483fa6f9f1fba3ca7dee35f1bc5f4f95ed2938ed2c038857fe7feb319bc42a6ae7b15d79b943812981a139034cd734fc26e9f8369ddc7334e2c21d97f27e90abb41faef2aac02c88426fd1d79189ae0d40580d4a6ca9c0de8875c76dd74b1b1b04a319eec6907c2b9b068e587eea611046b0c9f3a2f632c89c1603769417b768899019fc2fb7c75011f9e41f586d16682e4b9f86fa409af839e23324de76d7a1348b5e7ba3f3946b3986bfb8d7c55ce8232dd9d99359a16a88600a5e45eee0c492b9ba2a62d312657afb49cfc2f7cafeba248ce5ff90379902935512b16f3df4ff443389f5431a0ef4e6910767213aab61261069e41d0d700e81e13988211b7a554f144b7ec311e9bbdefae71b6887c4ad210fef38cdfc775cd855f1857b318be5b63db8f2421927e10a94ceeabd3b8c20806535e5dd0cd040da0bf2fd05c736ac8225958feaf024ad0e6b0dc161d9b4ef1645abf92a4b6b09dcc4d5cfd5c7d9a0208d0ecbc7e397f2e1bc874205be8da96aedff50e5e3a2901d664d4f8ae8fc343485bbe932be8d2c59ca268ecb0334c3d7ebf0a4408247db16cf1479dbc6bd28e9a40ad652bac3eba564ed06a12ecf36660a6ea9e831779f43f578b6d36904fbead9d62d9e8dc9b4864d10ebd1096a02622b1c0e3b2e5add1abbe2803d2d67758750362b43006a367a6abd3a8fe553b026cd36ccde163c92376a806474156d5a8c7e7d2e53759edf20d49fc15962546ae643988066d69c398bdd35c8f9029302b9028f398cf0e752dd570856fd9a6d5aa28292543e958609ffb998c435cad0b7b36adecb94a7c996f284301046e864668ddac3c168cc4e4d68403d4cf087f93204bfc899465e45836dccdcbe32e9be102349161574f6d091e4084999950aeaa4febd8fc63636304974513a3e70223a55d602f2c93f77dedd021786954921f167975f4c5de248496b28bb0f7232c4af672fbe83dd398be1437ffc2e6724835d9b4e46b12f6237beca364cc24371b5d3872e8130b035848db66dced227d376a62ce542233033d8151daa771b43049036971481229542a0c9ce33107eb92dbe9f98bb52513c32a3258f327fe4aeb9b6a277cea6dcfdc4f1841a82a0e26693c81e83468e1e8e4115edbbd11e49dbb142250bc53cd2ce642e41858dd339d263af3b5b98f7dab484bed52cfe4197e94d1e1857d59f19dcf9b3a1a6042b15278cc8a01336b5a9277878a40b69356fe1ad3b1fbf5727a752e2c648b65839653d4ceb39aecf21e089e9d3925343d4f4fe37e92adfdb54105ccddf02d1f8fb7116d2d59026c53171b6cae70e4edbbf2bf3e2b16d7ea90182aac96c03b9cdd4c952ba1fc8dc315ebc924564e9dc33f9634f9ee919b519fc710b4c8deadba0c87c733861b16756042cbb24d74ca2a5fdb8f95e6aa699e532f26c8b17e6554070cb252720d7d07756c3fdaeb8b5f475e2972cc520adff068734f26b1c33c714b7a72a8d27fd25847364420fcf8b962ac6f5112e4e1c9e0acacd14f98c1f16d4f29ba44089f3b40d8a0fcc832ad64831ac97cc3e266a4ea7551e9f05ce2e3bfee72fab1641a51e03b3361616fa042342fd381d645e47fa404f2655ed39ac3225316bd3f8652d2c67f1d3dc441dd9faf3bc9e1d675b65dd95bae50cd61dfb8e4e73a2b0e3d813c199527b07e128c7107f751b76d7fcbb54ecdaf9029603b902923968b74973c1423736f27b854cd0a12fdad8a22cdf2086261b2d8a9f267758fe675d6563c685791e85ef9472ce139acda18ce56d8951241108372aab8b231a028bcab251bfa952691541c9a37937fafa1c1751049a0c57b3ee96c3f8f24328481908013896daed7afc8e29193bd5db65a107e56c0f92cabac6f04b22b3923e64f674a9c23a3d4660d0777972b5011bcedbf0c4672262391a488a4dbc2779d220d1349bb67999c8ca5d3a1f71bedb31a4fabfc83a37cf35367b776cc54b7ce3b599187a19cbc63cb5ee98e67461992129d18eda5cf87324f9e7fe48ebcdebf9fd5536aabe1a3c98bf574c798f2acd64cfc2e69e1d61b03ff7fb3d13d18d8baef6b67f538fddb66d9a072031b8d7b30cb07e390ffa519377152640f83bb3cee69b15ecda48b1bda4f5d7f6501848d75a05df46fc0aa3714f46b03e2e1d9a1a45b232ac8fe1896add99788033a66af1b86e9a8d9ebed7092b9cbdebb261f14f5c0d9c9bafc7ad71e4c87912db4b6cfe969acd009328b63324d0119ac4baa3f9337255a4480f218998e65192e356f59b032160ccfb6dbfe88dfbd7baebe6eaba452f5e410a3d690ca1c97e332b9c2caba5c9ec7e8d6fb24d0dc461f3830b862618c0c8140b443c6699e766ce64194b8235c845476edaa0243845031f60a0597afec10aa0b8095677e102ad32b3bb4bbe223b3b89327289dbd32df850227ff7a5e4891f5e9fd39cd95cb47a1442bdfc20c5c504aa6e3f9d98037e90cf8c251d3f67d42db75282c4404c5c45593090f45513aec71776ec54d813428a1acc7446f385c855b14464f02e10890c05e97fdc689db1a978d07ba4d109c7601fae3b1f6bbd2dae77fa6dbf8bc610cd69108991479889a4d3289316ba5af7a932978f4e367085190f31a79149d07577124a3b784b97540840f9029304b9028f392a56c0772d589119bff0a812a8455b3dc57cc91e4d90ab3c51769b3a02596e1b4f2b000fea24681e638072bb570eae3dbbd968ec78c35f141a148192a2b169354290899a2b528fa2e64bd42ae4c9c88cc5c81517e6a67f768b3a1e803aba8c8ca11cb5a1facfe59278d92a9b985fd291bb94b30207807ae8fe0439894db09ef832b04059589b5265e4a615844f7acce199dafba38f4b20d7a1e8be9c86251cb720433695dacccbfd17e5c075c9d42a6d019eb1ed830ae9d638524ae543ab7f65d0e75af8c2a98a3e0d9a70525b73c3a6c72771458614feab4becc594beecd36d111f6c9ecd8b7b19640cc71dcc48b91177699c668c28d19e390dca41ccb51b87cbf185c55c18adf68943824e8a086ca40248bc7606e9294768fa81164edc47c73a4875904a0482255e7af028591446aead4fad87c1d0e36e3f13a6a2107a2e7b2e421e15a332599502a9321fbbeb9fa644cadbfbc3806bf1320ddc0f6d3db0cf580141a036dd461be5c4b57397525d2e45ea2e922c235fbccc4ef5ebc4951631f3cb512e7715cc900ded777e97f0292c243e3c9cdcbcbc290c96c19e33ec25d4b49ae5f1b89a11d742a4e7fc2c774b32f957c64c58224b0248498b6dc45d5859d50b48501af831176597df0eae9876b5930dc6347f7b26c25daee79e09eb286c8a463f4fc57cab10fc987d225aeaeaa38acfcd3d4cf27901b1cfbf9b874a26632571fef21fa1649aa594b0c624d197fed14ea6b8593d3c4d308a330dea049dc02a0dcf0b15e4cff421adac8725aa10b1bc424e5f7302a429496df2ceffd21e8a346e45dc7711bdd501d45f3046863adf66d114c5338c7ce18d3d2695eaf6462430296a3a73cb9353b52cef1a65b943888cfd62c1a9bc5fca47a3c27b79d8039539e6bb1c7e9512158d88a2ea272ef9029305b9028f397da4675cccc496cf6a0b37ad28185cee27a15588ffb7d643fb91c756041519af7f0792ff2d7723ebec543605eaf5fa8933497a28d92a847d4ecb40b3f43b9c0c4850fb4131236caf851338fd615f5d7bb3ecbb4abe3d9807108bce768cff272b506860aa96eacfb2665e2b4bbc71943c3333bc7a29e9f17af93d7798fa43e86651bc72e11c7ea7c96c72309667a933d54d2f44998dbd439b77885536bf8856621dc5f87eea39fcca74651ca61682ad464a2b5046b8d6f2c2d194142f2810a597233b4deffc656ec4d5127678e4b2ad1e67154869198e130f1fdac195127963f5f7664a38eaffa13d3e1d6fbad6e81b461541f2202b6ca452b0658308c3a17ac5e1aab35d636701397fe5a3d2d6ae6e84816dd64f76d93cdaffafb24691043ae220fa7921e75ab7ba8e5d9f18647b259ed3b2c429181a50c1f624793c33cd023adc854350952a302ade2bb8ca4bfcd7c53ad19071eed99d060f1edb10d72d8e767719efa150737cbce541f2eb24d1163be477e29ea22485bcb25c254eef4286d0b798aec5126232b79fb4169c7b10db532aa91f29b74914a2a8efba1654f531541a0cead1f814f456b373ca5fdb83381dd383996ea3fbc633eaea566543a68bc2169f0c3fb93360979574972c09a6691092dcb2ca655f0f1c4488e22fd4a9962ec398ace27af15fb3a7e68e49742bcc73cd13dc4a2092cee4ddcc584ad91c457369e1a9cfb3b9a40a152bb8370f23448df45a75e34997383dc6dba36c6b33cc1b70abc4a3f697026171c320a89e1230aae796d5232ceb53605408bae9064beb745f119adfed4814a9548c9907d188d8484e62c3acde9b38899b6b67b479e2b30efba4456cea8c774bd4e5c5a1a37d4be0e99f3a1c68e1a3bf2d0d0dd5f63c1b9d99d162e8f8b7f318b8e0608f1ed6f9029406b9029039a9150e68a164e71e39853252f1b3c527dcca3e47767afb3e871a3250b1f080ec1f24e3592fd47398dea42485270c9891a6fe7340c5f43d8f9cf92ad10c8d756de630295c4111205d2c1aeb179349ba85613ba91867e5804018fe950a117769778425f8f6c7dd2a013137f3f25112cf4214fae27f5b30932c9e2ebb8ca5d0657eb89e1a850cca1252b13fb3e34896e6a26f8a26263f1bc8182b13c3d872933c65fac7d26bde94a5d4c47cb7050abb6cd627b24dde728aaf3b6c83c5ec6b28b654bfc1b2ffb246d70a5d584c54410b8e11cecab3984324b9f9d43906d6ed89449363edc2a99d643e83f118ac5409a33592773eaf929ea3d61c27ab3e9526d2383c39b23f52b6189ee05d5f260d87736e23578a174342d8c8dcfdcdb0cc57289b64d968b4ebeeb8fd61814852dc91024052945afb63aa312d410dcac21d5efe472e4f19c68fb1beb7cdad1fc6725ba619349106a198122b17d33ea447b196d1455fbc831ff19c26abbfda92ed1ebd4dfaff6b1a3a6672a9b96209f955b84d3dc7f7fac191b6139feba033e47bf0972aae90ecffb1e9a55e3b943afc1f1baa8696ec8d05f08d61518ff41220611a9b614f8fd0348e16ab67a3a242c83604cccbe0cdd3424ab00ad47a11ecf4bb77c70f5f27b84120eb127d22aac558d362289bf442211260571b24fb58be749ba4d5be8ac4f24a92e2ff131c9069f748a661adbdc218b7b77c9510d4f0ed2519ec19dcc63beb21688bcedbcd352f9eec17d8f0c0e7c6d23f176bc7637148efc511620ac8f325a76ddbf7a91bccc70ad8e2a0ff3a8e012938db2e0b15fd9a2aa54f7ddfa3e9a277ed3a014351b438b388eec74609544da74e847a1450d85b66d1129acce33d8b67164cc2ebd6b8dbcf2af928c912bd3609a61fa71d77706896212f445898f9029207b9028e39c0462748e44b635229bb9320d4380ec9ce84384ebe3b1375d1afc1f87e773a6c2ee9de1124e7ffab83ab194c9ee55ec2b736ce263973fac862234779ddf4af50d1496191e63585f1a2feda7e64c4e66a1335865292cf3396e9abf68ee991b2fce7991e262d16093cf1b2c1bb2c7c3f40e0114cb5020ec3dd11f9b45615300ebdf2aae79bda6c3d66a6c810ecee648df47d55c48911dc2cb7ba69cbec7736ccbb77c9acfd55c392a31af77380a3e9a7a9e63f0c313c6b3f6edd026ae5c95fa60c42e5da35589cf877d1f84b274b7f942f7d81992069d7032ec8d5be28d4a257be446ccc79bf298bda9d2e5a8bbd0d036db8cebce90ec66463ee06a47ab7c4a7b787ed701bee8a5e8bc217d62befaaa7279d9d430b94a4471918da83ab9cd9630dcacd5220c9170ffb1bbe699a9ffe34c2f09cfab52984fddaf63a090cfdcf60da28c58a88f398e201958848e8de6889e00bf52f613c357c4e5c7361cd9645892aa1abebd26abbd81d0399e195d77d508a8d2fa267169a4af71e9b90aafe111d4ae50fdd96d1ce6b312d0316a435b3851165d22206de53347f1b243dbceb9b8c0d77205098cacfeb3e5323446e6cc7c05db878ebe1d7ba897821460919ccc199b5d620b6fe6197f926fb546dd1ec0b77b2d02bf8d4cfdfbe92187f035b9727d904523daeda1acb82291916f44fe39553a3749d8c8f619b8751e690580b69435131ccbf2145cff1f96716aba3d64a14ec5ba29f6dda4b423f24882a69fdad855aec11475966f96270cc54cdd9f60ff67b0e609c285fff2dc28171ab4cce98d7aa98fd8585aa2faaa205c94096b6cd3ce2a324351535cdb88ac11c7292b04f13d4495e335eff0dc51ed4ef1dd8bb64a127ad16f212a61323e9a57299dc3d96cf2f68f65fdcec519c2095b8f3556d80",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x22d9293b4705ea37e7308ec5bfe9b8b41003c093efec14dacc3bc6fd7cf847ea",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x97473985d04723299559f49b856effb47d7abfad",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xf4e410",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xc9d610bc077dd2cff3f54604cdefe04e2353b4bbd92e146576e8107e30c7ad19",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xd912fc5da0631a00e90c791366264f4aa10a37ba7046297dd1218ecf733595fc",
|
|
+ "timestamp": "0x6a91d886",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-B-9chei-anchor-16049168-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e382d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841de411779c23517b39daba4b68d6e3f9302ab1a513a3c29e5b96c1c3f2d79e5983de6cf5f1cd824168ff409faa77bfadd66be1b13a09a38d66d33a9389007eed801b8412f595ac15bfbb4bf2d582bf8047cbc7e311663fafff046f2e2b3c00fdea0ac51128820e203019888f85deb32730f2feeb355fd5b25267c494f7635fd68caf99601b841df2e33edd45549b32458a3da3c5d58a59f7bb679744b539e8f926db50f3d556928bd1ed52123469cc995a86a68c62dfe0b6a28f6a03ea47fbcf31c26b3be77a200b841aa87eede68084892f550e8ff77cad63d93c1cdc00d489b57b7c6442b2c6400955f30ce885e3c46e758b56b7c29f0f886dbb1756d264c9a482b8f3f7264c8608100b841e9486b9c31a31a8b7b6d2d52b6a846e8ed9a9da267f965a35593081a04c2ba9f5a995296f160fa6362f009a340198064bde33a93a51a91e7f352b6a0ade8a4bc01b841ddde3db1739e444092374ed96a2f0ec1e9f5589933ca5f354356424f2d958309470c9fb63ef393fa5a0d9d89eae9f1ff46c3726571c885927e5b49a5ab57c4bf01",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x9a39a88c1d20e5822c747d310acdb37e98754c0e42fb84a2a6434c683d2a76ef",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xdf09b32c761620c5be77da398b97a64f03c3980c",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xf5240f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xf8f35d48c483980712ce7dcb05c78f412c1010c7186891ceea7b60921d47de2d",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xb92d87c649d5782155cd739c2aff579b79284de4d4704a4dc39f0975250f93d8",
|
|
+ "timestamp": "0x6a91fc9f",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf919caa0c9b7cec6ac24b318d5f0e023180026ca926f03b60aa1d17f06f63d8d07fe3af7f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8414da9068cd6f838e74cd8127f5e0c276f9db6bd2e6788b62ae90791491e3547bc20e43786bb4e88571b924018cce69126c444e9b95cba5fe0c69725536b5b7b6400b841b38f1e94a22e1e7f15f4645517c888a47ebe316e6e8bf1df93d4dbd97ee82bb053a0283c4bdb44ff506c5080965b42ea9ce7135a87c4f74751ec8ad74d4b42e200b8419aa3fe052dce616fed622da964c2d919f010957267c5de9466ac5582881b9a61770351078fc3f002e4eb027f3f991868bfa19888507c63c73740556ec1234c4801b8418e443080635d15767f7b598b3d123e76721a290c3539d5b54a10aa7c43fb103c7dc055a96ece4072b1690ed3746d178df0dd9c31ef29b86e2fb8ca12739137d901b84168c69835df99c573d71cc2bbe15cb71dc693c5a30d21778ea476af323d0059f33c1f744635b260a520a1bada0fc58f5b86c18a68d8497674caedf07e24aa096c01b841c1eec057d639e711d8511e9a3c52370e0014a053c68ea3a0b64fc7ac66129cd30fde28a885ca23f08de88ae08d1cfe76d94e12ef36a169c862c217bef476aa0801f91750f9029480b9029039f3c8c741fce378195800c93eff0ac6c23fb93e4c1b3414bd2b619d57f42de705ab8ab2a61cb4e7f8997513374670ca108a176a85f0e2e3aa918997114031d424c552b930018e9665483652bb81c69d2b39016d105d0d8e78a0c498131b7571f7b12a01c6d24529e7c61e86ff91f8c674ce9668ce830b0569f3a46f0c42cf0e1632f5d92b14d3435ab0f659b495b9262f05c5acc7b0b170f747577f7fc316415fe53a75176849343bedc2e99a99aa24eb71d30dd6fe3c618cca6dd4c819b5a8af418fce10c3327907832d25b37134fc1cdd5b8d16f63d465b1373a6e3a3084254bbc367822d297b7833179af160e468a67f9812d4dfc3489946d3a2acdd530a5b2ffe16e2c5f54fd62a231b0a6d2ad30c093735db4a0c328fec45e5f9a62bfea61a9695bc7659063d1033191ef787e3d32b6d2d7beb1d43d69973368296c8c4ffdbd352b5d9b7ab308bb6c69182d9efa0045a3fd847a6edc18f799343c02fb0c653a7d5deec20d8578f4558e37d1c93888c307d3308521abb255d29d27ff3eb3bfac956197c8149caf5b2e40e652ca9bd98043208f3b63b6b94bd59aac34ded1e4edf380d876522e409468d2e48d38c521bde95a951eede7e61207612e85fb5937b986f2778594f43f6b3daad1eab8bcc94f9e2887a2b0f2196b527245093b826fb16c9353569133bdc5e5085bbddfeb21d86f6049cb872480c570ca3c4bbe83ab19180d82a3c96f6dd4e68ac9a886192f3686e3dd5710863af3bb15b8610b85b1329468ca6aa3ef298da9aecaac6b93ab7367d6829ed66f2e7d5575d0a637b8bbee19ebdae9767e1431c7d6c00a6b04c0ee5b4420ae383573cc8d194dfd54626043a9f0d85fbe26560578aecdab5efe9cf50065cacd52ebe4cba4c999328c9236132efc994e76751fe6a0eeeefa308f9029501b9029139333bbc10eaf7fec32e36e38fe4b94cc2ed844ad3e2584014a94f820e90a0c1533b69e0513f675e84a63f1d2629da5cba5886168b3d9e322af6010ddeb2dad8da3f93422868b1fbb8b719195d13f3d16ce14c840da890ba45e8a0ee37a720a775cc333adbdfdab24716f7b2f1b849564498af356a7a87981de5d52d77287ec63743f4c8c118dad2d9396052addf30c7d81e76c54ec8f0e6d03bfbe32451640fc1fb965419aa3f4bf0bfca6e70e8d66ba07668b856e9aaea1a0bca4b8140b7cd7baeaca1d3cf5425b94d3edc62d6ea55a69071f4eae30a56b2fb6247f364da14e261976cb2629fe7d3ebbd4ff1de30599498914f7a766dbb408dc1b28645d4926ce96abe7e9322444de5290f6544270695779225561aaeb859f2576391b91792af0d12024a56f2c81b35c42e53681976e7200c6dca1bd8bfa3aff6d67d4fa0e695c92b42c468f312952f4ddb88b8a74a6a9f34d49b84a206fb0eb8e23c46108b62ba08d380cda7cb32557a6cbe0d55e94c72d482482b7d5b823a9a96a57b9d925d325d89949d8a83a2ce142885aeff599de08e6e7e1b8bde157be1a38dc34bc13f391c22e8cf48a17d963de9b532ea55b7835262186f04b10d2fd03ace73ead261183c1105312b09a5c7ab584d4b1c8a21a7a71660d02cb6e38bc5867f69f4a2313bb1543efa7a437111e1968f65565680898f8d053a925583cf8d43992e0c571eaabeec5e5d22614e6b3a81b4e8d7e6a0e3adb4dd8a6ed8a8ba7e9ea091127ac56e2510306c5e696132881e27fed40fd247b888553ff4a3ed9057ad1168623cea3003fed932b4978674c0e43b496e7b2939c566ec7c92150722376831a3b7a0ca1c83489da390e51b0ac7adc537665f3c2f147dadd6756f36d7374c9cb594c8aaa103cf14d9849bd528ab3be9c9157610f9029102b9028d3900f7fde15a35a0e959443d9da4dcbdbebc9cd7b17319320b1abd2accf35603ebec83ce29dbadd5b01bd2a6acd1ab71db79ffbd17cd29c4c2933b6ebb4700ed2944cd44eedd12f4e63917e4163f1561b2f34a626ef4251c6b666811ea9d6677d30ece51106f17ae2ec95415e94f814feab3bab85d9f869a1a392d6e05a9c8c51845ca00e7f8e75346fd2780ff4fed0b4f50c2572198be1e16b2bede3a25aa789873b77ce6ddbce80d6b319ac236376f7a188f1a263d67b97320ac85447e2b445ea488b9f0d5d29a8130d3250c96102dc7a378b272a5885742a6d49287161e379015053e45a8a449b1d631f3c6d2accfcaa45a0747338fd475882d132b384d95671e4b0787aa545c220aeeb957af8b3be3e2a1308d0e93a5c1cf6209e2fb6556b9c9b305543597e5fbcbd7a429c6314cb8c8d5036be3bc2e86175a417527770336d1aead665a8a4a7c1f9460ae92d40717d6294c965d2360d10ab70380776511ee1c618faa4cf6446d3dc323cdd31f6b168c16cb95b397578bfaa4cfc1d4f661133110dcb13855a65a1b54ebd384afefab4436fbf5b6bb384b9bfdc3891b3bc5ce13a0d9127175772146571b47d2204a39c74c71f7cdeebfcb15730e75a6afe6932e9ab2e685abc63da04ae1fdbf3665976ea2f38c5368cb74a5f4fcdf3f9f482abbdad63b11b5990e8de587adf91b74c3c70153b1eb6f4f69d5c2d4c8c7716b27da99e741c7ab69bf3c86009d1265695dc6444f4e93239e92a0d5b451ab324dda7398ad33124a429d74cc465c7512bed5c8772d4330ddc47849db0b779346ebfefcc336a7d919d40d7947370d2033fb0f2387194d39cf352a9b1bf8f4eb1827abb58b91f4e6b9195495e221740c63be83b6f6949a632a406797d302eb6e70570ac990aecd238daecbad769f20f9029403b90290398c967e0368f718eb4b70096a63295e17847c37dbc6f3983c664f305b723b6a1c31354f95553bbc8473ee76f5872de6546b58e9e29134961064b63163d739cbcade80bb9e6f1a585c31fa62853d8751db5e5a4ba85e89ae56fa85c19417e699f9a2338ea9932eaa7e317dbf0a528188d43cd21f9f5562dffbd5c6a15794553970546533939d08222a7d74437025ff5cd8e7e74e3f1de3786a7648168cc1c962041c7ed60a89ce89241b6d8c52a5b748e58c61899090172338ca26b28a164e96f3e111f831816a7177fe5cf9ed90acc8ee53aae5bafbe279ff92b98ab71cd1a29fdf23215cd6479f2f7a791541eb898ebd46565849fd6cde74b0e40b4ee9f11c43396040f14d03de91c2dc7fe456e8bcd45c8436117271dfa6e5baf2eee3c54080e49ba4ae76efbed26ea30578d9b06a840bbc8a31992695b85fd1c84c81554a1db509ba7f28357b0a6d4847ecc8a4ef5d5ea3234fcba9d07b9546b2536949a42f3cf637a7f3e2b4f9e94ea22ee431905abe6f2b43d362e138e7f3fb67a67d0c98c243bf5316c99547a05ca115e9eba3750f1cad843dbf5e53adf959e0e72675aac8af9c8b7e5d1f317845399cdd6c1457c53fd1621d2b715f93605289ca9b0840e5acca978ee8aedce485a5d673d51e86bbc3d5adaef316e2991dc41d17262117307ace78b1eb45d1ab4153c6feb1933cb87c33cd4f9e38af8b33916c5243b4d4a488748f68830aae563315c849395d5eab59e14d17c494d350d201995c7d92efaf67d3b2532a59625d92c8b13629996ede5e0c704c3087e1465227e8cfb3e89e916b9cdb1e904d52a6920515bac3183b33719cf74f7568d9ba6ae66b2a10ba10d2618d83ef087a6162729376c28df050ab95b36cb3e9ae0a7f393cb77688269d8c71dcd3b2e9ca91ca37baa58eeca0f9029704b90293399743767ec76b7d2296ee9df0fb7280fe9136afc3b4f5c330cf774e74cad29ceb47b13d7bddaed52a83732998487475acb0d052c46588bb433eddb60107f8f149b30dbf980ee5172e872098c903445e688dd67e6b8ea1bd1a43cd47c689496bc3e5f3759f31f29e321cdac34524352e51006f63d05fef9276d9e50bbd8744ab17073f3d0927edba9491adb966f0f5c95cb4db21ff87514c5283d57c99ab3d2e456962ac7485a7681970a6c1a54d1d06df059c6944e11f31f62e56d752a19824e2dc7471b3423092a528fad36a522cb68d4a038b531084b2ddd65e37d81184454d5b98bd3afb26df60c032448f4389e536ea4af12498a1f114dde35a647fcc1bb76b62675a01c79c3f277e78875696f98cf7b73fa2141cb98b49d1337dab5665ed5659807af8766eeb02280d36b55ff069ac3db774eb63a8f6e6760e6b3b2af5e2ecc9e697bb7f92fbf3816c213192e0d5a92587e857561c0331b647654d7a9aa3b774565c881839a345aaa0e1d34f140b75099c208dfdbe5f6b97a33ac8e964b5636c708c4ba391863f4d71e583aad217a48125b167d54445ec13f472d2d024d1d966edb3e0cbeb6ab241d1a9cfbbf697f30079518416cfc44cca46a136e7dd440e11aa64e19fefd47121ffeb6b6e356f05fb6c75fc6f006c50373ebdb389a067419d6c7033993ad4d51b24149191a1c3acb75c072e44993eaeb428ed7c13d56fb7b3ce66564216c01fa883170f5d586d975dce82cdd807e507411b8a93408cae50667cd5b0cdd2e2a0ae384dbd420a73753017fa678725d113ef3660d07b13c8388601b7ddf05a652a8b605662e4aa3a531cee7645caae3b10b380d73d5606ee1542d83dab26c6532d4c481b6682ea6ce9636362ceb9731e2448f6c999ba28c7d298c97d7e024617a38e6248c966c23b1ff8f9029505b9029139833172d409d2f422178e1ad272afd4674ca9f57a4adbbae053c427573ef8a9fc73b2a21a0f2e30c106fe108341de4ec68b854b75e433d65b1be6e547068f096598cbea1a5bdb352120e5b896119736065a9f1944923624122fcd0774d8e0efd0d34bb281fe1295092c69a83d0ce589304377887254ed3c2b8987883d1123e5579ba0ae351de0c8dcfa8e4bcad7d53e3166964dc473abc8ea87d2823b260bb4e96f21b8da7153e460b92735b7464cf74e3f3b6d4912b1ed907f5805acf3472a48f4f2aabb90ad62cd17b489ca0cd5a7cde4196555bb70a2e6cc6c7616db1eaf1aebc0dcac34f776bf42292c5e76d3ea9fbe7e8d7e6d38fbf4b9edf6c51dae5044f97edfe143e660ae9fbea26b59b03936d44582c1e5b0a438f75414c3c14d87a9858a49217f7c4ab7bfc595b66f4876cd8d4a524ad1f591ed194e9a1394d7b6721a2c69abc75cf5fe321aa94e34c20c8cd7124c1e3eabcde25724866a3e33ad6ee58592459846a5b63f8eeebdda27aacbf567a61aa2d9576d33c85bcddea44d9a9e520cd9b396ce92455c32133e6df230d068dd64838f678dbe8dd37541f6ceecc49697112e462393b048dd45af2f5b482bca82364ee54e11bf4559d69b884ee98983cacabfd16c6a87303329a2049bb45275bbe38a7e1f571568f8d76dd4496f639cb89ce89b12238e8a1e75be660462b2f2098b79ceb979fc141b67514d5e7634e9d9ac1c7691c92506613c8e28911a84693b5df0c5be93da3493d964d93a443d36fc4c7eb172645e0cba013fb23828834dc0632227752c39d4d8f102d4c35d12f6fd5ceb99edbb0355a279211f1c947dede16a8c037de5d0ae0c1232c5e4d9db233d965311ec6900cc434e313b43a05b3f61206af417b92f15746c51a6d96e3d4f013286c922cf9e26adf6fa609b22f9029606b90292397b84255dc0e9ff4416fe40d1449f2070ffa772bb2490bba4652bec362411f9fd8fa25c7ffb367e27c261f98e2b106f67bc9abf1751b1f59349ce85f1365abc4b3ddae9ebbdf43d5948e418824d25c2e254b9c6a25daf6e904605dc9d1bbd36728e4cdc084fd58ccb2dd99e0ba4fb68dbba2ec5da865005eeef1513db4cc254e5aa4d6a55cf8a25c8fcf98023383cb125e27778eecc7af303cbcd1aaebab379fbb57225fa784eeb2c671911358e2fff454fd8ad8e5ea52748722e922861d5ecfbc19a7b61d685d04f9194825f0877a529974e2f8ab723bba7746371fc378f56c1976d9b32ff3f159629480ae397b14a677b76cd093d352431fb525f2fcecd31390a4621c16fb7cf25d1eb80d99ac3e5aecfa4893dd8bf73525c7b1a29f5dbae5bf6c175655d2843bdb3506d5043a98321ac2dc63f6ba6bf72ed4b70ca38edc78b35fee39c74ce1901b044f6bd3cee530b09e6b64a06a7808c055d7e83ac1b2c87c62d4fcde24541d1e8ae1b6a07abe2be553c153c231af2b5a63defc292573f3bd07a326e362852f7b3c649f2da25c21b16a55d565d4dcb04291a2b83c5d4ce475069cbb043636a6b2cd4a0701c133f83882ab03e9b2c808f4ce8fd29970f2f2b8650b9490a904069dcbbab1f175debb0bcb212cd5f611e93c7efd634cc6152913ce9d4acc3bcb88c2a0b2275e3cabe5606bbb106ba56de69ea5ee82b834d816993aa444a236ac12e8b321795b028a60b675f8f78718afaff1f837ad9661dbf5966127ad7fdc864b29e61087ca976277ca72da6bee6709c5a7c39a52c52dae9b398a6849888051a45a33739d8b510be6df2673c85ac35b8cb972f64276e5e9496b08b64b76498f40ab6f956cda32d3a8da1d667c5850f70f1b63382ced7482b48ffaebe424d6f90919317cec4445851d340f9029407b9029039e5945953665956c5abfcd1966036b99191369fd1408aed1bb84eca570e5d56601cdb76b279fa44e6402c0a7935eab575381c21286bb93297e9901ae366b9d4e90a41ebccc208afb9a946da8f9e819cc427199f3c23f5804bb03091924f35f45ee7d5832b5c2268d9e1d81b77779b6f408cde29b796556ece2dbebef2c3d82c84f6bf04cc638dba6162ca7c5051ea60dc6b3a5b6193a9f2094701ad8b6d697c1ed453aacdec0eb2670597da92d91c036ae951234d372d7ca854fbb43de103d0cd8d39ea610787294334371ba5b89eaa1e1a25d508be4335ca6ff3035cc1ccd6561b2c6bdf486a4f1243970caa92bf318bbd9e9fbf53f51d4cb1d97e54d67e11e7ea284cecc0dfdee6303468b96365b74a7d09b1db1c062e376b667979f220b9b82fb21d7f52efb084d20ac19b75cf28f6993a3b9936519b7522ec842d710e0cb729a26295d559e4f24c78c885075d6766b6b664d39f8ce110bfcb791d5a23d46b0a3883c0c9ef4583b341772ca9ccadcd46dd7d97685a14ee02dccd0a555d043ec848bb30ae61b4c7b7eb9676677d4c578e4b568bb14d2db198e667a254844daa40687b47312bc5a36899debda8ebf6e9d6bc299a88bf5d032fb8c4198370bcf6432151b668110ff522988bd7470997bcb63cc26451d774b6848e1e0e5dff06d6617365b5c26af351240589e9cef14642a51c34b71b1998c84790280a96ce3e7d5676571c6e5861983bcd4d751493f7aa74fb748923864218653a1d1485c9d204f8a8b49f1d4ad7b144c79a08cca30226f322c497c1829ed31aa5a5fb5565d80594e7582f5e954724b5faff09716e60a8f73a215cae1d79fc724d7e4d341e2f7b985996d3cef775bed778ca5782743099f8676f51b96de52b3a47213bf5a38f901894062096d8236dc27b278f411318f9029108b9028d3959f633b5714378ab639347d19984d802595874ea747e9795cb5185dc70552435a3032bba8778d0b21e8245edf18d75d984e20f2621ac5c984d1bb244d3fa4d09c9723dfd3b63809fca3ee99a789cdc2df61db30e995d674c7b2b655ff52b9b9cadbe53f418768a7ae5fbc412c3892ca03a2aacafa9314046b68dc74957fcf1ddce1595820ba2e7727cd40eccab4185448f67669fe8a2519e583b1fa4c54493cd810cc3c8dd1645405cc9a924490621eebeca97bf1d273d668095a4966ed6b798a625a04d2a118d1ebc85489a4296b29108753d99fbebbbb483159cdedbe1e8799aba3c137fc2768720f10eea66c94939abb6597fa63a56cbbe0f274a859c46250aff5390b2275da9da6b452af3a1e4f15a77c9326d536252f026705c65d778cd4e10d8044876981311de2a05273a7b30bb89d6389840e5ee97161a7521d4549f0850236a5434d964ab682f225cac7975765af23dc42a1311799190d54c9531c85bcd32669d35521e9e5bd946db09dcded5517fdd0e26e3db60adb527eb59b41b525640762dae26e0f129d51c66b354d0210682ebbdbab3c8e092cce57ece9d15af72e923825e7e1d6a19d7ad3e470e5440732bae9f4be690bd1936235b20aafb58ad921e7958198c3d854553f25fa58c981e459d40ae443e56dd842d655973ba55f795084a9a1eecea48eb42f51928c6eef5d33631465137bd2f1f3c9c81cb55f5740fa61675ecf299d138834d35c4f2246c14826ea8f55613b1936df3aec7c38be199258e7b3b7bddc362059e75c0fbd913ec3cb153b0205f344f2db1ec7cd0eb663fd57fd87493fc57c3e525abba3fb405d8abfdf6931dc7234ec0346ed7366cddf614e476b9125b174f82b93b4b9d667c8b6d3bab8751c8e1e833501d5b7fa9a0c421a955f5b17d341c28",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x7665efb5b04604a60c28d35dd467fa9ebd123871323ec6278e8639d4238e978b",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xe13aa491abbc1252dd714e7ca0e55717a2143eaf",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xf52410",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x9a39a88c1d20e5822c747d310acdb37e98754c0e42fb84a2a6434c683d2a76ef",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xa39302782a30123ed9f89d36f88f1f45228265c6d93ebf1edb6b71da7c844a2c",
|
|
+ "timestamp": "0x6a91fc9f",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-B-9chei-anchor-16065552-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e382d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841cedba54d78cb24f182127f81745d95b5bb248e76fbddbfc26fd773f3f684fd400ef278c6129953f30bf12cc14a85fc5bdbaf8929d943d087897e57c5638dd6e501b841ea4ad11454e9c61f1d244adbaec9704d8e5155bf3b9c360318d73aef27240bcf0dfef5d2b200d01e1730de6e999e699eddfe69888aae53da98ebea4a4f6c4e3c01b841f8e43641e6bfea29189810ebf0c9bbaf159502b4a4fd57cdbdefa38f1d3ed74469a5846d1be3e1c7a8c91c12130f83fba1ff420dc30adc4d2749598bc5b1217601b841b0b87d0010281dc3cf2b8de3c07ebe269bff447e177f4338775db658d801e67177417f50b1a0c5caed872789b3778941db2d46b933dd95ae2ec687d05d9a597601b841c6d4645849c7e19dd2e5bcf4068cd6553c0d816fc3e45e73dbc729ede742b21f345976f879acde58865a593bc24b2825434a6f4c106b2647c9a91850db1662c000b8411d98d1ceca56cc3f4d0565b6a3d7d658c90b5161b5da7c05785be50dcad15f722a5a00f7b9c980b76d7c0e872e491234117dba412f7c8f76198697d0da1baf3001",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x0d9232100d6e30e32126a0de4c93933a94bdfa17600f3233299844eeba063467",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x4bf6f91d84b37454544279cba152581ed6820044",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xf5640f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xa51456b3758562baf50704b23441a05581c60e0671b14d8e33a833345e46604b",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xde862742624db4e3531e4fafebf1d7154158bcea5f38f8181e0c3606325dee31",
|
|
+ "timestamp": "0x6a9220c5",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf919cfa0933e4aa8b2ba6c99a93f010519d8f154f7e3555275223bc9efcd872a9738368af8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841eb9bcdacc232b899d66c05aacb630cbd4925330307f203f0525630130c6442e359c11ce5554a257c6bb06c01a949315ed5019f3b4f1c14cae700088894f5d4f100b8411b091866bda75ce8c3005f6da0633ceb56a04a55f721179fe946577011cc3e936c1979d306c5a8857749a20c5782d0c311dd89dea2f018bb939d6c58374bbf6d00b841efc259550a14c174bc8adf188ef497d5e34a737adb417ab1bc5c4fc5fc1bccb30080b0edd1e90e41c57ac7419ee83ffe6062c0e6eda52fb928fe8dfcc1ddd57e01b841ea1e19031287f4c82047fda947b5c705189e904b7564877c4b70cff65e97531847ae52e1494c37dd8c2ae286e95c258a25bd41ece477cdca360a2a131ff2fd0f01b841c636018bf7e5137e60b9846bf993f2e67b66beef17c2f51eca0720780f591dbf0983e31f2a0bd1c417db24693c23e4271abfb5523d0f991f01725ab26b2cb3f500b8411e2e3fc96939d611f6245eb66fe068da6031187b00b2d2291c826ceaeb61f2b63c9c0d4fcc503e46f97cb939390b7a50b2a9e3aefab6f401b1e46f427d67368501f91755f9029280b9028e39abcaa6a436381722b2594fa1a9c8e6d38d94bea428a8059bf147efff590d96bd5107533ca7d250851491969ca14f61284a65752ea4aa748e460105ad45d0f7168105d2c0337d3fae00ceb508c5a773a5c65a287e7f155679d1aff2f225cb5d3b727c5db86ba4d155d6f2a91111556e36feb924968887f5f218723b0bf2c05acd1297c9360a2f6951a2af8d0f08f89f7c46df552a32bfae897ac1128a0f5634cb4259da9d3540b07a95cddc8cc5a005b528428f816ce6477129ef57fdc24ad89377607166bb84a21dfaba2ea8117f441a1115a772c8df216ec6ebc49191e3b4cdf233c1bb5ccf4e40a7445187c657afc5346d416880b38507bdabd66595e69b43b7a634fd4ab2084fdeb82ed5fdb43ff2682b004cd5233242ff0e3e5e8dceba35b2ac53e70a52fe92befb774e44bb32bbb514cb7a56b265f5eea9ec4c331ebf22940d91dc5abe685d0155bb64654df4fa291ac92cfcb67894ed55f64a7bb2cafa21ae2de2912f517a3975ca4547b8c460a5a158b5552853fc31065e9894770cdfa0972896429582d4b02c4b13b74411ae15092697e6b231f4f7a527452d50040b948313b99cca352a7e20636d735553f6d631edf5358b6e0e32e7cc500c5e2f656afa7698ba75c1f3685d559966b96f65c9fa591a2051635650d2ea9d8bbb09617d7bfb03a9c9421e3f6b22dfbd2768ec511876c2103cf13d425ea3b2b63cd3bd8e79f5b8c3393a4a375b5c7466dad53ae847230ccf53f32f565ddb79335dbc72999c5e332a7bdc87e18e5fd68a8bae7a89231c9e63b6bd042489c0b589aa7debf0eb7f6ae38898159d288ea7ec6a41cde8fb60964cebb8c530c314cfced5642663964596026948fe39440a3fbfdb6a31cf4b724b6afcb68195bab83b9c80f4d8d8fb33edf4781f0ceab7b4c5c0f9029801b9029439778d632a10e9b0f7d5bf2799cef1d47de6f204caf29da21899a26b1b9068d1a348dd9e6b6437847b4a3b2fae1da04ff808725f0475e68ee71ff34bc97934f33910569c34dfc687b75155a1dcf328dcd693c6dca2a48b9a9be552bdbc6b7797497419475ac73acd9d4c4901ff63e3ce742145c718a554a7635396ea5aba77f67723b28148cf55a33cc6b344efac9429bc94d1f44c3117a6ff47ed455a7dbd9a68c5d67df4c56eb19164604d9e3746eec492ebe2dbf83ed8a4c63823a66a531e523bdf4cc3db86ed576d3ca5c10464090e797f21e5dd1dffe1842e2d88f5b32fa15c9060f97b9f2a0459bdbee645f9d1e51ea6375f41c6bfd65a84e21ccbcbd0fe78ddb1f96febee6af44db92793bb3114f4519a8701ea83c32c85090f8165d8e6c2c4624f0c1d944b9b544e0e48d0027a2850842492b27807ada16964b1b8395c44e4e49d33efc925f2b11e7a6148c6b3144669b0dbb21a19632dc246a4934f751848e2e9422ba26312880b7f9293fee349bb41825aa41d7319ea4619b6ae9f76e428b43db61598c1927c77ee20c79d5fac7360b698650b3e545eafca7655f51b359266e4a33955572ba98d545d6b3df3e1924d313202939c304cabd9758aa29f0e1159fed3117ad20c670616a5aec4a0e6eca1ab2f87f636c7521d8259f4b6676099e400511972c6d05f19ce4658e6e1b5c8fcb337ecd2119c9a0d39360a56f5a0cfb0d7b4734ca6f6d3040590d9a7324fbf8f04469ec40d193089831cdda74a868d4f799662def0a5645280c295bbd309b022376eb670c547b5762aeed0df5fe0e98e21612bb1e439203bda530e90b7fa465e2f9b8099029aa0320a290a973b52cfc7597fb461d5c93c1a856c96597adec482a97837cd336926dd377c19495860515458705a994b8be4bff8d2a8df01105a50f9029302b9028f39b11d7a5ec28cb4106e51c79962f4364166281b533aaae433d58073974997def578bfee40f95a8b00bc92e96d3b031ea461d90451c5846e290b743193b7ac0af41a2afbc4d3a96abbde5517164948b6ac9938410d4247759c573433b1b89ba10a2c1a16b2349f6f7c7349b085f498de7e76e122a3e3a8887ebd22fba475f45a7386bacf074e4375d2b8d9246274d5f84f2ca27f32e5c4fe8ab2548c41de981d1927b7ee93d839907a7ff6819c2016f612307a9144b3b7769277f63dd5371e43d169f389b6cac5e783128aa3348cd2f4599e8cd8a85b134ffea5a9639256867cc964f36ac17796cb1f8fae699166bb196f8cbb4eb0e9f12fcc0549cc93230b8cdfb12cbb24f65512374d4d83b404ebb5f03b4db573d6ed92edcc89acb2c0a3ee9ea055b4a6be9b21ac409912e0fbf126e9563088c53d0aec26fa4c2f484b36b3567abf18fba7a48831d384b3519038698c05906fb1bdbfc70597355da801d29cc437d866ba704199e9ce1c82780fe5d2683a73a46b5ab94a47992ee4a2f07246a0ea2275f54bb95f5c7533a9522f7d609c4417dc47bdd2fe39602e3c44298764d5876d48c215673939349dd7ce5dab20bc8714d021ec5cf265152d54e6d9c5a651e71b3c6405269bb05b12b31111ff96cba150556c9e38f8d9f7dcb30897e0898c37545de4497e58a6e5764e44da0b6d4a63c9649fb15d8441a3ed5f362d3672e04a291269c95a6563de1a5a5eb2709da1ca5e2573823078e8f66f37d333ba5566c7e69c264c64f4c8abf02247c9f44656f6c90947a9b5089f0284b4d6f89faef6c7c79a7912e2baa0903c856f88a4b036afd924edc06d6f0f1f935ff9cb70d95294725e1c2217ac5520a8a75ac1aa9c4c288a9909713868620ef4ea245806ad58bf430b1c8f2d2c41af4e02d9a140f9029703b902933908b74dc880ba2ed136bf64646d7a7e3cc5ca5ebf30c8f027f16dd8f544f3f85af520aa71e67a555a1341f2e4bc9e725bd71d45dfab8da67b66b274d72ffa0cb575b053063a6f154b2eead90765c9b6a716a2042096e76d517a0d846e6f0f7f729c5b26d19d4e92e338868a51c4bdebfd5e6c457f10c357e3114c43104a0bdfd228125cecdd5a63199c3f4f506fa8b1a380d1259c02b4d5206f6e6be13a7e1f9fa55092c2f40898993ebdef0d60c295cada3d172f2d9b5cd4c536b70c1fae49f0689ee23e81a227fedb67a115face4a64a448d005feae5a384dda67a3a1e90caa00615388ed79332e5dd503249db572572cc02571695b6ffdacda0c9a43b627dbd552db34b74299e48e2788c77ddbc4c162d7481f051703fed20824b6bfcf5cb3e6230272c5bb6519a298a230ea10424d4f6b66a7d767679f2a4d2b4c45d9b9420f5d832c2676228c7b983e54910bdc92ff5d98665d9341236a9298313fbe9ddd0595975da22de1f33858a18923a382d84d667a4daf9baf00a2e865fdac0ae0628e5b02e7cc1fdd47e5a9c4bf4d8e05d3e29e9b2dcf2d377e6ed5b4bf8489c193d3998ed53bfcc834be5d89da0f33bf91c113c8136c306fdfdf5fb8158a5c561bd862535bb786db0f3578347a12feca6dbdee12d1a0f8d3e807aff7cb66b8314feacef374f978e659afcd9f88ff6bb5efad3082b8fba8dba9adfafefac2ab6fe50f84acf3573c7a646abb98563a28d6b7930a85b5ad321815ef226b2b462b4b9571339c0809597d2866c60f2b82d8f69226408bd233ad17b78cd91ac9ad1a79d526cabb1e8363a18712b33080281403c9d9ec6810b17e912628f43db57b996c40f3f33f0eebb497c9f5ce97ac75e68a221dd561149dcb57ba4bbde8179778abd0daddaab8ac0932a513e12832a41a5539c740f9029204b9028e39b065994490e3e78f9cb123b4f96b300620d8ce777639efbf3b4c5a858a42ae4c90647af07aef1dd0aa69979ca7de2c6e5862c36f547a1b54b506856011be8c7ae9cb33e412252144ddb4cd68384fd4a28e86625007824f0e52b1766939ab6f91b70a853278fc5913452287f7b369ea1d1869fc71a8894f6ae19fdfa7023ec2a6b3a8e355a39558d4c7269c96d611f4d0ea2348edab3b9399ab6ed3acbd765e6f1c1382c444fbbc490d3498fefbe426ef668702ab86852273e80a444ba203348a98f98e3dc8d8e8f0e9f174a620d3689a76de793b99d72673a77e72e82fefd9abe5b13ac196912e050abfccbc3e0d7a74de408ff66df0c0a3a8c31c36064178cda4f24ad7cbc367af5bf35536c6df6a45555396717150c6859f8ecf69685371496bd704049747a0ee3e3735bfe354203e28dad794aca365e6690f92a644c56195b172fd8379fdfaa3f3ccaa0c29d7972a1f8c5ae4939f6149c4a1af121686672dca3afbaa53154515e925ce16c96ef7ac31cf7f9085f30b16a1ac1dd58f848d64d96b0a425c71c832593db956580721b745797598757155dfa1ddff2e0d09c8b9ec6a07aa71dd847203147e21b09575575d26144816b26374814c3c287aedb35112234e27681cfa42d363b45bc8157867310ba61ff16fd0bcf3f9d6359beb6d4d26b89f65dcb6ee658295d4c8d240da73d22caa68fb475f74762b91438bbdde0762df4cfed1d56e20592a7f6507b75c8bc237cf0e4510cfd5a52ee1b7eac6798490d6fd220ded65b369a14d535aef14dec404d6153729ddb1551f231b16f06a52647b08e0e8ad910c15e32725ff4b76ccc425066194e92ce6b9889b17c965713fc122bc49e3b50d91cd10561e64ce66e568c9349b46f0aca39dbd908bdbcff66f9cd45a9bb86de6c7b910219a74f9029605b902923915d9d3312e4f1fe39f3463e2e71112d1141cf010dbc7e3a3f8a7678e78017521ee61a4834c149bd9528c74b936577109428facf98e42dd68f4d122240ccf22d6cd3f8ba2f7e18ca19e28e77d104629b58a75ad41921d560a0fdff0b5ab5e7bd859d844995d13b123cd1b22cac8b9156596d9bb826432ba6e7a570868a19cbe3dde8d9b671d78410f80199d15d5a14662e5822d28622afb93c11cbc6eec7be852b3a579b6dd4c7cd111b9fe695e7b5c777044fbfb46ba674c500c0a1fcc4e24adfff960c997fdd3b75c5ee18456b0a68cbc01148de3a74c26361acf63116dfc576cdea210824f0e4d5b987deb0ec20f3a87ae286d4a0d485b48d122e7b358cc2d0a3093bf2bbe9b7e849bd6415f556a2b566d1cafed687e373b2d2c7b09b0c3e550180364fbb72b4debf9c85211a842014f261d5cc6fd563eb996c110232820e95d11e63a259ac8fd24565fb429826b33d1b891f6ade48cd8d6257cd9f322a1c71b586f90e07779e310ed4afa93ef9e70e65d2e29abbf29d143a20c6ac153821faeb6522089c16a6b04ed2a11ecbbf6e8314c1474704472d8683b0f5c894b3bd4eb35f387377ed969eb525055b635c8609eac26edbd8b24a61604d970068d09bb52544d830cb1549dae7290d1ea20a649587f654d6884a019cdd3d4f0c823f2d54d8cf5b004f52f7be55ccee728fa4aa72c6a47ee4ed5a66d44b6d2d8a7afa2f34a527144f8796bbfde4c37d9d0e2316b92d1748c37d1244744979146b2b7e7e2b7ff36e2331cfbf3150f5d9a5aeb65f091284c79b655d3ffddf9a72cadba82dfcb171ad8bdb275d516f28a446f5a0c4b8b2a244be1a5aa22621c757c38a2151976645da68efe8f3f5f4c6759fddf6951adb56e7d32c957917669c1596cb60541b4490c33f9f6114627eaa32fa3ab284660f9029806b9029439bf1f5cb8fbc6e722034fdac46826f1c3ea0e3df19aa95efb1f6f4cea6a15705d50fdb77f192b9be67fd2579fc6b4dc4928499edab06b7e14996db246b2ae2e952e2696388fd6c1b6686bc94302f960d42358dbaddac9aa3e4691ab6386b75f9f141e2be71e8864e992f69b96dd3bcbe6901980eff0ed3055d37d47a78ad48f12f01365fb70cb1a18dffaed82cddfd0a5fa52b3abcadc58e6d49152cc9ba59d08510410b4ad539853c785826f775eda7a5844e4e652d6d4425598ee6fedc5395428f52f44b64d096c86cd697c3628aac1a0c8c88e2b52c590f9520db8828491ddcca64b1ee7750082df1fe7ce38d4e94ba71a3e87dd528e89369b8e32dc8334506bf1b7455a49d3678d2bfb5dfaed5da5315ce471c2471097b25141a650b750ce189836f42f52179a4daf3c6ac9c292b00ce7ca7ee3272e6ce90827d7d695fd825de5ab42fef5278cdd664b02a7531d08a3186ba49bbd04c095fb11ee7551195713f3e9f86a51d1062b7ce631935d5239c4267e96eb5a542ca4bf98c5af2699bed72d2e7b40be9d597fa8a7c2b44f1651b88733860e1ae192a8da62a8e0f00723a8c575d37e2f1135a1521be2aafcba78d6967fb234e425a3fbdf50c6dd25e532f21893a289e4dcc46352b1aaca9474c0e91335672ec589517d81628aab68b35f5af992bc3f3555e14a4dae9835ebb6fd4f2cdf516e69ee561931822015087db4cfc8f1e8e4ef911ccbefd09c1300e9931d960e938728d604412d39861d6630bdda559ee58b5f31149e3a8b998ffd194afc4a7370dff38b5c0c9cc4545660c5d87222df0336b8882b9b5a4532eef6999971135dac888232644782b230799566d105851b2ecb4304ccd9b78d92635a85eccd33b10dc0bee8cfa20f28aced44052d6472ade3bb036aa385fe64f67c9abe7e910640f9029107b9028d399db13cdef0294c4267aadf8af8cfdb86842294a0339e09b7738bea81329b63ef6d37a3eed45e43d263b996ca222ff5fceb9ef496274a9bd1eccc32fec3b7a8ce1ccd4822093efd91ed6bb8c70648621b35d2c3007568545d35250cc624dc1638c1d419dad47bf70d5c261682292fd8c36a364d69fa46236533acdce7fbc6d748a22c5467917b78e3220d0e570f048d0393fc139279a72299182ea6c9ca45a12ebb00aefb321b6d977ed69c2273c41dc6be753911345739054c22db989e8ea26eb8bc8e44995e4d1173bb0d4f5ea7d3468c5662955fd72af09ae1a3f11340d44f1ce4066dbd84a8924bf4bce7c01bd506a0f22b72644dc069249f29bbacfc1ace3b4c64e269dedd34d90dcad078fd3144086153460731fa8fd7b304ce4abb2c0b1ec6f797967bdbef459a60f2c758e50fc320a0faee56b9ef7b08b51a0e57ddee304a636883b0d883849c3ced6b219eca393a94b9978b3d0d80e9e5908efcba4dd88d68347c182320cbbb46a1748350ff9aa4d4dba16bfc09e4b6f9153bd44351a1d6fcefdc86ce712a8223e35e67fce8ccb764a22f12f754d2b98b6f364bf684b7d81d9ae5739f5936679eb3d8c4e314e95f075a4c13d6e33648f627124189976c31e63fe683b2ed5b0ef3ebefd847bd9efc350b0b79146925f7eb377177c89064a73390e4e3ac16a8d2a4e1499877165d617ca865eb310c98330d29878658f88bf393c75322edd4b4f54b5b44c0decc1c848e5455c84739c4e8f7e6b4bffc33ac6b5ad67b2d8a25e9bf05bdcf9e3d6a033f733aef849670f723a34e577759aa8e2700c3b484b982e2f23cb1ad93d3112631fcc52790a34509661b6063d9673be52d927c5387eaa08e5e50520c532f7942ef39cda03323dbc22b59b5aa15a875bff86a6d7d5298ab92cb23c7f9029508b902913956092a3c1cf7d77236e5155b295163a86e729aa27f4ad1d86713ad096b1f0dd0256dee687947bae6ae651902071b409dedb78dddf652f0d104bf8fcd9dc963895464fc78db7b33e956781a645546d93b9b652f18d9a2ca7639314a65b7669b38a39bc80ae307aefed377ec90dcde0e1156b294c6dba9b53d57b8f1827f677066cb28d7dcbe12e6bb2cec49a968afee33e839931e3ca1a9a53136d3b9467633195257a6744f2fe2088a389196f53e2f397aff973ef05931b0a2bb1dfec01c077dd08141e53c9e59c8841734d0600afc6ce87e13cdea5641d24e2b14afc5a16ea44b7123bb7b3c5947d9d27096d4deeb7e2579c9675a614587468a108512197368eae1d0326c40f77d261626fc416514630e4b97e83e05e5edec1f9dbe1662adede42a4d22518370695396a6aefd295ee94293d5b3b57c541fa3d7c5b0ac95c99922677ea592ca0b2ec491e3e2fbb2598930a677a915bd58fb8e77497740d244cf11da8df05a3d1d80d4c214ba1c24e2f789210f4d114c2f6915237d04e0ee73a5866c90d58a12a197ab1803624e38aa9dc7a396730e2d174728bdfa9fc64d997627482ec242a7677173b50ca2e8a76fd9148656f66e0e41f86075829b1b90b1f0ec60d6ee44c73d0472a482f35c7dfc4229a239e5908bb18585a8d9337f7b6ddb4b9a4823c88241cdb42aba59a41b5954ae6c731dc50e206bc8ca13aee4c5d0588f22fdae3366bbd9a1c1fba28b7be378c2a07afb0685af6e7916d464abdd989346ed6ab552957cd133cbee3f5dbfa037c560a12d3c185512e27f4beeb6beb8c90954e4ae7b4e57277eeff0f26581c797da31d339aeb5444e3e7cb7e8a426d67532301a1cb4fd2cb873f0d46158e7991a0e3d429a35527d0cd383aea1262a15aadc93c218a6e2d9406b99380a670dd890",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x732af524d8305c4ee0ccbc545d5ac9d231b929e61b2ab05724c1615b2918cbec",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x5f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb0",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xf56410",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x0d9232100d6e30e32126a0de4c93933a94bdfa17600f3233299844eeba063467",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xbc576d5732741ceeb6c479513eebf6ad2f10c0f0e2ec88f2915d0fe97c6c3bba",
|
|
+ "timestamp": "0x6a9220c6",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-B-9chei-anchor-16081936-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e382d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8413b87756dcf46dd4faf062f94005d8099f47992cf6f2ab448ef83ca85b4aaabfe63de5257cc9725426300539fcdd3ab1234bee7e1bda5a35fb4158b867ca811d500b841ddc11755768df4fbce5e1e44d8678f96df0346e0a050c962213be05d8b39524758b49fe43d8088e9a9c02feb25abf24227bc9f549eef54b642ef817a464c1ed100b841ae7a972ad48c369365ec5a4a05a7b33982b56a60a6585adc524845062ae09a2f706d83b00aa4c4301db343e848b2202f0bc8f1b9909ebe99d34dc98c004c20dd00b8415711647e596263fd1934f6a4b42f19a1e2d1a506c894b49293368a095d1e6aaf00678d6d3ca64b6e141722d43c77fdd01afe345a84352be9b581b95d80c13a9900b841444d6383d76805fa3150ef8569a394654ac0fbb5598ade3e0e8dcd1987adeacc0cd3147ae347f5cbbd28eb6eaf0cd99ce7f24ec73e976ad2a43faa254ff1733400b8410242acf3b3383f96debf73d353ae3285c2a61ede4e0961aa10dcdc605b45f8d40c6364b2abdf5c9e374f76ec55b4ca5ca788557179a907780ccf92e891328aaf01",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xde72c800eb6ae1a426389f0e3a24ced0852e9a43577c484d0c8d53bb0225eebb",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xc3314fd768bb68b986e80c0a14175f6f72630d7a",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xf5a40f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xfefe924ed42584d1d6e8db7e8f04ebbb59ee93fcf60b5c84d90654bcfed0e62d",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xf14b9abc5069acc62b01f0e5014998b6b8e7be89ad810a33232218fa1e2820aa",
|
|
+ "timestamp": "0x6a9244f0",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf919b8a004b109632758a4c67c5b13c6ca29a136fbad975f46f690372553d3fe17b49673f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841d24bf4112642c989a5fe07b85eac112c6730b6f6192e523f0b1c07149d408d9f448389bb2c9de63a88cf4939c719f697517ee30ea51bcad5b9d48cb20be345f400b841a2127891b67c537b94787d1b876377b400823a22aa6748133f188a07a4b3039840deff33b8e8127b4686e1846810f827bf337830c60e594ebbb3b587eee8d88401b84105f87a3319b5ba362520603f19b3ae92748c656ae8f1a5ba7bfc7b0cb20eb0ae0a04f3c4d5b62563edbe7d46486b03e957f9e1fc49ff80eae255ea75ec8bfb7801b841b8db35d504f6b4018b0d6de3dc70409521cf70854ccbc182d8e7adda730b7b19476a80976c3fefeecf92deff29eb4c0f74c57b821b6a2e268900f1e67b59ef8200b8415cdc4ba4b698ec38ba837f66700ed0b4504adf0a402dde16248084983cf283fc5da684943e004f56d0dd7da79fe118fdba9d660703a1f60f138bd3ab3cfba4c200b84163624d156e0e357929e9cb1f509ddce54edf2d9cfa3ba377e51f048773a6c77e0dcd9976414c4e1edaaaf669e4b9688c43365638bc59dae21fa1256e36e35b8a01f9173ef9028d80b90289396e1df374e6fbee16bd527d1092341a02786f1b011843fc42c356404efde93a435be8ca9e76635bf1c34d0ee24e7a3eb79f75f1fb6b14d7c72e2adb845bbe8fd9282b2316ec6d12f9b567111c7272e5ffc2c7278c46bb9508de902ca454c4737d560f6ea77d48b947e492cc3cda55ea3cd7c8e70621ad5197949d2dd7fd998882598ce0cfe99a2914c9266bd18974888c2d5541b99eab338a2f92c93f2c0c5a8e9ff3957c323797d339545b5b7a5b6ff5f63fbc816632f92b22e7e6ae44d7ce9bcb48dba9f4138f162850ee962eed264249f36f5246a04a620abdd15585c21b02206cfc823d799c3b4e0b45cd5a4a3691e64c29d9d27134a1479d561312f8a74db741ee238fa3538ae0c053fd4bd70fe4c1d878d6b98692a3936a35e0cf6a0e7de2ff1fb72efc29bc16fb0cfade367cedb79ace75ec0689fd83e8783529b7ee9c93302ce27fd762335338eaa53ce061fb9d412b99411e2cebf4a22f5bcf8f7131feca9b5dbfeaa710493072648a752154e7c88b36c1337d532763238cff9ec8f0f32324052a79ac1486d90c7e7ad84eb6dd815c3338e2c2aa650cfc6b2ae74bfe8ad3cf1e8fabcaf5a1e9af6fe69f2c9cc15f5130f8b676034985335895ad86e6d01b0ca16593a5cd274341b98dfbe7275a75977639b63d05751e9b51f0cb5d73d687ea5843eed19355b572b860c8590178ea14a4e7914ac85b50b675f2c7b3a47ad0fcf1d514a9f4faf051ac953f66a4fca471dd2f030094a2d5997a39e6dbe366396dc9a2609f9855a167b5a539a27897a089ea29899b37d1edb6072bda40cc610f19671667d4bba5d23541d88efc977d1d7df7a03b0d5737a183bc317bee1a2b44fc471994a97948adf9be0922a5e2a8c986fdb07b1158c5b3a3ae6c57ec4dabfbd09b681a2d74f9029601b9029239531ef1eefbd794d09a6ce2e1a5107ca40ec846d7ca9fc64ec14ba950217c8296a7938c34c768d72de26e939307076ee0a4ed9d50d2ee5142219479692550d60267a9de6d0d2547437531724cde71965ba3eedc8533846c93dfdfbd3a6ff1a92c8a6347d76eb7ed53310413f6be851326090a7fec4704ab28fff63ed8d4f133d89226b724773aaae6556b532135ead920e4f5bd6d13ac8e17e942845932692420a71096798ebeda3ad6a934e36eae990f219a7ef39b6e47bf5230e8c27ab7ccb89368ae4ff49012b98ae6b5e59a284752ae5f199d23f651f02381b08b2553edc1d8dcd4f3e90ea3f193e78a7c55399dfbfa1408b62cddb4a6355d1ab9fac0ee72e87c56c700dfac3479ec29d3fc9aa413453a66b2583aa13dd121a289a4857c040c862b346a7cfa1ecd4495724576525d38cc2a26d6b9f3e40d1bd2c5950e7739be61ca5e7d18369a8e6e2ce7e9d7f4e3ab78c4af286394eab76d3ec664ecf49b45450afc60e205021adcaf880b8b87ff71e5d238c464b4a6d9820573edb6f0bd55aac514797c1b5d6c6edeff36fae4c953e17b93669cc80a7f6db3d2dbfb74acc137b5fe8b1236fb932d258d76a7ab7fdc6a2bc3c14fa6946ae4d28881f1212d41a5c2482048fe6ef0954a69b10a332cc3198560b8b067eb205989595120c49d8e3aebaefb23d98d4fa8ee56dfdcdcfbb5ee6c212dba6aef8e3d9e0ee1c809d4c90bc7a218d6d1d1dd624a34a8c9ef10484b8cc2c921dd9cd90f7b55fd9566b98a60e44de7671658590b7e0730a6e5d9ff5c916a85bb1ba86204c09de9379497f99c75c29b0269dc145251c56d13ba931565dd37173d50b2ee983886cf00a736999316c1b7866610aa201194bd45379d544e18fc990683a25266891ed9a14bbce4c122312a867126b6de27953cd5518c10f9029102b9028d39de87eae55d05e5084d6298c5661b2f111294fd7b4305d406e7882f9fc712082f1d82f03d4f3e075f4741211dad32319f97584d4cc9e28be28a76738db53d9c814750861d2a579a0fb12373e8fc7b4d4fc9de749e57a6d740b14e5ab76b1464992cf24fa5635095650baba1883dda8d3da8d89b8b647d9d963b3cf862d94661ec31ecf1f7ae517a9ffa4433870def5659ead5088164cd671d9d54170ea5e1bad360a14fab3953e36ac48b16b9d1e40bd6b3288f4a18b892b512c9d7a2035f813ebd2435b6c850add57b1ccb87b4a7e47c1fe7065084ea2e98725cd611bd147d1e75e468de924445afb32fa656cdb85f29d464d30ad5c454b7ef3cd944234b138cde32335cca3077fd14c3cee51b79f49cc4332bc316d67177cf3dd3cd4feb290a72da6b6c8d5a17c07f53eaf519698bb5049a3478e0e8f3056350e3249e37be6350e4d724bdef4c48eafae97b58ed15cbb64335984251528820a31329eec1de14f5eec565a3fb336a97ea59ad5a4c82e75f284f0b86bda76e7f6db4c09cbd0de67128ebfce70979e19059326d7d55043258833e8455d206488e364ec7709ec898a6121c90314adfe9d14230ca0c99f0d0e0d9765b1ab66873b67be589a885ce7784316467f4b294579fa36e74b127b35eccf6bc10e4cf9fea997034d2048b42453649ebc395bf74d99a53d7785fec39dc1b52df24220ac012bb53cb97dbe99b7fc4e395aaacd9930d6bda8827ad41d3e8e2d26d1d45092308509d14365a71c1f65ab1adca8d0241f73239ec8f9abf6adc3c2eb2debec56eafdb748bc68cda43e678e28300dcc8c8b9c8274c7915aa75fa537ce3d7aea710b894df1a80deb82ada30b841235fa875163b7094fc6a462fc2f6b0eefce2b7e56a4ccb670f76ffade376d259726a85c51585a85348f9029103b9028d397f97c7aa15d1866577f9bc12263b16a962042d2b42cd7f3214cda7cbfe61cad4aed1744861073ddf87a71ea82f7b55e560c783b2206dfa2ba19d37bb5f6ad1e84c954a873f0025109c9ca3689ab9981c4435ca6395cf84beb48fd11e3dd3b2e92e1a0942189e32972b1365f07e9ca6129697fc1df8236ba262ea6eff2bdca2f4ec106662b4f54eb6698d9d1b4ea348c402cce20e1bd134b74509e22971f9d9e0bf9f26877325a0adac33529241c4c53c277158ac093cc2b8f0384941c56e19bb751d856f1a8f29928e41c854e0d6e772cac40dd1b140a4ad95f513d7fb72e70b11933c3cd87a87cc4a57bc9c5befa372c9fcbd8f51585f49085cf4362f732252ae462b8efec5f04183db5b9b3429c8f6525a76e1775ea07854f3a8c66f1213daa8ed532340cea2297c49a36291a68f3f443cf413f3d89a31c23c5f61f62a7c874a9cf231bba83704891cd5a0e78e076e410ae629f19dfd1a3faf47d784e1e14a5a9d8b115f446fef8ee242c6f2ac3856e579ac9914b4c4eabc7a35cd5ca330c8463a4cb0f0f40dee8ead8cc3a511625f12cd9347129fdae5b58e157102a55937f7ec1ece0561fad0263e58f4bed91e76138921e58e244af26966bf4b19fd12493a2536174a0c6e759954755a32a8030f508cd266bd2fa71fec6ef0e6bf6f3aa66a737926524b7f9bc759ba93bd52e9a699ff8147645d7f32d71f73960b6f6797c9cb7675baf441407e303daf8a28a4aad952595686344541f886072a5c649d6fa6216b61e0541dcc674cef4058bc43c3907375bbded115efdb2ede4fb130c327d63597279c4027dd95963a85ed5898060f1647df9c3bc588b5a1877ea2c153907a747d554a8ad1c242ae3b3c5f109f2922089c7b714723a3eb4a4c5c432b889bf66d981ea649d68dcbd62c7af9028f04b9028b39a4109c7cdc23b032f58c7b75dcf7c158fc3fefb58232c12d5a285ceceae3b343fc136af19f9f4f9462bd27c495ddceae264858b932808269a8dffcf22113d7f1a3a4e927f36b5a35df55c0d968e1b60b6c0e098a4d5d641b10c2a472760bb53ae7fbfc3473cd365af262d520d2401e8d4c85c3c034385f5cdc82ed6b2b84eacb51ede9da0686da9445327aa347fc8bc2d1553acd98bafd1e77e8ef5ce75b0a5b3c9c415d04de112da8378e2b992450abffc38f47685a96730ba3247a7d51ef63b345e1897a6d16647726edc3281a1250b4e653778746cea0842bdaa01c4d792aabc769fa2c360dde8d50573a6cc6b32d62efd2b52b49ead3b7fde842d294a4936c6ec8b432844520bceaa145dab8b1208d0367b352d57c5b30b841e82a27a2cf619ab2ab6b546e7f89d71f6dbedb959a76ce5c620dc4a76f19b1aabeee3297e1c5a24ff5eb81db3f1c02348673f52a2e27993846692cb308bc3b9cc75271f1a94aba3fc84c04db6823d2435fdfae29d8d343655b96c916084365301931b6e2bb15865d6cffb155b86d22bdae371599d171dd340b9131fbed298c9a91d28d7363b3763306d78b9e4a799528c75e25a4e734497fd753b6d22a682e05b0a4737356763d04c9f2e7f9636a4d28110a167e46564aec55b0d633b89352ffe261718b72931828151c298a6269700591ddc514394d9289f0697078f289745a26de4d2efe62c27154653a3081dd295173b4f3f62a517d7d1aa48c3897090f37e1ca82be8f5b206060bb388eededbe62b579f53b4363b3c93e7439b73360c4673eeae547f0c0a6a27c8e20991a1cb9b9e3c1c9ef8694ca20e31347ed9ee3c8a7de21aa148ebf6dc5f66e9bfa037cf9c7281bb601ffaaa2854fa0c1dbdd796a746ded0e26f4654aa3e97bf9ad3c3d2cf9029305b9028f390cc2bda3f5f85d2c4230c5c61e20a49a0deba9c5fdece7eea853b12ebf3babf07c339d4570a60e4c7bbefce7b7d960543ecef62986470a9f3b4d39b9fa5467687058dddecb8d8684bb0cef7231005461ebde922ff5d04ea2b8f29e95cc67f116650363f6703641597f24b21412be8491b42c6ee484990b3d2467d2d0c2d6e75e1dfd926a541dba2857effafd7d5275464e1eb559026f66fbf70749a743f0d67dcec395f7e5e61a47ad664acd1dcb12c1ecb5c97c3542ae7e8ec45327f1d8c4d86346d8a95a0aedab1ba561e3a31132962ff3dd45a1e6439e36a2851bc44958673d37a0f7dd06921b666166942cf1e5da4de0e429a7319558252e59247ad696418779111ffc4d844f70ce2b358e6e3f9b2a21828a2b704982c5069ee398049860f989c30c45950bea0addd5e6b137b7d39dc4aaa80c7aaceb7cf5dacedc714f655d7a0bc26eb3bf9e3da18c51b1f1ac7e27c3c3f5369938b0f4ba3794867a6b292bba60d1efa745f3adcab3c24d450f1e6b3d50a93c9adff077f52e2e9bf77f302470aa328db2b5e67335bac6bd34420dfc23cf5886664ce93e44bc0f9f9d78cab2e842a4ecdffab76fbd07bbf55792bac255cde1c76c36a4c3ab21a4c4329b0d7cda418710264621885122f89f55bf0339e823f0444a9cf97cea74c733fc618a80cceb50c6cc93a37ba99ccf10a529b30561867d94d981a2d5bddf479ff7343a0d11ed4d52047b4040a2886f7fb6eae96008ff084608e24263bcf49a7a267bd308529df1d4a2f1d5cfb7dc4397f81a6ed8db1ae45541abbbd267e52b51c4f85b7e8e6b5a78fa397d9596fc9bc4251dab663441929fbe71ecbbb53ebfac00dbaec8a3604788f58f59965f54d9caa9bb8018da24b5035b974ce5278eda1229e69660509a98397e5592addd553de8c0f9029306b9028f39d1fd9baba22af01781f081ecf31b9eafcf6f2a2598b5f8c389a8143f9a84dcb4ff5bacdf29e9d850a88a2653fa861189c7b52675f8447f16fe7f7ed2f3129b3e61fc716f2581c556164abc3fe8d266edd4b5ed5ffa137c69c751700c9ad0d7ec7cf3b9379bc46fd3799c4b08ad1d3de6d605c6f2ceb318bd391a7d6abf030c10a42d9d643f98188d4aca95752b9f8d2e0ca1125b55179d9e67144ec34f63488ad324cf4d69d584cb9eb3d31c76bee5aaae495b6c2d5d45839a57aac94a48664d738089eca2fba526c354eddf88cdb1b84b6de54b9187fb761da82a2352a5b7b823a4c1c8dd2ed5471644b0c87bd34be1c88ba308e4cf98362f5385c9216aad65fbeca31543b1108be6b6792f56d70790de263f632d07a9aef12a4a26313359637d3a62d84b4719184ed0b5aca966a8fd8ad3235416c9a42bacdc9856b302427b12446070b08a4685edca3e6af4eca835480904697a8f5eef2ec29adc2e0a043a95163201b57f34fcb71f22d88a7cdb632e62a02b7328e0afdaf8e586198bbefaa479163c712768196894a30e2a194b9d3c78b46b8f62cc923155f2e10d131438b14eefb60519439df96eedb79a34b9161316dcb9b8c4d86bbeca7bbfb94211a87a655a8f9d8a31516da2f5dd76ce3914fdd32d58df960190aab3e9ecda63358ecba1f6999b7392857788ba5dba92d5dc687e4797ad8a598992369931e5d0bfe49609b54cda56742c5d6e97f2a460963c3981341976b9c575f770099166a7e9bc691b3d2d616424aff8a7a41e0513f8f0c95e4f3659439341aa668883f28c23c96c8e6afa8f4379485e1822a7b685f4d206d5b524d7dfd73970f974aed84fddb1a64522cf06691ad3e04dbae0d73972d60dd1c8a6d9ee919a8e128246db390844c7664d5e775609b9c7228bc2bc80f9029707b902933925b6a348866a85c306528bab9c11b93ab388fde5f9ef29b1655e42a81893d4a1d979d933b6c7b1e5da79a27e85ff30ae308991611b7d23291c73d3225c4398f2258d110b7a7f648d6666fc048db48618ef29d22c8f197f88c79ad556eae2f388c3e2532a2a7b75378042d092491b7d38f1aeb719d899a1c53e35194fda934469658bf652b4ac348cff44d56116a92d6f34a83b195a1e9997db89f1de67740d6d4924cd308e8a3f39c691250ce1435e880e23833361a6ad33a9a825bd7406450c37b23d9a60c285824f4cc7afd1e3872cb2eba9a9098adb260a02bbc9ca44904749b9a427ac62bd44d1e9385ede2e61dad4bcfaba91629ebd6fdc478a82b495cc2a76c5ae19c85c97756dcb7011d99a20d111988989418daba4c1ba3c1b4922ceb9f0150eae78297c0e81ddc9f87c8d637b8efeb8536572328f509a3c94c2384473e349073f3f179c91be65258d201d1e314686c235fe5e5c5083481c9705988b5e3351648203314399ac48bdd962c894725f71f2e7e63779c1974cf36b1b13161a8b76ce0e6c50c4e7853db768d7690629b9b3e563afadca2dada9734e2dc2b5876e71599e5f8aa0614afd0b4f946e23a490b4d3d283811e2096f64de2b6b1a7e5882588396d81d398042dbd2111c29b8fc4c156177e9e81aa586aec5d1cf9ab58ede7f726828d3a9faa9a573070ea868ca92e30cf3d69ba673aa8913e1dade2d487eaa8a4c4f5b112023f37eb690e125494b8ab9365ef70e738e63e0bf6ce2dd447aa85d57aede322944a5d17b51565a017185fe27dd9d875381afe21eca2ea24f1e61d6b4b20d04d0972725dd8f572b5f5c92d10eeb6322eb06ab33f0224cdb6feedbe2a530bfdb8f9944d14f5575c513e58c48f52d2fe9d5dba2d0110788b4a220b5b0446728b766dad88dd1dc34b0a20f9029208b9028e394ca520abb4ff76ce27bb0db37cfb7ea477c94fe19e7b5bace17718d300997f8460ba77f61b90928ec17c4d271a51d41c7b355dbb2c7fe74342f9f5e48cb217a280747504c6a7434a65e9e27cdcf99ab6b6ef1e21f78d74119e681fbe221737316ee6368537a4ed50f6a7a9a0eaf2e5fb9a4fe1f155e29d4945e5095d95ca0a90a2c4ce3b0e3295b78270f13ccc1d0a034a7125149d046c97443465f98cec6a7c7d5d467990dce8ce239f284d60f0d6b98588a0894cc6e4674e4582bd2cbbb3c642c707dab73124b49059df5b644ddc44ba1f06ba3dfcf21cbdfc4b36422bb632091e616ccfc278c1d43304689a9176e1055d17decb5d00a2e216abbed54c5fd807e2cdd58718163aed97d726b6d9fa87cef8b4cf8dc1dcb07ad3972dc5219386f4f920ea457b950fb6c821b568133ca73032ee5c7fd0cb35321d9ec7919fb8d1996d1f7743bcc3e790321d91432516e8a4b67f54d9a2db5f171f3def73a2b8c63fced1d3d39a7f49a0ea4babcc82348533f99345938246aeee424262be17b39f9a29d2c33029748ca217aa6331463d59477b7507c5b2802453b70cb223353e862c769ca6fa298f8849d2a952610e496db8035741f9b9aa8b1cd4b4fcc6237274d25f460dc5bb36cca1bdbe6955f8ec7dd98f49353bd371dc50dc9d1b4b1b61a67cacf392c49e9419b9adc15fe8f3eb17415f899f3de9a58cb3ceac18d90dee31e1c69a080b7104d1c912138560954b1514a1833df2c438cb27f59901e77e236f7e42ed45c03af2e3192d75f931f88eb954382a84262e5ffb6eb94fb7ef7975ed7aa10330ab71a2852bfae73307f49d22233c84b4aa3946d930d82aede16eadc2185325c830f5ea4e864aec129d0eb6fdeba341e1b04b0469b062d0b6435f91ab468cde3172522f99c3df061c22",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x33ed75a2a0119ac2b4e18257fe1c045d4659330e9f1ebb01a556ba453eaf442a",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xdf09b32c761620c5be77da398b97a64f03c3980c",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xf5a410",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xde72c800eb6ae1a426389f0e3a24ced0852e9a43577c484d0c8d53bb0225eebb",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x94b7e2ce25f844528cb1a9505d888c36c81a47b949b4625139ad0afd91bf9c5b",
|
|
+ "timestamp": "0x6a9244f0",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-B-9chei-anchor-16098320-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e382d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841b84e1349d7aa6f0161061f0126681d3f56b8f4c5d88ad7808726e59b1cb6ba6002226911473afe7b0ce6a87764558bf9045ccbeac9ecec09d77df70c3fd112c600b841be389cc1825b59d51b3f47a72a34c1331b382ce41ea15885da423f1d67134ea34dab45ac7253b28fd8672b75ae1d1805a558fdf6630deea26e0a6d630c284dd800b8411893e46fafb70dd8d8847e4bdde4753bbb2ad84605cd6efe9c94b402cd27aec4669a330c40c3896e77dbd34cf167662f63c76bbb121a711013b1c176353ae82200b8418866650b98e7a98f50ada9743616f7215656fe1822a98ccb0acbc92ac5d6bd351cd2af6bb99b4218d4ae264711f7fbae2ef243ecc647bbe1fbf466fe27c42b7001b8415a77e51df80d4e8523d5b409ce5075b611a0badfca7e9faf2c137c3040a326b71b57456dd5a3cbd81b07a181655ff64e129b6bd115d3a1ae1a191258cf1abaee00b84149de8ba79d629eb595715340e1ed549afe23a314a95ae551ac98b04a09386d974e3956d71bb0ebf5098e39cd1ef5d4dbeb0853c8a05db1c1598229f5d7943aa600",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xfee348eed674e6bb95e014c63436dbda6f3a29f27e9b82d23a4e52acf8ee76f2",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x1bd5514286f5602a6762b0075266379d29af1c9d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xf5e40f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x065ffc6004ea62565d3395ce8079129cd19014256c235be1d07777575a220539",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xb1b6fe2e310d1f032a1936a1dfa3855fd6dadae24a311af86eff1bdda6f0de9a",
|
|
+ "timestamp": "0x6a926913",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf9172aa0d4acad274fdb67f8930426a8866e428f2ead6c2d6e6ae76629ab6de6767c00eff8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841c8591f120860f35f3f6bfd715cf2297c1e5ac7a5dac95fbafe82d3561eddddd91883b159a502c67257d6cc3952ecbadfa86327f6c50863ff4bf2605fd375b02500b8418e32a6a6bdc72656491237dae2016e69de51611020bf0c512f5e3c5e1566090e732214fbcf831deed270ec4a621f9eaf26516af47f239c24ee833844aa87c73600b841c8a22950ba0921deb2ca0b437e9a5f80080c7d851645c5aca5cfd2f2e1287c0f34cc1d659c8496d1510021dfea533ed4e63b6e7bffa5f5f610c886d509f6ee9400b8414796087e72a12eb36dd96678171274ad04c3e02ff345e9a55fe70ee32bb46ef3158c8c34a61afd36d5cad282807d5a7b3dc194dfb5a5c028eea72a287e52fb3f00b841b85fbb3f6f31de0b5a5ceedc1214562e7a5e3a64893f2243968ffc72cb45030d13b8a40f30c9745e245a4e37dc73bd464bf69f1113e875e85bf2c5fc4b3770c501b8414c156f2782029f099d3d4345f0f14c8ebee53e06e130cd9571cdd963ce745ff117af3d8790e40042f02edd16143a05990edf4ea567415a8ec1663852d7b1beef00f914b0f9029280b9028e398e6a53ab423a3d65c1c712c8fb31ea15a424c0d79dfa655a7a00e12796b54fe458956e8d074ff8b3bf5834be46f2ac99d46477365cc328b02202bfcf662665cfae1d9c81d2233bad419549b6ac97470ef9c45af9323dcc484a5b00509034e19f754cdffbc3d280e4a4f2d721be9eed10eaa94a4e92f41aa287baee4f6278650e2fdaa3ba837e5e885c7494a67ad5fd41b87a71d51e134da751d28d4fa7cef3314536de5b76b6be9ce62b7f46645de8670e5e7632b4d83b1be96cb78492a539abf74b77bce7a0d3d8b2158121cebe6b383939f3294dc2b6ceae3abfaf84b0aece764ce2c15bef644f0fb576286fa3175786d6f1fcc3b16bea69b178f384f2f5a0aad659d07215ce5e1f0db33e68c7170f85965eeaead34310d66fcde107d2e40cef0c5fd1540154abeaa25a96c345c2d6be5a8b14b0c709678a125e6f6d3ed0c2b74a1a76d154e29f75facf243c893909e61b26528d857c9475be0cc31a679dfbd1a83c86637f9356ebb0993b62421b278157d7be4e228697d1337636c68ddbc21bbf446e4958af6271b8ae51f08a32a625b86d8d25865b07bfcb4c6e995e32c5ca8984f3d9679c5ed3b24848c4b7ab986dd009c7b125cc361cc56b7d8596217aba1e43db9c9c26ff5f07ba1ad742f25c7631d231ce4388b313b52d9493567f5efb34b22dbebe215066667dc172d9b411807be957dc13f99fd05b21a899cc311e7a8535d0d55bff3a18e127c94a54aa94523a67787815ba647e7e5b0b6a02baa2dc9e5482cca6a604399095a34d768ec4a6582e0ef3128aa753aec44fa86b539cb60b65779ba4624ac947a3702389d9ee91a7cf1f92cca8919ad4da9a90a09e2fa978c966ba053bb94c82a79b97f385955c25c82bb6767c3e1e7ea39af42391f8730461097d75cb2b2ec154a5c0f9029801b9029439018e07398979fe490b02b2e61c83a6184fc37fe74ce8d1a81ee7de801d667ba4f3a99db22875069a7e810d52088fe62a2cbb88a0fcb6e80e5cefebf2ffc94a768dcaa479fbe7335108ad2e7bd7c62e40b7670a9d806321927331cfc4b689dba740644c4c0cebe8159e0984a62819f45d68570fe423ff8fb3a67ad4d090b468b78841d6f645c0e8dd3b3b3275ad551685417838f913ff9d68af1588388f29e96615a84956a65faf8181765b6aaf97c8736f2b17e9a7fb1f08ecdb6561c469552a37cf773ce4c291dbc3fea5ad92d549ce55e1c484b261f31256e5d671b307b88ae4f2186141c3480e09a793b069e3354a2dd37a449c9c231cb26f5ff61e9c29ad4655040c6ad89e7d8f06dc7925bf5960922d08cb0561846fdbf2b788b82190042503a1793076b515d5c6a189998428547d00dbb75318e40d4ad165a190b83d7fedca4b7972a71303a0d0467468690678a87d54f351025315b6b72f1f74191a9c4f89d1b5d37b149653eb7940aa6b6ee339b74a9785baa9e846b85439447d9bba9c663dd9573919936705d9ad8bfb6f77c632c767667b1db96e49bdbab3303e475f3dc120b3f1e5500849a243b2af06f702fb38ce935888a38c72e323df208517f3dcf0d0dc2e1e04ae19885c5da2a6a23cc80bd85a7350dc892beca155bec3537995418dbf61f334763e5984b357ec1c533b7c705235d5b8c7b408808be3a77dd7ca383bb846899122048cf1e4d8d6fd983e740bd7f38ae04bba8b613d6b363618fa34abf015b703968776092ee1236264650908c744924b864102d148396c2baff88dbce97a7cde9c37638c61522a8230a094ae3e1171476d0cbe1d15c03fedabeee9b3ad019757065677fd347dd884fbb860861de757278c02c8cc9fb80b2bb772556b7eb5ca8561077a86fc4ea765910c40f9029102b9028d3905a00e19ce86913c21f6045dc4a3740d2a29c5deb20941bf45c8646a6ab28cb08fb1d48a713064d3adae8e6e4bbfc08ecd9016e94dba5d789acdcf9961a760d2434d9f5be2b7dc50a33723f7de8f767373e355ec49d5d4b28682c6a2f54416f91cb4a548f3ff97d0bb10c3839b8f967a97f64a2f997fcc63eb40eca155584dcf9dbc374ddf06b5b8f4fb51be1523e1c4d07924dcc78a2b15873f27ed9579fc9a820bd251f499f438eed9e92f8d1b4f3359e0645a0e304544964b1b6c1bf2e722c418c8585a8bd0d5e2986534b8cb369a53f7e47c35c79f3dde9925d1ed04acd5d456780093a0aebe20904af372244e19087570f8b71c67f28db3df0ed4e90e2b84903c93a91dc28958f4e8a36899fdacab93c99265d7502dba471a2cb2eee915aca57923487e1f95c306d277d7495bcb406ea8bea991207f93b1968af0f5dc5a4cdb33e3dd323fe8254e67686e3b9dbe66f5ca45350d6b8f49eab36f4cede74e9de667238add2e744ff9ef812d9684e66cd3b4ccb2350385f5341567ee14c8b76a2e849ba2af17619285e5dccdc6a6edb6201e16ed807099725e87c46f9c1559e33de86741e1c96b6eee6c734d8d7a7057ea2ee347b8b6d39ec7ebb311b5a6ce7a554e5cb77263c765c524ce51b0aeb1cc615cbd1b084776f5ea26aa791e41794cf36e4d5b68fe7ecf387aad4c79ec810a5775c7dcaa95d966c5d45c3b0c63e6b749991b1c3dc5bcb7b01b022febdb44eac97c1e61793ad9eed9d8d098b31099bb3687e912b990def20558b527db88f2791fdc3e7826d34ea38edb146c2d4e737282b4ad2164fcb1bf8cea87649c7cdc0d66538f5594a1bfddf675e8a4b5f81803c0e3dbacf54bff0e8d2a42943d024f654e51f883ed97d9a85e6b0be556c42cb0613880a9767a3d969ed0c0f9029503b9029139efad127a941693963a119a46e004e43c5fc26f5d7513956755b637b5a60a20f8326e7e5e63832738ae3087da8fc38124421a8c178c5c2486bab2e81ca1ed509c4c4bb14584b73363ae862b38afde41d5ffd4db5cd5820dfba4d47bd5de8da97dc24d48dd572eaceeb3512f76bd3be7c8fa0fce5c889ae70b13cb8b2785173163d1b26cf47c7779aced297a54f914642212f035b70cc2794f64bc1276dffae6bc9fc331dd646bf7b4f1c2c4fc0a9fbe7daf77cdc20ae6a5d3dfecba4a319e0efc24d8beac6aa7c8e61389330c601345192aec119c89a05d7ffbed3376ed35dc057f030a4fba7aa5335c64e3d18e761f81053f7c492c8bc355da49726deb0b1978585b63755db214cff692347ad9f611c97f4c6d4d66be5cef5a59693aa0f10899796c3dea1b3c703cc94fab893828ec1f70e1ce4e13417db2b747f1938bed0d050e1db6c02204da17a78bac67c6525461c9acc2715c8f31e8759b53184b5a270b5dfc922bae0338fdc471e42f490858648c7b509335ff157a0b338cca216944a12af78b36761467346ca26ce431f9ee21042826a9544b7aca0b591e21041383a96128a6b3daaad4082315e586168e034560729ee49d947dd6dd2272fc2aaf17f712d44df0d012f26fba08bae4bd3413e9416e9438c8242f5890d9917b8671639cb3cf644d7e73d7577f8322d6242c7634ead9a5b4f6a1db4f0d5339008438d14a862488c30ca420c587adf0cfc2869617e9d5efbd8ab1bc9d4b9c7c738970f151b0637bae6b6d4427a719f1f2e7a6c74ccdd0116b65c18c97dd7bcfd78e0ef7c1d3b65cd64f98a86220656f1d1c45950b795534930a6b9d27f61360ada95424c322c80ea5d13dbfcae8b35d27a3e05efa8dfabcbb2675e6eb189ac36bde4e2dc6719d6625789d6906b9a6c617acd927c8f9029305b9028f397b4bf4375a5bd776fd8863423d7b253c47384b0b973ea14302feb9a5d0ef4a51b603b622c6d827e44fdf729b4936072291f58e9b10eff3cd366a696748ea4a35132ee3a07e5f3f16fd2d7ae5f3e196555caef6435892a6ab3c1725eb355138f145f99b08026656f20cfcadb6ebf170aa6395cf44f7dcdaab0847105e07ce46e0627b3a9e9cfa7533ae6cbc4944599bc2dc97e618d1ec6271b5f4fa4255e6f2084f93a72998ce24449bbb6ca5b3efffaf18fc6f2e58285a473170f20f5e0b3f62edc570e6b19d41cf7923f21d6dcd3baaecc2274a7648d9368e9ffbb9e997e7395b981ad1b3ea4a8c02c490b50ba19168ac12783b4ceaa29039608da72f059643b13b8e25a1cb6770663b5720b2af7069ee2c85b1bcdd1c0b668eb32bd11753f89a74cdf0d2657292aa9590c3ac4e089de0e3a40f337483e334b475cf43caafc95ca3138ad8378b24118f609af712326a7004c5d71fbe0c3e43b3d8a58d0f28b5c49645673e69d8762359906e9349dc4da5219aaf764dd35fdab57d1520e6db26926c1c36858a77f8cfdcbf3bf48785fdb533aba6b9e9f3c911b2db7ed93c1f882a2cd679b8f417b12fa77f9b29239959da33ec1c5e8f936351296366eb6527bda5611d212a4585451176b591223846df4d72ea303932bd1165f3bb7b3c070d0b8ad7b8d7e7d6387873e8d78a4d1ffea278251bc5ffb3e9a5afc4fd3ad7651e5d11b39aaed989dd1366e193099f85987d3bc8fcb07860471f5f54c65cf00790f2e2200416f49775bf91686c055fd8ad90461b833532db3f96fb13b9cc7eaca8ca1350f1d07da61a96af5e30e531a0c4f508d10847b4a58f2592405a84d36ad86b18d1b1d1b4091a54e3c71a36aa42c03b114c8608efe1e8dcb80a5042cc71f5dd65a18eb68d7dc39a3ce591f243d0f9029206b9028e3934979b51a19bf90bf4d498b48c860518327f523696079ba16a3f0bfc71bc67911aca2c8159f287ae1e28b88acaab915ad116871c483f08f41183caa52e224e99ec345c0d795ea51254188da28b961d75c22c34e9f3c97953cebaff3bb55af7f07422186314cf565097b572772a2957d7632ca70d0212c5e49e730ab9247531dbd408dbacd8d8abed11783e2da421d8d65af094ea6894ae900b6d1fff9b78d52c32384cf3e70eb91b9bd45d04c252e552455186e1e155e7d732e1c4a63dcdbff15768a1e3d6dbbad428e9317b7cfe8b53ebc7cbb5255221339b2564661102c6cb0aee5490f36fbb1dc8b26a368c5f1f68ef341132e39445d068ac85c04c20e4c2793fbd592c54cd6acb0d75775137ae15ceae4338e5f20ee59d9b93f6813812dacd5fb0ead6720ff5df9962d79d59e8f4b04f9a4f0010ac45918e61b24d1ce953ce401a4415fddb5e1303f54049591531bd92e6aa8f0efa77667933d1f43365816c5c9e53eb6a9b21d2293796c43d36f23e89ffe00c03f78bc3c9d23e0984e0b22d9b8f6276e43284d64fab37ce6a124078bb7a0cd27e94f37cb6ed143d056ff811c489415df1c8caf0ae353a2c0c1b775e4c50739398512be9d6bb67122096687c02eba8ae2cdc2a23516eaada2e75aa32fb184a92df75717bd643ceb763150ddb234e2e82daf5c63028abee92ee328cdaf37b655f54cbc77380ceb9f3cdc17f3d9206a28a84666a954dc311416f597eb7598329cc13a504efc6a0dd75713cd8eb5e79a411d6c9deb2afe4785c48862787736d7a8d534c6625ec8de88dea7894f81a5b2f3ad75486ed243408e48ec914403b681629846e5e0541205a8fe3211b8a6bcb3fbdbcf0afedf14bf240e92e841150ee2154fb5da314458879f060a81f198e06cdd4661a0d646dcb9740f9029207b9028e39e02343c696292d9dbdf235e2894ae08e8e8cf59e73c656b60f0c348b7ffa2ed57b2470daeb40f72efbc532f59783e3b098509ddd0af8aa4c6e1c6deb65a07efd5998efaf984344c7bd0b9131c511a0897b1e973ab7304ddd3463e1dcbb4a6eccbb5ae545b9381ae6f76dc97c533ad9828464679489a3c9eef6f7f319fde257ba24ce21eba5b1c5c99dcccc137e94abe2e4c5baf9c86c50e7782cb19875f9702852d735438671318d56675cfb4635042dec9162ee21ac6a9e7a6989685428366640cacceb983de25f266199abeefd548fa9cd5513828761f26b31c487b8f832654ba3ccdcf6a98988c196f2b29a40b3121bce5f22da6474e2d34080775e7b9ac771c0f159e534c149d2397a88c6615261d640f4661d46b1d96039d809ac6967d577e50033a8199563b399cb2712d8888f924f072e5226dd05210ddef3549cef8f7f4907a5c147361fe6dc642f9c1a6fc5cefd36576afc210a54594d7d6af33589c79d5ec941da4ab8497afb383a51088c3a78e6cd774c8b5994977c1857d3e01b0587f71df414e6319858fcefbc4c9321acaf3b4c8faffe953e938a656467c0fe5fe12e05c5a79ee6eba9d4b1bd35572837c6830c79f3ef4e717e90d1f2bd55f98bcde521b31d24fb477aa45f97d667df12dc73bb8c2e274ec7292fae12a6e850c69dd4da99f72ed55c8d29b8ec83aa972104d2509eee3d44591c216272c17bd2e90dcdc013a68710c590cb22bd8844c7539f30cdc7585ce3a66b3edfac3ebf5d91c244f3e4e715b9e4a0b86dac4538b9428a72a161afca559d7c93e2bd558bcda4cf11de210a7712121fb4193e5281a442e6f63572f79251546cae49405592f15d97e7666ee2d3bef8d8eab5c6690db612f825cfbb72a8c56e0e72feccf5e7d5bb4e38e89c8cfb645c74c68480f9029108b9028d39eab99fafa0192f2afe7731c09c0f0118eba694227dc4a688daebdf558162480fc52cae50f9f70c94f4cdd165d5c82685e652a75e45a26e3b8bd33d192a79c36d7682110e5f4bbfe9c6562f04c1b79ab32edde28a89443549d5ae94cb203758b3f7bfc53e0f8cad352e894141621e9e124aa864d6afd4edf7ab6158322652593e7722735f51e2cc938caac2497339c9b21b0d02bd2346a010749d0e71e05e52b5c559fc734ea693eee5d1547629a18e619d5b756fe9be304cf721c353e378222f77d8275d9876620cd67ebbb4eef60797c0711d456a2c5214a2a102dbc1db2cee2dde8913fc0113bc6118a75b384cfe58a95fa277c445f432c77b93ff6b7533ca3382c6b798035c84c3a5aa3c74a843160c630f46b7ffba1bc83c05a5f190de5a166423e96f312f2e49ecfdc9f6d3d8ca751a77cdcbbe4bace10df127444d03c44aa4744555a9de9dbaab22842a3c0455a4c89a6c6ad4c5d85e1aedf28e44c40b44a26e7ad18eaf21475decb9c2d0f15460b928df93be52f78d2f1282c83cbb6e799953976fc53608776b3ad465eb4c6c37484bc0e2158a1e179ebdc3909dd412864659c20ac2e80949463fd5d33d21829947fba914acc861b1554a738cb0d5d398c6ce6c87f39357914153995c9eb766eede2bfdcaff9a6116cd91eb0bb7118b91482ee5ccfb90bd5b32add0151633ac50aa15bd329ab4fb10cac6b636b2790941905999da6b3b72faaf38fd27a6108213324095b2ea630a413a3beeb316244c1a2c27e64157cc55fd0becefc758ac972ebc1ef574d1161667d1338466bc1927cd49c6a719ab4436b90f153ab3a08c454fbb0290b9e84295946dd4be2d571cc7b570df7b182a8dd7dfb104cdef5c8f5d85f86bf6bd1b84132d8dd053cdc4d58e98b70804f50a6b962a2e8b91",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x69fb5b021142f34d8b92db88c348281bfc491af0ec977ea67f89e8b2215d1976",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x4bf6f91d84b37454544279cba152581ed6820044",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xf5e410",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xfee348eed674e6bb95e014c63436dbda6f3a29f27e9b82d23a4e52acf8ee76f2",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xb4d7db08bf99445488ff054db56abb94fc07b3d72ab0a4d3634e14169696e114",
|
|
+ "timestamp": "0x6a926914",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-B-9chei-anchor-16114704-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e382d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841acd9c302913d9a30f733ff75bebe9b69106ce2183aa78caaadfc585a6556387130fa56af737adbe803ab0e51f61ce5d37d6c9d23df16497558197283e00363e301b841872da48e5d163a7cef37642afeea3c0ffec11ca02e0d12e2721fd46f70b7d1a75544d6f6b9256c327a296957d81b8599550c4cb84f790d9d3fbece65fb4f8d2501b84161c86368e9f854d259e6860dba466955e2cfdf6258801ee880163598a5d789ef760775f985a08623d6ec1d9cbe1753d4bfa5b6007ea061cd34083ea3a1dfc20101b841e1104ee92c4d83911e2cb36ad0fd4af1778ac4f4b4b2401ff2717adbb757b3634579d7f52335fc1667422b392cc10463398098c9bfa253a32dd23c1fe619c85800b84185f165029de059d1fb1cf8b2307d13a860fc15abe16868748f31557bc0c1179d50ac2310643ea147401b72702e7640410a3c08d4fe5aac5103a5c5dd7c112e4101b84146dfa7c36f81b007c972445c342a6c66514966a458b74773b9fc9146fa5d9a821619d31a1ab163193aac8522143221caa85d55a5e205044bda0d7220e08c098b01",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x390ee0744a550beda71ebe5f56511af5da51a5a29cde30cb6c0d796e44fed1d7",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xb5e768cb3117ea25175f51aa956b48691025c2a8",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xf6240f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x1ebaad35ab5edd0a0c31015d9db1dc8fd419a5ece2f76e47b4567630b4ea2911",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x24511d1c6bf1f01433de8289383c371ea29796de32b06a14f1f06d2a903a19d9",
|
|
+ "timestamp": "0x6a928d33",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf919c3a0c7e78267e24722d42fb99970b692d018fa76032a00e1d873b69c88bc37a90142f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b84186fc1d14d733390e49f39e5723220ce38fa512eb94bd023322831bb671ac259e435ad1b6c2be2b35e59b795e6fff1245b62e23d04c9f6a8a5ada2105a12843d800b84145be6d8d5fa73522c34e2909ee1ab992ce968a9108ecef826d773a50bb530fcc0ef281508691c4c3d79870f9aa14c363e952845d7cdbf70161de66c64d2135cb01b841d506840a02b2a064bd53f382974f27c08024fac93efcbbfe05e1e8db5e0530146cb544f2a522e9b3a464358e0fde450b4801a5193054d266626671f9083859c600b84126242c582c8683ca50947b5bdb48d55b932ae251f8083b4d07942c9a0729b07d6775b5515c10549ae265027bcd375078801bf0fa21fcf23e794ac28af5f5f44b00b8412ccd76c326cdbe96bf8d7a26315e27a637a13738f59538cb8e40f602c9f41e2b100dfc60c0845ca3a612ca04100f14234344dab99a98ef69d6c1288d4cd6d12f01b841c02fbe99b97ab597ff843a39370085864341823e31373fe91b6e936fd6efe28a16717e10cb3deddba6bf88bad5ae0a4f1fd5c9c3eb6dfdc195f1d0de6193e08901f91749f9029280b9028e395992121c63bff2957183fb79eed80fa5019d4507fa6559e21aed32b561faf40ef69cf270491732f7925b69969abd9bcfd85da02d6e7e00804e6ff6d6d8bedc51bd0c28ed23b3882125b8e8d8a46b569b3d3bc6da4192793cd8d64acce8c22deb32eaa59cac0d7f0fe53852d8e41b2cb63e99b561f8c2aafc0e0f7bd3a94767ea64388a767272b6fd12ec9473aac1125c6ce3058444dcb324ffcd5bbcebf1a8ad1145f60d1297eee131595b1cc71a8dee6b664e0a7406089fe0e87c3e9bb292f619ced3439a584c85f3810e41d5698febf98851aa1fc6418e2938d51dc65e17b8ea48ceafb21758af5960849681bbc29dbcdfd2a28551236b13457ea1c95f78cb308ca04226af522a0c3f7d4d692deff4916dc114bccaa3c7946a9945fd5cb146e4d9d89fefbcda23b321b5bde9714667e0d453ee97a720a92507b296f1f2d028b6865109885156ed22b7bc5ecdbab30e92403f44fd68f737ec4b832f39ba2d939d5014cb0f894ae4e6deb33a883dd1f76d91c2f5bd47a7090040691a573d28372f817476774a37b7a5049a18738c48977e69fcd7c58cbe2d755118af8666734f834b2aabb34c46fed76e05dcc6a48b3e55cfbbd5625b266a30c41ff85b594c96e8b834f6ee04fa6291d4585133d9921eda33d45cfe625dbdb970de1505bfbe2f7b984548b6bb8a8523c91dc8cea34cdd3d6bdcf4f18c87b25ed2e95d5276fbd0ef18a64dc7ef211af5b0e7a83b766b13b16ae5aa8e23932d2a192f5cc12a954aa46c4a129d42a0b2596fbe7790d468a9183c8f87c4da7c6829930e9c3394b445484b9b0c790831740d49813a6d93e8bb77b5cd5a94eae6b75aecadc9223d8f8d290355ea586eb47cd7e83458e314c3105b9a20de3053c7ee0eb9e651562e31395912824661d5167a3de667f2c8f9029601b9029239e75c62a592f075e48d911099dac8253013368193e2f2c52b6b64b4e786a2d5b076ffd6e3d32afeaede87a896c830854117d2796da9d9a8ee33699fdc28eae344c7c737affcbdf7cc2279fa5b7b3ede3c3bb21e834509b9d128c60db9bc302dfb0e9f437a5acf424f41df1648be0caade603c413568a68b8fe367c64868b6540594742e75d73f7af2c389ee555bf425aa54d594d059eeccc2cfb356aa57e536d8917450ec5659c4d0c6f2b76a6c725ae910c8ab7b0799545b391b0b03348c249398e871921b1eb7118237a43b0f5cc26cec0aaecd0a82b12d6b4acd67e2d89fa27ccf5c1ea8a6a8be5e17da1a6a621895b28f85dba5f8b500bb61d0483dd890b5287c0f0f1c76871db3c01c0471f624ac4b6069f72eb5fb44568da1efb6ce1641ca8ce3d0d601e57ae9f0f3a2e31d5e56d3f725e0a6cdeeb6006435a81508b2ed4d5df156f7500ccef632c8d053e12b2bd68cd5bf50dfff9ef956f54f92e9b5b49d223367acf498d495751f3c163b5dda5350d478f06ab8f22dedcba69b2d854d5525cc5a9d2c6251157e071f408732d33b40b92dd781136f6c34960854d4d89bd9a930586459a596b04de1d3c41d2b9b8d0cd3ad178621209fb1d1aabefd657bd8862ec069f08c54f48fb0fc36073f48c392f71745982a312f246e20e2a37d0963c306ece22e0463adc9f0db2f4a699cea6519dfe47b794e7915a9d5abf0dbeab79f053fc1ed1eb90312cd56a74caa291f4030467f310e2ca9dec08f54db163366f2abcc5f292823040be684e48f449da0541267877fa9c8edd6153cd8f4a61988fa81a334d6f956b652b441d1dcc7aaaf106afb50d768ceb22afcfd85c223d5c5bd186e5f1e614660fc999df3b65d389c20f52a5e1458b54057762c70a0b16e275b3c3dcf6a0fc680adf22ca4fbe5a280f9029202b9028e3969083ad4af4bac2bd86260f0cb8395dcf336f4a998894703614f1a272cd6519c4dc12498c4ea2fa35291e8d80432ba9deaa3582a13cff21f6f5477c69f3dd4f57a4d11e590d607cf044fa76ac6d33c563c9cb84a2dae655ee801e35915540f7e43c72ac0285cb6248da290e60db1926e332d5c908d3a5c17fbed9b129fdc981f9cec5f2b27426569eb7fe5d018590b295cd77bd68cfdc2049ac8bbdce4ff1ff424973e9f3163bf42d6e6f72947a5e471981f7cf4de9faab447b6923364d28959221f46bf332d3f273d1d2856edc55092d2614e9a375fda71f768d4012da0f20b35a7eaaaa554cdcb4374e98e82469fa3970f33b7caff3296656a20eb122087341caad735e2747c0c808c2054a8bb09cbe733ac7ede78cc28de89475a218f84cbb589e6a23fa42f1094d311ecfb4f2405826baec0cb2099cad5d56d190bce9874d886e5977d5008ae953ee8c8a43e3d9fbeba56b4d4949ac7f07bac90f4765f865c63efe55141f2c7de28b431eced34c4893ecb5d53fcd542085d6f1b9c18ec56fd3a7bae355da845128a57022134fe58a79b12a72560f293782184699d72917e4325db16413f35b306c10365b44bd545c7343e5e1955d8e43fd7f445af8fb126f1a74bf7ebbcf48771f0cfb49d1c220aaebdaa58f26d76693ddc16b884db1231f36756711888caa4dddc0d8d6785f0a8bd08c61e3fbbb4ef4bf4a71e4218d60420ac6b30d9656a0f79a9c0b32d0a3dbbbd33b1af45461318d0fe493d9713ce4a55dfacd1d8625217f92424289ba5b99920e7b5355d144e7d39d98a9edb52539e8ba755620ec868d474c79e96912cf58b1895a37c990e94b937b3fae187bb7229ed5393bdf1d8d4451951b59283b06b1afa654312b7506a1cf78ff5187b091fdecb9857cfeb49a29bcb9045a27df9029103b9028d39bcdb40b8562a09a20a122b5267eb9b14a77b6685cba0f26d9a50f022698ec8d0ae5955a4020b247c1282c052f347647aa3485a678a96463e715af394f1d8187bae4a5d2c99fafb15d40f3ee53046257120eade95e66dcd438d3ef666682bcdb6a71a5574b214f15bdb2bcb324a51a5ae7762d2cb13090f2d2ab0a4eec22691182f3275488492b49b619029544c8cd57a6d6999bd5338de79dbe933e5d8cc91fa6a965fe80c752d5dd1b1c89a45e0690a7a05c944740a1102184783d24498fa8e10c736197408825b19274f56e6fffc7949cfea1f3bf7629f7a2f3238813ddcbaa26585d84e5d635099ec55a972bc96d362faf924a6157092789415aa5a7828a2123e8ef2f7b6ddf63069311ef55b2b70361b265f9fc8ae3d77367139b3859faee1e629b24f59d3c2d616df7edaa329bf353461cdae813165b115d9fc61e0aa4d726fac02f18d693e38fc1149853111451e17466a9a2442a4228e9fb12c2a960adc2e939f572bdf5abf8b913457344d0742b4f0c85cf2c70da6572d5bea42b581475abbe21d38d7e9d0be76893fa068b3539acc44a8385f98fb19f777dfb512759e4a55dc89f8bee515ccdead0a8ad1e42f97327b458d203c1d4e05b4a5b7310ff15694e326afc22a9c76e8686c3582e589d14ec9edfbeefb654aa57ea59a4f83e7facad5cc56eb1a86bead5b607739ec735544d3f151cc1dc34bb769adc86451033a97b68513a3eb130214d1264c96fcd039937e0d3e2f138f4531897ffd4fe9e4a4565a7f4f448bbb76298df346d0995c942a308d3fd2968495aa3e24ea1ba61e4993185acbacd3fac0229334e087780ba8bc5f214d19944689348a9d06c02fce07d3f3b9edca554824319c7d17452e30f1f468bf6daaebdfd431c3a33ca5c0aae72466f705c2238cf0a7d0f9029404b90290391ad040b7acba0bc4da6a31b689f4470d13b63b454595f1010b6ede5d2b8c985695fd673b3e2ecf27aaadd7aa5948ac75b7959d889b42be554d1e446294ef4d11178ca851f60abfa0711d1394a647972c41d22b902b2506084ae2702a892dd16424fd2db76e0b60e6dc4d41a53e91675b124284db686b983544a6e5b48279946de7f388044cb8ab7bc31de5e1da18177d0925c5354b404bbbee88405a023708c5f71cc30a92fb8a455a34d792155a99cb55610a5a077bb193b467b30ca4de5ffb4297c73edb3e94918bca641fba3c4f6de885a58a3e8ee7bb7ebe346b5eeec25492ed057d68316ec7fa87c0e94cb073677f0b47757638f46db68034feeff18dd6bc6c029ed02cc9ceabe05afe34c46feea0a6492be9fe9b3d05eed36cfea0bbc5f7d8da2897e9ada97c2aa5adaeaced614d4d4f30daede2723846ca57f095523f30ee8586c9f9607526679167f4c1d1ef9673027f997bc41242e0b3c804ca1ccf1868947a117963e96b75055bf2e690c3edc9ef25c609d5fcc3ba888b4fc04998fa7566d96625cd19f665627287c658b5d262711a244b278c9247593d564f02f4f023f49438f5f034a58b351d6f38dcb5a5a5e2b2f8a4075537f97af5a3a53866fc8a2ec5bf3416b86d05f195ed0d83c4c4b1f24ef5e508ddb2b03a6951653b6e21fa9b31f264fde1d02cde0439def4de54933392b8d0a4d06770cb2416261d3e703a0bbc7080765d8237a18b376e6edda17597d6e621d251bb13a6756f488607d88d6a44c92a5db2645e66cc778de45d789df692d7338f968342dabc3671add9ea7b2fa3b88d22bcff872b7cc9cd793c261722cfbe9ae810c9a230810368fc5b0cca146ccf91812a745d6b1ecae1ceead39c675a8b7b1128b6a30c31424654c90524813cf994118658a27aa534c540f9029105b9028d39f54f03b072a5f267e4ec893c984000265902f61e430734230ca0dab32f6e375183fe3f9dce82cce195b6a4fd054925e4424af7f757f151116e16a99ed878d6e8a6cc9d193e547d6370e7842a586b27319659103370f5f280d9424c78ccff7c889e30f1245d0c87ede89baaf60cad85303646ce7111ecec76923d12bc206e60f222a541de1bce94e54ad63bbb892de91a8ea71a26bb72a16274e66d8c26898449254d346831c5f1339238dc071f6192d3dc4dee99ea23dcf96eb34ee9f224b16258b4a57da845c52161db0e13912e9d7998339a70b6aa2ec28f0e86a9d87501edaaec9c78636f77de99180462e6e7475eb5d702a2b4d48f0c70f0c872abd60d2abc67a3cad5e3294f7dbc82f8d57c6a7e3b420b14303b0e54322536e1cccaeb0395a14e30269b46db50a3fcf80a07a15c786e3fa50c256af74f55f5e04fd92248511a4e6ab90ca4c9956431a328640396f2a0116f7cf6aae8a47078490c59b16390cfc6bf541a251549984067c7bd579e49229a1d1f82553cefc71148fb007bd13ad9dbca64266fedb1b250d12a1a9ba0dcbad2a9a465f4f97c355b9f527f6940a3099d869957ff1e340dbbf0a43a035cdd73663fcc24d5da46e25d3da41dca5919e5c2277517d47e504b190931f05ee992f6c16dcd6771737c8a17de7299b4b28b587b0e852193ac4bfbaeb951755182d1584b61988a5cb130b2c1cdd88ed10ac3e59efac2e69ed69d2bdf57051166e83f591fff0650acf74a6e39d0a618421acf9c182b7313febcbb8c7a71c689459acb65c7664e92e6b2e71d87ca6a992c1307b724be5afdaf0762bc614ec31ce0c133119e59568f27183406593dd5b1baedcf3aff007be356ef16bb9ef0a5c5ce5a9f29172b02b6dab93ffdf5eea6d6354c2964d1b0b2148892288e0c59f9029406b90290396a41d06a0b2ae6ecad8ccda792d92a71b167e919a1ad4b7291de7c07c0a2332933f64cb6b3d5bdc2c5682dc6735d42ff568d9f8ec184a95b5bdc3e241abc37db07f2502792ee44d08a1a640f7164791304eef95af416e46d0ffb742fadb33c762b03e8be4a380cc471e1581c343542e2b71ec9ef76e1af4274376915f3bef068908c3567271537acafff3cca6f54b25856588375e0b6a1fbd72e7712d309e4f7bdf46d585690a2a64937d35c99dc6d3dda54febf1c56760c293ac8d3389b93bca8b998a26d6ab7e176531a76be64acf8226a2ceeb10d3e530e87851521784e53bbdc62f6eebc20f85af2286fe2bbd5c4c1d227cdc79827164c76df472251673c0fe69a4101319f4d5162af7d33a4db3ca82f9b145cdc2b9df8e40a12b255d2b66f3bea2e6984911d8a763f2ec33105293bc90d54c09329c4685c70f8535931f428ec626572d5d22712a4f151bcde93fdf2a0795a5914f6dbaacc497088018c3a247b466059ee6b27c489e952f87166fbf4fada072d939a5c92149d37b6426d6cb4c95c4b274dc490d9a42cf9a09dc42e4b2585ac3770d045de885137bfa0ae8ce8b11982912aea6ef8b55e6e0f612784d509b52709fedb3177397e69d146d145cf173950fb0e82273d61496b1d79519410933a0aa796ed11bab8d08726c9805077f74809ac49a568bbbc405409d480fa44fde624aac51b6dad3988e961b9bce42d65697f060b68a478cbf70708df9f5675815ea1babcb9d0e4b9fac9a35e85a808e90162b84faa270a2d4c4660a94024faf8df4b63bc84a34879955176b10491a0c89747faa6cdb8087b8df3d39a3432131ec83d2c3291a55c680a1204da6d1a71ba478e1c43a259e8256975d3a908a21277b069d114bbe3e43a85ef3f60cb9358db89b8636b5ab9d361d08adc69d0f9029507b9029139c26a1eaa660c8e3c08a2f57dbfd60467c60cbf772b4885edb1570327b89c221aa6e8ab277d3562028420a4265695e9781ae216442b3fb717aa9d471a163d4baa1438dc7fa73be9c1d8613b71af26acc8ce7348725dd98e1f4fed7d84803f28d9b6421f75d3e4d75cbeb4b42cdd199d873502a1f2335f4b963eac8bb5a24c913fdab4c356c0e92fb77721cbe02ebd82a900e67c52cd093f427ce97fbe3d50efea8ab4a6cebbb4940e165d50ca42a3bb3a5cdb38caeca927d1ea53fa15b416011757930819db35b2b2d297546c31d5eda4cb766c9b6f5f13a2641898c1a07c6de551f548fdfcaa79e4981fa25bcae3e9d5dd1c2920d8691174da373e8ea9b2d8be3f58c12eac20fc5da42fab6eb0d84a9ecd83304bcdc2173e706ecf64318f7927ca6f48e7a4f137ae506be6f93639baef22a6c6279cc14bd457cb8924461a64f6a86361e8046645c59d21a9a33e6bf6c160edd73f0c8c8961fd449de995fe709ae810f6560a5cfc4eec4a1ad1e23e1135ea02b16976c45297b96509720394cad377e9a2833d6d31269dc687fcd53d0c2911f470ebcd4323ee6de398980457523bfab9beda3b509fba70e996d351c83f0a2a1ec86aeb7e5cdbdb495361ce4109642ba9ad7270a2c493f5353f4f9264662a82d4f06f5b051ede1276e33b54d42248e7bb67b74161c725e78555e7ce3d59a9373a03450c6a65b404edb7f87e5db2882e98e4108db8c67a94ca5034eda4491c24ef26967c33aca66dd4cac1db9286b31966ef5d35fa306a0c4967693314ce2b10e0f051e8528e8537d53d9dc958dc41f9e80e6a82ce9473adc49369b085dd1e7b3490c861c1b466d649eb3ed9110ca3f9e8df6e3809120e9524db52047517a536a2e4a2f919446951f65d6466a09fa1e6ed41a958fffd14d0eb1358b608ae40f9029508b902913911881d8f27fe21bef1aa811ab6fc8a2e0b343033b4d146929644fa0aa9650556752c41ba49a99feeedb9367db2366a2b9b38525acce5f6701a07dedb85a077cb32a3bd6e68cb668a14c4e798c38ad75bead0790c75c4e3944ae1bea54c179e551236e6c04d0af889273bd4c91a9cabfe756f190d7cd23956132fa9e5552205736ac5b3877bdfc4de4f3412b31117eef08a3cb9086ba1f2e508c5b6fc0995586be40afa8b24c89b754216604c83895077a146a13b302d1e29d2eee998b8c6a98fccc45cea3b99a696f65b22be4ae8a68ddc8055e6b43dbc614c4d513af10c3deca9467c260b67f97c6b0e26725747631ed96120262aa72de9b96ab62d8b0b2db35068fb9f4e3dbcb5682a85df00a0fbebac6faa3640cdef23e42f7e19f92288ecb85387ad6f302a1e83d081d06169c3ab3a5d1c4f9e10afb9db39bd1194766eab1a42907ef45f13ccf1cb909bf49acef2ebdc343a39fb6b3c3d4fbc89bba9694d13f1f99d90763bf19682a63b5f6611afd76ad4abe2a5159e78b3a4ce336fbfb2ecbcefddd2c5612067b6a8e1b3ccb2c16d690d07ab7ec3e6b8f04699ff5ba18dec10c70ce0ad39d33e335c637b122c7b97062972d431548f3508e1b78294788ba871db7d4347b013b70d13aeb0b64e838689b3478c8a6b24103bfe997c71f5e3c74ab143661bb686795c9ebfdabb4e67c74acc7627396b754ba1ac2c7f79fee460606f214a2fd758b35432f442855c94f8589448beb5263ae7052d6e6412346ffda9e95ff8eadb8af9c145fa5d6e09e2f3795270c82334c99eaed7e08add26315c96a7644f7276e631fddeb431f861b7e650dba3aabb74ac1958d9d69db3e5adc92524a926e7933defbed5bd7fa24aa4de5fa96be9edb162e3099b1e4b1294ed3959b54c5ec4f4183af25ff73312d88c",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x5172cbc9167f82c96ae44a3ecd8e8be38270f6b9220865b9ee76179da1703bda",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xc3314fd768bb68b986e80c0a14175f6f72630d7a",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xf62410",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x390ee0744a550beda71ebe5f56511af5da51a5a29cde30cb6c0d796e44fed1d7",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xa59e0ef3134487158845ba8670aa76bcade2e37d5014f886d21685b3fa0ceeb3",
|
|
+ "timestamp": "0x6a928d34",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-B-9chei-anchor-16131088-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e382d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841c4ff43fbe1abb84d15612cdfcf7ac96805507ab5873a648824ba6b30fafa657a0be165dc95fa6431d18ea9acba758cd826d4fb828d7a6f1d40b116933977bc4e01b841b6b009a51c94a9156c4c425d9f2b3b0c992fc055b8df452dad984f494f0cb32e12d87ff52d298efed4819043559727499137b3898f420196bee27c60f382cee500b841b2e691aa860e824edbbed1802b82aaf61dca84bd13461be8b8d33bdeb4c5b5af648ccaa90ca6fec6dec7ea5d9b0d39da55e7a93b316140abfb2e745567bdffb300b84187f614711d8f80494f78d750305d1a900b0f86b7224b2100fe1044b6a2d07a8b173a78a5dbb9035c6ad17ae7e2d3e4b9210006f4df3a24496ff272c7ec20ea4901b841ce51b2e8c779d601169642206091894c187f7835ef113cde33e016766706eb3013481927ef0cdb6a45e23fd3f25e30314b018b4f548fea50b7795a842695e78801b8415822fd3637dd3351f1ae99c6c006d27cfbb986c58c01e9005606bac9d762e75a6c1ce31730f7618f3c5056eb136200d346912128f88eb247cf5e219245d8834500",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x0f2dfb12d44d64b7726eb30dd230e86cd7c04b4e305b92a8f3cc77bc2852bc18",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xf73bbbd26a82dbc769066550d8d4585eab2fc00d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xf6640f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x78eba75c144ccba3e5dcde9f24dee309afe555a20cef6b058e7b8414e0747f3e",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x6c28f29c6d017e1336e111c0b8d8f3a7d49f180b324c67ab80046c1bdabb6353",
|
|
+ "timestamp": "0x6a92b143",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf919c1a0de79a3066f1dc1377cde2d7e4aabcff47a9a6af27e318ae656ed84fad3aa740bf8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b841fe63c6c022a84f37e736118b02b45feb94bb39e1b44bfcd096221ad69133721f1f6a5d73a0e59dda12822b874be56a9fbd163275c337b076c74032588906998901b84128899d50a1f7561073317afc88f0b24778584045164713ceaf10e35643d675437b61360b186d7e8e72745204bcc6467df376daf9d6cf7dcb92ab813dff55009100b84193d022c8cc8ad19f2a14c77cbc7a7532ab1038000dc806be6d43a82c5a3bea533cf807c435d4c18dc6ac3ca1c2b78cf1ff035185a66c4c09cf1afd3a9bdae4bd00b841c32bbf35049f80476e2d5776b57adf409aa51318d9fbc8249fb75f97b716a126391335b8336814aea384ba3ea217874dcf67c7abe9a6230d0bd6e883a0ba539401b841adb7a59c3ed233cda2c760337b55f544d6774fd38835da79d44b543c15ee86911c8fe0492245c42fc313d52276bf0d8d4662dbae78b3b2808953bde0af78ee1c01b841a2986a608d79698338e002da8ce7482dcbc020c49167d32f198e3d3c505c3d146003e8690418da9f9bac6287fd2435d96613d9dbd17e5f68deccce24b0c4920a00f91747f9029280b9028e39ca0e107013418dd06b53812ed8259f2878d60ec26699511871961539738d246b26827ad63caf3cd5a13950e288ded314170cab670ce9f0748fa6c570fed1a1ad6c7fa9c9b670ab5b33bb94c0d5c8f40e7dddde40d53d1ea714e8c1bb5bfd0b6b545fa4890139612b9926a30983e93b5397ebfb2979a04f5dd6d5cfbbb05a86294161cac659104620fdc51b65818d1720f968d3078bff0de1be1886523c8a45aeb47969574b398cae72db1496c8ead9899909324da511b35063dc8669d64bce826a475e1c31bbcd9eda1b3a7ca1ba7d3319fbef73feb2c80cf2f5c7dee9aeeea1fbb46d5eec4ec5327065aceca722876d714eb292e753df7afb1ac8295af8710a3d7886b8ba668e05d10062b62db65b6893e0931a1a1492acc4f530bcb80ddc3305178155af6c83dfb4fcfc5baf8b2cab11e6f5df5a3b978fdc05f8ced4604d91344f19e7e78bf1fe579ac249309221a50e9487c1140ab65244bbe16ea89ee6739b9231ed230dcfc967a014d84e45a121465744244bb31c553449a1dedb23feff6c2de8173b1e56fbdba7e2e974a27ede925927ea9d023d772c93afe975682f5c4e2f49b134f1651d577d69b296a5196299eaa495059c61a0aaf5520cc18a7139c5b2cf75b2cd8dda0687c7baf4ec5bbb0b0521e5b57b4d57c1efcc740c6d2fcd898a372adc6236e421b438e48e3c76b5955a3eddb7545faff5f64693afb6847544757739b47aa5b863847b56ae5650fdf1644868ae367d2b46968ab76e7cdaf61b7c17d710a45ea041ac5326d604a5606f1e290378e2f2ccda6771572f369996e4921ddd75d45df0cab6d2b74346967c19139022461f404e6530b67ec084bab9889cbe89d6e33e3c576b8d4c96d52324274f87434613814fbbcd55e8e788dde1188c512f7db44bcb376af829b0f9029601b902923926c2ff4b14d65bbcd064dc8add7e284c8e6f8cc7e1aa222dda60a0c314281f3522cea2542727b3dc409e48ce62b358d371abcebd45d6c8c1accce0909607e361bb17cd50ffcaf8506455cfc4c85ac3468834483a21a96953af237d8cfe47a0aa8eab61558f619a6e6c4e49f5242f76261079db6823438c2a8aa7324e302dca27dc22897127b9a1aa11abe4ebca6e85dbd23988fe64d923b1c9b454e658f09d4ad24c91bdd9362c9e2c308e4402a6d80fcb5947c2f36c317bee4d3474586725a69719d2cdb3abadf8a937215698330dded5d77a6899069b5ecf625e46aabcbcad881b084bae4df449d18b2064b2888b56dd0f57f5f42056270b11c25b9328618594a2d4fd6c15f0ea09348a0c3309cc55355ce190061a259485eee7d5fa99bfccf8e90852bfebd8eee52dcf09f2dfdb3974020b058c20b606eac7b28169209086b6bd04ae7be351242f8ab45938cf8c25752cfb9bda6b0c5f305db7bdf14b2d7b64235486cd1fa917ad287419178367a428b976e60cb3ac7acdebc93782782bf27ae351cb62a862044110bbb39ad812bd43ca37e85e2c9ebd949c122d2083c1a1aeea8392398f547779a9856e7e5faa3d1933112d8312e2ce657cec79eea529bf897b4e72734a0eae42c0937d8d0135c72e45d18a4a599f5d7d5ab3bbb4e21431af4420e86551e3fcd67849cdbda7e14fe579b21700cf1c550f6d184cf5d0c9765dac64b3bce89d4cbbd719441fd1da82d05a6b77a282d727f355fa7d31781fe60a928c9847550216a8a28f4392af52628691df9228d41669b7cace0afbc6f19da2f4f3314ac18c1886b6d34c71226c6ac5184f29706470bf290efbca6c4dd4a8e9426486f3dfd382e84b2272a837aa8471ceee9f18226a533b0bb53a66b5db35723c67489ee41b49eb20dd23489ee52c40f9029702b902933999024b699547af2633b5ef85d24cee79fa0ba56de21ca92834f18ceb20eec84346fe2fdfb8b234e37288a702b99a256b4514c5639469cd19e6cba63756d35ce7273975cea528d024f85c490c3db67f8336c50f6d235b9edcb9f087fd4f65ab3258278ec78932594d5b7a7ddabe23ace12eb3f7abec92fe6fd364b950c4b3222a48896632edd9b021881a5a5858c62a8846be6e77118fc5545a67f592ef3d183c8e65ac8d3f8cbe6ea6959006db51a73678d10a501aa99fc334cc2b39295312e6e34d2b6ec3b719b693118d97a0258680db97dd8b5a451e5a5d3a78cfe4914d2b3395279b4265003e9abe94063732710e8e6219dac7d7e3cd934443154ddbc6b0ee1313a99c392dbb64cab259c9fb471d88c04f4e8d3825c338c61bc27662b34ce2158ac8a6f23fabf48bb8b3d4061a716f966badc10171dd24020f03b4d0fb19430c80276aa294bdf2f3cd0304591853f66fa8ba9bad9763947339f4986a2309619d96470d7a79f97ec308abebf47a5677631045a67566b7b2f1a630a6ae17a5690a7ca98fc57389c26efbb9b9bc49cbcd915c18da3cee5d8b93480ac260c0e52a227ea04a8904a6f9ada4edd674d223f8c2a75e9263e2f2e1562822f3a75c5905573522d7273352e3a669e79d2b41a5bd0b6e5bb9112290cb27d5ec319c08241396c44eb12ddc7641816e5b49f37b49c32968da5f945e58c7a20a686f641273a6e5efba6435a168adfdf530c7952fcee18aa31f44ad573e2c7fa59e95e14a8e91b86792f893e1e496c1f38dc2196c93f7a6cbc6a1ec66a4ac59358589b3188b977eb64cc450989f5be2ba5462a7edf68c3ad2b8023de5351e1d2996573a2be62dc2acdfabdba4590ff1cc34068a7d456247ee0b42e6c7b91aeb3a0c423594e25b1b4cf627e28f1b6e21551f7cb0d535dc98f9029103b9028d39d279bf2b13feb61a4d036b321ce6cd9f3700d7fc110d7117e070281aa3764586d544bb2815923299d4c7bfd11427b12b81b7b2ae7324b941365ab24f2bdfa64e4e9a6b348095b79f40aca9d2653dd282d50fbcf6d8502dfef9b7214791c378e635d8d9ffe28bdd0a38adee9964ce12caffbd4c9f263c27fd67cb3cbbd862924d8397d4ffbe9ddf2e86fde673edcb2b0c764fe373fc5a14147aeb94d7c06473764cbc52f7b0448c6baa8aa308f8beed1938ec75a55fe23478ae88e7d8a4f1274d1b050b717878489ee15655bc5d29af47589a9017d44fa76e7a212d6c2e89ca91516b1dc6a1b84dd0d5aa4416e86efedf1945cf0db72e98da98a6b6c9c250ce5c725f77bcfcff76a75b0370344abca37dd62cb03b2a297340fb07b2133faf55988578e2201a18be5681a27d9f070ea996c7953645734c77e26ee1a53634913be02bb68d0ee1df8bcef5b10a5b5d186363d8ed514cc8b24737b85b79d72dec259e797272d9d14cf4c2747bf20ffeb6bc08a8e3485c1bc69f158c9d42583f37635ab34e23666176c6fb16147e62bdcb96d70a189378b08660781a8f89b5834b92142e9bb55a71ea2e93b3a3b9e5eb9e5d166f4592230482bcd2c865749a9121ff3f6e6ef9daa577c88785c99aefe0726deb4cc83c0c3412e545ea25adaa2cf0a0f49915bf6b072750f65d2964923896631248e92c7f7ed3161ac2c769c2fc5dede1aea666786902ff4eed54f8aa456a2adc37692ea084434e54a1914fe6c1a22e384e32bb2c452406bf1fb6cd235eae232d887e2aad3b81278d41acf139566d9d9b2710ed09d09818b6ff7b12a09f3c6218c1308a37973b09bfcc31107f813f5817248dae9149eeeba403fbab22dc8bdadadd49ec5cc92488a9252a3e36505eeffe567295b7f923349fdb64b540f9029104b9028d392c26afde9f79b97e4f31d05e01b3f740dd979bdea0c5617ebd9f19cc096aeaab1d53910c1fb2e316f63ffc6b4ed70450d1c7731ca6a0267b2ffad1a81d8a1ceba872e3a8716ab894c3f3de47d95c6bb5884b33cc139386656c5801b1d6feb08d3538969a4ed721cdae6397ee5a9bb7826a4de9f441e0b09e0b76fa24372b2b4b1f35a59d8656e8b0c4ae8bfa837dfbac3337a721cfea950b96c0d522b3acc0f17c1aad9b8fb0834289576af1feb7c7da76cac72b90b0582d94ac9c08ec85cc902ecaa4a3910fc17c9089ac579860db38c4fffd0d42891be7f4b156fa0830c8434989cc913143e1feb5d5ba5726e7146ae3ea23f5d77d3107112f231e6d55ba1293449f39db9c87b70ca52ee32b5ab7bcc452010c624a84c383aa7020923910b3b0542a02d564d0f60a718a23ab5ec605189e1e794d4e7081f2f43576ed0a88cd1af265169c372d934d044bf4c9fdca82d3a0bddd40abf7b089d5aa6bd33438fa6acb27a579e2bf04737b0f5b232f4702b1fedf342737820b3cbe7ee25de6e618d95ff1f42e0a71c623649da568d969aa7387fd5762725a01b1c338108753e5525e2ef8835d18cb11534dac311f28dc9e2a9eee7059b7869b9d5df42401f47e6a52f699bdf1d2227e2617906ada86a293ce2797dcddef506279acd4da65d497726c97a5b58897c5f80c592c7264d1743702d829d1ff162eedf5d824fc96f5d3e64192c81b9e69178d2f8d8c7b3047915e7131eb0d3e429c1addd1aa771b0aea450ad676d2180f8e5728a96b794c27710b11953a2860fbbd6fb327afa8aa4ddd4badf8106a25bf06d4a45d14c935e2374aacc96dc4d39f27ce3d845fa9523a69bb7a352f96dbf99cbb7a3c28f60eec8647b7ac7fe2cd29261c4e6d3c912849a247b6b463a6b4de0f599ebdfa50f9029005b9028c39a96777a3b2248ffdd606189558d09fd3c2636005f65df80dd79077bafc23f5b266f3141577eefb81b0563d64554f735fb863d69957a0edfe20d7519157a515d39c98769357ca3cf2bf244a5695a6feca2eb2199f430873fcc3ad30114d8e286a177b13be9422f26834f18eab1218e2b507e6a93afae204a5ab789d170370d12c48bd6698fb27fd2fd67491ef61b47c6aadb241e23ae5479377437611ecd1bd9de1ea5ca987d536f6b3d663afbe981ee3469333866ef5d0ff6ad4e667e590b72b99b50a1c5788c17b9779e3c4f9eea4350c6b0e84be38fa3ebf918eb54ae8891c589d7818efb59985a550161d623130b7605253491693b15edea6ba166762cbcdddcca954b491bde3c3ddb82eece15db1e6760f85363386e04c785a04a7052c69723d6116b2e87ff53f0f29b751db46db0eba4ed2a42ee2c563f670999334ea433139560f0286b0b1c8aa299be6a0d4ca950b83653dee14f1886a0b6c2b0bc2792f1558efc8deeadca6c6b32c9636d6a4c53aca691ab7c9291924550952caa4c9be619ab9231c85dfa048769995e35e7cf14ad2633cd87b287404b21ebba1db791b32bd60ce8e1e07c438b4ee479786402e9d53f5be6aec7977060d3a555908e7e8b88ecd51c577ac2dfbbb13df397c5da365fff8350922798a8620aecbd9a2351e8f0381aa6547d331dd5c105a2e07752aadd5dcf98ec5668ab0238cd14293e1d841c9ec615bcfee34b0b4e267f090d19086058786bdcaedee207f785fd32618d371788b26ca3d49e28f60924c3c49546386bb3bd0accb1a28cbdccf7158c25a71357d8ca39d08cb3929874b2b3ebfe364b95eae5e19a424f13b2a02245da6f1d947ea9315095aec68a439cec3fda73d95f50b0e676088d7491cd968334c8ae369aa72e62c9bbea8daaea4f9029606b902923925063018dae599ed8fc8609c6544ebe9168190b1a29b433145e1c3240be8828f9949b3bf02e003cbb1dd448d20c76e55d91ea95fa34493a872a83078ed94969334c0a4f834188bfbb1ad0acebb2f155a7bede45be2d0e2a6a9258f83b317acf522b1b356298bd6ad13334bfae1275b200cd2092c836a0453afe1eba335a481c881bcb1f64932478aed51c8f4ad5de75b1e48ab95f576b8a0960ddb0268f82932a513338d9cf163c5fabb2b496eb531b159ea31842a5df6674851790c7cb20591c49fa9f0f46af9089c2a1592650e6f52fddbc0a30414e24c66a72b8b7c1dc32af8b689d5225669f138461780e1f76c9bd52d2a88e493c576f57550f3241104fb6ac915b1024737e9e23acc97aeee7e03d8ca260c764ad2e5c864be648089551baef1075fa55b97e303c3981855e67896a7b65297ba604a59a465db7e15a58d2443bde673e57375d216e74b49feb6094ef7da6ffea9da65c5ac6179682244c616076b290c641ba7baef1e19c4d7bf2ff1b9589676e1df2819c4971ac623c77b7aafff7b4c5bb3b34d6c6cfba1d987fc76b5e4e66fe161cfa643c0fc7a384855a33c977dd9558aa73c758c6a48af3d6e8214b22fef849a06d7a3958671a6dd3ca607a46ab8b052c75629f645b98f8f92a7af8a3594e9b58669d06951bae455a341126c0e5fe12a6261575cd4ad82a04d7525bfd2deea695758c11c1b468be5f0ea11c41f1fd7d2b47f1f5a258cdfc94c6b77194df4dd065fed686992e467af8445547f148d8365cef98af364d7716c125fd7731e48550f6e624882200ec1206c8cb53a6768778f9b34c6291459b486951cad16942bcb16daec72da05b8d4d7e0464fcc9cf19cd6ef9ac9bf110553890aa1a1c68ba12ed8a2d87a4cc4e624f20d249db7657df993044226c74e5574204b1dd9f9029407b9029039e93d0e0b5b5d0d8ddebcd9982dfc2c2d19b1177b0e5cd83750a02e6feb1f61d1ffb3f3fe205512027db23f443f62bfd6f634d8153b2ecd5b1cb8665b894e9fa7083f8675324ee5d00bf5df0fd74c5f9e76898c300c9d930537a15d9799c4ae43478c21e377ade53b4e22d6b1606e1232d8e4797569924c4692a882cf35a86a399002448352a3e870e6bd9e081ed8e4f16da89d4dee6ae392825f97e3cbb1edcf2d6b6771e86445f2d1936a59f7491311b4621ad45620dce808a3bec0886124fdd235284c822dafe15b10a4d944e078d468123ab17d1a490ac6ab2319c212ca22dd5454e4e2639106861ec2b03934a072634dec1719114e5abaca6d26a5a1bd9f82d4962bd5745d3062a83a63b8b02f4eac53f9a05951339a4b765125c5a159acdab48e3d88515ca4345b5cf285f5695d6b9e9b3ced297f8d97b12b7f958d5f4dbc6a4b02f78a92ab31d7cdaa7e1f2a5bf5dcfeca8907eb234edac458eef6b2bb9c7a1121d2ef5c98c1444e1e2815f0a22f8be723288422693709049d98e2efb4ec68585adabe33d50a4a02dc1813b3976a56c801bc7d9e93f7c63cd1cb8d274ad1bdf979cf82cc8133923366b362d456b7c730edd9302933aee9a0caffee873145048dfde320048f639a488e334c3e4a22fb4750a42e157e0ab9353e451cb05331329f0c14c175690e1a13b96ad8d509fcc7cf59b36b4de335d14587b5fcb0cabda98babeb73fa99eee68d812735161690870c57c10b904c8f3dd1b7e8dc367fca64836dafaaaf4da40e032d5289aaf6b4cf6e9138779604ae936e9db18474e9747b0caa1878e85368f6dbc56e8819f42da072efb60be2104c1e9fa5a069aa557957f60fd219bd1421284be2caa52767158f1a1d6ec11a4b1455aaa995bc5532dd27e26f77fa7d6ebf5f76c6219b80f9029108b9028d3951e0b9f5c7f40185b72ba27c07e4ded2e32fda7da658b593339eddbd73d1298087a73e552669aefa00656b4cc9b2f65e9ce48a0cff422954e65a40e3e49e7441d7c8a0cda40442d717e938ed702427cb24f3c76de9d51e7b6244b81866e11952dce8b41d2c27f28c5e51e1bbf7e9971cc4313176787256a1d7cf8fc46aead0719b4999c2f67c7937fad34bb8d7b7d0df1381ca55524f1aec8515b4ff0ad426133844452edf4c6dc8414872df1957c31de2bdf030299d354e71640493fefbecab6cb1ab57265da8e42934d266bd7e3d5b5694cd93e666412569beb3bc02fdab53173e6c23d547b5dc2ded7377c8aeaf4cc6cf25f5ea29060dc42bd056cf4440f08e7e570b265e9003d3bafe1467a30283c21e647383f385cede0bcbc5d5722b4a7d8e150355e7172e8ece356e660c39fbe51d460a3aba94885cd5f394666c8da6986f3dead280965af689430339c0b8aefba941f625a8b9a080f8f5b027d6aac557ba493b95a361b9eb9ba1b53f4d9ffabb8523597d81d5e01685b8fd39b043a4b7ed5fdaeb06ffe69ad884766a9c15b415ee9ca6accc4d974ff3ad2616cabc6d7e681b358e3050c922d4fb98ccac89011af990b2a2508ffcca13b0555e5522c88b9e9cb9269dbd5ab6d042520ccd831ae2acee44bdf92319e91d3281e383943cb3b3ff84c9e03f3c69458fc2b130a8cbf39b6f345ab5bed3a9d4e896f423e70966f5ae6abbeeb865e0d7ddda686f6caa8daf528ae2557d4cce7d83aeb9da3c4f8cefe060f48315b12dcedf4ea5b5633cbdaace5b778af1207f79eb718d48cf542b7cd9618c418ec8ca4cf995ce65483701daed21489e7dbb45fa9ad9fb4b8fa9a3ad8c302f7349e4020510a5cab2c6b691e4be703f93241bc1b5a714de14224492a2473f68f7a1484409cb80",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x5f9b6cb94a5bf1c18c873d0f57a848b46282362bfb60485a7e365f6cd04cbb0b",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x1bd5514286f5602a6762b0075266379d29af1c9d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xf66410",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x0f2dfb12d44d64b7726eb30dd230e86cd7c04b4e305b92a8f3cc77bc2852bc18",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x1fdc9c0970c0b0621cbf71c039b01439e7231a1daaef8f47f90ebbb26b91f4be",
|
|
+ "timestamp": "0x6a92b144",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-v1-B-9chei-anchor-16147472-baza",
|
|
+ "sursa": "2800v1-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa0626573752032362e342e302d616572652e312d643230333230312d7774613037f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b841d166e93faa5a0288a8de054f2cdd265d2d4f6b960b84aa2f39416bee718baec06706d3a81241db5704f5984e7656644cfbb05e4f2d855b3a0d71dba49edf7d6300b8410b85b8169b4675ea4eb4e4c74eaae443e8185a414b54579c5bcc46ad47f720147ca906b9899049542d78a2d56099cfe3d830829d4a67cc6dfc0484683def9c0401b841e1a4c165fd014255e7bbd39d1737c9c13b48f98a6dabc6f9786326ff69d5755c039bb05ebf8d089a879ab34d591c0a9ac8b2d16fa1bf0f2d25e13205bef8dde201b841809669ef579e41645eeaeab987357f00b80da8bb684ee69134294e7b46529cf81b601172af3da843c9b2212dbbfa39552369ead0398af59a139f4914ae39516a01b84149dd1709f851eb99241def81fd49b012d009abe5e74d19ea85c0d63489b05ac07cc72720e53da4f3f8c59155bb2298240c24a2466b2ef205cd8ba42bbca465ef00b841b8c0af799465a02b15d66196a78ad13f525db0f8a9f8cda65886e9ab0be2422143cd8f618b0a8f569da85acf5c1bd1544e137fe3f76a4c5302b926853922d72700b841b323c2b52d270ddf5849cde7c743299d05013ae19cc7f30ceb7435fafd4af8f75fbb5ada2b0e5ed40627bcd633cf3d77b974640a50d0c8d9dbb8e4d8a588703a00",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x6ec02a71a91d36b7f2583b7ac7ebe840dd311e187c05db9e6023895d956a6c1f",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x1bd5514286f5602a6762b0075266379d29af1c9d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x13747ef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xdc05c7113ce3a7e5e1d5131ac90ddcc0fa271a11af2268170d7804db44bc8e0c",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x4f0dc8fe422e48635eeb106e6e5337620127244a7ccdca24a5444cf58118026c",
|
|
+ "timestamp": "0x6ab8edd1",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa012e9ca0faa60db2a29e52586bd7f2dc154f89e6394a953e862896680a86ca2779a8f5eff8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b84109c42f1a461a309df880dd540d46623d05ce3c43e340beffba15237e101aa09a764785c0f0d464397a31dbd3c2b9593f6ad38e06a4ca0062a0a444c8f503aa4001b8419f582a4b37644fa0af2bbcfaf923f263ef54ec490de9a54f2a107e4c607e79546408c668e2068dd538d1fb050528a4e5cf123847fbc464986aa8c513d7260d6500b841a30a877cc1ef9f0d03b23e84f29575503a84e206796ad71558911332a1f02ec11368d44902a49a57bb458c35e47f22e1e9bdbaccc5694655c07e96be4909684b01b8410060b5dd962fdc24acfde6b13285f5996788ad641439a5526cd6e2060dba3de67d94e42b58b42fbe14cc189e4ca748cffe3daec77bb0e5bca947cec4616a361700b8417aa4b46e3d627db32b01f95e4daf9264b92c7239a8f32aedea75b874613dabad01938a8b801700a16b4acd36eb8eac2651276bc8edc7feb1776a6e0faccea74001b8410468f626702d29b3776ade18bd8efe2978d646ef29f72cc049c82ce48ee2895355f426af259824cfb1ba758d568652701db7d2742441a1bafb718a6819195d6f01b84185de9b0b4a503864965a75a2b19873c76b62951a9f407f56b207cfef04b3fac67b27cc13594c94c07cf19fe4846c328752d2917859c1b0e5f09ac2cebb9ef9b200fa012bc902fa012bc4f902930180b9028e3980265e90542900e550fa34e2ef6823a287ae20adbd729ffb96e12d8d818673f0472d371c888682b8b65135b8214191bfa484ea129dab7960ea1b72fc9d58db4705254a8a5f6d3e659e9e0a084ea587527f757eb6c6bba0c30caccbdf2fd5641d6f5737bbbaee244b06091ef2d6e42dfe2acf0e645eab9543e14eb4a2a872c30946ea5de776317a263323337bd7477b9a7cd3beb259fdb71905a8a6f15fc5e6683f0c4a066533527a34834d906d1ae72b0f4bff3875acea15af9afcde43c2b0222c1cce8d7971f4051b21008fba555f8cdcf6c6dc154142d106499f843eba6c45d78d7c9f9e7703992957dce8b2609a721169a2675edf5362720720cd91d5f3a4a27ce70d57650f912ed1e62095bf0aa28288f49b0d9b04cf7df61ac4993ec19baa4fc935a32152136785b81d928b1d7ae2eb1d19a3d1bc3edf5b563a8ceb2ee4b174af221d17e9fd664d42ef3adbbbe508ded262d974fd8acc7c17edbb939949529bcd7f874c468f835ee091997244c4295075cf7cb33e93262975deee5a19be61005b2e8ac4962ec7de7c3d28dcedc2bb49d02ce1c77856247da884bf959b2305c1a027b4fb1af2d5312b7ddf96a0fc3c8ccb0ea1689c1e5264c9a69e0c0e2643d996312abdf720469eae04efbfe286a41cf73617a26e10c276afa00e5fa5b5cb9ed1a8750c6311acbe7bfb1c691d6f653c67303b17760f4621d36c1b0c635b2bddf20fef5b94a9de154457c834a62df9f3e2cf1505bcc49f9c09db6893460f7870da46995ecd9903a124ebe4e0b6fcd24d78d274fad12e7777108f6c1776190299f25533355ecb60e7abc3e95059abcf8d7dd4c4d1950b9467442079d4459f678f368b3576e97bab32aed2e38db46fb65f356e7c689b5f261d50533ad48cdcbdb740ef376f59a7718ff46a6bf91eb50280b91eb04d8d607f130cea46f811b9a5b8527ed77b2f3f4088180873f38451b9c380edbed116679e308dd5e6afe1295a17dfef8bf982a075998991df954780de8a27960d657f0e66bcffb3b28b8d3c65465d000088e258d4748babc9e7bebd6025c26c4cba9aa49d9dc838dce81117290b0612d06f6f0a27bd8697e61a1b2379a1cf7879d60fbd1c58f80f594a3099a1aef68464b92e2fa5f59d55f08c1d4d5817454f1e02ecea15e629c7662f94e01aea8d521b9dec58e4e2c707ffbeac5daae4f599a10b91c9788f21f863d89d255d0237c8290c7e84db569d3ced5f2effbaebde3e5b75a6000e1d7af0cb029b73273bce68a58d8369ab5bd458182c63a914ff6d1c1122522602404234d5a7e66faf61cdc0fe5c6eb9dc7fbb3c6a61f1a694c4c3c25c0ab7d6f744776a0f4a82888e4bb2464894789c480b07d1a739dd59088403801fb8ca6e6b559b395ba0ceee7c67f183ac548450d46e216930738c5c76f23ece4261bd7da6ad5280d261860a89216e3df97f151ffe4e3e30ad96e7734abbf28984c68b8ede080c422e930d68dff6f0da1606a4b1baaba1ae3d29acd0f1eebd27b60109893e6e4bfcdfabe86da98315aefafa646b3eccac64a4ccb496368dd524b50bb74ca9726a8ef04e43a6ed94711d76ead950e4b6382659f986ee5cdb173ae37ea6fd5c45328d402fe24a938d455ee38fd8334907ab1f0c3dad52c2f81e29b5693c96361ec50d7fec245d27d7cb6945c8c22a3951727da988b460b002c81f7bc573b945945186e0697c542b643d0fc6239c6f5536db2f6a7f0d2a9d213145f92e318cd9df66fd68e37ee90e152715b991ceb96079e5dd0c1447987a52bf81e95d8cbfe0cf81ee7507d8f93b9c980b085ea4e01a49b506e6389da989f34bdfab139db28af45616059c8e915b4cbd0638bea67bc6d8d2da3269923ed3ee0972245a74689ddbeef4a6046e367b24cfae343b21d3e65ccaf761782d34917d0e1f829ec8a4a88f081c1f0dfc8e6b3b7fe585b8e43b05e00a1c5c630dff0474f24af030a771599092347d13911ec20520cfa5dd4581630542e877f587d7eb55dcf858a6c190fd9f569e84855953ba5e7c049aabefad5113bc5e50c1a92f30f7acae640128522f4ec180d37a52a975ca1aba03f6de94e380bb929b8b3c111deb41639645729c466e7f6d4d561f6e191174ce05b28b41f8a7f841d80733061eae4b01f70d8ed834655be3c07aeaa0d702faba023d163cb9a1f9752d570d87f8cf1a411e5d4fb9d140626533888fef7378ffbd66b730e9aa9e843d4284baf503fc14839d9220d36e1b8e9575a903c65c8543cc7f63048f9a22a37cdd256268f827cfa9b9600bc6982a33ae8373a306e4edf3de1a39452e34bc97254452e9480e5650fc389282927cd39083e67b5a24d997c216e707ea624ec2186fc0896388b0322a5c4c9eda8a5bd31052a273a771595d35c3d1ead183eaf8cbde27a575e37a201111ea00fbf21ade5a7e25744b718149e3fbdd9b3660f2021336903a40d75caaf6cbdb0ede8e9d220b5b2b42a41415716d903b1e67e58e818641eaacb4f724c0f1555c4c430cab43b4c0d223da0fa53e983db88d681a5888c8a0c974d7950e43b053cb786eb9a4075c21e1f52937e79eecfc37c1da9fd8d35f38fed876c7aa029f8fe9cdc39554962db5315a9c1b38bcf40a5d883659b7a670086c0b3979c51f4e8f5eabb729e60f2e87aa0b5decdf5b58b2ca63ba2d3ec4669df93ff19cc757e7c59944d0192b54bc535bd1edb63ee77ed3f2b353723f43e7f15c0877422ca7785781f01c1d2ebe84944db6650bf98ed8a36eae5bde99cc9f91ca9f5504e87d51287c3a0e223174c7b2099acd8843ea537c90da38ad158230d0b929ed4b7ce2a8c603fb6a87d42b6f44457b53fabb1d293064401dce5f06a8b5bf59b050aa0f616d9ca3dfaac3ae507ec29d8fe4a08c6b215735acf16455ec239b9ed95dec76b7ddb0c4d13ab6e8899e9c5ffe22277f68e47e6b3f9874434ab38ad60d730935e4140c65ad0fd6bbc99dc5197ecefca2e20c610efea0b5c6ad5335422802662d1aa901b7a717019600e90435ca03c4168b43fae2ccb8057845f9576a15d541384e35aec7ea05648926e672a2df6669fedae70f2ad33f24c052e9f9de835b582d15bda4ac0742ff06a353e6a2f024a4ed228024ffaf119d2ff80438f0582b657b7682bba96f9df9e9c1cd72348cdb3d1a913d28584047f6bd417ec88f19ff0d8b99c359ca5c276f2f1a1cddc8c98f66ada1badbf69535ff85e1495764b884b452f4f08a3384be6a6d2ac61945c832b4332bee627362492e70375e41ccb9c0a27ec7103e2ef2bd6d8251739d4ff3ad80ca28cd53d471cd3345ebf48d59a023b71de653b5ed42e6c8d3db54b6947e866c9701fe640452bd25d239efbb1d9d5a4603b8b8f42fb98bc098e00efb1d784716cedbddb13d942088c3cdefac95c645e4a6a53d6a1b4f5e2355c801eded3fa7c3a66b274bb6e996ceb3bb47d81cba92068c49d70cfb01b5c5ff2910b1c4ff5dacc0e698c13c6437484d447639d287672bbd2195a46c9a908184f9f57049bdab40b8a12c77de41f4d1ab68f87587dba2a455c0de989fa482222b1aa25b0da51a48d8ef1a88e68da91ef2ac84effe2ac6077a4469e2649b7a2709755d0e636a4a3d913714e078b3906fde8ae760b242239ad25b2901ef0df2e82793ae20dd71d0d698320dc187bac132e9bcd5f0cece8dfa2147f841f14be996336553ca0df21b3c5290a0b170e910b0b7d6a9c9b7541568160eff8178fdf9a8a6652c64560e64a5a1eba02e84e3b8261761a6ef9b2a7d9d4213f89bd7959033ac194e6ce093da654636d15017fdfbceee388f3bf12ac67c183f6c68cb6f04cd933b184441203da95ea0a93fbad20c157602b8e36645a5c7166d99e7cc9243dad0c973f144c43090ca86bb972b2d33518728840e835cea2d71f2a0b373f9d5bc183194829a9cca9710e8cd70ca1994903501111f51d4fbe4949c7e6f79e60b3cd941e5924a8ba1db5eefd11526dfb13d2dc4c81cdef41334c1e0a7c8802a9de60e7d47909e3028706f122c54219a6ef3207889bad38aaab025d6637590e6717ef4085f4d863afc4889f3750bfdc77f64f1fba1712b75e83dcb47bc918019c5a89bdff2e22b814182572b60c9ba86476921ef5bb977e5e15182b0a42e73ba813d6ebd997235fd215d6e35231b966bafdafbb3c58d35d1eaadf1d151ac080f5cc0ce53bfcc68b85b37410f1ed3bfa52c24c2c4442d7b53856acec0749e8375824eee2229f1defcd4778d2aef9cef5f92ea5e8b0104401301426b313feb14fa3695dad0503fb179e0b48b95da111df9ded4de39a7a5f630a6b153aec8ef01a96433541740ac007e1d2b2c88119aed5a39983f23215dbf347e9ae458a4d7372166ed802c233ea5bf43eb1372d091b7169563857e8180c6d34ea880959ddd1702dd994e01bb60a937e51ee3da618700b2624e3056432adda98060068bc2d6dc396a1aa9aa399869095acbb987291456e43f2c6b789e06aa0af5dc071f6badb955df7fcd7dc4628ec6e42371a8126da86cd89501666dff204f062dea9faeacd8d6bdd9121eb5d40bbc9c9ac9f3e7a4eb11b9cdc65d45c990ebaf3171d3897a401fe05cb335497a2443caee1f38fef010d5e2a5a1067b4baf21f9a8fe17410f3bf5b954b4a97234638c451720d985e436d03ff1debf491fd15fbe8b96eb9c883ce90804b2cfa578ff2f74ddcdcdd48b49ead83b8fa70d91dfff4f7beffa55538acb12de87f05c5bf5c40b2c9b9cb0a9e92e060fc9cd3c46e4dc69a9c33910777d15f4eaf9d2d5e790657402418c1f59bd00135f86bab26839c3288d6a32a9dd99e9a625e02a532141f58990b46c6c83ab01b96e9f0fbe20382d862738b727c9e509e01fe0ca9811dab635077708548e1885cdef052b80a033ce7c568aa12259e2cacbf2d469041b4891b145956fc99b97af3608b90ee6d298b7afb643686a18e0212a50369d1d406b0282941a8f114f6e457ef26ad8c9dbded96785dabda9d883c7583c99e598faf0de282d908adeadd0c2fa619ed660cc9c81d23eea838763593cb11295f86088e45ff49dd0c2de6ee737153ca554a982b0edd674c7aa62c959596e9f0c4ab94119b78a2786a6d08559774d8575b52b33ef5f29e84b89f8729ff8a0af48938aa9537c1669e3c8f403151e7d6cef5d1f92304c3646f83839907a1cad5add107cc2d92949c385ea534fb8a770642dfd76cfa95155938ea0fb2da0b6a7c9d4e211d062cab87d2569e026f14c7c64bd2affb7164d7f67a0de81e1b68f7b26c7ea0c699297b367fbc7ca33d49d2e3cccea661d91b60efc115030c2453df099a3e068dd13e8c8a112b7a4c4afe4bd712d4ee69ec8319b4a96e284228fc3c0456c817f674ff78262949401d58adc556f506e63b7c3a9b70c53c5f3ab5352ef9e8012e270851a81f19f2798057948dc7732caf68e62f4c03cebb6bfb43cb07241bb9614e5d2f4f030da81cd3343996d1b409f666e945ade76218987052ed7e8c50104a710a2c8253a8e72f60d50545e4b6040a695861fb8c0765ee1f8c179412f05f3f71d57906338cfa4b22329cc203bef2b95afbe95d7436eb5d4c1de8739072d7eef17df2b7385919bbb85987a7819160ace741cb4a4e3f664dbfa80fb50b39cb37408c78329c50fe930a4b9825242eeb66ac5d326c366a1d4973c4b851d542c88a5d2a4250e6bcc90eb1d8cec1822a05ce323f39c3c3d1229d4a402bfb2102522ce6ec0f0637dad4372f295f80f1b11529d41f3531f92ab40cf58f42e7e2277d7be03186965f75640933b6c05ffa5a1d2f4d4b88dae8d88e0f9ad7c8b378f715af32785e084f0212d94885b11671a264539f2270a61670317828453263a6df21a2fc17f89559613a45a9a7de2ca8c7258ffecb92f6b4fe1ff8e2a368169010d1d69427da77c67bc0a2b9b249945d7bcad37f4c09d1647ad26326aa3b3408c32c373866c395860e77bead4d90940e7405090d83804553e697e6203aa4fb1cc29d3ab7610170a54cf62a16c7953a6309c12946a1019a528ff1b68b9b52aa1dd4c332b83185e9242c8ba4b3beb34a469b4da76443d997985c746c19040a4d14a93ccff63461c64543d2b34a6812216337ed180031c3639292b4e45e4003abadf581701ce6694813a07229e0ec3065470b3a182ea93d5872c3fde13c4e2661785b35331065a67e44fac73174341704475eb4c9a68fe7c5be855917ea8efb03d3dc7a6587a287985ba33fc0a1aa6f486af201c570bb352f7a5f1a74b564c328717fc2f737fd6d7d559152f77c7b593392667ac1f60707a1139218d674f3558e7badbb9607cce534e40a48e86bf58b2d3533ffec1940b45c2fe1d6ea8d97e110e11962b73bb14ff7efc7af7fc9fe29c72494060782fa4b4fb4dd53290dfcdbab4a00166b395ab94d101d5f552b023f0939a8fdd812cc105c91bad8fd196078a63e84954406a6d190993b5639834267905c86519aed466c3a04f5d300ce645a4058edc4f936226d022c16984c45dd8d04b428bc8793a927312c0cd3a30fd517d9fa4354b7ef4706864bea372db1a5c5a2fc48e51cdacc756b33c2ff0286447fe20e009c052e573f0eefb939637bb7f7efbf5a16acaa5000f1efb8d7f868fbe8bdf3dbd73759df7b4997fb45ca52213cb1dccf9430686649a07b1fdcf0a1c52b0eb31c70218e1d12be8f4e1460939e7f66ee891d9f6a25e56aad1f7d42a3bf4349d1670ed9385176425f947d2ca66844cfd4e3268d555e9e8520d6b00826f320d871134ca4fd079291aa531f5626244d3f75e168cde9e52b48a66272dacedaad178731e3bca9aaf5feaee8f8b9ae5a141dd2a9fde29776bc6a95bef8e44461cefaf76f5849d78157a1bfcedcc2ba253b427a7209f5d771344d4b94afd7f9e9352d4f0372a6c0dc38c3bff828be900aeab4c573342f415cf4a947563463425c2c35a9fa4ee2a2ebb9326004dfe5381e16336515e5f92dd02e74772e2c169b8c2d0109fbfc69df0f37e1fa5514a804089c43c048d8094f00e7cb1808c44c8a5e9474ad9b11ab2a615229a0ec1a37eaa2d008215c3773e75c050c0d255e3af28f67608f0ccf88779df5377e4b4057551b49ee532f42807bbeda902d3f31eafa1b34b7f95064ea47d7b3d3491243aa20dff8fba37d56b70bee421fb10f479c07cbc4a898025d1cc54e5f7fe1df6e0632271fc15b2d2b26b077bb07caf9d1bb8ebc71ad31c6944c6ee21bdc40f9bb4efba5bfe63c563a5715dbd1441c3b418919f0de51c5159ae9716b59e9e390c045e639ee1df5a9d6be3c29e70c98a90b236f0d2ed9311bae14c5aa51c1f55d236dbb604bbaebd038b38a156c195dd81c2f84d3fab699e6cb062bc1c8ff0adcb87df8dedf30077c6e7018b80a48836d88cc625e95f4f02e4d885241e03f4cb76c7913fb4591c2b950038d151127f68043c791bdc53efa1045d49d669cfc20e12f060902ccd3aba065b7229e7a7779db2ea0a348835e04a0c80dfb6295bc2aa60c6c4d025bccf29c9dda1c4673451359162636e068a1824919b891c8e86267923860ba6c8737285ea548c10c8bb4ff71cad235181e9135e847166c98e2c8b326ea2c50a09c6a2c8c164806d7decf3f51a40811c6bdab28a5974a8f4b2ff58ef1eed68120b1e1185c5f4e619a3871d495a84d26e4e6af74b553c1afff16335b8ac59d8066c77ff5d2d1ee69bb1772de1fd50a31f367e7e0a36b01b212231a2821efaad535e9ea67099d5989bf82fb04e207cdb1511cd75fa4e8fe7d4e241c91574cfd27ec2dd4d14a00444ae4e62320710e170ec0f04338351007f00dea7b830476b8d1a406e4023da67ccdb256b5fc5d2cb6d1996600c25e0b3ebe3c874e5df14f94f84e9830890d1544022819a76977aa9647ecc5f6ec4dcb446de87fed640c48a1527ccbb81b6e68c9e44cbf2a508138c8ba49b3d1239a174bae23bb5c1b13250ce719a096b293e23154608726f2232bbba7ee010c4637130e0333c7fef802fc4cd812ab05526a6a8b1ed73b023f9374d76d3078da476325f2e078a43e82a94501586771791964103cc010b60c94964bedd31a66b7070a2f9242eb403b54769ff56083bb6c7522828ef3199850e362f111ceadcda6db8329e6785f14bf7237e9cc629aed0478dae513fd3ce10a63a05f64cdb517911dd5e73d85a9bc782f76d1b3936bb76bf514fc4b1688bfa06b800702ab351725e7c59e2f91966c4764d69f6b0dca15cfc68b0d625138ab1e17494b5b003cd63a0ba59a6992669baa1035f5bb240bf168c19e519664be17b1e149d230acdc24113e96525b4e3a1ac731ca6773ea399f2dcbd5c7bb3d14efdb376ca420209d69d843ee6194c797fa392957e1b1b18e2a884356069644290c95facfc7aac5520235296788189e8dffdb49bc4ec619e329e43835de301bb7c0c78773d815ba5d98ec1ec0d2914ce0c27e15b9f2cf573acd7bc76222b3c42fef911f1671d19213d274b5ad4506f975ec62ae83e70fd155e2d7dd25c6f7ce668466dd966cb8ab45cdb592a71070adf73539668d09b262f24325fdc02e45e55bd897b0fa8a9b42b0423c6c153e35c34c948d3d6c257e5c258303c548a373f06cbf8f6e8920b55d89e426030d8a77d6442284f29417b856bf66a586d8349911e50abbfa027a3d93819b89259b15bbbbd16632e3700b3089dd6ca51658f3245394fb1f2272c822fd1f68508760e8f876dcb0b213487071cba03d9aea33cfe5e2194ef0b480db2bbcd95724618166cab88eaf381facb3ed9d87b9b576466b0a3bc5432bd6ba7414e3840fa105fa2ad64f4b832c2b4e03be3996c716653e27150c2d2c3db59a1baf52ac66025e77c7265b3d27ed5b54dcbacb9525b83170c398a2d42fae383109b0ddaf90066a54b665c766b65de209b945bd957f916e602e135a7b45b1124ac82abc65f68706f19392a58723691f3b1e211e3f3e5d9649c152e3daed3e93071745419ca147cbd6bc8c6143bc906f23b94c87c0324d9691852443028187b09801b279ac82c884bf1840f1b657c8072bf81bb962c24866eda56d12f510eb832e506ce9dfe4ad014ae16c424aa313ccefbfd4924fd63855d7991e1e422738246ab87e73a02a1857ed3dd956609ca77b6252b4c8feb704c6d2c4a1116be62a422b522fbb2e8e51d01b2b94cd0ceedff501d50601781738ac709e63ea1c2a57fcc6adcd03938fc41011ec7f4dda3babec4563e266b0e5d681cacdb4fe3c30a32b54ba83f20e4f16f3ff2ed31d6d7f23cfdc127e901a16ac28a7caa2d37750f18c42e4cda1939f1b117bcf4dd74cbce33c5a10ad623c94bf24277e75c9ca43a033ab253e5f7b0e1350d97dc746cb520508794bff5dd700385787f1ab6b43f18760056a7742b0638e69401ee5986a3fa03ac1b0c0c8d0ee457f1dcd57d91cd2ddc5e43e6dc9cd3295b92637f4c0064ba953fe00a3e52a97d20083b6d76438e3a3315195009baa7b1bb7c85b83cbfe9f5d29e8a0baac1cd7b3b0e661979cb74711a61a2d04d015fac62246e960f7113c63a8ce6fad1430568a8d9aec287f4f57a38b34c1bd4654ac0879cb2c01e53e0f65870fa191fc5684018a9e8d8bd4f96d543cb88768cf57b82e96af095460b83673f36c6aab481c71b7e9e883156245b25a6dfd637649342767ea135f72ae353a9719356db6d34a046f9b69e2691260351133bfc251f5a5e2dc927705f520691c1283056ecef5d051271335308460892163b74b08e2310800c5b5c4575448c14b971b68fd73ab2f15cf24c3ad66eb20b215e45f50958c1b3c0230e94705b4e0fd0da33698164c724bfc69abd130235210689574d9d5ebf6e5e88e09099c08e0bacb603f7f9a0393142aef51b939c972b80eec3172cf6ab1f6fab4e959d06786f2ba69786228190d2e5a9f23f466c0cd49f910ee5de1ae4f2edee5ab2835618a500c2959bbe0684bb5c941256b00a7506cda18027344d560b66ba484e25f4f455f6018ce8d74ef8df8d068ba26046fc10e2df5a066cbf71802524f5512eaecf5355e486cd988fcaef6390a00857aac08460de4ec54b348f66c918a5cd9bef4123ca259ba756af2e2c6a9222fde43ed2e7864fae50e6c6c5bd75fbb2ad049166eb942680d6ef379500f23c7121bcb6a8033f71f20a36ec63fea4f20ba6f1be6dcb1fd01d600a8f41c4f2e304779e040c9d09045106991505b94a2d56a165f1ae44d5930e98d03aac07f0c11465fbb5713106c236d7a9aba2e78286f74dfff39d303140ca12a76c07fcfbf9cb50365bb94250e2dd76a9fdc85fa2c9dc75a0342b3f4b1c84f129eb96a62657fa771c7c155baa6ee66bff794907b2b88e848a90225cfea289e4fc6893681dcfaf23c5a514d5f8c01df5c7a9242a5d3758b530c1cf839fe791f26d1c4a13b1b3c0c7076037c067ed241beabea9bbde5e683b3041d2b0b3f5c3445d8635a7a5eca5b3d3443faa6a1f8e995563964e0e5d1fb481c97c5c0f0062211ef560575055bd8b88d121b2c086fcba50d24811b8e7ce7cec55ece6ec8479508037c89612100ac3e30106318d86e34fb82cdb3248e3e799f35e9d7d98a0f2e81ba933848e4af586433f7eb3442b94df157de2a2257a1b7bc8b7cb1bfe3a1c0106f3c7d9f2563cd599e370dbd436b06be9a288c6cf0c8e2da2cb8aece08ce6caddafcfbd28b1ed7b360978be5169be43457a274cb62822d9ab272a080ef7601d996e76659dcaa8adc3736c056f023f37555d4af7d6e0d9ec01ff7638277e52c14b194fdd7b83094020e8d91fc2063009a4545f359ee5e2595822a7a575050fd584b4277b5b3aaa332c1a8b25540f384e2c43b66bb1d3cb4a318e55311c984b80c3ceb6e5543e611ac4e4f4f92a89d01252bb72a1221fe57d57ccabfbbb210619bab1ee7c4f2e1a058c2815ed1a141016fd6eff3144b46a9e28a0cd5330d22b151d439dd8a45584e554d294ad076d6c09d923f648567a9f28f52ee281e45defcc56b4b8cf6c9c4f31e216b45914a0e67f973ef6f4647912b91f9985f17f8254e322462e102b3e903e73a40b3ba43f5254ef0e04d3dd14d11bfeb6f636b3937a0132ebbb81944755acdb05612448eaf155b54024cd9ec83551dfd546b954d80d11f851fbeec1587756e227d3c7f01436a858db375cb88cbc9d4051ad0b2ec56e96f10e167d378268a90ad66b774e461ebc7c970dc6bf15488cddb891a77749d122894ede0df3714fafae9b472cadaa8fdcef1500f5887e6a29db3bf2a3e54cd3571866988214c21c4ad4541d9039e9694752b114139f3aa3e6b564a3c03b356ef4ab1a83ba7eb5a6f1b1960e7c4bac2caced53fc283ac4e897a01f3e9913ba85fced1bfcdcfdd59baf4af52daaf36bc488edb82063e66e660096916d7745b10891aed77e8927b35541865f754b1566791f49329eb7d7ed13c417d1708735539d17c611a7ec1bfac3bfd6121eabf5cebf6accd4a49deb1f44c259facdf266e36cdd5dce9457dab23f9ab7aa66d8465ffe240e60701ac83275833e187d05b26cefd4382be29c2f43562c874b1a6d676bc18ae23b3cca9fa0a4066e811c093569b5967ddbec64a48f1fd37255f41ee005fcda80e3fe7d0e96ab62b657242f71b46ff8d94177aa37f1387dfdb0f5154e654c8b3dabbe21a024d92620bb23a368c1d28ba4e8a28e8833ad23ec51c36140dfb64643ee576392786eb25cd7e286970f841d3b3364d52185e7971191e3509f485068d931096d767e9488f446a9def1ac3c42fbcbd60725de04424f3ac35534647a537003a5e78e5e99625232f9ca61f8735d414b977cd1eebcf95aa6666865df729a05b40c209e4a821977022007cfd0e90b1e037ea6373a88d74e9e9a3e23641bab816fec61ccd865bc57a6f7fd9681f8da88ed1a2a68ccfdc298612cf86370a1cf7fb9294c8068ea87cad2462e606cc14508bdd333414df2a345b9dc60a7762cb1a0c2f6d053bc1da73175b8d786139a66b95243865cd82a1cb58d7d353743ab3814329720542c72c30e7f04e27686a4ef7c49c1f902950101b90290397b3650a481c1f481de8fec49740d60803d8973a2e5d3527e18b817e0e95a61ac4293ec2e870527c5cba5a0cb7700f8dd5ae8f6469b32611dca7c17a8a59f17df30e24a33b4582233336b670e6ed30721cd614bfecfbad6735bd7ce15e79963b04f2441d349e10fa4aba6799307efbc93a1b04a5c71ea839403a2af7511785e2527c372f13c9c4c1979d523dbe5056d49f145b1216160f19ba97b61a0fc4adcca83145e1a7871ebed4a9d2a4663568471b5d57a25ddca16dd02b39665987276f630502b05aefeb072686e5f25209618874376ce128cd5e335bd6c8c67fe779faa12395149248d3b4c70cd35ca6d30352b941890910806b8904ccd894635688e12a5e093d4300d475c2c5d8436a2ace0e4cf2d4a9cea6d8684c28b341a7765eb49e0941c852b1309a87763b698afcf248eb229f9d97ef7ec9842ed3afee69ce3fe2f354834fb874b9c360dc31c242822b1e737aee5031f26a84490060c939981c744586e8b46feb8af38fd590b0d9b11d332dbe897215a766ed42a2c9a2ac653ff78386615c1f4c1f5594554d574dc521898a7fa345395a148a8c9bf0f7f0b630a1a1af65a6f5dcb849b0df194f763233ea53e1e68573ac90cc9cef5110d0e537a992c8e9a5deb99362443c7b253a0989d313721cb2789227a361fe52e38f267a198067767f23783907f716c414667c949cad67610cc7fb74631555839664c9d76de617246dcc84c7ea792ab218f4f8641bd372cbbf7bec7c93b98a48b86f7f254d784dccc86d8c4a578155cbe333b0a13bde6cbbfcba8a810cdc3d899d52531d9af7ed183728415c62b3896baaed14e1f8885acdb9f38d30f85d63a1926a430db471567a4dc5a32c8cc6cad501fcc31294c96ac9c2da5b575594d95862aa1ccb15885c207e7f3881af9e245bc32737bf91eb50201b91eb0678b7d27551724db651c11bd7fed97de9069f11024e149ba45d7185190fbf6280e89ae17b641c8fe4c331e5fa6f26da9985ab3fc9e18946f143bf2490d65b3af946a0d266120536a9f4217f95e008f2aaa0d26ee2672bfaf4ac7de89b05612b921c1afd5266a80e763b7d9cdad095964ad2adabbb4cf47176ab6cab59c9ad6b64c2b8381c43a12f14e5828f702238b6d5b5d4ecbb417b6dd0c60e4d127b57f7d05b2bb73a3e5fc9c4ed05a91f6c65b9f276327fadd92945629b58ea4ae3a816f24bf269dfe153c3b577576d925ff874be8f6536009c73104bdb71ff7e5151c369224fe9fd69133884fec0a9410ffe8f7181232a4ed45ce024349945ef01df58965695288b6fc9b6f8020657481eea22ef514958b2174d860ec152dbfe7460bd3f2c8a93c9c113dbddcb5a5c26d83e636287f25343ca1a402aa4733af42c757d6c291115f39c59a35ddec7af000bf18562398064be19745fecdaf20fd40329b5034826195738f6e419470964e8871bfe879a5322051f7094959b03222c84c9e614d3f91361b64e08d146d3abf9703412b74af884ae18862166a1eb682f4a9e32748248c1b6685944652750a7c28c6265413604384cb13c0b61051a7cf69365f6e0aeda178ed57a9579ffa497246f18e614078d9fa1beb2830f20e0d3b2de3cdc2d0f728bec60448ab32ae9a26e2f083065d903051bc539123a388673c983e3255234e73dd8d3c1379b2d1fb40ad27fd866e10f06d624c8a9d85314695d8c7c8f23f729a2d9fd25c4bb1e3663589707a800da634199169105fb8b6e1b0040df170712372d61730256e8beb5ce7014ecfc2e71b92e094e9630b014cbe654c29ceb2144544f6c16b23dee71abcd70879ec73dc58e52da92b8365eb642bd8ee651a8093100fac0a46b4b23e8ae740d6eef0930c4d09122eb5f95080f0ded3f272e44cb729d988e71851402a60e07260eb3831b258fb292e105fba3b483f26dea78ba618d8fddfcbc58b4291f976fd4b36cce0d64b6ef7cb29c12934068e5c2740d21797222a936c703d58d0b273ada73b74e81b569af86179a3de21ff62157a0ee90b0e6b58ac62e24ead8ce08566b47580e844eed404914b5ee362b114b8d53d436f7c4199c4b076469aa700efeb8828fd368f12dc484a4244abc723e299c02c70198ad176c770e5945d498619940658e48fc37e9b2c6870689cd12bebbc042fa700a356f498c50e4d53cb4100bda771678f74bc72ceae574693b2480d1d1c05df2a301de7fed4302b5858a0c505c41c6d9ad4a1633a6f4b09d3824a560566af4fbb07c3ffb1060ed1cf280890919dff43fc18c783f916e7b0e3cc61ec040f385a422236ccf0083b4d4ae45395a47c5899c73b09744e266d2773d91818c44dfcfea06732beff95d1304981a44e437d99e07158ea864b83bfa496843c3accbd674c8e17580292902889eb8e9071e2663394f60f6662fe29fb6fff257beafe7a0a9c671b043c5262c9da20e0438c8cf4943a4cd6af2cd977035759f427d0c65823e2c86b79cc09e2d7e45484efc4f8a260cd97c764c82a438a0230be4fdab814ac4047ddbf8f6c712179d69921b848a71d406ccc2409fa454350712c2af89f3ae91975dd34cf41baf2836736df8a479c176ac38ef12cdb0c64ee1e55a55dcc60a2d8b908074c23a8ef929bc4d2484f872064d30eab1587270c041959223dc38fec042843c8048857339cab21d452d726bb4b809b7410639aad44a2f553b46b3c7489f9a2f1789e373dde18c41840d4a5ec9d5a4510b0d703cc0395a1a27d21de98f563ab879819334e4344d457e78d0153cf548e1fe8e970f86e7255b79cdd0394393547928524e1b9122bfe836a7e0fcc72d608c84ab90541d0c8f01a56818822d4ab15b81200ee7399d3ec03fa69d18f2037cf4da8cf9630cd35ea0cad2dcc12f5ee10c9729ee0cde73a6c694ce34f018d54be9d24eb324b5266773c8ad089dd61045ae66b06c8b81d0a8e70d362bc3fdfdb939d573999b372979761479c36ba7cf73c5508bd7e4b91785cade92e10cbc8c1f06bdcf2757949a421e1b01eda837bf83e6b6566e97ab11621f206b01995800d7043aac9102d2c2c86eb7c1dece477afd174fb372ee59b05cf9a18bce8865b86d26d1cd15bf67b0a66034169c66366e8b290a4461e65ddac31e7b40d3c5960d32f41763e52ed042c1dbda90a0b6a8d4a0607bd00683b4fe37ddbae519fe17d16f0570e82d9c394c40e4ab66def70b2bf9ea9ee36c6ea52053c0f6fe26c599650fb47a9a429328e95e918d0db538da13a12820313c6d4037eec6f216db7d168ae1847fe3fb37e3606ca02e247a80b4400fdc163f52e9c8ee1823d19b2aae4036ac1d46434a38b51ecc144cb5c0e2edddb8df49f79e7b086335c426d5642282cc91f4a6f712d4152f1e7c3289ef0685383c51cbfc2dbcd9c920d876078fc290fbde1db07db4ec5c0911bc6670c1d37ce298bb8fe2b6d79662c03b4adb81f224b4394bd70910639c90215930f2a8c845f579f1cda59d97d8108be5bb0ca7faef5bb3677560a4bab900613e54e3a8d8b61189408cb37e762da74c1e82aa0683c558c1bbd5e77a2fa80a572156b8331dea70def3088fb1421685af5fa1a9c45984f03372d4c5491dfa6054e29645edc2dd5c2fb5b1951eb3e148ba0232b6260a01e3b0a923b6b4a081d51ad8650ecd9d95a1da674a0e3421d976a54cdae63273030916fd6aac4a4fe674d9a38a0782da13ac4a6d15a4bfcfda2eee73f7e52fcea8215c5b13c63058ba49cd76ce53c80857a163450cc546a722fe2d0180906d2baaf82e64abc7040c026211896f57e0a17e70b42209d4539fd6f4f714b615c7092feb9c273694b771ac7b374d9ce1ee7ceb753136d96db59de49a59fc2dd5875b3dc6047369ff711e46d41cd88c7eb4d4eeec9a05ceee98d72aa175897280a47cbdfa33fa4b58b4f5a33741205578f069a05e15b769885ce09b645f6c78198528e82fc3d10caa9312c654f841f05b0255eecaa101ba5e78bc5ad4e8e173f14c2be307d15d75ab32e3299af7a4a7743e6ab82ae18b09cc832dd714b77d5f8dfaee1b5648955d522cbe7ee8ce5d940cf535e888bad05f29b8bb34426a81d898bab04026daa9551bf46e084df8ac44e500bcad697072680890aca483da1155349dcf5376aab434ddd935aa27301fca7fde418d4bc00965367e22e2d1a89352451362d10d0ebaae1b97493c459220faaae0ca42844005b303888405466589bf43e484cc43cb4b1d1882c70c2f03c2916063ba9104129793892eb7749286114366ef7f4dc37c39377c64f21999bbe363ef5c524a81602a98c937231378978e0d111b16dd34e6ed0a8331bd8b151be3c6b71897eadddbb4db7bb00e5d442e9cb44ad0c9a11ef60f11ecb7bc8b6af9818f7857ab1c9eae1cb24a5a95b7430b5933f1535f6eb5d848290fbe91780d31e65096dc3119cdfc8b80bca16b3fd32716503d224fe699aa6e17d501b468d85893a2e7cd8a2e8ce69cbfec277855002118f422defe44e630000614a29576f1ad605ab4f6830f90411558fa44425f0b4c51c7746246ed5aa1fda44f27f0f08e63edcc6dc951875cc2bcb96ef298cd333026c8da67096e35d082c33d1ec20f2d22e0bfddea87166c4717fe4ecdc79a05811ad900f6125373b604d233fb2c556a44dc48dcf5ef7f66295a1ba40688559f7cedfb62fe49d5a9001b62dc39dac318a64075c59eb46474abb5e1244c3c6d2bd4f060b29aea4dc48f715038113d32644b3ca97f916018d86553e381336743a73c81987252fb19fcc891e2bd221a19681030e12315120ca65b489850f38676a921999fa8835d7039ecf84c115ef72f65e3e0ed48ebb7b46dbfa5d944fe20db4bb6fa4ae7b51c7e226da28c567ec7ecbcc3a062a97a9d8c8d486fa34931d2370d7be6344d8f248f79a68224f4b12a71c063853bd5843f277bdff9cc21e51b96fc83d3bd15bf6744e2d046cb141aa2329caf8a1bb2737343bc1eef048ef37560cb469b4e30b0a93411d17139e548a6ccaf52f05186bc530ccaad3419c63222770f3fe434c9c3739a84c3284541e2e6e36a533a965e33223a6197a9adc0e06511f65e2bcb4d4f0c50774cb9202ff7024bbfa24cacf2b857158ae2351cbcb9ef8c24b6935dfe0bac6f2f10036b74bc689fb678508ebbcdab1e488b4bb14b6a89d41a7999d9429a537d827b05d7d1e9b91594564eb67c24f473b50c04e383351f164414cbf29955dcf52a4e01665e986b328c2429f9938b36657488bf3dce6b15b0e9c3cd3b0fad0d6bf8dcf8381ece38d7e1465722d29c2f0576ac2078386f73d27ed8f0f995d4c882e46343b0a398109bcfe38cfb16c84e42fadefe586754e51365eed381a0229fbb49f0d9025130896c9598b57ae0a03029b6cf100b314b510bdcd4c2261453806c900a3340300ec1f3a2f7d763b8f1a55308111da2496e3d25d71e498d82cfdfb151901c5b825b782e737553a1499df8a7cb09bffb418dfe095a1d71667dc2836b212c7aa745d7c3415896f3b3ad51a242f5c2a54fbd7c8b7b37ad372e4092c8556b6df09d415b400fcd810ed3fb3f31e103a7dca96abec92fe1949d44a949f6d3f36be0c7c6f80568a21512e8605ca0c3ace1f86bbad4443ff3cb6d1e6ed22be456c1860841f67b3cbbf8f9bda8ccbba18cd2ca562716df424ac8b29b7a1825cc56a04386eec697a197c21ec5c6d85657e8b4baaf9e5068cea12af0f533c1b1b463bda3f6e5a339d3228037afa16fdccd700237f4cdd6f8f2c81e5cdac1bc8aec6d6d5ba210b52d2e97740a2d3261200ed6f847bd479d272833c7b1d9c92cfe1bc9f605f2c84c28d3f360ef4603a2a4388899405101f2dc8900d39d82993e980641283943dbd26729009d3e976c854f601eac6312bd9c64f5f56f81f9504c1079ed60b0b02c29ca11c73d26be266fe55ebd5c79793dd93678e201bb63dd337afba7616e577b62d39474dc6e1ec773c9851abaa171de0d1e4ff3019794be188760532ae9b7fddf35ff056e6b21f7aaa65140d70f939e56b9409c1585288e76ab65bf28dbbdf9f0e53af6bad546c5f5944bf6218641ccc7a78cf3e8544bafa6f400245abeaf375d437a773a9afedbeba9ad240b099c3303aa13af64f2f4b553b5f786d5099fa0913163ff079417edaf3e7b2cbb3acd57d135799b49f1a562773ed363da26ebf3365c1e29e709f8d78e8de466384d8294ce5e61aaf0a54837d6f27a6457add0f7107ceb1f713beee9050140940172d5202490b437277bb72f77200be71d14fc85efc3ce0b704de6a49f084821cccb7acab7cc009a46cfe94044044a734f9e47af109301629151f75f45a89ef5e10cebe087c16003e4a8b6e000920166aac7e12e1080bac0ce4bde02660a7eae5c286146939c396c7be475bd2f184217f74a15271cfc61cb12dc1ea09179f5d930bf26e5c2995edfed524d99d1bf55c0f3bef85769dcc64ff4aa8d941dde469ff0dc720de1f69b24eedcaec6bcfbc39058054a41cd16a515b80ac02d3f5210b34a85789a6f1493b4b02363e58ee7273ec5d9f3eed4fcfa1a317d8755be51612e219cf78ac9c1e08cf2157a2171b3997a01f192c15571b27632f36ad19d313d3d1d624e76836d99b17f22fae1afe66388237df3ddd47e4337e44ff65c3777f741c8c25f951d058cb17f1e41fe5e7fe3b2a104c5f28e798a9eefad39271f28ed8984fed534139ce2b1df552c0839f13332e4ac2d73260a41202a3797e1a08fa0ac36f816f513cbef0465dd8cc1a510b6b2fee8f09f052eb541dff5b1ada72ffe92693bf203b61231ea76291b8cfe075ea7620969a355e0834d21c24f57ae010f8625a25990b344d68b7086772f49103e44b790fc1a88570f27bbc8ac2123cfb3cacb7b6cb5839e48d61d9d0a6304978a6f146dc74f7c45db66d2578ddcbcbab98ea81e4d790c84ca323448ad833d673dc7528876d8b732fe8d256bcb4e172e90b0e497a62e3ffa70f35bae8d44d13e50302150bde4c08e8b89b4babf274a8379dd9f745716da21fb89b46370454596cf5fc35c62d98d92d71db02e5265764294e704798cc6dc6a950e2a8ea40deb1e66e894417ec0578eabfbbc2fae4934ef2c6e3fe8c10e243c929b3df1e39ef0abedc58b5dd8d8de7e5b31aafbb02fb451fef2c6ec1e81e61e00e8d1bb13866e654153db0565eac94f1ba3ead5091659751eead65dfc2869b0763187682c99210f9ac162194f5dda9dcc4ad35546107a8050dd9ca052e7ddc484bb16ae546066fe0eee730446912d1f00860642af20c06580c408d2556692a1a25fe20966c703969a6d5a96be6146526a831ca176927cddb749a289f61814ae99fc4c5f2f39dbef025611f1fc87ed2eec2167b365a40a6743e1bd48ccddfa001eeee2c5df122d4381856233734bc31841cd3ab94754f7e12de415cff45890c4327ff87ad259993929c2434eb490a14b0637d88ddd381a3e045c5b0580f95ceb2009c5d1a0ee80f4ee28d283928abe0f7c57651bca1156892f65aa45bec8eb19930825ce4440ac90455e020ddd4d0bd1e879635f53c6798eb4a46a57255c2224869cefbb0c90f477cc9f98dfde51446ec5237537a6ec99748d492b8f137d10efc0c69ae145fc82c52de0c937e715902a3d6d54dee08120518e7300521045a98f9c8c95fc9cb13d3c2dc4aca641af9619e67eed5ebc800cf31ea9c5f96ae373bba5aef43482c9387476ad1d5f81f1aa8b1c148de365b4b713c55ec5aa57c47b0c0451f12f9732ce9132b3521728441cd2c8d685ed0ed6b5a0659933adb72c56b6ca3f8096b10c161f32ea759067e78304e819f597ce32606bfe173f9fcb835ccc668f6ee34d6f7e0115e2359fc2b56b318a6306333c9d195120473aeb6792ccbc0ea710949c3dae816af00c4c15fd13db7b2e67e37d7f922e10d327e066fc477239ffbd2e2aac9d7f03ab2b78250377f708730d0da6a522f65d6ea445476594b022fab04a5ed85d10deeeaac3092167fe5ce3043a95e299cd782095bc0ddea2fcaea03c5f2b883d615788aaee6ba51ae803e941fabf86d4dd7d8bdd93924ffe0f5a03e113322f8aed2541b6ea37569ac90d546c584270c60088128f497afba3b86c50603ae5f3b5948abfef133d077722c284fe952e95698189c7614f2bbef1e48a84cccfff9e1f2981c91411739771501c84b1870e34860cf36b499ac492c5e00b7836c3e4331bf8fcc8f2ca08c98e5c56e63344a32662cf16e377c48c9a914b16747505de02d28803d7c446096ca43136e734b706034717bb5508df0b8e0c04609959155b37f45fdc97612da5356a28944f62bf38a2a3e2f80d50f98a659c0fb1558ec80cbb5b5dfa5974b1b8ab2612fc0bfb9be8643cff6e49fb7f75447d64a81e22956b95203a9b55a637a3764ce3e6e902f899e51739f57ce93d7f4ecc920c226cc3f52bdb9db709af32e1b92a5d1a8ab9eed3316bd1c7e7d181abaf8bd84bc6f02035d84a5a2790da576738f472d84162ef96861375d030b07dd9a110ea42fbf364527e0166cb73f09b4cfebd01a220715406e488f05493c18f696fc74fd66aedd7b7063dba5e603c6311f046547c82262f6b295c2468a26fbb0a100763652a6700ccf2636246a3766aea4144cbcd800ecde1a6f7b886e4fb6b8a493c53c81491a78e4c86bccc826c897f41fafc2b42f03b075e6514e32629ebebbb22df36ba8687aad7ea1f624104fc8049c36eb12c2b9934043013371b84bafba6da5179f12f463c03b341ab4356d57b3bfd545550b0ef21c7b02f46c2776a817b0aa93c56d4c9c116fc69e1407d3a158dc11e70be4e8c6cede48706b985b1e21ac22028448362aec5288719b9c67a7830442221d1a004055c2a36e3aec025fa2170140a8735a7c80aa8d533ee07631d1d28c1e45e39ddf96d7484e12c160637bc45ca5e7e219d61ce5329114de41c57167131ea2cceab95ebcaae1cec9e7ff29c5828694b585ccfebd3e8d2b827157808b31c8ad1a97a455a4d2fdc5988f27383c24e86e1cdb9033f9bb794f12b692c7a3f699f7ddfb897ed0f3096c4fdfa7086a56c9caf1a398fd9d7e3df4bedab22610099f7910a61f854fe499e750dab3bc7f89ae8f7b23423145e06d7e50878fe54c39143b9b255a52bec58d54c6698ee6c3c30cfaaa99608efbdc910c8cb6456998e28889d5dc5316a22069c279b59c7a7ec594ae484e87604e99029fd10a71f668772a1c50d8c7a46420cc1d04104053949c3cdccc71f50ec90662614398d92b1ed3b196c3b126095f79e8862ee998dc64534e611498e89d1743b9bdb08fc52b0f5e9d3870b2a647d3750583862230644999458e8663641851e8d8951ca7fed0349fe1f3fd1c46d419178bc404761d863e24ccfd79b1436a6ef540fbd030be17e4428850d7d176587ab6e85d503b418d0c2f40f2fc0cf70abc935198b62a345caa902baf5931f4a6b5126c6c86e9942d24ad74cb4554c8236106a5b343088bddcc08a449161df4d4ed3911612bda02e4c50ec0e54d05dd501302ffde7232a4d213fc82ddaaedb274b3a2ed7768b9518eccae78fcc2c4a789ae82b9f5f75c9eaf6675ff04a7dadd34b013eb9ce5d04b2dce4cb2023010019e8b744d8055340bd1d00f44d604454646bc3ab6aabbb17355fa3cded2eaf035b6c601c0c3d273c0423cf009fadf1373854881a554936b3c492ed32bb92e6bf9a6278401b1abcd85f2e48b631886c13e8f67fa1381fe974079d276b3106ba1227d4bffef90711e69413666b3fe02f978c9a6da1075e49838dcdcf12146c16fcbc50de02bd81960d4ef17aa3b6162a03e9c335e8f07496e150441f000a9c33fe0e393cd0609adc099b7eaee1709298ff113540ca6275c22a20e3af1971422a5c17ab6985652ca5572e393adc3d5342d154f94cc7a1dc1c42268b4136a7ea9c2ca6c715e7ca1250fd4df2bf95b6755ef6d8a406107107124796ceaf9deeeb66340f41e5890cde8fc25e3064ee6fa38206d6e3f3c1eff47a614f69be4eae545105723a2458860192e6a7946dbfec55dfec01a7b9759307a6ad47c97a40ac1db9bc80c8013dd7e0fe9001ed63987ca0af632cc9bbf8f08ebe8503463433fb8bcf0e66905c6d709d61e3c947f64b33b091f9bb136e0b5231c2ceae4712bc2f752f1e0c60a3925c46cd5dac6fe903befeb186681d0a20e1d365409ae5d548a3c405424b4b55bef86c294abf9cc9be4a2c2e081523d2cbab08030690629cd0acbfac4e7acf08c6fdcbfb7b1e002a8a554a155239e8f1f758194fd71d5a81e5e3d944c2cdb8214898e763c6fcd515e07ece67b359bffdc32b8418ff471115828f7d7039d070261a6114e5a8b2f6f636cae5ae2735c4539162e065fd4aabd2210d2a5195383f6fad64452157699717c70477798813b38a16066ba7188739a2604cd082544db0b88f00cb72803e99978570a2177e1ce9520885a61445a506da39896221b7b14cc421e179d2de006e801d7adf60048e378bf21cc834498c0fc6fbfdfc896bc896328d5c549840213b89608a411cce216a74d386f5205a6477d24e38dacc93546a5a26447db342e11e1ad820a2ea9fc0be1883e6f1f2f9411439a926d47af03bd32cc47f2b11766654d791a88d94b8028cfc6d109915bedf77aabbf807422a43d81cbf898c8b72a8ba65d149a1e4345b6dfe1f04b4f35d769d081d0243e68e812f0b2331729911905431f2a3488b18a52fab2c7986a55a3a6944a0d2dbf3eb618d28f12d0d7bfa70f8b10059dfd8acf73b7cf3c13bce1474fd306d6709a1d7be4d868f67d76d1faa916fd3f7c3a14ea3cd81c36c0c42b9b14f52f3f1ec04bc97ffe7a0bbcd9acf88bc6bf71931c45bbe76639af8401303c2e4820587ca68c9d91d7e12207e461d4f0ba47bb421b7dee607aa95a9206250689009423fdb69a9e5c606600edb8910febe73b49c04beeaad2150ea4629ebf0dedabe9bd181e7d6250380c0d121bd4d2c9b5e9714a6723ae3c01a48e572d84213fe17abfb9fc1f71bac0ca8fa072c0373b27c2a68671f31af78400b516ed4661b8d658ce6542d92098ecb0b047e00839026c1e88e9812c8b5a0ce776a13ba13e5eb91a1edd2fa329bdc79e6cf3e9683682f97f21b950df8a9db0be364982f53c408c4dde266c5b26454e1caf3560e8177175da3c70f69912eac5a43e86f1dc005eb7c5352451ac4cc26199dd984eaf2c2b4d4ae3b72ca386a4117f7472da9f20a1e9e8bc944b79c08e6d29161eabb246cdbee57b69bb6fa8164be2ce94c8b1ddda8a948979fbabb52de4e793fd925ef44bb0d10d1a326a688a4705ced9e6dd7de4bc110b9d65f1811d52d9f10a7610b1d62f419b21f84a2b95f5501d9d72dde4a3abd59d85397412416d07255c8cc2f3b67da605149ceb3779ce8eee9bac81f64cc8bf3a5c8a3e68fad50c9cbae37fe31bf38462c81b31b55e7fe5651ca8eedc6d4539c3647f227344850ee2f310467eb3ef9b192d15fcb27f6971af7f22f3f52684e9cceb63c48c54b019b85d13176e652f99b9af8bedacd90e35011cb789031b32f00ae4d46644470f57bc306561e91b18691d2e851023c2c962ce0d06c55bce27129c642675124195831497013343864ce4bc0a63c7b52ebc8ca5fd7b66b11d128682ea3c17688c9af72d8a8450937d790671420d8066cc3045c1c48373af49d2f16902859c7b418dbeba0620dba39ce8f5c07b2e1cdf48b6725085f0f7ce144cbd30a7d458caf40ed46239f7914645cc09caad42e94c9c15a8b91deac912f61111c3d145da2cfeb57ef13c1a71656c9d1276afec304496a0ece7804e79954e187174c2ffc969ea3102259c5ca8e034cff29d82363b9b2f4a45f6f25633d54c6e51b730bc9da17bd0b48589ada497a9f92d9e8ab4788697e4fba7d7a9b189a5218b624369f9206d32440a982c3018617b7b63e48b28e2e0287f063ff46f206f2e609ef5d62dd6e3c22181c99d79be0c45d1e7c2d0c7c0ee7ca66282dbe93c41f2bd0749d5512179d548cf04d83a660a144a6edf684587714d1952f69dd4968af93baaee277e7e60ed1e9ea95af902940102b9028f3962269096bad0bc315e0708e06992a009575b2b3560d7529f4cbaa3d8c4a9e103f5f830aa4d1d7a940cf760db4e96393a8219769611d1213245c7055b4d144c815aa78c02efdae421e2e8e092cb0a03c28e15832ce4431eff6f71284610af2ed90533dd680b7aee8bc37bafc65a7d11ecff37a106742e986efcb1c9251a34651b97f2ddb56ba75bcc9c9610ad38cdb10ed9e3e230268324d2b1036931d012f7bd9c3cfc1d591e6830d8ffc6cb4a7db77ce7f72d2e8961f9ec2d0a39c7d64a1c7f973b77207627cf6a1edd5f5868c721a6904fdd6deb9ce6cae0091c4e5d1fe4c1a626393a1d0410d12729b77920b630c6acc99d75d72a8e43bb7ec5db656d63d90481dbdc67962d771c5975dd79e3448a63c3d1c2ae4ff4766495e0733a8d2a325f231897fd989847c6bf493c38586d4377c2a4b5af9debc518270b26389a3a153421f5cacda74edcc67af92029a71c8fa7b81ff4402474861a33b5cf58ffba7c1b0a992a998d89074a5aadc2af92161f3d4263029339fa8adc1f45847aa2a278e7e130b0efb257b44198d5c696e72e53ffada6824c61e434bc22cc1b83a3233e1c778b238faa13e2aefd613d0fc7d2888356b25eef9c414cce9b4f39606259c58f514e46e42a4b67918d53b1dd9d1cfd858aca3b5364176f135d78bebbdc7237e4653bf2664936243283f15bf3c0495e993f966a052329cb6cffb49494dac259c6eab6ae3cdcdbad6a26a8c5fa10230683367065ee2f21c5102afc088b34e61798b1426516d5ef431b6812c2215852d26abf6b46bdaaba1cc2ab21709c6c57edc584e2f707ce68b7cb784d9c4e946e5608329dd87ef0f9222503f794d1b0aee310ce725877b05f455a33288ae651c93ae7f360a4b85914198d44d9d47ab31c71a6ccf4cd7b57288af0fb2f55fa29f91eb50202b91eb080ac4321be6fb73b0847b58aabd405e23f66f56976f165bbfb25ef8836b52b16ef13370c5bc9baf818a0e48f2a544e74d708fcf376260657f4d82a1fe9a0ca6d90aca2ca4f18dad126cd159ab981540ad0b2b561cead168257b3ff8573ede2cea27259063e594ddfe8ad574591e59f4942af8ccf41ee31ad389776569328a45eb3e1b8d394a6646cf6be11a49c71516f12c44bdbfa833d38a6d561c3a5ed980dfac3ea3fa28085ccf48dcdb8c7e6934947c5052be0ad9204e56478f52174e556879175f42b92a0c0ccecfc5224eb6baac2711e3efcedd655c73d3ea76328ff7559e627faffafba61ee1619408f37aaefb257f17b95330445bf0579c648438b497d731ab52eb70ab6db4fc05c62c31a0db4a77992409f475ad96bf5bc75dc88cfd76f95b7d94985a9ea328141d99da4c72d890dacd462bcc5e8e45fd40429109e08a54d1de09ac57544c52e65ff4c78baeb76f578b381147a05bb7d9e9c8f07176b45e0ef27ef23be526487d9f7e95cfd3266a15037a1e0dce710dde35ebc337ca1e4ec3978c8800ae02b7033526df0a6d039922906ce6c32336f1f088aca6b75e7bceaf12bb3f18988149a5dfb877f7ffaa3d5003183b60cbda3036ef1b9100ea8d118f8e4ecafee8fb4005b5573e9e3b7bf62d332af6cecaf22c272abc96c69d5d795630a56cd45e71bac4a349f661fde3c270d3fcb5e82037964a431b40816963e01197ef725c44740b78c1196472983186f545216babae51d481076ff23ccaee0ace3386248d4eb8c244c236284ae174a04ebaa15194068383d7ebe54471e9a77b09c754c2727f028b8e88cafb8df913e9ec5a44719521dc6d272e3631b56d7afa0e9155a87511446728729886a4649dadb90c14f0afb4d1934e18af73ab42119434fbf6bbb8e453098ad7d85ac3c83f53fc64e16624796c0fffaf032dbe600c6602d323fac784efae1467d5b5b3470325e9a357577602f60324e32407cba04a9044a5b8b40d8e84d537c31f2320ce17c319223d9b500c7bc3f158893c0164ccc884d6f826233c84c9fa84b15cb5d04cd8d7ffb437eaaf965fe218c2098fe860de75240692ec24f236f5147bf4951f39b7eee9baa205b8900179e5e9c2a6ff446629b77f7f4a87147a0cf3fc59e7363f569a16fd1e4d111893b5f5965baa8f0c5ac58f13b0ab45546eee3dacc28fb48915d757b78722241b1b97a9d29fb66cdc5ef8528cf14fdea2e7a48ced2b15625c7f466d31f4bd63d7ae245fc5b6235886ddb256464eace2a9371b515b112378fe0b5fa10589b87bdfbbfc4c258791dfd686cb0a185cbda5f62d72c798cb0f1fdcf82c943f2c326ffae4c78c259c9354b8bfe4fdc30a37051c92c8ed24c8564d1261b53b3e8f9f2171d14eb95d39abcfc95b8bd6cfd57931a25ea4ae18fbb26789f0cde6148da5f97326aceb631fcd196184e3524f5de12555b7571702b7c8b7122b218e499b89908fb9b8adcb8fb0cdb666e164857a44a55a6e2682f74893e66ff96ef8fea349278b5d09c5b807d2fd8b0ceb3c54efd4214081c8069155eb2a09979402786d0f1b681bb3c75428608fd03c90538c17e76678dacecdc383a8107ae0edd9fdd421706190351dd9e834b2d42938022dce27b3c1d61f6aa4175362e4afdb085b36ed35b7600b275704f83ee9ec4b3f169f7236d4f49b9244bc44562ae0e72ecd2594ff57cc537c09161e2ed1d2ec1e5b106e75cfa78f66a270b02405a81d5c3030b4d476f0d2636da6f4b26447df272a1f52be9514d9ba0124722cedfce7c20f77cc70f1740710be75739f6e60241bba98262c1674aa59d97b97795447736970076ec37cd7e72cb6256fa1e758f80c30263680ef5eb9d96c6df42baf040f421d93704c0c735183523e31b71c00b727b799c6a5e93c4e55c9790da7d400e2ff707b21e76d460f40d2a28992723cd51acec063f294b203c47eea6a075fa2dc736471592259282237dca870641900fffd9beaa07b9c92de99a3f5d73c6519abdba040e8e92a5f1b996466740fabc892112416ab7b92066021d2e18efa802a351642996a4db9ab464e4f9aec6261e309ecf3281b197ff0378372db6eb06067b1af06cdc3616b25fbbc85a0f3df0cd1b215c18236de125529f133c65f762ac6313e655aa5058ca56b3a4ff2558a407b598e4ae5eaf9ec30fdf34192cbd263b829d923756f3487acbd4cc450216490ed6d9e6c5c3f704319c3b67b3d91b1ef8def03bbc0b7741b1c13ed6934658606445f026a2a1938a9e103f91cb8ba590c939c5eccda79d14692c060f0bf1849be94b61dd0e54985d03b9fd94cedb144b03c4a402bdde9d375c2be13a94c8227bba8e60604d0a16cc3b6e8e4533efd358ab04d554f3ef9f2b2cff8a0cf312b1c43f1529991ac2c6bb84ec1ded43b38601408353612dbda10930dcf91b51e95397143d22f416158cf9d4e649e6af4cb1b97126dc21539a9930df4aedbe240f960900d8223cda01b2f059f24e35f962695276f1a0eebec5c9db46c18bbad241f8af976ed52bd1004250572a05a8d4a77364e312295c31d9a26e8285d06ef03413d683c8b02d647d4019acf0b6d01b219058800f31992c1429f1ae88c5a1c893c08c87a4f6a409cb4eed54038a1b990a3a63362522b731c06ec8172e2dd79963cb4c85cd73804bec51866795fad68254a873fba90cf3547079dd604bae09efa761445949f70711b5917473f8453135a35c30bdfa0a4f73f510e97f18bd8187205e90356b90290a6a5462ae63d48222278d42c381c855de2b7c863ea537ffa177e4fe86cce82958a43e2b57d9b160bd861f1a047a6a433d8fdd7c3977f32f58f2f8cdf866cb7072dad58823438a8a9f17d10903b4bc201b885c4495f3ee0f2a44c50f662174e824cab6afe5c498f2f900978c1ac74906f5be8ee125181dde7469692a22ea85b1fc721dbf70da0707c015566da7ead00f4b3662138197eda4a1bd85987154475ada15f1738c42e76664942c35c334f898ba52260e05252016e68c5838528b7e1af3fd0f9a1b64078b89c67e73eafb0aa5ea2a7c13e1adc3198bd9d0d772ddbdac66f94638af84c550bcf6aba37b1453fab68fc6dca9343340fb00c7c054374a67734625f6be94693d393fde4adbaa8d629c53ec594c9b75b8324657f95951ddb6e5bca104da371f54ed4ed4585d08c076e44d83ab5144041e966c67362788952fd011fe34b61f88c8e421fcc418a2be1f7d7d12c46d471f7616cc8031a7007de423fd01962ea9f77e2909ee3d5a77dbae98d196c4347c2c0251fd316ccc9bd6dff9d91221dde24df62ed4a720e95d4eeba04a10927eea0cffc557465da90af06c0f82cd8d477a3c98308cd0fa78fefd0fc681f974d45f96ccf66ab4901ffb5cbf47fe338d8518e5b697b2ae50b9f88bb77a7ad3a12726d836044682101cff2abdaac6869470a0ce0a36a8ca4a98c6f1fb52164c1b9f4ac97ad67fd759d00859c43428154edd5d19997160915069e3ee356157eb21bc898fb43a2c220d900eb3cb855c450fd6c726fc616591b6585d5e6b713535a35e93379471064c90d733a552b548cab493d2081253910816ec83cdab35e816736805c5335054e7165982b1cb8d40e112a5d875d9fa432f27e6019a67fd1beb4afec07e4151f75ec4a66a5344fc025ba53dec375cc544bbc92f593173d089eae8e2dfd1806e481e876ad9184e3aa804c3557b4ed7e0f7ce762a4d2ab7e34d4790b46fe9996cd95d9b52d048e356b9cf53e36c927a2a5fbb4a7acba43b2a5648128e3954d589fb23c3349b6f72d8f0c06b306be55481eb3cbf2400a2c50ef4860f115cff926630271526396b0d94820149d9c48f6009e6a1e1213fe28e3919d4e4385507070d34dd10fb0958f54cf1706720b54d70ecbca989c80fe70b314eafcf481d51cf3c93efa2f798d3a53edb3f43285d2c7d30a3b08f83ef1aa4f88263111d3240388d19ea0e2f68ef7097d228703d33f16841cbfe6071a4c1a622d22be0dd70cd8e366a04631cebfa0753875c6557040e082cb3e0aa802c3b321934a21c0c6dd326647f7bf209967385f508a90f744a81da570c21d1303fd5a5142ecb46f34067aae660c4ad0f235e7bd862a796d50494a76e386fd59d97d2effec009ae3cd700dccc982dc6ad3d4125b28fa507b6232bbb32ceffb37bb1daaa0f8e6fa38e2f9bcdf41b197de8ed3029cdd2aa85f4471c83a973e29a085d8d9e0ef08ff792d31f9c4118adbbe1b0ed77c5432e3ca38a7fefabbfe1d7ea12b83790246350c70aad344bc522a64d36ec8126dd91b6d3e8cd719587b69c592231c87ba9480cd04545c5621fb49939a042038577f1c3eec39ac3665a040dccd974d290100117a0b3ad9496ba61fc6f5d7cc95f9180cacf9b7e70cdaa7b587d088c795c5969fffd0db71a0e6f46ff01dbdc20006b3ddd06039a02a6736b948f954d0167d888194950db3fb60f184631e2c7987d7d11a50de5dd9da9872f59a524e3106207bc203a7cb5f34a8fea75d06f0a9c40bd72f7fe2cefe1e1bebe9aa5027515b7cfa86ec88b8afb7707a5b31903732af3a36a295894a868a0e88f323a63cc2ca47ef6e707ec0ab675d6c859a55a1a4bb119bda4996a4c21a1b8dd6676ada57cdd31a6d466c13eab7d4aba584b2bb47c9dba2f250fd26dfb1c0bfd5193b41ab1a117915e037863693df64c892412857ea6f667883b4186229d22ed367984323262d67676c45aef670dc134056833a334788d84297ef687d404cc54a5fa332cd67bd645fae8dad21a5a6f2f856832ff29791a48921779feaf96603501efa861d4f0456d4b51872edb075ff62cba6fd1fbe5aefc3f89e1faf03ecab0c0b4e5f2a10fac030ba8f54482eaa43756a04d7b10a5ab5dbd7c120d76b4ca49c4db7e2bd94b2039edc4df689c6a550832aa89050ef592d96aac1e7a6e0f7bc6948ebd031ace67cf30b146c74f9f9d3125e6a6dca1a32cbd5dc9e1eed4e70ce4b45cd91b079352eaa01d3fd497d1a4b026f09ec64a10ba9fe9b32c492fe4bfb6e96344a03ebaab29628a1279bbc594b2595f37c5edff63a9a4497d3af604c96dac23fc94ea0a26c32c38eecfd5abb364207425d3280dbba35055dbd1b7b3530526b8254e3a863113e7dc2cd760dc1fffee5ddd412464c29ba60680efe94a74518445a30c1637ed4ac6f3d2b14f5dfbaf1b6f46f6fab1a170d736f72f12b52791cde20263cba647aec585d8c0f5f126895a568c86d62596bfd2f90932e8040808d32e4608ff76a1e3ecf2ac9f1a09a99d7c942ef8bcdbe71a044206b3cae0173ac3bef436bcea8e92559af83fcf382af4dab83ede36b7a03ebda8271e4f2d1abf918169195bb9f793ad9d3a42600993f0c799b215ce547b0d72ce4e3d49ecd9510b44197587ddeda7120d30b8173d950b40f667bd3dbbe4f65d9026624a6d141275ba42a85d1cde397a47206652516ee73fab8131c8001fa7d0d8e218613af082562f351271adc2584591e96d7e2d90cf9c78983c60eb173af247751a29f979b431ec7e3daa7a73e7df6d5039410632a894c9e062905ed0b922e504ee07b7c017a913808ba6978c866054a5ed784cf9c6ed7f814c5786dfc329dfb640fe04210c2840e4a9e85a9aff8ded8931f9fa0af1873a994d81a5a0e1a3908c44442dcacff602154099f9f657a94a8a6ac14064c0bf0c0f12682836b97f91a791195f8d056a17996d15529e942b113cbeffe95b9eb2d5e18884e9a81fc0e53d50e0b8db88f6fed53280b232c5213e8b3c6406f5c643848fd07f7bf196fbf7543edaed7f92cd4e38ce7fde7261126a27b880a205d85e16332ca86dd2dd33b08dc39d90cca7abe0954ff23a06504385d281af65ec935c7d5898783b6c47bed8ac2c01e235b23ac3b08ea59ee0ce9e526317bb90d6cff16d0d4fdf0c5c48cf4ac103839ff70b7931cc41ee05dc872c334608302b8fa9dd7b5e0751d030fd6e3228185a0f86648e4a6e343eb3605633969fdb7d0aae4ad2415da2467a5d5fdb3ebe278ff296585f30f05d88c070d4ea554e3cc911193e7577872a600487530205f3c3a55788d56ebf7cbaac266fa4f9d2136df6b39aef129468c8819cf5e1f9bbe1751cd49fc6568ff3463a56e896e66a881395c9ef9339832d22c7700b03e31ecf5b8f38941215519e54eae10bbff148febbc88d674c9ffee2fd489a16f7bc81117c48bdbda905776facc3883d5567cb807ea934f3ca83d377c6c97aa96ecb20574ca5125906931ee79b260416e2b8660b4d5983127f396e9b93ee72c40494f8e39fc60d2413f4dc44c22e3e17579c9ba1491fea9bcd37afc55fa154beccb2471c0a7d6af8a0a886584443c651137fc2a2c604691442e11c7f57b02e8e070764bf9b566e213510960983d2b8d37c68a85ee49afe85c50bd99fe748039ab00046cf1d8ed6701b29b7dcfaef56fd771f1b967f40eaf5bf2794bd63ed5356862747d4598f030450fed0120f239b5910906609fc284abce2d97ca8082e73d217136db3aec31d9edc49e831cbeead5981f5517c296f71ee8a3879fd208298fef06b6a509b4947f00bcb7677f6c900c40c6daa3ce91e86e985341997bcebf40d829a7dc6b52447b9bf9fb91d1f8a5c66c4cf7c4942dffc4254df23f052dd6a1862699f5a175149ebc03b7420df07a8a8e1312f2b7650b1c4f3eb97842767d29f3e7f38aab661e72fc0b5a402482d534d71421b8794aae1d6da76dfd1a7e6ed404a0288a1e38cc5fb7eb9815102e82e2d030358942129b5b148d1964c36f9d417a7ee79b76473943a999c120c72f90dfa8ebf15beeddd160ab5d666b59465fbaeffd5424a1f682c6e8bf692c84d721e4dcf01e2bf8a838101f51ed207b09f86eb361d59de5fb0b0fbefc9c898b5a2785296510227b899af8afa8e3d94a35212fc6591676e26726e26c3551467c09b2cd58a981420a2b308fb421eaef19b23cdcd50c1bdfccb98533c92485b09b8b7bd61647e729d0f080bb93790b33cb91e2c204435f6e404db1047caa4e027e7de9a11661f72b7affd254b9d520795f56e3c144b98d61cbea70f1a85ff05ad0329538ae13a55bc2ad48d600ffdc3f06462fb828496fbcf9d5a6412b68b11ace0d154ff07a1582aed21e2e0299202aef3882016e66647838e0641ce9b01e093ed8735fe7611a252918f6f5a0b344fdee9bf4b442ee1574fe7677a031c0f1de63d5457f594d5601832ad3437ab420742310d9277b070930c5374a48c28197dc46e1337dc3e4ecb7d1887ceb2418f0ee51269cd8b2af5dd74cab36fbd07c51ce027d892a74e938aa7936c6b754c3907db04f84064082fc86743f6d45fb7513e3cc21624f4ca50b797ae3b05b011bdc7b191a077370717c6918af3e7b0e95904d268fff270c814568476612a4f1c57e1262e71c82d3e54ccc40bfb4bc10c4333cfba42829d01a5205242844a1a1104f85654b64c15052837a0f5e59e20d5970dc2ea45759a08f60b02c82eca7937e4e3b3fc0097869e496ad85f662595c7f323267a2e069f5336640f2327024b075159f3279535a5c14b5b50d6d6feb27117b4d3f87b89caba2a59ded2547a21f141ec4068b447a7d29195037f1ab4c01032600fcaf7d41443b820533388358e090560f0f00c9fa3e462118506cef7c59043fab93ced288255224d8f555c0d0a5fbc64c1cf95688845759849302d1787960c430e32b039815d816a9a12ec9dbcf3e1caaac19438e8e4656aea0d641be89ece2e92d9dda25fd5a51d21a261b03f67c729200dc1f823de0df47a21c9d4adc8a85af1534ba21e3ed9465a32f4ac8fb714be9ece60b9ea7a016e2abf1a1bdfbe2a4ac80aa519baf84d9ac4a8e62c5b6995caa74abae49f1a601aca1e81ef2e9f0da9c421c62e04a88b25ec125e41d102e9f3debccfa49609213aba8e5f5d88eb7f4ddeb02fa1b5703c5afc0551c0a2062e63c3005cc9bb705f71c23a4d394a2a15a45f3d6dbf7c43e764d83e79a9c6f5a4e341cef8ddaae61cfade5aac72fdee32b2d231c41339f340f66e379ef5fad6723e1a759c3bbd4d48baf41fc38cd0964de9936a382b42d187ddfe0907da5989562f27f06fb97546ffdc21f70769b7404bff6bd6a1aa870265efa617d0ce5904d19e9fd21154118f4b6a9aaf0a7ffbe478834411866861b88ea4fad5bae7dbae2c5589334440ce4149821f9f63f69019e6ba06aee221755ae397ddf3c3f82c60605f5b06138686d3356f79811613a99c9fa72a94883b3bd7c8ddadbfca9e3329b0ead4032d22af17d6cfa45c71238cf11bde066666f25dee01e989c8990d2e328978db48031b5471f22fad8aa339306c6f7675a6cdf9f3ab9fd47bdcefc9e8697277bded1a979db4cb574acb6b69f633d6165d6a366d6db716cc4f3e8e9a335eb7961a1650d9e74c42821dd77f9211d746fc9fcb784601996bdcce2cdfc89e5d78e0c652052abdabee5bc005f4ed9b7638720445d43baaa229e586f8d8020aadf1a0061ba45e1e5cad6c0a8d8c36ca623de1aee13b11ee9d342ac23d37cf5e2a6440552d56e2542fdf94890fb0954a5e98823ff48204be2eb852c47d58b456c0ec480e227f41e81219e58b9166b1da29e450ef239894587e715fde61a1cf08ff8f9d4f6f2da404bd0598e69007a867202fdad7ca032ece444839714912239ed962afc8876613e83299c18ba0e87c30f7e72885239a0517f12b27049b50b8ff5186c497ad76d1339c557acad188751cf9a6427d1aa9bb983030f8bdb3147769b4b8a5396087422dc16fcb39c7a78e70642517fe7c4595bd1502637cc34f0eddc27da008b4733f87a9eebc254c0ea1e907981fb630b43edac33ead53b8767ced8cbe7dc562ba63b3437081bd336089311e8f4773a3f6b12dc1925087f38cea05b0944acc9ca5ee7e612af028c4b17561450021617e37ff95f8d9f806bc45b2a2f8d04348236526472d3febcc32d0168ce8b19e1203123fddb2665f2864a23db513729881bff192a5b27cc4711e37f88864d28e2071467b02b3f7aaf2d7f4b1a640f699f0b1a5bd487425771f53dd1f124bad5475699d62e39b4edfc75c96d454ab4eea682feb76c7c2ca1acac7e1fbed3aea725b774aa09ab6823b5b99cf055cf3cf0e92ed2ae0918fbfb22b51efde4df9c7a98de8e6336779a81136dc34864e68b8b6c9a3182efb293a0ddbc7b176b76f545026dc7bf553b3a88227604f24c0b1901f0433a008912ba43ae42f300faff0785b5ed15f76fcab417898e63268cad8ab3bd84ab0162a90e245d4945126de7b7b1b2ae121175bb2fe9b5dede6a9749b07af4304de846e3cf43517e25abcb0e406ef9be50aa6ef6b9a682929736c54e11ca8372fb827c3b395920d4f7df80ffe017f7c852acfd148ae1133401a818967eef426329fd9c5126ed3c197207b05fc14759905265814d666f5cfa83ec9bf7506fbcbe8af7b28e04a90df95cb9503797f6a6de6129bed7cd06488b5da6da60cf514479f339a6bb1e25ba235fa19a254d7e2eef3820889105a2b900971af23adec7b463e75d5744c1e357031a2643e54be20b4750e47da64cb15af0be5ece620dcb6a298d1b9b564dcb26b2e6154111a7807c7c34a9c1ea00b69f9e2aa229577f34f39a7244a3ebcd130119c498c2dfefe918c7821212f0e6f0d9c44b8b288d5126ca094b12a9c2142e3b6b95bea17288ea01f74880a8de7d3bbf3b0e2dfd12c5cdcfc58c1381b871ae99c4cb4301791759383c2bdb7409df08f7bccebb25cd347883fb493fcff5bfaac2128c8ca31ad5447e8e82d983efe764c3729ae6b72a6b269223c4421d2cb85e66465ad34c4a62bb6990f63326c03abe091e8edd765981f8751e930b35e97073ba9195b2b2ae5c543d13af8a95b826b2f07ce94f6deca880a8f4a362693ab16e030cf65649c16b7dff29f91bb476b387c05fca8822f2255c060855802addc0e0bd6ad51c221a144726130ef66319e0412db9d971e58540e1bce331cafe7ff1a539fcbb895641b7acfc5e17a9172ecefe6fc4dc8a99a81412c564b583dbc3133ac16509dcaf44ee2a622f2b004b127f342c7d635c349612403f39577ad35b69b97df7b8d15f3dda3f3538f7e64c3f49f15801194222d92003918d4fc4c26597cf1ecf3d6730ae0a1ffa4146851ddf4b08ff7af74bf89cd0994fcb4f08e3258fef70f631ce9745870e6971e7575475bad21963ea61ae094159ce73b8dd828f7462f997a8c47a6094b5358e0a1859af3f3cfcf95ec70aa510d3c4699148253bd14e8f2b7915a55734f38f99465587fea56bbd5022b896b32f94aeb53839147f6550f9e5c98d78f0066db2e06fe8f98c2db2523f8559168a4a4ed594b0b34257c498ff2a7befe8b4de128ade478f951fae60183f0e9806bceaa7b41bca0f4e23188e93250319aa8f112f4ca7ec4bd7ca652c662a4a9a51c35209b7ede0ee2e5db935a0842e58cd2cb6427ab45ff5f7da123e11d204c0e172bfc86c1bb26a1b74fd154515c37dbeb878446c41504fcccb9491c7952872ea05149a1f6b6411bf44841aa9ceabd94d097a0a72f4ae786450ca11e6588c533c67f342d6989f673b170df94332d21eb26e24e16fc8fbd9609a43bdde9dafa5fa3704a93c3ca6c0806cb09dfc95f4160e9ae6e961f3d3fa9fcd3bc878a973f8cd04f94ea0a7aafcb357bee1909e408d262886fd9122a291a92dc6661a7c72dfa7a47f82b5d9f5246bb06c5a4c333646fd1966127f3e02e9f7a4fc304d1cc2e45325c9f0c0110244a0f4a3e5ebb5c5e8e35f554f62771de8d9372ba561d5058167b88043eec5c6cd688073563ae3612012a11458f95c23264373ace58e8aafdff608fee48dc8997688bfbbaf070ec1949f19087679de1cbf19dda12efe4568f6f4a37ba112e99b4d6db133419236b967369a79973725f965e0c5371ec4e6d75fd5035b1bc270b5a3064f7b88c0887b14aa44698d43c0791e49d333601c87c25fd580d76174e0a4441014c14093983b012217508363a815d818f8483bb894be3572ec6adb1934c1e184bcc4789a57b40aa5567b0b743e2a4fb1ed1bebf9008ac34ff843ed2b018ca24c8b61c7eb8f1a58ab8f5f902910103b9028c396f4810331502a24e5b2a9df106a790f991a3c8e2938d22db5750d7d3f17cb302a27dbc4110535ec985e8f745560ae8b72653f2418cac6b12399ad839d1c4eff2d1d8c4fd7b953f396c5727a938fa3cd208564182e6e8a15eefa160f09c5c25d9823fb28d5605055aacf1fa97f1e9d4c9ac942c93fcc2a09e6c97fe1a390d4985346c577217a066b14a0c35f44e5707f6a91bb6d39ce328c31b89e476109252dca84581176c1dd6e0827a9b1541ccabfa3f9bdc427d6f92956de21ae646dfea149b4453f0521bbdd1aba6da5e8d38d6ed783f89d4c23a5614094b453fb1b584463900f69facab488426dc38ab9c6ea414aaa1bee5d4f30f15be708d212cfab3cb8ad235dba64de1dac718266a27447c7468e128b0ef223a8ee68903f7b31dffb45730c4a0ddfffe8baaf9d3098a01c04e9b56566584a6a36eaf974d264171595cab4950ea6050b58d146f7332cee41bbad3b119aa1b04a6461caf87479140eda999a63ed8a622b8f62d5461c9aad7b1bfae31fefe7e6d05c5610b5533ce9633ac0df5dea4ad8c3355ad2caa5116dda45bc914b93d5a4f6e4f55e3c68d9b35bbd0e3e90707c3c9a66a8ece1d64d6a63048d67bd717c6539d4edf7fd8a642bf1e095fcddd4018d9ef71a966cdca2f4aa7a08dfbb533e4a3aa392ed2a8da8c419c6ba82f0234f9348e8d3222d0f66165262b814b252aeeef54c425fc36ee6c6452145f1100111c22139fe96303587b213be41e09e24c4e4c3514c87a2b8941028c4874ad3dbb6e9eb50ded7523a8420fbb2e8d99682192387aa36b865b35c9d562ac8ee2958f1dcc4b95ea1e69d7d224ea5e95d397d4b8d27ab788f0cbad6a34390529d4353aeb21a07c178e04aa1043cbc685acf460fd794daa825b6e2c432b997b642d7f273fbc9027128701f91eb50203b91eb023c775a40b7bceb30dec9a8a7c03ffc1988a29cea5e6df2a16df0e41f6e3e4ebd13486f2c8968ac85d210f688149d81cb568e8900f6e2d326331075ee8b3a0f2384f9eb65c38d586ec733596f5dffed38b247961880a307757ab5cb8b0d6eee8c0bb86c3de935b3043afd757ac0c25fd4b76cb1c41f3b94e3f6e1169aea483545663a9c116e09e107ac6bc9c8964cb1cf1a3f07d84b8866c181c739d8dd20f9f6a3774f7180139ab4d1088bb9c290f1c81dc8e544e63d87613f21ec352623e384ffea5009450d4f7b2b036584ee9333e779e765e8ccc7f2102aed01e9fbfaeb9241353768fff8a62e68c47196aa8e78b2b8fd916e4a40cc06defc0f94007a09a84a37e88d91a4064ed4d284b539006e45e5678626c23c0200cf70cf13b60cab57ee0c25a111ed36ea8cc773bb83e567d967dad521217cdc6f807101e09b97200b0e33c5de974a179af43e7d3b86b39f1e8541fe68fc8d9be503f5ab7e9acfaa35551c5085194b918d46a978c2a9ed17f841d6ffb7cfd96ad7eae32a40ffb8061ab810cac3d2edcfd8c8bc765480e0e7240ff2771ed2bfe572b754d081c41956c3091a6fdd2238d149cd07692b92f09c12d49bdd9c9e59598ba42c025ade935e14d26617372e0b871dfe6b4b6e3f9109c8c9f8d74d5779893363ec83b9f9d0b8e180acac7c80e36fc0ceefc61275fe753aa29b79ee5e5cfa20462556bd29f5ca81f323d8c62bd9d592a4bbd6ec3755fcfbad29fefbb441535c1c1da70a2a10ffdbeb71f2aa46d963b35e489fa4d7943bfd36063d9faf5ded76627bcaf90bc7c09933c1b18e5cfcdba83ae77f367112d233803bb2b7467fc17135e068c403869c31af7c1798ccc2d3db0f694f5881fb5e7a83068bba4fadc291458456d1511e93c96c4e56a007a17d427ecd3df66c4f1cbc0ad1a86299806d277d1513a07449bb10f568dae796d1ac8dc08b5d197cc82ce47c87932d940e4e5f3bd3a3fd93aca2c97fd640624dcbe30e3111b5bc346c125e5d38e9ecaf6e1c509f92dc94f0ddf508aa7f955204376acf746c9fd60e27d0271654da55d83de921b71d0cd778d0b59e4ae4de3b7092cb172353417cd18b72289899032d12de98b999942d4d39a62c0d58dce6e2fbdffe743ea17dd34acc728c0fc71fbfe87c91219e34a7650405ed79686d38ca6fbf503f9558a3d3bf7917fb84d26c075c1caff12fe60640771527a67036070201143ba4815323aac5b9f8933cf7baaaa139b5a5ecc14763fe8b1bad5b9b3c0764bf46ce3827075382d392b4684f1eb4b7f1b5072a2382a650798fcdb285d4c21eb0d021b76242a5f3c7c0439f10480cad8dfaefbc7bd228725d06875e20937094f28b8b5fcaa15a6de5e4dec232e73f3a6acd1cc02d8ab00060e287a3bff3be04a1c3e9ba86db0d1f35387629dd222dc9c5bd0df9555b9820eae0ba0e8d79999feaa4dec3a6ea551e927f5ad74a1d7d864e39e43a9513bf6e52d5e7e0b5ddf7f26215c048ecd8e82ac2088c6401230feb91c742402076b2d6b502414803bb26bf6b97d025772828b55671b151593bd6f17e9697ae58dc20d89e900c810797fb8ee6ce3d590812d8004d1039106016c4cb314a6dcec2711bf9f582582ef43d3dc56614606e1f81168c5b70a91e3983258526618190d963653f41d54f93d3e7bcd6f02750d897c005adbaa3afdb13f7672c427e6b5a8b5aa54ff8191c88d413ff45133a3a65f07a52ca2e7bd947d83ce1ded1e3cf33690e7c89dca9cfa0179cd78d4e14a6f3af26b8f525d55bcea54de23b5d38377c7a19f79dbfc88d9e82c25e03e14272d7333a2cda88bf6089af37ca454d11451c9e34d522fca09cb9834ee3caa85e82238be4da18b006bd395be14688d4c2cf8356d2c0d568d82ef629b11ca894cb1956768c18391c477049968d6b9b936b2a85b6ea0def3add683110e24b2dd89b7b776fe68837b8798cbb35ec82952ac34fa6582426863a8061a68911229b16caa64eb919780e234949b2c9ad1485208fcb832a1a8415a6a94efe1df97f9771af329d1205f71845fa035aaba7d9ae36b500ddbebdddad3c88bdf55cf0c56a7ad599e36dabdda9c7e4817b76c8f2632636710bc531216e4272e42ecfb6e732fd1f92ca4c3b3d8f99b3125a1053dc8d1b86735805b9cf823027a74afd92b36c044325e970564b13dff519afc90ac1e789171b82e5d1ce325c59731fe8dca20703c0f41e2765c1de2af84871623cf8c6e0ce8911cc667f5bfdc3eb3683813ef1f430b5c94260b6aa686a1e280992001cde873ccdbcf7d42280f169eff1732f991b925f0d2dace772f8c2853039bae697e362bdc461518b1fc603defbc021cb5158100bf7d084b628309d2eaf76a47c39a9d0b7e9dec6e07781a8f3dc1a4d82dc9ff3d7e7af7d9aa320757ba723cae5127ac1e313fd239cc4d36a14c09aa8377c26b8f1985c1e11056f849846c2508f4db66dd225eba9cf5efbe4fcb411a39107e37cbfe3204ead66fc2f9797f4ad6f5a76bf54c4601845303b6eca629428dda014b295310a9c360a5974379df5f6c598d6e4494d2c183ea290ee2b0db61a47f3f9d5ec30bc8e0da25a67693ba53fc936bace7b3112ac1cb8ef52dd162ec8f6bcade5c70ef54f8de3653815ef4d25802415ee89dddfa1c5c91bc6a32f35f33bedd909c71fc9264f510e720df3f86ba8ec78a0d7043457d6b4f1fc019545c61df171630b9dfbd23cb127dc48c44836ba7937f4b5cb35cd4b7e35f0809ef41c90a5516e99e27f306b659429f700317c892a06339d4aab8be0adde6d83dd47be9432007dc6fe8b683a405c18cea541584dd950a829a742471c9fc1dd3fb630cfaf1740e3fa7fd6a87067977a4a9d32c44d0707eb73714b98b38fbf1a5b3dd827f79fc6fa8acb1421d5f9abd145813bd7dc0fd277fc8f5cf57ff81ae7fb389c877d412f57d22db98ea2a3094767978627e5419ac4f080780b083f1d3807e5aebdd0460097cd6447f4fe343b049433a0c8558f77ef390d3de76fbb597b0e86b897d2b672c44cff4eda1104d70a5e36e3dd6ffdb6d5fd54278b2dcf3b5377d6eaa3e4b2f493eec38446e11ab4668941926445666b4629681ce6d7950e0b6ac7894a328c86136558c2fd14f0a1c262962ffb205cab75ca31f8a5232134dfc8f4222a4ebfad2b2a34d0b9cadbc1c12823d2181cfb84b2602d83baecad8eb16dc82524ba6ed6d9c74f66189164e6c516bd27a86ccb03e0a0245a9bb87fa7a326b500de37c95d05ad35931727e7bb8464176ee95ea484f6ffd2819ce7e7f1e36100c37265d634a83e3a31d00c458071b2fc57f7c744e6626494d315e2ebfaee8a2ab309e4ed6499278ad89d82b96eaa96b717c2cbb68f015fd15fb402ae0acdf6b7c9fbabebd3e814330a25640472b028accfbe90379955ea0b6067fcf34cb09009b86961a33974fc49d0c182ad5e77638350fd5407ca0eda2089392d63002368ac56bb5614a8cd4d4ccc7b8296388c144ee0a00c16477bf95964751fefb0e4e1b0f251d2f402be42a9971c4b42a45d20823cd4ceb9355532b336e090c16ca2600e7b1ca237777b5e10f12e6f1077554926502918eac263c889d9f046fba2e72bf66523f75a92f54aca625a21a6719762e6107f216e82f5495c032c0d7ed522229d6022fa4d4e3837fc0d0a050ed86bde93bc73cf8624a80fcdd054d805f75f32f0a05232784f27f9fb649a69e327b6e021cd8a4c6a775fdc40b9958d8ca71cc927535b6d0232a83af446a95e3f2550664a3673ee03e8522ec501934399ec440396b9cc78171d27da9fe042dcf6a3946b0e392c7344ea548565a2debf32046e5a2701a6b73e8b90f5d7e47781968f3e5e0aec6e6d1d2d4c61e83953b5d117c0ff26773f85b3a3d93f9eeee67d12aa3134b60e5597cabc31b30342521d9cee128c6951c9ee571f5788bd95f1040d1af1f84c0211bd927550de0a9c4613818c9484e33234c9d0326242392349e8735e6ea3d985e7fcfcb775049aab5eb2a9f49c57c3e106c2c489c76fbc7c12b4a6aa5f1a5f04be8c437e47edffdf5cb60889ecab8282a7eeed17d0ebe7fad521f2d18a968c04389939c3f424b906e9cb79facfefd2621b6228a6428bf8a6b88a29bfa435b072ebe6412baaf9ccc23f262e2ea023781d152b9d2fa437e38d55fdcac192702c90898b8a8828903dff3f6682518e5625a7fa0eeeb7c2b91e0cc3f305d26c8d38d9ebfb716c8c476f8e99d6ef219f034d07e9694ff87f308782f648265f2ce440bdbcf3ff0d8c1232ed818fe9e7aec07602fcca6752f761ebb07b2bc1def9ba598601c1a5f52e7f66d933a0bba5bdf61eec3e481cd7ebf14e6d9371d28df32366ae519170fcd5bc52a4c216394e64c3d22ade2699b73eccab62b9723da2f6a0b2c7b96842362cf270995afcdd9d7d37f272b5691e09915d8d63b83a94813dabeac124a6f0ce7eeba63e323c54ed2f6fa3e1d7537ee1ac4f8c7505f43c680d61d1add78e2d5086dbb08c3f3477897ec7017ed837dc52505b960da70b22d0977d495d8635fa6e8f944e0e2d4a1e631c9711996a2ed0fb5909415633640141a8a31c578f0333e3b24d5dccb096ed49bec46e2655e90673cf1ebbf8645d0bd06f29d8afe315d303125eb93af1c64052182dd95c62099407f7d43b682deb4ecba56f0423189c06ffda30edf817b06421a78b9ec63c6c88eb568ea4d8c93570da5fec9d35421e98843e6e71b6d7a9e378b5924b9bc290c7bc1bda510dd2ddebe63cf1714a000b0a5ffbe51e4a5e288b4140ae82b95b2b89b6ebe5c1ffe51dcd2aef0c4bb09f00525f778c403b5e13e5a2f80b21094f301ba55813faab3232b1f8e017fa4726eabd7345397f369afd75fb2060d311267490af314c8c0b8b84fd80029f05f2183773c9072c8e66a469f8d1fbc3712fa1eece7a2a8d8992fbff885dd4104692834d57c5623fc101d5eb41b514e717663e6e3c2fcbde7f8ff0accbbdf62a6b4b5c8ea7188022a1b48d232f7cb7e609ecfc4c6c65fea59d57806f088790e2ee2500732edc066064b8db41fb628059bd11f8668ebd65a182df402817043a9a327b0129693d23a73f65c3e16735fe21840d42fe8e2b11c60fcf94d2d9e8e8d145c14ee2ecff4bcb6a8b15a1b2d87e5e099b6afd9630634a169296a17c2b613dbba2abf16d9bef5c6d4d9abd7a441f1a163cbe1a28238d1acd94b6925bb84734f96c563ab6e77fd8c286a9f9d2e0e6560c0671f4c8305336ebcf9ce15508c36be5393c8fe58cd28a30357b78bcc9950a457f0ffad51de680b2dbf2dd920a8e019d1e53d11e4181816a970a5f8d13f6d319cb50dd20766cd9ecd126213c9ccdc4d14b14170ca169b2610a589b515cf0943992b403d9ce6824b0743592690baf817cab34e48b3498e97bdf08b7b4c1e90ff0061b76fe3bc750e3995d00220f7e53a0a5e896d70a56133b4cf319bfd516562505d65374be73af070d50bdca26aadc804984fa0769d2d3403dbca24ace45cf66d6701f100ac06cf540a06f1f17e1a6c5965e07ee7aab55a3d74abfa73f7dc925fc7278f6952584327b8d13caa5c0ee6650d63997824c15f88fa7bb15c634e157d3c6b1806ffd3ddffa2d3653e1ddd6bcc95cfdc94c9599606f36ff5bfeafc29c8631db1f54836398200619116efef21203314e58fc653dc746db80f50e0b469acbb4501bb1c4583745f8fa4765a95411044caedfd2a5f44d6c63d27b0085dcbb0a0d9d16cac2f22a59aaea3655f785000e2857a2589c202d03bb77009453285848406e5c45bacaab6baa1b24b2a445f216e298f7134d9fb81d504dc478cc8defa75199ed5cf4bd0504640bbb24fdd5d1fc79e26ea7ce1ff99dac1944269b05db078458d65df89077e881d8cd485e5f23e5dcfb54d4e9681119540c6ba052a6664294d18af64e18788ac0b77f5de15ad8faf5562b998eaac907c839a7f288bb048fee526cc965b983131c29213b9f5c5d4eb64d14dce1bce38374d7ab0c17d147756f80ce4e500639f68f7b4ca9f382fdd115cb87ef2e3c1902097467b8c6c46aca237ab678f0d9dba67f4b425ef70f1a79a9c6dc031cc8ce70b6a57cc1de1f5c6c2e0160e080f6efa004b07a67a2fe97c164f0f47c02f2489f28ac79f691536748a9bca438837d36f91b8f2429d26ea57e2710fc44acb59903c54a505a19c7676770617d503579a79cf998919600fc29ddbbbaaf7fab4653fc576857fb1d6f3d316ac4d30910d5398a6e8d8c1c8abba88e45150735234dc1bdf27dfe006f4aa8e7745e63be2cb365386aa7b3ca5b661beb48240d8947b1fe90bf455db50027cb71b8ba6cb39441b3ba710b8b1efd20bbae9002028e58f70d8b1b3c32c483eab2f40d0b7ac8621959f49d4cc82f1eed767410576c59a21d0d1e46c98f41872e09878cec55e62a1af3b53754be06be2eedc26dcc505ed1f389af3a2183f4c1a92d2d4d22b040d775fb4ae6985e2f111b53e049ab82a5d863b5af974ac7ea011ef8b42a7ff2ce9c323120f7fe534e909d43200cc1f64aa6cd52c4ceda5d73c194a12d57d93b08d393dc3fe613a6938a66971ed8ccd0dc35dd63f6a8b4486f9da22e0279dc113cd39c816386af553316de9f910ba5cc9e0963f14a58034b08027025570f54e015414f71518d11489c7836a4f9f0c6c7447c9557af34a960b14d88b24a98e5c29c0370f0a2f80aff6f2a276022467f6a38bbfbfa3a268adf94b479d8cbeada6ebe8e02fedf4fc36c2d3499d85d01fe1b9565f5f05cafc4200d9b0c830f5e4861d4102a1532a72131514db60520676bece1d2dc7935eb9a5f65d0bba31448da3b15be23a10f49fb8f68eb22831ca93e95f7352341f92c624b49a876835a412121498afecf95d77caf151a31e76fe07677a377c71719617f7e408567843e61f28d35e4f1f195f5d7e2e7fc54fe07f619dbac7e8d3bf24b5b6c2f5ca9538de2e345f785d74e803e82a2ba30dee8ea28113d169efe22b5c0a72a9e4da5a5200ccd9d84bf8f2020f0068aa52722baa92013b581c1aea5b0a85c44b4f6092435fbb6cb3319b5d49ccfe03baf477ac801550d1b8e17b3638eb86d94a3fe815c82c9b8071e967f78fd283fc5f447ca81568a7de3e255a4e0e13e09b69f334b0623de75edc9948784e8bfd2a687a1eae96a9ab24372727b9b50e443e56b3b8312a6b2e8d54fdb2f76c8be6fb1171b5f5a3833c89017c91559b651809e91068a9362a0fc65b3d2959c48c5fc83c382761f9f499ad89db969ba1c7f04ed3574f89548d818fc004b953d4921f0ce5afe388f17631d9a0b87421c8f07502ef14a108f0bf3711e650075bece75abf520a4d3bc86b8ef8c937fc45827c4974b56ab6b523048bee662c156a0a3782e3bfe70c4db376f9ab2c8c0475e834b76908d80968057146b4ad1420b0e99270c66cf941d82bc12d65c59cc1c3e2934b05abb58e6d1bcac1fe4cd257602a9418c2b8172ad6994d3a32c36cc19477a210726fe5a15480d5efb634a9bbaae6e529ee045f89b35316afb9ab20e3d12f3c23a9748ca568a618ba230a4c5494aa7be0ba9476df354e4446e4132c1ada65824a4343ea73f205252313e8e96b523461d29bf55c9a6c4b3c88c1766b33942a43f8182830826e4ef2ac0571efad544f7c62fb8619cd3e962fc2ecabe80b5f4402457fa1b9902784bc135bf0bdadbb35e2171be141c12b1f0d5e3b42a7131f32afa231349d437c07956c1bec60e6960524f59645929d3a4d9cac8e14efd86382f85d9601bf4ca62ef139e8bada5705df0d9e90809e2a198644b6b506a2cf3f29fceedcb8c0ebfa64f8e96c5893821b681d6463afd7b922044c5e3a89b33fb00e93f86fd913b47629643a94b8d5ef8ecbec9c6cc4c8452b389d2b80a9f2695c763ec0ff26d519bd9accc73b774a3ebfc1131a2daf43e7c9033cf4e4675d98b48138a8313ca145138fc4d42ab817e757529aa31d8f532a91e5f62cb270653faa2d57ca1e5ed81f6a1c8c78fb3c11ddcafef48c1d8c48e96a1068e790107f868d850347feb064c5b7a64cc25a431d59d40b8e35f04987e9e12283d5e1e2fffb063badac6f110661f626677045cfd8aceae3bf755eb2fa313d9aa407720ad3950685b6513aff7e1d1174d971e0bef1e209ba9eed567e27c3f239c51d664837099e5b3231f8497bcdddf1e57540f61e14ec2ffa69a55fc873fa4a9671fd8c545eb79474b7333cbea4b4a4024708cb7d579e55a7cbb4e54d172ff066b4b9dca20a666fdf1d24f8cdfa8bfc646c3cdb9642152171193d0259c25836fc6df198c754cfac6b0690ac65db883b26ebaec2b56505433bd6f927396e8b4b9370c2f41227e7cc514a73e16f3eddc24bfb84011d4e2890b4f3fc9dd5e04e6b6a1671007dea6b536e830bb19b889e477dec15f476b30b281aaa662f8d6d6242856dd08034171ec9080cfadf15108f3327217494c2513b942f366d179448183fbd116660f992509e670cdc88b83c9e4c0f72089ea7799d23b9f2b644e8c0e7fde5cd565b3ae73d38004f909fc52ec53d54f99f88a937cbd1381d7cddf853abdd2f0eba7c4623bad2a8f61ede04ea95aa48ff05fe3865d266f481a7d9caa5472da240615dba51b88a78503e12f02988bea51bea8142d44c5cf40b55c07f87dcb52749ef48b0670f675826f444a37beb11e8c0705079bf5f7622b246ea9d5de52d0c366c1f0e3c6ced1be511beabe68078e7186c45f207b086910259f8bceecbda741f2e7e9b83cb07bd500ff6559541ac244c3f3b4052dc98f999d81ff81c41ea321c8a9307d0ddba467e7796d156156946a3de5497de243de6fc15616df7df97d5b048e060704386e91fd2a733553cbda1679075ed85ca117e5ccfebc088f403bf9de25a7c7711d27ebbc1eabf3162ad5c08f6ce855eda9d145043b667789f1dfe2c906b44e71642beb9d9629be891e95e985241a4d81a16326531fca2d6b1eca7817b904a28ce1df90dd4fe73ad4df1e662035b3aec3ba24aec3aae9d496794f2731795bf1166e0c6bae2b9b66b9a93adfbeb9dc353919b299e2edba189b093608126fabf851221fd3d4da0604c625acc8638b6fb9a2c5f4888a5b2ca8a8c03561b5e63f595a9d20e5f4a437155bcc6aa37527ab580e914a3bc8d9f1ffb899459a1d2698808736b22787a810e37dc1af1c60f68f4f5366af62073a3e12269bb29cf23ba13386da6b234fe6bed15740c24a4bdbc525304b2ac72a4c8e53a0ec61ed97a6a4263ed82cad810701b0ede495ea23932ac695c73f42e2b629e75841bf8d00dc61dbbded37681fb2a4c63ef5b612d832bcb68c373f4cb0bd9dfb75319e0b791257fd860270654308bff911419b00f22e3fa63ec686bdb0d35e38e9d52b57ffa990125596f9056770c1797e520e052e4ee2bf5021c2d64970204d0ed51bfd357a8e43c1a656656d1abcb5aba90e6e70c56fc93b6ff4e25daeaafed804100fdfb45c894a8872c685e3fc9db07d40df916430b5c88b0d1594f05ff1c7bc113c38d1958280eb5086daf8d9b90ebdcbdab914e1053c7d1064ed044844994bf9dbaad9f1702d77da34189aef973f46c335b2c9f0fd6ddc7bd62e4854d81930dd85d00ff93163bb0b233560a785b26778eb1e4799c4d0f0810e1014d14044dfe925195a7aad7b87aadbd90e241127c761ad35c6d797e1474464f6fa3cf38a08309fa751ca93d74c43702f2498781cf116712af1a265d2eb98fd2584557fa832aa7694562b6e7e789bd48c557fadb4c3390d40482b4c8f576b8e7d0d30c129564373bb9152641a37550d124ec18f8692c35ff5e914aa165fb8095bb1ccb1e93c709cf21690194e780a5e1605535a8c0ab87a945abaa6dacb0b8b7e9ef9fbbbec47a70b85453d8fa317d75ed0791afca0d31320608b260e588e3b21271c5ec3c6a52c42847071b0874fb36e580d93a452f9db5221de03e3e886ee344ebcd8932814995f12308662ebf1b8c110a34c54f3edba576a94a691245f30d5f996767ac2653abd67ce177f1af986076db220bf750ecaad55aeef3408f40ca5cb5ffbf4fe3f96141ab5a69a4247c1c7371a949fb12e84af1c89b99eb63df7f5fcf3b7805b6ef5d2f4b181d55b3abaebf18fe6f09692736ca62c85a4c3dec23974df35ba138d58acd210404f495cc88f753d0c3a2dd7ca92dd9396206bdfe52ca83b2db810b4fc8c1e6d5acb4b6bdc3b5a00e284343ab172213357eccaba289938e7555544eddee3bb3669522b4a0e4c13555264a5fd76ab491e0dfe8ac3e067251ed00c784881c93ee1b26b9db5e7e19b3f54e87c9ef42fa7903e216c8925275eab169ac6c89c332f498508510b533e609e11ba9779eab5787c4fb3b8987b8d635a46bd22aeea9b09fba41a256b1ef3fee81e21cc973e559122a291a704cfd5f338b4e85737b759f74b08eb42e47d0e5ebc6bb9b0ec71ec67c645811fcdff4e42b7d98e0694d70cd188177ad943d7d91d1a9f80313eb3591800abdd8703e12070400afbd6d9c8a9959da2464f9e6607559fd67434aafcc0c3f31ea3a888f79587bc07a8da3ab014fe702cd37ed6486aa23c917e3865bded2d6b56e68fe00e0c05bcab721af0f04c844986b43e76ab86e4be0df8d7d80e5f9a42fa9a3a12542b15e98549fbbb1a441df201186007f20f0f17b412cc8537d51eddadd5a039df8dd3f8f7c7995aeef88a3460875499a6dfff776c17421c1dcd95388f2720e38262513ce852885c76b11db691e54fafa52c2a79d05db1f58ed04ef4add1f30d992ce7e45db0840a4191f3d464b92cba0e2d86c6a12bfb66d197e72a106bb95e881f9f0176dffc9fd58f1be1dff4ab8d4ec158ef4ae663c1e17c558b00cc6b8248707684cfc0b86e18d8c70032fad22072f12d352fb688d4c1dac044f608dea6bed72c66cde65d1329813fdf76acb6bfeca124525494f4c129cf5973bfe0fbec5200151589c0ff92c01937eff1bc3384f2f846b45b952002043f9aecef9adc2e8dffd4ff85e44befae0c26a5aceae942a980e233c86e47504f9dd037771c664cc78a41b3dd4f582c0f1f6991b4c5468d1fc60174233450e57cef09bfcaacefad667c98623fdf902940105b9028f39b18cb52624b7a1782157b092ae1a60890a595fb8a3be8cf8c7468110aaf5e3304ac93a11f47a43ebae8a38991a14f3c0c1ca8c8f4f70c9209619b3974540f07fceb6aa3cbce77d997d671b29b1d664e52dd9e9c7f5b90628b6228f758e9b546770e2bd8e67fd598ae21c25d8d8964cb0506eef5200e97aa67bd730d5c07aa3d04710dcb4389e159fc633f308f9381103df54cea4aeacf19d4013057d36356cd989609655292863c871a5f0ed8dd136a85365f0f80337edb24b2c3226090799a88c1996438e31fae948e6243ceb6bf9740e33270beb788e3777c2b7504aaa1fc430d294496b6aca92a910675cdb0d36dbc7e93307071f23881e6ab2d55496c0e22f232179ecc0331b1ec4b7f24c90f92d24ba766471e48a55cbf839529d6f565799bd58661489697c70b14715c5bc99fd42b726204e86f4d6ec48bd4e062919c4475d4d41225d5430adb2ab6177a8ba2f7ddd0deaee96b65c8d3ed28e342d3291308b0e199153d1d40890bd294def390e20bb79f27b72f4ba51230bf74af55a48a5e91a92e5df8426b514b771c91246a13572871942fc45b5e81950f23d0d76df65e557a34dd2e3e292c07882e04363c4c962e778695847759c94a1361de6652c4d5bec6cdecb4cd02a560629c74209399b207aad9ec55d93c2098e15a2c4d8f91984aaf7b3bac18c791951d2957eeab5c1e08a9a21ba95e109fab333b1637bf8f75f5869bd85414a88fabe66adea9c07ae5f0c9d5f5353ca8cd1382aeaad8c25f28454be49b0640145eab4581d96b50186f9a7cb6c0dc8a940d0c6f354b7155d391af1e572b9287cd9467959a97ba2d35db1e7f320cd73f6aa665379e8ed4faa54dd779fe79c83248e0ab62969915cfa65f2d9384c119eb154d71627c6b9c51b3486c91187f8eb310dc5629b9f40f91eb50205b91eb0088e2e38798fb36bfea4bc3685f1730a9029a945340f1a39463d98dc661ea10c47de67127b023b77a4d96a393cc737a95d5a1324189e6262b217d43e9177001b5e2af1435f792e520c6045c337a905fe73a948dc3eb4e060d193fa4cd3164608966bc6127f1e4702856e7962bb2389026654466fbea966a37474ff892a0400de274adad5667129bce78bb3f3bdffe59a700e4b9caed0065a464ebed21e3066470657ad0be23de6e75cab75cd69e17088502130a495044711989d468cba2848f0ca496518c31094ea7b83fe1e3f72955a25d4bea71058fe76bf99af43b9265fff66219ec04139173185677371813eb3ad253a8c587e82a6815e16844b8624aa05994787ef487374203134e2863fd416f00b99adff1b9e29b99fa445f0f2eb90d7d3e1f0c9e7de3c8237fad98c3618e80bedf042f98281c3ef42cb48894c4b1b2f21779ec5c69c5cd97978915dfb7507984b6bad683c8b3eb01228e51c0b9c2fb9a73ce7703aa8a2c06c155493611ca62adc1ede0a394ea8eb409c9bd343d65edd42b79c39edcc7a6c9aed00720e802b4c3b06e638e771bd12e720d4f52561b90f695ba959d8624379b76ee4eee88bfef4c8bfc026ff47283953f4ce4c429d76d38525fbc581fdff868396f770a8142f8d2743b0747743bbb83a7e636714ace35724a66511ccb59ee7416df06e71b8cd1f6e5799830bde63393d7e2598a7fac4737f6c78ea72652a0dfa0ffed48701fee8e0c0051b4be57f4ed177ec352ce5f6255d7be8ca96c7fecad2206018eba9cbd7501e3e25e49b7bbc1c60d7af586d0ae63f240a2fe34853fb0e606fac393cab3df06ecfe1f3b10c700b3520932657871de9a54a22edbfc0a3b3d9e3bea4296a2eec60ee1c9b238f665d1ebd1b5704392c209cbb7fcc011ad64b87ad1e79eb611e24b754468752a23e1e8daa2be4b2f5a83baf63567e5a955d63a3b63c6404fbb48e7dde706a2f86970780a1c604293805be5e68b2a54903cde9414a95873baff89335e92fa21c19acd670bbbcd6b10a6dedf83b7547a953babe46d1c89c5bfcb5fc10bfd5941f6029b9ed339edacdabac9a253bf0cdecd1c5e40101e4e1a1a0021997edab31ce88e7c67ef7d378961dc48cdb99cb0af7da650b891a47f755a32b53d081859a928403857eaaf3898063c9746e9aa526bde5016b811f5d95ee0c78f72d73e1c56573dc37d11ed8f0cf15f0f241e1d0ae69476b8892880ad2c2ede55a79efbf4d9ef0720f5a3c74df80ad890d8a58941935a4c6fb69320dd98c273e04dd9ed5f436fa21065c8fd0693664084207e7ee76faba1d45cf9c003a09611a434a8ec32f4e6a165e81bf0b5bbe959becba72c42fd6dec1bd392a5b97936189cf143bf06b9593ed1289c810a1a609a8d60fd421cfc7483a737c0ad7e9c6883d3ef794bec54aabaec4f7e563049bec8341a094878d691de5a6ebb08b6965e55d12b31f5edb2372dae47ea7c9481551eca96fc13bfb0f74e05c4946c2c0f87863c8e15a53a504dbfa7596aa715875d52f62686b7f63b64fd92596b8174bc6f3bf4cbedcffd88446e9d9e7abf7f58ac79d573b2593e26b6368f0a93c89b0fdb98325a7bb73acf4d0fbce8958c7e2d2ff6ae8b0daf349660227f7ab2ee054a772c1ee2ef49f435d816f7d211634c23c08a73d5e5257b867ec4f3143b07bb2d53f19301081a7dcad0b367f1eb4a2e25d31157afeed1b88d623219ac39623642c39cb5d912625fc5b63c7f20a644312070226f5e32d7f1a1f78c83cf5167356f176a8f18ad5ef18f706d5744073a180b136ab11e58504e809eaf6d13b349423bf3858c43d599fed8f3b39bbc7385c1a00e50c904865e0540e1eeeff41cbbf6bce017e119c155606f7473ffb9e9143aee54c391286bd68706fce36d23c6224455104a6d5af874183529afbed251da00133062e1d729fd50e7edae68b50f4f1bf5c162b74a190996fdb9db5a19a8cfbdc48347dbf8b7814570d1a7d3c872ede801544c18d6e5f43f6401530decd0368219377333cb16d292d9b48c856153b17c1876b40410456c40bca7dd6e1e2050b425d2104cf745e6fa58a21d17d204fe16e4a1ef04357705b3d6ecb5d73495100df17494d723e4021c05424868db201b41796e9cd26662e2a1a8e98f3b0e27a5f8c3280204c68735e5836b0f1ad9490c808cff649c12a5f8740aeff29452b7def797dbfd6b97385134f1defc48394082a528e7bd22d4e8961a470c345dbe4a93b1fe0801200c2f1280931f2ac1a13ee2d89a4ef04de1a1123586b85cbdc28c0b4121b466e3700cdfcdaadef7679595949d38c860f4dcad9b1668f289a26bdd9ed6c9133bb625e5f1ddd547cb37e3c37e53cf657d79893cd614b5c4d838756c9616d43e04b01c7b840601219ba9350258cecd1a30e2b59f4ebec2caa892d4adb9c8e3e228fa2abb1b52f6b85b13c0f8033f0052a09e998d3becf917949a30a736cc0cba36b790ca1445808dd3d0b77e7d406e664e652ee494e413b45e6b873c8e2167fdb71b01c197129d9717e2ba2863bb819cd7afa6c42c09accb0a56b6e439fb665d51250c9e783859183e8e9e098ad69278cd16405b236d84c61d65cdc18086824c8f4534a874829fbc0e33dc367f449d75baed56f0ddbb3931d22ac4a5067696e49d2007f5fa0fff1c2a64db174d66ead540b86c18d91afd1fc66501a65ad54cd1d29dcd53aeb850dbf89e69e75c588675601a4709679ee11f10c0920c4fe532420c422a76d85d547df851fa28d11048e0cae539ce37252b596bdadd034d1c5f03ad674495e3154b3be051e0081b48804667e1e01d79ac7a899b5c456983752465b731eb5b49b0f2ec469494db97584bf51a462645d544094c62877c809498f7d660cd6a2b85131b14134c10c2436aa7cb2122fa3157028d878eefbf80006b4a26ec2924bd633dbbca6b66f981aad2a1668865846a77d15a3a89a85a9b1dff85d0e8b91a683b1bb36ed54bc461556153b582e23360285ce14289a049d15395e57c9f3d2eec2fe8a986e8b302c75f3bfbfc3b20921e75b0c07d168a684b4322217f938e9a1608035a6e74ba3160c7914bfbc071ee6d5009f9a48680917fbfdb7b8429883fc168c8d4838472272f16f777458b2b0fbcf8b2f8e20504368f0079c62c859cc42ed995f87d44b6d2e1959f8555734ca101582c07d8b075d2ad07a6b1a1906ae996a737dc40b2e1f08affde55512e985a1da2a2765de3f4d2ebe1dfdd5427ff85c36af57a7e1d543dd33257097d9bcb46f68d65d6f16a756bb344e882ca5460741f14bdfd3a71fa80eb47c25cfdb6486114ac06e730bb628d1000a1efd2cbf48d2bae0436f0a78b99bbfacc61ab771f79aaa6b5a238e9aa9940deae83a8ced4b3d7f8c1e64be3288690003887057d0a8ee308f050a7729721fe83c73da371a0e50f293f0a599da0d7077ef9328d91cbb9fb3542b22baa196d84306d9d0d0af5f9973498233b06f0f2753a217e1e57d882ab535699d12be2bd78cc670ee77aa7abde6cd643641f517bdc48f5bd5decd7ad5f2bf0b2b6fbaa111c3b33c62b930dbda85b7d9aeed6fa42bae32b80c5cf9341d926c9675f1f728657ab0d1bf5c754ea5517f34d55b6e0b972932fab335f8616029f8043bda71a1269c1bc3b15278d5eaced8b6ee7c37e8b0e689860f9204676a6e33213a412dfa70ae2b8a5052330d7655d636e2ac7aaa1fa6411c1d1b54d6cb02530fa738afed55b1f9818c583ad1870628144144313dbc463819f258f2c44a74690bd034edae53119a064ba48b6b99fafafa1b4e6b8a228cdac4a0d7c16f612f89957af127035c12eb4b32196b05aadea851f7ee0bac22a740e1e91b2cd1507604fdba32fcc96daafabd42b8208962ce0c437ebdb4811b4d0686dc3969f08bdc20e2ad187665d75f3c758ac00ebe71ba82c1ad9b31064f62a9d70d747f0c9366b884194c540a0647ef732ab2e3cd975130d5be7a0a9f482f0e06595b7cd6edfc8f87046541bf8022460849985ca463941f76504b0368081b39f1b0333462daae6fa78a8f60d5d279c19d1de0f79abf67ca341977ef1cb049c3e4df4a8e10f3e989559c77a0bb1cca4f3cff8ea1402e5c72aec608f466579e8820e0c1c7345d7c3d76900bee931841dfc87302c9194f6e7e645c02b916a80af18e6379077abdcb4b362beb1ec3a5f1d12f4e4bec91a94d86a6e9d2cbc14b8ccac9d67f5cc58898b9d4a7ef98b5b94066b219f3fc804af1c813e1fb469976d12646d056139534886f186ee4b9bd886fc83a0b2c2a579216239af9358d0bb0532496afe596a57f0f2bac0d6a6fee0ad41b8493c3bb5bb9ebba76cdb6fa896a7da0e1dbdeb6f98220ec61cb0f4aea4edb98e0132cd7654f29d9276460f6fc476d9cc636551ee23022afa352cdc2ea14c7c820270ca63674c573239c56a67ed520d55079ec59267a0fc9a02111f026e9fe6a605c59916c4ac53e4530d85ac0224f1c38ef8b5a4aa8f0a4bc575b92bba7db2043b2830e3bfb11c5f37e48cac1a0e60e990dd56860e131a8661aa8a114d97a1b8f35721331df7f92a4a43e0fcfee61ee65035f9db3b500bc267ec6c1769530992bb58e0a5007472a2ba2322e9eccbf1747cbd53ce4051b0ba060890ed8a31b66a42d8c9a34a0ab4a7f9188bc768f31f99f999ab04f4bf9961e3c7636a9ebdfc6539918b3e83f6c9d08b577cce7078c63757e713757641f87171a26b35486f95b43557136b4fc2fcf7bd170495f43b63be49b467b083ef7b5ce2979443243177d982279d277af74b8851a10555f3036db9e2bdf7bb74778754dce59c2ab4b24d6a57232bea1721345f186103c22ba99d97363f7a1fc35ae59a98a29a23af2ccf15fa6671fa098dfef0238af256a448d295cba072aff6a138a332d9cf6ceacb897a0f45ed5f7e9e4c32a815dfe5f64d0b3f022d5ae687ebd3ece09ce22866d1d51af790cffe74aa6521ecc9988b368b321f81f21872f7601312fd083399b990d5cbdb452b61a74149fd1716a233b078e0388b1e425e9cf4ca29e6d591e2f2e28b3e9aa609f39eb4728b6ec14b3b9306e7f1547636ee4740974acab561f70db1f6733b541ab85d7953027aae814a261ca0cba4528ab0f2e9a98355ecd49b0431f06d761e598f5ca26e8355e745f8f3374120b6bf3cbbb36d3499d7734bc8477604a3e7526aa5913a5d6db919906b670956e2298bb750e05463f3d20045b3124a5376bf2b79c8dc6846f0e557f93b9c1330ef8a7de16ee601d4b3819eaa1826a5cb3d483453109ab5b040be6f1dccebc2e5039830597e856e6a1280a97f17831172b4826eb6ea058ce15910815ad3a2cbc0c5708dd0a43202937443351d2d5440d55f2920f6ba9933ce5939c71f8662c686f0f8ef9b8333a63f877d45fb54cb5b3bce3c56745ecde89b47c422d8ca339390ed0f85ba90f91532c6d3ab6cbe098594c734889bf76e6c171ecfb0658fb38c4ea19aa5c8a202053e5ce81ed081d83272c9ee94a38379a627aae2067b4bd06fb00c606debb9b02342e12ffa84ee2be243e351349d0c6cffd2526bc7657f7184cb88377430d19e02ce19fa3142a23b68cb621da61b98705ce5d047fdd41d07e8700a9176e7037d0fb023496b36cb661c66a59a43562510e8cecfdd2625184a19108e662015f9a715df2ffbcfaf60f87167cd03292df50194622fc2d564d578bc9c402542264d2857cf2e3d8504951b3d3c4381e73124e5ef5fdda987e7c4ae3bb8562787840efa7727dc2df4d1b574846a19b3947a4cb20c005f4012c82b47526cdcd5df7c518ad32d3d1596c14bb948911514a47a4ca771175fb78d84ac230ce04a79f7ea76a4415e2515aa1a4124538719eab4dfd97c56f74510c0879600a783b196f7c38a3b94929210cb23e7e3664faf393415af7b1dfd2c3d4c02da8cc27e1926904b7914d57609c04a219de569e9074e54cec8ccf509ccf7cbec57b882ddbdd014206a5cceb7233e2bebe3023039f930d73e9f7d1328dfefab1366b574c906edac3aae5332e9c48857e91c8bf2c7d87f4525787ca3572c00a2f881243701656812cde4786d496431247213a8faed929be7715af4a462c5ad48e892df73c656ef2fb90ba9ab6db96dddfc65acd14d839e8d35cddaec62f0ddbb9acd8f7574245a5d9f0e92fe7c9d28720bfa030f4f7d28d83aa2e9a1f5b9a1710c9df60378765f3cc18f379426582f02566da805b875689e4a55fc164a2513e7739b99b49e175b3acebdb573aadb1ef3148a8ba532c0f549a92fbb63881cf9d97bd823848c037869a140778642027e743bc2bbba9ce6cce0b4908aed69b2a9c0f74527c4acab5dfc8404b9e23f286589b87663a6dd1f0f953dddb792751b1271affa84456cade785c576125058e94f34dc36bc68f2fa1c400b9bc6be84921745b4f58d9f74c0b97a260d8b8534433ea790577ff3728905557487ddcc8629dddc734d5a98d0cd2c8082d8966baa3029bcadedad23689ac48e9ac55b33fa9b65c9d915b28069fc68c039feaffa423c53209604dc9559211b827bcd087ad92c1d3c904211208f3fac3d19da237df492c99fe1f229b80682b968bc7aba849674a777efb090d548f63439e5b14b7b7afa858f9c94b41c29b4217daf2c2e9ce72b9b63cc1a73079efa9dadac52f32d20442c9f0ec0c66b4f2b94f1fb65278a3458038038a353b3dd1e98cbed70680dde402b04dcad0c007dd7e0b8ad42c5cb1dc177504afee025a123ce9d3a097f28cf83410f01493ce960223d08b523bedbd45eb6b357f6fdf3f8f149546efd0afa0261a0483d71fa64e54732fe714f1f715989365b7f7c0a41b5d9b16afbd10d783ae4d5dae40d6114a09568027de6e85e6aaeccd0c507844e985284a3aac21c9d8a684ca56436439bceb011c5dd4c14dfb7dba6adad0db55d761fa7a4f6938e0cb1e07deb7067ef718905c628e20aab5fcfb92b1825f993775d2e57c27721b515223ddd30b4fcb0784cbdb9df41eafc17e2a5fefd4105b1b4bd2d479344e8078eec92dbc40ab38450f5a9f8e8d3a635a1fa62067d16bb77a1580859835f5bdd4372be7f71ca9fc39605e02a31ca9a7d108cf5bd5c336486a11ff2bb0cfa6048fd706feec81484dded247d50d84f52082250401f5987b1a16b225140b9d06d6e125c3eac35489bc33df6f0f8a9ead2fad6c4521e51da0cf719ed22094dda3757ae998ca90caa854c22817af771446a32bbdf4f1cb59ebfe0f1dc533dbd21cfd1bc535dfe3f6d08c9fd5d2e2f06aae2d025f529df961c461568979cd17631c06c1c99fe81d4f4a1bdd4ec61ab30958ac90bdb434502cf3ce3931df3a73f0c0f7520427f7a8985267f0cd6160d7fa8d12849f2cbb272124f974e46f6114a72c8238e4cc826ae8bf505d87c8fb93295b600887a2e91569decd21f96b4e3cfc1d05f9439df40bd3d2039496fd560b97e434c685e4ebbd9c9875ab0265cefdc46316b105226145cac61feb9d1af96f9e168476dd103b3099569f5e63b93c5a941193cb19d6ee5b9c1223d21eec526a39b5a4b8f6a08f15b0e6097b9331007adeae3fcc4acf10cdcc971775314dcdb3542cfe88c608759101dbe0f527696065bc8ea8b6208e9b8575b1378cbe4f205753ae083e5cbbe3161a638e36427ab2ddeca886c10b729e7321ed3be5586b333d5b4af967d2fb4d96d4189aa0e751428f418183bedde4f806a8aeeedc1b3cbb8ec87ee64bc407fec21f161329fbe256ca9cd3a4636c82d8bdcdb39862e44b309c91fd4c8f9133f670ba9505d50e412040a04baac881be1a9b70c27e2263440593fa9d797b60954780af07309298092ada06d8a9751a885672822d8f94e10712c5604d86cede7af92ba53950f98418a093e32f194fbe76a5ae5088267e6ecc43c54d103a284d8f86c9d5616a95785f6e5bae44cc9e4cf3111719ab222e2f48d88e32df6a70fedd09f8755bd3096d770d29c0b24937c5f8038d9e7d81bc4a2077ac61c14d6c36d4597d9a5e277220bbfd13cf3492a6d1eb43d7392f26a92e25362f29e97c181af2d9a5741585e4e3692526b0cf82e3f976da2ed053463553cb24b4b545e838bfd97bbc093f71a29202eaf170e0513ec5f68f54070bbe16a8df3d2e2eab571648eda57740bef96c54a07cc94a6e97b00c94abc9803939ff338de772c999f7b8c8ca6575cb2a37ff8ed42cabcbb89c9b0d0595bc739546211c23ee745dcccdcc3ccb8709c872d03c4fd79205ae4fb136535a1783506a9ee0e49d2e8ad542f3e91ef69804ae9fee2c6ee8a7d30fd1931df09a4462bc0717bcf09c315062f9df1754681c8b26310196c5729b40e5597568ccf3878fb35e791bd74fabbb1534b45cb192753791debec9c52365e5303daf5abeab24927e42827f3ff8b76a15c688e9de00c413a49b37bb45ac8b088dad1f32bdb1fe09d9cce9a3bfa9a7cc1aadd499f3946252cb32a4324ed9af37d361bdd64e5633347877b35c74ed6f7883a5e4d7037c6c6611a2ea863d12c942ff95a1b3b67c266953fbe6b309de1da15b9a8feccc9442f56501fe681cd3f9bf2f7aeecab59aa16206224f464c24da52383689e0acc97214198f1e7f8caf8c66675cfe50d9eeb04cf8bd0153862eac20a458c1172ddc7b23e583016037153f6af94d621140faffc231c3551c24aa336ba94ef4cdf9a1b7f0c1ad70733dd6b7ce2362b0f076aed495d792aeddb6b756facefb2eacd913e83503533e2d050562b080f5d0f1329123631a5cabd92123596cb510fb1c5df996758bd4a26a421e1ebfa9ba4620653ababc4ab51c7e47b5196878a15c5481c319c934dfe5c41249673d4c056edb7c395782c907713e253cd40e3ef2d01d77a8eeabc6b38ae28c58d38e547403b58eb0e0f7be7a5a348376a00e720d4e04a2d4f228172303f1384726db6cb7c890992d22aa6b91b8ab7f565b9e4e185d3de60ae6e80317d4a8cf84cf73b0390d98d9afbe390f3afb2649b5ce9e480e55cfe8507e6e0362af790ace561dc4fa430d9ad456a1d01b54f7f7ee0e791563ece9ee67adc3bf032e3a8ecace2be4353165aafa4bf47f80a18ad70d4b60604cc7244fe191c2d15b1bf5130e82c5e8067c936d2e62abc3819dde39b19d65e75e99e4f910f9950e503c79b31528ff57580d39aeecea6fd3831ec1169e450f8ff5f5d83fb9c2785f552c9cd8c48dd01defc34eb62c2bd402642e2361918a40556f09a0c240c580a99a8e1abce49782565a16eacbcf9df19acadadb4522e3449ff3914aead9fd1c474a6296a0f507e05a92422b90835c5804870c280e5a75cae18e2bf02e2d0edd38cb534c753723ec4f44aa305232f6f4996bcde08886ab61f3f5b370d318da2b97d21f31852c66a82526b070e07d8703fd264ca6ac912f0c91852850af5e4e66dc87418dc00b56914c7133678c3f409b66be91a818128759d9e0961515a53b913a2e2dfdd318d40b24d9781bbe20dfac962a06c4f1ab68f696a223ad21c82411a7e0c1a739b3da96bd8ccf00b8f962d09e6963624146f0dc89f45c2a5692aee7b689c0f62a4d9278fd5cd8478104b6a397df38863110fcccac853e0bc14085fc0297089ffb568694661a643f5b855bcd46ec73e08057e18301280506a23001177332395b564d6fdc3c559ee5140d89615deb93695b9bdfca0d23fe36f9d2ef22137787dbbbdea7ac24fa31322afb3bf7eb57366756987e0719e2b7f14f8c0faf9ad0e99c9757b23bffd477dd55bd59f84182678b717c8da0c68eeb6faea35b2ad6eef522aec01c2fbe4ace2af39a5bf99f63843b112c89ff6ac620068700b16399ee0f05455ccd14c78e45fa0e86871a12f6120e3fe856d4c0b69bd461a4779618fd6a6e45afb75f83a057dd910b85ada677573fd33e7b87bb453d752f33c6cda2b5ce94f7e313651389e3d338db5634528645c302584488cc9579bd57f7d86d1f8e0f4394920f49d7fa5ec8507b9b79cf9634480baadef0fd1b2902753308a1770e9e09974448900a79dd48f2de87860250c4f531a99f45148def966c3935a992afb2a14366a8c301b8ef4d14241b63ab4aa2fc6a1d74212e1f88bb53620c4340f4675692d1d21000771538eec40dd47a9f8a5a59c64e98b78470221a19acdd4a8fc59d661e198024ca78363520af1b0ab8347558a3c2f50c22da2e87fa75228b48c93e10411aa076775ab3d5b56077ee4deffc300ac2c2553bb79cd755e4873623e5683cc04a1116cfb5c6233b36b03f4aef8f7a5395bbe2a0be6035c70315560f362459a043f9394a11a6940c172732ceb3274295e65952ea6542431bdf283d1d842157ab4ad6668a39d4e778a9919ef16d2715b6a898dd954a06f082399bc9eec7a01625fe89bb4b716f6f5cd6cbbc2cf2a16a94c3d9d02cce438947e546641d580b377bbd7f3a1028d0ea9d83c90e5e1b374b6f823c69b10fcbc25501992c9c4a89fb73db5c33d0dee0356a4bf1668ea4cc159e7b0c3c1cc973465c237100353524db1f83ba34ae96405a5431384716f709c0d1b8048523695b2c95178ab0b916e3d4335bb593a6a26cc72ef018c496f7f0dc27a6df5af8362f8cdc547b33d17ebfc6b8e170f32f16f50448bf9f9e76f328e12cece0f8a47f94802a0492e8fd7dd32b65feff90bb957242344f69ccc2ab7eaac5118c494d28f88e0c65feac27467931f570aafab05d8715942c2d5060e190a4d328b69da7221cccdc501432682385a8b763b553c032cff3b1db70570fd2f2969c30b4934106660c6f35a5bfd9bef813ca4348be794e3a56e64210da0e02ad87b012e5cebe48f627f2303137781b6a72308ec8d3654c01beff3e82a32ccf112b655ecbd9049255ff227d3457298e5ded0685083c501d42d52d1aa2160d5e570bed41c12c97be0bbc574d16a22e923e5df71f231858704cefef707685677f50088f03b423df479e19eb3d457eb2f69dc27f043396f1dff6bd710bf0a19fdacbd1de6ce805d0f988961296a7c1acacc7d67ec3eae56640a72e75954b8f4aca052eff63d0df59e5e4f8ab80b516f143d6fa266609b84ea4d18c02f7db6317d0467ad7b841c679c80ffe6cadcedc9fb975d58e86e1ca29f902940106b9028f39cabf7e509ae7f8e6bf788fbaa333d7d942ea04203e28d8390e7e9bf4947ee9f422e2431ecc192a4e81f361d0f449c32c33f767ead6a51f5d6c81276e566ad99f236c48c794fc640a96f82e5846ed40d85c6166711758ff7bdd3d11b57317749484b1ea5ecf89964b115d0a6fb1942593d86eeb679a537689dc453f6ccae6e11179e571fa2760b779771393625f32d05251e5434d71b6200a9457cfeb78493463a7afb0d49011c2d0a2958e271e3db557ccd709f98f67ab7c3a036b70934da31c52cd28f77fa1146c4f3dc8b523d00a742b22fd891dc9ac335a6d4c01f3ac4acc461a1ece641fbc8f05984c8e15c6b8d0b5543ecf98b5660b9bda83cf548f4ae1815aa313fbf5251b96e552276983e44ee33374594354115731ca79b6ae3d9fa6f8b65b443689c5772dbcee435bf8b2c5779e499f52d325415f5a49452873684aef0ef1fe735b0c4d5e4312213c4feec486b5d5223d02d5db94c2544a3e3af6dfaf9b2927492781dfa10dfca59a612130394779d5c14c10fe55f1242227a75cdbc29459c78fccff79e315fb0084971d82fb008e71d561f7fdeba451427cc58e8ee081a1d3ca2c2d5559f719e423c3fdb7a153eea281896fe2f0132514801cdf1212b5628a17249ba05bf4d5f09012249d08b2a0932ca8f2d0637e06a22d76ba6f24ef9ef2e9b8ca21ea069bd166759d0436fee946f96cbe7754e747f18f0f1732d32cac9aff05732f756d6391716d7636ce96e970dddb9a06dd965246fc85dba85f9e324f4fbf31368a6b1e2bc38f0c84f068a4658758714d39fd4f6ca32e581ccf390fe74827f9844629bca865d10cb52315ac9e67101729aaed2f12b2d2c8920529ad208c4a7113ed4b545db58e88c93c7292479eb23f18f6105cae1e660eb496e91b394364bfd111db19ac73e0f91eb50206b91eb021d3a4071ed133847864396ef28993e6095d10886f69d364256e0c83669c598b0319dd10eed9f0dcc28b17d330d3600a6b065ee7cd664158f4f23826fa679fe3dd8c3cfd7a15c9a5eed875596036c22eb97b7fc8ecf6393d2034ab8307ea037ba0a279de195754f63e00c7a717164cfdb7657283394f6ce6cd1c2a33f2664f9e4bfbddcf88e73e4bec2b56a90b7964c8cd7539ad45d87cbdaa9f69981525fee6bc98e601276fdccfebc1d9828d07ebde6d472f91727a026ba3d4e8eb3c758a53828a09c021bb593a9fdf91bd06c2859b746d1d25dbd2936616be7ae2499820a4b7dae43bac3d4c638a55d326a1f22827439b3b9bdda6629d5e1faa4d9d81e25d38d2a63b171b5de42b805e4855c6d115cdcc8880b0c152388ece9a0475239adc858f3f4cb7cdd08e83fac52ba936daf2c905e78f0e1bfff4e05ca475c65ba8485d2a91379d9edba2ea9fec7d5a9605f502c150fc7318b8fc1079a20c4ebb6e93fdd879502b9155631c204ece44383778a7c1c38166e6469c8c1b063a9fd6ed7012c187d5f026a0784390efe7234ef6e8ae36f8475c7e3f319138b750a4739a6cd7efde75019742cd03ee6fe77600abba81c3e7046d27e9622fb19629f8bea1aed1afdf62a82092fa9801c9e9df4d29352b4da137a56ef93416bb328daef1194cddc92be9125856e9bb845bdad50d269fbb1277c835b0ccf231d75c912bf63be30f69e84469a020dc088c000fd200f79f5bec737cde90eceb0a55d369d9b5caaf34733138c034b915d988b088474939f1405f70bd2bb4abec07b474e9ce07fd592777b977b127474b9d9593645c3713938c25102669acdc393eab0a1342c885456d0846bb212e3373aff0d6e0ac60e54167cbc9835efb5ea9c63686ad525db67fda4bc7e27e2a07e9d84c2e6336ab324cc8a4348dc8060320e535da670ad08a6e0d60e47fa1bdb9e6f0b5905c4b464c34b9dca395067c0f7ed3647373fc056b9ea902ce9d2ca8eddf57e3780b998baa577baaa1f5a4421049dff5a788965450609c0c4ffa95144ac6a87a9c4aac4ff3438fb5bd9620522b0e05866fb273552c80d4c207df925b0606a79f504954c69f3485c8a45a07a7159e0b439853a0468a6e017656278fe61edf41085faa0728486a90177a5a1ac06b3eb51b623f4f36de854479f8725aa4cff149470bb90187614a329a0645d4d8044e86f2325dc6a1c82eadaaff3d410f6df2f823eb761537d544135af3c7ee35f7ee4fd22ba9f3e3a8a6e1e962ed750705c3e1c05c67d55213107258447b1946d50663576fd382eaf0cc73444210cd8a0264d355e8960fca403f882620c9b1530e165b626832fa456c7451c726639c791385050a099fab364ee9dcc94cb3519c5543c09f13e3b93d42715768d761b15bbaad8ba0fe7aa39fbb02044e3b0783f71a93c81d4ddf20c7c0bf77f0064b09fc00893d87d911a435b56cf3a62414546eb135fd2a7bcae8d0ef883b20e941ed4c667fc537876843f8416d6b5f2e98ffd91df8758d1931e51a3d67c9112c9fee6fffe6ef7d714c10976991ffb035c80bfe2446071bd2a6eeeab3b1b3a6563e7762283dbd7174b13e55330bb20721e9ecadd70c02ec0fc3c6f3ccd565a37f32e65128e68df6e94dfeb6e4be1d137acea49e4c6c749c43eb9364908418d79abac85fc4a68783257ab50e369a0bf8b289e6db5c918424426a061f2469749266195f6a947a189307c11a31b96f6a80220f1d318bf5f660cac9ebdd8bea2a1ab2547d8d61d0af65f83cb82215b87b27b342e7c87a3df8c49f7b3031f55361b88fba8f0316510c7d8544fa927bec9e57900b3057dbbe5cc260d12a00236a127cc97f720e44404b6f952be41d684f65649762c5260c5adeece6b1c0e4e79ae99b53cfb4e0958bb31cf86cb2cc2858d94e3d0c22b60b3aae5529bfdd5b9e29316edfd0da5ba9a5bd848802181c9dbf0395c21687c80f9bbe52f3292794f823e72bba6a207cf6a471ca85606f29c9d73e3fb0b3c9026cbe79919ef3e6adce3b66d80778e106db5339a3ccb697abf3948def5f9c2cd742aba66048f5d06133998293f737116ec92966dccb9361f43002f5e0bc7900b50a4a19f1f2f8b7ff973c37b396b70f983dc59e406837930932e7e90503a021bfbadd2a6a23f3313b0b21bc4e7f7eadce2ec449bee2fe78696fa0ac46c92c49bb45d4d3261570d74e3bc8e8ef3fb18a0ff84064055132c95a5e02765ab40b54b8e2933590b857132ff434cb5b19f79a7052db89f84903bb26959a7f4289c36a7b8f853132eb76e249e77a26493b7d7b77b33d9acd39d3b3765ebd7594b29a98a4bb92a12b16a275a9da3ea815214e38a208ea0a973288384859de5b1f9151ff9a1bd8e200d2c560b8d4ac6672d532662f27bfcda87faa7d62254f7a2d8455dcef58add02f14e721e0ead513f32ec5a1e8716d9e6be7a8893c2b7a5ab332524e6f1ba28d972c2d543a68aa777ffcaaccc4c11c384bd81a8fdda359a424036d6bb1082910ce029e5f449d98aa439a6c3d05ca4e7cb5e3ee3b19a0065138d682b240a56ab4d528dc6ee838c83a28c39fa38c843830ca9cbb80e742b04f40b162223d9820742395d5615918b4921e8ef23252c1f88b634facea4eef01d53239e41a45123d14abb7f7e07d0c0ac9154ce81ad6967816574489c09b9f78ec2d55706dadd62a6bc79bff17506bc93663a3eb0335027d8d6472d8244fd33bd522fb71eeabf79598eb57febafdcdab32572db77e79b51012946a4f6fc5856804393b1499236335343b7652b89f8723ec34d81f1cf4f2ab90f08a11f62f127c2773d3ab5ff65c01cf238f8219e8445d23fe68e899b912ecca5c60a82572a7dd11e3e0b8aa9e1f3cd86e16020fc49a8378261618366e5c4b4b4c40e9faf48daaff2272ee3c928a01c612875c732bd646ea84bb661d0a515d6e777b16238e6435c2a3fa099fbd33cc6b38f4ae56537e0342e1ee51fe3559a22f1ca809483f8aeb17fe9cbdb2ca91156308c98ff35a54e7417f8239f3789d9e9bd3c3f31a24136dc0f1ec6917c93e9d04fc84f91a955db655883df170e753edc26feb7bd71566792e909a8a1933124daf6f44ed0e26459e5b143f7bf6285d002871e299b1643cbfae453b2fb511f15d39a12aff19e569562a42ce8359be6db70568267bdbf18851d769c94d5c0d9f82b715a5090f5b1cc8cad484fbffa2681fd9fc0b9b2da5be4c404d7933b95dd9ec628b5c2aa5d7a32210bf4a225a300809d340422164bd8ed22f906060702438e8a3c27ec6081e0209b397ead1bf53978b4ed27bd4f0f988bbf168acf62334aaa5a6b9f561826e80b2fc3fa4d6dddbbb2b3f48913eb1a12b160888359519f0a32bd2cf9d233360046c6d16c2b9c562fd164b3b483764f47fe92499cc92c840091fff570738171611c4df65ab9bf160c21cac8a2141433194242454a18bafbe1a5cfbf2c4e98b2be44b76782e58365a63ceedf1906fc95a24921c6e8fe5ea5531fbef44cc45c346eedca801addfb1a54067ffe1c517bd89f2dc33c59ca1ce59a3021e49f04e469c1be14a665850a86971c6787d33c9ef275b656b89d55c02c235c9770c5d9f9d89faa123f205eb69ede23791138259cb0cc627e813ddf155c3508a096dd644f34f90faf66f951bc2de755f066228c9878feceb11d63f119f5486ee1cb39127745e537b2674345771105c4d65b6ebe9094912e0cfbfa5835e62bedcc7f744e71135e15d93ffbb763c0e6830d1605c56569bcc64e1bab5b2ef7f57447b879dbe3af5042a9f7684cb68f590160a5b876fda5d7420cfc286ef0dbc1a5af734961b5d0de685425ef805a53cbedbaf0606a70940dccc15b3afa3b942ec0a30a3670a12b018af1f6d59d306fa0e1e7056f0b7afa786b013f749f4b2e21ec6bb43bc8033a99595da72730e89d95cc8896ab90417d672ddb7a2e73cb22da0f41d1ff84eefa1513109e857f0126e55c502c7bd3e74f6186635aace354db9e32f9a03e48d0ade95bcb1b384260b72ca28b5975189c0fab02de5870ac644467178a87285b0cc251bd3fbc47b19c60b71b1036d84e7800763459b8e854f638ae6650f502222025cd0badc6810c23c2205b0264feb1bd3789bcd7944f065fb5c8751f683d439e044e70efcfc51ac129a33c8655c84f7840d648c2fc03aa30bed81c9596084c7cd54f4ca5076b6cbf49fb0a20034885dfdb19e53aa82947d35de77b481f5265d266b5ccd565dda08c02e7d22990add12c68313567beb9bc2f4fb8fc14ccaa3e581446b0cb205b4cd70be6555e08c34e03073d055a068a1905f37d312b360135b15cb53617111926d6fff3b29f3c0d99e4155e17799d68a01f7fc4ba2864e420fc2d8e8de094d00be6bc7a04c4dc89877b2f6f0e8b6357bd440710caf45a130d464764a3d0c1736fa03ae0e4df2857b0c7413a53b098ad91f42239abeb193af2e8894d47bde502d479560a8779df31a6e49414334f6497c238a790ce92bc874309cc5f9710585968f3f4fb686bcc0a09fc23ebc68e465302b268d92c2e6b128eb15825804ccd5fc0a93aead1fc33e165c3106ee141339534b79b2be056e5cf255c3d5aea00d818ab49b9c6c51b620993019e9b21f00d7e5966b47061074d6c017a1ba95fcbcadae4bbc93a400fd8564ebd2ab6a77432743e1d94610cd86485d5b5639bdd0e4ce5429c9216fcadf60dbe29a8d4bf806559974c2f3c23dc49edbe0e92376d947094a6de3a2119a815ef835ee6b3d31bfabbf5181d536010469ae91b774fedbbb1e7c893a9f3e93f4e0ea11e35ce518d173555b3ba0a9122fd19d1c1c00e3a4bd294cf76afbe8c795e25bc6b56c8cf0befb72440e4a236d564dc526c4a7ce46ff6f6e9f02ae2a327dbaadcc23ff47e7f5a4a6cc753f18cf32677cb82b9a53636c0bc1df2611f4a699ca5e54a56b8119f3a2aebc27e4b864cd9694dfeda88d210dc0cb40041edef5fb69d369417cb88ac91bf5a5ff0f43d82c6b3fbba8d309cb538adc8a3e6be04726356196a2ce67900abb19f54f53ff292d9096d47919885c8635425fdf0003bb2145b5ea3af47b3d2001625849cd102e6360ce6ee852e622bdf19b07779f77c717866cb62ca2b838d438cfe027cfb0a3983016a49022f8acc106475a4a57fa728b3380846923ca912ab44af9bde46eda9cf0187233f4fcfcecf2c7544395fc2b87e14a37302e1ca6379ac00cd079dd36dd5d49fdfb763f491e84fd63cd4057fe73b9a1d7cc32abb648371d6853ba5d1299fad492c720a1ff2fd3b8ef128d76e0aed4301cb8c643ef245e2db1b5a88a3bf8f7fdb8dc9f0e4faf5ea5c450ea3875824bec57249fec29c393ae2ecc942702ca73c66a3c8172d60177306e38588d2e869e9ede42f0799bb0d771a5c462f1eb6ce44b56ec6481d5fd0ac53e09e443cb43e3d3398cafc044e0b081da667db939024f473e4159d5e6a9a8623508347bc1f8440cdc71bdbfd5eccfea58094fcf29a4833a05ef41bcbdc9c99f7ed2bd6cffda1d86409df91eadafd8209bbedbfc11dc91a42f099704f40c94735f276fce738f35c09057bea21bd12b8fc29e2b8f6088af7725527ec4bdd343b6c3f6fe785fdbe07ecc73c07fa83bf3430e056c751d70ee09566500ed67bda5760b749f4c5d56bacaa61a7c4b289437545b01e1b6520f76c5a71932fbabc2898a46833a56818955f1cfdde4a520d7cfdb8ce2098b10e97835f522763258ad347ee34b95fdb7a014e8be61cb667a8137f419124774855c7410ecc3658d0cbbb6f0896b4e99b699d26f3bae695291286b80ff391065c749624e786187f42e7f67218263152a421da6da54ff9ad19085e98bf36bf04284da8973039046f6f4bb9ea64108953d61ed54d1ce2ba1dae651404ff8badcbb06908f93891edeee44f6aa41422bf6f7a99d0c4a1285669e2f8bd3ec89869e64fa274ccdd91a2277e9adc71f4cfb0c99d1f6b690167ea99d0d28d45ec61eccf7d935d967d2932983379b2d70218a4dbc7d613bc93cb30176a4b3f8a72c1f296890b915893c7c4373dbfbc4a447880c3af1549e851312a6f44b76dba19beae064181dd128f1fd54ea7c16e779d8973e83a46bc9e2ede4f67d5f1eec6a53331ef8f65dd3942f1a5989bdf1a6302d90ef555a0ad81fe62d206fd76417195176581f74f046401bf6e49733e58562ec0e22294af10b84606f0935b4790d4a4a06171cf7a66ea9dd1280c68482a51eea620b1d2b3dd108534db593b35e1d85bce24072084421afcccdf6010188d706e044dffc673f978bf766521a319a93280a21f731e65c36d02ef63f799a20f2d0d279181ebeb768f87abdb3885b446ff023a6b925969158c3e5d36dbfa247920319658631fa16a356c6a4c45b294ba62e1a7c68e004155c34892ded66f700d58c92519a3bb564a850ccca6f552f4bcca2ed56c654300ec67bf0aed716855ae30577837024dbd390507b14aa3f53d92e398dc94bb0273bad035c20db7a51a28dabc38b694b56d3466d7f34afcba9ed6955842f5fc3a625bf45289c75c06139a8b359469aa676fb5c1e2a3b9f758edd3e610062516d07d7510ad0346201ce43d50093a366151afb3e449ab4865cb233d1a44b9ffc8b959804caa4c33b416800b2b8ea847ec36e20e4d58fd413430dd1789abaa278efc5b9555d2ea796d07e599abccc664d9e50bf5e7de8f2f49cce255c0789a31e63e64d056436c0e6c30bcc3b7137cb496f855640411c71d9d674609622f65e06b36220772523b186a80fe1c862c2ff1f590335573a5279844e86c7c566ee1239c0a115d4b308f2240a3a88f54f4f9def928d78cdba2dd651f2f591a95ce4a24ab9778657b0ee88bbcae73df519cfc6b810a6be81f21b81edbc3e197e5cad4811411674dc1f5e77e93a8c7bd3e05a98aafa149a5aba440eab53d52210bab16e7aac0c47c3e7f37bb54cdc6b04bfc1a2cdb68d5dab0a8a27541252846b8dab390d76b08702c24ffb337b06840a8ef8e4fe29e7706eb141bbbc65bcac6ef1407241ac81db32f8b32d380ebdc9e2ea52b27327156d6851648b7a437e41b48fac0c7ff20b904a190c138c2000ffbbf1df0345dcc905ae63840ffc46020e949721ad51e7ae68d114527813cf62cc9eb8dffff2cdda4ad93e194f61982649c8f2c13c7b637022455631d4315ea95799d174e0cbf815264e3845174aabd890f92ca9a7f8e97f5c728d1fdb25b38733fd0d25a0b909d05d05715091fe32ab2cdf69bb73f17d2514d3246bff6c4e43f6d801df4d399b05f416b104ea8d483f1a1f4391b1ef0045a69dc5d92cf872d1285e1a7bc9dcf8d894172826c8171cb894c950334f59ce7ec2a6c61468d4181f4614a2e82c0746293b544681d06bd5188e19ca9ecddd5d8af21da8d165f7efc34d32ca46af1604bf9b4a1d0f693ee08c2eb5ad2cc8646e7cbaf923834b341c93f177d9d25f928338fd1373368776ea5c9a47e69377b3e460b89360a1045309268a88696c99fdcbf0fcdd8518799e1979f4b61722c17457ec90d58956605e25994650c7cdb022efe3538d00066d4434e54d4378c5ea2ed17621917dcd74bba592787d79e7791d63baa2c2ba69edf79302fe471c4f80b1a5ebf64b69df7d2e5c01e655e677f25a5cd4ad97ee9cf1cacc4ae16f5a280d58b7a8dbe12ed3cceddc6a161e9e745b7c380b117a5955e3c5c55cbab1158a00440bc94f6443dce8b277e2cbf8ff7d05e31605535b2975de38758ec3aab4b92f0345abfff5b5f549b4130e58cace859b1acd57c9b25cb7e5d629131c4c09af830fb8d882220f26dac5fb2e48f2311568daf95b923147dc983c1c0994f1a7fab53df9d0cef543488b069317d743d5c729df54d1dcaf24c8822e6f07eb0bf68d23212563efce0cc7e778e493d698b0e1305a92fe943b79f2a8a31be7a6415279649242398fc12b50a9e7a129386e31deb4222b72cdbc5d687cf59ccf2979d42caad1c747fd3750b4bd9e7a287b35eb574f5ba27473477eecce7d8cf5ef6c4646c6fec49edb5e1388d1494985f787dab43b16473c43778e622e200f428aeb6bba9f696c765bb7f9027ae9dbc465466fa3520ecf673067ec99876a510dfd085b9395bf2c176ef7991dcca02a9e5095966afa74c841f780c62b202a5761822dbf5359b02f3afccc8df723f0bcffb86fcb051eac92a040add144d3cad325459884d42bde21edfcaf545bddb25c741615e5318402cf57dbac7532f29ef466b0aa9e4f61dd9169339b04710c1a7e3a8d2eb04fa6fee21c513a6f6adf4db46eddb723b66118e2ce6e38db2925bada85a83cce36481191d286cf7cc52a83ab6a019342fc6457f51a2ed636e81a425bfd0619f1f66519410d68778aeaaeb58075e4b5539ff789d79b33d2e3e5db8cf449b6218f0fd780c1d872375171e09aa84b43322605668812a52fab1e5c441a42434185a5cea45256cfe9132b27c511d4cc0d09026826bb7954151047755db36c91d88e7ab3141270cc0d39974e93697ad79701d76a18a7d24484eefc898943341dabcff3fcf0471c07cceb8313bcb9c840b12517d24063f305d310b39b4426926e4dbfbd1053787d8d7dbdd68e504012b204009518672f90f3b037937499d8b915523c32690cf36e1df42419d5b4b13dd8280b99fea4b965190662748f3f3cc17cbd0448aa0baf474505d9530857aaecbb92b1443955ea703bd7011278970c9d2c3f1d6ad9d06d63b87631cb056b2bf170c03c22b4933b8ca2e23a96671214af4eee87535d0d45e6e1278f256f23404d88e9b6ac60d9a5b6b1a126ca0ab1ca1d2e77787066b9349285f6a379ff2ecab2e757e7cea6733fd596edbfcb193f84ea2aac7d8c5fbcae19fb0816458fde2e1a8fab00a3bc3fad84d44df085e7167532e40fed16f637e8b32f87505535689ddc0ab290e72b866085233086ef9f05cfcc903fda21c202164ee937c78b3f69836d6a2ebb86c2bd74b67344d9c7a336bf22adb3b68e2204a7e1e89d2e35a9456076cd36d20a8bd14e97a0c8c2acf5019234db392720ac4afcf7ec2ffaa3fb66c76140affb330c379efc57c0260588cc29a64a58e74dfbd32ef0b1aa1012b8dba160bc00b4f4240b21a464382ee8c3dd07951215be07e7c16e39d8f043517ec7eecb02b1293c08e14bf8c548a751ed18a48dd24fecc6d2082259068aa22f0b25757f9c167329c7ab83507a920381d08f26c51968f13895a8355a99d002ce09d49702f1d269540d822decba6bcb224cff6abd03e0c0d944fb295b89dbcbe2ade06149cbc57a9ba74f0c238bc1f4410458feaa08d2f70921339d4a8713fff001dd5cbe6d76e0f9b038efeb0a02c987ed50fed752565b1fb4937cfdd882a92490063aef7fc7948d174e75d69c9c8e331ed97f5ec82fb7e2a1d976d9ea2505f97168e6d24a7a7a66e8d563100b3eaf33b94e9af46fae081bc38a63318ff953e114c5b57d3f85aad32fbbda5638727ad7367eb04c1d42cdce383fa7110a0219ccb4f78a33930f4f030055465691ce7c9d055d93da1428f5c27092dd1748ee831b1d502820388ead0ec4164f39d31aa1929caf58a45a741fd51f34b3c400c4e6cb5dda2fbd38b3a57bd23fc6bb0ca620d1c6dc265dec2b4095ca89deff3a33685bc77ea53748110dd64fe68e30ab9f0f16439646e44f6bd7ea459645cbd3bb6d2f8297ff476f4ea14a5f6e3b8191c62f625d350413de8cc89a615e6953427caa9d65e23203455d1a47c87daf2debab0ddbbaa5adbd3662fd713fb8192188e40d48e7a6a6a8fa9879f97b698d1b979e48f7077b649f3352a04c6cf39ffb7d4934d6523d8a83885846c6c474fa8b694399c17218424fb6734d52544f2ebb565b35ceccc6e88f4f5a6924917508804b326fe43acb48db6ece232c299fd9064cf35146eba503438b2b00eb320d12a22e7c801ed110e2008d9139057382ffeff2d095ae0966af5859af7874167d39bc102d0f98529265abb30e45c210f41cc0cbeb1769ddd197b549af0c9882cccf316c9de41ecbf9f9a4951420503fa2ed6b6dc2a7d2d2b595dee8090e5e98ba0892adecf502e729f29e1f1e69f471f120a22d9d6d1023a2182d7986273c4c068797f06d2cf024d510b7c6c0ce20ce05ac20841375e619c0d995fd6f56fd1fd424ec487ec0c4bd20873b494a4b66e619b5021190f1765459856147dc52d16db73a089e8125609ffaf5cc4d360918d27247cdfe8926ce736ee0add776ca74792393f34b791d7f300b345047a8cabbd8680b56447ab5260de45b6afb46280fa6c18aff3a6cf1cd3075b2d32067f8088af09cc2a2ea22ddcd0f4cd54038db7e74af79a7d61eb3e3064608f78f54d2b16ce657628cf5014c5ba54e46018a752905b3598674ea2c824af027caaecd85f5a9ec107f39b9b8a53e96d788d8b7bf98643497d091c2d5eb15ef547133db6a9b930530ec80a6480bb432a674063f0448c66aab72b9539c80a674673c0c72b74d08468b4abaf3c5393d2f84c64f882e0567ee78af871f68bcf13a945ceb5ee0f8e1d54a7fa4469062da762b8b860bcb53baa9089633e1e8d746e2a8c39a2ee1927ff2860da22c0df40bbf851d5c22914514386e9a5effe5514a5d54527cf2e177dd782c23b4b405afd676d66c50fd1a559a0951003c6003c0b76737409e97bbbb1a3f7448d0bd7ceb31d5f75ef58eb2b4373d58633f5fcafe7c37f400399598f74f0f7dc9ba439a77839e56fb974bccdfe9f912ffdd396c2ae501d464b1490ffffc60a8f1f6d720559d13d10e24be436aaadce2a8110de28a570d1e6ac54b8ce9821773dff7c0c0bb96e2f125e823113f6134fe7414fa4ed1927545bcd6b9029f7458c8f0edb599c43caff0ab85d20e91c87d4ceb89dda2e10828e43126a043695faf713edd7e787bdf08c24070ee51e3b69d55c6350f078b04f364113a0310099c054d8943f4c528c88963c36db0ad0aa5411c8d66adfa8e426c2f19bed2d3e29555c358588bf6e7f381023194fc87420083dad238255933ac5662c6048f61aabdfad9ac003aebd0580fb0764a8698427faaeab8e113bd20b632dd0fcdc0e949ee90f860c65b6e3fbcd80ce01ff902940107b9028f39ec9456d6b285936d807e8bd58580e69ba921c978d865563f219afd0daff6f23a1445bb5a89004bf0b0c26390eedf9105646210d64511de67736bccd20bdaf3dde53e4d5685464ff2d06544f2f8cfd198486392035668df08e7fbadaecbe7b4834acfb9d8f4d6b7c7a1e26c6bcca4d9dbe0fb24086ae447abeeccc9792d6256f9cadf0a66f5c2f236e91fd635c087ad699dfe2246ae1754c66b6b7bd34f0fa77f15649ed5c741e5d23778d458a36499bb4da212dba932240aa6deba4bd225073ded07378667963442b515366ae3627ad99284483834b871ec61c9b615744f931e540c906997fe64651ec445d572cd6ba4a337dc752a3b0bbaa12cad67789733c8e34e9c54945f5208a278ad702c013bdbfcdc0e6a44855c6a9a48633b1260718b9c5e91d761f928f31c2f500bff3db1f64fdab3628d9362065f191f69078c796394d51a330163ba0941694de673cc4e15dad2142e5d3558cf230c171761787a639bf7e1d873b79b2de6ed11eba453261f552df6146855161d5e4ff751c61434a8d6fed765564e43cb116e2395545ea3eedf206df6318ec3a5398359b47b18e37cdf95358ce6c69bd73fd1f1c41f75271adb0d3765c76ac7a9d14a562cd2e5092417c7d7a4f2c4f5f12df903869b176e5cabea14a3f4a9a1cd5395fd4660ce1781b7eb4d3396ecc2c3da840bba7313622a9f2c4c7bd6472b06eda211cb8d9f418d2656ddc45b5905d0607c9f4dbc53fba7c962f2881ea5d889bb4c32c5df635d9b0d3f15eab340b5f9dbbc7fe4c66cd903c3c17de795e5d24a5c89f455435c7af2dd0c219c2870dada0a4159b23a52599e52870656d0b7c6fbc27fb95da42e76d1f17bc8f3e5a7e06430782ce625d7e05a8913bdb18fc4b57078bd963a8568c86e67d50239dc2345436f5d13dba140f91eb50207b91eb093495333e9bf02330f38f7170c7f0af7f861df1439a64a7903f97c3919f22e37951b93132706249337e26052568e0bd1bb4f2db7ac938e2c91749e96f7b3f78f8a6f1bb4d7381d0dd9faf97b2579848361b869d1f545441b4ed6fca7d1f14633f12bd8824bff5e418d56669ee45cd6ffe55a5890bf8813f7698836903ad9e3d3f0e2d76f14af51f5784a1a10e7d6333b0ebba806570c06c8ccf2628a2fabcf9a70276a56bbbac86e30d47be1572937a3466dac23817bda53590a0ea382155d4db93b4df041dbae76baca9cbebd96d864264d41d16f9e55458a87e510efe5f0125612e47b9cf58886a335315a8241bba771d6465043b21288579dd872de1de69de46cab94123fe0641d74a5d40f28388b229accbf24ad5ca6a32d39aac363c7b032681ca93cd16f0ce35463aa959786ce745088b96f9c7c9082184fab8f63ee4f79e8f6e79f8d8d1b5fba44ed6f1c3f7bae8373ad0bdd40709ab9f8fb83a33c952701f1e6df18866b63e5d717e0b0aa11ac2048de12a4efa1b2a53b9bc3169e0d994a8c05cc307730c89325f77a2ed3258ec99e2660bb56c573958ff6c4c4f721a25b06a3a6964123ae8246040c1b796a865004bf0b7ec326bd0d42f0d850fe75c9e607341bc5bb98936fe4dc5fcee1d2c820b79cf4b83c7d8cb93ded3d521fbbe4e862a20e5a8afe7e4b65dfcab228bcf26d94eaa0a8ed5e9a2fd39c4802d25aecab8cfc800b8f0e713be70d1e576edc98c521766de9dbea34e9fcf5d3b08ef7d467fa3873ec9f7964d8958e529be5eda90d784449e7ebbf2e2f586e56272e82306f6d24f02ab82a77d915aedcdb92757c9870bbe2300f82d892144437585069062677df7618ba98161ace7dc98c007b2c8632191da3ed40c97e2ea5df006ee006a4a45c41645c3c9e987d59b4c0391974fce4a9584cbb887736743e02c308519e484b2b7b28299a9d6cc9be73a59592982fdf8cd926af14ba043ffaa8a53a0714c9e1318565d7dc993c0e7b569789431ab5c29644604b6f18157c9416446e482bd674cd603a907dd1474674bbf61cee1518b86458ddbb6ee4a52487ade6aa9863577f938a5b235e37eee4a2f9cbb278bbe2328b837f2f36a4c9dc5fe07639f6c5755cf0c8f22089ad4ee4f28599a9fd0a3e91c0abb2ddd6205a209e0c2f0d31ce4fe6fe81f115c7aad77779fd80de3ed9ab0c4c212511279b94c2bce80ef4b9819206301eb1e0967d2f88bdb35fe373a014e873da0eeb6c20bfc2aed1739d639506c2c6f0d60a835542dc83568f3f26a4a55fdafa525eeb5991b12cc9a0d58ddbc38dd783813470ed1df6d628fee797d93ac2e02524aad3c7286cd3ed569c4ef96a98b8c9ab6283d6024ee2aead535ec1129eaf40e64a5f8189175612ee1c603a145419ea6dbadfd578d073e631789f8eb047329666c54f4ce43b61106ad11698e92f98922530608624b4cf7cc4a5c30540e49db0fd3932754a9216aa1d942467c2ccb30e0714ccbd6d352c2b6f103c3a9552cc23fbd2035168d498e871e4a88f822d8bb3ff0dd8d5e89b8a32ee9eb931d29cb9d7fc1eee76a186e63acec6287be7b3aa63043c539bdf0c26b619a9c7c29c4e69d7535599c159834aacf47c101b9e77bd6cc02b442e413454caad8904cd9775ec107b482d3f8b6106c9245f7e491a4f4ecc0d3934f25e0ea19403be34f150add4f4dd653af55b27861864073f8dfd63322f9d2b425ed45acc7e487200700f4ffe79c8f0ffb680f4ad40cb56348ce341b0610c4e3033f017224fbb7b7da1cb4845ac9d6fe790c5725fbeb39b9f63cc9534ad37c4bf65d4d63ce8c2d8944d46ae2aa90b41e71072eba98a157cfae71d113427e258205a34ad1be67a851ac70dba4075b9fee7caf0a0a39a5ec7c34c5ac10ec4e07608ea142e40e2fd22acae2d4efcff6a9a0672b0dff4cab6ebe205ed740458f4a4c66a66e52d3cba80ac08b2a8e53bfaf4c8339c7dd53dc08f2c03637cd51a31d20f1da1946ab27d278f95345691d587c7d99eaeba70c4a61f02182531064fad54b88368e6cd535736d722cbe91557ca7671d617612fd2d62df2e76003173d289c00807f1ecee17712ce81f4bd43d38ce1e77ab6ae89cbb88a73c4437e6e12d1d00d700e8f99837c6e6dfa436d79e78cfd006b8f34a07b9e0bbf5c87284c3bb22e43cb13ec3d645a5cfb9cc4fc56da7ab7bb25b6e4bf3d2418c066e8191c4425fe87c1d19ade5b7f2bcd4f19207f79944391eb2e659b7567188049c6864ded5f8ab527a69f8811c83bab669daced814858bf36fffe5af78fe5df9fde5967a29fa4faef3fd3430428c0ffd95afff4b1d5e601970066d776b91cbb061a5a5b872a3607dc0f34a7434ff3bd2c599c1fede7c9ca80b205c583b4167691e72ab8e1fe50f85e47abf66f1a35fcb9fc566910a5a59b167ddef2d0aea826cb7a3f7c4c87c242b051d30e1ceca56f5d523a5fbac2f87b076a901790e6d6c2a9c38d02a791634e9c5f4a295223360421410ebebe294ff28428e4ecc687bc7ac996845c42b513e6964deeb016404c6e34ce7b48612cc7a4e772ba2d9b41edfd805ba3a416a09e02a773441041a6c6eab72c6ad1427ca85fb7a195863af8abbbdc10b5022fb76a477f76ee7468e9c06fd7b265b063f1c15999901016d4b01e74f5177271ce16b0a22a782eecf0645ac376795acf380329a1cd42dae3fd847f2fe74af0a203fdb0e02bdcd4224bcad0ee096c6f8f30a6d9d4c71104db0a3361f1f08bb5b92a84315f023ad1f4cdea79b4d3183686be612532a845d0e6737086c6056e32c9a610f669827e7e8d70936d0b049702fd58e012e76b5dc2ca00178e8dd6212df42464d51eb139bb139504a85eb447e68b458dcf56a9e6d547ae6e09df2814ce1669234d54259fca70b1f59e80fd9dda6e6109221816e303b9b283838c31ed88b3463ad0f8127feeb9178325ac1c612ff9889c53d49c8669fc42463c35799dceaacf120cb5acc2786dcf6f8f9621df4ff11e7dba1d80920602041e60eb0865ad523a5f0ed352fbfa17a72ba256dc8960e92f01d480f1f9052dde3fab49443b9d1d7826c71dd23b1af9354cce5b3dbb88f6f958e106d3f17f2aef00f7cfffeea9a6051672b38bb0d1945160530e4420508225c91bf7727ed5f706dd78971ce24db6ed7cc484087637f2febcd2ea89ea6cf9467fd4b38d4a502185f334dbf8bc563296165baae6366ee4c5cc39530063c734800afe92deec37e0536a30bbd1a9a2a97229cd9efb278244c97d07fd8303a75f1eb84277d4460ce51660bf69466a6ac2fa5886786a5ac5bf6d6e5b173ac65a861a37ee0c1348c006cebad26f58592709a2664e9dd213b7006972a8222bed120bd7b456140b4de46ae03d793d9305a0d4d115bd662e5ef51d9187441f33ecb87a49097d4c9aa83db9eb72d8e0051c155de566f4386f16954a5ce243f425024959db0b276a245f22ad0707b04b75cc766bbd1dc8a43f6024e0d48b47c7e34a60cb81438c532e84d77fafa17456e9f47c0be7e2a8506a610f1f98a7dc10f4565f53ed3e2c1dbbd33f9545b1ecef84f9619b63ab08d9537fadafb6e1810014673aafc402b1dc8b1e32e923a4dbe596dea110beccd2c1879ed0ff9338ebfea08f14579348caba49f788b736f19f696269cf5efbab4f3fd321d95ca2ed667c696cc2ccaa9fece1491a8503bde4ebd1cea89a3a44cff78a62a30dea4293312411ae73892d14a62ea372adb2481cc22ce455ec1dbe017dcdf0f78b9892374a7b71f7e051cf05b2b84b7f8b67bd5a24250d600245479116cb9acbb4d1c7657bb088e18c9cb6587de68dca9a4fdeda51df757bf900352c96bf07735f68b753fd0db773e8a7d184567b66c065594ab472cfe00daac187a9d4a67688a67d6da34e850e2245211812b589a9950e0777c5844cb7bdfa02cbc473cf9d04144086d52de6c3dc5bffd60ea260db903f6fc57fe14c1b4622e6a1cf1e21411b2cd4b82f94c9bb7ee4d20a57fceaad60bd807d3b0d2c56e5195b5bc1f24588a3b797c134b39876f2737266a2de98a097cab5874307b37ee28ef20142fe3cde096e727e82a8b9b7c05de7c4aafd1e2185882d2aa9113f27816168972a6e062ebd6c6f3936d0f342ce81c6abee4746eeca0fa7b11e6a3b5212930bc25060a5e13282a8b4f7b134244caba9cb7c170835aa40b67c7d45d89e3db8d3632cbfee0100ae939e4a2994099b4a6acfb2afc46a5e9d744ca25b648e36afd503d86964303836ce65fcfa86203a3666d7f371605326a8f04d5b86b5e215cba6cfd4c2f71416f6f9f9ad4645c670a1153bc5febc70fb6bee6bec1fa54c7aab4a55e4efd1a5fe2bf544567ba65825c82e74f81ded252675fc6e76b12f7d7b52c59f695aa7b5cee5609988bb17c8ecd1b73bd73ea52dcc4bf4a91e8cba2a549e8c0031918e8cb01856caa6498322ec5bebbbdc77d8d673633a02a0e1b2602355bbece6f104a2970f74cc7a0d127b1d1bc2ad3bd9bc99a4d34d975d8d33feb45542c3601c83074554078288541b651a9748e0180c6cf5ee149ddcd445b71debd2dfb07d018450d6bb0e9253f93ad2d7b96646eb8967173a0df29e07ebdbfdea508e271efc19c9cef4a96f2aa695bf10ff24352f77427049303640259f37862c16cceeedeab25646a04686a8a64aaf034527b381090c29ca89cc4795c12b5555b5abca282f9e90780e66c94707167bda49171f941af75d945278e38e6e445eb616c49d7891426e8a16c58b55595b12cb630f88f8c9a872542897af8ffcda007078d12610a24db47950187b1a96acd21124d5251f710ac7e6e1773c76f874852bc6c89653367f5cfa202c736aab830d819d5a70e7472285e63402519f8bacb9105779509dda77dc2b45fcb5b4813631192f1d94d663ea3739ab804a9cab8acc9c9e9ff8f55b40fa5407004b780e561784d8a3d73632097a5977554b405a3119bce1954c0f7dcb3d9f497313a94cbb75950ac67fa2d9165e392db87fcf7ee0316aed33b5f84f88c70938231a7c8ff5f032365dd428031b9b16638aed78a6cfd30ed5796468c1dcc004df3a6d5403483ff54f435b38f1017d6d48c15d3fb4b7cc31672a03b614c2a97038aaaeb39d4f266777f4729035843252cbf7816dd732b107ad3560cbbc4a65b21944926091aac06e374fed19f0e1bd33324e50d85305710500eec37eeddb51b5a59145e5b3b103badaeb90ca6880004cba1a39b237361ba0faf0b990b6333982150bd4c59dc58ae589f265c2dba2b8d6e4ae1ac508821eab5f6f2af3cb9329f87dabaaf50362b4758e5d664ff8029f8c1fe49e7f6fad3b8a5be6c414be834144673fda323e97ccc6deb5513d2efc8083a535af6460e3fed2031e0ab0cbfef3560ee8f99e27703a381f04288e377d626e335c0be44290425ac1e4921168a327778e15edeeac0e5ac71115286e0bfdd0a5d812d331510026f154b072a0330094cb66d16d2ab45fbbdfdd8f7b7a25386a5abbe61e423fa76d60ec949e63bd3671cb98f3d432cd5c1fa6ab584368e97ff3ec19d0413fbf786a47e6ae9ac95f679701fb3b25f1d080e656e7f8c4d8f7feedf89679e01921b3432fedd611be62b664870a1794f1612fd795ba0ddcba06d9662d0d3ce16597c61a17358cc0f4f695f5e615cb40ea823431ec3547f4361ed38469df17f97f22ab0a1af1ddd9a8d4e9ee12568ea87cd350e86bb17582221a39275d15695b2a0a245ba3a47cf30e7681213abac314e8e90059a4d3a1eaaf70b10aceedbdfc83bc7bda6962345552458cd1b931e13b5122b8433d7268ce18599353a65405ac41e700307b6df492aa3b2500b6529d8d9e46e1a1de7378ca988162e5fe2aae45bcaffd1cb0a1bf1364b06428dadb85dbfadc3beffa36e1b3cbe945dea89f147a1b4a9b84794b6b7c273bd8c205f57c5481bfae71f4e7b762fe52059e880450c7da39428d785a02088fed5f819e1b844085acac13e725475fb791c0a5c9c72a17627d7d38182f4a8016e710136747348c62128ccb8cd6e08c4eea36f5680f445970b23b7f617634fab645c1b0621f7a325a651b679450317cd4f045bd4e7e8b4af2eecfc179fa9c9256893126cbbacc1df5905a3333a951675483f78a463513f12e8f28949d05669acc77a6835c75385f43ce85fd395ea69646d8b8cdaa48d38ff5ae6399201d47071ccc63721a2e4abd489978ba72ff3ff12e45c94995bd4dadc74d9a41e9364188f1f43a619eee6c8a286aa3b347623bb25cd6f344b433b0bbdc3eeefe2af26f8deca9300c87600de4492cbe1d64376626359f8b94be485be23099fbe2e38f502e97f6eb3b5ce4b3984ff6e43afef67a11819a39e48d2f8177fcec9b6cf0df01aecc94beab7369f3cca977f1deceadcea6dae68d8015ca54ad4da4863605c75e78aac2dcb70442f0ac248f07d2bbe1446d6b99f60d889f1c2a820bc15dbf74b3bb657f175e926f14a5c2f771acbe06009fcec02b77c3481adc156d38684fcb82bf1b41799bf591d6ab66eb1b8534aba258ec282c948e34097fe875800dc7a8827caf0c52d6e8dac87becef7136c21866fad7af21a5e6d6a6e544a525326fe10e09c5e8b9469a093949da2d0079b33d0a0b372285598a625b3d82afa42dad62b1b13fbdc38cbf350382d1720c149d0954c75884714b5be084f7ef0e85b91ced1b318e719ff90ba8247da8d8d65706a6250c23662c91cb53b8547856d1798aa0f7c33f3df519fbf19f8259396e421e67045a3734c22351908da07f012d9cb06cafc65cd4b69ac336ccfb890910173afb4eaa11cd201a1035cc08beff5c2aad6feeec7a079099b851e41052a0255fa6f8e12c25f342ac73b0e58f3439bd37ccadced703820c46eb592199cd4a3006740c2cbae3b82b61460515952f46ab9c60ed509a58d658d3c9c54f1b1ffe8ea8efcf74997e4906d822cac7dff3055ced2f20810ed0e52804f8c664b126306bbcdb76add65747a31b771682e115d814d883a1cce6bb5c16fb6101ad557019b20f6a72ecc19258841f98aea46dc86a73408acfe4f831c345cc8fd852e214be8b645fd3fe1dc7de2de0ab658ea386a87d79cb3ca8401ffcd50af1166aea953705519b6322ef2712eff134f3c3c24af3aeb582a0115958e324864448a55a3256ff658d43fa0f88bf4098e4fea708cbb0a147d2a5c57a7e669c89c22672acd653283c5952feec596e202e388083e0542a5113d58e5716727b34483ef1e02bfded1a44d60a28dea1f75f477f1bb765861e6c00bf609f70d201b644df9a4d83e043186e7b84f9839eab5eeda74726f40e349957235914fd782e621c3dc20399d796c313e53b450fa5b6be22c5bd3c351c556e38e576097c8ce035114f16155456edc3bfe8917a2f0c5edc56cce944e3a16f2f7f37108331359434c84d9191f8d2c9dafd91a07678eb27760a8cab2aed8161e626776253e87c48f478a3876117d76a7900132a089bbfb0dbfd1a66df09a403debd5db1c2f6977eb18724b5046c0bdf00488d90d9dd38107f78e3650b566420e2d2c98aea073651416db99b149201f58a06795a1749a765dd5383fcad743eae7eafa908794f70deda2c33fefe1b90ea1692f070d15beb905df25216a17e7ae191d95f39d9060c388f48431de84ae46142a71aeb691bb66ce1c8f86f2d90a14b347bafbf69979c4c035f7647f61e8805d13bbc15a173d74fcf2978b4e89c96e12a174cc80f0ddfd505ac29946b2e09fe46895d9660522e10428926ca4d321408f0dd66a1c158e8a9403757099436ab1dea3acd6a7acfd849dfbc1923c2c922ca28b0a9ea4ef2108b4a7c61a309c051161555a2c3803379c6bc323caa5e14e3fb2c6601eaaf87b37d84b03c678347d4930790f321d46f977514ed098c43980aeb0127bf50f116b52de21ade5d5e533f12c2145413ac4a91f2de9f4a6ef3e0eb99fd239fc1ecc52c0e972dd8998202d74f85311918e9c219360cf755cd4cbee098b9860c270b4a85de46495f253a0246dcbcb0ec58733a41945a1f32ee6f16ad93fc94a167f7c210e8f341e366100143be32409bdeb74c27a26fce7396262e90e13ce08dcd9ab97d7403a68dffa1c24271d2c8d430f5613554f1fb481f5683a5dcbdb5e5451dd8d4f437f73e5789e4b89bf420a8c49edcd5ae343c13b94b606531463b51a7f4e04eee18d8150c2e0356d0b3bc2251262a91f81dc04bfcdeab5bd24b699e40be14f77d836d08826428c3254d2ea6dc936526b9b028c5322215d5147c3fc6dfc80a99b6376bf38d741d7de1e60982ab46a59f28c9f203e2d90220b96b3e21d02d3c8827291092a69ae38b2b17b683efb97035953a5c1b3d1108c96b45496a7cb235db32c9c84e1e6ef1b134dfeb16b1be656c119133292ed712b1bf5572b3bb43d3e7f00d82f655b29d811f0db46a4ae72e26b95bbb1f9254b7ca377c71d1dfc843daa7c3b2d89d6ce50d18330fd56b615cd1cfc30ee67402df0fd0e3be7c0b8a2c4c1dd97fd4ebd662c523677e3c87e1b271736e2b3e005434208d869e065a99e61ff585e3eab7f30f70015556d1b690a1593b7baba260b6478cb5ad8f05e9d47b2dc770d2ee890b14ce80a93b2f5eebfa734a2851f478b6239d5d7139370ffe01621d1869d84051f933795dfd5003b89377c1e8b69648fc0e74d875112e7d8d86e9ba83262f05b111bd53011d3d35612822de2339a24008ecae206f3873c6c4042d0acdf6d33bd65656ed7af93b927506c7d14c5d8c80df96841fb2064796944cf466ba0bd748c146c94485e50612a2d38fc50364bd23a5aa5ccd59295b9ae3e102c6a84493c5c75872af4048d8122df041075701e16d36418c67c79f2d7a5364354f6cc28c01572a9b17009fc254d1c5c054fdcd21f8dbb14dc31c8b1942e32c3f9939eeaa8cd57073b944dae543a171a5c365bd7e69c23d8bcb6a2861cfdff26354f9314376aea61c3e41ac5ace76492d3886f1c11a970cdba1698fe7b37232e57813095ec834b7a0b75e813b4e64d9a833597f92f16b73306916bbd892b6c921abe23e2826e4e3b69928fd6696264e583ed58d9b2ddb99c571ff14c02098fa941ccc6b014196e5f4b1e70ec57d98c49b3e03d73bf0a3eb8960b25a859234f48bc7cc1827177b45a1aa20aa95a94f03a1c9acc9eca1463db5eb26e9e382c00fd17c76427720c8dfcade3c899e8d362912c4904fe0fd799d055d13313bafc5e99c0ba5d3c9435016692a435453ce22f58a0ff854b715df8bda1551fefbeb0b964681c15a1651c88d3c1716aa8226d5895d69e1beed6162c112c7c5b6ec74147816f90daf6314794e18eb397d559dbb9a366066bda8f06f6689497875b83d46a43d3a82f9058b2213ebb9d8f4f02a65ab5ca5536b412493cf9786ec2ea24f8a58a7bc071c042c72dc249f19f20f06940aa58a1173322a20536b65abe805e5e382a2629a171cb188ea1b28cc049d85ac14bc92614efd666f40bd13dec893de525bce477f40cc173989ffc4d6a74e68c507d78676f9aca9296734dbf55a6a8788289fb8e481254e9427dab094cb1d12251c2bd9c1fe91ef70b568a6c40e9e90fefe92a92fc96b795e538493e2a19a3208c114371986e6869db2fd807d6506be2084825d814a5a5ec623de07beb676fc15a72df36d71a7ef1ec4be52b52538ca8e150fc43dae1bfe5293ad8c4a1b273ee54db5b8d0565b9a366e26251755cb5fa8b85870769781678660691a47c3272175ae70014662ac5f0fd8eafb1bf8236a738445069d882b37f97946d0c593bd4b4376b2fb3fd216b311f5afda34ea4d4eb3a310e86ba2bc912da1477dbb044f06761ad21018893a3317f497fff50dfbfaffd8435794a2f10285acd02ee1f01110ea60f57237fe7b51be5dc7fc9d689b4e357e2b98b32471dd376929314741421eb55ef1185143897c874cb26fe867ecef8ad958edb6eedce1106718924f24e8de7572e5836016a2239b6e05b234f9c3d5f88e5b87e24b2028c128f98a76cf55fa878a245a342bf643dd3d72da2785d91fec41d1eb5ca7576b2c634d9766bdb76d782717db1c67ff0bd59505d50c529596c40815c441e645a805f1671ad2da169d61b96cb3f4465a81c50aeb225de8830a29d9679ea17d1fab4077e3447e6f59c2372450584e5a1aff9720f0d5d991ce2812b61adafbbd1cbfef060037b43bbae9a2002387cde34539ac9da43f1c84bc92af7c1ddd61d1d85b7e52f000caef0a45b05abab1d31f240c8cfa28d7e81658b0ebc0d85e2ec1ac0d52289a8fcb07b51a9149e83a9c2dba98506c2f93849ae3005cb1129b5262e3f0fce96f54ccce07683a2564815901a88eb49e70e79ddb1090fc6f79eb6ff8068e74edf5d41cb95b389ff7cd6e107e5464a24485f8cecb5aecab723a517a517bb0148c6381c3702be3866e130af0f1187cc09937b09e8689dd9402a1cd00332c4fffd03c850d5497898e3e19875b26ddc7e23779acf9cc8760a62bf6fb9851f1ec5d9c36b19ae5a2139337ba40fb542dfe9ba4c983a5cccd51e8f743292ddb64daa85a3f2df72390c6e9a802174d140ab49185f7b4a727d88ce9e606cbfc3e3e7a21908427c2e8600565ee9af1b4b7c7b5d8d34526616a3fd29adfab48f291b656e974abbcc5d078926b4ed2d0965400537c01a01522d8953cacc53da7e5dd9cd485c795a49694ab9c8f795b48e438cf671e508bcc5395c6fb762f3add5a4e2b1701d04b4fda39c59ad2da71d9559c5ccbb5dfff0356c17d69b7eeb4e95e415d941465e4ad7042465c6aee3cfc8f9a7890d1236774a942d711c252c362a416ccae2ac04c8f62cfede96657ab95d8d036514c7629fcf3ec8df31fabb40e0dd0d628a634e01485814dc66f4e18fa7b669ee459030f11ae0533bd0015701e709d77c6cbf1af7eb469460ea00ea93826a9a3e54e04df132258aa75631de3c5f8a1d1833c79076308e25e60916497ae61712bb051497bbdfc7d872de30c8888603c0e1dc5f01e895268a32ebd8b4442c1a53d65acca56f450439b9800241aa0e29caec8e53793eec99ded734df4ab05e866a5f991924d99e7973bfdf8deeb95f4d7db1b546cbcb4e8f902930108b9028e391e5963325f115a07c3d7600e7b8c7b44a528211ec645ada946a640e8f1caca0575bb0f8793a90716b780c68f271f772772731eaf564260dab297fd1a6232f23b4c099d4d0ffed4d0a28d5b306c910dc3527553bfcc0b8f22e3cbe7edbb1a3e520a5cb667209d5bad10030be292a692d7af54fce718893f5b4de6c60d0b5581d43e6d356e3100332538fd1ddd3f4e557bc6e1a8f7b6e349a0f8c8bcf3c8469d538960eb97b5e9a3c7db9193432a60a90f94ebc9b62a4885bd98e29453bf6996f6a041c8adae17ce73a16183961ba4451488a3116c5a7a80e00bcc117df4c118666a9f374b513e6a069e39b51476b0c1a94bddc9e0d179b39cdafa9595a5e2923394a67eeb33860582c754157de2ff4642d926791222ec128f4d94e1aad4dfe3174738d6bc0a0e90bedaca8faa4ca1b198452bec8ee166d039268b4d1167d02569e5c6e8d007753bce435220b7a38ccf37c1edc9a4662bbf5e7097021745867a505aff190f853e8ac49f027361a834b145a8c96c18d73759604c739d542d04493f38120c4d5625aa6feb408f8217122e30c94c922e16a3e5b65e08362e3f74e02538b2396d701844ef23e927f9144a44459812a74e8043e2ea3c2fc19a7b9930e59dbd3bbf8c613dfd7d8be6368e7e0eb8c25111c43d3ce2c9f070c7b2c652ba31a5b2772b580ec3d0e6def665162abbfe5cccac550359a45033d73e94e9972b0e8fb11899a8e9921bab913170d2b73685c7597c71d0f84a7ad41f954f70984e72056d3a47f93a4562bf25fd69334fd273aa87b6f11571096b8f9a29ea6c20ee3d8b91314b17c4da8e63c84bcd1ab75ff29413b71494ccdde3ab4dccef8de0c92d0c13438d903f0a8c7db3d2d0ef1103278b229c4f2218ec62d9a3408069dc58baf8e4ed2b09bebb34cbcb29a91cf91eb50208b91eb019622d55ebb84e1ae4e50bd3badd3416506ddbc8102f040e16c8a2e637775692fb901f82ab807b6325c648930db99c1b589c852eccec703d4d159e236c3fe68e8d9a5e65aa2bc779c3bb92d3dae981bcb650494c955cb208d59696984cf1fd7b3f86a563c5557a721294de650e863440c15eb93982db615bef07e1d9befdcfdf469cec13af5458744b88c1bd13b9ba8bec58d22c22c750a6ff22a309c862a9cc56be17c25d6574437511a0e5eb93842d19b6b102d78fba978b79d04b178682a0c92e88707e0ef6e1a3ccedbe1baefbdb2645769555253569124f47e694ec8cdf29e8b049519d29e48af2404e3b57dabfdb6a6e7f4689c881a710b0c551ad75007840d67d1cae1d6003126b26036ff58445a43eadfa365a2f0f6a68b349ed630251de745b3ba4fbc4089cb4604be835193c5dc94673ca653086bdf27ba067a1cfdfa13ec418fae51bf446b6456bcf45b5f630ee8421deaebc75b1c4c417877ccc0e42e01fa68809ed52d9c10de07c75680e2303124e4c2f8f5d39b4f386ea4f450fdf0bdcb975711ac5254e792801be65b6609f6aadd067620c1529d6ab6db265a9c338aa9c28295ec690cbffa18b457c59651d4e5c3d23d14e2c7cecc5c34c5f36019022276c9a4fbf39e5abf533836dea0da23ad2ebee5516309ea76cbfc3545a940ad1f494f9c78be1d8442a58b6a26aa1e45198d82f93fc891703bc1d26a73c233bf20cf79476d2e3f670889fdbddf43ad662c2dda02a434c640bbab23eb0890139c4da2f26af2d1aa355b554cb0f084a25b7d861bf38908544afa8de1eb34d59d8200f6387914cfeb8dcc1be7810e21e812abd4c089da13a672bf04b4607cd0493b99545a6e16d5368ea6861480ccefa33dc3429cb4f25790bd5b7eb1687d8b146c29b6ed28977a4730330315975cd667471354f8a33b1fa0b136ef1c01db309fd33cf108b606f0fd72d1e593e696a0e453718d649ae9299e336f4bf2d934f66f92d3dac999601a07d6ced91d9c21e974de4e184e6a5a91531a4031a333e1869c64bee4c6188d9ac382c60cf5e4fa96393ccf667bf5a799181ca5ce53be90e86107d51ea1a2986f9cbb77b68745d4513ee434c4506dfcfa81f1af3ee4c4a50b0aea78301f6b214e6b6d2d5662865dfabe5985cfefdc177ad0341bfb463611387188fd64878f2ca6488af9418717baca99b62303f9196e583330a4488a4c65498eacffe05d9e5c6683702c40e12505e9427d06d321bf647fee16f732ec28500ee0016aab3b6782f7a075185f85eaf52848e6103c49813a68c553169019f0c8090dd3e56feeac191948cf1dd20c814ef736111fd4138b820ef2bcd34ed76e5fd893fec37fa3f4af76e8f1464f8cbd5253fefb92def1a642a5bdde7d9daf6aa6d33b9c689de2a03407363b99b24c951a0b96ed7ec8dbfcb43dc82e0079588ccaabe654e0a472d20de05aafbb96b258b1c9979dd9aef1b121f4334c64aa16669b65b605f31c893617d0670fb6d03a165b7bbc35ece942fabc02d678f33e3fb2769476f5f04c84831147aba4ee020eb2501485b9c032a4c300248ca9e0079f92d1d31e18ac75ce5877b6d45fccb1863f58ace81bf8503052d84e3998979b7d634a16315c2e58817f9d7ecfddaa0c90fcdc813526692522434b09ce864862be5f7f7c37ffdea62fd6d1ca615265ff8686ebbb17b2c77f5a3271fe6023ac5453d33d662b7970128ec30419f2c3deb1b79dae0c8667f44a77489e5a7a6f0d7fd9aae448d50051d896f061e4ab37ae46c37f0cf59a41e0317b59db70d098e9657a70c4e278f6df1d4888a4e9c70b2dde50b63ba73c76aaa27aedcce153c16ddc87a05c0025a61f8f5dbde33cd973dd1f84478fc16a70c351a9df9082e6813f4091b8f2fa5e968babc79a103e9ff4c07bfd1c88ace088af7a139c270b3a68324352eff3f1ffcf88a0fdd92350732ab6d5feb4e8629a3d4455e5d2afc458a69ece5c777354b31708a9adcbe009d78f44e7710114d082e52c995d396bc187b6a8710edff7dc29e299d46a54aa9a73738d67f3caa07621d656bba3e2d6950081b2f51ca6df54bfdf91761816baa0cd188751d86c70dc2adba8e539a57d69326b3c62d4ca812ab2a256b191a3048616079686983fc7ced8fc3f765ebe99187cb2b7b23b7370e9e1b65155b05669a0fcc46be4115038778c9fb8df99585896dce4f24a26afcb74292df1e1a8022012a07626739d4df28b3c1c6cd723ea4152480da0e1a622c4238dc91215ec71ca79f07c68d1265c7130dc1233b0c2c7fb1111dbec4c14243067482144f60420611a9bebd75f5e96aff43c5f18c178c1287bdf522dce84ba9a3a8c8e8448e2c562b0b6c1246f0bb5664cfd574864e02df6afd260179a24bc2190effd82b87b193fc63efb2c13e1bcdb0680cfacccca19528c06506db1d4369c1c5de4bf515189fc2b9ed8f05ab938f21894050e3525549a49f3a8e7a94d34b80f328fce8baeecb3102c659c4a1dbb59158dd825961e4e9f3811a0b5d3f65c3acb2ee64b855a2d80821b2bfd65430b898b15c067ad7741bcb590413fabefcff735df12eeb52f13d4a250fb98ffa12dd4fd3f1504b178636cc2c1e554c49a31d221b49d5362d58e79e5536848e0066bcf2146f0782de031dd1ff9618de3e0913ed913c53f47642345591cbfbdfc7468ce5065a6c15d5c5d5b6b734c829a3f8ae530e673a9b038104bd57084293d5720e4604a6774faccd853f8986152df9a7e06103194750bd6854f44407f5d02b94ec6e9d9ed9e2863aa93ed61337cded70181b770b10cb50af0e1e44bb68c96b8d08e1e9de8b7e0be719ef04dc4fa0057a7b78e3666e12656e20e4ca90d2545717123aeb268a474832ea0fb94496924530bac3aabc84298f9718e6c0398b943f0da66fb74db7d4f88a539057b6ef726fe478ce34af4a19c84363e182dad3f49234109c0ec7c01210d1768d43304cc33ebb72f9cc6533b50cf0862970ee7d5fba60af4376c57dfe6059c98f1f57feb4d2d80851228ae730ed3e13db4ed3d951a71fd9e91b3779f6d79d297451af84ab0a4d99d5c8f265e575fc58c04150f73d4698739ce47a9711afd55fbc0fa745fe7ae436b42764c94f6a0e57d3b23b0c833259082c001d1401503a206e4a326bc9ca5fdbe6524e0961bc1237bebb9e8aaf6421c1d9116987e29cc0fb81ede9d7e2dfd5ebddeaa5813d16b98e65086037ddb4bfc0fe26b5a9c1b5a427a8a6680431573b02fa3027fb3b529e12249b9b43c8ee301d4f1b81f2315140b9aa9285002b8a6f284b6599df0952b00860a378d16b64e5ba308d8bf0d14ddca7a0065fbdebb465c927f1e9df87a461407772ffa34d6622489b3f3a1e1c246e93b821a8c07666172877604fc364608de59788b2caf1b44ddbeeb7a1201179207f5450e247335a65230ae3143c63ff307aa840e000c0aff2a1b7498cd5b6916ba983efad4ca0bc215c0edd5ea1efceb4bbf5420c4fda7a0b96fad6185c6cf7f3e907e3dc295af5afa452257fd15d626720f53314feb46c13ea986c6451f4651705489a158345bf2a722f3e139d92d75c74d3cd3f59935265007552828162f0424065c051a5e11ff87a5b3c9ec2b16c3cdde34c3eb90fffe1516d44f94c9e912f1c84d83d0867af7c9f0909b60c0cade1ff591e4e71bc6e6ad97db977fc07422a52ddc7ef8fd03819c84574ae5b524233e533673dbfa0d7d7108af001ae7edfdf8e61d826a134606a6e53d703b904db77b716bd0fdf9f90591e259e3a4909cdb1eb4bfe034341c9f6ba2b8d0522f8cff2c4fc9ba3fe8822ffc6cd6ff7892f201df58bcc561b467a13ce7103d966030c1aac951f11f2769594f2496ebfd1b835c2009e6d53af08be8ff58f6439a77751bcba712c3209a916a76aa170c13923a19f1919e0eb1097981b9a55468eeb9ef725a76db6aaedce00b94c81d7a0e05d3dd721008e4d95d0003f7f0b2d62b2f1de32930edccbdb84e9e068580091d01805dfc7406d9f862c901b82e6bc64020c998f34c3819c780a5d187634c462bf194714e897dcb0292259cb905f87f9c465df28c322445abe49c80242b3b6a081f206882ece0b4a7603136c43e9773c657a336db86a597949b92ea7aeb402b325f2c7264c0f9e78877c84bc59ab7f523895b3c93ea86fd0fa50840344da218c5879bd9bd692c3972efee25dc96041df1ae48cf465a8faba607b42316d81916fc2ab2c79504378066a8fdc6c4b44d00d8b2b74bd3bfd6c63da7caba0df37ded310e6dbced445de08afdd1a257a50822233056ef383e6014cd7aa043df3f22f59eb8200bc2e4ea02b76389a2b0cf64380e8f79cfc58ba160075928f2fa4dd1c1dc3926f8990bfb3145a9037444332732d0ffedfb5bde66ebb63f32d0afc301447ee6756e88b4a6bda0eb3f5f23fa3d58c4b38a3b940bdcd979e45d6bbe83b4b4dd44a6712a0de18d34c6ef8d38c4a609b85aceacd4b7fab01cd137d39b3036ffa6511cc78ac57a0b1f41df17daa501166f2cac7e82c6c9e9cf047371ae4f67edfcfb082aac5ab5d144cc7cd51c15b1ac93da435dda0cb5a78e5b5eb19625c3d6640fe45d9cee07e6bb2059059e344c7675b0a21b0889783eaa583fdd067f5ad61b9939664ae6e8e30031c5e5cf03ebc11cdf0a3ea56ebe2d48ab5ca116ceab83cb5daacbc3e72f971f9879f9b6853f33168260f76744243845d660581f3ff7f5e2b37085e611911ccb00d59bb2497534954b717e214d9afe04ae9c4328d1cbee3199790b8a79af7c6f7f4e6fcbe6257c443da619b3a15253d37745671de9201600e3e868a1e0ba595b945fcd134a0e0838a0703c6752dfccef46e1b001bbe4e952b7e62cce724127bdd0b955ae03242de6ac2d76bf659b8cd19bc5f1dbb60a9815de0f14e2abf8dcac5df8cd4f1451925748f14a38c25baf174358a7a657ef975af275460c7274bb78de6b2336199c2b02c13d9928611ecd1972516f3474071fbf0eb0cf9274c4218d8e42bb23487fb40fe09e12b4cbd02afa23bbdffc430327fcabcb3df375a2bab361ea04377150382a532f6122e19216e0c50db3f1db5750a6dd3a65a9c165e950e31f08293b6a19e1978323c0b99eeb87e8bb8e9d660edd48f787782b5fc36477cd12e7481771c47d0e43cf01ab266560be01ea0d98453f9268e04fb599d676958f9816738e6f430e6e8adddde3c91785e49516afcd8b85d639e3a8f99b1cbdbde95fdd1740a6381cc97cf91dde7527283556218c040bda6390e748cd6e3f718ed2fb8528058cf514296fae59cf2b1700163bd944fc9d43b85e918df843e971c5e2429746102eef9481d9e6e05fef89bfe5fabb51744e6c5a366b903b775ba0e67876520902c59a0183f1bf91ae9d891750cb70133747fdaed33a4c87553310d5913ac2605301c992d1bc512f6ac0db920b77e0e0213c21478f483493b80cfea45926eab587830f5bce3057daae239bd7f40ac68bdf690a3cb27e67de3b20ee1122c4bc7f3e6e4147d93185396f53f6fce6ef14a45dbc2d94dc9ba0365e4e61ce0391408776221dbf8055324cd47a28480486bc0d95249fe0b7f228707904b71ed2db5d914817d1844acde415b30b6cc627493756b52d59df7337d800390be263ddfe660e905de04fb77a42f8f7101d8f116e8bcc5d21b0c905392f8678c3561ca774cec65c100b6b9d8048436c16c102053d7bd1762c958898ec852239841891a0bd96bed3e454abe7ece37bf3a276bc7f2e8e4286ee46e75abfd5f31125f4f8c1e06d0f3d4234ba46dc8d644b23850c7d2b710919ef100c270959e861e1853d874623fd5d07e9449624772700a9e96d3448ad674afa5e6d02386f01a0199f6fb6eb1fe45d5a2c54490cc74d3192c594d0fd6787779b9f63415f5ab98407074dcbfab59c29ea59c2199ae9080a107755c4f13c54e6956a98c6a89e7b850e34a6ffe57151ab71b25895829c9ee671733069a20ec21f1d191b314126aa9daa904c83700dca7b05445944b36eec51c7c0cb0364d78e05024ac250a68069ce360a87bbf76d711d4971f14c6da7f9747652985c93565e04a48dc1b7f1ada102795850e350ac396b8c7bdb40c42261a3b76e3ffd9a3073e51c4acc0709c7ff78308e4eec6559ec7802aaab91af45611f54d8b1f45ab69a7046b8384afe5bfffc0437024b60f4c83bfb333ca7c8a0efad573fc54adefc7f576e8a52ab0f8e57188aa13637f7b490bca49ccf6c4fc1e51848e3217986eb82d19e5ed9e69b065ac9cc5145b7d695cf015f2a9ee3f8e003f445643c0a932d39f46b6800961405b579a62ae7830f068471d9b6aaf05b6dd6d093c65441665e463c2d269873ce1eb23c8a932829f63f0c24d488a0ba3d3b03699a4731df4f3c7f26a42dfe699a7554811ad4dc42d9aa01cc5747be1ff9d1b58fb07fca451cebcb7ae2e34443da580ff6269c2ce60e382425666eb70cd93dc10797b8b9abe53562e00f2c743ffdc59d65937fdb23472da197d23c9df6a90a856f05cd455fbbda5ce5e42397dbd3e4f5c49e321e2edd22d478991276aa11b1f2cca886915153ea21197ede081343a6b60e97b45951c0e04e9a39c7777eeb744318dac199355a61882e058fa5a8ce315300ea591516fd6431ac0d479ff5971dfdaf0cf30ea2f97bbc71cdf0303ab14178fd2826e2e07e2e5cfa90acb23046276073e021e6a863809876e9eeef3f5427bfdb7503728c9c899f62cbda53b39c7125b1c1dfed3382701c7bb12079aabfd2127515ed3b9adf66a220c28c3fad7307647840701056b7404bf125a052eadf48d3c698f4f35ea8bbc05049164f05d764bb4785a56be2237d36a38b7c4722cd5e48682ff0291f84195bf1ee6d724d03357fb7181bb5b2bc67d2d2072c4e9a8d702b96c781b18accf1070e344ab9c8553f27d284b0a86bff16145aa953ac44c9ab0a8dd4fbdae92290e740b5217f1bcfdef2fe0aa754fe5e0ff55a6f86862f08da7542ba14f264ae03c969a614dfaf0742ea38842a0a385d5be57dda75e875d47e35b5fb59c5ff326cf4756f122452c6f323e7b5d0e20f46f77fb5c9795837f367785d494a655d4cac86dec7c83c13bedb9ba6c71c06c08ec62c521bd918ecb9560212e933abb9189d3423b785fc3b8d803fcffeef7c7f94def1d81aca826df632dd8c1f1f0083f26a142726b81655c8dfc2b24c047af8d4ef10963e62b0ca2186211cd101807fb2cc78d7d8de927d10015ae2022c19e4ae2a8b20e3aab83371ee86740a51d2e9769162c7cc25a69e37c345e62b5143d5f8052938063e727d21db0a962a79686d7940822b8f8d378e111d33a4a04ea0ae944790fb33fe7a9f6908cb727a355b47cc25a33441a702b1bb60139972cb897266cbebc3e1e7395d57960a5b043bd3adf84a1bd1394b8516d3f95716e5c364f4c747e2f13e6c36c8b24094a9354b2569f153208230e23ae48e956bc0353ed78403eaee0e79f4bcab180ebde65361f7c9a8df9b2eba8017c868a4faab8d05803cc8e9b5c78d6581a124505331e2b84eaa8b610034c5cd8ab0e4d9de655a095202a7e71e61f3d93183288a24013a2926acd8497b72459e3aebba4d9ea822368ac41656820c9b90a9ee65d2710f48f87b1484a190583d5f3e0804595c349f80697ad53094ee79826959ad990cd1d17a662bd0f39a225e999d5261834bb19a0e38c2b9d5c657a3d60489a2a6c5e3bcb7cca02af1c3da2ffec6ca7eb5db217c899b4b953d15f3ccce5e9e44398ed38795c57c2e3e284f03247866296450a790eaf07c45e87daf58248761dc83c63d31d82fb15a86df5c5f64a87a579987e3b260b8f9ee6974b5104e2b8a5e5141ee2ef7f2b9d03b005e2d38df9d59c49af58da17c52a38131f6cdd673228e01cd83ece24e9751e261345b8e3de3895130d79d52c762b8f746b3a8516b9aec1904e76fc487dbac0a41abb41a4a7ee41b4866063012d9e125575ac2c5409eb797d8fee5302e9a58d0e4a88e96502dbcddd7ba82a650a33e28f51d7bf1d459bd51078992252f65b12dcda7fbfed99abff354a1dd4ba39cbf493db59bec073db2868dc087f8c1db3beea3546fbd2806af634de30b2889f7c671629aea09d97de2618be0ef682eed1842eed41017ede9a5739f08e21e5aa2c02a3819f1151d0ddf02b66af14220194f8f6ac548fcd347e9c31e142a7e7655c1e49cc1184367e9a89a9d731cf3b06758216aceaa664ef28f62c3d37877d953fdcfd21ee49f16567c39026e2bbe32dc52906aaa24eb5c8a465bf37fab9f97e803c8cb66062d244e5f8d9076b5360bae2ea1f22a1935a0ef16d4e6a2c8f56c7769fe32025cef7f8a634a3824eabaac2e290f00d3f1c2241cc7ade9b2baa44068f3722a809eb8bb37f6483e11abccdeca5c3a33fb1c965530da353701a5241f21c6618a52c631d5fb85c71fe1883a83e72b8613b1015e6eeb576418ce1c105f2cf9774f83c41c680ba867df6448cc0076382319fd7319bda81cff0a61adb847c44d95f097bd3f1258d57a5f4bc4465b32d0e84921ca4605b6d2a907dd627e35ac9a88efee33ff4405509b9b903e39398cca4c1f6c0a12fe7a4f908d43d8eb218103abac03ebfbf043d8259d0c7c5735e133b0aa9e987d4327617de5a1d94b1c28a00cee3bbef7153e67a7474456b9bf3f451f6449bb264acd624ee9c2fda0b0e82af1dd72b6ea41901dea921ecf4696f8e872ac1ac01afbb0d4a896e9289b1929902e520bc5f3f31cb4dacbd0d1da872556af5d1dcedcde3360d96fb7ac8ce227b41e258bc70c82a449fdfabdccb0c5ed998e9997e6d82dd079fd9aa2e36c3423de49b8a5ee4b0ecf3140e2488d290d585d1ae97f5d02cac7417c48a4d6a5806e20dae26aa096f231b1bf57dae517874167f659e4d7863e58b96bfe042fca2946029f03c103779303047c300823181803ce9fd162684d8f06f1def5f258c1849e232f64aeade729a26ecf317b54bc6281fa727c4b7d38eedaf13ba4442bedf69fc9037319e13dbf548d8dde011f10526aec33f72da3af504a3f6ee55d75d33bc16bf4fbc1d9b08d918080c2a669184eaad2c4ed59ef1c763027a9da6e9413415b4783d97bf701ca0dc3f559c285f331922c44d60876afbfb4b50f68ec81771163dfb2d6da3ef4e18b4dae7689d46547eee480dd52878ffedec656f9028f54f99f8fec1f504a12b8ae6a5ba025ae10188e559a50b94a3fd19d4ba7edd8ba82db60ecb9cd25967b9e5f46312496b52a1420bf77fe2f6f34ce4546534a1499b7abde37893e9733890c1824f33ed38281920a8ab986f636762842aaff9609c0dee933cdab6d340be46b6d816d0105c509f95eacdb0958081b342713e9215b28be10f12224b966cfb2cae8949362c847986ee0142959eea4f6c0905d79a0f245bb5af2f07e0a407205c7566417cfe81aba2344170526a3db40b3b793d7005c0b76b311f8573dcacc7575a4ed9a03ec8e704a20fc0a3b3bdf7db68c156c1ccc67f28dd19ea45d21cada05105b96e28a7768d97c7fa4f8c4337b1524e91318622d95329c431212847302fb33fbae5a64a3c7cf04c9697cf054140273cc00944ecac22e53939f67359479981a4e3620ad6b7dda14e3c0f68e748e84ba4199f3ff93aba84aa058e4eaa1a1598852bdf71382d961225c0973d942fbcfffd09284c304f3e6907bbcab8596da171ea3a0313d6817fada3d2561a7e820fc8aed89a919f33dc3d90e90c55740291dfa0554f91e11b10d18384c484e6b7b0f73558d332f0413ed76853dfeb8da12adb8dd2683f4cb116ee07eec84800e4c96d060d3415144ba73467c5e88ca1ae5cd4bdf8f445d726424d62642eaabf4e11afdf7d2dc67dd45d95e1b5b2eedd708803e63b7a947d58b4c91234d5dee983a3b1e9ac7c7696bb1772a6ea175a748fd77f3b968c23a9ab27a9993ddd105ed36225e2421cf5b35b05526117a9e5dcb195ff5af45ec7ef40519bfea895ac6aebef8585d5e16edb724479823fb1b881f31d392a8f0175185f01e28a8f0000e23d131e06628d67e8d038d4216eea102931148c1446978363c0fd75d08b0cd9a6f393c5fb56f38049e94364f59dc63e05252b901c5b3ff5fd06354b9783b79d8f30efd70a4b4ae9cc7ce01f1ea705724a604ece50dd5583edd2bfb4be68c0ff1b3c7a4156f72c5a281453b08f80f9fa653e948920b2010a9018c0266c03cbfe1574d06f7f6d01450b85ae99e2c68c0965d07b35b31c3954f82c8b3d6618b083124c068ac04e109ced9cc4d36a30773566d8b06341c3b418200b2a994b4f4c255b4adf7bd654498ca3a622ce71c409f0481f580a4fed5a90946c508d309a70e686709da918ecc7bfb3a336d48d7811017bb78829012ce784e0491c4a3a1f54a154df2a1b8f1b12da3a83847c3f2d2627738f2a0eaf51e6131e7c974a3080fcc7e7222bacf3100db69c417cc5c44f1ad69ee5d6571ac7fff67549f17dfb3b34a00b716e6748f631cefd721681fa7c1f7d288b590566ddc5bfa23b19d49668d5bace791aa3ccc71a095ec70693a117b8915a97dc627cd4b23b6d744784e43c264f232283194a8f63d647dafe4f6dfa2c7146cf259c81e57d80b2d3fe4513e5a6404c4229881170ad24300371b25e76e3b1499326b5f1247b0a352c08ef6f4caf2e0352474438726a1ecf9aac1ebdc5a53b2a0549eddf92db14943e41ff2d7a0f04da4deb6aa6c523eff90877a9cb997197fdd106f70f291aadf052823d3f6c1e2f06890b7dc725177451f3fd600c54e673e1a18144b7c27fe87f1cf02e1a2631db7acb2b45e2bc5530abbf9eb22f3d46190dc75d6fc38ee999e1faebe0a3470454e8c630c31e2d99d9d018c8857534e4a30dcc5d503bf41a25e20ca06e31c7db717a7261ebdb710b24ac061548c50ab9f9912675491379bfa9687a011bb7c22a03a03c1ad8dbd66e18af3c70affd5b7e62412f09951390a1141226f67800ca2d5423fb998d4efa746a2a6e16ac17a3992dd74422b51bb26807cf4b0186cb42034483de875855b6df16493ded317cc418271ed0b7bfaef13272dca1c624df8bc1302a11037cbf4a5ea620e63b618c7a3287f902950109b90290397aebbf6897dca9256ea4910e559f2410432683ac4ca1afe3cff8c807a7a29733daf15c7b5fb50c67f7ceacc9666569f97ff6d7a20f36d32b58666a4d51ad9146e5953a8ae716b2f275e6a87b0e9f94ce8eae3f235da56c0b2feb33097b2083f9d47a925d737f7249432e58d2dc757d8a7c903b0cb9de4572ad32c7036f468b8398837bd47a27d7dd466f76d4582b06f2da2df256a16ebc53ded74f1d67bc29bc1cf109aae75925fac35871963c34d5b6833ecf6ff7479beb4758fe4aaf9117761d53d68965695fb265f08a6094ab6cab069ee7ab4e951b9b40742cb45b0ff7e0c20d5e6113564c133102647ab52ba45a92dd328628ef08e9fbec67db4d4499c9543a99256c97b77c1945f1ae6754880ac94b9e6ff5a9a381ad158c5402ecd0aec92e34dcdbe2e961c8c6342f8bbda6a7a006d5a7ac2f4e65c6238638939e734a41b5451205d6e2b8daf6bd86c71446a2a7b036ad536d014219f641186868ccda626255634386d39a1a9ae58b275b4c9f861e4f18079f573accb38c3d2d4acc278f15a5a947533a6ac5ed6e625c069ea7ac445bb7ea01c6c5d3507854797075c657b12e43231bdb23b70cec2adc58da3f1fe4c0729224eadcc86cec2bab6efea1c976d15aa86ede36bcae567b2c97fa2eb025d5cb33e72945b0a8e9924767f7af174a54f23a7935de68bd8cd272e39786b3e9fe9121255b3f6e43fb441102777d13cb7a7f11874b766f2d6bdac7861b8ac4ecda0d391f6f0d75f22f694bde5c84dbdb8330821d792c3eb4450a4f9bee72bcaecc30ad52e3b3542792a9c3593bdd7737ea23ad728c8ecd0b91d12fd84f45e6a5ecb9eaecd1ec262b530c9375299a029334d664d2245396a8108b3ff35afe20c66f5919a51f151db1b3fdff3a29f46a9fecd3d2322549ee9840d9035040f91eb50209b91eb05db79ddb7a9ceb8bde8857cf5b65b4be487fd65f0a2c065d1e07967e4da56d38f3ce02dbfb705871ff5748e79a60f589722e8e41015b67f082c6b729bc90ac99bb4369aa25a88a884b3ea6861b66bf74118eea207dce0c8db240e30a453e1015928486b270574eea02b861b3e739bc57631cb93f768a1f0912a838c47c1abe88e348b0216e7750538d08a242a47f8f99d86691443627d34f0b7f5a1220c1602b2352d695a006f12b553e0cd82b209490b981cd4940aeb44fad2338ffe3d7cee2aa810acc3beee7a1b29f7b8c47a44450f9afc0c654a6c6db8f56cff99a25f63e006d0ac7d7fdeb3bed5da0e93005b74380608dff55573f3f493115d1559ed8aeb2bb99fa24a3e0bbd636df80162aff60353fcc4f8cf24933982ddf35f9b427b2013f75d16f4b11724e10c7ee80b5219f716cbc594d2d0092727d29d5007fcf9cc89c5b3e380b05ac6d93d9e48a64a0799a59b4c18ca42b63c4d75e39fc89f95592e5193771f717918a99e59931e121a0fe5d8797c790b6377e117634c18b1827f9925d478bf657b8586d449e3bc722ed39da4b01b23a21e920d5bd3cc55948570d4930b0ef47d2a7d067060d3c46ef0820fe6cefc8230ed9883fc87cc6ff97160a9733dbf6e59ecf2f85a746a3b702d7d102e275258188c821598e95b8f4a31570d498492c6afdf8e3f94813c35ba29abd76bbbcb2d9846af2940a5c22b58c281d9a732d40ce1b07b1dd1ba451a92ce10b51ee38ef3df3fb99b7bc765303b39a4345af99a061cf64f74980041d3d648bf5a36f049a9156f2d8dcb4f6b533e4402adc97fad7e991cb0c87e9887faee8c8d8ad523d28c6dd94e5891f04ffd44975b875d9b1bab89d16f8d4d3abed6575c6089a9ad2cfc68a7f5f3bf28a0424c8f6fc03be5e7c9c8441845fb546f8fb084c75b6e35e872cd9bfd9761bf720104975447b32b38f8a3262f6a66425262458bc889fa8187aca8be2cdcac640f399bd8dd4b2ff607ab09ab0f39b18187871d2b65bc8031f6e49a8bd22f7fca623781cc34ad847b1704bab94451ac5993101ba0dac42314d02f19d6554eb2072cc45c78194395edc9be21d5f5db096eb322aa0e8f093306f1cecafdfac3da12b1a96dc1d27a19b1742de7c040e54c813fa15748e10b18eaf7314aff51ab7c1368c94e11be79edf20ffa4cf484394f8ac5ff109d96a5e9256b37e8ac28f97687346c73a293151b83024fecfcdfccd81ce6a0694aa26a4f5ac00493b202da2260f52702fcd0f71e276a4f2d7d30cb4e7932581ed68deb1d5eeae2265e1261556c7ca7d360be388d5e1dc9f5acac8e5ec94b9d053fa570b1980e9168e72a8d2720b40898b03b1f09c1f8df384a056d7e462def72d90e10035920e55cf9f1b746f0a3733de95856bfd33e47316f4bc7f313aff51579a64d46008c6171fef7edbbca90210337417925c6d38c335ea7d1196bda19a2f86f57c5dbd1a90a09f26b49e3f6fb868419534c5a2e26040645e557829b8debbaeb7f0340e79a387509f167352f9838bed59df53fdc950eb95543125c7d2828ab1b183843465a212ecab4f2f9a62a24b2bdd0a69cc5f3fe3cff76ef30f55d394583416ec489c51cba5af32d36e8de5b2defdbe3f007fe3796d30bcfaefe3a4f20a8e1dd07f03dc0c3e4d4ecd3f5f070b1554be1dd77b9e7f733c99d47537053688009e0e2e65d00475c7ceaca048ef10e9223087af4315eb781285df779de7eee50dcbf5ca4e5a4dccb6d58c09337fd3c97ce8ac1f723e9468640d8f64a0034f8c3d4cc15233a4354dfc1526467db4eee342affd995d4d2f0a4463422c4ad368fae5ec23b33d748f9c86bf047f797155dab1e51db56c24beb75e43642837d8f2e4bb68575a6380bdb2b59a0336db32b99aa60785e1b9e6f72c91825cc269a931fd711aa3e83780910a9b18fa931153ae00a2e182339ffe0916341f88425433a1c5bdc069e7112e31e1427d36894782d25246135af26d00768ba1a869e6c8dbc9e184090225b1b1a54f596eac6152058daf6d0c64c66418f959fe42d6fba1f8a8ca180b34628529e10bbcb78b78098ad34f51b7f254900de714ad98810349ffb5a49fa2c4d5050e6f49f303a296497232f4a6865b282a7f383532618b295dcb446437563add144b5189e9d184a29b72bac887934f9bcd472a504be7dfc6a1047678c0b4ac8169d96ae58f2a0b48d50b6f2281d6b4f475d206c04d774b9e35e681b268fd73a6711391f87e84327fd0003316a9017dfc7f6833f7c1b3a51ab4afd42bfc3a91390656096042927e3d6eb8cd88102bd7ff210df4cf55f5a60413acaef320508110d90f55fbe1de89a7be4b11ba28047ba9b3ea817ca41ce4b3363827c025800190ffbfa2b9d3671385bd38ddb4ad922de95fbe66cc5af15f4881590933a4478288dc00d761f4346c1aae57424867e4dc3ee25040e8baaed78f99484a66a105e9839356bccc7728eeb25556df1e06143c5779e988f2aac0de7bf708a51d8d4351e5cbc0a5138344a7f6a6ab859271f776d92d1655d41ff6613400423643184183c7dcd5064a05d02deb216d01cc4bbf5ed7239e03799bf5389d81605f138deaebea52508304f7e86e78b06184b3b675272ee000262a9f6686d0cb731b42d3030f469e54df9a7508af50778e1416abb8a03e9bf126d066d483bd737852f1c0b9e7a34375516ed6b0f9d2f2b547562976c35ca76eb76389e7b0d2cd71b215e65d14fbc46dc659e9a8f6f9014e607c5b2ea335415af46bbbfcf93438f5fdd9f4e0cbd43e97790caf9b9821f828635d4eaef742d2c0d32c24b2c276d72ea7b34f2ef7e042086d61811cf47f0d3001c222e7e0499f077cea405bbf1a327ab2da92769406aae9e2236af3ffde31da36e3e6a14381b14427d567013effb2df78293ad70eb6fbf6f90868e8511e9fcc3ff7a6a7351938189707e7064ba66ac18b949bb41979facbad25d8a87f9debb571a24ee928cf87d98f818114860705126e3ba629f3212e3a68906f0f7ec9576a9259bbb0afecbc64d9a337d359d05ec45ff5f5e21df8bff83d05f975f8f22f3dbc3d7aa923f89a959a4bed06e941c2b0d73c5aa549602f3036e6d8c752dc01cd00144437dd3ad72179ca8b4ec08718a7ca0de71c28b451a17866f4ded552d5c501d50d6514f13bdbf043c59a9495aed489ee9bf5181ba355728b788d5de0867b7495c28f011113433927b595f1aed9173bafa8b7535388d417e03605a7350a24dc565ae7932cd757ecb310618520e02e3ec5fecd2f741a908512b232d4082f429e3edf59dce6eff23bc00d086f6ab5413dd45f314786d784384fe1f29910223cab217e9482296c52af9ec5ac242f1653254f5beda19114cc8d80f3cf842cd188892794155dfcb576f0080e4d686005e0233f27d3b9d2b8ef1f63f050f034ab548ab3b5d6b2036f631b0ce7f9f42c84c9e648e515b38dddfa5e5b3ee1452343e70a26fedd15b542c7da43432f06d9c6dc0ba0a4a2354c374832670634f94d36b21c07e9860447a23da23411b658238f0fccd542851363bbb35c00323e9b68da66803ec9aba6d22551897e46cc1ab3ed447a34f5eeb72f5b66e554bc50de1453ba32ec0e982ce1184da1f769ba09ff37d672ff626f5f85d8a202691ce4f4f290f71686bd2af38e5e5e5439320dbd8c221d64262d04574ff03f7fb813a0ba139ab084b1249f837697ce1092d36f7937d661f172a0864498a1e84870af7cacbf8f02f7545d295afd226bd0713ba9805f3ecafb262277c455e15eec6b277dfffe0988bbcd6890c4cdf0f8558aeaecaeec4a2d1a3d3eaadc315947f4477181cc4f741864bcdb73f3991482b05e3139af307243933d83c0e00926194987cdd2af868ea98b588c1d8726709da97db1aad411b2c4ada0f9ee88996e01d78440c03fe2eb788d2d9a878005c6a288d0b71a5a931ec87cb2ef5c44928294ee9e7170afe14ff46d003eae05d6fea6fe656be0e34331eb3e7094ce0a62bdb45ae847b4929fe69ea15c83422d7f790823565c37cafd5a801273678660fdffb2da1e9e9f719628e4df9629c9556aa02cf95ed1e4cbb461ec9a84c31d2f06500d0b4a45180b223d8fbfa76741de088435e6a722640614048aa3bca1837192d13a7a2e9eb23f03117c6ac7395b3dbb774596683d765ab2f31a58c02839ff6f0cff2b2f4472da7bf12f3b93e61241ccc3687a1074e4455ab6fb4639758290b5ad46653234c9aa07ef2a764ca9bfb5176cefec30d746ba25fcfa299a096a3709d10bd214132280bc94743ef555760eb30c5ea7318a9df3375fa335f59c0aa50bb45408bf36bfc7f8437df47fed02689c4c6794c5957dcc30bfb03a98959c2ed2c896c9d792643b5522e87cb1ec652cd54ebdf2a4e81e5b7b0c0ed5eec6c37859f88fbf72a17c8c34e0aee4b6538de8b9c826754f3068c3ec8c1f665b59efec4d21f38e4809a642b06072e6a7b56adb90cc75ab35ee742418c329197150397f8251d45f57a3d864d75d8536d01ec62e64be5126b8624bbeee2dd749a9b4d40532117dbab0a11b678087252998db29720404a48aa1d83075ed00c74d6c57c0ce27411f5349d153a42e175e85781888e4fcf9f67f0957be177e2e590ac98109c7eb9075f444f76571615ee6e323719835ffb8f1721282d2e28ebc94ac395569bd0f7cb879ed41b78cef29e31019a4420bfb60cd7959e8cf408cd36086f185f694890bae487e2a8c3852f884f9cd1ee988c0fbe195f32b325eab2ad9d11a1a3927ddd1818771733515e871e5636b85502a2a05e610d37d105938599e04192f300428580968386e6afa41b63c2b5ac9ec7f29ed55c7998244cece4ab4198abf9648165964980c63ed109f08ff119f909a0ba7a80f18c364fc06cf161740f3d4ffa64bffaa8f3afdef1ad36fc2ba1d887bcf5dc5b09b500f1cc4080132d43019f9c43b452bcad71db290e1b96beaedc83a2d7d1d282e6c3f6a34a31d7d5cc1a5125cb09f9374f23fa0395e7c2801af069a9288cea12c133efef5ceae89f7c39f561aa2b5af78d8d7b954215c18a89bdd7358510ed8058ffca7803c4544e19b4d7566c116a87b9310b124bd55e7c645fd7ad8c8e9cffd25c56412cdb64a1ad47fdfb4ad9b46819de970fee8c11185aef03f2d329437ff8828b528d35d59b4ea73754a1ff8f314ded93074e50fb8c08dd98f3a97e321a791309e63e7df0018341c82952f1cdf1765572d27acdeb120d15320573077448c94e9b12c9e11c462bdbd534645320f7fec8f061af7baee6ad557d47d971568be3f39bf9ca4f963eff71b1f40369dca04cecfa2f7e60c47b933a0269314438b502e619a578b99f7bf21084b85b09967db858244c59688c16f44f6571055edc6f0130ff7ddce200b1661509c942a69b61561fd8224dd43f9874648dac52d97e6d4172ddf3380c66baa4b18b96e1c4b60196e073f647e27b12bd27147ddd073d8f87e1dc7dd490e8d7524047dfba1672c81187eddd50baeb8dec6046cb8389a1b2770fb75427cd6a3b3148db1041d1f24c7b3fcdb258f0c805bfec83ae5190b41c5f0c24b805b4218ec075cda9c9d9ce32d666b8f3247e45a690c09a7e86e266648fd4a5b50c6b88de3a1a69dbf39cfc5e3e2939af60cae41ea0a2e3536c52b4489e9b82daa25d32c2c1c8f1417b3a7015856be49fb7fea8051121678cd40664fb6d502d433653b6fcfd8f58d0c30415dc02f97d73393aac0d495ede5aa64e81cde98044ba0c8734891c1a967588620a74d54095528e0bc0bac5a8e7d238743b5b4fd90883e178c9e5485acd08fe518d2eae0cc2866270e076a284633290b23a0847510981baba66adcc61a2e4098205c0d07f45ebc3aacc98fbf857fe9e35225fa896c06d057759a050d8d00b7282a714f46c094b3d68ca953da89c4a92866c87ac202eec3ee7f3607edc6f8c85fc6875580ccf7c24607988393246a6f7e87d3964cf72818ab4572ff3b0344bf94b5cd7e6bf568a22fbfb2451bbb31c2885a982a92d48054b8691f2c62f5e0113529ed7890d6ad493f236ed09fb03056f503448968d596a9d2bc86a0ffc91e7e7791dd6aebf7eee97f9c736d2c733c64172ff8d2bbc81a0099e113d09ab08985bc755119c4d012d1cc595bc156190046adb4ed6c01cdfbcc50545f2e3b2d68ce7c801877adc53893686b984e91e82052cdca1f4c748576be6ad73fcbaf339a3b569bdd0b228cbf5ccf541d2613eaec002a64ebda0adb7617f39c95a3174f61abfac5b796714d92d3e1c0029d7055bcba78b885d183a2d9001ee348b05480932190d1365fd1d31eac226d76ca53daacc9bf47e8c5cdfb56c88fef3799c25f63666c0814313673b36ca82c8015fd84e42453e17d0bf726d0afef53923658e8cda29de5cbcc8c89e113eea1a75fc5aee2bad8be6151744bb45595c2297996a82d5fb1d5e4400a5421228ca4c6a7887592ab66c471e50d05db5e10a3f2073203e144d88e14be2c83858263bba7cd0bc344e673dfa056daac8fc12e0419b2b0f81be918bb66072b1e83908adc37c03a69e604cc6aadc47ce1098fb5ea50293a45494e1480b9fd2ed51bfeca53f54799994f9e7436cff0857b4b9bbfcb28bf102c70b8ac080afef6c7e0df988900d35fe839674bc2cf3142d0977256d48113d6aa1ccea8aff5741942358a9e796b315720c78ee9dc17a5bcb846dc2d2e5535f697cf34d756eeb9ea8b743eb998ff7047c9dc347b02004a754a49c363b87d139262910a16a19eab8526143d010e03fd6938d6b1450cb664d43951316fac73788786c3751ebd395bc92a19753ba8f9c6692be56158bb325c505086cc9e5b2418276c92c3026322ba9af3b0b706be13999d13283c7eecf8f4fd611cb679b5e191e4803bfb658fd6d469f344fa1797d161ac642db73b6bac915f2810147644f298fd0595af3310459d6b90d618e2f3b57cd6c21f44a24e2b84fade3b599dd5e9a4d078cc0b3c0e843de8027ca1ebf241d2748d95195cbb51277fc3f013472075731159f12e1662f4956e8c1d4d8f25eb2b87a692375b35f2f03ce8ceb726d22f97aa076c68375d771e2e441435dc760c0c2fdd47242180ea45ff19c76b4b488c407af1e9869b6437de928d0041bcbb1fd47465e35439ec479c7a6367ca3084555ffca3e3136df0e490e0b3334a6547daaedc954249db4adff0fd23c71d241a14c02fdc6564cf934ce85d542704a6ca027b1af9deb1d72fa0f94fe8d16b6c2de539d05f9e9da59cf531648b24f7be8083c8247bd52c2e7af4a56022e2db008925497127e29558195b235f3e807bf168870cb427062d00558cb2a711d5e9f63d666655b338f772b4bc944967775d0da32b27034afad6fcdf72caca35a409f8d45b5b414f7cc2006be88681a21fa5c00105efbd7fb89fbc9bd826f69ef276d1257bb83037fefedbe1fc4121e2610a6813d34ab31c7f5f6d441a78315d53612c942a149c3ac9745bc35d2b4600c8076d0776bb1f4152cdadb14c5760b8c6d2ab32cd028747deaf56674ccd842b57f4e71dbe794e146d40fb8d78da9f73a434970f25954182fbcb19b71e0381249c3a21bd6b30cd3b63583c9f01937bfd0cf9e7921aa6175dd7ad050ac225b5671dfd754f49b67b0c6a48e3ba0e5f7a3f5c255bbf73eb5a412bb48700050e2605326d065037afe95a46f33ebf6ef6ca60f240964f93900af7dceac7cdea53b454ff902656ed6ea4354101ef20020856ecbed91780cadc7615e9f18c421b475ff1556ee40b454bc1d94c35dcc59427d5f1d286da7c6a9e286f972eb4bd6e177585a6886ad627b3d7cfe8ebafc473486aaee0c2f3063afb8a7b60f1634c3216f8f799240138e3270eadcb5b04164e800fef02f0564ef8149370645b4061d80fd4e25f89e2c6f6dc44e2b98b074bb23eef3c0a786e38065d54e15b03eb1e94f736f5d2e9dc2055857fd77aff7094a4661c11f9480955a36dd4f34e22d7e748e727d8efc7b430f038fea6052cb33c7518e999bba8eee0814082dffde5f6467a959d3fe826f48ae0e1c6415f3c9110332015778cb5f6df58c4e2cfd824fe78729e6b76656b809334b481751f7bc0e48bd7408bfef092e35aad161709467196c683efab21e3d058b20bf1ec5b23f7a14911d29757fc791f2e06d62221c89d9beee2fca08c4602a43de8b07fc27484ffb8aa99216054eaa6ef1c8534bac6ecb9e539caee0589ce3147a338196ad5e13e8c00e280ff19c79e681dd0520d352183409f8d7c9c04211557b1f08b6303cd969b62d580c2dfdaf54f409b6313d770f45c839f830eab55753f4a1652c86612303d9887ec4d64310eecef429feb7eefb9c5ef73a0e9af89d48bf23472b1252eda3cf30c129f1edf0593e0ba8f8ebfccbe7e51b80e5452545ab9d92a205153c84dce291f14b05c45c032b905a0fadfc5ca6d987abf9b5d52076beec56d2124573d23f26f17741498af37f1826d4b55da5bd43f3362e75da5f9d46b9a26527d80ed2f2414c45e3929940ab94217b1cbb057d0e6d9a862e2c23f758e421a3cc022db6db3ed46ad03b3e198c8733e192fb0213ee06abbfb9484166f63650907e6db6614e425bfe1b58e44ba993bc1c4b1f98c855423d449d64db0f799297737853944e347585f2ae8ba11eb3ba93a07937f7ece91d35c0b64a502d6924c1bec43bc47e705b476d699e7d8e4478268e286541ee492df6a83566aec8bc115ad0a21edea2bb9e959836517f121ac43d443f2cdbaa6ee8200026142cc1f4ea2e8ec186882a90608dbd800283ca14f57834c964c09af0a34b850f35284c52d5cf0f3db9e673572795e404120ecdc86b5f20457c532707ee5bce73e12caf348490d2c73801d148a428bf6f1bcac56709aa1a4ddf5e6731db78fdf4fcd8f837402ca93c59e04b5d0dcd10c37cd55e11f5854e1002c32991d5b191d759f97bb218588a9967575afdcf02f0320e751ee012b650ac2dec3ecf26ccddf0618d835ef201e2d5621ecce0109ce7ba7aaf2a8c7fbebc13108384e610a9484a5a01bf15d28e069b6267f078a2226ff850f1b757d9c32dd9a16d52af27252393a19607a694b2af847cc33943f7891d5c3548eed6e28a7c309e6aea4285cf01d9c7f459e53966ad6a08cd426848f40b3504963f21856b85199fd0240eb95402b1373592bb490475f74220f3a9cc20165fd57ad76136ab5f82d4ec49faffe57a9ff608b2f8941fcbdf752ed0daa37cb491d44488febf857688dca6e8b51a282b92a511b056f66fd8e996c12a2e8457eb5140499143c7c866bc19df9b7894fc545fc8f51d40cf58aace5b5d4db4833e2f85cad4ff350c8a132b7da5e3f2ee07aac27bc348baa5ba21ef2ce90ee9e4f966674d0377a4c6fbf7d8a369ff998a583c33d94e755490ba6a9b8ff6da2ecdef8915ba754edb3a5eb8dcffe9121b822035e2d96c8a8c91a51dd0c5eeb2163a14c8410f4bb04f36acac814fd1c8141530bc248aaebba42209b5742d96d8ad65a71be85853ba6b3819a7fef2d07e9394c4c6e931318b346861aef93473f5f0de405a753030dc8f32efd8bc8663beb31f6b37a8f0e64539d22c35086ae13e8e60d73ce2c012dc93eb1efa3ecb8d5c73ce83faaccbd3de3cc6fb73e1fecc8ca50bdd0f22e8ab1d2d66ac5a0e403e7b978ef885ea556df498b3fbb0aa17e9e1a8ec96e7e645e1939f18538ead1c3414d0da02d225db9d64ea9fa51d9debd4e5bdc03a868d0b63b2a5171540203ffb4099306a3b5fa07b78577f0e138af591c89475a370b3b658c278fe5321787cf0ee810911f40fd08b7f44bfd09f194280cb1181e586de1329dd1afab51ac5fed29cdd63a910185361af1c6b7ad7e42d5c2eb448f663e08656c35bcaff6ffda0b63e889f7097ca4037f61e5cc787ba6dc2a3eba64db413446720c8056672624b70bfb0f29bdb7c5fdd4291010e676b45aae62d318b4c897d1590887ff1aca24f1cdec3bebc1530c25bfb67b88557d0fd796e5f122bde8baf9a0c29dfe9cfc7fc86992f833753dd60b881e6d9861ece7fac475984a3c28de26a5ba23f18e19f0fab02d9d33a4995b95ff76bb02b249d8b29182dd1aa7cf57b6713ffd82fd39e2d1f337b19c70de8c6acedb2bb60d5d4edb4790c74b719425e6f65a68425d136d7669b721e0acc6235c01daa6b7b54fc5f213c557dc46cb9f802d440e11351cb795ec30ae5707919606674492f23e51160b7d9e2e9154b970e90177e5461c872835aa5335412b2ed8134436c6ec1dd0551065b52f38a3b9a4ff68be9b03bcf0209e0edea8dfc40850151bd9f237d0bb427a66788d2520aa64d527cb9e412776d4e9183ad68a86220e8518c87aee28597d6ae25df0d48a491859ca278d17c614507081e03faf3b5cb3022c9932116b615cedf826a65b715456d86834d6b51470a0b2b03c06a2b7d700279b39cf38ed8e87a468fcd6afde5a9d12e30d52ca12883091183c7a2eda1366cbe823981d2c95c83b9f2282748be0fa8c12ddd5b3b8bd8f01c63616501c9f334a0ba492adac9730c14ed83585e81f233b1eda7aea1887446a1958c8301a5a7abaded8d8989fed321bf082b4b1d247deca9e34037bbf54fc78d74d7bc18b12e60d709c69bc7174258db03932afd352c60231daf18df7a66a4c106699850edc71705633f82cec8139d264f8164b91cd0a6f9dc292c409d42d85f9ba54de3f9fcfb1695418894f8bed86628a89c698df5acb4eb0575ab520a0b8d05257609780c15c196f5e8b7277c93087b9b2ddef835980a06a94f35b0b3573773d9717b98560ff2403ac3baba13a92eb9a7108d23616d15b890944454e64b82bf42bb652bc2b371dabd3527bd371c4189b6f27d3ca583d26ad009d5aa1a156bee634f24e1ecad366651392949b86e82288e6383a3e15086a79de34c83f814b8eb3baeb6e2c81b96089376a14209456d486727b06232500ce8daa090471aac3d52c30e3d32078233d4c3cb4614e6b0c2b3196fad0740da7ec46d7ab870719cae9197b24ec8f6ef2e73ab7a712e7d01d0d15b79b02d7cdce7d780300189681c8944c66579cf1b9145ef3b6b03fd002ee3f9989cdeb82f528b0ae8974",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x6a9bd02549c6ce542cd1b392f6e58db9e4661c8214e46865aaedbd7456235318",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x4bf6f91d84b37454544279cba152581ed6820044",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x13747f0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x6ec02a71a91d36b7f2583b7ac7ebe840dd311e187c05db9e6023895d956a6c1f",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xc83abf31990cd6d6d13358071fe634990b165bdb4f96946fee74a0013b52fe1c",
|
|
+ "timestamp": "0x6ab8edd2",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-anchor-20400112-baza",
|
|
+ "sursa": "2800-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa0626573752032362e342e302d616572652e312d643230333230312d7774613037f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b84164ea248ce8ba1ca874a0c3f0fa66ce62470d4b5ba918b83714478e28785da2974e1a6aa8991379e41970bd3e72cb7eb7dab3153f81fa91fa0aff7017b7de90e200b8417ffec56b257b9c3bb1b99f8052c15b600958d829d92dcaa0487b44f674ab304e5d07dec0f46dc2de91e7447665ae406bf27dcbdef04b95957d1a5b916da959e301b841b99234ee85ebe3183fd4a1188679359c67dd423e582572ebc04ea33833e66f2411334dc309fafe51f37121e34dc43cb603777437a21eacc5ce25e06cc8a2327c00b841b458d0a1256a72865b916b227fccea29e778f3b2542f420f89842c06f4884f074302a0d494893aab3081a02659326d316ca4b852a6bc07c85221d416f8bb6d0700b84147bad153ee12b655a7451208c3b7d1edfaa9edbb3477cd6cac1519e89b648ec27b351ddf95920dc8f6712c4090f07ab1709b30374c38aeb466482a880b7e060000b8413e603a29159846804a799b1517ed1a9e8a3455863aa0d35885e380090d87360606ce8d818ebffe17e96f9615cdb7ad69722c67902564dbba9c6f08d4888b807001b841374f5ef3041b141f7f15ffadce7098c4e43ed50b364713286af81ba67c28825d11dc5d6af15a294f5ddf243f796d211c795c929a772e9b3115e5fa49954f286900",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xa6b55790589165f5e48efa07619ba028e9bdc4f6a6ec0c1bb2f7dea6d02170b9",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xe13aa491abbc1252dd714e7ca0e55717a2143eaf",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x137486f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x456a42b020f7d0988aaedd6b8bc5dcf195aaba71e8a6d4c1c5613447525acdf4",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x224683f28c14d36530dc919d951703247548ce91ae140c5fc8a7b3489f4a2539",
|
|
+ "timestamp": "0x6ab8ee1d",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa012ea1a0aaa08a0c50c708b7463928670d219ff6bc414117001e66d956d5daa5107f2f71f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b841196830b478ebc34c8ca0303b8c00d9ef2a52515cbe99df479fe91ab0b7027e1a4762b6668712d0d9fac0de97875eed0ada682dee31778a78f365da50a08434c900b841efcc3ef68bd2df5a72965360ac621de62eeaa9ea75832ff1a930be226b9de78a46f892f2845e59a936c0d048fff200d88ca7558fe6801cd8b81b47e6d10c3f4d01b841fd62ff589e0e3f4a6a7ca88c7bbb7ca0c248225b5723bd2aec0c799acfdcb2d14e31e7325b305443d8f041c24889a5d8d2a23bb96e44d93f2b91e75cc0d3b26200b8413f06b5c98b36d660a016a0ea6c334eac0e23ab9de0c568a71480fdf12bf112443e754c563b59d0b78bb8f87264ea8b78c9bf6df3b9698fd3fec3b5988ed31c5001b841eaa1dae58412620626da5edcca43e62f89aac8409573086f01b2a7e355bb505255072a07edf9c12a4df988e51b2afeb22e92f6046ac05448463531c5400ec49101b84190885519900ba3851b246f41eefaa8463bc8a16fef33e70fd36cb8bcd591bc784be860de1c044a9f450a83a973f602215f095c6a9203fdf1d892596e9abb9f5500b84176ca8dea9d3a943697739042214dbd7d1151332bfb7845a9878988f36bbd473030e55f8f59839af27c6211b2bf83185b3c7e6dd3449b7fe8f87400c7448e079a00fa012bce02fa012bc9f902930180b9028e39000f3457184a14464212991fe85a3b1f1e79ecd4bff4038494f52649efee23409b8c355b7408b578836134ff1e5666ae481bf65e1cdab56617fb2a966330ad2352aba10f4f61a068783cf92288cd157aa3fd5453b4e91515645d6f51afa5ef2da531522725952911fcfaa0dda8fca51230fea4654947ee90ee1b0d9b583428bd76a5f78af16a1a44e52899880454434f365fe0c998aa96863c9cb772b96a538c6d96eb4b215467edd9ace924211054071635f0f6cf8932bdc5a647aacea769fade530e9290a8459edb18ca6b989da1ed87af0885160797a141359a0f4a29ab6aa70e9c314236f78a832e96a5762e06db6f0bb5fb5562a759b26dca3b81e1623a3b26c5a7a0625246e511d44c6e3e3d08d629282b57e29ae00cfb7bbc27cab5650859a1b56ba4f944ca469d332b801bc1055a5cdfd7556f472e50247db1d7149d5a1d0d67ddb8c51a604833e4856a536210ced4b1d288b4b1f35984720f94cd16e3279e48a35446628443a31cbda8d1db948b8b4b498b031696787f15b243574e109f1e660dcc367a7a87d38164512353b8f6e13db5278fc9d350d818bbd5d0de90af9d927751deeafe95de6931499c59d61d1f913f300ff7788c37755beb89efaad68d1648743b986381c622ea90c4e0cb922305c026566c6cde63ebb849985205b172f0db3e1faf50c0cdec22d3aefc31bd3b5bd382f029f0c1fd709189c376af262a52c299902ed4d71d8853b04a16d72ec7be984b1c932fa7fcbd92e812b475e3727eccee36d561149cf93bd4783ecfe4bd9ac84153e114c8977cda692757bf722b040f84873d47668d0127495bf105a5d6dbfd4a53e09bc0ea92fd9e80e7f47064a272a5696eb279da4974ee64fa686e1130a235b4f2546f990ffbb7e4382bee811fd524db5231fa883e70f91eb50280b91eb034b9ac8f20e931a563cb54889a3002c0330a1cf12feebf439e920fa656ba131a8c73a977b1dba8d53286d973db95af33d4316ec5071ba1911e8fdc66bf47c2515c2909a4b7a6e7109b3359a75161e3893e837ea259a328b0c3f9963b4622c961c53bb3894821b5f252ba467ec962a04f67c024578118312e17bcdb47145269cc758494f2690ec48a806632b0a53af9947f476e9ea7aaf642aab565e6e954389dcffdb2185679a5605865b80b843bff852b8056ae1e371aebb8207df1d23e3c0183e13b2633b8d9bc365f38a689f1083f261913720a3bf11d7c25ab74fe52bd49406fcf4d50c199390252a9a55aa5d9ae79b3a62654ce318bf14748257d4d86b01fc79ae6cd0a0ab57d8d005cff3a9ba77137e6e1119049385911610020ef8a3dfd7c6f8f9543f289ddaa7f5eca814a1acfb424dfffe93ba26084cbec63defd21d6e7e02ceed29a0b3540afff31d30630ac0e6c91dc883aeaf044cc7bc96f38eb125a48aa2a044048ac30192eb6fe26e7bc8656262bd22b6d1ee82ad68f7d1ecef4ea8480dbd8c0aebcd6a17231181b8d2f7fabee31dc63187c5e48f279055523df1806f89a74d36f275c1552983061052cd94b7f1a530b1b72a9b2317fcbf04a3e2dcf5dbf59a43cf68ca733ef254828e2d78193cf70a57f15999e4d3526ab8b1176a9eb917ab513fa6a458875801a39994c08fca7575f2886efc5364bf972d6fd4b31984ec976880730b5e316bc5847358e3bf8905ea2bd1a6f00b70649e8ebfd1e693d3ed7792a4e4e24a279413ddfa5c2f40a923e950a9b64e3ad7d9a2517811f672a8b3d92e75243a9a1ee264f4e94823a50439e845f36646f09cb32fc3a2e3ab955583f74f7e545426cafd093eb71fb2b5d6d8da4776598968a28f7ff5ab84a72f839803deebe739f8d571263ba80fcaf3662629776849066081d970a71db16bc5b3f389ac80530b47b133128d18965c141832bf3016e4e7be2dd5ebd6dd894c771b41ddfaf173c19e34e4820ec9e75fa3666368721afd68206157356230e41875e18e199c88da24b6910280e9c65af9a7c2fce9695c2600c74cdf8596e1fc468cef5c20c4780f89a6298f12052994142f2386b3388037a75a6dff7553b8a948b98e913fa51c25b926933ade6d60945029229ba7285f5eae8bd746e7baaa012f5c5f6039cbf62f2ee1b2f4e4621bf44b912aa32d3b778fbbc9aa3a9c233815013fc66397a7fe1aaf18a23052296f5194334a9dfaedd5eec8d9bd3885e3d22f94b940d459e85820684100c1127d3c32b302f5f94505f295b0e164bdc281a8ca7aee1e5e95f3fd3e4ebed04205527bad2bf6253bc7ba89fe6dfa3cb90a08448b1826d9db731e9d632762b04d0a27597fb713743f13cc3f5f6920d07c4d280cda0ddeae8d37582aeb0a54f0785771076b4abcf637a588cf1db723f8501633d55046dfb16bcec08d92be3ac74438772aca293cacb981935942039d0ba58f6d9d78721b0d3fb8a97be24ccf3340952c5cdb494046b111341af3c74ce45176d984053f32d4a21642e016731561de290f6a5de8f9138e221ea7a51aa3576d7423827ce28d662a4e50972a116797282ecfea2f4ba1920fdd7288624d9105758d88d900708acc81f7f0f7df0715065ff7242e6cb17dbf981d2eaa68dfbda283adbcec735d96683615c10bf9c75d38c84abe748d323304165ae7b3117edd01ff75a0928c231b4fe62d929d6a5c1b02c1489968a419c24323c1dad0af0c27e87423eddae3babdebae7a108e86594497bcd3f5a2ec2d29f98a6aa50493b89b1070a80438e90b57d266b529aa46843f992334316dbabbfd9faedc55c787b0705db549b5fec1c24991cc2d92c508b0f53685f14dee1dca2c6e7b778d091fb859b3c7729aa1af2f9ecfcc7c2e795f7f02228694f7b82006dfe78ff6e6c53fd56faa8d7949da210fd15e3aa1829aa02b140ae39c45b4577d1712b70075241d4849ca697f1be771908ff42705d4ff6d2a04b67cca9edca9e142bf50828dfafc927861388d1f1e905a89a8440910455930eee3ecffe6bf1d14f91facad475c3d9c0b2d6dc79f34af8b296a80b79440d3ce0dd70d1ce2d17da0efe580ca80ba8f613d2905ca86df07e9bca76461d443cf628825e1571112813b5cbdc194079cc0a488c6804bb4e0d733cc4c16503b434f7f35cf13785e6420e54aa23a6936aa6156c524c65a5fc682fca16db10d9be339fe93ffd7511446329c2dd4403477b4d081a1dc2b16de347a1f143de7b4b035423dbe7bd1f35f2a2eae8754c9be859973e4da42498efb2fc3ffc46038a14f69e7b54b47c516d0a57a7655cd092414ce4953bd5cb7ec83bae7d6492fcf9e20a4ba45ada1e42cc11b7c19c02e27017f48e47292f837a300fe4050534cffc660fce5f5cd7e0bfa3ecdfa25f8c899d7411274318e5523490da9c4a39f481c9cb92014e7c46c498dd06fb6e6f09b7fb0c852fb4df23937219a66db5d9edbb5f22e7086c8a13cef0404970fa32589a7d5ccc6b1d4377b2759e5f16683d5160b9389cbc1bbad5f0ad9b22d834d0f7239e274c8ffaa9550c96de92ca1650bcfad733a915ee1b1e90458eb2ff5ab6d4c6527a01be147d433b2f0ba9a080d52445d3345aa83f05baf416a1ba04b0ecbb9604c9eba17f5853e09a30ff84020beb3c375c50e02350445bdd5ccd9e7d7ffa1cfdf101137738c3d2fac8bd8e08e0c26440d7c248618c4819d1a857cf88fc85b9d399670f8361927205cdb73b19b179c4377cd9615fcbd2331d1d2e413e70012bb1a584ad58cbc322fc96ce7c7d835a60d6e577bb98fbd372868662f27c33ff5e1b21db571e2ac1afae39326c12ad9933486c17503416851f4e02c78897a2c04d9b11b3416d9e9b8bf367639fbe2d71e3eaa25f71124ae2ee821ace70906457c9da2e55263733a6f5040e79cd403c3e61e6c250a0909e44d202ee9343ac381643569a032ec5b54defd42ec96bd640afb8a29be69a6864079d24be9590491681fb22a28444726cff79dfcd9d18239101492acadb4c87d51dd92afc1c51d94120a7fa5d9e578cb430336da3e2aab86d785a00761ec56b995ef2cd6181d16811f6d0d73079daa7b3350fbce6d233fdd483b440d0f714e10e384bcb6b365a6fb321c979c0ab30de6f9ff82f1dd2d5935f30478287320929f1c13f7c7c9af2a273ba5bd47f02d6c0bc049fa854276b69096ae1b4c207fea37df1d1ba90d3cc56a45d497b05a1969ee30576bb47ee2f1af5cf33d675c7d837369ebc1049f5be877fd79823028b50ea1363b2f117bf1ab5ba883f7edbaced450fa9764f601c8500f3a2a490791e54f4542fc68b53be9b1d6df42211780c95972cd423c52523e1c81beb5fd2353afd9da18d415df9019ad794e58022863eadf11f1d26ef4ac03c885805666462aa065248560fa92667098655f728295f46494471f55a55c933b34343e883349bc7c5589eb8ca356826b5dabb240eaf0fdd1b0a113da0e46e6ae57033daa6d6660a62964b4f4c6a05fb62120c0e1b00586dc5a8974cd9ba63e6452a0347d47c331717e1d483646a81306f1a82a448f8dd187d1b62c32334acc131d69f9c75f54dd26aabca0f884a4cb462977317ac45c28f5e9060c8955276ae4d33339b53b9d485304af3bd1f69886e8618d42676d110ba9a3beef2c1a6332cb1d6b99ba4f9b66b5475ee8eb8cbbec99bea44dab50f3713f0d97bb5022e440d597b233b431964fcafbdd232b97b599f6add7db104eb4b237f3b0deabdcf1b1f6cffb6a6d50c34996381fe43c860acb19777fd04e4d6c3741f72cd4a73499fb055aaeb5dd312abb5ea5925d6652aa00aa1188ef9d98a1651545e4c48aa78d25ee211ae51f92e93bf4a2c23e6c76bbcc0c89362a0a446c7c47fb05fca83b8f801fe834e9a6b1d9c817517fbdf839b857cc7709e4e9dba4d6e8ed48d746f37fc57c42ed3279e5dda32956f2026cf3e0ccb252cb3abbbbeee3b10e747fe119677e88fad8239ba6721e468b252113702f1562231c168d844ab0de12117b400ac0d577e8ed7d02186b230e7324dbbcc71b92ab57fe1293b266464453d6837a95b1e7b2f333864f17e590b4cec4c34e89745aa97323842d9631371a37e6494c3cc7e5c6ffcc4f3fe3c16ee5d8ad71c8776639a6f8944159768dd8b9965e986444d5a59bb3a05e6ed83bb371f9dd17e33c50cc6a07629e6dfac6871f64b32550bb6f108ec3dd15be28a37bed430bb35e38994a7fd0dfef73d5c2006817cd013d91a36286615510a95fa317f7338ea7ab101543c00caf3e505e6348facdbae7cc1d53ec150db5c0306220f58f6a1ecb5688fdfcd55dc128f6cc61200615b26867be5eb5a65145a259455109ef2f62f6fac5e149503a3b5aba70bcb8e0920d0a32b3212d0cd5f590ec11830c582b728b2291728aaa9b8c1fea9c99eed0bc7f5fc41bb2b21de9882de513e4797e0ad7ba314ba482155a5adcb6a82d0b9ee9008bd5bf7b6afa37981fbdcbae03a4507255dec2561df1aa4273ee55c02b66957f3cb0860d071a51ba553143bf67acc71c5b80a08e3dbf36f7845c2ef7d4cccf7939aa365c2953cee3df25c6a863f6bb532c462c10d21a6f299ce5cfb90a7210c58da7c3fd6a577175ece5ca9fac1223f487fcd272f5f08b7eed0cec1ca3a7b7867bc46bf6d4162e14c49b6b19f61861ed9aa8f8ea35195fdc1d73305278fb5f26886f29c5799bed2c6314fdeb70c3c0cc3a368cbb25088642231d53db9f453af629e096ed7a0d5ede8e58e9fae1a44b4957b906ed845bd1704b89508c779d3d58fd2960d914c1858cd64acc385e3ae02f8400a1f3124f988619fbbfe2218372dcd07811909ab4392c62d45578514a94066cbd05f4c095f736d9a19cfa9c76a2b5df99a6dd50d1257835464f4f40a7adb06f16e9f6c857342030eed7a22eca866e088ac7b411d5586417736efe012c8e75bde909231c9497fe784c918c957eb4d4f6d1e66a495ca0d4cc0d15c7631ebcc68afdbe2217a462b2d7711d6812910f4fcf2820e445c9dde4a80262790ecaeee00630f1e3491afc520997e80e57a9053c03e87933acf9a29d72736dd2ae8117037ef474855a1ca8928e60a87ba6ad2154a6ccd56a88e33660297aaabd4716cc16799198e7005a7b6190c8863d267fcccec6cb66f111c5e9b39501e4ccbf54019833c5656744eba759a831065e932d6c6678643f69fea4eec61d4217a4fb25abaa40f3bb1c4b1ff2639ab8268cdaa97bff2e7ca777a1b0793573d567dc73a566df2c2845119026ebfc8e1fd7c859d18a9cf9a352ca6ffed8964255c893a484ddf0feae266f6c6feb1f8e99bb5e6c6b0784098432964a9943df06be12301a7805221d0ce6997e9d883034a186dd9ab309b5a44a58f004f3da07e8afe47bc18b5b407fcf77e0a881a3f8dfd0ae3dec2aff67763bd7fa3deb7c3599fddd946a9dbda7207aaef9a10edfc01cee4fd363badb3a46cfc82c40a15aed1ab1b83f81ad494bc85711397d8cadc26835f48aded03197c19dc2df42e8eace0e1e7f8f7a36e4b411836ef73d706b8c0420ff9264877d8774876c4653cd7c8e3b322b662273b3365ca180b60e476e967f9805514a6f9853e4b78baa75a8003fa26f1b3923e07589373dfec848bb7547f755d95cded065ba381ffd8803b23d6c31ce07ba7ce6ff323391c69d5573ff570b52897bbe82d0aecf17a61f7ba7b77edf98a2092af358bd69a2de4ef5e4c8422c72622a3e188706e64a975c95b9ca4ca1f9617e3e09bf29bf1f675e724573662313012e22862f5854788d31317b4eeaa33691fa02efa7cce591ec196c9b1fa04aa5d3464c7788094ce1952baa600dada18a2aeb9b49077f7a03c0ce9a0301f1f82d98582effdb917adb56320ddd83ca9f55633f77d562d81a56b7e9bbf480dcd2565fe0e042560dbeca4c553ab9d3c68d17f83b1e33b2f6c2e7f649877be910d9669a804e368bc2cc44a500bc7d5235a3751bb501b2d23ba80ea80dd4729e1ccff69ec29275bc7c1da0bdc58b9ea6de6d559a5bbcf15c94a72f0cb77725a32765e39c1fc97cc05581efde35ed286bc030cca54084d9ae2fbf4d9c4e3afe366deab6ac23a1f7814321728cfb6b65c052adb31a27fbdc6289a7dcde2824bb064726479e103c0c1fe8076cd8978150216e45fee12fbc27497640709b9748269fb4a364c18461b4fddad83cd47060afc5700826abe4cd638381fa43496d2790e8ca532a0bd57351bca233b39a57b20457cf68c20acb19bf9ca7a952190bcbc5a4b994730dccd3bffe992fe4f36bcdb2f0b135c14c8a323b69179e926739bd4ead99a18faf158518997901371b179e796d5f9fe55f672b9b582fba389da9175ea1e8e218050bf8921a99df09e658e1f6568b1f758ff316693658199b3b5fed84b7235697f1998e375c6fa8c3f63614c3977a20d9bc2cd927359967fd6dd5f033a3bf1a1910dd19278580a93157493842d53645328cccb746ad710d84aeb85f6ca0a5330083d010368b34aa975c52baf119acdae588065474d7c797f71d2b6ef312f1a9e776f50874fb95d0bded49c67e4f209f2ff137dc9620220cf6760f672ab5b88c332243d0fcfd1b4b9d6829e51212ba9263004420f96705ece729e64d356b5be950f7b82130139e5393047a3a25ecc44bb62806dbacc769830c649f39f5c82cfdce6b78605f8e5bb46f4080e8f83422805303c89f33b5d63a6b18238a54d91a615e5872cee8c8382553c1465d2e8c3502272473f5b8874c32e8f560f5f490a07026f675c3b5f7444c3019ad821b8796be056753b9b616d33e39e86c2f0b1a6ce91549f50f15a4557c9367e5cdf800c08bb760b3391fcc6ab6bcebbaaf18b5835216d810c7f87255c9ece38fe8bb829de1520519ab512f8c319ceb4be157a305259d6124d266175302ef499b07a994b17334bf7a66c1f6728b0df122a39b65fa3776609bdddd4a93e0b15d1b49bb4eba344df6c9fed3643c5eb61c27ba65a265948bd401d57d969bd2f3fdda3334e1ec7b2d806ca17367ff8abba1c229fdf5cc94fc70639b62ccbf3c44e64d433329f8cd0fa4298605e2237f59713008f794d639fb54f8a29e09eaa2b18389be8dd12c594dc1c43ebd8d76b12a4f1814f87b58203fe288aec9fca6e47bab2cf49f791a24b2aa0853a673296abf0fd6bcdbc34548cb4a731105d22493264872b2687c8fdfe3ff5a1ffe4928b30b71b6a66a76ffd2ca4955ba0cf6d11f10e150a7cfc6d1f4993aade86a307f26ed1055be7860245a31232da52a76bf5aacb39692aacdf4bf59b7f4e5e4d8c4a857221418bc308acc647272b83d558caa5b32f18fcd6db4672bfe409b6a480d08ad7232af18b332afc96eb85d583abac3f7c794eeba22d20f51a3c7d3e752d1176e533c720ad9596982b02dd536e3a426ff1f7cdb3a018a55c35dffa8554afdcd2916957b6652cf303ff3a1cd951016afa7149fa45bc87054e8d6b6c56fda2fa9ca7024220c64a1f4c04f7496d6c54f1c64ce710efd7375c33bb2625eb321308771e813c9bab452f6856b9f5f97fc0144cf5d4075ac46b020c95c1ff2593356664d12cb1ac1f5f8865e26657c5f9b362b59ff43e322b19b5493b72c5a345f7b8ac29e2a99fe5d9fbcc6d424737850222cdadcd7cebf3de0ede0d22d706f9ab0ff99b62d1fd5e392eaf1a8d8991e4524257ea58959f3253dae4eb535f119a94d44d3a2543b41364364fbb63db243d9bbba9a8fe0243f22c43bbbef782ccee5c21d8f0bfe5e8557fb5d22da1036390ecb0a547ec31866f07f6fd8a17aa95524dcd49c56dd97dc38389442a94beca4e47392713e68731833b90cada234067494d38f06732a1facb9c950e4e10572fe2cda125e5ab8b4928da0d52d02370ec8087b6a9cc62d64fc60a804a83e94e296dbe0d68dbfa37d9554a3b0fcba388096e9030da733a4bf4cc7a6bf33bfc758e283043c003c6fb7d6d292244f97f72e7c74c0519b6a69428115a9ac28c5a2d4b955d2f4b4f7ffd3e769cb3a1cca987278527d01e49bd8dfb1f345c033b36c3cecec72edef44a6829e8c5eeed91b2a27713a94b12253ca866a829b20ca34047f6c0b78fe0f898e29e6a25412ea27b606f1d4314ad09a63dc8b536eb9b92cb8b1d71c14da1906b50eb1d9c200baed0dde2fcd007281de9e9e047a5bace43b209ad00f5974567975cafa99c9a66e99190f6fa4a9da29ca139cc47750d54f0c5b3922ae440a8414150ccae64d5ec5cbe94f1df6719af81bc7b557a2c4510a7f4090d6b87804c7d34f6a55a0ac43310208773d7695c0f0b4835dd07e6051891c072911bd768aa8ee4ed86acaad7bd31bb366a3f6346065080d50c20f0469cf2df5abe2b83c20aca9dc803f4d0e4f688376d1efca4184ceb7b1d50feb568e7f0065e78dba744fd128c6e186f693714211cb0a856813ee225840a2e69746ab031072c057075bc55621585b02a82123a73faa436845a75e545089f238864b764ed645be93ee199e4318e28d3ac2ff0e4711642a720c80cfd56e5c027184f9ac340a3cbb32b264d8485c0141c74fd6107fba3061c547cc3f724413a0f9f38ecf202b8b5461b32435cb7dcbe102f61e007b1f5fd2f4900a1089c1b0e2999a9e85c89c2c7d4ac9737d89c7f5365d18486d36d650d18146a81d2f18787ea0d5598d603df75ecb7ee8f9d82ef2bd8c47334c6c6d80b089f202209f01cbc49d3b9e17753a7be59aed6795545d1575d37aff312ba269f6b9a6464c2f1b426d5a20923db9ee8e4c8cbbe9005f7572bb41e4fda16c5e21e9a42c7f2c618e2d7a2c5bd3b5c303e91239a0874dcb63092a0b668d9addf30b06afe403b2204553e6fc8db2b306f42d0c17fd088087d8cbae8f444d9075203e2e141363183da9c8526d0cb412f0d02c8a37b58ab649a06ebdaf29f213e821d75ec699f11e0e3c4efcb4cc7f6fbc46524cfa44cc4635fb3ee57ecb1259061867d352e4188071f01d605164a851938213d19ac659bedaaa27466fc475dee737e3e2f87443ef801ed63da17c2cee7c1414ab7b8ff640b96e34e953126557f9cb2c462c688dd6b52f81bbe5bd0bf9bee489d310fcc07e195c525264032719c2ea53f3fd8e81ed91731bc153833c492bca6a5b6db3892aea25af2c20aea3e81d7504c7a4e7fc3c0e7e368934a8d7fcbccb0fc8988930b9588363f30f63d4e8b549ca75dc2552d6ca99b427fe970a02b0f6a1f4dba782d1052659a1e3438cf271b8ed33f226fab3a80ceb84dd0974f3797e88a4281e156d6617ba040bb23a4385df5837a46d99749a9f1606a2dd809dfe55fea64e31ba83411dc51bfa365e176de86986bf3a2ab9c76a000ba52f686d6dee680c30967f64226cb3aab21b5089dbbd98eadec05798c5d0076991647a3dc5e94f688a46653f113d8011979037d907237558677ab22c8d0cbd7d9658b200d4d6feb937105986e59d2c910e205ee14b1f5fb3fdc14e511e8c5d36a702dfbb48587d1cba9bdc042e2bda12e519c0f2813608c1bf98561530ab06da9c7b652f9ea4fff49397af85bb94fbe6ee2fab221c34746051cb90805b26e083c3dac1a009edd897960b83c948258bb041eea0e88e831c2eb8749b3d2ce5c474e8870d8f90a83547cc263064f192269a95e5aa9cc7b64eb80538237ac599fb1dcb86342d62ea7607dcba4bd11623363c5d62551aa37b64ff65a63fb395c7672518fbb0c1c73c39e1ba35766686916553c23f98ca77518bb0f3eff2b67bcfa63eaa5f390b0e91204128abb36866b73956c5af8cece53f6ce1ffc4a329300044ab9e883c475ba54d202ef23412dce734a5436d05f18fa9e0db90ae31f27b6180c20ac3ee96f2fcfbb08861ba8c4c6f255016e2ed9d23eb166de4f4f018acef998c5224b30be16ca5b425abede5cde0f3c37a873f867cea71e699076c7616cfe7d188e1ac0db5b739eb3b449fea511fd4bf0467d07a164a16b6df25022802666ed1d43b3e89b3a73ccbf66e68b7a40de66433d7568e6b31fe1b0b0bd05f4157b05f64eb876a1f787c0b3554333ea8bb3761548da3feb27892a9c5e0ce2156c0c65e3dd162bbe262afd2135a5458367010ac7b1eee2d443782c453ac49596f23197ce3026858e8af166c65065c90e929c487055260c13ea155307b5caeb1071e6dfe6d357764cc60e225d6d7ff5a7affe5ffb90f8974936cc0bcf2317b01c7c66afba8b1600eb7c68d7a9b4cddd22b0988e7c3970e430fc023365fa3709d597a2879bef7b8d96d04b6f64c7bae578d4203d46c0c0772ad0eb16eee7fa7921d8974091179591d6b44825c5732e970798986d43cbf3e6d668b049454949d23dbcacbfea1c196ce56ac49f8d19b8ee428869d16b1c888d91ccd09ab14497c492dc295debd0678542cca567bae6a8530df34c626d239c662ee3a8704742acf2c17f4dd361fb3bc9069ecb67cfb5047f883f263cec175035f1c7ccd1b4e8a7e978917ee858285a5c8ebf491a769b33d2c73b38d520276138d246f1fe41b0e80c5d0fd2e97653b9ba6312ee9786e03b2d0b0ced13f850e682d42940eac0e0fdca8ffcda58d6139f2d88027b2782a8beb23753d46ff5bbdcf4643f18561a0f0e2ea60a9495d2918b628cecfbc6c4fee9fd6c45a83526aef611418e7d9c75991f4133cbe16aa733d25fde6bfd6068c8e0de86f31a1f9c5f41bb21fef21540e85e7d5bb4f102e654985bde7e204d557a726d01fe93336b6f67eaa2d4aa0372d6587b4651e863f85bbfc548faf9fd9439ff075346d63bb509a961e464cac8a18a768e96430099d61007b8a22241dedad6fa5f5deec0c98db8e315e87daefad301bcc9084f2acbdcaffd9d906f696950c3b16e64939ffa48b87fe3e1be1e41c5057e951ad0d4813efc43add266de25bcb5c8c06db48047e82b9c2ecd338ed9d96443d497a3c894c98de6394f8fbab431649b590b4d4c66a023a94fb7b6d63e525072ca615313f12447ca05de22c052fffae5254693792e5d13a89eb3d21a0726cc06fe91af4f77f297fa8c232b0425ec023bf67cdc27a2188a89d567216d534ce34e919b4e1e2263974bb299836f18107dfd4dac4809d14df902960101b90291394cf76f639bc71c2b700de39a88bba7050a54c73c165042d4875f207925fb8898507f252648996153c9d33f8cce9a67beb5f26213d5b6bfc2d7c218199ddee7186896a359cbd52150ab0cd73cc263c86a88e2fba0926ac3327210e77b29add1d1b811dddf495143ed6799eba750db345102ef21b9d652015127d172c7e6fc25e43e1889373b4686215ac011f5355ed7aaa943f52cffde71f28b36e3b4cb236f0cf1d14c61901d65512bc842b87a6acb808ac4aa0e56899296a42e047f2ec753a1f41645c8395248f6991a32eafc60cd4e466a49aeb6dbd02b1eb29888a670e7a1b06d62e45f0ff4bc6de812889abeca99cfcb7512459e3d738a9e2106358842d079071b9ac70c4a6c98d487e571dfd1cfbc124595713cdcf82a2dc7d3a92d7effff8a3d1beeec7571dd40cd0ce9ed6c99945f6ed4cd6e7f957dad533413a316d629b3035b773c48b4c71f03fdec470ff0da1c647908d3fdd6e662167419538121aad608bf43787239ad8a0a2264e98438839122a22c2638f33f305b2bd307f2cad86e3a4aad42127671855093dd22c0f16651529f9a2bdef6df13fcd1baa8bb49a36d5546f10184a20c6d359fa2ee2a43b379f8d1d3eaa5224d3ac3e8a40c7b5837f3c20e810663667968a9da5c6526ae14d9544a8985f3951ab422245112dad4a7c6557d42261ba9c3c306672b7b36afae8c4a33757c831dc2ed6519ac1e9988b368e09fe5cf3bab30457364db4a573ba13f41742924abd8d4a82f92234589a68ea68ece617795e796d891ba68c9b957d0a2591e2698b22881797aadfee5b9a546dd0804ccce8ca9137bf2ae1d7fc3a299a129c90a82bf75362564f0554eba3fc738d24c296c6b6a7946a3292f8137fc19bae7133b965c87718dc431acfbb722f637dd18c12be77ebee6556b9e472e90f91eb50201b91eb0d693fcf2f3b7a29f3190c860786b6c3c4b2bb2ff61f5adc2d3bca4810709792ca6a84d0527fff7481b86e66fcd606c22b17dfffefc723d22df649cd7ab3581bb49ee89c43a961e5640ff4c70ee0664f8cd5aa35414e9013cf02f1dc2c4c8b0e30e3bce8f779fa50f36bbe3fdaa7cc68206a245abeaa1eb1eaca25311a8890babd65407d6fe1dc88927b61a601f8fbf79786ea684dbf18630aeee6ccc795c426f19dea51b4859b30894c8e103f6d1f5487e4f77cecf588203a01bb244d43b1f12ffc165f68cbe1400a33c9d2dd3dd2596579dc789c0481c057eeaeb9c0ea17d0162be1ba1133bacd27fe9e07005bfd8086bf793910c09bab7d79cf34f39fadfa4922ee38913f399a65512a2b1972514583d5b471dba9a86d5d9218a9294cf1ee867535f18074e478fe059f3a75896d23639f96ade70c2612f90e2ebe4d720ca644fe819727cf977f2249298fcc2cad9d88735e48ae83edea9b95c859ce59fd170b17592384f010f764c1b2fd434078dd62e991281351c72cdc9e99a4bdee172b618e188e98838a56705ea36ec7f6706632a103236dca2977a45558dc923e802aa46464f8ecf741e7f0881214fe56f5e021fa6e7581846201e9febf6b0a4b66b973fe0075ce8cd067d14bd767c1763187839d5d2e04e056383e77e6e8d354c90a61d91e03a72b38fd2c55e124e9abb0cdedf554b41e927f61ae778e41b1889b9701e6d3b13ddaf9ec4d2d3c0a2900a22eea798f981b3e61ffe6062819b9d538b9bec9d9794350080a0f2df9f29d230d04711e890bb511967ad13b7e14a526b174fb9079fcf7e05341e7eea16ba8fb55b001429d109071ed46c6245cfc69584861d81c1e9199f419d1afe00d0bf2afec9662bee10ccaf65619fec0d84a7c177ec266361d1c46adbf01b00374ac7c50ef049fd3de1d4d167880f15f4e16405d06c3bf1dbb80a5e0fd9f30231f54d386cc5e2132b1824b091b29e9d009df4b773b55a41c66f7c9021c1ade7a08ee17abbf80ec33fa8a20df896ee6b6c8c14586d5491c5c70b1aac1038228126bf2845ca47a07fe2c1e3a0ee7d56a4c1ad35c1c2d570ded868c775839168bde196739bbef3f61a5f76847038d88ddb636fecdfc21aeb6f7f6517d545edcdf4fafb1b64ba58315fbb299fb95e27bdcf22ec8159dcb56ab0d808c64287192c92885dbf97fedbfc51a1a7e5b082ec60d29541a022cdf0a1200a8b4d78f8036ca36212842fde022da2f48af2f71f6a82921f0a7b85b787c99e32d4cb2c3fc27578b030c0e033b3fb3b1e124f614ad2dafa8df013ea3b8ed7c27ce545bdc6c351082ff8b7e8c62ead11d07b5eee38ccf6536cadce129a08d7484a4929f40129bccea4ff5cb2e900a2b5d55b125f85b9490eb0695d5c4c861bdf30a9ca475a39814b34ea5d126ad11dbd5a3f1ab96ed62566e22da12ceb92d014adec7129aaa59c661f66640a283b8fedf480fab0d61fde1a28b32cee622829a334764d302d5199ed5b2aa0bb7265d1523835a581cd2a7324046b49530bf9714c77f648a3a3127b424f110db5f31b224c61f9932c09f47f6580c60a703abe79ee6b814792253c643f4313e61526bf2534a3abcb1f3a49ef10ec8a9ba0959b92251fdf814819e679923a20d4c6373217d590e4c62b76e577a03189ce91c906ab857c88cad77f5db0744a5f543ed32bf51d01e5c5e363204777f5a1b4884be519bee0863a0eb8bbd50ff2c4927966eeb5cfbc6a2df72889f6d885a24d214cab2f2fb41cc6205ba30aa41e960300b68f57a8ed5618045b34e5e3d4a7f9766ce2eb47fa075f0067b518b2789f6f5337116e9257434211fed6799d6cdc9f4c8f39c351049854038e66426a8546cc58638a1a4286940f72bdae2d9ed2af48d0afe58e9d2c24a598341a778e36168f52c32a133af02f0d18e5ea051695e5ea23415d33236272886f5959739d5f3b1e4ec3818fb6ca6f22384d40b5e9450ac5ae9a95e68d476e10a8d2e8cac3bfffe40163f7b815c052300c8fa01cd903158c026338a9ef4de50d51041ec2e9f4499d85adfa0caf8aadbf83966f46206e8397c1b85c6a54837a0d9b253ad56884c1f37062a8e3ba952a934f1ff89173857386536f5bae61437d175f39456fa04af6dccc32bb09f92ab4d1e3c394e8446ae1affd87a99b9b715d4c782ebf91bfe778c164f03351acb0fc1efb45fdde7abd6452ee986d73ae61bb940113a5691893081a29eb5ebdffd5310cd2b713b7ccdd0323546327c7927399dafe0bda15ab9839f5a7680f1943f411252369c1e713a4c3044338435b85ce284ea0d183a2ad7b4dcd557329b402d7d82075bf4b7118923885377f634d7e11a39a0b8d0f7bbed3ff36a5579e3a86e72222c13905045d3020f8cd159734c530155f249445c50d41c720c2337f75a584d3fd94ed4f4fd5b836fdf0222ffb6ec9606ac930c7d7136ffa50893445c0c5d7b583d2973d93bc082a32f064e188c01a32961f365c8937c58c0e95fc9168c18b7b476ff45e9b2b76ac5d59ab4f6ce7564363bf4add5c1a55bd9941a618b6d16dc95cdd5bd8dd667a2aec2b64724b2392a8da049a4fe956a69e71e9147484d069a5763184991c7dd7a7d5a995c35280417ea418679264f5215da9b4755d38a66d5d9e7f5a36163e15f33e8139841bf639528c179ad95c7edca4c51e1198eac9f6aa20935a19178e9e7820454b2fcf100a14a3acf70f8b7578b2750def3e192ed354154941f96c3f3074d809c9c4d61622a53777ff2c590fba35f381bc8bf9e56fb2798b063c679c2659886ec03f0c1cad1074a96055785f2a42c688f7882478b0da7a2190f7b4cf7125171817aa2443cb94166285dd79ab6e847f2e68e73741aadad9342d6a9abfc6a4358c5593c32c55145acf500c844e4d5050a096df0a682dadc12f2020a509d394f77ab06be255265258bb4cbbb2c3537831f3b8cb65f076b3fd4f7a7b6aef283378597c8c1abd8cdd195b80ced8bde0b23fd908683c5cfb2c03339729ac5319c678af8cec7d75c451b6227d1ab707e31a3ee2d30ef8e694fe24f1fe15af350dd62af7974fe7cf00b69db9c80387aed3f0c2f40b7d48d58b802c04f9c51e0378c240839e90455fa0ba7bf528d8a85dbe6ab39a4f3c0dd5c433e91e0a91b754d96a9a95f12b14fe954020bb0c8e9f88d11bc159b28c022b570c9bca20f5867dac32b40eae24d38838fd8a5265d1d2271062b5d40c9420d01572a3bdb42296b91d6f52024c7139cd64af8851f1962a7a9245fe5e021b3089d8b5ec42e5fb56e0ea0cf5208a1847967630146cec4cf8733107856ee3a334cdda7dbdc7f4dfc73ff3209494e1034e39c6c6e301c1a8806cea5c7daff459948600a12692374e1b65af4e8a41d5630ce42318a4db3cd7dcdc3c48dc073f16c059584d6f7be1c1ec2b82a2882aedc28e10b6b8c1792ad0f0a9e15225e15052ead0d78f91fc47ad0d259dc626e9b92c4eac8947b74b1260644254918af619f6c4f81aeca1a75b5a5b7a9a9180028270ea00a24bec7c9658ffc8cbfee71ccf14ddad3ca41f5aeb52b4c5132495fd7e783e667732b059b286f617addf3f92625fb576f3867eb67fedd16a6f7bb182563b3e13f2bff2775f5ed5719d391bc1693bc2f1f46554ff3a898d5423e0e2dca8f306bd5f445ab9c96824b8181e2c64d96ba227ac17d3877de6a65b70ac3760adaaa75169ba7ec94e84907dd0f9bd3c2607f06112d4958ea374ec042a034fe97e40ed8bcffb4e307f7779f620be6507e7ba89dd550119eb5ef8e5f36e46193629502ff3a1ab576fe3383dbd210d37b4e2725154d3e828776d5e50d5553b212eadd4ac7daedb907c478084e65a9f6979e3af0ac6dd1f7eea4825c0e894452fcd7917022d0767aed9260dff8717410d7d73715d66d3f659549245b04519997fc961018c155acfd279d6072a809fbfcd6cbde3e73c4f8a664f0cdb1c93a49c44d4e9658bf5c5a58a937708168f1b0c921f9b85f8e57d8788d10bc570791cbc0ab381479eb33de9262a1dbf7b2783bc3745742b14947077883858ce3732bd58c7e59593ada9e0fb68476acc0bc8664f481c770335e788fae3d3699aaedc7940f77b2c13289c5e81970dc4e2302cd190c1e6c6ae7a1c173e2359ef50128e1d4f64572bf0dce2e1f6e138b221939979ef1994fe9d75b2e93aa664ef49dbd9c479ebf3607cc797cdc3199c78c77a696dfc55e189ad272860998ba5b78515063903a30c82a7914a2acc1ad5cba17905a9db86040364a6ff91d83e7d9e1312ac6695aff3b9c9c28141c7ab1b31c4221c305de6744491223df476db0f446e1759f0c56abd00c306ad0e2dbb34682542bc2e39bd65835ed1cec7b6db0835fd9dbbde6bdaaa247e869d99aee2dd3b501845cd39dd1d17ee99252619a61101f000ab842ad34e32ffb8222c319c3e1d3d0864aa045e369247d171620fb33f64780edb07af00ddc2b05d5f44debbdfde7889db2949dc6d9955b543ea2a6fab82503e46f1d4790449d302ac379fc83eae521aad2789e41c543fabdcd8534a86e7088b602cba4ebbd720a335d26f36c79c338ba08e703f780685b578db490bb7887e184c044c6502fe91d31163c45c4f1102e4fd73f0156ffc1325d951861613fe6aab746f0c079f770f78715a3c0481c42bf7303dca6972e89d1da6f9a0e82697023ffef00bc634c02d5bbd597c06c0226464a2882d8738f76a808596cff39faf17bd0ce522619f683b7581727175022da48a52185edf847941665c1793658c8b60e2b6fbb49d0d39e51bbc4c126275a9c993f56f738155f8a134cdb60f93d47a803607f7c300a4a60a1762e7c181ca7c2a78448b10792c152437a5b0184bfe6ca5d99cc6262d980f73ba881a0d888e002713a5b627e2164ade83329d66352f55ab444263a41979f79e036303db8579cdb5410cb2d1adfaa345bcd2716ea32dc9552b4f5569395ded4f59a2f23a0e4099cb3a410cc698c318ab0a0bf679f50e4c0bb58591f971e590948bb61ad91b4f5559fb6abe1382eda40655b1a3e28855bb4eb8429be2470e2143c32e782bd205c09b640055fbd31200c9a16d1a6eb7f55db9c297f43f1bede810651be11c0443555de1ebd94a279c728c1d53855469cfdc88c7b7ff08e2d814bcbec44d2fbf9871c5817f42386d33e94b946a2480e5de002cfb99f07a2e1b646ad17db5d40482deb34f10590236fbc2af371cf5e4b4ef08dccbe6b9178aed05e51c53204993a9ad01653063a138c0b15489931c6f82b59880448f70c29fc7b0461971d69389c1101367bff6db568efec8a35318558a868a8a28507c0990332856e9c4084dcefefcc7b486393cdc092245c5ebd0a67bc3ab136e03a7186375185394c0c0eb710d927b8dea7a11217469f33e5836a5f868c7a343273f2dbf0e33270c494d9ea2e555b7c9965b7fb783f0614edc456a46e19ab387687eb84993bdbbe1be23d28e14e4c0cc3e26f75d61bbc599efcfa3cf54c095da2dbe2ad193151792f72154af0b0c83ec5788819c465ec8b23e201a3089a131e80c681f8cabacd27133df97cbd29e61ffda30e43de31f74b9c69ad3c84d7340cdd415c470d8dfc8dd9d7f5923cdcfdbe9008ee6e36a88fe0c2c45b3804c6ad5b9498705b93c7d9c1a5ce3a6e4bd2972dd7f1ba9acf71ae02fdbeccb029db576e9f00fc258dc04f81059998d8a798ef26d32b3060afb7afb7558e1b7e94c0f5ddbf37ef2cec4e6dba528302996837991ce64d5cf22727e23d8a8a859fb3fc7f3cfc6f0ec87a5392884e36a7add85af74c568fd9aafe85d6bc102de3e4fd4f092f38e28c72314a41c958f6d894280258d5f561c9a8771ac242fd68574f682e7b5fbb39f006b5fae64face35dd4d0d2f4e18f41114cd31e14ba373cc7f3570b698e64b03d8e0f88a2af18ce9b288f3652bd7e8df74cea56a2ed2754283965fdf010f1addf0570eb762a73681587d8ed770533e4ec4f9952a5f07e2e68f34c83a81c7478631d23c922ce22702e0b066eea652f6b71a80de657c4a063bba94b42c930b058f871c09a12d6ece038b92d4b5fc346b02fb1fdf505e5d0d0d8eb95a403116166aff506d25bddb4eb2510ab89dbd594542392a29f5e7ca123a615924fdc057c7e70ec2f8f3ccfab81e00bf375c5a7b13168e0134890b3e66b3b7b4a46613f3716e2890fa90f843e20e3069192b4d9eca99ca4e0f3a18bf979586bc1f3adf401664abf8a4899da7eb0435a6381d1e71fa4083c4563355c9935bc28169b5b2f56da150bf8c8173e992a8012601659354a796d2d06a28a2f0e8b7440212a93b9c6f6d1cdcdb9e6b01acf6bb508152a4be4481aae35e66a50faa08cafe9905e4849b9bf3b80d29a8e8ad5b4e09a63b5e5aab296277722b07fdfdf3f1d6d28f281a5451caa7bcc8747f484317b50e4484270d7bad62b79f776b8c82fc66af3bcc780f704cc7d4f80356f3fe3e03e13f25f386f0d002cc743a13c39b4c93b04e6c9fe8f4282c61eea7cbdf67735b95ba5e8a6f435099cd90fbf9433e401ade5fc3b0c72882790946ddc7607f86d1825f1abd6743f42d1224123be25270bbed3fdf61db60cb8aad785aad9f79c1c7020c52eccceb9b4ef671515d26273ffc8f2a58d5e0a1954e959409941c31542e969f131143bf88a51ead62cd1b2dab69e8d7fae3fc741e421547e05df50d36488f86743daa0306b937e1278cfe2a87d01d8b4b5da691da5545318dd88374f4593b99be7d17f854a7acfc374b1594e566ec65cb424b50a5bc8f2a5c129921e34356b3c80161b64f4a0e0af3006db27d05afed83718f3d01f853613b5a1595c39bd9d811ecfa83de40302443ef72ffd711d68cdbed10f3c664d0209509889130962e19b2adeeab4ce07cf4c17918638e521bce1909d34840ea3c7f87a97446ef78aaf7ac9fa3ea670dae957869dfe52fec0c7428a38c2a5422be1664872bc547109a37269cc1078e08c8b9b0d289fd7482bcdd83c5b6b7633994e33d36edca75c085bbfd3e07d3de6e499490fe0680342ffcfa36f34409a64ef67f94e8832dd6466adb30287c45e490fe8e5e67f9df27628d5a77acc1f0a3acb022e00e04b963752de9f381fd556d4d90b32e4e749583a4ad96dc6cd7431eb879acbb16b47c8d6d8fe7359cae6123cc97cced42929c61decf9b80733b18703548f1eb2f92aef06dd9d788d2a34020f88e12343a10b34adbb38742563889a056642aff330a05bcf1e3828c2789901373c06cf6818b7235879317c4ea3ef8c17107b63819f8582a299a8c112e3199a0e21428a0df4c22e6012781a4bf6abf2c58b36b06dfe7c3decfcb570014855d3fadec70ddeaf33375c47db210febeb3f6727cf33a32eb14346362429aa3fe9f556f92994a0fb42b00b34e6b5fd939a57c06d97fb9b289508b9538cd57de4efa3ca91012d7e9fb2e7a4e12da01db2c23097d07e8d980eb1ac6d7ffa45ae37cb8c6c0ff28d6f115aa14100b3af01d2da63f4c1dd4b26df3a520cd69d2f560d4a1534dda483b09c1a4f89289ef93daf144f72dea1e05d6d8fdebd69e16b3b382e37f2dc27e3a5256a73cbd19a2bd189d45c5fc3aabd8295193110cdd98e5e4d73c888c67d11eff9e05f49f58b4fbc68351dc96f4abc6e070f1652ca3dd30aca9efbe4ad94abf6162c4f19506970a22b3c1c9b055251583ce5c0e7f46e69f51de8e4a1426320636bf19241f41ec808e1a515374899bf5dca17627e3aec9e1d444116152010b175a667d06488392d052c99b9b8e64bfca4e2a97fdba0299c26d481fa1098cec313053f7b6a5afe08632ee6153d19dcb9dc22e7e61c17ec46a7c6a77627eb1440624b46a6eecb1aebdb3846d89091141dc1cccd884fd6f7a2bfa02cca6fdd4e99ec4815878597d6f3b8cb772f55ef4982648154533bf0a2ccba8a69a0017191ad0ef47595f5a1209c2ba5b4de15158a74f441b705029032f33ba24a2d918f1180a9899d4f5853ec5e7e9c76ef6c87f5cf8ee4550863fa5ed88cf5c697ce5fb6e8545fde6601761f5aa864ad4a6ecdb91d1ef4847ed2574825b3ad4f03894849e6be0a722591a452dca0911b232d4a185730794814050c5a2f069f6051e0187fd4cf4de55b1b58eceba0f9f81bb0966a22593060ae32ae21e72165f27c90e122f3dc5ee55e4096abc3647c61918d424e37bf073cc450f02549f2df0b145a97f3679ab5870bd695b3169d6bcc422009faec10621108ba18637128ca29940d59c48f0dd002343cfd4ca469c1adeeee8f9193487f0a9d35f3ed0def42500977f27f8e3a93d9401920d02db0f49ae1f1af6b78efe5026eb47f8af417c7a688539943d38f0c686d0f716f5631ce5250ec044648b268afbce526a8dd99ed03959b28abbb81aa44152867e8c312ded12862464c40b27a7a4ab3144a65cc24e2e6e4c89973a93afd230ad5c4af8d88e0ad5555026c23b4c76500003655d990e7ce80de624e5746868d18fb6923a1f1cb7a2f8220f2afafccca12ff848ea099e0c167bd3370f25c74cd4bac89dd3a20e929e078dd82f6d0f53d3d6ed35c8f7b3f2192549870ce4802c48cb6b3d74759d31bd2996d47bca584f06e37221ba307774088246fdbf213542902bf2cede4ad9a071700d1d01fa71333678198f3f224db2a72de7cde25ee33832e1a3c963ca22794873f4a5933f631e5ed6e23da96eabf761ee6214aad0d4f5aa248c3a891996bb621c64625a93ab86226abaca55d8ee931ca147b1154611f63faa231662c6cfb2ec1546ed714f75d26067f45344e42205406cb3a9f32a3c7529cce543b060506a45cb15e229b511dabca4c3ad4cd1a1d7239bf734821ca129ff16e9367cb9b324b25fc8d9a3d16b900d7d258f857555080c41a78ac98bd3ff475a6874a23533d32b63aff974acfda53a606239dc105e29949c46159448d12e8f609a392b8fbbfdde406fbc97f26ce2991b1400df20c4da83502c5e562baf7a89eba819b0b9a211d08f00a77f35d57e6449231f9af978f67c22aa49faf050ab6bc76dd927acda2d26a87ff5e359b79b29bcccef125f47e9efcb3241600ede21a262a65ad01e361bf276d166d7922bb424303911b05d75b546406d25ba11a51dcddd67585b3d8f9d26cd8fc0edc9215385211326b9955305c257dfc4ddb1f89abee12eebe499bba37deaa14fefb57827350baef73098114f49aba78173a3b62c92c17e9dd43e38e5529681f11f331ece78f07580bf20c4968c83db5a74cb4597e444cb4250193e40fe59cb9d137d8b349bf6701d4893ed318177f0b0f5cb23937bfffe03e5c655b880dd6a4e35170219bcc4498ef38e815cf3f7339c85c2ff7648aa94ef43ee03f7ab30ad1cb2fe9fdb77482b0627830966d5c88089e14edc0a070f94bf38d920fb83807a1114fb46170e35593a470dd041146724e29e388958a58a2193c827d0816911c4bc0d50bc0b5c2593f2cb1fe029afd67ce3bf0879d5ce467e53f815b6d6916e4cfca3487a6dfd1403c0a86862e66e09ba4edbeebb59302fcd944c2e202db9063e89693a12cad54884718da46a4c9e8e56c88e253eabdbe530098bf1a7b0813bd33f91417708dc744cb8c5265cb8e8d170e91d0356bca493f517ec438d9ed6061487ee41efdf6c6cf7e425a468891f6adcbc3f146189f6d3884152be2b42d24773242a1387f67131aa93d9a050da84ebf5fc9ba1e199bc0c512a4abf357a7977b5d360bd1ad5a2d78a58f58c09dd018b2759f370d0dfe9c34dd11843a025a1815a11fe5ba36d40e0c194c8b0e08f547bac24b42729217fa4c2e1bde1a28e90c3212ab4bbfbee1e9ddc7bb853f9cbd7ef47b5ff2e48fcd1102db5a4eea43c974653651cb89343fc9ff384ceccfdb0b6efea5d162eed63b7fc363dda9a639ea36aa1ea3f0bc295221315703973fbb453ba645d9fb744839d28539d9a57757a76c2655d23df04cdcf952eb55745bb8ca4b2bc1a22116e01a2219f3bb9111526fe79c9e84c656819b1c89f1f81e4b66c2b4c2c63ef386ae2695f118565f01b5615eb52eeec15ceb194e5f2be7fabf0b36e8488de72cad17c613f0755c41c10d36916cdf96281458b8a3375f2ca7d6bdb025f32400714e55cf82275dd8301062a1bab181eac8db0794649d62e3c9aaa451da9a236d13f821e285bd7a0b7267e155b3f0c9c2bc6aed95b5dd1c13e8551b1e37dee35dfd3cba9ab94098eab1e2d0059785a6f39192154e4ce32daa52b1ad5670553bd71033272ef620108504c77b19673ccd94ac123c0c446aeab82c3658b82d61717af5723888970d3dc2dd0a9a35e15901bb78f65165a4f95ce4c49084b24a45911e7f38815fbed0b7cbe1140cb6fb5a206fcedc4791ac1d66a6abc40eba7ea4d9a016f06b4d8ead1033048abaa237465d6e3e1e0d6d3f6e5091dc1aff571dcf771c4d3a186bfa9abf3a0073050a22fe67f0549dbd5f61799ad7b75b35d9b53fab2ee69bb9c6f6188fa19ec0b963d9fcf3ed9b366ac93c054680782f5ed9b0b2e8fd3426728d886c22660dd33fe6fc98451bd236abb57d6dc8349480ccc1fca8a6eca1bb2583d16456cc1af4d8df5d936cf616b54cfa0675aee51a5d87d7ab070d0b5aa416eca9ad103a7acc8f3145f74b73add49c951840412b98c182ed821dcdcf7f303496863dfee54f33550a1c56b22213af0c47d98cc9d81d0770568a76e3dc64bfbcbc08cb91718cac2212e5d8f52902c3922b77e0ad027d84b495db38145be138eaf30cb1f96f9b423f7123f9334516ab4df289d2c42a0c97b20636079b4a21dbf198974120d966c5a07ec895e4b6f2b6ed4587296800680fdee6d5d7289a12f49810c49e9f31293e268063629797afce05819e1d36daaa63d78e030fbe48a54b1cd5c88547905dcfdc64eec6478163483369e9be607af7ea48596089ec641ff8084dd23d001926b88b0f728eabe930d7614a3619208274cafeb7679a01ddff9c7d551d6221b6f0fbb5c1a9acfbc67c9525e4e59c821d48f5fe3fa112ab96d287c3a9576543bde8c0fad46f5a5ec1a968f3609813b97d9e9e094613d39fedcf6de8462f33a4150c01afb12b596d266d7d4968af93baaee277e7e60ed1e9ea95af902940102b9028f392e0d01d414746ec2ce7b37fc5fce40d6c30ed191b8bd50536e7ca7e9703aeff103d6104cffebe92c88b9132c9536592bb25e939f9a6dd1df9143b362e75c712eae362f68c73a0a9956c4a1a9bc1274451b580b5be8aac8656537c966b27651d26c822b68d3d3a5382d11585ed9863fff3c4727b9657b08132d4268ebfbbc0a5fb7a36db621df5c81eb6359652903b5c09692a1b22635a5376c705d4f3c5934821c3eadcf3cc4b30c7b0291ce69dd7be121b744d9514342d9ff958262a03bd44b32dab71b747ded481c6d5f8a332fc32349fd059d791d0495d0a8421494bf9463e3ec0b2908d769ca94667682b0999936da36cd06475cfdacc9ae10823b5c87b5bc45ea76e4cb979ec4daf528352719205264be2d329ec7969143b562e80cc08036ff0bca9d196f132a7a43c96e78787194af572295f48a86d137b12575458f13387428d1b134177335f8fed1dabab73a5cb6fcfb48d7d9c6c5a490bd349d11d0bd2edc49e837b9c51a8986b172b09a56d741b945bbd2437448a5f4977b359384715b86454ed4e1a5a8c231c6295824eefe8c519718d687d1b08332eb463bb3f8c7a669fced218bcc7f518edbfdc971a42af63d6e81332e4b7df35eef3207b5a66f6b1cce49a95b2c3418ce2da140f79de2b79141711b16f5903664c4ce300556857ad53b0cabc1a347d7c43ca2b333dea4b84a6412135f7afd756c48d4189f7e6a3e8f2e173ee443613125477f664f9a0259dea6330512a754c393f321a2aa98755e2b37d9162c52cada33b254596fb1694a21edc4ab52f4a3c58187b2ce2aeabadce3374f3f2b3fb745a8fb52858330ebb3c06f17d6cb97634d39c66fb093c517953e6310dec90ddee95c5973ed41d56bf7d565d3f744236933778585b25d49f26f9b62b249f7c6614b62e2cf74f91eb50202b91eb0707e59c02427c1aeacd1eff6e82a5fe5752cc64f6a23f320d5dad087311482dff8b72de4d115785f1e0555c8880437b9ed6b5e97a002f66413cfffdc7e7de9985f7a5a13894a32f7dd86632b38778b74643b13ae4fe3aa076af73de32c8a05b284004fd8cf9a72568086c1b9b5ad4ab39fa1df6250f1ec8f0fa9165e968e328319c31ebfb0e0b2537f3699cdd604911f540e6fb1ba4d56021a892dd21ee865dbc66767a65d961cb49c1a3c5f9d541dbe286d64a647084327d6118c7ed146c99e421a615f19faae25c4ff2e82d565cb11818e68ed9c31ddaf3c74b660467bd3b6cc4fb76971e30b811e89990fec9e96a3789b39e081d6e370854b7e6bd7ebae8f8794ab0fd289af1685a4121cc9fc381aad52aaa740b5ac0060e5e84b2b437b764e4edbaea878c5c6e24362e64dbb7330ca303473a50d7830fbd76d1e8914a4c2b2a09b86a6173d9d22bf0b6a614270f5d556a7d4e204139c4b578415abf3b48158987a3c3f81647e13bfd805ef029d0c345af77794312f4dbb0969f99a609d68e7c38b95b78f19a015eba2a0c73daeba809d864f67fad356cf010df437512f5a152a9008b47d2e07f1c871d9156dc6af92992c28c5677197ce3111e9f3937c2eb0fc27f5cc2f20ca93d031976706be47c77ac8585836e62d36a97e232e153186569f55e87d0f18f8b11ce1f51c6aeed90f24e71945ec3ae8d150e8f278bb9696dc4d31139db2cf8ff30e1ffddc462cf3ee3bc67f9181de7b36d0b4b20ada38ad840966835ec5252f4d7534a62603946883d06c759b648cf12204bdf08d330d101fde58b9008e21c344ac6b59b879c140e752d08f878bb1e4861c0ee291b2d8382f2cfa964d642a73fa3a141c97d6f113be633b4a94f5f3d7df916354ecb273fa489e87dbe57829a4862e8630fcd4ca42bf66d0392b3c726a8cbc57b11732db5616607a0c98ad3dc9468a58e2052f3158a6f8a8fdcab295313d4556bfff136844be78a7ac96077293c57ce6121fd33b82cd22b9befd8f825ef5033d224ec37a412296dfb9ea2421fcdf68b862cdb254d7eadafe5c4e994be0170adddf602dfaa39d629b6c2dedbebce6dab305a02141cd60282d9c9d0950a518fb8b05836183e62024b8f94b85d62995e9639c503796b539a5c720632fccac4a47504aba89cf45bed759f4c77925945bee6aa91304014b580793dd380f7087e8f55075e70a22124c2c81f4274528bb18f01efa985e76673dcb9409fbba43d2b1d4737c7ceab93d8db324a1d1273b0e8633531025283cd48c5b9102f47ef4591c5094477a3c82531c480a2d43afba1f613fdf64aac9aa103a9310c2540bfd1a83cb50aa290b59254ccbb04915c02e4c9d53eeafdeca752283f0574537e8d19ce0fff4d95e39df374910fd5d463c9ba312cd88aae7b5f37d1a1317312795256d39b82497e1855d760fe9b445bcce84aba8b0dc142163ccebb239f82792d5e5a7b687c135565a0a4f5b9a5b7c7b05eb76b751a3eb9ab49fae0ea471cda257aeb41bbda5e85837a57de862341c09024f5dd074c359301d31845fb77c4f484bcbebad4ee563c3effe1178b1cf93790262ce0b7595f7adf327c6865f2e7ca3c2dff727497e71b062bdbc04b3b993af42282b2dbfa01ce93817792af1de7110089c1a5d43c902312ac81ad51b63ce6c73ea6896ed894b6365748a531fe5ba8b08b4402da70b54535883bc51bc37accb789115059442ccd4ed7349c7406a0262e51bd971819d742d741c923154ecbc7d1daece9cede54467b794692cb5268a19ea56c2e9c73a095d1c5cc6d295955ff723fcba5f0722fb9179038ccf4df36a87ce6c3bf2bb3d78068af4692619b83f51f55ef3a895d4a978473b67b0ca03b04ac662a001843473bf20d4a29f3e7d672ff05a5e3ca87512cc74054a2e4c99e27cdc3182dd5557c802642fcfe8cb1ee741c0d26fadb0b973c5977138339b49b24be4720d9a93092be468c9cba1dd8e001d6e0bc45915458e5a251adf57ba7199e2438c44c0e85fd50f5c3ba515cb303ed25a6b19c575e43c8f7c855e30fc53237a77d1e73b0b56dce0d5ca9368a7b4ae1dd04f79f2948a1c720cdee171d9093863d19cbd05d264c7fdd830c5f7ff79f0dce541a70f5c9b9b1d79135558de565f4ea07e89f5759300912d17f4c03906486ca5bf7e4c0e8618153d9cb487c6ac983efe1ddac1c3e18ed3c90fd56ada0204bfc2c018e7a1edde483b0929ea1ad3c427bfaa9bfa2a487eb687c600a8b76cd8dbd6330a41a432be2f613badbf5fba9b6db92890f319298d2248eb584b3a0c3260a570dd5dc6bbe2fb7e32e4c4241220626779bf377abf168bbf901027c40dd1157a58480a78ed206f799a079adcf2c4568aed2084dc0f3cb3fe2093541297535da9de72f3de3c0c6fdc7aaf31a588050d32a514c8ed82a769bb2d91449d164fd23a8bad25e08166cf4c0e640136262081142952ddfe0b2c9df031e614c973c6cb8138219d6684d8b21ea2ffa7a0595f91658b3c288a547645e075446b452c59312f033e2762f4960c2d12b4edd9f7f8174996e71754cf6e6b68d73ba44291819aae728cac6d8b12b38f09bfc5498c660be8f3e167b751011e8f2188002a17dbcf1fbb5d3c44d7ce59af73b2ebdf588cdd48d3281e6e837a67ea50d66299313d24ea22cbff1216f1cd8503088221687ba5bf9462f67184da9f7acd8256f7c5e47cb26397995e54139891158b0c95612de9f847b7a20852f037d743c3d36d3ef55094f9a163bedae38c04d03d088d5d5dcf8579d7821265c850b02c3f5a3144432e446f6a21ca860cebc0ceccb9cc1efe3302f6811392f98407037816cb3f199c36ab22d93412b281f24d5fb4beabf02c228a2182fa29f08b68f5045fc3a3d9db2d5b7f44433805646e4af1131b07aaf7568daa195cee82d70664d72507b676c2c7844400b661c8bd0a422a63f29ccffa707c810076003e8c3a91df6756714005c5414fdf3f7acf15a67f4dd855fe2c3983eed8700036153e8267f3d9ef522fb6a82b9c4944277c35509760e8346a15859772d6cf729526097d43197c33e5d82f49fd3b7e9d43155fcfc200f955a84ed23059c6b90472b017e891ec2a33546cabce96a58a135fb0f7caa29053b4d6ef74f50db08119656a1adc07c9589957f7a74874520b73852d6fbbb0e69c61e0033855c536fa8a3d9af9161af1cea6ca33f61aafc8ffcc1d6334df622059620fa843a263be007cf8f6b286cae45ae525d21e592b6572d419d0965f13687c17dcc14431bcfcde803c471e1bc2db085e1e98a03639b6dde2ff3c11dcd4ca49169d50a0e42236a6b572b770ba05f32cbb9a888d224bb8515333025320cc99600ec399a7502f50b31e634c02ec6ef90c1c85c0ad7802d2e576fd4bcd11bda503c838a325fbf4581e1c1741ca1111a1f9b4effed1423f18d20ffb221f739458c5a4b40bed88e5b5ca433139d9a8762738237d02a0ee451c57c47a082abb4d8409ce33d61067abbfbc9c3b8ef46ad95cc2a1502e9ae5f436106b1e0d0453998c3e56bd8e141274b4fd548d114864630bae3be0326a2b6d07efd75e764003e6161bffa21870fe8557b86e325083f93eb03dffdb7c728fd0046ab7f082d10680d7445087ca0f203c88e387329f7828982aa94b6d45682e8bf3a8708d45588aac425d2a54ac5f400ea4c548c9fe30b57e3abefcccd9bbb4adb67fca3b7f1553ffcad806102aea2585aa6b4cfe4b2905c1d907b973408b2e89f17edae8be996f310d12a16aec05a9bbdb53ff4e637864ab2fdf3207d8fd757bcfbb0403f9d42fa15af248d114079a7f68eb3f05970aa0974f8043f825b8096aba5ad8a59d720ba7b4f238ede5564e55c14a297575088951c8d22af5c5ac0559df253177f31755ffcf44825ca4a6d4ab311379533ecbf58657140d8623083841b365c2d1f773a08c3202120cf4cc1f171cfd07b3df2e56b4576705536baf9865fcf528792fbb7596c4d018a985a352a1ab8fa4ae98f06bc549d3bdb7a8998dc6ecc53d548ddb74c470ccea80502229ae75776a2209e8c8e020d7051e1026f4c3dce55ce52006fdb5616bcdd448a5e1e02043e765f7efb85845e65f004f378046309a01ab558d81c80306e8c9b9ca5697521114efc0b587b212264989c8b45fd92d518c2758f7fd6d79263c32052ef16a564f5c6ab0f1d0b0b9aed4cd83b320de30de4d82b33069ed17ce716a922ccd17537d6b062bfb6520d8c8b4e35b2ed3a68d797489e29dae76bd55fd86363e32cfab6666e9d69239ea85273bca256e9f4a1e5098ad6437b9191b88e1e0d8baa531142d44b2307ebc8073d85fc3467069f5d86b729885ac005c37b98d792c5eff4948ec3c252444e9f63d81224631b0cad0bbd555dc5464f7a0960e19c2e776be751583372acf2aa68edd7683f4acb749448201f422389b2605979565976e3f26939c44601f142c115575b3fa7f5e429bf71e11cbfbdc68a4bdcd3cbe7fc94dfcfc088349cde1e2ad01da1a72d170bf4a5f6e5497b27c61f172e637922ed5e5b1bd516a5700737626bc7c8a5a69f97d7482e585206d00ade25f5f74d6eb4477f7296109584c2bf175be354066a01c9dcce3fd7b34f4476d5c4912e56817f888af65d52778045d12f6ad081f3ae5114a1493209b1d495f783615b2e8bf9ca32cf8d2535739d4d70807797c1e54678813bcf4f00ae8feb98f5cbec75736c75dc2657ed09208b0dd95d354a3f173100093d1a2a0b60324d211d62dba80c689ecf4cd0055bd88b8758e4daca49150f7235bf9ba9fcf8ba8f178bd20c8ab1786931224dc314d3e1e041e4cb0d6c649282f848efac1e18a523d5913e1b096267d88166a04d8ae08f851728b4db98b65fc5406732eb7d0e3c0fcc148ee07182bc1146b4d9e10761a316c492519474506768ef15beaaacec806ef294b8872af56e57613da43e14a999b1013cf0a8be44387d82d64a20525cc0bc68b08dfa45d62c8c80514738fb4f71f4dec675ef2710766077ebc482c422650f978b13ad8500fea42423fb6b6f6502ca500c28317a8994045bf86a615e354340cd5da2a27be07348ffa11262501792b742186d75d06f3556d6234633a76283710b87265bf616ed472815d20629e8420b210653826b378a8d25d4fd73a9e0e00490fcedb1c7163179814da7b8f6d126eeb13aa3485e188accbec944503bd87475200c3246880b0287d54b4c872144873b5ca5533f88cc0fbd71a256c55e4bc662a3ffaa9c2d803eaa880c9accc9f3829cbcc188354989fe6eef8210715fad8bb1cfb670a4d483f2af6583853b293364a8155874672d9c8ccef20717e8402cffedd2c2a546ed3473d99f0aead1cbe29bda001ce229e424c1c39989a30772de272aa4e91baaa9a8c5b888cbcd51188cba1feb51ff73d950ba75afc03cc78f76bc9827a3cbcb3e581e604ecad28c899eb75c4aecd7dd3c05d87ef142f421e068513046ab917ac79da38be4641b72a8868ba5197de661a01eea19f4f7624f0e8a4ca41e11b412934faa5b7e2194a79e69878e315a58af9851beddf07775ff0b47b262b43c7890d9780801adea4457d8f5701c137e52857ebef24b873dd6a5fc305ed00f4228e0ac9f73692281829365392fb825ee81158c8767b970bb47332ed5de4a920449bac98df1ccd483a7afb4d069fccf46dcfe84b954863a7a5586bdf23503db4fac8b4f88cfc9fbf25e28568e4907dd9c9397266e6c24c9ea7fd71f08c13774da3a94705596b963aebeba2b2c942d90a30920dc05689f1b095d5a924af384c681e151e656102d8cc1d0b3413638de77229dc5c8103236f2a5eb14931e0802232718a84394734d646edf58432924a83bddd2f19d7cf5adb14344e8699964c13f865f17f862a47c2de8f9f94f9fb98632e5ebaf82952ff8aef62faaa02a68b83cb4b3e72fcca5e5ce75f2ade376222a2b7f004c10617686d84ef6177e005c1e0748f6ecee67a7c7bf643be1a69a6fdd7fcbf4e0cc2d13c07a2f2f71a07829b5515879e85663bcbf2e7231758725e8b241b58afa66cf94bb69e0593a8c06ca2696ea273657b01525fe68ea13bc96adf2eaae7314edca706c395cc89136659cc0fd1e7f7b71220e1283a185efc9273bca9b4865cca726bbc32b76c9f9327fb02db8a4e4516ef5b80109adb9337e1336d785543c59a4f7ac647d16f740b568743a5b90455b244e810ea9a3356785baa329973d664f5909cee99fea407e9357634e8d861b29410e5de660e85a3db102ad9a1f4fe40dd3772f7c40fa4576d54a072c24fd14518b4c7fa5fc26d50a309677e6378e68905ec99fffe721a799f7f26d189cd5d152c5a357480c1653fc8d42cb84f67503bb541c37ce9392ee38732a8bf2342e405fb3d29d3db13b6c0542732185aaa09f3050c7ebf95d3d84224e5492365f345b273dabcbd9a1ef9d906b978ce24e9e59e37f8a1fb02877a44603833ec39e46b91f0becdb374156535703be6aa2310a0b12541d72c6b5e3ebe285e1885fc26933353cd3bea61f91c38ebaabcca40a11697da59c9b93373795d93278e23a1a3177a43d109428d5f535a7165d4f1f07a8cc398fd0f725f2510c81f5387d54647fbf28199b24dd85273401f55e59aad2a31f7620e33e4b0ab6471f39468b056e777a2f8adecbb46c26e311094f92d93be020cf2737abef28dcfb6f491b169b14b88e6ebaa0d7029706d8983abc882a1da1a0b22072a1a4be6176778e25b91934c23570dcba88b81eea5d2c5ea9bb33949731dfbd05d3ae4754060922f2f3ed40f13ffdb67542f0916d1dbda0349f2f0778c06df84eddacb697e793df05deb97b86a72f4b16c872ad37ebdc3958a775b5547194d46f25edf35e13e962d9706b1393e30b43b8d82461f18c4668c251e4f44767d15b060463835bf62b93cb36f7d52173435a92e06995267f88a1f799230e6364281e9a4d72d93c9c60de6a1223af369fda8da12ba934e29144388a3629a64d50c4358037cbc55345526448efc93b32a5d6da8fc2ddef09f37b64551e17203105111f0a5ab90a1ea1dedcb440e4841199c5f344a7e73a56d85106be1b181af0b0f8972ea7457721741e69bc53f1a4b84ceb10f6c87da3c92f64bf786e56e2c1427bd95f7fe1320ce7c9a238ed49da8608605f48ca94df1fc81bfa755323313c68fc05d9db5eb603152fd7606fba7ebe7163a4274a3137a2fd9bd81742a6b57fcaf7d01828b886b353f929923fce56c61ca02bb674acc8236fde591b4b9079235d59718b63bbea38c076fd5b43dcec7c181e45676c4a958282e5469bccd4228c23404458ac8fd329ae8bdb83351958a2450cf46ca1d0a9784132ba4c4542877635200de73336f039e0c3dcceccdd82606b69f38778f18a0054b73c75acfeaf8a54a779b9a88ea6469d103c040e2730e6ca075228602abd5c9c3d8d6222fb758f36ef059546049b6cf70f62b175883d086d39bc5f916b656f897627ff2557652ca29df33618fd7a0ccae43df0bf07d05e07641cb202ba349abfacd0f8136ca4d5a2cfc495f2200fb5c6fcf4aa2a03df5f2859a9b49731d992b5d434fe987eb3c147162a67b0437dfc7dd26c5d0342519978faa779b6a52b5d0751ef2f47bec2c2f7a46817715087ffa0bf07db85cc11941e10952f7c14ade2e500d6cdf567d69a18ce3d20a00a5b0cf61d9a8942955f62c2a0f69352329837ec0fe3f82502612de36bc2f47f15106d7e2cd8d559fbc169356672a70291a84c0d7006a9cd8a46262f25fe7b5426fac6fbea88e9aae339b6ec798754e18b9f51a27f830fb502d64f8ba167d6b5a52b4f65c2aae408a4b249ea5e9560fc395670592fdc1b659ca444347b613d820782a92f033bac68b043a1cecde5865c8f3448d3c6cf373454b529e48e3ea485d468c2f5d2ed4afb5e3abf33df7f25313e2bb21f9a8609e8becb74c8c693a1e62fac2de2f6fe479b723c16d13f509e1030337ef3b6924029ebfcbd20bac6149193405eda74b8978f0aedbe57dd37dde2adb1a3bdd5b5d3492bf4bf09b017ae2b4dd1c92b370016a51535f79fb34a2b4d6a1a878c39e6502ce7060e3c220891e6d7d36cef68217b567f2163977dda2faec06174454ffcf28941e03fea326614fa690924322222588453fb0ceeaf85d953c65a71692ad04c1c89b47082f214021b082dcf4870008f772ab8ce844983fbc5a9044e030e667c5be9b72d564f1ad9eedd6f1808ac33990c3f7ccaf207917be1a01f56a285bfff2a4b75174b6ab65f63a8e5862fc166e1379ebf32f49c0d1d8a4e8aed5998974ba540218dd70b61866483da575e97f4b819e40c1c4d88f1b04166398a921697f9325e5e352f3e260bad83d185854afc5e13e06be8f504e8682cdd81410aab5a275bdbdf55ed7230906e2645e52dc4b840a5b37f40f893165a91467a1a39b0d3c714200ba5677e293e79590103335fd2d9b95a8dd00b69a7d3d8361263e686a5b6223d678a974b5cf09eb153c04e2a1bebc0cd30304653c858430475e0fff1511685c504238fc92a614eb97eb3b8480a99fb014f9adb0e3443a8b5e86b67229012d2e4295d421e01dd0ff756b99b58fb9717a52396b42ca313e1d5a7bc09d3ca5be8492515a811e1b0e7deb7e4ba334086000c0bd804eed2b5d9976283f5c484fe5af1b8e290d98afc96ed6f6ec422056347eb25681a702dfa82eaeecb932c31468282a0cd4b8b74d18d0f5906cdaa42ab56d9cb1bcb2fbbe402622c59966689f73ac46e95d4faab564905add6bd1538a54cd699d88d35c4a53420ee16b09d2d33387a6172235a963a637e712e6db892287bb223a62edd688287b7c295b635eb57ec25e19d9be1cd0f9da20e86a6955f5b72c58054eb41aca326f689d2870370732826a32993d7eeb47c3c95d6287c49e6a4577a4f786453b5198ec5a1d9f0819af11c208035ebb0f620de54ad31e356c78c350b4c6038587d5f1ef591552b66a97dbed8411c578aef7978be404e8929e3b008e68c050c4b1b2888d458e80f3e2d7a7c6809f8b8902fec980e3a1cfab4b47941d3bf97f73ec0594fc962501579f423ca4e129d509839334f52ecb6835ad889a2b63994917a6e8198169489a1ed8fb1eff37f90f181e4f9773a033bc0841318da881519d09eab59b8f642e89b849d2ce4029df067aa0c46808ba79b1ad5126c071a69297a5ebd6ae9859712bcc95c57389f1941602f4defd4454d17822cbaf85d23e465dc5fef6d136bbc073c735f36f67a4860e466743f1b7669df8757f43a8e4591e0a324963caf8be68f9ef8c2985474fc7b3d8c1d5e3bc264b86583b983267b9ccfdb397601dd36bb89aa7ad9aca56300f4a24e478fe881927c8d1f300b4fc4d9cacfbc51b2165e4daa017efcefb6aa83396f1be9615f47e030930800e16ac008c21fc66b88f3a81eec2778f2114cccb4444541f5f5450a142c6803563307db5ce0264a682afb63cdbf6e66aa1f1bdc29a82e82c951e5507a1dd9ece7c2ea8ab09adc7b0d4a95407928897bf2cbf391f11ac35a46c962ce25fd10d3130838655c5e5c059643069145c3550eff7d14762fde6e92ac7daff1f15b7c67a651a585570646f8bae77c075f89094dfdf4439dba3258777de5292acf14e12aa08207ec36b641b96d15e273bd1c9bd8e4ba8a7f13e7919a09cc45134b782e3bfa39d39a3d35692225bd45d67fa147d683b2fa4ed22138a8314318fabbe393bbd338bd608dba2be66e0d5f0b45794ff60082cef762397230374f289568bbd613735233bb0d5fdc985beda678732bb43b9d3d259386e77be243de6d73a131836df30915bea5c2836efce99f94470d1cb7aaab396f9e48ba8177dc150b19445565796a637d332da2d8ddff0db0fafc3bf28e739bcacfd39b66cf28b788f3fdf05581e112affcc5541bdfdd8f5b42eb43dc3c1f23f89be593573ddc9441cc8ec16bc013416b728bbcf6175aac1350405acb7833b5f805baee57e50c5326a9163334b1e8c0711199080ebc89931772f33bc06205487ba76b868318767c348f07994c2fb2fe25fe94c528b2d04f5b17824a43302fa387d79094feb20b8a4da3004065fc51de3b9ad18f514e316e497840f9f4efb3c1623ad505655659852e3a6fafc4dfd305b439ea557384523e6ba17fc3290fec1e6c8ded907ed293034ec6dd5203054a3afd72a2d6ad804bf69826fc432d5859d82de2b3f888eaa899ce78d8776e46a2e29927c3cbb11918d51ca05d8a17e1d0f2cdfb82b6e42539644e7367e6922bbe21106cdb780df0ae67229fe84f6dac3dd81966da3a4eda4fb222f33673ee2ee737fedb33926c599ef108354e71930acdf1c57013edfb683c0ca9181de94e714745d257463b3ffccf0dccfd130f711bb12532f8fe9c5a7c9af115d982ac1f85ffa3531c230fbf8a876279f1c29c2e2efe451d9b1035f2163eb7228221bf245ae2d85918131f7607c8d51a850dc5365a447515e5381a0b39eb2a3709616a721fa099fca45fa8201c1b58e3408eb0cdde4fa675856a278e0d5a4eb94fd53b597833ef2bd26d75be532e0efc2903aa68ec0e39e67fd625d83530707fe55a43bb629f669a959d5c6396d185d2b2cb435e3dd3e7659cf5afec03f45777d13a24ce600269af661d7c11205d464a3211938e1ebc02a736c4908659aa2f9eabcf8016a2488811ab1675765ef9f335280b2e0bf3813a723918cfc59f6cb3c8ab808052d2dde8542bf3f555d6469b363620f14c87b3198afd459bbf3dee05c915980d34279ffe22482e7b9617a8cd750cefe4780e8190445789e15ca9e35493a33644aa864868b1f96bb9b8736219b08c89187047d0cbe2267a0adc9375562801c77a86afa2ed445038f2b2083350621660b755b7a7b874e74d7a9b6ca23b4238d55d7a8d242d686b12d485e43e0d605aedccadb8262c5d7f177ce4fe834a34d8073a1d9cc99356b45ddaed7043cbb2299d7d7ecb88f80f3b6f5cce704b97bca5b9784de44cc97fbc1ae717562092c829a35a8f00a9ecab104c5ef5ddf7106e3438436a52349e0114e32af2abc72334b648d57df7e0a71f9409190573ed2b018ca24c8b61c7eb8f1a58ab8f5f902910103b9028c390f44ce4c83e475b522079cf2e3a1435414260b6a02ce58aedd9b94dc4d73ad5ec48e345be63428428b7ad72e3ccf435edd296bfc075516e7b03528c414d5e50d135849756901829346efb028f3b156d01392670621f85f43b196d10b0e55727d607285f158f9dee3e61b90d3e8d7dafc009060097a14e07b646f460ea1a9e523ec0c460359b2604d8ac24fcaee5772daf31a44dfeb9764fc1695e55dd662e0daad951ab3268ca7b37dfd337086148d2e961cd7f328686cc12e64e79d9e390facdfa6cd345e452636892e3338b34c1bebeb407b88b5e57680a7f6fa26ffbad6ec739a0654220fd70d499e31464a5e4c310edb1a4635176c6e6e75013b858639e39012592c8781c78620c463d2ab6d649528ee175647e33cc879b89f4f0a472744919b2ba9176c1cdd498643f07eb7e210a71fddcc9d128a6aaa5cdd0c065ac15390e2114a489a4dde10436114a6e9359e78684e0250a4d51e971299e94778d605f1933569e60497ce659bddccdf16c0b746d665ff6bad49f38fcf53b2fa6435e8e16a13f76e038a84268adefd8673a4f5df432e69bd0460ce666f163385e30af61aeed62ef09f6ac9cb836abe6d2e0b7f0b2a99c89e2edd1b89d7f061c39b5a1296bdae8030c4c4eab1aa1d372c8b529d2b8e9a4381e9a6fb8b9d2508e9ca123f16f2bf923dab6efa8fb59b32f73aa41d95579919c51221b25925ac143636f5732345af079594e5daf5564b4b68945dec05df835e1b98031bce7eab02e7e0996f2faf4d0fffb8725aba49c283af4c441579c279e27a64af1f8d6e10768f4f8e62d1f275bf65dbe9245fcd3946fd29bc5c811d04e9d2b1d0fdbb69085e12b3e09d959a05ce3a86a6cf77db92a7acee5c5a28cba2972bbc2af3375b6ca9468ec70e6c5bd8a59f692cc432f118f91eb50203b91eb0f3703fec1e4b7b2f8388ac6ff8ad6b8c78f7ff564fd0dee01a19c81a6c17bc7e91deb4c2ea8d3f8247d86cdcb516c6dbf21549f34d05c3c2c772cdfaf3235286df0a7b08e62bc6914329718adb53801c3aa2fbad5eeb08d14c2c6c63fe2964d0aea7c9a258683a2d1a747693c7697482b6cf166dd535284faf2ec248d6de9135e53bbdfc907591638283cbcecb9845993a2ab17d9096c1308188c08cf798a201b34a9d6ded98fecf668fa4bc7f73c71202b0b5d53795245080ceb3ecd0c266070d631a4340bdd243f1a8e10b0f3db4493456783845578c2c00e176342bf396be5a93c37475aeff2594e4aa0a142b0738458b073612cb1f11d2f94bc11c59af79a7d55cb76d0773cad564afe14dbd4b4705d9c7de6d419a467ae1e11c8725f148d4d718dd8627a0a0fb8c698953b9bdda34b6739486b1b1d539ebd5d20f29891f59d5c18a652bbb40b0431b4fc11b92dcd3181afec1911165c6504d73f8d03afd211d82dbf6e0887e650c73c57af3707176a73656942b70175d46e80b35c7dfed57ca8af75b647dfd487fd38f2d7c10ffddce8417cde1060a44547541cb46e2d7a39ed5e74b4a4bb17e8c2d2c0d2239c9173667aee32c6c2d6f93a0b59ae8729c97a97d19449e0f915ec1035083c9b9cb17fe30e272ce10cce2d3611084da6018375f731e856104a9998950036d2f084fb4c211aa8bbf45e205906cdf885fff3f39e5a9e451bd0a0a03628aad2a59bdc52e82e7fe04c0ce9f2f15819dc211b74018253f0171f65e1185105acb3b0b21fb511725bf89fa48e3fc3f69060d27b57b033351c243d9204b05c7b17595565ad4bdbb1a212d02f15a371772846a450c35a4d149ce32a355d154528106f52d3320ad917520f22e038ecb008397f7e1b69db8b6bd4e0115a1d411dc22bc3f5d398d1281891c872f208fd770ef444499cec80804885695f108bf5d0e0ac652dce0c869c26f90ab039acdfa2435d58829729a6a55f901f90ea7de6aeccad94e918d54806d3c714259e7f06489e84db98722ddacf0aea03690c116a0983ef4033014e29f86aa11f7465080d34832d47d15b4b9e115f10bcbd4fd3e83727237012953e3d4523a4a6ec558dda131548a7b433ea3d8a4a941e49869c69f7bbdef03c63de9f4236eed21f03569e5223e7db7a58e525d2bd1ccda93304898527f6c16d4813fadb9718e3121f60597b2306c1d0312dec99c6ef2e97ae1e6320f9f05a8cd2653b6e2c7ccf27135524d14ec7d1ed6fd3e6798985b244d0563bfe3b116a0d6894fea7c61f36d9fa634fcec282370f45c4c80b848342782b996bdd70f070b80748ac6846a95294ed36101db3129580ffb469897c9ebb9bbfd35f83f23ae736267cd59d21163e55bc2d0e5dadc995b53101e8ed2728ff76c2633b0d290d0c9079ecf2fa05b1aab55b37e1fd566deee3f6d95e1a2766346753dbf2c67ab91968c08f3d5763a31811b68fd4ca45446b94af719d0eca8a8d57b64032523a2a0ded38807013ba5f7af05d9bc1d0901f232721b104c7b921fcc2668bc37da82978cbb01bd5626321963e0efe37ab966c4b396a888755324c15855626cd52508958f51d1809859bb29f1e8a3394877c6f7081d4d430e467598fb8669718631c5924c82eeb91958a1f38e2aba6f3aba6dfe80c24586aa66c1f110ecacf491d6005ea4020cbd1367a323d6f7342f37741cb7be80c5c0feb4a9024d300060fe0d719ef51a74922736595865d50d1c76ab75f3f13f93633d18a6df36d3bd7fe9709aec9bc3dae5ed6b09cafb514255e7767ff8b6e5433144d13553fc63696e30508e51d7af9b95e021e29f1c26730f4fb4c0afed82c75bbfe5190c5a79beea59785d0d2afbfd14e9c0ca3fe191890fa31f5bec6aadfcf5e7895d63422db19bf617154ad6e6fd0b15d93e87fae4b35eb895aab3379143ec5b11f1e440087b195aac487c09899acbe7fd0cfd04fef6a9374e37e0606bfcbe98971d0390fb465294e5d98aadd7ef96745e820449adda6da431906156c0018459b35082a10ce39914ae9f285cb8b96aa5623ac1323e7ba4917d92ab9539a11cb621734af9f36730763898131e628dfcf0105d1debab40ac98799b9d61965037625add8c29707c70f38d7de6a6f0e5e0295c4f9982975a7921edfee25dda229d7debe0d18b6117e8ba8bbd9da65c7181ade7bfa965ea137355a04b6711fc50bb5590a1d140828c4e147809ada79c15df874046e0020e36197c69faf50dc0cfc641848bc7c795652c5e278f9daeb803a2879d648ee9bee7f592d03ccc7a13805e43e47fc4a665bed9c3e29d8706de251fe53db43576ed1279f9307a8c2775ff1accf020840f9e5f04498e56e6595c07b82a03966d57de66436f864e6466685e5d324372bd07680fb7be35c9b460bba9e784acf585001413b9f6047a501ef1b155d85c0d8cac6858a752f58261ff9a3f0edf501715ef327d13264ffd81433a5348f69e575a3376a3fe7d5685b3b8bbc27aca699c44914c1e728715d14fab5cb7526a09810f1a9854ce05884262be63452e5a176c7add3d7c75540a5feb1589a9ceadc2f0e21dff2c42b079f5a1737b2f94526213f9e4c75698f00295491324e4d5ac23958abecac2273ad6780b1b9632103027cc736d7e68be57cd67d440687c780d29482a7f9d0de57a8e06ff5aac7f265e427d6e458cd769dc8ecde141e5a82e1145c97891b3d5f0e5bc185daab3f421bc35a5f13b30f8b13c6b26d681c11813c970e7f898ae541e6ecaf1e169eb6c680d106f8ff5d2a5da18ca418eae14d55301ba89265934643bad5e183ea803bd07fb865682225b985a053601afdda005be7084716ff6426ba7456023ca504862dcdcfee30a8feb423c6c26061b609d44dd17878472b1cd80be166a8c492e87400208fd0441a0f167b0d630f19e3004afe02cdafd461ada49fe7e4c4d52092f2207ba3083e176d823b57268d9142df4a5cdc5cc8fbae95f8084c1a014ef9db9e0048dd3a5be52ec9b255d59b4291de4ecf06cf86950741de22255c9a6755dccc7131cdfa543d8b8ff4ff9791678de436ca2d2900bced1c87d5102bfee94b7a3e68768a15f53642d042787474b507de17e2c1525f90f8891780f13c3dc0fd97ea2c9970a98be1155bd1dfa2106a7dde44838000575525ada390187c2a0e26bbc600e41b2a49113cc669200ac7b98f934e68173d54e065faf3331fe965e053e4835ea5323da79f53d4836d20cc5ea8621d3f2efaeee9009de0e0c6af3a3eaf7975f755490923f736d8ca95bd5c8b85d96ad2ed4ab71497d5484b9de94329012676ecad38fd1e2a83aeeafb228fba3eca11aab0a18648e8a1b5f66629b50751ef8a8d497fc17cc9422d8ef3d701b658615163863ace557bca7b00daece08f85da5fd8845909ba83e04224644b5ffe3557aaec1701d751977115a7a25dd3b6641328fe6af93980312a554fb49d22306fc0ba899d3f677a84b661ad164c34dc393b68215e67e935e707d95d5d8c2d18084d2793bb7d3bb152194304f4a55a533a6b95ca6e51bcd0a838f2d78d600b7fe4a31641e00351d64e83ae4265b79f58f8b9a949d479049cbc88dfead5acdee407c99133aae996faa0343833ff380e5aa932bdec18df771edc962edebb972fb3893ed87656732b1433c4f7eee2281f18b7e0d4cf7c713bb4813a1a9bbe7668ea09eed5e11574dd7ef211e91d1b4c82b8c6ca150101a91d2ff4b1aad51bb3cde5fd424c32b261e52457d67e3cf332aa49eb79da025fddce8cae7933ba7de509bfd465d7c10b6c65fedea81c6f84a55cc7a84886d6a7290571cb445159a6ccc4a1e7af52d8eebb0870d16b9b02f98ff77f2d45818d08ef4e1a3d05f98987c49c871eba744f41c873ca0d78aad205f823e56b81d0f4ea270a7eaffc4df231254e946294002792eb0a28a23787e2469321cd815aa1cb579a98eea1c7f88d273dbeca25d4b79fb3e872125b5164e0d1af58903a3f11582c2cbdc20a0109a45f9d9c7c898dc7b43ac9746bb19e1c60a753ade30a05de0a5e31f0f55902f24962d5cce66bbec011b2113717967f09ec0fbe2108c4eb6aad84f3c64928bfc960f6208336ec5140682841bd2f506374f07517c7137f6f0230e812f8ef34882b1c4a96b82d2261fcfcd1fdad6e5f1c67089825326eca18d47a71121c7965c5c3d4a329a20303d6c25e1dcbed17f848446c3ff103bae486f18c4d51431b8ea1a01070139aa676fc54c9bba11881172f80b04a8626bc9a8443be47ee41930a8b223d89267f544e258d81c45f380ca62788b319a744c10b1ad66aace3ddd1d0e26c1765855e1738319435683bdce80a1c6e1d294c4308caaf94b909797e49e682ab57b65efa5f498d506c1897754ecee78b44976ee23823e6d64644d47c052901a2c917895d3e20994b717bfd4bfb3420a2ada215d6789a167a24eb7c73193dc927761ec8054831842eef812da436e193938d28c45b781a0a77f6d48fb863fe9a00d1ffce3a1b0942cce8147d85bb2d48a22fddcd5098a00103841cb7fb5b1fbce053035998d3774fdafeed4ddb6bbd4218ce963b90483037be5c279c17a4e970206b85119ed6d752a4ccee0b14561a27bb32d468b97166c9cde736ff1afe5148f5020cf2be47ad411005e5ff461f85a13ae8bc545802c8522f83d7dc3282cd84141801f77f96b7c4fd8177030e73ff2d918cfb88ba8b7547d9aff4e392ab15b719f47bcdf735316d095ed10ba56eb653256b44291acee2d176250719abcd65652f00a6e9b2f89e030848434f5a62bcc1409720aad7a63e073f7eaeef33e8d55e27aba0e7be7b5482f72fe07972d4d29005e03060fa30501ab7c257d92867311a6fd8b39de37a3eeed0a1c6d2aa2f8967c166ef0b37b3160f03c3cb6e1b14bed2820d23fd42b0c18a945a09c09489c91f05d68e9bf22c01cffdcb76b058ba98217ea1a6fd00f7c1caf6ed1c57bab2d2055c54f63155205350539ab27259d5be3fadf1c1f51da21bedfc14b64cdc48ce63adf7345c0a7e2e2c1404eeaf33307c781362038e0eebcd7f1a4b856eba3ef00e15d278e45ebb4c43839b3fa6cbbe16109086cdcaea0964b13e5fdf6e0d639ce57f084ea2311c0e4db1713e2246246876272ee3f0935289f2da673241bee803bfd23120ba0fa49d915837d7f81af950c5a98be181e331bea6899158c0f7ce1d563c54644eb0f29e0316c282cc1d0cfc1b0eb9f725de6b22fbfdc88b280cbcafbf8c88a0641f8a8c8d92b24d18500bdf28dd9c059705e60f8b248f9d51c87dd85908939c36abc93f427282ffee424661f4b697787541481ff59dbfedc31dc256cfefbee1fb74af9d9bb48ac2a8d8b3cac050476c6041cfd55dae97cf5f433c410089929748a353f5db4f2149b2d991c7608867856d23a7581a3dbb6796d43a7a9f7d5342327fc862bf2da971d1d666ea9662b1f45fceb772658cedf1725e59cf011effaafd3163016725239e35d2c4c4b9e72a0d0233529aa4a827f498f3608bc0d5a55bd7e85761749d4350d2a3addcda5543845a791a9d87545e474e9de57eccc62d6d0638ab44c086cb219c1a055637e659a167d9878cfd7ef83ff548216d4a5469fcf7aea5cd05fb380af795e3341660c7a98c2760af8719559485c1733e8ca59e3207740cb9a4906318fc37ee460634e4c93b9f5f13b512684d36ed9a667f46c1f7f1229759d16de8040b0b210f21c77d0bfa00c007303b2c033bc2fbe1c5c3febd6bf680fa747318d266c72ccc4edea8bc2ccf47e2ba831daaf98aba63373e68dc5c3c00c73e3f5db8f95184b211c32d9ad5bc5de0ff1e9761ad87b8f60734e02f9e27e8acefaf729cd36a00549456760a3aedda5ae3ca4bef5aae3a7201b9fc434f6f90e174cd39ea767d37665e4c1d0bd73f3bd403eb9c6a4c834b2ee740363b54d0a68706bb2c3a07b91cea4d52b0c1aa7489a9e24750624dd0f9b1a22e971deb4fc37444a3e2774742c66714d3cf2f892f1146f2188538d95caeda447f3a10a186018580ba80ae8214a7dcb62cf10059f0de6695d9692fcc516fd470e4ea7cc0777d2c99a16a79ab6a72a3ad21357f4041144f91bc8254ce75f99de3870a9b775866dbd13ffdd6e95ba95e9fcce3611bcb035126e6e26eda4144773311f77988a002c18b8febf52d7ac110c1e660606cb9ce22bd8f930e660db4401bf33f458c4e6c2c92d21943bd60c7240b65c4390b7c022fded8da451b2cddf44539c409801d9b54a87de6af67a4e8673cfda4160c971b0a7d020135981fabcacff85d5a2aa5622e91df85abe67201fea07f3ee050c1588d0ff652e92353b7c4a81e41b07f022c6f1c4eeb42794dabacd200dc4a730af5c867d3776d6fe13c095dff6a52b154c58319f0d4a5b2f7a478bd625e6b2366eb68f1da8f14c1ac2152cf547da9e8a6adbfa2cfedeb1b3c1c824a837a6067449eee1badfc9e67beb141a766b92b4c1ea9e5ad4a8d6510c851fbe1bb9d033f91b62284489dabff7a39295f70063fb118710c1c5605600bb99eba598b8c60f7204d78cd09e2e9eac762083a684fd312ec4e19af7fd6d11b73c8ee4a5b1326a7ef740849d90de604f6b28e2db1c0b0862bf6b88054fb779f9d88020f3ec79961943a7b7aef6e08ca9abc20500ee0ef671c67b467ce5b5b0644ea1effac706b856842f4ab538a22f8bc88d2f433903ae1eb6cb4010209abe31d4d68307c811a7e6edd4c5d24ab95950af66626f232d6ce82abbfebf4f15981eef98479c2c07e347bc92aff983e796aa9bd72b957d85b99aadbc2ccce39275c1eff9f81021bf897f6acdfc294af3b3926f6ba48c792bf3cfe41f720d4f6523ad776ce856c4150e5b2c6b921d8eee8cff898e872b904e7d255a39772f441507079aeb8a6bd16b562df1ef4e6d22b0dcd24098b07cb7b3e7477cd2724588399c6da30284cb646c33f386c006ee4a0a09d938fff53e5c33fc5c45a18a84e149258322183a1cf92292f59a933ea1314b005799f5f4a7b022d97c9a82037569a23347a6647f03c9eec7a3483da895cb60806750000274ae465a28d0990e4b61d1b21c072892da63e38b9738f81555631811fda96daa6fa5554ae42fe661726982bad60077adc5d72a9ae168e8e3b4a346290a5e3e415d26d5be7ea64c22a5f371572ae21a3c05d8f857f15efa87eb3c51726704851ae18fd00ebf7a89643421cb31c75130cfee79daa37a913e7f6019bed183dc4dbde92af1050155a90c54feb847194ecb19f39659941c1e8b2dc8698c097cbaa47221fe770f836d53fd6855aa10b42781dd6f6e8cac81c29f3f96a8d6d5ede78ffc9a168d6571b3cd63ca68a5ac9ddd166ead128335021572942dffa03b733c0a4e28bae44053f67c1984871e87295be8072b36bc2f954f43dca07034fcc5056cf45c22f0e96d105f260a316df4ca15c027654d7d2bc664b23dfa4d4c1fab5dd28f85c1c255ab8ee660cbaf5321aaf2ea2ddd42e0ccf598013cf0808d6114ad320460694569c17e296ae62c296a6f82fd160798c48a08629119f4e240ffa024f4e199923bf2b4e1757e80164a1baf951f3ff0be7935770a78b2c4e805b46f9c382c0be3e57a9bfb2a09d41baef284d38f196c7f4fce3381859dc84139b987092eb4d6f466594f03ae41beaf6859c44e9270c916e5614ab03a256aa4fa3936b60b8efc34e5de43384560bf893e4fe05353dfa00bac321980770cbebd13d14e09d53944afab4acda2fefd02e976d425937cfa177206f0a0f3b73ac6373c84ae2948abeaf9ce1a921a354ffaf7769622b14977999a7bd76cc36d39b56ca98684fa711e38f02eba0d4c6e094cd0a48a715cbb16307240d6cdb11c35fe73b23c92711f98c06e5b7fa7e89fec5e8b690cc229db98c4f506ac73b0de4b7f00a394c330261252ceb18ec502a1727fcfc8b4b62331fdd0fe6899c97761c0927f3697c423d45e5c40128fa7228d38118942e489a8aa8b6cd25f5aa003b69577a4b4652408cf5628aa88963a304c47ea1a0a87280737020ae8f686cdba85cfaad7bb075b4fc64c9a5eb312a78fe5c4f2619b02a3850c8d314324fd6f4d300293812caab4d16cc3908a574aab38d1c371a6c8811283575ea44303f52219d3edb94feb0483205c8fbf2c3686bf718730e1e9569e0e43eebf9b575ab43f7366cedcf7f49ec2d528058246a34106dddf3c788dbc5f11dc15fd43963cd829418df37b4bea3b118468a3df7b19b70303503bee0b5f691a8464e920edd00ccc5eaff502cdbb44373ee2c8a719560b9858fd00d60c6275a12f89c6a454f1ae376b4ae6fc4d500af95e86c8ae386d1e675a4eb463e7f00252129f0ce1a439a1837cf739d9b16acd24f35ed5f48e559195bde2c9bdda036bb1443d7b20ee34dae0ff201dbe5f1d3ba026f0d92b36fbf0c18841f0ea75d62e460aa851594b896b406ca0c70ff7323ef4b9835f6fa4461b5a5be5a5556d2c051afe1d2198ce8ef8ea7128d828c5bcfcf6d4b9596219678835687cbe72cf6dfa94b47e961ea7ee8885ee76a188b161697bd3811d81138ac344bf0b36072df22347a966e6085cfa3c4c684b769fef11c050fea10749b9115151f9b1b95dc3d839d7ed8445ecaac90e08e2f6c08b3647ccca04b18f5e5cb89ecea0659742a230ad39d6fa5fac31a4772f7e5bdaa361c545534360f1377b02fc76eaf18205126fd2c9d153eb5a874b4bff067446c44ef93610023027a3dd83b88b3e9b827069680ee0b596088373f50132ea35fa1b151fb7679d9e6ae2b54e9709866a8d1bd9259c46257b010cce78f247300a1edb91294058e29613546c97f1d04718be125a518e3854eb710149dbe90dc977a86133afe49bcea150108fbffaae37277ef70b123e4bfee4b753324dd047e31bc6808c96d60eedaa26b809f8067aed8be349672cb59a4deac6ffa02657814e87a85d4f18679080a34313ba3a265a2fea2cf67af45b51764ebb5ddfccb2b0d98606943c903eb4fb8d805b0c471c3ca817e53f640d3e87b6062a34d62d5740a6cadba4b2cbaf3d9a6ed2ecb59379fd2fe8aab3a6d35538125045a99e5c7088c2ffe5c4d1fbc379c4122a4f22415bccba82876581eb2c11f729c3f7c17d3ab0607f6d75adaf38c93d4e035cb933ee5b70844ee611caecc1e5f2a4996c5b8dcc2c30d9e0022ef7e1c200cfcb7ed78f68b4c3b1ba48611da2ce988bbbed452df23bf7792f52918483b219bd72f2f63993394784c30033e020a074cb6e3c042335b24d587f7a21e6e94878378cfae8c44503144723cd4fa072eec3a623bfcaab3be62a2577ac1d01ad6d5d1c7472df514bdbb5832ff2f5379ebe8e1ae19d7015fbe10c5e3207ea313e899575d9203562801283fd94dd992468ea2917e8d446f4885baf066b463ffb843bf6049ae0489c6bb3152127d689eb2c4abc7bdf7424ad46a783a6d9bef279d833ce648b03b0483be8f113618734feb0be5b66929dec04bd88071f01ee29b6bf29bcbb0a0aa4c105d5593df4087eda62cc2da8821489b9cdc06edbd0bfe61c0eeca968280fe8d20ac98605df828d6baa4e3c209b8d8c2285f0714ad47242963e3324ecbf989e4e2366c8ff2db90cb4e6d0b299449bc26b08f80a9222ae7116b77fbcb727d1a3d3989d54db4c36f6ee5a6eb1838819558df9786807b0759958483e5ec2ffcf3195f11ed3ea6681ebb04508507544b50407638d06651189996a78d1d635951e550b2439f9b470e13408ddc7bd43313637ce14de914a4c0f660eaea28376424aa288a5a64c163754bc9110ddffbfbfd301d1d56f5cc27e17313242617b5efc47018c86338d9146033fd50892d27295da1e84021bf4b98f92e65ba70cd562536c93643a5f64ec253d96be46bb5642b5d3340f8cca52d627596452b7178f4465c3e4b8c203230d273c9547405cff1a1c496cbd149232f53519d23917e35f7523e6eca6af7faea79786b2cd704baf64afea299a599c37726e1f8ddb3eb5070c5b8843020b6c649934a0f0d42734f8889d2dae667364989277c0810882bf031dbaca58d42675e46a7406fca2fc2bef3774862ddbb2a010627269ce32376fa426210e6317fd7817fe9bc36182ec0eeb6d412a8b5dbf656605eeee719907434e30e05eea2b36de67f01982c4b7051d374f3e61e59aa9d39008a2827a3530551e0ccc3dd1bc4be7f1fac5630ca579952c8df039d0ccb5a05c9f0acc0ae6a3e8b564eadca10e974d2505b7446c7833e8a1d40bd39f6b91a5b6d7e2a66fceb7e26acb76b08ed8411cb81c871a627520e6aad91794e3ac5401db26d6bb9c415990405705fc5134b7aebc0ea8fac155c20e0683726346531f2d1f13eb1febdc432fc6abd98867b96d89233489eb8314f41364e40420c265c86a6025baeb0bed2169ddc30ee25f382732b20e8ad4a14494670345d080641d3edbcf91688601e25fcf8ed083d9bb85d99a7ce2bc12f26b66aa51298d302d32492e4e81ab6aaaa2f8f3108d622e12bc9f96a1908956b1991e448dd92812c66053cf528b12c7da3ef9fcf19cd4b4cb6c45bad3a1453f97a381e951e2e03ebd623d4cc9e5e3fb3c8f81070a81d45bc07f68a632dcc7ebdd70c3d44b138e1ff047ca0be4c3f23d4fa06c217b8154c1637dd3484b7c99ced4a68bbd7e6d838445bb6cc8e51cd6d156fec4b81b5653a0e41cc4de1127c81deed5582694fc2ba77d63484324bc187ba8832fb82cd8e5932f9524b92495b6b51391db862ef6014ed9b277d3934476be222379cf66eb9b877011d103c2a3addd76fbf142a7d5c6e8f27fb6d7adfaf0c776d7ee9234419516ff19e10a9b188e62a3732d186aa0c105bc3a5b53c8c387e14dafe534642082a6da7ba7fba5d019871c97701fa13f73855f71f0601d6ad04210245ddc2debc1389f0454ce5394ac53480524c7ccddf9c28d9ef60b41a114457df890b32cbe8889706a7ea547a8e5370576fb4a8ff2bbe31ab6b3b3c44f11d433312ddf72c403c41287c236583421de6649233c0e72c703dc56cb2ab62cd33c176c50068bad89bad5c8d8d95ff74837a1a00ac1b987da76729edfb065a59e0367e93ccee29eafcfaa77b6a913d312cf6af902930105b9028e395b6bb80343573d03a716f787b7f8ffc545ae152ab55271b03416ee87ea50be8b6c99f46526f8c064db8d14fd02589b12d83c4ed2f1ef38c6fda4cfb98c8226d9725d4e49fcd119bafa0445f1adbf333b3aafcfdc7dd979924ebcb37661e86ecfa51a3a5b3de695b9b24d53e4ce088412b782bf93b23b2dacc0ffe57598aa73c7b9ebf244071a5755f97ee71fc948305f248e2e9d60d11d0124fc5df2d46e2f99d5979ac8ef71a62156869b4d189f32f4bf1cb986aded77e8137cc0db71fb3dc3d74094d9c337b0b53a08ebed8c1a1b2c0c77db9d6d8ba88c65e07ad4a10b27ba65924596362ddc151af05df7f354b8eab48e751135b35957b98e7ab26731888bee46db2f94dedba523f1481364a742e54ae1e4c4f164968e99dec39c6acc63795c75c929c06ffb0e752a8112d3e67dfd47f912c499298b007ed8b127c1d3d0041f0a44552da3c27418d9b29924c576dd361622610e1b0224374df78283a8bc18bd11fdc4842788986cd34d61fda44f5bdff303ed68ecbc0631008a97232f3b26bc78b75e856e4c4f9c86accb337698fa2fc15aa23ef69c98611a33fb08a12e0cf8f0e9f149da356abd349bfc9422d5b7882a2977978b70e969ef74593236975331ee64388acc9d1e3e5e699859f8079b5562de56e6499f34ddf11b65654e75b819c7298d80d7bbb71b3fbf6bfdaacd5c0ba67ca0e0a06ca69700b42ef38d7b9f67be653f3ebe548efde0d1c9a3ca6f62ed12441fbcf3bf13f4a6249735e549241bd56c9c77534d0333f6aa7d880e770ca7640e1a7eb1aa83998cf26a2131fdbd51ba9b77f3035f9797fc1edafc87b4d97094aa0c468a70707ac33cc2308936c8817939fb7ebd6d1addccfb5d19a67d07976da0442a9e891b73d29d64b44924756a32adb4489e1beb0cafe38540f91eb50205b91eb0626714279be9a01a691b3ec3ee4ad90ff9446a8b12f99c203f101a03f5354af762720519f4bb9f2e654a3235a0010eb1d166107506911c4bab3b6499f226458e86308c2e60ea8abd7bd1efffe8361dfd056e25e8d4c70508ed706c577058fb52b2dbf3c146467b88063a029fde5967287817a4cc4a9cb31dc26081580c7c3d54dc01cc3c5eb04aa730f23ccd12b8735b8a28e24df1d7ff1fd4c5c13d587a3bd76a5bbdd6f12bdf1660339c1a03820d7b96d7e6d75188a4c034ad140b4ebd1581e43f23be2101547734a07930a03759e02d4abf66924fc0f778f17c112aa2795cb639c147ac566e88f7eb37d86d58d1b27b992d9561dc0f605014bf402e686003eec5ddea6b0fa60d5cb3226c86ec031d2ac793ebf631ef30387f34546a142e2f9733c8a99780e025b49282112b8435c3838ce0bd5073f29da9316e4a3eb3e226f77b38bb62cbd7bf33b7aff2594ec655cf544b918ea79941a3b3dc9ee4595dcf51ee252f0b46b6759c34b6e5ec128657f77dbb0e097c6b969b57c78d5ce39402b6e2e94acb45f84e14bdddc8d71d41892a9b61adac6d737bab8c428b8fd07feab4fecd5fe12fe0a46713fd687449788f6236d94cff2b8fcde83fc296d8a4dddad9b1e639c6e66c4804a0331a036d0d914b8fa2d01057b7cf81b64c7c87c1171156677c8e4e4a05137c3845f1513148e1c397b7007eb5ebfc18cffdc2aff48e324220e2ff64edc8165866fa50b7ef3c155a34dffde9305758040c6e4ba9d0d2742bf33add33d380a7ff732eea7fe30b7d943870693d70b18566293feac447cbb4f935511e6e491a523330503dcf760c40b38c0e655345c6760cf32bfa0e5716b4c5079262c5203ed07f24211c037edb25f2445ad534f5f2ef03ff1948307155d86763194038a0ea358991109738300b833aafba12a00d1f9f030694b9ed8cde75ed89fc8baaecc01a1bfc7c64928f935b15e7a33ef3453cc63df1fe4c18bf52ca04ea23217d3dc6c09c0419684efd6150c303719da9b222f3d75c3617a43f5ed49fad3f452f6d599da9505830ef3b228c30045116f06906c6bc08682430bcc299f820239da467d2980436e85f1eacb8f35576f6aa3ce8463d1bb69a05cdb14c537d16ede6083f849186f02281964549ba8d0dd8bd25557518f96d416ddfcb58992620e701bde4501ad3aed5b44d75cbc7e16df4e47d3c39a6f324b3f99820feb9e967726e0c93da68a2e62701f3d00eebb9797b7d92b5a527ac44a82504a48d9ac7c1e139e349969255ca748470a45beed1938e7215b780a670f587a703a6be417c4ffa99ec9ed80b393549014e22818379c023cb565619be9a006bab208b7684f057051911b4c0758d3243d73260d3dcb96655c746571491d322a5afe29c2546aed9b53a4247d8938ffc193b733d8ea80bfba1efb49da91143fc5d9f877d8bc01965fa712507a608c41dbd745903a1fb319df4eec7985516896a654a837885d0f8df3decdcdb1739e38e33c98706cdbb68ce4126ea8850f6f29e03adde85a67aebeeb0b287416785d002ac464da444f22b166fc0c75ef305641ff6f7ebb332f86794414d4a2d84887a9c650996390dd68c16ff11b9e8f82aa6653ac517581433ed2cf8e2c7b5ac9e784a5560e2e45bac8762d2b5a75e459811cb39cf4af903af2ee9a82c023729fcfc0a2df954dcdeea37a30af67264c016fc0c7d2c55f42b7b737cfad1c3338bd1ecf1071a0ccc28cbcf4b5bc63868077763fee16064701e71e8f2551754e2b8f504b4c956e7a86e6b44d90fa7e500a660ca8d18370109de6bc194d1586c86994d97ea86d1768c2f08d52277019fee80b4d42a5c1e9b93313dac071ae4fdb5fafeacca11e05cc4189ab5a59afe29c1048f9523e2927d4c5833738cc435cf6a6fc9d41b2aa7b30a006abfdea5561074d7c9b1fc6f0ee65273d7368668f15d0c852ebd9e14f7e766ba97f3879ec07047a8d555ec3aa1813c83cf2a3f672ab5186e0effbf0b190c61b8d87f6de23b614ab73380e6fffe029a7099386dcd056ec0f6562800c7f29bd94bfb1d9f3c31afd2b384a1d8168b763338309f10c245e39e64567c5be02322aa958bd03309259d3f2d2a28bc0a157a4462796a888b97a335bfc1d7028da4a6fa65af5ed7ebfb36a0ef9f45722be0b4420fd2444ef99f6bb83ef4d6ec98ba7607516eedbaadf83ab0d7a458e833d1e0435a8504d3d1b9e464cd7e7da0b873cb4a0a3469c30e7150c0c1f88f586e525fb47ea087d0cc14eb1680de0fdd682cb5d5b5fb7eb1a83f778f5abdf4d797f609aabca0259b06495125073c220209be2b4ce86ee0c97a1e65a37f2c5727cfefc3fe42bdec0cb31fb4bef72c5ae4a17bbf5ca9b56a79b29192c305ffbec062d0cbf36f33ea3d1aeb0737e6b1c5224aaeda4628e65d3e38b3c69d8b2771b8d4790928474dec3b026ce6c7733153c85a7c23f5c605f0b8c0460aba1c06e9dc704de67e80c7725b4725a38b6bc049608067ffabfd0fe7883295d39f72dd5467f64f19c3a14071c7ff4776d682089f7c19a8b59d4d6c28fc52f7f123354492b61434ea244c93d569d707bf1a25c23cbe2ccb258e2b9db41c1263431185e7ac310c4e7d0c936600ce63ff26e348eea1d19c85f2fc5ecd51d7cc5edb2774a9d834ab9218c2ff6f5c84ffa2407766af2b5317effa6c81eb04c0283146975e2e215a6dec391cb49b16b96ee6d298c1f594a3884dc4d69d45a5d2b834830b0257a0ccaabfc99cd12da5676eb8df20b0fddaebe896c74386387dc2535e9867ef5c3ee1ca751bac3a7f92f9dc2b1544957287f6370faff40754a5dab45c4dfaa18e0d3269e8004b83109c0767039f7719d7366d030454914afe39316c740a16955ec06c099d0d161ca876b685739854a86c1b8838bd68d02f0ba3f5a3f07530d5bfc542071a3f966321e132e4fefff03954b9ccd6f99dc24c64e7309974f7fe6c7a8d3b503c2b3e7bd020131b1c09c3c04704881818276bace557e0d25c01fbfa9b2cdfb9fec2d9eeb486ceb9c198b00c5aec2fd1d92036e43af6ccfdac12f28350e809d153645a8619080cb6dddfe3d94400ad1601b5919a6793328a796a1421c96346eb87ad5754d442c490677aa7924c757d407045cc98eaaec44f2c79f98bf14adee17f3ff5fd8800c388c3aaa187ef06fcc90e3671d43adf9743b5a3f84357f0ee16d5247ee5fd8fd40677eb9638bf86abb829cc097d41d0e611c9ff86ceaeaa5f8ac718d9b8ce880e1a747e34370d590f311b5037febe1f06da4a4ddb9ea43753209e7c047836430eea1d96952dca43892c771a906a7f3a3885dae2dca522b7d4070c2242a8ecd8290a751f1574ee87e2447833dd519e62364b65695566efd3c5ce04a90fb28a0d57286fc6bde9212dcbb4ed8165d6227b8f36ca668d4cf3801e5f3d09c56e748966786d591be8c2c798838d2951be2764206abd113eacfade8cc0a17b1fd9523a614830cc061d1f57d80800ceebfe5e8bfafc5ee88aa31f8f6ff89379a99bfb194ccf56b08f652b5c5ced1ac80c8f8cf1f8fcac47dca0f70a1c8ba577ee7f17e77ff4b19e06da652f9f768807c240dbd170912b168a8ccf91e8354df13f43641d8fec89d6b79e460483d88a9b1826b38bff8d38a0dbcd135961640b279c0407bdb7b99eca09d6ee3cfb512f8e159380e470f246bf1d5173427c2ac73f0f9fc3db783609b1e5a04b929a21b6949fa212357770aca1cbbb24ab870eaf7b2824d414b72c991da33fa89159996afbfe8126d392c4df5253f8409bc43ec30bcb60f10a86ff510109bed4a52a06ca92f60e4c2bb7490579a053a6b7789125a29f03fc450e2f4f03b3f033d037912df284fae7f9007175ca391079498d1b633a55ec8c2d788308a28b021a6327c3ec7224f485fdd13cad691edd93732506225840cb321e0d85028997701cb146fe4017e9f82879b635b8c0f765071f9c35ff40b9d711254f833ecbbb30de3efe59bf29b940d7b61ff5a317022c9dad2818eb80abdfbd0382e47ef19ef41a1a756157235a1b68c10488c6ec3e3cbeb053a13165ff797e5619a38a0af62df22e83d87c06c2680fdeaed82f7e7d214011a5b96470c7f8827f62ae1748906f8c2b3c5cef8f23aab736346e69e4b7678b67e59f98e646a6a139609638c9eb7ad41dc7b21fc8a4ac50bd9e3ebdec53dadcaa77d5b4a0aa68e4f8d199a137905d6e08070dc3dfff84c0140e4d8252c81a5321be4d7cecf8f4e00416cf3dcc51c5d1739a69c1fb90d7d94ff394790541c34d3228034b94144796ca84bde546ca21fe051bc12edb03ba6fe2257c3ce7b5bf429f747194d9de15d2a0da8a0bfc0c2b2a2d289e0b10cd25fc5822df90cba9d618d5c35539b320cef61a57ac633f9bc1cdd71e353d036c86fefc56134ad0cc2970148ab1c802158e82db44af30042b4cf9c2e467fd102d9f46b768dba739d333f98c036c5d31d586bc5530941f6d24dd1c594aced6b9b73cd490beba483c2999ddcdab6fe959140ef0ff3b07bcd487761ad03017e9e0a6f7b94a9913e776db000885068f06c8a35ff81048e1d58721be99210c93399ec09fcff44c5945704603588c1042517028d8f59ece33dcab6f22efbe7bbf721729de4053c980130f2460a821fc6c5aa9d9394ebe13cca3a6bffed7fd431ce78c5242ea446b78f0040f61e8a3b2a07c1ab559417bf4bbe1dd769cebb6a1c0d348ef6c6f14e7aa4567d00b8838ab84e7c3d5ec0ea2ea0db4fdf203b4b1b362df3c665883248ed2328094c4042c03ec88b1274ace9de3b38284136a86211b2fd6fa6ea028b9e3092d56e74112c38ed1ec5c04cdfd315a472444c280738d87b4022866cf2a0af28ec7d9e03d07feaeb36baca78347a35c524b3a03fa3de5d9767ff29f62b42512187bb86ec0808e838a80d850d52619df04c696df31680658f62ea1b86e5de57c8c4f27f2ed82a4655bb6cbf707a0f0a1b56878cb20f53eb6e48c81f92b37711ae3ceadd27883ec2d6d6e6798eb72aa8429f04e35739a0234381f9a050329249a1d086eb004f9a08ba0c28055dd5ed8b1565489f0019116e651ca0dd71dda22f765d26e2b996f1f7c589c6a27107026e47d8c4129ad7ec1a4163a307752c44c167b9e907c1a0e5035f8b5835df71da3c1edf443159a6960026c165f26ef32f9acc81f5087bdaeaafa74b93e6f7184439a2c3c4dd28482e554b7abef7c8cdb4d81d38036d2608b14c4ac033d20a7bf62dc086dd4c7a16cdd56b52eeb3454c31d933e3e59da67df5332d8e619e621469f4eb0375371a0a2e9dddf93afdf870143c3078aa84e23f2ce8b68b196c2442fc094f2a4691842bb5fc6d2c7a5fe8a083682cc4bbc5176798837e9ae37856e30ab1823236965f43d378021cae07f110e72ef83749d4a0defe0d76303620c55e0b23c9d1de5257152264baaed3a3fc7697b234164bd9dc178d34cc98bfc781a1093988c273dd419ba50af7007f9b64fb51f7cea50c565fdea4d0547012514958b7340c696ed898910f99ee06c523e5d81742770956fac0a972dbeab53e06be8f9c0a941fcb0fef0682f269c71f14c102aeeb9ceeec875dd92a751d43ad17321fbc39abda38e9c594f99b8fe027b0226175a4f14d016e5ac63e1708c6a26e2de9d2abc4bfd12514160ae7efd3efdb2b3ddf1fd167f72ebe55fe5cde7904b68eacabd20a519316a2b24552d3b6d05bfbaa8193443d3b0a0ed2368e4a450c06d4804a469193bc680b9642b860952eea242a53b64f2c3a466c7027eb0ccbcf9c381dfa281517b181dde322402ac943175ecfeca019a85791701853cd6ca002f938ec683472b9909e1a428fd05d69fab1096f8f597c076ac9330cdb6b8ac566bf7a7bcc6a9020fe3c88ea46d8d7739c19c3018504e856afcec8f4002f9c8a47b2c7ee37e612ccd0f76fe97140adc4531b3b72d029786c53a4e3f041f562b97aeca25ac815987b3cc505c1bffd58617fff40a489c3d40f375cffd20014d009c9eaf66ecb59899af525aa5ca0d8a588b953ad6198c444be5f6f0d8f87c7da779b879fdaaa2496d404449e92d3385282b1816f8dd5bf8cddcc32fbd312d798975837aa92f655b9bf81dfcdbe8cb6140f58703e04feebfa2a0d7ad222cc70ee7d3aebc9cf9a731a1139a5895151af0456d7acefbd8edf23b67686f9fb171281cc3e0e0e89ee5e444a0da4d717f67f9ec4756f82d281907074a437b10075b8c4dee883a04f01122827883bc040b809e37efa2a01252a0713fd316554afbae963570138584801bc82ee43de6a730fc1d1bfbdbf93eeff93a4339913c3bddd08cfd4e9cfb12f195c52b47cf298efc0c2830fa82f62f76428dd6b38bd347cf32e2839370519f049afea999e3ca3e0b68f22277693ba8dbecbb1ddad2efa1f5041c46590f10203c5ab991eb7193c57dec137acc8ed96f4b656decf8757a7d7747373407532c28434be7d5a3e1fdfef130b033ec95d5f9532cb529c40fb84c6ea5792da29c4e023d7a2f3d233a94ac40a73dcbed5667313f6f4a8e84783484b18eaf7c5b27869fd7b2e7e6a314b9ba712724675fd58246113a2420423ffe25ce9b70de106bb3f03bd5952641affdc9e727b18b85deef61c793eaaad137c67e2ebc3a5774bc22944b9cf779f100c90342296372cb8c0d5e1f02fe6a94fb9e9728c13a5f2997a508a0f2580fe0f061de805ab795b914f9512e704919288d13fa140b91089b12d7dba2793d35455ee81df95534657c09116ab4ef2ea28a8c63459aeb9ad12023c8b539c8eaa8241da69f99415e1c51123c4cc1495f571ea41cc2d8cc1e6932e4c0255a388347fcaa50bbb9ac10bde2229999e6a179779575e7cb668ba37e07f77562a54ec4278600dd71b454cbd41dda0fc3277e2255a0fb2316c11c5e5a160090734a0954c948577c51610ec2058a14152ff5fd0c85a06710ce88434e124165f036c85082b38e3e21ff5ae04e440d3acf7d6435092960b0c2f002e42e86f6d85290f820179ecbd49d080573864ff1bab0d57f88ac15f887ff269e165896addccb08084c166197a8363bf22bf3b98de4328a3ffd90c51f15a9365902d6ebc75c1a60c3c408b4f4cdecc15a8eefb6bcf83828e9b5e281e2c3f1cedba00f68fa53416d48869f541edbb558594f536263baed6585954a4999c3d92f0ee2145b2e4b7a2a5030ac1e10520a4c50a8fcdedb4cc206853fe1662ec540f4dd88515c800003129a05462926fc13fc7e0a8f9c259a3b1c0b4446a6e584feb0eb5bb748d1efb9684d725e0147f9fb4ab532a804c269161bb709ab4c17d905ea7c57ac1c112aadc583cc7e86227d297508d95551650e50ec04094ea8b8f7c70ecf6848dcb06e8988d8fcce5dcc8ebe56328681945e8088d00592d2fecc6af7e6802ac5b9a9d8603c2d8a5bcb60dac41a4b6803af00234610ca83ab4e109be300094b16c63bdf7b315ec3844d7d4756bd9da81138f851e9dc7cbd8bb79e8b05ffb833ef57982a6a86470180f4e33667a90fe858a87038213a46e8486b96ad9a9b54801531798a4381bbd14f1b4ae39444056ef8f96f76da414c5b46c16b340b0f5e653a64ac6000fcab2f625b3edaa5f7ac4e3cd2940cd17e9ebbd39b8952eed7d7971af7a3a05a2265aa933e5a284bc3142ed15df59906536079f3ff4f2d218bd0c6d18c461ee7c149a67bf12b8b15a4a385cabf9432ef1caaa7d428b93962da2da38325704fbbf771553ec13a6b706d818b3691a7f0a0c53ad08e1351aa428ad6eca67276c4dd3da4c134180ecb30e6f374f796fe59e531c138a2ed2d5be6bcc274edfe93aefab7b887728727a2478d0fa44b017db8d7fdb2299ef56e7ce0cc03bc808f1a9c985be64aff1a92cdff794f402ef7767d25967fbcd1c4ccc705849e9924260adacb43e9c3e101bec8aa2d81d0fb778f23f32ea886c293f129608da0757b24d968e3b1218e9e50ee6ae90f8c21e15dda13edeb27faac26ef176a71a8573de38c0c431b3c732a0fe1d8a59221b69d66d1f0c08e849ce9dc28db3e3eb319448bcb2b79c3b59837f3fc2983f6d684f0717942306e20e26edf4b4c564da8fc026f927c2b045fcb8aed138ca360058b2b1ea2010b3538ad5a62c79a087a8208d8943daf9f260eb2aa2dfc333d841a1444d034b8a715a318213dc872effa95e269d4cb115dbe216ddf14985d7719868fd9b84d9e344854d9b6b9e3f0487cfd0636c0eac46ef8e811c4d1e1cb628c2d9134db88c27c62313a899c488158f54e6decdee0fae3acb253cac90b63d668763daabf91a28769ce3e1d5d6299f291765498fe6762b6c6084fe660e74c1b66d5f0c334dcfd3873b98f7b39b224f859c8293e5d2710a64d418bcac5aba65fc06da6e981bbb59ce3e376b41028b6fff64716784d8485baad1ca31b01cc64577b5e8a1c2c0cb5db5208b89b869583351d03ac50b6409610709ed734585db18362abbd8122d93be0642060866a8dd3b4a8b777e59c1c584163e8669a4e80b8aacc47b30a99bdd8bc11eb6b26c3e15319c574a1234e0cda7702a167ba5ecd59286f7da2e7a641db74446dce4c4ddc4cf2dc8e555067970b56600e92481b8f499bc01945b8767344c8318f68a9ebc1cbf502e34b2d940645c9e8ba300e89509a3c72fdacf10b5f8d226cfa7e4c553173df9099a57917ec122c12144c2c2dc0b0a4a00ae9621196633bfb9a2355e67cd66ad8731e6471a45ad6f2d1bcbdca5ce9735c8efc391d73d84a65c5a00b3db6b4994dc57bb9bb39a6801e308998b8c85ee4b3a3bca37554ad4bcf3fa69bd73e6943b6979fffa034b2c00f4f7d0793558e992e2de7a270965481919cf9f70d3ca4d7b57a504415ac2cf60a8e23f4b26e23782e94c0341e3d04ae64ce5fffe24e97963877c1dcdc971b9ed6da96b118d80c528452296780c7f89a2eecc16ca8b0152c8913305e20502729dcd380b5e2284309df9091f3ecf2be87dc97c95a623457f8baccf28b92b78690db411f636b61ab7f8e28e04aeea5edb3aa8f6a1ea474410f7b28c8454754d46dd822d71da4b79a4fe9ebe9b76204f53fb8552a1ea2c33eca79c17c19bee796b8ea8b4d572a95cf496a3d4ae59ffb7d6e60e83ba62596eb45ab6814e4cf47620ed1cfcbca2b5304724b59a279a0fb757d330b859ee0bf99b4ebd2ac14883bb4f12fda30bf4f2e8cc88983ff3722f29820d1597bec5bf2f00815130de6695b982e52386abe427a9892115c025a842ed54d1bcff84adfeaddefb556cfeda9712e82436775f3fd64ceb6ff2dc8e126f1977fc6cb440052aa069d3ab9ad25548b35c85e500f76a1364f86fc70d58d1ca5c4440a0213174142a190cd0a73f51b5d7d9c7d8d0ec6d567b7c18014121a47dd8f23830b37b56ba0664b94935f246e3fb3f480e6b9fd01df5f968a5ae6db64f3e9e973d094a8829685cdec4a3f3cb86a24a7bb9b9c8ba5681234f4daf023bd00e83ec9bddb145fa4a95409d685dfffa62bf25f11be22042b108c61c011c49f877fe2fab739dc983a60fc944b6d4b7406098db4c8fe340dfbc45f54833bee6c00cc6c55c351dc60a23aa7cfd6a101a4514b292154651e4612bd8b63c73e74c5dce77f7eab20debe060defc40678d8f7eb7e0947a64797105c39eb19b86f24f41a6755c03391d8611c308f90fe83ee8b52d9ca8e65811816711e6f6f24fd432944b5e1631f42908a7721939107e5465e698011fe8ac65c210b2a7a376f8fe319c16e77ca0980196605f2154f75dcb1905dd9952f95f0209780171198005e785a0ea2c469de8036b71309be814a0c6b7961ef07d7b4f5b8f9c7c36fb6f97b7cb3e9d5b358e479ea6b7384724b4cd151957460224d3fe76d176be96d2837aae38a9cd0f7a468a4fc077ad1248dca50e15e975ebb74f91dd93c2b252972256173f66367bf335165aa1f0701afc45d501e36b3cbd4d9ffae80ddfa43cc4cb8ec13d0b9cc9869b03a3e9b142a4cad89ed9a302afb60ed38f649ebd6cb33332edebac5b3927fc8e84941e53d5ec1dd3fc7dad8bdb31667c32a425adcb0a3effb15d61a7b9be74441e1941e7752876c1c5a0e53b90f21370f6dece61d0e89b7f82bf1ef09d80ff0164a438e41a21093ef88a552a4714af8569bd6815fe5c3d5401a6a7d6edb2966a759d004151253a1acc0234bd38bb9f6d31d024894dc2b635c2b43afe3f6ad34aca6994f612e9d9dfebe2c93d2004884649389179e2ab38c375f09e7dd1a0a574c1855fb273637c8b1090ad48a5821ab2f9ba8f65f1886ca80177fd064b7133f8848ba364211f80778689cd3c630032b02eb1c9c6d26cd36717badd2234024d2cf76f2bba990fa2b718f7f820de3324fd0ff7ca7bcfab5d2f2aeafc9a9745e612491a98fbf137b3797258a5166d5344cf64904acf10cb502f23e3566b498cf18885eb8bbce260ea85d81a27eca29701f2a0bed1801832852f834df7590e3e28471c243c922a6a6478192aef3801b3b05cabc81d871482af813915adde7894892032eb8919e71a703782bea1f5d830f21f602331d931e754a1d29678b63722bbd54b66cb677766ec876f697ad640343de67a40638a347e21184060b739ad06ae838af273b518316fc8c0f3f0ef01f5b04650d4c2560b0dcd43eb01bfe14988051a770e5a692d5f73d0c30b1b886af0740e0689c4ba27621141813c88dab78bb1fc99d6bfc3c2ea1ec65de507782de57ccad7eb4d25879c389671026cabdc41c34d6bbe362bd675d92b78f7e6081f0f56f09ccc1edf6f710b423a3a157c9aa6a1ff3221a57b6fc38b722e241a73fdc0d2f2feac58103c24ccb9de6b26ae9b876dbf6f95f80f3e4da2f5d5f7ba8e1c71afc5d2a9dfdbce15e35eac1590b2c14d6a4c663a23ef1a5a35a6b95b69905936c209d471ba16826b55a5190dd588a3cb2eea19c948cd5845fff18e7c23f3ef086d5096b32ec1e07157416b4f0ed6371dab7568364bcafd88f09a11b9be49c66f5ea48b8eea1dd60b7dcde742a3ef0e338c490c7fd0e1b2f47f1fd33587403517b5fdcc57231587eb4d6530fffe3626777b9f5a4d18c02f7db6317d0467ad7b841c679c80ffe6cadcedc9fb975d58e86e1ca29f902950106b90290395e0b9318e0e8aa1a2f0e5f032d28f35d08c8cde3ea0e53f91233e29b483ca03b252748d31ab82c91b26b06158378f0590427d54b9752d9fa75c4e7aad5e95d1177b8eb2b53b5290e4c89bd16971db07fe249d5b1c34013882e68d077f2af862dde42cd566df534b99770fa7a53c82b05407d60892630f6253f0ddc07bd129a2846a158d832db52cf2d746b29ca77fde6ae7f28eb54cfcef02bae354d7fe4611e4971f0b7ba098a2350be25318d8a4520e493d116889ea5394a5f3d7aab9e5717b9f118ce32a3528cd5df36ad673c0d9a81dee2f1ad7ddac2c13f34b4f8434afb6596e6f619d8f0277009657e19acdbf50e2be8cf474ceb61653f8974a9875990991da6b2b9790cde3cbe48985974191419091a3dc0503cb7392465694bd39f761619269267ccafc767a74f9072a8e8c784529b1cff4e905ce713339bfb29e4cbab4148d8bf94afe900aeee8f73858052eb05351ffcf115dace599e44e86c0ad2ac921949148fe9f0eef45f0ed348b28757a96846dae4fe30e86ccc3150eeac1ba457345c7aa8bafd7fe5a1a311058f8d9b216c72df2eb4cb0ef21126a9466618ba7c32b6565d283d32de817979246100e78a94536f1e6818c63aff5c61e0894ecb0b29709efb4d6eeb2062e65b43693482ab4a1f210a8ab71a9339822e3905c9bcb5c05a84649f2cdad43a4e93d36c5678af858a284b37298c8e206c6416c92bcb23dea878aa616db4abaf4fc193f162c65d3562b94fe208d3b71071fbcec16bf32c29f7946eea940ce5552849da961793e341aec847be0168d5123625756973429115ee8a93e9ba4a5cb61ef2ff3f1b1961277c90f91b486739addc0d002853f44306cc38d4125ce0a478b6013595951b23864471718b5c068466d184ab28ff4ad2ee13118f8ad1a2bbb3b6c99408f91eb50206b91eb0013379d11156367cd8c8c6564449fb09a160c3ce037befcdafffbf331e73c36c8e24dd42fab7a8e3f71009852dbaa89ecfe00295545b0e238b08427033be9a3812051c214177e2306142c758053745b2a97231108bc3e0cb18b494765409ce75b4a1f3940d20079997f5d42b6fb66a0165bb0b341a4ed9b6ebedbdde43558e1502ece04d7360926f068575867e49425072c9def3ab548e614c26e347db93c4512287007338e1f0848e8840fcdd2d0b725fd2df234d3b1668c491b79682b6f1615ca14e9ae595f38e33e9f9564f46532e353c4daf636ba94c7c5ba2f0afc866600887735fba0dc59b5afab307529593dbc74b41a1b32351890727a6a775848d5317b01cdb23988025e1379d19cbffb28ae239006fe50c37f545af6493004b84f29733842aa5e146a2f298ba959f0131ecfc08c922cb865c788cbb8b50671f55eb7df28d005234a90224e1a400fbc2a3aec1683959e6c3630e5485936823cdad9e8dc1c8f58194ae5ee2abf19db375dde02869a6be6cc2379a7fe2988715201c5de3b4f39d5fb75d2ec99f464255c17b26559c7ef86a6651558f29aed558494c1532b5acc1a586c39a5f89f32f365b43fd94672232f5c7b9531877035df34d4791dc5ce7e5c51ceedc2beeb59d1badd0831ec0bacdb1e5b57a8ba9b570604257fd06447ca8683cb4ce1c711a914a8b06363ac598410965d78aae9af4898671e160b31446b8060a8556aaa15f4ffb6a57d62b982d259cbe117033d2af3114a76b31674633cecc4db80cea28e04925fe7979b0627c06e6f1c02a6590832bceb23bac1c84bdd13204b0174bf56f05a8b14d4f089edb700fab57e0ec8bc403cefd537ddbd7089091c22cfc25233be637ed43c3e368d88c0fd03c5867e169913dd5d3c16f48de575fbb5a942a1da34b841d4cb6b78a1a361548327e8a82c3fdbeaec52b975fd0651b5d56a5a2aa3effbd5fb834408d8620d2097420d9d3b49e14b9e8e391208af035bfe3da8e5a4cc662679d37bad53bb55a13583658249b5be4f2b038fc34ae146606257e202d32c1307bc3a80e4e0892a6424e7f15c10b996694c0992e23adad65f465fb6a7c880a0f96f412991283beada9c0ff94943e50ea0b3eb80874d0f6dd50caece627f90f500005b49e1a101057f20e4edc15cf2c7206e8e8eb767d0b257795a427e7b16aa642d8ceba1e1dcb6ee38325e9848ec2e8d82ff1b391ec86afd7ac258c19363c067a827ced375ee7d6e1f0d0bccf322b798ab124befb18dc7bf80128910f7b4a714820094c7f0daa5a8a3a456a617b3d9048c283fcde0bf25cc34ff8e04f7c04ab21bf45201de2487eb7f2d78e0bf002d08f570c3432e479d4c5c04cc1022cea1c8e857583d1ee2a362c29435cb01e2bfba75679dfe340580d92d96ec5e8fba46ac99fb8658bfeea9daeddaea2dfa923d959f2313bd546d3d4d4faaf2d1f254aa2d4ddc86e4d7267278041dce10801c05b45ae04224265961f30fd36a62f9ebe5218952d45e141f82305735e721617c962f429e19456a7d2d271851459915299b9ac15e6131b73c72a469b8514382415a876ea9a7179db7ce7c9163f86affcfbe83caa4c5e4fe76e6f4093a4dd46ed6c531d1af672781ef6ac0dbddb18254547f89a84a8bad022219acae28501c4a41f2df0a4a23ffdecd96d13eb02cdc755c5595a84722db4c3efcedbc88e73ace195fcdbdda2ccfa4b4e8333077308f5da74517accbb02dfd8eadfc09713c2951e939634a638c5cf7c6842d5f9b148f3eac2af225a74af819def127daf31cc146ea459979aa56a98fc8eb972a9e498ca788e94205364fd4e42b91fc889f94afa306e1cc61473bf1f139f15c44a2f2c528facf9e4c97868c5bee5f2768e3490655be6a7dc4dd830612a8c95ce7aac43cc2e332b9395a199768e179fab8f61bee4d4ebcfae4ac9b10b556682b1ad852010287408d041ed673e71105441864158b29455ccdc6b0a3714a3ad5b4218f7a81a7297dbacd167a17ae3fae886997186cebc2c2662f8a45ea793ae29a002d6c49cd8c5fb6b4d228baaed37f7cc19efb4bb7e1cf9b8e66b29d6a815cfc55b3010fb5c2f97af9315a4c5ab52e30b52534a1afa42266cd7e371a99f090dcfc9128b07f5e8fc5a65a249e73b7d3454d38062ca493c1b3c994304717cb4a600b2f11411dc21ea25c58317151cf16d70dc967b68fcdc61644e8dd40f053f85ff31330b07270d6ab1f00599d8c2b96a3069ba4ae2d3eb21c583566eed77e27568523b2990bf06940f15c075ad2478480ae8ff262f90b5027a4dad642be491723382f5c1aa64e36cf8d8650386fcf553a5dfa71098de2cc8a2f83593aa538dda8ca4525fa4a39a7622376631539da75e77344249da729d8a39d9279703fa54a07374de06e252e03a2b5fe1d9dc28598c8756b200af6df7367d8f5135c94fbc0eb82a48b7338a43224e7f04f5aa40e182b17a90d28cce35f42e8d2d3fc5f1144f1cbbd67326866c66779aa3de5961aa2118aeb9cbbf2b522e39feadeb82db2c39e633083a894d9df4f0a077ded4411e3ecc0d1a22d15b92ad31d409fb13a15b4cda02817cdee3864dbc9b16e09b7e9fdd881538501b23efa316a462b3109655e14a82dac6a239566b08fbd3641ece182ec8441e8ad0d3b9e00b2906a3cd324b03e86f8d39b5f2d0b6d9628e33f0131193eb29a0de1121de454be1f9a2d6e161dc9dc83e003be4e0db8c7fece68fec5952d623663f7d528df66fc0603fd196815092bb90827dac270afa7ac8b6cb9796e6891e1cde4f9057ca7a475443c3f42a43973bb627fc82405dcb87f33b1ddb590c795eaeb227cc3aa3e992c0b1eac9e061e1e1c172170ada33c752ed2e8818a608ea63e9a0cdd3fa1276ac946d34962fb11ccb1b04f017e2a5a0795bd6593002c2536c80555f40f8b3684d5e13ad6a916aa6171547c580e7bedc70532e44db5ba99fd594b12b38b5ef01843b2b1e7941e386a0ae1d83e9af5297095a12bc1583fbc3afb643e3414f59cc03ceddae1dbdf4fe0517b0888598261c8f48b89c46bde3ffb02f806acc72c2872b5ea175a72c60441444c807d533f9027de92566b6d4db22af4fef4ed4b2d775578ac9eb3744368f2287be8f446a415cd2508040bc707b6f7973866cdf58baa37f1dcbfd1bfdca6cddc20a591278734a311d8942b30092b791bf8c7a6065f0e471777e4ae8fac3f8eb8ac5ad198d710895ca1e5e78f1efc95ff78e396de02504bcd84ef9215a0a5edeb4e712a821510000e63c47bcbf11e3996d7cf34ae611e8c057be5767f177ca4d62ae13bea5d773efa66dd2e5b8e3de31f9ce046a9e5d3c4c4cfbb3e0a50595601cbc78f0acfad84545151e5c03262c371bc89d309620f9b5bf047443af4c0e2d68e031ea93dba34d1e070c89c20951a661bbc6df9e73395635757e8efbf7730e21fdd26eccae13b9fd2b9716d48fb607271e6b3b550c90a2d2993dbca34aa93bdaf052fe3ba710201cfdbf949b7a4fb8f586821927adc00a9dc60ce90eb5b5ea4c7350218972d088158a376243be6fa7d1f8b9bc4330b1b19946f484cfe0e0d18026140416e0c37d78def7516cadf75a4ccb4583e672cded89942b5a5173a2ada08b4f1cd9b477d614f6f35efba7645febc10314fec83b6b0440119ebe9affaddfeb708f550577a463615622f833e6be49f19166281a43713dbe673278f9a0cfa434b767fbfdec3036eb8118b3693f5cd5964edb2454947d5e821bb7ab63541131167501a112563c9e5a15c45b39c7e4f421866381b2c49c8bb26a023d23c750e7206f46472d44776b4cff619a67b3ed55ced0ab63b631cc4dd0a2e1efb498ae76e9cd41cd367cf8900bc31b9c70dc2558c86b1b345084f90f9c0f2accec343bb117fd482e29775c580b7f8a5bb5526e19036dfee9ff4264b5a6762fec7ac33fea0b8b20a9b77059a73d22dc53c50a24fc1a2b6e9931c7cf1d8b43659e09ae622a4d308ad32d04cc88cb10838193e844e712c353a23b8ca9f0c04bf488c198b0f8cddc4453d852e049844058ae683d6d2b02d5fedb94671c480ba0724d9d8b841d384da56f11d4d4a8ae986475916c692df16d6432b3d82eef47a972c7261828d5d165a7d3f1b4a34d96caf3cc16504e6a85fe3202c57a81ebbf6ffa0dd29464fef3fcebb0897a4455a8f8e88f97874cff226893bea1ce86316b928e05522f52d1fd8c611b7dc5da575fb9ee111021eef6b08beef645319d2de7ecce98380a4048a71d23a0fee3c1da7248500c2758dc0954fc74aeab9d3fbf4a0cbe8a4e1f1c65f29485f9c32ccac3a8a53fe4e9d6ed9ea3b5ff425b97df0e9342263af4741461c99bed2add00cb1b0a73e5c31151d442d2f7c8044305be75b1305a835ffdd4bc418f0ba1f80228f7bd35c036437e3bcce018f5c0c0d9e693552cadc057bed64412017f987c295b8f26e37e03a356db58ad32007d8146dff68b5cfd5d3f4ee302e736f5e3615f48f16f5eed1abec2c40f3637a94b5170d30a2a0d120fdd20fa9bb35d16658589cc3bc81bc6b396c4305afbfec53a5db969d69659ca752a1cd56df2d1c54df3c7b3af3fce32b31bab4778c2c9f52b4ebe27d1a056c21b9f62318fea2b5c5b495abefbe2b06ba5c6d5f7872edcdef82fac9c150ec1f877f1460772f7d874d4ea63141244c5810db469c4ab37f4c5a95a169b4b0809f4454309be1bf6d9b618c5e3f3d62e1c8297ac9e4aabff1dbad7e87931dc414709b94cbd2932ac65cf54a363eed6e4709c01baedc9a1127e3c6e48c49f05c636105bfe80183bb19df1008cba7e47947cf90dd81013878131203e5232ba0cbdc0976b99614bf3e6dbe3a79bc195cda008908bfd4a0e9faefff34047c47eafd85d3c288b7b8d6f6328a8d758a3d87402ee2880a48d39e5f07d14154d9a11ac4ca4abfcd5ebd1837846751c1c469d4f48223ee2e2f850faa470c711a224dfef21a83ddf6bd8c0bb551563259cf6ccf2187ea04cc9f698cbdd83df3f10f2d7439a5c07287dc3476b86ab0cb3d1f0f9b26b1628b64da12aaf8e0e2aa2948267fc5bf5d1001a1df73d43a6090e3790589a7fa13a9380c3572d3b229d8c49246a1fdf7c0a68262254ff60c69ae56e62d484f4e0bb59a6fb7a9548222538524edfd39b9db19d00dc8260c93c07080bf2fe442ed8348efea40fe129792c11c653055921d56aa9ccadbaa14142040b3b50b67a3cf52a7cbc0d157700167d19e310ed92dd89af090e4233646a2fbfd863f3ee9f2b998d56c093c76c4ef2f798062b7b845982c4ef57799830e360ffd17029bd913a3f7707ba1bb35e36758b602717c6a53ddb3a6debde678a3976ae8e8a6fe1168134898683eefd6a1c0bdf2339f595831bfded80131388e78a2c5d38e0565a1844e70699a973953178de1fca19b14bd33184900f9743c8594dd0a27001b82e43b30a4867e665aa8c1b681ffe3cff1dcbc8f25b774f9fb0587b8c6e6c4899f8aa38bcee7dfe29cf90a44e725fb622bc65ccb1c802d42c3ba33084832b1b429a614d44eb9e14fb6440fb0694c014293b0fd6745fb2862fa0b58937b04418aaae41f84a3b35a60d4e6b4eaabd1f59c605a357674b6eb0abf13d9e956a20068b2f34431eb4307dd35606ddb1192bd3ae20dcaaaecf01e3ebf45b723b8669399bfcf18f622d55a0547d0c4f5c13b0538c4b703e84b0176590728d79e34636877a229529c7abbc5eb24ee935228f6e143011393dd926146aa60ce596dbfe10d50a2ddd4dc55c83a483cf27c4e124ba70f6926e8f3e0a6d26d5f67a7cbce7a3fb92d6fa82b61e21049759d6f6b8e0f1185776df0ecb9cb695e4493ae5eb464e62abcfd8f19b21b0bd79460c977110cf7b3865869d4f2ee73176b884883541a6e355e3fdd9232e970fe7e668a7bb05b95018e60e026f3327914c30c0a1e4444dacb2b96991c656743d0cea741b88288786045ddc0b0bfe06d8e08785c1eff950d867ac19c2f5163e7a4576dae425657c1f02daddfc05fc568700257485a0475e9c82a071eea3565fc844ca9c3df1025c081bcebe642cb87f54f6ff85bfa492a0cfdf77f967371323cc45995e68fcc55e5ee4164bcdecb232a406d108aa156da6e45d2ebb92984f63991791dc45a4092e458c6d69405d27d0562c546e905553536d684d0d4eeb210ccdd4148212ce6abb88f0e8e7aaf1852140b6f0687c4cf21fe48c759898d4b51c14b44daf857a0a3ff39be2d7c7d8ce8e884bfeac46050308595bd54f878ca3d1dede28b8d935cb93262457725e41848c5caf7d8927a531b4e2aef3013355796ace0a214b67edcdccf6f7708f4365cb52fae71dbd1afd7a9d225481cd9adcfa7b7fb9ce2725fc41381416ca42d21902ab205b08dd5e4eb3b0ea0242bab202c11409ffef152e107a25aec6f6a17183f00054059bbfb85f1afd361e56d964887798d1ebaa88072f9a4661dc2237cb9b3ac812521a99458f06302c593863b2f4000ebe1209b7e12d91ecad0e0a4b99fceb6bc7caa2657d13b0c36904f8f1d90261e9bda03d61579da2989949bc92c7c30de60c00101f1b382f2406184fc4fb8ef1e9a06f567d9f58ca5f5e04208127f9e7f0074e9314a09a6a959c6b37cbb58f49cc5be90f77b0bebe27d4dbd94ce7cc69a91a06f6c973be8ee0085ebe5bec6639acaf690bfe88094ac430e2ca905db8960ef827bad99f4165dd1e57e500f65e4516d87bf673cb45c4bd656a8e7cc1f82cecea898ca373b5b5b0e27662edd1ed3c146ed502ee36633ce47ba6765988ad2d6f221579ee38386b19259cfd2ff4b5df2c04abd3165427fbf477aaf6f8ecc796e3b99db10235b9885f108076e3fbb686d6cae04c2b3379a28981e88b0cc187d07eb21510db2c870a58dcf85418e3c99ab2e75cb0e060670ad8b021b91158e1f8d0606b2c2a94cd5243133d52b1787efe3cf76ab8e3e45a4cb096bc8a1bf2e535abba8f0ed83450ad466f76a41cc056295827719208b80bee706e4cc943615ac325a9b4ff137a8f3e84202233c9f168b5507774e7f6e1f68b4e14f12fbdfe7097fce21d603231234cff38c5d842bb439781a0855d5b62ea784aa604170597d2c5bd3b5448f84f105ad97532eded7d3ef797c89c38eaac99d3d14ab3e6c8c0a310091551d439c5bbcab31d1df69edbe6386cb4793c72a64074001dfee5636e70260b01a7c141895994e074c40e582b12acce53847619ea010fae9b2a5ab8ecf867dcdbb5bf7f66271ff9b383aeda013de62b9af41a3fc7cef309b252bf3f1575a0ef049153374ff926ef0aac67e956dff3c23f0c4e862f147f3f85fedce3e8af39aced55c50da66e3e2d2024ac7b6f7a179580dec806abf472ba20cdb779484550a98dca89c55807cf7bced45bbb5b18b6d2c73c7855987904e3a77e3b61a4da0c863a69b67a0a155ad8c8321230d6db51f141d0c66990e19a660e46d404a77bf097b1684f8c033a1ea0e9c25b12e632187b32b83706cdd8924cd9bc85431ca6fa5cea669ee4fcc54e8d28bc94a14f32164a263a775a83883a79fa99c8dc29a188bc0c3282d074de906525de04dddfe7025c368cffa222b6f4ba0c3cef3f1b03be0ee2b600ff7f810c36cefa801c39d64c77fa2b1dec98fdb45cbfae1b2f4ddb5d1f0e2302b97c4f7f34a8587fa71bbd7dd7cf6f6c03231efe5a29af05dc37e55a4687842ae1a6337d8874d3d8e4f94fb81843254f769e32177685ba4fd777b5ee5361e0f9f926bd1fdc7d94e90915acdaeb6411091916bcf6bce7eee79db0cfd28b8e8dc1dfaa799689801c60bfc4bf20484cf0cff6e4207f6068e678bcd1240f292fc03a74f632ad3c73a8772533b755b58cfb79edb4e4a9d6a3b7f3fde8a3456a88ab824076053c80e481bce1d8bb9f05726ae31756eaabf1b2f84f0c931d9f145485b11f8854ab8e22c77d41d2aa58f7cc5c932dc8b6b2d0e6dbcf1e42f31ab0e63d8dce479ffd360a7add04739f85cb7072a7e987c333f805e2e8327f84d8a76aaba4b7b59b66805358b379113fdf60684586a1eeae2e08ce954d0781e99122b8a29375809db11e2563e21e6b1152e2a4013f88e3342453d819259c37781e29feabfb18b52c106497a60893f717f9c2b30bcce9cb7426d566154bb7c3ca9e4460865a51a5963ff0cfb1100d898ce9917c9b256c9655d21d40dec79b74b2c8517d1fdbf4a25f6126e0589ab0bdcace516d3925288be29f2721f3931bf262f3220f0b15538a5ca01faa7843ee85a804baf9e8edbfe7c8f213b4e892fe73b780d018bc06e6f0d3849a1a66b5b7ddda62ca246536cdae5fc75697061d0a51bbe46660754f31d284ebea340ff8459a6db1f98221274d5931eb4a50713c6fb4eb158a3c99f467c308d54829163043677e9042948ef0050252087e38e4273b16ef393ca2ab50e6337fcdf061c58447846b5eb5f69b08dddea43dc6e721abcf91276ac7b3b4ef13991c5e0c1e37729731b36d05fdbfb86ef4f962e5f31902653a11ebbeb3c9f9779d98522571c8c80f6ebddf9a4395115cc08506b1b8e18d87e0e89e3d409339f1266a1afc064a8ed17ca968ac830c02cc4d2dbbc8cece88d4d05ea41eeb3aad41bda47f3205de5c32d5df57d4ddbbd1bbdcc055e60612b1e08d88109aea8593a703a672b1f69823680f24d2d459a7676feee77c1d9d964a9d931802e1543e605821a1fc9e40ed4bcdf660602af8ad3ea6402d413e9677adde8a8d6247b0f5823d9b5b1e565087cd93caa8abc1c81b413c2a8cf57a96d0ae57c1f6f13f069395eb3971cdd39e4405fcb2c6f564c1ececa67955dcbcab951e7375f2d3739ea9c7bfef4a53cdcab29016d2ba6164fa841facf52391c87da5ccf453245a0dd6af64d6c9d45d1ef7db4c3cafcb0e37dec8c455acfc8a7739e6de8b12679214ae5620960354ef8ad45390dd674169251ce33956cba31aeb6cb752723e8246d1d26a032baf85ae66227ca57af5487688438451080915410e3646ee4ef36a96904f1665362ae9c97598032cc3c09a05a78e927f9681b66aa2ac6e186d4e6f8e03ff110544a264738024c7531254eb8a07e0f3ea8ed62d87c3d241dc5521137602e717663bc24a84f6d777657cbac3bc2ea6e67782feaac87d33980df7d4f8ad182ed392125e7b9c8be5b6f086f002e7313a23934b615888fdd79ee437c7a411e9e437ec17ba29e539be1173242278b83f177a6bbadfecc8ff10f018223f7bcb85b5ba59bbcbb755b38f99026670afc9e67f1cb4c11820bc648b9247fe08b6fc8a87b29b7adbd5343eb51aa44b168cead42eb545b53810ff4e3bb4305dc33b560aa216fc3d8aa6e6364f341ea3206de583d314a2f90be7b0e8d07d3d8f1d140f2d4e4b01b73095edfa90af79127de900d02f198d7535c8925569092cf5112f6e5f6688bfaf0af2da90c71e93db9d5443316efe5b0fd9cddea5c0075fc3b644b5f71c1bffc3202dddd97871b4832ed4d2e0c7a49e8e7d630fcc672eebb5275a7919f05e85f1ff269bb6cf1cfdbdc46fec2b532415e18580c965ea758e5a1bc4456b2b92472d168e2bdab3ccbf7dd330b542600f4767178269514a2707cfd7583341171e5a222625bfbe71d713c37aabf03ec647e671b981b0d6b3063788d1ba9681019184951cba00ca06798925f8f33566f477eb0f4c37718c2041d1e8b131f6ea21be61a3ad5542132e40e6700abd1122604fd3805f2f9ed22b54eb5d5517ba366130d91fbe2e27e1ff877aba280b3b55580580e618eca6a245bda1d5d322a4e141d2cb75cb806e12920b9dc99c99d19fe7e0198bfad3d783e8674fec3b6d22a3d78c3347da5023a0d74a6e748f5ef5147a4d42ad96bafe2655f2c4de56939ef1789f5f166d462ce9c18727d443678d61292f3aff1affbbf6562bd3fd91d97d250dfdf02c38247de564600e64c985f6afdc7292d610a42430b950ca441236b0f123a3564a58a3f7c0320f970a5971795a8cf7f4500387b4ca0fc1b2c1e63690f5b3b367f376e983858e3dd28c10cf0fcaa0e5b0ee2d86c076f371c57bc86ac2d1e3580f9c2cd83d87ff727ef6b575665921221c894a1521db95d8800e6c775de60798b460ecefc57b3369aaa2fc79d17c2f752e04de46bae0acc1a430f90f6cd72a366002492c8577fea769b8be0b107b53d43151a5c759da3164571d86b02e042a7e276be6bb5f9b57798fb0712e2ed91ea133ac0c99227f0d644271c84e108f2d62d60fe0f71a01dd7957d0b58b23480c6b997d61c5cfa159116e3435a822ce36c2ff7eff322a81018225c57d974ff294b7c741cb5350039a26b70eeffe73a3cb5d3a7b454968a6d004bec1a3d57690b31968339164e7f3b642a098b6687eda6be1012b4e9de832b689aafdd59e88226a0dacc69739268e4cf896ae16837f2a9dfd42872281c0cd53e408f31bcfa4f0cb00b6a54a46ecebc3a82182cff7d76e4d2531bc90f1228c61064f3817032c9732978d095979cdef0d5f43c5b7115a40645d18725f12eca4f09fc216982623e05477a1b30f6a1982260d4f77a75b3dc29a4e0e6a0e07fdc4f55c3a16dd4ae328ddc04e0cb6f8a3ba3a53f04720a848f79b97f4c8c7a1482a584518a8b8157377b25635263e93db632418a208afce7b9ddb09d3d23138e75420a8c8b9a9c718d65dfa376462c413455edd58c1364475d23cfc35de3a045cecca1615cc5e2e3dc4475a8dc79784edcac4565f4e17892df0d5b0f5a1489724c2b58eae1a90e019a382b28f8cf5fa262ff41ca676bb86b19ba06f0542de75f212c3ba4d71e2df59a850937eba37efd63c082d17bad5e527da3de20b5078a3c5b381dcc522b48a15edfc92186fdf08344707953087d50a0a2e57065e6fa017c87717285269f99ca9081632fded42cb79e38b74c0901ba3ec5b9196bad88c11b676f415a5a18b65eb5251aece2c0280c33d7d65d2f809efb241d4960fd252a9df29cb7d06bb67432c2ede5257a313d60af4b7eb290e97b01fd68b32b21d5fddd869cce24f04429c1d70fcecbb76dd6e232ed34d44e724ee89081e35f6ec937b7524e013dc027fe4343e661e8e46de3dcccb23d105bec0e949ee90f860c65b6e3fbcd80ce01ff902940107b9028f396a7f73eb7ba985ee75bdc40ba74f1819717ee101deae5bfc3068e21d4fafdefdbb8067440932f53b0fcccc68e2bd058ae9d2f658fb65160da51dceb9d6603744f636de5f29f6090eab60857f303cd30e618dcc4320e9f433123bce80f36feaaf6a19fba6d253a6a2938bec68470ac46155fec4409a211d0a76da74cf2dd9554df9c3b6f32e46f177c8477a3a1138c8e3eef2859a0a3b796205e8df4d97f647acb835da2da759dcf1d83b6afbdcb333eafc29b46b384ae26de96851ebea4267b85252ae5d43029663d35c3f91cac47ba3542b6384a271706cbc62e1c57177a8ec05ac1c98fffef626f7a1a7a352e802cee24d518e1b3b42552fcd6564a11a4d3537e5ae8454a5a9ad8320bc532ac926a545a1c6dc6d0ecd0934cd12aaa2ae1eb46eb4c598a665880a7ce4c5a9510e2a99ba9a61d60ce34a8aeaa02d7772b88c28f925dc80212df37782674e6e090c6733920a35896c6adb35513c7f19f81d110b2c9aacbe4277823cd4536dad41b7289915cc50a43a7a9e899db0c38275d4a9f7af3cc99b5b57fa366d1b8afaf064d0bbdb9d9c7ffbd6884688d42a9b10ecb92e0b33b2c9c5ac2afa97f6c944df3b8791a44815ed84e984d8f555d1d097f6abbb083ce59b7e19b86f4388d66e264dfc0928979308d6270d493785b5a735162cfa8f29a09e8e977b064da22c4be69d31314f360a567c9ca70cdb6ce5374acdcb3b217b598e5672c49d35524a94164151eca8f96b6c44e794697f1f005edcca7e2a9341e7e5db858db15ce15bec512b668d364a067d9e98a293144ccb66b6ad9a5ede5635e26e941633aab46fc8e23087228e5f6b67016a339b150109db728cd1cb8f47fa29eaf0793d5ef6ba99bd8658ab7a942b1d34388c6b3dae7f93251ecb15cb21148be5951237d4a35fac4a60f91eb50207b91eb054d147889a260157c0b72023f9fe4b36aca6a3fad8f43654efe418161cc0418cc7243ec3c012bc9b56fcdd24267d7a9b2e3b271ee28a36aec7fa2c9257c3501780c2d5cf21ebf4da60e3944c6f43d7b4cfeb4a2f2d3a0584337fff1cd570e174cae2eaf6004080748252e567aa33c2b15e810c6fbb6d9f203d26b4cf14463240494a2933c609ed31e958e6d4590da2c3cc3814fcac0708d71bd412527775f9b561961c31ddad5642e8fcaa4f068251227ce7da791007c66611693b32708120818094d45d4f87db548f7fbc7510fec4e5922183bbc3874ab2ebf846ddd2e745d4106391fd9a3c022efb0bf64bed14e3d5db91a63a555698eb5d09e1ebfdca5b61f83024ca20f9b77548684005a4e56600200e6e805093fec82f402d12bf45d1f8e3d14b78d4e066773ec2bf42698f84cc7c9c3b323b5e068e7255f3ed69bd9e6dd9dcebf551ae15195f3295cece855e1f42f182a0879ae9ae3d2bdb41f061a9d0e2329d5b5a8972dee9529347674ff05841413c582525cb80fb9ba13d1365d429c5db2003163b391c18f5cf8714916388fa6c39f632d9f9095a28e448fd645d3bcb4f4b348c2498e5a5ccb01cee05689698d50efccf1fad2709ea227c4641bce4baf13d6d45c36bb42c05a5d69ce2b8e79652c2bbad183ad5c28af9ecaacb7dbed1fe26cd5382f33ed012f8643a818b5ed7df10797a2fa8a63e1cfc2cd6a0e4ddb21251340dd9a6b96a6408863a63827e8e6651aa49687ac84be5f59730d4feac79fd56dfa2e9715cb5067263e27952519ecd12dfa417a0e48a6f7c9d6d90dea6f091e198b45e7409c3261cb256ef8395e74b80ec3011095152d5b4991847eeeb99f1a67c6aa2b4b31db2662c0234f3523c4a34c48a1d0ed588f54c2ca5d906527e3a4580672d1d050c02906dc46d409e5e24d0222a32436370ff941625775df5a5e108effd0f0cbe8ae0825ab9920a5e3019cbac74982723e75df21404e5b70f686988ea66ef1f95f00b316ffac446da5f23deb4b4ed043b9476d39a122a88ccb935c372d5ade79fdd18df723d655955c6de1c001ba909e3b162487132a8c6d0ee7b2a47875294a05858b07bc483a95e25645570bbfea204c2aabc0862fbb62a8c7a97bc7b3725d5aacd15bc1b0075cf50db25409ed10dfbf3259e51872cc3bed89772f10ece3ca661dd3f4af91e67c060ac51c581d5982728cbe3b6a1e8cb4b6a0a1e695792e96bb8f046191006909558666ea1c38db3d51a3ddfdc0c24d4130d52574a79c3772ce8d855bf95066f48787c45ce4ddc433c7418a2a61518f37e7c3bbe0fa4d56afb17f23fc96b19d7d33607e56a9051fa1459fa7a3c668defe3a2beafdccec7d573bcce166d29b2ab0fd7d0979706d1ab1a0790734f4a6754ba116f1aaabec29d64a6ed0f03c7afd997de2240f7b024a7dd8462bdd76f2d66a2866d8e9ccdff065823c74b89488b946331b42e8a7dd0e709291938a0999e526312a5ed616b79bf2963e03f70037ca5bac3d0c266e3072ce5af378ae347b861f712aca402e2dd5a0f56c1a1242ed3c9f8c609d4db0e3cb8fc29174d9e54900ee7d376444d86e34519d63fc339b4d56133a34ffae5a89416e827f6c3d07f0f3b372f1a476d0383cc0333eacf4ddee5c2a22e8520c2fad70e5039e2838b0c67ad2aec6a68fb7284beda9a052bb0ab09e9a3df831d2df99a204db0e6c014a41d6c2444a20360bd48c66eb189eb900edc0ae91ccc3216ba3dca1966fb43bca2871bded4256e15c0c091f5c250d383e3d26e04176213c0f2a116e5f3d29d8a0570bed2571c39baa29bb6d8facb5310d93dd13a62b10d257bce0da2b1cab38242680cdd578883016f51b02dec2c5a13250cddd17232f77e1cb399cf705f77964077e0bcc826f26463bc3a6529f0fa1883d9d05e73133f34a9c2fa54d0e73be2a659ee497c61563b17001ae3bf69691feb0828de8dbf910ac92e33fdf5ea7556df5fb458cfc2a46f30ffe3ff9da2fb5752149f650a857a1c1cd810a4c547de27298dd29a0d28f7899c938a84121275070ee60e22f24af18c42a2f98f6ae3c8eea2dc23e941a078076a769b21e48049bc1246b28aeb3432638d3f9ba6d6d97acdae5892be88b10233a1db32d029a546ce47f3c6c0195ad0121f3f478816072d6bbdbf742ae539185a51e04044b7f1bcd50d6063a7c80659f8e2d88f342a0a31932f2499c2570a72e0069b08567daf27a858df81158b45710231f17568d82bc55315d70c2ec1382ccec2aa802a47ab9557f1c3d3f66ead6a7f2c291c16535aab1268814756bbd04b041aba167851c75dbe37cf7abd118f946939611c1121c0d9595124f48d5bade1650c62ebfb5896315723b5cf17e3ad81d75c1e2b2b643489feda5ff268bfb8581b7572ef55b71f4a6b09d5ef9a5981389879b85f1abf5020c14be5d872d3a4262dcbbeca97756b9a2ba748a177d178219f40aef8290ad1ba522f1cc00b9d08a07859410e56ab4ac52381a2c059169b2c41242639bacf04f3eff6ffc8aeae26a6fcabfb1d7c80efc395472000e44d7e6494c2caf9ca720046997ceef321b8d7023507f5a647d1672698c09b7c1faf90e1a1e0116a27f2bc94dfb75f96f96d6d76f91fd8cc4e2b6618c9587657d6bd157a64b1dcbdab3d47f1a7bcaed1e903af070d679c312b44d11307bc4c26e765a78a262fb5deadea848033030e6b009da6da2d7005d637e7c604fc5f9be32840f573dc767280903ecac8ecec6848d2c9a16e38db864aa6c007c30a5729e151fee5905efd560c72bf83438f984427a884e1cb75ecfaf9e21b4993cc18188fd37cdc80aae3049aa249c686d52bd0e6c6ca4780ba1b4e757c9a859ed51888cec8f89a760e4502fcf572b7ab8e44922e7387f0a2df2e7206e7093247a1d77dbf1d128b69bb5b04b14eb413eae382b4d61272f8fcf365ec1fa44fec0f80d0e407ffb9fb98a791efd5587396749909995b0b60744cab05403736b8b940d883e11326cb8e050b65ffb1c7530071b0b8f3f05cae4ffe79dd1afa535edc5f538388035be267126dddffe059d65740b00b9f99241afc7c7c4a60584389abf1af0eeefcb46b50a7f76aa02b770c666ee58f1b93c67e77a16440bdd76290673062563c6513a4a88ebb0c43f52d19d9c7ac29f07be656a855afe85653ad87212db56f3c7fdbd55240d5e479f3939d835fc710b3c2f0eb4e35dc441d3d2a409857948e4e709ea72d7ee29364fee8407090e2f3bac3716ca90bf9c1fffa44f4d61baaaf10ee75a7ea634e8a73642e790c9b0931c7a752cc584bdfb00143998d71ec883d6dfd2c3758533c1083c1b565de76c086ce7c5c5f13eed97b6ed6f571026d192cc95e0a6d9aeb7349e4490697d8bdcfa48be632612c79682aba366269dede2a49bbbf66f86e84a812c08b8f1461585661e6c85e294e354db1ee5a3e2760b54e5606ba2f73615ce0580391add41afee31f27bf83af2ea7e456e9f091a2e9b37fdbd8b655c00116e65f86eb7a8a83067ec1030b972c1ac8261ab99d957930a6a61f855850afc198d2c8ecf8a4465fc037d5bd9ca2553d47cd0483e24be102463826b5bcb3e0f504795686eb39351d4255cf4873349d9ac050ec349d408bd1a7c1fa30d0aab70fb119a4ff90345aa0ccc52311ca3b220ac0ca628305b6516a92b2841d2593dab71f2a13bd9a2f195db78dfac310207fa54873a80958d9eba96b584ce1927832b4eae414e4937d798df1920a1e1dc24e9be14bed554df0b515fe8bee1c6637d2aa822bd3bc17c2a73bb18cb3cf9adfd431a7cf2db5cbfbbbb3e11d90443781429c1f6c6e442a4f0c2cf44033c2c609cc8f94bccf10745fd5ab13644f5379bf3a6080f9679b4ee85e5adf71db7a5b0cdb346fb0ea3b6d56b5d1521912c82f5a682cf9b9f83f45f2940c43f642647b95dbfc6e48bcaac8fef3f13c05a9610b0d11157c5a841b6c9b394463e411303e35122bb4271d4a2a9d9902d408ca9f822db066fdb3875d2bc2fc990f1126df185592a24e4e22cd9d8c416f013877e41d5fc4f67defa889f9174481f676d1e9101766401d961b7e94a272d0689236ceb38f0949452af0f4bf549419e42c6af10def683d7fda680a5e1a3e3548b3d405ef625e9949cc2624d2e726edf138666843fd0fa2927c622dd0261a83833296fba40c83644c81383356fb856d6abafdb86ac0642dcafb195c86f1d1917221487d0443282c127bc51dd88c05fb9582866b441027245c6879a5aff5b4e25d907368b9f266ceffa7cac417b10c6d9043bd4017f0598bbaf902490860b42a4610b104cdaa4fec91f8b31de5716dc0e1d432117ac242e821686d0daab1f1f76acd6ccfe546a67ccc09eda6593a18a2cb246c5bf4065734eb6f7de4ea0b03811f70966649822ce93feead2877dec97905c52afb1c5aaf6536a9126b7e50cb59379db75bfa8c817950fe40f7c711d1e60e8eef6ed6cd6bc263e4b3adc657738bc6e23ee14487e2bd3d84978336ad9d8a0638a8759ba85fe2bf0b16909304ac38afaea78a10de8c062381506d685a68cb50cc2bb81354472636d68548c2865962af31b1e79fe456d5a990cef10d118196771a035fd4ca04bc7850b216c1596b2161982759a22ee2d99193f23206656f8bef9d2f2f8f1e5ae7cd4bcfae791ad0c67309ec64709e01d2d0e209ecb63c54e13bd2ad5ad1e42804178003e9858be1fa12e83a1398d3b63362629c8023bb8a3cc260aa2566af8b712fabb48e75a6c85e7fd74cb6b63fb99cbdeee085f2698b4b29dcc6de2b957fd2726aaa02ec002fb1d91efb756f53e0470ac756536e73cbb84494bd960653a7c424a33a2824d2415a3739ecbb21c0630f101859cf9d1e02deb87ee9d1b014b01915e61196445382fd4ba17f8f9e0163ff415882f4e24aaea6698681e2360fa5d6755690b30dbd5ce751979087c83697237dd97291217adcf827f1d117c479473e34365760a1eedf5d0efa125676ed72b84b9199e1ee9c14ccbbeaee8f796537cee613feb377a939757635bda24471048a47637221855c9ef554163c06998e16b45974d564ea67435552aac93fa0eb4e03ac109f0943fb805244995fac266282fb37aef99c8f51d075c17b6e65da3ed59095a8728edd2c24168b8ff0e640ab0524cdcfd514fb3393d85b86d072f11e1bf7651160e0ab7484b373ddd221c839d45ef8b8de8b564d79d4fff01d2a5bbd4891b1206bd7f699f08c14f08994dbe7f982ef853177d66f6b52c94a8e801f8191befc8ee35efdd06f9870b9f15373e434b6a85d3dffb7ed8b17c4a7aaf472215f4487066141ed1bab168ec1c5ec144133513d31593e8a00678df86d73e75f9184b69bbab6cf03ea9c0783b719595842d40ca87e414d6c8d8f5e10f5c31bdae0e154d2c7adf0b0e3f01f2c14dd7f8918427b1363a8e24689cbe18b58664509e8b694a5e2744d57e1f62b28d8beeba4227964a7b6efd03955c47a71346a5ee5b139eadac0a4f0f451da4870635eda091d733f725cf2e033f6e185736326166d9e0484c4ab6d4abe33ac92a2fb15d588ff77f1688211369d631bcab670a58a0a65dcd58132dc0b12e3d2b2d58d1cc04965b968e6f6831a38c53f768aab4871d4e519e84505a65cc4fb50ba4c61b2d59ccd406f3a65137903466e34a2e829b0b9551671d77d37034fac611006c8bb1b709c1e078d8d46b96da823df28272ddb035fec43f381096060855f90e691ac04f8c85ee8eb41e7f4394f887f7d4ea02b52825e01c633a16a7502264e4c884d03a95b9866a9e24383d587a4d445ec1dcea439a0dd5c63fd3b189ad1c70091aae6d0b5065deba23e383ecf8413542ff62a152420aef320592d693d6cacda0396f376c7c13223f8def618c152f06c90bec8dfbd8dbb0236c40197d505e6d7559dc44343e9b8ad78627fcb6b5a3997aa3f81d733ffbb3fc4079dd0a814db80b792c698926f39a569e9862cfcf48c2976baffcf3502f60dacbe753f826119d284b933dfb8113369e95bab66b22bd816d37494ecbd7d44745c24e37733db9b8d8276dd40a5239e7e457ad25885c4d524e8c1564f135dcaaaa9938d2bcb4c37270352cedf0316f05b8d0db3876f492ecd311f9695732dbd943ab2f76cb4dfbff102d91b511b4c5080206892bfeb74fcd70059ed6a6cf41115bd6ccddaad17bf94d8b4c71190a746cdf1f04eac526728ba4601b1d84c6fcfe1ef40f12b34df1cf26b40c69fc361a214cca874402f65d8be27fd98f8686e9350013a8cea99b6afd3dce46a6f88ab46f485b89cf4375f68bb6edb24887a561ec6d403e5ad5154778d31bb17ab1d541b5146b7b5a8c5dfaa6084ec0bfbfceef2d259b7924903d5e947e8789a86fdbe0a9ff03bb2603efd888c05af6df2c1f942b028826ec578360000b8b9616a91ea783da9efddf6d3756f47cc395447ae19d5fcfe179cc83615a72cb7fa38d618dfd62cf32b97f5e8014762731c37898fc91fbcb23fa375fd85165c75729c7194fff3f67cf8511922e07341f56f6635ccea127924de835fe9b9759aab74e4ea6b35bffcfa5b180283c476cfa1c0fc57ec1f8ccf9fa8d1070ce85d313a8dbc453fa7ec7753c44df6f04f1ac64f12e65643e3322002ebf69864bb811358a64b2353642d4d0d90f75427e03ab9c24baea2b8be8ddec575853169ab2a9d2bdb593cd5ec2221d4cf322c553dcf164354471a56b364a8284de06b23e7613cb4cd252756dec9fa122750a34f4d38f19911b5d596d910d050000ac5b11212b4788281292a5268e32a390db7f53a3e7889ec1425a3216b083ad46637ce44785de5a35422559bad4d61fb4e74966f0bc13d13f788cab75979232bbe7a79902a0582f4df10144c17f92161179852aef4794f2f8734156e4a0e5de70a1e977adb31a79058436e4fa3c8bb6d74c459802b80d5f6417b0e3a28e261d62dc34fdd01d13bfd63452949005cda2aa76e4464b8a99fa505cd54cf7fbbcaa2134d9703be6d1cf9ee7428ed3f5278a00e4b4c178fde711bcc1eb2d492316add200b4ab02eeb681edc268bcc6b0c8c8422b4e1a7f67c804f12842b3c99320ed36e0b48ecee8cff954a855b06f604e759bcad4cb9d1bfbc50e1bf047fdba23b70fcbff3921f60d4cdcc1a596d2ca5c1814205138254b48fa12ec38e67e6d755e26066ed6ecda4da9986caca6be521340911ee7adc79baffa7ce83d52e02569ada0d59d46747caeb83782fa25553005319f98fd4c7bebe0162c803db88cfd242d894fd1d0f50bc4870fd90239b4d64b3f88b3e62420511cffb8755f248d150a41ec617231d124b019d9d44bd9f7e3c79fca99e7fe9fff1d9e552983351373e160aa6272892eccb5d4286d96dfe3a780faf8e59da72b14782c722b50bf139a717a1bc78f03a2813ed7cce6c4a2df8283036eec6fafb6c395cc7e499d0836a4b9485c7a6b1bf00917eeab54ff3c5eeb56eeda17e1d4a98d6703031efe978b9e7d05495158a9a2762d88a4a145b174cc9a1d930767286d0e04af777c1fd4a04c54b9bb54ecc7b5a9afca56a1f12a707ae904669f4dd316817a7914b1eb68b0c8b84f60f2aa277e2e80fcf65248fcc2e7cb2abaa53fdf0cff764ec0cb5228b12cdd934944a2eb7a513a089c8fdc9cb0d807ca5a670854ef2453cddb7376765743880e695184effcce0f3fce77ea7fa65da8e4febbcaf230e3ae07807cbcab75b97c14cbb5d21918cfea580154fb957bb27348c9d55d523eb930bf58ba0ce8cc2d47ad59e60e0430c8cc35af983b92371a9221b046348e315f95190c74b04eef7b52ed5d951c47f7ce156d108169ee08810f044ea3c9f823dab3cee74042ee6dd6c69b841b61d7ed3f7af8f8a31dea8a81cb0d1ef828fc760c599048c42bea1869568807a183d25798f89cf7711f06cae0ed51818df78337498223b62e7891a994d44ce4eddc12a09a5259f004e42f22d0e3778912aabf80ae402100b9001a06daa88419ad0ec93521534c51f4084945ff7d04ca1697ac0d5eda92dcc72896f71ed7e9b8658f3221a9060d14154b8b1ea117e7baa9e22bf0a8a280019ac79c4c084b841245642bf281bf903e70ad323e9d16cf24828441914ae0af9bd7209f5cffb8c2c4a6655546fda2ceeecf5ce12d0516d04e979178dda5a2d89b1b9e685315f3b86fbe7e592b6841970aacbc29e77a59029b6dbe7ce07203bdf6fa49c71450023b0bbb176468bb2d230aa29be83801b4ee0f6adcd1e85b357926a34e87fad3789c9bd0e8cc5bed3ccad4c5074040a26777e226d8cdc662a3923ad8a2ee79497685c9d0dcf4ccb3f7521846b3e115edaf3602a0d88de0dc52c2fa01dc77cd49ca9cb52c6052fd55b0012d4d51ecebe2edc5954f63efea558b0a4c1cb5306db0a9a84c5b6e145902700b442974f0365cbf964934e7aff851464fa5117b1a4b4964acbd53a53a2751c0c4a89f6b9c120089ebf859215c9bc6e6af40891905b8c44c1039ced08cc3b6e9e6de14cd5c8800559f4c6841a87f37bd0fe2781c3c42d04ed15db25cf63a92350ad0d8d65d99053738bba262c9975395da9a0526b57829f662c69647a15103fce43579629d336df7e9aeaa55db894b9b5cd9672197e0d651bade9c8a53e789d3c00f2e4e3029e07b824ccc2242836f24b3ba646e3414820d00a2efb1ba4834e7414c8605eed1ac8a18d9ea5548846703be48c79d04ad8dad9bd746a13698772851518aeeec9905df6e801098213bb3346b7c42b0c3a2b6669f2d248891df1df7a3518905e06b7c0aeca8413bdd15a19964308913f53043413a4db3e6a47bf1c6cbc3fd24599f5020329662ed8353bce7d8aabcb510029a9c5f92875858ef954051eecda0748847047421afd5cbececdb26255d20b203d90725d5de8dbe92a79496062151a08d5c888a94e9b0b397a327c187535bf8cd23f06ae7251f0324a39af1b7b6f075203ea184fb21fd6a7964ae8aa0c14116239282425c1e1352f903c686ad5b54431c5c39632812be41c89124a5ddbeff9e7f18bb9165822780b4fc177d36208aaf40886196782d8956664cae496fa75c3a0181df2c463824f2ef05e59605ce4aeabaca35a16790bfcef23e2e1d9c25904b587041e82ae41229d1c5cc52976a44037eb2e5e591934a749b255eac0c017577f505445cbc607abe102c80cadaf112abbe88ed0c42e5089aef2da4699e70b47c474b371a8f273b1889b033576772dc3183c592d7fff35c1c6d21c4cda404e2ff56ac2a73e545c5aa0106808a27d2111fa6bc490dc7b13570f8882923a86229718cd426f7d14a8efcb85b68a419398be75b9a963f8f2a60068440821e438bbb4677bfef0990a2dffd41ff6e9e792dc301369b22cb8984b1a2800bb0e6d7fa3af2d27e5da1f58685c5c720696dd1a823906d8f7857259279db64087ccecae2b3f6231175fc00ac45aed50653ebedf4c78831ff3df7e9da0f947e8e71636dfa0a3d162196bb8a5a124a1eb0ef74b80c912b08afada30b538f27666a2483ba93e23234dccae26dbd0972b83d9e239040d0a76fe553f70651d9b4e3607e8698bc40dea1659f452457eb721ba8d84ba4a781f76a1de425ff556e9a773f4249bbb6ba9b67501ba13427a1e3bb122303d58d6cbf39f370d7c79a05ac99e1d301aa27a6ecf9dc054951aaef82b5122238771503d727f38438eb63be8c13f3d7571eda38973f3cbb440fca84ed3b87e4dc6aa06b99e6c6fa6118d3f99d146916d42e738fe68058ff0a21705d72829261e78f8ef3aed0003c31ef61a930bfe623484de3b90458039fee3b920c19c51339efbb2f1fe9a05d5958d75bdc0c969f55c273e858bec9abc58f086ce32235a29014903a2b40fe64361f0e747203bcf06cef7028a22e6982f42dbc8ff38bda231d6b8bf826a7bfa34caf80ef4693937448e85d805018a1ff10579369e584ff85be599bfa617919199879d8b5514a8c965c1741e45b480cb3894ffa337711a162d2e2ab32411b53d06ab46c436db6ec44b4b1c1d67dc74c8d87ec560a88e1ccd4fef16859100cd512d9540409b135f2533777d551771e7252a48c9eb0e7a9c42e08edbf232f47d22ac69b28e5524d0aeb325103177dffb1a1c272fc2093a357e02d4adc26f5760ac4e6eb683ee84733745f7f7ac80d3c49655af1cbff905fbeb12452421057ba448ec2f9b7eb17f599f38cf27db992ecc7a8e49e35efd9c28c5c8d5225efa3da0ea58d404f75cbb159327c821113c207ec0adf39716cc766e8459c66e6784ae11ba89bca8fdf6e03ead385142a9d1e1ec944328de157a53f67a1610ef37d311129b3ad37babf04026ad97f04bc45af75c0c9aed3ff90e67b5c325c57d3b34cc0c758d915079377f2decb3722f8c62d6832bb32136704130a9c057616c79a976f0f7581395fb81126dde8664d7c0eeda67f72929d178112357a246e673ab8c48db55ee26ebff3836bc940a2d5032705548e33b283ae7692bf8a2b94ae7a4799e50d82e06d63a550bd1595a6f986092015a08871c21a6fe2a8abbbb240e79adf33a732cd3523206a2fe0fe26dd5e13d904660c6d29a06a0c52f3c7d37ed99d3f0511250c0d0d503f953ddf77edc13e6271eb5ceba50141deef23dafd92c60ecd080d8360f1f50d73af376a54b918541d2439da11abf48bc6ae4107dfb3af708d9851aef75c43092b0913fea56cadb12dc4bf8e3fec36f2f27ed79db8cdcfea717d0738eb2d60430761a1102cf27c105b2ba01922ed8c4f4fb996814e33849eca43d21884f904fda2b31cd390580b0a738c43e619485da22ab401c5b0edbc915a7d61852ecab9aea0793e8224a5a9936c6c9fb01186eb7ac47eb266434b294a6e1743213f52313630f7484401cfdaf270a684e50b18214cd2faee96110c6f880296508631e5c7b0e39a5d8f9815bb7a0821ff2ab6f003fe2c10d6be727ee54c307d8031687f686507043aed5d608c053672d1e55839f3e87560b47fd59f045a03140c9a510bba7d24b5becfba5ca8018f52bb91f68f27a60533ce43a0f230912822b869bfb7ffdee387ac91a4f2a0c15b84e368d9fdf22fe7eb584c388d4ce6edf0ac4ede97fe78c8f446a4af9d5789078f902970108b9029239671c972166781f537d3531d49496d743174137347149a6c638f87424f33767bc1543f0de08adc6e4b8943c9f14a1886c3e725c94255be80b3669f92b6c667dd3c26bcd2aaadac1481d560ed0ba2a64022f3942977e7c5085d72b49ac9874a20b5de15380182b94431bc9a165faea6ac5c76d650bae990262b1a9ef50cf9b23a3164638bc088aa473f231d8eb656f97994952efc6ed305704c9b5d0e761646cb1d2f729df75c43ef1ed3a49c731c8a7f6347bee4f532f95edf60ad556d6c7f0469bafa2b56be0ccb631a663627d7de61b12cc2c31375b92c31801eadba8587906956365d027a08baf95b911ffcb5ea697ed53bff09e4fbe4fcf018d8deb0f820c8dd473eac713b8de9953bb6f82c658a3af5830aa5cf34eadbaf878f25f154c31d84fc65cdfe39aa5298b895e262b83e89d2dab8394a23dc8f22037d969e9155b6abb0b3df3967ae2fe8793b9817271231e841fe27f67d2dcb6d2d9560cd34051fc244474126a84b909937be2240ba99577d1dcf9edcba32567719c32a8ccf8a6af298a5b3bd6a20cfeee54ee08be1af669ab30adc3e99ee4fb576ab1dae7e9b1d7fc2bad5dbd6a7e480ae4a388cab3bb8dda29a3639a2f3ad60a408496a9134ef165203b347741238c948d42c5ac90561ee36898e545039954d94b514a22dd1f7d90192b6115d492bef6d292d46105cd396568eaf4e36d4f252387f28b1f69ca642928b7a140edbcaefa648dc46396ea13306a5ced657a0243f92cc96e75e8b1ad13a3e7946152c9b3dba67f6772cea378a46ca258d995b1155c18230d74a61ce4c5c1d64a39a9ce4cb7b0db04f504321952478344a668774d563288524585cf542c48d6d98165284ea17f81a34ffca606f97e4a320f5941ab1aa375914554bc1ab17164a43e74b261ac439cf5226bd480f91eb50208b91eb034246e404b4087f9def9107c22b468f1170a28ecb15467105ce0b529091a580de928889c60e5b115c4843bf435b4451d8e1c920e1e7e96bda6d46423254c5bf2db2e84b3bb49a39c5318ecedeca440edfc9bb721862e5da9e43cc031e9bd12815590846f22a989703be3ca336186ced57fe721e4cc3339d2fad56687e702ba45d8cdabf87bef5de68e6266f043edd54f23a97911672989968903d303bff834863a7fbac4ae768c9e2afefb746c04405fa56f18c0033d0dc0e9c5a51dfc7828774dea3ab1e03250e15eb1f8c80f71b684e48d9dd09d0a7f69908283c2b6ae0eedebbf8d68041be6fb87751763b152a5e57654d5d405fb51989fd29f988e92cd4723ef0d657a22f769eed084b6ce94ae4babb23b1d2220f7ee17c98634231bbc62f4f0a703dfc7c224b46f2cd026863f31adf1d27c7d30a9067a842144f89f8a39e487f0177646aaab580cefe5af9bca223cefa731876c49f9d15d40bd68e1cbbbc95eec558af535a36c7a71d8bcf380f429c52c4a9e7b29b03d04b4fe6932a6df8109a84e3c4aace3101817fd77e56f9a04e6da4a5d92168c4e70a1fa6de4d1facad6f32324eb23257f33425bcf1d94522c2cbd300f47677e20bac034aa42452928f6b89d10e69abacb79dbf2ecbd8aca4f44f2372342b4bd14c2c831b15e2353c1708551d0105c40f54de8a33c10049012b7f6ca4b71de16e12174fdc9e0dd494bb2b2aac8d80ce32b5e1e811c43d35eee96b7b25fe45b117ace3238171bd800aace2b5d363d6e98971177a4fa81b2fee5d8f7227d3605f1bae12365eb7fa6f5637e1af49ea514d15af59bf59126fd1be27af85fc068b4fec9fd4f5151b6abbd887ce399550ced7bb4bb57f3301996a43e7a93570f0658ce4b473ecb4c5208220e6c4c9075bb6141dbff0f4d4629c4987b15bc8c7aab0046c79589dc2e71719fe8d8050734df17f24296fefb5eba636083715ab2c54d5d44149c570619eae082b54824f16fed4d3b38665855d866f4cd49117da81325c94bd25ff9ec1d61b55b8bedb53e6706515c6471d4da703daa9c00c154accabf8954a1d298730e58799e45f231b165ff5d4cc29a56c1276d1d3c70a6348994db6c502311f8bf35a94ebcfffbe94545cb05ae16841e99e45920a19f560fb28bacfdba90d2be8c254d09f2e8add514f834412700b146f3135dec210abfb82765c324bbfdd877f0d8bd4f600b58e39c80c8a9e848cb9c59177bd5cf011b3b8876d1f35d8932748dd247c4e4d44c623d13b1b62c6da9d09eb031ce634a3f7ff323119ffbdac4b4fbf1750cab30815e0bba1e000704dd85906e6a12a3377db8ce5b0429f6e12d23be397f301960345e2cbe16721e02db0b760bf29966511014eeb33698807066ea80f7033edf7966c1d5ae37e139ae7a8e9182bbab3a0cb8e1168a112948fff1e9d398e6d9e89e648c7d366bc65e108b672fce99eb4a1053bf27eb9b5d0eb4b0cfe7cac273cbb3efa4c72f1cbb1c4e038c9431eb61440ec8e821b2245f10d123b070d60b8a942aa7df3957b6e560a7b288c9da0f6d85079ef041abb91844fe9e2cb34eb4d452a3943abfa9783a9b3631b84bfdcf396fcbbf7293413eb19e059cdbed5d8da601be34416b4dba6ec65fecc4a29cc533c40c057560aff57882d30183233d761c73edc1a76b359bd93ec229c8f7a7a365e0a209a5146662a5421cdb2ead436dbbd147c66314ae43bc1f0dac435d9d0f5aac1745af71284b50ec30271ead18cdc0ee7c4da45defd578ea7761005208fb69eb2bb1915e244e2fd7541c75f213446b2a0c5391aace84e6efaa7fc7fbf9e7b388ef3ff9865408e0d1cb807d7e753068e8bc244a8844d8885c3520b27f524ae6012932ceab163e9fc810389adcdcde9f230a9bf8921016f94993baa700faa3bac538f8f3a96d1774603c5f2c57837c99d26b660d5b95c1656d4c8358065348dcfe0be38ea07f1ab6dcdee05e987adc5d4af436fb5c1d2e1c5ce8a9ed6770ad386ae86e73145cad3b423ab243736f48e24f15d2774b0b7476f575b682602fa9df2acdec5ee0f6c12c685d2c5656aa80ac1a247d7e4797419baa5aa897755804c34703d99e46729f26ba7f87453868061df979f3ce90d571da8c0f1a2f54fe9fef91d99fc894d878db38c89809f24ac228b508044344da346f413f3357942d7dbc48285ce731b49c0fd15a622204fbf0894f239c7911235ff65cfe3f179157b627c316d8a7c2a5aeaeeec28294bbd6ed7d0311ff1f266ea3c4a82bdf841dc1b98de5b7d2c237b995f32c64ea1c63250b8b9f9625ec0cec89a50c89660772ed731093fbfe41d6237c4371cd541c7a856f637574116b0032190da139d87d7b9dafe40d58d8ae3d260046c74c09539dc42a7ef6f5ef0a5d0a4b307d27485148a54ba9735ead73e13ff74fad8ed36aa13a71d22d5bb4dfef5a0babf1414fb584a4b09832e63950bf2faa4cc52677efa6cdbaeb70b103536beef757a4d6115da4b29d037dfd2ff6ef9c8c9718512b072e083972904918923cc854ce9eb612e5ed286068410851906e23deee9f78ba45b19a84274e07e80823b7e73b30ff0d2a166be919ca9f6c220a66483f56015820b8f3fcdc88f8251ea953f981e35898d20f921189e9eedc0b7ff21fa6ff2be7120301d532720e8b158ad468684ebcc9f4f440f5441638e0497afcc5c73f88d0b59d7707e41ad3c684cc16a9657b2c16d63a94a3a983e809ee6f33ac9edaf99a72ac78d3a260b0cbb09cf3e611d85934fd1d30cd54d57b1de97b49d04519f45e590f9dcdc309b3b4447856a3fe2109d1bb4acd61a1d6d814197dc3b17b8738e500b6149dcf38eae327c5508f5b2bea54bb32fa66ab7455e3949ddfea5fe8a70e5331009cf2350ee880256dcbfc8484f77ce77392510c8eec6d0fa429efda43ce174e66101ac8828407c40ba9856bec457b4c54c1bef040903605be969067ec3448bb49b512ef085f16844b491651d8d9ee3da82e6c3723d7e89a9fb563ae8797573e8e912e24979cd77ce6a7a791f94456652bf002c69a83e410b255c6321e5dac6f61a0828fe274ccd2e93758581243487300e9aa35515be69ac0539b399673c1ecc2f7dcb0bbb3e05ffcf0527525d966edd8e9b105cdc4fdffccef67100d1a7c6c07604fb816aa8b7a2cf2231cd0add53090e1ac057586e44c4c73c3c8bf687fe5feeaada0e177c78f26eaf2aaa08cbebc041a3438ae3a5f0f895ec4f7611b60d94636f23a01233521cdd46e3752aa6846876c4bcc053bccb4da09e8a1b6973b2e6d00b8d173391e17eadc509fb5bbfb3a34e3600692f36e50c4d7756773469961c738286f46506fb4fa277719642f475ba197989cf29838d508006ff521d2c0def764ecabdfa0d4782b0e5f2d0a1588dfbbf759484b04c01d5b0eba8194575bc99a84281c94bdbf047a146fd05f5bbbad1b16d8df29156aad7501831acab68b049ee4300b1e1cd83916536a724cf33e5e7379056e2537ea013518e5bb70dff67781f8ab5e7b18f17bde4d2bfa66f2f91763e63530ffc67012cb7382825303e57790ccf85ce4b8254c99120ed200b1f63585fdfce2d1662220394d9169e1755ddf0a9f2812738fbc331e523755a666daca557a45183c3a7f14a9716be79ca7d1518c66dfc432d5615d0e28af2a87ae8f224c9a63cf74f9ce3dd04edef265a9b33abf2271adc63d43df33b0d890ff7fb691cc0529f1a38a4ef4d5913d1b49dd8e76c106c57844e3041372ec8ee419309c04190b359f076252725dde21995d025fa2eee37520b577b81b2d1c24a59645e5656ba08a589b28ed95e4b88ee09fa49356e776e166d47acc3303ba42c5d9c663cfa0ea9b70413beb66296b0099510bd5b917a6d49e1c430831d3dd34369a03cb552cd7d1aac1e74e6aa6850df289dd7604b19b2a7ff981887e5c88fac6d9e47bade6c9e3125a84ea4798126185cc065db80d8cf26ed15e171c791446eff7ebf627d1752d330a069bfe3ec952f943ac94109b821dd87145cf0a778d0f05d5d6987144981099bfb6933af197e068f34e35f0f9b648755dd57b3dffd0a8826e850db3d02d14657f1b1220bac76ecf241ef4da9903622f4ed2f11401aec6abd46c852176062def79b819ce1e39b5ee56233ee6e1ebc6a90ce3b400868a29fe8804453641837471692c7e0023537ca1b50df62b73f8979e61f6ec819331f3afa49d65217029b4c2ea94c9b6c11b4cea5bbbaf412ebefe92864efee849947d9f9bd18eecbef212cb7d785410954570b41f275dc1af154a97682a50aa70201fbc1b55a0b1232ae465690e45835a383f158a05a8381137946156de528d2010e9a2437ee948deb96d86d2a68bf1e49d5ed039399a8e22c7e794cac7ff6ef89ed48a818d2b658ed9ec4833920a7d42bf7ae4a42aeacb5ed9244f14fb540622b04fa60e425ae24ba6d72f1ea6206bb6722faf08f5fa6263ef7accc6a776eb33645cfc8aca5de8bf9c0d29bd07c02c701328b07f53cfae0b92bee5ae4945e38166ec4b882e0632f7db3aa2c4631d6864798521c7e04be3d6f1b4315c183d4a7ee6e0ef8a70c8deb62cf153508374d5ca475b94f44b2da84e6a5579d870e2d1d72d25ab9dc354520ad8e1420b1a1369783f66cc5831b168cd3579b77df00dc1682509c4b6d6ba51df129b5f67a2873217aedf0424f16d77eb6ed1123581726a3cd4617ef426985254f25f7c7c7fa137b6452dd48896cb9424394dc496d63a6ff040bcc16ec6f00eaf50b2e65710df3c78a46c10b0dc214757f7727f22546b97b6c0e1fa16aa0147cafdefd71606fe1e74a6ac2ab980196f4d149bb5c9b7fb9f2ae3d4cf662d7668dbb66c242ba0be6ea4ca491be5a75a73cdb10f6880236f24bee8bb6fac914a711199ef181cf5a619d273912ab672f4a9fb73a3a443ea90d9b7530df288b8c9aca6a0ea8d68193bddc23f3b14d75b63bb40692c4165293cda7dfac0179935f87f47fed41b25df80904587c14c7bca4aa46780015d42aa28fc4ab229f3d7162f876976bd46b51aa58c57588544b390f572707e9328228c1cd4b9a4c1dd335f09bdf6c0ed31fdb8baaae3b0a508520a2c81614d2d49f2bfe9f8e849b93206752497f3a122cf6239d23a244ad023bd8f0d7cb36c4e6a281cfbc6b86bdea3297767b3ec280380a4c2045b60ca48fc6b939c9837ea96fd05a79ef19cc1ccc5034a7a761555db86e43fb26644a39776072e13680281148cd7aaeb2bb086e5df06ceafd2371581fb27a4f29795878d0932ec9b71ebcb37cabb9b64465396a06357bd6f43f4d4d458329e13d0c0ca7a3b2adc5b44ac5eac144760719423ed96189ab7228106b05a94f9ae7deba6116c415e844293d8930c2d53dfe6d7d6d1005f56e75c0e65c5d3ff0400bee598b2b8369e0c07eb8ae2022daacf9f21419bea3d94b1512971c319359da2b5d1d6791561ce5ea9b62994c36a98564014fba6c2e1b17ec7f4bc61ef509d080f4dc0453a31f6ee694bb6502922659dd1d1cbb7cde606d558713828509dc113d395f184b8ed835bb85217d56d318132e1f71532894a600cd2f31ce58949c36a851007cf4eb05d2e82cae6a1a2dd77fb3e1409382af180d85eafa3a870337f272f653cfdc9875c7f3b6f7a89ff9d1e2b4ddf9161d79cfae8a5bd61da997a0d638b17640b1b6530c3d7ed64c3dbb32c81747d16f5758aca5fa1a733b1432493b1616ef1e2c8366ff147ee5d7f190a68b17a0a936ace18afab9210d2ce0e19e85e67f110c3bdc62e40f25ecd36c7353e9e8ce6e68a4bf5b3cb240447a1d5a384109fd13c6c71cd5408eba657a4b30af153d37c041f8dbe69269f433578c89dc2fd4dac8e1175376ad31a287e17936377adfd1e736f7317239eeff59485c718026d8cfe3646a639727e094424aff4b2268cc4c8b12f1cbb93393a5df30800122fa8da2c263913645031065415729cd82cf9f3dbe547a566f6328d01145a3af3cc205d79211ad31c3997d0670acc1da475f0769678dab53db684ed736ab6894c90d4a1ca19376a928454fd0e2d57efa7081b628ef93acc2dd01f030e2d8721c17b845aa45b4291b883764a0136ac576b5f5576fc2ec2283261b5f1ef9216347abbf23f4e634ee33552300f40274d935616b43cbc55c1a5c1f2d08f26bfe4f0f07e597d9f26b6aefc64689c72d80068ab9157314c29beb490b7ab48874e40c6a69e00d36be161a61c36a42133fd232db98a6c509af637c4069ac7250c449b949e8b2d4721922d88fa4ab3143485652c2f318d5ba7fb4be59e50c37ad8b48d98cae71931d81d3d3d332105485c256d1f20eb91994695823cb09df6214331e3d4c035789f7bc7bd4759afd88cfc5f0f27d72d7e16098cbb4c7e061f5a984c59e2136e5f09fb2367e2a80fe7fced791e5558675d5eceab00e2bfe6fb63deba5d1ea8bcec42317eba6f62105530b0b46683abfae696f20feda959169aaaab16481f8a1b43965643826bce98cf4c532f69cf38559536de82684ed72d1dfb0e02f03d56d4f57b4a86069a68f7582448ff8443fafa2dc522b957ee8f3d19745ddae99cee74ddb4627f287bd2465be3e3bc23d84d021100e914ecc613ab4e4b1deccf6d278ca2e9ebad36b76814cb71d9eed0cb33b3778b89d2ad86ab5c2bb2ffb669b9d414bf022030930047d1b62980bf9b3b2e11bf882c80f631baf7f591510f38deadc1ea4a1c7ddca73ef0077e8a2e73cc740b29fe188461d03f76a0fe3989947ec74194e91c486d6214b9f1f6dad80397046ce3895187454e59d7aa480b74d7cea53ee01558958c313bc75df29655ed798616b739032433416b753de80e9186bdffa809bfe9ac48e6b721d313c427f5d9900fa26671bfdf53e10028c5feeffe89ffdfacd7e77aa72c94c62afc3c393509a0042d2adf290846a741e1f020bb40406741b64b9491b48250d65e0f6a38ae00ff4c243226ab5a0ab180cc6ea720e1b04b61d4c4bdae6b38aae3955be5d18b738b6a84c91b34258b19b37e37dac8a64cb167d401e86720207d6a0d9e2b7bd517dd7baea8b04376da83e8a6a3a7a88c664dcb8e71d9d83dda8fc42b94e904a257449bc9ef57de25d535de60c12d07e4e9a19f0b0b10cc6248c42598ecedee1d2f5953faa4d8c0a63d6cc973a927769e7f7c4031d83e12571e86ff74d1d7c1de36678db39403acf70c95f9ff4756179bc69320db02c00a681760ffb44dd116b88ccd21a2e658af0f1f5f8f8d410a41a481b0125b96d2a25d28e7e52bc9793b55d33ed728304761ba0e09bc2a2e9d4e07f80af1e937cb4452528000446aeca31328498f24aafd6e3655a5224cd804aa1d11af9805995f3feaad6a250b28f3748dd0d1d21e6709772eccb19aae345f5450cac81d6cf3eae2b3594c93cbfacb32042520a61298f7813fc0d5ba01c997e2af01bc5944f6fc94ed4e40f8c875a09eb53dbe0fb45a16e5fcdee2b87a7678221fb10c75eb14510a71aa6ca4a019d180bfa4a7eaf31143317c73ba47c3a555da0435b834d747ee8dc9ecd11fb14392c4ff3f2920eefda1e076734aa8a89880c67a41e52ae779d8fa1ee9ca5556ccbe7ad5c98ed143c9950da41989318a8c7d2bf64b1b9aabc1b27f6e41dc3dd36936b173e059bf3b16d0b7f20a66e59b5a33799852b3f7e9c73f0062b2e8cdb4376698c7b87741ded9dae005cf3d9d4abaec957ce4f16e069eb12a1e211537266d68aa4765210f1083c31b15148de99d374337b5e8b335b1cfb6f5f55c5f5b5d4371bf2897803cd81033ebb6198427761eb1d7f1a9791a1f88963f0cf007c3835b6bf805ddf634e921f47dc2eccc80749eae602a50a24eeffdcf850432a065ae23922df9f7f4ca344136a4663a782c38c01eee9dadef310f0a99474c13c6273fde0ce8cd9cdcd52dd602d660f3ed092a0a685fe7d536d2e831b1d99e300341f8e9e27b88605a008a6f9b659b32a74d4b915a957cd64d830595e72e342c15b5b0aa22ef902b5e5d34285acf98c0e3e3d7c6c134e627419134757a5cbd1fb92f54ba3b9266bc0314a02a2f8ae7188eaf657132df86f26dcc25efd11c91560314bbaedc0a6222ff669a8750a71f35fd7a931d0f70de6e2debef195fb0943642f34f1f8ee80f1f388744cb0616ec2d6dbaf7ed188ba5bf824b210677b9bcc143f7379ab3d9f837efd0315a431ffd8b3bc9c43e054dd820f669c1f1538818e92f92f20658c27e65fd761572fdf3d1cba2b544e902111636a799559190027c4df494efc23e4a5f74085cbf43c45eb9090ff76e2d48d66433ea9a28f5a00d2ee213fbbfc2e1172d0c46cc48c03a9c75c51bf695f6f3cbcec09f8368ecad85c9306f9c7747c34b2454d3d32d5b250b03d2c33d569aab455bb916d578275c43a0b78778c936f2ec232cd1c594c86f629d9c03930ea0f7a9ac6d17823775f7fd7bea71abcb9914d34d3a7357850c05590ad3f8194e9e7a3a5badc8e04f1d341cc79a316ecc1da1dff8997331886a82e2bee1755e65388ad7f539435ad4be39a855f43808c31cb69163231e2616a948040072c73d867df8a3a73b3742364c57161d373081c6e0c532ab67c396e32c635fbed33bcb7c86e95f3ed884509ed21e17662ca5e9b68c7ee4e95057408685ec0e4e52d6f104cacb4ae9c34dfa0478cc945e36aa6872f94aa5a09686dbc565aa61cfe10a556c3b93ff90e338614592a1e76e13a052790c5ab1d8c67bd8e2e4f33e2e7f278d861f5e66ca322a53be8af5d4cb9e53176614837c71e39d3d8655008bd4c9edfdf75167b2e7441149fbcc1f8220eba5be8d7740a0057e4beced532f12a7bbd8ef36efabd02849f9f315e79b5b0ab709b8ebb8b5898f04e98cc45bab7b23626b5ef5558d84d13f8b5b6ae0d557f34caff0fc5d64cc2f797e5e4a610f6bfd68faafc1eb6a4605e609279d1ed6cc1d297837e5e6b66ab3e4f83c2e7356971081549507b0f8b55b2da7ce1ba8377ececfe6e09c27caa7e1a848aa07e3714a85b5f983e336a6d6798d6f41da8076dd57d8a13310fb2223536c3b797c81cc25f0c7469478d44d7f82671b7934f5adc906c2502f143616c22c87fec75f20dee8a199c7653f13f391fadff06e042718664a2c8d600cd0979835691457899ec26f6b1655a1ca866d24a6828d287328b47646ba70e35a1151cae188a7eb46d87c2e142755644a8be53ca611ba338075a3e6d5d613559460be5a88f652c7ef0453abd3930b680f734d482db660c088d474732e66d069f91336c1bf870e1ea6a4c0519e41113067e24d1005ae84cc9a0c1630a4a6d2be259d65188f3a1a5d1748589ab508c4fd27f8b914ef229249510697c4f88f1c5c26bdcc59898941183e53eb14e06a8713c69c76c75b2a2357d41255f16c425923c1800a1520d11d7f65c5688a000a9e5197a016386cbbaa3f25d7d1401277ff8f119940b8327085ee5a4c70cf18a9674695b24485f00087af5fb6041dfc37c95090270b993961b5181ffe0e6bc7e169f89d861d9c792502b36e2fe84d2d6aa829ac36035860a776fb931d2cb1be8b6f767159a6c457a86fee9166adb4cca5217cd8914b3e4f6a4fc013cb0ce02c4fd795b2df631f7ecdbe69e9fcddd212fc918a31262fe82d75071449f3118c8725e0769c4373c60db94bec432d17b2a88517ec8b640b38cbe24cbf753670a9a9907f43835d88d486db3cc5ca4d3b28fba7398c0c52c622c528b0c6c886a6f41bb68d53a0f6a3f16c5f2cc5141b63d4e4ed2d128587cf50e99dd5871e3162c968a5737db78f5476a6260eaa8d2bb33481a6f59c9bfaeb8cb0ff8399e3009e668b165e72e46ac202011e8c48d14dc4f3f00301bd9d7dd0c33135b04eca263f1b7b4464ecfa59c57a151d840eaa85ddd8e8d16b120c49e4194a27ced8c9c0591d82c1abb19e6d7864e9c4f9afb25271bc15c71ba8ebf8b439679a4edb48dfafc3cbeb3e5dfd5b0b88c89b90886cc11a9213cb3026d86b480524031ecaa18b3a60b4524c18c1c0054fbd22950db0899322afa91d060ab36a3b4b55f7bcce9549712de481932aaeacfbaf9a8db84dfc57dd51a31e390e4b27b778aeb2a1f94b9a1394321bda64a0215d5a70818eb0f6719099fc6164d28d73902ef2bd4b3a775db9d1cf363b19c77c00ca1e102a47f9dcd8c1885f74ff964f8c85dbf9ccf04db624ad6fae6cbc00cfbd41e8ff0829387c8c14ded6eba72b18211ab78fb8b4d94b13e49f63722c991f30613d83cec731e0d2dca73781fc5c9a8f1183f70d465a095f7095a344b9d6c3bf9fcda23a2fc023e603ec3c64ccaaa6d568cb662bb84e8328946a594880301b8a3d907862b36054d1b90d3d7aad6c471f1de4235081e834270eaa47512b36b8c73ae78c45879233faeaa9060dcaf9631868d84150d4cf4e9bcb381ff6a74a789fab54d656e37442202b44dc0e542242a465197c3510b5dc3efe99fc420261ae03b4055eda36d7d960099a115baa8348e266d8fe1ac58afc2fc7cf28d160147e2cfd4f792f319c0093afa7f94ea2e32a800312d41932a08c2e226b1f331abd261d495228d64456470c5624dae5554e388f6341ed45e8ff61544e290a3644919803abab9c2a2d60e2e40fa9c98e2949af9f042f958db1c163659ff42975e9dd186afecf93f2bd885b1b206867e745044b1449acbab121100938ca47c68313ee07060b4dd7958f14f79b82bc001063add7b35fe5a93342cd91212d36e4a58d405f314497d7edcb154cb2fa9824efa08688d01b387ff4e228e1e5baf5af401dfd853a0246053087a770693375baaf50a20d7925370f900ce7f810a372a4e32e8a71b0d1834ee75f1e2e6636766bd9261812b0cd550f8dca9c736a7ae1669ac3a11c85b1d15e81dfae86f58ebf84f5814b277bdc5555a28802df68f143cd5038355aa28f61ef2b43ec992cceb7d0523e57cf40a9a2d85446957a80cf0ee8ccddcc76843454e7f77e66af22c465d7dcbc60506e9d0c7b0489ed20ddcd2864e8801430aeebcaae92c308955daf9044f63df146b0f91e06e9e01771cd57bb6adb3a5184719aaaf825ee9f8cd735d0821fc3be5d433587f053e8d8d90b7dfb98c388fee5fc205b5ff902950109b9029039a321b01493fe5cb5984044821e5f46c66a8ceac859f880fb540466cb7e62eb95f5818eec45670012c6300ad5c66d0de66048d3ed6a53f724790a4631273190ee39aff45093561177e97ec9dce15dee17c758cf88db1aa6a6fb16b34a76896fab0a3095dd43ac8c6314764696c0fb63a50208a4eaae4c65170049e8043931177cf9684473c4514a387327359de15952cdabbcd0ff9c4c77d772dfef18bf3f42c76bd1c490548725494a5681c782121e4d8108616d28acb392856457f51e415cffffaf11f47b299b86ed300c41139c895ab7277e1f77e1021329bbe0a51977d77ed247ef956d4721b7d946a87358e2b0ca98ac7efb40fb786d114f247a25946a075ce05b8c0ebf2258a6867d3f6e72d3ed8f9093225b57af550d78d26b94e26880356f1ef6c54390a8d3976b04ad21ab10907d5e29d1cbb963190280fc4710f7d12d44e0767f664536ca1a8a26923edd6365e84cf5e4c516380448fb5538d184866e80aa56a360dc401878730af55479080b19f0ee4be18bd6bd4880a12727bcfeb2ac14cf39499ac04eee1306a5c2578a8bc4ed36727849586533084569ac3f3b0c8eb53c8ab31b7a8a13e762ba0ceb9dc5a1c2f6920608fabc4e1af5e3f4375e486b3b7e5e6848ab34d9aa59bff451c40d174e5705447dbd0749b831efcd914294b418b8331f1cb9fb5c89730b069fe43567577ef529bb0cde29d8da518851038f8ecdcf6fefacb03b65879fe18709ac6bbfbb1347b94f6f7c05a9ea5db25723829367d92ba6bb55a94a128e340afa84194a5a6d82a829d93291e4a3605ca41994d25ae85a999e27d48109962b139b8cb8767e436aceb5f918f76b9848d23aee75b5c2d5fb5f0ffbfcb937d922c30ccd28e40fcabbb23a631bd0411cb36398fcf0e71cfe473605c7f0b10c15dd3240f91eb50209b91eb075243e0b965b506f2b459d82b6f833e2da4976f3b3a2178d32caf7e0ca64ca4d80df65224f74aabea0c55ec393f1ca40a09ec9a7cd3e608d25f44ecd5de270934b17fb9dd8e11ea067978963be7e50a7c78ed129e43c6cddfab1cb94033d019528749d63a5d602621592ed13927ea5598694bfc81073b1f3ec6b6ea249a83b5cfc43e8d0021fa6dbb47b68ad084052a0ef9162fa9ba4fccbff87aeac79010e25cdf61541ddcd1700a40224b4b84bc94e4c7d639c31c921223a98cd2e98017b7364dd49d7a646533f212794232482d6c71a393129b54a8ef419077c0700f4dac92f738dd33d7d95726e6164dbc8a0ca86e25a31199ed49636e490c8379c9b76320ebe3e28ffb2eed68cbfcad45e9a0a4cf41efe68b52494d9f2d2fe34e742a4a8dc8bcdf589388fc97b94b51728361e2793b97910dec076b8be31450e26b766f6f24ceceb3563633a7cf4122d3efdc37b8560eac9a414ddd1f35a12ecb417e48924ded4e59331d5f908b4818c6a4aa795d2b8ceb82681edfc8996c7ed6b44e82193d26e7944051115056743b31322b8d4ed130cd80d078499da5e822ab390d4ce20501a5195bf381392e1e38d47a3d7bbad13207ab0207f4d7ff9c60eb3f70ccabc8fb08271628b989853bfd99cf6f8419efbf704811cec175dbe1dd446e183fed43f7ad73094f70b86c8e3275d85ea5bac50a1fa3ba334736393696aa80d5fdcd10a0cbc9cbbd824cabf50f475d207101bcfddd355b5a4e524c958d2780b535043cbcdd38b855c8ea5897199ec19cc7ddb5c5dc1eff627ea2b73f89f3348b37e7a9e06ff3bf65d11123728db0e18f04d079e7add17c417ca06a5264516e55c1326b3464fb575e3477639616eb21ef3a75cb70ba423e30298e7d7cb68ace308d30a01d4ddbc7ac5ea9d261535b5f5a0076db395677a82e818e575d184eb416fc12934322554fa42a44276107771d3c291bce99672099c6b495ff6a532e93520db9fcb44ceac4191d346ddf1b900722ac325711bc4bd476963c1f9822c5efd22427bdfd0cf804ef5c856391c83eddced646996a71e5054918378da3d6dd244efb4f159d568041cc62c106411bf5ac4f87ccebdc0c224e784322445162d636614f0fa728e137abdf55391967b3e3b1b977b41aaa52e4429fd56b445f1a87de165f2bfa400d1fb17f52384e96b3a65c1c2245f4f8900d4caa7e68c0bc478cf904113357a0244b460ea46ac89c48a4851f939a16db321a74f4fe891e71556fe477fa2b153c8b988e65af14ee39db02655274580eb6e7a552d19d2282aa07c14f14646f806fba55d3afd7bdd9a1ceaab49eba8530219b3e81624313d10afef80775862dce2ff61a39e50963c01bd21a358bfb9b5c55dd57308f69828e807aca05a831b1fadb384c06d91f6667306b165d4d997a6621db25f665b1750d3309442b4e739d54f3a1a7574e64de9a29406b3af15681af98656ad10775bbfa21c09cc5e76215a5403efe12b1bbeb41dd35ac3b51eaf6e17470f2cf0be198194a581e6c33e6541842560dd3e22d65768caa2300398884542af4262c1dbea7124b14fefff292f294257ec99c0b3495702307fe460be870b4f8036c51c294d04e75f710d25df2d154d347f0e5a3d19076b9976691ce3e17c338440ade9de61fdbefcd6065c8780553e007911ca133e3926897ecaf46b52316263bf01d9e38639089c50932e39e9d2650a1b7d9345a50af931409456fd29d5e7e55264591b14a3102de6ce72e4745f40976fe8849f149b854ea2c9aa28022937fa3a33bbfc1728c6f7fd83e6d579532bd182ffbe54ab96dccc3860bb449b3c482bacf1305c9d297975f3ff4b599c245655f00636e453fa18806808bf8b8fc38494f5082bd6d3eb201a7d424fe931c05db424a4142f9fc3953277362a8276646793cda8951a5bb37222eb02d9f3cb63a607d83212dd714ef4e6fa01e9ae2256612c6bd627f935ba6425a4f45b078af3af657f12e8658dc4d675439d1ed5244d78d3002077f3fee177b46c529e03d16b5b5c6a402c62002b089c79b68fb537fabfed12a6173ba1a5352ed010fc5b7406e0ad98f87a67ce9e01993e60cc5ba7c0c2eb4862aa89aa6e5d7476600b0e29df9955d5fe810da90043d19dbce279c9322abc265f9c14df07438f644e5e3b0eff18fc60ec9c16f8f4e919c30e66a86027b5f02004ffa3bd34e6545efd935fcd780205bc86e13f86e592a58387f0957d49dd11bc79c5210f75ed11f2c611e9dd515e019ebbce74322d7f51cef8d02a1dd69993c40b36eb500f554f4544083a787dccf9bd337166244ad272c6bfdf2f5396b4aa292fe67399d17b9fb551df68e4c74d829be26734beab479370357a738f05feb79a33d4e466d58c12468996ef69b5b051e5ab457210296f1012727fa71fa4393ec4c2c5bfd46a36c481190c220ac48840118ff9cacfcde40788058e878baa2755af38d462b8e22a3df13bb1f4ca8ae8303677337a88281e0d6e0378841c45005320215dd98682703b2790e05163572956a19c0f62af13793c8ee1f700b4c535cf6e7802ca81125ba26092f6b5344c254a8b689dd0094de9bb664a28fc4e747acc9f9747ae240d81508adba833c4ec7d3a4e9fe5021bea3d3dc890f288306a15d0e5350c836c4494eab35d412703cb2864159f5068a6e7caae2ae349d4cdff3d0a3e493aa3b302912988a24d174f7c66dc86ed13f909d2236064bb228b283116ee7cf7538314b38081c728c30cba255b609b6b48e907720c051bafeed1738eca81aa8611e78e0d90b1d57d4b065e459604a364a0aecf383afb40b5632bcf508a22ab4bd76c3c567d0172938f16264dc0faeb51ad8c95ac7afe81ea42af846c23af27fdcf658ca1c178807c6185f8e3f63f89a9c8ae2a213c2abf7b8e800ac40ad88502937be43e167d869a944765b3aea2e52bafd00ca5c631157c9338a2c62812124d037680360b6452ae492525f4ff89d4f81c32792ae920628c566e126f95818356b0e4eba7587b75ce4d4c60704ba92cd244c38454458c2de07e06bf92b38508f2a4ac369b2a05df8a42b8ea74f8a670fe3b10557beda8c209403cd43bbe8ce9bd61300ba04652e2041b8dfb7294901ffd4221709bdadeef0fddfaf0bf2f10afab0a184b272f195c54cb8bc542424ecae828792714d485ca670ef924110d9cfd43f6c8e33043634fe8292f997e8fe4ae466d8045ad8ce9ca527587149b7dd9fee0a99651a0bbdc5ddb9e8f525ef0edb6307c15cedc867c93f6c89984522e7d9f8c7254ca274485ab9c35a825e82b5c2e559a12e0428bd31758a5d4390f93e5775159bb19d6cb6293c47d0f3cdfd6586fc37355f45a655965dcaa46bc028b4fc7ea1583a886044702b7616653ba3a18942aca5f07e751b036666d8c49605bba8cd3a28d0f3ba234238d90cd84c57cb78ba563cc9862c600fa82c792710abb4be5b3d395efe8442bc33430c664f2de79fdd263c84897d2f817dea51582d8c395b66ea8eae5530f22f6025fb7c5ea5df54e07de033a710df049209d5932e9d6cb974ec03fff8439fbf300157ef766729874ea74deac23e4ba7ba149b6bd3a883cc95f2c76be72f513fb1d661b674becc8a00105975bc70125f35b5af616dfd96964dd724beac1dec4e164ceee1105ffad9047658dff0f87ad6130a67535da50318c35e5ecd5719f720d6fb95e1b28bdfe12c52085ad3c93f828c1e685c7b4c6a2f7b5f61d81a215192cba70ae0045c3e8255ba360cf7079bc7d6ff13408949eef2f5d57a4cf17c3d13185ead4db5a46ad7abf397d3aa265f039159f3468c7966292a0fa5c163c606a124165a8953e4aeb5feb6ed4a6e2c0d73c9c3293f19e22eaf861a8719c91c97b1c0131c0a0c846cce441f6c392a644f6fdb8ae04e9c5552f6ed301245c623080f5924064d0be80808a532257cb6ad0ce91df636f2701a864861a37bdb22120a6cdff2a80302250360adb5c6d89758b29ef6c774d10e34c6c077d0d145570570688bfeaaefaa3918e2ce20c24afad4c3983859b8cb621468ffc0906fbdbc0cb4bbc5aea146fddce7c8cd1f87530466d49be368de41350acacff2492773e85661624554650c48cb151ccfdd35e1ec5ec3d30fd1c6f928b655ad6b8c75c3147c23da8ea056babd9f81c0fd69fac98d969a64c2134e33dc727cd2d99be0e58f7fb8359affef477180b9d18ae7f4b44dbc458e5d1b26c40a718198be81fb0910b894d5ed1b1b421adfa7dba67772d13904d56bbcfb3592297a37672512e0354c51742e63c53d7c7fba980ca8cdea15b2c2621ee58a17f9c9e94d6e20aef82caf4adb7fe9add9ef42a016945d9216e3788b7b1438cdbd2e5d8fcf3a3544e59e784784448bf7198669e9d4b3707fba630566577fb9dc46cc5036c21ba00f2f2208f09af390692cfc3b2be2c701307e6aaef6dab1648228b48699263327af59d6069cc18165b9cc4710d1d0bc88721d3ce15eaa0ef82104e55414b8271613a9bd851a24ce2ca354d41558f3dd7eaa37553d50597071b9ca4cd8c1f59597c7674c5209da809797ae4f6a030cbaae4d814a9d5ae0409f0c42173ee6931152b8bbe4288932d0a21140caf846afeec5633b78b926a85715ddc3a965cb38fa1d4d6afe18f392ea298a32aae2c768f5fa6e6cc34409a92924b161365a907196d7e2e6aa6de1cb781930ac10e1a6cdc9ab563770e51fddbb7d3fa9ca8378a209685c6163b524abe191d11894c9412762dee136409e7bee6f4b990ce5cf61476b402caad061f47ede85a520eeb274194307f0c19faa114ad0fdf1be73a1d9bb74c4042bb9f633b85b353bde0fec5066dcfc708674c2be43c57a22546e36be0ce7b43e1eae6605391c178c9d00353614d40842d008bb8b2d639395bbe5fc6f6d1fbe52c4b1b105b627d462f7acc2920fa7f9fcd2e0c7cff7f8b2034a395d148a3135e12c421a047eb7a39a015b0e95da9cc129979339d2111df345cfd520032a338eda428af27313e30fc5f3935ffdc0416eef6ba6ee6998fecc8671bfb27af986d0b0e276344180fbcd93cee3f3fd56a03a5d9e4e9bc6fe9eb05bbdb9cc8dc33cffc668732cd2f704031a1d7d6695f9041395db5adc83ed31e7ddb7147902172e61056fcf904c9f018c561aff6256fc1d5021ff7d17e692ee49dfac5ad16fd1a9a00d332c5574b5d706e5be223cff55ac31cf30d3e3755c3adfa3a52576fa878cb3770445b1333583a14617d7db68332ed9985a243863277bc99901ce7d9bc84e6271359ebaa4ee0ad1173395282a5c833bd01adc1dc7ee413266e091728f58083d8bc7936c0c0b0221b3dcc370506e2f7c3f7d70901efbf743a3be2ff8308a18b5030ef358a32134f9c26015a82fdef827aab8f955a96758846e0b21a1c303bfb581417f8ec0fd115b419c2e714f2860f568592afb10a96d56b64354fdff706d570582b019915d3fd948c7512835fab3b9fcb1677bcca85c1b5154fc3c10783fe313c3a2b3e89a70cbe250f2ccada5043d05b94125f77d71650ea89d179936f64b6e70a346733d3f4f25b757c7b18fdb3d84c7fc487f582f3f08af95a02176ddefc94e905c52a021bf7a7fe11afe17b6b358afe1d2886b88501e2c27cde38d6fdae9c8a2b0905cbf91ca60ffcf1764029cead91726a9d391a2e73c562e6453c1662083db78facb6823e3c6ebbd7adedfedee031ac40a78f20ce6be45939a216d1f84eb45bb01b4ce48ef867bd501f06c1456bbd52c8229bf245d7aba9eea12f74ee8fae06ae30a448e035a4d69f757e4a42857a11c6924f97329fe1f40892d0245364f77c3bed68a328fbb985f854fcfba814e0b49082ac6a1a5cc9c96b86348762d8ebb1474e4d1074e00041f85e1b6ef322622765a9a6dd807cd8026c4956243976f27df8c68a889fd5d2e3eb7fbdbe4122cd304be70b2dbb203386a6e764c8f26755d0e36212a5718f7205c566ecbc5951e5524ca263f78e0a904171f8cac007789aae5a650eb5b8bb4104c267f33dc6bc5c1a67b66726d3d60686c70fde40b41662bd9c802eb7c78830da3389aee3275c41dcde95925205b0090377924ab4d6eb7d4cc37ad4dc5f7301d997ba657c991b11f1e23edffaa96ec729a53b7a597dfe21c0955f54d5dce9227df25c75b85dcd6d38681b3a2773a074440b135f14af96bde63484111cc8988a342716e9676d3989c20348c330663f137b06199695051f7fc051241eac09f3ab110caf9677e573c6009feeef5e62901a53d767d60e6a7ea9a90f50ffa7608c72eca1bab9279d7a00f5e480da444890b47080e1b52078691903162233c75fbc9a67eea255eb9f76711e771aee2d4940cf60c613702fd50f59938e448dc41ac84c85be9df7747e33d7c2f30018c363f6f8e39c2157dec9a17115f37ee0fc162c0c32b4060c84cf9fb9da086d3df26cabb4ae16eda8b5941f2a6641d2cc0eb67b44664a2f67f1bdbed1b77557a9ee4d1b3389b5aac2a3ab863bffe8c269e0157796d25d26fcd53d0c8ca213434b0ae4db3263a77e87d0d106e06e0a52f2b8605b7d1861ec03a5385d1d6aebd9f9894215ee6784fbbc304f8f3f5f2cd2247d17be39c87e210b74fbf6886dec54ff7253c6043e95fd39271218298fdf147f508d9534701d57e7da4e98f0bf9831b20ef0e636503c5deb4d2ea9d9f85fdb27cc491e6b01ed5d3a9f692631b871384b87b6e07cf13fd2743b827d7a5f8bca8e0d0e26da74faf1f433ebd8ee87eee3125ac9d01af921493eddbbba2514082e7335adee751c87f35383ee1a8347155c412eebad1aecdc9afe8da3ebd64b534aa8741ea1d077b1e75cb56751b4bed8accdc39b338afd9df2a3e3376380ca03467376508b609d5cbecf2522fb862ea240c37862b2720dcbb60b2e902e66aa503fa1eab75e11685f9ed223040a1e4e50ebfbbcb804c923be203fd4dfa48a1cdae27fb2f029d0c1351ae64eddb7e7c287385273ca5edb2d44601eafcc6db201479a4ff0bde7ec5fca5122041bcc51b29b14a2fb16d9d2743745bbb8330387a6bad23a21431963e93dcf6428ea7ccdbf6c6f12c1a07851831ba38c8c2b53f39eab418a53ae7302e8431cb56eec033a000d7caf1393afe6b3fa4bf1c566dc7185be1210b6e28a981bf8a2e105a42f02b4484ed0b98961c34f560522dfe2440342fe425d74522b85b41cd3054a461efd7e7a2c51709b9cc450f34dfe5ea66865a96310d9671b901970d5e74f8a80a698802099fecaf6b3709150042c64e4aa5dc4adc9bb10ec39dba65ce9d962ce4ce72a0789a6569e06c02c201ce15e0fda83f43bb31b0a083ece5ceb26c7ef2dc5782dcd41d3b1efa3f8814c189ef5306d86fbf79eccbb549cbc016f2482368b2a26dc6e00a830ba45c93b8a8128bc0ab3eec8f34f8dd5df00079b0137ec431d5aae894ed27ddc16281857eb07d82f7c8de88adabbedeabe60f32c760c496cf184a84dac62801b0eacb9859b6b2683b304c8a0a342ec04506266eaae242e64db833b7981e150d89c02545a44df87ab1d29f6db1f83211867647b1598a62f7b90fb6918419e7f0ed60bc0a20aa7ba4cff90291f3d2095a37c9e4c14a7a0fc2c0579138b84191514f4249bada9d238bb53c5cdc2cc81aebe34b231d98916f767a363c21954be3f1bbb0e26bbac8939783f31072637b52a5f3cb5eb40489f40707d7b7c7b5b509b89d2f29f330e63b229fc13fa8c619ec81f0b0358125b7a14468b3bb269823f9e99359abcb5805871ab4c549ba070916dc650d3cc66a143fa9dc93b377996611c790e06d33683d8f70e63c1b4301389bf0eea2c8b7243310ddb8363cf57706e912adb676adf38ef4f02765a405e9158d96a7e7871c66a2bbf922cbb2e3e102fb9a476abbc0b399b59005cae170effa1d76e2ecf5234595d56af213299e9954d053212cb126e0bf603e7ff1dbb93fdb1fc75d65b4f413496113583053151db6fad57875dc66c923aedc9fc4a0a5fe10021e6b22613bc497be11d01dd3a97c7ff318cc30333c0e27efe1d72d680954ab891d662245a1e480390a85edec22f53fcd5b9b91a6f0625b4436e18bf79b548529fde1c5da6d2a97243d1733037fb5cff39aa52df303286fb415589f31ad819f2b0a5b84ff09fee5b0ec9286e08864eb8ab56d74e7da0705deaa3d3809a2886d66c2c98e9b4554f9c85ee7f8e51875476d99a6738b09f7d9654a3d36c1a7e1277b662128b08ac3906c5fb93fbea7c6bfe0c596e28ad1e3bfe404e73a582feecde35214fd4c575460f624cbaa01ea9c0b73137af364f85597479ca50ef87b92fb990079647ea85c798cddb5f0b8f200305fdcc09b3ebee0da14722692960c9a0fb04c0ba3349f12569c8ad7068bc749fb34f85eb23fd2a8c0f4dd9b19e21fefdda8b833d8e86d32968056adfe902b53b7af3b6e30616c310cb101abe7543df90fd42fc38168e9be81240fc5f573bc60151eff39bf7597e28c2e5da0dfa62f14d17ff2beaec7a5f1ecdf315261a1d6b6ee3680fa862e5e8a15f431c0ce49200ee193456c77390290dc5a9323b281c6bc91a298c1979cc6dd896432cb596da09190c41cf03e388ff1b2c52100a4cc49fe046df9193b1a42929f30011cf59974fbbadcb095e666b437bf08c14835a04f63ca3b12420ebd096eaf116bebc86b582b3d31a35cd00e79487a44a069bbd19367dcac459a24481f0fc554f329cc7d2bb4175c9a5d373f8dd3ab09621b3e35b5789a2bbe1c2c5c20f80c1b473a3f61e100da3019ff72b2e44b04ba8dc8445fdfb97c5314eed22dec9cf4f51c9073511f455f1bf7be9667f89b796b12513a8a7916e95fe7490db89de41b8fd8053f1cd4c6eec7ce3f03a1caf05398aa723f07b21172581e8baae21da5fd848afc7700fe88fc4f92d682ce1267069348c634cb90b231952d7a8f92af4b1e27a613118e25aed1bd958e0a740c8f7a9cf878f0de836b772611d499942e3a76fa0256318cc880e80e3375a190a8d8d3cc80c5e6dc15f54a9093212174dbf87f71d5082c6c0d6df8d03094327b3d8eb170693f0fbb33dd378fcbab792f314762a5804104ab90281ce35111ac3ce99b65b7a3843220015a1c53776ecef73414c32ee1a6504b6e68fd15e89eb39995167283f3acaabff80d13fe07286a067652b4c63cf892dea982533b78600dea207d02de7f82a3973c97ad92686823719d21f3e404663af6a13872ad96855ce63f84c1e498c828aa5dc232de04c1ecd9102d76fc8d30d1a51a9bb437cf533b221398cfb0f2f047cfb00f153c95d72b9747e39fec02dc1f412538aa2247aa3932595cf2de731c1736f0ec7f9e1306bd029e8d74cc43e4499d73df30f29baa7a0b7087315aaf39f52e68ff927152cc65b3a03678db9da7cc0d6bfc1c9e77688ea73fad8d3b0e0badfb43473d5a5e9a670e5fd8edbaa894c6ea4471dd334e1d1f9a2de2b827570fb50bc92a08581b33731e89445f7bdc793f05316b52e7b0c0aedce24a3ab3356d58f177b4d1cffe0611217c4b0026b02175e44e4132ac8613bbec0b6a9f7b84787a6c86c6b0907d94160fffa8f1f72f1748d94042fc41e5f10ffdc366b3874ed58cf00b0bca6384c969a510a7df4979de1b25769cfff95fd9b3408630b4b2c9f9cc9a0970259e0870267bb28aa8a6d2cccd0314a3b2e056bdb52db04aa4843037d1e40e5ba5d749ec8fed4eeb54d204c0133ea94e20e2950c0cc8e642f1fb103011ffd0427ebddd052e716590ac0393993985d9e87344b1c74b16ae55dec4cf684e845405cbf49946a0575a64e2e25a66af2cae36b126724bf93fbecd246b6fc427016a97aa8bc9520356c90855a1cea1afa4e645b36df1bcd3de51418c74c0874aed279e158fbfe9f00fc7c8d443638665bcefcac80c1a528e151087bf3728ab8853b1cfb9db6d636b349984e3e79d2b0f950b0cf49bbf6922e8bc4d7d407411aaad9c242c5b2f760097fd63e2568c139fe27891b3bda5dffaf2cd94bd367cedbc7e959159318a314f12f3d0762fc23cb100bb159af082eecf4abc09da00adb72e9174caca9dcea8ff9a2ec6e0b7a0d7506b88fc3c6554799b52712974aa5e523780752edeb3f42e27e398e46525084e2273885d7fa425996a59a6c2a5187140947f1fa9330b74ed6d5b80b375a4327b5cad829994a36e0c97a11be92b4222199f3fc2ef5a865d9f31dae0ea24c6cca31c5eb9e965ca5338295c600b977a47fab6c2f1cd8a3a017511bf02c41c2654d6ef9394b3829385a447324d57ee21e145bcfa5247a8396fb5154ef099df35405fcff7dab0e7ebb18975b87187904a9020f6263d7935952450a21d30d6216c50b52a5d24efdb2970c32df38e962f8d9e5e6e74f8b73aab921ccbaddf0a6e7202a671ff239eb91e1571eef057dcad0490d7cba3aeae67688c2230c11bbcb374c579f7bfa7a52a1f9d82c11893daef9b3ade2d1775ce9be83ed587da2e5e92217a01676d44281648c60dac44cfc574c75e65e1bdd55e5be5045dbea7c359f008a506920eab72cd6305013fa0c06ab42e99a05082477bb75afcd092e0f9ae94d6cacab0848e1dc088da5f53ae0d9bb6cdca90bc15286b20b419d9477aec42467e3bf3633430dc04e62915ee29139f85bd755499b701d0a68752c55a1012c9d37747c7940f1c8658601a9a9d150ceb6f1a6bd3ee6c21778eec24da3ded1ddee8b2de63b215e0dcf9474628dfa22968a9640c7edf975fa07a083c59840fc8c793e8fb5b9236b1b7520c93d4de76f612c94d0ff80d00bd824d06bd39c6d414e30addd6bca11ac8d6fbfd405561190c815e53556f33f86d2cf9360333179fb5f75f3eaf7dcd51f68d6418030bf35bee47e409d9d31342179e51ddc98d2dab353429e7d26c1fccce50b60904a8f2d9534cafec2ab86ac57919879f34d5bea6964d957df256f7f6ccc3b96d01da545f18a8bede2d157055af68f53e967a16e7c4eefe67cc04fd079de99547f39863cb1ea9cc64c5a790052b787e395e8d163277bc69550dea892eaa193004ff140684800b692fa5849a438002d35a5cb1ff3687eacf26ce4b417e422d5d6644f3dfde437ff79eda13a2d0df69bfa87385ba506fa",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xbf4c9ba3d4dfa507fa9c5203e1804e4d0888689305dc1c42f95c9bd81d1005ad",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xf73bbbd26a82dbc769066550d8d4585eab2fc00d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374870",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xa6b55790589165f5e48efa07619ba028e9bdc4f6a6ec0c1bb2f7dea6d02170b9",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x1fd7368105fb014ebd3433517baaa8251c4a0821e0bfadb1b3eff290013f913d",
|
|
+ "timestamp": "0x6ab8ee1e",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-anchor-20400240-baza",
|
|
+ "sursa": "2800-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa00000000000000000000000000000000000000000000000000000000000000000f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b841bc7e08f46f2c6e73a1668065443066ae135919fff837fe1bcbfe933618be4bed4d38377c4b440d21c4d12c64a335a9264b47b44abb2801d4aa176c7e1286d7e200b841a7e56de3a78f4256d170e2bda2754948dd3082e37d9d13471ece93ec44d61dd55e9769fecc906b1908ca2454262c612249dfe5afbb15f17d1d2aa75f38f40eb101b841a784533c31dde9dab06bed2650b7e202b6bfc1a28efe50c9744a0d142cb0526d13d3ad8f82682b2f4196378c7edad5a12379522d948cb4a163662db2bd1cdd3e00b8414f2e023c279999d794942b5cfd28f03fb002e3d8355cdce71a084a2d124f1e85124c6fd662d9fbf3065c3f69942f3699fe77a181deb3eb457b4a50de8e5f12e100b8412f47e81aaf31c04afae343501c4941721d5ce1ef1c39ddaef0f3c964e5fa76a4555f45db88724b1f8a7ab4c132b0a03958fe08376c56f9af34b8a7f178b365f600b841bf847cb82a9377877fc6487643778d81e8c0611e8c1cb2c9bb8a4ec3e672461435d67d476d3d3efe031acf10c1988f93d2039938d55e5aa6d214cf3eefdabd3501b84137d132d307ee2d6d3c30ea4c0fb97b01575d36e08190667c10c5252b3cd79a9e05481545c615c1b32f60df374f61689f0d97b6bc8362d8642a8c1771b28e0ae101",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x82dc1afca773df4ee237252b2cbf87f23082bc86b919d60c6eee13e27305ec07",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xd38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa2",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x13748ef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x9c5c036776585acef4d8eda782ee3942aa295aa25ea453d95e0c1afa514821af",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x5ed32e1dc2e540c07a54b40fb83f2e6368b4925797036b6077e0ce9ac24fc248",
|
|
+ "timestamp": "0x6ab8ee69",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa012e9da03a278c766722a47a1baa5a43e9bb37dec7e913846aa17cff9df03eb21ed3d415f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b841a5fbf77d2e2a88860267d7e37e195409d4ebbcdf51325b2209251d68948110dc5087ce14504c93dacf1380bdad29059968a111ea5b488f5433110a0b8ff8319701b8411e0ddb1e52b0732ff4c88bff5897c7c99c842b07ee22a014484832cbab7152600a72eaf4f65785187b2d06e6f5d26933f1f2dbf3f6f7b47b542d4a3c7338ac5100b8418e0c1b4971806f35d4e0fa8677f5c683a0f834b4ffdd17eb0cf39fee8c66691462711d84b49ae223f692569bed05b994ef9658b0fdce550da89b2bf192e93a1301b841f09060538d7d8a185dd17f25d39960ca78b92c7872c81f75c0483cce2104167e2bc7739d91d8724bee443415cf4ebd7856a5bf799aa87d370a00b51f95133bec00b841fcad06801382da304342af0ac2e9f568289da13d136190f9c678f216816981bf3bd28f0f42d1b28ab21fef9e7240aadd5f84f9a211fca189d1b41244cbb0cdf901b8411acfecae88b719c17df33e350199a1fc18dc5829d8d15ea4411272d72bd41b49620b4be3668a602d3e7aee975c7b5f1f5a8498d535bf000c7ad0ffc7777e500401b84178c0cc9c71d851f38c84dc0aff53cee9198f3039c9f874e0d8b470694f909922729cb5c359398bff9526167306da7b59ec827b171d19649e0327f5248f7ac21300fa012bca02fa012bc5f902920180b9028d39c086b042993b881a60a34f64433a2ba6582ddeb5a1193c82ef336389553145cbe0e0d2ecb1a8e56fa2897399680cad349915eefed3213cd991f4151fb3f7d82bfe11d5c442544c915c88d6fb46d28596c3127871befe6cfa9d747298946e598ec7c1bbbfb57de6fa3480156f3ee55ba82b4ee5591b372c87338893b30c54412561e370bce459fbd93d068f262149c8b83386fb65d7683f98349add229a2ae803d89031122deb3e88b2db43a8ae65ae566a053a0195cbdb7831aa4c1a8268f7dc2d430fb4b0d62dfb6d3240df41526fae5184884322ac1a3db2d0ab179d6131270bdfb0fe3db19d45937a47102439738b1769d31cd1588c01a3550b3ab297c75c7613ffaba1dc970ea515c7484405e8bea75c59d53e6aa2ebc84629a0d5472c8c62a997b86a161ca365ac823259880dfafdb8543804de8f2e5f1fe5aa3aefb86cec5c72f1c9ad37d9acaf41e091a33af04593cceceda5857bacf2f69f747452a2d0509aa18e2f563c7453244a681a36232ae0cc92fede00d4a9325fdd311f802b16a4a305ed16e425a080cc18c7f38e5d712c2efcc31df9f28e541d0eebe3bc716599c94c34862e28973317f7ac976e3caa20981f7ddb7f136fd73d76d256d5fa603fe23e92ef20fbec273b425e9adcda885d227d46be6abc7c316f1d2d29499c0e66a638f6f22e33ee5f1e20d0a4c5a686d0f07127e583cc7a7cfe9fffcf1d0242b2e40f158256d33726ed4eea472f1f69772d7ab7ef9f245bcff96c6b041f1315913bed2443e7ba88a55f31898d37126772cb4386d211e6f201126ef7acfbe1f6b6a54e373bf5f9d8eb3c267af4312d020982b4b348c222abe9e22d8d8e15729f54a85bd900a8eb94456322eefeb004db9b0b7c26cce751c9a65c5c98d48318d91d8d5c0a043497c889e480f91eb50280b91eb0f3f719d23f9cc97580e280dabe1193a8b93259aa32ca9d4ae9192a57786074f8c7848d6fa67f82c17c8b608f36c06a9544955c6e4f6574a14e6d95aac3a3bb492c8a53e5c8a703bbf4d198f75303fe41504c3ebe0fd8e1f44e595a78874b04a267e809afed8b1179b7a202353de268e472dc4cca735504dd6deb18d0887920b7bcd2354a88e695a2a0edeaffb00ba9ce408928b9e6679e79ebf761c3cbef08c6ad5d3a13ebc1d59536ec487e0b286036d7298f82e3a83a0de78e906c610c35bc9fc6492db014146711ec3ecc600e1f7917085d73ef64ef8c39eaa30e25dc5c24e44c1042df5f6c3034da6cd3912f2169828a3744c67b861b1294754b66274452991cfce4b4eef020ac4ccd50770a62e45535f3c13a4c65e16d5a7f0d4d565982ee80dd6235b332460df07f5fc49a9d611dd57cfec4c26c030cb715d087d40a58299ffd51a72bd31339d40428486705e89075855e70068e8b2f95689d88f1c77b3c6163d4297048ba2400eba552c0248d4ca0361080e9820f3af418700ef27889a593fbc7d3676c29936ea9fc40a3cf39673856271dd5873d16a3f4a3cb14633ba8533d0e9ef9d39e2d3cf73ff208cb4521dd147d2ebb38d8ee974876262d8014a76c45e2f370fbb6c3274a12e2b778e3a8b6d443780f10ceef3ab697b014c23d5f308a3022909e187cd07c0f0ecf77b3b822c69beddc135085c19b2fa505670f1f4a4cd05b5a20ee40d74122e1fec85826749fbd8531d9e59535f5be8834599007f6b6903c07df2208f71d7ef5ff8d2bc2075093b1b4af2ead176eab594b347fad747419717416b87e6578e9a6f5fd8a2999fafc24634917af40235ccf2cc2e211e8e3e715806a3a69eb6314ea6ca6b23bd1680831731b74cfb9390c793a6207ae9d50b223004a4a1ea182036e736233ced303d0fa6a6be7577c37853ff6626bb08bfb6ad4e95648b5cda776799d8c81033f9b9c50e6006cc39b505ff82605bded0b33c9440389dd2e2fbd9f1db0b9c65d9c20ed0b3d41814aee46698806a343affcd086e15f02fe772943fed88d63d3e0bc0e4cbdfc228c399da85d85289cf5407b46094cb98a0145e3591eb3fec597e089cbc98e7fc1765b76e7f8d15c4d6f199668dac122a4e34a561d04e07309862f6576ac307177d4355be474fcb989d169872d9f37f3f94f0b6ba107badd63c1fbbad1bb80a21a22d4338bcc3bddba1cec368c3e24f1b86e1e3604a60ef8ecfd3e5e1ea6c59ed290481d6347a6fe34735c6d94f5354b8b8b1cc898cd34f45280451d0374fb494a13bc91a5cee2d84b82526cf20bc8236b4a0a3f4d8fd81c642484ccccf2b160514d996126e71679d65804886303232ce14d02bf43c8127fdd0ae9dd5a78c05eb78dbdf1d05cc6affa706e9cbe8fef639b3ffaa44bc8a200411a5c18a4fcb73cc0376508418e337f6c28ffccbe33a9d73190c7e720e1832debb07900fdc610dfaa92cabadc04a98130c3955f989496e2f6a6c3de7c5783424c6793c67f3469f0e3cac3ef216bf0d54830d851b7ce8280683b20feb6df9fa5122b2fa9fca24f0cc77d36a95bc74129d67011ef621469879bca410b57b30af3656a986cbc918a5c15f7b43bf65eaf61c760cd7c20be1f212f32e1cf299cbd7a1321d67b7b8156d6da586a8c711ed34fff8e19fe2b99c4453e6bef710081277f9047cb695939366d97d255d4f0836e637a1c6c918fbce36e591dd17483aa3f5e07191df513241f96efdbcaa4fa3ab68595891bde7eb22965c910bf6777fd9ce86e4c27b117e20871e613a995c05d17079c6d07cc038d560d5339d46db845a59259cc26c0505509b1e385037809344d72548c793fd504ab3e0b3332e9c8baca60d3fcabd49a6c563aa06c723c6da04c46c5409c109bc0bcb2cf16127de41622929211b4268a561aa9572380c1b724c9ca6e9f22a18dfe399e3628f6165578bbc8b22f482ecea3499803c01d938d32710aba97e3a454222f4b5d642767d12ed9b0dfb1d5646510456d600c0cd25d9555cd2df890f87b166333180ca0ab00cb5a9cc728173c8a841c0c499f13843fac4f8b21ca947ea16546773c99293a99300ce72f19d88bf0a34d485bd4dddc822f1c25c04bd977590df11b15f37bb2d336aef117e3d5d076ce411a1b20a7ca4f82f4627ec163ab3354c41d9cb709360483d5d2a11b0a7fdaf2ac6a5ca9e644c228df2734a5fb21158d630edd057fc1ab9ce189efd2b2ab817363cce723011a424c79749a01126bb5c47a03f540b3c71ec928e4e0ffb94b58ef0e3186fa8dfc35d29b8b43c0a290694ba686e1293b2e6ba1e0fb357e5f3b986efb0b9e43c965884e28496393e6b7f3049601918475d1095a892b19298369de54b0f974ecab1e5a3bdf0686f29d64c2d7a3253d3fc3dc3aaaffa0e5267a3abb8574dc1c9405f21875ea5ceb074c3c735e87b155817791d6ca96a4638fda23f4e767383ec438c2a8c33d429e940f692776fe506b9d5388a256e91d4047a18948946a1e821933e52d26262d5ceb0c04a7fc52221bddaddca034fa3f01e2753e6e48aac449362214a9fd1afce945a66a006dbc9f4b8b2176197bafe74690b7e36b7ef8e76ee27f8624e3e3881953ce896d3fb6195cd9bccbee04384f504df9c468345f92002962ca952272f39b4c0516c909ffca4589bf5f8dbbc11439eb18b0452d925dd544c23ff9a20baf00c2dd8c1442105dc14a4fd46a0cc935f0d416d75983152bf3a213cd7b65a655c8cbf541dd7144117c76e24c6eb54fcc5792aac1a2a1946b3933c3bf1d3f71ad45b6610a9b4dc23abd3766c1a1f97467a6ac497029f6336d243377928e4568cf783e4b5fd39ed7efcd231a51618cc83f1f1bdf2e16e234645e79a6e394a4b6ee73498a0a1bf6cafc0cd838576996c179d7aa6cac6dce072bd55e01bf2e8376635894db75b24e612afcde228f46e85d14bcfff9c50c80b83f0027465ee4a3bf2013b31aa9bc1e56dcc7beec20d6fbbca14121b6f3e77b8f80f38c15179142918900bf60deda20e88112dbc39dff1913eb27dee6b361a05ddd1360d0e81134c7fa66a6f22862c13ba289f3cc19a0fd85eaf3559e342f8a85edc78cd0b5c636a4004bb3d5a10c9f21ab6daf279bc10bde48fe2b5e6c110ad6b82959dc6364083f91bb924d17dcaa99ab24c6c159cb69f0c44f9b243a1aba5cc4ec38b84323c3868f40206acbbb20a4046d1b60a8d18e668d8dbb05421879c12ca98573ac44b5214a2c2fc5b7ddf3e9cfdde6c9a74d5d5af9e112ada113f5ed48aa6a076870f6d8fbeefb78bf10481f1d6f0c31c5d37aec76bfbf7ab610a3829b4613bbdd9b7cf82cfa3d46a8f86c257e3281b20e46363f7016c02c523e69fce55b179dab13ecb84b0af09e37e07b24ff8fcd838ca715932d74198878d206f80a8cef509c715a05ff52dc3fbe84f980a7bceea8fc7599800ecf1fda325b5ff258abafdae6eceab24e828f6eef27d420b92f660408343441f92ab7fc13c9d2b1cb8ef0da2650f80efe66f1440e6b916c634e53d1d757576a2d17d9b348305a2721ff0622e3b9dc26c2a74f8f0d41f351751dda0f07119d3af8321a7942ec698a7d642640084269bb300cae4a3492eaa309a3ad7892ef12d5e4ad4d82479ce0594e80579a425b4bcd9b3e8700c263b7112cc99174443fdfad748c92b6bbebcb6ef826820d4ce3028feef7d4ee6966bff0b8888ab2a442958bc993f16e46d6dbb9a1cef2853eea0365860c830962e70d3073f8b8403af3d80f55e5bb12c5ca8733d17141678bb431f2ceb1b986049e4189f38ede3be376ee0f55fc63fbd199b2daa232ee367c0491e520c81f907a8a7baadd82533b9518d086341c2abd30c81f98a2905c6e0fa081b332332f2d5e2e83f5db49ff108dfe080f14d488fcf1621716cd432bbc80128778fc49d3cb97116f772c658e48321e803b322dec65878cbe8118bd9325e07998ca9d08dc1b5a5051cbae690e16edb1e3263b719ddb6bc2d52f43f17896ae9b81aab075982c06511c29d964bf38d0faca7a77f530d833c6273f7109368c5d61cce7a0d7c21fe86b3f92b22b6f152e124a02cd297eaa3121f74e5e9537325bc9d8eb360ba117bb29ec04fb3ac66aab93962aa90d123e014ebdfc5bc03e38c26d4f4ad7f8068090c4dba0b75b7510d8ba985d846720a9245af96ac6c9d5e0a6dfa369d9b3a431d48e7221a6189b0b8a0e26c607f09c208acbad0b03500b2d5f3dc12c91d6ae3345db2e8eb872e0ce758b9a8dd7801559bcd547fbd31710978339ab7db4b2d03068a57bfe02e8d8422d1b4196be8e22bbcbd6d66c82c937e14e27a3974c138ac0927e17d0f220134799cba00c2d92c007f9ca87493e28a1971f49772145caea10c05b7db48d4cdfc6aa00cedcb47391d143d82dbfe893cde0fa11d021361b1f34004d3f4c6f6160fe74d3f0dd8f9a26b0e84c1503b5d8edcb3924ca38fc9bd14b40aa19a2f0a7e8336c381e6ce1e561f4b4b178e70c5d7a697b545d1312631e8527c58cd082e5c6bf8e93f5b2b2a5b3d0ae91903be195b20db31e57928b0eadc2dfdf180adfb0806744c663a259412828739e53f78a98d444b1a33bd59eaf1d0548d417af8c2288e0436f8f0eaeec23caf83bac0ec76fedf9c3af4f520c25bcc871f19fdd8d01aae8b060035d472ece31a057b6b606c1e30e6ad395454d9a40ee1f2a09d94448c1891102d3cdd2828ee66c7ef8a565d83f5b2b23a7f73d793958f857a4b2c7993c5608ac6df767de8a37bf507e0604cbce0b46e2aa40e36a2f28480865cec273f66d252c85f78e777c8670bac876cf5af3b099ce707adcb2ad4b8a8f26d0226c4a9cb43dc825b51dd12b4f8228f6412f9bf244c987122aede7a389ac7d58d05d35e0155427d2abde02448e296748eef412e1c6195a8ddc4abab34dfd56accaf2ba991a16b2a0bacbf3acf6625605cdc1d70291106534302f72ed05b9debfa988d1b8f39c4baeda2cf4fd5fb405f8fa059c81db33b2c110c09d10eb0d505f1e288c99ed08377fd49770bf055c3f4c070467e759288162fd468ba8405943ac12248bb26a8634ccfbd959a370d485ad330ef0bcf4b41c9dfa8655d6cadcb90768005ba883871879015c461989ce109418afb7e21189dd1ab979985ca0aa914e68bde669c68f2b5fa225cd0fb4a84480fe28e7d7498c22edd0bff4f8abcef23a2eb748daa4351bd5bfc56b9347e9859b082be9c7e060cca6433a7758b52671644eee56122706eca2f3bcef4244c34f0e7366a4b0b85baefcbedc2df2cb96776e48ce284ff63142e7bdbe5939d888a2d555b4af8c4c0a7f86d30a110aa48e394f901a99f69257a5b27fe02e75e4f3679fcfd826865180d2538b5875b170d98ff8a305bd1e134bcdca2059b37c86777520f2d64cf60b87e4f614938af2024a4e9fdd0f6f68f0c5d30b28726bc9bd1fb16dd79dc8d7247539a0ef43ca0439a239866f8ac6bfc7d6d52b01f6ca4a17a0141b4499dae898d529ea02d4b405e5dbb3df02419f2a1010c8de92ecb80e96b06409933e87cc873e298dfa6c6a5ef6d42abd0658a592e7d79eff5a4329244b5af6cf6c032ff1f8f39a0f233caa42a0d1d59f88ef2dd28b10f04f17b440ab4bfbdf17cef47f3dfcd98373784eba45c4ce97610e333cfd4ed521542ce439c9469812bd7ee2aa630d5b1d3f63261e46bb960bf7d576c35934fdf11e3d896ffdc7961aa2fd7197483304bc8f18006b5219b15e03411a511ee24ecad1740f1bd4c64cb58910b1eee8db9e07e7d1fea205ce292ed0dd46c3680484340726b4d07aae70743a243af9a7f49ea6eaa5aa617533852cf6ff5c33150c1d2f1bb0c31eee0c0dab63d750c42861c22eb41a66d404826e696c8e4e70d0d9330856b28073d71c249efcceaadbdcd391b9975f5b6f461ed0cd32d85e53039f6d8f7caa33baa13f7c24622ff535a431589002d7f92edefd6050fd39ad0e1f1047ff59cd58dab277ab16e50a9ac47a7fc6a23e0accbeeae1d6f9a332342bcf6b790364ba75217709f490e1c09bb6815356b8337de9b4217202ef76394050bb8d83d8a3f9e1cf674b8e3dcb888ad74d243c4bcbb7f61bdbdca5c251aee17c22f010d08715609a1235a1129211f195ddb48af28a8114f06fb2d1f43c801d9170d451c9bc03439c83c29f9aa89c33cf0205b2e8fa4afe035ae41d30cb5e9d0470fadcd0d38339d39ae49a53a7851c2288c2cfb4717c2011c0e10a46094d271f0987f36f418595221582ff5cf5c2a327c9fe620a92ae63773425bfe27435fb2893d8732c6b66a4219baa679f281d917b5f1f6bdc646e2c85e7c86b27c95359587a8d825b0fcce4f3f37b4f9e8cf71633b59799781c9f53b2e54ac0a6ef242fa731774144605457cd65abf4d9c8b23c4e61fa7a39b106230610eaa98509755ae161f15f3f20c9ae95c0451c392339ebfe5878ee4fceb62fea012e731355f50903035ec19d4fc7ad28f48ab898befddc5b8d7e33763d4bc6c1f8b87b0a54391c23717f088fb1c48e92c14c11b344db2a933f4e16508d0a2dddef966b956b51793038941f5ef2805d3ba246cb897ecdd704f89951e66a3f932e36b430c0ee552c7b62170267a594151b1adb46d3500ff021d27611ac8888a210ca97d3529b4c148699f7b7573a769d3bb74784d294fc824b302fe398b65bababdc649ff1e2b4e3c5a7b0d2844685e56dec957a323018b9a5ed9c679f23949d3fb746d1ce9d6000f4b67937e7195a1596db14b5b8aa308bc5aa60bc8ee90d9320fee650887b8e9ec520361500a8350cc0bdbf92c5403300ae6c5f5f9066b7d7130871f79a4b4df1dae373d45f6f1913414a99ef7abef8741e46586544b23503fa7d70feabcf9d8b44ef7c4510194bbc2174c0dd2345755e7b14834149492d2ac69b79974be496dd0e122013d8c076d7b0ebbf2905d890b9d3bc4cfd524185dffbb8eb76227bae06c1111a17d8de9214d1cc5d9ecbfd166b7c5e081e44255ac4181b277477b1f5f21f455f3283f35770595664da6412f253735cafea3b3ae6b19a4918395d788679eafd4dfb1005475c396b0d407e6831c5c874d3d0783e5b5b3e1dd7f18c8d4621c0945a0729381cbd41fb78440e0538845452ae26ab6444c16a35290a89846264900bbe54de9d75fb3d48abaef8f07cd8850c75ade7b27a85e37f3caa3edc29cec5920161842c8a3343ab5916b5aee63e027a0c615e211b29a52f31ce438666e07b9aaf201932b44b160d8021bcc60960a414cc7498ad79f258ae41f969e902bd450028fa215811225d1690424314228f83c887a6a9370875212a7e3911d97752d36e3e44e48a834d89c476492a2b8805f24136afd2c0352fa485a0ae451009aa2a4bb4fa612729c90b966d0d6ede787a36fc07606d12f84b2ccae852bb3ac8ac6813ff98d2a350732dd3b91afb7925ecf3b9d5379cfe41adbc979212504ad32672f5646914ed38ca4e27babb0da9cdca2f02f6a5182b67f70a3eda1484f962b50bcae1b81e4ee6c17df0fa75422861950a51554a5d377c06b99761407c5e60630968a279c3a1acb0e2df44aad1f82963bf1498d598d8f859329ed88a567e51461cd4ae797bce9519765f2aad2dd16c2123ace2fd588e40fa75e6f35b09585a14130026d53236e8aec88705c8f640099ef161c1ec25a2f471cf25b28684e303f331ebc381b0ccca0ddebaac11be3aa4d97fb79ca7bf35162fe92339252a01fa7ee51e2fb39a238c09c2967a9e8ca1f7449d83555a2635f3db05fbd0091353ada83c15c068698c09bcda840ca9abcae8a61ab474909893cf45b316f4e7397354f720f6b3bcb9cea3f9b4f8d07821284f211416005a017736963c738371fb9cd94a895ddfa21e055250befc089ede52207c530458295e3ac9744653032552a0f5d250201bd17264051c7681736ff51845903fee7568ae790079f89a147c566077050659b271ae5b6f75d48dbc663143abc93059dbfefa5c2201c76ccf6745d75ce7e04aabadf196c9a1f2674f6d41ddd83f963dc152ee4c3fff225d44b74c76807ddaff47f1f9d2b031a5185de8a849ba0d0700203c2f7a0a3f1d44923ea0542ec96c3146510534f45693343818b22a5370f95b29641e050ef1b5b7844445acf0749320ebe11c89eae5a7dbcf978979fe41caa17e33bf0fb5c71d33cd1497b3a12bf9f106d02a0e852e912c442eced3e75dc317904fa0ee5ee0a953ff95dc71a48a8850e04e85cadd87291d3ebdbb365891f8c4d191309109a1001ad08917f09347c2860f5a991ef1005e61ca4397ecaf3ecfee550bacb7a655b9284e299400a8c724cd9b5738adb51f3dcfb457baf464fe56b3419057fc5d4a294ca904081fa338ddc30432c7705d7409cdd645a2a89a40d3b8f1de46926c5ef2e382555e775eff7e398d4bf88f2f37f45993e87fea971ae7fcb63ecda3b70b5ff64652a0c2d07bb2890fdaf4ea53cf1d17c4fa0e224121074740b2eade497c8296c90f82de90a4da97b44449546a5be5a04fc9e9d97c21da0bd33c320eae8f69cec052136e59c09911f2075ad920b74c483b49eebb90a4aeb441f0812bc719ff2928db87bbb3c8c9b793e44b77f386d52c846110bbc0af0c2cf2ecbdff3f3f72df5da2f419557bbcd1133192d747af470cfa5f0884ebfda125ae932adcf19507ba3268a4675933af3d4a8ef1359059e8c669a10ee48d8297baf16a4cb7f0f4ea9f1da97da310089d8c26201ffd2b7607df7def396fb6791c5034676d03134efe6d9705daaf3eab6d39ae9d0521e9f3cc68db627e524a033e419dd9149b025f478017981c3feb7d1a62d1087e12a7a863f838ca9d14b2c33a29f1b1d6cf461d8345be87cc286565238311fc3421169e0cd40457a4727bfbb0b58adafaaee3a61f647332e8a5fecd8ed45a6b7ec328e40a658e3325896f486647579e3aee40b4676b46acc8b3e7f6e33c8e538c0506d71441f4d138aa3c7e1a1059659df3e72c3dc8aa2d93bf259da085ab2e37e29a6bcdb469ef9872d4385242521002c74124ba453e385c23c3891cc3c93f2d4e3a01bba16d50dbc7ac40b852d93f8e1ba3bad963401abde4b3a5ede88b083ea137a8e735563c16f6551fa27bf323194d4c250a6c7283dba4a803299884be5dab56bdb8c7f31a8d12209742eefd2b67a76ea8e91df0b2d2cf3cc6d48cf57a7ee33aa98916a52a751865f0dd20d7bf114a6b56ec7aac62dc97f704df522f8d2dcb11f07e02a4ba57919e5f8bf518cd6890afc69c7e457d264109cb9b51ec2b7e2991c38334cba7094ce8a9f9c4ab8e4b25a1a825a926749774474e642851b5ab8c0a71c0bb798af5a79f9697b3b206299d7686e501f08a879f61a396c678b33758fcf36527a11425cfee9194a445663e9a1fe5901baae2183274c4c1d068cb2e8b07d86e15e2571a3c11cdcabf0da7ee8c69424bd23a2f6133eb92bec05b4bb6c55a88301a23f7f7319fb924ff9bbc44108e2b57433ded774c4e974b0f4826d7cf92511a04623abe370fe5de74be45d5aad8483c900912d4ac729961b3adaacbd86ff4f74e54d167a44c745139f436f73b9290616aa1d4716741b47d1ea3ce516518b457e7679a53c5aec50c54484c180d2128b084e7364abb644ab3e994bed3f6e0b0ce472ec6f9f6f1a234d73dc4fa27fc6b433157f1b1a361285b31b81a60ccc9f9f0708409661ed67d5b42e0a8bb2d3a3809395f391569d611b6c48057e4ce1c590324ad4c73db20234db4fae3367a0eb4653b6159c846fdffe9456bfe602ecdb36645c1a17db4cf35651118fd44d3a180e5bc75a78293c3a83b600fee84ecda9c6c6b22934a81c8212e7cac37eb741364221f93a4a1560d360238e510f4bc33411f9f5f769d7b28b313b5155af961eb4aa014148c29da826b73ee14cc2cba4537184eebe7bd4cd1b61ae18529902640af86c7253e29889403725fa3f3cdecd9917ee94136d9057b24e6802dd8f6d40da56429b9fba8cf8583505c91b47d5ca142f417b41095dcf8a58c0ca1e5bb7a9b454714fe36f3e61291649792262c8f54eee896d24b92ed3192c93ef16b7b14f9d76b71a225ed90d791c84d48f2f056f2fd054748052638b5b567ae35e98355f88a14738db5c89b347a2ad261ec8e56dae371d9a96c2fba005abf10d2a1c486423f0bf1aa3b63fee1aa7c4edd8b50207ed2f1d8e20f5a8f0d1188ad3db158c9b939f4e8321fcba1d76968bc8772171163fbac87a0575680132863c4e0f61870f7cbc6ed11f7fe8937b39a1b8be166eff6d5610f7ab2a7eb66e1662bc5b304e4339ffb3f2af344f20489c3b8e3c17f464295664b887c31760e085cefdebbe1aa049138a6ad8accd10ef6efdb8c5032e4fec1e90c5011bc5a53444103eee7f27a345bcae498422f020b41f5531443e60aeb6bfa7fc4b46652527eccca9b394d9e51e3ddde4aff57dc523a72611bd8a01de05859c205b77b433c65eaa77abb31989917d1e5992a657272b989d6f780f9405790eb21704cb772cc7ef94b04ba2c2cd2a0db928891fa7ee2f845b0cf8454c5eb6bc130ef388d21d9ede0bfe47507a119b740a7d03cd3b72597c596f61201b49fc5db0d3f6a00f295524d26451c6ec72f364ee0afc462970002c3b5a063743a504e418df09eff5633d1f9b604b2a59143f98b59f4fd7d1f3b21c46a37439310ec2a328afeb50848efdd75a7804aba7b93d2acfffcc649ab699019538a4fb64f2cd81456715f95eaf89810de2ee1e30f7924f20165fca49b2580b66d173dde5b386812c6e0073dab47af481075b9f2cc15e5e4cc97a583e59bb124ca455390bb1271b01ca61157a59b4fbf158387c23e4d3358f09833bd33aa76b5080d7482ed482ccd85335478894fa5af3e1ae5340d6f4c40a9d9646618e53409487899d40bb58dd4cd243a60462a7eb08083f5fc2b6976d444832dbabec0a8229fcafd1b5f3860c212d0fe4fc9b484c54421365332fb371ee10e5b5a367012ff2fef27af72ad8c3713a89eb3d21a0726cc06fe91af4f77f297fa8c232b0425ec023bf67cdc27a2188a89d567216d534ce34e919b4e1e2263974bb299836f18107dfd4dac4809d14df902940101b9028f396204793ef387e21324a7f3aee133bdd74ba2f087f8a2b099ef88b8224a26435abd58c5803a5755c1338e305ffc5bacc9cef02d2b7069781219d943abb195ed9b4517238d9350e6e41ce425d6893d095e36b48cae5c1e01e2f866ea3f633e6972a43d4836d785edf55074d3b8d2273a45737683bf8550f0280af5384d7a905fea238bb12af12485c6c1e39d5c3141b34f8f875c4330fb0874767595a7692a2e99dd2ed388a8e538a59a58f7477bbeaec2675b46e6e416e3daa1ec1cd43a6444f51ce789826c5a1c54c7d542ba4f8a2f3be0ac2acefc659e419ba4cd6e5eb1f1f40ba3122d1ac5dfac8958d0533665323b4488745a89c62251935ca52cc9af806e390c56d53e6b1be3c0c44a6bee80e0b5cb3365154a247098cc433dbf869842149dad297bbfbd8752f72c964e0a67ed3ce9609546981ef7a605057436a5d65f3f6562620f4face5319adf619b6d24c446d391685953d5a7c2dca32646b32b96cce2dfa6829c725184f08ea117de4c9747fc467a8c119b6eb32ccd86f2b7d5a93477663702a227f405f544c97411cdbc591a158df6f19698417988ef6375c442da896e2f3fcdb0694c8a5d7e830fa4dbd7c9f99af4666cf83c8daed707448acba02de7adc1c36f24305280a2ab8a0bf48ab2649486a4ed050526286b7492a9c75bddea6f37bcb166af2357679d71a34e740c66769a5b075a4a77a7fb57455f7dd0ba6ede7644d0475a045eb5e4b911ae65506b661f0ad0ca70935f91a0c8ccbbf7929101976d0bd53b18ee76aa5f39fec6813360db7ea976d2fff1ecf5d6917b61d626858a9d2bf7b7ee40b8be5c03bff4cb70cbdcba6acca1e54eb58d102b6ee6bf54f33eeae6ff36d9a77035cdbbac6bf30b0b5568a09786214022476a99b3858e31488a77218a63678b48bdd7b8f91eb50201b91eb0dde144ade6cbbe79f8f17de61fc2b3e5c4978340bdc0430c0685e7fa56e7fe005ab221b4e3b2b963f173c83dce6d9b3e02195c0bef9085aadfb030bb65347945008ecc92691e00cb5bf32b8207890ac90f2589e3582c9f8f0b7c1571036ad1a7bc9e2c56c46519898bb2b1b05f08c60c467f1d9eca844dd1129dcfaf29361b57e6e7010fd17009725fbc238d54cabe5b20fa55be41853a03ec8f43b807712c2d16832931b3271c0d88aad2ddaab0c6775ca7da3e040de001db6b1f4cef066724ac795d20c5ae6d00145867d9b215578317e3637592381a471021d040df6d43f361afc665c47af96f90283e4e284730a8894ee4d91a8ae54f77928b0b67af191d236c5a29e797a5efeda6134a7e4006372e41265310bc382230f48a9e82e8840938aa51312d32c28e8f69aa55a0981ce2e306ecd8fcec580046757502a6914ea6c58bb7789d987784cf049cd50ff7805877a751aa1bef1be6b90046355b2ca2b1ad7512d2b4fee6c3ad10051560868c6b627b77fc22d954feb2d0b1fa3475aee3940910ec073784d2bef56e456922e63d267f67cc287a0b80300af1784f77a8dcdb33a89ed34f59cac343dcd40600920f3ac16b23404a2bd95518a0fe07ac31f95ab092ef35e0ea87f0aad9872057df7c24da9ec290feae0317869253a93580d85e4af13dd979384c83d9cd27531bcc6ab693197dcb213ef0edafcd560aa4d12e111ddbce9a5b95692a1e4198fc261d1a8f7a4d962bde35419e91716e8b18bac61515d7497f6abb3f5be217ab9f882e09f13001b89d20565aa18bdae5a88209d305de2476a7a5ae3f901c21bcd2699a14255700c6f1b950b3c979322ab461050130d94600eadfba62f46ecdd788af5817dbb912ae9dc3ba37c49a5b972faf0ca1bc3124d1141aaf0b04722e06a353c97258b6974fc03cd933928c9e219e6db6cf307cef3303c7687e40ed33d63a69407716ae2c68a056fe251b57c102e3654cbb44bf3b3e32f5cd20c6470e3175eb36deb6cdb9cf7d9f7df816f39660731b55ef366ad5e997cefb2673f4827e669e425e1e8b757e222c019fc81f41b380cf2231b14263ae3361393cd4a5c07e58644a19e2dff91502856fa1a923798f9ec98b82385105f1ed8433d48e0f8e98f6e2f49f50f157983620fb42d33a7a159e0030a744cf581e7eddf7943eb852cff1488402489f24aedf1197ab51ed6a26eec205c1773268e76f2ae4164abda5654b5d6bbead045b0086c3671797d9efedea9956e35570a5be0b5a737d6e80d24556984bf3c3b02d6235c589a37989b7d360951bda40bf910b3295d6358f787a85599b56b5dea4811fb9f6483e2803bf7776011687446742b8b3417032a536d19b51e84fbd859de2687a741a7f000dc0ad3d63ca3d8de485aac594f122181ddff4e26b9db6945b3b83c4a3700036bf09ad9dc8667472f3c3cde8afb871ebad93dcc0cdd23ab6244826bfdb01d2dcebc8b0142b57c320b80eff82edf0d84c3c500c90db4fcf25a3fa35bc220d02e66c706e51a4deeba3c8b7a07c9fd4eb4f7ec6ed2c0f654825d0227e0c97ac55b9b3b1cc605f15cff628ac3505b42c34c2ab67c9b92dd6861a4455dc58eb5909d079577379e6229a7aead252fa1a81a4ba68a197685f73be97367f2fd6ecce69a5cf77576acc864a8b7e51a0371d1ae1df489fb17c74cb5961d8e5cda35beea35e8b61ac35ea514a3a3ae8479a893424d376dfcb425f3d8c563c65266c52621595eb5b7e62fa87995a7aa4eb3a28a9ba50cb1f700eadf5b8654fc7d4bda45a9d10f6c16734d7c44cdbd1aa33ca20d49bbd7cfbd9ce27e10ec5176e172c62a07e195262c081a8ea31a0e1dd21d43be5d73b6a924c9272d5b764ddf98975e3703b2d8487c0f422c847fb82e9919c0195d1fe31ba78c5ec98aca6d622b66a872ea48a8a0941c7208a00b5ca352f14faef0db9ff9d14f3a0e40ade5bfeaa40934b5abec00f3a34938464170e842f4ea8d618333210c58ad016fa1b0116c82d40cc18c67178618a2e460f33ffcaacf0ea7393990e799016775114a346a6dd295d98efc27e2c175a7c84e0b17a5c851477fb9c364bbb06bb3a5e8e0d31f8b53a5ae74fd1802b0d954d619214b556451940aa5c07bdf0600ac79469cc0c02402ad073a0b3aebb3407012ace5188cff7889bb8053d69f4cdcf9d2d11a47666a2dbbd59ba70c4a1817c92d22cccc5b03fc5f7dec29836ad73ff9456efe77b1a4ffd46954903f51da3577ba31f536417f49452b2535840665f08ba2b82378076a46e84354b36ab0ef4681306c2a4c4e176de10baf1456d71b3714fdefe942a55556ae078c1e60de4a541171d512c4df1415a9b64813e9b44c98516f128d77f3cc4600bbea5d805d2f7befd26437ee105fe6ec658f9f7d9a1dcc648850ca7a0c80a93a4402861361c010036ec87d61320276927e804e4a4b9a1ac047e474cf6d0524f9c708d124d43e865d5fcedd6d32980cf1f33836e8827b1916b3a597ce2104a931c369b08a2ee8047fac3eae3db411ed766b94fc30a5dc4f7c0d769f48a01ccc5f7e06639307d23dee8a73ece1399ea425c92447cc66b4b5f064816024092ed3f4fa368b456e4e5c4372be8e998442affbf1e53a051ef930b207ebf74849b76f9a77c7c20d75df3b69b07e2975e5790eb41f3ecff592fe343493c4ba7af065ac0c70518c0c7cb28039fdb33e53cf888be47516647bfae50496b797a73bcaf142a0f4878a845b25c83912dbea3f462ba77d29bc44037a6b8121d6e652b42bc4c7ee08e12c0f8a7b2b58e8ff1afd7d951bb2a3db43c072452337dbe8893284e328759be913f91889837e7a31f142b93b69b788a8051c3192176265b4a0a1e6fc1c3fded4d8d48f1604922f08d242527912e3a3bc666a87e0da0b29756c3595280d012ce2e2382d499a0281cd58b7574c214860e12e88561bcaf51b439c487eaf90713ee4b5d1e7ad6b7b34d00c9b9a44b72f6c5bde0fa78d089ad2f4973469601aa9add68094d0f3450ebb46dd635b4fda2ec24705afc7abf2ab3b27c8f27cbfe72039463688d0625d2aa7979a9ad39b21290d47149772e12ed94cf26b35bc63cd6e258b0e4bf8cae0682aa72e2b068bf37606651e58da4b15434e5db243096c41316ebe25e27e121d0ae570a75fed9237c698a0fffed4226857ed3d2ccae14429be389f43974f9fb7409822b32ad727d01923010983c97e309ac49c2188faf316b3f2bdc6aa1acba870f934e73b49859e439ba65b8d76f86c65fd6d97b92c9f168593ce26e7e122926c1ce4ea7f8f5593a2f5c85f6cb117db5928f82483bfcd5abb819c14912538e6cfeef90d7a38d84563c6ee2b615ff957fd366fdd9d96d23129c094bb7241b902d6720031283fbea66fd82d8277bfc9d1100db0cc1e5fde22b57f5948b5f92c3cc92f3aba8076804e78e22829cd2371c96483ea23c5cd1b4c4c908de7368a3d9c36bd3ebc638c9e29e7104fe377859204885dbbb59448d9215ed9b41afe9e494a87790b82efbed4e47af3003421439fb2cb06de92a3413a908f27565909221905f7cc101cfb2cd3698ee805c48047feff402cfbbf92597b3728ed75f25eea9ec20df1ca2155b5d0a3cc176c345505901435a8dbc61142992d3dc91c6f766881cd6cb7f42c9dff3fca81b28914831cc9edecfce92b663200b0f4ce5f18288b7a15bb8cbb2e70942a3ad80d372ee17bba9de7f2c515e51cfe1756f48a1072e2e61327b714cb1f1da38b6e90474ae1c86a210e495bce864cf1abec814e4e110a0bc08cbe5f6040b7e91c53d05e894afb3c30b7f904719f580f668a14099ec1f0c0b08d3be5b38dd0a01399b19b3c638a1d4af192409759f3c0295a6cf43793bf67cc44c3902c528c7c1df1e6bbb8018351f250f8a0709f1ddf35e908c43792b647d748e8f126b7a6c9ee4cccaed220cb0defd0c765862b729986d88f2bf84e29fc625e4f2f247f27683266947baf56c23457b50420b9a1dd1d02eb395883908b49680a4395c921fc07ac0018e4cd46b6a00fd59185a090f9c858b4adc3b23c0f1648dbf9f0d49845bfcf6edef86fbe148a7f1f568b7072d68aea78ee9982420ae2d2c215d1dc88b97ff5b5abbbc4b650a4acf0fe6f9db35f0b6ff0377782d25a113d67160942f941ebce54d29e50d7790a1591eb2534cf05a9a611bec584a875b6e1c0bc11ec263f10622e7a36846245cc994e9bf3b5bf46fa56a1fab897b9776759c44b0f08f820701e4e3a4985935d96b80411e8a81fa61dd5b0618bb883b3ca099f808fb62f91f03c2a4499e0dd0bc1b034c791a0c40ecff288c218895a1a75481ff06dd558c8cf28439ac4c7ea044064e30f41528d99258936e2480b21ba153fac7506266ee4f715874668f215482e9ef2de909c48a1a136635be612a315c9f046bbd5d66a18379ae16e0ee6099d335796a38795517a388ec5ead157df40765690dadee050139165c07dc2bd8212ec544a1857372f436dbabe084c170bc1ccf5eb8d26014a5160644478f5dfdaafc89bc637b83e391bb62e1bfb6015f7933637418d0ac64eccdd09281aafbd213acf8746c5dab5ca82201a6d53abebbee8a4d38cb0b939a79685b58cf92ca3ebd73d0ac2b5a84f3cb188db13604443bfd8e14b8b05a719d4c6b24650c3275cc927119f9ac0845dbfe67d9df25f05c04e3b6996e9b8e63aaf1a8396b8a4d1139bd08fbd08c5ab9d870e7d87105591e81a14887879523b69f0ac174351a26150caab9d0afaf0c59497b89e6784f6203630e7bfeedc07eb3bec2239829bf96ede28940039e354064808dbcbdfec228b935ef438af936f9056b475b1780ecd5281d395f258cbcc0bd930e16fd16adfbd5565d74a7cdcabe82bcf3dc2488840624c8e323cc5924d926687a33f2587f28ccf1a99f5d3f909e8a4be3f9ae2fd2d58a6993ed9c98848b0ff47813645f3ec17c0d8db27b0ea68410c770df1aabdeea90edd867009c66714212fbc2bfdbb99fa1c51902237b6e6d947a321344ff21ac1db55d8d03dad8e8a36abd067b9c04941980daefea01d2d578fb0a04e4597a80c44b1cddf18d685ef319ac6ee4565503807862ad82aaeed8c041ca47b6a883f5536bcab9053517903c783181b12bc98803c2eede019cee26ed84bee0c8c1b26b4a441a3e15f3fae9020fa9e5d76ec8947d113796d195820bfe808043fe30405e7483ac170fb58145be3fb9e715be94f2cc7d420c1ec010d8dbc1901ca86e74be26ea71039a6503883d1ee5bbb355407790886b3c26bce2f800d227f9d371f4f0f78ab83ce7e92c9a1ccf22d9368fd17cc87d6d134d6b64bc28cef6c434637b2fdb1febc2922acd4cef4c091555f1504a3a8216fa8cf4081a26a18e4f0b6f6ddfea8140f6a0db4099021db9b6a453e26904b39f353c2b1094d2f97c2b05125fca8f339eaec22892a68482761b585cd070b580b9b814903a119b5fabd7d860bcc683fd1ef91a6b329b14461983084ce0b907642aeae7e5085bb3d834f1b37b589d4d18d025f98a1f7d239aec62aa18353dcc0445bdb84d6ac57c23bed77f1ab6dd6ca5fce2f10651c520ef056cfd536d5b810ea27275cd3d2dbde4ce54a61de777c036dcd08b3301df8b4be04ca63e0cad3bd2711c0106faf7b0286948416d5048b5a0cca45b9aad3b8c962ec7c18756dfa0eac9fc46c522bce2197ce3a29356135c33b7fa7fe6e6258535ce2be1fc491fb7028532cec2bad4b1e7ab426dd1d2288ba445974b97936e5ef7a92b26255bcddb353b124a9f35b51724b536b7a02fec67aa04fa952159ef5c9c08a00838670210c970931e5b0c594c0ce709b936cbdd7f019a5c1630e405b21224c90a6df06352906cdffbbfeeeb503c6cd183357221f56c284c18c640fe2dbff5045bf186959b795c35ef54f6caa6139b3d57c6f49376b12d73674908091b1545c34aca72361db9b138b7f2c892d83cbf53c791e28e15b6ac5c77f5507c7ec77c8372868cf5243231cda299e5705cfc6ef845737ccb270cf2d3ced9355ebb829d174b589ac2927cb72829d9754c4765a6db3112b75983956cdace8a976513fb0321600b5e0271f5f75472822d59b6905e690a03ee374022da3a71ce60012faf16492c8d1e2665bebc7cd86f879baa8937cd61c4635f66d0a39d4a31864d273be02b227ddd5e98ae89167f5b35a624a85110d57ae46ceac199ae4f5799ebdb71a10c3fc5ee67f382e0cb42618f2486dc448f988c9860db927de348cd90b2c8e78ebfb2fa52fc25260022bbba1f2d4eddd927cec64680a5b11b38ef7fd003e32446680cddc86359f1bec9cfcb8395c18ccc0ff6ac752f0b9524c92e9fd55a1ef71a255a49a86640851cc68484f4802d0847e726671927fecc9c8e6e7a7ef418c7d110ed7f90e5c7dfac384256f70b37cc1d6b2f25ac137d300040ebce455d3768029091b88726b727613e1423d8905f8ec855224ead370fd426af29a3f63237400729828d298f3ae9083fa41518aa8c19af8ddcc18775fc94bafcd710e682d67144393e77a6ca2bb9a9b7e21613c7f63a38dfdb163558cb3d82727ab708fcad991a171b6d21aceca2d44bc2330bd39f99baeee259d31e9d135952c3949feb9e8e4992d7f23e2503670707cde7a605b5e7c95ac6a10d19f22eb2ccd1d4b23562230c006fb2ef96274305ad19349d430bd87166fa21dca6a6da2b610fc078eedbccd4e24e8a84b04c7525b70cbdd8f7ca2f5d103a4296bf01306121f3e47b6239a192eca147d8bdb0de121397594e019d422e911362308261fa9974d5d369d74e089ccdcb544ba1580b7491434f51a1cffdfb26f28f50fab4f5cee75cce6529a097ac8c580bce026f677797aa2d3b43e35cbbfcacf22abf15bddb2d97e9fc2ca6b691e5af4e7a3a3da45bc7620ca0857ab49fa5a3adea8572406fa87a5167c23e3198e8e47e4f00723feff3985a782766deb55ad84c412f92add72abb7682fb1ac97e038ac0203bf8f53319dded6fbfce0b212650ca7860650133e96f99ac304da4760fda41602704f2ef476922bfa2abaf6b786a46a9c7c3f8fc1bba1c33e556482e215e5ae5232bf1ef8541174685106103b86d33fd73583b629d1c4e82c1c9acdd638bc9f1225685e358d5de82e135ba9d442318f575934e61d6734aa496ce397228eb762daf19a6a50a00fdb84a69380909592f20d8c119a59a810aaad2c77f670045200c1eb981fc49525e151ded693d8f08b053e0efb69d7d3b5879e7b4afa8222ace022502194864a9a717771f2fb1c584fd9a8ac7fc21f20bac03d61fd05d4ce5e1b1073a45dd400896853f77972405b48c58aa698666f011dbca7ffe0215838238325f9a9e3f9816d40f80e212b21a4e31b6578a0c02f87f40fc299882b08a633fa7a8381e2872a5b973bbf8106eef9bc7f358e64030c184347c835bedd0878ab79fd65662e3e33d3f566b9cd8b0541baaead0f30c051ba99648157586bb7836ac974351c7d1c2d178fccaceca122bda50ba3259b8ad3a31173c2c344776729ca4c86fd55b07ec58f7de15095707b3289a112fbce22d35ee6059d880fd93f20885e58c9d696c897b10be67323f3c70275bdb094834a7d5315137e69744386520ed9771028614393739cfc2b3013d6c0296c7be97c4cd7958f8974335ac1660cb33ebe3ac60703fd73951037d65cdc73cdb64432b9dc18a99360851f364ce271078032e93c0d50c458a14b3250cc2a6843e027cf220397858361e04d9fea79034b8dce795920bbc00c04b2fe84ee6081f005fae37c81ebed04592de9bd93c6bfc482b2c52d047514a2c2a306f2d7caede6de78645eff00181a12c8950a1afcd7ef2d39844125b31fc9d00e69ddcf4ee44ede40e7a54aaba4197d1337ecd927027954d92474ad8b373d5c850c69bae9b1defded0f4929bba187e49f64fb99ea97695144d39723cff62ca8585957eccb9c009eabfb0547486e2570c2de5847f2a518373135478805cc4ba206b2a48dd9c782b82149c6f6da6ce0a98e0321f9dc0f7691c566cf722a703e605327724eba9c83d8b9725ad709fd206464196639852ffd5e80fcd094755076470e4b67acf095b2419aa588f9e0f8cf638a347d6ef4e5b398a98f97ba87f2b03e888df39e6b8a2c26347b8f8902e3d360feb4b8d71ec412ba4ea2d0f471692b5987e285e74aed128c397ab2530bf49a7dfd24585014a6b75c60fed37026a90c4f6d4e28a50ad66447416bcdc5a0facbf8ef937d8adad187aa0b22b14709cb19ad178a82846fe61684285fe0d7239d4d8c71f435d62a477fe18fc20ad0a47b5ba695fecdbf37771bb8cf96935ad361c4003c81e9cdcd7b342377013b472a1f749f90d9ec65ef689f9793b5878af25ce04784f377c305072f87a71850b5fe91d6b53d17a245461ffd4d563b2b9b2ba6006f6f164962e87fd825180f71682ca6692425f8657df7a7d3e42d73068bddeabdcd6ffa584a89092ce3c8fc6151e2d41e98e2ee7faef80449a64db3f7a9f043e6e10f6c8ac6f12c95d3240bfd37c92aa1ce3ae41b24197d42469f009f8a0be3fc042871b3baef5b2b832ecd71c8391bde39ff8417d14d8c3b7f2cca2d14660b9b20cb4287d987d0804994d47ff83d37abb42986ca07541c5c826fd712b41606ca6ff6960dde68c588e080941f6457593c0d9a2a15900363db8aef08c32028317c93d6a94d984195e5b1ada82ed2d5474a5c8a544d621d993b9837be79282aaabc8e67e8198e8c6847b58bfa66c6ea5cb8b12f8ad0d12eef9770534ad442be14f98ad577b09a94c6b15fe8fa6bc8ba278dabe5cfe44a82748e87e27f14c05a0db25866c83eadbdd5d90f1230a5b798a003c0d21240a0befe11fe45082b7c3d105f31df1df3f2cf1b3a67faa2efd4cfb20c928ca84bc2a1f19e0640fcdeb9a7245acd6ed921525a35e9573e70b48cc5cd522683503227ca9683903ac0ef741bb25412e73187bce1cb22ba410e4cf638d7acb9e7d2de99326dcfb7ae64cf68a3f18079f035a56f031550cbabb49e23052dd8418943740bc513bdc770b981c7af714b4a44c38a176c88022bd8dab5e1e74d545479b9c658994ac4dcbfed50a51f1434be993ecfd9b5dc1f1fc8ef52108767c71f90190f53674ddcf72bc427918eba429d3b5fb6d2c32745a036a87cad75473d8e866e5a391f09d2119afbd2b56f638797dd67c10d27857fea78817f6787174285d0b7293df01a36398b04a159fbef031aa44902167329fa732033c3a9b143c16205e20d5408f30fb366324b7e82dd78dcc59782c5a34256388270217d6c1c9263b789148121161736f1a81ed30703c87853f89b5f4ba9a5abec8748c7bed755beeac79b3f61e742d895308226efd205b7caac9df25d02a054afd418d324b0fb7835e86ceb33dd6788c879f32b27be4f712bff65ac65f3beba1cb4df80cff35537ac57e30cd487da6565623852abcafca69c54b266ea9648055fb8bb1048bdb3ebf50f370fca9d7c127e51a3bc4ddd31583c6ec3d842071ff40aea6b3a720b5adb2c50ad42215d0396bab41c24370032e569c8998f43d4493eb94f93484090850896d1a35aee98b185151252363e61b0a56afb8b48d9fddcb76f52a37059b510b3f391dd45e309fd4804f4efd8a87a56822089290214547c41a14c5b9fbd1e78f2a159cb6440b11bb3a4a73384d1285f3cbd8774ce6986175c699363dbe5a622cf8b8209722425a146224762da61df23168bed1c26aea0bd315113e8bc4bc161e0695fc51cac9f3bb724eaaaf5a434558f54bc1541f0c496cb3bd79bcc6a7b91a3ce34760d36ea182b4e77faef215519e6bede4e64ec741a8e5c2c05b8366fa9bad3c0cda48a06c83342aee0cc2a7ceea6b6112ab07886180988194e00a92e34cca8cfd585fbd4cc9c446e9ecbbf2b6a322fc1f2422e1d9c106396e23212ea3b27005e49eb9012901c36ed721b077570217740ff58dc2aed253855b5ad75c568253e9492fbba0732ac44543ca3dabd022f1b426d4450d66dea986b241a0bdf4081deff409bac5928049a96ef82561dd81f541f06e79a8ae7e63ca70ec6b0e962fd90a9e00ea333010785b9630f12355ba78aeab391c944b6c9781aec2b16d1849e2e91a772a1549135890ebada2ef554064bea114424e8ada6c0e6586e0793f92d7e11e269b17765c9f63c999d08c4a9c02b4836a1c9b0f0e48f2e9707b4d217b861e8802fc17fbfe6852e6e672165ece04e5b10c777c0f6ba93b653bf0b47ae709d8268fd680a39518652d66d17f04843c85c99bf158312cb105f879b58cbebfd111d4aa3829fd68635879ba168889df377b95720c1c6ece9c655e13651bedec8db2a1220e10690d44356b61621b87bb151028d7f37706d14ac76524812c0b79e5b1370528dc6ddb3e011890758f946d723a8fba977ce115498df02557c350efe21f771c30d259555b26dba499d9af8c24a9d315e20679874598ee706adf306bdf50ba50380976c4e5752539e8b9bb740c59cb436db238462f7662f7386027d2778d0282869e0519cd5f6e2c08554a783793199e2037ef02cdee3cda9f36ec1eb7807fdaa9225346d17d64ec8a4410168d370d7f29512ab856e899d8ab25d3a21575231aacc394c2c09df97b0d229708be3b1d70e0900b8b44d02828be173049b3a0f6cceb7d2d483e9815e8525cf9bb2e3c2e66ab673dbda31a772265fe75770de47129a41dfe47fdcead7a4ada09e44d5a4565c7b31928286bb5c36b192f1983689e75145e648d01ee579778ad03b0534c530bb4d983a64f7293acad2e460450f0f77f0299a01a42f22ea13cd2bfb550aabb774e2f9b64a23a22e185ad661df2b533ef894bfefb701614005fb9aabe878b23251319b93200d859a441c48ccbee2974f537639a0b2a602308c67e4ede74de9467a05eda21edfcf20ea64d5c9f9e5c97a2e1035b750737bca6cef07c758399ac998ad75946e283cb4e2baef0f156b322a192a5668c9d79f05d3cc181cb38d1c33f53a8bcbb42bfa9a5ff7a0c5158963178ebed1f259fcadf4421d10275cd1c76b6732a1cf81457b0d6bb1d1ae57a3c35fcc5214e17673b70a05fbcaa5b0cee71f902920102b9028d3901617a79f7c46c22c4ebf37b116b4ac6d88a7a0541c1c5d2eaa4e931e8ee8b086e6fd6285042224b8a23b588cacf8c506714026d43ce5019c9b5d9af5ae50a648ff3ef753110946a0f82147a89fea019e420bd7f673e1dd32d495d140c0bc59266e52dfbd52f8f25d357ef10e751dbedce96cb8ef66608ca165161b85a5a23b446f2cde1eba94a9b8260d4bdca2c0bafbc975170579ead1386c85fdae6b066e2b8d6f9184d6c15e7bac59a5b19a3996a89b2879d87d1d951158937633ee816608944a0a4058afaed11615af55e2506bb878d78b3e9b71c2afce4d94c4e3d1dc8e448629ae8e3ec7a253b44c34559445e6922f76dbc362fddcb58b3c4699c7fb9dcbfd0aa95b79732c0eb5a584b4d735d6c06a4c0a625216fecd41173e39079e33c2e099f65337c55a77ea0a6511fe55ab538bb42126c0ff25a6bd06d366fd1dfb138993306fe44f5273a154f9170d9ec43cdf76eb2a77fc5b58e4cd494fba2becf9fef4735f97c22a1c176bf8a432d03eb6b9838edefdf8c2530999a46d347be9d64346b3755278ad4f2dffc9204a960e7f27631f8c5db5ca17c6a5f7bef026ba3912f531263e7c7a301748bd7eb095a43a149d7833eee7175354cbe9e15ccf36ecd7b10b3f34a420ccb30f10786229ac67856d76c98f269fb97b50f9d1da6e28f6c6b7b312d17624081d04944155e626285096ed7e5594991eedeb3d882dd477adac24dfc9e1e390d221b7cc60c27a7639e49f053db1ef73971dbc0de38a598d840fcaa3709db81907feebacf04e2b99dcacc19867ce0f148d2829b6cd56f1df723eb6a8e72a4936f54bb67d2a2ba2307d2852354397fb97f52b442db92c5c63ed19c3962224dc78ff4ba49491798d1e59bcd710d86a9b137b3abf6370eed7954ca3c26126fa9c6ecb93d88f91eb50202b91eb03a7c4463a34afb63717b5b59871d682e33fd00d1813c9845da0f1a83c28aef727d1cbb53f4b7662ddf74fb30720b389ec28146a4a0c243ee4a66d5b30623d85043c8780705130fbd9aca0b2bc194229243da42577c5866339d18aff244b0da6e70d479f734084388a5011c2a74c498d4a2add896d5f4a7a3e5681f41c6aa8584a2e6c2b67dd02556c6389d95b4bcb36f93ba5d73f7b9cedf702eeddbf46a1c9e85a0da78e0eaf634934876882e2f92627a11abdaa074e3601b5801610035a4085e23624ab18b0d05fc333bfbfe78b0aa15581598027dc60741dba0948963cf234066aae678ad930082f76ca49aabbc466673ecabdf8e15e6f5015fdef4bea34fad842a37c99680b4fe4a6ee4df51cd116763f1adae0fddaf5be9338cd8eb610af26f73454a8e147bd3e78686a90fb4ea4688bb0e10c10ea17b7657862571a90c4394971c6663615644cfdb3437f638a860fe2b2077e409fbd2fcceed9468436c454d9d62ab224998cda0a5c7805fa30f9749287f10cefdc134639c94ffb05d6bcd373d453870facc1313f2c07c75c10829af1301128431382859ec4be07b30366eb7029f9719f12db2761e4e25bfbadf1555411f8935615dd51e75297b18e93e86c55aaf551a9dc2db2bde9b66dbb0647d630133b88adace6a8d154e583602bddfba01d453e0d3cd17fc9876a9bedb35deff5b79b97fd75a495969b47bca064d4c5c5edb4bcb45b27c6c867d5e6ede76f2b729a1fb60c7478e794b8ee970a4b0964d5bd44f26463e0385f7d04c7ebc7279930fb0a2d2d3bd57b90fe44fe3c053a7bd5cfbf1ce05e0d0aa8ee6b7fa6efa5586449dc875abf866a61d62fc5e8ac5b943b6c5c88897e618939ccdcea1ecb9eed828ead4d171e7e0bced5bc7b73ce91d4c6eae1e07d8f58e91df429e51c78362ae6d07e03a7f34447ca43c30dbefa77459b09bcfe874234c0bdfabc570ad7bc193426841d82d757afffa5d1860bdbdb060b909b9f193e5af77825598f26c963c8af8d9969fe58bbbba10680b846a7f535070bbe6b403c8108cc6cf475b7c15aa4b04de0ecfd3cedf6f254784ce21ddb673e9047a783b895733652d46db5e51e57e5309f2728889a41f2b0be076ae5b9bfd7e9f31913008077a245136c248a6f4c07b225c2858e4f5d815c846e56742ef9139038f088db0bfda5b6ded3c092c5e2b1e9df67d80b7b310823f01244474e9cffcbe98f54a9887e34e1ecf251f64c10dfb53b778b5a57a7972b7978f084c040c4613d8229619c16b08fbeb5f725691af181b062b2d33bcc7a429cf67f7c2fa08a551b2bd03069ab801eca24194a80158437c0416ad47d54a5c8d0615202d20192938a3074bb5d7b25c53aaa8c66ba93770de48b3ab04329e5bdb25c132a98f59ef51b93a216c071c96c80b03c8aefe6dd021f71a4b5b9546fa884559470b16b6081c60d99c804e62bdb03f608d3cede9ae64baf1db5536039f946d8b59fa8d9beb0ee4a76959a0a42d6624b67fec9186ba7094ff8cfec5f092f9bfc1532bb6cc86971f27745f29a66c20dd17f744bc73157ede27296d6ce9970b95e631e463be47be4032cfa5629afade958a5fff7577559a3ba473ef5430c4850630318200d8e70bbef1018067c4177e08a73faf792b54aad1849579d0ce4fa09fd5a1e09134a4e8b3d32b7bb56b188aca8afcd5610e95576bdd3acfdf7167299e79f00b27b0e685a03c7069060dc9633f776e44511ca9542e768a017e53da312ecd11fdae6e6135a1f7b78dbf258764938ac7952a0dfae9d5110fd9256e12d7f6ee8dd667f02db30cbf1ecfc60f4a54440745693239cd1df87a44e5197d4d463794985ec0cd69b8a837206b3533d453ac41c99ee77689735ff28fe60a13baebb27e8c245421f70651d67a672d46ed3a4ba328fa4dfd83a903865e985c2ad50d44418738b843726eeaa4cf4674a2e655223db918b23bd7aff52f6ea6307423851a7d0660f8236652b48431723e0331d8561cdc53a401396fae96a36626ee68418a831da02ea46e1482bc3d0ddb36e8819b692ae527e152054ee1530ade034038a54b37507bc0fc3eb0a0dee0f6ec4f59c18d5c8830a47caa1270479fd8a9b13f51244a75b3a95385307bcc78676d263eb7f31b773a45bdfa11729dfc8c34cd5792d76b5ee7345697956748edb90f66fad154cf4feec58003fbcd204d535bc586dc9fb9798d685b66af7f300bd23d088b2db8ad0fbacd9daced94575c2e49a2a84f7bf8fa0dff967fd73069b5d1e808ee11064557caba1608289fb10a53e94d0dfd48f4b626f6b4ec5fb453cabf71b4067b007468c6b37e55b7bd9f3bc12fb4e218194489126bd72f974dfcf8c34c997e0b8bbf39b668f19fd04a33c5dfeaf8bc0809049baac93db5b2a5e5e786eb76680d48831fd308691e368f58bf9cb946e34420f1c64db9b3503fd44359716c580304b455307b9f135fc3f661d16ad1f22f98854028ef75a8e3749af7ec6eed3603b71b6c6f2764f02e758064f38b3cce8212106f83ed821cca599ab035c15a57b8f8549e6a98ce9975481ea99cc719307556f168c07e64b39cddb2b9c74e6e4c8defddb0fc9608062e1d25d03f764ebfa11a4a7977f2292a037ba1d39236715c39a746dae43f0362b39016b5b96cb94d36262f57bbd50dd9761f41c2eab121d75c6064d7dd11977b55277ce1f84ed8cd2de1904c35a703dbe39bdfb7af8a1291c9cdba4acd6080a3b3a95a48b0ff92fe799d98d131f647ec9311e26a084dd5f57b4d7e7ae924b5bd9395120c5ead804441de67f416b304554a4eea9a00706b076eac9688eae88385c4673c2ca39133f7ee8b1a1c2832dd0e03b7289f35a2c652abb196967f7e8df302c5a2850f92b7e436e5fb40a2e2f5f1f992b47c08c95cf8329ad3af0b1a8d0c59bafd9047ca20c49da3f9f1e579a26cfe6dafbb89418cfb8036d044ef0e6206609dd57dc09af09d83494ffabf3405850cce97ff9e9b13e4ecdcf91bafb6b7e14c400b5fe48f470a43ca246b99dfddbb21c37bb51f48158ab4b253b9cb91aa62db0d54cfb3038ed52d5d916c54c53290a9c5fcaf82e563c899d535d7e411bc2606e7f792d43cdefacf76ecd2dbec8dd0f5e07528e993f909c1db076564f4515e4a93c18984850a0157dd028a2b71d3f50aabad5f47eb88edfb4ab0f7cc8711ff4338e3a4eae1fa66f6c3381481dfc1fdb95164655fe3fa6ed84c600f436ba5102137523299bfda4da6ce839befab7cfade146da9c625a2cdf83954fc8651e45c746957771d18ad51bf17f3f7bfa95d4f0ff94b50acb559b36460a9f14b97fecaf5c859f48598178f4e5fb4836a77600f22c8308cdef831c2215074d4dac2522dbd32f74676f75a4d02805a2147f47d6c322d28d848cfc33a25605ccee3161c00c8d142c269ba28ba9c90d81ef86aa18d8d7eca260abcfccabde349bf98a67960ae9330b38112d69dae7859568a7c6bf5dd406f22f30a1d72bd16c3856f30375fe61509cc4ae0c8db8c0af091b93d3dc50a50b13743994922a867f8cd9b0ff2f701160baf48afbdf71e91a790e34131c7cc66e68440b5e7cbe58d88dd5890578b3fb7d0bfb69ef58f09782d73e9cac1fd32e3e8d9828247050d3af4159b612bd4a29e045b6ec50406cf7721a3b3339a7bd11435258335d6e43e53f78fbb02246c1d6449b6b996ceb022da348ae6afd24b7cb67aa66151fc07789ee2a4e2e7b71348a4111f989ee26cb17d22ba075a831aebd27320145b7652284caf4fa8e776fe78ddf587489d718fa8e3aac0b7ca2c401f1dc284023af6a213873f6e9da7d4f6a14862e4a859572d02c04fc111e7d05583b664fc40c6ede4df63af501ceb7076c2b0137ed81db40d9969fd5e8a323857c6983300ca3ac703cf75aa52fd540943e5f89ca24353cfb1232898ccb983f454a7e05bf27ff893ab32577bc44028a7db4e5acdde112cbc7964eff2f0acd27c0fc5ebc2297fe6cbcfcc98f68f3d82086a6954fcb8666ab1fde15048e0ceea21692467ab9d96d9c1748d0392e59513ecbb1703ae5663128a6669f70d2a4071b5039146cdf0f7bea906f4e354f1c7d955e89cbcbc56741d1966b9873ae874809650fc1d696679877d16378bb68b75c4b1d3beb8a1168787ce4ed83fca2a7fc0ce6d061be2441a3ee97fd784c94a28b2848a29ad8ba1d47f512e35c30bf53b77bf1f0e8fb54a9961fb371ef2b551bc466413b81e74e030aa2ed3546e2f9f58ac4640cc315d75351cc6cef75e04bd6f6664df1cd008612410823d04680626c4af2499adfd968a64aa57a28b075d44f6b1388dd7b3d8458a109f4d6aa3203f51b44bfd43cf90ab1a4818a74dbb1dde2f458839bd22a39815c2a3fc92ec571fe17a13d8ee7d1d7e4d62e2bfa5def495ffc0251696f1a67494b4c0d2ad96cb4c819e4cdadea2e8734f7433ee2722d46e0f286b2f6d34f7d3176d968ab4269857ee31c6a782bd75e146a266efb8c2c0280e019cfb239a1a21f15adfdd4021e5d705b7a10360494f4d516651fdffece7a54f9d4d1d75520742b486f9234f2e162bb4d7372546279060502be6f3ca21d8c0afd877527e9c7578a0f0e29f104ca8d5c255f0019aa852c11e3627d672458cd1b4df58c7f70bafa1121749e20489c5035f3b3f5888643bf09c89e32c9b5b1a7b5e79bdde7c2a075a3344f8cef5c10b8adfdcafebd2d33dec8c6c9272598b09c87509eb2206ae6f7f5a307ce7921fa52318fd28f0367b48af6b824b5f3669f582663c7d0d8ecaac86e40ac442413e356978751a83af4046b3c476240231be24891ad04ff7ea119f17de461764187f0e1883451e38f6f86568de9c59d68c4986116b7ac9158b8a6ef93eb52d581da9acf95aa6cb07eee478bb25032f1f34d03e681160340ec03f6d0db471eaa185b3af77ea5f8e67987a7127a35a7451cde1354437bfdca4d8d9e21b8e853faa8a1dcef2fb909005532e15731f300271aa6407c63fb30d8ed6a5ab9c2d5ed949c0fbab814cae57aafe044956b27846f54bb7798b2cdeeda83c4d14232af3de5899f3291964f0f0cf95495f30cb827a7cf8f83da0366474d2865c10d5142db8e6299951beb8ecbe683a9aa274c8cf5c296ff1007c695524f447b678ed9b6637067384e0cb6c4840129acba1c0721faf87d13a50241a8f858025336a0b2e7c1238d789012bff77ec45f231cd4728303979e7abe372f20351547839928d101bf0722c51851a6d90031d9a98d62a30701e7ac0754e06253c4744ebde4990076a0144e9695a73e835d2ef0feb265d8bb5589b67984658a9659ae482a32fc923a70668ab0bb1641acb78ee28825176b3e900b18e6db52b8d65af7a97aef3f3a9a03d6a812c17d9a996f166d30cc325b0f60baee5eec6c69400f4f3c7ca7bfe3d5792c117bc9b3e2ca62cbf84fce27eca214a4238539215154037c03d0dad091ed428105b04b13f3f20afae4f7e512e5832fe29442fb7e6ba014003fd1e98d03b2e184876ee3e38632be89ab561abea4b852d3dff8af8df8f9948e48d3bc4ee8b6bba7c7c08165e8c82ca1b39638f50bab1bd8832551764528e6c9daa55a73dc59bc566b869e30c7c47af1ebc4b25ff4146fbea8b5f6ef6ccdbe9dd97e80cb5e86dfb4e1754646da4e517b1859c8f869838eb5a35885772551f8430bcdfef5f97edb87e9537c28c5c569812c0ff09a307bc9bd4dbf95587ef983a7d9854337bba9ffcf118fbe359ab946e9d122eecb3fab44ce49bd97cd96a8d2e265617ab98b2bfe5f41267e9fa06b7636fe805e8cb7613b61ddd4854c1ee0b7c3165d296c9a1fcefcdc8912dacc227067a167bc95ff3aec21795529b7025d5e9e14786130be4cadb4e15b093ef3e76c2ea8a5b87f85e23776b60a2facb3833faf460c968c7e86f739a2b3f5725fd8b9e33440e073320e31278e043c926a84a004a687a5cb4d9732e44941f75697019e90cd100adcf9a07f45b967d5fc7228c9180b28fdf96b807e303d9fa6567a14cbc5bfcddb87b2eca1ff4818d47668291ad0f083ee8af9e34644808fbae8c2db17122570420559503882edc2f50ed22b28e414e8ddea3272db67d3c0f62999071efce272e58bc16a8141fdc0e4876737d8b7f8d4c9da252345f7be19e549d061abd048ef97290c2563f5c173d67fb347576c5313aec2d45386ed3101d17b979ec4460aac4346051fd9bd7ab1da464f5a712bb5f2a1cd633fc50c200dffc5fdcb3af76e7bc2e114c62bc4c3dda729c4ff413c10b09dc7544c0994bbb8b9211ad955d93344d8dca32a0b3e2b64914b843c261bf2ef7dd447191e952a109557460de1f35098a8d6dc76c79061ed2710e935f65c34bfb1bca75728395a91ae055e15cd9092db5b6dd6a0c6a341356c9cecd7baeda00499294c7d009a17f0d2680fd927ade6637bfca6804a1fa28342b389b8dfbc23ceadac888ba4922441a4a92ac00b7e8d91d905b1eec2c4df9619688991b6ae87b7956847bc3f981cd130cd51c5a940f0d7fb6af19e1c42b4af0982df855b51a178ade620b6a9a9001b4e6b4f924d4d50883172a8cce5fd110fecfcfa7d5dfce42c323cbf975ae60d59a9b0d1ae15c6b784a5a34ad28b44f8c7482260f5c2962413e7f5b897e5948018435eaa2464377efd6cf439b5bf9c8969fbb6884a570ea15a699d5c88c2fc9031e027f5d8be7900dd63ba0ffab339e4a06f53bc62731aa676b54e77d72804f3b84c622e331f6e3427fdfd8e097c39a06abbf3b22678d87c7a973addef493674e6e6c6bfc56c88b3cffa1c996bd4b0fa99586bf15c56bb7c074d5fbd61e53fc8d3af8000c307092af9cfa64f62eb1a1db2b3f4a6ed770388a833dabb0dd2d80a48e75fd7cb38e4943a9779e5460fc30fc3c75a9c9bbc453374bb861b4864803d2034f3e77594b833252537b9cc01d0ecfa9a828fafca4537e4c734f245290128309e684ada4aad0c504b2ec7c6009520a8cd8373be555db7b7635121ea4279e3956e14d14fd8db3226a4a825b4f1c8ce92b0ec931feb230887e34977c361822c192236dcf9f78de6f13d2b550da2698447078808410f37436fc7bf127f34ddbb55eac93e33be61eebbce865ecbbe31018aceb8e36b175c906096f503bd8a93fba91b1f18722fe9b98a238eb93481ce7c941d9845c3d360b27a5c27310dc324a17368c70a85ee692e36f1ce3c3898d7028365a5ece5fdd1d8c3a8145615be9730983722aea14db7c5d4ba30ed13b00e99442998fe2a4d7926c43aa354fb42a6dc7de918fe9e8a6575c658e71ca931db7729ab37314979e651b40b36e8eadcfae790eb6f139a370fc851d355cd64eb1c4a0ff3ff861d5c6e2e7213b2fbfd1e7d6abbf3a6956140bdb8f9f3168615df2b2c76facd9ad772028902fe167f33ea3102c7a634ef4e22654483561c986ec46d0c218fc3ebdeca0b7726020ab48036ea5d0a2a4e57db18f71e1df87287dae37b53d6c72e0b6f1e0ec06b47cbebfef959dd5f75b492c396854b9eaec8cc9d8dbd36c10485251a19fc17587d489e4dca877eccabe5d15de7883a3292f00c5f91eac26d572b1c930f0fd0ff1f5f2fa920267e6d4d6b854f8b1ae2cae64c75fd623268573fc12c02882229f02d8413fd9f4fe5af1ccd6db0f54deb5b89294753d23286107460e8a8c6916043d310c8911f9c4c13f8994378f4143e1e46b891fbb4a9888883ebcdabdf863c062f9678a5434de77d730cb1fb467da97ba26f86472ed96f67a3e126df23befd7274d68ebb6654f200ea371db1b02b26d9f74ff4ca0ecfb22d8a5a19632010019f85466ab4af2d1616450f293a6031d7f4166ca0c9af599b907cd537c3c5a2d90630516d5376d0698adc9887b24c8813b7ccacb6d2ab0bc8fb9416c8c4ddf0ec973b89f3d9aefb64d1239736276d737e59206059e7af6dcb0a3ac12cd153c0aaf88e11d557d1ecf4e210f7fe314e64e60a9ceabd326b8ec943812056ab9a2644bc7787f44badd537c580aac638db546847a87d9a1496ab2c4c01b1c8bea89d6b242c3bd36237cbc028ee3d16da3439dcb8cee35fff07f574f89fe279d264e4f706c82d5b65309209b060298f540d95bd667271d3da11708652e2bb182ab4d9425a70a0bd755a5ef02c1f068b5f3f3cea245b543ea02a7ac210098668c98307078d7861b4e460fdb8f666a9cc36f0507b2fb7bfe50f9ca038476736338276a0d44f9b769379ee7723182486fc53ba7f4ebe64467d8fb5d9646cb60ad8000b607668eb6528749af19d523628cb39aa8199cbe3733c1390fca917316fca735e6120b331caf228920bdad4178338c76b0499fbb3aba6a44252ee301ee488510119651565411a8c8f0db1ec34123a32b3acaf372b8817cef9ed0a6448672710e6cdf5ee7bae522fd5de9b9e058fa83f99815db443b53267d65cb0344c6e8f6c3de19fd25812e865db501be6763b7a2edb04e1badbb851d82c77c98552b5ad7bf603706262661c281d7b198029bde913f4b10c99665a078a5671fa4412b5f37376724a39e9ac7ecf4480ef7be30067f6dff8e406c5cda0beef4e13351d198b767b9e6651141ab2c4f2b4169e9c9f7c78361f33b5529d17eb8017c5b7d3a1eed5da35effbb89732f0d48346a48936b4efccd22ea0845ac9b8cb909f47e68adafd086442093d0045144a9d73b5a54c17a46ecfd87e30168b53710a0850479091b1226834da2da95cfd7711892e1a5486b9eb581f9f6f7c041bcae54d80d8062a9c1964534f6150164e3f79cd7d2b14879bf9f188de4e00cb972d1a27c676c9c716f3035fe86054ec740877dbd0f600b3b3672e081b5a4cbcb9c1093b916bcb31e4b5a931191e74797b37f9006e4d9f52a01124a26464b129ab742adfdd78913f403c46788beb512fa7ea5bb81917514d0bb94ae6935d05accafbc202a79b3c9da80300b4ee56852cda5d41d4c96d85c740b2a4515bb99daabb06b93a1ed4e27e5f6d5874d4b404ac1555f8b0ca409e06cd34a21b615261a61bd6a540eb794699d5359b0ecdbb8440aa75e5e7eb23fcfe9afb2fa36a55d7a729437180d9f0944bc366a1aff8629d152f1de241057d56dacb1d90aa307786b458e1ee06ab0f1b0d6541bf33085c903cc59e4a5d53dcecc695f6a71e2e0fb21cae327b66e4512b9c67ddbd5a61a4bd2140254ba09caac7fa17f1d36d2b2018760fef2561107cd1d94915c667641880c204a8968ecb637b948d9fb02fb5d66ec0ace4460384f3e176b65bab7bfd0a4638bbe5dc155166615ec53d5c9e967ab8065e8d6084cf63876a2da24c5ded63b884c19e86c1303ed89051a2dccbb0204602984827459e71fa2f8ed64f1c64735e8b47166e08c3cd264aa166692f9bd5da42eeeb8ce61b20460d381ca1547b79365623728118a8e8270b318c6dc0caecc585be501ca16d28dbc071c819b094b47ba725c744e2db6f8ecd2f62c2ebe516e92843572625b28a6d6c14c0b250cb30d651b71408c12499cdd880ae20fbe6230e5e8b574ce786136d40318869a4c9f4e8455f859be6b1c8608a1dee9f572075d2cbd8522c1ae256c3a463966f0a35d3a9314473c8370e89e8ed2523ddd649e4d9591cc1bdf48c8e05a27cea9155837069ad586d2e820697397c9c1e2efdfe0adfe624b6ae744adc31c0e0857db204f20b8b4f6ec397c372124e00405b29f51ef1a0e6004868a884034bd5fe2ab283ea217b579c455d9bd81ce96b083d144bc3b68447b6d7bcac3b7b08a0b73adf274ef39be80100187f6368854bee3e6724112f2fa954d76b61ae8dc9791cc6f9d75ed32425ee36a9ec16c6f773f43a47b3f468bc7d2d9c4bd3bc55a96893acab1e3684e607b1544b3c3d098cd4bad8ad8f2bef026a4c90223e193ae87c19156f23bdadc3802749bbc932d8b00a06a1e54fddfbfc6a0d5156b9a53fdf40fec85083866866300a351b06ea1711dd5315c186fc2eb186a1553ead767e88abe0522a43b0acca32b7de0830bc044e227bc436299446d74586c81e29a14b88e7ed35d0553360d957b9683c826c8372c74d8c54a61b57503cc768d1b111a2796e6de3ad6d64085bb8cdf8ff6d5d24e5068ef8b1bd1f65c16a341d3630b63d06b7d904c8ff9599d471f96e7c9938019c3a2fdd8a578f34f0d8fb3cdabbc3968bda27d709701184dbf8bdf8f4b294383d87e15056812d43f212726b76bd54ef96c8511ce37730c7ea723b68cc70256b77440c829e817b72a3f287a4dd14eca0a869c70ac2d5c38a850b4529189ea3c4c3dcd96003131ebb144ec77162fea2808639c528817a27e3e465b235215401e386d41e356f37e1a6ec4c133fb2ce8cbdff60d3f05d98df62fa1777f93bc6382b60c20ee53fd3605242a15745f42fbd2f1b3763133f8879a4350df8fd6eab9e5895c62d1795ef29762d5dcc157eca180ef90abaa3c61da66b26aaed99456e041aadf440c9cf01cdc35f2d4665f676831eb325739cfc525ae95f0ede68549739b2b33f3ad3c5713012d143b4f8b2782544176f82a47e3b12b917cd73ca57a955776682887b20821d4b435808a7c15e76e14bf1c527ec876b807801a1fca33830952766a7d762f65c73658412e994224cf063fd428237eb8f0c317a1f78fe7de2bc94c7014da0eaff7d499b927c776b6c19a1b5e0994666c50cd59f22928498a6e0c153356c87d8efe38ae38b9e2e50f476ae61ddd2c2cd184bef89514fcd9f24bc1889cb6742caa3bca2cd56d38940c49260e2bbcc7e608c4852de4a54fb6ac8c7aa20b6f9c7cb65b177f50f187ccb9f4a3ca9968995d164bc8ed3655602d501c9a5a393c314ef75bb0e512d23539303d5193b40d59344ca5a9ddffe2263617cae10a7090d1857dd6403d45168a08a841f6d7343422ac9b3b3119c2b4561fde895aae06f064d5c9be53d7b5cbb95446e0bfdb1c6d95f44d1d8c0548035ae2de9f4cec3f8fa101d8be7e47083f4a03eb2b1f84024767ef69d6bd418d90e25a16ca97e3563fbde8b069581bd43069d3baba2856f720464afec9c75781b301f0abdda6dc199d622524216b1e55f6dd92defeaf3322d4b836963e022aee714f9cd6da9e90cf7fb1e4b7af4e21eab56358c00721dff902950103b90290395bbd20af88fbd8f355a34e72ee19fc3419087c7c48400dca39d72c0dfe5b1a990bcec8f7bb3bd9c729417b2ff65c60fef66ece97098ec02ab0c47b0097246d61dec308442682cf3e53284d6f1eb4cbbcfa14d318666e8866e9c566d963a987dba2f194264b3acbc1563c57f3b510ad36bbc8536924fdf77cbaa2dcfd21ea4576d5756ebb5cdedf0972cb4220c551d842f8a8757b751d3cda697b4ea9c63e19e4e9138b1d165a1e941198a1c4c659975e0f731582ff1e75208db35185122984d233ba07bb2f5cd8f4fbe81d13a48936270915ccef2a6b263e37ff549583993e7eb6cc57e7ad8df87724d8c2a9b363ae880b374a7ca139c48b690b8f644f0c8214c298e236792b3b9dfd9cb6e258778e7b72ab6198250746a6ab1fbff46a13ed24666673bca2f9dbfbd44d3df5484cb46f98d6473e1a8cc4a203335c34521254d5b426e2f97ddd08339399ce084a0b062c37b43e6e85557766895ef8727ae792f384c648fe6f16a77941c4891e5cc40e02ea8729946b0e9bd1082fb662bde2a8d25e45554c489853aaec3b55f35e93ebaa8e94c90d87e9262e1c29bf638d8e124917d63ff072e8d9a4d4d99b60552f15b5fa25374072f6962161f9bd721e94b14328ba76375d7df32730df6b053733b11a0c6ec1c42a965e16529c539b16bdbe87f8ead152ef42bc2d3125daf2f245ddba6baa8392631523518c9f8f936dd17d4bb4a45bd8176e9aa823ae20d0bc890fe117a639ab297b8e63e8a7d73a719dbf2e14c8b74e6fc10e6c9ab250a6b887b3947fb1e80216d6ce4d794c4611466901cb9e780216a04b0435cc98bfef4787ecbef24faab770d2c3526e0f31738acd9cdc7291c3dc41a1ec7950c391c4ddf8cd30ff77f487d323443c8f457a2d9409dcbc7c6159a6358f6fe67c6137b6ad5708f91eb50203b91eb06bb5ab3659f335a80ab35216233df49902368a1738be4b9e121824edb3bfaf9284fba275e11d56ca6e994aa8884938be495c3a62df76a6d7028a2e66b34006087f646e62919763dff875439c7af44f7b467f2ec4d0959c835671829fdd6eda2e23bbec0ce7475ae58d0b4e51754feb27a0a59b5593b1172075bcbd70b99377672912bef947492a1d9aa86806f6be08be51ed5e6445a93098130135bfe95b96ca9d849793d2e6581e61c3abfb6ae8050b976e342c74beae9cf135fadad0e0a26b31e80da5b4b03c8dabccd451829aaa8eebafce173b90fd45d29f163b05778600a7e5f97bf4e584f4e81efeb26677e42220e1b244447638d4e8b1af9e455685fa49783d47141169f1b0941ba5d7a4a50ea5d3704bf6aa2072f6fc57180f4fa2ed83ff841d016d0a8156dec2d1e752356cc4dc01bae8b0fb37b863e3081c0edd00e5f31cf20745cde7573ab40fc68042da287cc86d7f538a157d91ec6ff92ee76787df61ed7e31e18da23cd771d1f67af1faaf3aaca2efdb469b73c09551464ac8215bf03213da1319061a6582247ec55c4b8e8d2abec707d06cdf8113a44704cff0ea365f5bb46bb384003e8b6b76e4732cb0fd3e451e4ab754b4c87d09ddd4eafbc34bd090979a3e356e9536bd1378f07b71a3e17be414414a4237a0a7b6336ec84a783c9610344df9ce2b3ac6a9876fd57256df231ff1db9fd0976757adaf87522330824691ebde1263e7cf852f69d7060f991edac1ddc98cf1eef24a5dcb307efe3023480875bc9d839d923ec8e725ffb5845d38c417cfd928e742865bc20f4539532c8ebaf9fea0ea92d92815ce566754d1686a3bc54e1f8ef22b449a3e0b353f8dce3337e8f09b5f52e070b8324ac88d30fd064e863cd270ac3e606054bf725bee358969513f369995a648bc21c19cd3f2e760ca6da651969ce26e005a839dc536534da6333a153ad7af92fc84d9752022cafa2676ddc535f77d7a24b6328f34f51e43fc3e03194918ba0f9d709264ca1aa144c471b5982450f1e20fc064078348b24c58479aa5e281bce1223dd7cf459c02b857312e6b0c11a2225b3dabffe8eaed6eb6a91f11d37c66cfdc5ca8b45a22763d8448796c56156d5a30bd69e768cfb27ea20342febb026d4a4fd2c0157cadefef871b1c19054b7bf0d508985f71b894305df66c20846f99a2c35576c866c4daf8848146d442acc24d9f9fa994fa9478ce104488002e7bae42063734aced309da3acb6684e7dd921919ad327376532e178bf45b04485aae1fdffdad3a8fdc2764e8a7ad9d2311b848c0ada0587a446e39aebcf438de266917e08bbb9078e76fc3a0be9e90a95ce19d536448d4b006011ac1d717498d6e77d0b4584fdb452c8c1faabce292a3d892dae20bfebb773adb150f675f1b4e6cfe073c3ee44c2a4c6e189a9a328e6319573f84da3a3ad79bd621d52ef84111456dfae7eb48d15407ef161545ddcbd93da29df935fe6f29711b32da2b3634e4b579d38c2fef55d294a0904a7dbaa6ccd061c99b486c8d3b11706d1b404d1a2988083e490bf2ee05208283d7167e3f82405559f1d24c578d17065c3a2aebb297d986c8acc035d727c8d8176bebb2d12bbc1cfaa4767f0273e08fb5e0714ebb6a029a0fad34d5683b69da04d14ef53f5e1b4ff1d2e650f8f6e4dd9eb7d862855cbfa41cdc599ead29971e6e4a5cdb4567a20df472d48386bdee110e1423340a6cff81118c2690b8cf5c7fb6c34bd0863f773e10990423ca4bfdf7e79907b9adcadc7efdb991101c93c353e45f06e6b6192bd0b67b11b29585bef8b9ebebfbbdfc64a3e1cce659924bca5bec3f214ea4453d53cc60274d2cef4a9c2357b879b13b216a85ae23d07522fc34bd2b8775a28707be68529be2664dc23b049619d94dcf542eea2ff20048a427f0aacc97f814e21403480dd92d7b28215af5e20b81854ab73bb6713c52005ad3037bce36253daba38304361969d4c9fe73cc096ce90224dde576ceceed169616b4d256b36d69b44d7b417e04df3124926f110fd02362d23abac3f7b16eadc40e7056f5d07f8be76714be3cbda2585fcc1c927cf747a3d4ecb5a7e68311a054fa57be34f4c13ababb325b558c22e9c9f655ddde1f5a4c81b779d8214a05b0263ec1ecb08725f313dd03ba961eb729dbaf74cea217476fd251a09a699786e80fb7d5e9640acd872697f53408082bebf6f49670298be07800f80fa1bf90b8bdaa6f1585bcceb4543816a0af4f441021dfa4f967015eed385c6ee01bfcc5b94c02867ab4666410f14703d2abcf06d8f1aacb5667bc820344e5832d2e4b8ba906ea6bd29d846f93156cd7ee8a0d6c2724b7cd85ee5315873e04d6cad35e75a9ce10b41d396423380258811acf0543c7c03610c1558c03234d0102dac1e27b6fc05888c37449f63da19991511d5d46b31f4b5fa3675d974e2f4f01ffc94e64b678b437c330372d5dc5fa30a89828ba763199dc440c54df0274f516be9afb5fd99256d6ef7dc4ef32804aee22835b8c2932dc208f80f336c212c29a10f6d3591434f73fc6ae1306c1f2d65ea49bcd70eb95caca48f26459d5b439d8123cda2b42b1060ccfb758c7b1165080732529e2f2c420ac640003714efec2676a52ac0521e0c89f51d025024f04b682a133635eeba4b7721df600c6dd05b883eef16a0055e8aa058fdd29b37f5e18a10ab072331c711066fe8a4899aa5f10c489f6265f3a7a9cdef1016c95c48de60acbb2d7218bb11ed93f1c0e3b0c73cd07fb33d4ce0683316043d283599586227c35692dc48e19fb168f1539313bb120a3fad50ab4f972587d3d92f0c56f8ca2386924419b22c03e14c35d965ba116952c902f4f8dbedb22d56fb913042801f6d42f1623a562611afc3cabfdbcbd2da7b92928cbc6f701f8ed74a387a7f4cb5921543a4c0c194779ca9eb05907900e5fb22bf92fc4b2e2dbe15e3cbed46d7c3a92b8e6c973f816e82c3bde6426c110dfa695d53efebb313f43b8fa83a8258ab2dedb3000e1f7d5afba5a94d8aa619bfc26990153a28bd55088ec9642b80ec838fc63f426d0e8f85b15d48de0e7864f995fe7db988eb55a81116b54a80a288a2325cc95b132faf9617f6b3d24d7c472d81a30ef63a0bce3a8c6f7f0b22a258ba62253f0428e67df69700018847d95bb9758f019cf912aaa80786d2c1a2ee4371d94abff9fc5948c3c4444c1b97fada2bf91a2ed50f11ea2b56306568881426db4291461b0b833090cd0d5035f73ba483e08c06334efa88b56da6aea6b11ed93518d82730655b62f09a8b7e860a9308ff1f18f7c45ce92d859f406602cd49a46e5ce92dc2b53981cf18570a5d7f71501ea4c7140f71d57d5d6b4e63d875cd6a042b0dcc43e9a3907320897020a02a969c28ffdcb3d2fa0bccc4cdbbeaa5b2265d0eec753056c5a5ad3be7c7df19c0d1c5b432b634c474073a22004f08b28f82997e4135ee5cf010f85d6cce5b7f5e61900d5a80b486b7a59bfa6023ee3ee1ebb81430a752e20911065c63a958d7e200551ed7f2deb74ee51d39da14f7c5cecab26a6c1ef8a48ade5da4730f12dc1e0edb16ead675f1516893a1fb2111e64817880e3786bb7a12a51a84b72d313896abfdfe5bb730c5280b4451c3f2d493ac2cfb11e03f86b21cfc388a69a53772bb5ef4d59ba73c751786dfaa4d1f2f5e972c619e6fe2f874218aaf7d0f30a92eba28a53913b2cd9acefb12410564f0ee7a125754c67ed533694493a6109cac1eadd4cd84f82f78a7aac9cc3d328caca0741311f476df34527d614ffdfb2e1be6f1d9f43c35ca6efe53de26bd08736c1c851583b0d7f17a722ff293b33227c5583507fcb4cec845d9319c36ea0907786dd59a88933bb27d60ed333b45cb73e49881751917c32cebbb2015ea1a8ebe42eaee704d48c8fec8a288acc397efa93c7da6e68f2d25ed34c3f561778d828cb7391d23aa860f34eb0616c1976f75fd6771edd62c8f5728797fe27ddba2b7cd662328ac445baaa3fb0a2732f9caf0c0e58ea8497d05e1cbf0098448c258c612ae04ceefd7a8b20f68dac18d61fde35377260f2800e6a77e8893023eb708a82b35962a8b36e4f7efe0b160f261df332d0bf25c4d6a8b322565d029e344e3693441b328eb6fcb991930bc81b96d47d53b75a5b3fe293830577e7730b512fb9aa49e4c46c3eae11623a3f5d29aadca43fe5a6c297094b08c3d7b14fa5ca60920b6c2687ed1ef1ea26259a2266fe9d288247d6713eb588c976b10c51295526fe6efd8a8fb9fdb6478448f8a0a99ac57cc89316ab409210bdb5854cc9bf1d4d735ac442feb5b62a8437cfacbd386aee708402c40049f57596dc8f5847decc97d320fef2c2f50d65c42957941e039b500c5ad96977b2d2369249204ced269901c5d9942c3002a51b5169ba41aaeb1217e6342112e0abe68426fa761b782ef0e5367df937cfade38f571a67b80f10bd003db1455de424684767319a8d5d551d795668530fabf68b231de92799f1bd09a4125a0693b48f3425bc95016435d7ad197b82e9f443be21864973f622430761674b0261c1ecab5a61e089df5c8cda9304cfbf923f3044a55cda4e4749c88bce5ab23a2a313f11fe9aa4f751c4c32d94b338b6277366c9aac32fc3c28c9f6678da9e27449c8bbacddc7b443b80b33676c3beb1c0e94025ea4f5db4d023234bf92ea37672ffd809b6adefb3abaf362baea04ef3b2a23f37cc90a18f674ec7db4fce69093bcb4b4db3b3562a5ece58013db7cd7c01dd57854f09d025aa2b943a9a9d59d2a81eb1fac3ec1a283bc5787cbb34822a76a2c8f71f3296fa13a3592ae67a618ed6c8349626fd643d44b49050f07a90b21702fb44539f9024fe373944b9d12991e6854b3edc022c221a43c32b52f85463309a71bd3c27138f43742de2559654346abd7370694c0ebc9b56605b3661c076ac1c1403e3b6d1484605f5ae055bcb0a3c43927f524c4df9317e831191c263c54889d9b272fdb6f4cfbe18d5ce10673d59947d64dda29d291f4a6835a2591b068e2e78b081e322317fcf2e1d5738a730d00644228cefcc546b3e97d92d1b363a0d4d21eb3f2bcd4d3ffdfa76c1a9842e36e3cbcc97aa7be70b354bd9304a3d7501ebaaf77105776156fd7b7c050fca83870fc2cc840fb56a1d1c182ec4338425a95c1a5da13874656eefe4eada6e63aec8315550a7fb01ccfff0a19fa3b40e6412070f8726e211e9e7d0162f9fb5e6b2e1c7aeb3c4b2d09c5ac5a0d050b735001ef2c2dd18a717b4336e66ac1892241ead41b3a402961a7a3fc661dc4cfcd3033a63f09ce7f02d9bb342c95fa84f5cfd14f3eec6c8918fa45b14b2d5b1430d5210c6fa20277fa3137572e899bf9c290c2a9d27ff29daae45ed5176b08a7b997959962f08521d0377dda3a64d9cf8955d8f50170317f9a534506dc47ee7a06df4dd27828521d310468dab9b304da7f6a5872b548e20b6c81c9a7eef30572ce2670b17c62c4d70c81a068fcd81431741d64ab5b47b3d38047de7e117aae6002b5430bc9863dc53505e5bfb47a1addefe16444957eda8704081869359776bfe16061fa6dad36f85de95fb5c12a6b3c5b58987c859231b7f819a62e6955796aa852e1c4f67c894b5871001f2011e5f10831ae1eafdf5a8e71b4f6e3e93bc76d6f0625c304ff4fb69049b5a7f2689ea328cc6d8fdc5d3b5aecedd1415fb56859c8a2cb5bbde8ef10327d8fcbb18ba476a6ef0e65ed2a715235d3624e182fa63a81bc03e297be2d59c06b1c506a9604ffb00c5be58b50a55df5bfe49ce4feb83544dcc8a5495bcf2ddab72675a01c65489077f1d92257fee1456de52041710c9c28e69154a9b40beb73d6e1e333e8b46c620b447fffd454f6645299e7a472d14bfe5944863ee09dbacadb7cf3d0b18888e059e9404cf62086d6fcf50e98c4305a7edb20ae809ab00814159af960418cf3258e1edffbc053d296aea49a22ed2526ffb42645c4ee1b8b94baa97a1a739ebbd31be63e34e997df1e4bca1f4f533d0ca2bec74f05c3e849102dc29cbd4415bdddcc2c0275bdef0bcfe9df407958b676fccf1333c4976b9e659ac5bf51597eceb768e21532c41bfe9d17446069ce9a45624b731ca13b85a2605e811903c231f7a0f6fe74c2c313a906ef27b19af93061365d8b5108bdc1681eaadb0c9f8a006409281fbbe180b963071956329e164d82ee733873fa6aa0d9e4f68159782d80329d875f221d1bb86ac5c8c0ba80b9ad4c6e089e8f2d5d61ff664247cc05de33ff0e3e689d0c1c611d0ae0b52914d8821cd22662d4ece1142eca6558711c7c2b6c8a5505cc89be5ef0a0cc5bea6207a5fb29d9a427960e00c5a9a27921937013d0c1548b4b4aa0fbf406a4f18566952026965377ca21032be0853b1ec60c6a6b2f16b0524ea04bac71c0854729941328ae272da4a68237ba5af35bec7574f4828b1f2f48249149ffb5104093e5526ddabc915dbef5fe44fd548da47970162ad3b8690b91694c40b67c28b5a95d115892c81e4c3ad73899a22ddb12879b6a980a069ffec8047aac040347e2734033f93f15670edfaa7c4bf3dba6aa99706cf0b6c095c004fb58d884c5d81efc4a8ea6e74c08783db70cc7eb6e7b25380a7d71baf5b3c6c3f6b7f5c1d67ede30d55e6fd5b7d8ae9c6514ee3d197c225bbd1a69e4b6342d3a6fe1356d8c30133a27270cea5a118a2bfaba4fd350e27378c27a0ee94af63ccc08faea8d9b9659db7e6320825a4bc9e49dea85e04d9a1ccad51aa0a76b8ccf428f69e4969289c0179b99e8393b48465ad044b99cc3c69e76bd3ba8a2cc62b6fea315051c46784d12fd3226c08e24ff416887d8e768c84e6e12ff7c7833b52ab3aa2e7d18d5fdee93dee52132debda4c6627fb16bebb863cfb22a47312e0d1c1c247c836d0387163b74228261675d222b3597faa3334c18c20a80aad17f0e4f942c91959adfcceeaeea42d32b0c2497b2c7ea80b77c920fa7c1da8ba60c272222ff815dd39eefec7d215c715d69fc180827440078475ab6707c4dfb740a9a570d355979700411b937705dfe2acd122a7e5571ae28aef1e011f496ba7767c005bc8bcf57a2796289c62c8790b7022f01b65424639432bbdc5fed2d616633fc7ede66439ad3f990672966af1c2447694d9b46f65764d6328813cf9a355cb9f6424a304f7123ae73c3f17462f730f1ad87fed10bbef1bdb9ee52bc9d8ceb1f1a90bdd7433316d3ffbe1b4b1507d96507b40cbf7009a2d1d0c5d6d9a4ded8ef394033dd1d4e67fea6f08a178c90cdd1dd36c46a45211ad5a3b4649b9fd27eaa257bb8faca0aa7138c5d473e588da840989e3cda10f00b1c13dbfb63d0a82de683e62bcb423133e62264c0105587bf77ce13eb77abef8bc106005a2f69a45ff0090ef37f6dee0adeb6b22a7d074934cc28c3f3d3fc50a368b7ce23ed752b9f206691143947fc4244a2c453385ec966ff89ffb2c8c0047b6443bc80661b3acaec8f3b02a8b7fc861cc965d16bcd9db5aa9c0a6d7d85d243434f6bcd9bfc319bbc68ca785d661478ec441b4adc4bba47b7b82a76d07e21d9703b0e6544d8a3a2d5b09c6b32c4b18622ba2643b4de466c443fbefefb4c55112abf713768572b3384467f46d1d6ff1510160e803599ceb2256b7f9b44b4d62c8d6fc0125454a725f0aa2092985eeb25b680f5361dc5ab2a3417ce041f11900739346e703153aaf4cdc984638beaaf965ca0cd61b2a2dac48b514beefd0320a8d641675439467bea8c10f152d1d9f1fbe2831aa839f160691fa921237578dbd1d74833ac262f1e0c1ffb25ac3a4b6e83cb4f667f04a201beeab632cdc0f6021ac1884daabedb9ef507df2b384f446a53d26187db8ff779b94d1de36baeb05d3f20f1a3da9508d55f9a1f98c7c3ade6f2c7b3c72e7babb852f7bfe42d6cf6cabb8c83e5c5d13c6f5e1d6fd5ffd1b445c3e68e8a554318a146258d014b9fb2677e251450b35f772341a2e12edee509441d296424be6ea69b7a6398b5420eb7452f782a4e1378c452b6b698bb32efd50b415eca88235219646b19d8591285f4cabda362b6f3e05148aaa66a222d7a37583220061109ef6531892574cd6dec6a8cf539b9c5fb09375db3d65945441dcdcba30838448cec1c4eff18ae52e674313f361f552d71839db587366fe352203c74a311dac2a85d7207c69ec5774544e6e8785a5bd9bfaa2167f11d2b206cac394e1cee292cf2737b6fc543b596634c65854679869d394b0a3c63323db2161544f7b9d52d5aac22dc7cbfdf7a3b5721153711606852fc9ac52ef71a5495f2a1f2ad42e4c2a1aeed30047e9ff2b66a2f0380461588682dd9623ff0e6ec4800c10aa464531029c68f6c967d9bfe762f79a0b186ee23c1f07daaedc2a38591f1796831acd32a9cc9743350d561629f1e54b8f7d8248cf29179dd661e0dfd7e25d56cf39dca1212c531ad6e4ed635d7ad67105dd1655ea7ddd07fc572ba80ed2b8360a8153a4a92eeeb266754dd108f94c1a31497c0f8d5d4dbe05345d2c560fed444bf9cd21f497cc9d2a9a77bc454f3af0577a0c24346d591872e368e0612e26a9206e86ac754ff1e38c07ad17ec09846a430761573b71b66e4f4c2173dcce0afe6edd45f7044bf2f22dc3d74199c77a0db453a82553265e450d8aa74d4d81f3d3484621aab0e162d81aabf373f48a2bf87f7026c2fd94fe1f755e81dda3e4eea24e3e11b7a2fe13baa2d34230e266093b20d561aa1be4d18a959dc647a6eb836d8e8c1fe9ae2393353a5525fe4b1dca98c6d44ba5df9bf46ade0eebc1201f5f1b3c0d15d1d080b79326a54da4ad065e141a2944d29b8026e401343bf802ba355f9eb59b81b358c8b68e023b72245bc090767d965aefcf0bb3c38e1d41f805ce78a9ead365abf55f0c298c83fae55f815df8262fae3b40eb6d6974bdb3963aad3f968c40edd887481fe0c209ccc75f31f4a2788827764ae0556e90c4e603815ea7f1988c9ef68ccf5a066b8cbc4df85676d1a5f7f7e30261775e7f88d41d1c1551afa4ee1bd626f30a810ac929667e7be7079afab9617a71e0883be561160e3e8a3d07935ec54582987458bfc72043b38cee4ce5e0727f49cef1360bea493d4fef21ce4de6e9746e85e26f100bee13cf1555a691fa4727d57c62c30bdeb004c045e2d3652c725b7e6e6ff706221849095dcc7a8f9ad4bdf7c4ea1787ac8e507a59fd364385f935f1c4349c4e384b8f62eb0c4dd24a8a407bfa78c7f7f8a74470709a3457b36821a687a01e64c75fab21c7b25c364f6ff7c0ddd42f8fbd3018051e49782d00abadf898dabde9604e49c9725aa19f0b1880767fffc8a417f899f4babe0ef5c66e5c71204487d0b2d5379d4d083c9dda19a510dc368ef65c44eed07fc84b7d168ffe75d2772bb4b83eff2c7edd8333652988b3aab07e79c01306d2d6bc5a798dc2361a91041bcb86b1c76277eaac832a3af664fe3ed4c4874796b6794cf99e2ed7cbd28138e284b7f70b11914133171fc47dc8b18a3845f64f3346b373888d3061e13ad53a80f96f3d574ca6dd84c1c8be28526d6632d45414e465b983990345360d4300f716a2fb65bc13901c2eaecaed7fe9101b0cd2d9474ef7d3882de6c2ffa6c8eae946034e71625970f641a308e9c9642fb37f941fab12ef3f286446e42abe02e9676cb2450c0121618b09fc4a0443e5ebd9c6f640ca00b28b2c4f963517dde1e0c45b1bbdfa041b5098e2e20fcf36400f1f7503648d702a487d6f0547dbadbe8a7a439907b5e8080d3e6efddc99644a53b508d027438495de752542b90ef9c96ee46f1f4098664b241fab38e23ac16dc662236fc1686174b9547ab49bad22cac53dbc9e8624d5efb4a4578e60cf6162e27a4801b5f11a84d98b4ee0ca6991ff0fe126efb0ea78a3db19fd171fd6fcfc6c24f758b8b62a120818f03999a41236de9cf55f1e05b24e12f89e232f821c4089cedbb461823fb8088594c749ead60e61b73a97d1dcfce1f8ad8f44f0dd844f794655d4157cb5edf4b93669c873560913f73ccb0c0246891380ca20cee7466bc251b0d415ee95a116136470e06c5b4134eec47fad4e6cff63d7123bc9844c8fe14bcecdc6aa385acfa03de89f85ace66fe5ff86ae94a80588369560e51f8898f16e71878e2d90c60a2ec93cd000f4e542e531841fa9887a40e86d365d754fa7c647d6d42be53b44fe4a32c468c7bcbd30c30add37c306e5dc707d5c636e4991b75ccff915ba6d0ce4a1c4b87674a1d6707668b67fcb30a19f794a51276e48a4ba682d1a5a440dc12b843e3abc5d2e35c918f3ae1ac594e9e286b74473cce760e7c8940be0128fefbc38459e22edfce5237de6d50b2022ac64a0b30b77d30211b328ec43b0c3d4ed59e7eda2ac0cf8fba52070ed09895474c27d2084f5e636c6aeae6845dad39edd740f6c41048c92df1ffb8ff2bf57d00cdb6e282a3146b65de7f9e6651b8746a19e1a7b4ec5c39903a297e3dc15e80c3ea626dccb29a11fbc3567223af5c8642a05f0f4fc98c41b78310584bef3950ad6697a630201c0ac5d938ecccd3adcc8ff93fe131f7296e4c194657748cfb01cb7eccb351ff0ae744d5f9605f34b71bccecead837042e043a72869bbbb03057ef23b920e18cf195bec252b602bce39f0fb05ba5827b3f79fba5dc165012647f3479162110d5d9c040595e2b9a5683e0ed200857b6a0ba688080153b0abc5f5830066653e12bf69883e324d932cfba6ac6407ebb96dcfc62d95415b80390fecee7e8910f386a8eaa83a0446893d2042d5927bca4e334158c2866b2aa63a446407a2db54ee0d6a74d6c162585597641ca69a055118356878b79d7fdef1189d33fae2cf4f6693e59c1a3e9ef0745dba592f18909b4261545b81c42bf08ea3b759595be41b3e90b00eaf04d5e83e1f29d0d881422cab271e40bd4331ff0218949b0f32e48a4c7aefa5d8f899f9dc9d46d32aa9e971f7fc8346b5169f5fec7047775d0a3c6764817bb47ade028db49ab66d4367a3d892c219c6a71f8fcc23ca00ac1b987da76729edfb065a59e0367e93ccee29eafcfaa77b6a913d312cf6af902930105b9028e3995f11ef5c267a312663f3bcee039ace28d6ed403c153efaabdea18ac8ed3234f1548c6b9975628479f423ac34507e6e2712874c379d189a8895b7199d992980a6a9f75d35d16ad9476a256c59ad5218c1bec5357039a65e6faefde3a7a5c6b726937de08bc506e3c69acb1d229b583e4fc9064c9d89a7b78305edc270baf72d0357313de9908eb5734c9bef97cc989a1738e9bb5273f0a71d061d7f5ceff93e94de16a7bcbe76b9f8659022e069259872b1ddf49b94f961e270da9755e66b76fdfe2fe1457cd33b2c855abff06a6b17a6ccde60bc8ac4c9fae161e4ff2e46ca9d3b59b2236c68a3f20b8d7d3c7d71565d63d1e5b1659ddce250eec1260583f3b9597d9688f4047291f7d66b2c5b3fc9646176620f0577c16da8f6969b47ba1509beee31df670e2385731ad9e388f5a7035d073a4c49c679d49447bdfeb6a60de18cca370ab3d93b8cc12b1882e6c23818f6e7bd00da3fd546c2282bb1539ff65f7308c135c4bdda9d4bc92379b8f9a2227423ea9e1be0409774a3b2ecc59c25bf171935bc6cbeeda9435c37032964e6e5f65b6ad210c4260fce2722e768e79cb90a4080bb7c87f13f38b2d74dd06b97a7ddbdfbe328df4ae3a8f8b46b9c51b65cd5c4963bf66fe3ad25df37d82166ae3b5b96e7cf6ea2b748d3e9221d68725a8a5e5e75d61debb9281ced2be0abbf317f226f8e65f278bec481caed632b91839aaba00c0b16b92ad8b2cc64f7d5b89305b1499906399cde08f4ee55436198763c536d5e9f86cbbb11de2c362d9af298c764f022068fbd388547e70e7568ed82e989b9f2b252ba0e0e338dc55c5b3e7fe1fb2f1046da81aacc85c22e90185e9d1f7ceba3ef7ecb44704e790c217a9a42c84bc5434893c6f06eb2cb59bbf893898254cd9a16ab7b1feca70c60d32f91eb50205b91eb004a426e537fcb15f437483ebd4eb09294cf856802682ad0add1e8624ad8ace73fe2aac64c33ba45e9eda9c6f1c59c9d0b061b2893216454c37a33b8b6fc0cf102e2618655f7ef9495e56ae09b8bf67dff443d5d999f6b73c4ae148702788c3448b08245cffb16bb5ff23d97152dd6f0ff34c319ff9648cadd5a63a7a4891481535bc23f497d9ba4b3cb27b4b06e3ffe4dc8f5a2fdd055f778d0553d1e96e69539437927fdc2e2d04a258b12d2abf0580109f685c9d3c4a7b59e455e2d0146e751700b6eac87ad9d5d982a6096615d0f008caa905e13f4fd61a89c28d1563492018d68a2033e6dec590d603d7d0853a2f3487e0507a8a5b51803993776de321a5fe48faf7c012552cae1110d92f83db273442436489550d9464dd3cfb71d93ed37b2477792b3016cf350a536032ca2055d44a3a393488b9dfdf153c9300ce0be1847224dac9f2a63699f3105b5a5d183a237e5f7b6cd8a4fcc5712803a8b06454fca59f544a09dfefadf0277923370e38ff6800934077ec195b96c4c873029741a9695a3acab261318e128fe7a8948e7f19dc07119bf5d1b567a050b95ccb1a5650bcecca36d9796c7245922f401f0b6a31ed846a6b3446821a9fef07f6bc4112e3752f6e4874cd65d691598664a29b91ae40f61a36c426d2085588cdaf0aea86042e30eeadd8856e312ce6ed3c791712a0709506988f07a75f524e53bd7993848599ec477b5ebf9e1485e9a965251c38e7179148fd8bf83ce42536d1c2376cd5ef716cd022bb6be2d25e4e53bb425fc4d48c5262101a7f46e72c1801f0b896958e742530428b6d41b1335588b17b01eb51b4e4f307cec781c1bd2c2471b9db490944693ba6b6be3e78ecaebe6ac5eeea0fc8b95f204321797949f46681bf998bc8e593a30ac87a7049a1945ade5930c2a0f39790070576ef94d2fd15131c4d68ceb9e57b3004c65396552709e780782906a0ce6d78a4d17b6ddaad4821638118cba9bc1ffc999ed57220fd8e029e77d8b5ec0266e20e609ae9ba5a78683d5852ef554fd9caa7d2574ffb29a9f8c749094b8df00018af6887e82a91bdf5d0bcb5652e260d245c4ad085bc0c776ef0524c34b69722e0bb79f1f90119189408f1df1c1e119aa6e4cb88c3cf40d53274c03e39277f432288ff0b3f42953b27b5a301e6484943a8de774c8276d613633963ef57b488a5df6d3f107f23224522aac04599b395d84de436d0dbc4f36446c7e44214335c4820b1b2f8a42d56787f99f5419858083646e0be3b12696a5447dc49957351e3662121c1c183e6ff148ee9ffcf885787a8b956c5b1bbdde3e9b2ebfffca13ba9f59b48c920afd1ce2f3c6838e325c8fc1336a8f8968a44ce7d2dd0f8922e8dda9d93c10aaed6d4d32c93644a9646bd73a1be82b01476dbe174cab8724bc0ab5ab465d43b46696e9899d35bc5127d79aa317f4a1261ba6ef0e026c299236f11437b99b6426ef7f40e4f94d6db8667742df3907daba76c65097132d8cb5a50e4096fe2033bf9c0aa769766070660916dff61004d28b6f0d46773144566a3c58525b0287b7f9a34d4c718b3aaece12dda48ef3921f9f5e1d1c5beeaa47b337bc41412b9a9bbffb7ee1bb05611120312b1d2e2017913d58d00114d22d928bf608ff92ae90f5d7139de5dfa354f7e6c789a31536cedc56b6fe1e07dbb7a493aaddd9068859ba37c78ebafaad3cfbfb0657c57d68b13baab53c5b067128e7724d0f754cdcba22fd1de9ed778df725c5f3caf80c7656e07ba6355fac94ba58d4e06da591e420b3a4c91aaf06d5576dabf0d36e1e8e58f0cd87fa11146911efff2bb88cf347c4d5b141624250818e76ad6d338fbd26c6179645cfa3d39e19df09d2218bc937b335e288b8918964c00e69d8682c83dd03188dd85fc8f6613e2aaea4dc7778f4aa42c5949c32782acc97396591499e888884ea2d7e1948f72aa8df0ebd7308b6aca52682329af706fedafbacb1c78a0fb934a4f4cca753f80808b1756b05fb0b83c146f3523b64d1dabfce8160eedcb41719b841d59f0a472b6a5a5f26ef0ef192cc08126afa5699b7bb473da04b7ea3a0d47e730a764c9e299f5afbd88c6065a587982c685d1dd7485ccaf8aab2bc4f976f3ffca543e44ca075903c306222b2072a4073eec20c6e36a709b6d18977f745d2408fd108fe438ff015ca8076641e92aeb8bd9010c99ccc5a9aef644fd4e639196e134ed8784549ea530ffc42b12c1816f68201d399df1d788d68785d376133da073cad19d11ac2584b77d69c5b9a1ebc417315f440fff16aaf79b9fa14ff86ccf67f40017cd63d51c756f24d6033d8b837cb4c8ed104e59c310c7ef472e9267db5018aaa52ad6415a30a300b81a02e1faa2c900d341126c9ba4770c242dadef5322f07b25f4b2a47fc2db8326f1bfe3620fb0582f610527ba05bfef79ee54c240f1436fe51da2528709d0e5328627752f36887be5e82c1715a49f833d140292dc78456456e031db05af6214bc42cc5e47a61f026f3ee9c579be97f0271cdcdedc714d8b4679cacec10d73072eecc5252aca11509c63e89dcdd23e973348d90344fce631833df0b895b15d52d1b04d1d2bfd844c12751ade5110cd82eab31bb62fcd6441b2ad4f3e5cd564c9cdc411791e2eb0953590fe2b5ae864151c95203d5f3c6ebe658d975ed2dd1c9f75db504157eec875c7efc26903c7de693f78a5177cc16c1528e3d3d2f930f273f08001ee77c767c5ad4651daae1e3be6b594f7e65a857b9aa3913e8be54f207441207120e7fbd79917d0b927e1bedf2e8d58a63656d9a87fa6d8a68d8154936db26d3c67eacaa70c4b1536b5ba893d92456bb74d6241ddd1139237582b927bd84edcc215100f79389657caaf5a38f9190f622f786742e6d90768664cdffd4cc22437536e7907950370803d0e48f7daa83232fee661fe259777697ce6483629cf4cf1fddf5b5047ac7d971deb84c1f9203267c5239e744dc3c8cfd811c8de434f61a8e23fb7209e40598cdc84d0c3f12518054d7834a151a9280a2a53259c6aea87d58e623cee19a5d8bb4dc9bd2170335a480dfc37abdc9645c12577c40a75b7a75416ad2001e72d5723c1f815f98681177f404f2bd1a6ed288a01896164bbb3f92a137f9a71e4a8424bfb02c97b708f584fd55f2a8854850b1e404c66568e9f9f221ff831069a47d854bc26ea488855473451932c63f93f50d3a204a3de093f119784ebff2c7e27782d078f4ee74ff6c35b5bdbd69c82ad3cb13662d3d4301f8c394616da6afd229bee831757d16ac16e9dd4027f4014498a93634671e639096b581a023fd1b5192fa5cff83f6474bfef08979e2472c5160a0f6e0e7496984b348de5371de1c39c689b12a5efd030ec87baef56725a5f84fc1814edcb058daabe4a82af545f7bc02b26f7a4acb4b27f7f37c803817c312dd6faad2b4b7c4f0e5f004e12284dab48ecae0f7206e7ba01aeffa5ed6eaf795c2117a4c05af3f98e2cedd367f7ab77650d15ff4ae903bb61627213cb7cec4231d26bdb64e9b70bbd2983180336116383d7e427b89da00f45dbd5617ffda846d4795850efbfc61c6f0ed41e7450478cbb707a7f70b38f598896e85d3a3742d51d27bb0f1f75467b6309df17d81699379b60e475a4bc70466ff9c28a23a3f7172d33bf4e6f221d2d93c99fd82520537787f53d48aa7e3c5a2b3ba041fcc64a9adc8a960c795092f02d80db67a613e7173098ab1cf1436bdb1f2903492636c8e876c748360fa6017cad7b5af3f817a5302d51a7d096f35f55f5f03b03a1e7e32a463975dada599ebfcd24740dca0d693545cf054559e21c3e54e037c1162c7a7e4723b403f056d2b962eb5631d7c18e2e59767568c2f9537cb4395d6bb7433145bc7e297687b316051b583a15fb4f47d1bbdf3f47a43a9c95be948286d03a1e070ce79068e87ded2be268bfe4a19d667e81d53ba6825f7367973ac9382e7276f31b44eed3fc68984f39280899dbc9df6c68b713c330ccf459846ca0a1effa9f717fa8278684ff2f2a77914ea2c04066283174f0600c3ae244844871800b96a8100fe5327adf9cae0cc93ec2c8536de7a9ce7511312f4e4ba7e567cd5d6051aa9ba657cb002d3afc5634ae7033934597f6f1219fb5a7c724ac0f80a71425352ed35160ee00e006f21d703df2522aefdec91a48c8570cd5ec3a915927b3bd432589da8fb85a79830dc147715757ca02f7ac66d9b3aa824df5c5a5db93f2034ea57c54b0f37cf6fde519e31921c7a8d1a4f787cdf27c4ea4d38a42c160abde61c77aa30a8e2443f57c313ab3c94c70acd552ff3dc626df102fa6b61590de891a68829e06e4ef48f93298cfd0060fe93dea8501e69ee89539a7d87b5b7b20fceb89a2a53c1762f8f83a008488b8a2a1b1ed18d6c7ee6cc03c42a84389fb7e35ebf32bc00be792564b4148ff327bc7ef8b2c0b8edf5f99e9f305409b3591176eb56b981e3e480d7aa5141bfd57ea87b5c90ad967d67de7dc6eef334c9c141c9991ed948b3d47ae95ac2834ff67c41da18e71adf7a109f7d489b49a2e596818dba428d4db599132af29719497f1731b77b77906831de3e665fa0402d4e59a86d25f660e862f61b9acbc71aeaa150b5c870e8c3ed8e916378e1381499d46e5807d05abb57b8de31d589e6ed7f84ff4d0bc885e94596e578cdb03e50202ca5fc5ff675a48bbf53636bcf6d18e12c0c0dec16ad76d7c27f0eb6c0a4e4d84ab539b160dbe5d78bbccd3bf04011c70d599b4783618b6b46731c44d56ee7a18c418e70fa4c2bac567c1af1e1070a8d1d9aa0efa8b73b8cb4cd33854a282cc8ebd34b46fb3c8327930615f73af84be337c95f19c68b2a0b79d6596770276e64b2ba40bf3d83ad96a85967451401399b6cccbf9bf0a604f6c69380049217e3439612fb0d10c210dff007892dad34447a924c46e82f83f270c6aa866d62353135d748462e8318cbb864331843e7d14712288a775bf1585799350a802a327d391af30cfd6be49237c90199ceadc44aaa45be91f478a329721aca4ca38ef95a2b0da19c2537f31aad9cb9c40ca52f6c53f516ee2d4728e9807fde2c04bf5b89a69260f7dde291b346bf17efc0e2242a7e4dfb027532b1339b48d2d4ba24cd15681258754d2401d30ad43569076e714892dd24abaf8908314f3654a8da133a07b851501d389f02aaa0ac2718dd812479ea2f52eb0af79d959b44a8c480f9b066476823f512b935a0afdfeb1f43404cb66bf593a8e5462ff94ecfbeba3d5c71647023acba2a2ec635dd4387399db94afa6d9e2d78d9e46b6e114eed88568b201d0f3954e40ed73b57408ad20823f2a235cca70b78f89250dfa3dbf94e19d12f2c127d0e630f70b65fcda21489fccc71fb4720b25388b12bf411c11f790b5adf0c93dbb1cab791ce8519cd233eb3c252507208f33a5c98201b695364b2fb8d0f512bb101ad6508536aecbff1b1ceec9576338bcbfb5345e323821e965bc7b33ba7b2a541ed158ce99d070461afd2c59e8e459284085552484be2248c7cfdc74000448b1207122402b41ae0cd7ebbf0d9b41457d33101da1ce7e9eb4b203d23e4be79cdeb07676a66b7e9fc298312e57befa12d82707be3cb9aa8233f99a941224ce303ac59badc8b042eb64ed43ba12f3c241f5feefb211518a2eba531271894398b91db733a2ed3ba51fb9b2c44df3e07373fd59948c501ac963fe3211c39a24332f3cf53e4c85a3727f742d5aadcca19018293891d9475a6832a3fccf20d05915f475b2fe4cfddaedae472e1d1dfcab610d95bb9f46366f110e6ec1ec678035729d24c23c3f94cd166bf4d5339e57710a3ead62ab4fcdc6cd1f372d81f487a2196038366facb30ce3c4438334c04c48e3d37413d8516d4e4ead5d7c933b3287e4e3f96a4d25d294fc617e59ed1052e345530d5f71bd9370a4cd7de2dfa0cb11b1b597b32ccb271d84322ff1ca86db1e3802d49278f0181e29f0406652317581307a3bee4207f3d41089fe0ab86eaeef745175565d908e7789efac36199fc14bca7bc30024b8a7a87f0d06a247ff79339ccb35da48ca68aefbba70854f56bc3c858e542cfacd8d9e28b19335e23a1fc43074d414317a8413d1cbb09d733734ccb6f44b2140e338ac2eef8dd5a74af6a0551ca9d5f357101fd9499fa701f026953ba52bfb0dae0098a239ef2283178254858a9a748361f31b79a47cd149ef166691ec13b42fa940732203384098a26fddcca32d993bd544156dea23f3d82c29280452b9a7ab4f482eb6f05adfe52e08d41f2828dc76f340744f9ba3b1633fc712c9acf9f55846c84a19c2ea622ae9e3236dd9a6d55400b856040c70b5062d98e5a3b9922c525ae7c660b5bac71a26f38a9c4bf0a0f75e469a2fbf7c2a217700b7ab9ce5d1fb3ddecd298029cb0ad2caff61d468dd3fd75dfd8af09c883ffd4feabd9e5977c894212e77a55d41c39020eb1e10cc3ad601355fbd5909e42ef4b8d1c1c6bdc548ff22296dbf33f5955a6c633817f6f6d576a17f779785c1f695be7a21d7b0273f4d6ee5babd15b7cb2bb17cd71be327cfb83d009e81c98ede5a3d84cee474a4f00c8b3af821b483ab5de76ac0e629a214252563a24d0769594348fd48dc7e2f2e818345517cdb4dc6e985415128f55a68a2925fb96cae85556a8708eaa6d95485fb6f95c660b58d3a08df1fdf3089df5c81382c9c339fb220241f33e5e02b61a7b9a817647d57184ad2d3b97ac6f82a6f203fd512f891d9e26f707e7252fc159d1a5daeb1b29de504a19bcff989083d7296457f7225966ac415ebcf4ad2f56234346d138cb6216cf5f417db1a4388f5f78cc740e2f6d2a1f673980fec36c2352b0920ca64d6133c8bf78f6e8e62b52eee52eb15b88ed587b0717e05cbdb7aa103034ef767466c70221cee4ce6d81681c5bffa13098a7d5c1a840e9a6b2769aa870b90b6af62f2d9cd9bcdd80ab08ceb0f2858e990400d4fa81f8ea8910d5b9a0e1da6488824e1b5892bf20d937d12ecc18c8429d41b8585b165e12af49c013a3bb9b9efbd13c6ec3ce4ec9bd7a5bc019df9c9ae3dbf447e081cb7dec6cff548034867a547987c9fa868d5dd8071a431e8e6f8ecb0a0a127c8973edfd58d7f14c578b7ed06f0dedcf5d8ac7265a3d19960971fbc07b8fbf391016f3a5fe6db45b0043c8df8d03bbee3842df0304a930039e2a431c2df02a430f365cb91636cdedaeb3ea9719f7cd2dcf5528276327249ac12bd3f5125866d3c552e4055f4e18b34e0f5f32e74dcb3ed493434da1f92c6a5793bfac3885b6ead7caa314c19379eb8f25f88c052f716e81aa2859ab1f17772eee409ab246a837d7496e436be85f389ad989fe47726c4ebfe83f5f9eac25a63969d9e9c8c5b8b5cb66e629f0952ff522ae4421777b8f2010b064b277814a3cfccd561ff19043d3dacd8f7e90c692ef77ea6e4a867e705c954bd4ab8ecd02280b37c9402a4ff65ea3a8dad5168b93675ed3a2d7dcad59d4c3f5357aabd646d59ced3d20d54576344ca541be49bf53bb7e0ff9e1d3be7ea95cfee334e460a6053f5a27fcc1d04782a6a0bac0f3c5974dfcacb9c3a0c3e9c663775e57e3ccb62f06b9a294edce70154195909b756bf5f5b7de7111db58969bd5bdfe9960c344160b3ef71663263db5a2be838fa0de8303fa797ab28a4d58f9d20e622c4d6dbd98d1e65b70dd8349e2b5f2d0318a75d7e3deada8ba2560b500181851e89e11c1c5187c46ef09ef1209e43a31bbb6d025658b416e94089bd146ee5ec7c601ba7467a7a548a8ed6bcbddc2432330a8b5ba1011774842c34089e7b2cf8aa6a27f05ef438010eaec69a9d732b54c8176b1438573f6b183fd71ce8c0a07b3f240eb539e081084ae21ec9c4deb4bbaece15aea494413023e1147d71a0bb4fa8edd96da4fbc352a89e953eee2c14cb2a7c81b0eb1e638b23410e12ee98d33d7cdac612246ab5892719dae1dcfa5ac7fc0319dc964f95249e36ca858864e250740b5575cbed615a6eec850df46fc1f0c83c94c9b4709fe3853ee1107bfc0ea0e422ddce970c150562dee03ebf62142c7bea0ab6faacf8cc22f107027b420a1f8c67f4ba5298db8cfefb2f8449a308871d8d3ea5875f6ac3acaeaffb6215300f3690ec7a370e8436a08bba945a87a7d11ef9aa11489690b33bb4b55b7d695c595e96621656f901882f22d2ae010672aeb10f167ac96979e4218c75b37540828e80072498e6ef1b234255f2f623b62903b6289ded8ca957226824fe098310ad42771b0bee778e4f07da3edf04858ab127e7654382ebb9dcb2a9d6d36973660c444e51d9c477198ca4826dc21cd95cb33ecf14fd20e09463d3b235523e25c2ba0b01888e8fb6201020231879bd92b5e15c7ea3ba8b213e240fa79f487f8bcb4fe92fef8253d793db0d77f2eb5fe88368d55d98f9b7d44ec6e5f532b8ef6560b63084c1f33e297358cbdee5fd26eabd883d586b907d6074d908f391ec903dd9c716d3e86850e85470f887211e28f66e53563f53a3de7ca435c9208d4950e7f7ae0a3cda526c5f957513ccee0b74b0f2a51ba1a95bbd1b3c540dae291c008d2fc6de2470b197ab0316bfba893ae46bdd4c47001c0c6ee8e5ed823f6eee2591f70974f67083a228cb69c55129836be6fb8b3e6d62838c0c17a50ef11886e5569ebe322db4a98455379758627021a2178b46ac20607970fbb66ed0f4d4b0e774b00e9258deb428b8974cb9fa0f7b6f14bce9aa7cfa02ec15726d316b9e3289ef2aa33048ed9ee5dbc8419ecc470b74ffc1bb2da46de492a38ba30a194446f7d93c56fe515c33cd71990ea2236073c39e5500270536c4d415b458428c5b43449842356b6b5958edc19abb2c63fe2acc06963471e400b78ee5afc7e9a9e3d57941be4762a1d8df018acc6e5c8a9363b3cb03ce718317484862908d163004fc33df80be718755ca2e9dd6e4c5881feace3c17a94da4624e16e6a128d198af6c125a8ec64cff5abae968741c884379c918a861372533f0aaba3df2c14beed61eb816a2b3adb44486a94f8583071150253d53fc4422d6a428df01f7a27a6876a5a07e8f5d8b55531dbab227ad3b7477b42515b6bf190b43d48568f4489e3fe46a122af9cf952140721cb877838fb883b843b3efe691de6fce8a37bf8f528e8b9e33d98d1085e8951cfdfa8523d3512cbc38f25a65120f645336037c38eedf2e2e46b99186a09740003b244e5a5d29a12fddf032259505d97738a32be56451cca0f087de84ca997e79412770f961498bac830531b9e54b23f8ceae4d211e2d98905cf5fdca6f35761aa23a0f8c0b4f7916592b9f811df1b49c53142c5b606f25e2c2c37c81e948c06e077ce660abd3ef718463f77b5ec9d691b0da338bcc7cdbe79a61de6b7f8f5a89a89394d911d003e1e131c0cda25b3aee1135d1a961da3d455a9c9d666b7d632996293ef35d70e4b9a1636ac1b707ff18dd9be95030ee75e9f579255aaa58b05be3c88dca2c3ba4022e5b7c53df8a1a662ecdd64d30724907f28a9d98c24ac04203d9a8eb9279b913bd854f3bbb6cab7f86f7a89ce7c498a76f585152a40a49c08e8ecdbab0fb714b8072d154477398964623f3530f79339f809034da166fa0c941fcbf39a107d18f6dff6efb99cfbc74355b408a2871260c99c0285cfbaec43b8e15c2e1c556d854b27532e57db68a8538b3e708dae725b7615d6999a2ed1aa36e35bd7720c63a7124cc0ce1ae1ffec21403299c880c1c4eff8bac770549afc9da832ed0d55494896e17d345e75fe5910e86d0363ba4f70516e57d26c686cab3ba41a08a739df4fb4de712850cd41da0dfc75bbcdacee84d21ea4044b4a43ac3d36a1dc650e6fbf4741dd166c36c467e3384b43d207b73ef99f3cf151b035cc6d1e6e3068c06284e31d6f001b63cf3a4f970d56f91a331d48c0151c210a3e59e2d0d69493051e0f890e423372cb41b18706d02fd6f1fb4283a5fde24134b39765fd048b7e42b4fcca864bd6b18f1b7e24aa0f3c2dbe3b954bf28f43c42fc6a80ffcf1d7e3ec223ca4a2f64522536c204dc68f343bed1476cee9959e20c0211ad1292bb65dd054934c2144073dd70e675a268ffdf99c2f5a0512dae769e91f0a1b1954b7d8cd8c7d5c31cc56e56413e38b88a335f77d7b066b7a290fa9bfc21f3f648ab369106be9dec3a57c4e5d31a2201361a641a9b3e30282f6fb2ecf446854bacf00a7af2fefd9434377ec5780cc644abe1ff9a0c011587588de418c7cb31f6b44a5c6bf93e4d8d02ef9730002b4a4fa0623b5c4006764689fab838264298ed9c859906e4184e3ea9824e663d47042722ff28eab5190859f84ad27fb14035576497d827ea48f69f4d72b80ff2abea8f707d5bee01673e82fa689d61dc0d2c36ed23d2dd0dbc0d566fcc81591814dfcef79f28fd9bfe28511399daa00d6843464c36dd28b01047ad1a720a23cf96acf1c8695faf88bb2d9738df3ebc0ea4d42df97795fc2dbb6ff7c59e30906720ba75c981efbf18ac11137652502ac0f164bef99bbef77b8419a78c29d0a917e378e16e5159ef3a72cc60f83b195907837708004217355e91108152b7b2008b0d9d2d2e1e5f3ab3a5057e804fae9938affbb51e0d723cf5678a1e921b37a41cc839372a0698d88622262abf1aec9b6ecdc817800347be212519e1d340652262049799710ee7b4bde894d8f6c3bb67b338640849bd8ef2fe5567b31878a69691391fcd7111bc09ba1a4f19188140803240e48a0571dfc74d61dc92019f0dbc66724cb99a0e90ac000103980f0690fc84ef4ef97a047198f02f7d414fef46314ae76d69460704e31137bf8c6a466ad1eaf7afbe77071cd7850612967e3b9899523fc38cad68df4655d413a86454cbe0253bbb34b2d15eda09e0232db14dcb872945b200ced845f105441b2f00fa4a0ba746d84e26ac63b69a238955d8f906be04032ae0f66c25855ee1e908e265a2620ba15024b9699cc3e5fe3fcf44d6be010e91e23d671e1db51967166de7e7fc0d1e8fcb1b9ce4c5a948596e56a1dfeacc986ac80ffe6cadcedc9fb975d58e86e1ca29f902990106b902943902ea5a2a66aeb9dc0a309d4b5c686de4c271c8077c1cc17b02e39c9cd2f257014829856dbc90f5b21fe1565990cd35663ffcb92473792189614ad2746c0dd28af3c1e17f666d0d4aa75304bdfac70e79053f992d92f1e6babf363771cfb9fe9ac857c61f9d93a5eb37d5b473788c9b7a84363469bb0bbb9647a8c84952aab2395e44b06ade0896823f87457805a73f8655afdd6cf7fd3d475138c1f3cb2ea70b727b2833232c82bee538b589e1e3c9cc1137390e5235cd68e4a6339b2b9299a9cccb47f3244c1af5d0fcb036e61e72ecf02e250cd9635b9a3b6d9fc2ee35a43709d4ed6d18b4ff73c7637504d1a6a1ccb9ef37a3a7be4dcdd462b8bd675c1936e8def9643d4d1eb333da9d67864f47b7e1acffbc3f82cd2c129924a20be5f71cd278abd9db13cf10c82511da690144d5f9937cae411398b14e859ca96eb51f98d496ae6abf3cabaef97dac277706e73d5b77590c3c64d6a2dc5363375b91ab71ef7bdd1204c3d40ee586f0dfb2bb6787ab92dae11bd308d5f131acf7b56cfdb086550f2514cfb2e8a6c1042c47f51a55553ac492d78275cc62a7eb440505556c53a265d334bb76353ff2a709fc929ccf3c112d0c3b6e8394d752372c29565990fecf5044b1f7512a1868d1c9f9d96ea6a1b008fe31ecddff7e8c46bf10edfe26b822bfe364b833a5123d54ca18d93c456694f99068a49322df6b38cf4bef2b4f7ad4684aa10f412c6dcb1c690d92590fa94fddaec244f06223aca5b9edd3e35f88fb94cbc7e0526ca16ddf9a241cff397648117d8ef1b027e58445d934d5150dcc3b7bce45da13ba8a47d15235137c21dd1a46bd7a754f034ee3480c817424cc78f15a35ca7aa5d44bc4c1d74a4eeb87c5d817364e92b9b0ed22edb85b10723f13856451168be35af54f6bd7675e030481fb60f91eb50206b91eb0d4d5ed77ccab195f47c7d216bdacce71b79449c548d56f3db57d64c2383bd547052c2ebb89d33f8eef1159a61d0616a5b107fc310e57085aca0369c5fe18af02ac45bf23c4038aba764371d8ee207403c1fb63c41b47fd7c869ce9a0bed560c9822427090d25e8d50c943896d41e9cc3794cb8c4270df9c5e4a21cbcf38ba11ccdd1e0fc6b4b073178c8188f4b0a62a26d98058edd5ceed3002445203f1ebf96ae2bc4683a5bafb558e6f965355287d8931cc4f4676ce81e5ca51ddb9471168d0f8e829f6fd3bdcd400131dfab1f7bae7d440c90e0c3fe6ae353d88d65dd2066d8d757b23f074ec1fee8d71444c5bba6cb9423314419934d17693fe0802c8326cc1d31d4b82b33bfe1b62a9cad9b43688ca31e85fbcf692405e8109d1801f3dc561236a2f24aca69e9efbcf01473d41d5df7fb5b03db65c902d295d8700cb8d2563e2f4d2a4e3ecbdf556caef3b55726eae02ecc518e5eaf49e9a693df4f6f49c2acfae3a2b5ba0d5d42a226b243484ca05d70ec2e0d3f7e719f848a9d146236d1979c45031cb926e482e4432c24de8af5dc81303f3769ea553e8fd0c63c605ffd6902ed8500ec642614e2f89f49db14aa43c2421967e948baadba6ca5bbbb3547d234e6b70a20a72e1d220f3e4f6c9d0d1fa4cfc5f34dbd4c65ef8f3d8dff91f23bb2663c8c8672e380f1dc862fac237efc237edf5f70dd1958c7fc3b59dfe7da155ff2d03719892c4fdcd4848454ade5f51752ecf9644d5be45e98839a148db8201cc7c1b9ee5e3c349ae0292855b16b1d196bdca81927e643fe2fbc165486edd158e8a0fa49c0815c56e191593304745d54eb3a6d0ba322453bf1f3c1113171ee9ada1c4e2805257812467e354f052ab5738765a9d22e3fb87ddf2d2f5e72258730d55262ada0b2a5cbaa92499e753917b66a44e61b865b0433d4a4fb74a698a0473d6a6ac07ec1f8e37175c377c955d43c689b2d9c47bf2b58a6af023dc0c32a85a70f6857e918cb9e1f1f23169c2d9afb3c62e0dd0a718cb2845b064b272cdc7ff50fc497028cdabe3b38c0cd04161b0a9914eb434af9dd47dca8f7b1f88434930b6fda4a4fae01dbe07bfdc2339f6a4bcb93de26d02b2d98a27cf67bd70a51d457afb9a9de79a7d26d43e537d8a84a433c61b6bbf60c65b8b11c553fe7f01efb6bf3bdbdc31d694c8d26a030b9257bedc224bbf612cd734e3d31b853d018674ee70a97dded4d224ceea0f626d0a2872c7d210e1d52df62d3096b7d157647a68992d0ed659f02094fc8e4584f3084c1a49dc3ca2b41d9c8f8b6ec9e907ee5a14b79dbe4edcfe3c5d7821aedbd5d0533adb20f55f6720ba3b6da62c85402da7929a06408b20c5714a94ce9b8315819b40ae7e13f871d53ba5d30e3e56e68ee085c25f670e49502f53b3e41ae523e095cb67a8f67b066320effb78922ec0d32c417ade05605337853f5cc69ac15d5834f27467340b8ea8cdecac73397613a7bb70e92b917ed0f97b29b0ceb3e7946d1cde100393e75c36a172e5f581e599170df44a25ed078543928186a5f399ec97ec04076b128583d47255ac4a3ca778e488f8a1b1492c3250cd22e6ed0e6762642b2aa3de8b2c96e2f0af5b8d0379c22b4806d9acfaed803a8128dc7b455fd95290db1ff85c3149cf2bd4d3e942125822439287a9be009c4f734bbbfdbefc10b3fdb66fc07b240b1b9c7d49043dc038bc3566e15a00e815b97db990b2c1455739efc4a0a18db6db289db8f29c46f972cd8e0ebfc6a39f41574a2e22c13e4adea0795e4ea79cf7b0b09093ec7893f6da2199b38207edc98bc36befe13fa73a99f1c7eb7044774b5e8e11665ec501d4dede628a6a6772f1b3a3fe1d32e35b8291725915115e3cac1b2ae2b93c113e036fb566f53345e3a0fa77d5face2b66df50937ad3fefe590d7699031c9e598443ae22508fa23dc98385062cfae5e628747c7370e0e5d69a157f2f4e844022c7e9791be5a2aecd91638b1d7fe503c9257d1098523da6b521dd9a734382b984a0350269013fcfbc79e6c3384d7b4e2b35d4127b549f444b47592205bc179dd2c924b80e4208d5a101494c56db2052e5e5c7dc42784de8138d36cd1df228e491da85cf194a1d385b8708fc49831840df80664619310cc5521163caad2479d63f287def5a5a2fd762e994a86309912d0bfa93ea0557e9027be7fff62339070a03572df0bdd610fc6d937baadc5e443fa2a04a5433012bae294ad28a3152de848342ac6aaf961d91f4a17ef56917646204a9978f03f44c06ebf32e7472fbf35e6fcc5f4d3d4f4299885545bc1cd6d31436c60fd885a02f4a76c9e934326050657aabf8b6752eb8c7c7f8f4be8d26e3d365354507c1b2e30c43327bf253689268adbb03f524a4cf3eac83bddf24914d770b9f4f45c2234254d08da90335e5ee66fe3c19fc369601f1577e147da9e4bbf7d8eabeb2640331275beb1d161761e81adaeee4e47b8144e624030a64d970506f168e15b6e3883340aab7a9e16770e12f87990a97edeba53cf959232f06f2831422ee09c43f894a61c7d54c9ab63803dd2bbb34e2aae9dc3e0cbb46e454e3e2b2f206b382746b91e454a6827fd87983c0ef052e8dcc750c21bfdd55e2068e14611fa6e1237e073b527eebcafcc137513c64bd4a39de78c6414ecc89d17cd8b43022146035b5f562cd2fd5526db4bb44ef3a50ca490d0776107cd0a94e3850cbc49de9a4c399cbe22718ea0dae6cf940776e3dbede03cb87dcc7ea96b2f84d92224b21e04ad52c36d70193dd6a98231d1cf1f42daabde3a3c7db9b2a53a5d76170ab7bd6e77c29009b6bae5b6b7ef9516f87d397b2bc82185cc3df3b9e307b911f6f7c1f44260c31a3f2c0e8069ee7d73c5cd3e9a0852a29506016b6fce6242b14a5c416e38bc07019ab7b657da21450b48d81a0f73de49ecaa9394ec1d205b4f5ebb83f94f4d9fb180c2618ce80f40ba65191a92f309e7a0281d7ffa1c1df20d52c1e0734f80856b79bd810fc4cc2fc224fa072ea2b6bba350a016a010dbe41180b16f05f4935781bee06f3e0f50817adc3d55d0a2c401a96f73ed844d860f4e8cb6e4a0d08ff9758238f8c05a82c5ce5ab15b728fa683ceb68cf9da9f2aa88733da5d1cebeb7b26bd79f9979eafe3219bbd03ada1c78b7154f6bb423c5418a81f0a1f24287bda0a16873da99a4b5960a4a3b86a3f41163452d809fd55da40de64cee37875cafdbaa4a84a18739f71b0b259dbce0ca6eada2a4e105d2c524068880da0cd7938849e5c4b3a2b39edf9130ab62cc377469f2ae41042282d405da0f8e346e6b0e29dea438d183d8798236da5b333f344c38995e8bac7d2384c759bc28c549bdaba57f22e346b2c491728c366a3fd7a9b280efd1bcfbde6996df4cc6c498281908051957c04c28033ff203b51f613665c7afae47663f5dcdfbd4919e65a24a360f354a518156a6fed79246e879b0bc2549229d19ba4a580ea658a615b29e19ed3a656791e234fef4c3d5d6e9c03318442809791783cadf0bed516b4e0f7ad2e219f1b2d9b3a783c133fe95440ddef7d7d2e6890612618832ba6ee0643f5dc7259b5290b35bbafc5e3f0028e87ab1198480d4739a74f3fc2b1f4395ca543c1b6961701ec91eaf280d14c6e55fe4bde2c32d8596849d0db89829c9a47c40b2c42e76e3f015e08de17967a6c12d087a1abd2ac6940b401e3f4e41c115379d94748f581583fea6b8aef1aa93c5d975342c5bc1cc02b22b06149e26cd1839075e8fc90228268167cec0916d817e611d7e71885ab2419a4cefef71dfee742d8e29047db2428071af1ef0ab5cf2da4de752a838cf0961e080448f7d1d8e7619b55db4fd2c6db8530f14d63ff0de491c321246aab445e33a655276ff089ad0996ae36d161c6e5a147f49ab363b4ee35478d3eaff4a4d39cd34554a9c328cf67eb3772e966b5154c1aa68c022154953a657948d36de35f8de18551341958a52ff188ad294f11b6537fd7f7bc554f72db8386d57f130a8714e1ad1a3b941923688dce9d8e1e42eb831fc542fc2188911156d9c22a15d8ffc7cebe3bd451d7ce7eaf6594f0bc2c4c93c34893b74d99033b21bddd22247e372293643093b9e29f6cda7ade18ac2edb1541ac95858c419db7fe94476a3955a53d545e97095fb90f4e902095bb7fd1dfebaac706e9b0686237e5ec65bb6b53d0cbc7c70d004fa26ac32b0430855f26be3e9ff3ca91bdffab7d9a5f2f1e0b87e24ccd9e05b05d54eb1b585901412a2266f69565e083de01270ebb9ea892db92cdb47d33140cb87436e0b5dfa64aa49d759ce6d561e67d9d407313e19fa737c6b42753b8a6eb154332ce3d72be43d45808084aa67c8f4704c48dd8c4f2daeabf0d147a2b626005d168a5f3f144065d9bc2e5af828523591961e755e5e42c4868e9d834dea86add689bbbfc6e9262ac8089105d7b6894d5ff121c2e04487a94aa26d79ce27ea48c4f71ce1f82ae61559f915d04e4237d05788251f511fcdc0c54241482e742e4a8f4f490cf44e11cc3d0a3024a95d4d8e3e03ffc57e34470c1ac100b2bd3e344ad52069a8a26a32f245c0fc8ae23272707e126d80a20bd44425e38b09f540a1c2e88bac1127a264be3695e49a770110b1e92813b9abf60b89b22b78a8e6245c6ca302d0e63174849a1689cd61ebd0fbde0c14a97fe9205a1d77860c1e1a69d366411ecf4ce09c464d21a8b808da610f890091ac3d0ffd17b82ea5d0bc857d9896630051c3d8a99cea4b2e19e5fbbcb10aef4a2df998db6608209160f3a0f8e1af65ba425476d436f8e119919072b13c86fcddad35017e4cc3cfd150eb2a512dae1d4576e5e2fbcc285e8f8f32724f3a050314b517f28d1d3e2eb6abb1fc5bfb3ce1d7ffb4dec77cc29129546a83c38f333a8ede6b1db183d1e6046a444344a0e59937e5087d61c50f3e53a0bc9087afa303dc0bd558cfe25084f83e27895181abb53b7cabd83ca25004bbe044b9af30296053267f138ae789ea3301de119e24052cb1bcee9588af50f0c131f5cae7ee6c1be51ed6f34d18aa6d27fa159ba008a57b2f031ae7af6aa1b35c1e9d7cd6b2621155ab87e5841c3eb162a4ca712248d6592b8a978d3cc6a7d9f6652354adede4d151071f678ed072b7f290cd95895e5f757d83eef5e6e2c622aad3abe9ba3e89fd1c2049f68cd7b2cb9b59b7285092dbb8e0b244c6498e8d03e67a2249bcdf6fd09fe6ac785c9d7474ce8c3547541d95f390e285bb1c408e0d3a6829fa5258a5d97b2a27385b5ecea63486d05b8de41a70b80c4d17952c958a4680f44466fb8b028c292737bbecc10c9b6d564da9e31ffc85a0f8430c0d48fb88e223604167ddb8239f0a2649c1ed05f1be977ac6e23a23d877df2b4cdba6930c6de0d41313cc2a8ce4b5f65b9f571d28f62ab9b7cf84fe3d47127677873e01f5a69f8a8d4bcc4d63e7befbf77b850cfc218b483da4555073183c52d6d4ab9789a8363d90256d08e09c0638a547388ec4909eb7183f4adc5b76b3df5467c3c0610820053959286e0a97d1234cec5616881dd4c7b0e64d34dfef64ee2ddfb705f4b101c41b5d80371d142b774c366d6774e6d4ea38ff830ffdbea6bc9073d6dbb09f1979767904d1720aaf8aac2d1c8d5039310a1dea5e3df168d9d7596af76c373eea72a7f99aadd9c50a21082fd8cbbedcc2b70b7f35252ef7fd6ecdc3090f4dd1bf88e8018db75eef130e1584de4020d109672cf17338c6612afe0374a97eb92866f7dee49038f25ac652f1920650eba1c6dbf24fa474376786cf807a36327e91d86e2d4d1170f8968a0b3438919ad98dd33cf2857e34d2846b4896deb5f3951a03dd2626afdcfe38c2992653601efb18c3c1fdbd1416cfe17b5b1b46bff413df65efc900f2ec50e4c7f0ca76e5198a22c0182be7e06289a2cc89247dec3b9f6bb6179d0b0109c2e799112678bda6f156f9e8da4fb55d083264dfb57355783b852acdca641d875e0aedbd7739fe8aae7613b9e9926fafdb3a21ac439eb505bfd5d85a6e4c5446c02180fafe6fde90ec0266426685df7a350303f82a9bab1e4b342f4b1886cbf51be111c180c4db38fff687e8f444e73ddc440bb1b976bbbe3bffb71a56c54847d00210abfe817d514e1703f2da2c0da9093ad5fa063678c0789a6a8e78e0022b9ef988ca6266edad65131690e7e42730b3d5ba26858fe5abc091f4ad096a6ef58a0dd6417dc000f332567e7f20ab5f335beb741aa4a99fad780fb5a3a5ee84ba7c6eaa22c515badffcd0f468085833644a8510c0482808e9055b3dfd03e583b99e15ff2e3310e2b2689cba3eb841258740e1ac8d91aba580b97cb4a6799a7c6e3b835b6b9d1440f4eedbdd6e9a538948de2795335b730d4a62c27235a2f331deb6f8b66dd413554504c6341f0c5d23cc7eeb24c6755be2226884d4b89c3a77fbd5a807bc8bd91d34eb2f8907b74d0e3263ccfe02cb7fbafaea6e74dd1f70053d7bb8f1b5f0b649e38c9c3d9220dd0c75757c12baf2a9777f8eed42fd16d714bd72fd299d420fc475941f6bcc867db2cff3fd7f0adb49cc2ba499e228b7a2581c55a76fae9b8fc185386187ab60a33f079fb1a632b72a4004a9ca68f474f82b555f4c87f4c90b725d5f017162547c251743f55dec7c5918a9be69d3c7f01c5feec5127e0b141fe7128eafe36c8b1f692ff345192cdef898512e1f2ccd2c4de8f6339ecf19f1b0455e7bd90239938990770cc8ee244ba3ccbf8deb3f4094423fd438169711f00c90440c7a055357a306dd5b422878dbbedb0c490f08d23f3bd5ea68bc04c4dea10d8515fb78de87ed0b1e13ffebe0bfb6c426520151a6117422f504c77b544d364b5720bdc0452e07e2035aa69330656d6362fe18055fba0b181ce95bd25dae41d17f8a197b3ac5ab6fc37a9dd6c5c5402318ae0b6f16efa511e55ff8739b3c684c6d40a95b3b74a6021999b2dc13957f6eb4049a681fbad351347cf5080ce96375544c06cbabce0af5c62f1cad270ffb44822ce48e9913de6917fb0df8ee204f91d47cf9b25d2e084579299e4072ba6486c238d02e2b2dbffd63c52512d0750d93434eab59e7a8fa1437fd8214e958f215d0dc520578ca392c2e59d4ed1bef0cc512e8bd15020891ea4ea86b8f626fdea28be8b5d94010f156cef64567797fc73b81167eaee5f3e754ab9fbd4e1f186a7e298303f2950be38feae5579f80b4367cfedcda177ba526bb0bd73e7c16a9ae7235c3ddd3d161f6ab5a5610424cb199afc982bbf829180a629d41f81d52c24a1ade230022138afb9d6fca2657fb20e13cc1f5129c0f7e2d80c1cffe849b4c22761a40f44932bacbaafeb53966b3405bac60db62478bae2652d21414b40701c44a094992bf6632388671dbc277966bc93287b6537c9363c489b7b95b1770808ab69dd5d0ef5b25df502beae8c7fd65457634c20227107de046128221031a42b8f6f44a392d679bf8b60b1e0a8e7f7a1fff79f7b258e8dbebec6a1ca7377abe708fe6a7371aa120e4f61dbe9e11776e18b7cdf3f322fa5d87eff9cc9eea9e90ef63e7507559eaf75c51f08910c9b0f458c5eb2e9e9bb593003189391a19939825755187f3d46518cd987370ea96264a0905e4aa1356cff708dd37411a04404c2c4f252ec15997e90be322da8abf93092eeb0010d9bdd835fcc6fbc148addbd5952f0d8e81d6ccfd31737ccd9cdfbbb05ca3e300ee2e199621d0e91c934298a5387f78d5115db124316203d6a821bbcea037ed94c883023c8c54f6ad044f297fdd1481562786b072b3560f0a7cb993bb7155d2a70128a70d1702a19cc6556a93549d18b29c8f723ee591972acaf20f918bc98bc5ec309be610f4521bc3456f2d4ee60f8366c11d0132a8ade6df9a97fda04688efc5bfa08ffea419107689971a26d8f4fdb61f97099129933e3aff7c91bb478dd16548fbb5df2dd2d179c60ce12eecff5913e79c9517f0069d292857df2259ff6eb76749d89ba81682e48af4e596a00315bed916553f8b073597053350a1b1292415148d36d9b439b2f89c1b0d5451a35a9468420e6dbf3e49b5be1c1c5a7bf6512de65fb5415970bf76a82633466f10761da9298bb0b27d50845bd938ce4f7d6b22f4f8d0cc6fa2779ea17df6825e242584a473a992f5630af8d6254858ab8cf7bfaeb23cf332ae1c1999f3e96f7d5aa85ad25a8c2c2865d467dda2986380cbbfe65878c1556bcad5ea5c31e8381a89470062a3acbc82801b91880de3b2f9026fc3236f32959e0162254c2b68dfe9f44828949a91052942f8f5678de7760f98472182d34e04bda6016cb583c3eaa815f06993f4af58163d21de1cb257ad76b7f4b9fa7d337c448f775ad49b6c033f55a3407a1aa3359492af99e3d23aae4bf1ac63e887b6ce31700576fccdf8ee1842794ab86e4d2f2a515581d173e36ace62eb33d8cd21842c993cc36d21242979fc7e6d57fa5afeb28f4a965f59377d017763358d31ecd32d9d82d06ecd1e4193c58d029f612c045ffcf5a8ae7be5ec61c8780ab1f9dbc22b7d429169c0bb42132146417d8772d5f4ae522454adfe10736c77c8c14b037b09639aeb94d6ce546871d3f48afa7584288aabba77bda19001381f6d3f975573f6e1fd5a0f76ab44b93f02827e9d5ceb29b2275d8f91624d159dc85980104b73c9460a6b23d6cd8c059d590e8d698c33f6297667ecd4db585c53d1bda0cc0371dfc2fa9ef17ae4651d21295859d568a0783fc9f9491fdae48d9b26f672d0212ed47d83d5343c9dab444c7571abc907275c36d4d43b8e77304dd4c5a06bd3b71d46698b03c0a942039d5fbeace7a4aed33e8405cbb0c2952f67e70dee309a401d1b54bdc0b2eee6cd5244cb3977325591fa22ec1e255c0f971db3e02985c221adc0280e0a3891607471c240a42f7b624272ac90706b50ef0c863a2fdbf8e34fe06dcff59f2500619efe3cd492dc0abfec13d89b223872d2b869adaa26e7f63c205cb5d7adc4e712e24ec87d968a87f6817aea419eb4ca8a02b2f7e4893c0fc9a60f73f01cd639c548cf9f211e92de69736d7742c8636e713ce39fe3bd59f42ec95bf8d5f2c7f8ddac304243fd063a7e48a860b1aa90a98d873e9bf96a3ff8c41f3e933843b1f90266c5d30507f48e12a7400d984163a039a85f52400e3494a82e66bb96352a0b8a2483817208e56a0e9c2e7ebbbffdd5334bee39f0b544373f01629d8ad6356dabb3f669c7c3a3077e7023496d1285d2e164837f113e278e3f27fe405a8339598e82513b276f80acb6ea0cb367a2b3071a84b06504f6a10b8115a4c24b4ab7a02ed878d586ff30590cf1fdaaf75593130c26e1cfd69f005094d1a3619fa0ecf94797a1113168fb0bf7010f03f0de99511aafcd716ca567d9c34a7bc030c379ae924982726b7960e169eae95f1b499f30a5edecc3ebbae17c2fae467c017e1d1e26ea6df2542e9798e63053e32d14164a204ca184192d16112ebb7eb78708fc0c7291ff113a5ca8e6edabd94268c9a3f6172333d58dfea42b9003ec5be80155793f6eca7d9104635a9824cbbc44f6b89d5761ca93e8cd1edda94947e64d7e8f1701e633bfd009b789a5e8fca64bcb26314d961f8c15a21762b1961697f4d8d457b7ec555c90c314293b9244798c961d183c993531ee99a6c6680b8ffa0f9c8665284d441fabcb5a94a851929473ed0825cb575f5cfd86522b26680eedbf303e387f959c81ea4e96b239409e2c1dbe8e09597193b6a71c3dd2a0766278f66c11e81f91d3664fb64589f664d7d671eba6d0563ba55dcc3de813aec3ecff40ba67c806d974b0eddff257a87c2a18d6a5baf2839f48838d62ca0f224f5eacd6195d68784eadebf8fc42cdd881ce17b6d5befa2a540858d77c353098ff6c4af24039a2e8d6ec31633ddaebddf925f6c795eb9474c4202ddfb9c5fedcbd4d0fc191ecf2f779982d53f642393db6987704ff7f3a245dbf7ac54f9a3d4f3d6f3f674bb225499c2bded6ee74727a530ab7024acca6bcacb5240c0b3e2c176111d601df89bb4decb05d8912ad18849e28373995e55e2857c714ec021a637e8dd2ed76941d7031b9e2dc42e06e8323a3198277ac1eee42039c4df40e5d4e611e105bce721af0ef84af41a572c33039fcf41f7869637cb7832d6755cc68901b79b40ca3848b4f10bdfe716a83aeb141164d89f2a6fb39f0cab787a4790b83e0879a03cfc90b92e08c5289f617620d29fc24fab3d86ace68f964198e4827abb6bf965726b3595fcbfd582c2146994664d4d3b28915bf3ef8a22c214414327173aaa7ccd141d1fedf92c67fe0f73a0db4564e08052570120fac45b03b179dc1540b66d03b136a569c41945c0c9b148182c6da4abb9f34997ecf66ca19a513d30a12d0669bcb0794e81a6c6b0ef14fa738448053eaf02da3727f1b3fa1fbb362ebaeec7d7ff1b55c7938be36ae078c3bb18d9b976868a6087917659aeab5d15dceba8b58bce2190fc68e634166f1f4e2184573421c9cb7e6573930d2e5792b1d57db8ab4ea4e2418dbb23464ab65d6381dab073cae7302557a9ab2daa18b8a1775c2eeef509e757dfc0a873670aa409249c9a0873b5c94ad30da3880c5cdfcdc1dcce14189f6f05ebb50ef7bd9f0e8200dafca56508d2d461c28c125d49ad8e440d27aa05ac5e93eba973de748c04fa45d7b60780e1729179b6ee09fcc211081d4289be1fdacf2a18a83364809da30cc7b1e998d8d4d8857ff1a8164ba6c98fe3a8ba0f70867b55bc80327a8848bf43b11637f2becd50919ea1bd75c350180e2f1d72a30694d0e23323ae8eeef85b532d2ea7d0313244765196cc6cdc31420d762ea38f2700936fd7cf1510e3d384af1cd1cdee577727302649688541462d34dd5d5a89a7f609fdddde030040d55b187832ac191dc25ef58042fb45465dbce4f461bcc8046169675058d66243645f15abd1f35fc31672d6280f59281976d4d63bd43ff026a0e9570df083754ac37e98617115f48c9319872d45ea50d4ad4e90018b351d395b2cfae2deb7cad51dcba29ddb1b9aa4e670bb902b39736e742230a64ae124024e49d96533af95f902910107b9028c39dcc1b6b8d48c72d39fe3e6158736f4c6717a62a21b1817b8a890051d65aa30d4da8f86b4f52748fc15f2a4cf86fb259cd7d5382f65b784b3afcfe33183a8696c09d198b9c859b78894c5a6888e95d7347af2109d40ff89e55863084d1b17ccf5d2a6cfc395a240a678965cd6a0f3f5da0491b8eafc0248f4ce26a829edaec15885fa00c5f0a664524ecfe36b7fe99c375aedc27eb8a99c975e46dab95314f5a7ba4793357970ea39f33db849370df4e9291c188ab4fb3c329ee7f686a098fd669e490766275bac4e5911dc3fedf320c449d1b4675ab4e27afcfc1b0cb9417cd4c5559c4fa2e87b7f4c4e5c45438eeaeb4c4249a65fcd59ce51ea2c5bded7c51369ab1c9cf61ee562f310f03375120ee6b277459cc1bcb6e4c7a9db61f2b3389116787a7325429aeee07bad129482d1da6e86448e1c0ecbd08fa6c8d769902aac6a8ffa92b038d435338b193c5acb29a7f0a43ba92ad52d964d201e1c962e30c8987821be85b12dc95bdadd5b6504c1afde8eb6050f22246f6e2fe5671738952f71697d659177a7cc19f957db0e4a03fd901148e54259bee9d9defca73f8b60edff1d285d6730d3f52ab18a7e6d2d5e59ea1b9f148ad1f2ae8e830450742dbb72c0ab39b97206df270a6d0a26d7fc357b78d70a71b99c43924ba652b245ddc61b18a05cd40daaa117df75635b1d342921408d8d5f47a842287f694f7dbb30e92b02d52fd8a68fcdd1a168f1ee22292270e65d263e4eb09a0eda9ced33f97ee53d425231ec84bee76459674efeef1d50bc43f610991f2a4d9da0fe5f28ced54b77910c63852b1093ceee67d96e714de3208ceed263195c249f076f49da92bcfc048d506f9daba60ef6ba4d9109b183d9c7b8ce85ba35929210e6134947561062c7d485bff0ac1f6f457748a0f91eb50207b91eb07ddf74a93ea372300064bc49bbe055930c402a196eb9dae7bd976de3ba513a620a9828d42364ada547afb333f3ea2ce09b11c723f32c5a3645ce96bf783afa6690d1c0ee687eb02dd6935ca5615762ab53210700ae684bd5e333f46f3528b84a7f9507f4fffe5d9b2f4f4d5f5c54605cb6d914bfa32a392a358644b5e3be2e2791e2424526a219841edb7bcd3ec7e7447ac5902ed15e32fa4dc7d9cdec4cfe369f8abf5c27f8965c3666e75b4e858d25c350422aee3a137401c8bf8bf60ea641af415dee0eb6c013b3ec52d658ed6e6b2cd95ecd93df53db12cd8534b0d40ad220c1b5cd37f31754e22fe7186c8f503be526b356e69c831cd93279073d6748160dd1b2fc7439aa5f161d920a4d03b83222ce2a9a4637a63f3634830bd82bd3fd5d8c62d6935c055fb1b1a0eb98d6c20d55c2cf7c355368b3f4052fdaf2a36b8838ba3ab3dd4e532ed1ac7ac47ad34725abc5c43a0ecd3a901a4f7ac4f5f3bf0d51b92a39aa4cafa852c61324a1cfbef9ee5973fb0be0bd6eda5f90306fb7caaf8e8c086d2f02598546e13291994fe8d789cbd80f30f891d9366f3d2be4c32be7532507162af146c820e8bdeb332d8374523127c98612dce6aac6861b795530b3ce31a48d0fbad9a24808ba2f8b5e6e118084cf7ecb447a1531b2edfb5996df2663fc99cc42d9d56dae184643e5998ebe6bc0593455722cde570c398e22c3512176b7201895116737684b55c90a463b36af13ae2616df9e8c5f97b820583accb53b7071629e00992fce3cb43b2cc6637776820ea692d8813661575745de69795486286d68f4e029a4d914ddfdc239befb6d6a57d492f817619244158c0410aae90a3e65a292189069f1af63a941466efdaca99bedca4d6ad19087434d625f08b5cc35da946247c5e7cc4035d23130ef68a00e20fcd071b504068feed30582310518ab5355bb2ed3cc2e7c02f454afd847ee10270eae4d79be968729619ff3531ebc8f3d9fef0a458743177f912a62a5588519bdd9493a0be1030071768d0ba0263e9347351d32fe6a04411681fe68b4941ef844e4c58f329d7c74400e6ac4907270cdd2aa581160353f802a89f5ae8ce8d450dc5af744f6c8673c1a746e9b78e656896220bced2c2e87463662fb043f0dbe6a391629fc518d00469cd780fa904bce5dd55f82d2ae4e04d13d8b814c2dc7969f67979916f66c06a9e51f375d39d88e0c70735b4de133ff0e9de8eb672bd97868a5298f254e3c399be54e55f57fd0f32ab2b8bc3ddd24475e23ab1f41b958b33c2cecaf9fc1526c9032c0b08d53d0a29f898e4fc2052c5d65ecb680aa8892444079bc149381a6d57c12999e82cc438059d21ea77fcd39f657cdfe07185667b12db5d92decbd7bedf75a469550212d662eaeeff2c487359a24374a5a8a5e5db27041c5c2f8eebacde299cf0444e8cb9d4c30606b6101f0518f44204445a8622937f0d0c744c6dc1e3c52320d3fd88cfbb929db579d155c472725e3be107e2a2e4eb5ebbc191329f4ac892dee12fc2eadd02ddc32eafa841efbddfd896b794302d5282d5d213d1d153c16775e94d2a8c0b897d898e49c409ba252f2500aa0d2158e89af590849d0ed9b9bfbc5b66b8de0677a0d5af83c955169d7bec4c356d4a5755a26e2fb479a5fdc540bb24f0a1d7fe8949a8a84711de6181826c26e24f60659eb929f9b331ea2ea344994165a7987bf7a923625f50586a32053fe5c578ce056746c8a60c9040ac89a413ccddcd94c7d03342bafb3eed8bf6a29f95997d80dc79e2531b2a2b06d7150318c701d58848b9cc880f950f7fe43af7a809d0e249aa0df8aeace3f44b9fb608c24a014c32df6ad9198184f5b7a7ed08e85d541f5e039377654f0b63c70c3a945facbc36a4a90be3ea338402056c691c99cbcc9ea8ab8099050260a9a0e522889df826239a7fa86fdbaecf2f3a938423ef212c91878adac6362cf9e9fd3cc89609e297b94bd5a6f5bafead07a463b52b285f6edfce429a59c78f1029d1c6cf9fe3c2ae807621ce1c9e4eedf6252fcaf78ca654b0269bb6d7c7a76d8e2e3f92ccfcec2ea2d52e41474c5e9965187f3184e9198c7e6ff4121c7b1dda38c3e41f7195a084e423930285aa14d8b1283ccd235cae5b9049b2b09a963c55d5d2c3145b13aa2eb3cfc87eebb1dda34e0a64762d54402d51f36da0f9f85e9d2b969383400d9cb8b33202e490ce6a087ec2f1fdf1ce3b019caac5f2d4e512579aee33bc9968347274421bf8667bdeb99ca5dcba1e6020ce085a7d8fa688cb6ae96fd13ad28f55c6bbea6ef06769930ff88293056c3f7fb4e6cb69535836d4027a03b527615040d934047279a0e9b949a245228001fc52d60d5bf68877f26c3271dc4465248257cd04b67302e53b03c501baad04d75eba79ef7a7334decb89aff45f1fd6be22df981e8164bfdf80ee34e948525af41dcbe92ad674a3b68a324f086ea0be908000cd3e5083f4b5170b74023681ba3392929b3f6f9d87f38c13c573cedb8cff09cd3e447e3d06a1ed8dc65d311572daee9ea668ca0e8de6a9768d794b4f239cae47e0e2bedb9e6a2d067bfcd7e17ef463986f8d35e3e6f780a4106a4e416ecdc04ba633c76afeaa04a5c4febbcd0bba757925a6dd2d08c5ef35370adce120b54bc6a2b2c2f4bef73752dca7560ba969b53b451a6792f1b9244aabea807b431103ee116b1742b315dfd31ab86c241f1e980a56696c541784459941aad9a66d85f5d54b57ba09c60827b9dd32178ae1a660ba783e8cb14f03acddeb49900e6bcead13b37db051b6c675027bdd9179e5eb3423c83c9b2eaf70910c4878f85a611ea9071f9d274969f2fc20d6d2d7f48b68b0b19e367584ff159a5bdea071d21f36e544424aef83044b52804a528424ef44d77e37eccacb54ce68580afd20783e0f31c31ccb0d17dcc76cb504052e5ad9ed176895b90fd425f12074d2d6e59297273c0447dee6ef215528979540e5e0ebf51e266bf369dc46dedb51940cf95830b57cd0f7318a1baf091498232fe76b6d73a9ffd690ae189218b005ae0e362a4dd0e9cdb2e34ab7d55556618a62265feb35c34b0c09bdb44b16a6c207c2ce79dc3d72c9859afad3d5f1fa998190bf6004d9e0748d8817b3dd95a4da4eb4c0f420819b1fefd75571ed354e8deb4232fe0e7692f44ea0ea517489be3baa1fc19cec0c57d6e931b8b0665fd195d6e405ac3584e833541495cb3b66c646102591ef8f2558f0a6921bbad2bd71580d8d4efb69fe7ab53008b2adee2331de65a70efa8080b71cbae861a78cdcdac6d91edcdb7f741efa92398d28f9649a0fba25592bc0cf53249b5c9a265efca4b599930068a71617fd2b8d3ae646a7c0d043c8464e62799dd548b35fa5c196860a237eefa2756b31d3dfece1676ebe2ddae1d8e49ea9b76ee5d73fdbe519ed96be27176aa85ec169790d9e3f282831f9a6608c015a1e5cd9963c52d5f8fe84cf40b464da9dc9e14d8b190db8b0795084008ffddb0e7cbd9a7cfd4a067d72a5adce9f9eb677a5fcadffbf1b7a3bcf88e23c363bd6c7c39671f0e794d9f812b4a5f04728a579326e6db137f8496ea6d57c960cee45b0f60ce00a3e00b02f95e081704f88052e0a9aa978c30ea8d707e12869af29caa405f90ad43a87769ff92b055613a4e4a0bfcc3df1b004f9024ac170565e60e1f82d77d8661bfbc9e964c165f6fbf30947998bb6d1a3c049360716480315266741235300f3334a07b98a39462bb77785ac1a6b4f38a23a803b84d4a0401f9dd40b10340e3c20146441f7627aad0208bf98e1751077600a486220b920f1cca1268f1dbf5534daab4d7c607bfb9eaf7fffabdcbae1a6f60ba5a72d7d668c9568025832c42f1b7d50215fc20fd584a8c36d8858721e075599949c1754ada17f5e2d0bb5625bd634428f5bf88b04c4d5f81f86fb21ab1e67c77b6735842374191c7d52a8d523ca98040b12e18fba18b2724817cea235d19b539acf7fd2be916b60289a96f51e74042aaf671c72326d832ede57e510a1678eed436782a8836621d870a780b51f140d83796bae31e6f2c0e534c697ffac16d4da280a5d60358083f63ab5bc039426494eba111193bf320f96f93800d314bc1479ed2d4b7c03a9d4852a8a3eb45859cd835f30fdf74fcb95e06a9e3d0addbacd29add53a495d50714d645bd824c0c630d5f1ba7b8ba36629905fd6bc4f5928e79a221fd5bccd9982c8d5cdd4a26cfd792bed5e8f220b483a730dc3b97184e19b81b42dd23ae7cdf7d314e5fb3b03808d7dd1a6be206a3545555ac0394eb94c32cb5e8aa4424a21f7afa78e2d0b8db0bee215537faeb3f742361eea5164d8101fa7a18afd9434788ef36f05c0a3b06e71209c6ce69287a301060fb12c279bfd60f619f9576428dcb0f3232da42937dcff935b6961b04b6054083d769b36b390bfc987f7f55210784f1b2fa3b2ce9d9917f7b536ace76be959aa994806399827a31d3fa0a0048b9e6db623f0c25194a15bb3f22d5f1b75dc18c3758ee8cbf740be2b2450a1326dd16281f8dbd433ea7d357da1fb2ea008064e8bf5cf0f3c266b45e41ce6285709ad7f1657baaebe80698c35aba044a857bb273facbf0eff47a77d17be64505f35c2a21dd046cc30c47835ca7873496e046edb78098b25ba34886b963f696aee07012eb3ba5b6a4f210a4561a54295dd8ad40b9876bad3ad278064b7d9d280bc4c358b599a1e7256f324721501bc99b8bef8d0b96fc8302ab2a30c5e355f1cb2e46e7d0ebdb0c8d0f7e08cf072d46710bdf0ffe3b1ee62767f3c656d136c87a29623211f9e04283732321fabaa666a5053c45130a17530c7a7d0f001c4a8a4d829b08a089b8098432c9859cbab9677fc0a0b856ee7caae884ba56548ede90f2fa3a8dfdc3bcbf701952792e3e1fef20f15241ad582a7a1f86dda2fc942b48b7734fa7f2c93d1ebaf1231ce5b8cce3487c1179fe5dddec49259b9f284ab228832776afbd422b1617bcd19b1485f19811b80e3ee69e4ac0df07475b041baf9e125a2017dca7f7e4e9badc2a168c59f9a5e43ae701ddda2fa9b207df13054527d7be414c072231637c17eb2eed7c5c1bd52be97f05bc08092b8832a2450d7460b394d4fae1f0b600bead2eebf51b67e4db89494fbf5a59ae6cf0f6b671d9612923c196e9a3a996ba77755b9bf6a9bc95a3b9db55207eae02228f404ecf0916f1ff0fa3d5cd9a68e56e78c6f0fef7b78f635f3a7bd764e5e850404fdb09ac84b4c444085a1d9774a39dd8f1b828c4178ce766ecd6c7de77c5f19ed7f44788d7b9c3849f06c5353011e28f5a539623f58a1e59dddf0a22c77c723cd863ee16ec7b6b80db92cb64a446fa437878c42afec7710b9834352f846b83c54ad4fcd0fe74cbc9861c504c2acddf464cc3b524c178d8312976b48397ef3d2beec450a16e78a0c2ab9fe7cf8e6d3f89b0fc92bdb440dd7a5c90e704d014408afe4284419b698bfd23e5c09751b29b931d92b3d4ccf411e231105dc951708145cf3a6883c6ce2ff9492cae55a88a0afda424f018e7f96f630fd338b35851e63f24318ff4ae9c5f823413d8a62635e8db5af8562d2025d9c20c1901335ef7e293b38daf7a6a65e97eba94dee56afeb89e41650f0ca65abbdca458a28454388029abef0e497a515a1edb2158543cbc18b05e53e74ddacacdfd11efa2126f57a443ac40edd7f0d4320c620ce71d16a4bdd5e723a4adebbb85974810b11169348d3b76145a09901ae7c8d166e8f3d469a0113c1d8b4ca60181f51d0302dbf41dd1e7294cf89e0712e77cf99aaff8480a576f85ee3d0867c1e166493aeae79374fb5e42827113a72ab6c4823364a86c2c8aaf73c65bb9390a8361a8877355ff92237a3b05a2b289b1e99e0d5277464c4913d877a95758dd05997e08ae6914ea4f1534e8354e7ecba3223a9f8baec420cce7ab08e73aa31598ed2ef75eebe2d1aaf769fef9ee4604334751c08f71cbfe8423fea1ef46376e21de04ae90a4fc090bc49291db83b1d68fc731cf487862dbd288a1fbe0abaf6925e7985788293a8b0399df2f5ab46128f2ab5fe9cc17139e3b7bf80d40993413d2e2308ac4e358976707ebd06c6261b3059550a23596840c1ef40ecdf93af37a6ad081d43e31a7e87a23af45c7cde773d1a9489a3ccfa286345770afc37ddbb1e9b3f57bb8305644f26915848bf4df8351346f0a71d3f82263dbbb7c80d9d460b10774d2ec59d486524449ffda8069580362babfb92f20d17faf6a732f2167367dbac0b469a4f358e8d941491eb42cdafa873edd2e6a7f03504a987d3575a9687db3bf122349aa8931e512938b28372642f844ffdcbc432488cbab310a5e0e96a470bfb6d46ac43d974fec553db2d01d25df07a9ca35fddf8c952acb7122163dad8d29dfb2a5e072d7cf8fec0827842f55e38666baffa62188b5b618c28862bf6ef6d56fbd54329491b474b98d38ad6e205dfed9de575b21fe12691c8ba557ca4b9d1afcc0b0091043df7fa1370451e2696e024b9ed0f3b081370e9c661704acbc4f69151a93522f4dc61b2c2f02bd2e5958b11f384b9c0ea43194a94f2a583d292cee3097b4b8606de69bee7ff82f9ecf7aebba3e831a9f4817529eac6384f0136d70babf44f6eeaa0200ca4198c37f1df42815043a2e2845ef10bde4fbf6cd3421cc7321a9909762f634480dd9eb62954462b0d668ae91cd8d76df864346e937741a7f169de55f25af79fa8032b3556adcb9aa2677df76fbcc7176a22060abe1bf87d82c78787f28a145ba4b78ec258a680943fc3b1edf2fd015bcedad1038d8a794426ef20b39121620f52482ef5da4bffa3d8984c5c0d8b7fc70dd89d317ff744264edf1b16515b3dea0474853cab3fee4f402248e3d0a033a21fac5823a0883eee9ea2693819ee718a078506676e13ce1e8bf71563681d496b9f2008e9c1565fc5557469aeb4edeb8c70c055540924dda099d483b4963ed6943a0b564d4cf71cbe79227b7c5a55678e7756bb429e9d341083637b28344b857997ee51548ce0ebac6184a6e4149ac574b82cf46637b79126eb0fb64664ee107184d2737a85517ee3495337032e7670e1653bd8d1cdb8d797c391c6b9c3182d37464596a15bcc49c49a1d1427ce3223cf0632b6cc3ef2966d714965ab1a68914659cdb7f9eae711e6781bcd42ff974387ce70e49c035f5512529e2abb463464d69212bd3420a731cf091bdeb5c52aa20cc8716d4ab13091c692fd6ed2137112da8eb1c09e6348bf526ddf2f37c65fbeac9c969f07a4c87bf1f6d07d6d65ef1914a3ad3cc27caa0f27111c03d16fd87ed0107c5a16e946865eb848e6294a4b6bb09aabc735692d91498418e16f34776f99ba8518741043089a54ba2091c5ff9f07e6860590f46196211bf712cf09d986999a6cd8f17c663678b22fa4b7ec906a3614ee9a4d0eeb37eae9aabbb6fb58c0950dad5201748f829cc00c198cdfcaa068976411182248d70d29215c401074d4b28cdece30d4f066ff422e86b88515e964de6461cd37a4868bd35c60cc74b425b869006754a0853a5447370fab06cbb146f80fc87cbf7d81384ab3b90ef8584f8d6b649ecc542c0443b4cacba5d2f06bcaeac85fe3e9d9c4cd9ad566485296a4849095085dd3e1b0e2cc098ca1389ad2a0d4b0845d659fd65a9947ad839d87553120352069f8e23502022f399d350dae9ae2406e066d70def46ecdf0507775075ccc84540fe5be9a1832e9a6944e32ae6d0711ac6cfbd33d44fdbcd5026149c8727698bbc0c10302e5495a1041a650c11e8be3c5ecd54812ea37a2424097f8c286e03c8d1b6e881ff7140262f0134e18161ddd5fb143a4852050903f5cafe91c5547a7e67868f100a74af1fbd4a845d190aed6892adc1e6a2996a34de5ce3f4259c96cb8bdfd344ba4fafd20603063f48ae54478a5f0724c7174787431b82da27cee285fcff9312700049521375b5b6e4cd1388063770020a9166019f8ade7aefee3b91290dbb4edb58d538608ce9de96bae3c61813a94de1ea61738e6b3b7af9a7a4abf78d05605cef6b2df8b6b427d1869bcd6f1de91eaab0bc2f16cca2376a06f11532daaeef09d7f8994b998d5dc7d536e708def7e429843e0cd36ffb43b51281e4b0f8a593e87289e2241d867d13a3de44e0ac3a12b23f7027f27dc9f43535657d673be087b843ef27cbbe48f60732a79afe3e1a6094d940f58cd6d6bf371db061deedfaa0299ad7743bf1ecb37fca30b5d2de50d988bb4d19dcea015664e7124cf20ea6a010d38e6ba0e141997b4c23fa3d94f46d07c6ed8744e9953fc9477f2edfce832943e83e97e9ccfd2077cbfad6320371bba8907825d9a283524301ce903c0b09354a8e0162df5f8f4157f0f410e34f6d5cd252b181e6d6e97441564ae84e786143fb2ec747833f4af3a8322fdb4ccec712befd628886be42947aa3cdcf23d73434d9d21c9d174a78874b5abe820cd4302f2fbd78445dbe454a2c2498ea9e8530a766dee22b746093cf03205e3501c130a0b902a81f727e6cd36e976b06c687adbb858fec991ad2a3915fd1f2d1b5a19c0a15f28cc334d02fffa4139bfea514f25c89b001fd7f0a410a6337fbf68325f5a4cb75a98a3c6b100a3ee45d9f134cb5eeec401640b87f53d739749196ece3eb2c441b13aff031a6e71e4cbcbc651091772081a1929db1ada35cc2e6f328a708870248893941e910a8e3342b4379e3d6fd7460edc74f24ed62735b4b8bd77cb8596be9264871b5fb1e25fa89b62ef2542e6971942754efc37cd7f904ce1135a9d4256ab8bd20e73fd347d973b58514f041231774decea4ada60b40abcaa4b55dca5f282975c8c6c85183e5644b6f5ac6666aa1fdfd1a668b23cae69db1e0f6b33478e3804fe4047652fe5c4beef7c6900b3760507790406964a28dab928e81772925ec1975b822522c49936494a1a55309fca75dc07f9ca5a7f4d0e0190ce0b1be6d113a547ef241e092f02e052ac490b8b74379223377771e537ea2bb3fc3ccacbe8d7e09b493ffd4556550d21597efcb628aeee5b5477cdb8c4f9bdf5785c6a4b0d0ba2946bd8f214b7ff6f117bae589b3a367b11650c3fe2ab0bcd064dbe47baac473a0b2b8087df683e02f3e24a3605d014fc9ffd202cb697a5adcfefcdf780bcbc4a3e0415aa73461a3d964ca4b39c5673e0223664fb18d7d5d6ca444a1e649f7eca9df2bd1fb9d2848023cf5718f9789aa3d9ca79d7e93a26ad94665f8123ec9a25ec9757b07067438399d9965997fff8e50695be68533f07f660018641627ee85f5df18562598fbb34fce0d26311be7c5a280093de5de2f02e32b9a4e413f83ddb081ba7e72d3a761304846d54d9d7c08be56a8dcd9ca3a6d4b6251c416f6851704e129f02c549c40b1be7e3f72e8c36b99acc1ddb1c67028a8878e1169337ca7253e58c76309af9b8b36b3ea8e5573b8af960db9b3b5aac04ed3e0ca8ca5a5314c58fae142d03050ffd36009e7fee1da4c3ee2a2ab032bf1a15f61d101e372bfdf92d46cf8e5c0682b7cfffca2780f61764a41e417ec883301f783b48b7d3d962993fe015c41507815f01a8aa71469aa26ad4a5567145169aa2607baadfc4ae56268f976714de639b9cac2dc9aae98c3e9530ba01db0ff776877e89fb822ab33847949dda2b6881964fbcdc36474ab8fa5ea086c2e3c21875803112fb96358df9bdb25a87d01a43448b6c540ffe58f88409819238d269724d66446015f49c3fb94befd10be9db06429df16a22c1314a682e3bec7f838f5404c4026f568da7145c5e9eeebee35201d6edc8fda2099fc1bb37bcb2b6ac3ba63cf2042b9ff187f27e6a6c10c4fdeee695700520dd4bdbbdc505e0ad5a6548f802f22e13350e11964cc44b06495aee9dd6a8035a627464668b882269232293039d99c3acb6c4f225226e13b15aa843964abf852a3ec974ee2188f13e6756eb3f53d23ede425ca5bc0508fafa683995ce9dbfc5595609ce908373d850c17987f3bcb1d296b0a7c1871b22aed9e40b292969b7b65f794b95b6855954d0d41d72d39284a53c91a31bad9815fca29584900a6547e79ad73ba871823cefafd72274027d5081821153722da2e039a629ee1dcda433283043f4920d6a22f8f83cbf9087fea075ebf1a25ecd964ff1ca77e33323e5345b4c6b38e87aaddf4596fc609ccc6e91a0c6063f1925d13e7e56ee60bad01ce77fc83df9408674b321e667b8f30fc2c734cda959764686de9f3b39b68ed04ef1f83e079534a0fec28f3f2a750851a7487d191dd6a2061065b8b85ced234ce69d45f3a8cd9e3434d3184b0aef3afaa55586273b14a9171283df4b0201b3ba132a2f3e4fbdde2714bda690223a01e220e07666bfb9a898dbb1c87ef7cb54058719ac96cd32c8f45648361450210f791f161fbbe46fc896430089ed8acbd11f0db62fff36cf6f291c8710caf0b1818d464b1ebd6d24fd0029da1555048a68f6f023496739021a2e9fc41b0de51c3858cb570edb317aa6abb4a01854f9822a4e41e0b27a7266186dbd866c60e1076259009cf2274b3ce0b6b142711f653ebe2cbe9b99e745b8ce18c4b1c6ce4f7a4905cc070f105c37474de1269a0d34c2b2a8d4b5386ba1c48582d46f8529e7885bf0922b4401ee8b872ddedd13d950b3534583739ccf97e9f64e4f066ef2f04bdfb00ee3fc6bd0addd618a541cb471159797bb0449736e23598e89745e43806a4b4dcec5b4ab822342cf1795674d230c67941711dcd0363690e9904bea4c6349f2bc144b7acc65c736db9b1b10c9e72a123b5f671c9e9d74c475d8f8b8461c4057770b327b79b9e98240578fa16589f7197f8263c3ec4dc7e9e2e530b0a425e2778ebb85981c22d89a9ad5eac73ba274818efab48ad13c33e76673a7688338caf066379fd214323987766b816aff05121e5f3d319fb113543accc18c951b919d3e478eeb9c89b31ba6425cd22e81bbeb169bd8fd9896066bda3835a52b86b96e40c599e099304f47c24515fda6914c7f63612741d4e368d9fdf22fe7eb584c388d4ce6edf0ac4ede97fe78c8f446a4af9d5789078f902920108b9028d3973a347f51c912299585e1d1861650fb8e82da156a8130ecc447d497b2aa54fe8a391e63cd919252ce9a0a197920b3a87b7dc549360d6d7e475fecef6254c95c3a1b0b28b3adf6bd85e29d487779b8e2bfbd8fda14e26beb7f3e7e2981d7d3f20ad6f2364a1c2a37111aa171965da71fc8fd3a29b89e289c5dcd34db916def0ef55de2ee20bc0689c4896892a3306b296e2d0288e35be5f3558b049dcbb22b192ac0242ecebb7b49d185d53d89a0e8632d43a6623f3ae687dda8de2a2bfdae26999027a294908a05472ac82d496ffd67743f389561d7a2fdde28dc920be057122257f2702a27dca82bdfdd57198192a21b58cba21138a1ea987ced76cd866330dd3459f92059666c0b74d96aba0f5f54cea3115f44aac6cd1f5c39186655227fdc41eb3f0cbc7a1b9ba1f9d67b6201a34768de592b44cc3c4df6c774382ceb6cee43893b2651a6227df69c9c3e99936fa5304bff261f9d73a1e9b41a573caa327a2640a33b6e8ee1caf11cc992dd31dca5cbcb69a0a856395229eb06564d97e5f4def6ed386c2ca208b6e2d6c86955912b49f4dff947df19c8ff1353974a14be78dc98d597af77ac6eaac973276e8f9b855237477f8efe5e7a86fa3036cbc1045f9ed6ca7037c97a8fbee92bb6ed9b597fb64477322dddf152d2323ad87ba2de6f58d41e0713d3adc94f8543b2bf1389add7259e13944ecde5b3e551a23d11f799148a0f0bbcadda45aa226fb63cdc6188446b184c6fb6bd14e918f3b641cc330d5d8eb488610954ffd1668a43c18eb7e98d36754b4aa9f044316e9376f45be9897be445e928fdddb37e1e72391c83b6451528bde3d1a83cd099c035338c5407daca7144764f38a84faef1efceec917292af6c64bd4f2f5c9e758db05ee1d4bfd692e50b66456110b7a4b3f80f91eb50208b91eb03a26459d28c48c76b46e8493a19297f72b51db28d90af4e05d970b1dd35eda5c44b105694b89c4edd67189c180fe4aafe084c7e99610c2c5d2776e3e31a2be1affb2582adfff2dc29b2b044652ff83bf0de86918edf38c217bed53d66a80fc745911caecb05b56ae81673555fcecc33ad2c00d19b7c9c19e11d69850f27c027d92ac0f76c033d3b98c17ed4e038152f71aec01bc414a48bc3f3bf1f4d985c8cc2b45994da69ba8d3962d814b4bf8f352a1ea1aaf790fbbcaa09afe80d89fad35fb9b31d905cf73ce322f1fed7f2b0da9f0bd7532aa3f539fcb2a913d5449d72c62e04bf846ceecae869ba446406a6f6cc9e6266e78952644be81555eefc3c1ddda33261c982e4e6330566f0e8f739d96a6859e2e562e759d9dce32ae423c06344b54c7c242c9c4d23f1789bb5e310e0688940c98f826c9747f5fbc98fe471c8b1fc16a9129208740b02e2cd5d80569488fbf68fd77c67b849dd185a1421924e9d472bd3aa70d9f7fecfedde51575623dcdf6a7d434b62b35d251e15b4f87e1924c7ef13ae8b099a008d57de8416480549e5cbe26382b6231cc2ac0f935278af9152e54ccc07db279f3c8f68353255735dcbcecaa00a5c84e655e681a61eb1d698c8ef3f05841f241c642800017c7cee98e34826cd023c66b696d90db71f92b6adc44eca93cf63f029bfb3fa1cd40078da8fbde502ac5f3559bb0dcde3ee550e271a0656a72e008028cca6842ed80f7c255d4707d13c241bb77d7b85d7e99e59d817bcdc637586f9b27f93ce3314bab58c892d88cccb0125027fbb37464165dd5135a6fe2f3c61585fbec26a1cd7b627f31321701db8d78ab1306529b021bfea4c2e39bd53330d6807ab30dab306ef5a690e35be36cd199c0fcb514949687d9f1b355662ee3b63c09958239f14c15c2fe438aee4f5735ca13777b6cdff45ad5477512caffa7e3ee0da7053b9d20a3ac5ac362ae98b545cb2bf354e29cdeee65e7ae2b6b2afaa0950de6e83ca4a5f17d7813bb214fe53a77f7e065d4f14f6bf58cbe88eb52851e15b7ad054370bd5b9819dfabb6041ba9f0cc2de56c46e3462a8f6d0a004dff9657a326119cbed2f55e4cc84f651dcf3b5d46254cf284c7afe525011833a87cd0dc8608056f060da650426ea53aa5d8e834c79ff663e4dd38ae9396eed4d039695679edce09d08875148b9a2a07897b1d01c4df505677bb9a4993baf7acb12c8dfbb8e75cc9d956afd2a20bf674f9b5e5c549ea4daaa48ea8b57606e25bced074503b77917a29d83ecc00bd0029038b3cac90132e6c831322256c9f80130c7ec1d9e68e982792aa4456608063cb3d17068b580616d2a18931f3c5dac1da3667fb042e87e25749ffc04803bd36b2ae428d5d2bfd6b6446e12d152f3752edf69b17db6a7e63b74de5f2a8fd476512cb7e6bedf990c9ba3211f8f54282fe258877076c9e2633294ae99a658be52a668ef4b17ff9ed698813367f50d8f2a3b8b85ac078facb2b23031a71871c563dff4e1f7d17a4d49fe93be475d20dc703447717c9912d45a1a14e07cfb4bdc0745f2a6db55c96255ef670d6198457ff9671107d3ad4656ad599dbb5107a0ffbee1207ffa675f3f90e43738a80ad9a41c2b53ed162ceb30baa56e159181cfd1fab81201d2e240626edbac3d20d03af88d2145de4d13e4a7faef54c56fdf4f67e5fff77f795e1f9df20c99f0c11d7a1a7b6fbc8a9552bbf06e3a15f894c2e64c8fffed8780af01717a1eb7ceeea5a2290dc61e7fe3d8df49fc731986d382d1a6afa9f1a449c43c0029986d559735a1af812707dc10909d78b8fea22b1c7f043e626cf7446e5882fe1ef5509756486d0c9cf729b09f1fea5f097a71041d1c10a8a788d1a9b801a1052eb180b3ba1652481ed8097409c9a70125bd52ed6a3283d759518d03f923a6a10036697a1c838dcc0a2ed991c6d660a67ede251ba9d4d139cc47a26287ab174d86571c3423060e20e45c214c261551f07d16b5d7eb906bccac16986d12d7417cbef99b708eec2ac81c110a5a506c4f0500e9f58bb07c72aeaeb2282d33875c1bcf4fa6e3604ea565969d29247527f3ff8fe07643ed2c124672177b17198d9c932ea9af20a8dd1251390e122ed482776861a84d6901edd4262574a6dd667be2bcfe2da3fd0e00236ea1992ebfc1c54b718a5ec6b096e95d9ef42e7e8ed49554ded50dc66963e545a5c73fe3a75816b7b238a82c7758c5030a9806c295d5de81b2a4ba421281fee62c9fe41d8fe72ea5f0d5366f3d857838f4a48f3d8db2c1bcd5aac6d677c8ef22e49339f2e10eb19aa41796f026f5ad6476748f0950f779dfe32eda22d069c63ba31a31869b85c644d63913a28539f21117660034bba7d6cf9d10fc3d4f7e71b7ab0f7e0d466bb678df6de81156fa9d04216998d8e483eb6c3491750b016f40adf08e429ea2376279f33d46f85f8492bb582d258ae30474dda25a05165beff0e5c136b962ec1f99af3cdc524d46c02c22c8eefcbe800182e3660726e24aaecce3fa6ec49552cec6a8a6a69d9d1e846d9818b24d17c16c56d6e01d4de87c24d98d56e3a8a9ba41d01a7fce37038f42dc39abb094cedb6fc3662ab2720adc8aab1ea7587d1420372b6ae4d1c0a7076cce9188d998eb01f7d45098f5f8fee8ed0f5b5b6ee1742139338c3b6755e852640e64abc9675f1fbf39bd917b64e7bf4250654ccd9929e4bb80583b21f103ca0cc4189d86d7aad8481d98cee446bac0a42c4345758ad1d1bb91995898a61e5e75d26258193296a4495a22d47e51fffe10b6ab36237310ed9c8fa76c3c91a0916f471b593a4753530f49b6409e854143323b366db8c5d3fd07e31fbd6de2fdb91ffd64dabead255c322a612a1748dc28e61bd51e34e4a3b57a9ba6118c128fd6517dd25c647056bb9df7f1429b6ccc7594666eddc3b281b7b82f54448bd3e06d20111386672ba3d24354bcbeb13701d7bb9369aba7cb0e90a69c80581a5ae362e5f73783176a160f421394ec448d17863f774907be047454d81cc96d9f0266a6e2fbea1102a3881fe4654ce02d679e0afbf7c516a1b1013ecbacb9acd80187e43aa228b9a7632c6c7af66ad85aba970e215121a1ae93c6bc4fac062febee61a15bf5ff11fc53b0d1bbf2e6a8c8c4433fdcf9027a39b1942394e3217cb3284441c5ebe3a0988bace3bd0e95c00c5c47158a7e820d71be3cc7af069cc8e648a20d10ec5eb641df7b1473e56cd43f382844d51395753247edc0b6856c59665b7d4604cec5f9359f54a0d84c4f8590c1c2ac97ba595ec3afb8c39bc40b011a4922fe4c78d923265e7d48fd48b641533305d625ab241bc83f7b82329959ba9deae2d51b1f335c42ff20248b1d44d384d0037a966658a779a05c67eb95872efeb963ec39fc8a905e46e609ac07b44914bbeddf3647e7e330a2d7a6a23283d51f33f5111b5f920479ddc39ac18c2c105b795b5e1c90900fdb57a41cd657ae56fa5f8e79fbc1040d657e227a7b5190468eca824abd171f234766910d4746908d3973d6433e9acf1be235e903d6a76595cd168f35398f7af6ab2f8d9ec107c07691b1116383515b7cddc250e6e3de1bf77f36ab23789879ba6522e992d3b81395cde70f30325e3fda81f613cb7243266ba1ecdc4976164c33fbf9837e6662a522c9305ce6576f89b0eab19e612fe5e574ad8bf7cff1269797ed5cbc70fb51bb27a20a923908fb09d8981006225c379d78a04ae455d2d28f90365b67c5f7499604f96bf128c65f2176ef84190380b83a8b05020899b7bfc270295be24315d62d3b8850c77afc036f2cfa78d392a646d2686a87ffc66804adacbbc3b2f423fcaee5f6571355e0341787caef3077d9cedd8359b7998cadfc1378ddb42b42517b48149ab336cf185f75218434cb0bf8e665c22659c8a8f59e281e3e842b79367681451be43ceceb0ff512091e0d30a82539c4e50b0a10a512aa55a80b65d1d5a1e8376a49ce32a8e41194d69dd1937c7df1a571f92ca0fdc8fe20a1a26aab083e06611474caecfc166b8f2561208cb27182df036d0c268a349fff31cf3b630be85d55951d59031b6512d62c8cb090a39c716ac8e4408f76b94a7d8a4bd508b56d22e6a3e0505082d336b1e3bfeb751b96f2bdbbfc379be156b5cce479390b5c1ee07adf543652fef9be527916718a08e5906cba49f685af0722f30d400d093066616eb63b875e98be3e36876cf4e66c85fe45c936b3fd23ae4b74c35c30947fd561456b282ae2e18022b099ed733a29877e1bbc049499f06ed9afb3556cb0c72e44d09ca80e59488b0efd2c6d3e31f2f68504b4a2d57c958d64b7cbea74379e40c009f372d2b08a5a4ec3a98b4ddfe30bc21759031811d2e35c3eb24b1fadfe94a22b9ab42169c76467cd46b19a4bf77dc670b0f61c322dc1a6d246916a18ccf3e805d54c226495c29c06c9c51741d6486a44e3ad6ffe071f156928b87469a77dba15047272b5c3fefc1d7e74fafc460e4641827e5e8cc63d3e3ee4c13b9bf39eaa3ac203b07df61994d438408597939fee80427595c08ba0af5e61481245588947cfa3e8ca583a54d8c5dac8ecc98dd3c28305f882ff534f3c114ea0b6171128be52d167df9c2e69ae47ed99652245692bbb389b0734b5427a8de2f4ca0555fb5a3c3ed5ecae24ce1f79ed73cd69d3f3d1a135336e0eeaa0cbea35855dceee9ecd4d8e9cb014ca92ab920234e233d7225bdbef3a858fe1bb0f87a0fa5df66cb280c9b134cead46979c5fafa57936e06e367ae58693aac6944f13b663008492eca2b2592bc4de8ea0577ebb5dec043d5219cdf6fa18d38a66ade63a1d75e50174bf42d2030e59b2e3f986f010a7b7ac98f957dc0ff88483921bfcf90e1167889f9a155617f200e30342c4f1d7f1433bfccc7f247881df85be9d48872ef39f42a87ade6a0e6dfa131853938f833197ff591b774500179f4c3263dd4b4f714b93f6e00e2357e9f5bfe4117dfc450feab2153a290113b0c142fb5d4bac79bcae5e3add248c33a2195daec803c4b01260bf4acd417ddd45857419982c18209bdf63af07b4a2107643c70eae91142156147eb7d3e4b9df1a138d47c340c7f9031880bc3db1c8235262664b043d3371c7c2675e57d4dd83453469530f9278882fd707d444bc0cc02e5257a68309554be6b0558d3e860382120dcf513b34c8fd460737580367c730a3b82178786fe50b3368028e801259cf30cb54c0e55388ee965b6a0463e0aff8f1dee489abacf566f087e972ddcb1b0f214a6a4fb771f280f2b3cf46fa87ee1f6ff797c8896646a360d5fcea3bb3322a9addf91e781b1ce01faed16d7f3826e71bf2a7689406bdca4c981809fea27ed64a83c1cec286e15b8a0ced80833c73f18598afa653e6d42738765ef17da4b6210cd177c4b5d70a59a94d4e1aa198bacbaf3fb203f192a96362ffb2ca5ac6aa114f6b8a5b0efd261a8a3ce4afcb17089397cc53a487d4233acfb365c7bc1de6cdc9e02b58565f09a1fa8718d4b1f4ef283799624153affa5b79407dccc5668830d84c31e91026c21c88bcf2d395662130b393f206b6f58b7062adcf6a49d37be60b0608d6ca7349e6b9a8aa720d65a887e80083a136dee79981b3980b2b9e28475290ead299265115ce34231d5bd6dd4a8eb1da5ab565e1606ff1aa71b92a33dc747e178d6440ddf4e3c8850aa6489755116111f8c1fde0d4fe72880bfb44ce41f74866421ac971b7fef42deea62baa1b11143d37a70d7d5516fcb6527a3efbf093b1ccbb31abb2c64d312ca9b9a065e6a633550df8b41648d7dc75d881da57c7da9aba535ebc53470f8c5313bb7758f3fd4f75390f1fce0a737869c4f42b22ea06f33c3ebc7f715d202d3f226edb6e630674c4c2895dfce5fa5ab293931d46270cc686b03a9959b623814395cd7ac1b95709a575b6347412bead634b7e616dca881cca14416977729444188ee0904fb804d461df6569323c630348560c7668b4ee1a4654264090066514ac66bce6c2478bc5c1467b5ded65e8404077b5fceb0595554ea93a263f398d7bc0d04dc9353917f191ca3702f9560d7d625ca09859a03e5554ba58e5d90c40e30086b3c7aa48b2f979f2ea3372542b2826e19c281662f31d0d8167a5cb41d9dc986be0334e7f1678506a1949c29da6475a3c835ab52236697c28c174e8e051d8db56cda8b7192d1211d277f8ecc087ebd380d278da1d789b5c434e559bdaaead7430c7853ef944f4cb7bf7f8426779936068529974dc15e4dbde628118243270cefc52c2322405a6272fa58a0faf0538cfc25dd84804093c718c547fe897c05dbb4549445624be7b492cffdd19fee77c30097826450a018c21e0a42f91142bc247dfc0bc5afbad66e153eaa5a17279bb65e48467fa2df56dc7877b3b1bcfb00f24735acd12831439c4fc8f64fbc40796960ac189c821efda50328d7255a804c225730f895abb701d03d39b18e34fcb73648d433126acafa5499fb486ee02cccf1edd9b13bd97659e82bda678ef2ca38ed467f12cd628c1034a435de4c4ed95be6ab329db92d375875c1b735ce0be2c15aec8c285d5c30a76fb66ef6df4a7db61067b45679a692e71191e904198d8c0a8b4d15f51ced7253b8e59e800f47a0969ac90982114f734d92d7a66bbb0fc05d549c7fa0fd5d70f0fa5573da06706505ca4389a961e804186a3e026e4909c13e1032a7124aee969f8bccd6d6fa1a32ddeee14fea61b541bc30260a046ca4da347973f3e2a2a42eca07a464a1ff0ae4a8802ccf58281146f15a58e82ef0fcea138acea04a604e7d425b382ced38b1899b92cb86a34f6293272446d24981a14393a3436a0bea773d13c4696a5247100eae06d976c05245be369a9a81c2168adce332e30c1f37379554a1ed08e8dc0d80f30df13dbe3c53dcf083439de04aed6e634fa45ccecdf778087addc189826456d0cb762b20e6ec76dd8b3d4221a845f516c5e7784d79fa84c6e7fcc18036e7b4836f323bb9879264608000e9379da2de5fee1a13d69b178ef92c7af0bdb35b246616eecc86672dc5e3b71e8a59eb3bf449c36ee3c9edabd6eba7d6cf5741d32cc10c418f2d53ac12e6118d273df98a11a934a13179e538ac931c131a1971a22f911a0e544434dc0c5896e3028be43096abd1e4171c05bca2cf8021b1dd9d6a1185d39571a15b011aa0b29f251198e18177882980181ed1ea59b9763d348a1f6229d6578f8559cae1b18bed362e078f7cbf24fb93f4bae45b9ef67044a1bb6e810bde0a305dad4ea916caee2c3a2dd42cc564b89f51ce0137261eb2995ce2b7f7d0a8eacbf51c1086d728036466cdbb7c3c5b174943c27788e4b323dae9456c63d5818c61adf2ed2be0b9c678f9fac5ded6cc0e2dafba84c808cf55a09aa7d59d520ee1a3c68e947f16b57e6308e6fce5bd7df6b3491b29a871fb5d2d7a6b42c34a9f6341f1d998f95aab3c0c304b213c3e5df2c7186d142b8a56602f8ba2e6cb3b64957337289967e187e27616897502455b80d68569e1fe0fc7f99684bc316dfd321f5f65575cf2bb1a8a03c69a5a1a1857e10a92b28d9637014e5aec4cbf00510bf77e14879a4bc759eda134357ffc0b40a83eeedb0f6b90a3d513918ffce615e6ca3938bd75431daa799442c473eadf4737a7c71296801565d5dd73fddb1bb2ad49e0b651e26eccb2783f86e409b641f88c887ac74f683259839a4c273c37d0791dcd98bee845c74338c096e4539272850af56aed632b72098df7dcb77510d12fa6c1b8e6fd9155b081afb694369ebb8352dc24b38a8fc3c2427c6a8c6bba9260ad2f9f09fab7bef03de7fa006115ae4d75d8d2c7197f8cfe6939346ea8ef3134ebdf63789f6b94cbe12dd5760323554fe174feb90764f269e94377c3a38e533fcf8002e97e93c3ae540dccfc49d216047fb42fb52faa312425f0260e82c6d96583940377ab52dd3312bc64a8230e1332f33d4fcf6d17ba3f28c99fd837fa4e8d65357b4737f2fa37d43ca897c31d09e0ffd1e0b17da5dd9e9544adb1ea7e71a34e20080af42e859245ec3ed4476f1e2f7588f1182e7a30b0db10923742ec7ffd46dd771d95a3aa915847e191c1fabc34cb92bcaa04524dc4fef691af1e4f12ad19a07e4d1e1996829e6ef58771a2611a2803e0dd9f78f2cd91ed31680f2896fc17e410250f46e9105bd09adaa9537b24ec1f4e6e050fd2d798912269ea36eb35fb1a4fe9270bd73be961fc78261edbfab88d393951bb36ac001545ecf27dfcc0c6ae1f48a267dc969d036a83d226214c7456a0c703f214714dd5021e149cf4f150a714234466280156ca6b41e7e6394979e18d0e9b212ebb365218c1754f631f0ec88220aca62c6e8fbdc24cbe8e8af61eaaa7689cbacfc28b006166abbfca4842a17cdc64c840ce896c7f2cf2da06e5a477643bb6f44172bfd56222780019b0db6d6baba5ae745ec05d88db50e90e5e7f48aa9cb148d87eb4e18506c39a691e67066d758e8b10abf7d33777d51026ce7a532232547cac8cf70c8b235243eb3d0815a9c54dbe39ec3e06102cbdb9204e280d14ec5bf2989bdbe1dbd26b53714a7f11f4b87477996a13148b13afcfea2bfc7b0276f3ee6d91764769d869410a940337300c3ca435e173e8d7dba469408d1bf1fc21a3504f5e870b080a3af2c86503cae467181791dcb83ec230a45e1276acfac22949fa6ce9ab5b1e77bf3be21068f9ae9f59aec09eb27e68903d223ff78eb1cd34efb65130e61dae5b84491ea17cefba34462b114614c1b2e3477a5896e61f42854da9193afacdb2523a7ed38dbe1acb9c02416d9ed8e91a3478797fcfcc8d61423abcb1f8c3eb8fc2790722c31c952df95309d5c8e7697a8557ff2beb07b12a31d522284c7d4cb32555b73499ce9a24ce2a124c2bc66af5de37a9e26ae27d9f128c8ca8e42050e4fadeee0dc904e43bc97d735e4fec439a2dfcc548f70f260bb9a7a602e03bb548ea42880184d8a0958b90f8bae9c7bf8e5cb3d76b567c22f428d12ba6341f1806b61180dfbd17c60cdb4fe781842c5b391b13adcfc8ae82bc889e072f8a28fb64a5885f91c094e41e7c99470dcb1cf00a71ebaae78538ea776f739e9c209fc5a5ace1b89f9cb68d0be2ef5d7bbf82b26a970ce414ecda264008cb2caeb4fc60f5cafe3f63ac221101dff895474abb8ea45c8c6aea24ec06366522584985ba4e5a207472b331c16b82986ad2f9d7df8e6bb4c75fe9041ed00b1ebbc71860ea2e587c1cfcb88c4850ecc23ba25cec3ac557972792ac04d7c3659daafe5744531f878d3577700cdb3d926352abced9caf989919f8877d8abf0e579a2c3aff148f95c98eb164ebe4c6ab6ae7a5eb5cf1388cea505dd7bc79eb9d31da87b81600dc389ad09d1fd79742f6ab2755834d5f54d55e5d9262f1ae450eaae530de86c077a1e06160d68c4c4282bbce865ee70e8c5baf4b5756be03629374d76a7dd220eb2178321ba09589bda4580dbb5c248266ee9134e26cc5ded1ebd4113efe1045cf52d8bd0ad540ac4b73ee5e86666377f6233427a0d098cbf5880be29a3d43b5b30dd9c86491fb9e84496de1954c10fc8ced44ca25620e7e4e7b49a0efcbeef951041308d6d6320806169e38960b7d04e659ffb0e619c9f4a894f06af4899e698bd4aaba275c654dd30014a2e3a65dbf1bd2a8f80438f2577393a2a03adfaf1438c503e6844155be59c992561294078fb54ecce2f04f7f2ac081828c205ff29d391c3f316133e747bc96b3b5e5474571f438005c3a0e60df1053ca387f4aadd622f666e1c1a7152d50550f9083d511f44c76805bc55a8c04244aec5ea095f5be93fcca251b39ee8637a67be98e442bf041cec2e61485e0a2416cf6bd905da26088813201242a31bbc9bb782afdec45a299d57ac96860d864d6b21cbd1757bb2aad400c671cba390f2f05d73d69d1d776f291c00ab0ef4264f957f3c60d5ff77a6ca69c0cf786ee747e71e9dbb924c4befb649195874ed4ff48d34dbb12cf22ff0e83b89c30aea12f26801a77d6b65c2e01c8353fc2ae246effa85ddd1711f031fe6b19c90c8c057dc30fa7b1d1dfcb0a88b0e2da03b42a4f73a393788508abc43af10a0716b3e3f366c70dcd64eb87c8ab0c4e1ee25422a92d0cee81d9543b1e249891f38693ca660cf18e2bdcdd20beaec19922d59eb252163d5d17999e00485436f68a5758bfe1874bca20ba937e7b8167c9ccff8b66517919b2133e38d96ffb98eed53874575263e239c8c131b7cc3bdc9353fb3b935017efb5f1abe464868d04cb209f237f73204db5dec24bee4375e151e5e1ba54e4945caf0caa2c88e658b030e1dbb9422b45d513dbe1b5f68508be10eb9d0a3b93975c36e252b6c87d88e3cc4e361881bdb66cded6f88f7972456df1b398b0f7a806812ac913ce6f1a911065eb876cfdeb3e2c574a88f60d5736396aecb349c97fc0065ded26a078b0c53565e6cb4461de186fb580191073de13f05b07edee569e087a0300289e152c0939eec3ef2186744f1d71fd08e24963db01cc539ae8b6bec809ae728cbada78d6bedc71b8c2ebf98ba875a6863bdbfab9f3da05d276b8cd67aaa7e3a318c4bc4a1c8aa5ce0b542af82bb1bd7b102dbbe5bcef7594dab73325a8e8d8e686b34a56a6f9024ae50b1b4803875088a89d53b15804ef665c585b97c3ee74364983fa48cba3f9af2986a0134654ad9f0015fbbbfe35b57e8dc233479a6b526f0751afa8488aa1f6e4032ccb6e3b51c2e6aaae180ce6ded6b56156d438a7c8959f18064cf05558d5db7cdd99784945d424c1e1f742863bfed5bb9888b90a0dae73bbe3a681360ffbbb35ef7e20b9ef70e66b6cc13ded572553c5c005117052ecdcec4e09c7765799a37dacf4576434ea8ca01c986f8a0fc967121c50169dcb83f5ae6ad23e524164126dbef40006b3470571d6a018c6f6687dd150a01733cd16d80589d54c7301bce1bf97388ea14a630f213d476d0b78bed19e8155dc128e1d8143fd8775c83de875855b6df16493ded317cc418271ed0b7bfaef13272dca1c624df8bc1302a11037cbf4a5ea620e63b618c7a3287f902960109b9029139ea9b5972e9d249306225dd15f1e0294694821a79b4a893e1b04a7a495b7e80b1e770bd606098e3ed017231c8960d21fa9a72317686900476e303f542cf8c40caba88f5fe8f6f841e7e0bfd1dbc9a0cf4bb18f57b174e4cf695a241822a8ef13a4a3ba90cb7a23cee59034615a514ccac99d5df7046a5142726c7e93bcb66b5537fee2fab12f9c3772ecdbe3bb64274c923cc5cb771786e475cbc37998b1e40d641197ec6ea1ed220c84a64d9f1bed269d4b69885669c02664f9608ca80a31a8cf18df85b539c9a619bacc4797a7f02a38ecacb63358cd1aa917d4635ad5c9aca1f167552c773316ca60ddf93e4b12daee685836c26f4c4fa4ed3e8de6b86813fdd6196391cda1343c2e6c90d4482a809f2266f54b6a243c7e97bd006d934152f363a653422346640fd4efe4ee37d8cd3b9c43582131328dbf073ea22927ce93126c9047dec1aae6ed90a522106aa0d6d4a1a7a7254e0d78c956d0b98684dc4ff15de4d93980e6a2aec36ba6def6949e933ad8306829f36e857449910e54999fd2ac6c290bc9dea4c68bf44e6bb719c769aa59f476587c9f5c2f38b766d7fcd53c0ede8da3b4139635399165157c7457547f505cdac525bd4d8996ac59b98f5a264767b96d9e3f497bbf317318a38ea3ff59b261872b33e6d4df9b99ebe4fef8cdf9c6fca69655675707719b8dcc15763abaac8adee5b0936618a094b4ca1d4c6234f1726fec429a39f6c0e96959583391a3911f4cc72381cc689aa073b8b0891425a1d81cee67dd74fac5b279593abe41947d8c2721293fd26e5470bfb7bdbb2b4e3ed8b6370fe0fcae921665867092a60cd8e3c57382d5936d43ab8bd1d19d3680a15c5ef4f4bb2847db648a254a9f8b12dbad72cc8d552d5e65b35bac3d86b5a091fd0f63eaa077a02f863fbbcfe94f91eb50209b91eb019dc4d87494e484bbfbf35bd346c3de18712a1ce6de52e36f1ba866f9c3f49a460cc484230b15d2b7b742811463aad8ab3285675f256aeb9a75145523596db903f7cfc7c80144ec03e7fe455faa3432d9254f8a52eb1aaf5a1b80087e1780478577b577086017d5e9f7fafdfd196a3390051b3b46832b6ab9cf68d4466ce4d6a9b264189c4b100bf1de43d2329600b2687d78ec01bac033e3e0d36701b417c30698d226500f20d2ff0111dcde5701006114a3e269dfb17495a140290c649e41697def35793303206ae8117a996917fa395da8f8c99f6560ecde1d551b90b2714adb83876038fcdf72462bd005731612df087ee3fe9c25fee7fd74d53e60c3d4d7cc834911d8ec7a25a04e1750bd5b4c3cc0973026eb98e0b91e4efc8bd07fc9c5fe3ad326d9c83cbd1b862ed0704149389d9c17b20d71274e4b9664679a6d37abbee665b7091b28847ae209ebaaf6400845a202e6eedbe2e226dfc401139f2c293acb36c06ec0535d46c427c384f4c8d77f8f80f9a82df844b5c39aff6326e1fd3435fac7a75f354361492d27a5c745a731179f3a94e6d593be9db0398c45bf833d93d2dafc9cee5f346fdc231a1aca28cc41b4cd81b723766e53a0d7a6f8793f0299ad10816ff2f8a63ec01a2e35e488c3d08a8338afc070c5107f0396b6ae35b7fe5af1affeeecd5429d944b59208eb0ad96ac666dd9ef529b5f5a96e44b7d519e929adaa7b015f38456364d2b23c99609fd08d5c456e10f09f7c319aac5d969b3db8befacfb17d152f2bad4df66e39e4d421ac86ddf8abbb619c154c05c3ca9007fa65f87fd5f60ad14ab9edf4d028e21b962ed81bfe81d461543447cb8b82f0f1492c86c91296d0cf9deda97c5b13f63f2329fb80f1bf71fa87cb7b81a498e5d7f707f1dfd8118d653b395734f10d8bbf9840bc9fe8fab4476f1fb604bffcfbdbd681a0de4b5a82f7bb197779906870bb71a3cc5b299b8f435f80a6f348c73a205fd755f3d254ccadddc76e74dd7eaacac12609d9f72256a9f8c58d3723188b98361ad76764a840b520838d6a1e0031e5964432236d4cb61e68bd92f2ca8729044c3562381834d3a3aaf78f201220f98bdc4f4114b54a1bc525cf69266dcade8477a8c17edc0f8610f28ed6619fd003bd0126dedd9fcf08855fd304a257ff0822c73f60636a4230f5dda3f753b044c873d4c73cfb0c475e06a23c4d46237472a9fa07592b0567ed1ce2ae91ea1cccde4d160d1d1a4b2bf139d292fb9a24a19246cebebd4730109bb170d4266fc87bea349dc41ab763d57856b21a6a70136208b2273429aa6d34d5eb52fffdae4c370e32c5238ae62817abdb81c4681e6f1ed3c2f9a1d55aea6a27b08538f1f82142f29780807b2b8cbcf8fe320bf206da3da805bc606bc9afc51733bc276498fc0e3e5ae9e06e19c2b5ec57900246fbf54b115d1763ae105ae6381393aaa9b691733736e17c0dc9fa926abab5969dbd8cc8574cbaf932b0294aa89ff91192d82875b9ea7709ce24058ec0dab41335a9e88cba4d0928857a312916d34375ff4ef2e54898d069e4899c3889605e3f4ab183d7a5ca55fd935301492ff08f05dd5cb79791b112544c7584ab56f349f88c6b5c71525b57573a80ddfc85010ffca0dc1a5a7578dac722c4d8b8157781ee93100a91fb13d7b86a5105a1ca15c91e9f956bb9b174ca6e8c288ecf4649f90b422d545520952db7b941e3a577c0e9348785b70e38fc0e8746c75e8b4438bbd263140361912d0343116c97f94fec4711d2d1a2f2d7743f16f170868630894b31202bc8d1ac3aff4ea09b0503391b48b07e383f21f3f68206135dd725c644fd17efe48b427861ec5cf8f54a217b3f4047f557e81b2b797aeb86c47831742d47301bf6d561b14bda8aaee83487d4e8c14d679705b29713439e90bb06aea60effea8e999bffce29a6b7250805c5611b7496426ba8edf01b4cc5eca7818d849512c54e6a98607dfff81379837e20721dfa93b59e24de53b4e125303b2b206a39317a3a39f47392dded0c85d73f0085ca3079defbd37061c1706a830c85085456553156bfe2b0b2a30b696105be6f1071794b8076b782c1d06a6a393b51ababdcf5ad81faee488767c23d461b2a6e422bf14d179cb05ed24bf5a8b09724d2ac0a507266c87171e6141a364a914aa10366a71ac55206fc8b6678ec1aeb4d7bcb0b5f7bf55e8e93f9ba9c25ffc1a40af20446815eb7cfc4e87b6e44902d8b540fc2fc2ae37903790c9fe6ff38386326cf8403425bb32e902a9f805fafbca9111cfdc694e34cf4a2b76f3b063ba950a1a149921087c13a87b37b7e2d2b1f4af7da6ee4c02644455868b772de9777bf1cce6d83b7127e56f41ee7096fe1187f1768b8be06739e3a625b4e3c4481d14a7a8566e6fa59ae493b24a5ea9b261c6dbc3654d22ddae0bb35e7be54c3ad8f39cbfda829cdd77f20256bc724a4acd386ed9674b8c8ec6187f88f2b74a80a4a099661218f1c3130d3363aeb883eaaf40c3fa4228af33ee6310581ed3b5470d9165d9afc78dda45b51dc26abc22e40572fe36b98c695dcd5a29ffd6275e30f6ac8cbdb3872ae6f42d9eb115bbaad86dca64342ec89265bccbb4fbdea3aa6c25874559691096f9d454b99b0591b82d0eccc3a49d8849257554bbc43b6ffe437e4ddd35bb0efc674f8739cd86647c42b60778f2a4d617e05f3af309956b2392deb11d543a33a8df47071f7de62b185d50e1348b7fa8803de7d00ac8eb8fcb3e5d9f3ffae07abc09593756834eaecb752c1caa221cc3a00aea82677d6a68d270f2ece1de2b56a360b6635c2778adc2f748d7898e0e3c20805b6b57a6f451b748f2df12888b6f55d413b7fd9eb4a28a888763e14da05833fa128070c1ead7bfc75d56297b9161f04dfb7b609c3d3d2a21cde6cc07a14643fa6ac11a1a0c68f21de4f86cc76a435e6216ceaa8a87fbe10cb5b820668b82d882b32db850f228e2e0207bbafa3e8f63b2866d66ed1d907b4388d5c71aa1c287a064acb7e83736716f3af8db7d78c6def1c78c14321273bf42fbb601d56a8a3ea4b696b7d12cbf5bcb8e59e4b31c2db221190ef7735cd02c6b1005311c1880a0ee824b9d21bb7a6969f9fd0ee706e0978c99db5c5dda73bdfb474f62c42a520c797867127a57b470b4bbb5d5d9cad4e8997ba762ff88428f35e9f713c1bc95ba15d1e573bac04b1d00a77f21e6170fc6b44acb1667c8e05806e6b3f4b178ec605c92f3a5319d43c4f64ec4d3c9fb1f52c888b09d999de7eddb6785398ff4dfa4de2e0285608d4f335ecc45cb2f8185d5f3b1e32edd33f086ce8c3195542b7480e9bdd8949277298ed5bb13d9bbe96ee4e940e780c8c31d48bad517f9adfa558296d72941a9cd870f6be84424e8a981571f578ea23b5687fb2b1f3bce7e902d2d5d4099791ffaae4db862c16c1325570de248f6faf1192aa3d95d9794ca1e676b3296c144f86b5dcf987a19e62e7c2af633e05274cac11f331ad8438f07c5bd76ce028c33489ef926368bf12da799cdaf155e65930cf2af536bb3e2951ac4492abc47aac71809559d4880a22048fde56b117e831fa207e92b1bdf447ca6c515caa6116dd7b8b0db9b6f24578824b7959ecb0401ce9f4a7c480351b1a42d55759712591bee861d0770fe8d0ca4f701cbc89b901745c3a8b190a19e481c382beb07aa3d10f6bd419ce59275446a62a7d9b78f331f119c7436e570503e1d29ffcb71ad58f9e86458ac863c5ea9eec2e8640d4d8d185f205d77e2d7d4fa717ec14ebcc4212c1480675067e9be7ec6f94b376c6687eb8b7e03b6436f946cc6cba7719cd71aa0dc7a9be89e879b113183663eccb0f36a99e3f5d3361b5e6f5d1a40972b52d0560449525469a864f98fa5c4a1de77b4db8568d7ac9aa98362729e599f5b0c1b9b81e38cd3729a1c73f3ac347cb662538fcacf22b9b7e0a850e610a46114539d6f5733256730303a921a223bd8da48ce898fc39a8cf4092463dca2f2b4a4a060e2941f092309c60231617884903dcffdf90cf28f2faf865d0fa7dab1a93cf2e90106d74266cb730c15e1f53933d2c7c17318f563f9335d9b81f00f889ea04dfe595ec90add74cdd1ec2b868a0135442f24bdb276bb1f8efeb008286bb1d7bdc4047dc531429d2758029632dc1282528bc3373768cca8d8b6410fb6289de07220d651afdd64ea6fc5649deb15653bde3df54f72238e0dc668cc03d9c4b5dfe378237ee49018d30aafec8d6ee9384b9dbbbd6eaa5239dc69c079b3682397df2dd92599d07dd2efe42c411ad57f626178b180b08522caba298363dc765fc6233bf074ac4f651496a72b09378620119b5b595e00d0bb3869883a5bc707a1b37c9916ab691b53527786257369b2445579880ef4e035c85d11c644a54c4c2c5e0c929d95d815b9198ac5ab50ba00cfbde378451e39ef1b104d3252825ffcfb6e7e00fd5cad9fd3020d301ce5101b80a78880e8512bd3994b87a0dafdaa481cf8ac84196123af782f1f960ff76746ee2124b4bb0b3cf6ddc20a883879a53e72925196da5cddc8d7d1b5883263033a106343ef62f7e8140ced0cf6379359f0d6ff347b563ff6c3306197534cc7d409e468caacfb6665e54660644aa20ad35b0d4b429e62444f5f22314b0be69b322c541050f086694df516dee442bdc45175883d58384326bfd2075a370c47e1ecdd33b9c837b8705afe0c48ad85dcceacc493acbebc17824892a8ae5a16d28ae7608fadd0573c46337d5d49e5332520701606020518530d6a38fd74617391cbb83e46328dc8086f6b50c94bf3c705f96a0444f37df88450f6c75c5e30cdbec77f918fe996e1e2deff40b40981caf1d32ac93e4d958d781c5b8ac9c1ec95a4a816a2322bde873d78f13211a047a9be570db3591001b807b8e3242f4c84b8168d15a836f2c15ff86a51f0072ba11253e23b660d779454f7b7dcd9e1f7f6e24594be7cf876eea6e4c7d3873283ae22384c3b8f57504b626ef90a609b623b15035adef33d3f28b0c4aa44f8a5ec6cab7b46c800c5bf993c9e571c8db465a74fc96258d9d5025540d6bf13f5918e49b9e581ea355dba34024538759d809d7e4b129b7814e54f206e8d376e9aff1c74bbf2643c0a4755e201d14fad833f2c342b7d6594c31fa6ea8193f73134d3ff3633e9896a53f22be5793026d4d031685a0ea57fd27323cc1a2242c7a9b1c00f366ed43b3e5c4079375e03000f8613f1222165eab7fc2ab73414126fe3856d3e353ad62f7287c472c2f9955b3834a85e717834fcb869ef5203c4279fd2bd167a0d5385b3706b872d06dfc44365cd23d4d64c794e2a11f7ec7a7be62eaa35c2c122d034d65ac71a51132d00140118e8d8cdd321be11bd1d2662c667476799c69bb53d676135807fc627b668fee8003c81a5dae4643b1fbe5f419995b91517b60a5bf9e0ebae3615071c371549eb61d43a721da7b7793d31a37341b3abca782caad277b14554215dc262881f27bef95a4a8df69c8d1a7f0fa5958c51f5a345fdd6d48358c1b034435be705e619787ff663efd531293a1a331261d8e0f6ff8e01732033c65111ce6390c6ba7f1547bbb972c101e4a616ede4f29181b34151ac72f137262be36030575081f7f2f1a1dfdf7ef30635a003f5c3a831aa328a3c89aedcb15e924f88e9860730ea8732992d9fa19c03596fc20c5c0d3a087e2eb3396d18f36dd9f573a3bc1745f929daba2f384e06d30fb433df59e4984909273e9f4061dbf0ea61b2b8e824d00f5ffdc7f919144191aa147f1ab758095de4fa6b9409939c36a00f8cd4861f3e24cee226213fd91e8e54d9498a599b56f0a08ddc547200d93ed7292a950fb5288639da92d7b95fc19ff1f1b567fd79526a72212407df230fefe8b8db9597a2070eaa8a55b342e11aa4be2c994592924a63a87515c9c6f3f5ebb04ea5220fe8977880b96ef383f2c00c6b62adf468634e79ab2a4815a3a6969b8f1ee00a5bf347da625f42a47d2ba647b9aaa646078339e81e4851c54eb2ebe0fa3e9ce3ba43148f51880d5b14b4b16306093ea3f803e1051a29a12fb6465474b4be3fabb1d9e63baad84f683434af21e50c4a89736b8d691eec99649aa3596d427e7a5d48c7e51934b42ff4ca19e5264d14a824a337bd833725300d807b6d48cb174f863d6f6bf1a4e99e2ba29d64d95d7ea7ac14649e9079ba9a64efbe77c09ebd9ae487b048b5a935a0c87c881af04db33e5555e5924bd4f55096c422a66285b32e09deb1140e38221ba6392f2aec9c79a0cb2cdba534562d2f20ebfe19decf0384dc0899d8cb297fa0ec6b8d3f21f1b1da27a35a1a137f279dab1f2c2386265ff84f37757443101720332efbf221fd255ce0075276004cdb0863ac751552f65bb693fa52e084fa0a71b379108b968fc14dffdcf3bb4e8070a12d967247ae8cf7177f62542208ef702edc3f36c4e87ff103b00e306712fcd33cd08d3e4746b5b58f53e9571d02e5b895556860690e781204bd1d5ee413109da2a3d25068a4b074b80b869334e6f4e2788a7e9c183e97c6dc8e488a67b363287f5767a2c5ab47669926ccd567a836ff438d966dadd71d1fcec79d6a36419b48345626cde288d094a222eda55cb64b39fd0d2da2d3fb010e7e982a05ef227a17e8d226878a4804fb5e31eb10dd6e41b58f4469d6b0a269aeca20bf9e1217f4538d8b9dca2758db4585c4e7a3aa14e8320aeeb2fcdfffc2d91f1c596b3e27e482bb6472a9e9e7558f2c88c22d021312d92c9f4105280b68110dd3ac57de40e252cf3d355c6c42598f82177e5d72db9040a4225be36275ee82c2205426ba6e11dd25515a5f6256f638595aa202793a67a8a93c5b9910794a77ffa40ed4607fd63cbeba1530b02c76e78733e54950d958f108304f451ce78c6df2ec0cf9a5ec1341004109f031db41699c75a99902f3086003fc76e5940bedb49d225bfba2741c021414a8299af821ca05578e3e8bc76b00eb34d8cca136893520d1e7b8b1ca19b27802fa00f93772b5fc15282d79aa559433daff8ee12b22ed6d82a561117c487f077b208eab1bdaef49d9e0c8c6d7f9ae9ca106edfdbd571b92b4563c81f700bb3e984835ad11190b31499c2ef4a1533a0432031d95ee8c8782c6ae05b46a4cfbfce0f7ebde786db792a31f6f2a08548c7f3ff3eeb59650c884e6798969befb050bf8a4ec495cb4bae9ec6a6173c0b3c752cf8ecd213473eb03b4cc30819c4d7ba7f6e3e389b24ef344546ee5e3230af63d523456aab4771b87770ea45aa5c4ac9169eb35661ef5ae51e4cdaf873f50a522f81d1caec535b2b803efe30921cc4430cd0a6273be2c8cef86618c2f531c59713bf6e297b13d10f82a25ef89e59aae670eba321dd883e3ba1e0727ceb5294360f43313dd7c46e980bd6aab77247445bcea8f6e0e06542fa7bb52d5b08d694f9cb5c8141d7d902e4dbca7e6bf6bbc8cd935115ff763f990d4b66d7a74fe827a67fbed08009889bb07bf546250c367b10a0a2c80eb26b5d3db2a26d2f06a69f9e8ceded5e0fe38470f80504f2634913ccfd44d7f7ab7302debc80e5274215b7e3dd92cb015585ffc0bd1114ca8b2f93485e8a4cd06e45d38b2b5570af7ca4e1df4bfe06544a320a5ee9d6e5dd181c8271bea6a1b1b6d7e2281dcd42ad73eb9c86e28a3d8fb6cf142a606bee89619aadd2acd3ff03d6a8ab67ceae3209a25e670bb15eb064c6cd4d18ab75698b028b3dd337f5275191a8f772456b2f0db6fa16feb958088a296cdf89073552bc3bd255bea2bbadbb532edd8473454600a079390a0ac568ca6d35ac8bc1b2a28113f3300272356335f044349a97bc9f4fb21c88ab5b1bd0333b882603e2c1c4c4f8d13909853dcfda922ade2d86f9ee7cb4ff2aac7154be25a84431240ee6cbe681f800356d6aa38facd2490b39b2fa4608f3ae78d5f23c874e19646c36ee861c73befdc3a789acbca29525e6fd314ee57c05eb5153ade12021bfa332e11120aa9efc63da4816acd033f5ee592258e38e1788bf2f7a0af0ff6c33d4431c34d5313cc221f9648263737e9a11fb5e8b6d23a1268e2b19beb7e24c2d0773442901444107d57878f4c484fab5cbd6ec97ae355ecacebecdae672bd10456b8d321ad325b921ee1b08b7b0ba55ea3d7ee8abae33ea6220ee3b4f51eb06ad19ce1a8a18c49a964f917526612d2ca1675bf5631130fe835eaf0636b3fd6f674a36b62fb85dba94f2afde979f6d4b56d9865e9ac19eae5010c2f5a3ec951208f3fa82e009ec33fb60fa25b0909a66548e08371502ab73fbe1b4c4cece4b3dc95034426b52c10d0bf47c1f34ae50eeaf3fc1ab7e84d571331d2f42a55df09a741d3baa37df0416e6c3bbe0bf35e3c3a1cd7df61ee9f4fb144f7083a0270799973bc87409da98a7e9fc250a99eda458763691e3fab3199f0ecf9b414fa03f410d524fcb01014a269905f0c5fde25934f156a401df11da2723d212089a667232f948a7f2917058188321b7bebbc95034d51e368dc27a689d3c8019325fd15cb3bebec20b573bb172c6a591e8209a1ec88fabc3ad4e3b633ffe17abba14c9b7a508c79d6916b4d51360e13cf1d6c0b8892200669c4eb3cec6c660efc512fd375b7b7e55d49dd7a382449976d9eafc70e4f958bf893098a69993123c60274598ecc9717866271c64870e54dd36a832f5812cf130fbc79c98496fd85728efe782104b9b29b7a80ea32bbd2571c44286471a9a12929c10305ba73e6fcee94703af3af7c6ac54c4ed14186830c259ed4e3a47caa4708d1c337923d2f181307149a150cb268c34a3a30a826394ae09f1ace46f68fe79b96d624eb2311e5f71246f12966b742931c8df10bc3760051343030fe76ab3c6eeffea8f8e00ca466820f865a3a3d16ef1240a77edcf2b60924b28689cde566098289f5d6d7a10a10ff3abe5ca115a3f206f905a0da35c4b4bfd1eaefc604a19b4a31e2729bf5c9471813e8067cabc1599cae43cbc08fdcd01109557595f215916d92368d0f741c8a95676a4720a973014db27938bf225ec6018c23fa1d352306621c478d5a8f73731666ef020d0cfbf2d2bb05f78b36dc4b5a8818cb4b20e3d12b35bfe5afcca708bada036a95b5846ba0c3c8bf2d86a8aff97a2d12f4405407299abaeae6df68df6a31d398b3e31ca4c7b978d94fc5a245ab51a388166109fd5b0c3af4f0d72919412195461890baee267f39704723aebf07962c6310040f0694e51b9d806f3813cd08e8647eb45e862e3aedd6c141b2ea1362b283ae229b7af254d42955e4f8a975d6fab2045fe2f8322be526e777104e794ad3f1d0bb003f068baa7ef0bdad223b8cd74553131a7992310a446b92644efeab0696aba20586ef0a5ef3e6c0ced77d7c48d6f887c54c6dd526211f5bb75426f86f547f0481efbcfe989dabec0855c4c099c4a2683bf64963eea1b88204cc485d792b17d3333680a7c9cfaf6ab4e7213b1e8fec0a5dc38be5e0814ac107bba2ebf3234cff7b50a11522b9bfad19a87c8c292acdb717077fadfcfd6c19c2fda0d5078b0a7363d101209fa2857aa91ad15f47e75af21d002cfd9c97f85dc59ccf3ccdd94d32dbf350aff8a6d1f17e13f43047a7ec3dd141c0ff753d1717f73e8a859badea0196a1724c1593e7f88d9c22fecb0393619bd78653e02b84ce913ace03949d9863a09b149ef221a06a3848135fdcdfb07dff5ff2682ba2812313ff48e8e86864906e0629a0547fcab12729ccd1cba0a71719c788f9b76f9460d0d4d4ccb00ca7ba5b8381ae711cc142204cdc425bcf3d672ad2955c69b7f9cdf142dbb19a00cdd598ba0475ffbb0e2fb0bdfc34ea898668f51629ff28007b518046e739329305781b40de64729f7a2d895e49519b585e840ea96f228702d07f9ba123cc2f124dbe21e1afc15bdb373eb92cc5c862711a4552451b69b0a5f2a2baf712601ec51398a07d64fdc929ad70fef084c694006125e7628a46027bc5b1198f07d92b3f7e6d42061911f0ce1f8c76914bc3d25abb3c8898ae2592aa5b0c1b7e4f443978f84e1245fc87a56b86a866a1849a8dbf853a19be2982616747870d2ea3b96003fe8c5ba20229c8db9fa4b696216db24bbfd5116242c73d9ef14e4c75e2ebe22b76bb89f984ccbb9af1ef6753397561b98a58cf7f46aabb9aff81c8e9ee7f38a4ea28e2e7ace2d2805ccd8fe68de921d57a5c5344c3a7870e89a4a06150d0ea9ca1a996e1853f8e310ec0c74ddf3ef379378a4839e9a8dfc279acb52ee8b0bc8ee4a7451195dfecf9bc4784b19eac297b8ce8f25928debe6707bd249a4490c62cf87f7d9ffa0ed036aebc177b890d0a92b92d593af635017ddcdb3bd26b0988149d4583d1267c12dd0ae9f3e145b09b3bcbb3b1ed4fe3d862c1b2e378d7d50efed325c7716e1892e61631fbec4435b8ab4a95b6421c72e766483091d08a93cfd5e69161ef1d298039d90c5cb781119f9f3b03671d3524d97deac57c026f092b301b20d581ca8399defaaa6fef0a46db2080b76b666209aa997a728c1b8cff489910c57ede9443d52dac8bf0a35393c8db45dd4cb2035e88eeef9b8eeb2f9631dce3f18ddcc2081230ac505f3d5d73b4038feb8e059e566dddbd19261d81da646a3f7a534bd8534ce76dd7731bc8a320757a9b0f6bf1dabcb880b4d239f5731d956a268045541022e1f89fc3fd5e39b1e6f7066d5536476f3d75b4aaf15a0be43bbbc95473b90056b1331719df33c911d798fd68a1b656b978b8160dd3e755033095b938066d21c7df41558c075d9ae15d663c98688d6b03b00d55b021a1e08ed15ebc5745383208dea7e6fb0f3870656d290a7b7321982e1d84df2e719c28fa97321b5349cdd1b0a9ffa973f48c2a8ed588f2db80353cea6910ceaff97974b6be321bd9b6ea77551e92132936e0dc5dd5a67c6b66852f497cb857772db789af35b08e224a74594d44266259ef2111baaac5ea2c164d3d622f027269f870719cae9197b24ec8f6ef2e73ab7a712e7d01d0d15b79b02d7cdce7d780300189681c8944c66579cf1b9145ef3b6b03fd002ee3f9989cdeb82f528b0ae8974",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xc6c2ce4dde02c0423854ea1e9a08ab9fe7cde53d22ec2e1a387aa1c3ecca947a",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xdf09b32c761620c5be77da398b97a64f03c3980c",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x13748f0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x82dc1afca773df4ee237252b2cbf87f23082bc86b919d60c6eee13e27305ec07",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x9456c0b86b1d1e2ad2173db1cf227b7107939fd5def3859b1a85973cee701dbc",
|
|
+ "timestamp": "0x6ab8ee6a",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-anchor-20400368-baza",
|
|
+ "sursa": "2800-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa0626573752032362e342e302d616572652e312d643230333230312d7774613037f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b8411207d07b73dbca60d647f0fb0c2379bbce622cd8f7f7fc20f21ff11bc3bb0edf08bf5c8f51e48be30f11a03d47034a0564afa413a3798b9a14baa592d49e9c6400b8416a7be662b24256f264dbf588f86957ae6b02f89487ebfda2e2bdcb4b179916c21d0788b2b06eb76203e7ea5785a875ea3274726d75a1d993dd0a94125ac70c1001b841de10b79506325eed8eb7412d8e70c46a92efeda454155d8037110a1c1bcd57306520c1b4f969dc765a2bbccf5dbbd7fbbe8501a3adb27344f6f28a6ff849b45b00b8411863b53082dce11187228d87158790eac4821837caad1005933d7a475f8388c75fac9f8105f404411a75af6522b83253a2622f8d1d81bb7668aad00a3d63a97201b84130eda34de9de12973a319ec0484282de5693c80f4dc87dd2f0220d5b21a29cdf693cacf7be2311a2a4835fbaa44e4761bf416c41bffe0bd204abf6dce6fa896600b8419afbd2f12b0c55a3b437f2dd3b02936fc4238f3a3ab6110bc3582907a13da65f4f1c2df6f20c42670d1eebb4da601fcafbd4b9c7342ef2414833fd2f5a7f2c0e01b841e6be6aa3958c92e9cce5b5fc7ce1ff7eb46bf35473bbcf1bb94eb8c61ad8810f08c905aefa30aed909f0610ab3f692cd8bd4724610f620a30326b04aa57fc5ae00",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xc16a876bbf85d2196b06664c28ec3cdc723d1a28cbd05ce404f4da1e9528d44f",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xb5e768cb3117ea25175f51aa956b48691025c2a8",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x137496f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xe323799607e96eac611d3654587001586abffe3395abe3303cb31f30f1f2ca4f",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x32f4ce422bfed61d2b5d29b913ef1037cecfb202bb3bde6261efbe75669825ac",
|
|
+ "timestamp": "0x6ab8eeb6",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa014ffaa0fc560616fc8004d60cc1a6cf7680867da7af59551572815cbd43455b1c7f0ed9f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b841443bc4533eef17d46b08e51427499b9d1a4244c33d72ef56f641ae66fd6d447138cadf7ff00ab27ea299d7f9bd433c00b8f61fea91fdb67b64bf3e935208426901b8411189cf07fa23be7783f54460dc1c9f7e0f6bd0c44dfdf4ddbd72889de57f6d4b4b187a13c69227fff78aa82d175fa7a40dc086cccd90c3e405ab86507bb3aa8601b841eb27ff63035be810d34817741f27631abad70caf8c66abf400ae84facc5fc5a574916fa1d0910f87a3ef465268ac70c247fbd106a7ef084383539394c3cd191901b841ef6ad8bbf69c535447a2acf6e2980f3f836540ec38ff2923f35f7757eec2ca74047fded4681b5bbdc568e1e1ac1002c65dd6b7b74deffccb75f466524500312f00b8412040126ac58afb51ed9e57dd9b5db050cc050f2020e9c0c6099e2ae25c77ae3847c90785dd9934e003e6108ccef7ad2e2d42bcecad76b4be166dfc10d462be5600b841e484d72d9ed13b4e9a0d95513a795728be63a222fb63c1877bb094b6c158d431557b8080438c7978897e11a05dd22f27dd0b8301ee9cb040e5d69b768b11e0d401b841f7ff5c5923be5f60d6d4cdaccfc6979ebcf1fe978d8b1f5e6e8232e5daaa9fc9237ca3053984a1db02cdaf928d9c4afe7b7b0d84daf3cac4cc5f46991f93f49f00fa014d2702fa014d22f902910180b9028c39cfbb513bb3da7a7249333b1dab9f007f6be858d505bd16cb51665032fd62fc4b59dd6e911f750171c9bcb4b35da4d9d9537faba39179f876b8728a41446aa12fbd03f5a0adcff399187ef6d8e41034eba8d4c127744efccbf1493a7154f2128b4d6a082dde87cbf5ccd6cc311e9cf261f62a07b96099e5917fff67ba6d2b696110e0dab0891108eb4f5caa5f459677ec9abf8aaace9b0a2a0d4aea39f085ad10f3b928a216a1caa2045f22ba232c7a6c903bae0300b46633b22afb0a223a35bfbd023c7d8dc9167663e64ff6f3fd66088fe1a887a0b458fb2f654935973936773b3052514fe4c8ff208df479e18d2d7e537cd9a71eeab7c66aef27f21f4b2ca294bab9a1933aef8e3880e19a6f73475f54fe2fac861d537c75e2e4624c435112f021ad023897ff7a3b7c7f7df9c890d6bf796a864746c8abc3693513490244d8c51f364fef134f857b8ed19598a20af4c4e38ec423026010d812043279f949626ae6d9bdc3aeae22848ca4e6d88ccfd6d9ff5bf68ec627579b476c34bda9b581985be7566fef86e2f5b2fc8507acd8fc5f03cf7259bd0bef7306c3fa904e91d143511cdb9f0576d62c4f730900add34768f6dffa1796df8703bf300a3e0941b4ab9e281adacba95f17230bf8aef2be645ed9306691d3ca81cb51c5d6ae9cce219ae9c7c3172830b48b99c6ddb1b0a9ee0fabaf5c501dae7a114ee5b02feee510d0cca67388a70f0490c6729cd8ad214a874d17850e6b7041a3996ae7f53ca1b46688c6d955ef14674c878f4d06e75ded784dc3ff672856880e8f0cdec422310304270b64127063992594ec15e9fb6eec43dd0c43aa91300b5ca885d56bdc16489ec553a55d8072cdd21bcfd35e10d8bca952509309edfde1f14376ef0ffd26fd4289cc0e44f473ec1c8eb4f91eb50280b91eb0b7dfac93fa9b6b2b1273ea937cc87bc9f7facba3b0e3926acad64fd1c892246b8c378e32f78facdddb76a457aa49a6b446514af3fa488ee95b7078c0eb0d5ff4d4612a8eb2f6b8f18720803076014a97138023c5776083bd962f7fa4aa9622c12dd3b814c1ad00827ad76486f2f7a9473af2483d920ff638db69457ffbc4c4e68d738cd909b3eb74f90d865743114db1a8a6dd615fa025b5b2234041082873af18740adb27f6e1979cac89af25531163ff874e49a23b978f9400f9a1f345fc22c684e37135d4f518194cd2416ffa534bb73e6030bb736276f87bce444c54821ecf9bb1576a51d24842afe6fe4084279dca12fbd0f66a5c7d8a48892785e174e2c481715acd53bb0cf09df4e68ad997993fc6dde40ec11645c8a5ada2f85765320b34c4af10ef97c3ff85fc0ef105a5b95e27b710557c8f5c6407c3fcf7efc4cd5092bdea62d738e8bf36e219235de39c3310fcb1ece79105caba43109e1d39bd028c79bf28626a4737113b2f2a631474542f608a2065ccd96bc612af085870fd27413a0d48cb1dfbf2b2c2b643f6baa17a00b0a2829faf23dea36fa15f03260e0b073ca9e7eae333f7b51717ca5b5b52bfd40618b6d1e774724448ceb4ffbdbe8c6f15d8f57f4e1b28f1f14fa4c6ea24a8580d770d2e54ff9379d9ad61d924dca8952e6ddc51991430c5ed864134c1ba893786ab29d4556b0b7cbb18f6e720b7a2eb0200947a4191aa591287f38f08896786d568df95b4c7e3a43503dcf132e278bd2ed955423f523cc283715903f51260bf7bb7d7d10d776380b2fea06c4825bdaf43688c4f32772034a52096bd6478317a9285f08be2c0376e4097fd0605020192b028fdda4cc67b367b98d6c2e662def5997c5b724c089ba44f79be86c089a83a376308cec9725d9650b8279ba943aef2ff92bb0fd6388778a31a79bb38caf6e175322db4190782750a2fae33b156b033f2be964341713c55414c4a078a40bc1466754ec69ec023b0c4ba7c64aa861b6785dcc5be0bbb14f5d13a121e2b43185cda1001e319ded31ec487b21b4b81b44defa63d9f446278e3f360da8222fbf340453d085c752718ef8db0e443b3c17437283335cac9e715d3a9b2882a9a6dbe99e3e369cd031d790e1149c4ac1a627f520ff3243ff4be499b7e0f1fe3896f71c6acd6e56ef985a12719419476ff1e937933e0f30013d415beedbc23d1290aee813b169eb710637dc7490d394083f5df36ca807f34198729cbedb96fa9ad63020b43467837c256e5d9db41992a23cfbd677fcb78a961770e6a0fec6ab1d62456b9e3697fb512e682d1fd87088c23520b2abad5e8f8d77bd8229c9fc285a1255f911c383cd79a88e2037b4b60e7ba49a17919caa9efbda85a8d05c51272368a08ac78b4d6458ef4d06ef8dcfdff0c027884d97fb0eac29e40352ba2086a4ac8c42272f619f0be7ad87701fbf1f5dabf6fbf74d93322eb1684101e8f52f85b2b202e49e05378eda0244bc41149077cb693ef7f4ebcddda252af8b2ef49954cf68a714574d332b799420d6596804e26469dea8468a3899934c75b6bc1441a8007d053cf52c6ff7c605f6f99a5dc40a0dc1b3c1303a31d0143165906797215929320a2de6fa95cb1430411de7c6ce9d518632c4eec7aa62f7111c8bf78b449078b6bb7058f41ca45f684875bf38cd0ca8e41563917579d29e395f2b62bf025d4e04b1258fa76172e38969e22fd38f6fc5ccfa461fb27619f73343d2ccf4bbe9496d6836c2e1a4e9401aa3c2e584c3baa3bf47c3b1d7623332e700771c0edd5d16a3e77253412c3a350d8c272422ebadc0bc706b207be29bd3081382aa9633cc76cd41de106f72025e57acec655dc6f3ffe5784125ecb293af9f26410df89003af23a113c3d4851b551ac9179799483af74eece394864b6876d3a331a25ed051a9c7532bdfadbacb5c42e506ef2358a1f75b5e038038b76c25f096f0504f55ab3bdc22bd96f8817b966efe7b39a1d03294f39adb66f2b1c02064a610cccc6aa26e460dace0f1689307ad2e404079d50da18a7339bf0398597dc83dcbc1eb9797323c011c204a7d8d084c19d586f4e3604a351baa9b3e1e99f6366952eaa29994b4939ae398845f6296d5c1eb30dca12be1fa7023453fdeb78a5a2993b42cfb631ed6df52379ddeb96d36996b9a3886e26405cbb046dfa65f512f4868a1810c65e62fbcf8ff91ab3e698e8f95f69e4d77618ca4648b65e500ccc5a0ba185efd594b0f9a9e3093f70fdf31ad3bb4e559d5f0c899f0ca18bad410a2c78ec3331a786b207ba609bdc4b6335ee6c824a72dc53f2fb3fe130b1654141f1b14e17f99c9204217cb0ee23eee76a207b302f737459d2b6410d133fb7bb01866ce6fb5ac6e49bcd305fca3b211ecdc826a50891cece7b4f98a523f740c92cb3b4672502c1493501d938673f93526dc3d35800231e0d926c0d6df5b5fd78ae5af91becd1154adcd31d19bcaa164c822e9b71e984887a75d57b87c54a1e6c7fb6236126e21ca0ce7608ea911f7bcae82211c9734aede9663f028b0bbe58dc9a04f2c31c810772bf47d732d74d2cf9c205cce889b7894ace5872e6c6b062fdbaf972761ffdd1db36433691d747845034c691bc346cf31bcf282b05c4399e2502a25e6ac88c4d38f4d8902ba8dcb268f6901b18d8863775099df9203fc6d78c8d914d96b71ab5d052388b1377223cdb1884b0e2d245866a93ba7b1c0e2bbbd353e8c9d90b94a98194a568f9be2b372c452c760fbc7307156ab1a8a770807fb489bd672923178d4505ad3ffe9cf0de02771561dc859a27ad925b1227a47d8d8e52ec9884ce9d889f9d1dbbc235a765b2ee70b032dabdb1bdfe3911f3f95c24d9f2af35eae993330550794c027924cb52a2eaca32616958fe1eb5923f7c4a09fe8721641113d178a59600ecca410930de9b852de97318a2926d8f2beb62233029f655b6f5d0a66ec581fee02a93bc7af5777588313f0adc712756380ef7d4e64abe92759c3e7478c50fb2ef52356f70fc9c8f743d5620dd1d13e575f44bacdd81dea1d4fd95e28b158c75229afe7103f55f1a7592942877ccc8f003eb003ce5b901e896787de5f7873381a5c895bf81a4b53218661373fb25b00bab3261c8958f02d4b886518c1350f2522d18f93a538ad629c7c4cc66c2eb65486f834b637b9d96f1beb8f0d2046e349adb9d732590a19a584d50765245691208416ed634632be4fb766694f7a96587205b30e90aa85f538d9d79e5745fd8dd30abf34eca9bd1cefeaa1a6254be0a21773f6c2c51b7d72ddc23e31275cfb8a2b2a62a9392ea33215490f811d6a96ed990399be895b37f98db3a3d8c60649e8676b9d22a0bbcc02efd9b1dd3847d149306d4d85fd4cd117c951d109f2b573d1d797e5651440e90f925aef669b370111c4d5a063af4b6e9de5dd16cdb23c6d588cab21c29495b77e10a27112b7c38d1ae2b5bf04cccfbc1edf32547750863c04472e78b79fafb02675051b7d19aca780dd741665c52d84fe10e270adf0510ccdbd42578c91612372beb96a5e1eb486b2f592e3ea9642aed9af32d93d87e458071ba97149bd69e138a01e487e84dacaee841dc9fa3fc5267a2bfd7d1033d4e005e4d70aeb47099c7e412d4ced9de36f67af9572807fbe84690b60106d64cebea306f7c7234f39c2769cfcdc3b5ca3756399cea2edba9083dfad66e1a4302a54c3fe49189dcef20207898767e1fc54ef7a0b25a4bfca3ba1f3d31f4bdfed27cb188b72af1134969a6a38409882d2faa20567dd8e442a7d358f51147d325fabbfa97f0784edf0000037a2957c67b09d8e8d9cdc00224f32bcaeaae131e40732fa51833751a597144fcbaeb91631876b6939de40c623213d20a3740032cb5b68c43cbbec88ab4e17fc78373358e8544246f9215c4742e9cc6755924a5d8e07900d5c62ca0bb8f72a6d9f45caf2c42a450eb2d6bc4f45d5cc440e20729b44085f5dabbcf33ba140c5e15ffdbb4eed2f61e4bd9ae5a9618e2a21ea65c0ac3d076e245f69edc12abab1a708b264fdf1f4fe7611e2da85f98d9428ee5329e0149a504299a867ea7e52ccd3bb11975ff819d4c3a38acc73a4ebbefd4e7c050ddff44ee2846c153bea424ff723e0c43303f4858e38bae1b4abedfc5782c306c56284a8711757c2b9404544df790f0d62081c93758723094351b97d49820e6fba723c0293e33984852f73f228d57bf625e582e63289fa037ae95aa662dc1b877603456e49559c07cf5c6b8b3dac7bdfb96b5ac503a86ef89880863d2eda220c5030c1daec039be658f5aa879b93bffe0d5e4e733c30d2ec6b7a6a11295f22e18a49e1f4df83d66a4dee76e021ac030aa3df2d7b96143a1180fd59eba4a31099ee30f46195da18bf0f6a10c5db4da8caed229455e5d149a07db423cc818cc1edd28226e17a3d63912cc007a906409f972d50105ea0efc74618db101c39afecfd340c7f768cd3d0336d0466c9b4ebc73c0f6098463bd2511e93103f019ef5a61b30d95c8a2c799c9063f42e1cacf4bca1ec98ec0bca77fc7aefab96df40dd69b68e793d617fdd045c2e9cf978ec164fc259df6cb40ae2151a2853aeb82b469bc197158373d71b68e764f6a64ed867afd338526dd1a9152f67c5c8a29bbf6253025453c030e1bced0a54b91bee926e38276cfce7065b7bdf4d9a3b9f8a49ab4373ee68d38f3a04e908e7670b3a0a207d6dbcc0f87f8cfdb5846d8fed5ff02e12276f14745bf393308adad853be83e674f9177dc24fcfa6b9382f835ffa9cc5972c52a32cb4f1141bde4c093005f01043ad89caa86a8efdf8d68e8e8fad9f4096cba1f4285a2a5295cc76de683914cc51f1f0f69a974f4558d3e47d4ce408822d068ffa335001c3c9bf3b12f108866f63574dbf194b10eca0bec38c07f00b4d133dce30bcd2a8e95d5af910ded412a2ee0397e9691356ae43cc75ec926e2aeadecc722811762183d6978fe6aa93cd227d1e90840012457113d9e1b90f495afa6844bfbb4676317ee212ac63933c3bb901c8b0083bf5cafaa06f20335e4b4f6d03821e57458208fce1384a5f5dc63bf623b9b355c8ddd7611661a32cd7bb9447b7548cebd2bba9e03d3214214a8f95c90f16e7b23cc47f267fd68b78905b83809d69c4f392baaf236e381c8cac9b56d4c3c98623e0124e8a7c002ecf40a57ae7f96667c6edbe0da3ef6b654cbc3b5c20966d76e1c30a4ab02ef7ed08015b7e27aad90a59ed6f472cbe8c4b862a34505a75db49be6510833ee424887503805e30292608bffb9b71ed5da9a783691d1f28a6843552d6b6cfcd7d406cf8b5bce4c3e9d544af02c4f172523714f4090cbcd47aa4e13bfc4a66ea1d36be5e38266ae77691754fdbe5a1b2f8ba122be589aa8948bd83c4fff4770a62daf4e4743ffb5514c1cfa4e41f0b7cd5f0364a61e4ccc4bac364b1bc1b3a190053b77b6ef1dd38fad02575470c52c9febcca4616feb4d312c404ff0da1a71a3aed3fcb32ccebd1bd659fd97a603f610cb9b947f3967c9aebcd5aa4ea535a48c1700f605f1832e8d9085af1fb6c9c84557da007493a582feb47b33bb2cb5ed42e56c8566c4d217b976c000bd908ab292d273786b9c1c53d9163393b8919fef4e116aec37b1ee8df16a18f78afcdd43191553a453b9f6999a3f11574658bd0cff7aa8701cb8fc4095e1252fe2d18ec5e2c4223df38b92c48d22c0649a640f732572e52d3c64911b43c77983d43e4b6fb733a7013660ec3073abf91fa7d1c0dd8705aa6b5dc7f36b851bf528b7e1a920f80d222a23d542e37c1c74ee291b0910097d2135538069f87262396302ba755c9c04df648aa67b600fce0ea7c390f512570fc384c669dcc039210af2d6b0ec80a7aa80aeaed9b772248e34d7bfb47ba265d0b1dbed24b569f374361eabb914366c640ed649965a058eff69a5bfd822499ffd6449692ffec7a2e10fa36ffa985fb363bb6a711ee3cf824a5790dc1929a7fd23a00205121842f0009712b8cde9154e823d8005d67f1e4c980bead5ece628acf2e6381c0ff874c25a30ee07c1c59f6c190079474e673ccd44838a56f3a99a4849eac6547f11574c91a271b1ad679fc86bf823130d64efd3faba415d5dff18a3789b4fa1ddc4ccfed825178c79b44d905be27e6b321b1adaf8841214533296336b33f232e13868cddcea38a296ff8040732b91bfc813514eb09ba118c057bbdf48f3445870c7e4199202667d9dd2058962587cd8961002e096d226de4232ec0d18c43318a5baac7d2ae82c1ec8ee70446261ea1664d0083f6f44ab69fb89afd0fc70ae0787a5befab8b9439da27600d957a12dd7b436f99410668151cce37972c8dd4e7902db60ee959ba167b7a0525fc6524418963ad79ca7611cb59da7ca7d69ed27d49a27d17f2991cd4b8e8a3abbdcd93efdf43a6bfb65ca4b9a784190ed1401d917f78202a66f6c513cc34102fc17391897352fb877bba878b8e34acb47b6b395b565b060929aad44bd0cb6b18bb52584b3338c5bd35d36b0cbfc9c70817f017cfa14e3db29a72d4a35587f233e7c65e769206dfeeaeb2f0abd27530521784e667895a2e07fd7225333e24eea94f65d5904fafb66b0ba16942e15336e6df7aa235afb1c0a8d49194848964bbff107bd8c9f04b9f2bd12889986cf4f6dc36ca7bcdca929c862e3a821b58391a46b960c134ba69bffcc8385a0518331484861335a8bf0c84845703253da23773fc39d66ee4584b7bb37e2e7022afd971ec5c0dd13092db269e4b6cceb60e01d0f1cc62707fbaaf22326adee8cbe37f65d2ff041e58d0f8f59b6d60d795b8103ac736b7797aa01b1becfcf64a89244345ba4eb168ae22fa9a24539cf870c58cb0c411a3a00428357b56c8d12d2c7fc3b457a5bea131c22693133c2ee7953c2797bb33f0d222e0f6063275d4a231925be19ed14c01f7011c20318f80a51b5f7f849d46f294f877c74d3bda975956981ce8839f5cbda8792ba1061739f147d652457c63b7924c9e024ee2a39678093f20479ac161083f388824a68e199bbeff671095403cda0a37069ae46ad89944a74cfe559e1e5255c4f0ed2f59df68c487b08bbf15416d5a951ac7e16cccb11c00058f8266282edfb5aba703b29ea76e87aaa535f1d23fb8310255b3b280e458f0af8bbfea1134d8babd3eb107ddcf7ba6e9211306a5eaf4918a4438e672130cd3f6255480fe079efb58dfb22469e8d12e2d8bddf0d77b7110b4b4c7dcc0a8616a6ed402029e560237f19293fb884e71707445ff30d121b1baff543bca1ed834c0b2403b2056c42b9fb8dad93dc95288e132ecd29a5974c53d126160ad1b5dd3beb103f7533688be6a316a4c22c09573b6abddcdbc99d9e86866a8806eecdec0d0c39eb9f6d19b9a1827dbfff87c2cee117114aadf516e2c702aee4185f4a45cfeec60737fadb7f67b9c2eb2383fa7d31858e374cd7303e8ee374cb698109402a617f35a9d1ad07c8f5bc9adc0f82cff163d740085a32afd7ca0e9c7ea192d8f1ef2e8edd254432d2eadca4b8c6e2bc6aa458358bf424cc9103492d208a22e790bba75995a3e9fdc6b8601c210216fa8e1416209f7fc2b48fa7863a3b4fa64136b8eb337b1614ff425176076b9089876659e340533a475b6c678d243c22929eb4e0a801edc9128bd17072765faba8ee82d3d5df47fefd749ad1f895b7b6d18d89e63192c8583506be78b336c6ac470c55de95bced5b739531a274ada8519b7a8bd0e15ade4e425219bb6f93bc3593a471f6302fdfdce1a293bf9974ac2e6b07dd168b1ddf738468ce2077b73c8d1d89eadd83669deee4e2654ac549b12f62129380d8a6e83cfdd550fc38b5cd142b9ec54af48d71d284fca54e5cae7de5771425593bb4d8cc5e5e879e23b713841390b4a1f2f4b077e8bf01f625c5e01bf73645f82c37ce97111a5ee50ed472933e3fd01867c37cca87d27e0818ab22e85a4543faa2abc3b20d8f9967c6ad413ad2973192a63788db73716c990ebbc6481cacb7896787d6530d992597036ca830cb139d4b01d38847b12602778147ca1380394c1a0ac864d5323f05abd6530b3688341b876b7e3ff41d0013a9e4389e0e8955dd0105e029250c9c8c2cd7e35ba9d8a73d44536e8167fa277c9aa5ede504a35d545904a1a7df2c046e8b8f5cde07bdd06854451e62ac01fc5ab98a2f921aaafb6e7e5c062c06b56dd05d45d967f09deeebbf6a3ecd989743e17e857b100c542d6cc951b8746a0f1cde509492c596c58b6799b0b1f2f1d101e80d6bef0e47c6949e33abdafb9a65c7d6a94dcab49261629235e19b785d177d148128bc22d3ee41fdcd0c558de4abe405242023bdf0b895a5d0b69374bb55f7333ca9348eb1a6a35b3f770eee28e933eb6d744a629826d4fe794887066f63310ad9f7c1a6ee3d26699c0ed26012bf02048c72a8dc978f8d7a78a5ca80e9b37c62f8aa3fa49d0b3b81716ec8cf94c878990624cc40301e3efdbcef7b998d3495576cfdf7a6ec500effddc4993ab8c864df4e3a65a221a8e69506607788feb734cbee799ea32ceaba1a567ef622d4b1180f6fa4169fdbff8110aeacc65db5d3017f7113807d026ef0aa834ba130763275f280e20880cb6a6a9131ec42e342ad4c152e3f9da32eba7d0a65ccf4655d00703ca5aee1006742dcdf8e9abdb3a6dd388c477ec5b80b66fecf0fab1e96e50d2deef015f990ea15b5de43813346455da3c53402a605767f6a0c8f73bd381d8cccd4270d9c0251d5bd5883d890423af1dbe9d0f28d6bc6dd0c4f7ad9068f05016bef2d841e4743f3df872d77b3dcc138ec5d78ac82f634d6b1837aece5519d0e47f01555c4e1b941335e7d9b38bf19ab9025c62d0356614576539c36186d3097e992a3511f11c6dffeac6612f8e0871bc4085b84bb32417e4809577a7113a15dd838e9f445d9596bfb13e862d901da1e7d58e53748de066af188da3dc55bb61e8333217ab188f270aba2a83192e5cefb221c0131982b8d0965de4cab9fd6896a5751f7e156295d463e63957e06f693b681f600b35da218e592f416fd0be7d13b5d0db8711cc14e08cd0063c172afa216f6b4123e708d46de87a922bf04a9fdb8df08484eef039bad3cc51d50ebf337f332a9e2414203bf9a8eba2b29a14675b5c3c8d740cec6aa2a54ead5e2e21d39b55ba0d5eac65cf3732872ca2203be96cd386b04721190f83deaff78cd88ec92b48252c40b789276055a73a9a351ddc19b8a80962e4bb643ef2db3afd1610b7deca70a498113dbb6bba8a529c766b0e74d07273bc16c4506687d52f78e8b0802b4129e40aaa80d501d60073edd0c6ad398a5ff2400886759170d8102f68c5f25231b7d173c9693b5c26d77773d0c4ed8ffd00c0469957f9c8ffe78549538edf15745819fcb39a20b35ea36be99db761c0b579f38bf0e8c428b2d0a263ff8309d16f80639627e228ce7ef475f0c2cbba12c1eb38b3127c99df45fe8326f1435e7484cb334fce2df045442f5c5b057f481972b195671f25d78310d43d10cc92fe8eb26e75998431c04f002fd53f9c5fa59c0e1f22dd6a9e1ab25b57b69971cb7bd561ce818a3fb7e8e3a112414c72ab68c042c305e5602ed5c0cb4c98b514187ae093df286e1969218148723c98933c794c1c5973ee9ecaaf2fc35dd9f22252e62a66fcd8bc5d12a3fdfe71f3b330097d33da3bbcf63e227d24f4ba0f025c453c10a1b578e60acf237013c4766287c71e1b46f5b5318f8b20b2dba7b22ab1ad49ba332340e09db734a0fd49aa66675361478b4b03860964d30bcb25e4adc8becad530b9db3441dfc7d7aa215feae81ea124bd8eeb8613b9fa85c82d10ff6d2f753c02a17acc3c4948f3c7a3d02e353cc3d4944e35da7323b390ceeda248f79c4e6a460281b13d29d34b2077a6df82c9149e8308f3fbe4f16b070e061581cf3642847001aae2a17e0877edb499ef5bf12cb2629d8259cbf72fd85a5e42de3f070fd3de7d09fed2599faa1c1ad23a1d656b0b18ebb65303227486e941b99d05b87cf2b9ee56dbe39c99bb5c3b7a658876ebe41e630854d683c1f5f3489ecf62ec76e723a73f68260813b82f01efb24b0ae404e158ecdde10695d49f1c380408e80277738009fd6827ba8c099cd1a4789fef21c0b18adb309ef0a09fd6b1f6cb960d63a8dab8cbf88bd5781ccd9412302cca9186b9d244a2ea8cd232f7d95a406b9fd449a7c0693642a48738260c4ebf92006c7f41a5834c9bf7132ea385bb3ac7cd604de0b9066cb5bfd67f2643cb8a696413701aa4cc73546599ff1616e8fafd5060375989298306a14f8c67af3c6e1f32d5c33ae90f3d55b799249d5bf7ccecd615d29e6d50cedb845d88912faea86613008c66eeee9c80863fc4debeedddeacd1bf728c9f763a8a480960c01090abf4029d73746ee25ac0cf80744afb35e72c138ced870c6cfe0a7249753f1bbc74f277172cd8f0f362059f12358e76e1f46aff49d2c80d95638158ef336c6aac8fb42706949e6e8726d9d5e7c76462acb91b9d48e87c5fbc335ea7b8ad7d034c233b288765a0b5b4e5c92d0d5f8313cb134c66478f5156b7617f635ab93eac9e461df7665f1f5c74f4f85013bbca966231a0f71a893de924384dc98c7f1af938b71a1f0a18594022bbcaca19f0b48c6d8f3873f9297e30f4dc8255f45b219e7b2f17c1c5117e772d4143c930081bddb8de9be1d1c800cae5e17de5c1238c7c6e6905205474742637ecbbbde8c9628f80a01a0c37d83971c8ab6b57ee3e0c8c25ff1c0a2651d41e5d889ef7fa6a9d479adc95acd8a1425ed54ef5d877073d7f543b7fc01e8f2aa8d8bd3abf45646ef06a33494c47b535515a94161f7faf2d50cd10c2ea3182e2214e9240940c790ecb0eca4014458084f67849a405ef198bb88fa083d22ee1d8cda86eecabb706774215cbbf2d24c78a7285eeddf075c2de26ecfbf4ba8c0d992107c303f89a4057fda510b4a528ba7e41818887af5a6e7378a3d61497fa8c232b0425ec023bf67cdc27a2188a89d567216d534ce34e919b4e1e2263974bb299836f18107dfd4dac4809d14df902940101b9028f39dbc0394f758205158f46a51b90285a283198ea989254b919f363017ba6d7712a390bf2ad67a521d6345c5ed5e7448d687dd49e159f49f447d97136fd1088eaa2945b50f33f5db1e5880421b3ccf3b070366927f8e5d7262dd07671870e39324d21b269bc8f5fd4951a5ab339c2aef020eabb7a48d092e2e9ede7131347d1a3c762c4116546b6b126dfc697a756e62058347c7a3ee33b4f993b51a49b04d427872e65078c8b1214eafceeaa347ed118c35264f51792f1abc499232e832c4b27b15430de6939e0b439cfd38cd660072fcd8dc3df242b6dad70a873882103f33a1beb9d0d08b5cb4e0994bb41cf9e4d1875ec5dfedb6ad0d82c58e94601ace128add38c96d0eb52063900dec2fadda9ae2d72fac798dd01c069d11687b9386869fcc5a5d89776f7742a62188778525caf23e448aab145a5f19f399087dfc50e748c0ae4cf42f469c3ea7715fb3cd75eacb6d92133441163c52e506ccb2f9b74d9dc3491dde47206aa4d25a76ad9f057d3fe3aa5a05d490ba4a6b8fec78349d71338030259e0ea8e24454d5be11130f8a61e87984328b687cfe1c64f1f0d314d67975d34e7d5dbae63665e9def4e8bc9326e2dda15ff8abc96e92093e44b536d1cb3232d46ed9dcc1312394c4c92c3c3a93205e108c0fced9d97af5ffee83625d12e8c12a1b9632cb0a98c04d3c6bdaf0746a864b29a345b9e9d7798acb722d94b4a48fb1cd1fad29f3c5dd0380eef8ee5b9fd4398acf235b48ee13c11efa53e493083d4475bc26690d8009b69a049c68989799018fc4e2073303b1c9338f073d2b40efd709fce1b88763de394e4beba4645de68287f762a4e9a631fed2c51f1ee94887b7da9b7b9c90418eb28ee5bbd164ca678fd7b83b0caa3d2761c88a78a16fab0844104f8b57da5529ec53d9010f91eb50201b91eb0804c99a665b5c993258c1facd7f80bdc1fd5d0cacf88949d47eba225e7aea39a927a2285fa1675829dde8e27e9f562439ee4b5513401588e8008053105a3d37968afe988bdd38cf1d4bf2383bda104a3df634a7e7a3f6803ef96178bc1c7d4e871ed963c15b9c6188effb7d1d276aff36f9f82b2e2285ddc63aa171fe78de2e6a2e4025401e845d0a126e188b81b13a44b18c6e306134102f686c7934c1245d0690401be1d572bc685b5d2ed9e666daa36d388288b7a18d687da92bf90d46af4c06d0efd605dfef9bbd497dc0a35b83448c7f331aa199331144a512be55a723ce62eb50857332b9a0b52c127ac36a9ad4737d605c2709f21f2982113be3c95dff79c02ad40d4ff3e65591a6c18189a30ee43cc52c86f92ce91de1d2154b5ee6d8bbaf6d9cdfc2baf7584fd6b75e5c221f01774125b5342a70be3385d733178bf99bbbf125f3a8a6c160bfcdc3f04cb64d93977c50a77bb99722f8a1ee65118124169689067cc32617c713b83e0455fdb9a83b86205792eee765615fb240ba1e11d74bbc44a859cd8f17dda2cb809fd190ad382fd4c1c6977cfb3faa6a1735bc9db716402532d7de5e7887ad0371d0dc4e2c6338d48e16ebe2dac159824c3bfa2e61b4f9ad75428942e5165767948e81dc95ff4a095dbb9359bde6ba16afbfa82408361c6507216fd7f023b8fa54a83eb69f6aa73e37687f4a6e9a78488913a2b7b754a4a58209580e08fa701c7a363e630b4047f8b683697a8d4f7a384368c7b8e1057cfaf5b52b6bccf1a689e1b2f71355d1c2696b3c12041d1ac73283d24e74d09b6b5a55e355af998d537c6b2b9247507a563590cdb0e8cc97e28542c14d5b0068e920fc4db361d88771715f24deb9a92c2a0feedaec8624bb7e1911a29ff4934e6d95039a6d26fad3b5d964758927209f356414cf5df89df3dcadfd53a00e5f063eff61cd8ebe29edac7d3fc37c740acc444b62cf99312772bb22397d0d3a8ca69290f902da2f9eb366a63b36fb7c241fdc7c2ea8ee59488380f1ee62c174530249912b1d0b709efe08dbd6e82f1c1e38dbeea34146c17599a210030b51306750ade659564e7615cdd725a8021c6fa5b21796ee1da9fb3c7be3d7a57952892a8d04b7aad57c2152749786fcb758f089d9a82b064b2236a33e422c1aeed745278542f41bbd29e76b72f2c0699ba14aba3417561ca150acc87dd6cebd4f662834caff2ce94b8a445ddc59f271681dee893da1839899122a9a6aebcdd6f1e402df3cd9d1604c16a7e6bd5a2e9a2ba67518644ffddfe575c4de14c526d6ce7b54b323e342462323633595de6313701a62a5ca67dfcda884fdc7d814b98508007428d2f62026f2ceb68372aeb7bc0efa3c3e9ebd02011e63e99e29b6d7ae8ca672258d70459d1a96dbfdc1656d0d78a30b42f205570cad80ac2be07e2bee49f2db38bd5d1f38503895ee48ea76f1f8a1c29b77411c112f0e81847731db367ad14c05060a61d52c200a2688585b69537003a137a16ac5d79b80f3ede7223fdb4718d2ce082f6158ea3417602cd20224644d0c303a62cefd99345a7a6b22dbbee4e31e9c50864121fd4fed7bf071a884b9d368e76c8179514695c709c1f481ae02e090eff36e6f18448d687dd892fcee855d1427f72dea1cd7df9a86473a3c320d4459cc539d08d5e3ad1cc81b029d38c96e4b79fe8d1bbf2828928e256e5232a00de25e8b39948a707f20b5ef9fc0ba153aeee0a11f981ff3727afea2584a50da84041aba6f3af043d4f9ffa230dec7bbc0083115c9fb7d0f27fb1a5bdd8cb1d5d6fc9b1b2e52063e4581f1e99f554767e292d24b46667c99c5670b7ff1ced36901c279420f182424f5e07ade33c886f77c77239a22559fd39e89389b60af5e8461758f94bfcb3c7568465b5f50f35b8a91c570b97f1914690096c8e5db3393081258490dbb671dddfb1ed954161d2503051463f95eebcdd2a123ce62c348fb9535c99df9a26d380984061715283c1770a885834cc3684c100119f5bd4a49852fed9e1ef5531376f0893c9228d7d431c5fe33ad2ecc548150d18383317ac185fa218288c0b18184ee8c7dadffa310582df0613a6f53fd272bc2ffaaba178a000e8d5b4b21514410338d639e1d1ec2545203384f154854bb9e679e1f4b7f080dbdc276f6acc750f62f6d2d67b36293a83a9ccac4fd64f8d8a98974529efa9646aad3a7b389babcff91bc6c31a3b57820111df8df2a11013ff139f9a29996dc2e99952aed09ddbabf3a5f80a42e53ec100275a4c1e1cf9f28c47cb36d888bcec6c44b4cfae96bfb6be36d3f9634e597923143c9e7ac91f4b3bac6f816b617000f33caa3f809e3a1e2a1027e5e9a417d6d0f5a039173762e07c02e9365a4bb3a7787a8d921d3b453dfdf708bd657151c0f254374007309bb73f5084ff5037f0c4848f306e356b89f584eb1acd49f9371f29baa7500ad3ca105a1c4ab6f84959cc23a608110e0abdcfbbd0464a9743cea099ec6204677e8edaedf94ca83c87e52f8c038a30168e2382189dfadc945add77f6c2785518634a52596bc15f0c2e93bd4c2d0d4be8a2a45ef0de6f2532b4313b522825446f15f58613dad9965e2c9c4e10f32f1fb1c7d9e17bae7bb98172fb6e98e58c9c7bea40a4b421eb4a1effdfd55df5b7d220c7c7e39d05f17639f1e1456c984113f92377d4691247beb194be1b69653025a1f6c44b6d0f2ca3254d61b5a7696aeec232992cde9fc84edc601b6765cf7943d7cdecf0f3b8a59d5af12da4d9a5b7679678c5ee0bbc395a5d4a96b78c7cd1a7ef88acef7857fa07a17edad422e0456e230ae61432e976aa1fae7dd91be016bebc596593291b07d6423419ebe8b97bf2e55df7473158048c307deb44bb34fbc9283c2213a976fca4bcf2d24f5dd344e9a5899b2afd0a342f6407a4853babfd4eab9eedc690cd2221ef6efd5151bb62f5a75330c02909a78891cc92a0cf63a67e609b5a3e24d54214303bdd19e79d128f8b7eb0dba52743027c906c54da7a31fedb4798e4d84aae0d3106488b52cd48f83abc4a7d3e9c63e0927d4153cdb5a87bde971a9dd55ee9c60bb285f466f3b66f4a60c1fedcd7429c7d9d107a964185d043b61e298634594ae231c3b63580d7ae5c3078bbec56a1c9e0767c1afe7ad314dccc70127ce6a107a71cd5dbb07829d280fe0fcf7957f833cd50ec842c15c7c3f348c86a0c283df75e3e9154153a878ff447d9ccf15c44959028f409d7cf6af8fa435663524ab33d18cf590f75d8f2b82d257fb585760279b9da4543cc5a9fb7e778375b692bddb153cc4ef29cb603b3c34c85d280e65a57856cbec57bdf1a54b39a59e406630763163ce4c8afaa5c2be5ae12c47317c088328423a5a9a1928bec54058c8901f964171f9e4f7fc9e56b1e36e6cf5b7e6798539ecdfe291e0bf47b459992f0d742eb09ee9e566ba4056734d65bcf365c032a17277f64e2c166b5ce746cb9ef53a4d42662661275586f1ae24b5c84113f88bd149a31cc2f91b762c88366a4759b1e5e44a491be43a8eae08ab740c010af357f42bfede6545ab32379a4729935dbfa97a0eb37fba9b9fd29f0a43d1feb0634a4653db6b669492f77c90cb935ca927bc44160c225d1c6eed2ea03eae5b22134ac3f51c20bd48816287a746d0b18dc13b8fe66423e3e0ba73b378a1c6974d7101a674faebdf9fd088526c82d48a38cee61f274f5cdc6dd48f4b4168b9f9b5b4892ffebb40c0e6585f6d556800bd9acb3c0ace5f4cb48eb90b6464193a2ffa709df32bb0adf380dfbab07e2cdf227bf7a9d3e684ca8788771653272a4d6abb490dc79df0a929bdfafef419bb32ace1061cdf0b4be14026a93c1c0e612eaef9eda7d678297c1268c71af695dab0ffb5e7791c9dc53a64995a45a6284884d7f9ce9070a5f00c26fdb19aac6435723695d93cf43113cca56e2c083605e66e08e60e9e8f332af7f7dcbfe3ab7a3ba6ea2995a34c07b095d6c84b2ddc780ec7434518c766f6e7d76bdb1f5b3ab62c78a8bf15d917293ca989eaf32d687c04679b1edf4885af294df87ac06b1abd5b5e580d6485419dac2579a65d2c7506ae64042076dcd32d99ffd3e1567f4b98b3995a588fe3e30e79d1f1a55b12482dfac5d5d5eb60810aa37514524a1ef2186ba37e707725613e6c708628b34bb059f5c0ccfda3f5ccfa94b95a3eb6808b904ccc03af4dab299165a3fc9a0352399a45f5dfb570f2721b2ea97c6108e74c10e82ff64b82eb8e588017c0677e6086263d6705dea3bad7b5523f0fbafc57129d8d59a272641d6ffe11afea797448f915a4fdf28164e218e5914ac2ee3b7c6f37bfdfd802c284a5ebec4019b9a563657a534553e27b5a1d5099c5350187d08743cfa9e0812f8b1efa71414961e58a565e932ff1382d2444e4d60df856434b269c343957259248e84a453c4da8e432462a304c7f986dabdcb9b61e2a8e9e03913b5e74a09508c1480b3fb06be8d8dc0be57392e23536276f703279c596023f0f3c03c138b3d04eed15a04fa2ccd4a12175046db74773a052cfacb60926db1f56922d66e83c0e0d61590a1f6bcf4fc6b4b2ac94ea48a503848465f14fd02277efe3c5e221b0c86c656588060a4113d816a31488da48bc094ae400a623ac676de6e2ea27578f15013f9b750fc836daaa6168fa9cd18720a15198d21515203c1151938ef41d1a68562fee31da239b10429db16591c1fe8bcb4444b859a98658433d4723afe9202b0fc179093873306ccb2d5f6ff507f6fca280a6ca70060cedf65c70ac7d2ac2c3ee001ec4a69d8f13a4951ce3b9f6bdd7240db78b7bb5ba0183a91dd68a7296d16f8904966cccabdcbf6837806dd47980b50098a93653dee0751012a5fcaa6b875793b42457a9718892701f8784ab8d080a1c8ae1a52fad634691886faaa03a14b83353f600fdffab1b5d6192cd6b23cecb6c3df0e2dafeb2741af0d274ac4c30a738cb45d12e9d59256ec76daa4afdabd101defd3e0f9f4eeeb20aae3cc1d89fab39e3a5b527a1866bee89f4279263ff450d64b828bd3449dfe58884b252d5ecf647d3b563273e5460d5b883798ebf244e8efeabce1a346063dfdd00a73edb059b35845d3f85edae64f7e078378102d2b22b17c9ae125132c9657e71a88a21bb5e390088dc4b9c732d6b8a8ef65c46fe8989feee512ebd636cdf2a164bf8c8f304d7fce01355221fc5bc5c10c3d5e0230ccfc95e275c5215548a22c3d230abcb436fcb30f94177cecd978cebdbabecef6e1655b6c73ce5fa7fd76f780efa70d4de7a9275e0ef4d075a1e8bb9cf0c733926ce1756b0f1126a544cd6d8a6fc3f9d80cb13fffa7c69c1e74c7e3d48e984e412ec16cbecd7bf9b5b6ef1a1c06543d1ca609ec9bb5aa4d51c4b705ee79b37f797e4de20bd2ece69aa9ab8ed924f1e148b7f84810b5156f0a2366ae3e5a37843a7f0a9e946ea97784877368552b6bdb988d8f5ec858506e785b4122ce0ead90ab3da6f6889a154b6e630452f0a5d75558fbc669d89e1b914da6d0ae69c154bc82e08754f79795564557b075417df2f49c38a1c4e99df9563ca6a88e9e3cfb38fa6f951fd48152545e93457b63e0dffc410b19f534f4d5ec033ef29fd0e1b7d85ffb0ab25c4c0dfe31a6a4394aae9cc6973f413e41f05674d63267a519dce8b80f06213f3d07222dac03267fef5fc1448aaab70fb9861491486a599b7515d719b964dc7c5538056a60ae08052b23268637317c3e4aea12085bc9d937be9ac0da1f711ac8859849a3639bd6298b3b3e62e754dd3cb6c4415ca5636e89999544e032a69ca0a0ed40a65337d712f46ab4f72450ddd304895aa3ce497e7c336beaa0f6f1b8ca9eda31b0a7d9c5fab7a043c71ff1fa5a397e7a05348fed99e8a8c3dc52a9369f49876f8bbaea52396938fe930efa738b9e88c9aabbbee34f157b27cecd658f1ffc36223b07a160d50d9f5c147c04764d3224de0f64a470f117a5e1d6e0405c6ad36de919b8e3a8c1f283af531d47d3226517550942875b3f45e8c2ff01f12dc70b0affc0b504ce08cce802f952ea731442444b0d64dc9d0738e877023a227d963adc7f15a0d878d7578b6f89ecf65aac72bef7c2a5e1247a6f434715f6f63ba70d9fc3cfa9e6d7e7d877bbba0bdaf4c9c5e64ef2f64acbc5cd89c55dfb5d7f9cc3150b6d068f3404b1c726dd7074122e81dc8c68b264334b45a841185845d7f28a298dd48036234ffee49576ea05adc9d7420e4d51ad1c5a9fcabd6badb37716166c81d8a810235e3650208fd3031ebbcb22bc0ae32b34b73529fa70092caed2eac32351dd750bbc162da9a1c86162a5551c4e6153daba467a1b6f10d4445d313c23d5ff0fda38ac741780bca8ee27d1cfca7792b79095252941eb5357ed1ac192f6445ab0a18cc6cff131c3bb77f47cbcbf285c16962a116049376ce8587d6fd71ca2f907ccd6eb122d140b0928c9e64885b500055aa31e5ec1c3fb186ecd4a10d81dfdf432d6d0489135596b8e98505773fff8548efeeb9936960a423847772e660439665fae38890f1882dc9ad1c18fdd01cc8773fdbb14ed7d2e2a4bdbe3ce1e8613123ca25b634b67c55a060b93a7997a334b4d84b6a1afea95e835d6169ae1abd1f1bfe0dd1f286a56643c92a2e9b12c3acb5439ce2f04cbbd5421c0af3093562fcb42b9214ae2e13b3c8f961505129938d8934ee774c11e1f2b7796c813a4ab1aa0c9839749bdc75221b84e4323f3a5a517b11963ee014e8f2e74fe5daa8b2ebc0673c3340a37a39786a8f0da7c5063e821b76ec75360b47ac19c0a3c4866b9785dcdb71b3a0eacdae6e06cb182a4f28e8de74b3cc4936df2d5528463b8ad5eb9c6ae250c43664fb3f811908e5eddda1604d0280f0e528b6946b0462febe4dbf19676d3f2e463bf5910f0fbbbc2e1b11b90266f34e0ea904df53d859e5360229faeecdc6f9678d5b8e23bfd26b266e1e054f0788a1117c6a478532df11a1d0c840adb63acbc97282ee44c653545342781c5643546a1cebfab1c9b5b6a971990fa1f4b776df731898895e34fa9074d578cea53dd138dd160b5b55389b5d6ec247160a3f58f0b6ccca9901381a44670891f835b1fb35c8fa88b3ca24ac5835391e93107ff956748019f47269c41c6865047df8cf7565a7d3859a936309390b1dbd4a2d8c3a3ac642744bd5b08c55474bbbd56aaac447ffbb5bdde4b0c07860d8c30d576ef49fe80ce04c3f70f29791f4b9f28bfda9f17ef9d2aa9d5b92715a0fc8f2fdf8c41a4160426604c21a9f3ff75ba587fb064d4de5aa70277c5586bca847af3d5d33c9e71bed39b58d3548aba82f64f4fc38e67ec9c65177c3b907e3fcb09b1b33af63666acead9b4d9f3ac7506e72c0e30110689ec9818830c386aee84b2816d33b7fc05f70eae410580ea026c7e8113e9b17d2828976f6c66b7e3d34f2b4eda699bc8623edea183024b66d1f99be1133a227bcf5b383a768a61ee457d9fbec850e0946d10859f9ad8eff97005de0db5070378be369c8bc2775601313d23462f6ff4453efe633933ad75205c354b1b9257a8976bad9285c71cbcd89f6d679101569e7bce34f38fa68b8f618e2fe7c856846c135702d4a6bc811a4024b3d19ab813c0fc6cc26e4cab06af106e798c55acd636a1485c2751fd499d64221c300da77d4bf25ee525a9189f3b681828952029fbd99206c53202eb0d2d5557e09dfc5b6a77f2373b1ce07194672a319109ef0af85bf931698ccedbf67442bf0ee0c2b91ec86be7a8a1676fc8b35e57bcde558b271ca150aed292ca539f93e6cf8ab16025ef9333c8dae916f5837d43d1edfd0307d222df5a9302511306266eb1c150cd86cf67cc599b99ad530e7b0fe67485241e23cd1da696c043d9e875fc9b481d77ceb032c9b00b1950f58d0109394ceae42b3779944b6a9083ff59966f2c6236bf7788adab497e384844b2e7f718d5a82c343101e9a3b25dc3d7fb77cdbf340b0de2237082b0ae8bc07274051823e5644938f02ed9a25cbd79134069747f016c8290489f9e6c07c953668a91911565d05102ae1fbc7874d1ea07590085de1ef20be3bebc257c4295d2e665ef5a6a3896201da94633baddc58d211c276d60450943abd4aea422161d83b3c2fcb7d0c6e146fe777117d785f980c1ef5a5ba3f240e4698c2fda2656c999e6a72ca12a2582921b5fdce020bd915f429a50a257f52416115ec304b32e59ff91bb9d0e687b8136e8698dcacbc0930042f0857257559cf3bb8efa4ffd0fe7dc1b6d38663adf2ffbf2cd02dc5e44d6e6e37ca9ac52d1652634b1ed3bb2a1d32f62d36e983d35356c930691422f39f0a0c02afac0f3a3c78ae1c066a2be913a3f37d6d7670162d5a7d22b40626be4c1510d07a9a5e13d818218c30644524c66542374debba66e92d1a2682026e493083800b29ff81f486ea0e9129c145608bd510e7b2155606ee81307ce4ff9a3d564fb63d464cb1143755f3183637db024e957396f83ac7b4818c2d33fc63ace9edb7bcdf512063357ba6aaa48a5ae9011d28aad92a299a640e6280f381a99f0a579e64c5a00ab24cd73995188186763dec44ed80508040b9cb9b3f71f1547a188e572f7365a3bbbdf60822651a43bc39b3a33991adfbccc0e77fd7e2f2414cf03f0a382aa6bdf0aee22a587f595d17a5fce92595d3f47c4be795a36e36b34e8ff83ff3c9c014877ef5bde18f505f51ba3dae64d879b63432e750cbf5e276c58c61967a1b5961d6a570f28065776c8328300e7a1c2a4d55f77c8fc96f2d25c5c23496cfed1a0c2d66061d8b857a6e04e565c93978b52ac8799d3805ed43d58d8717e8ca626b5232daad9d3331db07de7353ddd7fecb715ae29632b114e5b5110ec9e65d4c334f5a8432b842e6b5086afec735945141efd5c47ee2bd7a240fd041f02f72bd0caea4e4169630ae5b274aa58fd1c7b34ca041e64f24b2d38c209f6a4ace2bdb8ccb4e85616cd7b5c25001329aff3f55fdc0a43271371b7d06b150ce7dc6e867527271174407fcefccbdba6efba156aa4f9d480d29918651fa324c6559903757f65c08c7709b604d5f361f1c8d1bce66aaf34f4e6e53a8f54a327876a5d795737611516c7d0515bda8524f93561e66753280301ce6cf1996be2d6acf0fedb4de06455bd8d5dac2fa20b50a0ff137d91451866d72136e4636c083403854c93993fb4493b0a21537d33d15f1bb204a779cb9f540f12814d0d25e898ad9588ff1e6af139c10745109278285178374c89eaec2467424c9df19900747532b8f4ec42c29de057101389b5862da4879c2fb1ca7191746a4a32ef023d0e6fdd9cbb9d513a1a5d5b2adf4618d5d2b35f1e3a9af49ee9ba2b65bee8a1ed7c177ffa73adb1d6655a06edad2f67105978dd3fd58b5a64a63aa0177c33c01973ea84b390268575cc94dd6c5dea3ff2ebeeff1cf81b145e8a920f5ab51dfde654c88c29a3a4a2a8778f33fb799bd273bc579db936ecbbb551699ed89e6e917ada9e4ee64fce5e564947b1c23474cf369910d378c00e5097820655090ac874521ac0924d16abe9272fa26c6434eb21a83d7845c0299c2c83c30c47923ff1bf2662fb3fa45515d3882fc5ae8b00a6764a41fc2ec3b06e80a3deedc2a11671538eab5c401a3d51906def80051dbeaf0f977a431215431e13bd6f4562e2982901ac4c11cee8dbc4292eaea5c7f2d93ed5f5445717ebf14435aee4b8bfa69fb7d5390186e0271898139d412457577b9c0c9e843361067ff35447557828b83ca51a0a7341bee1ea0f524c772c7fc60e1ee91bb745db8224c64c701e1e9f976fbc2d94dfb05168a33bfae3ad4519f3df04ee3bbf58341c6050df9b3965b4e0e547032fcfe74828beb1f607ea1ecde2075b3de84a41aee88211b33a398f8e9d8324a4b19b7ce029e13d46f7c8e43beb9a67a86618bcfb9cf012b4132a78013a96fb9c316c7534722966b48deb788be1f3744fb7c9173621982516380d992f5fcad9e00606fc0cdce7f728d79ca7af6e532d3e5343d24ef4edb26a46bb525975419877aeaf3bf8984f437c4bd61945416b6ab2800174b8edd34ecb3551958385d307c38b500c63437679cfa290d2957e081889271724c5a101134cbdd79b52c75321f736274d2c5bb2c90e2c1e43b5ce931aae377d3fe4b02719b4bdca624370734db01c0eda57b9bf905ae8e3c75f76751d380b28be671f855a56069ae7e5f9e2ec1bff981b179bb332d36f0345d18e9005c25664b216bdcb94b4ec6417e2f27922b69a3b2d17c8133fab23fb49adfdf086ebfc632e82b76a596b1b7118addebe3e6a022ccef4becd5cb18b9f716cbea0b509fcb4403035e8a7574f40a0bdee145e44165ee1cfa71c5625cf307ba6dbe122603bd35ed057d9971eb4d66b6359eb05dff07d39a8509ef67b6731a4e3aa3b440cd891d5ba867ccef73d575021aea54564639c17eb5b1b69dab5faa514a6710a0bd98019a3f41b77b11527accbe7d697a5b10f41720b903bedf414278606bbb032d9edc0a78226857837db96e8155fcb9fa31049fd0ddf48b7ddabad69b616e6affbede88f8e406da1eef2c2e2d4ad1ce99b5a7244112daa78f0604ceab35ad7c2bd60a967a35d3d9b676e6561a9bfe72685efa0073f5546265897c01bfc7a8a2f6fa4a0e2b2e30a03585497a9bdcef276c013c682855ba074af1084a99ed0d035733727611fbf5831c968ca99d9e290c00777a207b11679689ed18f5602d1d6dd70dc55df67bcfa1d4197331f9633cd833d1168c2fd04aea8002b7c2210c3e5cc21332c84590ad2c4327bc6c51ea9a5f5421363b0e838b0de3af55e7a5e3a276fb71d7d89b2c629bea090cbf85876d5781d55cb3f7f4a18c2a2338f27298553951ed0deb9a769d3484b7e4ec9e9aefdcc3c36ef18631495a4598d2c208859ff67abfd02c85ce56a598c24632c09e7db72eab7cfb48d1efdae416e5d3a594a70a4f671347d7c79711e7bed08bc9db44f455a1a9d70bf784155cf6eff4b01292c50b217741eab373dfe9985a608503a660a144a6edf684587714d1952f69dd4968af93baaee277e7e60ed1e9ea95af902990102b90294395e666505c1b902afa3e1fc70f8b0e53b0a2de10d106267cdb9ebb42a3fd86f4b086cbc73ce58679a986b1627bf06ca3033520ee606c6247c4794f03769b3cbe08c099f826cb2a4b072508c2dff2fafffdb3132524c8c598e5d7efb9e36425072f22e4b2248367d76f5b9ce5b2f917ffab78d513c1d3659efa2adec1a5f005d50681122e14856fcb0731cd44700667ef01843ecd2670c00ae3136c85a0fb931a3489b72250855c29d24fff5a081805428083635fd5e10a4492f823833387a55e935a64314e93f98c3712f90e258b4da54b02863c952d16560648fdf3b4be5c4621b85f9c1b9b7e542bbc6e563fccde45d30afc26303009f30d2c560a02c3534f2ff08a1b224a1bd1ac4c13022c67b2476b2f362030938173e44e9a2c83d4e1c35f28322f2967a978b92c3e4bb05c1118ac74a07fb4e4f36f08208cf7dce14dcbad16718f97f15ee9ef2249b678710ea6cd7072e2db5a5f89b9363478f78d46f6aaf12e43e56465ef1684e0836f7cb934565070c63e5075bb5f6601aedb62f59768b0ad22b10464d795e501ced6986d6d0b16392f26fdbc1915334a693beb07d7da78ec58fb6ed04695a4039283ed21d6d2bafbcb33abcabe5118e882588228bde618c4a0db59a7c57e7bd8a6e7b538af66e1c7afb0625fdda6698a42296bc4988bbec9f4ecfa3bef2280eae30ec383a59c6139361c2174c7661bcf07d71298171ceb3aeae3165ac3e535d2210eba46b4eebf1b56cb2d9867efaa7608d52ec542b2fae64cbeaf27aaeda88e799b44ed3e9ad6ab7a41083bb081a77c7613614d5ca28aceafcd0bc443633569ac7a02dd7c6a8e72690d2852236afe910e35530a9e35ca24879bb7d39cc6894ef9d4e90dfe4abf08c292c8ce3de46b336b3d48d2a18aec6e507c53b6ef0eeb28ec179dbc632b235f0f91eb50202b91eb091b23d6d43f2a88e2533ba15a2503cebe34e10a45eea3d56f441ca3bb40e528e692ec12d560b8a9e45a249e1b9de7526bc6ad8944d0c41335cd01b6ab3bb4e6eeb96b27eb1da3e60f9c0fb31d6e4efdfeeb03383484ac078cd93838962d78c2c48270b5006b31c6ee90d22644f9b3729d366f38966ebc2808394aea8658dca3d4f769a2e3154d716f05c42146c3a7067ab08c2ffa4531777979436409ed51d91f9c06d303e02af4abaa1eb539ca3b256778d0bef27a64b76582ca2fe9c007d5757bfaae114b4c08f299f51412a9d46f594ffc20a7ddea6ad7eed69be8f6f138eaedf9bd2183528e59daf06adfcee80e409bca2843995becb9c60c2e370a17f9dfa8640432235d39013bbb310e3959f944ac0e11c90b74e01262a029c26338a69c64467232ea333c8e3c1759cfb4165eaa8efbf0e200fda349eb25aedc527abfeea03d7ce8fb348d8e21faa730b658d80976ab4a5e64a8da7cd9a6ba813a7cadb8fead0bd2f88f6e74aa5a65c702b2e63c950f30fd27bc9c433278376861400c463e7e0c95fad41f301a8d3c6e5dbe7c4ea173cf8f20d65a4514e66f8307c2befb857073336c669704d63c9beb10b2595d106403d0166d0fc7738657c2759d22e512c4d86a23c6f7e815754c5abe8f92b065bf71332ddca0d76babc5fb900726ed54d003efd851026752b7185d4c7a33d1c19e7386a3aed7719bd754ef0bf104879d86870b203eeb7699dfe2658ee6281b2377d06ffd386f7b6d7d36201e445408a44ac39b713c7c7afe0ce87e38028a458f5c067272598ee26a411b09017d49e9a0d5a260bc2bf646406e768b926f5a82559c256f7952a4d01575f639e3ad32a710568ed3ab3e7a52e1287cc9723449dfb3ba50e4bda720e0f3c88d90b9d5d69aaed90d9d40ab50c279ffde2ce31a395ec94db410bdebc833ad0c9259b1aec29c0c7cbcb89357b0ebf61b8dee637aee13e5b6066847ada3eeb2ea48f2049e545de38dc382f9c15c4a5dfab474d006349f4bdfba5dbe85e703652ecc302243cd65145dfcc448086720790f96b94eb90ae056c8a692ae38813fa981c33b9fb6a15e878990a3faae95be2365b87122b056e20793d704deff826c312c02d0079299ea1a0f3b452f9fba62d8a89bffc29dd24dd1c665097aa3f20f692ec1ce331bd3d76faf92366c685c14ba93c64e94bec6bb7af3006f9d3da8c287612fc3b52a45f9f5b4f9dfa7ef7725acdbe62dff18af6bbe901267d3fc4c65179313d393856c664149e8a202a7688918a3b231f98e542ba86fd00aa119b362fe048c06d69c75037c7287ad40ec9ed6a28b74b87562073d3556feab531af8dc6ed497d0dfa365afc20f9790446258419d5d804033c1e198afcbb43623cdc093fe9791ec54d497540cd59774cf096bd468cc9545404772d6b86c34157102c6099da03d13a0f2c84f997a7935c6063b58f7202a1c320bf8603b332c78396d3bdfcbb86088ba8bf4d0950f4a80191c91ce47ed1e088a02da38dda45feb58cb44efb680d5a0bdb2e4fe8eb66b4283a6ec787a6635da9b542fb723369d051703b96a5b74b2796ee7b29f2c300dd2f343462316da393c1d04c7354d6f62118bb1e7314b7cbce8716be1ac31ea62f22ac4097880c1b10b744046b4943a4fc5691e87c192a0b856f2e25344301816310b1020deee986457743eb4abdcc8198744f48adcb7874a280816fe0ac13886489c71aaa37456174ef7c38d1ea45182f122a8891fcc936e42b5a414c5c59f852b99f06cc4f11015b2478f67d9c629be771147146c29b6ad1f7213b28a0e594e9287128d7db6f8b1b42b7a5d66772a99dbdf7a3f11e472d94b672634c1840da00e3dbe1acf2a47c1dde46d9dcc9fb7c7af802826235e7b9a3d3ca77cb9e24d8b829f90d5e5b2658f3233f4a3cde5b379b810426455389fb6dc69e8c2a2b1a89745d6d8f77e3a0e890f40a1eee53dd11b6ed4786b4aca82714476122334589bbb25b5df2786eb0a95ca9eb2cc94aadbb09a89675c469e7a0ac53998292f3f805b6cad9cce38308afa7ac8d7db4f2c91fc1611fae0ed91e67d529b5977a59fcabd331b5fa6938abdecbdf562e84fc34ce1a5dffc03f006d1ed4dfe4bbef3dff5ca65de1fa12663dbda466871522d3784ce978b9cfa5a0edf1e6b7cc2a166b7136e9e7f24dcddd275d130112d817d736a5f2a1f16d0b00622b9bd0c9c6508fcfe3ece8cdecc0496a4aa9afb4d97f73e6ad9706da95625bcb1729414e0e1c64bdac41acd316524a47b2147dd45039a54ec51059fba9b37ab24261fc866b22286869ee455b4f6b880b4e7a3a27f216323988db3db529ecd06f912fe014a6d2bc00dd20cbe500cee23aae101ef1995c69dd759fc1b1cce81da8de98a1875909edff064ec02350000a43863040753a6618aeb566529f9bf4f4725a6cdc2e9a795e6ed0998a713feb5ffd04b64bc1673e3b80dc378de4e6a59c4d8f6e330a4877a890b2aa6005edd3a221b1ad8a7e6a72f9880c9dd1719477af5d17a6af4aa4bb3730f3177561ddc605b7027ea331b0bd4882392006baf2a7c94d4ae674a0514ca618714a2068e131a9f1bb348adaba3aa3b19469f36c0f0f0ea2b7d853fd3c6bde3d92cc9f3f2b8c9f5202c5aa575b937ec1c3ad06b43f3ac9eea4b9aa9e929dc98dc5c8bf54580d81104a7a004c4894554f93036721e0d4157298c202420638f6459c422f553ef14c9f8d7d41f1fbf7528c8c6849e84227fbeb7fce6ccb9a2241c28c06a73e60036b31f8d038c5d9e773d5aab4af77b7f55b883d4c399f55e8dfd8033985d65e1d51dc6def00ace64f1102ae7e75ea83cebb45587d422869a9ac9190dea3dbeb0bdd64adf8c4e81b11a1ff1232d5db5da6dfcaf3dc205b882c8bb3742089f5f6800645d1def6cfb59fcb6b08a3ad1b7af3fe23aecc62b5982ecb5f03bc34da6f8d34d2fd609beb01df13654eb2bd569c13c982cc6a03379fd7ed572bd66e759657a7e09f1bfa104edacc5bcc6c04738c87e6c828bdde9d7ee546a1024021dbdbcffddfb016714d839f994a38faa609e6e9274cd4ddd92e2ba8cf89adc697ce9c589038b67549b236d8d30539abb29b74bd9145aed6ffadd1f6e895af949580c520fe248ed6731acffbdf02846e239f9ebe9aff4e81528d372f58dd43527c928027422af6ea79b9141813f33f192e0df2acdb697d97058e228790c4e352f50cb672c2c25de28421a0805e19d743da4923c09b35616a7e1e9a437bb6472686546354660ebe092beba61ed1ab626452ebcd4e78b465311223566743e5d4045cadfa834a0d743820f1271d392706992135863548bb79ebe9b8ef8dc6d4de690d0a8c7e7ec0d83f6d7d96cfd713d6e1ce8d1836c41dd2eb2445aad122fdf4c9e06d48499b5499a6e7fd83ef19d0bd48f7b58b306178c51575e226d141c580ecfd51b06d8d4a8d5da4fc5253831658d0a392464a5182e72b6e1564c4432b5db132eda50116ce801dc858935a127c1b8b48a2cca219c3383c0a153ba7822cc7550dc07c15ebcd63dfed9fb8cdb93bf22697a39d147472f59a13705cb22b19d9922d0ea92c56e02a82866f93308b8bec689f7a1553aebab547d59a4dbec89dadf67f7d2f98e31c55dd53557af618c8eb6aa34cccc1d27800080d8f83651a9983ed73a1a693f3ef39ff867996432275b0e1b457a83c97e94ac2685e7ca65bf00cc0c3335bf88f9e9363884912ae897f81cae0d0a09b0d13ae45d60ffe48f805613021b2f2ec56398ff72e8f9161dc79f5dad110edab90d7e612b2e52aa29624da853b55231d7f43837477e3b48790d5e58c595f577c1ea6e69e88f9926e5492341556297496b379108c6657fb0e157b453078ecde88baa5b0146384f58c13fa4ca944251fd479500c652e8b95778cafe80f19fa4762874c6491944e9df3af1c3b86db24815c4492a065de0855ab17188f6d09c2372cd04832c4cf10bd6a1c1a2d214af4c7262e148a5a0295d8e4841adcd82ab655efd725a2ef936eaca602cb201c31a83fb7c69a9e03c3c46f46add406f8f1480b91905f94f9e6b0b5d63d364de8034fbd70534accc0743d4b49af43e25263b1a2e9a7a74c83470aa2cd06e4b0df6b4eb0aa7bbaf442e1a4608d17e0ff0204328dc7ff65a6363d652aeb2c7f90e555ee8f42d0b9055b5f76f1c052aab47c0f840ff8ff0919ff6b6f7f870182afe61b725681fcbc013e122c4e20286e2db70eba5b978ed820fc18dea87758bc8920da17a394faee5d83a89c424a2c0889872e42c27f9648e080f5c9d8f13e7c36f382bc09c3932c3b7d50d0c5ba79b30b0d8f07b97e4f0346ca74ae63e11d61b692aa7580bebc4ea1489c5dc236a3f42cf4a34a4b43d59a02e901f5dd4f1eb3b98a0bc1c942bd8533ea6bac867dd26b01837e8b71d85e937fc9d7915b4283ed76a06118f20f2d232a5b702611cda5c7a5d49bbb31a1887e72034cb0adf04e7f76957fe169f3e1e3ad1eec8b6ba95175dff10c04be5881790c0006562cf1d66f524fca2232b6c1680a8b3e25c4a1d2d8bd08e7b55929f572c3073e77cbdb10e8fc1a80e4a60665e7cc1c20f4e68813db1b176a6460cd4bcf4a632d08017f91d4971551183fcf1ae15aa4c287964615c6cbaac9aa3edc0b5d077b2c7122cc23e75ac3f702a24e3b92accf4eb49e7f123cdd58cb4b623858a927e3fab992716f609a49ff384c6b8c69487f553e112183813168f09b21bd50048d96fe2cd266cf068f4cbf72a987440498ad9c29a9c4635a32dd1159898700299c02883062bd51ee9f6a317ad199bc203bf051352cd83230d43b9f28ee91ea5d8f64176af8da842fced919ce7c91260580aaac1f68e6ae4ceae92859649430f921be43adda1101c3fffd0f08d2ffc26a4e08829e322961aec9cfd0ad28ba94a15bd42dc30c3d72d077cf59928e9d839196d92f80d23fdeaeb378e8c2e28f6733f2fc9698834c9d23ac6c9aa68d1a060ffcac554ba91d4551a18685a5c977cdbc173a8998d228d6fa3070bc5d49c703efc180ea28c606ade0ebc97b91685ce6c15c60caa7484ee038230a5afac87dc83b322ec3325400931f8313e0dd2b1e4a5861537e1bff47e89088cb8ded087cd8ef3c273e7f1e1f3f044c484871391030e25d089ffb8ab670e0c0778d1e9d6baf67ea5be143fabd8ae5da8c3a47387c04a081381bc5120c37b4d26e99725b57b19a84625198fce8150b24e5f5efc692105750a3482ab2401c252db02f4dbe941abde28f1fd518635259c18b85753baf159367d553a7b7f3eb952b9e46ca0d710cc291fce9e23d400982b76ca1b53f59c0b265eef828aace2fce1c9834c412bc1f0aaaf8e1279c618a2d1c226e428dd192077ff99b55d9157557ffbb151768d03ecdb3aca91bc4fccef72d785e887b9ac0bbb141c48b303218eb4e4343ffdfa83b3d3fd8a9cf4218512434e2f3505ab26cd20e472380f617763b9b570e735625451069ef0eef0e7c608dbe2f420be7a9c0c6bdbb265a297d4385487c3019421d1f847fa6980f49110c7c2e1cc3b282b9e5f730495cb1853e46a01477ab5c1fa7caa1177c9116aa5f069fdd74a94cf8052abcf207767f0d9aecf6157dc6a853c51085b8708fdeeea84c7e5045adb016bc1286c427c4e49029d6d1f0e9d066b2d390b09a2b683b1a84275cf4aad8ca9fb540fdd0d0bfe7878e77771afffa7a03bf019c0d2ab28c0223d81affafc759f11fdfbae0d79d69709a640a7dafb894cdafb704ecfaf71605b331e22e417ba785232dcdbfdacc3f98ba13d4c8e5d03d1296426000b88f64fde4039378600dbb110bf5a317e1ff42ad88062c219eb9402df9aef383762ce39a0402ec85dba194851a49cdcd1afde18336c45615d7a837abd8ff4dbcb0ea8dfae97b7da982b6a33db47a60ef913b79a95c13c8a0b9caa26734e07d97ab397a7abc6e317179e27e820069409d40fb8bd932e33cf6d97b1d373e1d1596d3fb8d1708bd0bac5e7b1e6978006e8c06613770ef7a01c0d505ee6f58b1b0d49afbcae226b5087465631b7e855ef0ae2f924bbcce4b3f820c972eb0a1ad0f4d593f2e9df9ace6369bac926eef15cdf322c87ff95b74e3cf830fcd1ed11e15a2512718a19f15104df9abe91620c18e0d772dbe577f9005c1f1ee6cffe03a05f1d46fb9a16103c50c860b3bbc3e78ff881efe07caf8c3e94795892dc67368c56ae4d5505bdbcc8c59439a9df077ab57a58570106c5044cbf6d702517e7adea68d0f3e0ed984d04d8a2da4976e275db1be29bdb43c5a19c52dbc002ea3b310b393d515da2034ef84987e6063c2220270a9e9a9b7b45ee1c256ec8494c607f25daec1980593d8e4edf2cb06f5318fcca115ece5b2f37487dd76a88b8e3d8619d634a92169ce362c60e1939c8f514f6fa47802b03ce8672b2001fa416233f766745a3913a073d4369120fc409b045e046637aa4b77fba99b1800f85ca044a0c7ef7663404be13b2157956c4dabb762db32dc146e2887faa8e9b4c9a8ec081f1b6756f7c4ef2c3e8d6b8721947f75812dc926c4440efcdd767e9e24ac6b1c339c9050edd10c4138f7d1beb33cb472f5b77b26115744922937a1e32c6ea90edab7e566ec697e66ed7ca4f22acddd9137ec4bc64541a36c55937d4d5434769006fc87ac24c21747d74be554ff365c422621af9c7cf0413b4cfa93dd771108fef9c475b9b3243327a3609e3dd104b331a5491caae51c3fdffca43960bb96cb211c021f0789a5303f41309ceb370bf20d2a4ed7f4cbfe08c0ecc56c2228ee72434138e4b169c7d2f105ebf8bcc25e0ad533bc2d18c0934a28714cfc6c08d5d930b1a86e161e76bfdd2a3a7066d64746f8b2644b027867a1a3341042c2a8b6b03e828697af729f0d24d80ddf8babc24061650b286d10e71324ac836ee97ec48553933bfbf62afab9e9d3e945f0ee7a6fbefd415d34513be29b9bc90dcb47a137090664418569c8ca3312db9ac32974bc1b2654730ca2dfa7312e720328f1039af8abfb90356967c05ae17df7ce5fba4a2f8d1879762a9dea504c09100805906f2efe5a83f14bc64cec4659ac0742cec45563bd9ea5c38824deb143e244ea260e727398ec3f3297f4783e844dcc1d2eaf48283c35d7985c5610b0273051fa36a4e04d4bf6022feaefcf2188df9a9aa8c636b032e3bdcd1f5de2ac4bf421639b5adf9b7ad86988a0f78e52141f249ac04adaeacc826e23faa65b504e04d63b77444c5377fcb3e5fb80b4ecba17f85aacf71dff29fc1193da018920132c061743a0761010b0933fc77f14039633db48743bdc8d0180f79199d27fd683b2b959ee48df76cbefa0fb0d65bd2450c77ae9221691fee93e6d9c40f5f80f42ee0e4f406aafbaa14d9d1387b5f16ca01e15f699a6d6f3c7a7c3aaf13ab8f4ee1a6aed5c6a0f92e627576c3e9f981f132e69aaa8e38a9f63bc27d456f1e10d1c27b35deb05432d4bfdbd2b15da513ac15e3f6888f7b2747ead65c0b22fa70890190aeddd682b8ebf1093835a434b06e8acbfdb31c17cb3245e3f4bf7347b2aeca8a6a3bc2a4cfc8ad4098b2283ba4960c24b3299f083cd793029251ab2040301090a98b3843159ca9b2f6931494f2606b2a2a8ba9c830eae64452b4958a019f88d27cd734f72efdeae7d720ee0cc98bee385fe98fd483110243f2ee433aecd639de7a2df2c25c8d0d6ed4e878f1b65783e7a334e7e46d0a6062be7a92a69d693bae4bd9c9ea58eb2652ff354f2e75e76937615dd4e195d8afaa4341d9c4ecd0f709cd0d799bd845123f5b5756afd0c40532a144e08c34ba797fe4aedebc4d5b4993fd6fb3a3cb658a324835eb48f4e583ed4e41149c19ca713699fa94596a40f091042fc260154f09c4c51fb73ebd6b68ab8a9e286d7bc258a958d564c186924222407a1cd7808d8519bc3ebcf0d8b06fcf851f821ce26472bd6068dfb85ed08a6ae859cc15d6e674025b58eb7cd838cf53e9ccc53f2b16f2bbcb9ccbe86d13359f3b647c44f9790c42c101a83e4c96d672eee55b7a07e1f6872cde7ac56a3f142d6db54d01eeaa239f072eb360b3fae49c9bc4c63a4fa326135677625754bfb410cab1ba1d2c3ba29665da32e9f6157709403a07980cdbb3682a0255fb0adb68c6f7e24eaf5c7c1d0eb3f6c6a8e671dedd680ca127041d57511085a6a8a890bbf47776cbf9a7c350d64f844ee1a621af728df9f43b20bf53f9de6ce26f775113cc04ae3e6e74b0ec95949ffa8ca7c1789746bea9c9fd557175fcebb9399e3793f90571e5bdea3ba300015207d6ffa2faa6b24fc986fc55ca75fe38339ca746623f676c0d335489b3d7a65074739d3f827f71d1ef79890712c8582ac4e6ac0bd47a59a50145b3da9da52e459cacfb570aa163082f91fdd66acad4eee9d0c012ddf5491514137b0f4064b3305dfeb78384b3730a7c6c79c335ea6d6f596a237ebd59818f59abd1333e4db432193f5250d1e97ff249a40a8be087ef1459b16fa2aff4d1f5a7488f702e4383b853d2f4b6c974b498ef94b6862f5b229f24a29fc3edc7fe78aebca74df7f1f523e255ffc98ef2128a3d1b546084bfe4a5cf37fd9166688c5fa1a1353f05f9fdab2cb48d466b2f3b3e00f1e74219d0e7bf29010dccafeec0e93e2c6dc3b75091d1cfc88a452b53310b59ba2ddd13d29e8ebc2f8a7de4f275e1ca86814cea04136dab96c7ec1ba343564dc6b7e7d9535f49a21830d55079ecbdfc71a2c0a8c03937df58a1070f559db71c366d646f27c3adf5328d1dcd2190680fff33cfcf35544ddffeaef10c73b0a8f3b80716fd0ddb5aca5824957c17c2502e5947584915e1e4c9417853cb83897a369dc351be06363c8ced095b7d46603ac5f95af67d4c17e6bedfb16a1d608b97c34208904e59ea312bb93a5818dc2c30181f7f9360a03ec71fef7d1a8c215fa896a7034760f416704fce68ad0d04b578eada8dc94a7a80b0040be3a33fae110110f66e1981923434326dcbd8c1584904c307dd192f14bff1e16d451ffdfb87af960552292fd9b145030b37e72a862d6df51a21574de98210b18f255f8c0948661a19db46c188a13545dd94fcb687a26533f58a3fdde2c367ac520cc05d00d3b2c122a1ecf5ca11b4ede2dbe4e73d17deb15e8d922d70cc559e259800e4fa2bfd14198eb8a95dc81ddbf4c4e9a5eaab9f719a7913648131700567792933ac8d688fca75e2bfe7c34332145a1e595b0ac1b5421b4ac8b4b60694c1f0b7c86287ccbc14a2d70ad3cd41df22814070537436b49411efb758c2ef4b8fdbe8cf09ec02487dd90e281c260cfc15b2769a57e54ec9311c2649107886ccf72b6e0f63c56c96a9a7f3832220d5760359e49f5015a2c71664bf9ca4333a7b4b45a33bb03c0fa67067682ddd9801654a8d13f0dbc3bfbfd8f494b2022b41b46794aff2bfff1e587a07e268a927297aa02a2d138d8d03cb6c8a1e69b6d185aced57ca54c493bb419405503a63c208f5fa2902b98e0c5d68223fae477c609d95fe2d5f39286c12927c76330cb6e45a8e3cb7ba20276ff965350c36e3add8f457758a3a087e2ae25bd26defe352201c84f7afc563b1f241f7caa1d9b8daccc59af0136f4b55d221d5ba52ba6a649f81c2a3efc8b8644ff99b000cc42bc61913b67c2b270adebc02978444e8fc1ee3ff2bbcf0a6899f7f9feee640e0ed9bc12e8fbb0f334d6bf8802457c643ae411c052323deed74928b90288b34adb04174983638f07bc7bc784d83a467db97e6b03535fc51bb3a3ca0a71fa0c342ac7b19500251556badbc92ecb3e1dccb615c0d10a9c43d2adeb54dc38447b32a6655b65002cf4a7850177945d95c34e861164aee98e8d5e1fa464c51c9336f51d04cde23d37f4b16ee5a178ccbc42f1ec3dc60af6f6ac5c23f6f73664ac0705a9c01887a06c38e285d9a0cee6c60a5c87e5078eb87e7ce29ce3b36a71cbc2d88498a68ec78fa9f3545c532cf1db684c1b1414687f06392149abb09a5b4bb8a33de165670fcd6a8f0f968b4cf4bd29dcdbfec8886a97a3f56213214648cc79e4312ee40145e3a3579b9b89b3d90b66422b287d62bf4f6954c1bad3132a31ab24af3acecc3b765a30eaa8405ca58a0692622702825e942451b3b2ad92df66fb8a384f9403b8411df2e3b8c44d92cca0f2e310d2190c366e9fe4ebf968f6e20fd8ebff24c7e0f7a5f28e22c24d29cbebed8deb536e2101c398618f1d0240871ff431d7c72cf2ab1402001200235a9839e55228bbb2d46c77be887f6103e1d09ffde359624d64303f22bebc6adb019c608b86bd338e31ece0243a6e1f535c43d1c9a7965903488c0b1e138318abf61d04f584f6051c675e084360570dfb5b5c6fc5d66825c0608184e998a05461602cf62ff49b3d2721ef35f4f692eb344c7e618d0cbc0477c21ccb9d205eeee3b3c149f1913c2369ac8236b414f89e749c83df52a26655a10b2e429c733d7f11f8e3b69931710d78911e35de4dd40fe180d59de09d36b9d01690410087224a976e4f99f0dc8cb17670f8557ef9520f451a18f432f072f8cb03415f92f2f3a5abcb7fc337a9a5996f60e491e12fd5e7598849e0055675784039f64924df902cb554880d201d01b4a3c7cf9116cf29b393fb1d1aa6532966bca6b3317f6f78a378e310086af531a50fd4709a42361760ab868f4ef381366bf5d7c3fce1c764b9eaf4e61673ae406ae55ea41a8cb5dc82bf14e42454353aab9c1d249d1abe6bf96c443b7efc4a73ded20f2998abf7ac1ab45fa9229c02f70f5fd8324663df085a6675a7e867a4c92e9c3687467d0e5730dc1631413b72fd9da6085748250f72320b4879ea3fe90e97a0ac87750f44eaa80699037b040101f2d5ee8b0111f95bd806385da4193cb3ac083e9bdf811b95fdf80572365c527657759816ce9b43a7369d5ac35b385a6d30dc5ec191ba7716419c8eb6b9ab1226177c87be5536874c4fbbf3d32c9462d11fc5f843db4cdacdd254140f86f3cece67470b5a7527d4a6ded31fa834c6e53d13802be275ebadb1934c1e184bcc4789a57b40aa5567b0b743e2a4fb1ed1bebf9008ac34ff843ed2b018ca24c8b61c7eb8f1a58ab8f5f902960103b9029139e507b80a2257236b12e9a08616e95dd8bb1c2c2b8f997b1e69b08cd7b3c0ea697ce412a8beedf13a9361fbc700cc66a09474935515517b7ccdefc1011ee655375fa1cd7a24567e31b497844b0f3d639bdd22599d910fc7074d4c2e7a2434bc90933d50f1d609bb41e5771a4e62c11b8f51e7c99a9d70d5ca51c50b81a647574d2e60e793aa4358f2ed4f3bb0b3eae0f7271a30a8b12ab18cf1fd5b1bf4f91483b459cb24c2c711a76d1135064a91ef9a2b0322eb5febfbf7f1e4b86f56387399c9db10bd0b1bef931294bcb544a20d4d67a31093dbbeac8c130ba5eee1dab9ced8ba209c9ef1ca5be42e759a6a452559bbbedd065591822bc2af6f6289a2c69335f3bc50b8f824b853a5cd297fd72257b840673539bc0da5d29116aac501a122c33ca426e8e688f89afe99901258c16c559ab816b1e04a69cc8ab0e6be38663615354b12da1ea63305483b168ca5b93876d40ad75b04b2722b6a1de16eeb1919927a70b62eea14651f5db3f1eba67cd453749d9e6eef919baec350c4dbb67ce8f40deee7e69db9f8c7c6bf223b2837d351a4e1b7841e03a15b300bf4e20bb1c9a3d3fdb2959a76b9124c52516c8e2af6f53f2e81910873c0f6d90d765f12a55af9458f23de9df318941e04cfcfb6f16f2473650817c9b6662d4bd8ec1ec8ef410fd7f5d7341322953547a72b8460ccf1f387c9690bdfbda051fc6959ff6fd85461a444326799a6145a6da880ae2df8ace15dcd33fea7e6f5b999e639266df0738944635e63bd55435b09ee531804cf33d98aa4a27cc03acb44fbb35a7a476142791384165763824b5298a2674ef64d489f751e6fd40f4ad79bab5ea50a6d889e5bfa994d4316eab353fd2e6a58be13ad77894e622c926dfa639543499bb06da16589d3881d9a716b86592590a407f680f91eb50203b91eb016c72e7144b123acd187c88b68884162dc507d19f281a2ec3b5251a69fbb580e80900755186fc3c1c2379cda69be8b294afec2618774a3503a4619a62b2fb55393e3ff182ecb26702ddc9bee53a140dee1e229355394d9d6603aafa3d573220f63adfe83bd017a4ec6dffc50caf407c4f12cdd9efcd4e5069f4afb26fc7174de3f2c1e7d366631642b70670173b4168d2fa448c4d51429e0eff106cb00b10633b835a4d65671495d5aebd3b55ec70ff61e900db693eaae1ad961d47d551d6ea6ffe90f713a7e08898dfbccacae15c0c81c6aedaee8f64e5bb30c3ddbd56335472df30d6a1341a299b7caec6cfa7a31a70d1e62c7772052bc5111af97e6899b38d5c9a5a9bafbf966c5bc9abad4b2781b3290c343211d4556358ebbf1014114001dc6abe1a840c205367d571d24eb7a9338aef10fd793027203ba75d5a1f8208da56abff6c13f18c516bc9098889104e1a9bad008496bff4cb9cbabfe4c4e7ec835db9b97bb466514742eaabefa91f11c7c960f0397b4fa3e260544015295f272923e59508b924708239dff4cf507b63c3d5170ca240fce2ac16d26555e2cb3380525a9de36b8186efa5c9be2d221fe360bb6644222635c5d856280e9e4f9e7df5bb8f8b0f3c6ed46d15cf6405f54c79f9c9c81cea73b607cee4c0202b57398a742625b4808fed5852d0fe247b28e0c0b15f105a2b2beecdbad6704310334571327b6ca667df4cb98b7bb990fbff43c3b4d847991a422e2bc847a2da5ccd4cebd54aa51ef075673f6c852623e03d0fcb806dd37c6416692a5cbe50abcfc1feab51adfcddd6bff3fe0704cd78b35e171bebe8897236d6e5cb5739553f61238878f05d73bc3a01396e605f174e210e68b215d6af46ca7dcbd492737ba8f2ec89f6cae694a0a070c849d3e2604c0d883b935674b67b3a276ac2d82d5399423162a053058932543c223d7d96cefb139e4e5fb221f4fbdde739da0c3f52d3fd6104fa593bdae97032cec86b6423db6e2407f05123867304ffdb12336580e6b1d72c061f87a1af3a9ad2e8544c791e8b85158872c9ec64423d3492d71d2a9d81ebdeccc45f9d0c7b7cc76dc42f30eebf6997834c6f3a1fcb87d330d8cdd5a2d1dd71888ed00ef27a56363358eaf7abf3d8c33769ccd9a2e677afbf323c3e123f453ed36822a2da972025b4166ba3e01ebc3375be1f8da9d8cf3376626d1c813e43279c4ad346d0e3e48125c220bb5ce002e4b4e7d03ae2fcc2f56e459ab97615b7e8590d93fa9642fe15f44fb0009f4468c9da565b8a28f7c9231b8271de5d4337722360e22c8fe397d4e0d01aac4188ca50d7c1cb5d7190c9673432524e09dd5021143248c0cb2ddab8681d6f1247982758398fa58856b31fd06e060d3296c0f0addee2cf60dadee934958c33eef4269c23a098fcaf6781f288e0b71341aaa26d9b379ce5d82afe44bd4ff539cd31572f959eaeccc8475533a23e2e1a99b13737e6987b3390969e8ada4bd1fcf63a7502987a85d618506bef42f558b73c2c37a59611dc633ec6b0c67cf8061e3d2fb723abf66f7d499b24106a9ede65f63d98d252c918ebcd75792ee66f6dffa1da846451bf4538ab6aac3ffe3a8169f02d680fd410a2d049e4ef877236b4666767e61c7a70824b59b659dd63bdea33b4018be8288779702cebbd0a29bda595060415fbdd2d207f3a21e5d2af10bbc82fbb2738ba19606b747a1def27babb9a1b56a415b78f500da3843e1dddcbb6ec74ede078d360b5487951dc9b8c61913cdba0dfcb4ee10930164de32b5e004e8840bd5aa77f9d041cd680fc612001507451921f10128c0508772bcabbac4f4533846a81f9c017f84cd3a0fb0fae9751d325f1477ff0fcc249cdd6bf223db338b718459f6df3cc12602eb148b3a549280c8acfbc46aafcf549ee91aebe5535a8b0073643b15411318a1757233fba97f370c56f56fad7b2eacd66af1f15694818346f3925ac8b200db73f364b9e4212346ce1bef16b286214724e2509afde2d1c97846a1fec9e9c9ab4ab732ae681fffdc9ac0fefcd9cd74e1fbc8ee498e85be9f78ccbbe03f418072a8a774636a95a2208818c7d9ba089aba719ab320dcff38548031da1996eaeb90bd76e61871a15b5404cefaebc1b42dac1e4a14e3f73d8417806c3dd00226402f495b4266b18a74d3bcaac818a101fe8ef031bbc43f8b7dcf92f36e21e198e242de1333029641873e5ab65fe9b36ebb5887f7ecd239987830a0df5ce72a4b7f32c1288a99638d7d07967cef28fa020ad2d0f69d0e1d2444e2a0628089698bdf692636d00e24cbc8b948325d2d3db225a6595656c320d3a9f6b5055be67c663c685a73ea684dcd8d7307e2927ed248f2ff6e369517834a3926490d79622bed65f1bce93929f2b5cb66011be4b6d508a15add6235ccb0481adaea39f7a2b94fbeeb065ffa37fbd6d7a3060b466b1120a57f88a90306e50658ca60800602d31534fa697d09b95b9f6742dbb10442bbe7acc448deba80c18a38b9e23f97d842b6435ddb52dfe31b2d7ea8f6adae491b64daa3c82c7bca612e7ad2c6c6d32370c6d22e28f37d3ff98c9bc148df5d1f97920045e3fa1b043e88c33cea1737c7774e37d58ebf1818ff272e039e4bf8bc771a903320b0929ae1f742fa35a32220f3e027b3530b1bd36ca090e46cbdee7f04fc5ca3c6ec976f5f2b9a4f8181682c05d2b56214032911a6ef93b5e006b6c94932a720c304ac5a94b0047042cbf131c1005d57f23198741bbee775e0d4ba6e6f7b545194f792214f51ce4db1801804534ac013c60e484c684b28a04266521597bfa2bedccf81f7f5af64240a7751f4153c3c5c5748dd36857caab11c5bfd88572effc3098bf7f418fb70fbb4b5e15da669fad8ec7798764568ea1df20691071aff4fb13136a73a6c81941a8ab69428f6463955c4858c50ba93af3413b2ad53294be1b555619fa0a004bdfa87e64921cdad1314a7d28962fe47cf2f97cc256197a2db98e5da8b0ce6d1347b597fd29baee51bc75e6240f73800371c46e2f5986ebe026ca8349416e7a9397f5ceb4c3527953737908721012b691c0af4f33fb12a57944f5c3626c6474d79b09af5f7e3ebff763a568be7768e68df3b1cb566e57212bf8a0534451fa3fa0e924f2f7a2d6fd072804eea641a63de6e1dbba28301f08fdabebb968a6ccaa3b01e303fe9c87e6ff03b449971e491988da3c9f9fb22c0e9457a98e399547843fa1aff9e112359fe647b7aa845c522e17f4d1bee5c5bb14fa4ce5275e76324f12fa8e36553a4ece49761377ea26e971cd564d6418ac9d7e1696482b82209283252e946869503ea46960ba45bbf627aa333a133070decd43750330dc8abfabf59fab4c65ce7cafe64e11820f72c2c95747328e15977235073e4c3df165b57186335bfb0f9cd7a1b43596eba7c36ae4010d8ab959cb84afa532dd921341557824fefdd421cd07e5cf8a207f5fb5352e0206188c62b874ad62995b1c6b6cd9191f3ad8fbddc47b618c837e3941663c3abb7af6453e66d65860e1f8eaa64c2daacfa93e8ca781b63805096ad7dc6ca60d58dd2da1bf125c50a2d05a5b2c362795f7a07c429d1a47d783c1139f3ed15e7e127c6f9f330a341e088576784d9236c2ec46a2f1af00afa7269f2ae049aeb9fea6b60769953de8c15e00f9fa253f05e7b09cdb7276e10542f931145aea785136dbf17492e6b3f78db368dd9eb3ca6444e109bc53a23f10cb0c889a5633acd4a59dbb843229da858d7bf9b1ca4d75d050a348a226356b2f6e0b8c6a91ccfffc43e3fbf2b976b2928b68be75056a1c7dfa0dabddcb47e1ef3216e2bf69fd79661396aa01d7901ae7aa19ae25d774c184fa23caf7eff617f6d630452d30fb11083657afe59baea4ef508260d160cf608adedc89104dc3a0189b29eb6f99d7628c3cf2b0a318f0e78fd4868a0b2b43e1d6bdbaa73c26a25c70e2945aad4e0f88d2c529e39f01dcb2b386fd31e3ef0d7be008807b6d240429b6f522accf5d5a470db2b95da4877cc14d655bec88ef106ac0315e0c5231fbf189112b1ec5246ee4e6d52b41303085e822dda1ddc53834d95e349eb51e5e20d1361a93cd6b72ee4db6ba3c2464c35ec9e4bd69d5e84f3be402a3354b35007ce7db2cee88916a3d412e10b1b025c06f06ba70f387d7dd9b892ab0a5ef412975c7a278400126ccfb87fad2ceb3332e0cc4e87a2141b3c4545804a6ec6bb24b0ea2cf6fcd324518d8e02b23e427d25ca15b78a967a2d4b9b73028a5a8949c50fa9a2a01656cff9d9ca9ed88c5f734177c17122b10d40302256608fa137f4657a7ca77291e66c8f39234e1635bdf946c7cbad5ae6653ac205b6ca59bf1dcac8175d12642cc5be938c39c413ed543f2a9c0300e6361d081de265a90febc9662a122542900563c28df5a01da3cd045bfdfc1894c6cfd9ac66832fbe3f4911dfe0c1125c26991aa0bd02912bca2b8f38507aaa968353a6c06c1ef8c999b54a26de7490bcd78361dd5107b8ea83eb7f44b00d6ecb6a512c7f9e8dbb39e4811e2c81c8e8affd4ac5bd5807ffafbb6545701010eb19a9505abeab5fd77000a4894a1e23db12749365e2f5815768c97e4572c22e8f4f69c35ad6811efe7a1678ad5ef4de66dcd572536a6efd37dc45cbe74df3d75a1b898391370efdd506317d75380a747dd6743fb50b02eeaa65365136006a2a0d97055017e05175e444dfb3798af57c49d4442ed4a38f1a936838a98649d01c0e2b1c5a2cae03b3a4b015e455c0f732671dfb93e4ebf88ec08090e93ea4a473887bd27bf5a5918d45bed37d5a7dc8231837d7ebf9660eb320dca41ae5eb3afd71b2f74f55d12d317c044bccdebbb45d96f255cf02991facc1f91be2d1e0c035795ec67af547325260f4bfb32c09837686f9900eda343bd81a6c3edc4d996cef8b99d812ab421e0f6240ace845af3bfdc66a4c3af5a0c3ea8a3ed8be94b77bf7f07007f5b3bf97d9d94f2e4b9a556db8a7333aaddbc29add0cc2ef06d4c007d9b4828bdbcbc8451e2368f2d27d24d47b529b33b6af80c7dab74e1eb35b42b2757a641cecf9d80a5077a2ff90ca42c0abde58e9147bd89ae0ee276c7641dca1a4c2c8e3ad3e6697d27d362bcf4e1d69d4a6d6efcea0098491c8288ca9b1af2375f902c28a33708432511e90c895777194766a84686d2bac1c7ec276f269c7683f1b6870ee69538b4311d358fe6679dbfb688360a6d56345659985e7399fa3d322020470e554421899a79103cbdb47d66fd5b3f052ba3922be305c6178b28fc05085a39d33752979056d4382ccd36f6b826223c3b9a083846784ba6f2b00aecab9800c85342617f1a8b90a44025a9fcaa105e0ac49b2d927db2b40ca1a999b184aa55a22cdf3c42cad5c72d0eed5bb4f071ff811a8af5a57cb16e6c8092e1c19596b8eb2e9cfec07b838cb3dcbe9983feef1a9922202c30a90a9ea353370fffe352ea93afaeed22bf3822dc2e6a82e4042f8f20fcf67879fa36e70dca01c9a3473b1e2618afec0f87324544054bf4acc62c1efa03f6d5d04f6e86475b4dea9991a81358b2fe66b6501da7d3443a44d00698713b55d096513db877050b45c5de16cc13ebba31d398d34ec21ea2e78594121f46618a78bb2ffc52f1ffaba570f8b98a53e9820181a47d9c979d1c129a19ca7ece6d1994094a4cf862d4728c7f88acdc6af25fca729a0a2a62a25858387c512624317e132255ed5ee6cbd10606a62c3ee2d1e3d1e79fb33e3b25381b07d2241dd06051d8632b6c346944c82dcbeae57833704af8c240fdd3fb90961a7e0159e64f8cdf96ee71ada30f9551608b4bca53637a3746572254c83d95009e05396a989ca22640dbc9ae07e96ce4911f44cf858a80811bf27b86552a1f78caa589aaa7d2737f465865c751aa2d8b40d76647eafcef61a90d41e19f5b8072f93d47f6b1a89d141df15bc82d72701e2041ba54b74950353939eaa4a9b7252291694cf3435dd595e3764a410846c77b0c0edbd1470b467299447a6bb8ae735b919155f2610b28b68f9bff5798da035ab51a237115401fd30f91fcf2bf04aaab44f2b586cd36a351860cdc5952f228cb555188734e65439394d11f182c20c64dad731039a0b504707dddbe3d60cd4da338792a0851912855a98ccddc344e4e51fd679c49a20844eaea9e85a92ec2d6e3d8a75cb7dfb3c45ba5870212d1235a7f6bf8b828df8fd43c113437d5349e480a1e65fce928b3e6619eb7e53a8427391cabeb1c029e7bebe5ac448c96a706c59b0f80145817d7b747158b9200c447eec0148f85532f64594f6058c07596a34eed99827f029d64c8f0378d891195c4b2036f648491f07709c6f07c25734b6e2407582b799b2bc8e316c0a798720bede65a5d6548230f1fb7dd658fce275720d8b15324525ed43b970e3203191b610d37243d92068f8d6be13ffc2c6959c7e4821486b6d00e00cf5d0c4b1dab02fa349f8746930fd4167b96beaaa0ce4c114402b9efd934178c05d8fb42949385199c0cedb7be87fc691addbdf3658793472c693abe5b5113094bdd0ca644a3b8599a72ffc05f39e3b81375eea91fde992a5527935bcdd1d8f7e2f2ac01a8066d71dbf824a507bfa8369453d6e339f32111f202e37dccd9d99652c738f7d4485e9d2d15263a51a80315ddde8ba6a445e0dffe12eab6688ab03e1fc356855d9d7e7e20a3c6644cd9453894e5d2086ecf225476369ca943686fab7255c95d611ebf3f6889d4681db7e4fae4cfc04d6b7c2936a261698838f34259dd6db4dedb93be62c4c878e4d4bb0620186687aac0798598369731892c47c968993b64eb909429a11571b29534a73a3b1d0f912b0837d2ee98077a553344b5e8c7721b6d592dd530c14d5b59ee18d803aa863111b3834dbb549d4d96d09ba81ce1bc06040854269836f22154e651dfa96188be2e83560ac353fc9be7798e16926f0a26cb925db797bd7a74e6e727aded688f479cba948441ea05ff97653a1355b1c46b347e86097c2b46e2d870d1ac105381da0511ccf1126ffab34e028c2395d87995abb9175b3c6249b6708adc790e4638d38541ac0863e5f8dae12ee283091e4e396ffc43641c4103ccd8f0a263422a2cc3bd5999326b2d21bdd792a2a7f701fb66609f07f60a757a39d8bad5b9819dd882f8676dd45af0efae63c7fe17173758e8c3935fdfdb06cccca99345754538485a09772e3e456271869ad5180a839a925e38d802bb633f37fac54f127b4abe4bb377cc41b0a7fb1ef046f4592fde79a50be5577a98731ac679f3f3b8a9e7c949e287fef6bc20fe76d8ffa6abe893ee81b0bebe403762df925e604d2b8d4156cfaa5512673258ae4d94ea75be078614272ad3037ab014cf1bf6a5c081f2ea00b8436cb3c1077b08bcc7d2df15da9b423d488d503e71b9e4e145e5cd40ab0a35e2075719b1c31745a4c68910a23907817ab90191ab8c42fb5b6c87f14461ac71186650c165a156e753499fbb79d6220faa1da473a5beb8c0c86daab98ca0e699810eeb0b3a062e34986d7659f2490f92be41d942a40d346043bce9d896cb72c125fc45e49e14a007ebdccbb4a3e29b7db8235d57725f96655c46085e0f4223ff3a0a0fbe4145f77a52a2eadfa1e167b3548144fc51568f689ab80edac2937d09bea4f8006905fe27346f2a29a483367dccfbddedfe92f161ef73b796f61de1b13855e262fd8acd27de68f75f9ce1a469602658639ca3d01717858ff111b80eec75317e1f50f894dffa5f37ef51f2186014542c4adea1b4d817b2777f385c75c8b159c37ac8eb5c8df040d1c4caa4c752dbbd773e509839ec09fe73cc7d4c9083bf41262b8fd9f9e0e191777875dd9382c39188b3168f1feb29001f03e3bc4abcf81a46cc8c03b2acf39c46250b8de835ff1c38784885a35ea86b7890ee02c9ee6af681a0ebb30a6f6ccae4d2207b293fdc483c9e8b729031f87d974da9ba9ee895bbe79ac2fde4ecfac62a4ea4fa27eec1f881cbe632d413548f9ea2bcaa26f1abe9aa3382734464594a44a439323b8da1558d47df30425c70fd1150f89e772131898e0700f4a9e6166eefbef5a72f5311e208300fb01d5cf312e056ffec107fd64d82b8470d6cb829f7f439d8d8aa39e31ec362db952aef1a6600d1a642c62cf3793a577ff7b571f450acb242aacb33003ef29c817278a378c49afa25c93232f5608b607a18c8ab98debff904fe3e2b9070223c47b113302db7921fe80ae54e6f7a2207146444c7e169220550cf6475ba0e99c797550f1d7b3fdba1f1cb28156bfa6316be1aa3faae82fe14eca64ecd8c9f058d16f7a5e2c94a734658f88acd757d28dea3ec5aaa01fb2103a4144d4357cf816dacdc1ee0b8afea9fdf5a73be3ead9be9d57157ddc557f8429c12cf45805c24b9fc5bec84c16f3624e22ef4df1e7b9e429e3280f902e606da7331603e2e4a4b32427db46950240b6610498c7d130403bb66dc8d1dc98b34ae17d27937ed84cff779e9a794c6db5edb3c2858e4f3fa311bfee4e7f4bdfd681fcb5a64252ea52e1f4939ee457146499be1148b91d2b508c5655c0722cef254f82f18b25dbef4e01025e91b69cc24396bc70e4a7b2de24208fdc7072f2f476c3d31bd11c2bf64a8a1c796923ccd149a3536593025284d2eab4d6d3ed23d4f0e20bab66e2869b1bf37802a80c90644de1046830725c10125486b3fa8a024dc73201b163c430c5fea0f611fcf99d41acd546efd1a71d87ff895eb8363dc241a3456b2beb5de43959c44ed4c1cc40d0376dc72f5e71ba20f794e28af7f0acffd7de07f7cc5bbb003d938085fe66d95e86467e463adddbed1e52ed8e2f43b3f869cd6f187d0338a79aa6fd7c19e2e81ac3d80640b8b4b80606fe810943d1628f29cc80eb4a29b897149fd5a9bda04505a2e6932245c1f53a328b0bc5a669c255cb8db7f9179398fcc4f488725e2d559f03176d999141ad9c96f6c46bed6a84d90842ceb38783fb33db8e1be5a50bbe8db8821683587dac3b406c3f3322cde4b27b2aeed7f611c9cdbb0dc3726b553e9316eaaeb2e50f3bc90fe28a9504601efe4b1a61135259cea8bfefdc85e1ed97715a36e4eaae475534cb98859082685828f0828894fe4154449b8a33833dffb3b5d1dfa473c49b938b7c638d98aa6553ff9a00b31dc37e1b50505d0e48fc6c9606473edbfaa211864e156db5d594b3e94e11811e8366f5e885a7624789f164c3f73022be4f1080aa65a9dcc531e255b637d42ba2492580831f8007723d33ed212a4c85c974ea642874eed3a24be50e49aba0cc645e338530162ef3fc2ab0a87c83c8567e532411c9b27e7d209416692150440d7f41d38d956896600b17d4d1fe472d3db687a1a3f34e98df336427d29f57932e4bb576fbb9734aa50b1ab241483713ee7ee2789a9062ef9885d61b85b4e59f934c707e590c11480ed80f06c7bf5d78f2196c98948cfb7fc62b565c4bd6622a184a8b9838437d29d67bb57d4b576f91bda9532e26f5f75fd43798fa8c84e5c87e93264bf6cc5345316f3b5a0913f5f5e6c273cb4b24f0bb36d6bcc798de1463ae6c35ed349b5488f1a283c7bbe22b71e072b35423f5e114ed56187db9ae36e7ffdfabb8aa809fbdf41e1a1a8a90cc0a52de79a1bcb4b9b8b7e705719409da3c61314224ea437a719585dd0ffba90e912d39cc0d547bf2e78fb875d4ddadad5755c00fff1f1d208494ed577573dd25b7e7a81bb5dc7017c593a2cd702ab0afe4e851f33129c6d260801c6499e28274ee4906d91f593c0e71b6e3e91442842e7e204df753bc522007c49d0c5161ab99c6f74a3d8281491642a45cac3ea8b36d3ca80f051c3d66ae73f3cc5e92558b1c3556a621354341ad90976acbba9a705efc14927bc987525b33eeae382f9bd4062148102843f4088678472c8e40cd567caa666c4cf26d103ac2db73af2ac2ed81798c42704220009880504389246660f30e2252946c9740e814bff53a64168c332999ebec83ed44709c933a013382a82a56a307ac4f5ccd006de2cabd61006e8414f28f9273fe4563a1d038e4609c6a2082636b9982e2a5248a73ffd0d8dc8e54b7c145b20b45d87018f70e27e200dc7bca3e159a1e7c5b0dc98dabf7e9dfb28578dd7e8d21a29e1cb819c3b443e691519356b9053b1aa21ec1187208877df27e277217d69cdd3518a699aa6ae1954b03df959d02450f3a9b0132403636108b2d68ecab1aebd614fe320be63b2cf006581945179c4090f0579ad99159d16effcfb7e7c9f320b0e15666e54e0e9380f99743f4cd5adf8ec90563ec8c6f45e6466eed36d7828b72a45c410eba3b9685189c28fc1d426feb9df3198b1033dffc65ce5d749d237d873bca851839dfbfc4ac5970ec27ef6a38a3474ca3692e4d098966f1c512aea8c08f37c13471b0e0d887df9217476bae3f38c645192950b4c0511b658e87e00a0b1c62be7b7d8077a112b4843f4516daf63af374e275a8210eb30ca34fe1ddd546abe5f179f55a3f6b50f5d0897533d2299fd2377f42b0aebf91819d0612b08a45aec84701e0f137dc4ccec2c4f93fe2ac99dde597c31957d80db7becba1ae0b22cfaa338f6e5155f73a04ef0a983f8a9fcb4694e0effb0faf4687f8d10ac3b07ae5943a0d13dcc23c8606e9d835961390d32d1d01254532a46a2004803e94d5f2007933a6751400841140a5273047e84a1300d28eb073b76ef8eb49e9fb203740817a4348c83060be42bb8068cce92a1b6b604e3d25924812cd30138b9f37657d4ad9fb80de291daab6a270a8265f968d75473b3a6b1bb59b17705f7abb2c0dc96e45bc8b65bafbc772e57316b9f70873126b7efa48db606c2d06b99796eb9ce83e771be4930589e59736e50ce2c3dea111c2281d21d710e6e003e74f3a7dba08e618bd3237f410219fb83c21811283a3159279b850bfbf44e1eb93f7ee65904818a8f0765925591ce1293bdfb01538078ec23cad811e91e10647c77e4cee262ddfd6caa1e2e47504f9dd037771c664cc78a41b3dd4f582c0f1f6991b4c5468d1fc60174233450e57cef09bfcaacefad667c98623fdf902940104b9028f394372d37d04da6d856deb07b11ea38f80c15e7a67c72129087ff5106ad155fc3c88bcc212e7264b10158fb9d29218f0d1474a4f70c91835f38d0321434c836fc66e3643d3dc22a676596e02452267f35003452222c651aea0be1142afa5feedadfbdc39bdb2610a81468f5828b1466e9ed5af72744c9ab9b282df3ef93bf15a592e6cccccc115aa7cb1d04e57f29ed09a5739e96cb0f3bc290929a7d565956ada3340b42ef8b6f0d020c5bf610d26c65b2ae0a07b3aec7ef11e6399aa5e0758866a3559a80f8681d2dbd2586c5eb5e04f7c5f8cd77777c84724ceb9ceceb61329ff129995a267f7bde403135a6d3367234ddb601e8d9f98d241ebc8614e8922db64b245677c8b771a15b93c03f31a6b11e4064bfd3053f8c940d70c2af764259077566fd5801c4d390d417b1c95774c6f2072891fa246b0e2dd59cf45c38f53ec4a2673285db61fc933fd5622747a672f36bb40911e4ba8a66997fe6d638b7343fbc42a5492d229c83bbd2a8954e3d2beee1b838957284df5aaa7b031dacb0acd5b937ab12f1e5abed08d01f4ae110776dcf53e7d8d1f2a734444e13d370b0f1ec9f24ff72df6f82a7b020100d74673ccb0ee244bea8fe7aa5098480ce14198b2dbdc2f51c457e7c8d4bd553bea84b535ce3cfa8c7f42867ca54f9cdaef5b6d074a4e2d33639378d2be59b4ea9ad815198118ea7461d1add56a848396f71cafa99fb6c25323873384e177f446fdf3fc01e2d2ed53b309ecf1aa8547850e6c6d35e278c8527309f1cf7b577c494328b3678d6089d568d4c995cc92a27aed5205f94b37517d0c016ba4f47ed077fd10f018fe69e173952a1505b7337bfeba1da8face124d23034e72216aab92794f7d4be097e8b1beaf18b93a1904f90d7ef8f89fa2abd1fa68e1d89a9ee85d30289af91eb50204b91eb00d1a4d1f938e5d9a0baa99df92d53b09246c35258f67df33b2dafe5e145d993e91e86c1bd3505fef0270bbdcad4be66a9c0b7cdb75dd71699fe4c7689dd982eac06f66d62878dfd4576ee499b1b4c3ab26e2f4728290edfd52326b979a076ff2b2c1c9105b9d1b0c6455e8f845d70da571374b627820046afc2b5de3aea250cf1653623da9e222fe7f1ff1f45417cb81bf21d64979e4319c328e3dc720371ea350b43b51dfe500599ebf86aa808bb16c9f3772211b81457c5617f2c0c1be5a58bbd06925ed8351666fcb61b7c8e3a79ca8a65c7e0183ea0bc2384d8972fd1c14ac6e880922c94310fbcfe5e7c5066ad7594d5e187e2991b37ae6366c6af44629bbb5baa26c413c215c5e38fc3ecf672dc3319b5561b23c3ed583e28bbc3a6a640e7768da4e91c12d578c69e5a5afaca8c7ef9bfdf8f34cc258c520e20acce6d9d570ca9deb59f21b4b9acb894f3009edf5ab31439bf8d9abcdb2530b93f74583342b4c068c82a1268d2ac326f2038ce6ac2885a91e341348ca1ea9d32941fe0a60d0962410fd7de15a8c9dda201e4e80582b63cf5ea89cc2dede6b88ddf382863c7c0da72ec52ba0af9ae4f1ee392b8eaaca2daeebb23266ed76f3afcac097ba1661ecbf46b138d95047c6d5df3ba234b198c676423aefa895dea9a4d5c8aa0bd40977bb51c4dfe92089281663583eea12a235ab2dd4a4200ee500000d66c59bffa2747a36eb8718427830e5a4eadd85b81638a7a999e619ea68857c19916a7283426d86e177500fe6e0b26e4bb83a5ff4aab1b990d918b74fe9239537f6e81a9d3693afbc17bbdb3657268f5af7f66797778372a326b9f16bb838674e1e8bcb8be7bc7dede2c9b21b4fcabfb6fe90c12cb34a71e755d061719424e32fc5e5621ca644ae8f045f43b846dd4da0a67fde5c34ecfe163cd8efe41240c13f2b438e59237ff8a8313578230feb3f26205dcadec01f059231a17dd7b66e07040d0ab2da6c79388a31c529785dbdb65261b5c66449fa8d8de1d6dadaeda5f0df42991858de00791d58c25f6ea39061715af101287cd265fd59c63220f141af721267d86783bb4e35ba2e98ee924f7827b8bee1f4937722740d6c0dfdbadacc67d0e45369240595b20e9f85cc46459b7cca2bf2b0b98b9716b42d0a95fa633fcfa3dd97f38c2aaf3d197902261b97787304e3b33d071fb3f809e50b842c19058f9dabe957bc8b145d421b5fc8887b6980c329bdbe3ad77503a5327ae730e1382f1f67b02003aca58dfc823e8404af2cb069d55504179323ebcc4f8875909f0073c96f722772f6aa3ce77d311a42378f40faa2c6b89b7501f3ff946b6394e64b951c5b5d813765b34f9bdec9425fbaad53b0a6d203e0b36ffb45daf134f290dde3ea5db20ee7c18b2262cc591a30d34edac546afbabfe319328122c6c2c255710b575ae34689559ffdde0f1928d1a9dac3c482be17a0c52b9b011613b18470e5c5de8c9a13a95122c74c349b4405d43e2ea3d1db7404a9fc4f284b2799c0c45da378d46d4a2a797312912ef0953167986c2edf055a41793d354352ab6a1eade89273adfa0e07e3c1cabc66290611fd82003cfa24488d18d5d39b3fd92eef95964cd0eb6ecf41aa1360beb3db38b7cc223263de49bc1a284a45a2fe5e0c31886ec466cd5425ddb02970f66920e3f984a49c73f181bd59b2e99d9b843c0042b542d03577a82a753d46df5c7bf0194938f7159159b5fe4716d1be5d7ff57782c544c5c4deed225e2671eb7b4ab4e0ad1787db303334321ea7619bcd5dd5f65d40ba88579ede5838457b95e48a613de709962616fc0e45992002ec8282f5eb885c2b2cf60ff5749502f15885723300cb90cb37f8f758744e091089b62853a489bd4ec8dc1afebd610321f25cbd9aa1b39b7a091a1bc2e9107744e15cb79bbd96b187d67b68d2145534da61d4c63a9bf781e5812490bbaea9d4b9b2a34b6ec55cc85ccafcbc2e104e3a3bc3718ce80fc40c986f31939eebc219e30bb1be538a2961ea2ffb49f38bfae43e67bb84229241219fc0e2422eb9ec732c64b2f44df8e1004e6e0a6d1fb29bbd9e1a65ffa59c11bdcd3c88faac54ea4b189721c25e4b491454b7f558e0730203aebc89ba70780d343f0d7608d1bb0f9ac30e268c2688eda9bda9ac421d62fc8c1c55fb4a7fe00554534c54609a9a056b3816a793927bf01f8d75d7fbadeeea15a81b134176eebc4c156022a541c4f5f31cda13f3efa9571b7d13f61a0a71139099b1499c45c6341677bdb82c097b1adb0b9eeb370d40df927272f93e5bc9e72c39166837ee20c9c52c5c60f3a969241501da4ddf66b7d41c8e8b528b6f2be5b83277d612ae9c27828bf4dc13b50d670422ea1f0b850a22e843803f5592022d3d657feaec179038b77c354d9db9bd1e13d2203279247f968e00385c9cedbca2b66368abae6c346393a970fe91a8b5e6116bc379660d14692b864103e98d36838c8e54014b69e42d2ac47c272551d0f163533cba6ac670ec7826d7979b80cb2c2cf53a1ad32f9fd26801dfe71ee34c9268a2f559c7df49dbea4f9650886bcdfab51408d4ca2e6b8159bc97e78940eab8bcbfe4d36392c3974bed6d57227a213d85845956b303a23648a604968b4b83d7be3d738f59cff8d2c8bc9888ad6ee523dfe6839979159c77456c3558f2c40a45dce9f39685bda1abde0827f44f109940df9433f8e8bbe034d7dc2a09d7152ce7ba9c321d6f937793843c6dd6e49955dd247e0f9bfa1cf491add2398b7cf5c77b9c21bc48d0f8532076cf71da0e87fac892aa95024808bc65373aabc730bde9dc16bc46a84aaca27edbb02538115038c37b21fa704b3723944a019e473d6e67ee4b313b1e6bf610893d4bab2d57a4d43eda856044ffc51eb55f24213b4c19dc12d7058d3f00cfba3960c768e71ba29b199a07e2eaeea535635cb34f1435ff9bd21e0f9b43860ba9cf0d7bcda75dd13a4636b1ad1fed5c1db2af86b2932bcd6901203422e746fad826b99c0a6ed12071eff516cfbe9123dc946b8fbb832be8113e2a0bb75d0d95e11faeed28f51b753419a1ff3bb748e844ba90ecf18acfb7dfa8d67b8fa87572a753363bef033710badd24dc875986b4e664f803a0ffa7795614c146bfc74e6b858a87e7004642fdd17b6708ec860e9e1a5eac1740880468f8adc3b86dd4007a98336874d01189e749386aa28fd9108621fc5803c0b0b60c56f68a9e54d0a0cfc78bcc8950867cfb666ce861530ecbf61121788770584f67d4c900e1b44381ade87e0db8fe05d9a94ab1e9baa719ce6ca62d82f2eeca59add14b26e73af640cb1f8984ae388707a971acdc14b210437d30c3850cd2205139fb7fc0673a176748ab2929e8ba3b44b836a92d7884e1eefaedec763193b011c091bd9b1e9f6ad227805f1b9a4c235d3e33830bde48af221f7c4547d59d8f8e3807f1dde3fe345ec677d4dc0614b2a0339102f9e8590afbc1d586dcb759fcec460a209a7f03d2b13270681ea0ac33a396276f10e4ed05ad09097340d146a957e71923793bb05b6eceb31a4b6b3613b68d2945fa37fea500eaa814841f7ec1b30f8ccea133b8d1c37930c726be4f014f340e3f2624e45a008f0b1c494332018c4b44457d9421d989311b8b544cef258b0d126ba5a74e9d645e1e37e7afa956ddc36270384e7064275238839577312e94d331ef717bdccd33b1dc028d0c8b15e602c67615c80267b4fe777a88eaac779b376d5ea1669b0280e8a38689b73b31cf066abcece22b140b30a7156d3cc22303d38808249228a27b0871db331ceac5be5fcb814285fd3dd71c5b0c0feeea4ef73942c50cf2686fb291e38786a4c787a5976191317a9d06297c0f24363b3311a7dbc0029e37bb48602bcb4240e7df1f59f0f1caecff854426710b294da1395ed19ff17957d7580437443a8d8c6da3200235abc67f0f285930e1d0e0733c66d566e3f1292b26578a3f3d0a3136d442587a5e71db5a7848587f4cc40add3046caf6857adf438db7d9770fe5d070d58cc1544ac20084a2724083525afd3edc8ae078ce02ff3ec845f0af788ccbbb8656a80ce26d290c7f2a28570c7e896800bb92cfaa65591f633262369c51dc054d8565074b0bac2508908388bccf4106a03d66db6205830f35e947570ab595214866f5f0158f2f10c9ac9f784be25e87b22c88377f5b3db3455ea71d03b6b2b6d78dbbb0429752313c47eb6212191b4a18a3799fc4dcb2acf4e1fc5b55262e2316f0537acf9e3d2638398b89d7ef86e0fa2d6da25ca1f0cb02a9c4c6d2cb9aa5cc4676d96ceabbe4d19a8f3d1fe8c3512ab80e76f002ae71f7b2196111c7a01c55c527fae0e6b5a31cc18584be1c827b2ebcfdd2b8ae544cd94c8422a750d9e73822459ab668449394f2967f1c824d6822121556f00e7b005e74e464e348f3b28d1fbde2753a601eb648dc2815f101f49afdddbd755a7db0d83b9abf6c3a09c134d6b03e5b60770873b5d407ba1ec3c1e92b9d400764a85c5ebaa4b6eb6618d30dca05f98cd94ca229b2de10fd1a2287d9c06a37f09a0e17b8e5caa71faf61257a9f13d78cb5d1a0ba42bd5547e58135bc2e9e6d2e3cc8e46f8191b4f58fec2464d29eb69c3d9b3966d32fad96425e41e8ff8ebb20236909cd623513c7b82d743491cd2be7adee349f07c83881b6c49cdf37767d01924ee3c014fbe8246cc4b2d359c4269629214b0fe2f69806f7850e505f7e122d35100a04a2ab29e0e189ad7933a2f89dff1c9b2caf6e13886849db6fb1de646497be55b80584f2a3de09d99f51cde877912c11adeef1e1ef239a30351ffe91164542b5e8cd8751657bdffad2cab1338ee148cb8d1c301d7ec9a2d91de9e31d38853afff3adcb694dc6d0a7d550afb5bf541928c18020038d25e7b62e91a5ffb329809eb11d381055be860fa8f9f6e1b1e6e15ffde5ceeffc97fb05aa66e789ab18bd142ad94c964d54e9ce0e81c64effc2b9448b63ea1ba2449f944c32ce17b283a1261bf2501f572e25241fedc27cd381016f3b59821b52974aa69dc510333a6177d60adb4bab8f7a5d0ba6d820bd2b508284a3f4b556914dccf724bde7011bafa4c5686dc2c476c7fe3815488e442fa22174258dd61f59fb0746f7a7003eae58d64990b492ca670305d124cc16464323ca33ae2991838f02c3890aa366cf95449ed943d7ee665f89b9127a85a2c27129fd6c8b686bd1e0833d544faed880bd00ae9d82e20e917fd6686eb4409c52ac0f6fc3377882e3caf299af680cf4bba181b63e414a9a5df299c6b266384ba7750c61fb6fe6fd998dc03b37f8e7361b79cc4d1c737c0a835b8805faf8bda739f414fcc6aa6e17390af78148ef48da7806d4b20503578786f880f78f63822f8c24e9986d844fc0e6864fc7ddbefab37935bc95f527e9d5bb61d1d0882c7ade29617d8c10756895afe355f40be1012a6c2760fc0932022a88c29f780758f8453068edf87286c06fada1da4c572f1c389da2cba6175600fd04e92013518725fc1819622dc05e2eed769432651ca87103fb42947447fb28d4cac24bd8d299e9cf5b526c866b6437d1bc8e8497f4a70f16f3ab776b0b059ab76bdd43fd0f966aa920288a780e0cdb90a569e4c9d7dc8e44f6141751899241408b6d3901736b445270cbcc306cc499f5d14f8d9e5b8f9cde6111f92b0efa6cbd3f5dbce26bfbcfeedb5b0560c3120ce71e8e4d102a4db7d47cdbd5515219a697fb737bbc32a96f2f6c59ad722303bc0ea00f0f179f57a2ad1e681ac72cfdb5b1ba2529ed9836ea050d562dee231b7946d55a9a82c90a11ec4c13d7487481e101bb78ae8bd82f199897d6d62ec6efc82bd0008b73b0b0fb4266000bbcb5b9d96c17705b296f7d3f07f964d232f2fcb5eabdb3c22bed6205c2f00167c386ae9a0e2d1de0e9997ef8cde59de598080c6e3eefd3a7fcfc25afb6775f2743f476965a3530f213a37467aca59e52d924a76053e1bb70421012a5790214610a3d4491bf53a3eebd38f0400becd67b0de81c4db33d8f422ef1f0d40b469a34ec12bdf0f5f1210323a8dd7a5563c95fb45401c789820a7834bd75a5da363ecc0853c052d479170fede049fb5b7ca4fdddcf4341f1ee8375c131728f7a93b208b167a699f32e93c496ed8d5b43a18b76abe94730f6259f62270ac5c62e7fe539b00305bb16a2e52c72249c4b55b13a6acfc59254530ab547da7c613d07b8849245285d46c2e168a31af4ee95bccd1f1ed2bc9126ebee38cdc1e66abaa15aba1482f84b5979e22bfe1aeee8097ad285635b89db415c34c62736ab928fe2fc18831acb4a5e4f2f97dfa073e5cc65f2cc316a34171590edf4c2595aee80747cc0b42fb101c7c4343f6457728ae68dc5475ad46988805edf96fe9f020fa48a904880536f606626b9f7e779f6746082c8c1c7697310aba5bfed4c9b56eec55927fd21ebbd582f5dcaf25b4bfc3cb2ad850da5f18c59acd6debb09c6c2108c70ff19a3b218156d7cfd8eac575e42ccf7024593d00c0f3a0f86bd18d0f430147d356f298689435490b25e8a7793ff108bb5cd312954c8c40f43c4394a3ac7daa9d79552c17b5beca5b01527ba0c9cfd87b835b5b8973ef8629cbeef0d83a64ab37662c2f78003a2a4ebeb2e021dd9c69a1ff06896fc151842aa477e72b55e2653295205825bf09c54af7bd6554f36dbdcbc3a62ab6a1b6fa5de91f1e97b4c3fe3d0e1ab0ece89e9d863e5d2e39faa8f2f987671e979b9a9ff065b3b0d9c36c46542568f3f03ac574bc47d84dd56045caabdaeb5e0a8a893fe2264c60be5d208630f9167e4acda71156305de3852f8ba8244ae2972ab71fa1f6fbeda035309007601b4514d1dfe50f2b015e03f40a749826a4caf93cfd22823ec4c0e98e8ef54db53131be1ea1c3ed57571c28ac513432611d588cdb821742670d3f79688ccf4784f929d0e880717b66f5722c1d7c30fe678e4a516a08bff9152f05a4a620382fa2ed21a25e28661170cf9edd609acf1220fb91c6a3e233ef0d809cb271d72c1f96110d0804f27de68f087f9617d602027416205f70ea9869dfdce1762f5dd53e896d0b35e91744151e3946c6f2c12f5499598b869d5a1c42766e7e34d41f24b0a404e1d75944052ec3e59be1e6279246b0d9cb4f49830f6bc22eb7561bbbf1e784a826f802f9bb0f4597e4701340ccdc5c98306eaf731d0702fe38d3d99b97898e613235e5893e53623c39a0a0e0ba2e28a5a758196896ad1b29700648610b2334d728155323bc42e34498198d77714177f069bb67917a952a69c6e5742fb23734fc34772d5031a7f7a73bb344ec36e4c064c4305267be24ce2c9e3db3c84d4655902400564cb3778b0645ed57950ababf66590e18faab113cdbe8abc83fa6cdb739a91532a92ad726890f0d93a40f6ed5b184bae08d9ced8893087ce32382824ffd68a2fd28fb9a7137068d3e323bd005d3b7091dece9e9cca0af22703b1b0aa9629d3aa77c77df379076648ec4db2852b0814a365c67d527763bb0503571b2fdb5b8622f30aad2affe6338aca643e246e7e9e387b7f740121063992a33cc85f7a558f972b118e26e82e48e1075a0128e194d1b86925ae5c6460df02cb903bd336628edf35571d6b03798a1e244919efd0a38839a78877fced8dc0347db0465ab5f60f356e6acfa18359d71b3c041ae831ca2eb521ac30b837062201de568bb2d4dd667e2097e5a55217761ab731bcb0272d475d979f6f345ef098a829b1c5b52ca38e0953062cbd619a16459530c3fbdf7fbe775d2dd812e5e27bda71eae7d335eb94de8d041b819a2a69aea2ff336e4959aa325db4fd91459920e3d361e72876a31e9cdb17c8895c9885dd7cca9b23ea40d07db94ecb7ba3822b81e17243392f10827ca2ba65107ada3a445f732ad56642b20d0018a50da2610ce3422cfe36bcd28ec1667671e279c7f8d1217f276a6e3ab3f548c2c11e832bcf55beceb62b235fb3a1f905499cb3fac0d20312bb6bb1b7f3ae61093a0963dea97e65dd303b68f4f66de2a4ac34fabae0b18115c974a871617d4533469e16a234420e40ad2f9e8a85f7f25d79e6e16856f3fd72bd3c848f329f649ed9480428a9c5a2db7bdd3df6eb3b6bf6e9a77c9c21be8f2bc4572d5d35be597fd8921906f6d7eab521e9dc7c63fc0dd823244e5745f0a0f760262c46a3d43116306627432f4b97cfbdb3f08d8828b7ebd5bcc50f0b2e7aa27c00fe309d81a6e3a15f624a17cec38160abdf3049e82566959c88accde4c9d1077330759de954d0fd7e97f39938006f09f24454733af52a5af6c6ae9fb87428466687b562ec9f69d2e5ca90165bb7d3bd61e0d7668a72d7d98b39b8eab02faef4f201f1e5874e09e7ff1a90cc3a9d4ad82933c921111d3fba9c3e3d03dc1acbdface008d1d22daeaa45c57827f8ae759a52b6503c1dc6166b8c21b8a6fcff82243590b0dfd4584ff89aa65ac1d80cccf6447302c7a111b713149cb30b217ac74fcec11e6b8ff584f767252a02ccec5ca69a02d88c0d6fd235e989396dd2d386c5721b85875e238494da72c7697c90c4ea82136bdc91ba5d81f8db6661bf152a597008a828c9271ed07040c78afaeb61e6804e48ffa638d896a6bc1eae17e047d6a9791a5225421eaf9a78c04eb26061744ee97b4485d66018b826062d0bb5c9fbc1d0acd60b8db89c7c1a049703cddf14ca090a3155865840dcb0016bc0a5377ce751eb35e7474fd0bf08a44d06b37908136c63f01eeef792bbd5c1d321fd875faebc2d2709e05c583aeb06912438f9052c1d2b09b72e899bb51afbd72c760a48f3148c515b28b80323f9d3d437720da6c52124ada6aeb3085590fba6940aa4da8394ad5573ba0dc4261de4f28ae13a4525556b3bb1baa059f873f7db5583ee5c42ca1a283c1f118ce9a6fdad2cf226f527e607da7ca7802b54914ae7a51c03c9fde809f898dbfcd5881a7a8989a7444d370f4e6e4a8db20a7455c2aeaf3f9a9b0cf22f978833b7f7ce5e87c1d93c42738005d01ddc9ea1ded88d9823294052cb0275cb2de7dd34cead37066d0186bb721f435931dd8988f9f6a48edb0457371719757e16d66ffd66abdfcad77905eb0448140062a3ed3affa6bd9e5184fb18054874bdda3ccf9aa9916f45c3383cbf71dedb38df6dfd2bcd7458c1a6469e16444a5a101e15be0972c690eaccdc2f9eee4b9331ee85c6395d2ff5e5f6452a4c9e8675104ec59c497ab4a560837ea21805ab4f55d2964b89100196fb7e62f8ca361c17194f27958e44df282cb70ae23c300fbc2bf6ac471cbc823d932293f58413d89c1b6e38d0be58e009062d77d31dec85edbc24abffe7b0a802e090a6dc0976a4997dd7aa6d50bd5df37691c5a8872f31c5f3a99eda4330b0697c13ea778666c431bc7dfa0de54a562f2d4c026889485cd30ba101b0c398f730550f319ec62d3352bb9470d82d6b821db5800a23b4f418faff85a32db1ddcb6cf91f19bd0684d65d4bde9bb0c080347651883bce52d3821ed9487a18ff7fbbe1d3a87f3139bb1c0efff419bf3e59ce07d9b55e6facc74449874b3d9659cac982bd19edfacc5ca61f842b964549a20a4a9546806c33d44cbdd55fbe2599918917a494db8e89f9d312299a66925ef308384819c5614b610dd92aff1893ee6466452a220c5b035301dcdf42551299193a356d87407976b338231845fc3b1688fa72b6f734bf98f18d385099fbc75a0912de30b88955a9be153103f50f6e4367e4d14a605d8cae5c54b6e5b8e28193975ce78b9e587f9768476d9de403d9fd12ae714da8250c854438f0cc77c061833a6390de30d07bfd0f27503462b5f0c74ada87b1779c71b55b9a4dc2d5508ae98d57a522a5a82cffd9b04a11b0412f84d478cbb98970a465f86ece8c10e083127dd6a8f8b8b88c829b270475c838a30b754da32de576aaaf7a3dd2aebd8ea4ef7d333a1c232bd080bcf0e42e3118a48e868c697b8570526e3ff0e4dbbcefacf1c62886637913bbae6dbc65f599767d1e14ffbf721ca0b37d857de0a728abb55f6164bc3e4bdf3ded48c2a5d292662bba2076d320f4075ca92d9b715a6d7ee1475170e1d86a225429cbfe7bf2c6d44839b4272ef025c097ef159823f0a4e6317d1927d97d0b5daf959994758555a3fd4fffca41d07eebe68e1f54675a464da953d19c236f80befab2ad52de7ff9b24530360a1153b102477481accc4eca0591ccfda8e6bad87dc2d80654a8e5bc6c87f9c9dc4f712605da50a0dc700469f6bbc53586a34796042b863ff269e9f05465d8a590041e729f376845afb4d7a6e7ff670292864b8b154bd95752b09b76d24f4d157b23743648da10a4a6f83e3c13f617616714282d472a383be2ea247fb05867d1c498bd8921575fdb5106f3bd513254cef5b3201fc02beb5122bb66c44581d3c21dda7329017b06482c0c481142008501476a74ff4dbbbc6c88f274742855cd55b93bf9decc7dbd0c12aad1a1bbba9d09f3d726179ada1e32928d99cd059f503a47d6c6e4646ceed5f965a230d5c5c594015a1719d13511ec69fed21d4989d84c6556bda2051a63d927fcf52b129f0fbad2510404cf509ee2eaac6c36205b81ce001b4d49c1b565e8ffccfe7b9fe50905400847fe3fc5422119c42433c755cf43f69d4f2b05de58995f888b387f87a4b7241d8b917960eb254fd90837b50962034f3dc8bc0c75722994f0cff3e02bad15ee1c71b7cb2b365ab3ddeac4ce52c6a97abfe3effbf9d91082085ea896ab13f128ee853d43cfee86597e4dc0bd077d4a3f315e7025dee2bb92b56db47df98dc5deda698facc3a79ffd6462c4da54a9e2aa9de82746fd4cc46254a0610269f1abf84a9a6bec63dabc512b49fd0e3bb51ef81b60cf6a1dfde560074b63719572d3b9f802d5cbe43ec2c0c552598017988cc7dd51657552e195fd1fbbbcd04db8c549b22ac83f3c0cee0dcf002585c6864c1223f20d6c47b40f012a4acdfc45bbabdec54be21df64c18ac42d93d02fc9b397a87ba18110d557a6c9ed9f8f99ba67dc6c71dbac7169c93233573bc20304a0161b9ccbf919b73dbaf036ef902970105b9029239fb3924da747b46f7821a947c4426fcbe6984394aedb72b084bd8a55b474111443f82e63a7f92a61f35c663e82e5b51ea54b059a41ad0551b5e09097ed69b32391e37f3aefeef153a7f3b9b2e9188af94dd42e385577e70e4c5b09ececb16e33da8e0ece05512a18b77ed4d09b668511e8cc38adde5f3af2f0d395d19826f90e64246452970d958b687be8a10326ecc130c3ecaa90980acd77d4dc28ea744bce5a600520de6268d3aa1392f8debbb0526553f5752c473e9d398e4d3dfd1422a254e09dc7220a968953c1b19f35baa106337c3b3baf29ac4d5b5eee71c626e7f78c651479191d62cc6e497ee35eb6a84158de60ee2ae756525c735c539474c46140d8e09f3f9be0e64054f9fb7770777817b7d33e883f2e4267c98ef95c7a59a6d8d2d31c568689d19117a94ce3335b78480195a7b867ed9c419189e231299ece79ccc29667eccb7b5697561d4be2169d143e8c7970edb83fa39c515762065b2767f3b7dd6ce449a7afdd40872b0ebbe14adfd5718d7e019a94d508162f5aa6c0a1dd07dbdd8fe8c790251d2392a01cae7b5bede3247d32c8aff1776f5d212fd0734e4d266c794eaade768a6cd396a1b3e628a5a6c8b2c155a4d07bb2da375771485c74aac6d92b7462c56ce49ca619e032aec4886b720f3753095c3ec5315bb2f488b24e37ec7e942e748847a35b0661483563969918f9054883542a10985f4d8456e639465aab80350fee2390abbd6fb731a26fd85ce4996586d37e5daa1d58d4405228587a65facd86758061b13b37d3a7a4dce90a31177615c4e62f8980a1173db44bf9c758fd6f1491b059ae9feedc3352e445aea41129965cc4088bac78aac57a8fdab7b74250e8ee90d50956adea616a195f7b718d7d0ec53931eb9f290e6a9be619d496ac17cce3390babbac2210f91eb50205b91eb0ba3e1536848ae3bdd7724c395ea274158cc7fd575dd84ae0cf03d4f44e8c2f5477f59e43eb3b5ab727c3219fb279a133b076ac81b83337a0751975d921f329fa5d9590eb3589b8e3765e073e3242a8482f5acdb084e8bf319d6a7cae240565120da8c151cb9a8a925f3fa297ce72446ed8e00cf2989d68eeacbae0d3209040690d1554a14ce5b43e64edcd60abac2f0be146463e3b68af8a0f7df7639564f312254a201121d30d8316d744c31da489a0aa2dc917177786793fe1fcad429bd23a2a5dabbf07d24301e498e7f6cddd3c89741ce727ad673108b2f413dd08c383d913dbc59e1b258342b574b08bdcde2d82eb366b617e220595111f0a3329d12d4de82ccb4362355798694ac76f62e7bd2a9f9305c7c71978496478f6ee3a3dd04051a4ca790b75273354aea6ee381898a15a258e856945407ab72c3d00eaad3bb3674297cc90a6029ff97cc729968a610ecf22e2f10b5de443bfc4040c819f0baac10be3f7b29b264679f09d88ee2e68f2220c0a4794a2cc978fe56b62a4ff28ab92e04e7a796dba432bf74d2c2a2362286190d4a7ce8af5f081a090267e6e8ca02c4ed3a5f6710bc947587a1562d3d3a8e226b74250a040d8e6d83ebfc109c9282ab82218d89deeafc91cc559121006c54cbe430f0f58ee67c87b9aa6ec97c20bb7cb9aeee540f042871b625b724dd4be73c84061f77e60794ee2f0a0e736ff08d0fcb9780c7f0d01225d85865f40fee22db875c614564decc9d8bd730e6efac1a4d1b9e1c2fd63a446ffbce6a587f8ec049fa61c9f01bbf052c2c21b59907e2a8fe5c621196545fa10ff3dcfbdc34881a090890a65af636d3fbb1ac01f2b5fbbc4fb0a9d606dadee43dafc57db9bbd1a71eb3302a593ec3036d99d4d4f7fb5fd6ad61047be6dd4c033c3f81caf160266286b7faa464f28515405b2599912149f62394a70cf616e5a316a33c550f8d64378d56a20c543f41f800dbcecc94cebcf464bfb85be89876861cda7815025f8e70d94bb27b345ea43f54a01eaaeadbac67bd38fa137c16742423d991b7157d2226e59a97b4256c44bd51941334939bffc0bd3b0e4241a0fcb9dc272f6c9258ed7572f683b22ae976ea490f19425a29ea65bfef15047f9a17c3b6a6d53fb0d5811802aa6615b6a0b0c7242073e1316afea36392fbd5c25b9d927a47eda9f849cf5ba14834e997c3f69451cbc3c7a7bfa0dd1d43fcfbcf2fce31d78643e41ca9ff2771b220838bb0ce9192edf4c0a88ccfd212d622f7d2f1a95a13bb2c9c8d56dd87c2dbf2722a464bd3683121f731c637e2df533be1ca4e19ec357db0e78b6041a828d549c5b5c490b15221b127e0602741666bdaacb3a1d7a8902dfd0e474132ec0c2d11b45c51279f82639f51241f4c9719be6cb6ae61ad56d929d2e149d6ad5fa2c8ae482d42b8ad78bc6bf9daf84259c113b5591ac1dc06ab5ba1e0fa48a39f69cd6ff3a4da87870dbc58024aec33b47b0d6444d12fdbbd7ca57918591982f15ba99d3db3a627e715f6b5ebc990737d546e142b9d4ce5858df23b56d6c34556f30a89c8bc84c5f22f61e7526cba87f2f56f2172bb182c1536850d594296a4cc1170c5172c2365748db97094093ad74b6823d8c607292040907567ea011c6c35e6598dd1b262e0d15e43deabeb1ffe85754de66d7f1cecb00a9da9d51142ca302a87c433058ff49486e542aaeda19b60dc66907c1cd85121cbc55add6a01ba3c27eea466b99c60daab04810e2969ef462094726cfccdaa0e66ca32c25a0e4b729cec6383d0acf41bc2e9f6883119b611339b6130d2acc0a7d66dbaf49c3518c689c429afdd4eb6de2e70f72a0c498d0caec9563913eafb80b07191388d45b51a4e7380fc967b91a339df3fbb78e5b244cb843fb7f263fe03e1e44149472395419c5c0d6e3095abb10848dd7639be063ec1815e47403d1dd1e44f1f7aca6d1ade5b85e62be6c94fcc9373e775d48a18a84ac008befba5d2467619aa120ccfdb2441fd33d807500ceeea889511df87266f5241bb128eb4b30f3d6e488947c45634b4f8991ea5e7c327f71af33d32d72aeb12aaeb609f460dc6e82d3625f5a9a7ac9c47ac85a80ebab62b62d9e0b1bcb25da476665b0a2b2f5158ab5aa22e1b6f0e43705606d888dc6f8e63721605934e41d164e410f10a398eeaa10549edd3bdbae832bd9ed4607ad0701862a946838dbcbaf8fd6e1dcff2b6e0daad3fe53c6dc2a6e208edb1a89c0aaa9ad560483a22475a589a722a54140e51e77d144c9dc993789af4c026ff02e5b686bd1e5e75300330824c576399ba214e12d21464fcdef7aeaec5a25478a39343a9ad9982a9a28f1967f00d930b1ca1c4f82b80d632ffc6b0a7ff6decb6e91c93e0215deb08b653d19dd1b8428831ba96c3d40b25a6c16e0f9bb9fce57f6bab0e86b4cc01b085aeeb5528c2a48c32cf144a69334fe4930becdb6e92835aa259cdd6c375d3f9bea57ad4239dd3ace56a7d09e96ce952624a7120e13031f4e6838918adf104db967019a234119e917053d0fe2cd07ed09f10a608a75f9068ee06a95e7f5a4543dc0c1e8c16e1f80adf97ca5984b337204a5bf078d46d06e2eb024d9677814ce1981b29cf63c3d8071d17dfc96e1f9f8e5a53e5712dcde186e333f3aa7dce0c0eb4dee6fb979194c2ea78e5dbed4e876a7ca3251100a27c95579c75815abbc1dafbd9d84fcdba678c531d0eafea3eb3e728a3768a5ed990d9f358aac9efac86df5faca68897ab75993edd6a7dea9afc12881748e1f291e2f47ca5057130f7d2c91fd119f958674e41a3de6ae3768e28352597b22898f5d570de7060860743edf37a2f5175f1e1a71cebdde51495574ca4d73d7aa5e573c3085e39c690f248d26b0904d507f5b86d55fcfa94fd991807c293ae9287fac1b210933fd9e20a8add2b97f5b358d7ddc66cea2679ada333d73cfb02b752531f9f50b5986cb19e1ee95b00783b6da5f025893f586b4868c66700821a2e40c2457fd1c932cacb444a10ee03da941f7262655b9d8f2b9f6bfa805bf01f602d769c85a9276ba2bf69cac1d9cfe2168805bf9ec2c5238da5eacb41e24a3ac97b571f57bd57f01e6e55061dc49c4e512132d6452d7cf631eceefc5a9e9ee98c6268c0bdc153677cd658984c6741e94ccca259f87791bc4adf6f5260408a550ee53350a925d6a7f0d37c9252fc0b6af0ac733b93ba2218dd28bf96759dc80a72485408f3c22f593c5dee0cd4c550be7a41176f079f97924c297f6072feee42f323b04db4fe06cfd5f4856ae0b2efdcfa4eb1af32bb62807f6f0f2d951d33cc0d3b9e13fa513f666293953eb88707398c7770b5d4489c1a3afb5287613969c09e5be7560dde3e3a68d75af89757813dc00e600ecf52081e0a2ef6d950b3ca8f041295e6b545f3b1ccb3ea8763a2ae81105821933b686720ec200d68f9e2764e7e555514ee3c8c4021cde8b80404a7cafa3d874646af6350bed27a8e8caaaad2f6ecb13e59bdca824f8dc190786258c5e5b1cc351cf575b1fb3bdc98275189e0ac5ff0e8914adcc1da3303d007bd8564954c5a314f41038be8170edf96d66ef27854a11f62417e9c30b7fa065bd53609597e5c9e2d759e41f8f77b74f00cec5fc0f834d64e2c3adcc32b6b7c9e50a45c2dad123304f40f73c6328083cf46ef5a297f3abd57c1c7b5509ac15fd59147ddc56ef91ffb6b4c334e084b753fa193eeabce9d5387f4bb462e38e7b3f70faf9726021203df83346d72e6b4c6d6bac1bf8c0d119d8c7ee22f6ccfdafa57141163d747bca4a0ff18fc81e43beaa10763845706ea94f40ac9d8e86c5b674377a7d2b844ec1a214d44f2e16e9c020f09564fc69be293f43bb34508e35351a59cdf44703c88ac9f87d4f4a9944725f34ce5377feff401ad57e61867f92fd68633acdf77a87a5259b610146cfc1c39d510aa7687d665bb54a494094f54c97bdbcd8cc1bffb6be75f23eb19289873654294e24b523000cb4233871f7b457c9e280435d5c11fcf29d7c51b4418c11419e0aa08f69356172be0074eb470794c4506b0a747781a980e9059a2ef076b9eb8883068c2835ba7f3323c4f4567bc9e63d9a51bcb071bd76c0a2ddbe2a80fafa7bb832306dcacd0387a59ed2d8c6d4a0a2bd62d2b3f996784b0a1df2d6a75a05f719cd3a64ce5acbfe1ec66281cc725c84a9c57edb5e7d4f17fe9e2d32ae42c921973c6ac661403569c4eff0e9438d59908a64f3fcf95e456ca347c2c69db9f6d36c07d7e7e563abcaefb1d11a67b4e229d1b7cb1e00063077c2dfada6a41c2d60e109af5d55107ddbb6243627898a1feda76daeefb6c68dcc81deaf6ad5732d95ad5633203924ea18f81223e9c4aea2cde15fb15e6ec0df6ee3efa02f1b76fff4ea998737ed99aeb97b40fb328d5ecdc31e04732280f748283a02884e886d1f764eb008468582213dba859fcca6af7e34b3989ada65527c36642ccced0a54c9511dea38c70b74a09f7a7badd20efbe8882988b11861419019698c2c55f45284d1f89b3950d5defe4a7f0ace7718029cd12c1bce684d03b95b5652f530406019c700982e171f40e13a604d3749d81fdc68c2564ddf5f16409c6c475166f6c45cfdd72dade82cc753f26a62a7b0be6c60ab8c090324960f83096a8f99fc7d2f54e1e37f24f71f405748f9ebc65eeaab29f45899896639aaa1070d895e4917bab39e6e85f5a0bcfde710dc49350b652a028a80533bd6a58a5f5164da7b91c2cd18908d1deba86afd26ca85da8835d86616416a2534a3f71c6942e704e92c90980f5953ca63a10bce4e1024706f2b9c3bb95fce3d5569e1277fa0a2073fb737e5865d8bf42bcc97b74d27941c3d29608c703b2f5541cda368e9f8febeadcf1349ebb48aada0321b564949fdb5d68c49cae2ab484dfa9546e170d1302fe216de42eab870f53f53fa67e20fe82c8e4cb49c9d6d9441eafa80d2512896f0547b9111b4cc7a80ac1277ec37d72d6efa380e910fae5134207816aa34f9cbd40a9c5a34fc117d2683e0411c2aa90fff98adb5f0ab9371e48666077095b69aaec9c6224710718ddc1e64287812384b7b7c3ba6360e79267eddaf8fec135cca4421a7c9147626094f62ab85a9d3a74160a8546455b56c2cdb07d3c7c252941d60dcc4918b05acc25c57c6e53d8df88e72c13c973a125a995fb1cf74af95a88f7e96e5f96bc1dc5d04d64521654eee565998a2570c918280ff31c1c2c0fad4b1dd2d87a424b3d111a551deb3413d8f10ba0b0732357b27dc6216ac07e601aca0520ccc275278dd18f963b6b19dd75a52b15c72925ecb5f1189cf8127d9ebcfa4828d34c9e60bac561366bf186327f1569ea4370ca9be9b3d7df063073a8291f9e5a71c2e5a05ec903ebbefab03bf4889de91daa781a30793946e58b1a2a0d0976138bdc84f200ff421ed36b1329edb257220a5a93f404b0e082af448ec05a298cd139b9b58e0abb0b6e99eea7d4be213b67b3f01fce87c6c3798ff39d2b27af6f7d2470f401a0b1a8fcc64c414d42cecf6e61a918712f6d6e4dad6048630174f41531611c01d2cca677e2be70b951efbce06f48368b8146fd9584bd5f91bd0fc4aef059dbbe6c7165cf09ca7bacf0759344f15e3922e46b6cdcf85f3a8222ae592c1f6e2a054e8728cb4de8355d358e4b9f4b258e4122439c352cdc8bb9e176f09c6dd06871a18eb88567a51d325b324c75096bf22a97b3ae86fff8331bd29e4beb1a38725c4e8daa9b55697538c1b886ae480af8e07755b25656ef2a375e535fe145a93db2757b65ebb615b643d1cfa2b8c0299acc7234c97d8473fa819ae52f5ce04bd2bfcd79e4ae218c0c9fc60733d2823848213136f87a6968a5a612e29b6044854261928ab6b644a521e1aebe1305270a9ddf113196e7da479dcf8722f678f2642c1a66f16dfbb22b9782568a56a49f65ad577b3e6407722b2dde421c7cfa6233938d9e49eea0f7fe9851b4f30bcac045c4e86ec8bd6f0ece50ef6f6ab25966cd6f48baa240fe07852e0faccd1ee24f2a8980f5640a13597400bb9f3477bebc71f1ddc02fa428ee303941f86dd2a11aa29cd1dadc859695e236c39fa2d7f0fd6142118c850c1b8ea65b85b1704c1739dc45ca0efdb529a1e11bb1f8c25c7e23953ed5e539bd7a699f1358c94b651f5402632d8b2b86250cd09c10e5e7d7cb98aaca5417332c6810b004a06d8d4059291752a63380b95e2a7331051c7cc3d1eabb324af1d46fac06980903093e2a6cd297944ad1319a24bff23be05c7d05a6b2f54650bafcb50988d7aac2b98dd9c7b6690ffa52bb07892576bef2785978671ed377b174aea1bbbdd6941a7484c9e5ba8c1453867207b6f0137731dfc04d9af8a09b29ff791a117b8ae30d330dc471b9dee38743d780eab0af0c68686f0a2e42dab0e0bade20630c0f37b936adb8171fc322b70ffb3d6786f8e40352b584774455b7bdc9cc1ca1c775f12a71d6b85d0eeab8c0aeb12ae73897eef10cc1b9057881fca9bf1c355be15e8c4a9bd908de09e3dc935624fec778b3907993e05ba39b63b23e3f095d7c8eb02cb27861f8e258ef869ed3456cb69ec8c3d88c1d770082a8ea219fcb2ca64e54555d16435d3ec61ee6d04aeeeb421a756fca11439de3ecdacb481e0a251d53ef1a36dc2ac9e74de3b6126510eabdd75ef7291d3ea644a9561decf0fc65b96aca36bb66d5767c2d432f3328ac87a2f4f73a8ac7f00317f088fdcb99bd2c37b4ec5880552b7c532b4c1ffa347fefca202b030f9c290b172628980f2bf487686df35720fcf77335630bf060b8ffd087871acaa225a54d126387535c2ba7724d48f3ec52173d0fe306021ac3da65dcc6c7d0559205f4d3e76ef456fd0fffce153ebf727ecd4ab60fee83a4081d4f3a33d5eca30c87c0fba812c0074336f6f42171790a6a9c2c58afcefe0da30706b5beeaa35b05392ac632568be70384b8d46ef7520eb70c1998a0123d68906e1aa68475342d6443b7e716a5feedda2a2cf3c84175d141c46a59f8e924085ae8bf73d8c1e9ae6668720316b1b90612552a37948d816c2875d2b4b3de17afa4a8ad9cb264d2d61439ebb697c8f3a039b68d404021ce3bdc5c8c435db8d1609d4d6a7d336b75b4020b8be4136785d705462edd974c37f7b9dfbd2e4fba184ae66e511fb9c4fad99c284c66e0a8e153d5f56ecf927d03c13daee7f5f37d476363218fe6235ee80000949d6f0e4630f96905622abbf3857cd45fc062a6ba791110417b0c8c15cfd126c7b1bac4fe8106d152f588a53375d34f71e49c5eaca1111126ec5561a4be735337d481f1c32f77d8b08e688aaa00ae183872925f9bb4e60983560d292e2f399916fcc27936befd2b5e5c0a44fb5bfcfd3d414769430ad53446e71f5a55bcf1db4b9ccef27a1bde7cae78ae041f43a474a3ff4bce67a7121038bc1dcbcc84fbd737001bb91e8ad44941e9f392d24ec2d309468eee79ff9befb65d6c53774a6186dd92414b32fb54d1d6aa7e41298199074f4445bc9dc2a712e53107227e77747d74b6baad3783e25da61419ca686c7a651d1f9972dd02cf738c3f539eaaebf72588f7a8f5c0f49b08cd9198f6e2f045889bb36b8f9030fd46ace67c37178d252d2e5ab591ff36c4baad15a90ba4ef21305eea4edc18182bd8c088972bf56e0efd405b4b56ff310d2057cee8509bfa72d26d668951d92dd8bf896f13145ace59c3d879f510170a5607b408d821bc310fb43444647566c02579fa5daa8729e0793486721c40fde1f69f1740d9c53a7195f39cdee2d97a8bafeb0c646931b5fea56129938ed5349c11b1ad1c2eedc7df27fff5a7168bc0e5ca54202f624c5adf90471fdf7bab8b0a45f4050dd386f7d7556fe5e8f61f853c26773985835fc6e463a9563810bcde20f880ab3f388c083df1f94f5e83508763cb7d675126c2b81212a9f5879034154e1531e8aa6a1ae53e291b860c3db2242f80c8d7f7e5841f1c3a1633e195c00ba1820858ba91c5ae7a393030d12a07f4b7efb07afb7b848bfda5176a7b69299039bcf5614f8d409789d1794986a01857f04558394481527940923fe576a30fc73cd012566e22a569e1d780cb1bc8a538233b56f7de9fc66aed536ccb539ca058825eba03b1c88ac3015ee951255b65fcacaeed33d7194557e27319e9d4ac363820fa509b60dd2fd9a4963eefdba1ae4499fb9208dc6683f39f22c744f8fc13f8b16394a124df6ef1bd37f25dd23a9395f3a92e412b4a99bfed641ee8ebbdab10176ee66dff95169aa21b19d4aad824d5be34c592cc7b040927201f04fdb42180513bd2bef4c91c92b93be05c52f05a5a61e315ebc2ebd9dfdc2c97b4e4522031faf2a919a4d50a1a54f5c3e0598b4bbf85af9d3ad2b0c16ec2adc3c19c958f59e8ec30c6c0f3297072da0fe7e591801236d5e4a333fa73c0552c38bdd2699c9cafe59db9774c4cfa7cd36fd67d10e5ccb30db0abac9e0cfea5f46a5a34e28856b3ccb75a5afd1796515930955f76578e65be8113277d4da7ec3692ff7fb44d067f05ba89c7f444ef167cbaa93588408c4a7784cc62c72b74910b571e25f963c88c6e015b44919976583a9c7a962d2f4dc3c006cfb8405a46a5fbbb9d6bd95946f81ba0bce87e87fccee5e353a990797af5199aae9667d72b1844600d715c83c5ed22ba4e83964f324d43a794cbb0d680df36464d225ca062817ce22842e8dc9205d4057f8743b331476c27f24c5f2551da4a923ee3f06a20835a783c4c0b9ececc56febf3e277db0d2d549966e2cd1f646067e112c726283c037f8e809a828d4529f2f97994b4f076b768f60a0ca20e44910697374f161593b2dcac03fbb1476d7d3f4ede9f9d395b713ae0e208857cfa6b0d7e2a3fadc8670574739f19540d8b8ac6ac136df437c2ae5fa328123857e14dc2382288660c09e58d60da404069f7dc25ab1ba4bcee429aa2b057ff3657f948c1434c7c63f7065c35a1a25b897139a143c831b9a68402fd89a11b55d4dcfb87c45f81763296ea32a0d58a34f4bddd94d1a802b0fed8c9d27a6930471f501e8ed417bbe3835d86f6e483eab1cf7310ff6191a42cae70289ad2d6ecfcdd21023319a55e14900d671574f269cb583f9866fcaf8892d402ebea548f54dbd2cf85de276b7e6eb8eaa2ac20a74220b2fb482279809f4cba15e4f8e2388f735720433dd95614d6b745713227a0bc8a7ef8dd04782eb5ac838bd2e2363ea5c98cb4141da97358674e70b362f3331127697a38736fa27c54636d5ffe8bd04a0e959ca454fe724c9fc1aa4a76750f7dd8f28b3a4482517224e5c2858a47ed1f9de1c7f238925859e5c65741bff87bfbf0fe8ac34a1b02a29f1b29bfccd7034a4097bc258c9dc2750444c07179fa7d5befa5a127544e7a8c3f0f8235fbf44a9e83b7121e44df53ffc8b31536ebf779e7789ba5cab576aa50724a52874aacb9309700f207d9983befab3149929adf95b66175b36784d5e47130f3a7db57c38281a09accb77553ad4c6bfbe510dccfdb490ed50fd15f2166d6bb5973051938e6549c3b8c4db84b3fdbb4d008d2c24fff6283767951a91a69d6e544167cfce0411dfdc9413b6a44144215182153c6651bd90e23dfaa47deaebe4a0f8bfd1b2b2be99b0b59a1226a4b9c660366dbf8ff0f8a29f9d82f9a0ea4baade792f4cb74606bcc38e081868c48281d7ff6287e95f7b3048b9f69002ebaba1f6b0a3c5556690bce3b3d61f1771201e834be6e92ca6c86d0775d51f5ea45a6ce920218c4ade45eaa3365d420a0d468a0af7ef37d2b5900f3cbd7cdc1b900fe9c32e8de1e4e7db25796e22eca2549306215a5268d611eaa7c4e519ad1a0f4f2f42c76bb02c5280157b1997c7c1831b1725379ba997ca6c82a4b6e02d40dd92cab4d813802e206dc3928d2069f5925ec7c2ec36896ec82ff9ece7f98bfc9cb462abb1a43812927ad5866ff12b1c9322728c6af06cefa5a06fea398bb1792a07b47e17c6cef90d0f83fd32288cae4e158f8c339de0da4a82224b476862549e99fd42e020166604210c0fa5ee71b45b94ec7b7aaa34e0f7d298f327b6d6c45436ba4bc2d902984dc2b276a82f93750a6a296cf4028873d37beb98988bdb42616a0ab7632505c84f12382c0e155d71156ca66aa50b3e9d296a2ad10bd391f8c81b5ea8105c226c755ddafa4771d1bb4824669c49973ff80b6d2430fe428c299269d26310d7eff6de23fe98fae38212ad8b112d0f9d32739ceac95c0b653041dbb46aa5dcec2a1fb65ce788f3ae883bd33b38cdcc699af7f68871fa7f8c5a3ac5ab7e3b179798f1787d9adfe248d4fd722042aa9aac16e874370939a6752ae2049f705fd162b9c4cfa96fc9d65a529dc9768eb9cdbf6fb92f202d60e4eb9127e6ad6b79aedaa83db9c00c2abbe7fd332981d8c13e1b9c84c7fad31c637a82722c2b982c1a5827073ef41098f7ffab65db2e17f31ab38c397a67fd1919d64812ff59d38ec14f0929c1cae87577ad93af9c8678d740109044b46a9833e2273c1a93f42609208e0aa5acdf912abf0b3700119d50bf888759d5b18907be3cff9b8a3f0d723d8eea3331c8885b1c55d1957a0a6b7f144132ff03c75b0e37cae9516b548e0d78bd1c21c4cf39e46844b492daeb79898c6100f01d633c2b620d334dc7d5c3829b4de40cd066b6a8dcf9d1e533242292fa796a33090029aac09d47557132b84f9e61a67f953d83e7a4286786d7975892c8008f202335a5ab624fb26e53ccca850735fd7303ac1f6794c679e47f1f874537c3110658cecaa924cdd3627be5b355d8422f574b929a06001f1d12117f2c8a6896ddf3940ab4366c45b8d50517fc15e05979ac8aa9a9614eaff1c129dcf0ad901ebaff0bb8d0ebcab8b6b2c01eb2d95f2432d309d19d0de47dac49a171536e8b573143066fd37d9dccd6d4f0c24ab46aa541564b0962b5fa497d1aa34f55e770f214ac60f51d6350ed846bb32234151cf02df0ac1b7b315da0c0ddeeafcf146ad8616dbc8fcf0c2bb53f0e7f793385447f4cb1b9ce4c5a948596e56a1dfeacc986ac80ffe6cadcedc9fb975d58e86e1ca29f902930106b9028e39121cae36a219aa289d89d80de4b4dbb7d152bf4865bd3b9f6697e74ff4de68c0c1adbdfc8febbb8735cdcd74888d15ab69d1f7190791f2258d4fcb176a92c7bb119ec789e05aeea9476e141ce7dc4bf5aa670534c3e3e2ca22841c556e95ecac36e90b1c42d3885f6ae926abf8936537192334286905d153a49c592e99c2d7ff3526488c3ee8440f7d8c88c258a4b3d9dcbad6a49c2a38f256f14c862219f062f143753875135c6e9b0f32537a14c49e41707e5464e2090764e097a6f9ad716ac32cc40b25f1945632e55b37f7936aa92d4567b69227cae4532680bf6cf3cee467f9dc148d8d6fe03f98bbbf9ca82aa924dcdf511ce21f7c692529fc9f8dab236de317e38fc20d0314ad76e4a9338b814671502e26370ea38d85634d5d596392586e39ded730d2db5ef487d6d1a6be739cb56c99134d1fc6a9a83ed34875eac81b2884093efd97b4318867d7498f72257071451a8b2ef177ae70d033729fd66555cc24018367a099e5f4ffd947aa89ce95d5a34c56d7c9ea6a6450fc3636017cf3be774fa265325f3dbdd83a810b64dc1ba4ede82424be6edef590c38d8a5fe6570c0cc20affc73aa871606f37eddef0d9ff1a0a270fa8eec0f86963335441d281477e9c72384f37c98a0f01b3489004babf956208241b4b57b965e4b363745fb599f8f29b513d1297ca00d74c100ff47132f26d622810c3e0731c2a1b4f6f829c855bd8824a080b694752d6ad9bffc760f5532a8b87883e50572f38523c956b16d90eb53c2beb6546d9e4127f67cfe39254cc46454f6b5bb5b321265667dd690334c69fee23176be0632b53018a9a4699d29b8d5cf31e92785a7830471d027ad0b526275f8de094a91a4b10eeeeccb53627ada9ce7bb6c8d18e9cfe200dab59372f2bbee9d8fc4dd6f4079080f91eb50206b91eb0f64e7c33d82f968cd0de7aae4881ed4516d9196f837dd4d6aef885479e17ff90afbfe1d990656c6274bddb4a67b2e1203f9b0bcd41a02321fc203b3c32f624bf1937cfe6d2afb4fc7210367b9ae13f94576d273457d2d76851460fd8428725f2df5d80715b63c2eb6ab48e71b2152a28e9c6db1c5ca7def6ba32a53c6f980512637a40f9f014b0367415549a7b29055722779f15d7be33c9fd348e5424bb266e4210f373ab51d8b2564866db611f8756f65e1c49ebde0189625e78deafb2d5d22f77dbb426d1fc42d28d0fcb938c91d14a10428a9c9e3db1e17167446e43d344b53a530b6ff85268478a2f5429cc1ae4be3f537607f67cab176196560287e64a1907dff62c835a5567bb0ab35e354e30c0f520bf494ac507d3a2de61a42b2f77f077c1415d6436c2ddeeeab627289824a89451b3348507592d79bdf3a2543a766a0f36e465cbb65d06473e99096ead96b7c3f3e7a039e33815afa49de597f5cb380afc2a1a0897527b2d64a11d5e8911b934ac24662419996eb6c1a44b39446cb482695da33fb7c391a1f1b63512c59b54ac8bb191cb1310f211877e91874e60dc2c76371aaaac14a63f70d61ad162f348ff0ea5605a221b83ad9e75ea80bd1c612acb03974c0d06a0f54346823306123197d9e5058bd84c1e7a00cd051fe2704cb188f416402958bba8b195e1d7aafb020f74837682826727c1147c158e0a1355d5a6c39c5a5d2e66487958c297a7cb4ddf8c161b279d485b31dbd6340c429e5707af3de917157b70f473a6951b299bae93122bf45f509511845d7dced4e5c9a8459d75c8a68a90f964c006e03d20f97e1a8addfbe12af3dc9a546328db9c0e3fb76b7ace8825a4d1a9986e73c6fba9dde39deced1b9d84067862b50c00893d2c738fbd3fbe5f18fef4b940847a1d2815bf85f85de2c68d8f044dd617df4a2841ac0a46ab30dffb6df84c9b2625357f74bc9018ef39eb06b674e96209d06200644197ac2c7c7a710734f0529d264723df56d01653339302be55258c2be5b1a4e79eba2f200221f2c06479df73beb668a380413dee03b48e426a6b8f35f63aa7ba1e9a4b7fe8fb7cec7d226cc5b6208727e0c1720a0f83d78271a7a1ee1c7a1accb5bb35cb8c197d21240d548d1b98a5dade4d10b74d9309160c5a15c6a4fa89e4b5604860f718e0286fc8d746a078d7e71eb99ed3e87873e87d9e94d84d85fd0cf94f69a6ba54b61b6ce379dd2e706faaaea5106cce86af19bedf8f22116970e33cc9f76b6b31e9865141535839b45940a82ef7d5fd775669100b99a263affed6c20ff6473fa84ef3f386da158332cc765afda68e0865acb533664135c6d3f39e41e140b4a86f812cf4ceffeacc011ef040c1c4bd99727734162b4437bab759b03f83ace41a49f8fcccb7cd37eab5d7c8cbac39e1fb73fb91eeb4ffcf915c712da9f9e747b2c131b3c338058e11963042b7dec610a1e7bcfd529ab3a308371cf98bed461a585f3a12a009c48c5070062f905dc202e2b622945ba219bced38702a5260e1130270de88f0d1100860f17a4894d9c6bbfe0fe9a0527e028fdc79ce196a8d0aa10ccf02bb5dd2d534cefa7680e0f6033f4ca72a8fe8ec24952e632f229b1ac8b94d5ce52fd0c20329bef354fe469230a1b8a90bd0c0827ce4a5d9c5afc6373082a8257c202759eb08f13d97a4402ab2a14602a29c508a81297c42a961c175c389791a958cda96fc4722873dac8f83f2b6445a021a4774bfdfde0a9339e333882e85edc5c87beb867c91b8a7e72a442f1095f9acbd65b80cf99da91a3961bbe8bbd7e059afdddf2c17b64b97fca5d33c80cbb032f757ece9971f63e74de291a1d9c25604dfa5643786e37d2c46a512e7bb30cde77e4e2035c179ae7cc991764b02c2dc38968be1fe94bcb320a1a079c84c0e8408ac5c76f1e61d2181e4b484e6e39b4cda36bbc8c7c5b3d58a0092c8165912ba2dc349bd32e6a3a5ec23f8b52b3e1b6ba88defc72e8c81d6806715586d859caa8ad1686d5ec1f55bf374efddc6ead2c53c809bdf07bd701a4ffc89d238a118327c2cf5792246ae98275008d9f84e69c1dbe170d7397efff64e6dae89c6df652c8ede0dc9a4c5dc4f7294652ec195174903feae88cde4b4fdeb01427da7525ba03e76f53e8d218d50aa07d19056c7e2db3e546d65f6d7bc580175105ef3c602a257c43fb391d199b87892fc142c7121d76d3c866b0ee609c40827ad5b06b59ee7844b5b18ebe5fa1200120dcaf3ed2f770a6ea44dd9a4eadf34d262749870cf034bf4fa9299a106b8277cb7de71d0f1771d981bfbbe2b39eaa6cd9720d82a11c1679cd40cec60a11e68898541146c142cf8434d3e9d380dd73b40219d1cae46cc701b8abe5ad4d02727a5a134530ab1a1934717b4e4a87d4bddc0bd18aadb8063fc952da0e69998328e46d90ea2a6e98b37e68d15b4542c9fd1e2b6c39fa776f05e0cedb5b22c4ffdaf6545f71c558fa77679e5eabfd093d95197fda0545c06210e67371ffec7c25014ce94daba8d27b194784e8f303710d011e7aa61b47b1e3ac534e164d400246d3b8c5bddab32cd6cd07d9dd273946ebd3a17d41d6abd9dd8fcf482be81b220658efd9cc4c0a1c43922f4218bd90c74e5affbab2e90e32ea169f1c44f604e721d37e2a1e19671e2cb6f7504cb4ed89a544aa0ac4695274abc9fe35148d308897035c4ebeb1f600c2931aa0a487d9fd233755de35fc872ec2c8a99ba90ebe8783148eb2e03561b6bad9ba07d8845622a8b4148d08b0ac84aa87ec1ddbfa48d66c8b69156bb13e2b173ae8155636da74c33c861b84423c19bb22c131f605152367ccbcbcc6deea0175e103c5c380cacf2e2f7d623f23d2e7dd15a74443ef263eb1298f773f2261795ff4d4352fb82f3dbbda0c5f5f93719eabbea48af16b336651a518eacfb67c6550e14aaab8a9fa1a3ce98cbbf01def539104d877139dd28c63757983b841e7e6c0eaa8240ed348ecda004f470c544441735a7b30eb48d6623204370c5a4a0428bf2b7568cec554e7b03d139c13e5d11588a271fa53656c10d37e0a320a026d4a291ec8061e2ee1f9fda3101cb4f0b6403ee6d1819f04cc3468d3dfa10f36486816ac638668174591f4f58769d5ea06f7f1199dde8df25d15df55fd097b267a3c5f83090c767e48fa2639ef981aeb6f5e2a1156806e6f6e65df10e816b5cdace79b053766a984694d14bb773f1b477c658e118066899ab2d805b5c97eaa5af63101165c25c047263e8246ea7cc86a89d75fd2d90ab246ddfdb85ea41c02ce3a442cc4cbe67953b7d9f7491a99ece0d45155bad04608c20e2dfb5397e76134fe23030978c813aceeb3d18fccc3bf2942fb9a89ef0e6e85d72ff3888bdd04c0648f9d3b27d570e08761bf808ced54064d2b53b74e237c8f2ead58e499af9053cd1db6be5e367a71370520e097eada0325fa2d1ab17f8024811934625a8304131b67987ce184856f55aa455f0021718fd8ab9bfd502f673caf228011a3fb35f60a1190c8c60ae6ab8b5e016bf85895cff185f612a0f7ab32a78aae84944b631e7909fb7c75cea3c12fa6daeb4631e2b8c92f905ab38010ba4bf1d3a72247f11733f1d167e6323c861accf46688842d05746f3e09496a391e3d9191d3d9dd82ee9ee4fb96da7326d816df24131509492b5ec31c060ea95626e06b958e170a624efe7b1b8d9c201e4fbbf288134c0851e0e4abf4d4c22dbbbe7f8bfdaf67109461b5ac1a2d09baaafd2ded56103eb11f7e4affbc9bbbaf958d97fb39c1686d0b5a411e14ec24163b1ddbcb2b58635f2b6eded4254ba095cd891d6cbcaedf96b381dc7271a14e8e488d0b1acf1bbc995a10813cf5f9e34cabbf6f117507c68543ab854d4a446dae5ec7287d6d34e457ca3189ea0f5b2c3c5b7c7a5062183a01c78eb69e3acdb55c1d6193bdedd701696a95ace0f9b5b9a83c50702ceaf35920f0ee5d328242d8e4a2fa1d4bc41759b1aac6cf772a18fc549e97f7412651c744d243ec1088410e39013942afb29cc0ae32d7f507cf97346c46a58b2474452790300e40416e18915ebe80a3179182de2aca618d8150b2ca995e7ac75205c24a11ef118bb2f76900ab77c7562e97caefeda33b93ad00dd02f573013d6fa63dd2fb8bc4a4cb28faf2a35f15528e37a6542a2299262509d637711207bcf5634943afe8ff65de46aac4395128b72784c0fe2583a08476731ad2eec197e979763bedcbbdf7935105e42b07c63928bc602f6640624f35ba5233fcdbfd556d5ab83a252b587f36055cb8da3398097fe2d533007cc920359e0a6082a0eba4f7d56d4b58b7530c4e0b16863a931296e0fe34f9016d6f1beba496ea83759bb7e582c5bd2100afc801849adeef704a378805d12b2557d1fd7ae3343ccc07302f8c7708e8f96856b9ec7306ba557318c4fb606c610cff7b6f919ca6e28cffe389639aaf7c827b830414cbc69683ab01de92410604c09aed39ca261ec624c27defa9647b7b86b58dedf96e6c510dbfa19a6610d62d256eef4d79d5f4cf5d9db97a0e94bf1fbae3ba582273b37c2d2d75a87e734d3686390d89eb93f8eda1892372fd30d8caebd1ee05f33b9763060d1b19b0e01f5d73c5d095adea1fc38dbcd1f806fd7807e111451880cb3caec2f462bd6f1441eff7045980307e922e4f1d9e11f3dd9c635e9838ea60fbbbf09b8ee1b78d2fae1574a451f5bef7e2da26e352ef8fc473b63d1a66ef6f646b9a05ef2976842dc95639cb6d7dbb18fde307af209714e87ffa8d6b58345fa994551b4d5325eb77b1a51f71ca7eae202659a72492fc737400d51b549ed9d4fe7be753ab5d28a7fa439fd640abbff6f019b7a2f2f240aa2e0c5b1233da16d00de353402fcd95c20320dccfcc1d17dd06e9a2c6999ea38942e0d8126ecd1688bbb808b52318832569d693f49035c10efb4e29a3939743ba239b4979e7507b487b12fbe7e12cd365b288411da662ba9e62490011392d3f120dccafac8ccb580f488a11b7e21195aa05b2f818cf521222ce902260c59160e511e6344c22d80bfc75bcb7c3bef8d7dc9b55f93683efca7bd79ff843d2713fbff7e7f48239cc2bbed0a9fb44045ae2f89b784a391290a73877ef74fe39821d9cc4c1fca154ee1cdf3b193012cabcc3500e1f58753a11ecaaa54a1f7fdf61a92a140694f343dd8535ad2c2441bbb8ffb4638cb0a4dd866d7025bc0f5ad5d6bf4e47b47fbfdc964113b2a1e9bb19f9a58f939a994cf1cbe21d42ca3d17912e7c666dfec8df669c0d76a397f959f8597d122348a2f9419fa2091832dfb8f6ce474d8723ea60231608ef114c711f2052626958d315f825dc02757e26720a49792b4387fff81ff63a9707a5dc770a92ba7b7643cf17610bf9e8b264f76d0d7d73343849eae924fe6c2781be2dc0d69e78fc562d9d80092d03175de7372c44c52919ad8c5b5d970202bfdca4865d793f44aab5f3da70d226eceb5ba9836fd741be495a361ea95746789ceb0e7ec4e5a430f4da683cba37c07ec45d12f9efb5a150d3a5e63351ec48ab083db6e9a50657a31872348156dd1b61a0be0fad4787cbc3fb8f2748dff65f5bc17f7961683ad203002e25664e3a4b736e6ba3c5c9df87e28bd1c735a5b455954a43bf040eb528947e460d7a318b24cdac18dc6f545b710c142359329d321c93445db1bcb6f8d9bb7f745642d410c049056a4e7ba6f2c884788232df6d4f0d0493989dc7eac118b14cd50cd8c771a9b28c4a44a2e34a6ce55ac1a946f9996edb68ffdc499a9687533fc6b8af0602fc492f758018aeb529504944e78c53bedae71abefb41e4debeea5a986db5d559dd8cef3292abf332da6b59133096829a09d736651c45d52509ff2163a858abba274c56fc1ff0fb4b087d0735c34644537d13a2a815ac0b7a4dc5040212638455e8f2e74045d66aa19b3668671a5e50de56d7e4e23cda55d033b82b21b3c6604929a33df658cb5eb4c95043e52752e1b2830c3cc2ab2e6693ea6b731389fe24a6d9379dfdda31fc7edc3f0f1504138114316343095e820d6c71e19cc957f204b29cd8be6f89885d392b465706c8493814d370bd148342750dcaac5dc88548aee50c3b4f276adb110e2d8e1bfdf17c7927f432d72280a66952432bb4398f8d7effa73187c8ffc30d286d1638578d41f280ca42db138bc88cd276e0b3aa49d9e9b6ce070b8d8635a714a5334db3c74cd0e8b10905859129232f57750b91b6ece932a7a09b43e8857c16a494515f5b2d32b8814e1f2743c50e43e4731c69ef46739c265ad040545e7ff4f8ed1d9f6cdf73983c1d8d2659721e045fc26be088fc3d28eefb848691a5c2e8de2da9ef99f1a062e16e4672d79634d1e5f2b3e4e4018ae7f1d0811d4552d7e45f1301f24f81c74693f4cc30462dfdb3715b29e2f5c2c6c98e0869b79792027a106d5a052377dc58d316ac16d7a54fae7e781bfceaad6270976b43d60b8261067d846a0cf0f99a3299cacda70f727e2f4b47bfbb8cf14b7aa300be6224cf6f8bf42333897747f3c0d60ff63733e7793d73e3979442e62985b9296272cffa99f5650c82e2585864348e62d6f9560eaea44e757862cbc1a6819b2ba73065e3382660b9d8a6007d68a264d09d0b8d60b4dce235deec05b9d919107c8883e5734aa0a0a60926171f32ef95eab1429b09dac76f81624cbda16c2ecd17a37540f722cbab8f69e48c120a8d8c3a140f477a05a3fa56a3885ebcd219fe53b55879887850b91db56af898513072a3a497e2c916e3a0a907f69329c7a91a8cb262b95762d441c1b5119fd2d92a30ebc851d804690e696e6f0c4ed8376baeb55ce21b89b8a3150e65e2a3ea1338610b13473e26ee13e566316b0b06acc0708d6dd7d8bf52ba8cc7a842bc839d6d423c6f9b76bfbf25b37bebe49a664802013a5ff8eed7cd65364b394dde5ebb8d8ec928d1410350dbcf582498e889749d43d9393854541707b44145ce6792205dff563b9b0e8f9f6380c44687c97499394f80861af18f8f54b7f9349d51ab3059b0fa72bf003829af6e6ee7e591cbaca047a8eb0e1bdee985a965e00c83c4b197d2b4973d910d564d9674ca02baf2a8f313193a285821aa14889f00c0d45a6293f051d45b5d96e17dbe182c89fe21d7a0abc8a6a580dad4bccbbec84ecf3384ff7874e529db7277ca556ffd2a4bb97e95ae82660c013e39c0abd42ccda52391f44477efc919675e9571fc5f99d8bd97373f0a2882aebc2005830006ac4a7e65439d0adae239cbf8f81b1dae45c23664f913e89f909e7101e1937c1a22769c31256a84084b7ec71d40b989c9f1872995a52a8c6b836881423e21a289b956a4fc335551be3167dac1e8d324147f2de0cfae914c90697b854b1e44377af4a21321a1e877f73615a7f4b1edb38b25a7902fc6106e24151f34199f80ddb1eb0b5365e4a07c897d9d28a3d9bb36208e6f229e2188056b2316f3b528a2844fe6da7f0e03924a17e4085599538e4e18171e1fc73feb83db4d7164b26aa04370005dae6dbca231e3e2d4f9884c9cf33071bf04b2358b846e33f620e74ec08156d35d622b2948281feb0da720119e12e20729ab952b51bac31b30cc18bfa90095aceff8065f93530d4f63f3119a5079d0fe8251bd7a1f1e2f61e9785ae745976175af4a698ff6686b9091e7474999609d710c8f0b403f1d0c6505a1521e12a5d75b58f164d8d32ba30cd4d8aee79b6593a6b5aab97dcb4889061d49b698701f1979e646c001f66c478c834f15a522a64bf14599a86ac19705b473d6de7d18ea08246c7d426f9700a639680cab1d75c7eeb32d0343adb5dcbb038fbd12cd51e19696500ee2cbb34cbe94c0dacd421af3e1c77d0f66e4587ad5cd38f8931d542e1c6ecb78fbcafba23444240400afa695d9494503bbc2641c90e9d5505bf939e581e61fa8d108c1b12f99bc8e2403543c6182ef0c820386319fe143842816faa8bf49212463a2c6bcc48bf955e88ea92365cfdecf0710bb42159c6f02d41935e7fb2c630c66560a79fe3154e549c9e821e0539c5c3e1f1013b67bfafb2402d989d02069544cec0c784bd7008c362299f1586588484371e4694ee321c71d37fd55c269e3c0dc7b1fc97cf0f756d3d32e44656557868b397a23826ab25625c17f08b0bc20f46c97e340e349b68d28fe34e5c8d1944b60634cd45fa76eb5aade6c7b384282303f27c158c5632c35cdd68f864599ec7952c18940d06929d14902d9b1712843c94754299db2ba1752cfe6423cebb62fb00fd848d293be8181dde4a57167e9fb56e8688c8cb17de83c41b6dca39b0bbbdaa3654d06c05859b74f6e66b208672537f6124a07f5b798d412d9b675e3ec3e92b162b825e6f314f596ba0f3b7ab51045a1fe965b3ed702ff7176ba8adf9a316e8a383a0f8c00075405f1635acc3221ff0e8746814c21526ff69b3a828141ee2751148151b24fbbf094a91081e7ed8a9bee6ef984fecaf58379d80b1bee8419d851b74cb2aadae2eeeb9a2c6cacbb28c9effc3d7f3b156c172ae2da7af67184367d07b2abf5f5eeade113f2032563091c10d10810d86180f962d999500fd215109aef14ea872db45ac25d4544ea2b34de2faae0a10eae13dbbcae84f30083f34691594654be96a4eb760343491183e64d8f44b24921255e6ca9f436323cce6eb267cb7d6565e081b0d981c54a97b32de8c6e21228f0e9fffe95421047222fa2ee4734f067ad8be9057b0e9cf8b1de6dcebae8733875bed097ec4603cca99e72794e4d7e96767e528e22021031264e367626d8e47893a7dd8a58d55cdb8e470135d634c0ec494d878c14ec719da56a42ef5da2611fa184a0624a678ba045d291aed1ec436584b194df6558b29e17d877fa50548b87a3efcb6791e3cec074ea64cb850a4afe12a425a329d1687a846384d7057b3e7cad94db6c1f950ee6f30fb7b1f45a3e551488113801d25e934cadcb43b8421ca716d5d6d5ea21e7c00d46d7c1dc2ff216a7b2f14af56be1942069522d90358663ea99e8222e4396a1ea7d19c7f53adb5bd74f89c38b045f172f3a670e7d9d3d38d837c9cae71b35ec55fe734c2d72cff627da441930c0111cf7cbfad69445946c326bac963f69895a864b1692b709eb109083756f9fd7e5f5d5fa47a70d03e8bae9860d3bf6a482ac9d8bc3e4b5f047eb9fd520a766bba7d1cfe33b741b1e524725277098c0eddde111d2a696872ac4a48b7480e5abd96bfe0e1f42d2259216b82ac807c4926707d7139e17ade13b5974d7d517a46c0590db4b434b899f3d74bb14ee9fcaecb498ad3fb1881027aa3c76f6d8a395c8494a335420b6aa87ed0732f0bb4af2647f9281ee574a5179de3af9f77e7ccfec071d8d022abd90e82d0213fa01abfafffa20be9d55cc5c271792c622deada8b544f792457327bbceae9b74a1e6e18e3ebd2583a95fc6438d49b79229679a78b605a109b8684d37dc4fd665d768e67c27bee46284ef81f71e24ff674342fa3fcbd14cffb3df6a1eb5ab0ef11b668e9e60218bcbe06b4cc8327ece8e7f7890a46c7a32946c9e18f9e7c15be391d616324ea2f1a1b824e5da1166796203fc83dc5def1a8c2d7bc21001fd257832c04dd652754830c8ec7408a1f3b0003637400a6c0666a1f7c21204c47d954d7ca868dc532c5591b221a60ffb8af38b810bf78571d8e8f0983e17c015c35c9d40202f85e97dc830e9093798143a5d189b267b191ae47af488796e3f99a93e8ac96d591ed803e636378b060962f844484e01d64515a296b70d0b2ef1b8be40af1a2401a30442742152f5d4b9fc8adde3a4b2ef6ed38c6bd0f4bb5080dc65a40ff01007a2eb78bf1aa871c61c68db28dfdf4afb930ca5c9ca282253561fb74cdff9630822a89b6821c6746aa695c1cb74da0b18f248b09f1c6d67a1e5f470383589c3d02d06e3621f660c3f83068f1f0df71bf8814c888ea656226832058686c01c9e09e814b937f4891d0460caedbc738bf6e1846d762874e498829b69540bbfea9406b65b0578f6cec98496227a682f7290274d060efabf22196ac92f0ffd5f81ee1f3d818b328af98018559df7ee1e30ef0e16fa4a67fc50784ab02f4197cfb9c43bd0f75fd0ebedeebbbe7aedb2f54aa9d8483a897376a933bd22c05aa07232434673b88e45c85cd0fb6191aa232c7ef17e1c82162f0b0cdf29bc78d49eedd5dd28ed5da80b8c5c5bdfbf4ba87eaa5b183539ca57280c957a8744de5d3b9239e0b4d084ef85d5d0baf84c73b2167a2feadc6c8b4b80018437f3b9afdf88009931736482aa2c80682e5b0b05ad4b805d0ee95ac3c1d20411fa7f118dff0dae3e10f09108d1151c2583f9e1f3b4bf27170354fe897e70259727d05b745cb15ede27f643e89c430f5d7bd58211fa5695b16fcf794e11354f590539aaf07268ceac99c7038f5b65d81bb190254c7ebc1476ce86c9c7c5c7717ce28b333915ef83fbc0aa952566ab36b6fc332485fec3ae4e0a4e9f6a283702dcb54180b163699f4a3d86ab5805e988cf0010e0d39f1b2b695a93cfbdac0bbbbc8e8ffa19c84ff676c125a9133657f0fd6b2fa2d8c1126911d285a39e32d0dc7e8a910212f0a32d6cc53b005528fa54ec15bcf6cb6a205b04296bab2abcaeb44e64fb9aa83d5b0f47badde1fb366778848156474530d4bf13515aec38c20585117510a696ca0b4e7915afa7a5ce34ea982d887ddaff4448de532d0469a4cb8cfbee94436deb2e8e0c1ecc3ffd0cab236c1276422d062b2a3d1b90703588cbee24a384ab86fc188fb15be3a0c27a58939781b686db40ac38ed5153aa9340da3039d5786adf4f5e976ebc34f17fadb63c909c9426f5b2b1d74b3cd7c8d2c4011059f61b81c3db49ca546788b466da1f5a0d228d26e131c11a390a3b31a59f77567827630edeb6d2740cc504ca5f68f66737540733eb27a784e11f023e2be81f7216b93321769b17dbac8d7549188a78111b21dfd602a673027a89b3f7832bff4daf0cd66bf57ce17fac4ce04b555ffaf1ba69e7f9cc5d51dcba29ddb1b9aa4e670bb902b39736e742230a64ae124024e49d96533af95f902990107b9029439f14c5cd223f9957eba3da1f3648d4cecbbb10bacd44ee4558aa6b1d2499a9d4afcc2f7d8239ef3c4c75cb5b20f64548eb2fd05b5628d1b96ed60866c79355cea3fa2d920e8e1004388217852693f39b5c22bfc92a48cde8728efb10dba0488f8b48941821b3f2da1c269525a79b07efd9b7e441df8d6248c29448733dbbeb6912f7a68d85f4502c441cb88aa6b9a5835412f1976f10535739f5c260744aab0fce271d05094e43ef9268e511644c2d585e732cd2300906f37036449cc091bdb53ac6b924cb32faa340e1e71a3eb4d99ee408d3eda7fad19470ec32a5e3c0628b9e70b9e7a478b847631418cdf455cedfc9273e6d6eead0917652fa7d033afbb6caec4eccb7ff32c9f8864c2945410f31fb24645e38c845b745a9f349d1a8cddbff14db708aa37aa8a4eca33f81378b16b8e6e94c154520f197440b9f44a2e1c89a05854290ea5c18ce251ceaa3a8fb6d318f05a9143471fa3756f6caa06de27c48f1b629939dc9f53a8c027061cd0222a1aa181f732106341df163cfb4441e9b9287147d340e93d18ea070c97f056aeaf63eb09cd897cd49b543fb4e962283ff82e1972bff0bfa42910645aba8fae0f60c190e4cd9513a1d1c31dc49190c227750849bf304c7bbe2f643e9b81baa9ec722287f6e62a79cfa5a48daea9474096a498d3c4b0da5456a8f7540b96a111f2bb189ddbbfea3a696266ff76513f656b4cc633520bf16654783eaa5cfe62aef3604943f6d9d81419f92854953854c664e8e60d7bdaca6eb087ba48cb4272ee5345ee942417c6ae35376e0d421bb048bf9b0353493ef3f864303650d0edc5e53d693133ff69b023617c9cfb0f2b9115379f2afe6b9488425077f7750e62770f9431c646f5509dca34d910d4c2baed6b984c3bbce963b104064de08d7f84527f5623cc7b0df91eb50207b91eb029d5d761fae5f55e35e3b81ea5455f6fe860038b3c01563c75609a7b7c975cc4ceafc846a38cb8024b62b23961f9f0e818248df56fdf96cb1a40f6b6f5eaeb820eeef4ce08272806e966e073dc89333b36d1c6018354fe6863d941748ac72485a5b6393cc4bd87a409089baf472f7d95b9b4bdbe39c539dc1081324c56851c811343ca0c55819b182a2dceec82fea4261fb2eef3f4eaccf337ae7260bc7e02877ea043bfcb95e25515e38e37d6cbd4c16130b281cb752a7215d8caea20cde61ee877a363db5ef8673dbee6ee4607a9bf9ccb221f5f81c2b9777b314aa440c5ade39b2d3f1a2345ae01841b7b5e35932b916e0154ebcf11f32981a7671528c44017cc3aaece99bab1e81a9419d18bb5ce1508c826472f305e133ba64b306ba3b9c5a72fcc99c0347aef6676b737ff3bb6ddaf1a938e0f4a22fba62baa6aa93c09285f694a73ac427085729edfe17ac9c97bc0a072c007957cde5b97f7c25a77fe5774ae81eec08596c48c973bec532151acc279ca723b93959ac11d5a21056281fe46aa431480269de6d50f29546747d71348760725aaca54c4876397e99e6254a1cf95ab75bf75f48a2be1845df5c5aaea120bc512af2124a2139d314757a264ae22abd2e8d2da57ba4e1829e873f3ff3904cd9d4ef18a1f3b57e8b6cca111d6c833d9e876988d11da318c14e3eba6b2ec0456bfe81901956df30706e10490a68a5fd641c50734e8b1290e27d6a527b721ea1b943481f929b693be936f3c077f25256fc8d7b477940f3ae24a466e64506287898df972ca9871fd1b45f2ec1ecd05315b216306d1039b7b874913efebe135b749d33c0b29ee5caab9676a3d32455461da68b055d9e9411dcca95befc546a5ce4575a75eacf71f9460856a01422530985de949fe2ed74149f1ffd5f1a02be763feca477cfc55eb7145e5181216172116a6964a71763ea446f44d70906226095a98651a88787bd02951176e66d9c1eb44f645fe24b6a3fb935de0197f1b6d4e62fd7073686d0748c7532ac946686109bd15e0feb876a8b45b465c2dfa97e3755c9f989e4c08a982181457f3e25562165cb0e61683cab6a5db455f3597774bd9fd1e18cbbca69a278be2a6e8bb30ea038bf8c24ccefdd63c86af6766751bbcd738f1b8e4bc48cbeb0653440800abe6549a90554bcf21f9e3c5abca822cb497419bee5a305f4c2580dfac112dfe9bcd6f660c71f2ac34bf8383ec2045771ff5ec1323839c2a4c11517054d4758067aa26067c0ad9e5079751342b2d672616712aa02786b5db019d94e3d972984040d7d6a2f733a7b3bd99bbb4e4582ac7191aae16c561f6642a52353f429b0a1969b869ee2bc5bfbc95254f77f6f46d01c26593b05416a5bfe5ae2f1cf4e32f636a75ef77911cab79ffd6f3922a3d5be91ec0d4ef92ee1ab1b105a404153d78db8d8be9c0fcb10cd55dcae6c773debeda9584439139c42aecc90d7c9c2a0585f6b29e0d8701ce9c47911c56675bd8759c701bf5c846514697f1cd19118307e8d377f5e93bd4ee4f24ef4145f1f0f1adab6c25601735a1e6a74db42c55f597b4e449d87be3838d9fa3dc5ae9910d4b849ecfd5259b7a62f1a6bfcd561a9a821e6c364b0d31dfaef5b03817dd1a0aa698dd77ab88698b27b638d08582f535b4a02b8a9cd71e6ccec923554e788bd9f21d0bd97c95c955a8873b5a208d47f59da645c6319567ef16a6978add4958c4b22eff70a1aea55ef8c23e1989ca2ded886afebf0bf0da948f42d2ba131e195fc66592fcb5d42d6d7936284e46db01e05f06195fdf8e6c505e36660f9a4caaf96b4fd5cb7e26467e41ce63b62b32b6c168945853ffc74261754e4b861ebe626f08ed339e74858d642b29385a82794418091ec2bba47c5796ccc8d45b5bb90ffdd30d312fb8dc3462259f39a123b9c2347d05ff1019e500c091e0ab43167d32f84932c986c614a7861ae5f3289275f6b68aa5f3f9d7819b3daab0a5f3242461422caa42a6569f08687111016db9c1b8cf54b944882842c74badb498684396e42fa793a70abb7ddde07d6a7f56671694fd132792b38a934bdb689b566abef2c0bba766a7aacf8eb9f3d3c775c962d515d3db33c413754ca89a8155477cd1002cdfb6fc29945b9f90a0148f786bf3f25a04b7967075b41fb496bd3a9642e16317d3282ac3627bc2cca1f098bfbb89b83b272149cf91e30221d4eba4ea36c1ce71ffe998e2c8f864c59edea7270cc08830f06825d9caa0b3f35eb2b58770ddf00b9b7e5f39c00202dca39173923339a80e2d94dd4a7870e0671cc9b934c34de807fdc6aeeba57857e80681dcb9bba012574f7940ba1940f5d2338388ba25be7d90ee17f6e6ba41122d6b40aba99d87547958efafdcda000dd54dabe90a51def41a4465634a6975c45f84064ae54159d58e3cbabd0efd7cf19a9c1e6d2df96d3acb3dfb830dfc0862c2696f9bf142926fd9aa740881d79eb43b3cf757cf9f1cf9a1c283f097fb8ccb1511a153c733ced1bd7e7e6cad52c11fd7233e49e39cf6e43ddd860b349ea54e53b245386b4084860e9fc0f7ef7b0e6a8fe31a82a1521103049d0d5b5a84927ff71948929f83a57eead609928a2fc0b413e6c51f89138c1099e04cda1601306679270f801bd582783cfe844ed9895348dfb3a4c76577aac08aad597a1fceaafc33125ef3836fcad35cc53418a013a6b26e428b357d0fbc9014305d74ac1ad1ea7493761a96b317b7860e0a2481699ac4a7b3adeca74fe4807afa39eb7633bc3ec50920379696e53c34a90377fc7d6fe8557a9d05084e43a50b6aaa601a16f6b6a6e7f3950002ae111a2c88784351913ffb917d0e2a173ba470509da7571aceb7731ab8359c4c10c18b562d60504946d4d747358ab27b4abea80c0c8717f701ccc9526a2ca4a3f8df691b57898529067ac1bbb0da6757a1cf7de6e44c66a4382f72ab46341d5a8e493794e2affb4baccf22fd1aad8efc05b49c0aecd5497464921f7cdfe3ef00d4e90ee701b4e9c0b0e0bc390e2db4989c3242bc9af0e89ac7d320466e7fe2917067543f74a71b7b37284d610a26d148ae5d1968aaa66fb6276e6beb1e861c2049ef96c3d4b9cbd62c455ac95947972603420da10272c0a4822804fc1abf27787c26af9429c29aa5ab06c61f5b636e238390e582f374f18dc1d7d0b3b1bb7bbbd1bdb46430207e32a279881fa4f76dab924b28701a7f1f987dcc1824ee8c8c3b78c6dac95984cae497642f022fc3d86f96864cae93826944cb2bf2110396510d73b2a23c4d92b902b086f7faf8a6fcd650412a6dd70eeaee871afcb5a84dd62ad1b2cf6ddccfe34b2e8db0543db0cf08936eaa55477e07b2a95225655e7fd21fa6eb927dcbca051c0d6c3e89b7f372d7a64ba685cf111018d957311ea821088c963840a0394434fe3daaa0d20070340dc5026b9f188bcf4cbe197f29faccc373d060d9df1927633080df8fdf2c9f9740299df46abfc7e1bb4b6b24b121b77611f2ae7f5a93ae87e1bef5af02938828387d465e5dd35351555da8bdb198799bba63486952b47226264b90703477204305a040bfab97dfee9d90d006aa1f8959649e109f8eebaf28afa6c9125806c2296ee837022401f548c8ca1de9dbcef8b790d2d65a3a66ac4f5a11f180a82f0f276f89a51e506bbae948c534dfbe3a2006ac6a3f28c4455bd866f113a109f021cd9b35ab4da17027e4d407c66d1823574c3024b821386adab70d3879c82428c97ee0c2382f922064da500e542cc8a582fcf1e20fdc8096f82e200ee790b04d24a9b2ce638f86073d2f90732134dbb8ec262dc9ea29d0cd222a9fdd39212cd29100c211bf5292e8ec91be15a4ba2991d40b025ce174ee04f177abf1c156d4ed760619ffad673de6b6a404a9eae1a295833d503c714a2a4436b84c1ab80210c73788104be9808b5b56f7a199305fa165f74a1cea38bd07b946c3a65240fa91af66ed9d1206c36b649bc9fa8bfc374fa3f92dc580cc993e3cdda92580334fcf75fdd8ef464ef2f1c453eba296f89bb6bdbf8317bc2a2c68213b039ed969ff95c8782667c3a52d9532a016d04961d43716c5760854281c82808d58a70ce87b70d3e89d35dc35dda3b3e54d1b252673d5beb9382e8f54b46e774d97fd1f67e070861155384f786d42b9406d5b178c5b1105449d1941ed3fd28efd2debbc37db5039792cd19e18714512c975904ee3be3a8097316ee563ea57d0790dc0ad46ba6edb75761a03d10de5119124aee60dd6fcbf170bec6149a8d4c80e5c969c79d6b27e5c34d28eddb568d4bb46fe4e639f4875eacc00da3456a8f61152eb00bce118a3e7430cfc137e4b82e1f887364b05cdfecb5abeeca8e62e7ac8167f703a90c723b7f3128b5e16a1bda2a9655cd7c050465e0c51c3636618cf5490c41c7f672e3287b810fc63af439e8ad28402a9800e2e50f552ea4045a1701bd3e303cba5f7db78738621cf31ca6a24d8f0378713b48ad54f44b795c5f241e2c174435e52889ea588e9fc934b2d9066de67bee77c9e5a120ada231193527368413f4a0842cdd4ef87a9121faae3944d32480c543471f5b85ef8bd3278104e95a8f2dace9422faedcff1379db347aff24e3e1630038894b32296765c3f24af113119381858373fbd5f6142f6dbcfd447d6e09071aeb0c13311e2b3d4aaf444a97b27d051a5482f6b293665770c8c19a21c7dfd31ef63124c68ba31927d115f4c8492c353aabe5954c3b7ab9355c05992e247ddce5d92b0198765965e49eb6e23610a871bc5aac3cb4eb62293ff019ad12f641bae4543c4c485cd1224812f8eaad0df13d867059040643067e1866541b5b36f647988eadeab1dc6818096ddad365ef66bd12026256db3646568d02458c4c6b968d31e511a81538372c86bd0a453fd34d469ac362fc8a032702178f23e4f4197a12ff0de4ea1d1e0c9d00d899dc2bd1bd910df2c55037b821f9d13aef5cf088643981538fb74448c13bbf9af618647003c4786eb63be606b26f048961070f1361116a7e11e23afbee2bef93f62861e3b45b86bb04a08743f5196f7bce54a90b9b811886eb84000bd8cff1a101047b11bfbba2be3278bba00eb05bc992ce38ffdf5c10d10c48010f6e8bca7b90256b4d59d03385cd8cf86e6af85b4331f70d0bc144d0d04410ab185e60c31a0a5da857bb876cb9dfa30ddeed65b201fb239e28e4a8ceb16d76beda59f05c2f26b612f4d58693649af811913cc723f2bc7fa58b420e94ec6c8e8695924013d74fd7618662ed4efbfc91222751c8285fe3a52e70d3c88d5c7e60a98993a8b2914b6c46541f1579ff480186a39f78f74e6d791c498c6f9117229abf933558d76dcd763be96bc2a459aed567c9f27503746b3612326c5f2d02ff602fcbba964cbb3df374753cd6e4c90fb6ffe4bf87857532838aed4d643f3f39e16a6af48d3a10f42cbf0c329d76601dea1efa63989747e9280c56d5d7f7d3071e69ce64f054c91548d44b6d14678d8e15b93e11fc8c6344a39b1a3eb1313b53ee63a304305ba9d350d86b2f193ada8060d777d1fec0a20c3239e32a21e270e2023d62e2dd147b0275faf81c6423be77b021965cab9b8022970b644da0585d5e7875d4cf35a6758e2056c0bfc493d9611660b31742d92a1a7a3fae6d1b7961cf4ccd79c109f238c7642ab5ab1b034ba7e02f7df76a4c14c59d88cbb2f938e63193f17a2aa8a60f43bc5239deecaa5aa5a93227881acc382ec9b6c920324b7bf29964ed4748548846c2b0fc37735e8a85feec2af606da611d30e8d90b6a1691e46edd910dffbb02e01e691a6a62ec0507468e6c13a8942404a3a822b9ceb5119fbf2bb7f5c27fa13e1363878510431131c54b5ac111f290797804c1db79f2277a720140ef24523844455995668b8a37b6d1c16138c39ba51f28cab9c78eef2cb0738efb6977df8265026e1b881ef71dc9497eba4bb510c3d0c1bea5597d6993037ef938a1398a66d728f00a2d83a3e762dec7588404ce7731f84e46e98e2ef3b4182c0d9c2947f26868b9c96f8aa0adb236f1de7cb0f15f6d31e5cd74a2f45134b7ef39b0e4120ba68e59a1f6634a8c46f483a9c3745492db8feb96ad4d1d21b161fc2f62187cd017f1dc0f63d0ad00b7a24b50b5bd633ba101cff63d49b3549007f530478d29f18d293f6a13a65afd27b37082950d71559b3d45a578daa1e112f5a9a6894eb43c59a3c9f093eb050282bb44c6b40e49cf29b265509b2aedea01ceeadcf11e4ec5a6a01da859f12756b6ff558024333047a729cb1f8cec696e1f997b894228b3401e2e7ac42eb550d95c6e92fceeaef08b79e2916cddc4761c86ea144c345713cb0d1c03b0a4f1ccf4c61a2ba6b7a021be4b3f22173cf77f75c1a5461c106b418e9f382be915b6e49f94d2d1e7a8f11d4466bfa0fa76146eb311113e366714b2ce06a008b5e65737114e7c26a07ddcbdbf56ee434e5d778e184f9ca895916dc45a9fbb12da2d57fc41fdb31cb6a05d2f12cb1bb9eb605ab187c21fe98fa9949d81b15f7b853fca459c09958c64604b8e7ed96997f4708496eee112afb619d4715581855bacf71c2981cc2865a9a0fe059591a8a01cc2952085cab2128b37168762aae78d602085b4e2b6c9812e8293af52e59ee3e47cd6770a3b73c768b793d16bc335fb87785e69c3d335bf230568d6d6f75706d12cbad2bfcd50160bb209b3e02837a2c22f648a02a151ff2e8fe33793db88c683797c6909ec6c95b4b2a038c3538c4baf0bfacc12920ce6550cdcf62516e8e677299cf4638b679d4886a367b907f5130293b76afe0f6b2d5b99f5ad17279263495133e325c32bc6613c77b94c6b502916b1746c0be2925e861bb88a44dde7d996c98d348dd8973180b0edd0e36b5d04a11f1384c768a19983f60d077631e82db2e2ca61fda14fc9d08837937cfea44f0dd672f31e74d2df9f910539d45593ffce013287594821a59d6ea45bf6d16562c5d369171c1c903bc0d03fae6d3d9d53f0a43e5a0b18aab1b1216dc9829776f53c1e51d50b1450c2715bbe0812d3e7de99acd5ef35894d2c71a31427ba6cfe4f398874edfea21daf9aa3f1c3506473c4fda8e1c00a2163f4169c241aa33385aeb27de6c2af375accf68def7d099cab29cd9f070318fd9a86417781529c6df743ef4f1cfac6fc260b8bff406a936f814ded442b0fd83d269679e87c26d6a5d718022866a0b537c02177eb899c9c04e90e21f68cb1f14b960d0153af8a57dade6d6b9b31089b49ec0ff81c0100c44117140abf26f03c9c834ca91338ffefc8346830d84713ad9c2344b96f687e5802de490305ae309e3507be4cafbbbec1cce0bb17e0335df1001c9ab04ceb6b080a58224c385b9a7f0d3e8487ff41843151e30c37d3cd6d6bc5a876536b5b4010154e9533a702bb609bcbb0217c49239ca36279c54e88c54b081fbd4444238f0bd97e1c5de59c3a3e882a2545b6e9a5c6477e4d300583dd1f12dabf2fc6db7a77bfe032548a842f2edd24160b84c418375d8ae94af0aa2d31040aae7362fae41b3ceba50739ccbebce091fd2dda99c17f600ddd376ab548b9063a4edc669bc203078bf791dcc15097805639d5ebadf184c2b0c502e9027464c3ec05203b206553656f6dbf998d4fa8c755581f72d07d644c773984675e0b5f0b91a48fc7d07ffca0078d850e2487e4a59df7355e25d8cccd96b54c6ea6f5db98638eb0e955d70fcdee3b3140de8fb778873e06929c20d62922571117951b3006f49df0b515569d9ef4efc935cd35ca93586f8a13435d5c08e6c896aa31515e8bd19e82ae615b42cdc84bf7ade9730ff745c5016bb9498d4bc846206a670174bf1608d80a3c1a9b68aad3f1417bcc524d723dd82a74f4f63124f72880d55ba3a431a73613a2b061c6ddb591822b4333e169438b8db6de48bbcd01370d0e84c50787da787297378e3c80e39eb0b2d74f18d9272e846d07f769bc8ede08671831905954b8c8768b53f787a6e351d8948667b18553acf3a996d16e68186cca1f54cf8dc35ae949a4e01370c85d32c310933a7702c49442dffd6268fc1d048663bd31d0653ba3ea1c0d3777c2089cf4e564985037a3b9ab53aaa82a96e75ead519c4cddebb80fe48fbe687aece22b6366fe5487ca532ad0875086a003b9cdda00cbf28c212a610bbc2f89e65993c52f04084c4e9d9ea925b55363d479595ef1d59593660d3995cda81b673b9c47106deb2df0472228bf9a18551cb4b45937d8f7a0af56ff5172109ef25cdfce24847d788a95e9135c8601a28226a8dc2ce57f217abbb8152a632eda58b0f40cb84556f86d2156b6d9dbee3788a9de3317c259abff5701d2ba0096e1900acf175d9dc66ba144ab126fcc34b0ac5bd33c20055c087f9aadb0033fc58d1f20b4c6309d359ac3e5d7713d59ea652595e3a704e87f6d779042832dbecc851862dc4770a7ed20b72499098146f8445cd59645218379b598c6d2e709f18c5c449b149a9d407e46161b5452dfad2dbb60a4534f4f2f14431ae5bce8bb3c8ef873b6e60846789f972ec2809f272640a1c905cfed06900808b12e68c6d4d6e151d49eb588bc59ac782be7b6f6474803b74e4ecd180cb10214c9fe4db2cf04a4f659f8aa720eb5d4385e0107fabdc83a9e480a5b43a46d0150d600c534adb17447d9549f3068cf0bbab7871f3fb54ce4fb699cec1c6efffb16281fd4b9ed476e9e3e9db149f4e44e4ecc63a837cf9f3dda033322a9b265744a93f7d611649f8018e5e22852700167a4cd4db71cc212e100044f23c7d4c5336d1972a85800ecd3ef295fa76be32350d147678b53b583424de46650d2b371ff14e3f37b0809e803f9f7225c6ef4dbe4bc881396fccddbcdb2b29e060e536d772610909a1a2706f07146f36d51e1dee9b849ca25e66577e76093d6406abee1c0c79344e128286bea51a739de0e0f73ae818e7525d38359da2f776a825ddd00c5499b25d01b4bb0fac1e0ef61a50f859629e23140ee2b97c5feb97c355cdd7f3bd829221c16988868379c524828b0e746ca3466fda15f17e3ff645ab6df46f0e252e41564854d002062410817dc22cee10c274efc92362b27713441004f5707399728406dda1d8d0fb548d5179d1b8119f5dc367cba928b3446f6720aa6c41d32b9b8795d292db3c9ab0493d156ec61059cc873d344b667b9ee2d24f7d78107ea6f2ffea949502ace8c8db5641cae9c4945c6ffff6ab066c14121067a3753c2d5439ac32a344708fba690791230e1a0700a981df73d59e9f8fffbbe105518d6f3bc17e30e9c554a361ace7c10433c5ecdccf43eb3597c8b5454b184cd609bec8e094071e190f2c44c11c38c5c9fff918b7f492542978b2302fd41d047ff9ee61db0ab9cb8391d9b70acd47e5228c757b59a559e8007de4b76d52de2663a9aaa3c176b6dd056a735cf564a97351a5ef0495a895a959f3f28f7c40ef752749e4349b88bd23a92f53ddce7836ff21cb5597ad2cad8a034fed29a79613be003bd97efeeec8ae4b439dfc53a6545d9531dd9e3d1d1d93ea1f89567d98ec9ddfbbc1a864ed34db466338c32e61c1014f2d10f976660dc5dd88c9ccac69ff0388bf9525ca931af735a363f647582882974014e1b6488c80657daaf9277a53ec7ea358551564e4eb4f3db84bead74d73202d18b137d808444687683699add71f1ca04ccba5699304d34c13348149ade978251385936935473a61c4dd213a27c09b58afbbaa3a0f5ce153da3268e56714c244307d068650135f0c39a796325d0de6c6849b32dc54b9a3c5ed1b9fba0b2d622d0a0ffa9aa9f0c7ff6ba5d41ad8c6a2effdf81d998e7bdef56a96f24dbe13d8f2c2a5fda269306dd20a6668105a81d01082d31bd59b17e8f7def868b6fc4124d09a415192936871239185affde5da76563b54b1fe45f11b499410a8b892b117b40293740061e73318da1d1ec92711db22210ebe88c69d3cac373ddc5b63878ab1f9eaefe41a3895e60f4800cedd35a51e8240034229bdff07ab1eec2f6a906678381059afb32574c9f06bc0eed28b54479d233d25c70ff855f3e9a2edf4db2e2b74c37c027853078fb46f430d239905e963eb54d19001aaa3fef6e28668efe6cc1c551f616306de8d6c308776833c201378b7e99467774a328af83b2d84cfab9bbcfb5c18a433434b421f3983b569c52a086a7d2fd700da3c4c39637c99cc6700870695724c8e77b25b091669560d268b092f93e1e7e42c3d25b9e586972c97bc9af326aa98477d3ac4843404b60c5facbc10c44a669837c305130d99fd89927da9f6c9d263a3d79485ccf72fcd068e9ed6b7405fa1902980a1fe0547ea5fb64dd6fa68911d137ded627a9737deaa7d99a0d991959d6966fe58df0ed9de383a5e11b7d1b62fc8944547fba207327a2698a4348030f9efd21fc63dbacfa949487cec654fe0a95b45c32d81fef0f00167e7653a8126f2ddc70f86aeb2d8773299e0050d58a50b39e8d9b883a7075e7793c815e36acb35d45b26c4e2ec54bfe4ba51f77b206bb72fafff4520d705fe2d5601b8bb438e79f71ce227d5f0c430fa6c879e27ce98d338cd08982340d568324750980d2e8573eb92afc1d50c2e7185490a2314012d4f31aaaa039e068cd4720c9f4ee37dd570b83758ab0c077450125b58073a27978dc5a571f1862aa7f88caf50d8b60dd22f01198504122fcd0bd0df1667566a7f3262e9008283dd9574b5df8dd05f4d6768cb275fa83163350c2e2e9928eed1bacd9860dc9ae9bac4e4dc16f1309755eb7961b479b57fc0ab05351c7afd821f48a2f60deaebcc417014c7d465032e1cec71e6e08a90c911f913d0346344450f85b4694160e04e1ed275dc1e501ded9438bea49f204e7a0562d92ab78c0e6583929cb0c7b65f19e5eaba084bd7f94b81ecb314627c39aca13a5a951a9888cf00a5f971f57895392c97248f9a277d0f82f447a1284e438f65dc2e171115a0238667136c28fa38441e0cbb974269ffe79304f47c24515fda6914c7f63612741d4e368d9fdf22fe7eb584c388d4ce6edf0ac4ede97fe78c8f446a4af9d5789078f902940108b9028f39829ef7a2e7690ee19d7ebe5cfa77b934ff21a9765265de87278e9306e78a90917b98efa1c71c1d8f6b9d88932388db579bcb1722bbdc57c865ab2ec9111ad1a04ef6acda81025a63b02904c6d37c86795b3e1353be6e2478afc36117bf9e49ba383eeb44f1e1986dcc4ba3c89ff367849d33b59eae4114543368bd0b186fe7db22d66e11082eca07b0887de1ed359bffefc224ae67b8d4230257886c9475fd41445b025e2bd7359b0794fe4848d9bebad609e999f6667183193e89629c342e1ce31d971e9ccaa6b3592bf3a9389d2f1c21bfef41fa18b5e5eb81fef865c79daa4652a707a95ed8feef124641d2909e9e52d7af6b1c357e61e99b600c2a3da187e854cd55e288c8911693dca82d4cca1b48b52ed6deb6adbe73e31c947c9119568b0c9a40741255af4b9b8c6d5e3f21c5d8c0663e5c2349b3a5ce32329d4caa3bfdcfef22eafdf3e2975036b46d18714846dbb1d0aea5fd8e1796371050d49c47d7644f9f9bfa1361e2983afcb2ffc56bcd8b224b7265c72d8f400e2797591668752a740512525b1e658bd78a711e99e5534491a36d4d437595b3345a0bede68f619b1a07cf38435cd2db074faa658140cc18559a3b3354fa0ad34a4e70272db187f553c26f8ae2accf5a08d1eb79755be4688b76dd32208c296ee6b90a7efcfda5a79ec243f6dce4f2c769bc29f49e4220502a4d8c5a80fa2c869a234994b4280434d99e7a1916ca9d16f60dfe7ad0f4373ecfbe4afbecf02a1beffb737b94352ec55e610d5b99bf431d555739b18b0c8c915dae2918abc2657861516814c5388498bbccd9eae926e81ea3bec526dba88a1da847f031752d95ebe6f0f6cff22b92cb32ba5c8c3b5bd197721a1403d6f9c9d8834998e5675c52290f5261a6b248425c1ab73f1e48988b5d5b83d980f91eb50208b91eb06fffc8952437a1fb25bf7605027dd83e920b884a4b9ee3f266fcaf24ee64e7bd04ca25eb1225b2738dd721b90f9b72dde141e2872fbf20d2e51d4e20627e5cd45d8ea87a90ce90ea2b94a6d84965330afbc873b84ddb41a9b87e3b3083ddd2f6512a06eb908ecf2f4b1d853ecbb276c0f1e6e0f13338dfa559ea900564d10643b5759bf1e9ad97d6b55e2e2e7af60f4cddae253d74e6da8499e0b2a2fe7a757a636f0593fccfcfc17666c2af39cceaa69fb063bfa5f4ffbaf828924ce9fb477d6e07a5705ce1fa6b913f1d321ed9fad769a40c9f549e7c5422f393cdeb99c5b5edb3eebdbc789974fea3b3064da8c28d9ae4da082b3f88bec7497465424939f933d9bc6536dc93f605de1d11257ef9462da62ceb9b65e3d588c05ae21da420a963fca208cafd6db17ac9b2ddafccf14b93b20efdee566753869e8aa196fda8f6fc54712b17152c1ff8347b096a5b9765803f66cc64eea4bee9ac274294ff8e51a8674aa9f1c81555c03ea30154ae6160578d7a2cd1f8660cc071b75aabf6030cc8cb041891bff49db882325d14d9f10dff9d0a096cdf51db0e54fd3e051a88f89739e8e337184860928c7934d87f6db3aaea8998fc04302f5d937b9d1bf06d94ea7b071cd1361f8c1d4d6e18274f6f93cec3fa9c3773c706cb5832017a56ab523a534bd6aefebc8dd4646a81435211ec91402ad2290eccf30f78b8fb5a744462d23f41c02170272e2d9143cb55b8151fe5d350a2c8122f19becd191e079f3cc0f831de70ca871b67b93625a5876c2d8eec11db3d97bf1a40e853fea097b929e9d7be36d5d4f27dca4c847cbc8658e6e9a5f1f49f1fe3075e79e6148172be5380ce1cc04210d4b89767655c0ecd810153d6adce326b8aa170da803adce7a874969c2a42bbb013f669f3b9961e4889a09d6cd75d3f1c1b413e7121cdb1fa80c425a5a6d7ee6af9f0b2fe82e1e2bf58d9de9e29122c6b6e2cfe0b5b419ee0ff7d556a426a48ebf309bace26d3c23e18dd07c6e913357afe32f922b587f38bbab2bdba6cc7f18f9a30698644850dffcdf21eb98b0c5736e9d2cae489d41b24c662da3a48655ce1ef1a362eaad10e73961c84b8053fedd0c0e5e7d10f5d2f5666a9eb5b6c6a6acb66067512f5ee27271e250b755220d3057a3588f21a6de451cb683a21a51c4bc013f7f81e00069b0b003ed9f735b22e8cf1b38e0f752a47320d22ee2d2d4798990552cffa97c9ec3180a2f083d5113fdb89ee8af50dfd3c25af03cc1d66307aad4edc9fa690ca1e49d0dde81d60b6f71fd1413184698fb2174b1401534a5c17c0278a545fcf9f553d6d7b825d7286f60b020275029762faa6ebfbb409d2377913918eb1465cacf03b927a6f5e41cc31db133582e0a1b838924641f33883d3f33a4d2704f0ee968fa2c167d25cb153052cb8577b47ad947432ad6e79d1b77ad457e6e93521a1819baade057dd7db7da10ca1b5d6ce38f4c07f51fadeae921adbf3258dbbd3bfac0c1005c4984e553dff2233e8f217653e59c02ed5a93dcf763e0e7b9b1966d88fdfd4e2ad9475d174cb015ba1875eb74bfd44931f539d933e4f5f0683fb72d46fd5afbfa7e3f6faad9714f999aa5667c5cd6528c6b846b21d419f79540e2dd76672f00574eb7f7b5f421bbbe2260066d7b40e20cb6b81986bf7dafb1d0378b51683e10b94a75064525eba30f09cb132ec613d2fb3846eaada7ba4ee0f1fbe25f50a86db383bce7cac80acff70c84fb665c23eb084f97994cd683bfef424904de46239fbe70e1c126865dbae734f15f41880953f3cb5e8f274f7392e6335964bcff5961687a329d5470487933843244b09ccbe13b8597b6534d207dd93bd2da040359630efb7a4dae6334c6eed6be533d3fbb808e14a5d5335905da745ebfb46335792953d0114955a6538e2dae24bf7a13523bc64cd6bcde54483ffe9e9b1a7afd43ae94cf64ada0e95ad0a3c762629cdb4ad8f398c1f8214296b072a9546f08172b51da4a190dfc146ce51ae81bf9a597ed064144b28a7a05eea7a2fa1f5e8417782f3e612cfa0b8c2de29d2b18d6d33d1bc5ea2604769c432c0f06c022949dc5ae8d6f41d51733a5a0092303968605a973f1657910389d6aa00f11ff7651825693d6364532fb99ab71700edac7eadf846716b6fdcf83db9a8d8a40619883ea57e7cb8360e176be9102cad9e84ae21cd9bac1300f7106ded5e2e8f2334e0e578b28315cab73794940a4462d21dd2dbaeb90da1e5897122732c054cbc2737f29314ed7e79d8a78393b30348a3a2360df240fd803c66bbbeb533810bbef5dadb8b3b161a040b67ae7f7d9c985c6b948ce841e5c65bba94eb582616b7463105008b764bf7126fce8a117245e8ec57d5e79d0e3e3750a44e3ea0b49ce3c8bf5977e316e3a59bc9d1e32ba0148c2c48cf7ecf5493921047ddf63f24b9722962539163b99600ddea514ec1bfd6de9331958d9485241a3ea080667be2ffda910fe0dada74bae7ce48f531db7800a5871bdd95156cad2e5febe1182305508930b08c739a8bf4ae1fa445837a753acdd47853f983800dddc6a517e051907471882b9018703d656845d7764b698e0354648880b39389f6cb3ab9d5eeecd447a3078df86951992e89d357c3089313b1de97352dc4983716cbfc6f82d9b14012f6fe07186eda10728dd7c26aea0c18c9058c95924ff199351ca7faaba06a1950311cc314fd949543faf5d30e6124fa8df43e358516fa9dfa784da7856d34cb1c8cbf9fe9e391a5ac4510d4c1335f81a636a7cf27cdfd9ef21ab77aee85c15a94b3390b1a4424337683ec192499ee9cfd83fa6b42b1122ff487f3a46404b854218473eb2399d1b1c021c9c7f44f4ec3e3ed72cf85c1855c00e190c5728c6e48bd19a55146d2a796d5ed332256d426dcc1b51b532595506a57d3c1ef17c0598c06bf6012742cd84f611b35aed5aa2a5b2bc5c0b0a8fd68c7f9bff4f0c8f4658c90aaae8f63c432ca927c11560e49df30b3de2d5a51b65014f13167f6b0325c2812597d2c9135c47215be71939494e0c0e44e21e2fc11f45c6257ef4c7a8a5fb3ce1fa46fa5267a52a61afdb4d8d38f17462152d249479336705ebef1e1d0e0ded08906bc43d3492a0ed19f175f90eaf132ecb52b381303a931a8e99520519e52189ca2a1a2875a8001de8f45296fd086590d6a5e2688433af369db2773fc8ae1ab6783e4ad43df44b1dc2172ca552c1f7c89e68ac7f54a42b520596ffc355568208767cf44c10c4d15899397dc18e272edb69631ea671c99e62617ce48506ab0d6f85517bae81d4a327cdf29404cd8f0f877bb631491c222c3d259299435bb50062f81d94987c83128fabbbc842b96269918aa895b1c854ee3823aecf59c0d9a0c6ce124e435084f908f83551d784b9fd8f8eb32b0fb498168102a110d0604175ef5f9dae048d1b35803643ad7a0989e5934f2417b2a0f11b308b04a0c7fd51138dcad44497ca4c4f68489a1a2dc809ac046b25cc4717b1123bba0ce0947e791f770a4f5339ef67ba4357914567b45abaa1f946900523c4b5d51a9dc4ee10d9be70dad45476e0fd748d9c174552aee27b222a362f0fcf3848f0c5a9df19baf1ec3a155fb5444e17b49890496189edb1e44ca916444075f13dc544c23afc9391db4afd83b4add23a6304305e68b0794df5044ed0227e259287221ddf3ab19f7ba48961fd4df8375325b126efe1e3c3c2fd952c46a6e3156dd147f23f7bd2b22af3e675d6f709199c824debd4f93cd7397df3b03c30f37fd7fedcf350f9a01894eb2e539d4fea67039d1e4297922164dced1217c133bc9be09115036ec68c6fc98749afc55416b61bbdfcbe5b34079afd0d8d1fb7c3b3fb8baeecb71c17ae9756f7736da563ae8ebd7a30214a5b55e19a6ed0f3a12027746703baace79e169f61dac7ea73f562ac999134a119e9c4b29d76a008555faa87fdcd4b30e15c12b625d1da417f1a814ecfdf8f8b9cffe53830dbac46e926e07b0a7a5abb56e97814477aa510ab1302248f4d1384c27bd6cb999735920c4d04fe6cec427b701452774710a0cb66b32ab9be6997eb728e3d48528db3e98eb620392eb7d0d363c028eefd4fb5e107485a45c646533d646b38798b6c9ff7d368c8e2dccc0a088f0f442f21e3a1d3e37db8a2c9fd481af383f99f754cac0a06b5a2b04ae91fec5291a4951218e8bf1609fb839f631ae98629eaac0c10d26dd5b92d73966d33db2d94dc6c07bded4430978e85f4b33b3683efa5ae2e111e41e9f7aa96cc0ada07f5e4dc84da4d8b5ccbbeb0f1cee970fb369d124e49c5dc93c7ac716c5a01677e1abc05c5ce14d773f3ffebbe82ff106ee3e7a8fcf89f70235c9b769abbdc8174e75691a35e05515ac9997eea7f024b55f7014129ace450906939811ae2fe96bef64da99368d24c7e2764a2011ff20578f40b8cf89198f7534cd951f933436fccb38da6d69cfdc1bf43b450b1d3e45d157bde7b337e341a9411b9af96e78b89080b175f7fd34d3ed24feedd1fac26894053c578e4c565b38e65240da25e07954924fcb9c685ef95bc995606fa40b61165f6678339ae9efaed09dbec02fb1f1bdda75797fed0acd2bd2d76aadddcc50963d5b726ff797a2cbdc47f184d81a2cc76086ee2e373d02bd7925e4615ed08b00af54a2eb6124e476b28c5308e95af95ff9cd7b0ae5fc5c379cd5cbcf5798a1e95b7176e4406b628117cdc60657f6b9b512884178c456e68fcffb8e8adcb2b2f0aa6b8414b299b65358c2e75af8dc563063d30b02d819ec91111f51e25a13099d8a97999350b89601922e8cd77fc9d2ac205cb0fee936472e73e764c48d707dedff7fe4ceb4fd3c2fa086e6616700956d500c60eb47de31fedfbd6f46307fc873567d12e2ea6438011b4af6073adce2361ec0d11cb0b574f54b398a66bdd0ab02eb231b0839c673139eaf1fc44f142a31a0d0594e3db44cb7ed27435255041d4b3305a0fadf9b9029d31f4b81d916e4532f2ef4f0309bfdc0c311c2414b874b63aa35cf83cdf9719a0cfc981ef4dc16df85a775fe2d1212e87ecbd557fea265f34819bfc70fb27a5d7d97548238a8adf5861f34a3d8f8926e3d44fa95484e95850a0332d1250b48f3a2ef4c00fa5b9626e96dcc0b4180a65416cc21f1da818ed7ceecd1784396258070a014eff150f3c76a6244bd06dd3dc5e3c09259a6bda49efceed72ef86325ce4c8e30aacac601c0d62d2de9b17df4e3057cd73bfe3cb11b54f975a02e286ab15635e52e3a5aec5311b8a3fac43cc0c62bc81ccd0da7d8b610f53cd4a373703880abb5e3a279f465d6a41ef2474efb873fd346d94d1310efeda5608fcfc394f5c58b0c285646a872a13daa1932e445f1965039d3313a5999e05a34e4fb989661f34d36042a87ad68a2dca3891750ae86d38a1ffdc684a7f647a36d39a60cde3df921b3061574bffefd10137f5636991a0c83b08cfa84b8063e6ea69c2a576f93a4ed8041e735a16b4fdd4f7793875d4036ca1c75be0accb13aaa8e514450488ee65dab41de581bd6870ced92b2abeee7be8f27bb02c2f8ddad06e68f6aff5f165ab71e11c05603810c2de2e270afe0bc5e6cd59207e10a89cceb9b02e6769c55e658faf98daeecdcb96356872526665ee209b972a3f341389f403b8c8acfe1df3dd78e8fffdfebc2e1a22f957a1b9a4198738f3614d3f9c39f032eddd5bc72f9f4b4bd7b6f614aa337568156a09945fdbcf1d7f52df7f36966d2a0a0bcfab121001f456bcf00d8f4898a3e856895a3369d31d162d2f628075eae928a6b78dd79717c54cf381bced8be4f7cd1ac6fa5de2927bd1959e65d5dc455b7d4bb480cff875f3a0df0ccdf42f94881d7c9a1c3c97d74eb9174a59164d7195c5b3887ed3ae2afd7f5e474d6577f8f86b5dbcc95a69869f474ddd354e826e31ab42b16fb9efebbb1bb6ff904984a1ecc8dd94d386e7b6bddb3d8bb5a650fd22dd829c90511c0dd8c7e8ad7d3c2bbb4b40aa90f706c8fa3d8832b4225c6678d18bbdcb5c15e198a4dbe3d27e58f15fb0e2f2dd99ce4c8ef9e106f1665a4a6d8f55bdb8cec425be51aeb06126445023278c3fb3b312a85150a70b7539b587ae98063aa7c6b78c493d007347ed4874d068e4026b36b2710283de4c7019877f6ca142d50d2ec1e0097fab59f7275108fb22b925610a60bd7636d806815788ff87ed2b01a9242484cb0c4b2772e63547ee8bf719b242b1ef17e0fe3b9eaee63cacaf350eb197d9b2cf8c55891cfeff56e55969088676bf0ab937f4e6fb75eca88a1adb27a22a4ae53080eb0f976cc457a90ab5840fe67d8b01647cc0cbf6ee5808184e68abbc5d1e3301cb324ef9a5a654ae4ad8b595f37b888b383ff0d1e3ff150f635a8e8e1f1a62b0615522b97e99207a3395555bf3e492bc5ecde94991e03452dbc27efa7774defcce69c6a08bdd5e42197c6a36cd0e27d239252771feb203d1acbf095afdbeecfe44d1c97631cf1f9fd248f60d85ddb52c9c81d0e0108a85a535a0657e009ffdaa2c51860a0c854bad002db1ed669a60a1dd84f452762471c1f5f63928803520556fb7cf423fa664be6fd87ebf5fe195d754fb13e60f659ea74f1f74bb39a0f542fdada10b6cae913316dad12b7e20e832bd53dc303f9783443be286a565425fc5dcc0dc31e6a4ecae6c8295a5d8f6b35cc5abcf72412e776c50cd305baad4bf693048642ed30e4b669357b884da742998ab965ec3ea41288a6b6f437717a9274af26aa612dc7e8a9a789a5d1411ee95e8e385616533292e9d9e51685dae8cba44cf3903d878d0771749b42a31fc54f44c6f7f6c75923e3a178c5832984270bff37e711ce385be0e3e0ca4a5b8f252f3b59d30c9d1c17e5990d1082150a5d47c57a0aaf2ad99d6984f56c76dd1d1c8e7085c3fc033d55a616a3803a7fc69acc137ed71d9dc5d9938ef7d84334331ee4ab7c25e0dea4d555e7cc4d708247aa0c185cb067e59682b16570ef8c237178bfcdbf230501ab823c7e19d27ce113a75df8579dd36431b9c662dc61ef25bd5ef2be0695058abe5e342c164250e2544acc74cfc1443700e76d0f38c5974771bab4e7179345ad3a5e94b259b040fab6702dc9c0153f6c642eca0c07bc0178802597551c523e2f7bb22d143a19f3aa57a5f4397477aedf8596ee42d6ae3eff2b3b974325884df846670796c9ba9ca92bd47c0532219262216468f3babbb27452d7979c044d6e436887d27894017291e5ea7a3f0aa37d81770cd1d3f85bd0f80025f1b103fe76ae33ea635c7bfe0f6ea867469d89d6569312ac1d76d8e6368cae9e2fdd9347e99d50f6fc9f27332902477b2215bf63133b7aeadf39da745342da88efe2871617f9eb00ddd5addca38287c9e4a6bea6bf82a127d9817acfff1fa1c03fcbe48f7ff7dec5dc1370255051e696acde0d402d70a6b961ccfd4d6b8916a4da659b437ba609cb29e073cbc16e71a567032168d69cd2177dd3ca1a30fccc83b94e367078246b92fe0c0fca54b82ace0a98c1e9b96393fe5768c1573589d38fdd15f7b8d888a74e1f746fc8361b1b638c544103a29d89729ca1ea4bd94e765c652eddd422a10445e1886ce3d76de57914158d29553b7421317076aeda14c8aec0014d0ae6c4af7de25518bbe068166d117b0194a92c64286c772953793529adf282884fc136a49be94dcca4387f8c92e8e67ccb73d3da00cf546e9ef8a742b2031e7c898c2a1ec203cf1048106b1c2a15c67b771088c9c1e93233be1fcc6bd2b7cb283f353fdf69704de0904c4e767cfc0b4468b65a5161e5ad28c611bf56639a58e3379e1b6fe891bc11f847b6f64918c9d3cda5195fa99c65080e69eb688ba7b889de4331472544311084d2e4b0e2233c3bdf5b3273067b66ecbd5b0275971a3e0df35bbb3e2cf705d628430801b8e7b569e06de1998147607f21d624ab9cb3470a58c45a58595d5f662f92d7ba9fd8f1dd693bc0db6c70f5564ee35236048cf2bbd2a3e72c387018a0d43c46602f90308f782cc185c3072d187c0402db5f5c0cb258112736a1b23b767e5da761fbfeb3c325164e8a0a2b9bfb38b903bb7aef815292c64c45e57574e70cb9112558bd1a64f04c3e7c6c84efdab7bff813885260c07dfa541bd878a062e29383952f80da7a29fc02d2c59eb3173e739915b52c98da12760d70428a6ec571bf9072cccd0a746c1aef168a984f484353812e783b899542da982092858d88c345f68a275dcde4203605eebd1a102582a4a181a67ea18e99b3ecbfe3f0d4b1f825369c651acb451f1cb13e40b0b80d896bc617f861dc44d69e96e2bb1ca4443d0cd95262c211add79acd58fd4d7def11b5c7ba08041bbf529fb39485662c239dc547c31fdd0fc5dc7c0d0e4005e94817d8bf75ae1ceabbaf303a7cc971a933a92a16a79989657365173861ad701a9adcdbf70cd9cee8428ea9805950e3e34d582c0bf3e36a9868b1a1e2ef6f063133625fe70ee9944d976ffb3f5de5048b5b3cf1dae9870f7cddca06336fb261cbe61c23a57f2d60b84e67b8b9b2ba3bd7ef4e3f49455bb17f09a48947aa64faea38b8acbe6c0877225975b3927353d564796be2e275d95fc16f70485a37d5834d55594e37e967e77054c4e67627521d58c95bb9ffa0f5af4a2eb365854167ded8bc4ab8e95f63edeb3281fe51759c92654d47b1d60a7f35f643c438bbcfc408629b7287a8f16a82296f4838fbd9de9e4f2b94ffcb8281eca1d813a57ed418f436f9378d65c9ff7e73af2cf4082e0f0ea322ab593336d34ce02b26170818ce0e6641f8417babb652b356b3a7efed0f7173b735ceef22bf370bbbb01a3ab6f7617a54a3343d7ae4228b99dc49d77e1ff015cbd092f9114f7c8e6279aa790c8b9bd27677f847ea626f308692131a1eaa8b20bb4a9899cd99ed48c8fda2813c5ea69de425133f037601aca84addbe0495bf25f9ace540375f631a2e5766f97be96971a59fe1b3495faf1d9e83a31437563c9ec75c61f18b1abaa4892356ac88b40716c545db3f3cd10172a9d401369ee80f0b618f12b3254c7de7d07856b3dea6ca8814f47ada7ccd90171daa7cdff8ce06b8a61d6355ba901f3a0bd73c91e66b1cdf66fda9b7653e663bb207ea71e5e04fd95333eada3aebec6c60ec4de76634c96f26634d16eb0c868e98e3abe0d1da5c612ed03af4fb017fe122184a7d86a9da6624a014bc52c3a986afb5e657d41ea8cfa8624dcd9467870dabda963279cc2d5d344ec3d519e29a65b96afb9a8e9db2a57b8d70a1e87b6644d679e41f1e5a08af7d55bf9d2e93f6577de62d889df282d47ab5db6dc52a3d267fca7722dafd753136014e6a8143996b149f7579c00e6a318b509415d97fff2d426f708cefd819aaa7b140b39f838d482ecb863d47271f71b910f3322530d314452f9082eb5790df6a81514d47f7049c77f41e8a76c6d633345a9336c55f614cd972a1930a78cdf1635b3cf7b51bcb8e7600b33f8f377b7a9e8ec5877e11906af4ea2fa989b175071608c60f0401020375e6fcf7cfd6cd0c981e2e90c1d5b7248ea6000c0e8fe55442914adec6059d4be18531549bd14857eec4f50924f10adb8b042e69383a4bab4c5a3d70e375b8fbc8fa90170627fffe44c897ae4676dd8168b05363e70cf609aa6644fd5ddd72dc59a6ef1a905254ac428ebeb23704abda7588a9f072765f37ca1105305c6bc27794f9582d5bb04841505bd2b5a431fb8d2447f364e04cd1a639bc171f35691177c02f4142871eff221dbaee333a49572707a431c6c87d59044e0a70d56d7e07c239340d1099d0a0b2e38c5aba2daedd4336d8be87adc2d09652bf5cb29e0bd0735fd5f6bfb6e6ef4a3c3beddce3775f16c65023ead42a28d212a16a76716f84352b1ec3358d20d18992d065e3909f664e86eff8ba8039badfebc6fa121dab901f69a92944a10db4f36de21a4740b5d7d9a160a48e6525ee696c7edb49ced14593d23d97b29d4105458534b86412a4d432852e08a8fc8b9f853e6d6e976bb275c448150dcc73b3b6ea8d8b796b282be7dc080ef7761973f26b9fb0b96bea7fbcaf73515d94dd89ff6b43aa47481c301fade17b29c041670483dd5855c0eea97d4777ebf927ccad2675509ba5fcbb0844cc637bd98ad3777b4edecf265eb29261d376bbfc317c67dd93f920187efaf70c19a9e120d4e568ca39b66c564519c8f4d8cd14203efcf05b6bae753f8117b0ef3a43eb5685105e8f558348894bd68e7e5ad427bc8d207317eb9aa5ff9e58ed157879f3964440b287a5655f35987b3a21452c63899748fc7464e6536d219b64b4677d8f64db5a4bb98fd3752d1676c23e26eb242b8b63ad68bd6ef7da19e9e3f320c4c05b691792f7c9245333196550000a346251895a60ae5be8c6ea4b9d333c95825fb43ab5646191f55280bd10bff51425d8493afd0835f51e7f37f9e12ac183be6140972233d8e15c9824564b33cf835cc32a35d7e9054173237c48fbddef3da4265c8ebca699ab799ec1299f8b1cf5b1806b6cdb5d1362788c1ef42cb2fabfee0e1710f4c0c3d33d0b015b8a6b5260a674f1c5f53ac23b32b0c994b09d84d43de285c6d9d516de3871936562e82bfc0293f00d09c29bda8db098859eec5663f979aacac018a7f00618a5281dca558fe9f651383f50bdac29329e926f3493be0d43fb996b3d130eeae675d20b50dbef9ce7e0290f7728d78377d290accdc1b7af196ebd4216f6e262dacf444ada39be12a023299f5789c8585ba93030721023b79f7ef34e57d98f702bfdff5aa23dbaf765d1e8f82e2045a133ef8081d8decadc25f60c6c23f8e2b1a1df69ed4573ad023e9cc231e08ce273791dee3e98b85b44b58b4b6976d00eaf679041ae55ba85ea3ddbf5edbce24d7185e20bfd85542687b3ad7d271df8e618a81a6955a8a3904fb94f06bb5a6d9f1cc450a1009d36cb8047decb491ab88e0c00d7a6d9e9286d13ddc9c1496223827e5961f2e2affe1a00fb892ce19726dff21b462e48485aa76b516cb0683f0ef795010b97bbf6e7ec975b047b6b7a38f32a11037cbf4a5ea620e63b618c7a3287f902950109b90290390150e37f33f38d5e461c2f9afe2c75a809cabc044aeb8e06f713c9c57c813af5893ddeebc5f359db0eea1322cf05cc99ec75c3cb97495b3417f291773f281e0e4d2be8ba5902f9b075cf3e74c5b77191cf93b3ce034321cd8dfae32de3ce540e8a08834e59d8b4d65688b1705286569e786623152b86281d6b4dd9c74919be223467e087fa56b1ed2aec392977348d86cf0d25419a7a6ac4bbd29c484764cb534d37bb2dc3bb5b9a1a068c9199d819bb496839982449306077da0be6a18e759aadbd87645f5b6b0fcbdcd0923c5a66c7d7e662e37d89f0a01c020a51b20d54010be12de8fcaf92c94fb50aeaed5548e99a5308d94eb36e0d2e09075410ec3c7a6bcffbe05b78cc318f62336af961b3a6c86245d854e18fb3f799754f3aeaa6b6de67a463648fd3f7b4b8256a370095c2cb259225817d6c51484b6bda6653a22af861ae370ec956cfb2ab24cf59b24faef31b2e00a32806591933465dd6d66e102eb53fde89b45934e1138673e4fe540b7d4a9322a975484cd4494e76dc90350873bcc492e5b5fd6050fc3faf716d650ba21e6a6411ef16cd428c3dc67a951d57647e7c5b265a6031c49534f1c71426c38adc9042bbb56a31ed8a3bb49720d4ccd374fd3f3f7dabe912a951990873877f5be175eaa31e412d797c550a42fae55ebc39f8c343e2784e2f9493b71bde157db7abf67f890de24863924267678d17a4dce4ed6cbba9d4ab95fad751bd5f4601a0c84bd3887fa6c98935373ba3db892bb3457ee1b4c37e725297a5164ad598fa96d24534323e35092550f6941443fea5a1f65479c2e239ca7c8f0b8ec639813d41225893dcab70b852f268c0b47f452ca6d4c691d897f2aa260d0f49a4121e1a31a18da2c7778f42c829ba54f334f7b062db628737dfbef3858e44f8a42480f91eb50209b91eb01a0e02652c046b563ec4516af33e15302ae58f7c2609d15c423f7898fe9db9aa057b17355a9f57ea7d6f67492a68268426db271fe788c3f2733a57c066b058e5e407b88a64d79a411ba5af860364f22dd83c3fb79024cebb68a83d28a59f4ebcbc141bf9c5f83beae625ef95194004c1560b4a680f30b3f08bb5835d9a84079129e7da0cc822751aa40443da0bd0aebfe35d853095d332734e42c5391fc54b55e14274234ffb52d6fdb983a186cfa27a60a9f908666b6192cf040bc68f3c58406f01741f3033db639c3f1b71e4f76ef2bfd927675083aae177810644193d26893178d57aa56069b2f65543d4fe5847e903366ddda50871618cedb67b31ea963486148089c4e9fe83fc470592f57437231328ee2cb39213bf49144b7c0b6115fae82365e628649d5fe0070020735b376f4a0470119bb533f3e49cba14b674e46ccb8456ffbcae3c950043d4ff230d8cdfa72e44ab75c9f79839b819bb112cac2b2ab8c0f891dd56523a909d86132e13b834c29f0d66f9eed0de30034ecab2f04a63cb701d26d0bce0aa290edbea992e50e6eccc51cd36b684349f89f157ef92a44afecfa76ee894870c863c1b4067bb0e3b36b5c9e810ca84948751032dcbe902f948c1a096c9f3b1f0e16ca3d2110b8069239ec02b19b2180162aecfa85519fecdeac3739683c12bc4437e8fdc02c28420cf2a0a1b575ab1dab0a28aecc3e1e8ed269f4640a656bd34621d7c9e0181a5e8441363bb887c090fedf5f6a5acf78cb5e41e31762c9501e580700d716ba52bc57138f0a70eef33b97a703272eed8d03ff3c3ecf44f9c3a6459bf709a49fd9b0fb67af00e5957d956d6d667f6d7aa6db70afbed908db176d199827c50a43e53bf9aab8578725daa6b4e72740913782e658827444b7e91796fa7dfb91c7b366cc0792e1b677d889055a52ea4480337090dfe4dc12bb93ff051ebbdff98aeeddc08a1fc73715320cfbddafbf29e8195e0c1941b397fd354009fd07ae9eccdbc5b3f6eb36c37b1a5ef80ea1889518cf73c0bc143a02bee36d0113fdf233ac4a38af9c343bff5289debf7132367008c10118a7a460d9c57bea8b79d73f1b92ac57a46f5805a87316bc9c04d4f2493409e8c97591989dbcb0a35b7d6260c3403d04207546bbf7972b903f96e24c4d61742f0be83a5ca7167e50493042f07170d5f0ff8243a66b2e7a7ef38188204df3886f5fd543fc8d035990b151c3d8fae309c66076e3078d2bbd0ddae426aa3367a6555cef3c5f4d00865236d38af9d1e613d42d9cbd0f4f9126b08a4a8d1d98a9b06bc0823caf580799b21bf46b0a4b3d2ff3ff66a739e0d0b4456225d2ce804b5e00ebcaa054c26d0cefde2f73eb786730d58488c1706ea1cc97434133afc20d033f72c844bed0ae3cfffd59522bbecd5c3f246659b26daa41167b998e702961729f57d8e5c2476b541cf519358a17fe4e4e4349e4f19c5b153b0c5ca394d12ee536b3249b5b930ab32f97f80cb2f696af71e7691a46c996a49daf289c2d3fcd22075d99698bdeb343b1f7836d3b7e42c4e689b39bc238cfa51a2ee9e531e027d3c1a0a306ba0151bc17453d7830528467e047ae82089ef502e64e0fe3b2bcb4f5f81e181e9006e298ff8eec1f01e6cdf7a4e9aec96ebcc6e4160409285e6ae729a15f3c01438094d9835b026c96e22c0bc3ee048c324b1958efcbc2708538345c5be092ddc166678fa3bd60c05411a0849d2e1cf7b19f24793be47a6537d67d939fda49ae7a017f5b534b0a72c9e7bbae8593e9d2d54a0fef98d7b996c385d621ee64b79b7c6a7a60df9fc05bbe4003ddebe24e4d0666cc1c0ccf1045091d1816cbf33ca7d3a017e81cff96424c6a6a9a5017f0c1f5186adf22f6191af8a7ce59d1ece821c645e761d57d08ba07adfc29dd88681da875e55542858a2729b655ae7010d429822cece3737caac6a93fe6b4ddf25f1d80c9c21a7a9ba733330088c815b37076dfde0880f0e5f6ca7c61b47669223fc664c12e7d8867fd736a6c2d3dff3d8714a5fb48b72c65515efc3dddab731423a86d73ce7bd3713c33c224ffec3c6dd0717853ebfc6133e3356ca12d82a3409c55a8173b4d85cb30d49b3a38d1a2052b3bf1d943dc80e4781b19b488ddc91b29d1d99d54e6f8b5beb11e5c4d6986952a538be341e915bac7650e781e2026d698dc98229e48f13fa61e22d5a28554e7705e12af28e4bb825fcb554866db64ceb2e47819929b20b815b737dc17a5f5e22a1072ef05736ee7f060fa954d1c2ab5bd80c03d42067b236bbe9af61dd13a3de7340bb0008b755f1008ee021ea765ad8c458f1afc6868b12433fda2b46e1196ca50428044614dd9a09de44f7b34082860672ff640644361ea574a3332080a59c93dd5d469fca72c2fb5f0424e8d8c49d2ff99db95fb9c157bd203d6403fb71a5c6be3060d12966533975586b629a0f1b009a8a3c82843d61aa1eeeb36852f9dbb6e27046e2b110ea644545e2c6d8f8fd4b72a7b6966055997832338ea1f8c400bb437636b7a5faaf9ea21b061f2c7280f456895f1a57aa40d5cb3485c8a767317e71b90ff0a6cb4b8e8878c14476e0d8eef51923211e2cf86e89e724c89325a361ae914ec0c421bd6cc6df1844599b6fd7002964ed44d094bc9f8aca63ed19ee4deff11c28aff7140fb9bc664dd7c3bf545b819c238620f066e9607afa35473cc9e93db4000c5bc1f4612648aecd92e0f36b92f3303860008fe1fe906a382d053b07cbb200a079bf92f9c49e8c9c1968fd967f0e9d7a636493692e70f6d025ca6a92994b277ec74480be65a6e471d25ba50571d7e12182db8a0c22520ba632c9e41baa311fd7274ae5dc88c699e295a6a6a53051f47f2824175d5cff84b103edfc6dd4fb5e6fd636b9fc32c3ffabe0cee19c078bce431692ddbf9ad6995d62a40042f31f0cf75532e9e881ad343415e102d6d278174c4f61a29b86acbd55c5ff69d028ec84af59db0588dbb8403a669655c088ed365b95af1111fa091b8fffe1464729099c9f928f994bc3f3b0649f13d1447bc6df07db1d1747b3f3df6898b839a8fe720af65d5212492c48ba69c67360017bc263bdd42764414d384ceb2af844e4911d0efb49556e64597bbbdd991a2ade5eef6ad8acf03e532454d7218d74beb96fd8611baac2a652121feab8117bce9884a95dce366d4920ec77f45d96f75187c86b1f8b0c0167c39090331476312c403f4f1f4cb0fa93790f2bc4fd1a0850085f3284360b6d2540b3943a6ace0d824f6cd4ac7e6670c1e82c8ed4ffc6cc48e1eb3f0d0b8a5c015dc2bc7b33d56ba0abd8bbf019c64f564192c1ab37f225da6029be8f53988de7fff32a5fe7fd7b6eac80c8d95e162e172e078028a6279c8c2f3ce7e870d21297f7afb8c8c2e6d01b41b39d2875a2dcb396203a4b28cd2ad24e64f097358e264c9e8b5fe79fb2feef087a83a62ce7a7a2bcd948f820fd623e1238a3e341ed5f04d751a80f6f5acd1052a63e68ea0d223135a34854c12d0d8fa45b49a4f09393d91cd3fdb1890ccefc19ff17a13304034e35704ae5cd347fe8ab5e059660d0cf41b51eaeba48fa8af33482457330af73f3ce6efd7d28dd1fc1ad3d14c6beed03aa3fa1d262769fd519a363f936f07dbd62ba6551b9b80a2e208d578f62ab592f3632de26f793f9d892dad246d79a010c97fc54f555ba6f2dd597792e11c821a5bb16d14b842140d51a1a97f41efe8c75ee62aacf900bf0d8818f6d380106089c74917654e4dd0064b1e2d6f83d8cdfcb6cfcedf9434c0efd9094b4cb7e8eb7ebd3cd92548aee2e8e4356e877b694450c24b8a8f2f14120cf49cbea717e13c0dfbabf697b53281577cba32585bada696b39e581d2db302fd7522c73dc85ab726fcacbaf03176a498523010359d5eb933f0b6c7357d70612a58d25cd416c2bfadf663d3b661c56d2ad276e434d2308c68278bd0ae6a3d89524c374fa50384281fddcd5fe23a0a87f3dfb49077f04090da6e0303c05bc32630688f49f5817c674a591595557eb2098cede41a0a8ec767947c700d7cca88df5d02924e225e88a61bfb8dfadae36be1d784269feeb65ef1bacab7721a9569fa5783d774e07919f8ff84d5bd1f5c59acdaca60d938c1d679e98226d99201dd602e75dcccdb13291d2fe737e5c8301b6870c5e40c053e7a22fe75cb5e14cd9c9fad98ce110195305344ada5e704cd818f70970a954eadd7b815c5c17b376efcfe920f160dcf89b77ef65c216e168e1ce0d0de8996422787df3710d5715d5f620f485a73d9b367bab4854cdd5df6b12ca3e745d2877b0784ec756bf0f20fa387efac69c23d4808e6d54e04db6ae253ec6596ff6c8844ee709b5f621effbe178677f3b63b200d6099b8fb61faede777b532aaf3aee39e46db79a755b19ce44f12685b385c51db27849b7097e6602288ad1ba153367b51842e770aca061b1609c0a53491cb03a7c2ad3a87e13b77bd7444624d6293e14fdf1bf124cef5d60a94a7bb41520766c92718bda93ddcc55bc1a337bcf08f9128a437a3408a09390e49d8f61154c3afda5f944243541fd1d76c37c9d1044ad1d62e4753256a81a820752be28bcced8c9d0da82fff660ade9c506d3d4a196c5fbc69f12066b7cf3a0f12f14531291f2900ef92ef26b7455961c0b9d413b3cd26151a9f99a064ec0770891e8fe2e29f650890153b31fd6675e74a823634bb466f54bd992a92b6def2f21297f5d3189b8d24c3f8716f583d10f43cc2494c6a1949004de884a95907d7f45086158ec1a9ac43ba5d71024964b3d9b65973d398923ee1d15d2054e0ba1aea2c708904c834e61e561d8fe04ce4714043fe27aff33854443a63eec61d366c07402caafb79495a66de197a9ef523f628e86dfb4bf9487381ee4abfdc53666f2eefe8c24207bc2e723d393dfe5cff4b34ee7332a841335be7b9829cbe067ed48c7e9db07ad37047875be11e541312f812344ce76aedd9d9c7b3685b1b073159c191caf7a4d2951b69c50f0ce9eb0f76bce18313097a795de77657cc1bebd6096d5403533e74a03b1bca89c4151d6c67d7a3245b0e43aaac3fdfd883ebde29960b03e3a494e2024475cee75d346c5920d29677efe405082d8a48ee94289a0b7f9be450dada618b46877ce5a8718c6c371315caf483153d5ddb3ee8cec79980659c7ae91579551462ecf97c24cdac36e5a32569390899c68ff3ddb181ef0644ee63a540ec10c62c3d18d87440d2f7063b038fce6673321ca6cb422a149771de4d05c7306b06ac8eb85909e050e97594b1b6156c8e687e26fa8834e3a73a5f6c61855d476fa7efcb234b3d4376872134fb3f8b1d7f07c4e9309b1363bbac29dc93c22b63d69fc697b28662671551c66b1fb3a6ff47ac86851dfde7b837715aeae3c2d5f596992a1c76da62a96d3fc276cd4f023ddecbd5780a262203469813168bd97053c986cca1a0d30db91c1262c7d45b73dce2af5bb599912f6b0c789c3bac1f05d9d5d0814e5008f510262efaa232401bb51b28e1ebdeb53973c912f109081610b2705556a3d0e95041778d1ace11687ececab408135a9f2f0dc8711f25b3b14b1c045a93d0500db1c98c3063931dc202f97e0734c2d6f9bff88a5e90cac2f6ed9b0d8acc70f9a1fb8d60097f643a1ca69e4ad3111a3cb133cb98abb0c7376a0b308a13b6dd76f92f3f3ff85d8e3b12505376b1056db4471fea5f4e44da90a5cf606034b76029ced6bedaecfac5f3f7a553cb07ab3c78ef09c1dd2dddf8cf483a2ca78c601ab7c0606ba5fbe54e831afea03cc7e1769f4ed8cb526147357c96c1cc70785e2a51db6e0a1baf9ff8583db2e66c167122c83daf90cda1c5c3d380a9c0171d12bc495b7c0db6e6c1ad5f10937958aab618cb827b3516a0e7b6ac9065555cb8315b76423466d7f4fa9ad56f5d7368cb87429378ea76315d999d861956ac840db9f0d6177447f0e37741cc100ecd3ca74b4911b14bde53e3f774a5c5312308486025837f1d826e870ef398c468794de888a8ac7a3bc302ea3bba800267fd0099643c4af6f1d4e4f862c60b9c6d928c23dc89286de87f613d8eaccec83ebc522137ec108a74970312bb3cf84a5153b9de07a7d0189ca89a0eec965b4cdfd1fc6d82d2c46496dc9ac2533530dd527a32ddb219a12145dde485b61eef72de1135a69e21af0694ca02c70d473d5744ff3e3d2299bcdb8c69ddbd9ef4b3962f8ca5d586f1cd6cc26e5257fa4a972a13eb8ba0642772cdeb2e86a667230a0927d684dd866a7827ce4c01c02cf8f190a850343ec1204800769aa1fc045b4859948f2ba49be1fe672a7680284b9709a1643f4e097940fec2d5bb0ab7cdddfcc06edea497e2267c1b0a9f35fa248bef1a46c04a116f24fb2003baab6f3a697a2e0ee441a1c12871f948b43c282661f5cd7f133a575460615f7e8b1bccb62c037f48c61d1d51c22e14eb38ec198d3e755b151d94460cd05816bed6aa691f71f91b19efc27e1793110faa45200bc515d91adb1bede27976c199ff7865ed45716d304ecf43bdc26d7df4e40c27c8e6465c6d55698d18feb2ab7a0d96eda63e88899faeaba53956d0141045496d83e1e758ad8c871f77002cf1e88d29ff1459179a6db1ef5e4efe3bd9b42c0d5e65f7f6a6c862d2f6f4600ba33619b1db3f8f1f355507b0e81c3c73b954859e3ae097205bd1b0cdd934ecd2f61c428ef10cc843b202cf35936eda175bda5bfa4ad51b2a4e60451967068d69034557ec45c9e0dea915049ec93171862cdf5485c473ef544bc34c18b4310de236bd9a0516f4af4e359424a9fe4b1a002a9b622123337af895ff127a9048318d27a645b83fa17d48656c61a793133086b22e0d729e86b57315147bc2019de382d8d6034fe13e5ea893fe25beb9d3ff7e2caaf07327b3eedc61513328f03d965bc7d772f507cdfb204aae890991c4795d5184a952b3a518cf207e86d17fcfa703436b7965a4c4b65c9d26b31393e2409f70b68ef8d1c7111b51d3e81dbd577010501738b3e12c34aa138a8374ada2d54d52946c05ce16274199a0f5e8dc913edc3dcd62b38f5be296fb24048f3f9c7fe67412fb768f78c5f7d233c517eb9351bd58cb29da060cca12eeaca0381796f4dc3c42e698c3991594c31e08bb3a46faa738a880f13d65ef5b3b288f2f90f1321732a4445d9e88b7160d8b5c678f4a6b66515dab6e236ab25bd1d1ac7b2a1bc3510c106a035675d963886678db7964ba235d7bf1a183f42ba6c07ce9f7e500ef595d927e03bf096b401506b90f9a571f7f3a453efd74fbceef91b89237072f7ba1bef82368a5575995a9cf2166c1d0febef2e93ce3c8d125ae1303d197e2cd096176cbd5416a52ddfc14e69fa1731e546dbdb118db18fac8165179609a7ffb6ab65c80dad8f6c9a5c287de733a4395b528d4a7cdadc2d6102040372e2bd196efab181578ad00e6cc8dda3dd67ae7d1a10d5802b857440e82d795417eb69a17923eeff77ba47e448800bc4a374bd121e063ed1f5a84155773dcdfbd9556495ef5434d0af4174199ce328deed1c113ccfcb006dc0f5c9ba40f94b436dd080bb85de3d8e52e5c672a24b37e6afa75bd1176817700485d6d31d9953930e02688aad60b0a03f06762a1c41ea9f6b31fb0c4dca7b02a73364a51f27c02799df05b6d3800d4ce70770fe43d54ad52b9aea0ef3eea22f0c0873d01ffd5993292081d10fbdd060950e746dd97d3341e084ba7ca905ea2c3e7ccb19981ed4db447b7d693b69936de4c3db6ba2b468fae4f2dcb2bd6efc5539729cd0413077574157e26d53b26e67e0cd59b61e47f3f9ddd245520d215c0ef4dfcf43066973c3947428f219c547f612a34a8f8a213026b1749727ea02e2b32d392017f39783aed20dd87351d7cb195e25cbfb6a35c7cf6e73888ce24bad08bd06181fe4b00810950396f1074ccf1b87b018269817b0855e4a6ecca876f102ee73d5565bfa128984bd5faf308d7bbbfef8b36882bf4420ffa84051176ba0df71bc52174243be2e30f75b82d5b6c1ac9a3bacb968739fb6641923272de2f47696bd8bbae96c23b0046d2ffce68f5215137a1bb3c5f9b11493b6a27505c599221e15795e29283749c8d0101cb55822f373e2409642ed313d52339bc51cfae3c046d1879d68b862f28f92716882eba7c1c7e225d977a3a9be74d09f6a3b647a449958657d6485f24310bee034a76df600ae8634584914460af832279f4c4e5f93dba76bf070729fac354deb2355d44acfaa603d2f4261b61d77295628428bfa2c530a2c35f24f1d369fa4264198212ee661cb57730963d4cb3bd1bb0a67753de8ab566c6b567f6f57e440c181bdb968869c4e15d9b0868bf02c60e399d14f3e12d4e1c2bf6fe6d9de95972334128ee07f03b5582247649656c80a245f1176030feb79dd46fc979f3847bc2a82a4c1b61adb34bf0664dc7de33fef382208df0e70ea2b35b95824b38eec6443c32a608240e19287d9d9581a063d1bdeb2afce6d7d6fca5934db28c9640276b0fec1769abfcb8379ca575784aced3bd2c0a45cb4ec8ebf9ef42da3d0611435174886cfcfb1729aa0d86848fcaf7afc64f9eccada921eb150e8363c05fe2f48dce8692371cf15008c49f349db07d69c8975730354717c0f95b1ad991ed84e0f46dad90dee79222d1a03436d3e288359283e0c35f503c7a5646986f3108c45d2be0f7ff1dec7954b1bfaa242699531a6f6b81c07b3818b56343b958a14f0b9381b8c5fe2f342349b60a10d54119908d90b28516f4e50d495e9624d7b5c80e40fb8454f2be2cd322e8482f08470666673c59f180a7cca30b0ef33656dc8f2ccbff7c65eef2473e5aed8b96de30beb80e1a03be8eb987fb98abcffc0ab4cee68c563498cd0e7b1a306cc8a67ec78a7c54f7cee5b848147144b6b202072903886813d1c6c6917399cf7b8021399703b8154dd869b568f24100da2c82c61637d383945e6976a22d9534279d611f2d5409ab1477d7151f841b915e772f1c2c0d6a378ff798045471876e17a65669298b028bdbd6dcb800ac7ff7a80d3473d63ee1db25d25cf1c6c8b6f82ee03bc73d48daff478e9a175a17e85b90abcfb5970b9ef380561c7f57454622d94e601b3e73892479540d435c8c8f02e7863932fd61e8f9ca325f7b97ac8f63798804cbcbfe352910eaa8a27358309d8683825334f542517ed4f74d5f718b458c0518922099f44f898d2e0a6d242f8b77dffd69de172ea96fc20ba518dd613e9e26d0a9afb9d29d7cdc4ddd1d4e93e3a25f9d80cad2e054d85cd2f80899dbb23333b955b3757f07bbfeec0be3b2df0d85f065413b5d1a677f80d252ef8fefab9b7daadd042b7a344bc58a77d6d359923171c7b3103372f32a2f1ed92aec1cf2746b5625378044d2eb2bcdc4058b943150fef235f7cfb08ee38c24824ac3b0d5b7a015a589455404a71d0eb2c5ab4097703ed1c3f9a94b98eb558a58952b7929aa7206c353cc287bf41f7325413adcfc55057e965e43fd55fad0dccce615b66280d83a9f8a4765eb5ebc4bec5186b139d4dab061f3dd88d57139de546cd1be33843cb7a62170bbf8f8e131a6e6071e0751855d03d51adb4a5dfbba457feb4a7a5b04fb297cbc79625f342b5ff0d61308fb30943d756c3aefe7e7f901f0de46139a3f9329560d43fc6b3fc769353940a1c20723d3f6b885619dc6463cb0d01b2db9f6c79ef47653b94f406436710c7b93e2cf43909f24768ad6f755efccbeb0526ce42ee697be3fc56157f4e7cc4868b208dce6b48dc972d39c849d2dc0510051fa9fbc0bd7fc3f92f1fab9dd24877e966964498b400daff322465c988b2e0dff840206239cc8aecbaad6e157295de798263b8cb42de037dedb5749fc4da1e1099b003743cc16c8ea468333dd895cdc1ebf335f318f1df807b4b9c0cff60a74875b20cc958f04cf2f08a9aa73498ba13d8fc3443c10d9cc937afb971767d5c6545ae4ba1f184c7a66656a079f685830c657833894cc36a26db8544f6b064d699e7959b224ba7771737314ad715017def6afd66b443ec466cb08b90482ff4e0b90d1379f3c85375425e5ce41926439c099a01f3f6706b1e371bbccd00799eeefead62ac77038d62109c838ad06d42914ba864027594dcb3d1c0fb626adae411a9ca98c55405d7867ecfe2ede4598fad19668269d8d3caba3598624d97e9a5674503dcc28671c4179bebbbc70eb9bbcf31ac90f3098d201bf42c1bc81fa49e30f081976fdae25fc5e580d24ddca87abe14d6855356306f5140dd15269fa918b7c33fc730714487430d4bc1261f81855b1745b260347549365ade19f091aa8775097d4d893394d03146a9e88762a18b1f1e96b0276fa30e89de848184fd602394189a811d4f00f85d4f74822a3bf006823d30f21dd9bcff7c9dfda1395bddfa9a85e5444a8f9c0989587287a6d101b79bf8c12bf881c9a901e09fe5ad295815117db11314c07b101a9c39876acd5a5ceaebec33122e1257ce519f5ebc0c7d604abf4a5afc2dcb168300681d00d02d90ee60e9f2dd4abedc7da2ba421ff5842880b8af4b75a2a33c6b44768099f4ffcd09edb35d521f100f7bcf8d44389d118769bdfd91d95b43ec0db97286f591b2f6960ab7fbb186374e9eccec574ab86ac50c0000e5b942ade664cac0791c8003989ea0e67b2b777547f34ccdb2866a7b7f538acdedd8b2ccea064a641d4799eec2caf1d4420316e840193d42c1c915bcc1329fe6a1f6b87de698f88120c76c11bf26ff0b24fa3ceed82fc10dda80b88b240b3f3e3a8f85644b924728871a006e23f77f13eb229e23e15ed1925630844b1efa29308924addfe80bb56ae88f4cb2b14bf6811f0a08f21a2086130bd11d89827192bb8ca09d0f63027ccec8d4ee0a8c13922fc705463921b4c27128baccb8f96d29b7815e57c04cece33913fc2dfe2fa7374df4c012e719a3a973240480b047f90300a07c839dda9df063068005fc21057b169cba76864ebeb12333fff2d223709b22b665713490b92cc32d71189681c8944c66579cf1b9145ef3b6b03fd002ee3f9989cdeb82f528b0ae8974",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x4431c0cdeecefb6fd8a01f36b7f75ad57adfc82d14ddc71ae6ebcf798f48a089",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xc3314fd768bb68b986e80c0a14175f6f72630d7a",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374970",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xc16a876bbf85d2196b06664c28ec3cdc723d1a28cbd05ce404f4da1e9528d44f",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x5293f2bfa3b7571722cfc26d0d15328dde91f5ac5d8d897a2cb15f9de129771e",
|
|
+ "timestamp": "0x6ab8eeb7",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-anchor-20400496-baza",
|
|
+ "sursa": "2800-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa0626573752032362e342e302d616572652e312d643230333230312d7774613037f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b84104505e230fb6d2918a57aae684b899ce0f8f54968e8a77e969ee651381e08ab2414342b9b4c7027666feb35a082c5976cf7822d6fbe3557ae5522f8c6541a19f01b841f406a7aff86fa94c4b9ecf0618142bbe0204d3175b5e53c7a1500c23a7d75bd012fa7c478fd8cabb548bd950cf3e332a6cd2a1f2f4778e7cb5d73cad1673f9f900b8419d83daf4654d36cd577ed842bcd88a0ab979f2d8f9aaefc7cd39c0a8200ec0ec50e31cb5e89b9bcabcf9066cdf2f6fdcb822b71ca684d033a8185150a4b6806000b8415a9d262f63c30d25ef346c5f37df9bcf4d7802fdf1d1dcd8e7c0ca0155aaf94e49ed2a197a006ab37d10806e45d8a4e3e9a6368d2274de8f8dfadde7ea2af2f301b8419e80e0da7bbf96226a24f5e70c402a9c1de8cfad9580582a097d601f58be7441165591eee601bef5e74755490cdff2aa3f979ec9efd6a030ec6f3a104bb2475f01b8417310fcf2da058f6a350d285aa526fbacf024591f23eb370235a32808b62f733860d96983819c7ce426b6d6a8329f1c21764d7db3748520fb0b2a1bbae35cb49800b84143ede14692f2b39430b456b2acbd536cbf2ee0a59b9d23c0199d271c52be396b05e675c4464aed0018ef0737a40dab63a8f3bf71cd864fe951bef3e23907a85901",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x1e70ec75f3d3c93e0defde8323d57145a5ccf7e63e8b2706ccfa4ad3d6a947c8",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x5f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb0",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x13749ef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x14d2c5fe3c570164e1037e9613481d6f81bf44a452e4eb4be83e962e6af837f1",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x27bd060b0f5480ccecd03c9d01be38af18e509bd007c5581cb950d3f83496711",
|
|
+ "timestamp": "0x6ab8ef02",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa012ea6a0dbf02d43fe6b93add173512fdc80c642e774faf690a5f7b2754cbb4ea087a58cf8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b8413fc29bb277593cbacfe1c3f2da87e90c6e556b1f2f232fc6d95f8e3a6f5694d315ffaeafad11a95e35e6180e60c34f915ca6548a2f27b87ae0e0ce431b7ae7c500b84181e665fd48bc9b1a35c0f8701b75b2b283a21de8447841b2a7f47adffdc70edc375850f6b96d08d6b67cfd4067aa50096c2748195aa3091ee22fe8ad49637cb701b84112200b37bc4b16cbb94dd16cf07b8e153305bda917bf46aa6cf7f19c3f2d0764294079d373b9e190a8fca621681194123904b911557d25bb5dd9c48f287ff76301b84100b1d301b182bfd66f1eb1e42d6b5d5ee34a24ebb5fba13c7afa3552da328ed25d0303b3d830b62a4064e9bf1b5c50b1a62ce2094a4fd19cfe0c539e5dfc9c7201b841f989a8d3abf7bd4ddc2ab7e33526fd4ff162c5fa903f46a629b40671fef7792744942cb7512e4ca29b27a2072637a5dbfff718f6797ea49b7a6f7c058eefefa801b841d6502984577794c501d474c309a340ae8e776ee5d6d2160d01ac51821d1189ad6928b8274e9fa4defc5298c43d399d7c7a8fe869119b47e491552424bf899cce01b84137c5de79390df73db1f6d54e9e8611e9814a81ed38c7151c50e2e06a3b2bc2fa6556751920f73abf31bdfb05aff0a6806f2866fb36bd00f9f1571cfb454de4ef01fa012bd302fa012bcef902950180b90290392e8c81ce9e423012ab91f4bcd1ea2d9d6c1db470372353bcbc69484e05cd5d207b150128b06dd96912eed066c4b1708a76a633741e02b327f7cf0b2b5332b4681bfe85aab2a4bd96799834a1723d1eb45d14462e2ee081e6dbfc0af1ccd224b7692342d53374c687a1c889484fc676fb96a3bcaeec1dde802b37c9a43d3b51df14f313246bfbfd758758e9721c481cefba9a5088861a294d2ef086e0b86da7c2af77c0f9f34d6d30546125b70deab54fafb8adbe427b5a714b85cf12b7fb99d66cce9dbae65f6357859d0b674eedf2e84efa4e289fb82ec209882d5f25e714fa47c80a0f6d70fefeceffaac7c4c6f16114757e1040cd2c727db9a3405a345b5df39f21ec75104b8ed29f2eaae56f6485a24253c648ba426d2a1fc9315dfa34ddcef29a94d0c9eaf1b37e8c12dfe58452c73d304496b91a5f403a2c01958f17d999a5c51f8fc6975d2211467dc529325adfe2f3f4de5372e60d106c1f72c963ddb4f189a610c9a9925460c72077df45aa4a2f1564d7795eb5414946611c4234abb60a8679bb6ca32d89dfc3959c21e4fc35587aa7e7f2f66ae2c6f708e8edda9a147dcb62433868592eea508d3d2c7d3ddd35b2a25efd33059adb5dc934cdcf5ff6c349022223a52d80217b250ddad5685b88a458c165f6e2148fc679eee958f09164ddbaff2b595c71eeb1174e4ea08d2b50544a37f8eed0e1abaecfadda85c9dd8da2f6ff76106ad93564a33175ae63d76ab551c1c682d870798ace515851e58cc62b0b9ca4ee89b4ce5d1e89f29c5318aaa904abd6e732510e6272c8b8a5e3b30c637d7f397491bd89bb347916f6c1749f2112ea7a7d064559fffb913949b3b54c6465f3b8c7526c6446acc4accd0ec72751b5f2d0825a46d2b62b9def4b9657fdc8b930396c854abeac702a3d34f91eb50280b91eb01c85377255a083e05f2925b489201987b6a35b7d81839dbae2ea68da3d402d6d6d911d4c97cb4db56241c4e2267a30badb246efc8784023fc4bdb5e3cbd7dfb03555c7b50127ffd5de5c75a44470d522cb070a6be14643cc0d8c29366f073b670cdee5c785260695a89182c77047d53a56c8c1e4e238d20717c970afdec2e4618ff22fdba02178066693f68f63f48e773cf033db5d3d2fc6a8b678b0865b73090c5c835f51345ab09ad60a15e2dc402c2e91eb7d331dc30bca1af36f972ba2174e9e3910fd4ff81a859362419af1c6f5ee5845fb987dd8fd363179e069346644c548bafcaaefa5863c1554f36621a4882046f040e95c2b0e31690a41efd082a7e1efc1a6670da264c32faccc6c9249d461ec0b3461a5a6eb8e2b2b0cce783653ba3ae3328eee8fce432147c78d9e93e9861acf4972c4a33bc36b5230d7a456983dce82d5ba98a32a3c20020542af4caa3725e8e2370a71310847184b7fa39cabc90fcf0e9c8d9a214c90babc4d197449d329178b4bf99d627a2149221fe5bf5be6554f3d71c37890f109a3e414f70dfd0fea1030eedd91f5e08c63d1b7aabab744d9e34539c2fbae181fe8f17c5e7e911112251763c5379d7f24442280e3176ea0188f6265cc405089c5e775b9d14c196fde534b812ebb6c450c0dbf374ffbf5b3dc12c63086f4e826d0ee6d5605a9670b478fec509d13e82fe22e068d892037e3cad528048df41f8da85bcaf21dae6992aee7fb502cfdac9e1b0afff07cdef7c342a4f393d37481e83d1e1f3b6bc7aacaed22fb652a040ed7ee943c9b407c4ea0d43550ee855ca2cafc92c3565c9e4b19e9ea4c83cb343ad36d0d0b8759c7595d17d092fce6425395ead52c022fbc907ad63471423acd64241dcf568fb6777ef7258d400e74b86a47fbff3c8dfd576a6d0a6153e9ee235d7b4b408a489b0171abe2bfbb8bc60e8da855a877411266bee8cc7c80519c9d72b86ffe095710b36f0b5bebaf4ba723552e0af03cef6f75da9e0f57f23980bdc263e94a0bbf8e4889e042e29c66ca06f423bb3db85ff3a20588b84d9029c5ddce7a599b387074a457b75f0fa824379b1f80cbb5d2ddf12243915dbc4f570e79e47194fb5afa0806874d259f439155b2e4c5436c7e788ab52dae5a757f35889a80d1dff8fe4ebdeccee2789cb533023454d55830a6fae188180fb73281bce7c3ef6a4a92b74feaa13242c44eb134c34da5bf2d889e109cc43c71b01ccfbd246d47e5055c949ff72fa17d8511f40e3d31a320876a296c37fb6594d71a3577c88d7d9ce0bd91ce1a4f0ce300212b0df3fe3bb745c8b7f76649338c3c16f079fa32fa8d71fc507c594cf4cfea4c557eac2a33130a5f322454540961a56e3af10eedd0f3a53237f6cc81f20dc9b9265afd99542e02554993cc752174bf69bf2a1fab68589970be631afaea7ae5d1c5a1badd7259cb1449cc3924b782d5742107e2e285e4510f23c071249b2f555b9368c35ea567df0abc9e3e1c1dc9849f7632e52df2c478e000ecf70e5819986845b88c97ba0daf8eeffc575ad484dad0fb0fd4eed0c96c1f69dce9022a16fcd1c36adf0148f799f0554d2eeceef0e5787b2c3c537a79db8feb1e8b2c14134794fbdb3c42e817182fd8597586d6f0598f8c051fb6357ca01006e288d501013b4d5cc03037ad65fec89a0adf4d1b31621a3cc8943eee7e58fc0477cf586553c7d8669792279cfc2eba041fc3ecdd737d292be53739b7d97665ae2cff360d81717bfefd7286c7395c7b8dec071a244807b46e4ed2a89f10a949a16308e666b384010813b563f6ba75d10419827304e0d7757023b27e3483e328c3ef75e4022f39f68dd6b2de08ec368f327395eb0f53f219341b15b359d91d916f1527dd40acfadb1a18e1ae629793037451baa36783d9fa143cf55630adb5a0fdb5762bd24d92ce8e6d2cda2b25db16a9074fcb64612642860fe80a0f8c16ae603dbaf50364898fac77ab52f8865d9f806e69f474b51a7b163f314c900fe6dc12e9937542f9ea73243c1aa603c5a718a19e977ba1638a83a882cdbb73c711beb0380daff45ffd39ce55c93fee2f460ed3258179641637db96a9a838daa210496cf22f356f9235da2845cb71826e2acb39c670c95fcc903268212f409934b1754a5ac91984a76d81b62f52145aeafe1a34057dde8b2a3bbad54e128d0449e765aeef6ff86f7aadd6e40f7023e1fdf260bee710705cef97fc18a8a660c04925e24a843f300cdca8a10bff1f87bafe7118357f0706a79f82421df345db3ec5c795a6f2c8a869aee6eaba2fa5c251e33c71fd9643a66cfaa552a9ec3485914bd8f2eb134c29d795c32bf581d5e6a9dd1bf43f4eb7a2f9ff5b1ddecd338d92563b74e71ca9254818e848773b118592c6a522d7d4b6a98a95c0cb01102b04c5c7fbc2cd68a7bca2307a4a2c26c3bc3e0688cc1ffa33b5ea0f821ace1b48fa0514600dfeed228b4a704105bbab5c9c3d12936e63ce82395161dbf94e95603dba75171456217ea68146dc1e975a940e8dbf5eee3a48514f36c9a9d876303b1c0e9dfc122c65a339182b201f63a99063973b5f8b5e76a11d7830c871992198b92f4ca66b486d2ca99a678f7db452fce07f3097f531f685598c6a165020d8092b078be6001f77d127ed872095bd798ac69d0cdd5575ab216d69a979db989ac157d5d3eeeb8db8c4cc91a835dec53d0cb027705c34f8420ded7e9dd49de13ccf1883de98ae8ccfa8c3b581c7ee7f448c9cda7b1c2ca1df4a9e4fe436864d7f4bd1170f436a55f4c2d6ba80ed957282329d052b69673bb453a8e7178b78439902912ee30e7aa3457d4f72a19f527bbfaf4b0c2500cec4248800d073d370db847328c7156e02c009c1f9d2291d2b876e3d963773abe070f70a10829ec29b08c085713fe2e2b1c24b516d5ebe52694766d8dbb6bcfe8d3977a7151c6f58d50eacefa1628331fa5d7925285c0cf94f8ca6fa4a532d598658e55001f9ac93cfd6e7bd60f9d9c6c1d4980c8223b0e22a5d6bbe8815950fd2f1526195afc1ee4d8d7a7a545670dcf45eee08e50f9fb59ef3407e74df6053799b9e2eb443be69de821786a3a10fdcd58a57d566997a507951aab04375b4887957c8c85e77e3f59445ba1255fbf1483574566ed16f9bd4502bda3065001de3362c6d0d4d57d8300b6adbb5de4e5066201f94c82c6c13c5319eb75cc31285bb6e1420e7ddd21b349f043fb44bd0cadfd6e3891b76ee03404d69e1a3e8c2f3b12142f440dbe53160cc8c3747db8def571a1b928e4b7c8600428f76500f79afdb0a72244535f72a2926a27a75311e2889d3df68a6e366dd43db7f83d7c479f1af85b25718d908de8d603d67359d0d018f44165b866060e80b43a549ed80db917ed0197ed0d100af3a8da2e4d94fc8ded3d5614ecaaf08e194fc023b49a477fc6e6b05fb3b87340f7fa34a0db2a01482a2db008cb0aa35b09c03fa4a942c0d9b97d459999a5d52fb312245105a17f969841b2b0ac45cfd30a8fcb97e77b523fa4bf76098cc009239eb75df4c15b6c962b479e6ce0ba4cd12398705d67ba506e96c69fdd5697064a71f94c6b54a6b25d8cb618f89bcc3a1c4cafb9047bb3cefc74937f0c068cb4f2cbd9cfb76970462a16f5908d96019b2a74581fbecab83e0d9152ae73f6ad74845a2a88307088dbdc1b3347a11004431ad2593d75f2ef9d466edc2e60e88d559a5024e8c60fad423a2c0567ab36aedce6739e13d7be71c952c5dcc586245ac6bb48c6b547fc2b39cb0d02986839821c0e9d35dbf682934356d4af79556a38349bf3da1160446ee8b65315d5307e5438ba28b6a3e8b38441a391523384f65c848df7c9feb8fb3326d940011b9f01afbf897e7a765d4120ac611fb0507808b659ce2e37603b7d1d3aa03b2c26b6a717ea6d90417fbbbb1f2ec801b02f769a5268b74c083a95726270a1334c27346513ad334f6b9de1a2c8a7e4ad8749f076286a47a97d76fd5459515e656951624639b61bc693d8df7488c645d296cb796a90f01867ee39f5756e14101a16ff2f8c4de0e61dd1c5e7462fbb8d2f3d76322eb754bcc7eb0b0498516310b60e5b6b0ca02e5e9c1459bc31b1fd344e19923783ad5966bbaa576af8a51acfa0e8125823a85df523b7d84692e8c7385ce933ca128672523eacfb2544887f7bab24cd2691573acf83af42d701a0d804abb74b5602a22b4379220afeeab23a6a18d132a68800273294c80d073ed1a01a543411bf1ce31910f592d2669c872961535e5668ab3571afb04f66dfb62950d12f516c2958f43849de9d58c5fc2ceebab11f7532064de0823f6dd53e0d13d3035ec8ca0e5bb139a68da5c570036500311a50cd9e775ed47e987736255e0c8fca7254b626b43c6d7121522b2e65d6b71e3262f0ae53705313d42d5db30e89e6644d5578b806e74ab9407ca6bda946de39d049f64015307e11b4dc245e0eadcb469a41be8508253dfb391ef7ffa962b7331de013a74b5a9cf0ef7a728ab08ee69f61d507ab911894382f152b464ab182be115045de976fad97405a97591e096766dce086941af699af261702400d8088b442cc9a08e074df19be91a4e0ddd8c1fa0bdadb330828f416a6d71336353cac2060835c4a349a0b5dfa2d7cc0e1d0b738aa83aba331ec7d4706001e675bb0e74722cf4b0858d6c0b002a3e1ed83d48040de212e59c4fd9fa57b8fbb33a1c7afc6ff6c51ab4af3f7f19de385cd960651aba582112d66cb3038d4d8b89785aea9b11ee6225c2bfbd5764d59d09701292fe95c1ae3b4ba5437993515d8477d91da616470f4296acc1dc6520f091049f979a672b3863fb4f3130f63d301e53415fc7d3801d35f7f91192c07062c581e49b280fe9d568fab8a190edc522f1821ae0f50a5c6bab4d5ee1339f5cfe882d1fd89ff3dd8b61b5441e049d63af3985e19da85c2cc158816b254ee8ce96e071823db9fe9003f46ca603823f3382ce49703a9dfd5666beee60bcecb731ff412b447b379b2e6c3ec668a4bf619add37ccdc7814b72e746f1028c11dff2e3e47afa60a5236ee74a9ae2aa7d090022523fe74935e5e67410517f930166fe54db9a91eb7f5d685ed27100b5f6bd8a269123c7cddaabcb70f59afae0ac04c831d046e1eb977588c7b9aba72ef1fbfa8e7eb360ff26d8b765b6316e99950386eaca8c8af4ff6bc07e1131af40a243aa7448805b8d9fa166ea0f87d25512f37f41ce9f105984d9cbbd958002aec2d80920a8578d03b9dc885012b87036b342fd48b3bc48c7e018c15baa80ecf3bb1d6cbc52f382154d4cca0c01425dd3dac74b0322690d30ce97b5987a74d93b917fdd4c4afc1a639ac8d55571ef10b72a0a960c0c4ad2b5a443f443092efca58cd36df29c8515f8c2244b965f1afd757e6a6303632bb0164562dfd430090d34b91679c594d23fb82c350606fa0e26823ad0c63b8a99952c087628da459b8182ddaf382ca3eb71e3142bee84a168b5f901b49a28cce66639baa4d1affa677fa08eae9ebda2e666b5d5986dca5070146325c7db9deb9fa8123212887410570856cc4d872edde7b359697f6333963841b6af6135fab33ccfb5dd1b85b51554a382efa20cf744400f59a49234fab8a8ce50fbd6fe7f31ba55279e09c28a1e8e220c7d47235ca9a1abeccb9521f3ad963ef0efc3d86a4925284ea35aedbfc58cdafc45e99ce263dba4ed38a954d0e2973c8a3345738fd1e7d548e729feb2660ee7a671dc118cbd187d3fed09339eb04a714d4d2d6d609e486ed6d828705f3deaeb99ea1709af033c6d83d0a53368833cced5ef0e100f566d36a63d1e44059eacfc1bd461b5e2c4cb39129b94e1f7669fa2ae46630406a05c3f929228f2741301a94b6ff0bff27629da00ba05ae4f4d7c0dc80a0adcc52ff4f0601046ac737b39d969332dba28926d841313af30f3ba537246091bad5bf411df96bfc09d13cb7a3ac6e74849faee4a13f692a21e61ca70a0ddc6bae2f4b17772656f2f177a3b8d6c254f6c33357fc873d55d8024d549ff7a415b0f5302c00390f45f2d8f3b3a72eacd76348f87d6e0174aec602c3a271c2067cb11fc472db29b36edc4383bbf2942b85223d13737fb236f3094076d4620d20d5952485bac4a8c98c6caf81817d3faa23b8540fb200547b010922d9d34e8f42ca53187c5758deb405eb6e71b0707d71f1fd36db75d6a3a677837dc48f0346b63c520bdaab05102b09b78b670b5bf5ffff4fb3e4bc8ea11dc855a56541febaec79a4b17abdd47b4282e8c67cf77c84dc8d2a6da4bab97ca163df76e9557162d4130aac6c09648626b1570a42f3b6d112228c85c693371953671970ee02b2eae05dde2e5f3b3e766d2a2c9b307b26f423dcc46d552099877f3714975b09938540d9210361d5397efc63802f913d8a8cb764bc7ce8aab126afa4be6791ac2418608675b4c0dedc3e2334c7a38d8ee7a2b55474392bcb78e38956c1b1188e9148acfc30ef86677588a1ba976558c544dbaa6c2c051a9844d19edc162773f6ce8c6cb5f3bda9dffac29f375b973fa3acbb7d2e3d7b90405a66417d1d72bede5014b2d531bee7d75a3ead62986b9a76a6a5d39c2b68b7290f0219cc585735656a3237c01da5576f353122f1aa07a9d50d77152cf2a394d3f5bf63b9ce2ceded7e6004d35be00ac4f7a700d7d3e9ce625721a90dc104bf24c78b47ceb0a276e03c7983c3b6ec707b7b76a25f26bb06be709a4e8d0cfe137cc84ad789c517db54aa36200e2e3cf5bafbedd597f3fd920f8fddde83b209c8a84746208ac8b7330af311504335fc1aaabc517355fb70ba4a26589a12ad4adc39540185b8d8ee06a1f27f6a262fa83660cf67f2adb1ba78cf9f6fcc880a98a503934602fa0d5ee80808cee24fb43ecdf92d734f32b6ef93289d5ed27084702f755e7ec9eb6fcdd4204bf3b241484794183d3282412eea415a21919f04a19ff66ec857c94acbfb65d6b23c2a0a52237e3425d384263f72c31d6220075d4a5a802b174780ddbdbd15b0cc2db53bff3277975ded901dfcb0548cb0c3ae773825153b9ad93923aa4ebca84343c37925aebb34268211814dbd2fcc41a7eaa7c4a3cf7fde0a9c2592210306aff7ac50eda80072c162e54de426a8d39f8861b0ba12aa915d3097e5c1e231e44d72e013201e7b077d20848037c561f01de86f28a0ffb26986a50bd2d1840583c3c825e6d816e841e9ad1ef19feeb5091a845df6f59c514217a8a6a4c05eaeed9e547b9b2a829092fbf2ac3584791b1f5d5e8689d52ce496c03d96a5ad84be91c40138ed8e2487e2b4e57a26eb45a8b51667992a2de7d72829469228cb6807c571a2817c2160d89cd0ef02b6e4265070d07e2addd453633c96f281d924f18229fc810f731101e4b45221c2cbd0e77906eb64d6a0d8d3c3d68e13af33b47f4b1d6f691057960eaa05f5ed4f2966ecac186dbaf7dbc5b33648069d6eddeea1fa0b35a2e5967839ff0030c4530f1ba0e1a8ece8e3c222d6223db7134ab71bfbc224e79a5f6398790d9ff8d468eff305cebd3a904a39f802ad3cf69ce8e4ed2060939a6cb9a7d76c019c0b817ac8ea99f54f4349d86c3cdf1c839429895ceff43035e5acf8a7c305cdeb71ddf6bdf92d8a76f6c40679a101ff89d953397cab9ee5a49fc1fc186bc51916e03946bd2d3a960eaa8deebff3dbcc84e1b585355dda64d783300a053e556db9f68b9d8913a8a776d4c25c12d18f880d750ecff677d5874a63668ac07bb66989c48fd97a2ad9aa2bb2f880bb6ec7cd5dbe3e9b9efea28931cb8cceaab40d322c770e3314d48c25d44615947a547df7961dd29eaa7f08b7e3e0970c6ca0473ebfd8d53d75e3f71a1234f29b4a15a43c26b741d3229872fca495795854be02d03d9d216e639a1fba82e81abdd792b87e8902c4bcf75fe48d24c498034cb6e516ff88424e3cc05136d680b6866ba89dca8bd4a7701eea6f5727836843276f48908410accbd86a69e12a01d25d8c29fd58fce6ea03a6948b7b7bbd51726e2111332a5b57bf0236dbea4238b2291ed568cc7acedd2de6e274091b98c53777b27faa7e60d765c2db2147b3434fe3cea2b22103a9664dca2fd0baea4cd00258fb4ef43d488c75f4f568b8986ad784988a75c6554228a23c70491cfd17faf368c6d86d3ef02dc5f5873ec64899474cc8221f8b1955c4e134661da67b1e64e7817dc464f36f443dd297f7b48dffcc8bc5dc0152cbee780b755e1afa9629a3db6284f7b6be05ffa617efcf81688649544e850b9a03b9550fa9b9fbe22bb5c82b8799f66f1a07d48944f386e2cff4fbed1da12d88a523f3f3bb09f5eff13a3eef5fd0f6998d3e97db410a657cebbe7e56d5d9d7587bb66e0507a596e1a8eb08bbb7f6596a49ddbc5d792db7664aeaf408a257c1c248d73098517842c3b22ad78892be2da9d265f2d3b962f682ce2bffdbde561509112ff51ada752bcf7a5c2bf018f25c72a403073aff82144280e05ec9bc99ca1c2e35365d76ba9209f108c0428a3ed2e2aec29b438044c75316ff848d120eea3e78093f66c79217e16f6a54dd84f24dce8888bcceb413de8cc309d1db00887db04bbc575f06ac0457e16010fbb4cd0e103853669fb2aa1348fb640fc4bdb059848d334c6906931146d3eb64b5279fef1fed3b677718a10a5c829d5f8334e63d1e2ba6fc480d1efa102bf3aa82e91d3955fee9a999079ac3bb8f4fa373f7215c0f0d6219ebf8a117839798ef154bf9d5cbd64180f156cdf8addada87a5e03f36949b218c34caf0beacd5493c61274f3fa62184049dd7527dff55cd6f17487acba5fda16d773e0f9a550e41a64af4e48748c946475c52c58107b9811f980395c8f69544c58f8fe602f02ef6e68800b6632363bfa612a2d76fc2b29358dea070d5e7c36e9bab6104efe3cc934439f76d7d5e24ec2f92730bd721c541d5613adac6a268bcd279e1bf7781829c8c58624f1e85403105f4261d49ffe07f81c42eacdc4e5b7a1604244a570ff1e6a29a8688eeeb817dee2bb9f419625a62b4f9a9d95a4d264fe687adafb09e3795e0635b89be5f108af4895153f7cefa6be485574a6844ddb234cc46228b3a1e9b9c377008c41a01b3f1bf45fdd2d323b11337d81b339a5a6e0a865fc3b0297ff937d341ca315884400190fdde688a46a4c1e1f43d497dd6e200acdb758eac3c717e70b3f6326c71baaf27745d1c65376f94c4e6766a041b34fbf5b9a2b9bb1d6b000fa0a7f9168d33a81f3828aeacdb859078e00eb34b5d4a9c031b3e314ca60f8c6f2573a0ab36fe1f59fa28f87704f832ecb44638a67cd5689ce84d15ad173e8413c3c02dc069cd9e8df4a2349b744b6ebec23a2850c0f17e3832757068aade087e7e18713d2165bbd77525f71ffc2864a7e6b71563da869279410669702088747ddca9a670e28fabe4a2b0a3b78277023e8a609b94befd02ae6eb93b51e84283fb104b3b8053c9a3fcddc533244c678d3eba15aee907729bcf7593011280ce642b8d8ba27e4e1018cb598c3458a1e1a0dad1bed1b09edd0719bdefc7b45d2d20b6e6962b1e2a18b64ae179f59b32ca4c1d6e2459de14f39c2b50db6a5103d8bfa806b3b64faad8bdb1bed11a63ab47151ad515ef5e67b8cf471f619da82b1c879a234cc3df758ca65fc07858531038f90558c15f9e1f567e36b1dec8c9239529dd4ee48d61847a254bd25ce2108d30b88a04fa075369c4161ffaf5d65c74e2a4435bb37793f4eb5882aa1aa0202b00367c1c78d34d169d65e5b61c3ec227b58eaef2bf7e34f3a00e5ed66f48ab64a3d20be546d76b360a10f7c918f83f56b8ff8366c07f5414f5ed39e55459b718d34c9558a4082703fc8b98e3b49fe427ccd2e49fcf838737d98c37d0e0a465bd615d9f5cf3b633795f9d8e2a83f0112dbe3009b2e5c813fa6a5ffec44e67306896152c3d100ca114e8ca101d4f599ce55914f23d26e69b0ead74126ba7f7202d07aff3901e1c87f8b7acc58bf7b1fe15d1e15e3eeef0a2de0e57506c5c7a7def3dc88e8e327ecab2811940220f9703e4e8b250e225843793edf16a0fc99a87a60f5071ac97e1116ebe169dee4986b3afffb1fe25591f46b4ab512ea31f73ccaf3b5274a0ae56edb37a662b7a8c5773b7e53f4e0bd7538f7c235a69d738d0bcea996c2721a546c6fb2204f24ad6c0c80728478ec54174e82600763f24e5fb412065210551c6634acd1cc73221a66531e49fa7724b9155fd8124b2b5b8ef2f87feeed65c7df6226f27f927fc90f2f0504e279f7184d0a46235ad8e1eb6c58e990b0fd129925eef7c55c012f20eeb65ace9b422c53a62963d70be08561a003138f6cbd0ab4fb89534aeabb3dd157ef9aee2f026d48937a716f02cd49e45d21c6ba2acfac5f9c8eef8ca55295865a879c9fd9794d7e15c9077799901bd11f1001339cc5cc9f0cb24e1d71de8074f8853ac49f2ec04deede4f1d18e688fac91476733fbbdd30c3525a5756ca45c3c68e21f8eeeaceb4b1b79781f73250e9341638959a176e5f0f4cfee7db0660b0b50433fc14f6f2dfffc1613c4ac426d308d292ec342079871bb35997ef5dc71dc4a0718d1cf38178612848bac91fdd327cd8cb22e200e40482a9471a296a63262e13a96546df15f6a5221a303f43216dc89669beec13a8c0f575437e82ddfa6abec97d312c822d8fb282fba886af9f3d9c450f2ee49c42677fa072954088a3714c1fe02d80bff62239a864acd1ac4a7d357447ccf40cb966a871c04a22e90f1d7b579db36f5ca66fd49b7204ae432809ef9ecf188bb36d4476ca36db2b0e5bb6467ec1c12db744a2867ba54a60ada1647db18fd7375ff17fecbc0b90e618764b9130ddc2ede911d04acb0025727dd1241a5b70d8645074cef807b70839d2aff5064b9e9ae45a02d7d1ff1ace42b0dab4bc49b34a28a8558899b25ea47f45ce750fa2f8802ac9d78d699bdf7d4c81b74be6660111f077cf415fad81ae60015d1c7a23a6b9a26d6b9e19685d85604b66f310283d9c4a9372fea7b8a89d567216d534ce34e919b4e1e2263974bb299836f18107dfd4dac4809d14df902940101b9028f39150dc31f0ffadec27659d9cd17807424b70ef43b243405aae238c58cd68fbbc17c60a83c3e9c38288c8ed6b8467092449ec58595529935867da1d4d39b34193485a0776e5b21c531e92c87cb5b86b9d2f1087d1a91a18713e94afde0b040467cbbc71d2cf753a7cda5f5f50f57424493340fc6d22fdd9577d25b3a22d951657879dbeb9390b646e669117d7079d4be3d517110bfe98460d0318e1379bb638047104359fd8a45637c04cfd085a5ec0b80f1415b5943ccc85cbbd126436729d569a53c3927d213cdf96d654bb96e498b355582ffc078e973293ef4776fb954ad8c400216a7943d67ab14e6b14e9b0b3010824397adaa585e7e7378d93e7d3a3c0712c13b444f3474df1d16cc8f3bd906264f87da6e3eee9435df7010aa2a69e42cce43623446e752c8e993498e991644262769739d397f5f9312cf439bac7ceb3f524399d348831e2ce1e16861dc78f27d337e6469c7d890364f62cc23ec24df2c9f18af166fbbee99bd8dc57f11cfc4399d5d59564e0d5c5721e730b6719064d5144542cd0ae629043a56bcefcf94d8270b4fd658d77a9362418e6c85ecc22ab3e117b1a2341c636ba1f199165700269cbc3aa3d0da6e8c67b954c93ab8ed0e67be6a4f0df9184ebf9e6b0c4e534193a224aff1d6d05c5c3b720bc49f6f656de25cdbd424b1b1e5f6ae92b9d610c6347e8cc5b218d614b35ac4bf49176b6fc2da749306704a8f177345224c148c42290a5a27da8d646e1f0168295399a60ba7bf51f4ac730a21f8b753232aa469756f25ae7a77b5464655e0c438dbd9af177b74d47a7e3abc4c429ec2b87f5899a9dc6829d849b7de8dd6aac8e2d82af4bd04e7340ef71ed8d9a73bc67cc2207e18b78a5477e1972d85f1e24b667f6dd7dde7847e70ff6909904d1e1b6f374fb240f91eb50201b91eb0c70162acd37da38238bee2b088230815249e9337fc5219d6ff5b327149c10c66e020ab4314a3a0c3ab089ae6d2a9cde708020de10a8a161e57c9ff7e9e2a46aff8aade4383aa022fc8df5c8a255421d620ad1e2f436dc5bdfd6272f0b1fa3b603ebd555d327150e79a6d8eddfa021173c38022acf37189f403c0e2c747c82ddd9d6abbbe429f246778636f26b7073fb35a557c595b46a80ce7e910484d04e4a12ecd24829ecf3717946327ea981e4c46b8b446b26c2721599fd4a53ca7bca98a41c5f94474c3a3ad6f6b990fea4724d90249c905198f92b16db239078d3cedc66b2c7609a66b4ba997ac94512dc06da850e865921bf8f03963699404e90686b10fde4e3aeb254b9d476e74818d2b7b0923aa2e129802d052f61fb3066f0ae51c157251e03f01d2b2fa7b14e59380347dd2399f3cf22feffcf7da037df82551b98117835d3c32c5797b7c182d83c1ad554c19274f76c5f5702576d3b716400a574a60c241086d59cd7d1be526593c2e41edcb4431c31e6659e8fbc9a9b9416c9e82b68f6a8b547f40be592d1a63308a14ee33473666ee2bfc7ae67ca445d837bc1895aa3599d04e8294854440f7cf1977b5486bd5fd42a028ed30b6ebfeb3665326f50c270391a38f86d1f6c71fc3259e5c90498ced943a0af5bfe71e43a5a6dbb939caa2d2ee07c5bc6a1679951440a49850f123d31cd1770903b488455dd2a61c1cb3700a719034c1293d133a35d3b384e4c1948c6bc65da3596a8362e91776dc72236e0cd434c31a503c8bf01ad0080a2750877792133bea3dafe5f3dd6b31e6806d7136d481f51068edfb625a49559bad7178f42196d981d3580bedef494c372ad1b5496de157cfa36a175a9dd9e1d3bccd4009d3f27fe1ace96ebf01282527482174228fb5f299ab9cc0d7d5af5380c450f1c1a21a115e6c82b685f4e99c6d50fa90bb5c225719aab3194cc99f00239ef6833c02fea751303026de3c6827ccb08cc46a4c3ad68f51afc7851622c3d06d7713f41df7c4151b29570ab7e45e107c211c2067a95a122827e7f503f9b7028c17f006e80f63d60efd3f8f94e05c91f7921516cf3c39472eb65781cfbf4cd4089fff366fa55a2c7fc4e91388ff4969db8a84c7024c0a90cf03474de65aad7ba173536b1a5a81efa31c8490b1026b2ecea147430beaa12660322d7e4b92c110270e5c3b011389c4fd7379b09b580dfa0d7f6da610da87dbf95ab8fd63bcf3a41364b2ae588adfcde91d3a3f67656472bf0f7d9bd7b16b15d1a780787f09b0c60392f2542d8af96dfbb2a3e1629aa7ef5572f6a03fe79c5ca39e577acb822ffc97e7e75f3b602f1e512515afbc5ad68dfcc350ef457eadf64fb4beaeb021f99ced3a03cabf15d46d83197a89eefdbd3eaad55f7efdd134e9f6cad9598d89030b97367fb1e60f3a7bb0cbacd730e011ba207f9f22f0c9b4e0dcfb6be70de31ab48b6c9f1d2ae80869d28e3204e87ee3a4be9f977436ce2631897c9456404c9fe6d448af7313b418f37bb49dd384c9d0feeb1a5f7515cf1692487e14e067f3dfdecb49e98de647e33b46c5059002185c6938b0f1ae44d763d8e449d8e282de0cb27655832f83af1e7852c5b738585efb2dd5a6e34ed2b52ce5759a94381f89c33cd74d8beb193325a8e4a0c367839232cf1222687b3d52f9c2d63081d19375e1a2660c8a6ba41840ba85c2844d4011e6ba27cfb460bda8c696a9e9527cb33caf0e36fb1432d1f2d57930541a14c768a12a83d617527bc1d9e5bee6937a82d8c79da4edfa1d81a107c11f2c41a4898d5dbc92279a6561d31f1948627d0a1cd35c07820c540131f75c72cc5cecb8b806c5deb030f0e2f8dfe02aff5854ce2547124dc9037e8b2547a35a7b5ea082c4eb93b104663bd71cc2ba13e833e2f541c3d1e519ad2378110a75139fe138ec2d713354a654f6491fa7b0a331478d96fd684dae1c93b0dec5a03fd1e66415db6ed5ce51f04b2125082c7e1a78d6c82dcbc5b9c3fe969fb6243ad496a73dbb47613ca850a6d2997687f7225039ba9641a3b6c40337fe3ca3d322e9a814c426398904c2c92f2855ac268d38f0111dfeacf4d7af5e3464b2ede14f2dc793a28b377e51d4329d0102bb72b1afa57e134b699f67e8341a18a360e5d6782af9bf716ff4a8a6c9fbd5302433702e79806c2f45f11c0b66feb76b5bc7b4b12d3b44a92a2f4debb5a2c5f0c6deb86131077b97ac82ad41606eaaca4f19777052cc0b48dbae708220dbbc68cbf47fbf1a82784a43713f61e23b01fb4091b1ff7e7fca8ebb7fcc79a12d20fdee459572252babc85b6704a49cd0e7bb78fc3a2493976ccda224a457caca4b4f8f5f53243766ee784cc18627249c9e485735a7b78676d2546ed85b8b659430040cefd619f50e69564a15910a9c410ee529800c5541b8c67052f8f9cdd9bdf87d863a73e8f9a0c10d4f89c434b80536d6bb5b477fc7584164465d369052bfca106dc3dd25344589b7b75d7c0bdae7a9380a7cc0754ee12c4176c9a28fce8a1906715f07bf88ce997155ec7078f650f117c822c4a6477107e167f1e93ca0d7bb49399755c9874387c653584e9249ea6b05cb8f149580081dd9c0a3c91856c1a752ee11373b48af208f54d40f69f25e1d0de51a6b2512b5f98347a4f902a3bcc1abc355480ad8864666856fffa4d181924353b91b9ba6713774998ff6cd0f7380a888692970d141798faeaf39a34f0546faca8d8923b4acf8f15a62e532bde5ae1f6c0f270d957010d8dba9bdcfbf7670e0e9a6bc72b8cb27f7636409bdb412dbabf61f56e8b159d4b37a96a4a22273a22bc61884f118be713b729ad6c37051d75acec16407f2a6500f84761f26ef2e71267f330b59c7c4ae0576a305d772c56debee0a42a96e05aaa9cd5d1a2665e68322ae938c6bb534e19d69bc30045c121fc1b660baf349b913e6ea6a43008aebce2268c188aa70e96ac802cf34ecbcec9952b976151a2cdb370fb8b0b7269892923951ccf92b710afc387ba6b84ee2ebc8cc5060847e011a8fb9d878ecb504167464714b6ea704a3ead535a5fb2cad91c7c23b30940283daddf5c23f6bfd12fea1c8bd00b972848360afa739e38daefd627835b452ef07143f6ba52326e2fb81b82611e97d604f24d64b8d660f3d4dfa499f14a91f8d9ea8ba1bf12114233cce2e3386c9b84d575b5fb0f5273bceb956c866888cad0fe959af4dd0746cf1c871306b41f37c8a9bc237e4a39939c2dd69c374aa60024df8c25791f3050e946ee2c48cc75f7c5884024925a39d024debc9da50eaa15c8ffdad563f6ed2d5406b17a5245b591eba2e37a46785d7909002fec4871f0422d853a3f6b05eca1586f754448c52fdc2be44a57d50581647c65a748721ada4d5b510e412b92402a4a3b30fe93a48f1255d3f30b195ac575d32426c9d7763f4faa2a428750bc34c3f00a5c269c57df68a6b14a97c81dd47ef55121ff05ea2ce51c440bd9eb5fa64001a511c44d2607a24c3d642fe9c8a949a1e5e73fc253f2bd0d7a133ce108a18f9f49965a65f659684dbc982fb879376ed720545e08cc3fbc29037ddb95cbc6d21be02d0ba7a63f535eb8fd90b0fc45756efecae14d03f1882be778b0c12836956bc82ec4207fbc9059a2023ced8081e9cf773aa118d545e6fd7179f277fd270ff407afd7c431ba7cb207176bc548d0de9dac171e21bef64b68ccbb0ad6f4ae0ff0fbb6fb1d16f23968c6c8e8babf605415b2d661022296d86e1b663190ed837a25fec94db478743f1b32940f57e3c08d9748045256f8d947c03805a0a2b636c0e877cf3360dc55558c3ae24a7e4f7ab4d4902b978a2ecd24e15dc7b9417f1fd0f6d0521f5a4ba8d8816faf56352a57b0c22ad71bc28deef5054d9862c477012c709badff79f75d447ca3a84b1cdc0256c04d4e35a35bb027937b204831d5ce4b7bb203c30e4a055b24940f70e0ed39384a23a0ae191c5d816fb06ab9a9bb9dc099cd79c1ed7b44990a422b09babf2ac901e7fd9ff3e2f97a2c4debb6da61436d056e009c3a78ff0dbb49cdd0fe83aaaeffcdadb238319eb15f6020f00305c38fcf524a1f08a15f020458282786d40694db3a220085fd386ba766edabcd1f60e27a7503ccd0292d2f004b5c0bdc2e4e109b05978e5023986e02f63d73ce52be14ed15e3d574557082dc42d16492b71ee616a5bc2cf7f2bf0887faad658bba77cf1d570036c21b711f0e4fee9ee2e36f062121c72077531158998c28c7d3faa3c30706a6088075cf1a01be0b6fd27455abc75b585a8d884025a69ffb8de6bb3f9ad8d52fc9bf639677d0221d9fdfb79ba6a39838ae5b2b2e6d68a04a6cb7c3197b78198ee4a6cad0674a950277b7be23010dd5db23257999fce9422b50041fa0042a0e2df8ec5efc576ad1d5997e38c9e22db52df800ad0519834bbb6d36caba87fb1019fd4105aa96c9d2ca3c273d05b5432e8d11c62c9786f462602025647cf02e9b444c017b7c031f4237f035dd061d6ddf79a1f286fdd7eb55c34f9c729c41418e40f86fe4145f6af78db13554d8d63ac401127646fd07a91e53c804242764a6ccb12ad8ee3186585d292642c1e2464709563d69c034adeb9b2c1d4eba89b7a27ae5ded491d74273fef2e01086961459cf60288e1e40c4462f4fed789dbdea4d6271d2dd8bd7f8542907cdd5cec9768e6366bcdd8e98e33df8aface036948698b38cb4965444e557f8226a6438719bd63ccd269de080bb07fa0b4f7d34b9ce66da7426d3c523690b8899afc2b2e15bf032014a93243a67b543c5476064b7a805cf16e84d90abe1678b2eee575d376ad27c6ee212dd32dd3303d23a82a482d8ca99d52a884854cb5913010da2936d46b347c40a1767da7cfe306443f4357ee7460014bb284787ff512e7842043c1639f59169cf5e6faf676e7bc957cef555245ba357837170f5658eccfa4f9c2dc52640167b4eb0388546325c1a65370adec3003da75a113e02a018cc3eea8b7e8e4e349a1b537d9c04b846dedc315b1bd94408fd0a6f3545b413cd576577b02359993eab8c64442422487fe10e3b42a0e015e4e1b8ff57d9778642c41c94b8cddf061db3960e2599e7ecd6e7ee1cce16a99b753c543269242ab18f68e4602a64511d7357469b3ff0ad7b914aae257d6add2ba0b558d76114daa59033b5315f795f932aa1c97dda03dc3c0035bf5c355ec18699e37dc807aef0195d8e4966861fcd1615448fdcd005d0d4e28c9345ffdd69408af5e1dedf072191d250b7e36d2b438112d2d41fde3c518e02a36e883c9e26776f51f1073c921dd2f5946ca1533910afcbfa9eab5297fb6a1f70f48538634f4f23ef1cffbe05aaa95e7bfdcb3f1b738465414eba0d7d8ec28de583b93f5d6babe535477b19c619feac1af41bb40adcd0ee3d12ecb8fe55d6f4cf6a8814ded86795a06d15835eb9e93d53b7d53979fb2bd611c57a5a5d8c6186c9386229217903813b209bc2e34476f0dcbc80475178e48df46c254d3b92374128109b9b781cc5bef9faa9841dbcccd94543b2a8cca5ad8bb50b4a5a016349ce9648872efe31affff3a30f931b35eb9784ae8232041a58ac0260998d70f14f683754c4ee35e01b6178296239dd50f0d357d40750b99ae8a7b7def329021c4e3bc3ae43b5923f0985590c5c80c4e8a114472587edcd3c9c771060049afdd5b8be8b5a804f39fa6d1170dc266ca8040407c37213d08efd7d69d6dc7caa1ff3f758849d7cec6f5ea72da08cb938694ffeaba4b7dec85bbda9dd7bb6062c3e942a25b0f2750e8ffbae5cf5a152d60b1181d8342cc2e6e93ec3b1d56d375eec8778ee5ed9a099d09ccb0ecdc4f545e2154773626ef20a2253de7692067452d7c7d97722d90819dfacd2a7a3aa3c1ee5570a7bfb95b7299f0fdcf908b5fa6791abfcb28b3c734374841196c62ef0f24afdfa5df0c63640c6b1dbfdd5cfcd0c006f1d94476bade38d2b8fef53eb54368b82967ab734f60c0f861e72f22167eb0a5c4e3d925f9bfc3251566193e14cbf63715b712ad23d0d4ced66f5ecdd75652b02ca4132ac9ee02bddec4d081de03c589b588ea6aa24dffadf9596d087d9d0b5ec210ffbab97930718cd44b9adbc898d9e63d4f8a85fa1384b00b0f7429e249deb7803ae82155d406caface0c3805e58a9dcfc7759c2de03adfa4ba02c1212334377e6619463cb6184091d411b19fe1879e9f60e6e8245b1f0b7d2226e232bc345b2db1b7200003d0ad7a5f234ce89e40a9ddbf5b6815c8eb22ed97f841773ae4a7afdf27b800197ead190075ede57113984f849158aad7eed0b4cd3ed3622c77bd784dd4b0e2ed51c49cf3b5e00b46ed5a1af1e35de636fe11307bd98f281d25993e04996b24e1647fd28966f11af6b38e6c00ece63c4957e16f641744f0c03ed6c3799946e78e66b2fc56e29a8df14f381b789d60edd1ba7b2f9da4bfcbd0aef5a3563444e8c2dbad2ede10b40eb23771726d6ecf507fc723579e19db879df0b426f36bc27b1af343ac342dd035552842161198149455f70b50854ef340bee49460e2d1d8e24816c3405d3a86998d8929691adefa736786a5b24bd02f620199ceaa4f53b05f5447e317d247ab835aae00ce2062c49ad6d38d19c51a046e61f2b1f6e280582c37344b60fedd26e939f03f734864d2f32c27e75f39894d7ece9fe30bebe417033f30c62b7bba6f5e5e44bcc0a9fc1fa31cc1181bb4a6c919dd3ceed3c1a7e0817d58048d4927975ff0eb3a8d544caf7101a5a3ec454ffd763b796f784c8074c0350dd0bdc7efc82b9f9623fff3d973efd8a9f7b957384d697f33976eb96b2965aa7ccbc9efaea7fcd0cc81d65d8475dcece9d71b1391477192bcf6ed657c12769781a52cea828435ec4e65ad3e2d1d892673979ccb870624dc81d29bf77df43abeaf296988777974c03a4440295908fe6084d89f1d4eb1f43354365b5b5866ad8f70522f43237df028a371b3c751f55a9f7bcfba8c102fd832e7409ed3e9762bf201094533cf4fcd928e15f4960b1290fb7dd41eee5354d24445aef6b9fb3012670f3cfdd173296dece81d994e47f9178d01354698f7fa55d5349cec466ff6bfa17cf2ffab1db55014cfb7b82578ace8b5694fab7472f5911f99343fcdc29e11304aab23df7617f592dfd425d2439af143e019a0d71a177ba630740ed59c5e2c65eaa5eb048d279df998f92009a06217311c3aa6967fcdb4bbe9ecee2792a1fbc90dabfbb197df5765f1d2ccaf1949aba1bfb28db23b518a7b857e2500e1f212797a7e2c835699027011e007357f9c16399928cff1d1a92ca4a424da89793b3886c5a600fe1d8d6e17704c86b1822f3ade4cc3fdf9e509a649c71ee7a0f978170e4fef79660ff9d8fcabaa58ee76184dd0b35cbf9c7bb79c47e8cd0be4a070681f92b476434180797a78e9a0e3ab3f1784c765823dd3f386b6e1014058bd692c1258a20c8f50e52e2f7030baf60883d65349f38381bfc519d878be2d91d373eb03fab2beb511fa42007ad578861ac6d2a62beea16e7ea086eb6b194aaa885d7ef4c1af07a08b2a7ef8b7b202fb89e98eb2343fff3d9fea04f646d74f9e41323904dbd677f944c4f65cb153f4d47f5dd8308201fd98998125ce83fe42833727c412c1f05bfac2e022c0856736d539e8c440dd00d7c1f6d9bde3adc7cf5a303c044dbe4b6c5610379a3022d372b6d397235281205cb222ffccb456cf2e0cbdddc521e449216d2a3a731889278ab5c6bc1031f90df60431b7f06b2ae5c347054ee8f163a3933b51ed4d2ea2a69970167127cb007c59902e57638e8eeaf61292c688767bdc2fbe49b9bbe1d31b8cf005ad708231e4c3c3f900e75d27a082ab5a9ede73431db57af098899937809a3ee268c4fb23b1d24ad64d23d8b0e488b123907bc890539aaf185dedce410a1dfa1e53150a79148a881575d3a3ad155ee49a1b52636003a1e7ae4f501a75a3a511cfaee070c4c2ed0e9d658e2b7590108ac51523c13fc0c82259805da674f5d490c9dddf28072497713f701d30021809d2d0de438b779d2314c246f1e685283294150a06e42764e894286123898201756b3fb434058358c5f03a88c8e9503f74056b81c2b521a89e178ec9ba87977cf3b660278bdc046455492f933e80f66862605687ebd9d86a8ecfd82f10628c319788468c1bee2c0b70210c93000d19c60723b9a6f631016883132e9b7366d0b1fe1226bfa423371c7e53f55310744a70040039f09fd3ebad9369dd2f279f6408badc6613a9d9bdf17d53c591ea266ec13acba73b092746aa7deeb6e6d9728c6be1906187caa7a5d19d05e02e5a3f2e79de1b929f1bc0a4ade3ed2831ae53f1bae03ad0dbfa7c188d94af2db69f48d727f88083e75c617a7026fcf895e6339728a3562cc94244ed9c1fd54fba33377050fc5963177d3a306309aae247a0d322b0679dcfd4810487a979ac55e488a1a1058970d471da11706f1866b9fdf9c0b9b7a852e4d3ab51086687e53924a09833dcd521967883fe25fb9da4fb3126ad1ccc62ddc653e9c0ca461a96a1c090b99cc685f5af136ee6e9c294b41e04375ccdcfcac0e44d212b423aa409b88a6cbd491d2ad4f6696f478a417aebe380ded1d44dc245166df8ac1853ae498da3880cfef28ab8d00d78a116ecb1ecf05c5c2a5efc757dff2a3f5982e8214aae9656f30645767e33d96a142f01f0be2f8fea70e936390a33a41d8dd0dd5de91a4342f382302000ca135e7ab440f975c27f26a331a1b398ca99f547546014b3484e662923f8259fab60d0f0b3fc6938d32618ab075afd8c426565c8866b90342ec0c2a253b31c3dabae29ab3e6af94f5895b03582ae34423d1aa5ec5af3d5f1d169b6c9c224ade684aaf9933cbe99050fb25212a4225a9797909b2ba5e1fc9ed9fc76e8a8781a75a6b7508202392b78dd939fcc2e90f82fd8dad9c9d88a3ce00f553d5f7f90b3b5d817acfd2e3f47ab786c516a9059880cb4d663a41abf5570670fb01194f48e9be7d4e0ad35fdc4c9aaf54ab1e94d95efa3fb0dfb6ba3d400fe06ca6b06337c0920358d0a9af4a82ec371c0e23b02e806d58f8afd05564c413e19b737931862c4d1c6782b6092768df2415e20eb4b03d265bc2650e980da00c243c77be4066b28fa90748feaf551d39711c6b468c460694e2fdab613c8877d0b9ff7d582f11201b59986e67ac74a7eaeb948598e011bd0c178b917d79684ebc423408df8eab2f60f70aea14e4aca984ba7260eee46778392d4e140c76c50033bf7e18402dc1cfdf88c36b1d4b5db321f69ee14e57a1f2ef37ad98e48a9e34d900d2560188d78f1c1946a3e232419306067316245404ddba3e0cde050dc097c0673d811b447dfe95accce74572793814f9fb3d91496173e4de637997827c29d51110a8744bfdcf170003d460434f296b4f62c5053701cc5e3ce727e60bacb9d067192d4a649795d0e8774ef61cd5a49edbf84e843c4215e8c9526de224868e20a1c5408ac3f6a420bb2e0870a2ab2e1cc46200a5ce457c4c39b836723c98095f487b416be5100d50476b179e465284cd7f63001ecf92a381f0aa76a463fec1f4af01c948e29cd6c0f2a2e494c8b7e2bc37d89dea0ad9a06e7c68c06ee44ee75a8307a50b6395804543ee44587f690abb177fe40756711097cbbf4253af52a43467cc78a3a250383aa5eb5a53a213609d4f23707bece8fa8d7b7d5499201d164394a18deaf3580e9a1ece0f95a5635b649d2355b5f30351f402c0202e46e72923d72281ec2a0ebe4474002a737ff6135565f93f0b1c0649890a31378c51629b7d3ac60235625b6ebaefdc3860c801b8aed1cb5fe4857e9588009787481e84f60fe3038461c72dc7ca94db653ba7bc8f50bfff764f5eee1f05c66912ff205b6abed7e101c3e3d479619dbfd6ab7cc98e96659b1f06da7d28f8aed2d9ec3cb6ca0c0661e1b77df3ceedee2490d247cbdc5568a750e726f9ebeac34be2c84a0b0b80e61b96340343647b44fa6a5006d4471948125bde08e19f90f6eaf7226fcbb1caffa7aabc42910092c2ec18702d135e4992590be7a1e6ab0472bc449789a4b6ab9301d80f1cfb98774b1048e000b560ba3b0dd5d9f540e4949b78eed81d8e0442683078b1577e9527feac5bbeaa6f3c5ec0db1e2124a5782225024e5940fff615378ba7cf2b46d3eb85a9e45d65d34ad70ccc21085fbcf2e850f27b6ae0a95e5677f363f7b43124fc1fae8c4773384a59cf4f251614b0026cee8554b8bb0911ff1665d6077274c131f38d224ba8e75ecd09aba4d14b079fe23a93488c53a552d272ddc416c238bd010ba83f378bea0e9359fbcb88afc1c1591ba2597737bd83094c59174d37501274b5c797b2cff488e8ee52d4618681ab46f1a263ea8d49e6e39ff173674e342b0e5c5d5a7caace6a76a7dec60940dff9083ea609935d45a0be086248b48a5d3f72594e4a41241162ea7596c48b8c0d0e34b6bee2faffdba656f812893d19cdb99ece5d6bcc934550e88781a34655e73419d72310d8dbc0177b2787d96a35df1ed0ff5dd9a4b4471b1a3073d879d08183f636c19a04de655574d4126af40faaf8e53a220735e6e2c728c145102b7ce16be22fb35f8e63acb4d8ad0abbaf19f38825ff3abc4be50f5e8c8e00237ffa989a4ab3a9e4d2d6a75484866adf2f8012c6e5d5cc65378628c55a4897f21b1e27e0f0e15d65a8ad059f3973c27f31ec3393f1f84989e39834f7a2ec69763dc1d8e132b365270c91cc2a6003fa8c5af3204a9a62a7f10716bc42f64a4ba81694b9f0ad84d9f4d0f2a46e6ec196cefb2d4d9cdf6e453ff94e1290bab423d5d8536b792d125e803e5e349daf23016e438cc3809d29d044bd6774c4696e5416a05bc5447ea104017e787dc2a7e2ebe0ffa5fae76b0c1004b121da6720ee83f12d32741cfcf4ae8b4db72bb8acd349bf9dbcba9086d1e52b27e8201a74a70a4f671347d7c79711e7bed08bc9db44f455a1a9d70bf784155cf6eff4b01292c50b217741eab373dfe9985a608503a660a144a6edf684587714d1952f69dd4968af93baaee277e7e60ed1e9ea95af902980102b9029339fdc6c6c26cc041df1296725fb798ab24194a7551de6a621af38ae2aeac462c5d27c61df0917f547d4642f48681f14fd5db676933421c1367b47d9a5cb91bbccb184b7e8d19e932179c86c1951f859ba7822268e7ad5e5911b18cfbcb1c8c3add64cab7f9ac7771d34fe1a6e9e54e9aad3d104ca7b8bcd6a77f8fc0e705248a514f3478d9c6a517c41d338722687da2534aa9bccb7a9517526474a8de908dccb624433901afa803daf1258bd4dcc5273348c97788a2873177a664353aab52b1b62c373b0e0b26db0d1ce10bb13f83fae2414d1c6bf9c16bfa129a6632ecb3a7b1e48d099df6543cbf009239ebf53c96e1cceae9ba7912b64b70eee1974cfa52429c1b0195c9653288ba56ce5f7268f991b9205a9389cc3f54087eecfa23c3b96a8532b0567dd4513ac33e90e31bde5d570993b6c6e1945657758b2189ae1630aad9071148857771337721c6c70b516480cada08468903edb3d1d555e5fa9a62c3436f10222cfcc52b5ba407511c2ef8674a38e9d6a0669116ee3374fabcf04de30fd912b8c75109a86fa024469c62e431d218fdd6954b60a047d01f9490fb4a305ecbe9444492da612459093700ee3f74cd5e1caa2cf1ac1e6690b9e5f9f36c2e4faf27fa5ae2fa09669dbed3cea4473a171459ceb976f94a54cc553d257ffb35cb773f2b567fdbd69d10c799e1fbeffe366ecb8e6756633d65894b6e1b482eea832aa592ec6f3ebb1f73756f864e6e655352326773f10433b3a21d1701a167bbf7d27fc78140777b47ba39f8391438bf3972acce47425b7aea33066b4f214b71eb5f11ec312cea1101202c8255e8461928911145b916faaaa36b440ab61ed8c558a97bb3b393f4f1d9de474594400d12277c5198c451ac44f7096f63c9b845997e754a87838cc4a485ac9ec962b75c94f080f91eb50202b91eb09335472caa0210f36b0ce46881e59e1b6749c597d7de09a13e33407cc365555cce5e154406850938a84a2f5011f075b5cae26508888440f13b11b166dfcacb4f76f84197c02030ce69c9b37749f35a1d0d8a2cdf33986e267e2f1cd4d38752706ec5a97172f3cc72e01217ce6980e45fe85593f7b2e80bfa2bc00bd4ff2a5cdafa698668caae28d934d46efef5f8e89b727fb14c03c00c84b0e92b8ee5767f25a4dfecf88e782fcb6cb718c9eedc8a7b375661ce0f84e7fc85b6a1f399bb52c983ab32cc8ecb272ffbeec32438a3029dd3a3f4cbb4311eb99a5e1f80331ef9bd5d72110e030caad7eaf53a763242ad423eaa70f23e1d3a5e84c5c3d55cb0beef17bf0452b21e88c0172ecf141044717eb3c14eb695bda1177d3570e838868c6f3717ad73e05c8d1fbd3462a7e5717417557328988d2f47de4ff71fad08a3d6fa1fb8bdd3650f34ee30aba71c0df9555db7d6345d2709cc188e5471a508434aed800835b22daef5e065d08e05eace509649d74857ff9087bf40aed8631039bf50afc1d54baac16292540bd4a17ac7faed225187ec8d32e9f0b887984abb0ef5cda3faa422320bf118899fc08c2a62521ff85986aadd45186053d61013d71004ba8042b5fe601d96cddaf440fd9ef20d81b07768b5b4d29427cc72eda0e82124c51acbaeefa855961e629caeab9ca0c4b133954ff7f9bb8729e4be36db8468b36d70568a1d801297195ff1352bb17f771d31d0140eb8a53120264b6f6a55c58c4fe40f327103b45e0d47a45156a6054fd1237baa297d8aee0c6007901170b4adf463cf7e9a12828e0a381e83e8262aa7f948e9fdb1394a57d21b9dd7b932265eab415599e61ee3bae59fec67efe029d0c0878ccb73253ee691a1450fdedb910ab535978c242857dac0ce4abc330db4b693a59940fe78ff6aac78375d0bf2973aea5f1781a156be7fe08eec5ee1af0c22aef41a6867375f5130b121320ee2eb54d5d009f4d63e5d3c5eb7ca6e91f0704e84e47d76651baa6fe774f6a0318c6cfda3430e5700ab9e26d5fdb54bdca595748f8fdfe7651a08196c56ebec5a75ca37f814aa9bce53d305a08f5ccf3eae2b0bef390f4cb74f6fc057bab27d66ff559dc5d8bbf7519b405bd82e5ad56fe11262a66547f5d8da507066be889ea0f38e2510e93a0f5ed1f68060094be14ae60b0db853ea7596d42c802989b89afa5554b4e7c36d10a80c95aff9a95eb56908a11b4f630617a63607aeb6bf83a5886396727edb30aa4b25b77588e6641850cc3f37f6820e80addb97662c37bf0110816e17adc31e6a0cf8296d06801cb8d37a0e384f33e62adcc67654577e9bd9be8d3da7c59ee3603cc85c6c46ebbd383850febdf22f7e457b7a09eb99aa757d20d8d597c62f5da85540e88b18ca436253077d6a6715e28fbfa72d7117d41cf11ad24c8f439933af70183e79bd141c0d1a8bc78c88d8f86e791711a52bd8efbcff4ae3a8581946d10ad39246a63c157f95571026b11d6b90aca6553748068c2fd43f1811c4a40cca2c4e69e8071f6fbf4d6c430ddd78739474346c096747a5bc79b57b86b4ebf1bba2841ed902328fec6e3354343ae79a762cb7148d8c30a68fc45c956b1884e33041b7dbf35ff3d2920c4834ac37bebd53f1572645a41576d220bc3c7bbaed045aad06a0318bfa8aae47bde7f696176f73488ad7cd3458cbef7dee063606e50fd0bc92959d1d2522f0a196dda80300e19b5f864d663995991c7d569e9f75c18c6281831c1e1d2be066fca8c574b8c1aba52873cb201f02009dec9ab9ce0699b210933a0a8bbfd5f90d4570a2ebb8ee61b749c802f231fa06846a72184409ab846e02e78a0dba4702f8fbbc2d5a27176cfbc18dc35b3d912aa530c71ac1de2c8c324098c15866081f675ca561a2f788b187919c541fb3616edc92eed53e4d02b3477fecb167e73b33b114c9e4e1d5a2d2e1f7493157442d003b482e77f70220faaf64528ae7259b25a121849a01a08b34ce47d7e0515c5714938740c09ff486a55bf7026d6f2406ca990b08af1faf9167f84608f41009dc58b6a72ec3134dd655cb386ffbaf0f1777adf96d7045dfa07069160cabf60bcba0fc2736134834346027c4cae9620ad946c5e420aff3e25b5c4d791ac44400e3ebef0bdbf6b926dfc41332ea39e5b111912f7ff8d0ae3425cef595be3adb4231b7d95f61a1895d38cc7ffc7297189ab2068e3b5c2b5eaaf8d2aaa8045e49b3b9172bf0d81bcc96ce2bf9448391ebbb19304fe64e0ff2014cc569578444952e85a89db52d9b0fce8b4e4c51480e52c6712f1d102fcd4609f6ffe8dc054dfd382b709e9d03f9a1b7d920c210afd84999c251c8a1f404fe4aad87345486449f559ac20db3587a76b9b484ce52190b0346ae316a4b64d3e80b6350d54d8a25516127f09a9b57630a1b8576391e31a578674be0eac9a5f1ee10fdfe203416d49d170b02a253d24d5e6c1afd2949cf50445d3bcf4fbfedafa3f8ab8ea014434ac98ef43e5921510e365f97574d556e6a908068a6c3c19c8831993c8c96f9d97f1ab6f12e13b93ce7f64bc2d010a1fc1eb3eb79685d962c0d55542c71f2e597dde960cdfabce8c7d261eb34331fc92a9cb97a578fa5e24235bbb64868b8246ed2b39fcade0bc23402d32fcb430bf9f21de6393726a953294aeb2ee6b0f5e9c0ca54c67eea5ad217fa2e7f1c87c7c28de3ad0e9870fb41f816e6a03234b128207b5d076030920c6329705f4d050c7aa5b94672d75b7f21e1c3930fd93af56dffe6e7c1d790feeef236ba6c687e04011dd39878d478497ba888b862442411d5fa996b21e9ef3c404b3675b3cd3c0f13c4a6846a9a4ddcb119325c7376a8eab8e1c4d79c7daa39707497c5cbb17bac21e316bdd8fe2b73c0a833a5fce8450dffde3bb3332222af0d70f2ccca81e476b10f58328c106cd81cbc1a1bac5e04be193dd5a50e0663c275a131ea3f2c3924cb9edbd45e2449598c1d676754ce2f5273c7521d9679b67f93c144ac269e26fb45e711824f22a347f8e376d1127e723ad7bf1440c017b222b003ad92b06162120525bf186743cf71328ff7e0a61325252f7e232b600df0b80b76500756125f28c2cec703a2deceedcfa6429d1381b8dce5a7061d5b0135f5296b73e4b9fcda4568128b6a38f6cfda430670a0b2126b07b5e02ae644f49b4eab8c25d52e81012018e89a0128e9c555876e4ac5be331c7929071790fc78b8aee3777e9fcca8a75a63b1e986729d98d13cfa290f0a0ef2e5f87ba882c0170c1c78ed7be9b4b58fbdfbaf2167b644c2ad7b3a307acc2c99c3d99fe8d24eac5ec84c1804d4018f09f7ce6feb51b51fb6c3658b35d8d1f040fa0649833d38dadf5f30d229c631c4ab83cb1c5adcae3afc75dabbab770acf03dc1d440e07b88500b9ea919edaec59daa3ee3d96110033f4558e35246ffc547f2cdde955bfac3c57468561ab90f8ba1a1b00d5c080c9358c3976c3f224922112b6908c65e167f5062bddf44b2444b7ff8fede208dcdc3da380b4694d39f6e0993682e0bd81825e68f5910a73c952ae0bc48c3fa17050139251e3e6248199f7c071d4b11346c59e6263791620fc8a044ebcd424774a39c0692ac6b7228b04a64461a4472b0bc2a44bc70862baa786908e3a24bd2a928836ce153242c06b959c610cb971e1b85478c72148548471530d8ee8967e5fccf512956fdb109a21741306140765ad44615e9d18171c7ee0b6c804c1acd3daf161f6c1211b5dc5e81381d02b2b201c7d5aa2af39534403d4ea8c2c286264f005f7d94528a2c40dd686b3828c9952a119c7ab59edf97589169abeab1bb7da63700e18c7ceddbd6041894963a7d914abf6a4e6d898cd608b17ab504b8cb5e6c30b91409d1717f7abf982e2756f3d7aadb2cf8c6ec2daa2ffd1ad1bce7ccd34c64178cd3d2160e9790180b630bb48ac036c4713d6401b1f7114754dc321d5634d6bc734af13816d15e06342da64b78b92a2439f6b2bf69f8daa50ec9517a0fb9b4fad893356d146054a958be51143590ddd4bfa741fd7a8a1ecb72e391c9acc1af8e0c6e339c83d5ad8d88933259fbe58508ad586fa130cb29bcb1d9567c9e737a5e175a43e1206cdc5d176ad0a624d1e9162988b7765e9ee7eee649058a3e34dcce82696d09b57fd3056c11e1feea4df6761f449344b72fdb1121e5e3e988a444ab12cc7ba3b1e118aa1a2b6a3ecfe279bd3d54215b4974f8742c2188f9519b956202541e042fbfbaace9fd350cdb641826b9a87eeff9d292f70a65f45dccf43dea4d01ce37976385c5a783ec791b758f99f7b052be4e16d9a02074e2ed5553c8cf376fa6747fc707ba510a849843a529487b67fbe531f35f68f74dd71d4150185710f2408557d18878dea18249d57170b84802b66df55e42d2d558861a84d8f6d1ef6d6176183c690cf71e5d040b82d3930e903cba4597899dc94dedb2951a54eafe8b0d87d8ecea5ad51723f006465d06080c2720ed99d95ab5dda288ec16d97bc3156d5ef8fca14490935fa2ea2420f341b4a875642857b1739958b2992ab946760ca5cd44962532f290ca043f3dce21ae8d1c9651bfcffdb74ae749400e7f92ff412b8867a4c4ae1e6ed13ec31a4322eee44267e0cbdf1448ba2ed15ff5daa0c190ce1865427287bae69eefb13b1b50ec0a3c42003125edfba6e1a26d6920d133f64183b8555e602b0a1295f51b90a075c7861064ef641b2beaf96df35c83ac47bb6ee0e4b143e679937f076eb25b45644730d2e16020839b257ba9b70e27d51a700ffa22a87a0f1ecbfe0d09232918c4d0a44142dfbb78f228d458c060c5d1ad847beb66f44a6285a09409538d36ef3009847a8c057b0eccc8dc58e36a2c41ef425cb0a92bd4390292f50be11d32ef902238ef92ddddeef8d501a2d29afa46b4a803c7efe7c719d1b180ae996ac9b98224563d4aefa87abf4702eb668ff3a18b38395eeea39a2ac85e8a6d525ff31bf5b7ffb03581bc525ab003f5c3145285082a2135e014da973458eb7eb57b9334629bc7e47d19387b7a0aeef4f0e50f353e6781185a1d322d9327e3b148fbfaafb638f92ce461cb53a26e9d0d87f885aedc1df9610f6bcfeff3ee8f30aeb519ca78b3aca8cda41543ee7f524d6c68947cb77514ead0fb11c0dde2db7b201aad74c05202d75ed56adc95721c4ebde4fe5e836a8b123d2b0357f6d55df6c319dd36fad66a8fdd4fd4d114c9b627ab9bdfa431ec983ad1973d64cbb1aa47e1cad7a3bdef4bd71aed379735f9361a44ce043e6cb6bf97dacedfe008a36194d308727de2115d11fd6f791ca5e13b4a1d7716f8a234ee7cbd9d8dba68ec31b9ddbf3d6edb7546d4b1f93bc1c8a12d7751adfd244d0a2f15f97fa8e207293935539d5413a23c2097991307f25d81415c701ee375453a40a3bc328d89939847ca709683647b8c700e0f875aa78eb59638a3f94e4c3746d10a3c9b94ae766954b9422bac47d424c18e0b9f75a21048a4a0c1a73c8a6ebfaffcaf313451264d80b80c710818b21ddf332a2c737460a7341530f42ea803ce4953ba37f06b7264740b58b0cdb64ecbde2fbd498c883517768becf0c6954095c8e093d7aec2e63061cfca80002941bf51f16c5d738063a0c8a624dabab076f59b4c2ca2e30948cc722956165fc239401df40776642d4ebc407ffe423e3aa605e579cedbbce398fc889ac9bf63d38bf4dffb3912f13da5f7c934020bf7751301b58fd90fdce3d6d2c41ed1cd849ceba76ef8635efe8d8f82aba065e1b2773a3286de280c0a4216962efd8be5109a9c3e426b6560baa5b0f7f27a8a134e725405e11a7bfb4252c46d49bdcae0fef98e975f240bd3eb40bb09afd996d3c64aade6e673f36a3209a10b55a868962753193f02a48e30cc2c561d90b5e17d87b24c91abb29e74d82641764cd89d8e5f1babd30e2b10bc45ff06c239e2929b91d3952e24e151f08a297c66695eec54e5e3d38ac510930e287e5b971918863bde0c00b969d5605cc9735174bc608d2a6e246b31e1deffdf34bd81f4eaef998b52e68fc27d005c2a5d9bdf6423040ed464eb30435ea11e33bd074aae13ce44752e3f9ee979e4bc999cde01389cf52d727ecabcb41c87c9419dd82cd86feb3def422afbc3e8cea6e25af449e631d874210f025b8901e1a8b46773bd646beeaf49c492cf7e8b141532a4880be8088d32a3309a07b0bb19847a6d72ba1e6d6dd2ab1bda9715bb0629bf20181be5a8c15b5109e57a86d452638bab3b0e48d2c03ee41ac0f084d4c5bf7b06ec097c022786dd52e724e78cff21737e091b409fcf248b40d97c3982ecc2815bf469517f8813882964deab94f458f62d1873df0141c62eb1a064ab2121b94fdd0418090679eff3b5b5125f13fb15d8ab39023a422312c855e468ac33856c8a9a8fa2842739170974b0bafe438cb2984dff3ecea644304a9b5be16fe4c368411f4b97d057195e768bb8755386172f21836026f95e9fc4ebb6ecc723eb9ace5f2c743154c90da1c0348d772123bb6b350ab0cacb2d4e1c684a1eed8a229e2149eadd17f1bb32da3b5647fa036b055ca0b1d31e90a64df2a8b42783d313f47c115ec935b008773ee13e73e2b402adf2238aa2fe5dbb53be2a427588e274cdb37585ab1ea24ed8beed859e2710fb03a1b34bd2a73d98f3b192aac129d042e92a6b36fd2692735e439dcd329501eed870293b65181282afb4c3948e278139a9b9cf3f09fdcaa0d59444cfb2e7920a769fd18def7ec1fe720c26952480c238cb36a941ee9bda809f1dcb88320bb2dc0b8787f6476341da294e2cec3d3be8147859ddaa699cac341d325e7cd1da6d5eebf9c141d3c634e7845fa79ed3b3fc2cd2c541db9ba5bd355f9c53bc37bba35a0c44c1f75b44b2d60f6969af0ab8902962aa275b767312a5a1566efa1f458d1b4732bba134cb05f53cfa69fd61b3552f60c0eabc9aa2c80fb313c54f46d4d8af506ce9565c862c4ccfe7ce9cd5fc6b6dcfd0236114ca0dddc0d547fb5d3f1cf6d78ac10d89e8472a06c3412f130eb18a3d9d6a1b029858fd11e8746a6dcb222595342049c8482963d635ed16cb1eed043c8e8e17028e1f261ff2dffef0aa3cd19606455bb672245e1ad1a6e74e4cf50c8c9b81d9f4c2b4e4637d2dc248f6fa39e2e0f5b319b509c8cea22fefd5ae63aca893d503ddbb0f9585e451131b4645515865b7114c695bd7a9217b077a69d9fc1475b8e5dee5c3d05ee958eb99fc0fd0b08955441beb065bb84cdf5a3271752918406fa08ed6a3d8db4789d020c3a62ead69f7fd1e78a58ec8d372b61b93c35009d4e2b2c09b501820dbe5fb131aa948a336bad5a24f13838abf48e928c0d8d982fff7102dec5f96fe3ea41c6e6926ccdf1bf10cc7aabdd0f948a9f149ea4867c910bd7f3df2bfec55857483297f8766829bf8ebb4ba917a808cb9c38329f048337082774714c3f6ede46e6fbd67913c3d375d18ca7e11cc9f52a7bf23d0db7226f67e118f3c4975391853048936d79219c0575db009f915db0b3eb70f4feb9742c6908eac62daca94ccd56e414ae154a839009047ee75d2bd40f9600d47d92dc7ad2c4fb6e6e4eda17a071414c013048c814a788711b845fa36c4d2460ceffb50c1191fe27437a1675bfc7e6678d7e3b032587bca41d53e8af0f7416c55540fe75dbbf2583d1179fbf7da3fb2f448b84613cbae7cedc5a4262ef8b3165c5957495a302b259742ba9b0e868724987e66ee84d48fbdddd3934d64bb069cd64d4f2ba1f9964e38f3235429fad5763b0d081841a9ea5dede257403e4b2c89c2d17c622f676962288c43052e52a3a0267692207eaff729e1b92000a0c154b4c06daf3cb2bfdfd186617e53020065c910a58d06692476064ffd93467fa649fc8dce4ead563a4b9be6235392e741edf19cb79a7e05987a20ac6639aab198e48ecbd633ccb92d316d0d5976feef8fb037c12b9ce9d3e255e50a51b28fb2b8ca0991172ded53d4aa4855e039762597a8b0208b5aae02186a8822fb3de6739d8469733029162a34ab13f673e8f9c0d6c09e7da41307d342cb136a6eb1a4b9504780d3e2b9296817ea4334f07a8e05d26f0865f092abbc25ddb72e664c36bfcafa78f23fd9a5346c782fb6b211cae98f97f18e7225552446ebf7d1bac1f09957bc7ab4df53a7b67317c3427bdb8606876c233261db39cd8657f70eab4b298c1ab6250bbb13cd8ec69186ec2c256d098e441d46c564f008df797c422852dacfd6af630a8204ccd8abbb972244586a42aca1d760db4d95d165d49970ee48fbff2c9e579760ca5877ae0e46fd93a24f231b49938f38500fbbaefad1c4a3b711ea034f4b42f225abe98967028f35c1c925f9859099e16805d664284741c0c9043c28ffcaed3372ae81a4c9b2a805a05cf5c06cf55a64042b8835926204860ed740a20fed0d37c089ab33d9d0b0f3daa0dc3ed7f49af7284705f456966d03a5fcb5574086102cff9e71d25fa5586a24e6b857ff1d6381f6127b9ebb4551fa7ec7b31d5433ae7103d8f16ae1bea9dcf1f9bf764c3657f45aa8ac1135bd4dbf20348ec7605fb3263b47942ff5bb0ab234bfc78d9c9f57f0930acc951ebf9afe2333d925669662905964f7c6a17f0cce010e4a82713e1d81c113e80b505ec5f0febedf961784f60340943fd54e3ea3dc0ac6e8f3502dcc4d334aa8893b157a16a46b8d769df04c8098f0a65e1b24d53059d4a8e180bfe3147b93aedbe788dde25954b5cba2e820f19b81bf0fa06a664259cc1bb83df80e84d06b50cd9617e1fa272c80a5ef4f67879f9e4854a56490acc263e77c6a57319ea9e20d570bfd174e9b7fb3a22959fcfe4bf1252770e0483fb4c65de54c455a7af6e5db4c54ae167909d02171d70a8febcf521be2766ab0bd0fffd004f2be1eab80dc4791752cb0f0c3245b9cd4e1b73c1a600a8091bf09bda4f6dca22f7f73140b95f60037cbb079b33c900ca6dc06cfc71e947a21a12c4ea9b98c7c33e0b174dbe257d26707fd9dc4610d31f474124d86ea06fceebae75bb3be54b70d76c359d384b19c2b021948f6d6e9f731e0515001e28d0487913c07b9cb6cdcd40ea1ed273e1f40f46d90affef4ba6d1e25d18a0605d9866b9c68509fdb1aa70a8b1720f03a4c96ca5d91b75f9b5cc08e03f41034af8106f0a1cc38811a71faaf190ba19e3282744fb0d1d795b7a3a581e097a95013aa5f3924434673cdf88c71c328fbf745c4f0759e08c9e64fe5b344271d4dcd86fc742cca159b112e10a9942d5008f2c36235ac4581e1abeacb78e2446b8b1ca1c79b7489db2ada7f027b1e173ba37968e47b744ae551583fdae858c45cfa4e4f3469c2632ad0ae90520ce4816bdc5b944daa6b6ac0daf5d5e741cea3d728913e3235391ed9f4c21bfdd5d50906b3acc4d8259bc730f7b7112ae9bb422a87c7fb00a02b12b51bf2ff010a5cf8828fadd7bf17d0522713ea0ac9520319436255ae1017a39a8e64197b316500371759a60d2d1271478498a6c2e85616d7c68cd51419f06324ed12da09e41929c035ed975513ed398aac42ce5733c45cce61d46ae9a0d379c807e6eff97b10849703b42852d370fa22870aaaef5ce1cdc0a241f9ef7c9f5a7610ec0202a2fb51539a1a38c0d4464cb4c96690ace76e03bdc43adbe694c6f4b73642a95c42890be22f0794972d5ac03e7267f5ce1cd6ce4dfa7b17979e51c62739bfcf7b6cfcaff5bfa69e898b7959d5c04e7ddc213b4d7ec9aae3140b75f488dc43a6435e610947a6c911652a04421702c11b299e2e466d4f31a962a0f7d5132c5821c8e4534cdde1f690887fff5ce9a4706753552dfb1671dd150f6253cd698952b449a8a70a254fa9773e84c1a2100718b8dd4aa834062a8d83732be93456a2cd60f063c81795814553608bc64d90161140c5301193e452e6fb17c5d32065325c282f3903b5fd5ac3eb64216f645d2d3a8db55f99770eb9291310da5479b778342bd08fb4dfd2fcf75ba45501e95798f9fe042b143fadaba5040d986ac9709679dc86eeac2c5e95cc3ded03cc075721fd6eb315ac2e03cc441cb147fd8773f866c06da74d3fa674bff9efd7ac46a6d36de22a547fb4f2df3077468f94a42922416f30a889e2dc7e2705734fea58d108ad0cc49dc59d69a315f53bb8aa9d222e4ad57a50ab097b844c29b99672320a7965b7d93979526ff4bec278ab8629a39c3ca98dd4f05fb8d80a11108c917ca0ff23b3d27a504d521159afbc55da89ef061429e65061064ea011c8692868e3596a1f1ce8528b38c2cb880b112fb724b168f4b2a7a6ba0e5b6bd3fb673f46ec05d3e25505385b2d884093fd7bc396bd1f1a91e0753d95d7868659e9ad5d5c827db407bf2870789ebb0742ee90ddba5bd8d1dfd1b7fb8e78cbfbaa2b6b5edf6bf1a5d1943bacc915ca9267d88b913a041ad5e1439b46b648d4442c5942559af5470e725dd6c3b84e54a5e528cd3ec3a0cf71f29f64487cd19498df28ad22e620ba9b16dbe68ad4aee858fe5f714e0e29a74238b7d2e57538a680364040c150e471c8a746bcf53801657c7ff6b3fe9aee7911bb3aee17937701a120fe61d66d0a179d85211804b542a23b826c6aee21801ab6af12531e6b9b620a74757cc057834bf7bf4c84228d946c189ff6fb11cb1ee48ef432d6f2ad83c8d34c767bcc883c906fe80886aa1c203ade6ab95ed1e039928089bbbbf8764a0bc197321085fb594292ba1feb80e713b19185a8908b97cc9568b30e3ff8b721d12d0aed52843a272657d10c46479c8a17458750cd1f8f00dbe98eea02fbf2e4fd5930e93114184911f456652def5054bfb4744f44b1c92bfc8f9cbdefe279ef1a9d84d12ca20a626e43dc5713859d686972ff3d182b37ae146997b90418ec04419a2306a6a1340f512f76a4f6df50a54685bb4d7b1e880122de951cdc1559fa0a06099d8cf7c7eac98cada83c282e1bce0a369911f2968ac1c3f18f0689b25218d36d60c514456e49b5d00d23608118fa296aa334bf205e458bc72334b648d57df7e0a71f9409190573ed2b018ca24c8b61c7eb8f1a58ab8f5f902940103b9028f39772ebbf6438ca99ae1aab4cfa333436c54c54b73691a6752a26de8e328e36b00c10ab3856f3176a619feeda05c83a330bc6331b248b15e7b28cfa569205023566f3b0830f7e80fbdc3f4dde66f126513562b70d3142e2d24693ff3d6556d2569c048a02c7a8a2d2d1fa1c711224d03cf88b34fac6fa14cab5acc8dd512284414b9592a233c5e161ab287cf93d1c8b51c641be9a4aa1f4c145e58ecc8cd3c6779b0922f584aefee10be502927b9969fcf189fe1cb42b4fd179e8af2f356aa0acda6b47bf657e97d39dae2239db596314ce2461916a988d3c2544dfcda03688b3eadaa84ce8de1bb4d9a1dda4f526dc7fb27cbcb5b135ffe68d22d5edc830bb3d84694cd2a8accb0ba7eea7bc16d198c9c95028b320f266fceddf3bf5fabd7694699631f44dff5f8e1d7cbf49119eeadf24479b971a64b12ed0ce078d6c976b2cf9a6e52ed464ed0e8c3fc1914493d42283967c9c3964ae0cba2366b13ac77eff9e4e6b2ec56252c7b60901421083b10b9947efaaf51919d1f9ae9c6a0fc119412496c314c274f30c85f1a743562c536686908428c16863bf7425cc722ed1c6b1cc70ce52284cd3596a5dc2dfbf3a68c9ad3fb767fef88bcba59a14508fb702d90e83edb0d1574594176c495bc1bb5d78489816eda93c9be04c6271367ef8ae3314e529c9844fa4a522f81d3c2306a0206486657db2e266719675dfa6b04a57cfdf5d66d48725bf7a11312374550714dd73ea3e786b2f309235c5b311b6d34728f4f82921827de573f447beca885a7088101de52da854bedac449c9801a338596c5c2f272dd3c17553fa5d01c785ebd1a804f531e861dd5d7548f1e1a3ca9dfbf59f9ac98ac77b4ae628d22c57831e8018e6152ae57a36d07ed1af64138fc22e74d1c71589c6239a3d8aef11fec620f91eb50203b91eb06bebd17996c38b1a461d599d6a6c98095637d80b06fbeb9318bf155cf2d54e9245aff73462adf0726173b4ed2a561d4047940bf5f0316f1bd5200a51d6b86be11c0b0b7dde16ce6824f78167c44c9d2e4dc0a75dd185668a63594c2bf71fcd418f04a2077242c1bd37a77cba1b051987e3c4654f347b333cb389fd1898899f293bd5dee176026df973add3891b195cc728c8a90be65fcb318d0ee6f10334f9a0668ac5b16d3c5965f5f59d0bd2c27402a3882c5b8fb92a1461ba9f251317c6a9ea2b1cb3146850be83fc75a79072fff6853a7871636fa38dd43832bcf0962787819e9d0908b522240dfcdf7c8bcdc6b6df27b909c6b95307b24fa6085936b665afa92373234599c7ea7dd67ce2d71a1c14fa399f6d09b14c129b14cb3ced91dca7576acf3c5f89bc3d3ae934ec3b1d9b6d2a4ce750747f8c05a49c56ca141a97eea10e44bf25b221f9532c90bdbe4f2bf0e3f006ea875f0299804b631b5a9b35dd68bbd31293271b8d49a81b972fdb86917c845b34e12bbf4b22edd34473c7a5c961ce85394baf6d8cb685d23b14fdcafd379e6d0fc2ebecc01671e4674f4b02086d0cc99deb91dfdd6fe61f3694c35990677107d30d46bd1b11c823679d1afcaf5133ef7f6d4762b135376122a338d88751af65c7ae2239f5f3b1ea75d575477e5650173a739e7280d3c451e38c984800ea8b49268293049a6e101044b8d084024291984d09518ff8040696aaf1a087223c29310212358edce7229361eea54d6cbd39be776b49e7e04bd1b1add106fed9abaf386685831bec6689bf57b442f0e559d649644d7cdbc0463e0b9eb7982b9a41380cda5868685e3111efc18f77789b4979c13b559a1c3ea0ad128ab85bc55ea90d8c86635896f469c64decd3085b1e32fac2e4adcb26d3c06dfdc22cfd0acd6f46b7b84d480ba5319dea5aa49e2c6dd8cc514d19e7a7da467e8e91998cbcd6854a31dce34abb6744c4742fef8a378c288285aee4c64127a351d0e7a5bfc7fc0333c45672f571b294e21d0128dabdb117908d31a68205ce96c2fd60575816f2f610c5dc09c4ccec1c0f6d4980f6f85ecfbaf2d24622396f9f54571aa80c9c5e23d890733e41138475b9e70e7ba0df76b553d1144f4da96cfe978bb15146d9e1322c7469cc6af5a97697e48b61bb73f7e8d3f6b32fddd9acd13c2dc73e5008a389f23764ce88429a4464466bce2ed84381e5075197df99d543f861e9e7697b69d80571c07a986675bce3783d267f4fab0a1c8da0c48c3005316629fff2da19271f2f564b20b9089d099bffd4fdd598c32494d0ec0da991fe6aeec770621cba6c419edbd9df2280f1db6efea3b8746a3daa4c6fd0204af9fcff342cab10f612bf5a614dbed067a34e70fc8a2d62b74f2b6c8ecdc9bc4ce067497589462750c59015b7e1dea30b0936df54166be64bfc6a41b9f5b38f21c60c9b18bb362782891a97e0d73f98a2be0500eaad474bdfbed3fa2d15fcb78d16a35b0e509fb579530344db8002fc323b0b80e01540a983928a7151ddbbcff122091377c2ebae9bb5844f39b53b3d2e839b43595def00c2da45d5f2ed0dad42ece4f5b3170beb9cb4e891c496eeef2aa7a53af97460f8bef59e00c92e8faf4704a3735a6dedbeb240af9b547f6a77549165577e14419c625b24b860ede360c05d34c242af66bfa8d206d52e234004c9dda291d99508ac42990649965303b5d2e10d3b94b3e29482ca284b7b474cc29a90ba5ea2068ad2fa50c07a4a2dc3c725cd0fc584827f91197dcfc07ee83f7ee0c2ef6e91bff937d2f8f3868dfedd16a8c4eb7e7adfc8481c58a2ae564661463b135ca1174464d2a56a28794becccd4b4b949bb5bc8f426eb8c4df4aa587d586a601f4c2cec4058be0c3353c42caaf0ef1c7aadff4f1671eb5c313f74bd27ce9135c5e8b1cd1184a35ae4d6d0ca5e5fb82e8f336dd04c20b0a459a514f307777e1fed439495ca98c3cc5b85ca9734ea0c3c4146f98e5ddb609e4d9f0cffaf6e19c2eb0e3975d83a51f6017fb472c27fa2bbdf448077a66d0d0e24b51a67e84768f5a9cd5bd3456527e427b1bf5ee7baa45d80411ec6d532af485c6fe9871cff8528261d7b9660654e7e7078956029f7f1d337aff5901d1c195f3e3e255635b4e572b41d5c51128fbedce6a241b0a734724477208b97d3d8d55d2d735857b73f5f8faa51ade7d73a8618f2cae2d020a571390ce58d7fe52775bfe7d1f9163ddb9db4234db8c3eaa66179ed9070b3f7a81bbe08188b127b6c7a51e9e14f09486547a322e3c2796544496429e4d92b9fe072e07b4ee97901771c900f80fc2e56eff0902c8210a070b70affc1cbd309097fcdfcf95470a1f7755c58a7dd17674745fd68eeeb3aac589604519aedd62d3aa7a7556e3742432af8593b6930a5f7b77e9d90e1c88b83c385bd1ab79bd4336c6589fc42bc1e819deaa64106268a400ab883aa541b2a8b58d67366c89c243e83d920edba270ab25c257cd0888461c6aea1aff2d329932b6d99890ed6e8b4cc19385855efd6de6124fcb2a4f8942e14e67bafccbff927aeb05e39b2fc7e933f19bf7c43b44dcb0ff732b66b12a9e2a332848e4cfb56a1c2377418b56f77b873ec4df358913b2b216784662f247a8a6ea47ce506aa068fde73d40da8c09934f3bc125c1446835b915fd1a7817812b4051607b84f3419eb873b7d4eded8a022582c19d5c0f0626e642e28ae6d888a214c9e5076b6f5e870555aa224afbaf87d42dbc148ce58b4ee281e21c45cec138333071172b050fd7af674eacda4ed43479ebfa19117839798bb7dfffacde1e22fcf70ac23367cb754e7b65e779d7e0aaf25521b7aab1c8d6772bd5471e202ef5ea40ab3c8723dc889f1907144a8e57c672c9e1ecfcde0802cd85f9534e6d34bb90453d445125ef6b31fda4afab620c8d3584e923538afe0cde567bc021cde486738cb165e59e9c28b2221d57526cd68e004afce18100f004b71d0b7ece743d4b12250cd1b4fc1ac347c0988c7b521640e7b4028c213f7d0e44f2e3f03c0d86b7facb26f0fe125351a293b6af9bcef1d7a260c5cdbfbaa84f88a2e22acfd3c9f9967ac15c0765e90ff52927ff8859f33d8fb5b05e5d605f04310d61e27f555469c1f92f6e288e1ec14ec84c754c704505b48bcc0370752611022333bc629fec36ae243ccb4680fa96a174d56c451c3c23b428dd58709980490e2a9774fd7bffbe909b9131a4f4673f517cf1f45a6a675e3a196a8b97801f3fbb23097bf521eeab9ceaefe41214423b725ac1079ce9bcb9290082d07c67cbff884e61408f9e13e69973f7c25e93901cfe1da96e5033ce4d7226b83bf78f3aab3bd7adacef3f8aa90f91040c1a8bc6411b30e4ee249754556b141fa700b646d7cc73291e49d58ca18f258be9a2f8d1d2ac9418e425748ec8179c44615ce22fc69786b71de6c19d319ceda0625900d18f7345803b324389f8b0d86e1c180034f958982d419824d43a57ee3727d4b7b38984c39b0d2d2e52b912ed0b34a34f65b9f889320ad95a50eb203e2f94c6b3a0dac49a88d3bd3cdbd0667c27c5ccb35c5fc00fafb56c25683d5b839611a66b925dd7ff61ebcdcba133ecc7a46e5fca9c62fe818e32e1bb91f3b2e5ea203a1890f9a1bf37aa0e5885bddb5f0365d383866f32baa389ca5a23c49bbae02686e6a9f3f88ad001bccb2905d24e009f7f168df4609e8548d8d59cdcaa0de436dd47fb1b4ea127eed2c9e430b23b448a957d6ef3a203cc87f762b7b845fab488a4f2136da6c0acba06254a342472e9a75070aee7560bed4a52be7b3b7773874d3e9ad911765eb6a8e02cadba22774c4f083a2f80b4416a8beaf3e185470ca7966dd52dbf876d1206ec57fd9646b50edbc114b774d389282cda8ae642752d992cf40785677b152d2c6c9d6f8b09001a9d59f19b6d4b5a5908f85e0f7dca65c0718cc203ed2a8f4b576b96a97cdd2b37f3e174538026a42bb906900e060fd1444def16763385eacfa9aa7d7e4b8a9c8ae35cb09e8bedcff5389caeba690ecfb118b61a68d2d9641065cacad6296a75cf04c4da7af4aafeaaae30a7260614098e987701c77632d826d30dc0fd33654478ce0c643550f1bcf2d8fe76ef0093730af508b52154132064db74aed0dbc71eac16212ceb72cf7316fba7a6c6895966118fe245ac1aa76f630a300c73e79cee1c7486e4ace9d45484960d8d26ca153dffb9c299dfea06dfc4990ab83f8476034767b58072d334ca657926ea60f8a35f3f1970a66025b28343acb04ae5ebb27347211e5156ce64de95a10e42c0f8e3ad3498992db32d874e95858efb488b6d1ca96f556c983863e47f9ca4b2118e29a8687dcc67466c837bc46b55f4ec2d4474450cabf1ea85a30457bb1779b3f0770d5db0f61f98c8e042dd3812205b3eaaa4977b4d7ca3eab532bcf9e75f583baaa30bfabc066b59997a3401852dc6baef647688feedf7e16bb968944c876e2052d4b46bd1116f1030237c3e246ae207538c0410e879f857fb367cbfab98130ef61d31d1d786d252069c4042e23a56890cc6def8e490181b7479a364266c65b1eefd6f7d87e28e94ae4fc4ec3781b8dc6eacb336d0b3dd08ccc89ea4b16eab4f3fdf543fe5f27ab0a519ffb7b1baa6fb6b1ee5477d094cbcc1fd2ad00eb4fe43eb84575ade7d99ad61607fa75e73894bf68c92c76acfdf7abb05661e36ae5de7da61ff301b5174151ec35bdf5ab1be8efc71928a9562391ef6b72b8800f3d479af3aef05f21f1a8d42e8b526d13b095d73557cbb8a2c01344f0f16d78e9e33d44978f43b550c22fe1fd87630b9336cd41cca2419047657492a53f11e2ee823e48ed815ec70a02bae828d7d430a047fa9852040f7b3e19a0ca92c31cd965ee9293f3e2c1969e3fe1969174dc6c5def7cb84a3db1326f37de316e436db97fe12425280591b980189d0a280b319c7cd596d02e6c7475d15e4f34a19e9736e07ea462fc389843c2e5577342861dc9093e5a7e2476d323c7c670afa5eb156c1749c22500646ac6df81dea5ad2467d2117b30bc5382fa19c042105d932a9e0c662f39a3492724498049ac6adaf9e3105b2727951c2c0498857365f5973630b0a4320d19614ed317a51e26050891fc1ddda187945ec8253518722ebd2f6a8f77359361943c87cb76148d1849bf1b72273e5c5e0119e69aa26221f1bb543f27f3508ca1c7bda514a0964b69bc4d251d4fe835eb14df62893dbc1a18d1a857d0a91fca50b6888888818bafe839285c40598d4d2b506585ffdc7d490fcbf632691f44bb708c377edb087e83c53a9ffbab1e9d9173d2e45494dd461a4a085384b3c765f5fd30580ae734ff9002ecba9cb3c2a220db065942daa3a3d36c2aed1b6e5482dd3072f7abe53fe92489495805db0a81e40f1d4e37596fefe6ba06305bb947ae672eb030e73e73118b0bf7075a19da08e76bb977aa733b919a5be99c95e88d820e9a5ea5e04b4cc6bc9e593af2b4827729c1dd77b2918a88e87c7bd08c920623176f831bb3b9ed0ab9d4e1975595d5a7d8c3ce7c4af04627145e0f872ff7ca291990771a1a22e5b16906304b5ec73ee195dd14d21565a3756e31eef37368c9aa5246103caabbc72e944f8a11dc1a7a0d2dfc58f2caac81bbdbc0bc3ea9f5dd0ccd82723f1dcc191c089c667fef5fbb16fe8cdd164d5fd68cb77f150d784813210f8191be66bdce17909daab7c120170ff833643f34786e5f3cfb515b18577f7ab55ae95651d935a35fe662a15ceb1f6527561b71ecfa49cd2d77d2bc9965c88d809317d63efb9029584f0d3fd1ede1599479f5260eb92b02afd9d42faa7c188921e0e079134587ba9bf2b452d8a2badf79e41c7aae5eb35ea59c390b354adaea87d617fdf5b0a85e29ba9c229925dde9568c5261ac6b665531cfe9cd96c3f503193be99bec4e39f4286a2b515f19aa6eb816bf818371657687b2e47ec1c9b95ba425bb225677f80308e337e8667902db7250e1332fa89b3f8cb9bcd948f02a6a4eccfe20c7e1b3bc05160541dae80ac647dd11577e6aab9a35cfb0109bb5e16c8a2d5273a8593bb772d0880088c868960a6f411a0c11617b68144b5cbff092e704cb33930ed42942a8789919d3f3499dc75dd2b25e5f3d04241bdfc2213d28fbc19e5b71fa7d7604ceb1934eca9cb9cda1811d01ca9e5c83623edaf15a75a70819bc7f73e3ca0765c6267f80b2b8caba4e632888da229b9c4b7aa6bcad42a4fc43c9df2ca50141ab23f978aa2af2c0be0106a4f62c777332fabcf37b3063541646f2ed5505173c5a3ae921a6e79118702b312398de30b07d40606a55b6ba018c1c32abc3b73200865940a8fc8971c2e06b18527f35f261750355ec4137b3d44ea0cadde2be43d19d3b5acd73a295eac8e6c1975041310306e8d40bb03e111e476be36989c52b3e4305911592cccb01269684e7627ad80cd88412ddee38e0873a04e6892c80b4b946b061e5585465f52fa3c8d9d40dc8aa1818aacda9d37e6fc2c13d81d343dff952713f818b907f1bd410b31b92d07692c502f67459215ee5edca2af4f7d914a91f283bc259291542cd733839ce4858944c468615329be20527eb3e98712aa626ee1be8d806110d9e467c36ebcf16ea8695acc95930752eaf3721c6bf1d9d9e562525784f2bb3fa166e9d7010f4287e7292aece13b757a57e30b907cdde28208389e89a08b86c4ccdc2bfb8bd931b87775467f75d57cd86df9121a561de845e62ae1a0c933d30db73a8794b32069cd2f3e03736f3fc30090e6bd7b15d410850089fc661fd53ff0c60972c673ed9f76eed830ff84b72c1d8eb73e9e878e3045cc7045d52ba5a977693fb6b1a5ff46c43cc2f33ba22541f38d6306f3dea6da4f7c1222c8372ea0777b702f0c227ed3d195b367df68ca6d47175087072d3a8753079ca613904a432fac59480af283e5b2924a914d1781ebc879abacecd680d568a297f4c37a6e12f8c50f07ee728a66dc1ca8a8efe1ea990dc2f58d0831bef3f651f48c0b0500674952985d93bcbe1d28a887ec497913efd7f59638aaaa0bd3994f48cad2ca1bef17e08edb99a85d3cbab21f6bc4cd63ce46757bc8640d533f7e63f5af3bacc8c4d7eea75867d908771fc0ccb63639c033f852be84138eea3c53c1c013d77449fb084838fe879b3fe99304e5fa34fc454ece8aaf267f153e437cc34de200dc3c009267e0716c999403ae380f48b8f22794cd26be6b19c795917b7438ada714a51f81ae5f132c6c2c264f00eae0b541e47827b740fbaf828c13a8f722b594294cdd41f52c7bb6c473f3927ec2beb443ccedb1a6911f84ce201fe601b5434e2455ef4bfd41dddb5c2c73b3329c60c57dc38c2445ceae9aa44bfa70ce02d650a4961d7ce1f99b6760612f3dc67618f53c0aa58f5c5fb2b82915f4745a746e3700e550279a7968957b68d7d56524d6e42b2eba74f83c34371111f193d1a9d446e1837455c9f253d4ec0781ae66ce52c91a382c7b816439c181f7dfa471e5207632d0f90d45e8d9cf06fb3ab0775a482e8a647cf2a48003e75d41137aa357bb0e7e8c0b68a4195befac10eb0492441e7a8748bac4b1fbebc1ffb3f0d0711522b384b723df0560ede7bad40320f6b9266949a49bfb4c6bb517f85514522be55d3f90f89d6f8af5cbad6c14aaf36cce170f920b2787c8d7e8ac358c1b928d4a6e5f2faf3cae76f558658c6189fb8771137d8af1e4e801d366dd033717a2a0923740ec42efaf0d2d6496bb49290c53bc0aeb4f0c6c35c4f35678c35c5de9daec6f064098f7639584782b83eb468250db739c0101c42f130e04141bd14df1983f269a2b3f1e3f117b20bc3e7d526fda990304bf639612d52bc70a460cf374d46ed874a4dcc32d56fc159eafcc0765c45b1575835c676c498b3167b67f1f0bba52944423b56caa17f1768e38e46977f9f649816a5f742c63383cbf258484d59d2f1bbeb403668eba81a268b9066e8633fb2412352ba0b0027f6ead585d71e8bad4f8b3fcc1e1187c9f42bf42eb9dbadf333e75fb29e65fd3de2678e53bbd29d399689260ac0daa9cbf17ffde8019e312fd9978b9fda916331fb23bd38414c8e44924f152f7c8ab6a860c59e7d275bcd6ab9f4c675ada59306d80b6671d66045cc2fb47fee8e777ecc079d3b6c969a0fd9d2bf45650bb9ad14b25eb15c9388e1ecc98179b4a6f112c8fbb91281ec41657a45b1479060251d5d78faa03ec71a7225245c9fc978e558b086896309cf831c08ee172004b7fff3b5a09336d4f463212397aa192838d9b303827b207a702879fb737a244b0250fe785999d3ee529c284f1d636f75311cb7ba1cddd836eb2b6e0d6ddfa9eb62c09f60825a5cc7416777ac350cd3701cbe39ea88487a0afbd643198e413d3de9642dbabb63053d124c4e077d2a3bf619a3f5f341f0a782c6a2bd38167675b8ec567fea9c142f4563b34eb243db8cdaf53af156f60d175769decc81dcaf510aa11e3b69429e2acc60c81cda0e778df03d4d051b0cd97374a43b47422cbfd7c5f52bb678989e05ba8dd001246385ee1afe0499c0458e77c1527a1958a6cb254a4ea98402bb195fdc629b3265f611fd3ec0456f6b31c0b2b3a3e3d8e598cfb6fbf7692e31090edf9946f967d6510ba847e430faca9610401d1223f041ce2928bc9d683139b78c2685539eac26048b63b7d6f64afc610edb84341c7e8dc163974d588ac1853ddf5dd7ffbd9dc6d482d51a3b49b3eee270121a87c50acd95ac705cba78a71565404a6f47562de2b3d9d2038e07413dcab2932c21968f5081bc3aaf2fb6f6718af5b9ddecea787afa26767abc46f32a3be42bf8d95178489afcdee0e39bc400e20293b2e28239b714206da63afc7c5a4f0cb0c59e3b45b977eaf273f7502f8f256df8991d7af7002ac1248d42bd1986898579b1030c300ee2b01ffc50c676d4c1fc82fb2ad1b68cb7ef499ecb92526976963cee8d4abaf3c53056d25967795ae152144e1f14fe57336c591f30e901506ec2255b8d7439aacec4661bbcbeb4f1c8e0ee1079e1a65d88bab43a619e6a3e20e63734008d394e0d30f6389c8fae303a0004f29c5a08ed9e498a4c33ea6e68cadf3ec7f967b6e26da62c012e592915c309553cf39699fe9bf5e704aa5622980f4d1b325da1b3f8f40655f8d1409c5a97946108d1cce7eb0885883fe55092e32e398de683bf9c91aef8099c35f419b10897122d7298367ed1264f583d59ebc9fa43873d65459a6f4fb01617118e443e5bf9a3f5142b410e2720a907b59cd3808ccc0a071316ea393f6b9c602386f7fc54b13a4e8d2a09cb63e379d20e9569c4025a8bb445a3a134b56948855ae6f22f150bcce4c317329e82eeba597763e30209310eb26fca88011102b2182f6ccec720f513204730c80fe1930bdcbbe1d0324730e5926a6a062859172f399bac5874b08fb4b19478e29f03e582852fe40366b6e098df5612c646af281e992b007ed4b8f6f958b5667b96bcbe209a22c3471272a9dbb8e5594a5189425d0b9625d97f3575f68aa3ae676ddba100bd42d5da92a53f8666166240c28c4bc6decf735763378dbf14df8012bedffa3ca41085723c6a54211855a2b2499845e053f4389017dd936884581f2ef57901bf9b99e94fd20605bd8062b5ec293513fafc0f576402583ab826e981bde3f5c4d649d4d2e2915026db5503f57636becdefe7fdc3e9985e2f8c969d2aac3e1ac0c61ca7d685c444c2c3fd06ceef03f88b5407f694c772895d7040f28c403aecbc74b406e0893e31f947b0875774e80eebbf64ec1fbe5dfd13942baa6b182de316cb96b15378673bfdf5d4ce0fa7e03ddeb3de836f502598924e8719c9cfa3de11799f7d19b7d7a1ca463ebc93d8016f415f7d08bfdaedd3722f9fef2bc93c96d9dd5e1c19242088a62578cbf3e666341513c8ad7f63e3797002e916e91b2d5785bbe11f12509dc9567e84b3f9a16ce5f0688ce76fc027973c8d01db41a16d1551f51d143af856821d6c62ec5c0c53d3a91afe969656191a8af09095bd536af651970cfbbfb0beee5a3991b09b5f8209234b78cccde82b7a4c7527c24d9a39ec64b672b42158b9e207eb9514e3bb1f4e1687f3e37e6eb345406d7b4eb85fe8ad549d907ce1132edbbf54d39d5ae80934aed5ba8a63f7a24a3d77813ed36392eaa751e8f384acebb427b81d7b4f9225de93768d79c8c809c3a1db33684d48cc6c989bb1cbe35b221a76e794263193918cbd35bccb91038a50c2d87759219c61929b160a0961f6e26c59686823473312f72d914f0950a437831be55ec136fa690c15f5328a9bb63b75f86f1b7ca78c1cadf626af33da7d356b5f60c281de12924da1e2a4221cec0ac0f5747776042c28c5399e66118a9dc9d85dbd2595f8cc3f4fdb2a242e10a492c51792a6e46caef78e2c7bd42441ff6022e69ec743eddbc16d3762030a0011e323802d57a6ec6d166370ddf5ab65fef8e55c46ec9e3460e6d99c15c6637d15bd38a0d96fd6b18635d9773b050b013e521799a973feab4d77e1e27cc9193592c71297a53156332266592cbcc27604ef00d6b149382ba9143604011b276351b5347c69f7a3ba7f94e13dae9713128aec50fa7a765db7d5eb467ef18e71171a31042b4e8f003d1c0fe37ebc098795a5cf225f313e267310883669ada188914ee58df273e67ab89136ef6eb4c8b3e1b91aec5b809d49e2352c8708e5d933a0b1eed7d02e352d8867a3344a2c0442918ee5153db631a47572190e3412a6a2d8a79ff67ca07380dbcece038a651bc026f9f4c7f3810ca97cec1844cde3b727690ce75cf197c7fe15dc39456dca98d0b618f3c92b161c91097c03a62304d1a4809068f3d987e35c85285ea8505a63d3de3245359e3e9d5c44aed26d030c7beecdb74e96b2861fcdd92e3724da6897914c3a76f975e5935c86b579475381508ae9d5ccb70a30eb742663a817a5207bf429fbf742c8e0f47638c52fa2594b5dc7a546692903ab66d4367a3d892c219c6a71f8fcc23ca00ac1b987da76729edfb065a59e0367e93ccee29eafcfaa77b6a913d312cf6af902960105b9029139f0a7662b155283e10ea061a36688089be8ab274689707fdd3d23ca190ede7a075b02a69820e42f2b96a66979f5d4690857f5aceb7182c0300a2e2da6e4d8dbdbcfc25e9847b3fe84b1d736194c35630427e59b9dd15520c8039f2996d8efc6c694d36d662bd25f96df63fa78f60f90da6fdc93daaa6c70ccdf31142f0b2f18abaf8d76558fbdea1b688bf904630c6c5e52c1f83ad06a04ae0d777df85e554dafd33ecf51c29c9803b30ba0a8d6734c882b90352a76443e8c252fb3adb9212af6230c88ecd0a7a3e52f8370f1258a8c3c3f4c74059f78ed0e2b16d63519a42889bd946dd585236d7db0c6b8f03dbeb6ad60ee52e52936261ff443b29a815f94118d376b026afcddcbcaa5f544fff74cf585cb68593ce29eb6a24c792465f8c55104cc34e8789ddd5898b1058ead455b055378630c1982cf3153947f91fc441dddb6f69c76685121b76572929b26ab77605adda605f761fe73599deb40cfbd711d291a2579366f936cce99c42e1d812d755fe219825410bee369e87c2d1377c70ec32feb99b05a909fa5ddd7e9227358b5d21030227198a3caf1275f24a13229a262789ae890d23db00448cad9f4e37dfbcee72f2904416775d1420701dfe2ce54712f4f8fadaf67d87227f4237dd6d6309f1d8a44b2b17716de6f14244436cc9b79e0333edb7e80e209820cf1712c4af45d1b71b24ddc9f09a23510fd6c1a20c5ab8259eff3e9a3a6d1e5e86a4e14212a9b745fdeccab7d8984b63f1c211ad4aa14e6df02738832d78b355da903ab973c2fba45c2b65f23a9a71efd3e77f9fb446f3e44adb44d0cc94041e6ce52893e72d944a9f1752c30eb7e256de7f82218149d11921955f2fbcf9e487365c5fbe04a278edb15b8613466118376aaf0a7c5a944ccb2d4df4efb36f7a14631ed791a80f91eb50205b91eb05e06b045760b474965ed12061db3ae7a0bf0a6b6713cdb4da831c199d7ad13c61a7dff199a5914d0147387af5fbd8fab068ba199c8cf4b56162215f5d4ff79f211529eb7be643470361c0e7cef6c3431f6006f26337f60933bd3550689a2930e7c34231ddfc60fd74cf997915c22133c428f66def2bd438e04764a91432e29b2a95ca15e269be94a6cc2e475298cd6c927ac8c05e4b6909345d9aec7d310f2b174b7ea22b09ebd7b8bbcd75deef35d51baea65faa3067ba51e8e08e7f30071979b4c32afd61d95a6230a662692651d1e259788b0105be06aa4711fcc8e1a4551bec0e964cf5a08aaeac462115ed5160d8c8487fb2fc01ef7f482321799be210c5880c92ad081a9a147fc3001268ca380d1acd95e1d7b7d752486d5c9a8df82e348f732321747951daae1eee7a028e910289612459273f47eba6cf5e7b113b21c3c085bcb6b0db4358bb55541d210df22dd6952faa3dffaad2cfae56d51a43bc8b30ced1ba81fccaccae08a837b2e6b3911525d4a46dbfd61074761146f0192f6f47b9e62506e1b6890e475bef8e68b3ce515d75e4502a64c3e1390e003249c881bfc9f9c991915e417816a763b74f85304bb3256065da2bdcf6dd72404524b0197871d45d6e06613a15fa80727f3dc2bf317d6f8aedae50d6a63cf2af2d2ba1353121972f9430ef3e9017f0973328f35a8b34f1169a48bc5f109c5d0da35b1e45623bf072d9aae408fa18e86e174c41131197334c1ec32b9bdb90e26b976d548c5a5c9460e8276bf9f75249e323a18543ce8a31869715d87b45eb786a8cfa12e6e728835900746d426f5f326914496489bc017ae9556758917a395153f4c2c8b40c083c044ede48fb918eb30ae01cd3c88cb4d827d69dc486471ebeadc0073cb2ab7f972500e6b54f3f83e608c0350d3903f5f33180bf84314206327763ffa27a612d4a232585374e3e348fefaecd3fb0354cfb440cf5084a326ee6b24edb3785c0e912b58a47f46c21653d879a4527e2a2c9800e02113a844d6ce415a7279844d8f855b445ffddb5e3452c311074f0a7d73530b42bc1b358ed480b62b7b2fae5a91b2a5fa8f0b4c553cddcbc60bff6c0dc316ed9f377fddba80b46b409075c5d5302010b58090b2324acbb74182979730e56022058324ee06f8a856ca990f85267a9e40047a24a676e2fd24eaa823a62f0a6cf2df37d1e1e512c3c37a98ab7d503dea190f9fa9894c6baa1e0f3b86c8b818f8d46f2e38b8e87d0765e9619d3919808d42bfa879198acf862b33fbb850efc12bdac37f8e65eaf6733f9204c2f30d9f5b0037f78ade59ef67f1595ee0bb5a748596fd1ba4834c67d135e4545a5b8aa77bb525f72f9354732ceb0eb98fdc461aaef90e8d3d99b2db960231238488472de07b1fc77a91a6b698fee07a6e6a555742e786cfbb302094234572295b3a69153d8a4d63c60fc98114b599dd4698660e87448e577cbab76daf0ee6b71809b89ffa24dc0f9fbe2a99cad118bfcdc2ece366000e26e441f46ee96622b6a0c95a975eb89f9c012bc9c5f9eab8810eb64a1b09353f9c6c9a12eadce7cf50914d1e99bcc9b0c5736ee357c97f34be9f640aeffb06ccd3b94506ccbabe409ada10364e33bed49201e2bec11275a150d069b803c68819c5b140d3cde8a3917cad730ae83de22b72255ba33867e3e4ff08ae970c10f379d8e500197090bb6eacbbe162beab48ca8297817143b40c1c9cefaefb2335ae08a2f1ec5e1a2d695643b0a955c8ef2027f0bb6756934693898416802ccb44b511e9af1bf0026b44e7d47a4ff5d7eb80a8f0ed8fe5dd7cba1bb8ceaad682cade515910e45ce3996ec752b3f22219fca93f9ec15b68f72cb427761f502e2b7ffc1b300ddd3d1ef72f6185998bdc81528c47c5d4bb27a76c705e9fb74b1f6bb3a272f9ff8c439b7fde45732a9bb8257adbf74db001d84ca8a646792e57d911f81c62858b398ca16768dbf9b68f92a9582fe20c92353f58421bed5ab7eedec0d8786984b86a418aee1def847366bb8d875770689c599c5256fb50fa3b8679101e3facfa26097ef99dc04f36504358c583866f5032290ea17f4016048ecd81b09f1fc0ae79a0a603b09a9de516633f5c6b61a201054d422baee6292dcccc9cf17df248f3cd9ca0d2eb2dad6ce63457a87e9e8b8a949df0b89b85a4ce6861a8fda7aa9e614c838483f08d54f67947e2e2123aab901fcb7e3d31706c94c6f8032710c7aefd026963969656168d4074ee21d26e2424d966b5252123455b173f92667a4bb6628b46d9586b3128ca2e56560b33ba60fe80edb177fa0cae924b52889c4bb30a74eff7a130d828ca99b94267501b6d537ceadff44d3f5697d4c22b2878cf69354b7931bf07dd7105a65d0c5819f6f527f6c2a1805ce52ea61c60f26a1b38d32c72d171518ab9782e022279b90d1e94be6062c75e8b3314ff2ebbcd29a32edcc9765324aed9f7fe6d32f70aaaadd7ddfeee46540f652975940c0e96f720ac374e8c479e5d1e2fdd3c56d8093a67607f5e1e741180786cce2f90303273d54d10bd7ce54a02641b97004d1dd4ad274c63e7d579af3cb6ad49b5b6fc26544bea21236592d82a7c6660c2e8aefae2f38240ebbf116a519149b79871dcc3e0e62bda1ff099cc8f25db9f15dc14049ad16548cb847a992319f27dc37bf5fca7e2e56237af5236aa7877a6c4245523fb7ec326e54b0913fe351ced4f7070b815ba7a0a0eb12ed6d25634907304973e82616d9631b581ecbd9fc70b30d6686ed1387a00156e293875f6965f3f9b09eb9e552974900d88000f26c0d4182ef2fb6f42a685337912fe9de29259f6c53c2512640b898c7c11a059829b56a18ce8c31fb2a808b0a4f6c9df5ee3a17bbd8ecc0e4b587793d743c0f02e4b3965b4596af610be5e1768d9e9e40076d62df73deff5593c41b47cc49c6904de4f97f75ffd624adab16a65e81bb7be738a5fb2ecc024b4217cbfc2123c2858ca3a7e3c8e30211f5c7c4e5a8322afed623f9b802ac4acfb20d1d94c183a2ed221c8efd9abf4ad1240ddabc328fa80aa113482a235456e356a04c294eed08a4117949ef5ab86dbb3b573f7751226234f557ba1fd4ccae9061bfe5e1eaf3d3323db235f9eae4465bf7791b8bf695e268016e8d898cfb7dbe68479fed8f8321297f263a8838fe37ecdb13af3dda28bde4b61f5a9761daf0e30036b8064924c872019ef6f77c1d0898eaaf4ea2471823951b7ea2faf2b1ecbebe25bd8623379ac8663cd829ec072241ea1a160501f7e6f075daaf18ccc4d033694bb72e73e959907ad39820c3ff3e6f47c54a94e2342bce5c2e35b1115fcd678b51e6152d48e346a42550c37a1b38ba0e069cb36460d6517e5a545374f9fa5756a34efd97ab7fe2b60bd758f925be914e3fd03c3e96c05c7ce17772e20fde82f75931d1be62a69f4979bbd51d16bde8f6f541ff6026e879a2f1775c67d7fa169cc4b70ff848a4df0af1493618206780c1f06aaf5ec44ec036c966f853dd9956760692077006f685c1643a3fdb9ea178e534cc270fdc157ea04724de4ef10061726db6672ed7a1d1d4609a1d44b9243a09e73e15500daf1af8fbd9208d6369075784a888461fe98e2516c64eca7200793ff8b0ed1b58036c625e6bd429d9f02163b9416a1d041cb94a28ce11e246d91cccbfb0b499f02b1f9df2af0f242e1dcd5a7020f410efa1c7fdb239147977e4999b97cb353b34b731fb04a6a082fd07ac14b168f851d3ab534321e7002b9bf83c1b79e25205c2aff0907393293e59943c4009002315365e0e06ae7e12cd8d51b1b94ebe79bbea2896f372da71fc8457d16a5276d0a9e4ec399bc25c5352ceea424482be8696dc4d9d069fa731b239497f66892e59a44ada35920bc92fbdba0b666a7782b63f62af458f8bcca80698a7093eeb02fc809e97a15a43ca52a768c52e4a15e20fde0d4eee0da523bf0f883bf78cb5ae821d987f223a8ecaf74e0de47fb41b251c0fd19b79c7c8d4bfac1c912ce1a8e6af1b5d902e921186b2b9d03006e1422e5640b1597e7fc051ecd10f410f419d9f71bdf37c512ac2fd0443c93fc560198aa3a316186008fec1f456536872e4ecbe01d25ddbc43b05d4aaf92f1392c89d53f7a81b461959ab38c9b2694506bcef87c1e6339c247c5a9db7584a68ddf83fd96473e0d7667b685c213ec2a6f3c90e97714e6b2466158268bc684404b437847841cba01d07c8d67e44845e5499a10b41ada2f527a845fe562f35b128d3438a0c963409f21f91e27639c5abb693a64d1f20e748d1af200b7fc8170346e2344b506fae844f733a4c2098595dd01b11136be6088911327d51abba1e1065cceff5e0fe08098d79720cb74c7ee89b140ebb60f2bcdc34225b82640f574056342dc6b738195cfe62aa171040b66ce11303a25a0d09223c7f62f4849171fd3e1568b19e2f67856a2ec2da6381b0cac8d488f7f98068f33420fe8271e90f7ec5842a4e31a387204777db64e32d9de1eb92194df49c72abd94a912487f6ef4a5ca1462276faeedb353a4008ec17eb6209e7802d6e6551e381e94109d4f8ff2386934fdcdb1a4ce4d35ab5c36c1c1b371f1ef320c3806589d6a6abf58fbeb707af298c4db9ffca76279eebe3f1a46073af3c7ee56de6bd19c21bb9f83fa74be82709e2c7d61d19d6b2408cdb1e58e97b60e494ec2d97c0f652b95841f85e60c563d04baed892be49625c6c90b59d1b613e74a596fc47df3deb51cb4b14fcbbb831425d4e7f3d0fc934621b018d2f6423853fff1b436bd7ccdd7fa11ad8067b94a988885a07c20af607b6c6d2023f52d61bf5b0f2392554bf076c0aed5f76f3e05146e9cd68b62a05bd257052d3d453303e6824c48aa07da9ca7b3aeeeaaabd897606422d0afc5e3688d765f966c419e96018c39b9d84973287d47fce63c06ba5fb6b0358f94e1546c548106a1efee135f063800725cafbe5e9732eb4cb63e93fbb5221afc8861f199fdaa540bee847845e809523b4f0ba94cbc17d9a326fac40678ea13e0d8754c7a42f91242f8d18d5bb1af6ecbbe124ee453e0e05ae093083ee7770cebead5cc90c5bd4a04bfba4f1446053eecc3a3e2a401fc98b2f58b249211299837a8019b70fdf0bbcd38da086cd1469f20839dcc73d38893566c3baf722aebd5b62d320b3c062378ccf7ede0876cf192c367c2268db590f2a0d31491d8aa98ccd6741f5219eb704910a13f08b5ad30ff9cec5d273424117d45a85a315b93676f8556332cad81baabea00e606fa81f8be8e4fcd3d45b97c8adaf463ebb986033b482c567c9667706abe894c03f2f03bf64abccbab34c63995edd553279c7a4a0ca188844add47c5370838340b5deb0187a0cc333ac60f6d7b1958e29bb792b6d5b6e15b63fe9a18cafd74a4fac4a9afdb8bda40ef65703502d6d5ca4beb9a81ae5a4d6420356e6ea522a67fedd023d8fe25c22d2800f4d94720a55b19145fe49875b050f62f932de24a64fb46aea0667711643f3be223264325baeca6fbbf2fc025f5af5982d9daba6957fb9251b7fa466bd79d9d54d058847b3d9d27353762ee16fd01bf1168832cd1f8ee93efcaa93e3af609ddece2cd7b6cb6aa8c5aa43b223e19de8789fba37768f47f79625c296a507b6dd12c107650a1a8164e2fe265c054f32766a948fe987ccc67751230fe800ef0df24f885975ccffc096a600ffa54c8e1569d9fb1feee73c6ca1a9b33181d351f3046ef4e018592ae7bff4522d1c344b58a40ced68df21e9ba2522fd60b89f9a294a273fc8401a9666c99ff3a2dca2c82a4a1b92d93352ca9b5df2436c71ddb1c4f2d0fdc9fc8cf31b085ede602c830ebba44fe638fb2eee9ce76479fb279eba8c0e084a7e68841d30247fd4b7ea2caa999015f33aea4e1629853d48b4395737e3f305cddbac2c81b0208106aebcdc7bfac0f9dd764c7179a685a52145e984e8e0d256f1518f22aa8d0912e26b81cbf73d59b2fc0aecd1ab9512297ef2031fa7e9844ae1eeee76542d03e0351be1be76046a1f22ff64f779203c7bcaa68527e018b520abd0060cf95baab11e0023c02df3210e735505c6069aaa5faf8eb686c5dc24cc5d877d6a281972b0e67d6971f119dadc18896b5545c73b89e793cb301c431fe0ab095712bed0f3aa01ebb2113e0617a315c7313f0814fb91c0239ad282319b26ba64e0174780a4a43687309f27ed8500e07fd058c531297e24f2d5559b4e5e1f26bbf7a7aedeae386b2281d9adfc8cf33091f97dd7b1dd717a13fb9a285344fddb72af28eb367b67391aa8f57e96cb3aec625b2bc35a76eaa3e14e5528d6b2ae60973166be19bf59c70916f97862f09187907e60d3b5ad0de511eb1e772a9754c8f5a7ac6e1be10a03d21d69f8e7116a15e8427c50134845ea212a89be1892ea5471d80d12d50b2ff37770f7613716e37808b50d6a44e3e00d630947ef27c2245912d5daaf0e3437d2e54d3c4427286a3f4184fe35c46cd048092059fad061b7245465127da0e4854636e29d8ed93ec85d7c64a3f1d1bbc3a3eefb2a596ebef8a8220ca19abde50fc7e0adf18bba87d641e460482478b4f17d64eac4c321c48671e9a04bf6492f2d2dc8d8a588295ff2b2ff7b096cd884d939e825a1c4b3e47088990528865705b66f751c08a10e26a6dca162d26a1d2c8d126e3d01a1ecc399520e5064d5348d4d72078ed42431e48a0af84a81834bbe9e7260180ff2dbcbdc6cbfbb26f52030e191b048e3145737edc63f53f046ccd8e91c5e803fd0287771c3e443c91bcc45fb784f0defa29293f98afc0dccc1c234a8969697eef73219b26008dc837436eb72c0641db3492f50d414078aaa5683ba2071e39734b0d04592737028b4a16f731bbb17534b15a536c8e131e2dae579f276a00250a11cfc0c862ece7007c96ca80128e539ff61cb8378d9d8cbf087ae97985fd2fa9a130575fa189dafdd8817af78b19c093f74aa8d4b1a689d2dc053dfd171967206f0437f9e499b605b78d3ec8a524c9ae99c702f711bf0a1c3ea8cc444a35ec24d42f58289302e81eb6f6fbb7f649b0fea19545d50357c8cdd8b2d5da6d56829c06702a83ef6b71ac90f29227f2e9468efc7a69240a294c2bf468a94eb89117ce3bc7c8c866bd719ed55c98e780e317d73f015fbea699be6414aa0f4c7013962d1bd305ac1fb4b5f05f43b36ab34c107b9b535cd051d41e6d8fd2fc27d9b70c4ae118bbae467c96240058cd7d27e936f5d329a79c20d69e8330984a2531e8d09908d28e6387308174954bea490bc66e98ac918563c4c4995e7b0fbadc5503108cd980241d0e69c8353c766ad151e404cc98a73918726598962fcf96bfa8da365584ecc2e5711d9ad733b628ea3ff4100b0d86bbf2e31d2ef12632d4f0e8d829e4cd9cce8a1041a7b9ceb1dbb7c3e48907af496f7c49e5cb1b87e102991307f46ad4640aed726a38e242968b8b043234ec542815f0effb48bf53e6d241ad54cb06249800d56cdfba9aa203f1aa5dabfa46e98f04604a6f4c33e5dc9c9e8cb5011761273812a8b627e1f7edc8a9aad6029ea3b664e6d9a8ac8a04d85d214d1720212119ab46adedbea101afa51e906445bc44248682af721bbc9d7c05f1c0fcfd950b239d6e934b4a13fdc4d706e0d7de819813679a26cdaa1b563c6f641f702e646c4da58268029ba3165e20b965806dc504d41126278b4ec3b8221aec987fe814d8f84156f3d65c5ef4ef323e11d8268cb39622f3a0de619d8fb9f06edc697f8012bed3f4522607347fda4a17f115607f76da16a0f56502373ea2ff35b27b3009238970541279489299bf3ad5c4d7360bfbb2abe5e68ae9a82df8239eea2f150775c05f81c133b881bf3b4ef5e2dad66ed3d06c46134ade9f7c8b24e76b32b2b14ac0a5f81140d42960169b6bd8f895b2155359040daf3c869d6e14629071d7568deb3439a46fffd99e7dca4311269945fae0a7d2b5c28c90c43c22f8bdee54e61e9e0939e30801b76738a37ab00f43019f314b427c582698894154ab94ef482b472806cfdbfc78ed449eb2e860ab1880083cdbdd5d6d0042635cbe103dcd1650ccc142bd6c0b90dbb552b1f3f316204eb6c92b5be5b24b554c96e2e0c31691446e037810b3482f27f34c77f35ef518b3387fea54fed2e1f247ede2b53b366130ab6defcc2c28ff274452a379229150cb0dac2601d7fc7c87667f061091a1d16a3b0af9ce10065a52c549b269b817be3a5d27811854f7e7e464dfed8ce57dab3210aafa3c360f111259ea7f368d0165c61ab827dd53c21a4997a352c9fc340b66537f61098e6f6bde1e5b71925d8b131fd65d99741d393e04e8cb54c5850765a8424fca866769bcc340dbbbe5c26ba0f54a4d100b91ec5203e0158b4531a4b76b9eeef7f3513831c90c2c4617ee4436b54d5088d73aeb79af922a8d98fe8f486c11b86468d02e78541763d3cc8476a9f92ddee71a7ebb23d5aa7a4f36296975535559e10e5c91abdee8a363e75cbd63c1b59b1b867ab920ed67e9fb8c793a568e2ba5859042eec4a05b87111b92b10bfb0dce488c759850bec53ecfa15032c4aca8d8d0d3b7ca6b18632f4fb8979586586022255a7d777f29ab1c86f03cf764e155d5ec3e6a6cfb8e6cf9aaff1119b8b58051d1fe932ec140a2ea5422d3a4a687e6c09260d787ce33ce9914206d78582e492e83cbbcca1b28176b508f6df192db830265a360a8b8377510fa6f9bdc3e199c550c92e3899fceae3c927a70e922fd438920ca8dde0d62f62ed186814805d65d42a5cb99f07d0e2c298b72a232db6fcaedf071262ea44a853c14aae620e9d8ef73f76dd90f64b994a48dfd6251a7ce037f46cadaa2d97b5ec6b4ce36a509e09eed7bffe7fcbb775380ae2119c3e4a8f8ebe7d76eff80c94f0cd8c20221f9cb4b4ec34aba39fc8c66d9876f0c89189f91bfab9ec9e7fef36c4d77c2aca3e698c6089b53d67dd02c2d15adcccef69481fb8c676f1b90f8a3118b855a009a02f501b9ed5b74be062d6abee81c92f18e361eaf887aa5fde85f9ee5d58eef763bc8cfc4eec079fbd843c273a2ce8ba376c93b0c80067e9d58b9e1f6e5da37b5e6c33aaab9257cf4bb4653cedf4d5f45d68e4ebb25d53182bfc3792854227534c39a111197187e5d0f51818a48159e2a16e1141266cf0e4480a5fdd8adb17868dac3d571479df06996c30b54f8331395b0ed380014d85509938d1bbb025945f73bc1d7645871c528a0d215983492b4b04da68d582c392bf205a8bc075f89d419c3b086587fda888437a8127c73658acd2a3685550687ebbbf6f1493f7432e241a402a6f6d1751d53acef0e03e0bfc5edef1068f125c67fcea7571487dcf992a79c9e99a1b35f409f8e6f5db83189fe012029c1b64f60f9417c26be8f3695131712b98f1537a8367b754411dfb901321a314c70df218c57f922c805be2aaa22bdb137aeedbd8cbaeb542fdc6a4b5cdded7fa20a9562fb71d63598c84618d3893a1844db73ba13979972dba4d4e7782811da3760fc86d638f8e90d6e9e72a9c005275b2eabdbfe1feda70247633d9a9788bdd52ca50ea9212187bb86fb8753cf1d034c1a2d973b08afdb01b589638585d3997da16c91a8a20cca12cbd26b312265765f269c0c6be3a4cb7815fd96aba36afdfa4b0da0aaa4b270ae6a83f751e494158f9438bec2942d33325830c25bcdab4b8ab90bf94d01a31ad44d35138d4f6650213aec9f078485a2e42441cb8bc9f088ebaea1767088031cbba734463eb5ae1cfe524d1abb4bd5bb20bf379d7ce81592c13006a5f45055fa749fcd9621d42076a6674b701f88827d8779ab353d3597da9a29a3ac9825514837802e6c53097b1e70a700d01a5ec5b4494df657bcdabf9c0c7e63dbdc455ccaae1fba5e436353bfe12b65fe0fe15e4c9be0e91ceb30c18c84afb852ecd260e58f05239d7ae4dd9dd4aad205361db9e58f123749ac2aa41ec398f954f0ac74a63b517112dc7c4eeac648f680dfa4c8f4e97fa2dd1f96fae5dfd678170ca3f4a35849cbb76991478994dca8e139e9ca160a28ae052ef6013a6e3684c31d2bc75f7cc090f65f93902984dc2b276a82f93750a6a296cf4028873d37beb98988bdb42616a0ab7632505c84f12382c0e155d71156ca66aa50b3e9d296a2ad10bd391f8c81b5ea8105c226c755ddafa4771d1bb4824669c49973ff80b6d2430fe428c299269d26310d7eff6de23fe98fae38212ad8b112d0f9d32739ceac95c0b653041dbb46aa5dcec2a1fb65ce788f3ae883bd33b38cdcc699af7f68871fa7f8c5a3ac5ab7e3b179798f1787d9adfe248d4fd722042aa9aac16e874370939a6752ae2049f705fd162b9c4cfa96fc9d65a529dc9768eb9cdbf6fb92f202d60e4eb9127e6ad6b79aedaa83db9c00c2abbe7fd332981d8c13e1b9c84c7fad31c637a82722c2b982c1a5827073ef41098f7ffab65db2e17f31ab38c397a67fd1919d64812ff59d38ec14f0929c1cae87577ad93af9c8678d740109044b46a9833e2273c1a93f42609208e0aa5acdf912abf0b3700119d50bf888759d5b18907be3cff9b8a3f0d723d8eea3331c8885b1c55d1957a0a6b7f144132ff03c75b0e37cae9516b548e0d78bd1c21c4cf39e46844b492daeb79898c6100f01d633c2b620d334dc7d5c3829b4de40cd066b6a8dcf9d1e533242292fa796a33090029aac09d47557132b84f9e61a67f953d83e7a4286786d7975892c8008f202335a5ab624fb26e53ccca850735fd7303ac1f6794c679e47f1f874537c3110658cecaa924cdd3627be5b355d8422f574b929a06001f1d12117f2c8a6896ddf3940ab4366c45b8d50517fc15e05979ac8aa9a9614eaff1c129dcf0ad901ebaff0bb8d0ebcab8b6b2c01eb2d95f2432d309d19d0de47dac49a171536e8b573143066fd37d9dccd6d4f0c24ab46aa541564b0962b5fa497d1aa34f55e770f214ac60f51d6350ed846bb32234151cf02df0ac1b7b315da0c0ddeeafcf146ad8616dbc8fcf0c2bb53f0e7f793385447f4cb1b9ce4c5a948596e56a1dfeacc986ac80ffe6cadcedc9fb975d58e86e1ca29f902900106b9028b39e05077267799d613bb92ec5a428e1dc5aa7771c8a2050e89ff79a62b479a940a61444e275f3298199d8ed1f0fc2b9f9f6e78c8e30c76f2eade7dc5439e0f360f1eff6bf23c96655c7ff8bee4dee312decdcfe6a88834675c9ab281576b1c2bbaa48e7cfd193b3cf0a84d886c5edbd666b46e5446a511efa2bb5632a0ccb9cd6b97b08cee3e10d4358d2ec8f51a330da53d549dadba067cd5b61c9663d67953f9ab9deab6255f55d7320bc46899419df412c097c7f0545a5f1168b9959f263e7fa69bb4b7db6b7d55c2e354188cb5054a77f64db471424129704796398931ae3cc333219cb36210bf6a94f3026a13c24c98c3e5ad83e8ffe1222c9cb9bf84b1de0ab61fcbb2a2fbdacc0a4ffa211a025546d8ec3227e58c6657a9269e7716870c4ed768cf675ac863533cc3af9ac84bb4c1b4ccecadfe7fa271e823f397a6488c1622a476d482f098c25933268b1ae44ec7d9fa38fc87b25d0c36ac95b4a724f9d8dff39bc38998cbd5a6db9bc8d6a69acc3a52edf758486cbba2c9c59b1e6dc37ba9703d71223d8c75a42a652f57039dca3cf76c4dd373e38f0d568bf28335a906790d21c6b9947f35d0ae6c3522e177b71a026e4aefc4fb284893ee45c5ecf270e7b469629845d177c52379fad1d9520b67eac825b2087f3fbe62bee9a4cf8c681b2ffa096f779f6dacd2442e7aca0c0c802df029ad7de9e81bdd8a01a36be9fa8e13512aa7fd882dfe3dfd4b26ffea8f2f1185796047a1ad6004cd794c4eb44f218c915b5548a5bd94a2c0d58888a33cd82523f19a7df5594dada39910855f9ce953834fdbb6fd1d9e1706d292f8abad2e7bda159f3db2aa27eff4e63ceb43dc555633b48a3c8a7f8fc4692b182fa5f293e5ee5398e5db2c62b0deb8ca8f56e9a57d22150596f89832f91eb50206b91eb077f3b26c35e0ce958552bd28fd5caa10761b2b784f07b932cd441c18cf84a84785ad701ba7040e5cbc642c81a1711ec13beacadfe74b2111ac8d7cd15533e5c7c3c0050cf0fa3d87ad448f4594c3334cfaf27658083f57fb8da1b5342fe98f17b9f826d8c95ca6f4aeab28e60d3c717a83e3ad8379f5760d2d9e65fcfcb3fdb082a63a4fa19b00f6ec0c9155f7335bc487bf67c66d0008e9b27f0f976cf854a28b90973481852ace5971e76c2a5c994fc7b111e1fbf6cffbc22772c5f8fa292e510977b063d7d0a092e24c0d70a9a6e3babf42c3923b281ec5183dd1f41ba118af80c68e2a429626a7be786ec2182e9fbada143725f16e515a242c7d08302b75783bc9fabc5349a4e0bbe3a68790e992768e2dd5d14325feacae3b45c717df1447dfefa23593503dba043955a06b54d2799ffc19f221a1f1165c74dcc43249453423f77ed35d44d0308671c613d7ae86ae886de0b9935a931abe78481cef1315e09cb05e9a861198b7b99234111bc22f2633b6bb932c455fe3c162ce4772aabdc863e40fb9d2bb0568dfb00bc8fa1dd021035606225ca566a4c94b96cd40a1d54162fcd621aa9337b6f71fe97e67e1dfb33584339abc0f02e8e36c633f2f1b16fb2590fe3f1e9ddc84a3e1a4ac60434e65c165e8f13a2d41b43fa672a017cd8390bb7d11aa196a4148d5ce0ba4983312c851fe5eacf9e3114a2c0b55529d962bd8afd2bd851f76916a820fdae1ec613b6c558a9b8fa137e1082dd1377592c0e984cc899d70ef29a2c1813e13da85a1fb0418d37d3ddb2cf9eb9ade0a6830906596f0934f8a07b4d35c98ef0ac16dbc7b31695898628e97d60a746a18bd392ec11d4e19f5517d4e2fe2e203cb9b2ef7a3c21d2ef99b497e47ec2391dbcaa80bd17846d40ac1b68fdb64f265468784bacf2c410cbef90eafbd6f2530c4e14040e775c66f959bfb72f2729ad5a672389b78e20c1cf3febe5f2fdc0b2d4e1e58eb20dc61d5999fe740cadc6a4fcb8cf55844c00bfedb170e11aba6a7a5969008547d576e2e587b3be212475b1055898879a604212770d3105f5a56dc8c3b4eb34ec17a51adcaefa95d85e6802b1721fd4fbf80cc96a97fecd95e7321682f140f185c0329a1215ef0b72177f32c6576b16d1566cec23d40921d3a3d78bdee0b6a0fd3c9d41f209593688fad5245f361ec846e4380c25ec558d661d1a96621601246a44f7435da1e0c17a5c76b6c013c01f4c5fd566f5fe86cb0f33acb48406405ea1fd54c9d4c08b173ca31f4e7964be64397933733112772f7696c13e4c77d365b862c9fa0f8ef0a458da4bd69e082c7515e5490978c235bfa682feb011232b068c2b65f53b7c640f48eb1ca8f283853f58ca046f76f811cdae126abb6b3d5195b0e10c1e393b28209cc3872120d3a66df7b265028368957c22401757062c2b626197027a6dfeea4db7bdfa78ca89390b0396875799f002cde4d8c92fdbb9b137ac522724cdf226b8d62f5042b891bc48172384016251483edb0a342cb3f0339073382034dca8261e8233f0c920ec950b31a090012e429e616b90f9e0c7d38ee314f0e2fab549b602c89f9a5359ecb3383ea5952767a2fb792199049ed241cf77ff3f95d4713564c03e1e05064e15dd816d5c4fe01bb092b73f8a525454c1c889beb57c507a19ca9ce832c40fe154de70f60f750ff0f6a93d6ab9ab6d282e214cc68c921037da2c52ddfdec8bf8993347b51d8b9a63345a1068970773839b11ce01d54f765360cc99f0baa175ef1f50c40061ae916e62254d4c2c5c6577117ebf3f2dd25ba3739ad279cd2da6515b1c41276e1a06d2d01f1da95c6d05d94a345fab22b2a55e3652d8b9ec02b4dabeeb34ee8935da443f6807680d3b0afffa2044cbb21e6c0e6187329afb925c6007984454bdddd721529f2371e32a44f4f9204e95d998a46200be09107234451c00e6bc1782ed6b0aa7f0a9f42861fb9a6707f1b1a5c6a95eb53d85f554e1122c012d7fe3380ddb915b919486269bc94a0d35f3f648e83ba8dc60b518c2516a882d85b88e0ab3a13d2628106eccad7ef88cb38f743c73119002b9a66ccf63e1d43ae16b4ece44763179943408e9cc176faf8371cf1a45479802bdab305c81bb8bc60c1186973ba8b26b6c505ff81a4bef136c899893ed906825458267733d8e82c8572363f7120187e87ac50dca613d761eea362523c6f0f0810370b1af10db385bab6aad37549a4892e46c294fc8be52d08fefb0ca5ad147270787f24673d3881813ea12d9af74bc2525f2165261c996d98ff6a2f4d49fd0f5e0df6a718c411ff352f02e816097283929a9e0b8d04d1394ba9971c84df63b19502fc501eac645ceabb4bf3f5396b11f8aba497e9ba81b6005411405f5c365b9d14b8a0eecc7e68879e9cc8f8f830a0be7387d1c74e939c115c6ad5c275893a8595f24d217cfeeee670dc46ac7d290b5bad4da2f599506e87cbb85ad02b3b40d596a7ce47e222f4f869ce4d27474b957cf7d8bfb8c41a774b9c1834941588db25381e01e9e4b348d3fb9764b177e168517869abbbb186e854ad6e1dd924db45f209b2725c4a78bf7fa8ebf65e234e3c9c278fe3389637b9822e9997a3dc4c2ca92d3de84a9b84d9d0b7b3d3da23b8cc84afc4de479480429cb5b3bd706bfbc505fa6789d30fcfe34b619cad52cab353e45f039881d29c881fa824d17f9bb7a0a256310e7747c480aad2cbc39dc1307fe6a745eab4bd972f2a669a4f70dd0b7b3ea6d9511001e94414d27a906d2495e0bdcdeaed1cf9637bb7c3baa2a7c546d2fe2cc33d6e1c413e1fd639558c5a0b7f6eebe78b3f54a7f0918d2d107ee5d66d430476c7dbbe6b2cf648a67c7383d8f6f3077600e83754eb7da123c4b5a20c62dc24b365ea483738b2787f85faf8e7d5fd47adeb5291f1a92e648b35ed1e1a5441590ba834d9795bca319fa35667162e36619ad05e9330f91417e56dcd1211d7bcc0a0788858050733b052db36a8cf45927a4ba908a6e9bd4d4359e7a642b8e4b04fd38100f09a0fa50f900cc38c17ac2031a8545f8ef0d77832046dafeab82045226543c50b1d06e2f17bb6e30fdc211b187c0f2eff1e6c88301aa1f1bb3b25af9295c89d782ad836d953a597216a8aa21eab5433cc3e742da7e753964c24f16d192dd4349469bf71a5cc0fb0c7d8172df83f266a9051d9791ea3dbb9ecd5bd94c071984ebd97bc833decd2a876958be46c1160fb3a69d156dc6f115bd08a42a340ed29a3a3f02334970e98f55260ef68e3317fd6f3db464a51c0be00922b6dc559fe1cc39c882222be074dac6473a18aea4eae173a6c2b2ec5ad7413ba60a7a2544524feac01649f21a91c36cd4d85fabfd1584c6a6a094c47873db415484c8b77d4ba121974d4ae5e187a6472d8ccea831341f6bade860481a0b5ca30c331e1697c3bc751a3d0232057ce72998f41f8addb65e402a85b8ab9c23f21640f9af622a94927bcdc90f5587a8b8e0b71c28890405209f5819f23a5fe23928d72039cfe1f5d6726f7d0a2759e094a9e59441ed6f8db8f9bbbdb8536b2035f2e15e95bfa99a64a540a9ffbfe6f2451de72523691c8a3aa033cb28e1c0ec4832e57de8e223a754694c7c4e27b339ea5c67db156af7d008814a10788059aff9a8e1a13b6908e086f1d936480d5367df90bdd51dc8c1fd5ee54ed114bf8aaf981ce214121d6e016d1221604a875a6463260bf25f2644e7d0e4d2f7d5466d2771efbc92e3e14a35a0f4a3b340d2906fe9a2f53e357f94fb4908a62ef17fc5545728df0ac4e4b41ada1653d18078a90406fc352a2772c26e1b6944dc821aae42496cc44ce5e8bd41db705b73dc8136c787a3e63c447cfda562b87faca06fa04841358b96317bfda6afe6021ca0e917883b852be55de822116c0451c0f7a1ba41384133111a78ae0f107525ae0614dd2f53e5bde8af454c804a1cca80d4d183acc62f7fb39f0056fa01c6e0c0e3a69418165dcd7c99ed1b0cb961305d82c11b2ca6ec8a3e430d8a01f75512ff7fcc728b0c85e72e39d6e7e1d50dc26575ceea50fb34a94f016eb66eb6ff15652baf1a4146bc72178cc816d8a868af6d06a6fc6bde4707ff6b454edf6f2ff7982349bac5cf5c15c5d08f6931c25f5fd26993ef1af2be7dca56e2b288ef506a26b4460b0b4434b3976dedc72052419bea2456820cc2012b9a82aca7bc530dbd43887f05acc0b1cf00b463e52db7d072664c6a89bfdcf96b2e250685a47f6a360d4715ca54b5ffc81543ca76b81b599f74773b7dcdee9b6818f4530b3ceead18e337ce28655169ab138e54a9f6abd6ace4e22e93e1f682ef375de5dee554071a50733220c34a2dabf623c5c5fa24deca084303d7c18069bf822a83b0980f59e564299ea541441335c621377b045035da378d51276b40a085ddc1f0c449a05bf2484e5574b69c810152d8ffa0e7ab75af241e90fddd93d1527078a5d85ed175332bf4f5ab6701ae73dae9800bce080ac31e8beadf7d14fb1d9f2336ca9cde62606f77ad02ed0e658b951617f8b81ad152ca59a16763b78b5817b331d67d9737395320308132858eb0023dca151bf07dc2bdd8bab1f2f90f736512d99a0a2437f2d1fc923d992996c158b2d78c6294badcf1a59330e132c53dd026ce430cfe807089f9c24d451f126bd6b8a379c2dc1236ccb365889bcf1e3c18ee7f70e78fa3f446417ef34c3408b8c272557d9c9db9a45d742bd69764b029a6561ec69ab9186ff31ddffa91e8962ade6f633572e43ace5b6834503ecd0d5f8b3c2e3d29b4f78c9edd19c7e51847abd5589c82226a32d8c4a01e6b669d905167cbc720fcf5c945e442f619b45464d5637c2a3202b1b9d499e3d9a7f9914e83a1de304907ccac4ebf23959d15403fdc953514772a33c24b6aad8dbed2f44565136c70d2bfd2c89054ba88b9d416c87f0c3b11028b552f910b2caead587f6ce2737644d0b70974832c52bf354a418cc9c159637c8b2eaf11dcae79900a4d4f02b14a985b7257f73610cca9be9f781a924765f4e3b382f7bd1659a0f7c86e5137fdc5b1334c62032481e39306ad5924743bf0c5114abdd06d937bec0984928660c6bce2f36902c3c1cd6b560a5ea8103a431fb1a2ff83d5e41c165a892c2799559127cc11d84a54c25c946272220f930237e4da330aafbf07037abf08868b66657ca2f282663e4c85f40b0b802d82d98a00e7f819179a5dc28ccea98b9b4a6ef23c6acbc9d59ceee623d9ac3941f5c2e1b5985e60dd1b856273055b0c6783f738cc44cf2f43e8396cdad558df5763abb47c23fa3ab496232ee3a28b6a11425c0d34268a000f03ec919c075caac3c0ffe7542086d14e37b01782ba9103026f16641cae6001d0215baf0bc3bbc01bbc461ec24d1ad97c3f3b6ded6c7e0db89f8bda115f0cda65a49f6e917384d3ad640997986a6f20356785f3d5e94836635df5687199592cecc67a4c0419bde99dba5852339ac15110810d6b88e5bb649b29056f85f206886dd1ce0cb1e0c97dbdd67179ca38d86e5c6cecaaaff9ca3e2f22950bd5ef292039c7396ec0bd37c01a3636a0bfec73c17ea903da0f38329b71a02d1b089b207498cd1cbfabc4c50d58f5d89593ecf205f047e3cc60d432f686f61a38ddfa1aa4c1ed18503a6488e9a811382983260fd3da2526a316b0b781d6f6e153dcbb7e0bd305a9bd752c209101fc5504c096bc153521729f67d58bcfde38a7394badb5c760dc167aae686849bd9c1adf6ae595fecd49781e22e96bdcad7849b33d5e1bfde619773a7cfa12f7a6e2d297f5d8678e4301122f2ab84124f738c360402fef8095e63aab048bfc02d497f364efb7b5cda72635df1e961435526e7efe0d9d04e4a8a81be1c453daa4c5a9c3a03d417be7bd30488831d07c315dfcc3b675fdb22986a9881e6a35eda9c9f0cc5d7cc0e64835d2f632f0439ac6a6daa993b2f8a4fc3ce8357399fdb47b90ebdc05bae3cc6693db79312f982c1839d955a9a815c0d5c9484760ef8240b604b6563a35919454986ee91a13691fffad7e783d4018758f40531fe9e54e9a276a70fe11167b10ffafb51e47a24eb1a68a616f2e4ec16e7f400c404a07b09c71107a3135229eb37ef4f1474e12652763ef746beb97b074f5c54ce6adf461101bd338b08b59769cc43b3e11fff921709a67cb5987931cae8ad9ad23a58dec9b39b6dd471c1b8100ddd50dde9b5cca2458cd76e9f7cad9e00208676d1217fcbbae3689b8e6600e7eef6729688c8fb63c2e91436701055b753ff9bdd7dec721a69f7ebb5357fc44a72fa584bd4a55003b243dc679fd0637e1c9715947ca48a984be18e8afd7750a23e14165e30c48456799051da0b8d4f4c8d24b2930d8bd50e8e103b30232ba5f3edb783222544e191d15d24cd19d278572c2b3eebca7f33174017192a437a13ca16842702d0b37a5548d52ddc7a5f981928914f9febb24976247079d480037f2f0590e65da9e78ee4b2d4e9ecd8efa744a3144ab5ba80fef25ae418e0ca44a7dd9cd1a3d31fbc86f3bd114f86849127fc1030d56979c43b979d2b692f9476e4d82c09bb35a2d917456150414500607d351c64c5d05fe730e7ab950c597a7982f4e36bd9ea7fc36a3948d33b1516dbd0f4322932dee30ea96b7dc7b67cf63e2ff91c8e6f08c5545971db98ac27a478a21769555d4a854f06e11c051c8572bb08802745ad5696538795516ae1ea8ba793cfc3bf851287b1104d66292669b78585914b587a0333f0377361dd775bc642ae5b512ca1dfad974c9370e1ae8866c021b0b23195b5c730cbf5ef3245e0fe279a3a5b7b443b595c27918337eb4f2ee0e448de3ff115c3b811ee2b3bc1773b1b45bd834f3fc9078de3a69dff2b7a19b393d422e645fa4ed415dcd412c3fbeb66f0a9c93d6f748ad373ab036ec440f2c6b577673f106c3ab1f1e75d1ea6dc66de065ba6da77d36642d900a0614e8d42aecf56403f9b1fd308525c4b2baea499ac4cfb8c4bab9c9bffc07939db3475dba512fc436762bd3c3734a807154cf9c67a9a95f5c2c97e1749ebf69349e80bcd71f5e470de7b0963a1949d2ab07827e99df92034858cb024417868a6468ed0c34031d762c3379daa8181b49247be8bebec705c3270cab2f2e2bbf58449906579a9bd88bab35f0d892c66844d021364a9a92ded29050d88360d2978243082cd903442de85e147c0be46ab0eb32f5421752326a97f0c1bb7b74a5d6f2d2c9fd792cb0b91b68c22812428a27162efa1c9aa9ffc0382c344373b11c8b7a1655638bc7de84d9a551a859358335627182e173254bd6050330e9972a713f08762c7255e58316dc2d6bd0f63314dcb45d91b77c65c619980c55bdffd93435ac2f87186a47f563684a6fb3ec4a9d3b4767c43259105b645c4142334694e4442309b114fcfa91227ed09422f95d6a982877ca74502ff44b1f9f92702d175f173e814daa856b93c5ccf439ced9384bb4d4e27b8944147ec87319cca1245d01b42da9f887ddff8f6eea22f02f515c91f676dedb938a5d69f7a49c58cb7bad364230e1dce14000b722a2c74d8334ff27f47912f9b92c8451eb1517701557321dce071485d8d20180485a6cf199e2d0ad72f0975d83394e3d3659a072180958bec75a5204a7bba25e0369cef7b13fefbf8a56576f26b88967fe8b8a91170b8aa3d15136a7a246a885bd6949babd8c58a405f954454d47a7c984d954f3504ec9855b96b3370b168f936bbe29dffa0ac00152031e7cf1ad5ab49847bb2767a58978a3fd1951b645c3dd77f6402428ba271c1f0c76712149b1bc553d9bd7ac5cdb009c73dc67256ac77424398e1a46858933441528803b51be8af3404b835b490ce66a394b8f1b707f4669ef039e969c42cfe02db1816a951277aedd0924d4931c6b5105a32bd59be22b4e6ab5f078034d68a08004ef40b82a5c1bb6a478b0e87bcada8c0dec550fd3f73be3e8519ad316fd6bc83fda5d161bf8a9177ae515926f8ebc7d913ae0f67a7daa8f06f27198896fc78db8a6383088197a3a37b364bbbfcecbf7db8008ded323f56a0cc07a076c4819f7af858291e5715ba42df704e4489efc96dd5ff6087f8c1022761003359c317ae744c30def2bbdfb7fad5aec0a0b140a72776816b06b9d183bc30cbdda149baa3d2db7f69e39bc9858bdead6ac4ead03c6c8a9838fd45a76eb77350cff83378fe4d9bffb1a4dd836865da2d190feb3f260fea40334a22b7eefb97d97a0e4f25cea1951a82ad5d03dfb4d4a0c2ceaa8f9cb5e87beeeaaadb6e78dda86191bc78223fb30f00b7f121720604a73c1a5386800234032294bb01675a550f87ecc4ef93c1566d5cb0b13a4a52684aaddc90e263de1677c2f929425dad8f37c35caf91b4b7486b6705543bec3dfa2d5e7413d9be57bd0a15ecb38fb339e79bba105550400c694b601d6745721982e5327705c547debabb8fe9eddde53497fc7434941d4250f1658df8c5f48c9f8d6b3bfc81adad073aaec067c5b0652f4202c44c63061d0205470e6dcb0af54df3435a105c9cd97638e9e198adfd9010122a2250cab70ad9ef460ad80afdf0d264c6fb7941b1ae98eb856f5c22d603bf4e3b9e5893ef0b6d4e45bb1a062aa7198c18b4150772f441ba0e1e3d96a6fecdb5e6b552106c79c6f5eb9af55d45538e9a95da235860cbbc808bf873252c4c64ba8ebf93304e5fa28491a65a4a2f7f1c455aef647e869f3876a6f0e2089607d5c2ca02b5e7553d86dce206fd0e73d5645a3a357a93e0287aa798368dcccf185abf5f0814fe3e1375c70ba4dc6bfc9650308c9b2ebfc97f8413c16798f14b61605a2e5652748aedf3dc096e75cd30dd7f628cf137209f98f2891951e9a87445666f9cf072b9adcb7657cde8c1aea174751bd725a6d66ea81bf7be4207c02b0899898b31478edfe37c0b468c23da10b7f3c6c58013b3fdd34fd63a6c69542d034e408e10650b8590ed79ec5233b4376a4b7928972ffe5a2e47db9ee255724701565e59db9e6accfda1dea238d3ce241729800956298eeda48a09401389cb7c073ec550d689acb77f0544033639bc83da8ad34fe17d9af84c9190f009771ea49c5681c768bb1b73adb696f4b7fa9873d0cfc4b4f65af5cff7847b6a0c1c66688a3301803cc81d45988b834e813e82c131f59393cbf84a6052bee0d2168ab2e786c5303e2fc43caee31d817b26d67cd543945288f666321145c814bc59ec8ecc36acce94f079b4f926771edd4401f32f15b834ece1529071cf6feb7090d7e46edb25d086a4edc4c3c2bf7b5d7206ee16cb537c2ff9ce5152d49aede2bed32d8f1048c7a11266f529fbf362e16790d3bf9bd32ed5b80bf9e0544e52032c04757ac0c8a4cee79be39e34216cb3cb275f1c72656a321174113d6f0c735053bd9bc22f942eb396103ad19976dda935efc39ea08935b3a9d9bdec0b0867a958784a5e17f3c6c6ad788694f1bb090b85e16b9780eb30735984a6db55345ef4b6ad8267fcf7488cf4d2beb1ba8299f6c8e67ee5b7d6904662338ee8aec134f6818faa2000d365dc17a5d99045b71aada01e413058fac20d394601487be037e011a6a9fdc57b4c7e2c53431b32a67ddf6e785451179f449bd7eb14bfead1c0a082d2f4afd4c22bc4c38c2bdf9dc3351f797a978dcd951f2c2ad558bf2343e97dc29d77a6686d00181b5b0c10b4e48a346cd5f75509ffa89aafab6d37100ea80859850029ea6a840bcce9d61259bd1af41537100ac32381a6316d1daa232ae08ab43651bde1dc0796d1cd3aa75a376f93fc1907337899f93055987e03dd856e94888a76cfc54685cdc63960ff12e5c0c4b88bcd2c3cf9a7f1f5c0798aab0feedf35b98c9e1b01edea4ebb6bfeaa06c2c902eea2c710fe438b01f3073bdd5bd50a26dbac265b480ecd3af05eb6c3c2faef454dac75641a4ea7180e513f4e766ef0189054ca4d418d64072810fd3f872601914006c78f2b439054eb596a5a69b42d82924c1d9b42d0eb2ea404d72479b5b3103b2b67af3167042f2ea335ca58c488c5b4766fb3755c7a5d304482861079e10d725db8bf5ff3767ff9351eeb3c262f643c6373c39c35fe3e89c98e4354de2608a139dc6f4801cf4c758cd901d780b5c17827bf77e6a3a70ebf7abdfada3e4afac586ef740074603f5c30c4677b4b011633a458af7ed307429ce4a1d624337d5aa2ac5dda9506c75b684f172f3261c52e361748655bee2b187231195616113e98594742e214c0d5b4183f435b22fdcf278c796068d73c42ae47148a0987f2efee439cd877f821b5a5d4877914062853abff73872389b3b86f3ad1c9d0ba1251b011f94cdc04567d2a6106ec1f5e3cbc14b362865f2bf2857062b026a90be63fd053e72ad018388b514d70f4ec5e2fdfb89ecc83ae4a2d6fc7b07f1d858b8d77191eb5abfe8d7b5bd31699e71aa8daca6e5c5a1d931cb14bd248ceb1f6b3b4ed9760a5d24afe9183f3db2a8a6bd9313519684a50754c3e4bb2f82f72d4b5084f8a213704ed021655e702d2fb40de585763c9f83f72842daf453c29f447ecd101777140b008250c3749829261d4aa22a1e05f3bf58ddabbfc56599f35765c48268679ec7e191f8302cfd785f881a024853c3dcfcc167e1dfe2bc329e2b1d80c4cd86bce604fd9d39fa6b4258f1fbd2ebe3235c4f94fb6b29327c216836b21c68f620a3a831f84d1717917e82efdb986c7e50c5f52716bff90c4543c46f797fa1f4c7cecb9904218bfd29034e24b47cdcd12f8dcfbf992df0dd9047a4207df5e4f4646e5a3b91135eff56c67fab9f1afc971c76e58db4cee5223a4fce868bd78b0a85dea388c98c1c0c59e027c5703bee082abfef93bd50a4df43aebaa0a47950e95c70eb9cc7dabfdc1923dac2ae8e14eeba7184c0efd3e928ae672bad9299462a27313761bf07cb6fd9bb82b4e1e83ddbfe80fd24b87e43704b8b2b12224ebf46e06a283c193204880004780dd517c4828392493e295064522de64bac054018a0575072d4d59896402e1eb7835a04d768698427faaeab8e113bd20b632dd0fcdc0e949ee90f860c65b6e3fbcd80ce01ff902960107b90291391775ab66242e5bd566c1dae39a0935dbb1d5c59a0043d3b8604d336de836e6c696963afd7a396653b9d2eaa5c9eb1e8c782478328c8ab73af95dd17cca6f3a990bf44a7096c321c8a5c6ba91f3f53a6734fc55cc76726c735867b0e198422edb9c032aa15533bdddcb46e2f1d87d4a1cc7953db65330923031e2e30c8528ee2a8350cc55665042d853f9b9d5d13494c77358adc6321dcab12095a6d7489dca6ff799ac631d4a27199af698dceaf7641108ea72d58678a7dc755468932c42d3a27ad2ea8fec2ace80473ed13498914b18f7f94b7de1d88c7c14a4e18da5718696b208232a5a100e9ac088e9ef0aad38c52b8d4c9aa90e66c8cdcd94b5e595562630986fb226fb992bdcc41bec3411af53887cdd086f6a5a0f0d12a6691ce4129ee2f6ce1d63e70dcb21081986897423bc285196b86dd1575a142baddbb9f6fe4858692a081baa87e0c5ea12ca4a2a6962f219e100ceb4f61dee0ca19108939f899e25ae235d8544c62d9d49ee32c12e4552dfda46fbef5c3252ecbc5dbd4f152b94ca969ec3393187a01e5ddf2ba907c66c783cd60de1c9bd70b67e616484442d384644c088194f30b79b667a8726dae7df0cd20dd1474f6a4f3b8de1f28d7fe49f488d846e8c1487adb2cf7e15e912d7c05cffb9c4c90924f54459399d130c96ca46d0e8d4080195cee335b545774060cffff3f6c3dd148b9a615ad53153726a9f26d0e90d56e396773bba3b4316ac43aed12cea631eb5e7d18580f09c9b52a51a3a0aab64daa9e95728c35388271df4696d8a3dcad6d97aea7bb503c2c0a5ece895f2242c6268d0c45fa9fd7bc3cb48730609b646bc78c2508ea74fb6aadfd088f032d5cfa5570286998674d4d7a3cde4e71447a58ad0af7e22cdd22712abc48b46b60247577851f860cbf5df76b620f91eb50207b91eb0084c9e486751e020bb622b9df9ce9efb86f19b39d549f33b13d3889fe2a93e3468cdcf693ce324e7d344bca6aad42f0dcb71bc4845b248d8c1b4075589739a18fe4c57f6cf12774a652501a59551b916754b5a1006d55deb159f4654c12647cf114dc7d87a3dede103321c528777ad98fbecc7082d0c6942fac5f376bd6f9f885764062250cc3a46b5d2cf779314fb469f3e3d1ea1f33115fcd0b3b66a4dc46fb2172f854b5fd7a8df091223f2a365ea74f8fca2f1c1a706ad0743481422cca078a5dd8806dc016540f61129d573a8d49c2cf94009a21f80207a952ed5bea81c7828542f3c15b6fb92ac0668e74ef972a6bd9e6af596cc0aff260868c63395fac15689a7cf15cfd8945b48a30a6ab33a14c2c68c5c688cb9558e2c5859d4f9ca6e525fc011f17a83d4a7e0e95ee7f301a4ea4df5acb15e6172c5bc199231654989371c45781f145a3d1bad8d4d9314a7cf3df9f88d1e07069d20f659d268c1f61961022eb647053f5ae392eee5264a2aaf4a54d83f4dcc9e6b52ff9224189d6fba2036acd0bd8b5b5dfb58884c81525d643cd4b799f4a3ebde13d8b5b8bbc98a06f73257d9d9e116979b3684ffd16e1eb4ad6bdb0878e6093005aac8883f6917aa03d0c512c7c18c2c43b3558f9d410ab214c09357a2c9c1d96f8a24a7617356258b2cb43723bb1f5d7ba9d642649d5a30cf6575b9d49782c5c14d14be0c4db727f513bad8a62eadd09206d55ac7682265a8786055de5477131dfd3e266e5ac9954d1b46b22ed1f5b99b16e5d3e77cef0f39bf86222e9d72f025b41311e868f0d964d2f0bc5c04a977b477f81c91f383b060ae8feecf706daba4ceabf7a5cff8ac45d7d13a0287fb17805683c4483ffd305e827173618aece14dbc22c814be766f0bb78043c26f10babb678839f9f94a5d25b0196e58a1ff284f5cf1e5d19a34b5a7dddcc7ab84381c51ff7b2dce0c8a62c9a2f01631d4f720d94df994bdb325b9186c71db552cba32f335d762a42eff36ba378a5ae0414533ad7058be210aee521a2be853864b6ce553590692b1ace3e8a26f401a89a97544d55ceb424f641b28eb1e7aa9a9841395497348f88387917296619aa86e0970e7bc4069889941cf236ee77b2ce8da2a0393b47691d93f19d33b25e7b9ad847c4887d56819e4d697c3bcf0de7717ee50227656ee714b2652332211a3a17e48f58ef44e8241f32479c01685becc28e258a28bca0fed560496e5bbb7a9d6d40cc8e25faaa82f5aeabc9c0078fe724c34a244a44b005bef617d00cca2bc67f7c6eee64844cf953f6e0cbc28c0c51caf4383604a2f04fe6b57a3a686f99a7bd16789763825f905fac86baa2d1403bace9657669f5efc29f299d3aeb24e5643e1454568dae3d15625e92701c40478e778d0bb0b76f4f16a11a4fe30adf8dfbe6f28278d11985891fc17b8cbc693f135424adae9f8bd647ee1f8506fbc7f731b5689cba3db5d70cba6dbe495f28fc6ddb93fd1c8d87dba7620a3b94e87abb84ffb68e175e03946af3e8045ed8f85feb4079cc2428564714aec173e480d78a3f263d6070580c9407af7c978d06f118cf5495c5334e0c25352ecb8e88892ad8c04b186b2d9d4166df30581feb86d112c71ff2f7be33a6005d3b17c9f46c1802d8af5e7ea9a057bb08cb4e26e504226817545109449a78e2497ce1bfa8ec779679ab215bcd9ec55f9902415e0ef4c907aec61ab1b4586ab1e4e2c7867ac81e45dd662bbdcc64522bdb8ddc996b99f64312d0ee3e8382cd0f9e87cf69e2046d4f204ea0a5608b2755e73640f74249d73c932c78df23816a5ffbef2d4bd16f35244686d472a42d449c93db900b226e32bb111685d4fa8bbfd2e745621ce52fb232ec0c958b965d9e010c17636690a48c93e69710dca2b2043898894331218a7bc7c2b046f26b3fa3370b5895b22abc3fc380f70c6f26de1c594c69af8a972f4a0bd32d0d794af1345e26f3ce2a1e08fee142d738998b8e5eafd291613407a74d9ceae22decd2cdd3f98eade8df3c155a9e22dc8bdf98636a696d5a1825cb04f4078ce2f4e5c0c320cc9574385ee5699d8d7ec32b0e1eb142a1780481c65fe53bb117c27bb812d1e6f7876a028a388531586960557e94eb1cb5a528844dd00f1a64b59f2bbbf0606d99c251bc64d6285488df982df96a3df568ed165611c467e286bd3f84febef8d103a00d6d99be80ccc446b371671e9b34d65b1a6447b6581bd5bdbb8411dd6d156f6005342e81e57be1840f4b95a1578deadd02b767cd058cf2979e1fa2ddda67372f3949ddcd0fb356586d1c610d6be654beebe1530bcea341c9120cdcc52100dfeb0449160aa1d1f88014007e34bbac97c0fad8d7fca14821bbc8963c7d9b20a4d48bec4fc73d3ee8ecfc313d5cf1ce2196c8c0367f6bd0c3781254c407bd3baaa52b666e90a599f3ac5b305c38ee676bc17894b23fc7100761c52a9b03b685f8fa5903e687a61b71b5928777018ad8fdd5af6abfbe987d04b84eee987b6a2fc9ab1f8455ef5d410eec0e788ecf768c6dd6c01c481460607d7ef27a2546f4fbe4279a398fe8c1e498c262bc39e233bd11aa8de958b971730ff899bfbf765730ff6c5aa37f17cce3a788e17258c681173c48c3d4cc585b9a33bbd4d259f1e19f035d5884ca5ace710d8f796f98057ba2f9c3831661fee3d3dc4a107bfaf9c51448e1becdf02aa0ff195df1947e7f5be0faf9f423b77b3ba1f425bedbfb4023f8b5f2177406a9c54c713b5c382dd48e118a9964666a4e5cf84f87052541292e0d48f97aafc3f2490f72764b355c7a7d528cbd485a8b3c20fbdbc83bc3ba27648b0b87367e2dc9c55a36851b103e88880702da95cc004b29985d43c30752f36d73de35718eea9ba37e9cb82356d8d20a3005e24ec9d55622be4fa81f5ba40c3eb7a51b9b4d4f13fe9c8219e7e10d77bc43ea7027e5d1217f3a867c1f2ce0b3c818aea581987d28db5cd9ef41c98df4b5b92eac3e139a9ac618402af4ef436bb524109e9183e2201bb6fdcb7a541bae7c46a5e8a077cd7b20597114dfc4f3f5dfb987e3c0b37bc363295966b22f526330e249147da6d6689e8adf1862db8d451ad8daf18d2fbdb43576baeb29e25351052cea83146e2d3b1f5451f9625b94e7cbe76263bae6fe2c8afe81591a9d14245a61060eba7b0b226176041af36f5bb45aace11c416e5ab29e2e01fd0ae5a7cfb96d8a9af4d8330d49d62fb3263f2a1f4fa02bd09af8bdeda314d09a7a6450f1059000b94c4826057183aafaa3a5b6ba60b332945ae58ba507d1fa9952d8d47726bacbbc60294e4f228293f30ac58efe02b78bdfb4e3e4dae554615d4ed5e3509521e215c79cd0727093bad94ec3270c791a8782d255c8884d676eed0eb85ad040a43dedf817e0d8309e1b66790c2a741448d871011059b70bcf028fc03f3cc08c7096a3dce71d1a5d664cf1ae52c563f4321bd8057f8e3f0f66c52f3d01273b55ece825490990715e7af509be741028f1e2e560c5966b995a4699bc51dab9c975135ad4801aef251c1469a0397cdd5dcd5ddf82527e1512d3300be9532a6b5c4a6fa9dc484b12af2dfde23f2ebce2f15bbf633b6fd7fa99884e9b3ccaf369dacd49fd3b2be367684555f6f7e0f5d3bdbead96bc08baef871d8314abd161526f2a00cd79a0794e4e84284ee6c07fb7f326c924a14a52f7a7cbbc1d0d7104bcc8a1617565656c16574d74d1ebac310bd77e615b6926a3c55220bd025ec25d03bb483775cb5593e8a85d7eb19650a0d8ddb29850ec763a29cc7cd9db4b906c0fe858ef82948d905773279173dfc083a65b4e004e847af5fdc19707bab8d139f199f868a376b64bad0b672a761ac53bff12abf97fdd50391217c856c90193ff61ac9bc228fe0d1ea8d7bda8dc8f4b44e4177fff8ea45a5fcd003c240012375cc5e99f43f8a772a36363e9e1dbdf464f4a8f21897034e032da292a4664e9d3ef6df3b8ab0aaed43698dd2ed8ca48523b81757c7ac9be32793f382003ff5db539c63c3c84819b61d9cefa6caaa55d1383b955158319b9fb5af29b313aea3ee51dbcb7d8e2340c6ddaa4ebc0b719b69616be285216ed270ad56a3acd9c24e5477da2dc15a63c7a76d8cac6e0465f2948fa5322577e5d46ffa46e83cc507d9c68dbf8a48a98ed16bbc1d5b2252f3393fccd292e568e61a0c80e23bc51a46c3c18a50dcbe8201d0e5591bafada1f2cc855ddee5c96279d797aea7772eb8d5be7246b0279a452b82d4b6cabe78721b135758479ba288eee9842f4dd97a621df794602258e49ec9a7bd865e493c2b883f9f28e548226f6765b1812df09daad32bd8508b81120456ee50e52018c864c98b676e387c57e38ea23190ce8a74353f502aeec4dbdbaeb7abf028a6493e89ee81547d1c6a2821b38a921054a70d6d34dd076f5da7d2c5f32367919f43cfb698b460780b399277052094fafbebcd6eb5c6c76a1a54f9f230e1c09e1ce333e09c107319d70d3511bab465f65374b2613f1ee835a9df49eca2179bdafcc3e3bbb4cdea1c86753b14d61fe111e2507a6b742c05225ea80aa38514c15997a46c7c84fc6e0f0864bbdc5a3c5bdc10a31207a0e7bb869db8ca2db1304ed7910770ca3c346c322ad9bb63a36b88f36c50aae4a039d0635e5089c2bbe9d74985c5132b3ff7f6dd73e6cd96ba98821686bb799a84ed382053cf1cb5f72db5f31119b3637dd24acb987a7e44b42104fe55b4136218363a7411e184f6cbfe66930516a68c584991810e9efcc772d3c7169741c95364efa960ef77b42fd5d6eccc29b4e701754505ba84ffda87adcd101ce866fe74d8e0df038ececb43aa13f670aa24ff2de52c14b4d2da0b955497734d41f33115e54ac8f5d1dc9f881a5d37199b9f7fab816d6f385fb2e1ad7e12e653b0913856637ed7f5b54c69ac492c737a8b2d40ccc04c71d6bd78614ad41c5f851c91963216fd8ed4abfc3b828647d1d68924896bf9d6480339a9530e4ade988c4d34369da6613ee82131663bfd50bebb349fbf471616db726deb39d8f65f6f20e7183260f115b3689cc38c77ec868d599857a05c93cfd5da27b973b29dd165f1bafd47cfaa7e1ede80276ca0e52db20ddbc496fcdd35809a0a27175b53e0ed6686664ae46e9d4954df092a1d7029edca9b40ca383c514b00caa90517b04236f735dfc95c5d36dad4c0d437c720e0e3fa63d95c0c3e2f4680125cf08b5d5fcdb92132422ddff19578e696e49832b13fd87721ba6a762e8a24ec0e4e34ecc1facdfcc7d1e42f1cb5c7b2a4d57fed64d71b2df9cd73567c81534ccb4df7955a5ff949029a887800a3977318a3abd914650eeeb1fc6ea60b2e9633ada4b01000ac904288ae4adc9c875ace2f1fa00dcf96adfc031a708178c6f141fc64b8a914d4f379fb65338b0459e2535fe0dfb18630529afcefc8f59e1f4a40e572487e66b13af121fd845c9ebf8d2ae05f23e1ec74b46eaa3c218ccc478c459995fa8e6616f927e96ee0a1f5c2b8a6a1bc011988d33488238cfecefb3fbdf0bf01027df81706d579411dd8d36ac954d0735a1580e78f1c75be082d0b069e2f7154cec9529c6a473ab51581357cc7b7b9d358430cd6e02227007619423256568f3f295d45632c7820c9d245390c9543c2c48d4fae830395cc2e334cc94a085e5a79b360b89cc421fe9454a72157443c8f811a9c18915ca9f7344ab4686ca2a5296629f7ee7f119c67dd5b12b742f16919817389265f66618fda5f0f222932d93cfb47dcd9e08a37d7788b56db33e52b452b776e3d41ca7b1a7c4d804cf57f8285f39155c5961fa0d836b3092cbdc2ad20ddf8e558812e774d7a0cd4454e821e3b378d0657dca64c2b3d6b08b9a84466aae26edca2339bec2087664429cf17ac833169f980f117636c75b6eb3bdcbcffd845aab291660337640b812c35e1ec1d55b2dabb8bc29d225c3a5d664a1088428e3ef0fff6e7c356be2d4954f8038e2dcc2ea38c13bf431f068a5d10ee276c3171edf00d5a31fc1af3b1d3928cf2f5b0d9f34a7fa66569bd4daa4516edb52eac78d7795068b725a629651baba19d55480529612cd8ee24c1a4e9c27419095a44ba5ba26706133dfffea43c5deb6900027c6222e3c7e420aeb61d75280da73c48f1f713f16ee944324900fd2326f089a10d1fceee22c12980466fd33defd218a2e3e8ccb2c4224b041e352cf89579fa6db7d3a1095caccf56b1e006e16cca63ab9ea953d2978b50976d651f1b3122da0cf0c1f342c187da90a43e39b83c393c2b7d297f56b495138a5d68aa6fb6bde476de100374499f4d037fe32c7a9e1e22cd24023afc5435a531410baf3be5b57e6144310fb1c20fb55ef8ed9ee9d3415cced7df2d0f2eceac0f31f99b7b329ae432e1c777e5b54e13f5225bab30c9dd9d4b230a91bbb3a30304037f29d6154b2fba9ab213e085981ec5279443d779f60f305075005e61acc8d906f6e46e688e394b91bdccb59007a77a46e4fb60192bfe4917fd93b3b458bc4785ae898fc93b2a33f47487f316efb4e42a62bd3cbce5c7ceb9dab35cede5bf88aa3fd1bb8ab3f63e5509d7a4f3cc07c4a689cb22f23f21d254da0859390b6d3d22c391e3fd39b987002652b12a80b53d2cb4b7192d15c5d666435e2aa7927c871f5050dfe2be77f988542a60633e3cf5058e82f626c9862967a8c1009b51070190c97706db284a39f8b5ccb65a86626684d11764db19d5a50a046523609823793862e48eae9d751601d5ec5933b25fbf1d0c26b8fa9a96f5cc2d51dd22e19d7e49bdd52fc609fba9e34abbeeb295fc3a0f82d0413a9870ab247b119f7cd9047e7017a781d136ee3404eaa2cbcaabefb031ccbfef905de2c5033a7c1c3baac25d00f499b980da40b34866eaf2e201cd5825b49092dbf5a91d019eb9977ea16eff59bde6f66035aacb0c9f47badc599864dfdcd399550bffacda28054755a4e772782b6c63cb5b5507c966216006688aa9a5d92bbdaaa948aae72f94f32e612c0dab450d0999287f3f163ef26fa51608a7c751e667165c2437a4848a28a70e8cf59996ce702e447743cbc9c2bbdff1446cf07d1d75b44b8fe0e4086976642a5c44a54a2c60295d211f1735ff309325eb80dbb3fc9d3fe03e3aa4eb7f490183f9342c2c0c956a1e3e34e9bfa8536f5297b7d1a6fd828e1db9e3778b57d9437cda327a8bfb5f72548459262d79ac77651f977875b6f8096f67573535e7bae6e0f94d2edd85341b6dd4bb9dab5205c3c3c1bdfc915fde270c73e968f42898aa2d50ba7a8873ef4b0aacb9d97fe500975d9e26e13a794967061b126fcba2aa1054143c5fe04a559389471022624b76e17b5a1a84aa4442149255122100ba684093b63ab9df4df87fc97a0652e167d6c89a6b331e3b580a7ae42c104b203b46c5c9997e5d7872f0952ff1243e096b25ac7885072935df7acb893203ca8bc4e129c5dc0b3e78d5169f72d177ea2ff997ea0db3eec5e95e1f15c16323627e00f53c4e890d76e71023352008c50f4128b6ca7ce0d572e8abc0749d56912a0de4551ca0017bd2f3f99d0442cc06ecde04a2edc39216cf063bf58a570561d99038a25754d8381c458a82af2bd7d6cd274bdf3d2b6e359123bc94b4ce27da5cc7c0971d0cf7955a679c7cee1bbfb52211bdc9a444b7372b9dbce1e0f53ab691200b791ed17adee5c1daa01d04b3ece787e5d9172e82e4395efc1a5f4aa446fd2c7c7c0934ec613e79efd902fea7051e1b7bbc7766775f3956962ad6c0cb7f98c70689fb0c7b11f3a3c695409a1333df5e55febe174de2e655b704a49cf749b693e126f1c63120bb428fddbe6aa17ba3ca215e72923795777233ec02477f9e7d96025189edb251a0a620a176ec9c685ad13d1750363279ad4a278654889f53dd0e4a5070314cda33b6498672356cca09ba700c137c2c2c7be5a294acdf64da04712ae339171e5315461b42acda1508b048812e33b6d773cdcd4714aeb2d2ba1ae2f720d988f5265f9d1db02f633b69cc1167952053d7ed34a25aef3dee97b2c3769f31a4e96b0106f5c56be7fd022b2892eb061ff9c6063fc3996da124ad876caa88af52fa60e835c7ffbe6bb1150b9758d9d80fd9bb6c0dd9c6c72e823fc3cab68bada4d73f944f294f74f93e72275c7b0b3949c86d5caaa04996c82b2ae5d97eec60b43d49d2ed50d5c0cc83411cae31132946452006b162a3f5fbeb4f192d07044f119c302a726d2bd9ef34aec9346787f9a8d8a9640fffce7f8fc0c855825becb9f6601b5c5097dd177a2619b6264ceb33a60460e87400374871ad0d6d778c5610e724982e79f48183620d1eee38032cc2d80f5b1fab6018f394d1106c700a23b1ce19663bea1640e63e2fbc1ca963a8d86e2334c709d53a858553cdc1bce4677cb4d5146cb2e9e0e4b91e3cbff71ece49ebb51abe858fe7e23c479ec9af218cbfc82c538a49ff08a8c593b66f42f778ffb778ea606ed0255b89a402383fdfe48144c7b75cc3d93cdeec0da7bb6c530f9e791f3645a5d66a69fde8652fea5021e4b2b90514db9a9ff3354ba3793eebd1b669551abe6ac800f4240c2417a27a1c5c9321ab112aa134d5ac3827fd9a9060e9a304a17f5ff2d05882c047b4f29f819479b64f07cc44f192879e969aaafd8d087bf52de09f569cb0a0aef17f84fd8f1941802dfa65af0fab6d939056909f3daec998d9fd1e009ebd925a6548cdafbfb8aeb2234095d062b1a942dcd88ade01fbbe91cbb992d93774a20705e1d7f1defb9de9b143982f2ba0d51f00a66193e6891d963139d19140f48080b1caade92575f29f5e66264cf9c6b1016225bc9fd0a0caedc272162671b9f9dd568c7adeb0a5a15caa116b0f7f3354c043f462e085fe0f41f996664b5af40674a3363c0eaf5f52ac57f2629a7d4dede195e53d56944110e493fc723d673e7a07c14f757513662ead83216804c432d1d6b971ea54a24f92bf7ac8fdea6f9713e901c13ae055081f9498bb7225b7bea16cb5a02071d8e01ba58dec7784d1a10423243901fac2be019ef5b0d1b149c361c66165bafbba92818a166db6a025128c1172c8411a73f9b5f8e511ac4fa625c2d7d7e0a96d0dca22056b5e530ad485906d36f5f0f57394a71e11a46434912046dba58ce39c630fd5a922db0611991d2452cf5f65a360f52febe04dd0e9dfb1c75c5d4e5c48bb85267674df6ca5dc0599adc2724bfb0e66821fcfbaa67a85bdcb30e30386e17e2a2c7ede62a88356b2aaaf5c27b7b88f411051e57dc906fe3684bfdc9876cd1b14d910a3ce952c0e25f46bed8abd16e1be54ca8246dbe00835d12869e19254e07f83918bad81db36e05bf696f97b5319817e5d8db4ccdf53e830697ea6b598390d2efb7b25943cf180daa82f6a57ffb00c6a2244b491f2b3e7f8828dcc0aff37b004ccaf993eb3be5bad63ec6ea7e0f1b9f6a79fbf86c014948267ae7dca4dc99df8093c2a488f8d8894588e2c9007caaf6cc1288891a2fb0de93e0ea9462f9c0414526a184758995aaa3f5585791c6fed294586e87f896ec1ab0d77120eb67ddadd4abeb90ea016438192abd302dd12547635c7bb979e923483e0923b5f9c9ddaf3dd17f9c08454992073286139d1a3707d1b8e77f01cb484a3bbaf88db5e09c6ae780c0c43853b5168931ad887c4da89573611ad469a5b5ac259d17bb7c8f579be920b3822cd5d61795453b90e791f14392ad3a3b95d06e5834bd8c17fa100ffbe56984fda1b4d2b02b69c46487427caad61163726e6bf8f3308df10e37a00fdcdedb21f2e080ebedae4ed84cae85560d4bdb3580ad45f2b1e6dc942c8aeba60f2808cc5a72ff6aa3b6182794c607b30984371f8283bcc8c024722d05e78a889a81bfb7658c9df09de9c49ebb20ac66f48000c2b3df1a6c4d8e7f9cef3a4c4bac797d7b7a3f11c9b3ec95cebe03426887bf0fb9c94b3f9a763c1c45b0857fe2e8af1c7b742d98ffdb34a9e05e28120bd1fee9ef5b713dd49bd15310427fb876bc2f774f97e77b3b845ec46f0afef7c6b202062b2fac8ae24086726402413402853ecb6adbb2b8f09accc2f519bd2ca58f9b2e55e6b24e15ddd5d28548849f34c02564bcd1dd558aecd0d49efe2cbd09b61942d5d40cc6a80a843d70753cdb41c5d57a9efb2665dfce0f80b4452a0f996e4903eaef1ee9daf0e81c62625c919ba0d817522cb0d897695065d0587dc61f9c5de0db109afd99072d91dc3ee3aa914588f51330e14717e29cb56c4db9396dd415f41db5d8341e337227121009eb58633ccde3f5e9b1c52d5ddcf84eb59f277f5471d88844eda25ebf185bcdfed410a265193e107049751de0bb15c8a8a7cc70baeda47dc8d2361b94a0e783fd73e451deef91963a916f760c24431ab66bfb7dd8b299a334351fd62dde9490d041e723f05a7966288f52d1cf995e2ed0ce40eb843078d51b818f2584d3b389c6bf57924af2658bbe154a7b6855aa265ce5c19d292fba368ae9645eef0c70aae64753bd310b4591e4a3dca63ba93e745949808c5d661478eb5f3a54534cf81e39475170d4ed12e72b56386fface54670226a4a4beba841c77a73c9d9782c897ff7d409052b02c0f4d09eafebe49ecb7bdbe163bee5a54299871a5437988106194c2346bd106543564a793e705085924d696e6749de48f01c5d58b6be5906249bdacd588bdb71ffe3278a82ee89c221b4931b26ccbf8c0332ce9030bd462b9b4e03d7fddf2af9ebcfdf1a3e145ccaab12edca003c0aaf984e60569d3412e390bbf5bb4d2e98a4bf93f9d6ca8805eb1becf2b80235daff9b94349f8ac9f76bb1bcc6b64aef6079168f40f25cd2e28635b0cf07ce6d0c5ab4c4fb0272ca0dc595dc18a430adf95a44f63eec100d583167dce772b8b23af3a7d1b373ac2b958f2ece4fa67de7d5194320468acffaad11444dad8957628b0121107d4093b6f36b8d3352f6799722bd30fe661b53cbaf3dcac1e8d41382071eabeab2ef4ec956eb8745cb762d1a80fa976a437305244f2a00d37aa426b026f915579ded734df4ab05e866a5f991924d99e7973bfdf8deeb95f4d7db1b546cbcb4e8f902950108b9029039201586c19caf846cfc37b855cc2fdaec56e0446a77542e8ec75d778b0b2b26b7b4467f915505cfd28c203ef9cd37968c6d6bf518b41708e51dd37127eaa8f5ed027d1b57bb0648f128ec9fa193788328d9abdb08791ea24c23f17330d397b812eaf02687751f97125f2f28aaaa08836aa1319a980a28d589220cea6d68dee3f19d337dfa1967598e6e75ca842363ffb4c9306c2b44dea198dee6093dee576aefacf1154b5a799b6de181cdac389ff206b3187255b848a0847298f5a41b5d168446e62c837304b0794a4a0068d3026709dacc7fd42cd9c2738e2deac7abcb356e5e20ac63aee83cc3b0ac9d8ad987d4587964462aa74db69135139b70ff75d0993119f89cd8d50e56da6adb8685519ea9675b8b9cae77aad2bc5281cc9fe7598d219b36ee575b54e7de508d4db392ea74376c2c1fd30875f988fcd2e391bf47dbfc7324acf3a3e5af08a02d3cdab48d5f73165df7feecacdc3fe9edeaa9e05c28d9e8672389a8423db418d1f2812b6a4a8cd77bea75748fb3b08cc40fe456672a286e51f47cec585e079a3ec238e58d23d9cdfb9377d3f72628ff44dcb65a5f786c30b45b90cca65a45a53b92b65ef0a85ab06882c6e7796a8430bba8dba5b11235aed6bf3d56ca9d495a4d056cf394d73cac5d5a1f4aa33ac73ab9ab9b459f884cda7c16d684bcca64ffcc8a19d1b1f09168e50a310535696279ebc233fe564c9cd8e0511384a9cd3caf19e554db676b6e9eabab5a3f13adb45a0c1acebeaab5565dc2803db38d01cc90ea193742c4312e4f4529a1d17ecbd66165dc76f3d27970e35059e44986264cae0f0865e4cae5dded9911c82c2fe7daaca55546365d0fafa32bda0036bdfdc5c2568eb65823e987d19b4c0bb5a5d59a6d9a331a299a857a19073f9a249a05cf268c9401dd40f91eb50208b91eb0789f88cf32ba141641bc694a80646b08abe1024016a8252bef09329c0027113d294fa7712fec74fb01b1785a3a932a0dead3e9cd75b457173e5ae219cedbba536150326a4fd5e74466d7f6dd3c8677216044f892f417700d7fb6f303bab71441655be640396d239db34ad202620c6c1e34a227c9ebb3dfcfa58310d434508bf550a000d8736ca5476fa7af9f8298e92b53f8a3a8c91d7faf4595c9be2eea7c911a8d2a07af4ec419de3bc601f1d035d5d113b718054d6c3c9ec976d50499a88027b87fb1086380e45b466a9a6863243feb8e66893d28067e52b5f642b9253c967b32516e9943a0347a1981f08c16e319aa4366873486d933b7e4d45e252dcec4aa8a5f8edf457d7c5defde34af8e8186da9bfd3822a2c4801a117ce7d10c2e77ef0f625f2a1eeca5bb84906f6471cc36b7f6f01b027237e23738a5229714afe6440fb767b99b1f6a9fc9cf658bf354ed01893045fc9a819f44d8e6902b2b056b6f76eec6f1c3283b6d65c0cb22be8f8b19bd7ec3e1a2f387ff347304347326e16408b288e6bf268e21527c2441b1b927d2416864b1cda8e2e64bd52009fc888ff5cfef36696e903da30c563f74dc32b8fc6dcbeb4dd0f5ccc60cc49d4d3529968e60faff2c832911857bec3657c990ef25f8b1ae324d817845ffce334835d30d34a541e3c8dd463be2c4a0fed0de142e3d265afacf2dac54a6b04d7baa23458cc3a154b4c23d8fe3f166e85f90b7f5e075fd708059d98ead408465214ffabaf1016f6c0f3cf9839457db3a4df6434ff8daba797d73fe8c34b95aa9318efc0cae6aab395963cc5313a25cc8d45e636d0006a12f0c94d0089b7717e715930909448cd45c784d8dde33bfb9b49c76ee7ac8ce41f6051db5013c10771ac55e655116b7aaa039f683cd880d62e63f32afaf10b193a9ec86a7e545e05c6e23bdf4595dab88b90d66205cef0b93c15a0197e018790b9ccd19497c90fd52b2bd70bef75fb612219b57bc2f9f337e9a2e2523c8b9b70ad840019d3ef4ee7f9e135dcc8c982c2a688b26fc4dab2a4e13f5d4ce131ce06cc958ad5bbea7055cf99a2f151cf76770fa99d7026f7acc07e12b4a3341fa19676bbd507f86bfe24b3e832f27f0cf08e9ab38cd6962d0a84058ab845463a0ebb53bd55a28005138ad5c4be93fc894c0c4845836dce7bf23104ea3e45de9c9218f93ca709280e50a505360ac67be73d54ebc054f31250e802d0e4d732d867a75ffc2f28f6d32ceb2349c798d9e90b0975150235d77b5cf9e23afb4210e3a8f8ddc25477dc96fc2c9f21a55a24370ee843348a42f650051cfb99e9487eb7e614faf673af828f4b411ba9158e9a4196db7b6a77b8784744f1a9374fd674bac4647d34aeb75346e98b0fd775c2cc5ef9bb94af8a3063d459b2191d8610878fb0c6ac0815890a1009f2fc392b5f275b4a06b13f3807fa824be2021847ffab4b264a9ed7dd8ab01a429caf365a673ecb0f98dd7735a5e2bef4aad95811fda66fb6decbaf167a251ff28784ed67b2fd61a527dc19e55ca2801bce6b87ffef579853ed5fe651148c67563f788a129109d69dcab0209331463f64e2afa5973fa955f4a4f5beb7f72fe269a151f49b2b35cd58d7f3cd4faa05bf8d02dbbd29f1a2ef1c348fbcf5144c7e324870adf2aff8d499dcc3f4f65d2972e40e4940b3ceaa2f76d35d55bfdc4c59cf517d4fa0f9f41a6da3b80630f2fed9edd0ff83debaf6f56518d0d747d028745d16d62f0b99d31791a622d6490b17832d77494aeea61567ad60a1e538759d9836606ba0932965b942bfa8d38698ac6c51ed38545d344352494b05f7d6b8430e07b34fa8a819e30f3b1a7e29acb6ae3795ae6c86307ba909a03f6d814a37d66c4c84467d35b0b626c5904426338a36b0de834520887034c3118a3c1c768b27faddfbff7514ee574a19f8579332fb90f7f5379cb991c696c7092fde07bdf001dfb23ae9eadf29400e8fe8acd6477cb6fd6774a6b15410d9aca988e19b8786240871dd59adc7646c1ce6b814666460ce0da9e45a9f10b70f5add74c84ec16aae51187a7a047ce8878bd866443b5917601579dcad2f88ba708e4aa2540e39614f29b3cfa9ed9cf94d6a44a581c3515a7737ddded411f7ddfe9a2658a0030ea1b0134620b198548e94e725cf2a2450c5c48fbc744f98259bdc86ab6d331d6e4cb34cd708ccd1bba33d1c36637c7de04e80083786ce41f9c5502ecf58ade77c18becd2e11705c62cbc21b9c68d8e89991e4d0be52f9a07e97aa051dfab5a64c2efea1c739e80f16dcbc6700f302002de0abba42f0d9e897aa43c0c7ad65496354f52e21e24e8c3e99d577c550f8744efa951996608ae4e497d04dc735d898d9f60488b95bf4df5fc0244a1b0b4b2ec015354f3e9761be03d5d762eb0463d1bbffd762cdd28818b8ac33e04bcf7af55a86ce8621c285a3efd397703ff19e70f460eade83b8abed9c3369e6c118b18426d079ae6d76a957994d4fb3cb713858b38d9b184c98c96e2e04bd67098a02a668e795d0fea769b9f28065b36dc32a3fd8d03b9b52b74f7e28263cb36a4887cedc7827a194f38d4d0a9e38c7410bbde069743d42ce2161c952619f6514d7fd20e69a6ca2a33eebccd99fa0dc13b4abcf607b5453e7ca644f4cbde5d065f4c5cedcf21d202196ac92bef5e3d77adce99d231d978fa8bc2e1003e7b546c1ac5439fae88fe7fae53a54b603b75ee3a7a848440d9d755aa37e677ee05645ff23912c2be4280b0e3a73bfd5bf9a096d6daff6cbab433b52834dc2144aaa11fb4f460f6e988e29a116aa639e4dd1cfbb14ad656b30ad2b117d40b8c88273cf5e05f0457d016e3cc2e7ecc4ab5826797400d2a027f83776f4cc57cd546a958d23561f11ff54421299fadcad41defbb467b9f3e1030f9a69439c8b1f08b23ac02c2ca19e914c0f171c69de98130c89f7aed2ddeb8e00a8bf9f2ae78925136b58d6cf064eb0c96ad92ec099f920433147b66ba06d7ea9d3b6f116a3499dc4a94b9efe6ebfd48ca2110fb6a5440215cdcb8702b019a3cc3b3d5e283831637d72f2ff5e87057aa0d37cc6603f8eb75aad7a77fcf3a75c6b93f38efab379ea52c57c0d39d4e82b4d6abe8d31e87c706bef681d4c7b6dbfcbd03ab5cee818a68a7cc845ea4162b09693bb4595c85feb8ae39f9a1982e1f006d055eb1f046571f28446981b9e76aad2cba0446b3dc8417571c93f6d1b7446a08f1f563a57cf40b2dc06db8d1ed51f9c7f1559cb2544f75032ee8945b1a0e0413a46298d2bb699472e6c2f545bbd136002b57737239252ae92e4f8873975b3c3a69357ab3e22f00781d549d17e21e71a506128806d0dcd159d6f666ab5d4bebadac0e45fd4485242f4ae9cc5fb08f6e20c9f042814c42c8ba0902651442765100716f8e560cbeeb0dd086ca89028384dff8083905953d7307a80c970fd6cfb2e5d9d7715dc0afec436441288344cdef29238b677c7337c71a77af5a4b6a1a2b117adecf8e79c07a67296d93b913ddb13079f82099aa68e4bfef1afc7831ddc84b5cef77b768b4f9f7b807948f439cd6c7971077fd43733be48df3fd43ff8d28a7fdc932b67bf724fa7e19d60b0d4b2d0e4cc6f7dcac58e724ea1e839675e25176095fbe5bde94d6c267b79a4028759deb4377fc84afe32c5fada9fde23d69ebaba6c79d3a475f0318274739c21962f019a77ae6d3be5cce7f0e7f87f1d02c6dbf21daf539dba785cf68f38c614b2fb10e821e7ab4b81c931f7e01625efba4ff3cf6b97fec7b759fcb8d079db0b92b1cc5b134247024e4f8c006fcd304df6b563b727629dc6e3e67b9a6911fe3e48f356ef3a7fc7550c8afb4f129db706611e3602a3e4d4d36a1d15f3be41d6bc431442cbfc6887c564dc9b08e453c90becc8c556061ec8746a91351feb5a0d96466d9bb4d2bc8d367529be50cc7bab5a90e42a9d28ab20eff39a33abe3fab7c2467cfe4a18f53fad7248728115393104fd915bd42714833a8f82c6e501f568f65f68ad22b6f81f0e75924c62b4afba80f226b12ff3b508edb6a8b6a70ae681defd67df71f88a72dc073cb819b41d6faf6f01e037be76daf823a2f154e3f6918414e8e6566dd71c4deac1db38680cdf22a3a4b0220308b7c62521ae8ce9c1f29a45389eeea191aa19b1c08567a746f4593a76ed3a5897c41e62ca81cf664a750115b5f3a50888e4315a6de1faff34c14db8ebb668a01785ad140d04f2ee859dff59a18067e26cf6ff209cf0d94786287d07cb5de59d0719312f6c2197e41afdeda192957ad002f49969ebe6d3aaaeb3c6a2ab0add0b07691e86783b67bd0444b9ce0ce76d5f8aff8500526d92b03d729d30e6953c23bea65fba17530c7141bd82fb073802bdfc301ca35d9be767b49fde0e864c2c7b0bdba47efb575993992c42c30b92c0bbbe61a080897748fab918f0122ea92ac9b60059b51b799b941fed738c0920db279bd418bf863454e50d3b5a65e28a06482db6e94a3ea61d04def86a2d39e8af33e3845ba55dfa930821abe4a0087220e1d703a6892af7c43bc6ae802ddba25333d22c1a3c1c55c308a391b8dd58a52f3d0ff5b4529b1ed51bfd09abd0b9b5bf8ec39406e65a422593b00f5f51cee060d11b8617f4f154b4b1125656af74b2ae073d382d75d01d4d9712d6311ff835b2353b4fd7103b6c326094f41c2d5219a64f1d727d26f9abf5a26de2e16153819dfdae5ce924935739dcbe1056bbcb3ee00282b21a7543b6e6d5f7f2e5573c53872f4315a2738cdca86908bea690dc3130188d0ff3a001c484690ce879f92c52e29fd04ddbcdac8f67adcb89a30efb04fdfd7dd69c68f07d6f89dead55dd38c224ad08b2b383a8f4d8153ad14118d6d3b85d7bd32371f478d358aa98f8331bfe81d21bfbf558e28e520c020f0d3b380200a70e7d874abb2449942571c4c7f13b46c09e9bfdbe86a8c97be89ab7106106ff79058e53352b9f8c1917ef1d353318b55ee4eb852709fe907fbf900779ee8eb059599713f665813b1c8b58fcdcc37b56ac7c3100048652c51057a0b1211279bba6133233a44fe5d9bb0e42d05ff28e759f5652c9ab68c843971ee527580a6f12b1153ef0802cdcb904da81925c821a96d5f62545a5340731bf95ff4638995581fe47897f6aef3665f167ea8fded2828f2102c672470f3cf545e1183ba67234193f4c8f54917c9aa4696a1dc8f4f2ff5ec6b2f070b8c1c627be1485303ef29d8d3338a44a6275d7b228e2d9cb2d9f7b3e171d99d1ec4377743fead0fac8da145cd2a5a17cb14dda849d93a1c235e8dbd37763c73dadf667934737610fe371774a60faadf8270e6fbad8f6e5f3738b2f7fa1e4f21f7234f5a4a9434d50a3f6547ceed06b3f2b98152bcc8b5f5f6e150e1a9dc6931a6c92a04c77a7f4ac1dbf41e1e80e3368316ab918d09bed3e59208814e4b6fe608134b6a50a7c394e20692564ebe13fcd3bf7228de5e9e9e28d65665ac48a05bebb6d49203db6858a4e33b3bbbf2747e4261c8fa8283e624ba0a71582e619340b5d247e790d03942aaf0af942088bc25f06a28733b7bdc4025e9718162ae071c3f7cab77044ff5e095992fd0ca42bd1c12db0a2f329179e58bc4bbe2830dd09c041f41f9a1156d8d8f6d6d2d766c50ee6d4c9a37b87225e7d22a074921e79dda693a83e77cfe417e86325c5d8f6edba0ec89171df7acd277c8fd5277939354258dacc53f1ca1c4c164186dcae0da8ddf52485acd2dd46cc70676e80f947ef0f3bbe5cd5136b3f6ffe9fd3c2d1409675e075993737322fb8575f6b9f66c7d211e67c3e0bfd8be10dc94fb780eeec79ba1f36dd60e5484d9c0d1c95daa29b6dffc4f3cd498eca14a1b1112f0c1030299a01a4002db96eaa06608391f99eab4d66ef72a9c767d356764015b9aefa651170709437083c46ba8d058120737c4bb3baf84f40109a72003139b709a8880d1cf10ad215829ca7e492aff6473f32a610469fe7a069e8a6bf9af05f6642682bedb2c071dde7f44c0480fcd63d7a65369faf7481c5cb9bec7b8e5309d0b725eca1445995f79beb4ab68eaacdf7fc85fec5ceec6638c3583330dccef8ab451664b046224886f2f009b22e0c7ec8c2ffa729f415638c14df4432030d78b945e95cb376c05ed69715db13f079610e2cc7706c95bea3d670b63ddfa21ac3165ce4e59ff17448c3644235ab70beb145daa16a241d3229e0b5fe3eb99578f7f6767a385353d87adf2555f60b13aa6700141b9be05f97da6234c32f34fbd28257b2cab33127f6984295a9dfabcc78a4bdd6b083fb18a3cd0557bd372dfb492f7fc4007898e322c4a65eb095a0a53eea0b79fd4235e1c435466a48868ab90e1c4b3fbb314eac7a564cebf49ad6869f6e5c55120fb96bce514dac65926c0c0276e38b866da0453ecb8361bc476082df188108ca201933a19571d55b7cae3d88d5c18767370a163de51b81198d29cb5429312126479f36975d3332c34bf196c1303437f7bca81be17ce498303eb27994c0576331215edc6f7c018bcf491d4e11fa4fd09b6b2074f0503754ce2c815f0b52980514d74c3bd644b938e04c86337f68b56f8670928b89174daa1c964436710de786b80431b2bf99f4995892f9dea7d4cf9212ad560528b4805620d7dc218e2f7fe3ee9cd96ac66a7257c8e77b78a74ed53b8d25ff77ee1d67d78cc47554ec7659572240999b67313f91f526aa6a57d562f50bb3cfc75872818a4ce0de134a9fb6870ee5c93f0a442bdd10a252a38737dffa763b346a8a6a0cac6ba96e9d2a5742dfae121a5262a455631202292bf47819b2e593f1a66d01c579aa41fead3af8af32283c54698ac15f7eee0f8d94967f2e52b1d03b83917266058ca6eb08f5d0fc1bee5638459cbd09066efa58eb11ec926d50a914d6338746c95778a8e22607265bd692fbc152e69934462032129446d0cec3e0809d17e9fe3fd1795c712a7338f8a442357957c21c14c5c6b8766d0d4b6063f5a1b6a822950cad011c3c97335635452d969d60bd17c11b78b96d57764c205a83a15f4b4732a4998d692c11c2003429cca4781529e9277cb7df328b34c2d0545aab432577ea5e5b5aadeed3f5df03ae2016f7f60147121fb1eeb95091f6dc2d53ec28e9d066c6e608540d11757b5222b0f14fa990468890a4a53d3eb74367aaf9ee4bad86cf51ce16f31394bb216e34dd7e68dca123f1caf90f8f19036ae59d5305971689a84706603123718ab4032a1d72203ee5acd3db07f5e9e5c07b7aa2cd2f6172b369984a8573e013a7f94968c605a00c8e6c7ac5fcf0066c969009e922fc03743a79afa5f8cdbdb56263e770fc9eece8772e6122c3ac55e72b9006b39ec6ee7f2b175897dd1b218fddbaa1cbee400ac2cc20766a1b8994c4f2bdd35d84e6cf767c3619dfa6f75f75f630c8ff520e0cdde6b8c39c5df53146e70ffa428adb94db8cfa0a344bae42813c77ba89849caa199cfe65bdc057209b205906a2747fe58cc0cdc2e32aa20b8863dc96363990b9c72abddce09f98012905351c8703a49e122a10850f6e6091932e7986a5d65da44cefc216610d8f9b4aee7c6de439f5548b8ab6a952547ec090e37b765ed2ded7356f85241ae076d0cfddd45282dfc4f605b2d8806283357e43131a2e823f04c7093fa7a98d13bbed4b3022c1d29345c7879adebeeed246a73e07b112d8221788417408cf62666884b5afbe3bcdca74c031773797bfb71406cc2cc0e8000ee64d59f783a7767c53cd59ec037845921796920ad0d5a797e2165403c1518854c2dcc91103de8e02962c1a7b3cb98ea68c07bd653a64d80686fc7a2476b4f024968d20cf50cec7c0fd75d1d3063f67286cd4e590303d93245991b96381cc2458de2fe6d7342454cc982241470a6c46eb36ee02ee364c6e06073f69f25a61da6dd06b0446f64cd6b1bf7db46da9119dca72c500cfadd58132ab45ba4026f3d7e7d66854160c1d670a1eb92de904de989a57f3923aaa1509fb99816c7f307ad863fddbcf5e26da550b4b2fb02c31e486c41fcbe011a666e19257e93a3aa21a6490abb963f957d6a60047a49f40fcfe27278bed21f31c1e5e0a7185b6d3778fad10bb8ee8e2d2f9c70a7e3cd9a989486c6db7b0006b8362f2aeb286fe5b6a8115f1854d790bb3107b70dba4190b1baf3b4e49d5beedfaef371217220570dc193f3caefcc49440f64719e4111c01fe92edc61e356d59bb01c84b9e341464de8c438349471f54d15be2a7cc9a96b98e7b74c7d400f1ace604d32fd872e778c1ddc5df944cf8244e692e38013a00d7a557483037186bae1da24dc158544df637386bd32dd2ea2d8ac1f162dd814d8eb700c98ab1ad6a071facdcae5c6db883612a32acb936692f773bc393268e870572f49ff93877d2f80c4a0cdee0574d930bc92aed45196e7990a3f05d48d4b4bca66d30f22d9426f20527ec8c70efb6117e344d499e44e35937e692d5ab661bb3239ecd428e198cc8f1a4d7be23eeda088c2a936da5f032361406ab96089f20d588f7d58e49a93e832a8d947fcfe15ce48dd6396414781301724b1ebf8ab284736aef78a620ee0754588a2af8c7811ce8ee818c0ff61a10255ef75c52de3581176e021d11efb90776c54d9fa48088a50d6397136ae74ac9f09e92928162f0a3e25ac34bd4a7ebd10a14fe146c4230936c7aced767bd5157f8bc6ad3320802fba5e11783af792383f9d0c8656b5378c6ae6b8457197f6eca328ae7f4cfb3afdf593aef2dc924a8da0dfbdf625c0f8b328478d6153de6aa79e164407cac6baab0b2e115906fbc89a6179a396f1e3019ccb13102c629c6cda45894f46b65efe7adeb279b081a46db864d70219591fd7f2816e968c519602503c5cb1f434e7f87113fb08ad1bbbae2188ae29c919441db986af02fc140194ae39d443c724e7db753790a8789e5e591b7a46667469c43fd39e2e69e469c876870481f6658552bce52bfa24130d526d8a084a7223760f5e5e6cd14a192481d36378134da7688fd6a5d4d6e7ddff6e861999c6c210d8ebb18db5125b8bb595280022136f520c2dd62f5ad1beda5def46a934c76bbd032441f14c5234aa240f0277c9c67f58e06485eaa8154fe01ac18437b2431a4f2360baee6d1a61e4afab036a088d5e66e068566bbe4362ad870a3f1cc77a391f482c4daaa968b5b4626a33e32e3229e4f69fbe99e007f41812b33145326db3226ae9c299ddcd2e9551bbd61878ceff5cca16d2e03ffd2c924670de07c5700e454988e7851331be94d6d23120c433232b6493dfeb36b05f593f570877d1b645108d1ef4d70e0d275b8d2d023704c0b024a24c10966f4724ac837181c26bc9346f1342f2f74fbca792880dee01ea0252fa350cc4239e8c1316e2dcf5bcb1243add62e8f47c15c7ef3992555c036621c2743cd9855025967ca0c9c33a99e68e4a046121d2a0b0523937837ec3a6e5b9d056752198612d67b71c299d33543d67c7603b36770151aea390b17adf1dc1574bbc79b59b274a6b8dc646b59be0b71d7884d12870e3637668e9af69c118ef987a28c6cb32daeaf9111085e571f43ee0e7d8048d3102d2d071e8c318507659693db3e367db6a06c026b16eab99cf380774e85e3142fb046d954d0bb34cf44860740db0311bc1f59c1da3312cd4b8f604f546f531d4940cf43833fdfe2e1be7d3d3861371fb6a039813a9f5b6a32360e8ae72c9f30b8881e332d3ecfa95b4f5f4571404534112295e3ba24400f4a971bc01008abce93058b9fb2f2d1edb234be727e98b52beecd5100c63f5eaccd8cd0f75755ac1acfcabea7251ee2c63596a58a1d7465c09af54bac727aa07023d6e1efed2682a3a4c7cd0d5ac0d87028e62c5d0d82f28892f2da0270b258aa374eb74809f0ab32ed224dd68dfdaa4652eb7a1f5d8b5da268b2ce474c37952875845081f23f1d0b0e0210ed76077a4038acf3f8781babf8cf2186824af650ccff509edc7f3f211951055172ef0d925e2f76c6e92f429f4f23fdabcba4a2cb10c5d7106faf0db338c437927a0abc80e01fc3eb650db3dbcd0c44bc2b957214cde979d62a3b503b6159413db6feeccb5ba8d15ee74be8eaae1e71587b4259ec7fc01d422cc28eefacde7bce6a9b05ffb723fd63480f59888df45af72f6b378238691d3ef4818f356700b54a6d227b994f1ae2cec57c715afd4ff0daf17a6d67398675cf89c0293ab47e376aa05ffc9d2c9d5603db78696778a25ec898799ff53f41788ffb258271d97db09bd2fa4cc2388cfde0ed88764139ecbae3a5e61b5fd27812396cd736c59995ceb5def95412625e61d9795b7f6a46954751cf127350e1efe662f66182b621a1a3c269f717203c54b92a4c8a0a23e1acf509f41f6b03b24b85b14603c7ccb68d68fc715c1247c88dc1141b0ab64b45126e56f7ad2a32627ec5ff0e02aee2f7ae15d9ee73a359653cd8c468b93f702dbe53bab9f13b518f0108330e5c3bebbed48f1bc0f58a95761d10ed434e349763400d940844e338fa60916303ae277a8da82050955c66c45bb4e8c35634864e5a74c307ece86a892205f2119161befe9484eca6367ecd3b870ceb1b294ee06ce2c2ab1229345750573061cb635f43f39c78bc3eb11de2bee336133e12afc5e304fbaccb57cfed1a1bdc82efbd468c9be8e66c7d445f408e9cecea1d1f965d6744df9861c94c7cf866d3bd14b69a923de2a7834c8ed426e34952a34ebf3b470b11afd12d5e81944f6e60df5e4582215bfb4368c4d97ebcc6f940b3c3ca52a69e2571aa730ba6632861abae81dec564889b3af7d7598d73b95693f8072c5b67b90aab34042d99bf6b96a5408b1c96f197d8358b1b3d326cdc7c4403bc16b659dd41c6472f3b261b32145a155316155ab9a730b09d9d8a6e1dc0ba3b092cd5f58c57a4dfd7a5e664567e017e463e0e3d5b1a0873de031fc3664b4a367f5ceaba69980a3b2f0b87b0431dca359d32bcb8149afd74422b51bb26807cf4b0186cb42034483de875855b6df16493ded317cc418271ed0b7bfaef13272dca1c624df8bc1302a11037cbf4a5ea620e63b618c7a3287f902950109b9029039bd33df5660270282d33fd89090d2237a0d2601ee7d2d6183a42353ea8e70bd7764732b4ef5a6286e596126551736dfa4913dd59f275f87887332d84799863349ac898f6b619dd9bdf4cefcba51544b1c76b3efa256cb19fcc0a3d190f254a7637b688ba372221d3e72ed798460641eaf14ba1af4ded59b1c7e664615b5a287188ad3afad3d69aa3296e4efa0b070f0b902a5e985182944fd6695a66914c96ccb66643f3bf4506a0a03f5ecd0774a43e8bf394c226c8b7eda4328879f8da1f8713fd2b833a928b7c6bbc628b043d0332edb3933661e12411e140207a9fdd4b04b57a1a6baa026f88953df68020ffbdb9d0d83d5cf854e76996b74e6bccc6467d9eb53d6c411974252c143f26d966b71adee69a485a261083eaca61594100c0e4b904a9f656eca9b1388651257d89270fc5bd8cc350c9e21ad67fde6c0d4606304352c133bda7314c5061de4bdc2cb93da89eca3d63d01c84971d36408c93f90437bbd21ec1a5d27474b4332cf140e8e5a45c65851ca3f4331b7d4cc261fb5075982826153abe626459b4d72af23467e90295c9fa4eb3d99ffdcf26e8bc3117676aa5b61b046f2713fc8bcb48caba6c0ed994f413d84e3ab1915cbb1008cf9d293536fcbd3931583a073fcab471f02507ab32551946ed796a2364bcd7619ec75334bfc7d9237cc6ff09d5c3506fe6b95741d3e4cd5912904ab0514d2630735c6c1fd123b160e7aeafd359e670ffe3cb4786ffe18c011a66f266a11834ffcfd3706f2eeb46118efc6f124ea5f9826fe3c7b510231b48d725e992b0678e0ee5dc1dac7e77995946aa76647901bdb2b9cb0e068926e3f1115ea6394729379d622714c5e0e9b6895f8d6673884afb8231c562307064f00480896831eab7749b29d4b74d67d51146c598d8985ca97d912a280f91eb50209b91eb0c9c5b5b3b13550e610847c4819cd63bae4340fc2fe0d96ec737de35b7aaa746cdcb61ea8f183cc06019c6b30bb682ea79d22341026b39d15c91cb556acb255de8432d724a58bd42b65b8081ac525d57b767bdb36b7dec2e0bd7e0ad68facbb1212196b8fd6201857a19403037caca346a748cf65147cdf7ae13c5c8cf4a46c916b6695df7f33709b1c5b4027ea1e216437962d760645478f026b945e61d97a681d0af2b2781c0f80bf1433bcd5777672ce60fc322ddc296c0c1a9f6d27867444ba3ef71ace42f64a5a428d179416341bde944d15ae91e1fb0ca42aef070427ea11442d51cbd08fc67f4208aa5dddcf678d7855fa02fec99ac932ff340f298cd62791f81b4a187ff6fb965bb3257036696135c0bb3a80cd3436556cd77d9cc21747079fedb4f25e7be719d303765d864aedd155f02479ba6f17f0435dbbdac2c236d4e3ea9352938d395fb9badb2c499f5d8e565b112859db85cb9a886aba7b731669cb2e70d8b8ef0dcb7f7ebc98c250200fff36463857f2f89eba14e7e47da42615adada56d2fa0b26149cfc42753c9f8e3a1046b78855b65197155bdcd3e2fbc60d146130de3a0bf64d7fbded126ed66d484baa1a010051c0b31c7982d0d786db216421f2c0a45ff6ceaaa9013537fc0b766993fe1730ad02495aa034a0dfaa4777354ff30409876d66e8283cd0a6db64482d0bcfa308744bbe04e7bff93513f148d251bc2d66c0b2096115515122925a46d2d1d96b2e77b4ab08b775a0fdbc5db0e89469c95cd47bc27f7de504234a657fb7f7d3686ceb9fa953a6de73aaf36d264bcbf3a7e97cc4b51da2ad3b27de72b148bdbbfce35588cbaf6660eacf92e50ea06a3c3099c71455e5f62aeac75c322156dc00b69a5df9b4d45bce08e66e62cddf0682cf27f2ece420f98fe4666e3450824bd7debe06e6b93979cad1d0c75caf95ded3de78ed687e28b97392e2b8b2b7ea8bfc098c1206640020de07c5ca0ea50bd597213f3c27d622978ad447e622d76f84fed0669a6a5bafc52a7e152d3f4d9d5337a21fd0001eadb95eef7119acb3635697ebee90b46f28432baa1e181f0fec2f1dcdc57a68c66d411d6f1a851959f2840f2a1e16cfde6636a2ff1dbd9cdf1e316d7c8e3972c7c8ecf9ec4f387ab44af63ac5394aafe1c0b844a52b0becef13af3e1534089fd8551305b3ea9e040fd981cdea3cc267a9a3be36c7b2706623d00c70c54266c6ffe2bfbc88e449ddf62d69c83aed15562c9f2cb429f04a370ccd41749e80dbbdd3fa101e78972baf9d7d6c97864017937f3fdeb82999e8291c06473b8f89dc2b1e0a22dfc53d8b3dcc523df15493f48d3533c0f36982383fa26c9166b9f43b4de4d9cae089c9dbbc1375cf174c0ed7d356ce387bf75c1d9fbd6a70cd4a8d30703aa4ee8565e522fad0ce09b55a47d23d0e5a02f5bec928979e4b75c6ba42d403fca51eeb70ce0de89972c45b19f5524fc6682ff28b2336041612da78eed4ac3c87fdbe1b096bc19e31e744a2f110055e40fdf6e389e1ea37b81cfd249778c437b5dd2c068a05473901446603dc4f6fa6df0e51b724b1ec6a01ddb1c02896f43f3d9c76e9a8b469ac04c64578d0adca5a4b582ad8d22415c6e83890d1bd8038ab5a7532d440552aef92d53df23338818e454306b00fcd8503ca27dc41aadfbf51ea1b5918c4896ee486304f76a260c3f28ed9b25ad682b216e3eedfe2120ac41140dbd846af49a6f7e1543de20b4ddebb5c8cf5a1a66fb53e50ec8a7dc6d715e96dfff7557af24276afad3a2553dcea2590fc102f50b3bf98e5d7b3af26a0d862ed1b225e0c0c506a66b35d9b207fa0aae1aa029057a45a3f901ade49c5e222b602bdea1e014a512e58d85d67a696bb635f57035ce13380785ed5775d2e9dc65e36f15bcda56747e0f060955194a00fdf9a251310876fdc52939b439692fc62f6b259e64a0b4beed671c1e0b2ec10c940d58b42e807abfcbce46056ee7d21f6a22cb351156d0bd55c22e5788a22e8e8e6647f13ccd75834cab428f10048a45cdc7af9dfaa6c64e49a334f521e9dd2503d699a323fec8c64868de5c600482e7f13af2cfb8bfa7904e06ad0137c266c2116c3bed80d068ee7a8773dedc144dc96476d2fa8b8909df029a7fb40204f7c051c81ea2240dfa070c57fee0f8277169856076a6f314f6539eb79c59971c63e36a9b3fd49965186eab8bebbd966b6c0461cd8903889752bee40e78d7596a87960c18634a32cb4ae534da46d3ece9ec9f42b88b8d0ce99dc283e19957d44cb823e02d260a08a29905902ba7f4e74067736c8822b39e9c90cc2f9f6eea389e8fdd52dfb5c05a035c1d9ded9547c3f3a51566a3198b2a5fda34ed1c2d0efdaa48b07bd3a71ff569101ac8c8598509fc75f11f1a22afe45aeee646e888e00ee35e0aa4f5cf1dc72a69b20cc29f5977c2468145bb63f94b6adc652c71a7e719941e602d254fa1d1373a47b313915670649abfc5d8bf0a6a9985c0ce07a89d52e6f87cc7f3ff0632c69a7e7144955920a955fac8e8fbe18bcc78afb638e8fbfe64a26feeccc91fabc4f7e1b7622c1618b4eae01f60e991d46bd11d27446d7647378a7fde340ff756678c4558f97a8d4a22713936f4370bb3fc76806a33f0e8cf23bd4a9f9c74952a743bfcf106855f9c042eb417df797ffbe14765e7732f3feee0de101224b430d2bd0aa6e4a70e9300c2cb71a23bd23b85aab8684e9d6b2c7d4a1675985a7664001bc057cdd81ace98d277566264edced9a0ad6d1179a1d5ba2a012b235773c0c8dcd88053a11fd0c4e2d0a8bc6cb1b4f4e1a7e4f272a0ac1a7c91f409f1f7aeb90255b38a042c32088051f28f8982379245cac0993350c073f20af152675d878c1a19c058f4645472fa817ee1cf6561b02e1d2b07d404f91b054a2dde1709f81ca15560bf60cd7abda545fb1aa0503bab06b26b3d05bd0af43aab4a5692d73d76695646ae9be498163b116706b64690bf5fce8d2c005d6f4a05a9eb62c8d2fe2c44b819e9d1cef8fff101c02fe07924b89ae6d0603c63ae9f39b1273de6aca9512d3a37c6081038d6f472f90f95a468b8345aefe9a223021c235db1c9b98a3c5e9a77d5bf8ec7686888c374ac51494eea144354c03d7b641f66526c517fe5b3683ea958e54e9991fd59c86cec5517725117e3b5b69d30364c0dc2e8dc7f78df640c57e663928f85f6d18213e09fe2f3a6e5c3f913621e52e6a01e55b13ac2b9d10f605bae9092f3eb0bcfa1574c7b5d1c5da13b2cad3d73e29f19e0a660df4c3e9cc2f6e57fe86dcc7c6b3537b11f26250ef9ce0adac3e78eb8b68408b4cb5069318fe4c73b30a93657a4bb541060966d1e1557aeec85fb400768f954bc0b1eb758e37b0b2a9d783cf304d3ea95c5e4782d81c84cbdd8205ed70d7704956843c2c17cc6a57bc46e5dd79e5be9a804e92b63ff2f80fbcc8def2ca626258e941572f03b2a7e0ae45531e66f39c8a61b31b1f2f7a602b26b6d8f2bcdea01f1e96f195037b4d1883b9bdb2e5831da004fafed47ff2baa04a8ac9a096dc670b446327e2188c3cfa4281647a91995cfee52dcd50e3f3f08c67c1699808a7e7d98652683e7e03220a228757e9d2a800c922b0361080ccdd6ea10809b7171d66e07020b8c6248c7bc3f63028e2345552b37adcf5e484704d320a1c4c1184555f035788c0d3d973f948e3935cf2dfba84aee7301644e241644e0b516e8ecf8d5e8e41466b0149f0972f043a23b45e001ee278fa084db3c380e60507f193b869247f5a1184b644634278b5596a2feeaed188fc8495c799ad931101dc0f852d056f0de50d959f91f367cb00b78d2dc5bff30bcf9d22c8b1b61cdc904fc5ecde1f1e7f889f772d6106ade71186438e79be504e1607db8cbf6bbe79f250c8f5684f8753d0ba0c864b40d7f9205874b213d65a257f0066a63a5be4d54cd02ea42a03bc671a0ffa91cace6b756b74254ab8a081abc12f084adf77beea3ce1fa5eefeed97341334d1341b453a1d5581f7eb86740ef8d5fad4ba5fb5bd779b37596c3db5d988224495230e5b09d4d36b42871cd9b987c42068ea9a5f87738d814d51c9d861afc949be583cd943294c48ed198fc3187874a85d3a0bbad992fe4dd65172ce2da1453d57a2123b39c3d506d1978688fcc8a23b14a10b44a30d038e4e83502907300175794a55c2704db6ab804258191519de66a925e85ef4c83e49b94a87247e42fb7b4042f5b470ee544c772ac4eafeaf4154639884fdb904c566e440f3e20121c81d6653524964b04322ded146468c0d0c332c7212fc0df00fe61f6c73a9c2ad40525b402f315093c9168015e081c6049704f87dee875a77321e07b8fd740e01902797e9ccb1524f10458f864573e090eee1f7e69ee3bcf80f9f163839b42f747b3ee21512c3995264748431ce3b128076b6a5d3ab7f125bd924929896745324ffa7d465aa0b3d146a909944e93d20a11818c17ec06710112807090d444ad7051c88f8d023f01c7e7dd63295660268d34473be2141a9ad79584260de85a8924e695ac9698b9e539ef122d59b5d4ccdd107fd5a38382f399b266a096a369eaf595e28ae7d05c02fe0731d2af97f7b2b9ecbcb513228f3b2e1f20d9dd529a6a262677265390549151a2cd97aa34efbcd0162d2446e25bee52f397ff815ab66b88b20a4c3b33f2e65ffca853e0cccba68e6957255392489628b55989ebe1bec6916df14f0420c8ada4452780eae3d89a70d44d95443268065e22ab4ac3494241025815959c1d1ceacf31f24e5b023d891d3c2c72c05cc9de849d2ba198effb265502fd7690808df4417f686f038e25398616d9b70de412241c12fa44badf2b8e5c5ae180acaf1c8e55b97992302acd73f71537d942fe7d4df3c289ff224c5c94c2effbc347c678b295b7cfc442e40b1a6856bef4752cf4a2aa1b425cbb46e57c8ca32a5562267c7202002920ba32118abdfcf8c4d077cce0bad008a5e01d8b45a4dab88a522b53cdfa18d150243795da73237a38e4666f65c3edf5d1aec1827b6bfcba3bcaf3c48648a64efe032207456caa6b3e53880b174b9b44b34a3304eb7984106024797352bc814660d040d34bcca22afb74826f855a08c081e951dca0a9c8ca4c3d89713a629c72bc852270455db513b43c06de8462f952af85b043a5b1d7d62e4667b19673047780564fcb080ffe8b5b8118a4f39eb1031773322697b02ea1b4696d690810622fefed955c9ac45ede279a7f222f7f4fbc1ff5f9ff9f002a1f519100632e9ee60a6b36d6113cfdff1cd0bd05376ce128e8f492f281a3ebc2780e871b949cb502a6b5ea90430fb86a7b66311b85e6f798c14bf3a6379bf6b816b0ae6ba8a3c135b37d32498df257d346615a59a0d814774b66ca4a774b590b348ed5b16d4e9d5f08ab710e8b522000faaeb367fb104e6635f2aebb7c539cd143267f783176ad7570415dd18b7a70f190d974f57372d806992145fc088c7767416eab0bddf307094c3bcf004ac545e62e46a6dceade9683ec09977e64d3a23d29c9eb7a37fcdfe53cc61f7027b36d186c8664e6cf2f1a55e0f3b472b17ffe84586a2a69abd2000d3f76a81e544480dd7df6d2b190718df18f6378d01d93a4a8c51f398405f137f7c67246449d210443cd44181187ec3c608241f1a5d6ce97471db16a99ac68311f1e68e85d17db7904c7634749d38c26fcdf986f17d07d9877eec548872c3bdeb030e360181e149414db816fe6162dc31edc76a6a762e486d0aa84954342f5131052b64180a8336de53a735203fed52c801a0a91e234b7a134215ea02555b92608a4dd9ffa2b54a4899282037b7adfd3d0c535cef46e71cfd6cda33d9043726aee5576a2f381e59c1c927d9a9cd0372a6a181079b549695414f8a69dbc08382733ecad2c12051a6e8b98d173b35767b2fbfc9c80fc96d6ff61772802d8bad0531ad12bed0c086e00d387815e61c019877ce016c79a838b1c1c5621ab00f763e1d060899c78df442f020f580cfb6c38d6c4f1a49663d79b7cedc792d474edcc58d00d4e853e4412f411ecf1a894e026ec735459daadb988e7cf0fd8c0006e5cad972547161f2b80e5a702fe8670c2b2cfc39f7063dbcd95168d710c91e212dda9671444cefcc8b63881be4a346e72df2f57da383c3e66329f878ad9668e979f2aaa64b02383923fe3fd89eea1383b403da99ef8a84f47d987e06288ac0d229ec166e1f59098c4d2b75d884689daf6ec7c6f535bfbd566404563b683b1ec45578bc08d014980029ea660a520881ec3117e6755634661a1a161a7779fc1a4d9dfb55a4016fb7e5f514eb398a3bfc09765cb6bd7a3368ac90746663a60c7d9a37563d4efaf3a01462621af7bce6bd975605ef9a7a7e39b668c0bced7087ee5f31165acf87815120794ec3b71154736a7a4355a126a4553c8ff83e93e2faf83f1aa56d1ef0ec0eccacd1db3888f57db4270e916465b10f147cb05858937752e38605475fc78d473ac2d31c2112e3b47ff53a95c608cd743e2e2262b40e6f0560d5e1181857dbb4c2f1c6416f3c502d49f8bce81fcc449235c48c4ca3e592f74114fa3c8e8104f7b7ee034739d19957c73d90385516217a057bb73b4211745a64bc8edad2cd3ea227e9b168bbdd838ea26a6055a4df7593cfc3778047f24a092260be896ebb94254f06fea311cc11e8f09c78e65eb57d97680537645c0b8f7334397f4d14e97c2464cbb932b828173d384b61d4cbea67748097229479a1c89f59f5f40dd17a59af41e6a7d2b6d7416fcae46d16a3c0c1d10a6d427128a291f3be7734569cb8c109bbc63891e03fc1e292fc5ced771d62373dfe196eecb5e60ad137065442442e641923e4a7e96c8397c84f743ff24e70b6baf85345139eded8a736fee14dd2c324a99f104b489c87f4f56064bdc974b60dd276832104e9d312a1e3b6ef6f94ccd23149e5183abb1348277c69d3eccf72761c0e1bf365f520584e9151b3c5092bb1f8480a47555ca18a3c8d3ec10bf28db504f33d1ce6032cd7d6251f4cc72b8e2a58218ce7f2bcfd964eaf58be3746e2c0f6b4c3479ff8baed7f584428dfbd6a0dc04bf899acc57e2ce18ca2d68d54b34110a31f1071a1ecc8192c493ee4c48eb6942b46a209fcdb4f12acf5991f403629882386afcd6fef5d6ecd308e3de96e8dbf8c7501fc9a56d3026c6148c416ccdfa1a1e84c4ec2cd17813bbf2943895a0a550585619fc1a6fa5d677d604e0be03402261751c5ff0a00b2e31cbd5c9d87b486153588030bc9b2de99ca6e20102398ba1fd2f72802615a6b0930e9a60ef11b455bfb85de7c3a9123bf2b18f6127094addb6b1211a53287064c6932123c21c5cdd8de34328426a38f30df3cce6ace6025e2dde82bab304b7864a0ee2c340057963c7d754a4ac1d84470c9bbb180a8e780a5f5c7d2c09066e5905d0449f155bc795f593f48628c7bd4bd47d364d11f3abf3c1eca825b279101ce2e4f7aa93bfeac8ecc574bab52f7ea48cbe1daa525f84dbc5e4d2025f74e221e724989420b191af6490894d61d8cac7435dcd6485e14278264c5418253e4676080ba33b4515b80105471f87239bf6665f036880992629de4d7d7766022804bb45c023c1f69e8caa5feab6bf6b86cc4dfa54cd7825f37d92c6e8cfc3a137ede240ead64b94b9c6714c8353ccd9a3f8a9b65f6bf105be2e13f1720709c1962be7fa1db28c44bcab7a7925876d46f303fb601867bb8c73c824cbe43c7abdef100ebcdfc52efb1c7dab35859a78d2c82873d0aef494052b8b6169ffe315650d9fbaa7d7f317230eaad97d01af9393d85f97197360651c095518b44c1b46921cec80222093ef9817f603a959e4c2989da7b50c7383cc15f94521d7dfbd0d437471cc3fbce9d4cd15a452aba051dfc4c6ca7a6d4b036e06f979b2b03dcee6cf97bd8ef06fd58241f486b9b4f61a5c4249fdec2c7724da722dac3efea84a0597f3a9d588185d0e56701e0e347e4a44c08f2fc0dd6fe6f1a90f94e5aff417694a622b55831d2896a1674b7f8a07b4658a559e2479b41f74230c72f8725c8f16d299b4253c425a4d90f7c2548ea2e202560a78f1d613f0696e9ac6de4561b7227ffa7f67fea85b18383cfebb4dda17d9d82f3018203a6216fcbd7f377cd2bdaf9f0669e50596798c6630a6b9ad9526696876cf7fca2bc7a094e29b95191a87fdce6d453cb186c39b589a98839787a04e7f7c95e517f2203eee01781f50cafeca0a63559e2926a41fd7e03fb2e98a08503de905e3e55deaee4d0d08da155ab7144f97e53cec6e6702c253e13b1d9f7be80abc3d3ef4b50e5caca7089bd3c387080bae77d9233901f3e75de691e6ed369ebd775f3f8cfcb9e8fe0f19c3f03808cdb7b6810d25edf3a3458dd19d55f3fedb0a277f44744f0b9d91a1aeab575be9ba7bda769fef9d1d58be683be54c2ee78d3f59a33caf15a59e826aa84911dd683a390bfe027001d52e98ffb49597ba1f259362700b616c0547c5015173673aa46dfdad03868556dde04325687f84b7a93e331536015c57472043135defcfa3fa0b991f89fe43b89055aa07582085da5e10b4dae00c1708cc3186c2ea2aee7255a06312eb4e926ccc77a1b9792040534729dcd04c80fad8fbf40d61e0f4410ce309938ec17d85accb021464a497ec2bb7fb2b1f63ef496ba6dac0c0a5ee1a70e37d6a393fd50b09fa59de2a7b27a5bdb65aa74179f706fff1478f36a2ccd05ec150f191f11a856c52ddf0482d9e0593fd9c78e866019b6d3b63da79e19ece3a0535c92018d1da44f58230697e5b33225aa6b9dfcebc595ffac3c1f69594c07531bdf9214917f5c8da62183f14fd35a2f18be6f680fba64aba1cdf68e34aa38698d8188db8f953ace63833ba18d09b3b9e2e3f192ea88c426ecf88a43e8f98a15ea15c6afee6f61f809366bec170c2bbf472c76af772f5bd0327564792f6b36e9c9f8ebd251754b01a23e833d7102369bd7ad32b6f3056dc9286b389c625cf37b07058cbadd2f9724c499c72307c965d2a5dea5e82290c521137768882b33457aa722ad5e58c906828a17128141957e2adf59635dcb5d7b298ace5b5d291ee034284795e7583287f9e9a31234bff9e0a0927076316ed760773e17948d86d24804a6106631f787cf3497ef80cbf71e822bea026be444d620b5b4b11d17e6463f35f1a1d67b57e72e16194fda9202fbff1befd44e73fdf631d6e83e9f6587c7b718d0e92556a74489c3f56585c016dc882bed5a5206ae4977b34daeb6029fa1cd1f1b67d2f0eb24659eeda1454468963f9096b34e73995602adb0aee6e833fb3bdac9812658f11dea1f65b2225b14b2011867c33d033a347df2353a50706d374063f6e7716b2f68ccf91d7293beaf9d30f2e9cef6ec3a16a74f97f55cecf77a4603bdb5d4b1809e5a5615ac55d8e697a68f7677e09ed80f3a6177731b97f1a91567f97f6df2e3858bf271e04c8ba3ce7fd1b8c1e95b1c780305837dd2ad877379628bd3fcace10f6c0b76504ad2799b8d5c64c1fe0b11de6881b85216758729f04f812c1b7d634d31bba7913011cbf367ddd83770b8fdd12b9124eff36f36e2aca8ae02695fc2f448f5111cbf05237758121876b86dd91426392fdc686b7f6e2c8f0fce398ca85c6716fa22329a1d69b3ae18d3e0aabd6e844a6b6caa950fe05a81e395f747f69be37f94e6e141acd0ba5d279d6e7c5b5b5f0233734984ae1621633cdc2773fabe2c3c1fe2f4df415745b2f4a04f23545e004e3a24bf1f169c23f849a15770167a249fa6928f86c53047808e4d514f16ba98d03b47c5b5a659b0516f1e5b6b59512a6926bc26d792d2d3607bb60718178cc4a1926d5b003f221da85b1b757632aa45f6006d60e9921b3fab4dc89667a65789ac8d79810af513811d6dcc16dd59f83fbf14a552b7f848828fcdbc5675bff10208b08dfe2b8be2f6a968f361bb90d18117fcaae0d2bf028028043b98b585abb4713235609e5ebcc97c54fe75e2f262eb592a1edf0c221c017e38903710431f93b8a8c2dbf197ed4d1aec2cd525a69e10374c54b3bd7dbdfd642fca30f6a7de95a70765182b4f2d0e5439e736d2bbeae23acd294e0dc2bf743bd838985f16e1888780425e9f9d0a64c56691b68256bf80989a2a5eb7880593c6a6a01b69fbd0cdf0349e9649d3e89527f5b733ba8e30b377250841cb55c441205c0a437135834f465e65aa01dc730aa21b28e2e9e803491d3a0323ac295611d1b6eef62e8a250774b245445f041942fddbc1e185c05aa61a51c7fc86e9ff89e1d9509601843a5284f7e0fce4d785472b22082c64663d969944e212c1c3c2e4a7103d80889a6e65f17b3154fbe021259e7fc68bde8bff30ba96428d4ddd7f6946b61f042ebb0458df5ded668c80229759020c93801c15bc69f80b1ccc200bc65f2f17a8effa63968d589257bac95aacae141460e1043a1f00a753d1fbe56af35ceaa726d24d0d6e2f112f8823937ab6280fbe029e34b9332c91d8f78d2750c56c32014e2756c05b9152053dfe083be9cd73f17e5aa03c2b5c4755639dcc001eb5d33b519534de3125bc5cedf544d93ef2e3b247384af4bdf58f7f953d8ae9795d526b49d46510a028dee0da991504407afb9ca5b90b4cfd38ca630591235f1cdb5fbda5d424921904d956ca493db45e9df544e34b2642dfc55d5a65959dc33524d39df74a3b4f79d28ea998c415ed3f594a0799591d82070e5824b8d5496079369a79c0f6a1801965a8e824356e065bc0e3ccf7a3ae15f9882efaaa30f999b718cc732e39300739d8e8ec2119c4eae06b2dbafefe3309b777df6fe52c3417cfeb76a95825f77a4aba8f8b7c22b0519aec330ac84342fe2b8a9863e157c9345d3add18d4717f0eee179a760bd6c45773a4ee949758534c4b66ea4e5545ee2368c746cb1ba1b799ffd3c429f2a3d0ece89700bb16c88e4550f080cc32b8c7c4377cbcd0f2fb8b40bc5afdc96ad4fc1442657bf93e676bb916e11fdf70eff348f2fc3527ed01f9c6acf26ce4b417e422d5d6644f3dfde437ff79eda13a2d0df69bfa87385ba506fa",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x3fcad213c0a44b0e0e85df812313462cd5e4e31d6910ec0203f19fce1a6dd70e",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x97473985d04723299559f49b856effb47d7abfad",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x13749f0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x1e70ec75f3d3c93e0defde8323d57145a5ccf7e63e8b2706ccfa4ad3d6a947c8",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xc3a7a99dea71b68e56ceb8c35a3a885f281a52d28d5f8127f6a8733f48fc07a3",
|
|
+ "timestamp": "0x6ab8ef03",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-anchor-20400624-baza",
|
|
+ "sursa": "2800-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa0626573752032362e342e302d616572652e312d643230333230312d7774613037f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b841eb9b479f6c54dadc3be243e8c1da4b06184aa4df5b2b94f3940ad62a016f822760bc14c8c0fe0c8ff813316afb3e23afe20afad1b59a59d6342b93240d22fbcc00b84130ab299b316f798cfc789e8b6784696a25499d95296a4d5697079e31262621860dbf71e7dd9c78661832e9e107e5ce0f8fefda40cc7069ac1880f616df2f28f500b841d23dea8b69d2224912d48c76f10c1a645b8233f78d1f8e24ee25fcc54cd822602f87548a7c2224ad08e4f49f7ead13baa78c7e50eee3725b31af63434291ac3801b8411394747c45d98fb460025445509fbe645b03065b928d9b23b68ad6785cea54f8032a380d7d2c5736dae9352ff06eb3efa466d05343d5361a198b70b747412a1500b8414c3fbb1dc78775a9e74e219628e8793ade5eca2ff1ec66792436ad7a45e72a851b47f55fb097ab7acb16758cafe3f26bb82b6dccdd2f53c039d6bfc0e275b10100b841c2f80145f19ff901a1e3cfd2bfc1252f1f255e5fda4414882c42cc292233578123429f734ce286513b40c7bf53022021af2c43cffedc8c8ac062d3cf243505d201b841e01d876554399ce00409901c07226e7749754a521875d6671ed1eca72804c77f624c43dd1d8d3fded9f68ae0e16f5fe0d45c0d84b152269210c50639fbad8fcc01",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xbd7fe77d86785ff559388447f596a730c461db1c588163be23a14b48bbe90e18",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x1bd5514286f5602a6762b0075266379d29af1c9d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374a6f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x49841a7f52789deb1fe2aab1cc41b875b1271b8f62f06d1e183b7883df5678d1",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x666ce487a8fbffec6a6d116f729774cc31353fd60e1d5bc43f6573a21f52d653",
|
|
+ "timestamp": "0x6ab8ef4d",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa012e96a024b6674da2bc33c4dfaeed7598b11f4261f8a8fc53a16010a3b9f1ed4bfbc272f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b841b55abad0e0f3429bd6e5cd8e265903f8ff139321b4a633a7ed7ac6245b16a03e5aae3ba9727c809a494f27f3c435c6270f2e6d04ee7e978327d7213b3521abf100b8412ddef8842037bec4890c1cad607c14a2fbcf2454ee92789344d4cb13b73274c05525253c18a288210a1aef4609bf3889f201262d4cd30a0c5619658d93dc6c1000b841ad3bfba7f3a6027bfe943466dc6d69ac75e93aff24d164919be50f26d98a74da02591d1c44b0015ad439584c0274c5cb0d2c52abbadb0ef8f65627619c3a3d6d01b8410e2efde7434eff905e65f568e2e191285af75f0c2da65279a796c56aeb1657fd39130b63dd2f8e7c2aecbec3b945800ef4375b3c5922fac1e79b6c41dbf90c1401b84194e080a980f723e907bceabf6847c6fe2b3458080010215cad5949d5f619511412d78b780d10540656d462420fb0acb371e133e2e4978b76e051404c4c2d78e901b84154a38b4794f0e6660812b1e247ec7ded19c65adaaeac677d5b8a5a1549059a2107d939f41b09c18031c05050a3856358d3b04a25b62564afd193c0ea4c18dc0801b841944327dcc25e674b0b05f8f15c8693455fac85ce54fc23000e748297ebd5578225b936b0025efcc32d3b2a7300b91f02c8074d9b528e1d8d6c822ce8f97f8f8f01fa012bc302fa012bbef902920180b9028d39e43795dc180901a2f6ee4a42eca00d843ee0f15e0458d425184a7f13118d6c8ef50982574ed9df95e58bbdb445560f44f4d78b3401777833583f4272ad691381ea42fb91d49b17565034b35dcaa0d7fb58ad541d175eae52e6ed419f94083cc71128cd32997f0f0d0394cedaf4c3169cf7a110440d0541911cb5d258e06639f649ff82afc4cee0de8502650062f10952c311664effda5b5f9757f4e43f5f5b3e646fb59c95e4fb0860c7fdaf9af94fb70d0daa5ef95eba842b95a8411a935ac44b55bc77158d8b43ba9bce7a019254dc07a685b0600bad5d6989a80ee1b7428ce14358e1ff73313b6becb52cf657d3bb447ec3458c894b21907efc6e12e9ccef71f9dd7d528cb4d0beb7ea5786bc37c4ff2cdf775eef64c274d3735c1e7f427d996f4859cbc0946fee10fb34e73343608047989b6c286512620a89b4117c528ad1582b54e8eed2a257745333bb73b7a84da56b890553da149f67b98fbc6d5d9b2866f2f2ccacf92f482539514368d4833728ad9af80379a577fbcd162528ad7018d2911527487fa193aeea7aef742e7988efd28e8362e5bb5964246c33eb9f46c0bd3126fd1486b16fbfe7b6c3a15e2a22cf3e43ca85b766863eaa1b3ac13942d73350a489f0cd3cdcc67658c9c49a67a24d7c683b97c9053147aa1a66b5833dcadf0282d66a67d0c40f5ff2d9e4326e4ad526895d96bb470e66886528c6059d64da7520e4aeb82433b89bdcfe32f5168dab2df5ebab0539250b0aeeeb5120546fabd0f37ba156b62712663c98958f618ef3a45da407e91823bde655f46bf1e6c99a922950a4bd4ab1238ed7d8c647b5a4c5ba45bc72da833694dbd2fc5d4f818a6bb7eaa3fc79ead13234d6452839f8a2ca883dc7cceb409116aed28ff61384f8faf75839720cae656c4a44f91eb50280b91eb07e38580484590328062c261df2c01ce863f9f78fd72bd98793b713e63efaf793c94983fc807c211261175993afe5b65e068c107d7ccb1ffa43fd19230fd04e8dc0b319c3f118a73238d8a5de0f29c9865fcb4aaa4e1e28e3d8bbd31e09f33d2e0350dd7f3cde1b734e13e59484966b125150f4df4dc60908c7b136590e82bbabcd5a4a4d866a62bef1aad9e9909f7805bbe6e05da21cad9dcb2de37782a2b4012afb4904167c56d8b1beb67cb107b91502a2cb416070de2bbef3e93465195cf244cf837ef3d43bc3a8bf2427832f3fe28c9c2a86eb03f731641c9202e498d4da75afb36e6123701311f9fc022295c5a764b27b108550d0b23cd041271c8770f7eabb04cb9e2e1f7a1623f580ce3bd3038b9b8169ff55dd921b04681a220a7ead3171994d6ef84c63c791147901f5ab0aa30ddfea56b1a377fea660fac78df1b6f07e8fbb6b5d05aba905eef578b44800e0cfb02431420a66dac45bb3e82192c111738574a33608a73264f0927e1416e034f9fe21d1d9699b31ff64322d9d19e4e03b36fabc12bc5b010ad19cb66b04343856b7c6853e9776387d856944496dd0f35430914d7bf5117449491274a3ae642d521dbb348af16c27ac1a67b40115894dea10103b3cb0646e2774e70795f3a30cce171a7a0df0c312b72e0adcede5d0693c43161dd87b2d26d738ea174c509ee55116186072f3d215cd24acb37b84b251b97ecf59705a3f62e27158c2f793cb1b816e825a8b068f4f1a4aace041b9f152d0578f910953a58bf693e35a68627c9ccfe5e37a201ec97fd9b7d3995c7342255bfecb6cdb590ee977817dee3cfef62a5db486d09521c1ed9eb1b58dece6f13de7a58f809b51e2d6a1a27141114acc0f0ad347e9c80d716e215f06d687bcacb605155d3317cc88e2ed21b680af2c17e01d4510c2c088db6fadb7aaaadacc4f24c9c2fd57fae948c8fb99ceb8d3a3e8ad7eaee0c078c8b4c4105acce1bb31af40a882c4c9ef29e8edf9577ec8cabf057704f897db066c52c8fd5aa08b5786e02b4f02c71b313f4b826330758888bbba3d5f23aba190649fcce15f617df8d701773934f0e1b8b0fd4331576a0f4faee0b9fb2aaa15223f5c5f5956800c97af89c337c15697814ee804c62feaf8fe7e4e8881f316e39ed7fc7e91322288c79df528035cc41e245b4a58b95db915e09c7e07290e26b732cbc52e2bf64930a544d0d79f2022d7d9c889945036d4f5c7b9173548b1d3e0e923b1b970bc7587b3aed64bb92dae9398263e346311f50bc79a1358c107423f3ab4f4e51cacd56fd1c13b1a86dd93f3c0b8fd500de53c2fe3a666801a0075e8dc19a2f0fb9aa4329cf7db392068fa1bc2723bb40f87735208ded9f77de9e0fc6319ede081213e309b384f0553cdade84985595889b65d831830abeeaed3ad522d16ed52ff6b46a4c9fce41dbbe67d1f042d27d2c35a69ea0243419a2349e40319d9540069dd3aaaf7f3fc8c3bc4ec033c1b5870678137108ae787ff7549f944089350aee0b5832b2fdbefcdb420ae6532e2a5810bf5f82f2eb53fc936d2c6010efbd6cda85610a528459be79d52ac8bcf6cfbd7f05f8e258470ba41a67837fa15637ada747013c09b361bd7c13f865c83e9bd6743814b65adf3f19a6e4bd2f611f815759298e0d89edc7ff4c533295fe9a1c5d9fd870b3ecd25d3d59d7c8444be790ae9533dbb7014e151a35ab13d401b067f9bb21d2d5055c1ee6854af7b0d4254b25a1990a45ac7b139e24eb39557dd89e69239aae1b3ddd6be041595d53cae2d3e98799cfdec21be89c8c4faf6c84f0c7e62f23eee0012e0a1d1aa9e8d591cb972e842990b5a8e150c9856679fcdacdffeb947b8e3f125140914054e63bb6abc2e87fe7854021e34e02d12bd7fbaca219099570e6a827e8220275175f0afa0c61c03704a1c897e915e54f01077ebb13e92d75295cb34c8b9bc94ade08bba3ba72714fcfbcd5816774828199e4dbb5dee7919b373778991c26bb5584a1c9828dce22411672a6d473a688404dda3e86c8477c7efef9f767032fff071aeb9dde3267c4008279922233f5dd0e21f0105b940adb4aa14a407c3adbc1f9f112752a3d7bedfccb831a4c4694857dd2633957a9bc599cbfa2abc5b63abd0290b04b892914816239b0ac80bd1a40d221b5a69af16abec3238f6239affcac414b258d7bc93e641edcb877d59666b4f19b33f810ef85518364eac7523baeac187c3d50a017c489fd1ee7b7635d9abcb4f1831f3125e8ba222ad47c816c2361330ff1037dd7b512c44db846ba747af74995d8a399259cdb1a277f9bdf012e538a718c48646801107d1425b046979d9a030b8f10563448bb697f1e9f3ccde295a662a603852b713f6253aaab51256eb957bdd7aae8b99120d0b2e54b749cf81c0d6e8f821d2316721bf7ef090108e306d84a0b5ad0b2fe0bd9c9a9ba96042482753843a2ac3c831efa554c704f7b3cbb91522514ed0e6b8d2ad450b3a608e640f79761bd1a7da592c4a1a0852760f88839d3a636ccf743555612542d603e075361e9d486e14f9e5ea05f253143838a9165e9d42448e5a550cfbc7172010b634ba55db4aac0c56427e35a9136449e8ae4c27fca32cb04d7b43b4d1ff40deae4ded604839b9a47eae1a08422fb7ec191dcb4d8a9a85b48dc2745abb9124f347fefc46b2729b0fe977c4a56660495a6764f05ac2c66bd8a18ed0f0c73422c66bb362442f463175265d20675ac9cccf5d18ab4123018eb5148981b7649e11d64cf6515d3d20327bb2b59859b25e4b25d93c9015f9d76013671033694b55100598009fa638886119dae469423cd213bb5a782380908f88291911aee34265bec6c858e9c3fb1f67d56b05cd6c304bf5b9c0e209f376c0534ab074542428c86e7bff6326eaf75295db8bcb729a11a589a50aa9c46687dd922b86e55731bc811485910144b3138fde04b42c760ad611b98be0426e50edf06c917aaa0950b59b72ee4ee3629c82b4b854fcc36bafbbd81122a062269cdbc0464e408572b12a82b3f675c1b0c135e50b8e2f1eaa055601c9473f90fd6694020347da16b38464fbb0201bc6bc89f846fe6adf9aadea0ddd514488b306506072080b4e840ca63e42c9bb1bfc6a8454709441b2f82681579e0da88fe33c442583593745cf71c12b0d21062e50cb3a9e59a91978b944aa8460968a4ff95a3f67a2689cb7280e916198af428a07db1a8ce877ef48dff4a933efe5a8644f9477b0f1a8f5379f8a30e52e05d419f673170dec8429b238838580b156a1c35e52b2097e24595f5d31b29f63963c395829c54f6de3339fa17a7420d651a2fd8acf40e1bf5061c17943a4459b64e79c5c8305c1c872decd48e0738c8754bac7a0b91725dc4da189bb9dbe1e829538a27b727bd02a95393d3608c2f19238f6d9d4c1722a1602b79f2f07e9d8305fbd258ed8a22231783ba665a780637f3ac402c76e52b4aab98b2ea4fbc3a8099dfb5f309e0299727a09b1d38172028c6b9cbdca20d5df4ad307c4272b19431dc9839319505a7a2033f8693fb430cfa2857398c1e272b6b6c4f7b8cbd8df9b0839b61a655ce08d0b67183de3c110974af0559dd2d61a1c80a9429c1420854e5799009121d65f3eb3d0206cac4806d7f3f02f4918c7016ae75c6cf93af553cd96b1ec347cccae701b5de3a598761494f4d4359cdcbafbec1d969d37a061bb131167dff0cb786d2b38817e3921cee2de49ca43b8a331862021e58c769d3f715705824ce760de720bf5cc6c01ae1f62c487b3bb480d8769922e7ccc4809b257913d8094acda71998fe3b6a97458353fb587396b2c80dcde06f59cec8f98c13ea2ba0a7d7762aa19e08380c1b788f9c91b2b6b17c12f74c9a389b5a5d50ca9579ee431c882063739e3230f2ac7c4d6e31577847edd4f55fd3d0bb3582e0b910c616c3726b3d66fbf64be171e7f4b79eda4c20b4390aac83070dc4610ffbdedcd08cd8170685f0cd2754b492626aea1e92a5cd24be93bc97465b235d47091c37590fad714bcdd39dca901229efb94473d4190a7e43f8804a14bf0a666590427bf28de85bae77adf458d7ba8815d3b6a119d381045fb280dd8579e85470884194cf27ea3acc56182a294ac82646b2f1b9e81dde4c75c64f8399be2379fbfdb3340ac05def76840532813b6ef49420f81a4754a3a1680603e917b7517dcecd643acf78dfd5ff3b6a2ba5d640e1c951c16eac5f2e4da0dcd2b53baab26e04a845a3450ccb7559b400f838037106749b07ead6163b5f3f723dd4552bf4efbe350865b472b5caa16058335ea1b8929e1d5929007241e43332fce205af733f4af0ec95f1b553b04517bf53f7bdd2f01296bb9df40d785daaceff2ea86ec31004e586bf279c1254139cc6af8ad5434e3d75f00551e96ab78c49da95f88adc9c1e583b1bace4a91af6354bde1e299469ff2d262df2495cac824a0b55e5f12c52e6224a489658b16e42859c9a105bbdfeb6f061533d33b53e67ec38a2e60905f3f7995601958edc1950d4ce8f98ebc514f847f442c2ea3c50feaff687f982c6465fa6abf8c4842f3cfa6f575be52c3b448dd84c3b9cac38032f90c72cafdad639df8dd9e0f72637f1b447557850f1e40ab640bfc8f459031e04e96d4f82c8c35a9d30acc4a069690b7f519704147dce2768eca657d69e89341919f8d29e697f0a3b96fc0b05a5132e018ba7896ef99e4c060ce196507be77862c27a59ff7f6f88c7a970137a66ac7c2e525c9e5d06b03d91f590e45db4a93088659b405a62377b4d33a15139b9b802496114aae3aa82e0b3d444c2d3050a3c1605987d5591f8757135d7ab43056faf96fbc26bcafb7c803e534946773df750086cc5a28beb7392855cf73a400786b5749319bc50d77e50f7feea0d28233956756b867b02c66c9d1fd13f349fdee74f48ceb30ddf94dec2c2ec10354237ecc047560c963727ce44f7b7c93a843d9eb26ab7ac2cf3c9284dcd32804d737ca8841b037e0a6519cf64ca0a4c251fec00cf852eee9f29420ad315933543445c9bd5fc4fbd1320e4ea87636dad3be1a14253a21f4c76f11e3aac8ac2fc55976db27ce5482f269524356c74ab2332a957d8b9143c6b257f6e040f416e18a1ee2775d499837a08b6679b1bbc3f0f4243a0dd1eecddd98b545bb5d5aef40f0a5b86832905f8335aca60bc167688763ca4d8dc40a3bb766e45301bfd9f840163271c3beddab96897b8db0bdcad9c305672fb72a270038e89b2b65b13c0b833435790f8083476140ee5acc4d1c29ea857ae1db114aa1a9704e81df05e6d0d7e4dd86a6797ca82330a7dc11ecb5a7d35385834fad532facecb16e5409a308847dccc8a47e9328d5094f3fced57bb5f03d29e7c0763f73003797770b65855fe4c86ab3f10da1151de1ef4291dffc72088933c7271f0417db46977008698a91e55607f27dc777fbab3f5a7280e40d19fce8cd14cdca5419738b969fa84940250ce45ef5f548206e699b7b73e0508be55da9bb3d2ec3628701d4e4f22928fe6e645b5de68036b72ef0093f23925afc9fdc8434df91d2afe8be95a89379760716297071a14e06ac3282dfc698d7d44a6a8b5a1ca1295f9acfc380f9b5e3dc62a34f708676176dbf1458394261b8601db0c785b69c60a77b6dbf551926822d23db255aec0cbf2052478562fd81f91fd10010e066a14318cc5c7cd969edcbf5caa945c51b5d150c0984100610181e281cbe9eb62a43260e86481a7122172c23793d74b05b20af5776649802442b75d3121f1a8e9e1c96c22f46171e81042b65ecaab6a6d5fec63007434da8ad988976a46583d037b99f402451af051cd9afbe301352a3c81c259a2da2b8d260b22fd8e27edf13d1cd0500aeb3a49d25dd71fafe6efd3a416c2b6c87250a127f5f339f527a5de7d39eab4315853e60f6c375802a1b23e54c0eb7cef031ae3c8c5e4d63bed10c2f73d191686242de7abe1a46a9606b8414524f365764eceda0726d4b74bf9dd5cbbac773717ac2b86b911ce5c74de97d7a0d2384723354302225db53f4f82dd31464b3452f6c17897b598dd4365ff813ad09b2b5d4a4978ab167860dc654fc51635fa2a6621789b90c8d76c24007f5d06d43efdb0e56498a559f9c11f4b1357fc78a293842a86df28b4aa131af5409a289b38bc1c96e97a5a675fa0136da28a3c0ade206ece8911f9ae9dea7604fc9f044afb386af70d1d197174023a3ab764ffe500b3865cc0ccf08df9024a818019ec16e26821cdae00bd210815b0c42b700340dfff54f1a7c43fb101cd611f846d61989d9f02e7d943110237ee07fb8fcad32ab50920afb8e0062b4d9e44414804642527a8a793a8c08438fd8f3eef288c9ffb26fd2554d27fdcf66ad8828f084ae6d8b303bc6558b8852c64692d6ea1341075c060dee1875ad24ac2f7e0eb638f9bb5a3ab5e9e7061901275a4dd577ed421b156fbc690e91cc46cb3ca12aaafb05ec3025e9f211e2ae51cec2375c9057b3cd5d6bf7af8ae2650dacfa2cd4c0d39d360a68f1ac4fe4ec5a64b6c12a69daa91efe850190d5d2926dfa75d6d9b26b9e7a73d8b1d947c70d0da4ddf812a7baab32f91899f09b950a0d0bc2cd2f3d9c28bc489f1e71780cc1898f94d0c1385e65e5b378577530b48ea019a843bd1bb38ab36295ac65b861d3232b057e68e678e7955a811a40de143f5cc1159f3369fc31933202fbb5a59a311722d4153cefd3c3c9c22013888b657d8c9ab8cb2f8a6985afc2d0f59f0913b4fbf909550dfa4316f1a7808905a4dd99077bd4cc3eb66dbde083b413d3d11e8e47096feeef168b99bee539ee5cf58dabe53e6153d1074e4949a89ee95febc8c18c9c553526916885fba15dbe73ebd0eab28a071ecf1345a7ef551a09532386ef1ec9d579d51cd47a278f9a4fa3551d4cc2a96aa3f71e269f410e741b5d548824e3a229d04f5ed8f9ef57814e30044133db4d54abc4d3e0ae31a25fd93025b6d951c66280ae87466ab0a53135a0bf8621f125ab399caaae5296728c43739bce299e9c81833476e8e374b781d2614da14d09c1b638a8ac8555ea7d5b56b9742fd2ad2d4fb91a6a2d4790501fb6a26bed97609b637e0fa7dba74517c9d0549b583c2a0063b7676e8081fe0227e26fb6066d88b03ac5f78f9eb09b6f8542eae1c3be428253e021de7b2470bfc3cf2ab2f4fdfaf71d360c82eed6605d99610a8983582e34e34e07ab3d09b37fc2501943016b3c7191f93e11020e353e91f378166cf18a2a00f39141185af4d24c0e4b5d6d16e5fbd66cb93ae7258b26fb83a7a1d7d930f5f82600e44b32422d9171f3fc1cbc43abe264247d62049b96b48baf4a6ce5045fdc7ca93eb7b3cd3527cd036f853c5ec7f039d88d2d8c839d51fcb4f2bc64ef3f9da0a6bb407bd73f9c01ad0716d4d914850a0ac5271308b96979bbd94b51afe3a8c99eac7888e1699e388f660a424eb95b615c68eac802d7803ed9120f96e5c2be45e4e456f8d306782317614f2df0a1c45922cc31d1c66e5ca68b5a15eef75110de2a923c1dee6959b27db4d95b365aad94c5710fa447349e96b7810ab3d67cc5042daeffe6d6ff4fca69bdb4cb425e5b1dac6dd3c1226de6bee286e9cf90f2cb68380e75e667b496a756b3138b9d08d32d9797d3651efe6fca1ae326053efa9ebd2051755658346abf0c39de85f30dd50d734a7e76fe82c80b053104e89b8cb4403ac720906df7679d567977cb2a6d36baf6b54ba35f86766ecbe2e3a0a90e032601da397a0d29a7fd632682c473b2ce448b771409b451ed4f623d063b084b3708ea28112ecb1a0649347af2a27556e92884602e6cb3683a1cc84102e24158dbca8b33bbc4bf07f7756c0db2f37eac1cc202996419025ac356000f2145aff817439f18b73636c16814ec1021ebfe7d2cadd6faec154317324a1f5aaba2c682a49a64a4f2e8de0edd6d3cca38052ea5615c713cf7b751757da81c572323b7c6495557406aea5237f43398783e9d3b6a77147bb0f8eb3af6e40a386a465b4d3a3cae2833b59bc5a5e41123ff5ada2b9a3447d3266c879aec7a2dbff3f609641afc1373bb8024d081725489bb7e3f06d4892e88a1e3447afe546b9331ed4b0617b9aa23c7b2f3f754e01a29de494bb33b3178dd5bae9f8e01ae8570caf5a488172d0625ee86a7b11ff05d453daa180b8ad9475a27d014e237ea20a83dd58442c57bfe0256a1e4c6d2d3747d893c14eb555f77cde3b30d678e66ba7cb85a1858b042f941f1082d914d8f9e59bfdace2776ff3054d650d01a130ee43ea6cadd0a17a3f6ba4b93c456671e2441f46e7cb3c73aaa393050840ba657b9bcae3317dff4e3f0ae6dbb488b90a49b2ca74283baa292fd8fa6a9f43b209a4ed200d38f1efc78a6adf33f0ca714bd27922f50c2076cf239ee91d29c35fb0c351db83d99a7fa4f23fc7669b8c635bf36af4de22be4d5a2f9814fd04c5d346fd2d7d76a7858f0e9f5deb27a41a1cece98f07bb8e0dd898d2d8f20bd3ebf4c76c16575c6ad6161339de3346ecb1670af7c57c0851e6c586b757ada17911952095719b04b27a26e4e3cdebd191a8f6f19fed5868dae09adf8195c30432e93357973e6a78abbdc53fcf41397236c21b7364d099a37b2f259de5d43cfeaf829b8b6680ec0e45690b18690dd8291db50cc049ef2541c1b9e4d338c4d82c18c3588c77f885de910b6e221b27e35954b39e0df58bdfe5e8bb4c38e05eab305868568a76a7b2054d52b573ff2e7d14a37d1e05dfa7bcf52ca7e15c762b77c7d2d05aaceb4b6376dbb44f807608c41e15ea6942c540471b8cfa6f8efb02af3504277e4a986d0801a02f77f8ee3411a333bfcf9e87966d2cb68eef523d3af2539f87fede953f02123305e144457fba720b3dac97c0e67d63446bc40398c9921f388f48e438cd93f0c8dccf6a1d4ba28a3bad48cad551f8877a3a7b0161531ef9bb07594c20b4de178aa4b057dda09df8874c1e9b072b392dfed22f3a9f1c40ba0384046c623d203b099f87549207cfcdc240e9ea4febcec933ad8cc1cdfe6042921cf453e0ebb764e5ec2ac70b192fa71e6811fbffe939931de11135217b2af071175d6231663dcd8aa455041a2a53150a64ee4906993fefdc1e088cd5c3cd4f705ee22a1720a84cea24b0bc92bef9e730148796fa8780d17e9cdee9e0aea476f7d08606477233148f45e0bdfe13d197fa07744d411f0f87b2f8ea1f8c624ef3631896d21d0bf909751d77197f789fcb8e657aa5de19e5e07692c9b03c026b81674300bf8fa410f686d597fab406fc4370978ac9b89790d034d6cd8d8728cb2e1cba5052099451ef6290a97797e4b55ceff5e05b5568f4c3bf6f5a35e027d960d6e8e852d12e1a8dd7adbc1cc5decb799e6cad6c83877bd293c15d13d2ceae1f536618d7c1a5a3a3350d6b714cc42ec31df5c23f8e16d4ff78f17ccce1f810d2288c442103d8cffa3fbbf6b7a0530eaf0ff3aed4a8c97cac75ad81cabd74ce0bcb9b1d167e26a957be342df54e7691c4acbadb8ce1478c537d494d7039277e415e6eee72718e525d01e4b407016cf93d34a8ea090a5bc11e967e9c8e82c54b2595e5deccf84eec0d829938fe2b81bb9a41f5cbb9a8585d5b4af3d57beec933830d7d4566baf12f108fc99d40b71b19957478a1867a68b200632c8fdfad174ea2ae3e28b4cb9e748a7e1cb09abca6c2ad24dc45f16b9fa2a53d8af0312494cb579223faa8ee1167ee2ed1eefeeef268e3382e8eae87181e119f5cbb55ed6f5dccb72ed114d0cd6a14783c31bd65d7bc8f822ecd8e80a0cc59923d53672c924b8c49446839872540ef32e5ff050b2307c56b7b9ccf83ab825c85f8c503b5c367dec165c91d05c8364c674e0721ae38a54398bab9217908b6be63a20b6898d1fd87ed8ca379a522b13e389bca9b8dead5e9c061dade22615a915323d9919ac32c0d878ddf8ed65f380b74e93192fa1e5cf72165ccd384a952966579ce29c7afe6730bcb4def99d598dba926e4b1e9078752c41714f31c5bc568416c50fb6eda27720e32b0c14b7fbb909219d7f4797567ec51353cf169adb836b1fc6f5a31da6e6fdebb081f81a1edef1cd3565d7bf832a683a9463d280865beb539b7b23803b169914b3bffde4c2afb236a985dde56dc2dab9521ccb002170730c97452797aa808ba5bbefc181a27c94a632853d5d2534f97d78e31a974a940b4f74fffb2c7fc4f80d25fa7616dafa3f829809959ed5c586a5214aaa5136f7c501dc7df7cd362fb9bf3d42c1472a721cbf48f086b1535bb90d19c9a5f8bdd038fed1f16103f38b8b5629ec4e20e88b5a1189934e81fd589a180b8bc50739c413393fbd716951253ea5c1a9ae3d522dce37d270426907d43cf4c3ba57de8e3c80dec80e1dfb6badb0ebb9fddfb5d74fcbcfd7157f7dd8647521edea6ae056d089f71d8d70d30eeeb516593b3e540bbc1745f821a8d2fbe6925ab990d1d3b5f47a00de530d642f348ee3dc3ceeca2431a38f7c00c364475c9f30286ed6e8ccb945dbc3a618439765caaa89174d0dbb388bdcc48dc2f35c39f90c9a42461d9541cda564b0f297b5047ce6d0c6b792a9ae7780f8f78d6b7249cc4f6d3a3c8b06e2c17e4c807108de8f525d5090aeb830323f1da9045bca7198f726e1fe6d421be9017287ca274cfe952b9b81c46cf577b24902b155ee80d39a193d8c4eb23cf760fc870fac35bd655571ecfea641a4cacb8b74534cfcc35bbc0864d13f613fc3eda79648c789a448322532b27b8ff2fef4509512b9d20943cf5cfc89e4198f649035373f533829c0ce25c9b3643545ca8b059aa8653cdda5aa27ba3e615c4feb7d08d2e286961f4d9a04a791fd5f1800f1c97fb0f6fffb29c20469e5d4b3ac93409f871101f38e7e740fc5fa3152f84ede9cad63a1e44f4d46db3549323d6191e7130125ea47f45ce750fa2f8802ac9d78d699bdf7d4c81b74be6660111f077cf415fad81ae60015d1c7a23a6b9a26d6b9e19685d85604b66f310283d9c4a9372fea7b8a89d567216d534ce34e919b4e1e2263974bb299836f18107dfd4dac4809d14df902900101b9028b39c96a5d678ca2f02d5354adc3ac47096b0ce465e67f39259918a5e5654d26d53d85e0d8d1439fbddeba7bbfbdce91315e9e68422d81d96f76d2b42e10c54b385d48321c38ddcb64be379d89b3a482509430f3549f6668fa32c90fb2490bbbab1568e2e59395cfd2e5aa055bd1428e921702d7c12af637f05012b6d736b7ccd2e783ad86e6a7a9923bf5a6aee70f8d489a40e1bd864bf05c33fc69ac5f54f3d1b94265d059a198449ab5e9b2420ccf223560c94092cb57f7fbd749df75d748de20da332a99419317c1c98ea558aefeead4e1e73b70e59276b73abd2cde0a14a6c8d08617573ea4a955957a2142cee62c08239864b2b54fbc8a4b2c35647d29dc6a5c7cfd3e3528db1bbda709b865d54de4bfe7318726fc1a349a78b84e657c64db4287f5081c5ecd94115b17c7d7675f8ae70785343ef1d6a6330cf614b2edb8d5ae795a3a1e51dc08ee4942e0f3e9bfb74f30d924a8cf571a6d920cbd2bff975767925d66537c43b6c86460f83685c1f1e56db81a749bb56b91cbdac672e6f2f7284e0c19574dab5dc82f5b830d51b547eebd118390276dc056b88bca05472133252cadfad529336095a7d70f5e51cdd2441ea4d1e9c03a6872df1fd864688e0af2ca400a0acd4c4e57fd0c0ae953b515bc57bfbbd0768f2108df935c3b4091d2e1f8b527848612ad93c1b691cd2a8ce4a44586d2cb274ab5f99d92bea7ea658c81208b45b676c934e3a6daf3aa1276d72e6de1767805eb3f0a82c9130a7ee7110348e9c651892038a8f195950a5faf6a817d30c4da8dd13f8caece49c7de354fca03517e6754598e4fc093c1025116d24559cc4152d510158b169fd9991f24ee0c284d533fec58147a95fb1ad02114c43f2796a14aaa7113dda114ce6aa42e0df45a0ea2d26cee0bde80f91eb50201b91eb057c0992e498277190dd7e5dd7d0d67df606583e68b6e3ad54e322679367e803c682633b735e557d5b670a9f39cd56751c645c45b857f1a5f5f23cebc61f39b7afcb7335113363bb280a2f0cdff4029733f1282f59800e218f33856ba3905ba71de8f7683c46a587b7ab6a097c0d91a2ccaf675902c104ac9996f8aa208e169251a064267cfb38ec056a4d9db19fe46468679ddc7f604e2087108bec3dbd93656bb1e2d316d979d07b99bad9f0ec686e5827ec80069ebaf72285fb4edc864fa8f5f4c2fe307f9370bf42831ef1a9fa205b0f75349dd81f9553563169b13bb18f128beb14f3f479902f21161e260491a42a7fcbb250cb13c3a4650bb0a5d38fae4d4776cf6f87f5fcb67a681dc8b91dbc5aaa2bb8836f5f2409af24c2ec6df251197ddccd8b8f8871e60de15793d71d837e8208c5bc4f74879c9e25aaad1075ef6c56cb2cc71e383e252cc154482f26aafd1b5c74453d235eab02ca433c36c11e8d60d185150329b1bd9ba1ecb4a730cfbc6005b3d88cc86b987c66ca5158d5271e12a4bfe2b40809c4539d1bc24766daeeeabbae578e24e6824c0c465a60521acf2aee5d838463afe7f651d5cec77906464f754bb6b903d0265cfc3afb7fa6be42168b9a8525e47d7b9e4a6a161823c742ed0bb8a199f8e57bdf975121ca93b3e16391ee1ae6fef6fc8c27bb597f4f48a8ee1a0021d5acd728c4658010d78c09b634d1c8f481347df9cecbc462e2e76374bd7d96cc8196dc501e323cfc50141dad66ff9ddbfaa31f0fe5df212976a94267ce1fcfbf9128f8c320f8c1322c1746e3871e4eaae0f29bf4a142d3d125e4e8dfdf4b9a816dd79684d9aa06e0064917152b3f6fb625ac8f859d17cbe0e1762dd558f4edb008355853cb5d9f0c8d0ef1722413662dd7a20e978c1a23546c6ab6c43801706f24d10e909c1542c5a7a624a582155ac0a397cf3cd9fc3b1a9e9dba828e395a4d5f64a21b8f37a24b29e279d227a27cdd02957fad93ff8f96e27f9943c4deb980a995921f86ec68718da4e720fc036cb1a5200a5bedb842e0f28f2234cf756fab50b8c162c7ad08485b52b8d0820ace686752e678748703ce6e1b49fc789c53dd35eb363a2ec12bb2a82133193509146aab6acaabe759facfe646a2d3bd67c32f9966ed08c7717214893f30e57bbfbdee05d6970fc4b98040a74906387c1474f79f7e9f8ab055d99aac08335acb4ef97d468cfab3709d04f3ff3ba169696bbaea0486e3db7a6cbc4b282fcef65546860f3cd94bffa50d7aee9e36cce06989228ad0cbcf80b15a3d439f1bced19ba311bc4a08bf86838ec9ba4c8cf4bf2cd0296b3360a7ef23b85883b7ec45783e5ad3f65d85087814481dd0d7c76288f289d4e9924a60a0ab8617884fd2f745aab1ab1390e8825830b89bb2de6fbf0ef3944e7f1029a716858e2d7e9ed85b0e14d6b88110a57e95e9df50bd96543f2feb740e98a13cab1eb51cd102f4c6917d1daca5c15f9ddaf6ae993b73ef4f58bf12300bfe8d3dd9a65cb78d9a3c1a11e616b20a7926ac13f00a9be0752945796c0cadb1a501c747d03199cdb674dc958bfa2c2c00217268a2b1b305123f5bdaaa9cb353716ebae01120fefb87d4c2d09557d53ccf636c1d39ef509a699a341071ab33419188e4ed0d0008430b7c7ae4561b4cfd11aef4840386e663a1e655a23fbfe7bb42a371e0afe6ef0e342b435455c8b7fcf04a8176fc48c99bf00b60b4507f7202292ba8584ed665b0cd27af5381897cd01c4b7a7bf518c98539bdcb0a6087c83ddd5b4214561d9fb6bd7a4a640df1b8b9f02205fc213c20a8bed3b575a68b9c19cd4ea6a1e927dadd4aace14ada9f841cf45e7dcbf4faa19535c9b868c4496bc76b800ca651d4ccbbea080394b6d381a17f80a4d9d42ea29020435d4a8441c45d9ffa96140c9835aba29e0cb0250a55ee52872f71f5a962e77d571c945e331a1fd920f4df48f8a98218cb48bb30a0e8d90d6d2036fa3d90ec833e59fa46f5ecb47fb682ed8a3e338e2588961455ce8715668fbf0041fe5a89b3140bf3d76e9b50e40ddce5be46b1d73a095e2d538d74049bf1360544dd8cd99dd58095ccf304a9b39d0280427ceae2dd0a0f3dba29a5bb0a88259cdee8dc0d9ee0f97bc20ba09190882614cbd9264a6f1f910ea58dfde0b5cbe2abccbfdb18ed77794fb11813546970c19fc7e002f11ca47347e34788eaaef8f67b29ba7c6273a031105cda34324a6f045e835c1828ede6452081d6e8a33a396ca92a50f99305ed64976b750ff10d9c19cfa3cbed2b12c81d7cbf7a3fdc5e11ad4731d00548fa20971b5bb15f71c0ab9488bcf062ecc1907c4767143247b3b75a787570fa4be063b1f5a4a3f9c53e1d3a6c21d196b8fdab059ce947767a575344600d98009769a33ff1585f35d88a6849f8c6740f561cf2114e357d248631fe11d4fe2c1be731fc37854ec713ce50a6db99543263e59de8025cfa7fdb1a8d0119a6205dce8a318651217feaaa35ac8b41eb811d7e6e347c6a45c2adf8d9957ee9ada7989d44a000243ea0903ca5f722bffd87b7b86b45c38c1ead6361929b8d0063baabbb7cb319175b7e96c2922704b3df2198202933811aa999382f90491303dd9adefdcee88faeb491affbbbb0d0dda87456c387c4904a2db4be6aed21965ccce916b463d6dd9d13b38b1499d93460463bfc2cd530c9d8341351e332cc528bdbf8a25dc6cb1b4e9140bf9f30d82c2c7c17e862b9d2b614a685488b23607c38155029fd98f4728f8adbabb02981cc08e6eafbc5c6bd71c24ce6a15e56be3da770f1ec38271550ed005429962178744b5b999b03586fdcd81f1fe4b60e34e3d84eead56c1ca8aeee6fd1c68fcb6d266c95397366ea5e29a7ec1b40c13ff348bb98b874650ea97327a012036a9c21a93e792cc381460a3c26c8f1fa5478cc6a7581461073a7ade5ccee86c67d08a63d69b56506ac0b2ddc6f5a43f454deffe7e12b45127897c479e318fed126761ce29bc271bd35024c0c57d3fca89fd15eecdabdf4072470ba78fb2f09d83bb6b1f51a1d72e700bfa4c6e890121590d47f400c08274d65905620189fe88d444015427824a14611ca2d9d6d53df4ac2158266ac627a93f018d54fe4032d7ba8533ddf2750ab9e837981464e0bf248ef73cdc05f793aaa3cbecee9a8037dc80d7fb3b4da2dfcbffaddf3ede5960e5bf71f19fb6f8fec919cbc8fafcf29d36eb8f51f54eb628e27928361576e300ded92f18fa1aad956e8fae5b97e0d20ae0617133f6664a2356970b02846060be642ae925aa3d74623b0e59192a768e50c5db6d25ca270784149b8387d07b4031fa6679310d1ce2005efefc39851fb2fa70c80b89de804783e4e992df783746d2d129e5a1856e7d90738812b35cdc5350eb07506c53f49a7513ee56ac9dded515e2c8ddeb4d851b83750b2eb2266ef638cacf478e56a8689a88adae72394781c8e11304a06ea8c52bbd37b376900d02775d31ef6e16c1d010de519ccbce2bb218b8737f85a4bbd9ea06ad3e1a1e02208ab4d5e1b735fe89e6c25636a4dc538e99c0f8de6f23f9c60c606ccf81a337acb7f82eddb18d8b17fede89eefd930a79eb46fe039b76dc00293a5be0a5ad1b82882fe816916a3e34899d12056def7c0ef24d33c5e4adfb5bcce9b4bf50070c02b149590c6bf10a998acf6e0dd7f8cff59140a7c9ad6588e6030eda539b3436b13720dfaf656e18880b5ce627cb901aa337053c0e2dce78157965b60197a6c18006ada74a0fe74720fc539efa8aae2438af469ee1981e1f67ea9cefc95ca8a2c61de51bf2ae480a8dada6d66a644f61978bd63e98c621cba3d5c904b8bebfd60e1bd410cf41986156df65bd624b37c317cb8da045e4559f07cd1b451f8ab4ea7d9f47a0e8dfa592e1d289b1936de3eb2029c1d1c4c76504c0f50cb12bab132ad618b26ad7edff57ab25191329c0728f3a1245ed87aa15cd10ba5880662561329ba1bdf43c4f714e0fb82777a6855f6de018c1ae8c3037c4a3a33264b6a8d91e4cbe12d755f1f36563863c16c70a84bc41b63c3020f8798797946d80970c49d388871b43d8f7329ae7c13bb1e45665de402df1238ee82475333145ee70a825cb60d0faf25eba944a82888c3397664c1f1cf10dd838de916323b3e3a6ae1f7cd11d16a6c0981b80d37d2d2cea0972a572bc64f2903d47892b2e87d45d015c6c632f43086a54f18ad3e6083be1991d89fec8ca94ac035df2c9fb544591ae227b0817302608e76b0dedabde0450b80fd1c7a6407f1286fc909f287cbb469ebacd82b7a4351fb0bd6039e2bff0807de5bb815f9f8766775dbd62336a715d6fbe1f3c2c9e9c6c8a860b7f6a948fe6d7da82732464ea695cf5dcb501215f3174e9b7d5d00cd0f9e0c1f191db09cd7b33ef131c27c8f0dc716c393c2ede9c4def57af29edf7e3eb8925a8a21518a9ebeac4cbcfbfd0d5e8f27d4f6479f413c02e96f64169fe130b81108a7ccb36ad2800cf2f277c2a52bb97bce7cfa0ff41510fdf83509ddff429fdb940b479d8d6bf430ffdd78c4a8439b4873311ccdcb82bf6009c6e035d70ed793c4305bd8ef1249db98c86323efd7ce8dc07b6fb22dbc4151b7dd648113d9de712d54812913cb51db39743c1faaf63b951ebfd2285afe201e7d4eb89ea5c2d72c35438a0eb538e379cd5188c135fe83a3195ccc48324a66692afcb725c77ffe51990fa20eadddba9bda6d85513f435b544357cf987bdb62609f974528f960ac2fb2c36fc1bc38909bfb0b747259a56f49bbebd08054d1ded650eb3e3968dba428bbe016e311efbc42243fd031021c07c57f69410c885480f798e2f836f30fae393749da22f4c59aa10cc9bd5cd455343c62013797c758c6e978955e426e44b2c2197159a48442f735b030692304cc832d96d77085ff773e94ff393993e3f57af33d2115a9a192d6fa1e44e5c83dc1896cf9643d14669c2036afcd465a8526671df6fdb7953bea1e892402f7d0b190f854023c52e9f61c17b58408ce9b593b13ec9746128619baa90b6a0a4f9966a7c0f67906ba15c41d6e6552e3cb72405532136dadecaa53b8829da8156e84a4783debe4c75470688c0e95bd66fcc6f0802328db9dad20d85101d9b3f7993cdeb4ac827345d3efb65bebdf8c5267cf107eef0642630645c6165918a9ab5385e58b62c98f2afd1a1ae29231fe7014e38e59e1bdc8c2f1fc79731f8b43125bdde698e94679727f7b179bce6a9909ab16703e4640169bbec5b8ba8b25a066b5d5da0606adc5f8889b9661c86d0346e027075f2cf7436e68f2de058f3d0e77110fc31a5783e93d2e5dcf095bf83e85aa3e5163db6af12add812e82e35edf14b558b0813c1832d9ede1dcbd537370b17f6cdcb3ee68220a403d06e63f3daad8b676d72902dc6874d4c74e76e1188a2ab19446a8443170407a4ad21abcdcb9fb2e540a4344f6584d33564f37fd66c085bf695617ee5068b3fffa73b7696ca565767778d70b4a8eb78a28f4fa06efa0a1d29ef2dc847f2b5ff55f4ab9f7235d8136cc6b7acbf902ee944e045bacee14efdb8b97e99029946daccd9dfc3375206b14f808f8468f6ee9f62fcdfc35f7eba130aaf9763d4c4e9c55101fa5fb6d7ad91c105f4752f6e69c8856707603638cb370da5445b3acafd69a2509e72aae0c0a8d6941a7addd4644529b4d98d78d803f09554d3d0bb6a1fe155e24f373cef41094cbfe3c9edce46aaa3d652907ce49417231ab77f278a7d78ec9119889326434acbd03e1a5d976c2e33995b7e73a955dec4ed4f23f44b1be977bfb06c2b98b11476fc3140692b2e76049916a230bceabcc8f4d71d05f56910f75c146e872242517c57925fe5888a0ddf52694ca028bdc523db41276056f443ab321bde105522fc06eb0861e50bc8a2790837a6f1ea9b398d2070479dccca8c4896b894edde632b063278e59917edb83ee0e79fc1a3e0a9f1727f8328788a8ac580adf8af9765786ff5a95ab9413e9e7dfbb0cf80633dea8c5d2adcfe7da5a1c75906608a49ee848e6d33ffbee5a51ccbf03b2f225a7a745e9c4f3651aecab14b36c9cf32563d5d9e0c6b96957955b00d3b4b060536ec3fec75ce1e2ddb71eea5b68a699703c2a3f75ba1098491b44cb94902e17d983185157af7861783bf2f15c0a2c1f14a6c72c7d35b3604d24122917e2941aec47485fb533abd98f2990d86d98e01d4aa87f63466f17b8cb1b55172b3c9d3a43c134dcdbb10ebd59a4be40a4c31086b35b0c375ce4d55ad639e678ac3bba447d246feecd4893ef9918ce92b9b6d2a90a11837bd57dc9dbaf33724f652eeb200a99ebf7568ccd5dc88aed70fbc0a267778ed3c80761b8b807988cde567d754f86f373f69ce60ffdbf9957f925d49ec3e2dafe7e69bf777251daa598a10d9d4c017184e1442dce8914813268a0ba2cae5dd339bdee7169bd01a5b660625e7d841e382cd6d96b191c7982188921901dd36d2f3db342c29db40eb52a8120e40cbbcdfedddec73bd7e48d90a5847fee1c1070def8af6006a78439bb692bcb2c7190ba3028f92ec303166996d7fe10dd1c91628b5d128f5a7a36dd3a7ad2dcfa3db3c05b11db2ab22fa6c4b2a37a0f942ae73953342fb33306fd700b32ef6389192a4d92fe6cc62ed0fbf405585f59bff8b897ba19216f89e92cde5fd37d6bd500978cc15eee3948e7e808cce88140c677d6ccd1c907b0ba941c97f1d233db102eaf9168b28b1fbc996fe3fe86555532ea33563ae17bc5175d283ed33a4ad24e68b3db9c8c2c91b586157b4ac145a167e63cccd26c3d628b60494a076a7284e42c264632accdca7a3c3f24910ed1c79548f9784a590505857823ba314a646570dd502a34d2a374505de11a18069f013b48598fab739f33cc7f918c3f321d269b9bd2a7f11062f5308f05ab7992c099931147ababdcc7757963162a4ad634390950ca20d6810f307ed1b5b72bc8781f655b61f5987d68312ddda79982f3006288d037856b4ed2b959310cf7096e4f1836f3de6cf373350288f3173d28e6a64eba03403a8110209d20a3191cad056ff427512a2ceda5d454222dc78006c20cab6d9388202e94e8562ac82626517f70cb3b7ee9c737002795ac256d65e5b2b2be5ecc0a7884869b08f27985cd53f17942376ca7c3e2d746494d057e30a82e3d1e7491a106f7805ba2cba801c55bf88f45e7c70f145f849f2fbe6747d91c73722e60e706a0836e31772f1a43beb8b80388b72272908846e2e458c7827425afb4ae8aff858f5c715dd40534898df1fdf05425684e4693e70864b173cd08e93290c9f676936c9515ed37868a4ddd2e42dccaeb4246a4fed30a24f833119361197fa7dc2861bc4a5397431d7e2ce1b9ee92d80f6001c0ba14aa6b09242ff0a3d992bb2668227d4202779dfa8cd9ff0949fe9dfe58478c324998a2d97393c70fa2b4d0161f26549dec55bd67ded31f1cb637698c5b64bcb21df1dbda7ac7af007ad35e715be16179c964bbcc448ea6313e8d95aa36d7e641e12333cc3e238a9e790620b9d1f6810f7cced8d607149b5b226e4f6279b008e9484b60a77a78e44e64c61291c8a5b78cf8238db18240a5baf1e9a22b9811e5ba12b58245f11eafc47f114d40aabeed108d3d91c34e5241249341cd79f140f36ab3401f8d2c0a907bf619f5282e71bddf6aa71c37e3212f23ceac681ccd6b64b4537b0cd96c3da2674ab5f23c017e0ef6e5fc1a39c8b68e74b3db89452bb2ce9512528d57df25ae8981069a1b8b9de6cfc99cd8965776adfdbbeb2dc38f9ff26dce4f03084a8f12ff1673cc89ddca102d8a933eaaffa3c0e6579fc048472a7cefd0696a369abbc6b7d712f5932b063826c099c19b339f57af9fc646281f0289277127706323efa62916dbf0a80e720080aac2dc587497812435a8e24fe5d6fd38592467096f8104976e63bbddbaad94d6cfb699598f8cc060b585b188c91c932092b9267fd2ec7bf00f1c0f577534606d83d5b0fb706ae130446cecb7863e90f47f1cc2bea225ef922a327fd8331439a4acae7179e7a00ef110fc39a667c3b32aa3323a492adafbc5495f5a2104dba8f4a80ee899a1dce4c3361bc557cb444508d8b800f28343aa359ae9173835dbe6499c66421235263950add8e38f01229a106b481870d9808d06ce3ee7091e2125b8a8e612745f7108dbdfacf17c3ca32514abc5e40de81615c9ddcabac500359f5ab0f2fc629979bf6c514e06333e54eb8e482b624637ccfad4e301e597ff0695d11fb471b9147d43fe8d1158d80abfad59037b27623663b8d8009d05da49f3544c556fb034f54ed27b66fe49907eb9e9989a3d4badcd4d5ed78f8dec4d29828149cb351d4ad13c5dce5727aeb8fb55ce355818c825de8c190a0de9cfc523a496f936eab2fe00fcad6d46cae7c7eda9ef78951c9383d655d3c67cae8baae29ce4dd72b8155048c7a6eec3d5de39850c2394480c1c06943037dc69263cd973843892aed92b6b0c76c4de3b8646338580f70fceccd42f24eb6c2afdbb5836a5a7bd9bc694f5feedcf94351a34d418cfbd6390d0ed6956124f2583525ec864b3bf938d2ebe8d87e7d01a22145218bbc7713739d014ad1ff7cf92bc56520613b335c1050a69d3670203eef6de8c5e19d5aa353dc5ecdffabf6dc870d183bfb807a6ef7806fd4773955b0de981f3f438c4a0df183152f43dac021b20b76db4a5f428565ba98b2df7566b7b52f4357f2c73c7f8020ff1b429d84d0198e6b6d6f3e46e3d2a0c74a12a68c311a266636fe448598f3cd903f1592a80146e9b1605235f5a99bc2de45d83e0914ebdcf0a235a7def9e355be2777f437aa2959a0dabda8a02939aeed7ac499356d4c6c0c9d27901ec53729c81beb926c7ce6104ff5df1544cc64c78a4e17e90a520f2137342909eb1979bb7142f18c3e74202cc8bc4e17b06bf6bf1914f571d2b55e58e1f11a2cc46bdd11cc2b6a3794edfbda1fd2e4b520b66f7fd2e98e97b72b3537550f7d160d0f51b8f8ee925fde07e66874ae1c86c1e092e9cafc8eff905eb42f911697c9d34096c452c6238ce6b2a7a3395ae90de17136ae8c6dc535c2e295258eb0d002ced10d21777e9ec4365b4460005d143eacf18de5d718eec7dd082786e933edfdbf8698ecb0636700987ec22bcd308317a6136acd64fc956f97cc38a3ef066877054b7da85f73ca7a80521f45e48f5eff581567e89a28d1c19ffc82d30bdc01307dbae6da653a025bc7927c6da1bd672e11605fdd3f48ec2da5bdadefe1a84106b4674a3150f9358b33d3f865475e8ad927ff4c44866963d3747bc918aa6305a4f5cc26d0c0518f7478add7eca4ddf068177cb5355ffafa9e505fff692193518b2edd16184a8c2d599d026377643712cf38527dd276084c6b4d25ab5175fa81a6526075ed657069fae82d464fa7d604938723c94b90e2fe29536d8c7dfe1e2dfed32e400f2fd7d1bee9f5e36facc5455629dda6bebec2fd94607884164d35eda02c398fc4d7f07d5a48ddd2219628e037acbe0810d2b2fcb61d9718e9b4a6374c66e308c11cfaa0cdd036c66d5a1dbaf11e92990d3768004ea7af817815ff6128e2910877a629d0ecfbf5a5b80030ffde5cf755724ab2262c0b87c0d06c7998fb12dea953ce615c82b5bbc7953babfd501fe04a3764129f96e807d81f43ae9a055e07f8ae48a6ee496631c781642795e3143242e7f2452e561b394ac1439ac5004fa66f85de8b4a11e8c96ab9a0f0cb1748d9b6d502c16de95f8cdb98b24f3a97d6562e1e7e5d5ddd1a66e4aec79ad0d6a6d910918f2850c5e8902ab5a1e1c2b76225f6af25160495540245b8104f148b08071883c684b1ffa4174c99430b441805128494c3fed9e3cc42827532449e4cf7b93b182f64612a6b3cfa30641f93c89c6c24a5e3dcb530544c2633a94301a86ae387c88e4e0f618b60fff419603ca4c993ca2942c580627616fac34224d1bdf75c5e36ffd557e732fb2f733fb0d39d23649fa10964d840494528da5417f837539c3d29f2d65313d928a2b93ec858ac9658cd01ff6088bef753b95a09fa2ded3ac21619d0b4b44d2952276afc9642806ea74faf8e5621fa0960319327e8082017a7fb1f37afa6f915b60da178f430173b7b9bcae1974cd74279473d8849eb406fa9613382843a19033d73ac752783a6e6b2e79c0d5174a0daa22160c820ddf3da1fd7334f897a999b98106d9293402edc6e87f0f5b05faf403331c347a7ae8559852f42a62ea056de5909d5b560272f3f0c9b24acd227599b87068b872b2ea93e0f40907c5b87f9b0d66b251ddefdfdb25474a4c8174d3da80ff1e5b54699feb4189a755f308ac9e786df79577af051e14384ccac95699c84160a4038fb1974731279a3cd6f38055b8ca7c7835e734ee1ab3228b17363d07a4dd0c73c2eb12e00359d30371a2f868af6a02cfb107f0248599748b2b4e1adcc17c5b1b76d029a7661e878fd881ac85ea2c4fd9feae8b260823024423c2e8d556b1b48321d7bf6bddc1382bf0fdc2d28a357b9210083a220025c2e27f14f43d9384e9cece5f2298cec6006c9cd4c66cc241450a249ffa8faf3eac36aee90034431c1b99180d2a7f392978f85757f3e8755d6b79e9403c5908c41dcd67f04760f9d0b5127bf1db004cb97564628c0660abb92dd844ff09a480b6007bb30cbef80eb5cf0011f1def17560207be1ef0de658080f20831981590bf6fe4a562f4e7877506b74c7435db510b7f4593a4688b3832ce010f85efc994315089fc727a0f270207e5c883f8f2cba7652d9cb5f3d466d097b1ab21e7a7460ba99a6fa0941947f7c39063c31ac43424dadccb22849df6d211360f8f3413e496d1a7837d05b4af24b461846efed7829357c658f96b29e485a42fa1a02112b7ae00332615cae28e29683ffade356d5ab3b90e9e2f61998ad75946e283cb4e2baef0f156b322a192a5668c9d79f05d3cc181cb38d1c33f53a8bcbb42bfa9a5ff7a0c5158963178ebed1f259fcadf4421d10275cd1c76b6732a1cf81457b0d6bb1d1ae57a3c35fcc5214e17673b70a05fbcaa5b0cee71f902950102b9029039e7935ff0fb6c8b02aec3a37c6fd331b436aa3c5ede4a575cb126442a9ca94f6aa14c1d966c25642261bb6577c98f1155a7e2e3790ff39e99b6de5d8ea50bbe74b78540c9b724ae9137c528369ebba538a9308c0996be531d067f3ed22bc83a94cec7993dbc77b5c052a147435ab374dd01b0a8fbe67846c6152442d3131f57f5c2b4668f3b30a029db865476f748b27f5b518c36d7c3217ce7247913ad134abb4303cd3d48e3569f908ef79697218e9a1691ac76a8e673051731493c9156b6268dc46435e8a27f1b82b3b0368d0b22e9c7dd1b92e3db86cd2123be97092b83c46231947f3d0c7716ea7669b268d4f8823883441f03106a211e9f6ccf11f8c95d3a75a719075077cd411df6b26dae46eb899340958bc52304363c26a5ed256cbf97d2acc218b275b799c01ebf39166595654630c41c282afcd72e8d16b72120a29053dc721b5c1ad28f629069ad4ad735e1e56e9892b7a515f81ee5ee82b8ce6611629a2bcaeac4d1453c0bdc1e3316f8ccb4870a29c28b5318ed9a4198bbf034d59f02bb6d8bfd2c2d5c19768d1ed7975f8fe5cb9c787d1b85d599a86fbeed3aac997b3c379353f3e6befa445635bf8f1fdeee21df73dfec038e9ac123c6345e2392071beb41cc8b43adc32bebbc719d4d6a1e08648983757a4993d6c1c494a59bfb5bd218d4d9d88f31ac897984c262bc48b4719110e95dd59c196b8a34c719b98b658ccc2acd8bfcc3ee395d6f1a4cc24b4cf34f68b26c22cd52dfb7a9654fb79b449caa4db7b177cdaf17c9f98d3931948e2edce0e4cbf5ba85396f95350a3dbb665037fd857da0f42a4a18a22d0b9cdd6756a157a9e7627cdb4e554d0254b5a9ba52db4c95b72c5231a0fcdcaa92f8aa1b3b45da26447bbb99341037d041c74cd4e426cf9f76df78c2770161d0f91eb50202b91eb03807c49ea6b50369cb3622dbf65c252db5b366269f8c2b375b222f3c2c5836fee9299e1a6c9cacde8ce037658690a131acea70d8afb8bfbcc84e17fa88aab43d0e565edfd93b8ce5445ad1872c6b1cfba4516c245df41fa9e390662532e9578ee5988d877fea9665ab3b4f8ffacc286921833317e2bb980a4320f9674e04e4899af2ca25f89c171488a3dc3b255106f717a496bd4a7e7bfa77dff19818a9ab6def348aa84f2e4f06e59cd814d20ba138e7d1c13736e2e21b50d9f94bed7a6cbac06646981bdb40a6b083db6d58e6c31f496cb5fd57e1154a128e43e9ab08ad2d3dcce54e26d4454e650c48bc963cd140f94f6c671f6fd2b798c70ca0f4bcc1e185dc7e45d00b69af2e8a84545c1cbfc8b81f45472b2678c1b9b536e1a8f476a8b9fb1a11ac0f5534be93f10ed97ac460193f4a1c00bc31d9c4f3e607234b9afdfde73d6b3fe4d83192d331a44173c16258775f2e6d1ef500a39e195435e1ffc7fc9fed3150b8f6f7498b3dd3347349cca0ce594d44c1131b521e0edf3cfa1393449e0d4564f459f323560ea8aa4cfe5c0da90725c9031ee574af3a0503b9df352520be8c35ffe79188c6777f93285dd1dca0130221fa41b5a312614fa50a948b50834f631aeea6fc3e2d522de0c7f5f19c27543353c1b27986a3b09cdf6b0cbd2b55fd7fea2534ae8b86ca7e6c2554fedae9f36e305c2d45791924a2e05667abce5b5f4e805d056595f08f28526327a34f3f5d20471f0e7eec1319380f3d8271051e9a7a61c1421a9f1eacc17583f059c0a23d90ee11fafd60b0e10ba7802a27133f15a206197a4d4772b04eefe1acd3b8bb789f1a174bf48c3b6faced31a29be4bd9220620ba70df3c9152f37610249aa51354b82b4ece2a434e255fe0373e3d094951ff5a66ef4f4848dab3bfb2c07f00cd8b09398906bdab98d6e308a97891bdb60d0ef475fd55504e5efe1093302fc8286ae9a3016ed726d29956bdd3a418075520d52e5804331e8d73831bc15492c2c9b6a05a534b3981cc320384e506017a1f383b9a9c82b25b8c46972075e129b818a2c7ae043bff4fef664d2d9acdbb1c8da493c2c00787ee0e55a9e5943a31d85cb3a1d336e89ccb405a3f1df738477e928f805f15cc78f869f1fef61a57fcc8ba6630b2ac8b50888b4db9a0daa4155ae181364b62bcb0c7b5d911a9950f0d0c17c52c866981b020f43f860c97348ceef8120357bcadc7e9b5cebb359ed474682e48465bb3af6b5d7d7112216c25630af26a5859ab8328988aa7d66718af0c318a9d50e1208e779170018aec7cc1d7c9bf081adaa15566cb7451f764221f729f343005b4771890e29ab365a306f4ce28aae4186c8825e293a6efa5ba2a795bc7eb98a0d1ed8708097461dd37d81ae2f8492f5fcd5a4a7f35c128f22f2c34563add0ec3a82f13d8adb7e12a7f0ac5689a26e6f0e7732d8777fffcb30f833614b7471d46428aca3c7a421f9c2a73b46e6f528f9b134b3dfbd2dbb7e1e81e0c5496757bdee2ad8c81081cd546f1346a69f623344f550cbdaa45fa4683f9a712c75a40f13bfd7006097aa01a3bac5786a5ea5e2dc402b6e800da66ee80cfd2e94ffc0e962a36b47938b110e2e6a51f658c526e49a85fa5d03fd6d7f8199f6e4bcc95ee6359b1e9aa21075d474e4c4c6f7785b84d983624a9f2681e6b8eb882ac2da5e6e6cc1a4e6daa6a6409e7e14efbdde392606e4f4355b6fc18e7ba42c0e8dbf49b78ef72b22fdcc445c153f756e44f009b56a04b817cd73ebffeac4b7c3803abb22553789b5a77ccc1e806c393ec675ac4491938db40afc37c8695cf8d2971ac91c9fcd442dac20316684831ca245acc05bc918544e74f644e4d500880cbaa4ef8068245d21340ccf5c79ef1cd0f89c4a75cdfa70edbf28df232b6c146aa05eeef7545a25a84d2e07c4a36fc0ff64256b220cf9be73d7947500ec59cae37163dbf4c2c6e006022e8932c12148b77df7f77aed1615ab9d2f8912e0de979b822ac530f7570e345e7574ac3597946e1e223b7ed355af74340b276d8e21e821beece8a37f4d00e198a56367eced5f18edae7a3346ade28976bc2159e32b63a1d67cfdb0b300f4064777f6291d73a83a796fe99889d0c74b15b899e36252d723a59778b62da1b6799196cd73bd3d1acd8cfa32adcac7f17a6f434d8170f76df42253e9e29a270f841f7f8b7d18260ba2ae3828b83d00f044eb52ac27184945f6256300a159db721192669d0bb6c059d3dd826546a02bc40d7bc099f84339076e4eac663e8ccc8215f11717401db35e8d3f36dac2e3288932c5008c19b1934f4af6577ca12db90fa2657fa9ccb638d3f8454c1088fe5cda2f2a7ac117989843781e0728e6830e34078df6d0758ba7bb1b84c9f37b2f6e66b30f4e11225af3dcca59bbeb88526165c0ed8b3dec7e9c7a8448ef63c9411c32ebf674b13893aeea04f4e7d34fc72b6074937d1886de132a55107e353408a9907d7ba4c0ac2fa455868058f2fc6dcf23ef46babc11b9a9a30ce6d2ff038a94d51bda0beb7198a0b39dc03fecde7b3859755f8a0ad61337d65454c1db84a4c4597d170a29efd2ebb299b8f886d607ef4ce61e20f956ef4dbaf57466f4b2f47729a30a7347a0d61ca947639db478f2f842e722f60bd292bb6d4782bf71ac87f93874772a34c6123bb76c3cd74b4cc0d9137f1c1bacb22ac2a00f13e800b299aee656e6ffc80ac8de1c8af9de729dee4cc5ba27b59354b894e9b3050d34b78cd7bd584280335363796e4cfcca69378cce943acfb83bc827070175b766daa38e171b82d023a45eb4932d053d0eef06e3ae8d7dae684154dd7fe6f8206ac545cc711172b0f6699518447c706bb15cc1b457a047bb56dd38fd470ba143eb79562fb75357da24b2e9259cd21b4fd874db0a5c473c18d29db413a17dfa62b4411c6e517b479f01513c237185facb318293f3341cd46866fad6a136669d57916527649876254d4213605aa17e1b1a3b28eac7c82754460a0db7e178a9dd4b2e20cb54f29a54964475a0f4eaf5761db216a37b81a6b84f3a2c53632d92ba613685e5c78013bfb7a433d462cd85713c753e529f98ba734ec5d8c58b314be1ddb5bbbcad68f45abcc7f423a427d07766662a85ec62a577cc85536f794a437cce8917dcb717185d79106e31304798a99e95635da16a9652e67c98ada355b7f445975c2c4d7cef61264f635917ea553917fffe0629561a52efa9fe5ad39e5977db19c722fe6b41395bb5e2d459c316dfb9a0dce0788f25b3de7b3d18367f0c48b5ce723445e86f883617f7223a5bd5a91be21d3eab30808a9a98da2a015448bdac0cd73bc78c582a04a6c07c8cdb086638958c6f3f395c0e36c74136c2f1d22bda2a4527862775984afcb0fdb6ebdd31f60c10adb23f4325e8ed130866922b345cf295588f9b3f06f024783f364292a14ee9d18a7765dd3c9165aac3fb07048a194919df47fa2544a15a12b64c46b8510497cd9aa8be5247b278a322e1fb56e0a8e7e4719e0acd5dd4a9be1d0bf66c028072c871eb0bb0325293e28f7f4c48562b97ab94e6b6dd36455c70046c2fba5d67ca8e8f96e7ffd8199c19f6647d30ba78d7220e0c25c80694810c8c836c208232b0f831a5e58527b4fc5adb42b5837d6a79d6e21340c4907a9f86606c56e5e7e472ae65b60780487a053d9e0a0cdf51cf08759b2d58c15f3be75498f1557ca742ff9bc52d0607cb66e49175c1ca8103e26537d094da2d981a892d21d5051ed37f4b8cc2e2e04b29504ffc3270e25d846ed372f0f4f14891bf4fe227af24df77b661417dbddbef52cdca8bc1e0d39f48ab13692d9d53b307cf92f1cde531c9746c50ae963aff8f7415002ac92c2937e0e6ab1122e24c4a927463d558e1fcdf0dd82af638af0b3709999028bf1e7691cb8b10606beeaaa04704d7523fb3809c4d988a141aa51bb9508867466d8291b11d20e782eea735e346a98250b3520701db71481ec9536c85c3031a1beb44d8383ddb9258ce190ea50bb9f2d760455039fdc6c10ff13cf8672df7ccbadb4f531e8aa1364863f6a5c4a5a52ef036d9569a1aeeacdd8e22807512ec3c615393686c99cdaaed9dbe468e5cd76b629514d77180568b1fda701a1863095ae4e2086a14c6c450746862b2a1d7d081cc36a35c289cb6550cf315d7a1c735925ccc07dd55b7ba41767e6e8a6778d59fb035dbb2da61b5ec965179ec26bbe4c0084e2d488d6f465445d6b483146a4d882966723de38bc05a0e94a39814507c968c97a8dc72618fd4bec666f6ec6bf00e5e16fdbb9c843ec1215eaa5d54b71293032d70b98c0e43236f57cbbbeb14334e4e610e4814e9ff5c32384a9b7927a4cca75e89494d8835bc4d9105938279f370978b7bd0f826f9fd41b2b6405133e6362a3ffc64b1f10a211c0d8db6cc910fddaadaf676570990d0ffa089a8a541d0317755e352ce1c47a3beef3247f185cadc7ceaac2154e3fa177558a7df9df49cd30703487e61673679b29e0de54d5af9680ab053d5d2954e06f0f518c651ebea7b8032ab42e1a6f38205102c328e5f0c7991ad584e687a2d1164bb487416d638b21ceea736ecedf4948903770e6320fbd248d2a4b37979bdc3794ccefbc83277ca61004adb81ebeeb124fc6d6f93f58a2943a4ba514ee8350ca2900750513d439a66fee55f407b8ec887ffa320df8a17251969a3ee3fbfdfdff0cbbb28bdc666c04c9bc40033ec1b63fb1395ff3ca46e67171dc9c99feb2d20c6fd94e7193c31f8cd64c5a57246224469dd37924be9a17b97b650b03bd8561de1ae1ef50bcdf7b47e9deb764ec4ba87cab17da234b41665b7565fd356a37009b3a488879ad4bcb991abb31fe003e98eb152c0752594838eaf05225903ca59e3e24387967af3bcde50d65f40e6f9a16501b2b09991db1df1a53263125353a5a1d25172f4288bd1d6b2bee337829460900a1214aa70b626c27d6e270b38566c1b79d92107f0616453964432335efe003deb2e501a5e7157ededebcf664156154fa917f4ac2816d46333d3b1381aa6289e249273b82410fdae59c5b0b95dbf2e58a281b54b88bfe48777fe8180a5e9db6c24948925d9c8793fcc4d6a6fd516ac934023130e203be0dbb2816353d23878fb3217f0942d711fb865f56110522ceaf5d161a47e6d21aa98dec6c640ec9b802d0f59e07238516415645fe6f7710a7a27bd38596102d82ccdae5ca36ef96ac479c70d248f4cd60cc9589eafb58848f1f785b42da2db8ef0b139583fd3ded89c9a8d7fc86c7c07213e6ddbce20a169fc0d7f01fa6a23ac24b1200b9e70585ab6af24a4f6d7152228ae2dbad506135c9a484f9e858268ed14a172606691853de8e6aa4674005c79c1c068fb694bd215cfcef87ffb9ebfb305980a30d24fa56e63dffe6219e79c946797a5ce6a975917b712b3ba2706405960c4acb5b000d7aded6a1593b65573472a2e08d9337989971ad0d006c3897591cb8690e0c26a8b068a2016e9269a168deaa385096dca3d2ade868a31e7da1be3907d66798b5b379bea9e1a18f0e2184b466b8dbf90b8a8e6618bdb5812f1fed03e841ea4c59d468d68d4a2d4731852caf7c7e6fc195019646ef2270cc893ceb76e2ebdf58a025a6ecf9898b258d4d24616a59e80c4615387c80cc6342ab4924f3c74d700ac2eb42a81826063bb4c25b7caf0756c0cc7b1823e425c8bc5b801c75c3e15f70adb494362f886ef13be7f85d0f8e31b666d565e033cf52cd4d6714c52cab120e5c04c609e57892ad27e75f83122471c68314af932ba8b8d4c6480ae9a42281fe10dbabd22c5df1c671800b68240c0f674306424b5fb8965e204efcd7fd8e91d68fe3c3a161dcd9b108d454734339609df05b6f7d4733414b1a59a3e1c26d39142b4a8fe214f3d6df795fb71a05af04ebb657ded120478b259b23f6e772933ffa14001c3e52845b31017a1c6f71d8211188f3a4edca1499940c13ed3729378273a9bb957331da7089f521325ae94f46ded5771f566799c507982b31d3419b34cf409374c48989abc23f6e5e9151ee3c4c4d1e1f9d465b4474d03a4559dfe889b9a11cd9f37a32c3d0494b16c1e2118f1e009c534713a7b2257f92c76d26f4bde6cc94768985ad65ec2227ac74f6fffecb727b1b005e6f7ec7961c38d0251258eda41bf28131244bf3f0acd1c0ba6a709775eb30933f0df2c514ab4b790e6a8b3fffe91ed3f12eeff2f82cee7d9859032a25a7f8585dfb197889d1a52cda140f84519bcdb7c0098cb90abaa1655fe5367d8dfcd7c452b2a6e334bd0981e3d8fb9293190257027534b475c7466d2bff7f559f1febc16372e18a6ad194883ac2216422352bc29ddb8e84ab24b32d52fdcb6c69a561393affec525ed5f81436595fec6afa92e1fc1cb92d4bb7cfa5971edf8ae4add18161bfbe45d7b662ef9b21e9d91e67532333c78a07989b924dfed2e159f1ace71e9442dc3fcf23af47d40e8d40f5d5faa79a0ca77d28af85e40d47aa551fa7789bdad133fe037f436d4716f1c0466472b6b2bcf636e5e10016a55403780adc7d1d40a65bb9890dae25126605fda10784a37faedb395861939e2d9adeab5e19fae4fc2ff808dd7113edb210d100c56ec332d914497071ec1073e77437a27d912ae020c7e34b6830f69409fe895684bc296ae3b97b42d2316373d8a8c115714035f5e65ac9367a4a21b574cb0862d79896f6c2cb77d5cfc2176a1d4b2fd7df3573659de1771a22d947ddeb4d2f1962db297a98a6447bc2e5f239afbad4671c12a72901e8712e8aa57a12fa5b9f3d53a3e92f18bbbae03f4ee4e3e9da82d81375abb4c5c7bbd3a1f95b99ea39d60a59dd1a9dea4775d296cec490ef5a4cfe72f15e86fa97610fc1a7e2ee0b100fbd2e9889cd96c7444fc6bfac7fff7cb9ad1d281b8be05f374dd122a6d21f6bdfc984e479800aca0e689a390f37f05c654cf14ff97c32ccb2b3329c2d724e1fdb98f912d7265bd9de73b9e69f5a8a9bb563022370d6b670f089bab8619119753fa36f2c9216f165c8831daa258052fa442eb2d53057a50fe6a00d9e4c95c310ed974ec8a0fbdf544061cdd356463112435be3b4e6f0e099211e4bec1ec7e662a50db65d8c5064ef7c7acb6eff714682dc01d3d20b4108ad2670cd2144f5602dfdaf35252e4892ae7c65c1ea9ee9f4912c636f18515658fa64afb55414943d557fb0034c33d98a6f51bd53966eb9290d9e8e19944f4347babd522858081cffe897755a744374ec8fac50f2e8fb61aa88913a703e2047999c74ff362115b092a4cacc44278d415e9650905584b366b7813ec9c9a80aa4f2a22e24dac6baed804a61aefd8533626d90d9ccc3bf679fc7592b407588403aa4a42ac810ba9aa2033de215f53edf128d8474c44c1e8ee797fa7ed03038fd37268f77eb2242b7e798457afc8ed4d916596d6d015320f95c46f559929a4d56617764249726f855326c0b68b8547b97e754e803d7e1b2792ad51c6c8ed6d25781b810fac96dd6e364275b023eed97362c64476325396270493da5bcb8f432db57901296aa1fb73a662f907f783b696dba287acbcd43954be12e22c7ad6edb9b28157849ad5e8e50cc2f81f3e5c07e91266df935d8cdbed2b685b95708a59bd3ede816b7fd1f9e95a46459b6c4dc6625f619c2be52b7ca8c0ce91563bb817ea5c98e89a2d3959d262e05344736452768e7b028a69da12cc5a004ad34c9950c8d2209ede119c90f0b2e7e05f41bbde5169e7b2484e65b31b3b7086eae45111b2893e35ebc2f2deaffa9e813c00bc8ea608300bacaac41dde712a3b5a8b1c423c375f8e85191a94e59d6fa6e0a6357d2eef63b4f22f8e81cab1e045db11d5e3e2ba15ceee5f7c6a0fdc97ad510d0699859f08405f4d2f92004ca09c101d6d7998eea7757abda183a399daa5dc0c9565a24805b8e49e16c3c572eee55e63bbaaf642d437bc2e8475b9c50e71d4ddd053d83fdb5ad2f9b4b3b3e2e762d81dc1ba9cd1118ef538bf0bae164170c5ef88f57e05cd21e685ac1225993d332454a41ca15e5a5030f9abf04261c7ee4ab1734ac0ce6c4d848a1001b0314eec0c4e283e79f59ac6642c3842bbe2aeb4fc3fadf919f989579950b46ee37dac5e4fe1f878c22cb9532b947af8937cafd2d52aa469073ffba94f5e85aa3f022edc9cbcc0a15f3b5f0a411aee04095b574882e74b457394c767ec8644c444f1c614506ecd0cf7aefd83566e5c081509037cca41d71ff0cb87e2853db0582d1b294000fb672b8ba41667159afe17549c76020cafde6936089d1691156423734878adc1b4fb2aab73b1a0d749c70db757e274fb788fd41d1dd04e27d4b009ea9825a29c3180ea92e0a5f2449fd57274332d3ec1c4ca61733e04b2d749a04b2a23225ec6367c1c8ba9daa9b8ae085f49187f3ada9904a4345577b8be451733ba361d4d51f186a6da5bf3344cdd31576ef9cba4038a1a6d1172e68b2dc06674d1c12c626cd71474228ccc426721add39cc6fafd18e82cc1011ea6bc8d5a9765722226754d52f441a6649a31c025a6c46d30bac7d0e66a134f3be3330941b69ba4d98495ad769297baf4f9db99f243b09f9fbc70ce6729d5c90484e0a23c03fc0f844e72a97b04258d27c5fb5fdbaf0bc53736c032d62a66a145df3b61a261ea11bc3c9afb81673ccd8aec6f3049fcd81da2fc444b63199d1dd2dde60c5937014210a44392cecf569127e94f3c8c6db4d3e87ecaa50f6580287d6c129b0164548d4e9bf09cfe4c4c20e6f0b56d92c3360a2a9561bdd7581b29542c74a9723c7b29b41a0d18d595bd7bae48ebbde7b1e921898df52afb9a635c2fedf2497edfccf5cbd9d69d0999ca7f454af10755957cf7db7392674fb73b1a4c4432da94dc580f7420c2acc25ee91406d550dec5930725b14ef452b7afda763f05261b1cdc313dbeb501b683e34d789d0f8f4b45bdb2622e2071291d2b90994b8e52b21ca938d835b4d1c01bceae30b745f26a89b91c00db04270c6f52272b6db378d0ada876ad95592c5b0429616b00e5f4db7e52dbb5152e8093185a295bdc72a798e1fa88186685d0c9fa6468b3dad808eb099638a59115e11b3f6610ba05c6fe1b71e2afc930edecba06ac032e615ce4ee5db388a06bfa010ef6dd77ea8097bd631f727913334d8dcf876003c5a0add42b53b0930d56923ec325d25fedfedec377d7b13134ea0c05f0f03366edfdf2ff7fe8c33406af7a99df7f3256df78738d5bbc110d3149bd053819e54bbd57d638f0c5f7f6f82611b3e91c85394a5c3995eabf02ce451a1a4f25f4a243fc151527861f79c21d7bb409039051172bdda2160fb384cec609a160d09f19877611da8f3e55e996b63d6db74e2887ffda1d07ba0eff3e63c9111e2f233717380ccec8d9227f1d596e0cee86f8ab09c4153d8066659b81719be59de2ae23660710afd342fdb22d99b8defdbb6d48447314180d984542a5647d118bdebf05305370674765124da800d26ac60e687f063a98f766e92200d7b2d43726094c994f8fd5a8eb57ee861cb4bb41765f49516eac0532890f814e5ea834b305b7ad04013458b8b1ce8ca150140acba043243611c2bca7083a3566ec314cf8006e026dd4c84ce0be35ce187e83e928ee818830edfb11496ef436b188feaa60694765324b3301b5e586eb5197e8f8c0989cd7f30d0609f061ce1d45c2749d8289deb76b1c2eb082962b59f8796039d35c0a84a0ba74b2bd95a7030bc68aa1df8a4b8295d8d507e3fa724490c62c7eed07aeed006e07995ebcb5592b0ee8d800646c669448816ec18ae19ccbe4d49cab0c033df1174bc4d02ff170c8dd02b71f207014179712e1f2f5ef1662411325c86c0787d3cdec758105d3bcdf3c80370f0f61f3372f2972491a33a7f1e3ead49854731229c9f4eac1388eb01bd7202a84be30a396f09f20e383c8ed6c437c3bf29162df0cd993f0d51eacdce0ead8b1414e1c3dc6c2131c3134325eefbd599ac080167e9354dc2258b692c105e355f6db7e55690b5ba9177d18ea9c9d01ddb049f750fa1e2130b9864d5f8e34a73bf3c5d791c21acbdc39a0819b66d6d895b7ac4f0f622fd74fa96327692c64b8c4a7eed12697871fa987e046d1cf5d394841dd915a34b4cf3976ad7405fbd852a2ff467f8230930dadb48e4aea2ffa7339d505e0b6ce01bf4951698a336d97ec129c1f67a8e9e8676a409f086eda8d10b8dbb6dd84eb6479f6ed83648d9623c36bfba5d57a48c6f369c906d8c486256e6b7022da2a09343046859f47c279e36b60cedeef491373953de5f1e22654130eb353291e49de18fe345c4fa0f8434fe211247750fb864204ab9ebbb408ec2a869c42db9147809a3b61f288162410acbc8cedc7ad1f9de0443d867d9858f3d16c3240c45604c79d23312faa8efb7f150fb31e8a471bb63bc32f0991955022e531d6475b1320b842a1092d9050ac83631769ebda762f49e01142f67294bbcb7ad03fad1152c80c8ce69206a3400963330960967e70a6b04c7e24196bec30745ac435b812c9e090f88d34ceb65b2d09d82c245e3e0309cdb35fc122b16667503b139f5d046d9855371d236aa4f5da7759a4e03911ad176754fa395df79e3016546f334ba9d64298b3f5d022b4475271cfc657ac773138ffec3b815bb5d3c0b78712d62fe01db915c2b2be3064ef67d6102e9b06ea7b3683be5a3d473508d2cc58fd6496b66f4eef3f290de892f7f51ed90a513c188113bab6151c50f88ea233845279c47ba846167c2373c5f9da39e8ac2380dc9b25ff1239f586bc105213ba882f43621a0e1b7b5ea946fda3469faf1382cce08d98f447b38b63d55da2de9182c61ca69871f851ed48a363d3c3d03ad35039944ced5da717bb39294dd1a4e58831bd550ec95b11b5ca26836cc63f8fa101d8be7e47083f4a03eb2b1f84024767ef69d6bd418d90e25a16ca97e3563fbde8b069581bd43069d3baba2856f720464afec9c75781b301f0abdda6dc199d622524216b1e55f6dd92defeaf3322d4b836963e022aee714f9cd6da9e90cf7fb1e4b7af4e21eab56358c00721dff902930103b9028e39339d54de17c765b1f97b96b242759e6bf7e0683b928fad8975cd9eadbdb2d08cffe9374bb08b379d9384137582e542d62b56e645723fcdac097bb5ead39d05fefcaff5cc8e4ab3196e2755bcd1a0c9dbc6c21ad5d60f6a59dddf23b2053dc949f9188814edbee31ccdffff08e7258ab5999b485c374ab752477c3e1833a789cfffeffe3fffa34dff9c22bf89f5b2489b5567f437265e4830a84b912239c4769b93694d65c33afc5c6c3bc835b3f1df9a2a70081eb6f3ab36f6fa27bc8a38cd92c53a94cd67c764cb1972dd54cca62dff4fd6f675a758b46f052fecd51fc86c75ac84a0d3b5eb0f254ce36a61e4cd33e5119c5aff51c41de9bfa17b58b7638a6978103e846b67dea62bd0086d451058e372dc2175fbc2a12b33d2fb16d87af93c74cf8435004eb4eef20f568f5666331c0c11bc88c56739e57252ffaca6b4e2087e17ca2090033e50aa08130667fd5d6a36932b3886244c11b3baf6cb1bd7df66a9706202c3cba9ae3a65dcb83712934ce0b89ca70677a7caf0185433ee74f5d32b6237819e2b16642f358ec77e0bf414ba71366aea2e2f4dcd8edf1f63ad9076111ecfc93159640bbdbe51b3aca3b9184fa773ff434d8d4da5e64e8525d3af51e2b6fad1671484d2444cf1ca13bd0a7721f57c59036171cd727685ca6a2fe256458cf6a50ce88eb67f6c3de4a9ff48a3fedb1e71c41928ea7b3dfc6fd2891b50e09ae61134f154c33bdeea2202cb6aebe04955924d083d52b4ebf39f6f99183f4187d4d46b1d8f9fc7cf8795fa7c0fae478e7f62a6d8646059d2ded88aca5dd7f1a645078d7eba72781f5ca9bee2a88e31b758ff28837c6e2b554fc39e93320f348367928f36b8b9a72d66cbe1bb39ae1f17d5cb7451b65907349f1596f4bbf455b611ef420d2c777992593908f91eb50203b91eb0dbfe68311897bd8411007b5d50df1137db318364ace71e15a73341704df598b6ffe5e66021091adc9f7354c9c1c3ba64a48425fa1585352ec2f9861065c9132479531421bf4a3b1dd126ff9ac3c974531b22115890f899f3006c08704ad96ef184e2b7c94445399570dbd7e77e0fc8c05714a1c97c0a95c0563b5447f1a2d01aa8152467eda5c07ddf71d6cb8ba8d0f2e3f69caa4634433b7be8ef156058caaef297c4a63855b7fcb6c8ba8739dd073dd61a9217dffa1bfa773917cd5232b82c77320356cf5d69b8f4577917ab0d3367c682bfc8ea84dece37b00c83ff1879f3042face37ec77bb77fdf60ae3c0cf01fd588a3dbabb67abc8474132ada0eb58f47ea0a46188fea92f6a69c7690f0cdc4d8231a76710fe95391eb8341887db15c72fa69323f74a7c7d12c9e12d412a22ddf935e0f1d31d4bcf0590999e5c51ab8452ecfa7c602e6cf3b250edc495ee323f1272b0a9b9e1dfee5dfbd91ae80a33f37d8bb877a266261c5bee9b323c1499d0eb1122a00f1e405114202742e3c384801ede36c2381319f65fa98c010dbda3e965c33bbf24adf5f383a74d7f1055d62eb90dee73b90c0d1f110088987db6f62b0f91d3919b1d1cf62bd9e20f2cebfb79a21407d2e45f4bbf2f8e7b1cabd1dd2e5c8381e2107800b787d01d6e01fb08fa69651d14c9fd6874807f4794a2e6a8d5a0bf165e8328bedc4d4e9b0340ba03436ea9d3bb6cd7da3015e570dc6f1fca747f94358e02cb657aceaf4d6e40ebde12624042847739e6474120bf094671e300401662f73de709fa5051927baf772e142c95aa2b25953187e690b518c42fd773f2290c235e4416c9fbcb2ca294dc9eec02fc837553fac714546fe11e52559b0576eecdc83f7ef2c5d2b8d455c0272c92266c29d8d9ea95bcf7ccd4efaea3103bed2f5bf9a18ba4a2de044551598eba96718da64a79a94be5c20c35f7d8770efff6a4dc274199cd7e9bcf8a4e308bbe9a81bb7bb5f71e7f18a2e279d9f6acbc203d34c1f19c2400b6f3607d59abe0231243c5df0336b707bf684248ab6222e75a1175f819c4b24404fd9b0858ec72a344b60add624146565d19c028f69bd4b96a7949f444edc991984ec7f51818fbd36ea0c74c9670153ea8889d144e35c7e9440125270fc8f9a350f89a6e75d546523567f5162b8c8f7a09b5cabbe24cf608dac916127169abfe2b4a43d8c70241b4c7ce6d1952a7d24138810ee7e6e8793ca7f7f7ada17ea3633b8f00a270d30a61b85592fac6ef5644c2312299013dfc4d12418983b8bfcceac296c1b3a0f560e682237bddbde97f99f64f5e80b8c48c5e50d60228c459dff433641a9319c0c6eaa2fb2f3d6434d170265d6f8380ea9c63de608f99dea32ac9bc98c3a23a70583082214cf5f7eff6d4d376fb98db8f2bbbd73383cdc302500cb96cf142c2b2b0460a9b4b5eab0955a0c982cb819c7a9e132aec9a1d9552418160702f7c7423c1f1cb433519d8f2285a991d18d963d2062eddf4e21e47c44e2c9405f6f02e7f04d5a0c23cae92162ebc684c3ce1ed3140e12a9d747e6d5b60a15d99148d490a68da2c5e217dc325145197889d95064628cb6755b360a3f8d2a31931e7a30809f38c0f3d78570fe2d4d0490ffc761f3675571aee1e3efcc36050d2579e215451de03204c5774c75d6a6b8f1f0fadcfa3990de92da62b174b1ede3ca36b19d540d6a49627492267329b3278ceb6aeb8bfd67eb94a61bcfbea435b17acab5b670846adc9feab0d6f571e284554aebaa38f986fd6b111153ec9f55221ee025f6cf5114ca98daabcb7f00d35472bb1b9e9a3015c76ba8883c61673f4d934c0f06829e07759b77c814cf8987d4a3a15856160d358e3ddd5b9d8a03d75c595824378401ccc8797a491ae4096dda99945ee69824a33035b8d0e72fd9a6cd537c2d529695c2bf1290758bab8723126b069c2d7521bc7d784d3e2e44d729a64caf9aea97750ffd969b11f949cb76fe9b6f75207f7bae869a4f8075f0609d4513a692f08f3cb79e300161f0a1542324fca8c4cec66db91137b5eea40c92dbac49db240355f6ade3d0472c6563f3d90e4d35c63dd8fc7964753ea777eef25f00ded0c2374e86a3143641778d7ce95d3cc55c83a5f0082250002deae75619e57a4b865457281e7978ffd537b3bae7128f2c360b7907eef4ca34dda977ec6ffcb9a9457cdf1bdf6259bf66c9135d5ace93ebe1926c7c7508d94ef1d094877732609e335fd364d089d1df7044f32f94e408831c290e58a6c385cd4b065a26247769b0811211075f5a3d83e454bfca0511d910ffe1bbfed36de7778523ca1790d20f3ef815ef7a2896ef79ec2f26e841fc746278eeb2e61cda927f07821a8a2552f6d76ba881067120ebfb67ba2efca838a85a08b38f99a55ccc67a82cb1575edce21c12d02135b4e59cc35c983bc1e265c84a5d5e68e39ce3f3a5585b1e216c5db15a93850c36005a59101ac4cc6539d628c4ae0ce5390c41420a34808b623a18af7fea8764f09577fbf2978ca072bc64a1244a44b95ad4c95c853e08896b841905a70c0beda7848a90fe6fa8962732108d3815b1265d8aa56c26c5cf8fd39a91173bc08110b16f7aae1519414fcd21a4dd8700a447d959a84bde8093af5ee965ca7f03182f71248348cf6859a1af4a0547273bad7903b1a8e0b935d476d43ad1d68cd9f3c4b04e9d206edbecf94c03532caad4eb7f22912b2e190820a44810a02275180455b6145e2aef3ead5a2355454a581bf68ca205d2ddebba0ea1f617ff9a4d134ddbe5d2bbe06f676157a1f743f73f40c7d3329c1276f0ebbca3c9cd218bf4c4deaa3336c073c3d88f82797f0efe2b46b4de85cf72213a30f9af2568a0e1dd1be70d9e027acabe5ced0f8d75cf0d837b892c87e3c743d55bad027d380a9e8c28c38b1e465ee504c03023a3ba690daf4ae0fc0fd7133fd8f60a54b9dfc49f00efbf6de9b41d9ef76d600178483ac079637fc5725a45b20834557ee1fd77cc4ba9ca3ebb15cbdbc0efa38e5b4f8d80458ea92fad03f7a26a5c56f743485d9432a44acb8037856292703a94b29e5064f675e6529c40e9c9a0c57be11d919fe5c46674cf9df948e144c553c2dc4b3b5190caea2aa1960ab04d614a0e6a7129f1e8b4d80ec5c2b68bff6cbf345524066a7a040abaa332ee6c82d4606fcacf2c4550277514683fa9e87efdab1e8f9b3cf6f2658fa882c46bdb3dd249b33044cd7ac5b61675d8e41a50e16c3aa7f9c48006a28f0946b21902760feb4ae90abdcb5291f1897d4bfb0ebe847c41e72610ae398b0016a6104f096f4f93f92d1f753049161c086a1114572cbf6598b8330636c14fab110bf8d4b270e78b9c6d29dd9fe01932fcff9daecc6cd43a7bf71a4e82b3223bd9b97a1f2addec67d1a80a167da4c363bf0a0501e1931df6a7eadadfc839932db32f09d9e5aa1b11447241536e10d555d3dae604753c68b3b1b24fc3368eca2bbce6d1ac7cfc9f456f1230303b92329f96ceebcdc85f6e8ebc068fe935bac6787064c541ca5ac20ae1850b37d15139ef1e8a06ee2cccd251be8ddbea1eb4e2065ff72fc37d151c8a94976f1fd29bb707b1bce3bd0728388cb4578d531f5d7ebed855637dbd5a17bcaf2dcfd701ac459d711059388c5af418b5a3fa4e6e7af67e0cffc805bf0ece69ca202839b8cff8870af1bc1fd0860dbc1e59a92baf1f8f2e799eabdcab014a76a762cb7fb317a37a14ee9c7729cec9b565197754e579efe572ea32633ea50d98c3b2f51a6c79d74ec287a59be063c654f0210f101f61f113497dd9c2779fffba48c80dffc215ff0f0e61d5df4d2da298e196b61a707c5977a8934e6b4ad993acc4532bf761593ec4ee6d48e9dd5501c66f8369e67b7d139a7699ba7397f6944ea19c6335045eca1c2a889041506bc15eb992c7cc96d0e92487201961a7cbf266e3b63736d4c60e01c230659698458479b887347abff4c734b92f34ca19116980a368b6fc24495f54cc43e895559532d54cac0c80b0bc41f87d8430ea81472c77d781416de740595585797674317fb75352e2b3f5b0d924a221bebdb1f5a207b92d38cf2f6dc6ec416da3f5572f20690376f3aa4bfb05a90efb8127b47ef755f4181b71b59796fc999d39884a09ae7aacbb549b983b9d87374d8493512c512a1d7d2afc7af6d80658847ab941d6aa2ad0b55843e3e308ada4f925da570a45c2f993ff6beeefd1db072240f72a69e868388948088a017a8083ccac305c7c189197d9c33863dec4885a8f376f719835a6c6012ed048e915ef07b279c7d377b9e6885d5472c5375370ff23d40794621fdebc7eeada79a53fbf8c0dd48a59f02527d4a09860e8ace57680c0a45950163d97ea6979e979958cbdb5d990a83f7e684f9a2ef5445885ca5567787da463b3377e9bbe8e2f380e74bfa1d8030592906b7b5be6915f07d575fea541aeff441c74a6a2e966a744e243db7acc91959f10fe047433e8bf98f92c44a2e862d3da3e62832db36bf8ab0da6de55cbf61994a98750732c8a7e2ec52face977978f14cf936c3e5ef95b2f34ff33dab9b1d1ff7d871d9f020d0e6ff43b24c115506b402deff6935805c697300e1b5f62f61b1d5bb60e25762b7410db5aa2ace38f4d2a6b9d7afe47245660a6d918fb12027478414484f8ec9360fe8352188998c084f2594f7cb95c34024ee7a7cf8c52c2bfbe7aacce620418628442bc869850b18d059710a28d88d6ab488a0752e2ef9de6cfa7adcb16397ef94e534d423d72dd312260e3dda45a54f896472a512822c7fed993a6ab3e0d4c9f8efd5877415977e14135675bcda3ac5d99770115cc8626bf1ad59a62bff1eafa39ffd2299fdd540de9f8ac440bcf13ba7fd9a20d4d96a4a9c92a040ab524abefbd43a01acc4ce573db1a3fd4a5c586e2faaef0f80317aa78ebf835559e4086ed6e90e384167ff49b477dc8b495d2bbfda4569b092fe47ddef1c9ae8b09c9269ce9bc1af5d625a837c05f50c0158ad65ea77e8193c1903ad43258a5faf23beb9953d24257c4ae77cfde2ddd7a45f9aed825df295e7a51edb9d4e9da5c14d4ee5c54faa3cf3c491273f9a2e61fbc34f0a41e6902b9816f9cb884ef4fe6c5d2381e1a18bcd73b8a608fc1f091c1ccaf92281b5f3254657cd0074a766b861ac25841faa1f2d2ca49a1ae6ab6f74c64e6b2ac25ead9aefff5d9fea138ecef7d61161138cdef4a92b5dfa272dd2bb680a6cbf3cb9fa0eabf730ae06c9c98c2efcf67c52629464939db7cebe2832a58e44f72f0a30eea8dddbc2dbb74929e91b328b6b399eddd7dc6cd3116ddc8a322c920ee8b57e306cf972b9c2cced539f0db42f44fe85fa3623a1d09be06bdedba088c7aa3e1b96a959e7aa10ab06c58135027731d1905ecf753d272a79a365f5b6d40761d6d30e07278a6ebbea93bb42bda512f2ee35a3a611c9dc7b337f34f81bdd27f672b95e5be3b70ee6970b43e4e15e275e71feeab1b0fdf33cedab122e8980087234bef13da86ef20cac986fea482706e5dad34eb81848c082c0a0f95a3937bdacb07098929669f670d0df53de6d6a055c9c8a124b455421adae51efac96fde6f557247542ac9431f8e98b42f16a555e5d43e1958af9342c31ea0ff16a90d10fe64209de4a875c11a1ba4765cfbafb3bd46a49710965f0c82edb0b624f196b1459e08b048fc619d2e6864ad30a398582fed69150c15523c91e8216cb17c9643b2a9ae8d0b80fece4a3b2bc04f907f6750c4dd40594e7530f3180a75b77e636eccb3f7244463b4739a4081b5cd1267cfe10159026e51b6e4118adb7864c7413873b1b2696d9cd3065f329af3b2ef0ee2b7ff55617941f077ce328c95137f8139009721bba4b79f29753d61ee40a285dd8d975352a81902560f0e500d666f8947448cc96fd35e88558eb7325eb541a2589b3edcadbb577c5595d80c03e8adc46a78c5473157fed23e826b5d0474441778dacf90a026b8fcc371f8b9f5a7074bef0cc2513c79ed847db9171a6af1eff226a70d8fff5a8d8016f69d1228880cbdd6a37a935f9debcd13eb137eef758a8e784e6b997f0e9191e5740c41995cbb122395d6e447badcb0b3dac4c52a6a58ddb1e431319eea26f2fb44aed416f57c8d5743e5609cd3e7453272747d33133e4d4bb74ff097d17aca4aee1db1b88fad97028ab8c9a0e0afd49f84e4bb531642670cda6ec1d42a9cba04a4a37f75681e81eb7237a8cfb58d7eaddd4cbe25edff3211b2d953a297e7de7863d5add3a34ecc169f551114d26faa3e1f8dd0e5e8cac122d2339d210b0f095d4230fb9a86a93e6b42efcab1e5cdbfd24b77fb090969f56799f083c8c357d2b7335b1583a0d91ac22664dba04dd1caf60c54a151f8be8f301538a94e2e81df0fedaf93350bec5ad3c1289f7c47e612af1359dd5d99e8287bd0135237fd35ca2c4317ac37ff87a34a26e4750717a73efe92db8ac40b8bc586447bdba32fc1da0a66dc484a5ddd2a0a1066670283a26aa3291339752cde8159bcb377be53d80baf0643aa372aca47b42ae19174cbb73513431ecc7ca44deab3a22891973422529283f671697e638c3aae62d258deca75b22734ad4869c6ebb93e234ed195aabd9b6113f6296e3640cd13d5f80c1484c2a21154c6534a14aec89f619c454fc54d00b4cb1f8f8740cc89f5d8724255d97445c36fc0c55e2d6e2cc03dcf7e2ae3957cb5450eccf36fbb4a2112070386132a8059e354c96a876589b4396183897372f0602e285ab12a53d1a16026dcc2f51f79d1f556f0c92afbe2a6e42417f249960c35738ca9f0a37916e1a2285dd844bd8a0f97a49fb6498aaa5eca89cb8a9e3b7445fad8604170cab397614992d2b5628ad47a7d8da88b15bbcec264f7285aa968749443a454e324095b3288e54ac0bc274ee9b7ce82bcda801f52759b59aa38916e98fd3ef6cf12eb7ec02776a7de2154e86f29159f49da57149d9cf7f5c59f462801d4f70addc3a5d67be29c2176e32ffd20f2bd8af4d645e0de1ffafcedeb73359e5ac4578696c0a537ba79e1aef7204760a2f1f26e8b526af0595fd066dc5d5609d3ba8a20b09699db2ef4121412c5c5cda0a5cc95e73e9d9a39f711df09a1cc337b779f06cb9c7a162ab57fb41075b1b620816682e8d17319822cd32e1de6d80156ce78f3bbe6097939290e978d4f3ee1105954f0de951402c6a8d0b185ab5940e956b93f4c07e241b16e6afca1fb5de84426f3f6f90ab87f4c27e67ac6440641b1b099161ef54a1c6dbe1cd9afece95ecce7764b1fd51fb05bd43e7451f4bd2ff6373c54b458b2ea09a101d44e3904457dff0f669b0a3a3e2f69c72268744466c0499e25cf4301511d23bcb5991c1feccc521115352ddf49aaddfe6f1c57988391291ab5743689e57e0af759d80ca7eed76a619c5b069461928ff33341da88b206d88eba2b3a5e447c02422bfb4fbbdb5bda5715652fedd1b7bd3fbc1f5871ed6662f4543f9d3d20cf136c69267838a2dea3cf613695f68330c19adcf7a9e7a9b6ecb1cd307426889087fac11a10e1100b7eb0c4d4cc2b2d902cceafe771269cf6891b1f1ba7c6d9bb34196d58050c44bafb4b73824faefa91dad084fb6dc72b80e679658bc8cacb50994be94a8e0113c969ab30aab0cfbd7f835d04b5470428ff1bb525d8f37c9c3eba12473b3a05f6ac2c7eedca29afcf46ac0d1f0a19a6ae77e980fabf467a3567904711db216f08f841b50aeb80338d54cee61aacc2b4551bca9dc67d01e18351d96ca635f35ac7fc91e4b66bdf838761f6f5cc02d2afba8700e6b9760e7f1f7cc098460b285e10e6391dd82aec52d8837efc2f1e1601a9cc5eb29fbaa1bb574a7d008d4a62951f627421637926b886f44939651a736fc2613a37dbb7b069e4f0677052be58ded3398fdee111d1d7ec4b1e9aef111f2fb87a1b86d8ce02a32a7ce5ff47ed36cfb075599af26406008027afd5967304809c8c21f3bd12b5e7d81c3d92f462b80c28e951a9d33ea19bbdab362adf67ee1ea9c603f6112bb60620e6aa1f019a83d588909f5d68a211aa81377a17745df4264cc150c3e6f0971036c486e65bd0c739d44c91de94d5d846585ae87efa7062d18873b0942af4f730db78dcf530f01a7c6538900a57996ad008604d663e0a783ae6a1585db750f30f2a984fc7245bed9651ffbffd71054925d6239cfbf1d298434bf42773e57073438c03e05d31cea670f748108a8c5b3dc8da704c0ce830c316a62e8a0adc8951b93683148120241ab47cab4d1b0eede2e35cd3850bc02d988dfab7360dd68fbae5e78c1212d145a4dd8f361ebe2a6d0268544f9b84fbde1674ff6782b2916700396b8902982564965616f7c7599c9a0c311255704f0ba15758297030f3bbb8a03dd0d1b2ee395bbfb91553d06e5524eddc49ad9f7e11c2c2a6e102dc7f1ae4bb78bd2c04e0f8e29108bd7ab3ea78331782e83d2deaac6ef3e034a4edbf36e80ac161cd1e8ecd239c039b377c7cb23985b12645dc0041a7b7295757928c5b9e7eb55ea6b468651ba88465862fa84baf0c53aacea117565970de9f23dd86188eb18fac3ce38885be4cff86f58513935d1737b2d9db2c430debf1a4b457b004c05b39b51e5ed5ffc803332164e3ec2061a126943c75fd3aaceb0345f8af9514312e5a70d2e861e0181d5ab3c8c3f843be1369d6212fac449adb5561a61b2a7e3038100cda635efd7f8c4e2f28eeac9d595863587b17145b39ad34cb00aa09c78407b6da5f3df673c2a6f3b9894e60d0139425c505cc06a6211fd9cd615155e16b422785336e80d13a375b9e0c133dd2e7364c91597a1281b4a8232f3c73562af0d4ab20c3621876d4043ac337558ddb92afb2c629fe39540fef5fad845924360f40a29ad602918646caecee0221575a6c0e4adc5f3c0a8c2e859a46885a78ae8819cd6bdeb51f181f5fd21c6d8dcea16a4a8cfcf9e51e5ca9de970ca5d88ae511fce3a1630719e08a178734c616592c711c803d23ceceed9695740594d2c9e2904b635ec602407ff518687279f77fb3736bff349105b4bf39981ba8d82f80aa1b39c5ee7caf5fd076d1e3b36f64bf6d0de1f66b73e272f64a724760bdc89d079194a895ebdc5e1569bb1b75cf00703cf592a3bcaa8ffe6908b415d83c36be9593a00d20bd1ec08a95c41a7f561dd888c11cd63e64cf39eb895e2b777856bf1416bc2a0b94ebe0612aba978f6a183e302014265310d1d3eba30a15b83574a31e62a730f9efcd031dd9f60b17fd4b290b1f9b118905d064a7f95b7a6ca8bcef5b3c308a8d629de3794ff8a0711ba34c3bceaca8fffd70b3ed803935ef4ceabe181d2ade6dfe89b363c205a81763cb4c83891311cc2c24005021fdc4c059c6790e27a8e18da0fa509103b5f6ce9bf076e0d6c32da66db23e9572b97183e83a90865538a80d876ccb9a63429054bc2b113a731dd4af78c7d2526c42303143d9a5d92bd2b9e10c874a8e0a809c05d142c5ea576d33e3d02d5c549b505afc75f5440d8967e410ddfbf362a1305d3b698158ced1d771dfcd4901148b7fb3bf4f31a85586879896e2e342af0c0005d1eb5c6d1eefb605223f12439fbb3144b7f1d958241fd446bf102a8b6bb5622cdab038d3c109cec063621e00d5ce60c5fc80aa9ec450a51952b135c75d26dd0b2ef653dc5bba65686829e6f53c3588f60a36510abe86ca910c20d7fb922a5ae1bec843f88e0469493af34425cd5f58af9d77a69b07791305033a33d5586601244be3b1e8effb671fae58545c09d4cd781d8a730e288dc4db2dd5a9ddb2f610a4959f9c8e27f36675b6ed2ad287e21267822d132d2cfa1ef260859af40efc9b8018dbc7fcdd2276129dad9dec944057f99a343914c004173098f6434d5bd8f8ac521208fc8fdfca22453e54795bf724fa2c0acf92a7cb9e7d8a3c8c25ea554ddea1213e9bf7f7ff639c8812adf6d5eb5ff8822f7939fd74923bc73a5b8fbbe6c30ff65261657e77979f2d97d6ce6a46a2cf1261846e88df59101c504a72556549a2bba0c7665bf6547b11519a520d1ff2a2c256baf21e89c440c6092b5095637afb57a97d197cf8c81b035532a34b4b106c248406c98151102ddf9b9eecfbbc92413a6962e71d7a35ff308fcdf680f1e804ff1214d683731b2c5cd51658fbc9c7b9dffef31ec2cf3fd1bbf307d0d9a1e7b34b648ca2f85b9c2d1bd2a774934a1a95af8ec3b98f480cfd98c8954dd54bd90a1b82e5888715cfaf4d29f863a8d399d0c40e7f871bb3cd46e105ca582e188aaa7ff6de2ac962912c54d15655b4281e81cc64b2106c09d2cd69069359570842513f95f2fbe78af67b8ba1b265c54f7ba56060e9774c814713d6f66232f1b536fef021e3e7d8073412f5b33094b2eed9421835b5b8cb9e1a3b706c6db1cb88ed409726fe6264825a6a04905c91784c2a4bfe03cb53a11abba15ecc886ee4a81a5c2f5f57b0c61957569434d9997a83119a21eed571fbe3c7a8b35a13e53b176854a0378eacaff87d2b0a5f5cc7b54795eb0af40b3d53c869b02deddea6c5f59c0009f9cddff1d211ca229477a61472ab6f5ddc8f685568513da04541d3203dde49cf70624c4b9636cd7f299b34036e98710facb3e3927bdf0405298a93ba3cce39c5f969462d709d07c91eddc5602024baf706e2449eea1048b26a620f929f2c437ca8e24be1203cca9bcefa50a4e84ffd2e07c0ea95b78fa34a0a59e193e5cc86125f3db92b419ed5586583c596f2657a80e95ed8086ccf280e0808493033d46fce3d866163daa8f1cc4519337426cb0a2e848b77723eb4b491989475a5f2ba168e8cc90716dfa86364d2a0e286228f6b2f5fdcfbc0ef868179db9d2937588a42406e1427140eff0f117d6e3adc059680161263a30c433eca9a70bd7a1898ac03a5e752c51e30030f219cbc0d29ff524715deebfc50fdc6445cb1ce83a045713e7783c094cd5aef3e7d6d7cd924c094cde64a47a9f7c5de9475a9a497fbaf02355a7a39d8531c1f75051e9c16075be4c031ec3fbe97138f1d27b12d02f2dffca369e647450e57cef09bfcaacefad667c98623fdf902960105b9029139d910bef21e6004dca51c8570326b60b07f5801939787cab73892f60084971ad9f6367ed000cfc82c2ca66cfe3b2dbffb27bfcdde328567a120c3c1624c5f6932452cbb9440df69f27ff639b9e7c6fcc92a08f66759c2d7f3531c28ca135a0e1faf357da4c4124e2385d84f48d23914210e0882138c62894adf45876790c644aaf0a2b38384293df90cf909a95a651b68c1a4353a411ea44c36ccbd6d48daf522082afd7b5e24da86736735c45db2637883a86c5a6efc677593928cef4ba129379edb73c8feac2f4b5e7731061898125d3fbe5b06c2ebc90453bfe0fbf2e048d3fec753d242633edfad2f45d1e470b27221077ee7c876b9354eec4c085716bb824f6d67084d36386354ea8a8587438c130b02dca40ef7295b46a066ae8114fd32351d0183dedbe12d7a22e87a5bdc09ed717684614e5d8f14017e8e1ab468babc2984bd1947b629dbeb89809e68fd25a52366c55d64d3cc4aa7ffd7606e2a2e5116648dfb4fa89410040a8faf4a734c308275678c9feb17bacb1578753f8c7d2dd7c949de49e5e4a1fe8b2d31cd4b60a0bed97787cf52d9e819ce7c37ded8684e0bf8dd781d65bda03789425fa0639e0d9fd39532410a5db7358c2918db76da1fce2354eb27f3173e8a3db7635786f13cbbd61c976c69f7c2a8f2e564d2aa563162f590a39872137959c0dcf992472fba480da66a8c718cd98d1dfba6e1c8467b38d6557eeea4744e94786c217a9eae61bac2a94d9d220edc18fd6c9521a43a3f9b3a83045af33b9905d529d0c0dc6296c84425cdf77e41a586cd544cfe10e54452b551953c78ffeebdf47e92871e6ba2e7eab1e5f2052c50e20ee33da2783ff1dd0d5306a1a466c5106f114c7bcdb870de18ce85238fc15f3a72758c711ff7b351d834d8658ff85bd804e2b514a85ba0f91eb50205b91eb001ec759ce945ad5a2d6784d6f6acc5372f62e4f01432cb633047cd0e45058b231e66e1aafa00ddc487379413ff698e1021696f650a1dbdeea6f0a04ee23601c638c751fb48d9197dcc552ad33bfaf41812d7dd89efd050afdf1f25edb137c26bb483ed75fc51c77be611f6b6f1d6cf18c89a4429ab99bc01787ad2ee5f762d0aba4b12a62c8e4909a2440b8e22ad905b05aef31cb242418d9d841b4e05d129915a35e15c6b72a25af39026efff748952496085c231ae1f27c3ea02e2c6efa7d0431e9950a4ea1f3ae57062951e2d25fde93aa799a162f0796f2ca4b8ddea7c1f7e8c78616d4f98da69c42fd8b91f872fe22e65dcaaea3e71ff6ed6983a94f8728510ba4ed4981623ecd0d7e09ceb6b28b56cf438999ad2319c35533ad83cf0e79b084a2b4140c35a7b8891fcff9b69a258094d6b4c996b03e85db53f142793b920368287d14263fe527fd6d9a0875534f8282b7be982cb4009c33de1c4d595b11b10fc4276f9177b8d65d78815dc0cbffbb53fb62810aa00574316881fbe07f229ce2b32c906dca8a88693c77ebce637edc8ad35844059c206ff15734ce80323f8dc4749b9b719447c5a4c6d41d2cb8253ce6aca118c8d81f98142e54060848a053ba461b09f9d96e217dc0ad951051738cfb10a551eef1c352090ae1b3312250adf94d7b85204489376f805990853d11b51703e0df7436897da51e61e151db65443f085ef2d319727035b57cbddd906d3c68cb8c0c0eeb6b1f58ca8c2854765dbe66a6ff1ceae727aaff45456d26d2934c84d4834de7f22e38de448fa76541a87643104bc71f8a752588aa9538cc117df2f4804e5100eee17791b51bc7c24b60bec1bc4ac3c7c4ebdcedb11a9806a7cf5db460d1d447a83d11407d7a67d4855c95eb4d0d7b0541e9e6ec26e1d32d4d46f6943c39827d78ac0b22a0eaf4e7f516bf5a93ad67fd6d7863d6b78ddf86479d343639b888886976af1c94f555ba08c3d7b4a8ce9dac1c2b2f498bb4bd4ea4f171f9e51dfd9042187b5bdfe2a7cd6ec6c50ed3aa89e136778be45b83fa2958cbb8068ecc89f4543fb215bc3dde78d97c1896d29f5942b55abe8f0330a30737e4abb566bf0986887832db1054231cc4f74a76c54736d94ed53ba0c7cc3d699a57a7bab41dca93d92120e215cf78fd6783dfe3b23a52e6f98afbeaadf50e6f74b501dc762a8a1f7fd2e4b9b5464d198916f34a5dd0670d2aee9e73ee9cdfdba7d9a6c4a8a48983ea9f98f5d214b03e3269e7628c32fce374bdafe5fb8a739be3346c1511702b0b95cc14f10996ad04bc1decf56f9cb82b31658b2115ffa6965e9d8fa12a391dcb763f9aa96a081b67fb5d6381d896704d877181f0dca31bcdd9975315232b9213f9ba03704e727919d051a248355eaa6f1a90c893a64865be9a4650c4f9614481485aa6542f1d8ac20569fd55cacb026f2aa014204ab4654c05b2564a9e4fe81f50dffd7e19ae9e6f5bb73328532031607655e9917156137764a9e3ff3e8e0f28eb0a8dbea2aaa232198a1a9ccb6c944923fe1c15a2a86a7e1c422793841af450ff0b739e1a1426380bc7501a9efd7c59f45f56087df6c372c98f6326c4c497d784c6238e6f43adb5dfc632eca543884656aea3e703f5a731607ff0d5a8ff33a1ebc3342e17fc1f4f0bdbf503aee77a9f851433b1d8591d0f5f7f8fe700c3ee0915ee1a6a5b5fb0e4a8e244ed0e86e6c507fb4badc9e557e09071014453673a0299a93d3afe5c1d6a80654e3632ac455902ff7708cd6bc0c7e54b7f037dea3bafa8cc1e4a0e3b31f74b0164d470cbcf888b08de543d885cfa0c859bf318ba645ab708bbb132c07abb0d139687c4a2a4ea5ee823903299c67bf23ebe482c9cdb49353a08b0e95162fefe60177c16246a8d9be922870c0268583b641a841c559ea379b4c6a97e7f234d297125234009c486771f122aa58b0d13ea2592bc575559b33ae5f0debeed41f3122fd202be69fa66949ece5b22b87a3d31b6382bc675d39af4974d2e0ff417c06f0e3622a41bf7fb4e801c531ed87cbd07a60560087488cd9227d406d111842c9275e6560acfafedbe884b103105fec1175f2ca9129e2cd02413c84ea3a9bbc52428ba8ac948a0dffeadb72c678b69419c3a3c21f2b6e7d0bd2cd926b141d01145f4c83b8351af84b9b872148bdaed194a5e565af61a5a90284629374bee5319bbc81e3b36bd1c418200fb22d03fdb1e845f3d56b49acbf33ed95fbb31a74d60cd933390311c2920e14c8b178498f1ae3ad8e31a6669836cf07df6485096426745c866b5a2165192efd3a6cc2f1cc4cb9946a8d9da0d1129791c4ef6e31666e71912e91801c20aff8366ca604f17fee4a5039943a9b630548280e23356da89686b7d8ec1b948daa4b758258946baba7c34837a3ff046cae0c70a6395d01183bfda8e1da06437c85e814095c230347cdfada8e557881c4bbd793d8d27767719c0dc9979f4c7487fa03d11e27d71ba9e6c16de2410ce49157d388aee5f63df17b35774c81b7a36e43df76905db151d8a9e4ee5e073588a04be59e00ca51ad5d5f62bd64fccbe3d7a0650e288f86ecd421e145c1cdefba431436a9da1735aa5cede5a6200e88620f87185e8e74d6010f0eea22a5e3a7094e19804b54753d358a4a47287e9850854b0cb4a28e9a4ef21f974b8969242b32869d24a21e8340b9a1ff16c61eae3f0b36757b9a09eb313bddd4d349e32959a3f617385f1e0d8d9cbbf244e66188c794a1d06402a27217725059174e591353142a8c894f632277e5361875b75133fffd30de5afd6a7837f2c388f8f48c6de2a17ae097b04c447c88e926f57e073dc38c7322a4263702fe08bf39bc6f66eeda41a14497cdff52e201ff52aea0235efad422deb71e3526294b143cdf3a33390b58aae37dd9609cdb32937294ef9a6b98d87e02cf876367c64f8def983f0cc7ed0185fd299f2c44ae3bc3b646f3d6693cf65cb7481214ffef6e8fcfef120208d3324aa79080b8979cd5cd0a909232a004d4992a4909e2ccea8ae16cb4571d023be67e31daedca04b562d3106f3079fdebfb4bbed8834641fde67cc2785ec0ce81de1d11392f8fcce01717414138c514b10c0ce445425cd9d17eb26e75e20821b62d9f7134b537161acd3fe30c185afa9e040c921ea2a911747c4ad53deeb032cafef9688c3de19bcec6fb27b1ce68fe585438c204301e1fe3974b0dfcb5a1e5e1b5c45e8be9640668d6a7296ef5f78566e2622575dbe19622dd9c4018cdd8594b3481a78fcf3dbbd941be88931393740c791094a33843d78f0ec33a4c92fb0b9757380d355fb17f30f4d6be084e42637ee05e83628c6cc4de3f60a172b98edccf13455454d269e696d105588836e649e057e553bce47f76bee5255c29c08e5b3b9630dda613295975ed63c7eb5be101b919cc153898e60ce23c18d8a4b4af185918e0f5cb586b616f74453a3eead8f74841a11deaeaaf69e65bf23163d055295bbcb0bb645354766772e21cc76e8e306499d51940e4704b68028c1f058db31c83e78ee089fe7503ccc190fdab7bd8d396f9488fd3bc9ebdcd7e569aff7f8b66022fa906bea6edff3860bc26aba1c27795a662a11c2f0b946161f90a2f4ed9f5dd210fa860beb009320fbf104aaf41128515ac79c5b217ad467059a0604eb09485f20e0f54a10e266fc6aaddddf032a1ff0ab01bfd339ded286a39a3acd6c1e323cee13d2332967abaf373482b62e5749185b5a58e5dd9c70e573044766bf98d9930f40541d2d975570a0e7504f295c1e6407b4d090fb3be3a90d41b98772e7b57f35fac953a92fbfed38c7097d9f42ca592f96ffd62d31edf0caacb6d2b0456e4e820be126ccce553a48abcd8375ee64be680ad01be737a6d516ec4677c4dbac45f1383b170eedb18a77ed24e024cae214e1008db326974fb275c8c12166232f47f737e4aa14c845c05b760cf1bb02af9fd53bdc9e7839fa53b9189be5d41a89ffb7ff1da965430c19e103ba0b49835e9d6da1e71c4be9eb95ad68c22547d67dd4d2d8afcb7be116b049f10793de7c4e1856faf7e15f78270f2ba10491e597be28fcee470a71572c85d9a2f4aecb57a82219bbe579127447f6ffe4bf169ffefaa61da984a62bb0bb60f131e40b42cbf2f7b2adc3c3686474eb2717e0ec2db64c03bfabd8fdf28e9411bb0632f1f081f199da63b1f28985cede06c63d8d0ba47afe6a5a17be1e4d01628b3ffb2a6b441a6a4833d5a25e97adb41991f27e987931552fa3cd43ab8d9679d9441551f1dcb7d9f5733e5eead965c6ec68c98b29fc1e5945cfd2f2975943027237ce79d848d633521988ec25b34ccac2ab503a37fffa13b7319b49a5b9d807692305b0ce1f37c9d377a9a4d1df60361a7916a520827defdc39cfe5dba998ef9a3d0b60ff6ae7525bedb12d39d14078c5a07549843f6a233ef7c7b36c8ff08e24b172db9a69c6d126f6ef837fb1d639947afef90f1e9e3a8425786c24649c38b2cfbdc9279a75fc825aae7881eb6f1b2c742160e71f96f53f2973c23908ad91d648b278457e32b728337c5389f1a66fc3011485c7f263e368395243083db76692c6827ceba134e6526fb018d79ccce11f08f9a2577c325cd318e44817b0cab84c7bc17fee49579086d418ec07f4638b7b33d87365a62204576206428ff90f1f5517d235c887beac2866549ba32344327ed0e8e3cfdf317078573a23914ea087600f487c072da4df958797a0c1c61b91fdd95423908d99fe50736307a36057480a1a5ab146823573e970d316f72569ac5a6b200f3befd3b1b5c482a1384f3898eaac2c28dd97a8237ead751b21788c86351d278b67ad5eaa9e084e5852be2881d338ae472fc792f4fb902f93695fe0123ce1b59048079ac925d3233874399495b901af739492564d517ef08098fbaccd5ef20bd5bd417e67f000599c64a9293e889b99af670459b6e72fe5ed1b297f3f9e164c18bdd669dedb11e56e2339343bddcb6c16ea1df44994024bd113efa8e01c6bd09ed99ddad42dbd8406ece435b536606fde6c7b1acfcd23444bcfa9901bf9072d3284a52bb2bec917acb80a495ffe0e4d478fd9ff1fbd154c0f912fd93a611d26dc5b570824c66c392a07125f0b8f84279c73ce8193b8e5efc9699c33cec9427def275f5ac19b28debe4168897932099375f09704702736640991e9106b5d717f6566c969fcc758ad6a3db38ca864b17f73555c77513d7a131a780128b925178df7cf5e453f8861a5b39fa85e4298e191b01d579aeb758517cc0093c6ee2fef2eca70faa29696998b53d534f21c2a2671c1ac34b0e217767536af3cefac432f3a19de9a85f9d625d5ed1703be96a999e1deca7945703727d633c85a56b6b21c3f028ca0b827828d61f616dd40b818e32ef7af8ba793bd68a004af8de5b191beb58ff2cc8f63637553c2e64af317ef7ad28f7fc59b4fda8cfa754ee16a31a3b51d568c0008960ad4a2328b1851e1df34965d134c46b2a9f993095f87dad382a32ed66f10755ed82d751811812e42f68d9200a6964d10d62fb0a8e28ae1cee22b1132137e8f140faee61c02b4ff9bf832dee57f01fbb14c062591ad5f6028a6a04c75168f23802ee810ad967fce7429544d06cf4088a43f73a4039d5e89333545e0ef5ed598dbc0b6580f6627d78a7554638d900ccd6ff8239ad242ebebf0c0003f80e27f18824ba8c0816607df3ea181e5073baceb52b04bf8735ac49ae99aacad5d825f3c442ac4d07eeaf51d8506437e34a95f071e0c4071b10a75ab6ec2c514ffd59fd4af423168d35b812289a3b1ce6b9e4a52e147036af94eab221833a0ec66c018a0538b9aa12000ed9decaa5c43898aa997e68b99ddc516a89efb894cfa818d9271eacbc4d62b65b8ed5a7d5f241d1531a261125b72bf77d454cb936acf8a7c0f3155f3039708503621e87bc462d1052b20bc69b3d26f0be55727e3ccf321ef2e7bf75571e5fc55179f46e449cea18fa9f8e9516ab50269c7c89dcc98dc8cd0907544034ff99eba16c838770c7c8bb5209032345c73708b61c19a13aea33d0d62409815466e514ba48ff68a7b66c9d69a59c0be1c47826fda47402489feeb378c42053a29442972a0e8578d4ea5a267cfba4c74fd678041aeb95ca924f528f0e1017e91022d63e80c58e3d5bc772dff87613499b438f0b12efbef3f45c0c667a683c7c519ec4a41b75c9b994967c4475388c5d3043f8e82a3cf92667ec8943d62a4fdaa8e99ec6b380e8ff2e9166c1723bf658e7906537f00a4f90858b5d549459599bbf8edc668085e0ec36fe50205528a2b85be94d4b9a2d9910d3331c805efe88f60ff3309f19ce3d28fc34a97977a2d84c2a22b22dccfa86aa00eb9725de6c6b15d7fa3df922a4629d33c13ef9a1189c397ac08cd3b832727b8cb583d871abc47061023d9ce0bb9d39c160d97f7774e7cc89a8234680993300a38652fa730f187ab8c6b8c997f7a7f69d0696e2c4c7f00442e800e2a2dab21f04636728437f79bdc37e50d6e900358746c9dcf1b849d89117f75ebc00f419537880b37d26d2aea503f99a9d5a94b77a445ca4606095df919931c31a75cf72beca3975e62594e3060ae720c6d8cef45460dca866e880a46574a8a0fc1839244c8ae7d95689d333bd0e1c0970ffdaaa1edca25260fbb4bd25fe3f1d59f3b55bdefdd7422c6aecde7c3ca07efadbbb3c2e738f5831a0c7cc63eec84a1090bd7ac1ec28b8c6f49eb01f750951885338d5516c89b189c98cb1bd000c8970aa822cb34d9edfe1045d82af142eaf78a71629089a42409c02a691fdcc0666347e7f4772eeb8fca7226be9f5abb4bb74fabf55068521a5474a3f1c16b88f9f9ee5d84f2af1d71185b26f3f16f5da2e6835b1b37ee2b90ba7e2e5b3882e09a24244a838bca936467c6516c2f129535d8a48016b7dca9ec12a7e4d121ccd844448a29f96cea802f120c0dd0c2f9fd572e83746e7ed1ab766ee6332eb330a18ac19f7026428c1637ec6a477fc5a584e6643cd600b57cabc10c5237e59ec97021b0323d7193aa0f31613cbdee3f563a89f6715b3a352ce49014d4f9d531bba719df880d7bf5979fb602cac9118b75300b8dd57a2d6b1e04daa65cf90565e2d0fa1eec6210803dc311ac584e7e8eacb4dfe43182c222056c4f3733841c9ceff47c6cccb639ea542b9149101a1aa321fcd43cd6e5b12356d53534c1e8ceececfc9cfaad7551bfbbc3dcdf94b3a4e57672a7761bb0030ce86d73a466cadba7f407cd96bc32fafe4f2047a4f07ad05afacbd8b32f782030ba6a9aef847f4ab53185e216c309a2f92036f8f72b1fa07a8fc0ed854d03ca4540fda3787c72b31ba0388a95dd95a40938d8e96a13a947b2bd08c04a2ea82aa3c5be58fe732624a8a277f7d3df27bce14ce699a9a5f93d3ca3b5ed24181e1152d3372583545edc1acfb0018e237342fb77b04cde3ab62948c0d6a0e3ec9d489fda88dc4f868c196eb685694a04a650633f4995597ce0799717a1a1e7c5a4609ec5824c2fb39fe10d5dfbb4d517a5f6c3d065c26cd46f7db193c8fdb9ab1edff39de0538f57a733c7ea9a8c36658e46c469f2de3b04d152893caf1f664286ae8ce79a2f4db81f49421317df9c7349d1a6a866edca9bdc43345c42c03e953643c8be66f1b86eb801b2532d48f602adf2dc0707f32c61154e12abda702b04dff653593a655d71138433e991217d281c29c11eb61fa5cc60c29464d2f35878dd398dbd60dbc4e2d301e88dd67104b1d375da1348881dc169363c8add58d5b9a79bead289c735959acce925264b1563331121a0c1f3759de28b35f2207131b3c1fcd833bd9e611591901a256db0be52d097200af241ba76a6f2f33a9e8fab5d6e3bbdb4e7bb0896b54fe56a2a072d1de12bdb88044e6fc79d52b058ce12d75728395e358026f1fd010bf4e4471cf46a3146bf672d8d99041801f83b7a5d6e88887a29cea3e4bda36004dccedb2117038ef12d09fb165df9518334a8fa9eea4f79697b4eef6f781fe884be92c7a6c33501c04d00df2a05c4121eb427eecd9489e21c706f87116833fb8395f6655eeb9b8d9d9a00226aeb248c32698a0d645bc218d124a2a8f2ae8a76ec8e17163b1309147dacca5f0c70821cabd989fb4dd9c22d4aee279bfc91a89a4f46dc18e8ff7ab3dc0f94dbea8c807d4f9d36db475f1df6fe71e114420b5316b61095e6c62aee097b0e86fd0e74a80613078ae54c816e182d973184d8c34529ecc01e9c6f5125de0083cf417131365aca7146c9cf7077e2c4e9487c286142a023c64ca6454d2872f15f9a18e260300e27071475abfaebddb17b3de53d49c9371ec41b4ec268c65f779f8cb7dbb3f912d1f46bf64af827181558f04e3033670ad96fcf551f0bffc5db71fc8843f5b8f4a782deb65204a31d704a2cf706edcc8393d647899382b6b0f64efc00890c7358c0d2e5fb842b4b2d368abe62937e64885fbf7f67dd958029550d14ec4073b35cef6e845b3d72131d393e9e564d1db560edf20bec3665aaa9b63ffcb93ea619be3becef81a7ad29659b27454f011585cc5fbab92d14db12a6ed04c3c54d14c3ae02576e62e524027678c6bab6f4349e364cb5941416e9389f486ee02c1da272a97895ef0eabce2cdb2a845f0610cd59ff0cb0d5ef862b2c62be031ff8d269016f262a326c1dd09ba8cde3a739e0b3ec6ea8279f98913e53a9673719c64b8f4da758dec315743a6b691f8f4962edb21ab8b81b65d0043fe8f1b06d593ef57d906b61d68e3eda3dc7b3e59e2aedc539964f3706668b1aaca8c7d0ecd21dcf5e423b21f1c9ff0e5afe312255ca60dd1d22e0cfb51b0f058a4defd7c94d21ade4f2f4e0215f28e50239cd769857f36597a5b9d37f0fb7c96973019bcaa114f733dea158d179b9e2720b7aeeb1146de158b11155c1f1dd1c57bf2419dabd686108097864dda041b0b9da3eb5ac5ae3eb0a934c986bbb9600836ca22c1cae61d711ef99290a78fb8d96caf8947e9794fdc3e610bad3b5262954791e32ab40b5597398cff3fe69e249d504cd3b90aa670969ae556a848e5c364f4f733df389f39957dbb9974a21e1c8a8cace64c65ac5a0794fc2da1432643d8dc35338f8bb60f66257ec48cd29d6992e090e4ed1af65e827278fd9103268b38b076f98841d0f9bc4b8586966712155ddb4028c61ecfe5adecb0f0181513eb7dd5f272e467933ce28bc99f20ff461e29c34774a3ef2958b07fd9718b96ff21e96d993ab3e5dae66546a4d9ed8c59825af5d7d3ebb2b16be9c2c14761f5e3b89db7482a8653bacabe7beea86ad442907a7b59ab77565460094eff8eea110eb83b1999a6f6e5d578dc7f17570c9900ec4fc772ecda6d589bb177e3830d00053a2d3719ec240a13f9608a401b83efbe5fc305f54057e47254e79f652b9cb9bce50e12d8a42c5f06a48a28634fc41f703cd88b6cde9a76b4b7212e04a6f1ffd94a2bba8419a13c9c0b50375a4c2540a1c3c588e7b8404da43ab02e1e6d08ee3efc1167029838b60ff102f8ac9b1174dbcb8a439b347dfe735e219f43efa37a45c91c46964dedb8a28f32f4fd16a41a4906c9af4c501763741cba60e8d57d85f37b30ee11592a267e1ee97c26b9b106d30ef3174f7779f879a30f62f8ea878b8aa18ef07a971ccb46aa071f1d4592e9917d799862b7a5e24d0bcda1b1d961c31dc7b3ceea5ba914cf7b666df98fc2b237949d3cdb0fe00d71876734812cf11511eb736202faad04b1ca0e179bb527deb435e0c810b70039b5bc301af7bcef05c70f940f15db6006646bb375665391e53062c8dc72ddb9424572eea53e505d042ab16136d6ee8e6f5302b62c9ddd109884ca4328fdcd73ce11b783dfc09bc660911c6893831767df420c6c8ed679ca71872316cd760a9a4b373c71fc8b9084d82446e775a8b943b461642f0fbd917628307fce0408bd0595f8706548dc661fcbed913463e57327516d4461df95dc0ca9a8d3054b47490cb84c96fa5283c6d3bf37a1b9761f48075b5fbb6bb76065b14e72931e578cfaf0d487ee851b3c48d59bf9128a8c082b077d2761774b87f8133281aa49d5c300cbe9fc76d9c9d87570846202c02f154a9f2f4f58462750a03d61f1e8d6b5b938372df2de0a8f9eb5ae029137a008f89d56e80605c18476bdb42c257674c70b01667ca23e806a2317dedc6de8409f297d52bd8576cd31ead57bf2d8dae5b47289eaf79ad3905613a50b50b6aed29fd1e9910a1c16258dc51f92a9fd2d833f8a2c1638e98b14782a2de66793860c128d514a4c425bb0d60877303564fa60d110c43804c751388dfbaef8eacb8d9d72923565f7b2ca9317b21c58cadea36cfc517d9010c3875c32bbd6dd5457694f69ca7f5a0045bd2d8bd5c7e78c0795a8c5354483bf0f6a7233a074c3e238dd14299d7b48df2ea714c80dd5900e8c217ad8839e31a0304145ad6f040e896b40a376f6aa6347d13f2806245aef32f0c9572f0308645318e2d3bc9de6dc4548b8f4217461f337e4950e7ae45c58e82b6de3c30c475e11649750868a8cebcb8d5cfdc8fabbf3439704e7aeb74dd940851371b0cee4bbb6d489e04e12a56f8ee79194146ac52da35e9e5522dd846351177ec6270f29ebc60bac77ba0d19cb49babd2359b7d3ea707d2e2e6a113e0a21ff98e7551632962175df94a6bc3ba2d3fb8b74bad67a045ac641076c0582306211c1b7fe2b066f9e41663f532ce5e6296d436b90c72a60a1c47b2a4aa0fd671effca44cf8e5d6ab2be805b0c3ddffd6f8a697cd525c04d0ba5d842ede3f2ca6084ab4eb3a8510b0b845f1a160a8a40cdb97205ab57f18bc7dc1b3c220a4e201caa8c196abda05a7cb2ce393533248a2135f3c10812591a9fd05ca41da35c284656cc6b510a18e7e9a84095222e1725cd1cd29d4af95fcb7db1336669ad94aea98ca85988b774b4fa40c173064ac60f51d6350ed846bb32234151cf02df0ac1b7b315da0c0ddeeafcf146ad8616dbc8fcf0c2bb53f0e7f793385447f4cb1b9ce4c5a948596e56a1dfeacc986ac80ffe6cadcedc9fb975d58e86e1ca29f902910106b9028c3952094dd9e4b693b3558b936348d1be080186ec4fd4918f3d51a387fdbbfbb030df8d97ae68a37bdb5acad4b457781eff4154a451a1127afcd302f2449ae49f2db5b6930d47c619c5c9e2904a7a4a5f6ff0af742df0c3e60a697bdda23ba497d59a36332b5e2db6e21ca51720b03b249e6f49699812c1b19331edd16654a5e972baab65b571b60f488e9eed0085a58f6e9bbc94da5987112997da91280f853a3038474e092d9e5a6af5fa4d530516ee916c5663bf084eb6399d9efe7b6bacb52fee694b6472dc42716371a8bc3c5c61c181a0d059ae77883896081a1ed52b4fa57ff88be094ecbed7f0d97bbcc312e96b3d8c8d1e6c96268d9147644a43f2e064d14cfa18ccc09a8482287aefbc2785e2f4cd4e02b6eebc4eba7eb12bb504debddce7ae54c48200827b2b0877de40f059f713f7ea2123698c8eafa46f99de67798a353116310cf374991bbec3f783ebcca4d41d6ebfbf96abacc6c9ec9f325034b77adb2f6df434b64cb5ed75c1b74b300d5b4ed672a32bdcf7819062fc8d8c18cbbdb2761d17459a2d8b3a7b2574ff242f8ef15db686da83b4f6c49d241bcf429bfcb3285a1dac71a1ed2cbf5f2db03eade15876b46ea409fe5db939e3e53151dbc2bf3775213b58cba8e5f50c1ca110d51bf47e63a5cc311497205bd3bf77d4b16e9415ccbdd75933a9d7eacc9a3ecc9ebede9e9ca3c5d362afcafd5f8e702a58d506fecad00daed7dadc3570a8b34d04941866e8a07c27aa169a627795dfe6f3391e42567ca2127fa0f33a4a332e22d8ad062f3a51ba6c8959f4536fc9c4a315ad17aa0f79e882e23284691d6662f12585b6c1557cd0574317eca042b4939c9f2893cf775c7b863f2c677925be7c82fe3237282ec2ab0ae25bde2e5f3e610635f5c79a2b1e4656124080f91eb50206b91eb0789c451cc6a2640a0110b12c0744093ec90dd8ffd89fd69cc89e96d2ffc71f28fb82ce8d91cdc9d037e461fb7f6b74e90ab429bbbd109cf8a69cd54cbdfb078f73dd14484bfda4b10767c07db64fc71ec2d5709375994c845810d685d85ec7c79211e51c1a2590ec20303eafa784267c980b1d03c44da3c54ff73f567d71cc1057514e7106e0f101716f6dc1862fddc16595c4db922bf322c4b5604a157c9644658721ebff5791b933e5646b3f25bc3ffc3d852ba203d8775474ed5ede7e4921978bb17718d2e8e5118f4400b4e0030d02a779c05f57f87721507243a04eb9099d7176196202164a968ffb4d53a4a2e85079f1f14d2b1d17e1ccd8c050dd341038d833718b53f2ddc1a03c3c72dfbd0fbe0b33febd7ea565cba1229a48a0c34284685bf1cf6f7cbc4009c25bc470f97342b4a2aa7ba5f1106d6f8f4594847f2e76af71e24ee0262302d44475b5ba61c8dc40ed00bd9e0118c623c5cc90f54e7da898cc972ffa691e18355e0ba374ea37b8d6d993076e2e308a6a3c3a3952dcc47fb690e6b0ac0829a2ed1c6d64c188e8d704c61ff33acfd982111acabc1ddf12126843c288f79fd81c4c7ba826ffb1bff3bd6d5d11205a388246aaf1a98ecb771ff1ede664fe66e3890eac34952d18691606954ad2f2f387466375f4b9373d6f3cd542a91bab335232a0099ae3a6d3ac345810a8b7f295ee52a02e6aa108d189093853ae0c3869fcf99a9d1a18a8db017702343f6a0c84a5752796b5bbb03f4cfe16fd529e8c90c6723818b76f36b06c1fe3e08c625bb362b4e0a52de7effde8aeb723b3e135b20fe7e97aa12c7e13561006c51b06c607ab8347f4fa80af0a7fec447d7c92f328df80cef06e48f371ac09d3d2494e98616e0812b6a014e685ae79b928933d4e4cdbb6f1b788eba0d78df3deebdf1eb4fa7460957f69c2a4eb3ab2553223b7bea042110d7db586995054f3ac6fbdba701477d3c073c4e43f5a05f05405d84c9dc9b4897e0e860d19a9bae2e9bfc19427aa9f297c3aa50b808b0a50f583ac4deb60dbdd153eecef396bdd8a918ad5fc0fce39792526f4f0f3c37b228dc9d30c41bf0ca9b63067d02eea1f73ffde737eddfb72c28eda2a83b79cd27aff82078769570c197f2be98894450e6edaf549e078cd6bb83bb1c03d2f99bfbdbae2bb4de35e00731d78c9f7d9a4afc35cd645ca42ac923561289d54152e092f27c4763e1010dc3385b85c3ebe7d29ceb74d925ce31c613d0f650c49a9a1200cf49f0edff832663ed7fafb5848d13bdf1c480d4366422e8b5f433fab5455152c45142d3bb986b17d93a3abc14b79b17ac96c40e461ebe324e22e0389f8630c6e52f5829aa8c328360dadd39acf510de478236867d34097d3f900fef80583436821e1c75324fe1a88a3fce0c1d8369cab64127a1450f15d92dbc48f284ed9a9cc612913f23810334db8dd5d28b8917ded740a14eb7ea2f6f271c50c89c384a3d696c84ef33c9f036b571d6dea7ebd7d856b1a352d55020dd72eb3c1f7d91c184f5a34ed168a638438b067e56f634ca98e0bb49b007cb4657a3c23c67892c4b8056adf94a487cd7fe91c00b08bd7ec308c77f884ba4b352301615b3db751a27d9c2abba1f54f0c5ad6b1465cd48b44913e7ede5dfb794ddca285cd799dbce5f7e79c04db67ec476e70e217f11b27494e278b860f467e6bd85fb83ed43546b4ee3f10ab12c71a996819af3c005513fa942b0c456f9cbfa5e5f8e1d79632e594ef804a60a86b94134521ddc121af15f575f5370d52c602c4918b3ed2a5b75f478f72c3a0363562654493a8c405a078fd69c142fa71d4bf6a1d99835a5baa2e0bebf0b654cb4827d18b412af3b75cd0e08f8527eeba3fece225959804d7d5a8e562143ebbe42298e1531de0c03577727f86cb628b952ef43a0259be8ba35780e2db1282a98a0be9948c1d62ecad31a069a2c3f99562cc5c99c85198092a3a5752949e334b20b0984aeceb1a31cf086be99e4b956990a7a321117acd2dfd085ec0cfa49f382f8c7928785fb68e30448a303c5248259bca5af8f146ef9c34d00c29c91098ca0b71555b18f10ac4ebc824b8f5941beda3ff2ddd8ec4357fead47f608572a86d31c18a45b6e097d5d682d0360916ff383d3bf5aecb9bbfc87aecb996ff92ae2c2a53dde08f66bc4594009c4b006339fcdae3f8efa54cbf5af9ba7748b3d3e530c9d8ce85720220aeadf029b5bf7ba4f6e7bdf2e327c52e6cafb8f07cbce462e09c21a2812707b286013ae0c4cd930fb9c87d32382912dc03c2f169ee856c3aa65aba3a24684fca4030b0cc1de2e5feae416cb7e81300fd0b53cf4f433227e0d5fac5cf6b5d23ebe6b2cf0406ce1492d9ab8dedc41e506ba80b7a57d8b51cf171d4d2d98433f9239a1c06ba91f5828d6ea5d0c838809943e98dfaccf045791db00d58b859d811e6cf5300f05a52a25e68e577165be5f87d45ece0656b67cfbb7b08e1784e011aeb3fdf26b56469208d494d8fcb28b1e76a5e6ef78e13e93c213bec80bea9a31f9291a4f1a5087e81e5fb61f76906a5f558166a6359e1bbbc01cfcf2c27a2ef689df55f0a672043dee845ee57f90f999e1970733f5b2715221754fbfc18ea3821d844810ac69c4a5c1ab253d63f6b1f5f3561e1b295eb579385dc226bf79f14891bc4b534e0ce7e7404578ed26cd47d8fca3b822e48c1299bb28a2579b9aca77ce21d56527343f9e02137b828ee4ffe3a03b11fb3eae90ea4cdb4a64353027d50b744584f80d0fea7437702d773b7e0dc5f0670a88c71be2a8f890bbacc621f5ee58a499b12cc50078360778fef90fa10284bc32b968597e4724d90468b0e19d799f05d32a26e01626dd3cf95d91551445a0f4da808c137f667f172a669d939473436c88afac4d15876a1eb51fd08a77b158341e2c2b130ca9c2261a7f1f34189340220ad65c50e669b98f9645e315551767e874465297c5cee80d9fadd492d1b4b9a76413b22a5f7c741340d52ca17025af9d9409b7bd6cb14f91f07e6709ca06f258c8916340dd04ab155107303e5053d4b5d49235eca9bf1b9165beafeafdafc7aad013ef88eb5af08de92b87cfd90ea77962f6c527e0aba4a1cbe7353d067d3e343aec418eda06f2f9895c245426e8e2f3889dc59348ff6291cd69e8153ecda78919950267fce8410dfe0cf8c83faefaa3164922ac797a07b5d20a698601d9b57559dfa67c48faf48801e6d271f81347e3da3de6b257abe4d94d7ffbe70a3e9fa64bb27964cd3edd6aec8f9ebf533efd3657d0f77556f732a5c1efee99c72943eac98530ab6448370474b3a9d137e5d0486aef5808630c2f488a48b1b709940ba6de09d21c4a0f3f21c837d4794fdef463093195519298b05715495574c16ce79b71e1b12ea04f55cebe9a82f8c2e125e74fe2759772920a4d5c1c740add96230f693d22d2e5e04a466b3ba97ded1424e1357be6a7e86a3f9309edc9f70289f2989dee7cf4956b45e40f9be63477f7ba5fa7ccaaebb928cf2a19c86b4b0c5393c034428f3a4abc37de27d51caf01fe761f65704e9630330c28b352ee98cbfd0d6ed3df49dc3fd5d896b521de59bfdfdd948b7b7888fb5c78e230ca7495999dcf70612fc9fb02895d4637883cb9acf09e0f85b5affcaa531158a0217466154d4dc03d0b55f3c9852bce3430d93044afa0f510c35cc9e79d487bdaf92610e9df2464959d0f6a93ae84932254f26d3195eed3eca7349b09300d0c60520e67daa03cb7fd732d4a20c305b43a1492cb7fe247a06e0f6bef659ef488f8d4ef29d4ee1c559fe332cfd3158ce7fe8dc1e46d71212d0750b14b41d18ee0b78815e0df13d155999a6a382b52e0d26fb83670346e9b2f276e333ee26dfe95c6d5fce6858bc02ba3e8c568864d60340ac1477c560b42861a47a1f06bf6d036c8f7016b3bca0c8312a7bb31c1f72c400e353677ce811f32150ba4ab832bbe334992e801845983f23eb9d4f0e82ac8309ec5767b98493aaefc6a12a556ef6929ea98854f4d796fc5fdaf4218f82ac322b7a75038592fe8642f36f3a5b0be362598eefa7e74e62742d0da6f5ebcb8a4e6c506bea0229a8c13039b7a3a7541a83e5b7cf96419a646c752a252aaf394179fd3bed072f3ac91d263a634bea7e1bcdd37f805e47347d035d156772657a3d6e2647f91d1782265f603906832096485b21763e1134d8064e9d259ae2cb09573b9f78d072c0797ea6e6afbd5eeef388a6adb9e4d7b56dd1c02eb3203d7cfc5bdc43cc96d96e338888750bcc410d4a1a7098545a24ebabd33f900a9944cd2780479b7c8f9eacad2cc625f7bc348f658a7d363d7b84bf328b5374e5567686f720f8c39c292ffdaac9d7c4feac505616616d07af525b6f89de709a059cfaf61f42b0049d53b4762f40cf1fc37c3f093746760a6b993d4b8ac1675a9370583bea12953baaac9aa5ec349ac58396d6a6623fbdb46dd7475f1ca912b3b80fb345ee3d6c1d5179eab47fc17cbde1cb1a38a4246a0265cbdaa1d18509407e6b25509733e46ba69127dc6b5073b4fccb81d4715629907dc9e33741ce2f5b7dfdfe8299d149f5b019191966e00ead0a2b0a6023a7a43c79d2884c2a3effa5485e32c52517d8c60be5b44eff00fc3de50091c61152e1b774f742e1ca244bc1057aca4f3710e10eb2e89cdfd9880c5c05e679ece670580fe6a7ea34f761bcae34a9a3011d4f95a5798319f33b74f3d6bc906567f1c1c0a0b03884ee77125f6cea2d95734c9a6560852ce1fb74af46a76783e91c4227dbd1100fbc69752e2dda212e3dc02b414ecd69c504c57558b9758a7327403a627461f416d079479025a4ba2346d9e93a5313094ae161995f244a184f7d8bcc6fb3ba92d474ccc1c07a632ef6899119904279b104e95bd1af0bf8032a4b66f6ca63a7a16945c45ffab2a10309170cd8e1a112c48dfc7f050b388f5b8d38c4b6698c6359047c4b46da44d10bb6b290670337e75021ce616be601598ce98725941ce6ab83b1efcd824690178668df366e7797734fba8b0183094ea8a49cd57dda001b89a0c38c4c2dde8f0185c1b4a7b2f158f77451c788b127c96fdf931512c7254c4b995f210228bcc3b28e0b4fdbb5108249a42ca245ca09f354a52cd1b965aff4db17ca74b860b9baf5d0d433e9e30f905acf84e0731b7816429f5f48c85be398d011c72179369b019e0070a77b87b60f5773478e30d942608e7b71f7392d8eb15d1b9278979378a0476ecab527203135dc675e77188d1efb9e189a29a1512dba644d9ba72e506e72de48c98a3df0c6fd301ab2b6028186c9409f14b5275d53d831e7d17a44e74ec0f9b1ead0d1eca4fa3b282772aab770512a3a40274f634493799a9e9754b7eb2e65849455b377d1145d6ee4e7fe107df31b5fe06f395a10012d009f35d3e11d5de622182b9da016aff39b86ffca18c2aed5438b65167308cb063eb275935e6779f5ce1d05349983f935f9f07d6cc7820c80151cc8da5918da988de306b15677e4185add96c1b52285a0a458fa71457d31e317ccaaa4355f28443013b40fa90506fade88a7728e81d198aab7c488f46364256a4581450d299afbaa1b5ccdafe4cc0213989d43b3f6ccead346ea2af74204ecc8e509438c3a0409af7dd9cb5514957c5ec2f264a996a55012f273132550b9f7274643de739b54326f2cd55e97fabae2b68198e3f4c8639001787c96c062c1352324241b9c77e7fe1161119c92b482e21dbe0afac35f2011a55911da96a503dcc309b42fa1d2138ef5c5de884da7cb2288b38d41c9a88aeb1969d1f7bb5502f023337730c926cb7938c043aee987bc34e4e2635ff7addabe4eb99fea37bf699ec55abea0d54ee44b7bfd8ba000bb2e129c79e0c44f49786e53024059f681d05ee3752ee57a06e305c8d3c92db1e1364e918d8165b8c17915671137c1a96fb403581b1a8a3821e5e6b748ff2e680af82ea6b5d61e13b6c1e8d3210303e5a4bc3b15a4ca9f7072ea5eb2135194a2405e06c8245db80cedc785bad51c5a1cb164515706e2d5669f1d5c0c541ec997d2e700eb8285c1f55cecd4b8621aa6e3568432689d3062bb226a8411cdcd985e693ffee56623a7c76e847dca00f01581c3d126286b202635f55762eeb27bc769ff76173036c972d9d9533dc657a106e48cbcaf6bdc780eb8a4a75f657ca043bc6d563822c0d449b00854fc794d9febb5138520ae3ad9ad2036bc3a7636cf0029f34350cbc8bb8c729f37b0784499b7b292d1745527ce6251f1625fc263dfc11e9133c909683f38cfd015f69fdfeaa0ff8ac4bad355f27c7b1a6b9834aee3c52e2bf6ccdf4e96c69355f244f709cf553bc114d16e2dd5971c4cd8ee94572e36f671e4a2fb8359ac47a458b72a01c19fca441ae28fcd8c200d882a490d668ef32da218f3f287e298579fbf3d8fa6ff365dd08390e9b3d902c227e3c284e021179c2baf22a7d44b75dbe09086d270c7cf96201d91010f3b990db4d408d98806f147ca270c658ecab56fb81139582377d22c15664900fb00fcd55499d3094d05ce39977e1845039aef1783cd39ca7f0b81054492454bedad6f5dd675e4c8e44c7669fe1b6076667e1b380f01f8d6fecaa77bff3140deb7ab82c7b5d019074e29f5cc1848ac6db803ba9411ff12594bb0ae22b6af9ee2ee4381b9cad37c2dc96a19d6919c682c10d0a5283df3a1643afe2792cf6c7606954a5ea68916d1a848df800ccf4f8420417f16fb9e384dcbb19a805f0198e07bb3426af366098a86b5dd128569e3763ecdb95c95c824d7f4ac3290ab55cba526827518dbc7b83a82da605a4f202689cc94af187bd91a41399264042878880406ae2b3992f9d70135c12a1f64d8ef458ba510d8ad2702a180675ff868659e0c3ffd75ae06e24361a78011743b900e37f59d24561eef4cd4eb2f3616303851d4c5d20aad0d5b5c9c9497d26496d5023b1ac92b9b5c9a0193a90b4fb2e1ea9587875aef64a2de6a9653b205c006e0ddbcda290131c054acea694454fe1bb79baf393b261826055519ee7c898652e25d5ad8be0853f7be804ab15e79fd20abbff6a828aaa1ae4036a3e0baf1a7df3aa72367bdf5067fe90453a9c1f64a3d21402b7d35a266685a1d359633d08328e6933b12c5bdc71c3bd08b116c68478d6e48ffdf644b9b647f59967c93cee397539dd124e27cfc0e5b6b3db2649f7290d97f2c31ef272e08b1e1ee1f61f50feca68b4746406b7d270bdb5ae260358bb6126121030acf9a9960ac7ddfd9f1f191a30d95312bb379fd3250059d5d2ec4865cdfb960049624d35eb17a33f00881bae9fe2455a16ce5700bb76f4541a997b92aa1ffad39f78d181dec4f2741e874bf622c60a151e8cb62238649d03bba0a34c8a8639b64f2c82b5c8c9bfe31c7d8d0fc91dfae6abeef743678cdeb5357f76f61f38c510cb916fff9fb305d2acaa06c2be6fb63858249ecab307b23f0e27dc508a95c228f1daab45c312777da5f16819fd5aa8a3680e7ef728d56e6d82dd65fc7940e3537b9e4816082bb978ff3d5cd42fb401dd1cb8e66b342e2a67250d4c51f662f043f00ad2d3bc204777b24044f7e695599232d9e9c23e76213a4896fc7907c59b53234a4ddf59ce821b5fb7bdc15d74bcbfbb67ddc433c87b0a19fba1bde073df96a0c2a20ca582d36172d7a5559da476977e017f098b1e053ab23144f57ddcfc5f77122bf5780176dbcda06977aed6d9fa8851a8898948ac463f7ef3fd561cb5997e6f2c193e2cd425c5d006a707d3258d6d4cf142f77ff7a6c8257ad9b20fcebf60c9b7869c174f697bc026c6edddd7af5ace6984324d077b8d1988b09ccd270f5f26d4f1ade0ea489772a5357e9fdbee212c7c8b9fbdec9964405a025357150cfb053bbf0499dc28da030bd216d9fb41e90b217966bc5a733637a3c9a0ff876f5c6cd56692bafb78f13f1c82aee8c7a9e5d1f0003ea87d44713198462d2080779fb850d7d0bbd920551214dbee377ad6a3f3ce28496e0f450e01b0c2292733a971e90cb37f05eea1d7e7b700220232344f1ced3c135f949cfe34d9d7f31d33320cb9a830a5d58e4e166777a7e3cae175387717bdd6d59d2b2c779a424bd9f7cb7830eed805c29398498c72f028054018ff5ad872cca4b4414e7a6fa843d1965183177284ebd5ade8328d26e79bd27c346ed070eb24596eb1463fe5c940afb98d93f453eeb9ef63d425d5e0031e6134524a0d04925f232c95b8fce5552a2a4e3073b890b9f6d91c5de7956cf6de987606bb5a9aacd539f932e98238515a139a2fab1e9bafa3d400b279fefdb4c0282266c614f31198257761a1c3d77713cf55241e47b1a6ce55e7daa2c2e350d9ccd53130367fcbe57aee09936294f89a928f709bc204b88ff8a4d57fa7443bd15e94aee5a76f8224d8968fc5f29a5ef43d12fc2397b550611fc08063ac8a86923d97097e9aea9a4f730bc573e00d41269699d27b66b5a8bd8b47d54e563e4eece417dac17d22fb66da6547f594a9f3381179116394a6a3ab52c3729d91ea99350a8938a3915afd4f8078d627164cdcf74684281e2d24d3a6e780ed0e21402704c4695c9eccf7c0009bd1697955c7119cc9de27e4a1956b50628aa0ae9a75896f92ed8147c390dec722dc6dc9831e17e736782908cf874d6f4b46792fe156c4d8c616aae24e9d7db239140b6f9026714e2a2b6c236b9fd2141597539f58315ce2e770b9f293b855c0f897157a05850d0275300ee299aca34f0f4c3dc5cf06245a85b32165a472bde0c6f74af04b5692a1e8eaa3a269ef13e4906561968d43059b68c055c28bed9a8b27c668cec336c9924e947b14cdca8b4cdba7f32892245fde11e33623809b988be9102123bc6337ce36d008d08487d44f9554722eaf388565ce17feeae0ecc0b702be5a4493b7e3c09f08411031ca0c2f83d09b04a9e022c64d11096720e8e14934641a07f411568aebb2d00279c183e1e276cfac961d13db6715595dc2e03eaf6934685b489d2e7575517428cf17832d8b0d28fbc94579ff2e61bc0e56a426ac7c0519224ffced0f9d4044e5035982da97ebef9a615d049c5f94543497708baa60b32049a1a0540855e4b766fea77fe162da932b647af8cf0f9e0a5009fe5f0de08d1608bb34fa96ef8051dfc7415d7c3bac0cc5c5f63467c4785711adbf680e5ba8306671e61a2622dbdf77243e2a0ab92a6cfcc0763e29e3cafd4f5ec485c4a657bb8e3a54434480d8e75d37542b0ca105a05d5291f0fb3f9f85c515a38994089fc30f434234dcad6a07a04eaff61fcc9fe6a1b6ab88b7428582b01741329b96562842eb6322cdc1ccaf9e4230dd21826bab0e3f0ad196d1cf43061095f4590024d1dcfccfbd8d69d4010e13088c26d81f3edb046d0f1a5c3ac4e94de0f7f9329780d3a9a4cd4de5fcf8a3183cf8ca5bb8ea2c4d8c339fb7f08bd92d02fdc4def440e16f247bd170e24a5892ef5ea71279df96869fac77a90b38c3cee6cc051787142f02c64a3c23621eaa66f3b9826b4c4a378a6b8607e5f49d2171a5341ac1da5289be24959e0d35932a54cc0855b2de0c79cfdea4aa7c89294e63f954518d0f6f63e02d1ab343c7005136c5204aa129fdd83ef7bdaa4b44e0c9da96bd7c4c65edc478f6687c7794136e78d248067bf04db44e30367197389553c31faaf1fcb4d505cca8645787131a3b6a3f4248e03304d94b38aec069d63cf2ad230804f61ad1798996fcefc679ac8d5ed0fce6899317e0acabd061956013a4382ff904d14b06c8966b157a2a4145a7541aeeb3800431e6d53b1b603a2823f9b8240492fabca359b650dc5e316f3b037b3474e196308423d823aa70bbea532c86709ac2f510f06add552e3df6eb6e491653c76bb0e2bb51b9aef792277d81ab4d8303c76a0ffba7a503b3daf7e9d179015dd3dd5b494294c1c539bd775c31ca7383dcf28ca4218f5f97b2bdc2a271c633438b9ebb0888a13dc1edd8423f51a7512af7aa21b436e8ef81d4fcd7e0c3957722aa565850253866215fd7ebbbd2b6ee735c39b871332cd7fb1db7ecafb27a8a605d435bf08761bd6d4450cb4b98c96bd30bd58eb3d8bc9b89e56a9671fd752f0a01d1460bcd5b6c972f10702193c828ad913d3f25f11ff5649a72aa9cf356003601c9c65a1723d39cbc94ecf0afa6d4a508cf7abe4c896b029990341fe619a4cdc6ecddfa08548d97a54f9fd01306d5465ee58ef1e4f747456ed1a308422f465d478ecf8fe2bcc87ddaa7a3143fbbdc4f89fff778d352fb171f209b994ddb869531a7d5ef18f69e81481b6ec47f5ee763d4311cefa27da8851a6ec4dce327764aea60464906f5b324968e3b9eb1dcc1377d95aed7923dbef6b97102c22b344bc4f6d5f625fe56376c070daee1eacec2284e935c0a9245cd6da2720b4de4060216be8e72829c744eb99eabb0971cb6e993115420f7f0a7724642d8485816430201fe3102ab806be45285d5800bf173d5b29a0442da43a43c36ae43a6bbbe137cb11e72d112427543380c0b2ef2a380eb3b2bb028cf7543084df9ce74951ef6d3077c8b9d318b0fce30039f10025dc30a07e84bb60b29daaa20c922e44adc8abbe6f246df9b591e0fe6c3122b75338d887991f0215626d0139a3b3dd02bcaab70b831112506f082225f83edaf57abb92fc0a8db841308b53765e86808b634d298f615d5679e015ea1166d2a1e24b7431296941f4485e3b6d9e8c8d2afe0b05e20f98e71b1b33db8c4bff0717e0c8d3a0cbe87de349f957fab8488d7d9f2f706b4cfc2740183ba0c46c5cc30b4834e5ad90377bef2d86300586b96ff6145de05ee2f89e0ef36df1d93e6c2c456edb341eae97df7a0911635ec21b70ce8db344e99a028f3b7653f2ecd8ee19c24a62f5712922fc0f687a35ae0b2dac7b202f7da5bc3c4f344f1a58d0e534dddcca71d72a37e1f7163da553761396e9620eb9a7e66e8f59147354d21ca2d1a1234518056e7cda11d800997afd528bc0c1a42588e7a40575072d4d59896402e1eb7835a04d768698427faaeab8e113bd20b632dd0fcdc0e949ee90f860c65b6e3fbcd80ce01ff902940107b9028f39f81fbb9ae98ceadd4e26a4be7790d4f91335a0b956b9959770003725001b0ff94728f0e9a897a47b4e89a43d1c511968b6135a061ebfca939986b16cd5fe6ac4814a44f86d820f0f4922b1bba71194a14234882165572e48dbe946496448a77125da65a74d725d9d6fcf16834842adf7d77f2da7cf2e1938ba5fcada934e56c0b6df674ed36ab36ad104b4aabff1c51f3b8288a40e499cdaa899dcd282c9a830de1da181802b93033034ecfdb2d1a53811279f850e8ea7de89165f091090e6307bb761b36aa37bdf150ab7843b9885b78cb23b8d024f8530ca4f3d6fa5aeedcd1946b639f9dc625d46618e6f3f9f9359c8b1036ee1b51e5d539ac772f210a65244e4d7b970447b44507819bd1b6788e4c69086a3f44a14c4cd06dcedf3104806a5c28fc9658eaa473a412d4e8dc1a04620ce71024871ff0daa005052055947c9a52652db415b26fdeee357294ee353a2611b95101fb45da4df4d64886c06e7a0cb31c9243fd8ab231dddd0be3acd2c11102adc147cf7eb3cd68b1791379a51ab8c0e95385a96c27287165402a3d2cf1cbe2188e6f3d22a69715eb1db36f53b350b6e0100aa2d14ad53df4bb72fff6fd31a2ef3beae4b810a6eea18dcf109a38712a8569edfbb116690e21164d5aebbd6a419ca61ce73df3c1b5cebbc1314669b80290bcd6a20fb1b4b6b14a2f7dfcb3cebaad5303a4ffb594ccb460c323cfa0e5f3302792f8d0979e4a590056513584ab6aa8b1d55ff6b7604fec4f8aed5b5e1575e84eaff09a29406ad3a4117f954a98221ae3f04e229cae3472d4e224d259eb7158a8b3ed6a6acaca79fb9206bd50f246adfdd5e72047a4a4fd7fcc26b3c44d9068533efdcf4b6d61a8535fe97998d5109fdff970611bd4f1aee82b5ed6ce49a1f04bb2f907aa6b9532b42a3a0f91eb50207b91eb0159fc1409a7bbca77177900b39016df19c0f46c353a35bfffcdb80353b73fafc9bea36bdee989c73948f3a4a3b9e8d26593cb81bc561fefb583f8fefcd6469221dc055f2df0194c3df5d48b36e2184a315e78f1ece3c3d4725b802e6d8d06af2641f566b94e9c0a712d24bf67ff281456600afdfb6fcc18787b5c96907f3004fbf72e43a02beb93b512fc0722529ce0950e5521bccbe8639ee05a9e45d1ab20b1e7c40840f2810f2b707b66d349b9dbc62106b1f254dc0102301c4b23a44cf068bc89c17d78eed9f77902c177f68899faa495d550524bea4e09d3432c7ae1b39d66933d2a664ef3487d38d26952cf2cd90f1b70532e14c2ab90cd19495f81c7d3f4a19fac8f0ad08e88d789bcf1073d6ec2a7824b451b2f2af157a42ee8fa5f23cdbc8ae6e215d16c8e1fbfbb475c128cd0e1551e9c22c4386a8286b7bddd235d258b5e82d49f3f040322328b190db8b1374a3a229ee0e1b7ad2bfe6c422ee2564f1401bf2a00935a97bab04408e4951900ea04db53b2cb81eafdd9065117f80fbcd4d37414d2df219786badaa60cdb416bcc491b1832de649580c939d8a2b705b6d32a151826d2062a7f351d84681b62ec4dfc4fd04eb7633e0c024665a9f1bf88cba48db366aabac4876874c700fe6aea7d6614226c0a581f42034852169361b9e67f0c1ecd6e46d1feb5dfb555a45a21cd71202665eb7cd6ae2929e25ccd6dbf4a1b9007b8a61c77a0aee2f6d1cc0499bc757e08039a9f28232706f6400c3a699e5e0bfa1d1f0251aa09c9aa44697f026e23ce9a65adcadcd194b995373cb81b33c8b2045313df022a25d20d3049e9fb3ca3806bf9b8e327390e630ea9a8bb1275ae5646d927b0572488ca49e292cbad321348e224f8370d1ce6704f04d2732fab2a89ce62e3d277aaf4d96600d50ba3ad2ea8d24dec162dbe0e74c7c5333940f14d22ddcddcbc419ef46553672d1f7dffa8db0b958c891c6f1867d7f4d21f6724ef09de7b240c660ee0941ba9519ca0a623974742ebbc628fb9ddeeccc3c7e7d56d367e20470d5d80297bb76582549c9755237c9547c3a1e8db4fba235097a960370b2e9a94088134cda7aaca4a0e000b78ff539e9006b7cb60f9c1c1e3a6ab1b749e56edda8966f21e4b5195c1caae7757fc2d81df17a5b76005fb4426a7bf1d8299e7d34523ff0f98aa0f26a8be5561d3905e5289e3e29e8b3fc998ac8425ba953ddd33e2dbe3eee21b11ce8b368d872b301a246a8df7804dbf86648d562128ccf2acfb74f438373c700aceb02b24e866cec2547630217c3b7cce6abd8b70d45fe22ef18ef24c559d51905a9b707746c756f9e250e967774a84507204acb3241d568903a665cb1da4d10353c001d049285a4995790a40ca1aec522ce8d60139b1a362fb4be676f1ccdd9f753ce5e9889f5ffbacc98ae0db35ec09a9e396d3e58fb47c1731101d37f05af434e5ee54e8fb35cb4746d3b79e02b72bb5e31fb10c4d210f9e06322a762faf473372f6c773a1d7392bfb61c795ee76a90cbddcfa788de8e36658d5061525e76ca8e41c3ba5a2c248485747fb76cd3888350f967c707787f28ae8ed0c8cc105fbcb014b8f492e0f50030583606602790d92438f28bd704635cd1e73a4a330a64b13cf6cdca32c0a6d9e67bff7ea584236f173944d0237b93b7beceefcce94d6c9aac423f8667daa45a7aa7498dbd5fc58c79388d559ec7c29ad265773a80256e81b4877708bb79276c8559a7d7bbff7a56dbffee943650e5a2aa5fb91800c34d459d8bbe910677d316b9606bf74023dcce107928a8f31338a01cb62bd20003ae3bb544b27d1e79e29c2863c431058f8544ea2e0d47d190b25469a75dcdad015b43119e0da66587b5da59731d464dc0c10e6e24d4a3d9318746908c4c734729e24ab3ddf474ba2f333c0eb8369099844f3a60d4bf27f954b10fe00941cc1f6021b2784a26b203de063ce83339f0ee60cdf2f7f5d57933806e5dd1b2c08a40af10ec5db13b589411c5d2ed85784689f32ff094c5b50cebbbf7f372374848a621f22588156c31fb8fa3cc7432994f7c80392565ef9ea010d2741068a1ce45ff1fa66e949de2588259d447a006d1d8d7f125f7031594169c55eaa1c86ac6f797288749a926440709c0484cb6a3c3a4b829d4170d819d6e8c816f62cc126b09fb08b71f5aed5aec37b01ecc00a37ca435d812a5ea4ea4895fcf5ffef6eebdf7f4d05708d7c48781b2ad6bd8917bbeed227bddfb0eef0e2ad4e37a659d438dd84d0e0d54840b0a5b61a156c1da1025e05566e9dd4a4d62cb8e04145ba68cc006ea545acde5f16e80276e713446b822ed6941ecb300f776a04c42fc997e13bf1ea1adcf22c7371b162a95e2ab22c650e3e5d13b664ee14445d550155894510c2306d8833bef60bb1eee6906bc67cd4143063541868714c6bcac95fcc9804f3ad44e9305fcd12a0eaa0fbdf9898614af7ba6473c1efd5322e6a4f287930ebae814ed3e5c2e22aab543f8e0d9972cabfa18576ada3b575fcc2eab56cf3dd92f27d83f7270a9e7094c61350720243c63209de1444c33fd949a3cf576d79dbcc6cffc1ce4037c21613de10175a42f07547453ceefbc9f62379eb92da2ea6156231124c932410908aa2b274186ba52294f65dc99e62d20988636df16cd45098226f640b2750dfa660ad9f4aba12f6ebd8389785dec61cb1269edf22474568ce635329058ca4cbe157da079a2b9481b437d86173e992ff7ee4be04e88429f6924ec14643d01b968d0acb317be4134f2fb6bfcb2af632092266a4c1d8b7446ea6ff4acbec93b39cdb615281b9c35819ad078651356f32268c9a942bd51293db4887cd7fcd2715bcf0d793a3098631832f8f64a022f3691aafaf530b181c4bd44313cad2ded92de7ac73fe2994fa71062b0922c9086dd310723f801983358049e70ce5234d777820f619e37028e2d5a2bb05a016859e236475f6f88f4f16d09b6d30cd6180bd422185c596f374b1a04cb95662d445f08a855c77920e5fb8813a9a83753e3989fe663d5014915c5993c17cd62b77dbd9326f21fb6e8a0f8a49dbd893486267bf53107c6f663f8dc9c248978f16148340ca1d71922529cdf03fd2348a26b4556b2a7923a0916e7f86e355861c8e64c9610f1a488f34b850ed0821ef5169707bba56095316efc8bb30948800ccefa885b38eaf25714712210045c3e3d02585bbcb7ae52d33b538659eb7e6ce2f2dcad996dd5cf7866e87fbad84ad5a87f3a7b4218805a995a6f6360d3dcbbb06ba0b023a0e77018ebdbd065df51053a7935d7ea9c4e5db60f330ecbaecc22458397f3735f0f79fef070c0b4e2e0f2b215eb6029d226aaddb5b4b2bf77d79252986e26f0417471db6701ca92faa4a2ef3e3145f9a624312106a72fb99a9469a63f74b32468dcfdaee6f8eaf748ca6c94700881d273ab83331713eaf9f06812c55549cd657b345c194d34ac78685d35a50ee126a92c52ca5d01933890f6efd9d681fc9ecff8b09680446e9d45d38fdbb785aa253b4ed12f20e69ea4bf251472c0eb228d5f6676f2052e4f28fe9bcf4364327a9b83836b99bafa4370c8994306c26a36bfbc6174c338cb548641e28031201904cef85e9fbf0e78b7c37de6629832a991a0d08d80a3917bfbcaefbfb3b4546f75b6d9df4b28e0489220303a0c4d50df9a90c24413c9155b971122d01b7e2a734de77ba30967541e403bf7a8ba0496b819293a2da889cdf1666dd168a0785a3434275a19e08d7088c04e2718ecdd0b48a58bc9db77b0238a9cddcb2451ef0ef2443e3e76bbce3595656a81dc7fd1687b96621704b746fd29a093a819b3230cf2e573bd723f841d2939c816d1058b6115361b088e824bbc91ee57ef2010a566b34e3ee5582a33e790dac33c1220e58be0786cb85c9bb9740c24b2061add8e08f2e3d0e8c6aafcc0198a6828bcb3f4d4e0fe3e016f79097228c4bef0956e1fbddf7d486626e19c07f956c10fd6cd6e4ba185915f8053602be1d77da0dcd1ff30b1273ab934b975e1266676dae3dc91e95bfbe511e3287d37a0eb9939569206038a3d0862ae64ea6b71216aabd153256ee74ef657c80347cde77aa305c2c8df62b642b4acdf198cbf024eaf75d1837f8b97d0fb3f1502d24a8807353e1f17d24a6ce4534dda5ac9d9c5d9a22530d96066b415888439cff59fe2265a86ff4c4eafb7b186fc10f82402cba93ce92f04a29d706a38e3cbf648dee5f365ee1b597e1c5939d7e3a16a7e95291138afecb1ecc389d41bcbefe1afa364ac4f7227225121a7cd7594d2a95468c1aa9f747fec7e0924432ba5b601dd147db89a3cb87899294c562e37be9f2c2c55d21fe6f80f3319b6e2b22524dfea247c6b15bbddaceaa475b7ed7dcf396a2639b83ec09cc7058b1398d0cd37f85157d134ef7f7393c849359fe0fbc93dee0e16aa96738c810f1eb964fb46fe7c29fafd8e38292bc08efc6ad6494316990af8f16dd689765568c48e3ceb42d86b509a2d1262085a6177b9e67e92efa7eea9f2fb06be07441cc1cc84e250f47b98a095adc7fd8025f6ac35ca9daab77c5e937b62d446f2d200a78031628cfcc4d39e2420f5c2e23c504733dc3364543fa61cb599858dd2d30eded923e870e6adacd445f95d95d111b6fa708301f7ee43ab4fa9c9c90667d8da00e6c97745dfaad0f94e3c5cc3985a3bf2e41c0c3ec19a488b19027bedaa6319c1e23701809511200452903c8f4168b8130dbdb68796fb77d6103bb9703c07fce659226a995bb6c41fe6ffa08e8254d62e6b1d3f1a0924edf4ebb5dcb59d338b26a104d06e7a6c1df55f2aa0df401a59c87a51c77b7986f1f8a692ecec14ce5047c2b2745ef4a91c2c420a1b2ca532a9a7745d42f89709b8b1febd8cac28ce6de1baf77831f3c845a2df0934826f8ede2b97bc3b456c8f254954dfaa3a189e91ac92efd74607bf57cef4e24659211715d0824616390d975599f6616e9b048a7daf56bd55c60a3400dbd8bc6788bd8516331751afcbd6c49a8ba3ecca024a705125c41dbc09654845d5ea612f1ceb85d2fe5abbb9062ee237ceaa7a4b1ae15445870afb21a23e57a705e6bf293807cccb975f558c79071a09906a4de7a9d31149a8e03cb3962c01fc6410eee4b0f7641d0584295cc58bc5211da1a8f64d5e262f0b10f75787e866c543d495d412ccd475ef706e8c1b9ab7becd5cdc143658d04e89c7d60e75d234b78f4d911c03a4f8a49b1c8462ff05c7e987849343e6eb229f6d0bbf2870707cd93e51cca458a4b524f60edb707a9c8199e8f0190256705b90c0f431a1aeb85d0a94cc8135f09045e3ab9442393f7693952ab7dbcb43600ba72fb80281a974333278fc277689ed2ca3285175f5b37d6b121f5abc302bbb211a4c4f3ef2e450fc5982a0d611e4756d322a9375e37e3ae52f56cd78072660b7822d81349655a986be8eadd5096f4156227a8754c0334cbea6059d72ef5e547d13aba440d67e4da49c979f08f59ac6e422ec31b3d46a6c675cf617a646f40b24764e254001c2f5b1159eb445f6653e36dcb04faa4c092af1015c7b70b76e5855466f9519f640599f173d0d7a602e50e95fdf56301ef39f43a0fe79ab218ba5ca9dd139b53bcb8da5465ef1fca944a17a0ba2bd0726c64aae4546a1fd945b2ceb31fc605c662a34f716e655fd899481046ed60e9c55f5fad984071e72300af85621b266f3837cd791d32b0f996ccd83d51d21b88dffbabac44b2cb8b1745043318468839bf59653791b41b85d6d395263e09cccc802949b83b89f30f73577026386ff516952b3540dda33b772e1c5975ab96ef02855cb63b6b19a245b8c5b37ec0faed36a04b0cdb23c86791ed45a4d4093816c522e4560863e5d1c7d9ef6218579dc1bd1bf416b54afdf080963f0b46cb33772d30b85137a02cf8555ab81726ca272a879ca955bf23dd97da9a757fed311c890e63796ed6ecd791b6003fc55d5d6a0f0930ca00357cb5c76dfd3d2ef8ed5e6633123938705fd5af3070aed12a63ccc52c17df95524d1730811328ec7d6d00a38d143eecc31c14faf3796718c7c9aed8951bf81b1ea58e17220adc541bd5bbe3b21eeda517f672dbc057096216175e718e104886782d4998aeee5d8a480bbba5cb06681ac6216880ad7f140363d33e349f9da331b29633c27a4f757774988c9531d8dedd1460e59e4fce847cedb350871b2ea52ab07e565d8373cfed05831cb9f629a0150eb609c481738b9e5e45b155aa738ca29f5e72f7d21f6f344a289a7ab664a2c5cb5aac74fdcd24c3107143c61cad3220f8d114b17d8736a05f551b9c1eef4b5ffe35f28cec299527f4f75a49922b3aee585e0460754486cb2ff6a6f67638dac7ff2a106223924901c1c101071a04a261a5eabf9839eafdc47914d19df4a61defc4649981ecc036d84cf53f959f4a75f36b6e278cb814e835cf0a80d94deefa5f62a8fc4c942af47362aefa43387285e63b5ede0769a6b1322d305f792d597b7febbbd020ba50ae0f4bb0549530a7f55bcff892a275b2b65fd9d3f5c06210e25c65ca69332b0d6b2cd76e75c6b412a75c015594c9e8abfb31c18917959bed163180679d020b16174e6d3b8b4049b33e96ceb46f285f6d3b4329104a27dc975a6e191630999b072a89d34bc7d0c05ddfddfe54f84cf2facccf0cbbc6fbce52dbaa8d86879d83d5354b4f5cccd924667273cd2542986b9fa4e85855c1147e58c5107fe6f64a3ff87138fffd2086a4a62b01a154403a96fb29a6135f82e7c9654043f086c28c9c8d80f426bc333aef3a9a55b78e3f59f63d6528ffeebe9c1ab99d0845a500f1f75e09dd5abddaa4f0d45065f0b2141c88aeba75df0e9b3dbada712939bbd49d0a3071c1270a547a498ba540f61534b1a64ac6c320b3903f71f79800f05c4417398a45cc51bcb2bce04962218daf1949a70b3044c29785c2566d5026a72a360252ebc2a0530286854c2ac50155c729e8f8dc9474425adae553d83b28ac5d7b18869c2fc919134411d679f82984a0b34ca49c988d52694c4d786280825e7c962a9de2459fdc057f20a57a488061f3558005f5b901a726c783c04eb9d3e7759f0bacb20c45389406fb23b55a7fff692317c6f50a8b5f7886314aedfb8dbd4d675699bf57c22841a5abdea300d6180590b65dd381782d4062f4442cfb7041c69b35ef91510d505250bf55f5ba77706afbdb2caeefa9599a9a790077946031b8a8d72d355b503575801e9ee7d81c661c3129a06d5c665d4c43af67f54c3bf3d93562afeda786f2e8d35dd9fa3e3f5095c6b6c2c6eb117c3b29334378200451b0dd84d211e897691d8a3f58a3af7c0d9c6f6a9a7cc11e21451d2873da3c494ad21534416da530265b7ffcf8634d818dad8fb0fd577f7de20f95601aba5b622361279697ae2e6b73b6e204fb1b6c6818e8e7ff1f2cc7419c3e2a43789dbd92716dc52107e4715c0549c5af17608313a31bbc904db3909e670c47570853c06ee55ef807ba1db42c44b9cd3eadc41c709d40455aa368ea5c49be9082f131c73f765818c3ce97e9e14a632ecd144525c753ac3bb6c3628b2cf85992ee22ebe2b73b8b6da73281835e30b17fa28c184873793c93df1ebdaa73cc52715d093aa85d8c5275b66dada4eed01f38599b0981fd52e19b0b4f2d7437ade3d6b9873414955df1c7d8afebefeea2611886a27e7a6107fb1980b1e359f2cc151135fda6a8478432eda454bf91e89c9cf256a659984406364750ecd8d1c032ac02018038003dfeae821b422974c0132584472723d85d1022aee450cb288bb994974c4596c06789d48a5959743d65572c7f0785acf730e4eaff9f1ce5204772f2566bcae6daf0eebb165aa26278dc55c07e46fd3da345ddb6820e883153191951cdff1cd0f4ac3eff3a1d810c87adecb36b6f14dafa32c879e5606dd785634f22adaa1af709f6a65a6ef885f54e670b3eaeeffd8d1c34d530d49767b1c92bbc062d8408f2767395ab81dab02e0f0601a62ce043f3d1a994195a80f90fbf88c644f3d4044caad7c12d7e4771dc7f8badeae79e38200b151f575a4039a3678e1e9d867e1e6afe95a25058dd9950744289a0ba0449f8c9b5ecbfaa48b8683a76c5c8004c3ca56d2c96f445d3850388889c72074ae98a1b21340a205df94d7cfac87be2a6b0e6acf40093cfaa947b0f2e5da38b1afad7cda3ca115f1bdc4fd3019494b89e2bc5cef2db743d3717129362a2f881a6fb2bb96fbcfd405550032d0ffbd41d14776c6f22d9c314a64e97985bb3c0f514776903f6365f1ad861117843b64943ba4aab749df2b9a4a76609f4479b882304f0345a91f391500799ba25ae684a8745afdcd0f50022e8cc7bb3087e2b9c42158195811146e39199f8706356dd79a3f71f2867975a00dfb746148bd5f71194e4a6c247f4173b8dd288fe1448c0876733399fefb842059d778a5354152a19d232c51efcdb2096f2cdf5cd87ecf8718120ab086652551d1db1f7f077381a5c1c710e6dc8e55fa84494ceb06c2138bb8b849ca76a3219a39175e64c850173134ebb7eef75dbc8b7330b7bafb4a526a986456d8d742b9eb613aa3aa0aad346d6ba8936f0fe86b856e3d4ba1651fc4bc7ac296b07041f7ec0f740cf3be401db48f834834d266a14e8487b6d71ffa6fc5d0e4d2b55196c96228ff761cb83cf1e5f27a2c4f3cff45f496904a0c6e91e704a2c3d7f3826e2a1944be002131c5fa8f945bf93168fac6dbc30606d684c8f75ea76f3b270e4911b13d00964c29fce7cb60ac932b8310f96933a3389f4206dac190fcc55ed8313d6aefcfa6b03be1da9a2fb1f9e0e40928c15f4b01e71a3cd1e3dde60768b957d6ca99ab127a4d73a2a4775395c9c8b46b4aedb0698ca539bfdd084af5fe57692640599dadcef40aaece6f25f282b0de5713fc1a6a9511bfaa139c8328fb5d4a663f10bf59741083122a7caeb5f8a1c8b65637f23a12e7e3b6ad093eb27bd9380c7d57c6faf57ea01f6072f5530595951adb366fc5bad032ccc2057f01eee82865f75b0af65ccf0e36cde77a894a289a426eb11d4a7e15e26a261ea6c71a9d71f3b7096ad2765fad204dea0190ed45624c3ca3e06d2a0a6df31ef11b5fa6190fd625ca477f2cb913dcc1bb69497f91d56ec5275e666c98dc4c2f22beffea464dea62233d7a6013b9bcca9fc0584423c8623c03baf290f9c6271587db0758446e07ba18bd5a193ff13753c7acbc0de3593916001864233afe37c09a36e417878db0b73db11f8130b20819d0f796c0fa73db0e8313aab120de1cc72d77ba97d2e1930ef0f219c508352a388d49001061d49756a772e3344a1eccef63166adbc2fbf1b84ad8172d235afb6f8b6315a5ce0bf7570f0122bb6bc6bcc5c6fcabe55726a54e42abe3083ccb65ad9454d54195ae0b6e4b48b9178f2a7561f356cd5478ff1316a93ce375232d675f0c25c22b2d640926c946d78332cb720fcdff336ffca384375eaaa7e40b08c738493cf8b2e2b07d8b29033bcc3f3e785deddaa9f00ab173a4a730eccad7379fa88b21fbaa5bae33e786f35bc6b22b5a01e62c80bb0dab81fd787f0c876eacd68028131f819c32361bc5e7867e342e06cb87cffa3c0838acf13f2876568e9b53866f888a0b9c5c1600e56dc950a8b038875014b9955c2ff83d49d84b3678eef89a54d944a1b3693a631a5d36ed4bfb214f9deb764adba7a468a7fd40cd384583ae6dc546ef08d8bf18d5fdea8fe06dd93ea8cc51aedf5390b769bdecd1e1eb3db34a87a5b9a5541d71de01f26c93d2d70eb892a607c17b7e0a1520396e8a190db9244ef73f6351416eec49c4b4e241507920bc8e3ffe7c5cc6e4eeeae2fc2eec9b9c9e095802ce5d85cca9e84b6a060c95064f0f6e10f1b8f3185812fbe0145d39e39669d48d7d462aa2ca433853831a265d8be074a8829a681faa5fdca03629e384902d62e360cde06e7ada8734c8675820429dfcfb159cd1f26cfe4129d968faf177629eede664d0e5b36f3b5ff91cf43a1ead4642e3ad0c8c33788c95bb6ad34df6c3495bcefee799acb449ce6668f5a7017b3077ae1869eba3cad158490018d66d561410b1ffc506cc32ee3ea78798319ae53ff60b11c1f9f6a625c88c8e8dbfaa5d57f1fe71339826ec9f31c7458970505357f9ae59d3c9a5633a405b065226d8cadb435a69459c00bebba39a7c443fc74d1a4fdc57320057cc4c4bd53da12025f63cc3997c7a85353c312bf5e00a3fb9ea6f1150d276a673b5fe433faa0ee2f0bef0227c3d874d50aca1f9e574bcec93d26d94a368ddee3be6affcd58d48e9c4ee56a5c9a7f8ccb93e2f522ad2d692b6663855dd7304a95ac4c6b39752f14caa7a87d27642355e3ce5f1ff39a786dd9ea26c314c096abf82ae88185b31ae9e69ed89ccaa02fb5bbabafdd84f8c8f72d9889feb807e26b0753e1902fae73077ef873cdebc40cc138225b240f93030b5cc2326f824d34946fff32de802195cd7f2d022ff616a332f2e5f80be71511146050b74d55ff0e3f887185b4f0f65aebf85e2ca23b69a67396eb7621fa0cca1522c53facea295c879620eea034203e254dd030d4e40c1b4c45d53aa9ee492f7cc7cfd3caaf5c220b1bbdd4225215fc07f3571381bccac0323534a3d07feebb58f0f27b33c82935a79056a904110d15b381ddfa318a89b4811adf275b3cf592e1fc038d128e920a78c7af70a6cfcd5ca2cdabc586858dfd3d5d88d9313f8a05b6868f45d0b77361570874ecdc8605ef7c0afcbc70a55d39ed895c18b9899678a14953dde83b3541c7f8b6895aa417f64bbc4b50e37a6a8a28a96c6c3695429e458faa5a697d83c352f32f45e17b05d20e0c787c81b3bb5fa6044c7ca8f08cabca1b0f2243cc830d951f39cedcbdfbec3b6351f1c86c337205617de744f9cc4eb7aeec2f1643b5a41ecfbefc1b26e76b62118f2df7ef70e51aa4e8074ef7ed53af90de3072eb83f4aebdb73d2a513df62c0f60039100ae6c3f5dfe3f5900e7d80ddd6e0b6052a11e752236b3157f5269e95c41153a6b06ce754cc5321973bfdf8deeb95f4d7db1b546cbcb4e8f902940108b9028f39a086b990d43e5df69dcf9b3f772824e7fa08031b1c8f517d0ca3f648945c3b46978f1759e92de206f6b26a7149499a9725cf6e7583871534b8df396cce65232d0f3d4b97e5afc2ca2be2b2679e8ba27b564cd9a9450189de59b48d6262386decce15ba38c99f3097a979634e8395d7ab9f51d00c2f82b97ac270e6d077923902dbd6d5981e89a720beb63d73f122d92d97350ef27da971b22e2ea6b8f622b92c3eeda6f5f6e6f0afb9d770fc76ed4fdb8049b104e1a54969bd6db4ee343ee98286e87cecf8f7a90665703fea4d7cd7a2ad9485db727a563ce5bc80ce5229f4635353a24c8af6e37b1c34a5a165c445726cccc3b49747d950d9ad5f78ad3dbcda91ad5f7106d546d6ff5e0f24c8898ed1b1e99826596f55521d567a50a840485685563044fdaf400a599a5f34714e552dfc763a98e6e52baf3a7f834cf619dbb7410bef3ef60df1a2251b79bfb79b7870ed3adde22f2027880198493ab81d0276a4421bbfe52311f0ac5d1bf571218db62947af714989a56aeb59e047f5ee0521cb6d15cff6d7ebf625f5428b9eb66479171a6c1c93bd9cf4b983ceb87f18f12de96124ca136ae724e66de39fc34b3c4d5851e24ac4f6c7badab4d13575404660aeaf7526dae3d23e1796568667483a7337b4efc99f67e733c445d89b5b5ecfd053347e9ec9c915d47505ba68e0baf93bf725864da030ad8cd7f51d92215269da248a1f8a4b56cc35848a0d9b71e3f0ac9b04beea9a6ae78d99698a0706404d116b474a7de3785e5c2f5483c37a9fd9c680e23b3b5f067cff4d71ee1475bba5e33cdadc5ceec3005f090c777860b5d6a9fa2bd6493630434242d3f44fb2e7b8d531d4860c22dd91e6af5929e92ea86ca4e8611e4b64b2d35eb836584b2219cda656104258dfc02af6dcd5df779b20f91eb50208b91eb09e7d24e3a8020a75c0e9f208113bf30ee5f405e53ee4b8d45a6b3ebee17f73c75b54cb937ddfd7ffafbcf1f0f4a250a3c11d091e29acf9d655a934c07d59d317f470cbf7e1fa5921c59e2737096d6673142cc5440f3a644a5e0d11d68e5f4249e36e056449388c492264b80eb361b1a27dd024619150709645895b55dd6573fe68d54600b12aeaaf0e24cfaad92350d82fe19c3c4d10c724ab6664fb36b2cd0ccb954c24ed042ebf528179cc7c55d9edc540217b068f04f8dc688d0e3f78f034db3842de06e4e89191680bd5f13bc3ece5d0758142086c0e92d9200cdd47f28dfd6466a978ce021b9ea0b3fbe2f2fe5c6ef31906d261fc80a0a561d9c054cba9f1e503002508a56fcd27bb67acb57a1bfe53c17943a391e24c162c87112a52ee429a8967d3827a69df6610ce379463b5ba02ae0f9d609fcfa520b3d95b23b004ede64de0adb17708748cc8ad8ce9219e2bcfdffb7baa8cc70ef4abaea00755c686e754a02ba5c401418888a63668420badac707f9964821b4b48f0c5ea9741c3f201c1eb83efac3d947b723cb9934ec6152e6aa7352f2495ac37dcb4ea781b08d4a8f46e6c09c60d42215174a785cd7b58e6d9b66c4f88272e80ebf03e461117c3879111f89799fa7732c08fbee712e3b43c0ec84ec0f56e3468ac19b51ba6519a20a1573e031835a016b78a9ce05bd9ed8e8a4502fc5df764906677bc4c578a59aaf5771c3dfc3deb52b79c24d94307b8702fe0e34b8c5c7b01c65f7d29db44352d997a1ace1f1ebf288f623264a7e662834f439c17e113cbe21ba288c87c451a32dce52e38e115d8493a36ae4861620eec54614a10220707ad986c55efbd230ad0b7b854a5b5ad372d055a57325de313009d8c11afdaad80eb96abe106b65f746211d87b3be44f7735e8ecb3b835974e970c065801f6fb5d635c586de2d4e9e9efeb29734756d401e1b6eb7873a5bbe8b76ef42e1e8f600b05c1457565908cfcf0af5606be98a0d79c7b992e6c14ed7b8be657ae90fcb4a0e99762d8d58a5392f0cf739f22903ba28b19949f4cb6854a313f971ef7388afff7633b93ebba324e97ebf50e8b6ab0eef825a92069e44c323df9b2465c66f2cf8adc07114bf73da2a00ae43081db549f613e080fa3fdfaa8caa689124960929655da0239261245523eb29a84b61efe15f8fa5cef2a64df60334b3f1a7e858aeff2e914b23192d408aa3b12ef660e77728f1a77a1c70263d4eb28b36e6fa47c75b0896c10334f916af7a0cfbb55dc2f3b586be926d473293349cd1a9ae67a32f73d09b65edc7e8ca9f53a8827b4426ff9a61b721ad65caa691f471b481130b404a4468236cf849e8e627c15e4688e7446483c9dac97fcf6bf2586fa3ea9a4e984999852ef70431db4880142ed8619f82b81e11949d186529eb4868435a7822cef86d9681a57167df1fd824d348fc21310971fb38185aa60d8193b67c26f4379bb95722eb5fc1d39114aadbc7909a2c855f63abe52ab80fd662fc86c987e96d2a4432b687182d008b840743d80ee985ec5879b969198b1cb3cdcc29d8b16df52a200efd94e3bc965e45e6537a374cb49ac33c5dcecbfead9320c9e7192af57876fa5e30f7af832bf7ccf66a164dae2607f7936782b8f9332f7639f32b3cebcf5a916358ca135caa307132b5479fbe291f2c5695793b57db86b64430ef45423411a260775dd2d355a5f1f710c54d0d479af6f016391bd241d461a2fe29f633b80e028e02de9f4f45a65105c9e56a898e42f7108b9f75add578194e2c7a226ffc2168fbf90ce808d1fb1e6103acc923b67675c73d980cbdc07871cfbf9931f6d4f7dbff6dcb533976e954910a771e04d7ab326929b31fa1f60f398a1d34da77fa072e47c7e41f962211ce3cfcd1d9a28c064fde218a84e3f5f7718b395021592a836042f61ad739314a880cd159dc24d9dc997c0b5cad24b39258576684a1308c199f94437ac21e8bf25e20edcc68bb002f95dc0fe5884e8fa2d14912b209d7119ae0bf1cd55229f1e9bac0048f4dd2c5062890a72daee46add5f7d1f28939848481e47385178989d8dcbab3af280b351351369213ba7312ed30cda679f082a200ccb421068da6637a4841bb30fa68fadf3a1e73a7c462d99e553784b65354ecf62771848d152d7f939014006d0e2c113ec9c1577a6fb5c9b2151c6e83d0e78dc794736329a535e17a8d0855c0c4055cd20ee63ea279f8513da3576edd9629d2357c966dc879e4ef20af78c421bcc50b7a6d451ef2848a54b8f664d3f6e8ae8b19fa7fb6a15611710cd20bc04d57de88c4167e49e3160d4db9763c4d11c4aa8602b24ff2026d22e3348155394d4587bbfd4b9ae003b5e219b6bf38ee877e9d346f85fd1e3dfb97e989298ddc5b92bfd5508639c5bdc7071b1a322c0288a81dc3c0835fe431e3ff8ebd285404c370a45490deee8c0ae470813e0c39129cd7d99b23083495c7f987c50640fc5607854a5c127b164925b9675700a90c69fa68bc59f875347e6120be05e5271ade1717a6cf566289ad2116437cbff472f9c3117063202550129b6242b5edecfdfb6451e2b8c7874c7bc11632e020683454ceead2bd5906c8c18c3f3631b67a1326bdc2cbb0224eb54fd60b0aecf74c41dc36ba814c489270de993647f7a389111b2f540301d1a2ac42dc1ada8c4b80bc9263f3981127921425f3bfe4997df6c217239be5950c4946270835a96faf6eee7a28e944f102b9971ab43c772223694e2e2b662952252e989c219d3cf32882f315863a2d5c72eee9f4f6744711508a1b7706d3d9f924646d0aef60da402440ecc8add87be47e0140ea21579c81e984621afc4a9526f5a0d7b879517687b157935f8868102e084659ceefe262de77ae520c6d1929e7a983c9a09f506e9417ab203c1f3753377b22d5dd752c3da90a840cd8a91fcce1fdf8f44847e00a2eceb3d15cf2dbc758cda251a16846afbe2c63756aed67aa8fbc65102221ce27d07cb96f321ee9311f844ee8435c6f92c32c43adc7e2d8ebdd59d33b25e17805f1bfb813aa19a858bc34b2c7fdfbdf9107890cb3730f38aa0efda40c30ddbb5d8ee96b601fdc021ddd696d962148cb926ecd026c781cc59ef4ed93a16bec50c778b3020e6d77c721f7e66be60bc6360f201934df1bff3a2fd1a5b5f68ba87d00bf2fa231a32a6b21bdc944fa6fabaf39f40145c93453fcc2f4116a9a74440ee1a6d2e25bf20c46873e0623cf14742c50a979207d5225755a4a9ee9c061b0a65609bd645579628d082a3c476d6f897c8000e79f9c46162311a1b676f05acd73a990ee2cb71083ccdbec47310af3cce50841ee32c018b46d5fa92d69a29bbcbb72b819901f2cec6b66516e77fbd79b4336dfe7978fa0642ec9aca5164ab3fd6ba021588b422b1028b5853922bc4eb735ef69ee0e70dcb418a2cf960109497a37ec44a24848ab57133a8fe9cdb78d3444f49a5dae9fb8568fc7fe198bbb6da01d20022c2deb4b599472d5c44eca580114a647468aaf166a11d48fb7938b2af38d7ba5f247951058a03acd85d075eab44c1c927bd3d8ba1e7d43e3b843448c2e4c48cf407ebce6d3e581a565bbf56f33ff3b1eb4ea383e9d1b7c9221f546e28d05f514d6cf6f02cdf38b9266a2a2c6451bfe00639224209402ac7d398a5419411ca2f7c4ab311c24d777088d4df54853bbefc6af72ece1f92f3070ab93176a696c862a694a7e1106966c8cf9a235eb59ecf9e64cd3566f7d45723af6db0552605c7a8d48b58ea5747c912431557b2bc3a80eafd4c8573b9e087a57a60907e87e312d642751855be77bb78643c72e4513b61529f4ec48eba697203133a8c16fcb91f650ee553521cadeb969aea06d45277e1e7915f55031bbc55267174ab306db8e26ced19082f5eddb64106e8c7c3c23cc2d7304afd110f6014eab00e0430e1c32e8677ac24c60b7e01700b02bbe03cdc28adf9ddd1f96cabf1186e41b2f38e44e0489566726b593a0335851c24aa67be1fb20931410d61fd6673cef0c5de9669baa29f19280741df12ff6a1f0d45696a1bb78a4c36c545c1861f387c888cb983c028718ab9f73bcf140b5ee8aacebefec42d88c6fe74c8e9eef048ec154ad50fdddde8253d2702f03a094fb406c430972f270ced064a196c4461da410a9e03aa687f3cc5a807a844ec9e74f3fef5c88bb9ac46f6d5e7706a1c232413885142af1bb1c921caa7e99bbbffa3ee9379c5f37b49202a8d31426331704d38c8d83442e2e09a80769a19ea49e57cbf89dcb67863eae80d403ed1fb10302d7ac26c8483650f72f041c45e76a6d2c6cfd4ac2eead8ca568c153230bac298a205e4481f3eb1433e2b70af3c3a5f5443ace9db6e0fc9eacbf4a25fc77e8eba47a8d8b0b7dad6acb3ac72eb63c1f2caab109a070b9f091292c184ee5f1d6ff8100763d8ca7f72dacea9af440f5eb61044e482d632ecb2a57c46c3f7abe08bf7e05055d0187f82d93b1d6529fb7b1ae443aa6191cd9ac2d9d413d0c6385e9cd7eaf7c30e4ff28d50a01712f58889cb4dcac5a9a1ff6e3b9812bc32b3a06e9253dee90d11688aeaed17d8e6f28194e6f9b2beff93d268345f61faf275d709b0b00817a7c8565425689c4a13dab5fbfbafce996bbe399654dcdd1271141b2835621d1503de516d5db04c8df4824d20739023fd7332d5e13d1458ec5ecb2c9eaf9ee4304d126c9c1c263411eef66fe535a560b47606b78e95d2270f6e01674aa776f41830d753bc48780c2bbcc205e62bef9c57c244d5cba97f844b671ae411fbb9dc9c79a185acf37de327661ce04a99503073726afd774da0606700a699666794b02fc9cc29b08deba2b52ed102404b655cbf90859c1831aa3cc0b0f8729b79cbb504ecd0109c27810b3d0e8cd56451f94ca142019170f6ae3be6be7e27964c11b253c089c4ff153425bac9b728f4137c5d4ee765f494127dcdd216f4cf46d5119c3160db353b386951433c35846fc42b27ccbeed02d182caa3156f0a959c093d1618b12dbe17c97a6c867a20100981848632d9aa5e8db10c1766bd3fcc81820d9b2e9ed8456c3ca3eef6bffeab0d487953c8da5701a5a6faf3b49943c51386fb0ac2c16736ce1337cff3a51e59dd04a7a72c9b6e69004714f214d6596abfdfe9b217a74fb860a4c29cdf5a56c1f3cbb626782f06df701af12b9a690b354e8e719fa39aaae0a97b09e9b62ac39c72bbb23fd01615eb101390b113456b6529d7dd8073a913e1e6b84e8af9015f0b984613da7bb9a58a89ca746cf7dbbb7eccee9537895983947e7d07efcbdebf13b73e1ce29a51adbb3c062d9c71e141ef6d11a9bd93357951285d345bac15949d479bfd9329296bb5104e67b9bc148b0127cc9e328a0d9d72b62f74f3e494b23e9f1e7af1bb75d5d62fcacec948ae29eb33016fb2c1315f7222732648d6468d3c05541b1d1d987a1bddae8a688020bdeab21bd2d46e0827dd9187290131b37e37f2325bbc72366e91d41472bf8d470688a3a56cc8274afd4bbdf2b48e9e281ef3a9f2d63edac4e1dc43f0a910cec7ba0e137ed4dcb0848af5ce43763b28d9af5a33418701ed9288912043edfa850b554de88c82ad5f4a4d8dc8c4680ed892711e176f9fe62e7fd59e5c7a015725125581b5f20a63ee00dfa37c9db7fcc5c05ddb0cf228d56272b4eae06f09f86b62acf8eee166efc4bf19fd975c1f496e2f9ef3ad577c3bfb5c31d1d6526661c13cbf44a2ecf360ccdef05903abe7199b76c416e9273290d4ef69c2e112cc2e41a01ab1bb9b4719c4b8f438c33d203c563313ef244774cd8e9017714573c3df8a5a74e54374a64c6739bb7f738d055bde89da89b149071c8d752b72d1934dbccc7bc680d34194144d2be1dcd4f42d56c0f251f92b4d785597f720c1b20883c0bf85721ff64c7ce6318e0424c15bf48d5cfe54de25fb6ee797eaa36b0b7b265a2f2c283ea60179cc95e8f950a2a141ea63e0ca330ffe78b9f4319ddb2e459b35ad8383f48bfb2785571f5ed6853601433b945805dc3ef50f2470572137ce10d7d622a7a024595b2fb5b1819628ea93670c9bcd6e0eb828bf9b5652a6fd9c379b14b16a0adbc752593883884e2bda7cc1869a1c2e5c7744f54f68c23cc116d75ff53d399daf0bf6b46b294d8d2a659e13275b04f8bdf0670c188b9beb55ad8eb222f2b65774a786b306379148845347637f1db126c43a7a204dc67e8fadd1c5ca919db2c09c1eb06f63b98db240cc7be0f831b8c0c7881eed541b33e6b51aceacf82f1ddb5c8e690cd9d1b3192cd33596dee058fe83108223f4868a9aadb41544a3049b38255ec9253f26b2082f41f62a2fd0989946eee8fac409a338036127e7965ce6aa553a34c54a7d71791764620a650c94751c8f27fec993818129b480b36195b4695950a159c8f44a2e5a94f0e9d48aab9b319c372c8a41ca6afc176f7e70bcf6ad94200c8eedf60d251b865e125017d9911e6d56141ab6ee60bf23843813ac7a552dd1b7a6a6c0505277d7ff58187430d601e5b98562705c2897db2fa6f7f8953c0f56803137ebc17096958f629928bc0fcba8cffbf7feac379db29a1e743af847bbe944ad986cbff24be6f0623e773c2a0b605263ef37e17d93912f3496542fde522ffeb92983e683ee98e3434b58ff2052965631c8a0587bbf95f0c833e277d22f9c723682b88f16e6a79fb4ea928d545b1b1581e48cda54629ed792eef04319ff8245f0d5cd358499fa1a89a3801f08ad94151fbfda858a825970b9365a4d20b04e637b814ab913cafb5b69dd9c9e85694dcd32db877837e345692d70c1e7c46093456df9f116bb7b9480282f5c90b262e6e547dd6fa0853dfb038328c9e27252cb753d085f29fadf86f6c0dbf1f091e0e033042647d12a0742c4383dfccca8de661420153778742307eb21036d3ad4c06e10f0efa5e23cd87b8edd789586395a69df7c633771273bad8dd295c9240dfec8a1c40c5ddfff35da0ecec2e90b0726053520e644c533edfcefa4f831d38fa35004c56becbc92cd79eeacc85856091a7046f56fb89105fb0bf623ff02a44fb7f303ae04960c4fc64b332be9462e1c6b904c75952a60734c3917f3b16fc20e1a6702a6613c341adf943b93b3c4d2ff3d1be5d12a065c0e97858b98f133ec3d4ce4c3d1e1f6ef0f472985f0afbca90f9d5da623fa3be12a521d45ff131641e69f507d927013314e2ba96f7a669a47de9457ccaf2d2a394f5ec7f3e0c589987e070501483d1aa96ad91d989d455d271e77d13e30c746f5534ab140f66e66514d84dbe093a02405f0c32aef8c34c9247234c89a83f047ac67863bbb0b1a7c8b1ffb1bd943f9e235931d226a8f54fe709ec039a450c1c06eeddfcd488013154ac0a71e540197bfc011752f10fbb02449f48c6b179c814e24bc9ac782607b1685cf16f90ce3342394553c774ca7951aaa551c768616c69ba50670348ee0e7eb01c2210c0beb3eb4c48ce5749e9b35331932957aad30520d421c202da3b24029161f7d247dfab3405ec7cfbbc266a013ae41d0251a3f73c9639e2408b443cc7e65e43eaa70ece8d11ae3e12169d4f784a21863dfe27b95899a1bbbb6f038caaef2c42ff00b9f7afcc9801626965bf83ce489731cd173398cf9fd291aa4f57d639ba82497d43e521474e5d4cf2a39a42c7a850275b7da5273f78fdf19c83b429c9f5829031358a4913856d005e753fb80aac78c3cbd08a7892e4964bb2d3779b04d1b5f02d99dcba8c170d27aa07df36872c9c8cb06146e2a3fee436ad51f4e846cf5a2b7b4f49b4d99e5e7f6420a14625841d8045ccee3262c27e45b7ba3d386200c2d3811df64a6bfc1094cc880b1c9d8dc8466e865199bd998750d50b5ba941dd0a6ee2b4cbb6b52d3f00322f9b46bc44868c14d7c64f7a47d3ffbd6bd992af20dec11d3350ec600419185a28ee5d24f09eeced747297774d86a83eea33fdd83ec51361ef9b75638592ed8c4d96f039c3ad788cef8104e715e2d7977f30c3698186825368a446eb77d36064d6a2e3766e190f2499a439c503f178250b6463b42958834992029c63cb9e79136512e3a4446c37b43d08cdd82a58fd712cc870bf7427802593448f4c5fabc0a033e34ab173b8c300c5696a6c25e9a9a1bd7c73b1c070895baae3e108b15fa787a373648d9cdb05891df1f5bb6328edf7e5aa554d44f23f8b39d957a93ead5db4de534265f9dbbd9d8a3e74c905bd34da0784e8d47dfeea85ae948c1ec1c694f4b2cc53623a58df2b20cf78286f65ba83ce08c787a1e40f88877530dd45fb6f3383bb56f283f5305ddc01ad9d28c12295959834fa1c1ab0386e881413a0cb7f6b71c011291f7002d9d81e1eff4761b8faed4263c87082aa70f9826d4a8247e7631587235c3b5695f3afbfd125b4848b9d86c026dece4bd7f6bc6c46de958d1a4297626ea98289e3187f671be156e482fca4c492161e13dd16037e473145b3e6b6a726319743dcbc168a2107caa62a2a0ad9ec505e157339feca63db6ae35d6899bffcebfea72f647377282976d3613e530d25fa823ce98ccdbecfee2f6ea6d65ecaff22b908fa1ac6620b2da158911ea6d3665cb47295c3f1e2f3abb07301432408c65d11b14caeab0fb76a959a87dfa04614755f2f0dd60b174231931efc49ac32d7a924774df525a395e249c7a0f2a8d8d1e6c9348acb3e135af40d63492b4333135a6eca7270d821504ebcc627f2cb47e595726fa104f17f3755b8dec28a53e9e654b00bac68bc6ae9c2b92c8dfa4f40f2fa0df3b3b7a055e61f716da677adfce82ddb2857e4fe587b082858510a9e7dcfad24d30a45492d496fd8366d1b7ee4f292f662d3a1b6bb660cc604d8cb2a07ed512e7c4668303db7d539ef45e94ae57d541f107781ae32b0f6dc6e6772ee14a0ce0066a2cbf82d7caf8ce8b42fe9a0fe5ac980394dca1a142de948d971bada0028dbd3ca5611308f529b02f00460494ca63b4266bb0d5930fad8aeb3ed96739573cd7835890e935ac91b017b5d54669eaef063082d37d81191aa037708730f41251efe7b1bc7a69656bc317d27e4dfa6ca6b47d11634b8c726406c1afe921964b0d7e2bf73a1b57c31edf29995a45ea727f7fbeb3fd33284710aa90fed6e882b005b6c45696b85c895d8ce0cf6884c31653e4cb5d8e60f4f61d3d9011b3d5761b4f4fb576100429db2c6a3fc70001ef01b811d47cd2bb7ff44416f604e82e3ef3f2ca9e02c5e534cfa251b14c54f6a8767e2d5cc779164e88744a1fb854d8110fdffa70af279710310588ba37affc1bc186c0cfba767d882d6f16efae88dd1b929015203524b4c1372121dd2075cb6f0bcc9df1d2ffa5d8fc704a8d07c1eda43463f6c8bf5a029119e799870f73f892e77b3aed8c0d988b38234eb58154f43b0e2b5f6c24eb9c73690b854f69d814243d2ee549b339bc8f64d12ba2e30ce018a5ac8f706e4d7acfc2a233dbf3e96eef62fc0678335ec30d31487280fc127a54073c63b2f278ec4f25ea5f20f3aff1a55de1186337da7520634d350a7c638141a97ded8a6bab0b91629531a11041f2e24a9213cfe222b2085f7ca1ea55bb0731c3d026b60d43723369e79c0bf593523a78dc7b98510245fa6ce357e3db7e872f6c04582b7e5a0bfc6ed5fe3596cd78fe1f45ba7e46c61f7a9fea1ab6d61eeb1a923dc6a6adb0f05af41294341ee62a80163eae3174146a4298b9b2d408bebf5c42efae932e65b0f29f19f03014d090bb50dfd5dd4bcb7f2c7b1a7f9ff5b088342e87926d2df3de88ce98992b21d70a180cb336b7f512c1c6010439be8f7be33292f990574583290cc8e783951f43809f8607b771b1f8dd0a3e5c7dc0f36fe2a563a06f59202f1a941e7e1a818f65f1e1d3fbf16556d2b95fea45029af0271a8982e0d1567522728a97ebb12ebbf5892a4f5d56c894597f7912f42cd68fa13f3e6b50ed7f15f66aba9f927fa73ce48a4fc8d1652cfee6ee9bae15f057bf9c5a29c1f4f438d3b01e21319d4b95a131607b9381ea25adb85d89b42a00fc8535ceab9a44e69f7818795096f17d67fa684ec1c1d102fbed8e835faabfe7a0da77c0ea113c4e78f4210379b9d01052062f9320cf5b4d96ca8f07a45e90c5c1eafcec9bc274119a0231c0dc3bb5a66562b0c9fb8f00b18d390d553238b9432fc073024c071889b45faa81b175d68a53db7eca25b7f15705f4a68f6c15f70acaa74a562a61227eb41a9f2f5b32b1cc4f1a2d13b5c9f9d03c30fdd76ffd29b0f1ed5bfbd83e76cff834bc94c291925fa1bfb5c391fe46023f3602a23756e37b4e4e1439e0e073016b54d2aba01aa5f9d76c5055fea239410e2192d4df717f4dd298fe452d3683a713bc7e3d2dab4d555e364af2e39d2094242f6a99305c035ee51d54ce7396f0bdfb333b198a8a869c26a0a5a01627d5aa1ac9329b218b466312ddda2233bf8558f67d036e61fd63379c540de003bd12c6cd67729a61b2da6a4e2ca161d3f7e558d11d5d7499077599fa31d5cc82481a6a93793d5a7bfe52434e22fc5f6e6985b5ec8937c9e00eddcf9c6a016adf3726f7ff1c2c390a089e3ba42edd1dec5ade41b4c5a95f4d25250fc288b737055e92e1478e8f8d2fc26c91ad099ab6e061062e4497810128fff8d21658e293b89fdc97f5daa7ee0a7eded13ed2b7f9a9c137a16e5a4df4a6d4bcb37765eb8807069744727ff171a6bbc71cdb3c70165dcc345cb767d6b288d9a48605bba539553036685e86a586f7f2a0aa9bdc21933fd439c76c54de7b67a8e2920a32913d505bd15f3874b662d1a4704aa726879e44d486f634d91cdc91fadd6c903049e9fcd40c0e1074ce38198b07c57828b79f6a37ef487e9b65f7561850a9c4f512844751a8c4e93fe5b94c5accae4514c882f55cec6441fb16e0e2bd71112e960ac8d0ac02e62306630f3bb66ddc5aee8310e455b96d9486643b916cc98dfc7dd7db741119841d143e5e1dbd9135ae7f02f72f6b39c391aff6ddc5f115c29b89606c2a8792e9c292c073b60f6b9eef9828a9ccd25ee9f8cd735d0821fc3be5d433587f053e8d8d90b7dfb98c388fee5fc205b5ff902920109b9028d393d309a67a6c932443914c4505ceddc809a41991f36ebe48c32b38de3ad9e992697c2b4e361cfae5d638c65ea5018ae9a653cd0bb1c66ee259f5adf4a3a62786c3c8aa3afcaef3f18071a4b58dadabd3d589e917b31444dbec8b52ad7725104cb22505334693877f8aa2fb24f9a38da5da8611ebd537d4a9b97b8b615b5ed1d0287a542190d02fd93fbfd659e2527be991e6ff20a8695dc2b88c9545259c18343a44eebdf1f4577131bf66d89a4aa6fa5466a6ec5f18c6854b905e28d199ae0081c712d60984deaaf907ebb14285360873e26584416de8d7744489936893b2c7f7e2bd5246117ecf30061d814e77cf3e1f0dd14088bd03eb9be5960d9eb98f4b2378a8136990eef62dbea903193a837c97dd1a60f5d0351882dbd1803b9b79091e5774520536453c9be4a3de69f6a298a38d66bf8abd42e3b9fcd3c4f26684467e49229176c57480e8d40505199bf3990f83439371f0aceacff7882dca619ae4ece94d2a433091c85a0552004de499b252497f71fe8ef94ca9e9967ec471a0e372c80b45b191696a7f4936308523fe4552a2ecbcd2321e0a5a61b0c1fe71eb9e01c35810ac2c2d8edbad5a658a5a886e2f5b04b3fabbdbf55b99bb7f72659a556a90bbaad238873ada96d3e596984e268e8bb4941a2427adcadae8603da763031bf0ee21a8f739d69b3679050b984be9b2a394ae47650a351fbb118d2d78b4e6d3b9d53baddb0371cd0f0d213fe1e3fce6b72eb6af66c70ceb521974874a91b54411042515ecbb00fbcb396ba52dba9d987bae6d656d1c6bc609a732738714ca5cd12c67ffbff46dbaf87851d75ba31359b7f972a9e7f698a11ccc35323fac4fb883c0ccba2135defa63db9600884945ad818ad2090c685d154b5ae7d0891c4a5e298d3e7b510a48d3994c890f91eb50209b91eb010a4bf0a67d58690be978c15b6c20cfe7edc0767bb15fbe5d44f0cd91bc24f5d2b34a05f372dc70df1f3f3230ca2986997709927f54f9651014ba7ceee432ecca971c3d1fe5ca94965af5452725182be30082163fae317822bc703df446ba90f52d288d448f78e085c0e6454f4122781c333b37bde5d65394d7a5d5c6c80c67f76154affceaabae10cba4d65d18149e621f77b7290131dfc100d28f60162983e5fe8a69ea2f92843aec3a5f68e3176f8560899f7f4f75fae43864bd9ced6557f35d133e7dd029d84905f9980219eabe36e5f2bb6e040510c9dad3f20fd4e3ceaaba649ba68677b3e505fce6822f11d55f04c5db8e4f6a30ff0764bda2549e2c514aa7b1472454afe8ac354c07785567b3f29c7403369b413608946e69c37852823b744dc859b3b0fcc696a84d5d63c24dba64d34ae9b85720c053be233d7e1227e47d097079213f455840b5a2e8c18ac304719fe303fd35b4792c2887f6a8486b1bfbf2ea6960bd2bbfa1d11710d2a6d2c5fb82e0d94053ff7179b246c24e20341b794e1f0ec1df162af572cd8ad1e8058306d0c25d775fa092b4197c7bc7040a4a42d155996c4f27bf58690cbcf1a3af16a96f67ac45eddd0e91feb3733dcfed2de3b721f0b90a8143af634dd577fa00e8862bdd3ed1d268b89dc44edb45f877df188c9cc754041a2374ce668c0b878212c88515f851d1864e6cf22ce8fe353e798f8458528d5f1957ba746c68c93df53f51d40a8da5a42880c4cb91c863c3b5d268d9b5fd6b0ee018d92f8cb7a11270ba663f564126b1f7b0d6bfb00d5a7327160cff81d1d265cf82a6ff240baec866930b50d6b4e8527178aaa2d162beaaaffe8437844f32855ca3f44c77ee4ac0c936a6fb5e6a9d892cd9514dcb6844f460f795a9f55ee0cba769a0e245b329bc153f95d82c9e1dbb69ca2acf1e72f5e81665acb07dd77077d4d6082f46b5b8483dfc439d70d06b32021442ec2a26e2efc1de0f74cd858917ded604c2f2a3ba2a7655a305c08c93676517a57b11980951ddf50d8a070d9ab62f060c80850ca491933f7e76b88d69262d58f5948a083ca68affc51f65198a441d408131906b188dd8a193813b98828bb3864c874e54af92cb275c430918dcc9d9c993a722ca4ce7d406001061c357e7ee849a503b1055ddaeebfc9c4a0b6ffaf5d8e4e1e5a54718efefe5686e4f170991facecf6786f817a47d51abeec46e591067caa9e322a1b593304040afd118b4ed40983b5f5a0af0c3c2b9e5daaa84e3cecbf9ed9b0cead5c4b302db8c7d650575a04d7aeb4bb16fca4c0e6305c2f15ba06f07fd19d121960dd23c2e01779649a4fc04156a1278a044a9c67c123a1ac63604d41e12e71eeaeb8a861f5a64c2e41cb5c61423ab3da8af73d53c13cd28dc1e32ef7c9f50d252c815959f43306702563ec17c4f22a3add1a7ada0b903bf4dd4716307290f2ec24c59f7f390f8d96929bbed35e1c9ce42dd260a2598e8166064ee583a6a78ed37d196705862e13fce10d8ec8a349c14ad7022c75a9f4ea49379d44595e6b258f9ef1f713ebf039362262ab439743dcd4df1f6aa923594bfb5b9402e26a3cee79eca2bf1489be65b43e8d7c50fd91fba8516aff8c378647a060594ad825d78db78a6c7ded3cbccff6b95d412e6c22a8cc2a6bef194694c0f8dbe29adec05459a72e47fef9247379617d2d51833625eb2e9e007b199c7d4745dc5c7f4f75256ee87df19953341be89fc249006092382455d11aa937891775a23ced936f43931f43cb65672bc9b4ff136c59b34186dc37bc9eded7ac1037603285a6cedc12fe25b978de1ec8b92301873fca08ea7a74f1dbe5e9e5eac6897a5736b5ea11ec412103ba1d6be13caf32a051dcbdef2460a89f3642f42cf1618d888223279dc74ea178789f2351ca1fd4a7cbd1fe611d0f0c6dbf800844f9dfb8f26e17d49de9cc7b48d79f4ca4f26a2436820be6e77cf42418d740fd40993c3fe0e80237093382313d313da718cea1dae8fff317b84ced14d162e3dbacf5da73c3c807942ab572360f1ffae070f6fa569281007ea5bcc6d5edb4683636cab351cccd536a4d1f27d652fe049b7c455b6488c0abd4fa2b6d86340c2d53e66344fe165851f054405cf285b2fe9cc6471148a9e42542ad75e274a4f794de6db519e81605cd0ed08a887bbb6612813f6723d7bf5733c78be8c7e8f8ed32a8796ba7761ea54a26d6852971741fe6fad6eee8dd5173027833e2ef54b75b6fd3cda065e6c6c518e930231c953793c42b49de434212c843a0b909155b9b359c3f50472eb8f4870d91249871f3bd176e2fe1d63ea55fdf495aac8f13ea81235283efbab121aec82b08948e9c4fea6a591752750fd10be7ec49734e66d9941db12b294c21f83e01be55f2794def3fbd0f0146f5312890bb459447596cefb20fe52ac24051f342e82420dd240fc243a864590bb2942fbee5664f6fdd28bd991673c4fd99053d49f2de0abf6716298689389b8953d6acb9c5040ed21f238586477d17944e6d84badf8781965cf3408b617bd8287e95810c582d910182953d04e37128319aa5a762d3e8312b1fdd9fadd011c1f020d8ce3f01630c0d41218c6f46b0265198c6a3b94eb7fce5d380a63744fda14213ea97ea1148849d854725f15fae0421a0f3211572b46628d2170b374d800c8d202573110e3a5e61acaba20b7eb55d4c0621d4232f28a5b491ef93912a2809640f55b86cc652be3ba6e9c32324fca40c3201b5b634b1ae44442b3e77e4146d719f4b35e53239aa0a1796f64dbb73e31b59a54180acaa8f9388f37f2f77d5d8d88b11afd655adafbd7e91feabd0a77a5fa3cde8a80b9022e6f844a19fa1a922a06262c96b349d8572cb4959eb632d61cec5ad639449da92c8754e2908837c0650b5cc9f78141fafe47fe398625ac5ab5688405c6a343e8c8141c6faa95d9d482fcff694a42a15834e89dac963b9b7465d3b8c2c855a9189813beb21c093db94830f12aeef9da0cf2a62cf656968c84b4a47cea6bf72ca3a51cf0fea9351cd329278bc33f5fbbcefb8a709f129a7da20e18e10bc13d963f35bc67ff517f8ade07cd28aedd4760f317c93ea259a7ca0633e77ec9463a402f46732caefc54299e8be7f62b0f1248506d161875e049aff946c39f0810b98e7d150944d02b4b1d0163b9fb1f73efad76ec97f8b2f56d9d03052b680d75cf670f3f97a98b174a332a60f39f302d492254cb65e16d016eb8d294c4b14c3dba318021307f101c4c43924eb97a6d4cfd2c4201ff767f92bbdcadfd432ac63b52d0f8b83c2bce1c1270703c25b607c822cd5fc05295e0274c114794e0e1b3ea220b39fc8bef628165bef63f1b6bab65b79d540b7cd83b9caddafd7b0dd7aec0c8d1e30076f2546710b1183e3c56ed1022e6cabc99da3fe75c1a03112840dfb0fdcae4003335d1e873963e7b7a8cd0e73a7b0cab5350e6c4f6e14017d6ccd44b1c706798642ea34d7bed77198da2522db274d685ea4f0dc1c37d42a8560232dd612868b59bff044a3220d72c06c8ab1dfe047b93e1d9bd1c535034cdea42b3bb3630671bf773751a12cf0683c73177487af08b8969dd78e3c3ebb61a8a14df5aab19a8d66391a315fb5ef48cf94e48136949a21fc9974a2b86a6a580680ecac1baad1b6625e6162996a6b736f5001b656a25423296c4bfccda946eb54dc2869748302a3f53316b907fbe7ab2d18bcc0ca22f325fcaf3600bd05731840f7e10aff61f2ab126570fe8a720831cfb0e5d2965867b9b98b0190d1597acae2c740ea7c7c3b5da73ebb1aae16c70657daa8c7d502bfa139ab9b641035756ea411d52138932d51b701616cb41a7901785e2bb9b049c86929df64b5b82d8832207ce4f264bc35a5bea2f938291324ecb28432510e91bf89722bb0a54683f8b29f26dba7d6f598c133a57f6ba45c0f8801677f5c3c5337d13df93855e89fd312b3a090572230a8f3e71f9cc5b82f8e5b0f160368b1a1bb6910c1f1541f0ce4fbc42daaacfcd241428bdd53e705549da16bda785c98cfd61f70003c28005bd0eff1ce83974bcecb0687d65546a1cf0ad0a12f3bb055dd90f1128b87e7914b2580fc1c14cc5b4d4c2a83301e885b3191d38d9f9cd825a0013b163d858da6829db366a74738f6c899d574599b218a0f845ac1fe1188703e06a52705a9e6917c06ae577eea6f46e1739f3a10e611040c2c5d37ca431b87c20064812cadbb41ea80af98febddfed6c38b508b67e48197af0866faf7a3bb95ddfd857eaf2999d51e61ea026fe60a5c83e7aa28012cb54d2dce6163e29c062e04fc0768f7909d542cbc8edc7d7aa14d24af7a4b012161f87f9b9e809e67ed9bb00cfa91c38f0ddb299ce5b88b1ce2b513ca2dafcde9ba5a1468854b0a08af091e428217decaf39e87d91884af1e136114a1cb3235ea8ad62d6b0760308b8aaf60429b9adc6cd72a476976743d3df720cf9825919cc8764f74f035dee596ab89df608a335337db95fb643fd21fbfcd31fcc65db1aeb6550338928f1fc07468bb1ab0cfba7cea3c6f0c84ed16d9b4e2f243f2f4301e6e86dfa345fd643485d0fdd00b7c01dcd6f7256b2a21172257e73c7e83450c0f63551385d72169ae569e48b0e8cf7d629896db4cdff655373ccc28ccd1aa7b9d70c8082555779f4b0a2dcee6d94bd26d4aa9124083c1d4337aef659790c6bf587f57629ee08cdefcfe7aefd871e928fb947cf20ffac3d5e3a9031a23a07bf6c2ba308609b09c14f85395235f7c4016140fe72311dc5bb27581138c47292253bd99f13685fb7f561d0163451cc51d6b1991870a815cf95363babb39ab2890084d30e9d713967f38cf0e37a8cddbf2fa99666c42b83328cc17a6be0a6ff3458c10d3e69ce6c1d96105d475b99a566c9104c9a7dc00c3f929dcbca95c1ecc7b8716384b5a3c4ec31edeed10a7c026785e8273fddae11426629722ed1db932704cda58d2dae80c489a3401d152758103662d3ed05161c37e916e36ccef1200f87377c70afba70163525f7efa6db3cc947bc472949eb31616bbd6011169acb232ed889c87f9585750f9c48e08efe0a22d38c8fbb571a17c29588e731c96168b0d3cdba5bf74db36921bca139d2f483ac8090539c69affdb31ed1fb2014237f74e0fdbe3285dedd1f6560f482b42074c637d9e0a5a97a9f52ffa1315c28dd891a9b4e626786cca4d1c9609104a52f3a5eb5dfe45d4e7d8c412ff6793095e62fafba601fdefc2d9a88013838dff2d4dacfb36e9a241f3403621cb0609357bcdd19b810c2232e0454819816977a4618b0a2ed75ea421c6719826343db9458e6a17c67b4712ce4fb315fef3158dc0a77f97fbcf7e4d2f27a329fe4e42280c666be5e36638050698241ce8ff4284cfcd84d72fc5861280f0160573301b1c047f4730f2d4712b1ba8cd568b9447ea95bc772509ff499bc9a101df34ea1021de90c068c61bdd161fb16049680cd4addf34643ffecdcb516498b05f75e6973e337cf309f05de6f8f6e577444e5f0d6fce72383590bc0c6a01155c3149937c1abdb82cab1f6e84c8300676e61b6fc3a829176c3dc3b18405aaf13e47c210c665b426034266fe5c4165ba6a6d2179ff01acf3d195e887d31c188bb725bf582a4cef4726a14f536beff10ffa4e12fec486187af7f6c033432bb9c958b646a05962d2833dabbffb1259b8652b1f9ac7da54fef4401c22a64b27707103917772b120573121f50159e09af449794f8d9aecfae4f8b6f8f9009b57f170fb939b2cd01d777fbf33632df0ffee2d119e0c7ab7a7f2e1203c576f94a0477e55f5873388b4ad23f9ee8a0667c0b071844d6f99fab59f8f7c0eae82b615b6320b8e24c236db7acb88ae886e1f3a49c847a7cccffc95f993e45b3e2e1b352efebe8ed6ff13c0226facf7bdc5e648dac63456ddd544bc53567398c1dac7b66e668af4d231fffa9aad713c8f37c0bb58bf7121cdd5a406a42405f91c94443623fa9385b38e7c9e41b5c5c12d9058180c33abc65e1a6bcdd7c8e2720e61148293555704f76e044b854a3c5c49c6e32a1d4462440f349b8f08f03549bb18d8fda45d638cb695ffefd02888d00b026ef368038cca53782f35dacb21bdadcb7266c47fbe039ca1f175ec8333044946cfc712690d359ec45a3f31e1e4929f9caf4aa7115209ce05d56c1f26f01cffc747e007bd39acb266db06d6a8edb13a544bcfe1a9161c2695407699563215229736039434fbf0f65a16b3f9ec80cd9918316bc4353464f75b23a0eedeb9ae931121ece982447e4018742e535ff5fa0a0194747691d16d8bb449609155b4c1730f1d8f24da66bf71bca9bfd1c56bbd70cbc3037a1d0817cf608d0ec448433d491286bbcf9fa50dda641712ceba7891ea5c8982c750314a0f5c4ef04085a8a32805328236c0de1244d1c1a4be3f41f12ef26d67fc6cf298588c9f0a6138498d34d14ef068031ba2a10e87bce6c3cdaf5325a03cf87616df6f9d9410c6f92dafbbdd64fe2eba7558ff90a9c2986facc4e0e04d4fab998c156da68a44bc143e3cd70f726e421c41fca58275e4845b7f6f2619a91846e600dc5caab9ae6c9df637d27f4524f8d013ef67101391f00c998bace64ead92cacd0aca709644f6b4573d0daf02249d3977633eeabe793cb0c9b03c6d582beace368c529d85cca2b839dff68975870c8c1b3d61c8d035d54d2f63dda902508537ea8775a31dbb8edc9957740dfc4a8c0ea4dbb59e4b3d6d113b63c23bb9894f0a872e32b42bd940322e28c1f6627c011379fa81882908af9daea54a80d39e48ba4db0cb78ce0e769b8d21d730ddb12df46d63ad63dbd1566b9e1b23c487c9a940b05f65e74d6a146011e27304383c1343d4de2615f57232d3a5eb1819606fa971c841f40227b62edcf42029030ffcb7f13ce7224aae61edd76ae66fa8111b1ca92e9399ea9b88be8de8a71e2e9e9540de1c5cfde7c2f231cb531264073385fa3a574890b1d6ef590d3cba40a8a773b3e11a1507440744ca7a7939e244406ae1bb1976ca2102b0aee9ceffb170a4eac5e70a14f08bdb1b4e976488e5d15ab95e87b3e46390c0d8fd4f00fd8b118641bba33cf9d6886c5c64e58214135c96a0a74f628b949a228c1a526ed98fc7036bebd9f923a2fdbc9c3496da328290a2c55ffeb72a33f63830dabb1bff7baffb733c0cf28e84e58306072cb3a4ba127bd02374c49267512ebb32313525d0e0894993df841c7b829185be187214d382b252f6e06c528874c169e7cc8f1a5da124d296eabb076097ba1abd5172388ce0cb3949561b01936cc75cd27e31d154187d06127f2dc7c3758d479ca5d0cdd7ca336579855739686d58aef6458b11f3e42593fbad38de53e5e75e24e0b4aa798cb5a74e5cfbf3b84aafb9f8a562b09577a6ff6f54ded4f2646cbbf517882f7a1e45e9a24a07aaf6a98e14a1f7e0281f49770c5d78b11271d384971a93448db8a317c3f50c7f7a36f34c5123653ae81331a844a94768d9dfde1eb9e475d02583c227491d45ce0179eb7894bb9698e371e87fe5fcc858ef9361a4bf2b2762bdc0540810171a39c122328570e2e23d2c7373a715cf65fe876851dfec1143920364f5910498c999c44154e92184d4315b92eb650710ba5f90920bdeba0b7e230fab81ceecf55953608e8673b4f0cdac05d4545d4eb540442afb2a08085ef09557adb0307371845b25b084a44014f234376530767567889dcf4e7bfc06410e40d7a3c1f35b070b8c794e4406b97b1b7076715b2795228624fe8c355879de0c2bc4524d2349b024d79ac7f6477432499a6565b748799c8b6cf3516f913f20152f7af39fbc5527f23b27be4010934fbe254456e96aa9890166101666ef17fc4a82447d4dd991ffc03301f286907249f5cb9a758b1f44d42e9f9b800265a5739f7fd1a225f3bea35c13d95093266df3eb1c15e7625d48861a1da766cf086a6a8dab11cd395217a93562ac61cb03d993b1b3e707944c32f23ca4204c3a320736531f057af0b8f0529178c5e6e2b2d420b2173318f0e544b44e2f8c09a2ddfc45737407a56509cbf6e9eea9d59ec71097b200937d3e6e588102c1efcc01000b47287a1f463662af2e81ce6626708a5774d3b06d9f3008193454dff12ef9048a6cd42f113731725a7d9f6abbf72c7e8eece496eb733e0841ffb1c13e1221e81b009e6615bae0182c9c465e6c8a4a6f4e389c0605482ac9b856a68d8333ecf85a452abdd5d2871b2786c95d5dea4b3b9332f5eaf48911cf7ae9bb86bb483167f750d53fac4bd8005a7a0e1b92d81dfc3595d1d8967e02446f3425fcf513066cbe6f31915af7ae5a5af175b99e06dfa7724cd3aa5d35355babc400252af4214e175c93e91629e3cc8224d6a785a4bbe28b80133e766ef68d17dcb376da09bd3f115fd84512240c8a45f24f4994ffb2336b9c8ae6eba216da67c5f6cddbdca2cccb2e042afb9a6024ecf52feae81d3ccfbdb06dd39ce137c162f9515f24c530e74a145f43e2a6f5047753b73af46f03209630fdc3684eee4fd2b27e89bf104f9bd39823d51f1a780b536ffe107e8bbcddc12e015d54fa032a398daf4142c0fcd2f897a161ed1a50b1f85bdbf6654cf6d8e2d7a64e166bc264df28d29a747a2b76663e120944d28a133bef606d8923ea7ec4af845ba045e486316f6eb37a4095bab68492069701bf9b0bae91b0df647c74fa99ac72332a7bb6baad024137c63e679da52b7435f192a30216f55561137c6e6e03dd306705db28c737d447edd97bc3e08317eda9f473690b303ad70044f0b4788ec3dde381bd9009b9fe578c4e619f4af8962982bbc9ba2b2d7a20c79aba0d1ae5f06e6ce98d71d6a5bc3a834d97d7208c21fc366da469f642451a1cf541afa2cd09f934945e4df6d4374588635331d74a4bf82d3d97fbc5571a7def6ca91f96d18c1241badfa0ca20f7eafa4da9a9d40a876982aac84ea2d18a7cb3b4d7a584fd791cb4e1afa983139bf4d2e370b100053799c5ea106aa68dd2dc64a55f66ae6c0fe39cfb62c3b52b05483203813a8f4f65c94ddaa561151b9f3151f62ef916c309087c98953d5b452c4cae7f2f105b6615e2259160bb996c05fd3fbeaba23c56295c99b8379f014a830a672865b868042b4e702e6d324b0fe25744a8fa4c0e2339cb47933931927237caf1194ceff05336c58041a06d64aca9921b451832aff0597ea41cf3c4a78acd86e14591876ae1da779967f61ed02bfb0bceedc3d19c36d3ab295bea1192ec61d2e476c83e059a34ca0964e14053192d146dfa33602af06be2f5b42efa2532c15a1fec3785ac54cee7ed4e1966d48a63af09984a2b7ef348b3a8650452e46184ab77edf95775f5a6868e8321f609c91efef7e7354a58b943190a0b97138a4d905c685419d3a3f4c8e9679125e0cefdbda89dc2b8696dda774e701896096431808a0c3196ab350c1187c29aa35308a77931c9e13e1bdae45a9da1a95862678c781d0c2940e00610ab3f82b278b940f7a5233962dc2a54810a19bd396757014849e9bb0bb436765e6a62132b6668744d7059e54d021f12c95bc6ae7a897165cce25f7f8f410e0aecbd7b3e64640228a64e6976904f794f12f9e8995c4e0f3a97878b66feb90b89784b1bb774b5aac12cb6c80e2e363f29247cdd6c409e46b6b0c6b888fa87644bca5c45dc9afdf24436a19911b2942ccc2c96cc34d828230c5acaa840f8c828f9a16a30029ea935c2a6f837913320b9d0e339b090513f8e05084ffe4929011df61b7ac8641e66a8f85697894c24ca8f7e0dce2f8f51c0b756afbfba4873af5ffa086210053f934704d22e94e4b8a02927ce71c7f7fe826d3e45d48a7befee7db1d4d72033f9b8fe88e41ff5e7b7b86a2547c60440181426afcb65747dc5f06968b533d6dd5a90bf3c7ca0cd4f88e33586580667ee401792e73cfcc11db5de4a431ad07e36b991016abe0d729d164e2864877c08561f818e4feecbe0a2ce0898e96be0c958f6275efbc5e3f998c51176b1dbda5a106fcd3a6ae0e2a7d90fef22a6644468cb0d80922c9b4a0482ff4e0b90d1379f3c85375425e5ce41926439c099a01f3f6706b1e371bbccd00799eeefead62ac77038d62109c838ad06d42914ba864027594dcb3d1c0fb626adae411a9ca98c55405d7867ecfe2ede4598fad19668269d8d3caba3598624d97e9a5674503dcc28671c4179bebbbc70eb9bbcf31ac90f3098d201bf42c1bc81fa49e30f081976fdae25fc5e580d24ddca87abe14d6855356306f5140dd15269fa918b7c33fc730714487430d4bc1261f81855b1745b260347549365ade19f091aa8775097d4d893394d03146a9e88762a18b1f1e96b0276fa30e89de848184fd602394189a811d4f00f85d4f74822a3bf006823d30f21dd9bcff7c9dfda1395bddfa9a85e5444a8f9c0989587287a6d101b79bf8c12bf881c9a901e09fe5ad295815117db11314c07b101a9c39876acd5a5ceaebec33122e1257ce519f5ebc0c7d604abf4a5afc2dcb168300681d00d02d90ee60e9f2dd4abedc7da2ba421ff5842880b8af4b75a2a33c6b44768099f4ffcd09edb35d521f100f7bcf8d44389d118769bdfd91d95b43ec0db97286f591b2f6960ab7fbb186374e9eccec574ab86ac50c0000e5b942ade664cac0791c8003989ea0e67b2b777547f34ccdb2866a7b7f538acdedd8b2ccea064a641d4799eec2caf1d4420316e840193d42c1c915bcc1329fe6a1f6b87de698f88120c76c11bf26ff0b24fa3ceed82fc10dda80b88b240b3f3e3a8f85644b924728871a006e23f77f13eb229e23e15ed1925630844b1efa29308924addfe80bb56ae88f4cb2b14bf6811f0a08f21a2086130bd11d89827192bb8ca09d0f63027ccec8d4ee0a8c13922fc705463921b4c27128baccb8f96d29b7815e57c04cece33913fc2dfe2fa7374df4c012e719a3a973240480b047f90300a07c839dda9df063068005fc21057b169cba76864ebeb12333fff2d223709b22b665713490b92cc32d71189681c8944c66579cf1b9145ef3b6b03fd002ee3f9989cdeb82f528b0ae8974",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xaa10ad15b235c48c9509cc610a0ce91609d253cf7c324a49847f6b56a9cea00a",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x4bf6f91d84b37454544279cba152581ed6820044",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374a70",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xbd7fe77d86785ff559388447f596a730c461db1c588163be23a14b48bbe90e18",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x19c0cfd2b5efcf7ad2ea668488874e6a6354fd05e5f0caeb8602e1a602c29b03",
|
|
+ "timestamp": "0x6ab8ef4e",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-anchor-20400752-baza",
|
|
+ "sursa": "2800-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa0626573752032362e342e302d616572652e312d643230333230312d7774613037f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b841197824841f2098c0bd67b4932042b1de8061805a1b0a43bcf7d1e5dc83fc6f2b708d95c50b89f9f7659d61c050ecec033b95b47819a4d8e4774af16dbf55299e00b841f4f237fc07df3698129b813b25825190b2837ab3cdc339329f449f88d4146ad8588b10d45df2329b41ad3f02e474e529944343ceb965862dc62106e70ced67ad01b8415b5a8151cbb667b4b4788bae599a68f64d5434bfa4dc165db2a4b3ea8f42628270597eacc49e605fd907bcf1a7cabdd4f78c367167d10162857c484209362b9600b841acbb118547255f579c64da6442a0c69f2110b23906a4d80841fea2d9f045395308e523acc26c9bf6382bc673cb1b48dcd26bb8c86955e59b40c820f5bbd945ab01b8414bc5b7eae5162414b645d1cd7014f26a9ab2f8cb4404febe15153ad1cc11f276136aa7418b127fb5d09654a05d7bbb9db0f2025b705c6a86c7704a9abe840c4e00b8417e2a3aa7b7c3730b267ae746f729fc7c8b563cd659eee7a4809d0a5ca7648e142ef7584b3dab309eae588dd342e264b079be6666362ca44779d528380e57f82c00b84101174f212d2148ffcaa3a4f58d5246ba95db5f6eb6de81c12a353bf1c223a270246ec8ecb2efaddf4d5f96a3d624b928012dcd7acf57b22e85ded23ba8182bde00",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x0ac31070f73ca9de682e1bbf7dc037944de1b3ba34837b3dd3d677717e9fd1e4",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xe13aa491abbc1252dd714e7ca0e55717a2143eaf",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374aef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x811f72cbfe543e781be726b87eda0ef66717923e59b11b148528b9a8a6841de4",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x77d6ecc05951ef0a54d7b30108680fcceda2cf91332ad27fdf4f1e7eccb0c20a",
|
|
+ "timestamp": "0x6ab8ef99",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa012e97a0ede58b14be3fcc8108fc02732087afd3463bb41b1852bd49c7910fb2a7f07aecf8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b841af7486a83595738f1474d38dfa64a578b7a722a2bfab39db81058e4e365694bc61d991993f98c89f44ffa1a78966c2cd11dadea8a745ed78755a88aa3afbf28100b841c6328e22f884cc053e46fb9240aba58f58e61b11c712d6d5290eefd41d51413435c4ce21d5822a7802fc56b7cddb55d5b364490fbed4e99d74c5d3ff1c1bfb5800b841662b97e58058382bced16c57b1a37c8ef25f7c297c6b7452be8cd60c8a9c32ea1fe40a4228974006cf81f92133abf5b6557cfcdb32c6cfcbf377355ce36249e800b841a65144a762b8fa6bb2eda1717417adaf1247e01b304c341c62d4ca975e304ccd1280c61421d87011332ec2874b2721fdeb32b8a0bdaef07aaee906d52eb5767600b84189c3243214d9623b97771605624a054171bc2a49e4a8bf6cc083873f94de999f0c7bed1c2d3f769ed91f99b0e0df0a68a951077354e7e4f3bc8d86c79f56759400b8412626f53e9043bd907698083cef76558caa52c222b1f021c10f4c5c12eefae722117fcda04e529d9ebb3b5de15d8825d6c50274b215f356fe2d86c8ddfd768a3400b8412eed8eec5cfb62d481bde6af3deead5ef8768e5fa46b6e37c441c65890ee44a57c0b5ecfa79b6b61325047b9683931739def0a6fb7412a028933a3e7acf7a7d600fa012bc402fa012bbff902940180b9028f39c35bcae7444cb1fa86e4b3f35d4fec66e37442d806e857f06db996ab2e972317f7c629606a9b9142b3c018e874e181863b1da9b492a2807254da52bcd221b74cea37a7536888dbaacbc150348a1f8566e5c83f99398f40e811eb96f5fb4d74ff8cce0bafb552f327ed5c5ad8e39317c4b39aabfd5589caf1a137b9d7be935c6bde67e702b6cd71b97a0c41c7510cb4011493f2a8246b43031a2501bcdee4d55c72c7a5e32416e3e79f95ea8c9e9b53bebd47a7fa6fd3fc90d78f4df78b1c5d8845db26ef226277a04cd6fa4e05a751718d9c91424c7a0c367974a1ee9ecd5e0508a4d26f5c9486f58b684b853faedbb508ebf1f86fda048f1a4d44097f425fef56e5804b50e45a392eeac35efa46a1954ea8b579a36a6d9aeaeea35452b0b1088aa12da752ac1a0f1f57529d153ce5419e2cb48394d0a43595da9f98246d1f0b1d3693500bbb58c341f442e3605da2fb6d015aba2a799f668f1cd3165ddc8b44cc410b6b11ec937c30da588a553166697b5a8777a32da42e7b4f3c51124e61164430c1a07066ed8582b0ad8e6966c9208844552fdc94b87f9a07167ce974d47a22ea2a49761623e59f3ab9cb49539eb38fe083b23ebc6b294089d1213cb540908e23578dce1c849f89cbd69c57267904569823f15acbe8450098c214041364af21f5a17581159a46ba6eee4157d85a279c24a589eab9cae0a4c9f46b849178dcf66671163a22408e0c8d33e66f5c771e0aedc03048ddfb8be1219824663ca0300c4245279bb951edabe1668dc0d5e721e1af9c9e8686f751c0370844e18a4b99343506453d55ab234197181b5a3c6394aa2cf1625d68a44776d6927d83785638f727ae4e638ffa6e85248b0736599d5aab0f7b1e43509da373cd3e7edaf6b088f69ba9e506fd7151fcbf1d420820f91eb50280b91eb04fe6f351c8ffda1f6254381cd23cd27fcb87ead8dc576e07c5d2f6e33185de3ec16a3bfeba2ed7799c310484e30a9b0a706d91e35de28a443f043683d9feeb96f7e95b1a646125cbb21156d4e5174eac120116a928b83864fb258d26e9b0f721141f18dfa98ba79c32636277313c2e42f36c5277428d6b18317f7f49b4ae72daa6a4ca93710558423bd21cafefa278b46ead56c0dce8e7ad287a782078f92c0bd24694df8d4bd3c51fcb9548504e8d3309bdcbd86a6118423e52f9d3ed8fa00e8055fccebb9c2de064f6f68bf6825bbd658bb008712b554c93d204e66ba15df5d989bb594c901e1100804a3227e5bf104eec2cd9f56f4f7906ad7bcc05df4c307f7af706de5ee50f7155b36c9c56d868c455dadaaa36a300f0283adf182060fe9379057329418ae51cb2e2fc3151daee8d188a11db4a6a85b72378dac8a3deb1f35f1364cc9375ce765e536271a853c8202e070e24f0f48803b6beb8cb165c17d853e800da0615229f02b821fab86a57c5e6d16a2f2c04254e272911b2d8578835bb0fe6cee9d3cf76624e9d4be9e1a4f708271a461e2e49cd850e75d7a22590b34bf6a4898e7a737f173510a6bb9df6c9ecaa0c7936b01e035ac4cbeacf065b112bf65ab3cc6a05562b4cf49f18740fedd5823677d28c5f2568b62aed602c1107dd5f06219cfa609e9b250165099a29bc135007cfcbc5b941aa1f63d62a51ecba9328e3a785c82921d31b9404426c3908cac3ef1e439f9aed95aaaf8926097cb4627e5e21fce946a19d1efba31a530d073f57f0d7241d08ec290958d5ac16e8e5940abe5a9a18df98e71662cbc53c64bd892cb06832be3a85e12304991740b2bf35ae8f42f14566a2ff65d1c7cfcbd7b4b3551e5f3ae8080aa428b62861f419c4e8e28e35662023af1fe3acab728e091753c259928446d54183c454ad58d0eb5f17d880c8489dfb72c88f287d3a60943c3145e39a584479a6eec8acc8f8d75d328e816405422d79245748c859fe08fc649e8cb10bdd60bc43cc004b44a2d21f63c6da3a2a7d1b9d486be46c9861b3a6d25554aa115fc83090d2535fdcf874d9877ba8714aaca6bae41e45b887dfc423789dd53a5d137bd96599a12a8e43d11257da1a7308b6e8267bcaca17b49ca2d9f088305b78fd4903787228cdd2a0c1654df085d06b57bbef152d9906ec47f2712ee49e0b18e2803df4933c4afa5808a16b31cb65a27fb13f8a695fc05d46858ac5d76d5a67ecec3249b41cc84cea241cc4a362280feeb24f4dc6c15bfd97a07895765d758e63799ddb70c76859b552a0094bb93767723998b6cb35a02c41136c9a05131151f9b56d436743dc0c65c1b2fe0b5f5f663b086afc8f4e5dd4700aced1d62dda89f27e8be03f6bc03c806575eded0469c7b84d260fb2f9cc4fdd40d4e61ca42100b48fd018ede25c18a8f85b19aeee680e6e31fbca0ad6a896cb3c10bd79670c40684eff1ced0762e16739bc8796bacaa49dc90b23aafa257f07bb9f9efdbdfb76dc3f068e4aad580442f539f926dda7e884aa3a5ccdd74e46a6fc06015eecf93328f635bb94bb32b0d3c0ac1fb52e2437974a1514a243c587653026c7066d4943a4173dad827e5913f721a8e067f1b19493a07f19dd3c6b20fe1d2eaa2933c3de5988fc29290af27be1c5ae6a0b451dbcd00f71fd27a0ee3169fe2f1b0895d5638ec831bd3ade3bdf92e5f5e9cd263472e9c3a26782e691d9e3b53b47d04ecd4198da49dc731c2f8fae570cdf0304c146037e0e20d42b527c69ec7e2e96e8c7a4be1798963f3a8060509f3766c63e26af5983c92011b86e1b40285cb328ced82e4bf28669c5520b14fb7f4693c49ccb1a99b217dfb22a78acb9e24350a6b659a78a51db5adb130b5df9d84668db2ba52af652fff04c8b52ae08fdf82d962217f2c3e20f7fb82aaf3eb5c2ea344c6a659cf088c88aedd5510591fca163b71face314eb43d2676f3c6b8cf039b90b29a5f4548a43d6348c271a26526d5f2eb144adc62ecaa9f23c87c493df02920036e122fb7a2fbef50ae3eaa69d080167018e80a6d35c4f31a39102da50c827e27bfc4382c8a0e18d7480b0a84a5b98e38db87bd99269006b60c7be21e0d0321bcecfba697f2ace12cbe3e4eef623393c1c546ef42c51a7992299ffee2d39f3f769b51552a16a834e9cc9d5f2c446776d58694f3e471fbd7f73c3677104724871395376b4a0d5fa9bb043f73b75c7ce15ad15bb9a972b32593906718455e8fb83d70aa312b455dee15767de2f1e582e2b80cc7f912b66e8dc5e8967b3399128b4e50ec5aef5c166ba82cf6a9d4d67bf27acb1022beba02c5a77e02034da8bc4afb99e5708eec5ef554a5dec83ba824525aadb36323df811cf2111cc256ad3959bb481abaa007f39ac9a95e5b072b5be506281de87dce2f8e87686824585d645d2f23afefa457ed17d18e59c2b24d593a5be4eb494f1544b2d20b9b4e8c23189f09abaa0240eecc460e4b4536d2eefa4310deca44205062273ab774a822fd5f0baac7a783c864055aa238411b4453c9db4a7417cbdddd1ea55fd414d9adb65c86838102879fe8228cdb9f4e212f9af3404d018a935e8ac08c8456f71aa581a376c7314cb11e726334cca649513b7753f78282a82d35b79251e896f0f2365cbfb1bbe380e39a4f5517ca6665431e91dab48fab25ed0d7f0287d944e7169c0f30e1e20aff248f068b6368a7e159060213970d82f9550c1bd0e00868d2a98f33a6d7221dfd851da212323f6574174225dd678ae7cfb22fd563b33ac2dbee7957b77f59e8366c5a1fa2036a94d716359ee78995c8aa885daafa5b8602e43900a0555bc269ce5139aacee559a7ecf8e8c6e07e863de5c32e455c7ecbdfba6a7dac6b88dac57247804f43fc5299d267e27b653bd37c973236dea495201e4606178fbaaeec42c85d48b0f1c63044f7cf2c7797b14d5db0b9067b8d3de277f77e0f98d4fe1a894d0f23c580bfe071febb5a4438054333bd428c83fc8d9e0b859efb60ca2955dcc501383628434af889f99e044697911ae06ce1a8057b6251da82c51b4cf8881aeef581da2a8cee51454497d93fb677b1878e188cfc6b5b97da62a5270feb5591e0d8d2f851c097e3fbdbfaf39ffeed315ec412c58f8573af3588bf37ffa0644a199ba2cdb7100278d8b38faee0bcdd36456df4b68da492d323d30352772d07e39ee20ec1472b31afa3ab91526265308c80e9443b1a7e5a642e4fc6e38fd4b1dbce36d78e238bfb2a6320be1714727f1a5fc3439ca9e2b6e903926110a4c8ae51e37108610d9b4e4b6e658a9aac5069c3b4ee210b35bf53c3c0b575bd0f845db45b4f88fa4ab11b73acf4553bb6a7e715b01cafb651c90173c8e9590a6291743d5a303e56f933f95f57af1fd7d7eaa92065b7fda9d919540a981a98d6eb2fbf3d0537396a2f74a2499af6ea0185443b05387513d748ef52f5deef7c1eab1a1d2e697240e9b28968362eae31355364da89c7cb67b4d131973c59b99cd75d1069552ff964d9de8c12b6efc99c3f7e273b65b8695e6b3ca452139cc80d9eeea970b39dfc56dcd33abad8cffc986147d6f7db0701e4665138137f4bb2dc15c010a84f15c91f7eaeedee0aefaae55000a7de0318e18008d8db34732009514588a6049f4eb890607096f64873ceedfe5f0213814c98aaab89af67c06edfdd479d2d0826323d666898b03e2e9d1be42cff1ec623c42c6e9f56d72e521f55ec24a2cb57bf002ef15612b503be27ea4e351c076b4428167a9062271921f691ede88f55f39dc773307d30bde11c409c9994042751385d79d7b29ffc0796c784654221ca22283fedf3877bf35f0f3a776f96d9415b80f2ba9e6e193f55cb7ea2dd7c8b5586b4e04dfdf51fcd17303c2b8a4f3a2b75f61c50155ed5e5c60b01875dd53b8fdac0a91351f4f793f2b80175f5a984086412b4db4ba9326787537752e18052cb926c256cbbc4f2aa56f88d2ec93c9206bd4f7aaef092f035c7f1a049536d8acab371364a3e56a9590a1dbfc406d29d60f4fe6b3d4ef7533bb3d2a1f54d8aa03e06504a1bad74e3a81821a665bc2adeaed66748719aa911f8009ed817676583622c0c4705bd2d0ec8fa3b416a74d5d9b7869bbb7ff266c45517c1b5237ecb6233b8074d4ffe06fdd89241623613895e965c28eee51e384e48e952a77bc703e3ef32a41358b86b92b3879d6c425af0a46095784d01ac3aec9da87820a7f6addebeed09a0579047f104a5020dc5d09cb042b935bac99a5dbc419a6ac4fd6860c8547f09572986e5336194a5467696087788f3bf834e3e0f72c783e84bc759f45c838000703431ee2b5b8be4202d871335b7c27cbeb525dc7f35c0c623fc51314e339d328dcdc4a733b0d05803fe6c4294b15b1e9f9e289d7e725496391177a4b4f0377ecc1bce3a4617edd063c8c356c515296d2412748e246b4a6b90281770bcd4925cf219e06ea3ca0e682cd3383adaef1665ee9eac586eec08a78295e6343a185dc60263f339abf15d6771a25697deb86c41cd4801ccf970e5ef7d9959feb7fc4fd96cecc4bdf4f9c1ba0ff478446eaa93eee4d519b841571cb1fa84864253a1676f5ee1e21feca4697c188e14501ee260bab921c5c71305873d52505f884389a03f5385946e68bb252355469811bba0af77c413debc19e684bf2a1e45a9b21a6b348597e01c3d0c8338fc01dc9d7d36044e7b9e15deb3b45a5813200da8ca816420ac045d1d243c095d17d1c9fa2632b3c94a5d6ecda93973a9710c877fbd42db3d45d71567052d70fb97c33a48310e40b9e6ef5d89ac5b935ea4bd4763325d00ea72dfdf13bed56043f011d68ad20e121382c62a61679e4ba3d065872fcdaf0a1d4518a24320afaa43aa2144faa56439a52e535a0ba336b195a212776a229693c7a3ce3f2d008e8c8ed794924bfbda0d44952a9361741f670a1226336d0c97eb46b24e45629d1515a56c30692771478584273c8d748445f0eb8bf92c9c20740655ef7091e8d49ac9ec49ec9704c8d945be124448432b857ad07455a37fd477aa46718826d9b06c117383855529c6d2ba7b6b155515f0a299c90128f93e486c71cfbff68662d0457de3005a6952b65a8ce494a3501b6e03249c52a0c1b543cf68f24ce5fe4999465991f70d62974ae0306fae3cf34e72a75e442cfdfdd50c70a55d818aa7be35c7259f2310b86c1be3883071ea7a00a0f3cc1676474fd17c91909f536d1944eb9037f0d7278db925b3dcc996ccfa8d8dd2a9bac510a0a8fc2305ca6078a729d045f9ff329e109b4ceaa38ceaf413a464a8070764381f61db399267a2b1dfe3c25512771694dbf059e1e0b8f78570f1f39f372dd67aecc8e8a8c37209651529d7a9f364a1939d46445299f42b727ef085fa4292d92a06bf88267d8def8b3f023747aebe8359f04226ac235cc258f4db5e9b706bbf148d7ff43e8c5b25311df01d8a58a3270e629a8bcccc3ef5b5fde1e873f859cb2a702fe2217f1a1010e2429f860fbc81e4dd4782a9a5f341cedfada4662b9d8297d98ee53dfe1d691ed19cb9e2e8112584767ee8359c386f78cb04ad720b2f238f3234172cf857305f0fbd20ec95c7d322a1fc3d816a7537715cad252b3c615c87f15dde815309de627e08ab85a0dddde8c6c55d7e14d6d7d70a37dcfed322bb865f1eed978507dcb31613cde66c52633ef10bb12caa8a164686762b2f29f8173bc3910b4b17a59a6d81e1c1cc6aabceca070c51189ae66043905688ab6d295002ca0d32ec1e99742753633af40c16a9f6ee09e02a0bccfdcde41a4511b4a4c0810caf12703a25b89d60f849c832a986b0f7aed53fa65ca228459927638762f412677504ba78f64ac32225f2e9ef0ede7d36c2796a004190c6dd8348b15b69f49bcea4a7f934b1591147edf172dbdbd720d24c22519f2e1dd161278270d7547d1eba471b3959f5dc1e8294dd5f157852e516bc189aa91b755f9fdfd137e085663ea58203a77d298126b300d8db519aea992cecefba9b36370174a24bcb147aeaec3de0bc7d9e6b6abb098b2f32bc5a7c663dfc5ee1fee7ee6d2458d8f19452ae572b97471afc5feb16bc32bbd70d3c59529cfaf5a9f065f8c049a4667f398fcfa54dce89a165a78b3f9762e324ed1bdded7dc4cdf90049cedf41a5e593786266ce156748b679eff18c07b5641a02154062d93fa2fc4cf32c3e66f56a5737cc3eafd2975ec6e543ec7db888fccf14ef1339ac2ddf071d58d4b0e1a2e97daf4e989f7d4f51364ee09fc7aabecc292e44a4b8c48da211f31cc481cf962931c8bfdfbba03d13e46a17fa60612ad34fa18c76ea9bbe1f408a8c529b9f4246557525bc4d34c61a9075aa0937fb3de8fb972355d77545cde780bfd2d91ed72e5857ca6a6cb7dfb054e63570f239ea20114cf1305e7d09ba640cbab825b86b27e1f0bd9e4c31f07ed779c2415951644a9ee8315f72736fae3482d7afc540003c0d4e3b16eb586226fa962b5c32b46354938d5d74ce2061f400df4eabfffdc8869e4dee07c471c7bb37609321b819d6c5cf1a4a352f1f9653f6545610062a9a2cd3dc9f0e48363dafac7ff26be91e512c0a35e740e2e29b909b75f45e3e93a440ccafc0a3f8fe42b2ad3f9507f3eda45194fbb5954fe55e50c514fb732836f4b3cef4274d9191a8b082814d212ccb371c369a8e9622791b38a7abf5e6ad8270c46542f51c373e67f00035cb6c736e7b877ec844ceebb91edb0a3b5c270c7d6f10efb40abcbd4c80a5ea8d0f30d5fd41ea119284a901e4e0b4d9f96ec1f92ca1d7b6f5c35d30bac8a8e791ec99f2272a2f353a49036b377a8a07708d14f790282d69a9148cd55117c59798f403da38155c987bb9e57012f93e39414683282637e10057973c4cfc358a088d9e9c68d22ca3e2aa32053773df63f1dc13b4f7acafecf4d3eb7018eae7eb5f01ce7098b49dd8350842c0fa9a4816d1309300bbe261a6ce39dc2050d91f29c7eb4ec63dd78db718edc1c793fa47128f1e25d133fb167b5bdb66660eb1e650ae082b6e7b1474d08170eb54d625187cdc5544019859be289d369821e119860d527e870804e7ce55ac64ca34511d7b429ea23ab45873d8ba4f6399532f6ce6861404d4d5855a13ccbe463c00ae67c888e0af3e075aa1ff00e35bb7f57b61bea31c525733a3b989bfbc8e375db12c84666b05c872e88c0733f4c7d00d779651477c76fff475db91e8a301c4f31aebe3cfabad74c4e4f4b31cb7d3849ae4b0ecd1d4d30c875edf3fe26b4a17da9447e7a97bebc0e45587160dcadec8443654b713ea529cb38e28540789e812bfd97ca2be0d1a06e76192dd70f4e750b99d709d9e41c42c11fc42bdf7201dd0178f0b10f18cde56ad93506984dc1d8db8f592c78d2cb78f0345479061541856435d64b897603c1bd497a5713d1e99d3ea16116085d6950770139ed76cd79c6ca3d1a2e71b65e19fea26f4384f18ae8d769e3dfbe4b27e10af6e579cf7e97a115476cf979d3eeed15c3616b162ab96ae14464a032cd4373f3d22e34e80e3057b70d11bb29a2e0a50bca48d63e029f04bbe45eca34ec0db040cbe303f847265829709239d24c8994704b365001462d26a5c625d280d6413a1324bfbc1f7f237d4b6d687838a0cbab8a2bd55572f70c57e438fdd3d5ab00bf1c08ab73a291f5058acbbf330afd4c38f4a35e0b9ba9e776888014bd863d432eb9d2d2b33a55f381c0b5b30e6d0fddf5e3f72270802f067145fad2354734b2309ecdc9d09b47e3c06d05a9cfe5efac79247c26b457af6bcee0b1bbf85608cab82e4cadc9cc9834732ee48b1724e1976c58e6ffbb414ebfe5a56d38e638f97da5d18a880510712f2ffdae954f1e662e673059a7bfa10a49325376aa78be49d179ba9adf52f0b562b16c67d124fb9c969bccd51cac30e582ae71b4f5ab4b315bf06203c99ae8443c262df6670aabe2a958a3fa23176da93a6098b7368466003d8f420faab153033bd78c5faecaf9b0debcfc6d1052e36eb7647b87db8b20ca6490fa08cb7fc67aa776d933c7a7c536e71f11cf43f978aef3ec853ed87e924e9d7ce7a23eb95b2d56c8c044aeec6b6c5b95c5c67bc905254d5fae6b66dedaf8b52c37dc31d408e6de6c1f125a96c65338d7a8a7c83d4acabce9606bfafd4f603a1cf7c8526c667718b26a96e68b07f68e8164cf315ba47112f2c882d3f24dad00a0ec28cb0f6c7af7c4714d4ba80fa407cd92645a260bb71ef67b3fbedc842ea37c7c0ab87bb82bec5207863b250215a30b674aaa018d25e6d264002da510d65c2a5a76e4353906d03c7ac68cdd1ba908b9451cd6fead44431079a1d7ab1b82cc0b905bd83c26ef18b26ddfac9b8ea3d02ba3b2e972a4c46a32304ba8a205067772cb7c2ddebabbdf518e31dde13d33079f887610bb444ceea06926acaddf5ac15262958529bd99e48cb779fcf377480dc1e2d2116795fded0bb808f44877572cfd4a44bce827da6c84e0b7c7af54c57ae568e35b2dabc910a4e6ec86295caa9e0986fe3f4b1fce6be45f92dc6849d70f739c5a0ed01f081c5a105363abec4c39e03eac333edcdbd34ab7afb8dd1872b774cecd3835c8b0f0495c95ed614ccb75f9087a1fc0c793ad492181aeb05413e70b2c32fa193d0d63d9725f3cd95ce6978b4fcfafa171820f278792ad33c84f578babcbd8e68d9a3b541477d9d126a4a55ef587a388429e155369080421549a867421b2d43c07e56d8e531cc063800a62397374be38efe9cdc1f9b757177546e3fb508b531dbef061c93358f1c20cd02b062496ca25b9188ed1fdded2284fc230b0df506417149ed828a99c8ba5fd26a57232a3583301852d2be77da889a71db99d8121a8418a911615bcde951c178812313dfaf82b9910f506eac8090af33ffe4e7b5c03d5dd225e9a4e8abac6c8c5f0a548f68789e6ba074cb5a90c0918d390aa68310a22efa353c0984510304ddb171e35997dd896bacf8437404281965029f9c3e18829431a47873017c7812af8772b1ee27f153512467f0154c0f4aab48826ede471bd3c005a6da65e9d2c10f691a647326027eee388451a7d9253538b4d8daefbf67c6c812c7855dc0ef05963e05cd35df20bdbcb83abbba64369648d2c939dd77e3ad4509d097c7c0bdb7c120da90deb29b0343581f1558852ff31f11d6ac3201afffe87a200b0c92a6a5195570806adb8305c8b037a49838b82490ccc87d72f525d3b8ddea69c66cb57da025ce6f7a7fc5acd32141e2da2eb4acfc1e2d115a34638301f1486509a34ba6711f76658982b14c123c24acef238110c38ccad77cf107b5ae6639ec317ffd5996528c7b75fc882727492ff491d37ca0f27eed4b9513fb5a595296d606c5cbe240f49498fd841335310f8ce9f680bd70e867b3e9adb6f49c9ebba79f675b8f00ad4db6d43e6b34455252fb57f1816e1fb85cd498775b9efb7d24443b538925f5e696e31bafd4e72c5b1dbe3b4828f11f2cb9f847699a71f3002cd7330969b39a188326208b9f2021e663dc0b217cd18445debbb192bcfc2def09ad6898113133cc1cc8c2509a15711865c9ac3652267087f6b06e0374e10de57ebb0dc99565f09c7ec31fe96787a33b4d6dfa1dc162d9027192f15b1ecea1d4a1798cf1cd4d41af7bb037ab925438e90809895fc07679d21284756381fe98ac3afcadea02f0bd9123d841ec11739f2d78c9442c3a30c8f37e88f7761c26f20c9026f3472378f7329d9d8ea1164df06fa2ed5b3f9e27bdbe34c82e76e061fa76569d31d1ca38513218c69e98c5fda22d2e01a9d439c6566707e96c604dcbb18c2bd10f5c241b5db71ff3143b68526eb10b2b9daa509a8ff9f7300c0d4f00d6e3a67454e7750226dd73be622c642a31fc277816d59bf89f5c47ec07195d1eeda67fce329ae5e19b5d76ec2594772b243289a82e3991e65b3697d3f010b1650cce03fc2541138aad77ecb55f125309c58855c5c7a5f4283cddf7338e368f547aed7bb612e5a4c5590a41f0577881c21173197b1fe04b17706d0ebb017ad37b40af37f9d7ca811bececac5745bfd9a23806847ad3f9fa35520e43821f4672331c9350b156a8669badf4b79243018c96cb47a1f7114b37bfe838ff110476b77580e886c1df06b5c1667b7ccecafb8eaa7d50a2ba789aec67e0e790cab39d3536f7d164a71e57d679e375a24a936de1bc72d2dff9df6593146f30c7136bc1a9bbce2da6bc22af3ac4cda426b3ac62d9b9b7903f672389d098d665366124bf2e3c2a9f5ecaa033e6293740de533c84e01c2100d56a892a9e36678809d207ac2a994ed81a167c23f2e2dec0bc5f86f78501aafb129eaed43ddb07cf8eed2b18c803829d6c5d1a00520ea5fb9c97b96557e9847687e4a1ba4ad09fe3f2184731ec63bb549d94d58e2884082e7b5e15ce60da75244f89af373ee3af322b82bb50aa3299b299f71455135288a26d5570e28c0a2eebf79d44ad35013071f813e532007d452e442c9de09a11061930f2093604837823faa5246e6ba4a544df5632d192b5c95b66f79b2639df32cfe91418b3361a06920a139acf36941e6f4c1498a3e3fdcecc97c80a7aa90be4bbd6336895421efa2c5e79394ea0d955b711694018ba7f5115804a3bcc6daabaac41493cf06302b37e98a463ddfdb91a593f1b740b425a67a9288ec568e348b3f0518780abf06360505388648fd05e1a506d7b235fcdea8498eca13fac6534f45cbac643b4a12072a646a876f69daede30887baf7f157edfc96f9fd143114c7b35e7be641de7f47720068510fae3d06a91760d42fd41977d0c5dc456ec6131dcc6c13c03676071ee34aaade51568abe97b7e98ee0dfa6145644cc707a86ea997e7ecaa8e80c1d199de0c40e47f6c668d11d5fc637162def999be89911eef655650be2ee95861f8cf0009dde83ad2d00e555c1997e54eaedf1a8242c72c05a96a7bb22099f3d974c5f0818e75da973e566e4691bae172d1c68705f6883d02536b292707f8c3bd3ed05af4a3f7db0fe09bc35b08d8b52518b4074b8e81956542d3a974bb299836f18107dfd4dac4809d14df902950101b9029039669653a4294f47f018572e468dd28c9b13d0a692b6ff5f67ef17ca676e5fc94b5ac7240aa1925828b06392ab0b0d1c23b44555056527ff860ce343e11885f7a3ef82f24b7ae958b7bc0487a45699042ed299c08793defb2c638e41cd5231134ff36ef6238d4cee8ae993e1ab3bca75fb39d96d531a8c0c97503b7406892ae8d3e3089611e22c54d1a94a22850df0b24319225963f1ba285276e33844c4bf42899e1f3d95a1ea7bbf8702105fa808558f29fcfbe40a3af1b6803b29b622ec7cb5913d5de65a7af22292d7b10f2c5251bec52d4f8d62d7ada1a449af85adcca60576d3473e0a946d08719aa4bfcb33f1b952d256c510cd1a32dd3db8ee8f69a9d0df758482868174e48e9f09549021d5bdbf951bd8df60e7f353886e764af34fd14c7d6ef68f0a6cf73709d23754573c6f0a72e5dfc9163d939ea5b7577dc73858a6f6a2e7c4b6fe74d68ecd32c172f35563d07e636b269578f0bc231bc87de7ec96ea509e9dddce9983e0ec6233bbfd657dc665e1088ac9d79cc895cb863d8a3730f4d0d625ecda1152d82237c4c762aaf5d70ba478e4e6877a98e2362572cf915a6ece24a91e93c53479331f6a3149d4d1968193d871a68f3a8ca48d1e40fbf41de12e901515aeef56acdb7568f6a874e1af7439d0c42aa52e36cd28925bbe87d90f8bee772e256b5325cf54d68e7e4fc5866018a35b3b87a1bddfcd0523e63f188195f1eff984b0c11efcb735f2e6a4ce4fd6fddbdcb60eb242bae8f633afb6c506d9d8726d139c4054e6392e391255af22ea46139b4e5ad7faf78b22eb2844d0c7cedaa1eed0020adbc6787a6c713536b2b90572cab94194540295a5bdb0225ce3636133bc3663fd9c63d10e8f1f2779c26b18d4c2d3736b77242712580c62905c7aecf229d03451a70ad9e46b10f91eb50201b91eb05bb18165fac7264a2bc939b01e65b8b4515e029682ad589e8040336b5237273a385e92dff8f57d15392388b89dbf831b5820c6adbacc0e1ce9c2d352b311064ed7b6b65ded70167d13598f1efd2811497b91a28c0169614b37f4be912b24e94e599e1f324778f68045a076426b9b8ff868ed1fb484c19516ea12d7c1615a55ad4a8f24fd422e2729324cae39f56044bc10a2a5e6006ee40490ffa4f9b9280a1deecaeb2b0d324be53b4cf5aecc33422f3c28edc9976b0a3fc074dd370511b4cfb5c999c1c65544d8dceaffde60f444e7e8292ff2a13d50d7cd6905df4bd8e1ee9ccedfadfe29b16aaa1f74b2583a254ad5b744c657933c00e35c08fffc01c4e04d8f02800e72067637a97377b0e7c181b577b0036d6b7e39cdbf2d8283cd7a676ae43f7a0319f5bfd73a48084ab3a9708272465e371286d5e7254c447f39d2e13b81f83ff0f92df6e3d90619cf618456ae71bfc20cfb6a6c9f8da1885ee274ce61a66b5222b46d01175c1052fe3917f19dced42916d4a116fa681fda7fbc06a26bc6df0fe60ff6bb055b8323ce5e0ef643940bb3d8bf90a94fb268bfb6c32e4db3c24e08d6bc96316a3aacb060b4f32f0bb3c80073c090ee2e0d78ab5ccc3ddc4abb1dace0db0de220773358a4e37351f53ddb6ba9de4bda68d9d0e6e729b80e3dbf2bd3e6468f448e3a0a767018a492d2bb0e3a679d85baf8c0996f133bd9b9eba58f1367ee686752f59bc4f15171cb548ef65012952add1cfc517729a53838c64be145d04509f1b1b1e98bd30591210cf5a4eb8048339162ca68b4e9a53087c815dd4d000b6994b6354181ca8cff1bd488b6cb320a39f000fbb89bf1f258f1877e41d40cb19b1604fee542be975583901a39dab9ddd696e603ee8f780657539d8e48ad09b5c22e1c46d628a8da66adb2e9da0522c6338782b45bba91c36700e5d9936be60d84808cfa787e97216707f37dd6166e3c26667ab98f02c1af1045cf0d58016bdd6ee6ba090a318a7ffd7d9024dafbb1f4988c0059611c2122c7b818b1a81974fef9532ba4a451018e755b1d576251b31ea93e04dc87ff6752cf1170899144a9346dad5deaa074c2e79542993aaca14586e089cd3972ac94031de5079365cee8613129279ab414de250b00059a1fa8d77becb01b83127796aa8d7b3c4fd9a8228d686a4f01f4afc2bf86be43e42dc4bf82716d6fd80927911073ae9ad6a5fd4b60be6476d97bf3e346415587d4662f0d06e768fa5b63672319566dd08ebccf0ac05cc073c95e66b27bf697cd092075eaef33f20072c1f5b8a5abf9a1ca166fa186c5cefae0851595b4bcc579ec4a8e631e2019b9e87e6060281db309a5265171ef127f6ebb83107c4ad0053b0690d3ef81471223e93d8333b385d5c359ae87287fa65fe32b1edc802ebaf88a12e9cd882b6b19adea198ec16b61f98a24606181e0c54f579a3dc605f367ea5a1adf9854f9dd19dfe41da3f326466d5d2baa3cbaf775230baf63b7099e4fb7bbfbd26244e671160030f4049d1fd4e05e378cc961cf61343871b2fe2a85845d7beb92f4d5c0c42291301e497162c4b4400b65ce37b29650785706044c9d252b21a68be7d61a12142b38b76cd9a9689bc1304197f6c2cbe5aa26846b7e722f6c24fc4eddee59df1c2c70ecc7cf56f5a3b33b13a0844ed81f71ef8d02a06b25a38e66c6f18310f6fa405589b587dcb075dfe56f5fcce6b786643729f5cfff9476103cf8ce3bdc52be2a43cedeb31a05a76ffbf0286d212aee5b8223fb94326966d932e391793793778aee0fa1cdfad78282b43b33504c92b1e65443efd94447e1b64355b1501255682f68fcbc08652e3a294932f5a1d102d978a978a9fdc2c7c7b776045ddb175306f7321ecf29870ef562229b4704170eadcceceb153413b8e3fbc0966deb019fb29582c83b615d2e6564b2f41ae0ce10bb8dcbd76738204303bc6e8dc26281062a2e702d932feb3737d34bccc77e42d423096f34669883b0372e74355b8839d8f618a681a4cbf8ffe14ae3434721bae512d3028383623acab1097bd8d5e3d24311d02f42ac185c66920c15948029b191da6f7bb364095a4f3495b2752897769203a10ae29be4f02a4f02b05b424745a2b35a7ed8badb562a0261139239e124c66eb4414afdf34677d5cd897703b74d6a1a4150dd809d674eda374fef95a97e345ddc3beac7ab45333c2c48741d89806e6e39b9859064bf6f71ab8ddf2da39765079dcd6aec863193002e22066847c9484b17e997ab83d4c5544295e14049f28dda8c2214f0b26bf0c873ca27c8af24a2dc8beae5a826127fbfba338c1c883276efef163e5c533567001f934c0dd4cc86970a8c0aa72ce61358781782dee3ee178ad107a1187daebe28351549e39dd9d8d35a7e04d79143a8ec61b22c057d22afb27124da3838c81f4886e0e630a12ca04483d2d662a10fae8365608b8b13289e72e1f5274f9e40485d9424d761cf74c3a2ba3ddab08f2abc7c098b5cf79580bca925c356d8a558a9b7139e149c571020ac60d7bd791c63859e06154a3e96e66f6b85723dc7ca56505528ecceaf68f5ddefe71972ef28456462f19d103f42fe0112ee82be528a3de3fb64541b5db89a5eed0fc4f68cba60544fcd2499ade348597339065c9e9688e4a5f75704d1c9a34e15a441dd2e6eed9d0afd647c84f99db11ed60142f89803da079b448201378869aa78f4a3a04d8a3f7ed5a5a7e0d4da9bf799cc736435dfe99f4a67640bd017cd6690dd3196d319a89cefef6224894f93509da05b26db58759fa76700772183c0898872215a856a40c91f4bd633817e12d9734c83f5eb57c78445d4ee77ba49aab567c462ec023a1ad2cdaa8f086759d08054eb0eaf490191e3879583849fe8d38ba67b168f984aba729e0bef9ad80d67037e1b56608e80b2893379a17a12574881305bb72a64b35ed5d6807be7f49bfdaf95b2319a0001aad24ce8d0803b1ecb55ea66ae68789e6a1700e4773f5d528b23bddee0e4257c1c14a0ad23becc1e74c443ee107e9ed06d47710e3dd3b63c43b4ffea8807a6bd0b039254716dd4bd661ccae7cbab35c15a6286b499619ef0d50a5473d144797566b5cb8d26a0cb446b7d94b6e11be1a280b90b0e594c0785541020bf219352287b5a4a0df3daaca138a009972aa468935c65a5d9511664f950c3a376a786ca7bca6e6e92829ace304eadc3ca5883519ce1be1475452f00332a4d24f58bf99d2c68da9dfda70c9925f5254a7685e73a97e0fa5188e2bc3c18f72a348b9adfd65140d0540c46187a49cab2ff1669aa4023e3e1c70c1d1ecbbb0021dcac3ebf874ab072e37282deeed7ebcda99dbf371cdb98ffce8ea8466caa0b812985dd79265b777850366ca9f2d6884eb5ba091afe4e8736c255f20a2cd9025c7b0a68a6bf150e5940f22aa870b009e9102b05c34a3dc0532ecc4fa88079b7f200abe8879957c2660ddde9ded8f34e66a5be6b3ac810a6ce543d12d3ec2d7296a6187dab05efb60f06f98188df2b74920bb2660140f629e9e80cc312ad0e42d3e874063a37b8a5eedf240bc0ee9194354f3fb1490977e929a8849146e130de1c67e14815655a95f41ea03bedfdc5f55a60681854ee859f1be2a7595e9a6a81479abc76a61ff37bc1db9a73d5890a49939fc28376ffefb72f72c1d2745b68f966295f5d7576db34a5367c88c5a2663d097fd88a46d4eafc1bda085d53edcc9fcad26b0aa1278bae339890a53871466e23cac01331a0aa2a2db60870cab2ab97e62c1b0317068769af904c2d5fb03f7a3b44cb2bffca6b59c57be523e3bcb609f870c69a2c4ffb5602575f0ddb21096b21acf9e125baf82bfcbbc2e2a06dec7239b7c40049af97744fefd6253da1dd3a1feec9063c005636b17d7786326a57736a735cf36b4d06d08bef450bdea74366ff4b0e37e58dc5b7877bdc452661a2d3052f81394916a413e214650d3e579ae3a43a62d82af61407a85440c19b4f0469ed3a62771bdd72f32d238c4dba575de0812282ca9d20a1223ff19f263e7b2e57e69ee043ac8839b82e965867af945e94711a9ad2a660177e02025a692111d3c2bfad00e56daa905b8cc46525e98c852b1d19465de50c3b9d62517afb3966ed16b94e61ef42a231a7c7ab31d593c5d756933583a88ed005c6c520163b529aa5736a37a90c6b9c624d093649ab88f4037ef49ac5824aa6414ff92d43fcad575778e650786232e541092707c51ea7a47815ec2794cc5f41c341ab4fcdebb16e1eeb1a407e1e96450f86049e1770eada6eafa0c8e0d1d95c7514f61270b05b822c88d7a8d9b00ba26bc1973cf890e3b5952f05f7b6bc74e1bb595fb9a9cb77c8ed27d656615309b3a6943960e3bcefa4a3b584356a587e21297da59461c3b478403db6d7373d0eae1bc77846fc2e355324c4e1c36f9dc768ab72b95416744a9b3e4782e36361dddc22c862b50f0f099c1be5b88a3541fbfd37207912272c755736657d342ad7a593eb78584047e29bf63049470c9ce41d2f5157852bb3fc77562a7b99db663531cb0f8536d7c74c69968f6d304b8d72291c72292dc6d1d9ecf6d329fda2d5e89c907972899cebe620a0dd94c785c9339ecc8dfe4b974a601a845d610e0ecf2738e1e4d5290433b924d495554fb7245ae083b38680a20f13829f3637d28ddad49f4fe83a7609e5c43a713698b679d3945651b3d03355251191f5f6a94b6751daa6732a158879abceb2ce56abab3a9900b42eaf0f46c16106f8ae9007923d470659a1ff9a68f7b63c712ea05ef47253d395a8f89497806296ad956921a595ccf51f062a1cb595ce721bedd2ac3b808a0103438e87c374be84b4d388f02cc8327b0294c00cc7b0fbde5e6cfa1c6b79e88f6708c9407359906609e946774b641a44e3dc9d7ae61abbea0ae00fd80a9f3832605e0e2c54188659e548c556be877f86923ae583bcab0774eb6e610a4bdd7c4ef38974ee377760f47d74e46db7a1a57c7781e7b27cdbc5a07b6cc43db44f1c495f59fbddeab62f69b789e43759f23a860784bc049fdeaffb280b798f964e9ca509579bc26b70d48b6cb210573268a3efdaaace1e68abe3e400b3f47cf73264d12b846c7b50a8d47e5ddc54ee41925108443c659cdb849ad49f6b7e9166e4227189e435792663c708666f8da6354840ea11f089727b24686c7685ba81785043cc0311dc6dc29a758379e2660697a9f35f1a186e5e7ba8351cac9ca167c165f9ed323507c0eac64a3a061d96419733c43c7c097f8db414682c6341bfc21cf9fb21194d1ced5cd745435477b1861f67d03c552761e2a049b1b795f6f149f86340df5474221957c91b2996176a5d6214ac4fd72d502568b364f3b6798f825f98077e9df79aa9132d30771dd37a5b08397ffc9fcfb3c70b89f4d350bacec39138dabcf08c1f935f12b8d0711d77107e030e5ef03dcbe098a68c9ba3684fca54776ab9d1eac84ebc9e64a6454b438e848463be956b8ca3644728526b439c5da820b03902031df1e2275bb657990a131ff7f5a8b732155afe7678039a253e282cb834bca9c2a352d07cdc50569ea0e1bd1a401a9af10e8afb027b1f55b0d705a975a9b6042bcad01a9cf587429bba1a9d7fde164562386993344418d69b5f32147ff2b1c03687ef65e355f93c178d40785d17965980c1d8046b2b7d24b8d912c944d1c1497278a5fbd314814731e7332b75f07866e38d008759d2880914275da927add737165e260f2e55c4a7059632f022d39ab962770bd57c2086219f78a9fa78d5b6f5ccfd4f42515b256720c9e2f48390abad858523c924a47b76c904ec22b7548540767530b4f39caf167c218dcd58389cd0532f0503d53ff9a0d415fe629e79fcd2b964155136b666e8d4a4eb34371bdc334942543d6660a79886f1306f18e276897a9d719ce0a6d30e3cfc80e8e5865c0a89539b1d5429f30dcd752b55961d418b1f712f8135b0c8f610d300eea9d20bcff302478f6d5d6a0f6cdcdede4610d7910ed74aa53c2456750633aa8a6db2ba2433b0274829afd4dffb45a75b4631abe0644985f4af991b1d8057f5beb479fa5b76db1f8e5e51508a8433316b9af327768ac60b8ce5afa343068bc9a4702d65b17b7ba5505d3f0baffa0192a66be6b209dce586994e9a994d13a65299db000add2f3a1ad2b546da34bd3e3c477ca34be13054b22e9373cf7b47741746af81a40064d412773b43d990eac99c3bcf944da5fb912769ec56d0589b9f2bce714c14ab3a0fa6bc7c85df7a7e20c787c968f4262b4317bdeb04406461df108da978dc445a6b2716faf829b066617dfc43bc3570d11014b81fdcf3828a62df459a4e57c3bf81e3bf8d813bc80ff350218fe55fc9ef55eab7d9de91894085e1b25fc51433cf67161928636f1897ccace51b90671b21dd9562bea51a4985164dfb56cfb7bb99dd3093f61c88c9302940c30697d631eaac6cba2bc6416578cf92391b9def50489e6e344e2771534c6513623e77ae6b7f70c6091cc10affb4af632df82fb82da61427c8a8b09c965d2396149d38988797f63581272ed71bfdc4f7147638326333c95518b5e88fa161f1cbfc2fb6abb3b800d9b0f645f13bd07771436b571bd891146970d1823a14d28eccf5af13375d82e9769b678fd8442de1271ddd3bbe55e608f3fdea788ba586f07484d2b4309da7d09ca8856a9e6ef1f397bfef0d10765c1de844a08dd65336ccc937546571f78dc919ebae70ea000c16fad574c76f3fb8ce02b408425fbc15c7ea2a12497f80cd1a67b1ef8f9dff0dca209de257d7ffc715e3eaf97cf62e13b4da427a468948b2f78dbcdfc9af8a1c10ababa65535daab60e2e5ed9234c03fd19334145df921856e0be01cfe6c8816fa19526816c3bda5e1c173623be8a28b8141c5de4f148efe2fad0cda58abb8833dbb685fb70a61c02ee874fa4f6af65112bdb37bc0dd1de3cac3670ccaecdeec4296e05a0cfc424cf8446ad4ba13ad8298cb97be4de3b276dbe2c1d39097de7e2a3ccab90da3fe85bd62fa094d0874e0afbc0e3a3c100d19eb242f4a38440eb100a893663cdf0e0e4a72eacf614a94d407e9747cb1f88ca4aeaf25399a77e41b66b6b4b9d7cb7a3c0b0c89ab3a787a8cab0eaea6705cd9394e9a1c4cbf8f316f74999191e16c745c7f54707c2f36164a32176fde5e634473cc43db195fe38c9d36dc6ddb91ad9d455c30f20b0ae0f8503c0420e10608e5da1c55421da11a309a94748cb4c5f80687104a3191005569a59bfed8eda5f00f731d70e1b994a08a5e95799c19d74488c3c67f7f69f9c6752524673d091520adaa71718567e19bcbd1092806af18348bd4b07138724fb4d0665b989e25a21f6f1f6db674ecc4e54ab0688c48760bac3f40a5ac919026b6444a03a60d8e5b7e7570d1cb902469addefc44a90bdee58025c4665e64c08469d36a8c9a6c145e83ce137d002a4633bf45adec4f7b8b782dd094f4cd4a3cc4cee7ac61813a44ac619521bbc2ce2cd50d192e2d67b7fa3b77213d901e27b572a2aa18ef2b2026909ff234d8e8be65342bb16d74b38b5d86c969c808f4e9a88b6a9a3dd846003e80f261eaa5ebd6ff88a18286db6f050e9553b965797529b57f762f22ed3c8403f784c256761fae0626d53b2e389841e9e4f3f3d0befd702c0d7dbbc6734f4fbbfd7a8e09629bb94c12bd7a720869fd2254efa62966677155299cf8b527fad20a3ee250035245b058b60ebb696093b0e352aabefae1974f2d31ba96626c3274acb3d5903bfedb90b7957b662a969ce700cccfa70c40c456c4f1adb3ccd753ab517eb81d7c6b049e8282a9f09eecf71a2506239c77fc6cae9279837dd399733d815367ec973f3ac198c245d2d9cfa49fd7ffc458c01827c08376796f8f02ce06f9f0e003050eab2402f93416a794bdab03b4b77f37736f59c47d68ec83ff7fb1fa9bc99f085c3a68dcbe84c740929f6aaf0bf6c6e6f2b37a7a7e0bc3124cad3a46d813c5e4c18a6c74d5fd93587e346689dd9466df00caa26ab1577ba76a59a2af6b9cf45e2a51de7bb5b6d257dc03d55c3368d9dd4e37cd933ff75b70a1b130d6e7f6cac14e1163b86455371d1fd3f90b412c5d98c7b1c6933177997757c0ff62e6077e3bd4d92720611b48142ab256ecf71f5b4fca171342a7a032404854557372befc98123d4a4ab9a5a308a5c5212c54148eb6c8466e1cf3cac3d81ddd73939d3269ad5e98d510a4f742fcf5dedd07393034ae5c8ec4a987b247b996e49f266a4d152d631922ce84582ba7517b38507c1c43e87c5327370349bba637bc2f52abc7eefce9d434f30967045d2f4a785ec786930e9f138525020ae3f21b3cd3568c8dbc864ea0d12f09e86b59d12b74cc0f11074e78c845ba0d7beb0b4878c2454292b73a75b3294304ae8f176f6f1fd564ff2f923c474cc61e28b5c5f1f57fe88b5d591de8db4d3ace662b3ad797a9a067e4a0e0c4bf47f1766f960a64b9c94ae8bbe048011a54729e0dc150217849fe7dc819c2b1f68d5502a613854c1ed2b7270d4ad4b27f782bb263d10a10c025b20f12ab9cdcee8c0ee9f244ece1ce0439ca0971ded8e90db36fbd4183461a3ee95dff1a8bd7225dce26c46ed1033a96d11f52deaaab1efe34401f456265eac9ceb9703a8f3900d372def60c0f91555bcf24ab50d1fa9faa690ef74a742aae3e61b218e86661c9e6fdc8e13bb680ebcabeef11c798ae4f8ba7d7f0d5a5d38bafff165be88ce07d914bf746906b25dcc5ff1bd5598f0f99fed7b213793e019d9c46f24b0e6f0fdb64c48dfb5d2a6c963324d1edb76e8fcb0f646197ee554ca7b16facc2b3d5ba9576a6088bd1f3b9430d943571355362ade5894f3f95e9472b894420d5615f68e8e9596288c2c3f4ae019b19e6237fcd84e2f3c77f7f0643cdc28477c41e5538197eece356c8803b4a831efbc7130d80be0a788edd6cccfb23fee161354bd7946eb7927a1842a8c7d2de85d791681737809af993f104c69b91ca9c226f8ae72b674e3a9f4d0420806d96d78d4099da2458f10c1b536c7a2b24afa3ac60d185ace3f7efe90cb2808760544178bcb1049c88a08bb167cd81c1dcd2a79a42549e03e0dea0543cf8cd7f6459327c90d7accc7b6e2898f37bcea25de665f4ffe0aa0db3cd1d9efe72c88738e734db5c4b5cb241814751c0b335574d222c7e0f242d7afb7726a96a19b1ddc0446ed3eca4a7e67b0468d318dc345c70ffc89befb6e33fb8cc9717c14c65cc59c6e1d61004b0c644ea50131cf10764621648b6faaadb92c7ef3d638dbfe219b375e6e95a02b715c67f659aa1f7c7c9dd163490c5b3c22d3779bd0eb661004d42487410414ab927d0e33e4c3359b42e14ebe0e21ad14f2923f462c459b02d120d02597659441891293bb5e1e6bc8e79bd2ac5bdcd3c02c2a9853e62dd88301ba1dd13f5aee8be4e1123b5c6aa98641beeb09f794c723391d10ed807da5c3d51debb9c77f42c12f29a50953fbd1cc1e45be656ed2748a61915b4945e963345b16d0205b67863b5fd530a651e339de1710041b97c03216311df289f1bc872b31b9d1d60419518fada54ba66ade3887b550f98e7e71c08ce31ff7f8e0385a036fa5e736ca88c2939a6f2921d7148f55698178be8892fc2749976b780dc240cf6884149a41175813097670f1f491a74a10c53389ef47da7f8bc567309c0f96917cc49a7141ab9866eec1149fa3369800f000c7111dbdc1b853a8ae9e990447fe5e994b69ef3743118a911610322aa1c3651a4d01562f571514f52f46eebefa78d22c76ac6d90f09aee3f673a5d9b0d6df1331a6c8350bb9ce66bdf103f58aaf5067a230dd76b7cea7cb37c056b0cfbe9a37c8fa780c1789b574fbc9753bb9a08030ed23f1b3d9af10dcabbe1c7669a7306540e5a4482f197c83e4a2bdb32f54cccc2a052f73f8c928828d476f47deace72f8e2e88406d2e4927389fd361871b95e80f614bbf289058908b76ad61d7b8b3e889e911ad8e5342a71139ed22c9cad5e9f1a427fde7e8309da7aeeffa7dc87ddebb80d9a311b21b27bbf84b8cc645dfd5551b51a6baf394b712d74f3cf484798cd3586d8acbda1a487a25227ff9fefbd45cb9fcdf1462142868b96e5e89732688bac157cebd3fa2fc53f0ebebf333974e32fe535d6d10ab4663814a8e7f032474a234605739996e337537ac051ce325ce02ec23bd8ed9aae4b2e772f2421f80e974e70bf0e2b14c7732d56ef058125256f48a3579497568ecb23021d472f894447710e90c2f9f2a6e6e78c8edaaa407930b1fa6cd203b56440e91ddf7a2ccfe2ceed2bb35169b59f4bef52bd8ddf9dca31efc012946b8f34b4f956524cec23daf5655836d638b195f5ded00ce0679911c22b445631e47c3ab8132a16cc9b3193d4da765ba2842679239037186d1f9b18a8c8f61c44ab1bc2a3b37f33366ff410fd0e8cefd04f2b502e777c38b82b0e1efe05832a0410f27f5c917b56bc27e492290221f3a83dfa11c7befed65ea7fec897e76834cfa38af236ab02afdbcf39d6b0a435d84e4196e9edc1bb958cea8df61148d11a0d0b5fb7fbf162b6613f9532b0c4011f5d567eaecac1c100d4abf1b9fc61a6b643e568dedd72f8ff512fdb49a8513074d319fd6644dc8b2eee38e3354f61b3bd094fbd9a36bdabae2ee4e2295d577d20498646f0964cddf6ae8428ebfbdf311d576908d8882fa35727f3118b21618e86c0ce03fa2e257789da67168c293d1c7d09a0adc4ce3e93b448336800e898cb2802246ceee900c7dca7cbf26724fd4b801e2d05d143b3f0bf2d08457ac9cae7708b2e88205150fa7a8c103b352382caadcd51d7dd1a11fc8e26d371355493650229ecc57d4de151fcfd263b5dfee2b5b1585190c8c96e561222cd71718405eeb405de447a39148e1f69157a5e8d9849c41542c4513d4281fceec5421586182488c64dcbf25b9d56f206f2e609ef5d62dd6e3c22181c99d79be0c45d1e7c2d0c7c0ee7ca66282dbe93c41f2bd0749d5512179d548cf04d83a660a144a6edf684587714d1952f69dd4968af93baaee277e7e60ed1e9ea95af902920102b9028d395a64a8c259db6c1d1ebc9a9820a45e73c4f799844dee86c9a5905f7f188d766d716dbe02f608e28b4e546b1478296eb1eb9544565d08f1b193b43395108d56d995ebc1f253ca33e7b0683a5d38bbc73f4ab9f0e6b6072437c9b59b3b9c2109a74dcd252a6b2e736e9d1c66aea82413bc11fee73288124927dae1d99aa595401a39e6e1ccc551a10a14011e517f3c043f66b070bdebc78a359423e7ee9342689506b99c10ee663add582709acd695556566bbd5359fa6fde3d1fdced478cc14a60ec011d4ebc1cdcfe18b9437450150fed6ce6671b3fecef81647c54320d24e1ae18022e6a8ba1c04faaf969bc792c7e57d53e2125627993c3af9d91f66a31857f6824f9df2aab24b864169ba91789aafc92d25995c93f423fbc575165599f43ccb4864f57fad63d6257072d8b69966ff98cb76db6de216f5722f3cf96e94a7d8f4f0246fc538936bb7a33b98a5e3e53dc41499cd5e8edb0841bb093b9cc44d62b187c52753e9df9430c97b1a3ad5860f4d6cfe9c3eef3d858ae55af57f117988a8d09522abbceaecad2f1d250198527d785e64f2f1c9e03d7203ee8d2b32632ccfbe3e7567a2d34589a0bef266ad2bb2e7fe5416faef8f13e21465cd06fdc355a08afcb60c50e26468b0c7d2588caa8e893e9276422110306d3ebb777dea64174cdf1286b244462c7dbaf523791787a355665a069520e856e310aeaf974bb62b88b96890c8af6fabb5e8e811251b54cf2af113e773d5df7de919362c0e2e4e7793b2fbb72bbb3d0ea5d7b0f66ef3934b52e8ef3164d32a8a8597f0a4d6d0b70684f05b2c8d61a58628ce627a51a78ab36d873aacfcc3870db2afff0ae3f125e46d51ad23a3beaa71097705a4f0e44bc33952baf9f6973eeedf471996464eba29911823e3d5a7677639dde76af91eb50202b91eb087a1527ed53adfa751507fba0c3192f1dc0bc4150425793ddb5c266daaf067ceedf69e2fe2fa04a0bc369e575e9e632293d04911a86dc2d91d7527e73a387297166e565ea77229dc5975c1f63522602594d6e04cd8249246e098bca2d96949049645e9099646d0cf75f20c2e696dda4442326f3e3830c09e0de0a30ec2237be83475957f03d2626153fdee43c681e59fd4f129d6633c4a16dfe4b2c35b98c121dbd369aadcf0e11d709b28693fbac5ff38a272fc175879e1c4af3a92ecaabefe6a4e4cd3f7a6fd6c190e8eb5592f9975bc0b2ac7c258daa6d1ecebfdc411fd748e0738c1fdc0359c819406bae25e7b1b3ac535e965fde36c946d9487f03a0c2e56b8fd60bfeaaa36b8eb431c11b5b3cfe4600a60fb32ce36bb707f751ed6b0df5767358e315a8e85270c3021670e1d1bcc159ce5637d92fa64843acaeff87ebc4b66fd815c8b4b1e7d6c9aa0c040670022dd41fd082599af5f054494f7adf054d3d00bc6b9a5b46298e34da4b6074124333a4b7dddf10e3dce64cdbe796d6c77e05c9801a00f1e410834b948c70d1d16ddc498db747bec05b4f6bf370748f578b4d321e9c48d93b46c4381dbc9aaddd27128951c42b44333f0b3d82645f0a328003da8cd2b3fa0f645ab5116b8bb8e9c190e49927ff35603e643690572c5dcc6a133ee7d870f93707ec15d4f79bf76f0741d738ff81c1382768d9cf37d7493647a9ee88d1c6e259a60fee8c72fb05a0267779c79fbe5a82d1eb117dd3164a0dcb3afaf6b3fb3530414bfb71215720fd5ecb79911e6f82207c04ec1b866d6003858a257775d0363cbc1b6e15c4532bc85c651e4289ce8facdc287b749d1c319b43444b9a80301e94bedcffeba9956672995941a6031118892f3297f9cae4e623547a41f594803b75f217a092ee7548b211a3a7c65069bf98bbf63eed0c6ab43a992a6b8bf2307c6cf51ea490c3bceb51483f2e82964ce3320587661de0e6de92c6b15ecf3d6570ec645e7c81deb2581246125c076d17e875d9bc17fa5fc47818fb118cdb6d21d4e8411a82a548d1bfa7149e25ec640e22d09e54354d82473e2733480ea2431c17c1ddff235bc6d5669308ce0ac30ad3a320c673e774a0293ccad19013e68ca9ad61431feab385749d65c9d71b5c830ced24606e67157b1da6dcfd36cb33aa6553234d80c4d5029aabd9e0f0eae2245691ffb34f16439921df36d33876cecd74bb0cca805003e8c7993682d69bbbe94aa91a2baa458dc3d70042f6959ced6f7c5290c13f77bffc52ef087b77cf72160df996b7253ad53f61255eb9de7d4fb84583611df83cab6d05807d858e62f40ab849b49a2cc6db65ed057e22d42b843d15f72d337c8e1f656159253c50c57f3c5dd954e7a5f51b2fa1bdf66fc85da96f1bb7bbdcc7774bf003992dd788def635a4d142cd9600c4606f5612d73daab42743a602a1a9dffbbf2296bbaa5a0a22b5a0836bf14ff08a176ed5c0ccca14ea770601038d3cc99307c1619954fc9daa3a0adf89aaef044dd20fdfd2d6519ba5334758b4573077b7051648b287c0e6a49ce3f1b17126ef07e7dccbef437baa19d3c22007e679ed394227d8416ff1dfc77aec9adaf69332e1697d74862bb4c71b4ee0fa0b7a939fef37c95bf27694b3541baf13210d6fd10e0e00f4f5507fb3f1033516d4786012db704b0c3038aca59013bd68d65017e130c73d9a4e55349b5f09c923a9c8210e516c486a3b8a4108c1eb7bc4864430719c53a93e0b14a10353b4b7bac787ea60f54f6f76f69e2c863626744893418c992aefa204f141b2fa6de829860f6530618c4f737abfe192f1e6c54b52efc9ca6c45f9ad496c1a5dd2f168cbbeea60494bceb8021d3d352721f387bc36a17238e0caf6b39c889aacefa698643a5c9f89b33122d5e1fe3494a6e982f0db68a01d47fb7eeb4071a4bf7a8a0bd24020b5f90d9123e854bec585a2e3d4cbf3ea8adb5639bb89c42f9b36fe4db693c2f9629a443a3c24943e41d86c83210b5c803ab595e1756507a4a6ea07bc7942be59e8352a7c025a1ea635ab87cfb76a6d1303b71e86d7e3243e0e18f9d43e09ad62445534a0c108e0d87e66618ca7f1a2159230bd83b643f128933d2fe21f3976a9d402cc20c911cb584be294311370b0c956547952390b55e179128b12e563faf68eb8c0e6e1ad8d6aedb12614e80ac35380bf048e02b6a96ce26e182f141be18bb900781bcccdb0d62dd22e8716bbb5564e16f142fb9cd97cd077a06835df8e316da17948b3b8dcbd3187b96b34297fbe7f60690fa7ec2fc86770f1246117b1ec8ac9a1114c2996e69ed6784a0c845fba0c5359972f522260f9f6bc1681fa3e22e4d6ffebdb8c2a39cfb3891e073f8d41caf9e97b0e005e4791717760a69f9c3cf94cbebfae231fb504c4670e660952423b44eaa744a4a9a386428886572013e17cc17709c3014ceb7f2010e4e24e0dd30b056d19024659a51d7fe963bc7820c6a82ffe580eb2e91dd254d7803dbbfbd06bf38d50a1e3c4468bc9d4b9472cd8268ef139e2dc5af7878c6fc7ab0c381734c7cfdfb9f5102f30bb22f7e1a7d4ded5277b3a8b51d185b8b49f90d752cedadfd659f2cd2d75864777ec1195664cf5733cacabef258ef59752fdc7bbd3d482018a76546f7db707a01334c596eb3bb6b5000118c1addbce2a935db6115d2af14879812d05dc41df9cbf6f271efc64c9fedc9d2e56fcbc38ce5d1aaecf70d842517a4a4a2e6106fb3c47cdc56a97e8120b2ff0f567b1d3a6fb46a9170cc13d3e08f7701e0f2696a16e6af3a5010ce91b71b359ba1833363021a5b3e780a8547d6d041138d86635342a166a0e14a28dff666c7348911f822bb4b572b821a098b259c6476144cc7708739d5d4ee8da2aadb056030aef88683dca0bc1bbb485121558c509af22d5e302fad09bc861dbfb19d50c9960819eea0bfd588eb7a2259456dce63275f66703bdf2b3afe14d327db2c32b87e41812a646ca92876aaef9e8411ac30117cc9fcc09a9cbc74a78f1ef857eaec23e605c45101e9e77e2f7e366d7c5b108fdadfd0f2c774a4e41010a403199b645210023b035c8d15470e770b2c7589dbe2e6103b3dd6cddabfaa27f5805e18ad9c916efde2ec9759029d02d6c839f27b8a53bdea9073cdf9fbf5056ddcbf6b9360d5f8c099446674d9030bf6e2c6f74ebaf6f1c672eaf805a16c7f7ee4b5ab55f84eb8a3ff3fa914e815ae89a4272a437a666a90eddd952c9f50e406d635b88f18d74f0388690f120a5187fd79764592ba43ba5a6f20f89a52701bcf90e720f956bd8a364d6ea4767eec0bef4f903f9f681718ca8154259c42bcf257953fcb3cc36b66f320a69636377ca48f6cefb4188ca6c5fa11daece668c43c39717a9d8d807948303de510e28a8dd8c1fa9e1f34048f034043c0d77271c14e2b3672362a2fb330358f853249a60f709d07c0303c213d314392e128cd3251cbdd590ddb15958713e6a3446de79a47b0cea1004116272c2bfdce076b9770990382306582b63370dab55798eecbb8a3e7b3d30041bbff464e36dfb50570f3decbef151a795f67b8118ca8b96ce50015a3e830eb1c6669ee5cb79deb981a8621d987795c2eefd57aff5066191bfe393349c6c3df567fe276273a012a550b4e24349e083653a2ee12d87ab25639eec8cb2d1d7733f19aee27262dfeeb8168e4f2de237f0c6063ea771e50e5698cdbe1a08919d0306392c216a1fd42a848577988ad1eac227d9a8ab25c690c1d8c1c496496080dae3638ee66a4e771770e83888c09e4e11506d6671a6f0e152d39862b9f3aadb2d062c820d8c05ab4958ae73e2dc388fb95ac0c7cd6984e7ca61c5ff45456d701ff6eb493ca2f4c5f990b710f936f30267091ca8012e1a5283183557a93f72de951e5b4e2fcdc36523c240d6fe2e88719f71e25c102be186b0c9e1e6d827a57aef54c82cf49e152e78df50e0dc04b6c35bcc0a2d7d08cfbb97b5213f543c7f10ebd613b1f4f795b5c50a6f910139b94f54af7fdd6392c20d8cf40b554bc83a5ca1e38c35fa7402d495f6e9218fb04fc6f815f6811765bcf8fab46b7ceaf319f1d5063a6bbdd0b39ea080958a2c4cdced448c72cb0a2d54fcea8f37efd05cb38c7b55548952b9d6e081eea409dcc09e5bc3fe88cca75a7f91fae3d31e5a9df91cabefcd39326c16f407fec28dea35e06d2246e6b1ea3b8e742e5f2e5a4890e37b5f659ee9fc27420529f888be335c2d221a61d0ab2c88c0a956ff32b935b777152aa5122e52105d802c4219cf80d77a4e15a0908bfbdf4baba8df30150d82631dc2e99eb170cdc32be4919b03a962db855d6c33d6ef6283137a4ff38514fa3f28de9ed77b915cf13296720206920722244e49215b89b2c951410fb1ea2d67e4b2c822e5907388d7741902237e3ea094b1bf42fbda549aaf51a425f46c1fe13cd8ed61f30984b1cd8be80ef3bda2b13e2bab90f95757fb0ec5e2218f8ee7094f50e70dc45eac8023ddcb80db35d2314c0e4cd05aba97e8e086aabed5226f11dbc964bea64d6793e635bd90a727469b0125f5068902bf4ea031926f0786bab6c79629adb96c352b91618950d8227c9191804983e978938ca626ca33e009c2129ed94d5dea82ac165d0475726d2b6811f66752aa6d38d246e54f14337a64db6373a0397b39652a03e4928bfc4a69b3038386b928005bb876a022934911fed944a142949deb756eca4cf4f1bfef64d6a5783f39e8e9231526dddf0eeeeac20e60c0a33975f1c047bbec1f1ba075f7d7924fc76faf68fabb11799b3045fc0f8989712fd28ebe7d0260f92d91eb34744e12e2a772a478258d2fe1a5c6b915e988fd0ab6a14de00db80dd0b1da4d689da5f9f3164be756cb8397159b6eecec1b0c7711e3054e580a3002d7730e5b1b41c5c1a03bd460c5242723cfa2db1ccf489a5a14ab72f32a80b051afef4c0be1611e9e14fbf271b4908147480c70568af5a925c806f5ae4ada641c5df71f64aa8c9affa37e3b0a878be11b575bb9e97e026ecfc143702648ebf6c0c9245b9bbb1d3c2517e24ce001b067de2fcfdcac48c388c1567f79d6648b029b5221736ce5307d5400fb7940dcec85b1a44a123aebd6d23a2196a177fb27c6ea5cdd8c5b0305b492e4be9899def51a33a2d87dab351da38c3c423a38f8eae1407654f3b44b5956ef254977e41da29e270ab86e35d6091be258285c687d9b55262e4b155a73e829562a0470fb1d159dd76f62d5413d6ec360bba15ed1f781edea91800bec6887996242135e7504c23fccf6967bb2baf6f0d21e4e601666ce0f184f798c218a1b798c87fce65b748192685c0b14de9a39b25b140db02880c20ccba15dfed0f1df802284b6b382265dc045fdfaa237dec8eb328a0b39ea883d8692cffa445069b8c5aee78db25fc1f190b2f58a7b6d0b7fa6870568282b0f76d5aafb92f504b60b955472fe3c8859edffef440aa30ec994fd648a74727e28ea7b24fcc35da741d6a632d2c1bf6d0b4d1cda5a01b316783914d5a675b8d49b9699faa87d799b2d04bc709a220c2e39e480b4f9fade93a2f8607bae435c0cd0de8522cbe6435efda7299e810fbb77a9262f283c328e7114ae4029eac7e6d3a4e590a66b7fdca5fb0cd6b5e6d34fb989ee9a0adac855dd6af3516391cf5a6bbf06cda38551806a9364c9324753bd01ca1ea5234a15334ddde2a72da16d650d0156c3a50ef03cf95df5c0b3b3461147a9d605d15b2820cc9baec5488227f4b64d94869cb94269522ac2f4a58248eb281312de99f34094ff50d266cb2386be1df549bd4f5245f01add980d99ea2b47d50e8cacf03715ffb8e771b9489ff78ee362abbad144b7421d4914bb7c5c2fb583fc3af7606ba24ce0d6c579642e08c087e4aed577a4beb49461f7e593922ee5122a2570286b6f36f1357b770f44ad6713bf2d7e0c6ae01663834884d5053480a43475b88bbe1fae498b2f016bbc4580ef87581ecf33a6b247f130cd1208eb98a98126d4b9b7d62657745076393915d1f92433275d6c6c313e00648c9f9c6d49ffdf9f00d845bd99a8d3faa032ee6dbf6ce1687e9c2e5c07d00ee23c5a5f32a4261efde9681a7e7c8457a9865c281c13c6c4a1458a54eac7e73526b86fef5ba167ef9da56ce27223088715bf07af359abea93e75dd03f4f08041729eaab9cbbccaa7eb31b8bd3e9f17abde11ecb02a25ac1aff179d24d0db721ad37ae4f43050332154025aeeb67fda211ed278a73b924515e612d4214144fe756a8ef7525bfe76dd1f94b5268324a7173822b403dc6b2703edc95463d276e62f41b0913ec45604351c974ee09de8c999dde1084e075c2fb019db62c5f6fc8f0db7ed2cfa5c069b36850bec21031114bb8bb9a253ed0f4a81785bb1be54d81976f80694cf8f7afa43dc160b01cecc0a93d9642e2d49ca656ac442050512ce3ac6c6bb9e85a44a6c50eab371e4519d818046584b188213528580fcc0933564f2c26d1d77db2a21780a1b5d3466c406ba2ca562ab698e0e9d270874cc920cb28f9b7bb80c60124c7dcaff3093b030ddca83acec98df50d5e26d1abe0fae07c40193d76b3d96a0abbf021785d8e0f9e085e448328167c06f4a04ab80f819e82039c4879554de3362fdbe49805c6113b8b60e21b93ab589a16ae1907665156e46394165bde6d7364b94408f407ef693908908384bf2edbe4ffd7fb6720310792fee4166f2b417efdc51f5b8ce012ec89c5fc5f9d306265ae851efc5cb37dc92676dee62d6ae571f098f3c9a86cc4c3326a409a5ad42339c2a89a002bb678e486e612e74bd7cbbdda7e4d4b9a64dddb687e4add4f42f3b298b839fde7615d1dd6f2479671e266f4a0deb0896dfcde75a0b26e10dcf6ee1266cd7c1ee5824d74ab126e471b07cad649da485a503832e80d4c50e8d086bcc3f4b9bd165407af9827982da7390519fa08295ab4a1dc1921b2215e255ed90b7328b59a7d9da310672b98d5e27bb87d236f147e0249439f999701d0f884c55cfa78d37961d63bd91433478c3bf2920c02ab3928a46d0d172d7462800b46f02ec0d61befb2d15e7d363cd25def3820ad22fb3ffeef6ccd7b5302f421ae913fc17cab41ecacd797444336ce6dabec0f66430e6bacc462f0bb5d23e65d53b876439cc7d5f76e20304d24c82ee72c4276dc3b7ecc209c3dbebd8f7fdd29e76311d7a6ecc28d32f4dec262e87bcae092c678a03c97ea3824dc954070b1213c53c5d3cba4a2c30cdf669f7acb67924b055c926181eb301ead79a550e815daf16346b2c7d04fd128a91837fb45f77d891976be72339d4b9d3b340224f8c0d1f615880f2f4de9f071446d61ce52b809e8670e98525d205b24d6c0f9de7167ec56f87678e694a31da441c06cde02b8f4fd00e0e0922e43905237f97b863dc6d8002729e93850c590d85ec7aa7b0d2159d81e5efa71fca0c728937d86e0f0ec47b6fb4e8417ba7564b039d794deb444665e0e6faa3307c01d7baee957dbd6601fcc19f75400e5c993d3c3f96d21e9f1a7ba420520ec3e625ce08c699036fd93d375bf918da925cc0c044546c247dd2b70c823b856184d82665e8ef56df32a68380cf77ac325fbe544773277a2bccbbcd64c1a287892c891608cc635e82b88079d80f855060508907ea05ddb51ea812028d04115257dfce7d278b52f64f2aa782d6b52f64ee7489a184fb705416a7af26b6d3a30ee1cee81d3a19e932ed78019b306c76318d9b544056055bd017bda3c11594c24bd5fda25a7d155aa35a12e319e2e6b342ca4c9dbf3ddb425fec9d986f19e3bafadc7dbb31d28f3d8a02eb01d4ad60f62b85afb82999328d0523e4ac72d0a636bb8bbfcbda07eff964a81409ad36dd674dfb4299a265d3a67718448d4817288486592888b3ef878f76a4587f8011317d23a6f4f8eca30c310091fe6ddd794092bc3571a011d6a712a6b7be77fce2636938bb1e6dcdae316be38159bca280b6fdb3213591002ec8f6425b759edb8e9a51a8c04262f7ae4a1d1fefd5056c7f862a5ddfdaf99d3f7377c0533e5e4ee78469cb9a1b90022a149e31a048423ab70cfb1619a92a2c28667812c7c4c558d36e5dabd394181af056e0fcd0e8c9f5ec51294a2890984825cae9e4f51bfbdda4812132884f1ea8d1691d9910bbd5b99d3861aef2c51e6f7ed6f374100b37038f67a10522c9776d3317899362e432ef6e87f0df03e972b72ccf66244277f8ede0099f8cbcbbc8eaeb65ffc9ecdc412388e2ebb1617abcd6732b706bfa09a8428df25ad5b928b972d443e40ed93b983c28549a1d865f33237b294111307a8b071632578ce61fd1284fa6c9507ea8554710b85956082ec055bfe8ef967a8d115f4a442740856eb0a958ed3b3a182b1ca6133c86fc06260088464c872d844db05188f5f97f9f8fe5cc388fc97be413723dff2f8ab824e41e11d3b20b07b144354c13b5ac283b784c622219ffe2dcc0ecd2ea761066723b13d06b6c1beaa4430fef4aa35c4372d42de1bd9a4dcaa7fc4c02e5c449de7f33152cd7f35eb1f77109a9b00efca934be1bfd8aaa16e1d231602d82acf573e1e0e0424c67a7d594599ca0c7da80e90c798fa755ff5ef3972a6af9b53d014f50b15f6dcf0c87b5d371c9aa1ac1c016422cee513323a6e911b63b2427d42fce7da7f0fdce88da2e1ea6a41aca7694caf17508e3b1f6ae311f8b45377209203f999e93ef9ffb18be0bf71a5daecf1a00e272cb81f2e94a8b971be2bf7a90fc5b1d6351d87cb057809b55f1ef5e6b16c24f3b00bc6e784622b5a0137708f1223879794e638c9366c43db36cfcc572a207a421cdc14983822f23a084525e6745363d47bd6f787ba7179ec9a8e94aae1a504e8f77c23d592341921c203aaefd6536cb1f5697f5087c6e8dfa4542250236d0e27a37146acb1cfe7b873b0860484957be77764ce715c471e7de2d671e12a97b3bd3f2353e60bf4195772f5f00c9faeccd851dcb1cb21c0b0262b09ab2a06bd54ead9750477e9bd7d30773acbda5a13b9dcb72f696e34aa42627519397f244eabfb78b8920b0346611f0f947e88b98dd1ceb18dd3bc5d79fa56b8a2bdf8d1982df05994f43df77487e3f84c2a5f75039aeb3ce833aff7a41c1501c13c5dceae7418cc4e5b44d907198e51e7f2a1f462d1032a6207935c4a2dd969adceadd53d6c0644a6cf7a0e5c95cf8b9c162ea9746fc71635a26327676704c63e813b03c28fadae842271cf2159136537f835c2511ca119e470121c20e39a5fc2218bdbcb0a4390fd91644c80374d9c70e21ac396a606f9f249222b1bab47952f88afbfe2a60717687a10021c70bd2cb497a07cff535b7893acccd3d6e627aac1b4d123777c9edc80d6efbe76a64cc70b7f809df35b8f4d42ed31678e530fe3665bc6f48052ce4c75bbe453139cb962b8aaf41c4b50e53c59c1759e5b358a330cdb55363740bd0edcbff3409206dd0fee6a0467237c5015f88d8b8458ddb811146b3a512010f05138f58c29ea4416b795bfdb3b57ec3e19e0166d779d9552e3595d6c9c913fcb23d91cd9465a3f1ad4a432862c97ea7dcb87ffabfc93aa007b4fb1a1aae09dc1fa83f8019a02feb5d0145d34a67c80e8e12630fc4152b9787059131e74aab5e61a85fcf3d979b1ec8e3d1f6c17fb0249c626498d4dfcc40386b0172f68483904f26a83369f3e37163288b5752223637de0477178786027785b058246f97445ce1305513fcca382e8562a5d658fb867104e7018b9c7042bc43ed0889711b6d8893e061bd0bcd60fbfb0782d09b0ca2d2b467fbc4100c6ad6a5265f888ce04976411111155b0a81157505377cc08efdb45fed0c5abd664984369a789e0d0d70c252dc7f7b04cb062f0ffb0e7193048efc4c0179ff176a2bbdba785053793d6fe034817d585b50b02b4517b6b45cf17b7b2fef4de2465a0773b9d93adf99067c6789e3b8eed18197e105f04001946f443274e0e9b371d7600c4edac1425b9be79ab59d671b88cd2241c256ab4043072add830068d608269171d100161f77384d55b2fb8a56894482e93e78366ee59f44dd7bdc309eb79da11a298f74e26437946bbc100ccfcc2fd5b3d6a7216b75d5906f9c3cd8d6b8c2c0bb9ad0f7baa5f81530f20a682049daae9894dd157defbb08684b960b72cc54fa09de4cd0560a0b812a613650bdf7b4bb496122bac2419e73063bff5083831bb976246c9fffb198b392e85ce19b0438b283d01d6edaca0f63e920842eba36e3d1ec7ba8eb21db2d734119e86b9cff18697f01dad5a4b5ddd13b248c96d8eeb4dc2cd4250878c0cb6f4e5de6827af3db5ec1e97550f15fbd5d3aeaf3af777441ca937597c013dcce0b96e0e9e2d6c863c6fb399fe0b222340d15403e039f6d7b572c454f02e90ad65d58bbdd4859cd23f2ab9ed9f945d09592aeecb7cab1504b3fe7594de301d28cdf32d1e6d02d95aa67ac8066bb9472843e265c5b8ef1b0bba38360fd6fbc51683b423374afea756a0b6545f578ec6c54e2a233bac6d5a9550888e4308514fc8b36cdefad0ddc22a31a5bf1294cbcac92c65a634c522ea6934320bf317df68bb7a6f7218bae1bac357c9b8f267b0690143b5943edc7fb5de269c3b5277e49e1b4cabcd173443b5da810e484b35cf6da405d4ca346bedb5c41a4eba74a961df45e2ca75c7c656f2a2621d32c0f72c0a00ed60b646103e282498a64c6fc7a0652246f197451bce38af9cfdf2fc841d30f8ce5f621ac1ef1a634f396b93accc0bab056aff7e9dbb5a2f7290eff48aad5c4813cf5e28081425bef01def2b2437c0a9cde7364686f9ca073840095ec34b3a52aaaaab68f0c42789905cd9ce2276ada4de7e1fce5c5a7b5103003a45ad75ea74c8e5a6a13f4ac0afdfa05d6e46326eef7e87ab34918505a6d07aa4cd39a507c2cfc0954b6cedc337dd585622e928b23cb04f820ca00593d4ba71cfd550173f6c27907acb078ef4cafa3b7a0c211d0754dcd18ca078405ba49048025df1e35d00d23608118fa296aa334bf205e458bc72334b648d57df7e0a71f9409190573ed2b018ca24c8b61c7eb8f1a58ab8f5f902940103b9028f39b853f714a144be4ddb6ef8779e5afebb4062131f9d0957755d21b11a36f4c8f6722ccf52f038215697c55fd91d5fb4d4bbb63949b971abebcab8ee566e4d7319858cc778b008eb03d263b4f68deb147217c805709c3614eecf11e8fee11fa8e119fe40488e71b88253771a16f1df41699a619431b9be544b7d61de3c489421a35234ab8a98649b12007a752e922ed7d6245b9b5efdb05cb2797c2ee33daf7ba84f234cbbcf0a6d8065aa98cc6e098d11680a839d61975ffece6aab6eac9529a9ebf2e9b99f058393988839b67939cbc21f081b1596739b540baf1da6ffb0e912d739d13ceca14a4ee08d0f1530cec808bf6cd2f48d4c1e169b7ade0c75d6ab083ccc26dd003a09a4a3a91876313837f2799f10df0436a8bdff2664be5cd84e93fe36fab7977733d89e0d215aeeb0db2bc36bb239f61e2be726d1c6e5ea465e3542ebaaf2a3ec80665865a6a3b39457d853d8c422e629a123c49b85e94c0f034e493178618c18c4b6513e8141f413fade3e33bf9fecd86421993999b1df5b631165cf6d672b556bfc852e43a5ac4f6d216b6973c7f73f8e3688fa20c39383155aeff737c95dc0dedc6f8ac773c2b91a9c2f40eecc4f34d9b6a1994b44d0c4e1ca3a5aa8a35cc4d8a0dd4d0e5b088bee610bdc24a8396715224ba5b4b9061192c3ba76c9b4229f0275cb396b65933c361531583ebb3bc4233349e17ee0f7f2022d6945deb6c83169330d5d4f11fd618d90c29a63025108b1fbcd408faeeaedbe45db9c1386fa4e52aca254c35551275f5087e094af94debad2d63c56746ae080300ac6724dfbac68b04c7352f5692290221ea8d1a1585a140c636a99b99c198251dc9f820344b6ed3295360fe19e62e530ba27039532479c59ad556fe2b6280bbc4e49e1ec5b327cc6b10fcf3224fef91eb50203b91eb031901e859666c16b66dcb7f684c4770c2bde9c777c4d68e4b7e428ccc5f3a84b54f3405f7a64874384597d4453bab724a67066b6da659d060c5c1bad5f0faf98a50a4c309c049b3a5bbec446ae23ceff823d150eb0da818cdd01ec2593a22a7af37e1c4a19d4cae421b19efc28c6d61b231f666c0330684fc79669a36d4d44b617a18842c72419cbb963e96089e62b0abf24141a4fd0bf332bfb6016819e0ef1650ac37cd0ab5a57b4ecaa6e8819ca35221be4e66859eff76488b785ea82ebe15dc80c8e31bb89cfabd61eb626383fac4795e1d0897a0b8f0e053366d7d7cd20a3f675faa195e1cdf0b2f9d8aa43a3d60e0790cd7d6913022d211be4ed26a3827c34c802a92dff2dadaac7d031819bdd175fb0695c2c056a4f2a20667bc1e672074fcb9b385ca7e5c84be1470c97a8a75fefc6d4934c2f75d3fb40fb5de59b38550a5dbaf4a10de311e17bf2375ec28eebc40ae0af18a07d8ec9d2f70fe0442c1891c97f84509012b9eac0096386e4c16e697f1ba39876e57f74124f06b524c1687a8b9199b75002d933503d0cad606d6353aa620715760beeae13951e83694683db4424629f8671ab718839c8821c8ae79aa9e85a967ec098969b21bc60d9df301fe2f11054d9f0b3f499fe8f40bd81a2e934e4fc32fe745ffdb3bfaf090d16c96303d94042c6b50a24645b9181a0c086ba31ef96c9bd28e39c9074ba98ae08ab9654458df65d0169ef4f7d3eb75691161a7bdef688ac94f19ead611d9fe16a5971b6452d9514c2e808ab5d955d073e7b1515159b1f417d556c15d4fa953d99d36a436332ff9fb7622b8f9841092eb860aeba65ebbe25a837def3a15be503972f3a90029af9f785001316ad42584418d43295ef7e7a31b4598f0cb143e767a25a034dc5ade5bcea709ef41a54cc069360e8ec41b9c5b0971232d6ae7d4c884c4b6878f5d7b475aa7b8eb11df14fba351ccb355ce7ee82c04829e271bafa61697e84c5cb9d8828ecb837dd69640933d47fd58752b680125f6f3a2963ccee5347770cd4ec019f8bd44f774169e8b4a01d1d12f5d4cbc4d7dc3d4b1a1261d50fff0ff3e6a7c99fd2c2ac4e3bace6a54549abb869d64159609903bd1d2b9f193753b5309f7226754079f15f02eb6a1a56e0b7b4ab5c160ba72440ce3a059f0e91ec437a201d26bb83d89b894369d62fe4270fe9b6351a2fdeb5249abd9445f42def7318b15593041d5d4b35f329af0c5427cec79e77123589a7d5e28b4f1618118ec33ab8ae4269f7450d6f9f45d0233f41555c6ab4c2068113b6fb99d600d73223537ad164632dbf484f64719368d6b4f9cc6f420811ba9b04d0b14d3f5494ef9966a74f6099d9c14f702d72c09c0391394fd8968a68b4a69c36d3d706d6dc0fb9989ed2fabe300f1f8d10cb821ecf634d4b8070978a063cc623d93ea656e56af4e5e9cd1407ed2ce1b2599dcf6c76e88775efbd8ff0f936bb478108023c050e41a3374c1c8247f0921e99ea5c30c90449d8c49702109f0c053ed224d689692008970da438cbcea0b6aca405a31bba653b1b65f3fd0882c23d1f79971d63c7fd71af9df3f238c9a5b0aa33f933a8e97832af039536b99bfe04882fafba8ad2e3b83b3105f889a193b0b4a14786f97e668421d5715e6db8bf1063153bf350a9343d4ff78ab61480d3811273196934d3f9a62fa175e877853fb81bc1a9313efab140f7eaf75ef345b14db21caa3bb1a07e8e1841eefa87984a5a7052045453ecb0aecd7428e84eb52392c89dc57d70e048fdc532d355cef5fba20d801dcbd515e9c77a188accf4ca957b1ea337f6aae044a6569c1c8c6caa3f8f3ba432779902ea21ce330e93d70b8da2da442c126d9998faabaddc54370225aab5ddbe96852242897e7a832a5049dc3352881419df6485c8f264a82eacff0502502eea338d016452a7c8c3f07fc2e1886ae6b179ccd6b360ed09bf86bc84233120e4215a7705c6926b4d4c7882d23685e53b37f097d2e2d48621fbc18361fd4f00df7b69581e9ded86ced68da6a2c1d3b4f9b7ac7b330d477c68cb6ad4c87e97609d441b152aca5c3710644e183fe563fc78fc9431556fbd1cc2d0592ca2d03edf85bffedde804542e815ac6443c8bff34e023abb925be7afbd16e1f5620a8c1706e4e0556b70276049130ad13774545f50eff9767fb0734fa34f1cda280005ef39222b43b731ec77af02a32d7b1d66151b181d2de20ad5e4ae7496b6c90d6b2636bc98198d994fac294e894d1d3cdd468f4c8fe17d68aa47a4f16d7a4ec7183a49907c9975545b851e1ec98921658303d4c3aa2a8daab668a7f674685340582cf819a38bd95391976e1134c31af200cc8edc6dbe98f323815aa8a555b5aa84d8ba84e056fe23505742d0b06344835692242dc558a821491af167d31daa5a4121af218e497bf505dca0bc742e50e9d01afb4906797df94072441429de1672fd8eaf5a435ab992a4764db5cc3b1c6dd132058739b6fcd05b25a5689e0b12c8aa99f6fa1f001a26a2d4b15aa859f2ab20f1cac59e5f187c0d9e39acf6499bb5639dcd2a2e7f18bd64dbd77c0b92d5ad45f41d109f2de03b0cc821122e76a95002a461883fe72e1d32632178a52e39d714c19f4de352441acc299f30e80a164c895940ee4e9a75fdad487e4e8eb872639d04e0f2ee94ef413a3279656438265fd31aedf95adcdaac2b1bc9b87132740aeab6055cdcb07a08c4f1d22692c76c4fecfcfa75429d39a8318a2c04bb30a7a1f8b3249edff0ab98daa5c55c840ee104254d0d61f1c8fbb77a8df1b11c89e70d931f739af6d0ec884d22546fd077490ff3d3ec3a4165d3c32d2b39465eceba5a85104df02fa9d6cf6922fa95e1a55fd6ae19e79b034aa639a046dc1b52079b975b5bfc262253830dcc10d26496c7256810bf07d3e775a9f45f6fdc23619e9a3d1f3abeb7606282d073a3d4f9c4527eba6d15b172820e93b9e12c5e7c2d577c967bbbba383b96e5e4484f05e6448536b6df679b506713c0b08e086966a657b89ccc97ac88adb36df337915bc6828b872a95f01a00ce24388137dd3c380a642ac6bba7ec81aa3e910dc790e990059edb4eaf59d3791b8fcb2388ce8ca83d432c41f9572c7ef9c81c71deb9c569f4078e9d054fa26ffcbb68032460f241d443986301909efc17aeb8c1f3499533c862dd834056cb740a0bf8d107c8e4ef5f1818cbdcab012f0fa1a787eced2354828cb7d2440b96ff1d70fe68180c47d247e3025df80d1092c063a52b8a7e206d302395677793288b86c1705b6e8c0a2249a677a5a26791d8a08e6d5b36f0e989da2561a281559ad39d02ce8213be88a92f0dce93430cce2f76b904862bb2c455ea2b0aa28391c6d57957f410d323053c2644080257e09dc4ce39acb18c5e9e1c92623f3310a8988dae18d5ba43a838e30cab919198cc33b5366d694fdffd6ca6a94932c1e2fd20b6897d94c4e8536624e0b0f5e8e94d6b028ea605ce5148716692737a89d67ef79915f61a13f166850e5e186574dbcb55b7c1ddbc9d38cd82449da9878d7bb78e5da997e35e275b3ae14af434cef599a9fe3080147726935372177361495f55eb2ef3ed4dec3e3998f2edb92b2f5699c8f6a49edf6c29fe7297fadd4c360ae5d348fdb585eef890a9c67089b59825a4d203cb381c10ef0343adc4b7f7dd3a086252bfc1ecade22ff6b52e561899ab5eec578d2953b60660b513f961332a21c00aa1eb572558770249ea3afbc70025f9caa22171d67b7c6384ddd0d7b0aa111fd8c93c9747cd1b2db1bef121dea0b669d237a15a27e1094a0f10321eaa7a8d20e1039bbc04aeaa67f245995b5f92841017da3dadf1df03a3e83f556928ece7a8380c7ea855f4b07b399ec6eca6a56fff1130606ca35ce87303887bfcfe608482c289b9c1e58d27402fba4a9494911f620bbf6ed36b26753a7516535546b8e3d27f7a833e37bc417447bdf10c9fabdc6e46ae2ba77e7184ffef1744d8dbcda220c1edabf36773032352e1791f7134ca33474427845c4074406797c44d91cac67a7814861ae1c5047f4b175d192343e25e573cc3bc27602211f807a64c903c29816c184fa7fe728d8861c3b4152f39f12398c69e4decee5eb7681e28364671d3fc6bd47101906a7798c196e0f2db261c5826b02a26aea652210cd4c4f95ac5cb87c142ceb0302dcca9767ac97002ca05453e60b395e27343ddbaa265399711fe9de13ac211f21f24b65811d72497b8b6a3c60749df09e160497df5b78e26fabc386d09a77e881006143289ad5ee1fff1bfbcadd7f0c75bf203196ca670d7497f110fe02e9e125c35ddeeb3a189430e72f8bb4b2ce1f2e07701a29757bbe486c9e2b3636f46f2df49d7ea65caaa6a9def8e2050f65435db197c6fd071d2d22004d60cd056c81f1aa7181dda1866339e3dcb21c0d16c725ee467eb35bd553fb80eee0ea4476ef5f83c5fbf4dd79180f3cd3a3e2e0587244a89387124a67118d169c37fcb52d4d05d8feba4286a703dc039cf4cd3afeea868ca40ca0ed05400b37638bebde2deadc0e7adabb5712361fa8a2169650c7617501aaa17bd0376083982f3c867c2925ac85170458dea751950df9721f0a679b6e85dea6bab0b65d105ef2aa4e2f42c8e6194cd56c18801cce8dd2fef816c6566a493485fad7cbe9d15965cb54a4e415cfc567daa187df6babf6d620cdd13e7297e95231967eb3295096dfad61122973e57e9db59976719de3347ae6c9883d60efa2985d788a61df0e0bb59a67773fbff8759a49a06a85b3afc6d5c744d50fa0192ae804fd10cd974e5879883a0cda3a0ccd08a1af2f634e41d73fe9f31ae10858d65a69184b3140d690c64655f7900e21151c7c6c62217385d6fd7eccda971ee772f55ca33b14e63170c89f370c6bb24c51a88adfab1d51dc1f547e6608d5222eed7a4e1575211ba02ff1e063a3d2a636abbb5d6889a2839d14106cc4fa4c5568f2eaee85782318e2ea92ae0352a3cb53dd34d3ca2adb50201a992d6cdeb51cf50b304ed7b5c661917be0678f438f745b6e51ed00106ac1f2cafd5614ce312b6e1deba0275f2a2c1bfdfc81fb24037d6f92dc6ca9abc1dd3a90af2bbdacef0529eab3b882376587428230585a5c12c0305f36214491a5fdfa25378a442a46e3b16cd4c021eeff73864baea2b7a96ed71c00f06b175be63c541d139d2da0b804794bf5799733e4810e6d9e405988ca6a6e29ce027406f671b7a7f964b4dc72434a1dcf7c2e226b6328885847fc906d6bdd6612a7c3750558585d98ba1d98372daf5f0c2b4d19c8b1f3af80c354ad5e26424a78f84d8471dee4f007a4f15528b0820dec643ec4d881777c366799fb2d2572d064e2d61c91fa9af8da5d175eb1b43a89159bc70963dfd4841d9c09a951886d36cca1b9498de9235ad104b0c4bd9764980d55733ed49525204966d3e67f391e352bdc268c114d2ca6fbee3320f59145bae2c6d934fe5eff4731fb7982a770a84e3e3eb7b0bcdb895f275cd1fd46ed528615f55a286e69c73bfe719e22f379460bcca0b2abc92d2035534bdc80fa1fd18f2735cdbfcfb1516eecb4c8b22cdf7f9094a7b9d7df9805a7d9738e5b1b2a26f0a7714228056d44588f775a3d30090c16e825e608fa58b8b1fcdf779228b080efcdd868c48a9204341335be961e76ac957c855afbb4550be29bbaf9e89a01fc861fa11ea0ede5576896868daad170caa83030f8222930bc28f6020bd0ab65cc13aea53f6e54474582d37b9ac9d19220a2812f8d42de24f64ac61a2ca35487eca17aefc9c380445d0023f147ef80f24423c6102c9ca62a5310ad2e60f7971001eeeb743c09923a6df1d1d41122671c56a7c7d36cf4d3c5afa1cc7c881a7310f496369623903c10bd30c295f6970a8ab76f4963f7c5f4648751f6bef5e82b9d39bff93bdfb00695ebab9b477bf67325dcda1eeb3afb4ed6d5dcae87f13d170ac99bf4694400f7c18810c71ac09b6a9a93f35f2e6c8c6c7e5c1d5d0b40793e59d76b2dfc5d79e3392398385dd0f5429769f5b60cf9ee53140b4c8c9e629fb723a8c3b44a407033e95c0eabbffbb855a6dec669491706065b5efa7cb3b9c16b037a09aac5901880a1d125153d025575c090e9ba0c24b6267fbe53b60d404238318f644133eb465d5d39b47fce701aadaa156adf308d2219509da79d3db9969ff6b8812da273240717e927a6bb0c70e5c6f2e80c316fe252506313764ae0bdd7ca9fb6166c2ae7a558e96faa8ddbc871996152017469816bb55e2e5b6d53fee5c5ef2bb6ff4dde9b6c99a9fb815b7dece51fcdd9a7d6ed970518a12de7229fcbfdf5affbcd7f973470331b109eaedc6eec5e03f4759f615fbf94633664b2658108abd8743a48bf613cd5124a8190a9cd275a081f4570f4d222657226843e280a5688affabac91d87099ee5b73a0392cd920b68c9cd76ce929326a90a7daed73d9239680206a82b9ca483ee653ebacff3896a95605fefd1dc58bcc06e90f8a467adcfb21203f39428b04e67bbf637e68e84e7e0b66c16c3b11206a359cd7bee3142dc8faf8ed5a2601116a97f45ff03bd3441f4e121a7800b44b549c9e8464126c10f06dd7f20cff50d469b3709e1422349534ff017463ca60abb92665543563e0e36de6a370aa2a9f7244dcdfa9e2851d958f882c461dd252bd3c8988d6b7f6e1984a7f10e089eab74a5c63cc0394a4da3ecbd7a385841385bb72ce56750726a9a7f9c5ceaa23a91883c501530eb2402eccf0d9a7deabd939ad30d5f318b1afd9d9496a59b6db5236298dba059887ec253072c06417b3506d6ae546070c295f74dd4e9b06f3eaa6d71955481e4f2ad41a6407c26c70b49ef2b3741fa4380d1d6c10d5ca5974ba6a708abb0dd5cd58ed420f30494d0211f706179f338938f1fa235543a8adad4c80ce82c18bef75f1e89c79c2ba5d9e03c3aac81d3884003e33fce2a4e61a20ec50b6044616a2dc7c3a923bd3a44c8d9e0f717d1517d3ca5935b09817d92d95b69f10608c29e9e2c81c4a1b7116381be7eb5baacea82ad0ce582ce9d3dc2591e294b1c0aeb3b1935b21cfaa3e2d6ab4404615dccdedfe67d7323dc440476d71ba2a88fa9c560e13e251c437b7fc2884ebad5fa1ab2342433b52f890a730d3babacf4e5196007a18a36b8d06788ad04a320b2684f2f619db0b57433acfaf3ebd145a3cd68ae9a8bbf3ef806994ef2545f554f6d0a095a2beca52ece8584a1eec58912fb12f1eeaee5784b9901c419446e0e231ec9527d364a49f8c5cdcd9a63d66072fa71555e342560f5aec116e5d349fb40cf2c5e1c8ece31676e99528d68e9fe1d9540f7f22e12ce2ce8924e025241386124318c78a2dd299fd904e08f6c23c3d0ca9a5064421d52efc0d0f1835681e59271a90597d9cea2bd419945f6134f8a8ae4c9693071234b3e46b48364ac10dba2ae1a59d0787422bec648da2b9dcba3c615e1c40249bffe9b59eb7445bbfe130828d43af7cd26038f14c15348727af4fe61716ad87a3eed0230a40d4e48d1402cd2b45fed90f827fbdcae45b7e41da1cb3e92c51746cbcc39e7cf83771eb237c8a1338d9dc8be3a6d91a8d72c0aabc1643105cca64a340493ec9e85a5e845f6cf7323840076733b68329da6b1b6b76666d5f8ce6bb10452a077f980404fd62fb0f282d8394cf6b2e93422f60ea85b085ef887f84bce905b909e572c88333a0e2b0a88ea4292bfbe6db75412ac7e674a7df03b8eae5bf933481879d402f73832ef00567669b6fbae6a2279f649123174baadea4724af0800a66c83c992a52da1e61fd80c54ea11e25a610ce5f472b410dd0cb414aba8101b863285da7963522e18dd8d432e77695b8c7b8d4f96a763af90883a335ac5c961600ad2857266c86ed5442cc8b61426a6658e749a7767da8731fb1cec42fc196e5c30bad48d7cbaabc9c1f17f434d90da2714a8bc243e50fdc58a3c65da2b393c3b0a2179976a063f797e7d6479b882388aac313d49fcf12d8ec56d802d4f12ae495267ba05429148fa536bc4ff66c6cb3293ca2d95aa069385d0a75e18c44c8c124a879e29f75ebfbb625226e44ff52017ee83f9dbac4f7f58a86b0956b31a2de4b57b16b60533de02e48362bd1f95b32499d19712789a338ad06da3b59ab2eeed6128136c935d6364ef43d9cb85eb5ae21ddd252aa782b3a8d86bd9645ffa0906dd19a7dbc2825f582751724028bfe017c34479f6962c083bb5c569a21bff6948de3446e1024d4ce85f8e36026fb6ba8eacb56d584229546cd355890301894a0209734c2670cd36c629082d1e2f364b41750f01a663012355e9b70fad4e9a5da80ff169de0a3dd8f5cb01ee45c51306fb716bc0e0822aae754313b813b7e51739592c023c727b7f5bc265380a59cf183361d31ca38e8e5a8b14b09c1dc058b8de15465a4e5f3756f80e56bc3f106307168857d656d9fb413b24c220e4c844c01a2a569b1026086fbf438da22ab23e77fb7dd8192fbabea8dcf332f012a3f40ecc0ade6262ac34a5076e0b8a63748b8a9745a56a220a36eb850b7f2dfa47d1a1e272ab2299672fc3966d9014d602fcd407260b5a128d769dcc1a979a70ed6e5967cb9384eb8bcbdf1d44faf0f4cb7bec9d957fbe7920aeec1dbeb34ed9678c8923d217a37915e63aead91b3b6d1630971656c551721568153961b1f337c7b7ee612e889171d3e29acb11dcb98e5999f4c2214ebac4ea06f6a1b14bbc296b1cefb1bcf75025034a3f1505b66cb21f17de96e3cc51623f0fce1ac588fd6c0c21f909833152ad5be80b9c7af3958d59d0f147fbeb446e70c72b03f5f244e0bfcb030103ad544a12f4853b898b4f1c4759a6cb47bb64598b6fd1b332586dd0397be274cf61327d537e1016985f1d56bae0243580ecd7bf7aa6407eb7682b0e7a70070e9320c3e952fe887e373ab5b2895f3299d3a1db4e51064171879742986b9f51ffd3e0690af7f51f381d8b93572a598aed181ee5c13d135f9f582c23bc8d718614dcc2594daa214203a87a1d2bb63e480a5363a58b09c02398197b56763f2a6125ba599fba4e2b07d7cf954651f1048c6a30b9d00e6d22611cad05536d81a5584a5c2f34862a950f0c62b8cfcceddb7a8b7f6797d01fa10deb18d9695e00305449b78855c9b20a341ddf1f8528f7b39865705b3811fc58958241450660ff563cf08bed71b65a9e3c8c038aa5969dd4dd3d5a1a8d5021e928daca972a6e6e11a2ff20f4de7cb83b5c6e9d07795ec081aeb169bc0f291448e39a3f29e832597437b6a25105792e530f481a5c8d40c30cc16d77403bfe5a3ea164ce4d45a833b3e649576c76ba6845219b323a92bb2ba1cc652cafc8c8998a3359248596514d26a34818dca1aa33769724cd50245689f5fc29eff1b0cc71d149fa4afd9ba057a5fde79fb3542139e9e2ee9d86c611205d81fbaf514886ca3cd3cf48f7ae0c6628f51798cff6c7cbbfc5718d72a13a96204b6a9ab358002d888df3dce04cbe315599dc53689bcb16560fc73787d3eb1212c78a803a97d0880c71d416ad533ade1afd37756a992b0de0500517cecdf58e50863a63c0f2d7caa886f540a5fdb8bd1e574be4644110f35942040109583b114fac51fc8df4563780bf474859d9ded6e76bf0023fd8d6380b6287f77016ba151fada64b891a717ea89dd94c614b26cae12ff83920620db5ef99ff632365784fdbc0829cae1956af11661caa78e1727b5ed7a08a2c99fc7504f1bcbe62835acebb1a11bb1c1d2eb47edfbe20247ff40c86f9acad6dab0d6d1fcd2730271fb76198a28218ea0dbc249ae2360db9693adbb74b0b7e7274cb39ff6c945aa439c3fc2f9d1e9276bedc6df6191a643c15bcd3c719525734226395487423829c4352b5e519348b707e49ab9fafde2d406a1955a087f203e26eab3cfa6232ec78fc8a2fae7f42e2ab53b28bf930d7da8a72091576dd3453ad5b342088d8e1bcba6da36852e401e1654b458ae3cce651388dbbaee33e6f79528f0c5b091039d525b548bd573f6f62d8535ca9d66a3a123258af4acc10fec60dd1b0a9c1c9e5692cb40eef783940bd2649212782648406740796c7e2d50c4b2232b89ef83f740f75e17306dcf2f7dbc82da81795da2389b79c3d3dfc59a0125bf1d64f883a6e902a341b562ad86600320ebac4a42719e37c40672b293821ea32d34d4b0e8419e88053af4a8038a3a9a48b5129f060ba80fd872338d98153c7ffb39fd691fb14a0892f3c308ef93415087b4a77d397163cbd4bd13bb01131f4de6546a42e9d02c5ffb1d15e99b42a20bdbd144bd11f525ab0ea36e4d81b5a5e2723784cb2cb459566519ab9986fa6dae1fdd8a3461b0534496b42fe26e036cf75dd380aba3211364c49a3f4953c5749c46aee3e07bdbce36921fec7b68dc4642222b0ad85bf2afa091a29604e5038c1a7baf43dd54cb4029df9fd81ac6c7f1a8e8faa14657169d069e4fdb5b7ac8439c02f527f80ad29047e81c3482341127c59d54e461d144856fb8a548661b4815a89ab701703c99e740cad197d8dc4e25f87af510be56ebb6ebd7fd1ae3e005489a000d912e6a7528fd6460dafce73bb8cf93b894245c2b6a9cd3566b6bf788a715c0da87af807ca5a8996824c9b8fe7ce6134f91bfc78934c4d9184b71e688ee3c6e67b5fa80c1e56c1cb0a25abe9892932db86cea23bba46796a60ba35df34cf4fab7e5328e6171c78d02885f264e75877edb5afe500ed59ee6721771a0ee3a6681ead0c2fc9a851fdd9cca86b4124957f193fda30455a64dc1f8587aa3083f26d6fb91094695dd27f058f52c0c6996372add63416450b510ac07286bf7d8efad91f1967b99b76c0e1b4601cba218091c6a1fe8ce792cd5deb37994de8cd76db27386070961868fed0d5e83e3e7ba3245f7596e1911519e959e3914e7bc9e988fd044a5cfe1f3bcb557a616472bffff654df53dc57cec0da403d4cad07085a29152b00dfcea7840ff805ff17f0dc283ddf4e7a238d8a184bf765fba90cf8829f0d1ace47826cf3511bf10f9780631e02eebe2be93ccee29eafcfaa77b6a913d312cf6af902950105b902903952f09bab3fe742b7247abfebf926ead1ec386665ca41d59848f144b40deb17256039cd1cbcaf33d3499d31a9d69cc5310f97edd2c93570352e29f8832acbb45177dc10176df02ead5ef65da161e04f7a1e211707439e4623d7c6ff917fa42fd9698210f25548f246a5d18d32cf10cce01b28f2ca9a66ee04c221dfc3b508c51a08eec7591daa012593354c81cc43e09b515fa452bd53279a614cd263b211780d234d8321f25c8faaa25c5dcea985996ee0cf1fd224665017798251f589362d73875b53920562a97c5e2e1b39eb50ee902a248add3273df4e0b479661661017e6bdb5a5988f9241b72c2c435c4fe27cff6685b0398c2128b16ca352acc1dac3360cc713c33e7ca34bad415098bccea9644ca5e96b12caa3d6184a136687c54b94332d3355302b0ca7bbc54815ab847790816f0c6b91fa211b45c0c5990299c562b1c791adb3c424e84bd090606ffc14ba4f0156f0320bc61d7a892d1cef2cd71677a3bbae4ce5d99c2f0e64768b5940e8d19f7b6edeee38ea830489b6e803b5c960138be31d8e655702aaf115ab09b826ef7d45522b2e33d310b5be8c913dc0d26288bf137cefd6ebb9c90aa4421bc1cae6f3d2e44c72edd919d61e14e3cdf452bb5cf38fd2b672e83e4dfc55e3bc1aed5b16dcd4eef2de91ff6532ae151de09fe5c99ebec2d7ebd6ac192ab2a248f454f1991defaa0512fb5227b6cbd1a2ea33ca8dab7d2f49d4ebba7bca225ccc21f88fcef53e1d3c5514442183671fe0241d74e7255bf5479a4bab46664ca04fe8aeabbd9527f157b1fa9621e75375807a0db2ba5a218537d52f26ce26c74d99ecc5992a12beff2971acff3d8965c75cc90c9acdb383b8533f3ceb97d44adefbf3c4a32891763b7f917951b6621eae3326d7e5da83d1a67c523fff51f5afa98a80f91eb50205b91eb05dc3d88e27824646a672b2b8adde25de4c7a00efc09f6dee4e1a40ac612ffe0639979d82c28ca3d6a21056cf3520af5d309563a23f6e2ea1c74179bf5615ff8ab0e349ab4de6eda4b8ccb19d35ac94d198e7a133fbb700e014238f7eb3aee4453b380f5642ed2c435e6468bbfb25d54b990c4210256eedea964344d30badcd2a23decea3042929e9e0306d6917da1bb46604332d81371d85785998fc4f3ccd0b7125d612a1477cb17faf954376369271835c0b92b0a98e4e0beacd344126addf762c9dd7263127aff9015c594d4c20bb30ec662967c25d03fa32dd46ed92ba9a5d9b727177b9158144cf8ed16f63c406bd7705e56c4f824eeed704a1f269ee3c3f2708198baa9f0b8a5561ba766cd458667a2c0304f3da37a519b8ed4a85a52aca539f60be0fcbf1b7ccf6b8feaddad18a32f313b2a4218e8c3d4c875e3c3c8d49b6cc714869b2a933abae9270265fec4440a88c704b04e18d3fbebab377c01941f843fa39b370a42c59ab970a6d25a36d85efa4ad850c83864b57a3903e15a1eaa210cac40ac5860a1a0f7eac9796be0c73463994e50dca27929969219590dc647f737a51ff936c2c99c589fc722e606132f3ec783aef13c0ce925562899b54429a6a91b8c0dca160fd9521f188cf7ed01991010b1f42f56dea7ea957158bf7151724b5cbef3e4d20ec3fbbdc433ebe22a6cbe16f8028cdc742dc825e6a53f0fb0bb4d1013a1669cad74c536f28f718f4a48289d33a378d79b2d20d81c41c777ecb05e78e768dddf1a81d34db704ce8f519385608b2b186969ec4f44b801a552da4f04b15a89404eb37549716a5c3975f052e5ad1fd21aa49fdd03199509a65e75ec377920b13fffef4de62647d6d5763e313da7b0034a8c010d7ffde4203ab8cb8ed3a382187f05019ad286d753342fc5069ddb13f53097e762a8f86e33cad516918d1336e0e36f107cce6bcf28d4c3b11db8d9845884d472662db5021335b9be91c46470d89c98f770bb9d1ea5d08e3c78f79a3f194d0f2475a3062d34e2ce895cae96dcd913a63d84773cc22e808a1766151c162c4adda02f28e02c8f4d4f428f64806fe2b6c1c0607f6d31b3aa9338e8a3ff1350172f531c9fd8a1741ca2c7321f8580e4dca1a09076a4d9a2626a998e4d5ced40023b66dbf69e379a81ec69b3dfc90085087bed013ae7b5a4abf8969d06c7270a70841c526beea6418cd181e13786833851c16c8149d87da9d01dbe87dd9ed99d059a81180fcb3a5e1974bcb25ecb5e3ee9182f4cd243395b9cd9e2d96b157c2882cde3c57d999ac2e852b7b832411dbd3847e44da58caa03ee371921a8a8c3a3ce02605be804d9f2668b2138aeec58c0ddb0b7f64c3ea493e4fb745340d0457cba6e7251c8e341f29e9d9940a70c41bf9ba17f880df61f0666ab09c555acce063a3e3b1e09c61d230bed16b7133842ad0504de93dfe65971bbf1a0963e0ba04aefdeb174e98893959fdb747d14fe08cb2cd9097c01aa98b668e4d021e5208919438329ec1c4c78a38a04f3a848edc4da33a4dcf4f7257ec9fac1c6eb2f72d1da56655521ca757ef6fb14ec4a2e20467c78aabe248ce56268390f2e99b8a0cf4458f37559acc8bd2baa6556de0a2b2fc2e6d105ee855095f6e8aa76072522237af031178eeb848efee8c2e5e10cfe85cfca675e7e7e9b7f12875bd297232a5daa915487318aabb03fdf25ebdfa317de67e729b57909c402ed1fab16105cd78924d9e9a645616b0fbf6c3c830dbd04d1665f653a9d015040be2b7b7dc4f9972410a34bd7fc5bfb48c2e021770964c3caeb874fd4a9a4a4e11e89fd667b60d46b1d7d7b9a4943aec968b06e554c063b96844937ea032376d5d71ce17920dd877ab824fd9900e9c05658da1f2384f21ff7069366a5fbbdd16e8ab3e3d1cf2f9c229cc353ff1390c563a0ef16bb3b3d9ee846a5da63ca21cb0b056770cf4ef42d0c90d7aed5edc4969609a565bd2ba74e706ffa9f7c5a617dbb89daa6cb89493224466722c1bedde02cd9c02b6cb5ca2b4db7f3ead63dccaafad14817605a5db5d9924a3f80a8e699872bd45ecac5f0e3c7d3b543a8a2c2cebd40f58457104edaa790c832e8ebc13e6200503389f8bb5aa9f2d3ba372c688d79ccc6a9d7921de10ba97434f302256b717a829da66bf967b8c95ac2b20635e968ca697d0ab3eb7e15a2558409b8e2c4410e537ae9717b76467969a094865cfbb391af08fb0893ca3df1f128eacf88d0d4e1c395c10c608b64559869c30499f3a30b6d55a4c06309b03365966d0dd149fd4dbe8c2fc062c6c3af975acb5c3c0b888306951630147ba4690de83fc70d3d65bd41cf4dc5d57dba4907a63960636b69baf687d449ceb51751ea50d89ee3dfcf33621bcdd872218e5115d3f0f24623aad3c8e107b8e5ac531376adc0aade8336f4519d3ee170c8698b02a49e02bfc2cc4d674d025dc7d7e0445000a9113e84f5813a63fc3ba2fd4daeb35164844149866200be7150e3b4fdaf09091e958d958258a37f33c362e8747abfff19e7444a39cfafbc8545e72d8a638b20c7fc761c6bbe232da6c6210cccb0534d169299abecf638787e69ab701a642051116bcb12fc4d0bdab100159a0141f306705fa29e3cd226903581bf3d22d3b619342baeb6a81a407a6c02a44f5f71666097d0cbd9d0a99fa0f34f7f78433b15f74aad2c3d5877c38046db9fa26c0559c29ee3c3fb900922f6226029731a7fc53b51c5cfaa5dd082e55afac8975d54483ea54a74ed19de605ee2d16ba57dfbde87f86457e36d518892b32c597dd8505a70022d6cddfe1e628d34310fa35eafcb1ba93299d68d5acb55865b705ae6e7233829a7eea04311166b5733245adf9453fe47db05e4721a9b24984972fd59ce53822e9d737c69d35ba7538aa9d32b58af682a591530b6d8baa0e6683da0c01468e0b42dd76960e9788d70e52fdf93ef267ac6833efa6810308f74bf09912222c37f44a1ec6269e5ea37fc98631a188f80e01c2e9a9056a5a97e2a2bec2b5a503139052e7f6eeeb2d9a2f705fd5493451c452ef4677321661fa688bd22fc4f42a5111b160ecc70f02229dea848c5bc876e0583f70830e686555274fa243384b45562f896fbd90e13e1cdd907b67ecdcdbbe4d89766a66d22523702d5f0884290ac2148d6b322b1e0c9fb76f233047e8e73e451e240a36d4c0c06d0d0f810d3a3bbff5010464f73be5f369b2b124924a5abf7cd642445a25c123ffc15195ba07cfb86cb2e5912a981081dd71383a04ec9eb8b6f3ade6eb2d5692c84ddfaecd6423efc533da6588ae7fb7b2ac826bb5e86b259ccb6dcc38289d7feb780e47002293911d8ca1dea9141fe1d38581e64f90a2c5079c22ca99da92491aad67627711f7e2881645f5ac100eda40cbfbb714e950905aa03aa22192c82046efc6a76c61b4dea08c398b37eefc1a4f52a7dc90811ceca938a12e14e714316023b84191acd2414ea51e2ad00505acb3dbd0d271ef7e20b6e4458568df75191086465087e49e7e388856157b493bf7d7747415d41f25df5a72da9aaf53be47c015355b7bc11b50bed6d2dc2d307bb1388bdf448ae2f0fa9c86e1443ba1363fdc1d5f2a28b4d26a9403f579a14d8e6e77e133289e60c9844069742655de284760f24e012f41528be4ff6e7e637b7953787cbbcba8f1264891da53a7e39eea6df24341ef2fee32a538da22813bc7112f2299b6922fc682364e744f901dc0773828623e086dd538cd7d8b6dac086839e250ebbc3896f207395d396e1ff6196336027de1175edb0d9da2296d6aab53db04f4a6780960c362382014e3da29b71ae0c31e510a64b4f465ebfc03e655115646b64d93610d4bef2cae0eff64aa5b6877dcd703b56277afa679f0defd35a7ec9d5f2c26fc9a994df167795338d36069e082c000542c81a13de107865cb83c096cd68d32ea0b884d4881d86544a7738cddedddc51a4a24990f64bd610a1e21052c6a664b46a37c74b4b8f5d9b97b37c4c0dd9a6112b80ccad09f71b5d63edcbc0f27dd712d9eec162db10021d5277d3f44c07a167f8a167b8ad8279be08e760a694527ccd350b692c7849823e24cf1d2aaa56bd795ad74bc95d69c7629b57eeb45f683939ffcd3ab58617fd3093d93b7ba3b877c06277d364999b979542300507e3b19d13eed8e7af73d2d04dfe02bb46f749fe9e07455b813c5f24ea663e98cfe00167e7eb26e0cb22f75396a47b2dfe5768c986eee39de3e50a4061f3063e19a431fa35f7522aa6f2189a22f5948646233768131df8db32ceb2d5a69bfbd69cd776cc018f279bbb7034a773585db4b8695e6cc26f91f90302a0160f3f935a593433a374557b1bd659f66ac6405734c99b3675690a7486c4cdfb11f83a29c66c48a1e1c80e362812458c617ddf8c7c6ce7e0d7f2ca50c664e03f7ac86885a8370b8c33af9501cc01f18675e20747ff9f98b3417e9a963a72db1c49733216f8f2d0cf1c22a107c818dff6ce5d356a676aa172b052becc6e6883a8d3299e2bf55994e471985c08823985e92e9558cf160a0acf9256c075546e17bb06891c06c59711e4b56489c2a8207a9bfa3d2c18bd45af36e21faf6e170dc5b294179eb607e549044c847acbc1e0ce4e28e641ef5731c9ad2c4aaae159c78f9edd3b9aee33b7d78aa8ddc2cc27afbaf995e2ca87fd7ee9fe6537b937d85a786c1a8cb75ebf201b28fae2d7c52bd09c21311ca997050ab4d3e5e0b87188e28707d9056954239fbae8e9872f74bc3ae04a0b511ba9ff8e81ab315f3cd754852ea1dff9badd9fcc8aa03777234908c1868e200c4c9a35bedb2a3b7b58af6cf35c189ddc3e46d0680df0e97b3d4c3846064e5de3a80d8de8d00536dc5947429c5973ce85315759cc7b65396451704904ea069f7a504ea8176e5c5118180b784b70cd077833380163dfcc9a80b839dfb928d02aed39a8df8e86ad971c0aeebf7170009e02e06d71275817c7116357b3eb81f430a147da317c4a72cd8fdfc90f42d32f616ff947e508b15f423bce719fb56748603078f7df378778622faba495d1c622e99bb86d6891af1e78f94f12bfb5a21ed93437d9bd56ffa315fc9c46150fec734b164f7fc4dea1d670bb7b002fa9c8359c9749875c79df31e7331fed2d742c31ef9d7f92514534c5c5a4b6935ab920cc01e35137d914c1e9d86a15a4e20e3b6bdcf5ea08480ad3c1edf069a590a2d66f0f9a5f68996186a74a58cdace1336bc436041330642f2fcbd8a2476412c2dcdb26474ab0c598aeba00faa49c0cf04ac3c5f9bb6740f27ef5b8a62040bcc02a99dbf685e6f675d1f17ec360860f552d1bf171e1c9e63f5d86ba22014bdfb309b10bc6973d563b8feb5887803b1d66d738bd932af4b51d791ecaca7f98bb59869e904663899fad5a82db884dc2b45b15dc845fc12bd1f8488a4b8aa29aa5a27f4fb46cd62a8a41e4f3a7e61b4256b953d76dbbea4ef5943e9dc552a21664b782a2334cb6cd775e10e93db0f28234b0bbb43f041d77472b15018283f28d1889a29b19531ae1c44d5262c13d9ee7b4ebd30e04af735bd34f0e46568ab108cbec547368421990f1b09b46d5583d5fafae105296514ae86e334839a1ee7c0fcc8b2c61799ace9c435fb111f4f8d9a8bcea7796f178fd5cedda6edddc596c40c0843738f0499289d5d72d356af99f88a158bda7348a75fc426e8561f6d16b2e3801c9d64132899b1b06376c5c0ca8ed0ce2abcc2ae799ebd326954be89b3a356a68e7074cc9ab0c55fac60e914be3090d5ee898da4e3e89e6ee2d0e3d622c9eff7d3eb034677ac46b4cb35a36d6ca3ae076ceac408d2fc9fbf655e59a96f055cb0b690df258acf5326a3997f1cddcaed6a89f69f71433f70c81e3a9a4b7c9578cd9d6dd1318aeb8bb3b45bcb227748b42f919b85c9f4069bd13f23b635a5156f3f462c0dcb7a66a211185b954adf2498684d4d6839072621569dda04efca704cbc8f6fbb280142b6eec86b24a8c5537446a63bcad57e95cffa210d5a164dc8d1bbb815b943498d95b984e25f260508310b4441ab5b8b8b7413ea22fce1637c2ce754759ae42bd6353fed2981cdafc097163b646095e63dc244bcce03410632d01f5b2919c003b4ba9292dea96ecbe7b87b3ed54f7b5ff16b093a83de44811bef0cccc20537054a3d9e47b20ae08457978a12c2cb60e978ed89d2bbf8050f585be272b5343796b2999204e2411a20e3bc926fb9ac4732832d7a998cb6880def5f468ac38021884d8bd500354d68f7954c6297d516bd81e9c6dcd9d33e54e899e6640c8b8a3751705ac037fa4fdc7e9a22e895d2737a96eeee5350cc6839d33c39e34776b99670cb50409d4019bc98d52c2d3b5e6c847f23ff2305a1524e393d9729f198e29585a7acff6d89359006ac509c4baef825bf36b41759339cf2fc830f9c9cdc6ce3d6ed49aca0d393f5a14b3192fce5620fc2697cd8e40946df31c229b8c9a3b4eabb46a000f40f14cd2c352261983175646df973e058baa2e98925a2939c041891738a8118cb26fee7d8da98708b38e388cfcf2607f1eb4c613cfa119fdc220431ddf9c6307839099b0f431294d7fb0d4d60d99df5932fa2155f6020587e4fd5867c50fbbae24b4ff6be79cc256d56a487e6dc9b321436c2c1d83aee0fa4ef33991c5e935e4aefa22ff43a8934637c7de690c47849cd6c6c41bf6011369f3767c4c8c46b25194979ccf1418a56d05c7db04ffe379865343ff14717bb6596075a14e0803cb162fb20df499e65e4b2459ae490ddc05f296c90b3ae7a6a363294d4124ffaa912970dcfa261eb09bde2fc80a88a95846992a9048700479f17d066bd96a8ec6a8775b2424be559d8ff659c5f8981bef095bc21201cf334caa74129bbbbc25cd3c5d73fdbb532a84f5e14a045007c57d0d32b857c1d1bf0c1821606eedb38759b6b35786c98f93d99edd6c8b06073a9d84ede38f8aafbc0692b79428e926c133e761fdb0dbd9b911778f27941b3ad073d91d6f5b2011251c71d49021da475f9485dea9e1cbdaa2c141df83fad580e003057695dea7d2c0cba2fb74c83eb50e7c881595e0f1f67d01cacd1919417f2a7e0fdee8e262c3a1b2896603fe1de1497537731d504545f51be6f3c0e86dbd729f0052836f512018d2305ccfc13dcd01f5b297066828fb471692e4f208099f656946ec8848016a8fd00afb188eb8d5fbce89cd1892a925fa5674810a17607092d323d7fd6b7d280728f72a4d7c0605f74b8858cca58e3809d786b2ab2a60b80f5987a7f3724a36b281291a738e509e2e195c565982d979a20726b565b2e04c0e3b9fca032d683a51f9c6dd876c60ec0e2a87dccbff26237e2c97ec7d2c8abe3ea41e7b423afbf9f06545d2b2374041cc221bd2fc08eb79dcc17e9c0c2cabc0d438a872f07946f92f555f83ae2a1b6d1e52602d3862b0276ba3451f0499c11757da76a214db470db1b53ec902c055e5d06968701f5229a88bcafd495a25f2eaa5007e9d7a24fe83c4cddce36977bddcee7fbb9f5fe3c6af4e3b2e89d9b1d2736bfa93ba376f9cee278957c72d9f4adedc2537e1c7f844fc7a5b5f06cf9502383ca8d78e5d4726f9818b7457c09a1b69fe6ceda2e305a6ae4e1640964a7b96d98cc432c8cdd76efe5bc0c768a505aeb6f557f892d64b38d68b889d76d9887a9e209fbefd30916314d100d799bc41323d3395bfb029fc28c83aa3143442fdd319a9ae38b2448f5adcc8e5a4d6809fd620343c4b94fdaa92ff8cc478d0396375b05af6f46658cd5e8b07854635eca5fa5c52c2e652cd212f0266ff080d07a91375c8e7ae951c90a03df18a18054404a6342bea2c172439d9135326c1171e6c983c8b9ca5565816909bde3c71c917f561172db73c3c6c779df74b7a8224a8904b5363c86d49d4af13ebfc73b98511262fb038c826ce426325635fa7c51b58668ba5c085c1e5315af90360f70399fe1a7ea7c12506c2ec8888ca5ee03d8b27d838c746090e8c55ac73efd151dca3c36751b430e5287fcedf4905760ba3e123f2d4bfff22b28cb9bcd660932f5800019742d03c2da22a1d7ebb6eee4d90c022729e9833c0013e1ebe51b778f058d76a1c868c89cbaf21767f27cb518c1fe186b06885c1367cdb9132be187be393c4c8ea3d849b2a204c4f445fba6bc70e3f933727c1f561f845c5fa41d33a729644d790af874e5d4451aba77c0fb95a040eaf5bc44b3f6a8b2106ea918a8c8573d37aa67ca4c53bfbb0bc38b32c83d44d0848dfdd3206b62f6ee897f0f328f534706ec76833a0770d2b67c1893a66d8432ffa02618eea5241b14837293b222a6cecc172288242e165505ea2a9967e8ab6198af034e57548415170bf3526c804196f50118b3941054580554779b2cef2f023c061a5d8f24e89b3d203fc707d788120effed91870b5cdeee3093384b474a692a4852fd8ca60f9faf1878dbe2263b8a427510026257ab94328eef9e0afb739073cdc13ffce2b97cca21ca53e29fa78475ef89ed4f17dae3d94fc1c0e63b39fa8ae9adc232e421dc2870c58ccacc1e14d572c44e269c422fac910dc0eaf35800e720c5a9d996da491833c00da1e3913d497ac0d0bcad578ff7c760be0feea6e283ab0562f375481340ebcc7cbb981ab006a5da0a2e127bfd6fc87973abefe8f7235e3cca955cfb713ed98e1d54799aa8f44d8b62db6e7dca851de3b2e68d6e9e8fee1596874100ab700e9ff2c4d823fef73e9af201f4c2cc35d5544a862778c4d9c6885a0176f7be36d7903aeb7b60eeadbf763d253f4d681720fd2a43d199b9a71439aaeca6adf7f0b31479abb976ea21c1479950aff385e6f06fc7961190a6587b7fa94f0774239f170180ae2455cb0629f78dec5d1cec3bfc39648c24e0079c03268bde43db66eb00af590d94096f99130e9b6ad652bf4c76359f6a5fcf7383ea108e6079fde1302c52452570d1a27778aed002509e004cb08939b213275c416fc4fe384913d639086f1588da5a01811a66691c265da48953d3fce239ce9e2c58fb46bce4d59b8727e164e78d0c19f9005b04bc1448ed87a7c5b7d0e1815e0e75e126a0ce9c458931849695349376a130e6d9de3d65f2281ddcd893a7204209069586fdc425c2e180b2a682ceae8b11e64818a86351f7db91cdaee22e0b64a40bffbfd8d7e90a0804f2b5dffe178d0045a361f5e2405a31b0f7f8a9240987be020eb0123c7d3b60a9593b252f1d264cd045e9cd16849156db20ed74074e37b40f4a0e7a3373f72f9812487005b5e7bc0a34307677c701208518268eac6b30511ef570e69419847579d14e96d3be78133265e0d399ae80c879e92c67413b2b5bfdb785d02a5fb1714a17502253867b8584d4fc6f10bbaeb8e035a1bda33b41ebf4b890901324e5707016a89596d66f575870f825ae993339cc4f64f31888402155826cb18760785a6c61cface6265c5ffd9a92c9eab52369c6c54aa34c1ae8cf33680f08a8327d1f7b304a32032c05fe68625746983b7d251266e055fb737817ab80aee44313e1cb2fa0efb4a83b1b13482e3d291eca9b7849ebb18940ea4ffe6ac9312b01d87f5b07340a7e153b7ef786b042565cabe867c8268c29294483d652c97163e06c139ddfc599bc696b410b2da2f05e70f29048316697ffb3b182ebe7ee433d400a754176f0b6fa3d493f4266fab467325971d280b773d1f471781fb8020e8dbb92d3c7a8c6dc3b3e697f1eee2b868ce24218edf17beae0f9c022620e1663e03c546a9ea9132ed20c4b1a15d9aaa2d5d58ef4d08e78d8b3114ae7487349ac057a5afbd27d9d616a64ece87328fb887e634e0f42402d2e9dffec4e0c752d058dfd6d032785f59947884fb9378a9d2838875d8aa09282349ff2ffea048f93464c4406f8a67f43d9b9bdb9534ae1d64abe982257991095b6ce305c5ffe3736a26c387168339343345b652e57868f8cf9f6f97d160b7052aca3b60c375a31b5d80f27688f4441ed7d1fb0a635419d33de1bd01c93cccba7cf6592605754cf145854a0932b9df752507c2665ff0cc29b99798fc1f623c53ef21cce63498ccc865f84bc2919367a4842cf9c43f4dcc910e4a3afe65c43a966fe8866483a338b714e5847565f1dff652f7e0310759a0bdbc58e8f920f57d59bde88dfb74d500f28090e8e4897846c74cd86bcecd81b439c5f153ccdf66e54fd2a913fd3b3233d6aeaeaa1deab468338cf85e528a427497a0afdf77a47f85d33b3e4cfd972dfc9a8dfb1adc08db4beb6a11b13f391935104aef74fdaad5d9ed4ae00656e5664887eb718299e4e6ed7d79ee1436d3ab99a32fb2face345b947fea1d14d87a4f850a48f428592c06db1f5b9f1ddc3c70431dcc9758afb4ad23b663648af584d8d0a5eecb31b13e62fef362f14c81ee58a9e341978bc5117e9992aae673d9db54edacec1c6876ce00fbab92a3b490c4a2f257612e4aede49675678be2f3124f99255c4bbeb9cf1cbe07f8916f8c1b068b64f098bd10e7c958c6e95e90e3b628a7429b9eaaa752915f71e1fbc5d169073d5c9e7cc3203eef8926a41341e03e8a8d515a43c7428b3c655ae20bd35c00cb9f5a0da0bc18e643060d509644b90a46c5fcf2c730254d7db621fbc240e9f8dca8dde580858228615557d1ef906a90ca6486869d523c63c3aaee4b00eb0905803947628a0bb37bcbe2046271ccf65cdf3e027bdceee675978c52c90243853c7e595453b0714d4e4c8599ab13658db5c59dd6e6589c417cf8dc17019940cc8075927c9573c051092aa8338a4247d4d0079b4355a8710cacc6ecd38832adde4ff29311af4444dd63f9bc8e9e0bf675520b262ed1e20e85285d3689cf2574237db714aaa2d8f73e0940518a67d7556a9047570aa7c7ba991da2cf2fd5e31d97358561b16a5d6cfbbfb62bf0b9582233f00f71b8efe69d6ddf9d5c60c379e2d824ed17cbab0dbf2ffde676c3e5e08e7e5682e951f638b75d807ed631e37b42122d0ed30dbc1ac897f288e3afd6464b16d447a9d4827b1830d153ded14bf503548ff8ba38696bd27e26b9b6dd97cd73b1fbcd784ab1f23a02e500664f902930106b9028e39dd98d7d72baa158b255e3615b3bb22bb42ca75d3976f8b07e359a7e792feb7d2baa97de295b79aad19773e129e7787276fdbd395990f15c3a31376f5321f56b8d1f410bcd9bcda31569f6d10a435f02d71d795f627d8ad745b37015e1b4859709d987763c1f84ab27506692f871e973273d342ce45c9379999667a80650db493174c5bd4e5826da9535296144369c913c0937060ce843ceb663794fd7d590163a52bce72b2f7a171de83bf7bdb2975f5894d8b28068ffbb690294d46475afc72b468f4e8649758b98c85adbeb5238cbca7b90ff40e3ca65af870ef41ca624f12c31eb960e32c3b88f7d3b7aabeee1d0944346833c110a77deb579f8a0ac1b5dd3aab94d97de3fa2c84322d47a675975da54b0bd69ed2d2677e56ccfb530a67e74707110bd624d49316f152d8208ca252681a1ae2131aacab757bb448d9b95d090f0a03df84e8277eeabedbeac8f43213546d5ac2d91d2fd891a38635d2d4a7c71d0572b0db2a4660e7605e0fb70279df8b53d5a28bf3cd39ab94c6f9805dd04b66253263165a763a21960b649f16cfc5c7db40810b2d52dc269377d54ad5319074248debbe92378383052dd10c2ad9d34268b41729f5821dead3629ebc04ca58441175e99d53ce81cf6f5a6bbd87325952c5665a199cac8f26e4b15895a33e478be4f5144db3d4ca570e9d6bd8dc55240881a8d60e43a721a962590a3d0ef7b0d25ab7f5883f325688913fa5bb7e577c2fbb7c3455c5ff1b44fb760cef9387bdca346f66cbde735904ee1ef26cd866b8ae47640e860b1aa564ceba16f1c9f8361a1110699afb1f30db5756c5e63ccf479f88b13d258f5ed1c7d23eeeca6660a0a96d425fe0f17a6f09dc0ab6eb48393d7ad60a6b4a1a5d1d6e26e2d3527c269695d07d7cbaa84d2fb33e4fd0e8f91eb50206b91eb095c7bfe6535c8956dd0cb209181d44177ef7082d12c457935508dd1a26a193a9f96f0f69574e7be5e5fcb50f5b13d3b3b33055457070c2302e453c475db79dc87c340a7ca677d9587aaf7d373634ed6a76849d3b7b8437cab3e696f20bd92958f5106e83e5ae89903ef07831f682b007b1d1b20e20e42eec5f2f3540670f55526d9e28ec181762cd23310507e2c5d8bb8efbb1480f8e7b021b8098e36829e01b511de6e13444e7ce21a7a216b54b36f0599cfcb8f4e8db1523a04bcd3c24219f63bcefebe00983252101979b2b3b1c4049953cec0577ecb60ee3fb59d7ab724f6e0ab12d7e394469f10aafa10c7e88a79c0e9154114ce334e96a1e26239d1e14c93561a90d74807b51fb8339141af106f8c46ec12a53d5d16a8efbe53b4eb91c94bc0b62871c3836c36d447a7ad44de04daa683009424f4f4522b2ff70f75df149b1826136976f6fc0a48cc76828631e7523f3a84be7dbdc9b062e672091e3e24efff7d96d4e7c5f1a9f8c70d011662630b06031c0169e0e1e95a636d502193a29b931cc0b10a0bb7eda452dd8c506a28c47f59391c62203660c2e6c6e39e6af841917f7bfd5f50163a7963d8e4eaf094551ffec9dbd3927acafc53803c88fc2614f4962fe7bd2efe3ca45431f8df3b3959f1be76ec3bc1e5b185e3b93fda9af79212823571f6865bd7b650288e1160fffcf473a94f3ac6736af0ba77a0de412d05d895fab00d975bde89f69f74ac9b9f28de2526cfbe40c243e854837aef3e8557d5790bb29cab5847272712ef21865ae148be13471d86c1c6d2d26dd20acb9b60bae2b388016958b8fbcf2cb3f1e6f8111cc8488d4484b5d1f0798e564984b1b798b9c729693a97e5a3459d90941ff75e582539906173cf43bde199e704de2be1bbb4f8f4154bc0b4a094d779a9e62f55fcf3dad173e8aa6dc80b70c42a6954e818a85e3bf468eba7f6629baf8fa9dc370a7fbf98f4b27577cdcafcbd87b23e6d60d16ebffcf29c1d82507449fa4666fbd1a1171c0755c384d305310a4b32f1441e46d6d9eca7ce608587a339f93c9f0887e143f2aa7bc786f77391741a52739229235f60555619a61282e6035e5ac163dbfc5e73857f3c769eb5dcf3e45336e1e8b0b6f202666e5d7d63c6e832200a11f3ceb6a8f3cbd09d38eb56a36f1e867476682fc613b902717cf6b5176b30821bc0c41c1ef4002046bf6095453177dc1116e4c5f56b329cb85339eadf4c1fda999988df9f148cce8dd2810f604ded74eefa13b90a8ba62f539a428df9b9d10538f02ef3b66424942e83d2200b94530959d5781e0abe4a4e0eefab4eafac726b3b6a85ca7d7c440c1623a3ba05686409bdc56931525ecb9a4ecaa35ea6987731bd898be133b0e744471f706e8b0454339279b4cfb6c653a70f1a8ec2f7e6b53f0f3a2240ce9051766a7fefa95456a0675ad3a56b4f90d64286498de54bf22bcb9ea5abc1fd2e4413f5f638152b09ebcde62a09e1db97964d14014bbf2777f82d467f646b3c6d350f27c819455be3bdb3f60c5dbf2442c5ae9877c679c6e133a06eb95f8633c0b5acc23ee9a90bf8afffef5f52bfa4fe04374ef83b50e4e69ae192f362a96e1419ee223213bb06529f0cb3514a55f6901079027faaea5bbb0584679cbe1a259fdb7a615465fe44d9d3538fa0b42185d90e003e98cea71eac9e34139c4cbdfe9439551db175ce612ae35ba1e2d8fc0fb8d721c6371787c6741a9197244503a0a51c50b93834c13ae21bdc8be696e73abb0923ba4c7bd8a628c47729a4a56b9f26d9eb5142b4e248a6e172de7fc66406ba4be9782f76d2f3dc7cc9d5f443dffb23ff9688cd87d726a98aa7774ce51bbaa8af91eeb12e44929ec7f1546caa78b2e13f23b932b85c0fdafbd7812626e79a9a6d4e1b7ac62007019c9332dc6d7ef78e0644c2a1e49f69452ca4bd9b220308bde21246dd0bf7636f9d0e79b2aa09a77f80e0267ab2dee95ad04204ce10beda00da17d633114e475d98caf652b7dc60a77ae43089bdb4185a8ae616a679b28877e2bdc6cc90c8a2bfd1886da8ac8d19cb72bbab4e12a6dd17fe39ecff3f1e8b2f38fae4e65a9251ed07cde83adfa23b3aa34e8ed19eb35b353dddf6d7675ff6c9315cafdb157f3768830f9d423640fd27de8678ba51129dd591e9617247949a70de07ba298f2045b5faf797f52d4024bd83dcee345004a95073d394780f4884058e9c2f78f5621fd036e5d092e2497e8d4d68034a4bcf61a78043545d19c5d017969664805c22cb6a7e9def8d4e4021158c26a68bac278fa139f3f5abcaaad4a3d9b885fa983180bbb92da726285c24c6b1422f3bbb5c85b56bb93592504fd7b53776eb2fbb21aad97c567ba3e55fe423fe35e1fcd11dbab5c0511a72a83404f5a48f317f416df2651e250f700c317c8bbfe60ff49f294c19e43e678582be470a030f707929fcafcd4f56840a3346ab89cb7aea6b096eb262ea99758873d8abeef54e36bcdd48a69186c2d952729f3cf5b7eb69d0c26e6312795c3a60f951a48e71f59f16de07f775cc1d225c04da36b27969a5963c556ed2addbe4f7177586352079675e9168fe52337454042fa5b3d30763e6b529bf3354279db801b14532280333fd3431c2d0a29136f254d067b54ef2354999cf9e9242a35e5fdcd23d10299cb6d38df966786ae1f5a5b13c4d1b6b911a90e5dd694550887a0df562e8075c1c6302f37be45cee5b44be93fda12cadf0b7a558819e3ba648162936e883cf792d233e1ef9b513f9fc6ed703c7d0d72f4974dabdde3f9d4d05c16f6b390cd9b5e32df8f557865de6da2ad26e7bdd3340e84ef466acc060ec8408af446837f08dcfa897470832ffd6b483899cf8397e89f260d1dcfdbb2fa7df5a5f4f4e818e3d2d0cc98de595af42a6e4dc3bb250317e860619871eeec376a69d755305fda3e6a74056b0f48b79b1f284d321c9b5fae16b546201743a36d5e8b90948dada117181d60fe8368ad41844990385872af8fa0330f88450ea1cd0af44cae440fb2ab9cc48032d0f7f21396f00e352f67bcc4efcfe8c41972e393656a5624a6adaf746c9b6e6eb4112cf090f07bc1acb3d4e8137ac05bc8664c00054dd2ad68e88b2a4fbde0cfb45c010a62e6d51807921075f22eeb6f8de2145f858336ae0da3847a12306f13363bfa94210acf70ba2fb1c8529538c3f3afe99f78c7127b1bb9870d35203bcaca68d96a8aff42d89a3061128a11794c55c62fadb66f033d96b72fafc40e066e898e19cbcad4a2d46476b10879965ad83bb9664253e3b68174202f3362ab195d03c779b759d6517914fe07d27964d565d22892ef4bdebbb1d6ee1a36caff73714c890db4d47e0fc71901abf0b43c48aa1787c76dda42639a14b3d2e8c494ff59098a4eac1248c1227751402a87285242c93ca68d176c4b985d655891a95a90ab3918310151ab83ad9970799ea8977c3ce69fa4c851b56169302b5df2b30c99f63fcaf55c0447057061c40f4ea668991c0f4c55b5e82f228479fa7658e7b42482c5a4303badd492b3e472150c8a159959d4a758444d199281893ba51a4941dc324baa1e58c566f9cf359468bc6ab9cb19727440acf1220405a290e5244f6ace6ce90714418d95c82b90ee6956231525cc1e866370feb17c32e85e2b3a9039918fbb7c8a2a778b5154856afc76258b343a975089f676f4991f855aa33444096e45d3a940d9672f3285ef3c27e9c02228faafa2d918545a161bbf4bbbd5317c46b13e772e5b56cae3a156468347bae22ebe1b96e6cd7f77d0224d1de0e9917a59bc00f35a233f09a4f52fee85130906ba35cee3555f3eff32422b54a3dedeb351d57ccf4c9e672c628e7eaccef010a9bb6f134e922239e59a4f707438d9fd1bd2050dbb3c02ac9b95d66cbe0bb9f14778b889ba77737cc988b82f4a5a897eeaf256f0f6b15e06f7a83bacb0497a4190831713f86b68d47e5f72c17e5634b513cfbf39ed5991d6a283cd542d4cfcbc4729bf05e197779492e643abb4aececf98911db17845c2a3879e44753b10e13cf3333efb001805bed588ede98d872904f02563a4c394ea0f212d86069f003ae9356e57b2f1ab225a40f172743a946492d5c4c39d3f52329864c9e6ae6e4801a37282304862721123751fe150c1430ba6631d8be204ea881ce9407c1282af6460facebba7cf1f3e45f40fa888767c3a8dab241f854c38fc4439514ba54f3df8abe91f9014dfe41ef489eb0a6d0cd58771e9e44751a532937c9c2a14af3a6dfad5e2eda7556bf741a47db933d4dd7743a4f4573d12fd9647beaabdd0718c8b6a104da18d0295533e1b73e3270710d7f2aa9c57c9269c9591b25ff68de49b489be57acc895312f6cd2c92d806366ac7b30f28131a46ff4452d0744e3f612e251aa970c614e968cdef2405b516a5d570efdffb3017bed6257becac7c2f32ea1861a615e69f5c60b6613b6136519522891711edea6137d1fc8c91dbfcdfa3d991cb213a9c866f3f3471ee0144af6294294f29205b8eadb9f428f6e11878a30018f36c5316bc915e488528bc2cc65f7944ebae84e996821ce989f2106ccba05031774dcb42e95263753ab1043936b3933c9fc62f58b483eb1d106f4ce4e06ef4073d8cbb13e65818281bc1bd0263345f1c50116d85576a2063a64930cefea90b7e3fe6cd52f2058aba5ae150dcebda45dd632ecaaddd218170df1351e6ca83c1f459e1391c86423c599658bae24ae70d19a0cf3c4705e72e8945b2730574c93ee911ae63795f1daa18f84cd99b2c3989006868186e0b42fe98190b75a0b13eb9a988cb40936061b92b49c814e939b4ea10a7d0be914bee76ca364436f669060792f26fc09e3c29d1e416b3864edbdd8890427bb8d89bc549ae00b7564c2eb465e2d4e77d7866b294a85df474a2e6fdf64573e4431ef5a00077d9bba4f18830e68cd3c18899bffdae0bb040d48d4990a47ca563a602b572394df402b208213cd9397bfdbb72891dd4532f1dfa4599df5974ae70228541e543dc927613fcf0b55d6eefce705bb6d67859c98106aff020d96abe410f86617f006def178851353a4dab4ae62e7175f927ddef93116168d04e6a19cce858d290a3a971bd3c0c0ce603194572de20b5aceb3286d24214a9397d5d72bba1789a77fc5d44af4c05fcd4554cc07fd5443e1474eecff2c8868a651ba3f0663bc515bb4d7930d6c4101b1512d088525fd8336fc7be6d5c354b0b7e8a4c92ec70be28e83f8b2837c1a97bdbfbc3fc84c61f5b653f217e6dbaadf397aeb15d70195f36993baa52fe88b9ccb5c0d896ab6fa3b2b3ff31bcd2300afc80e9cc5621b577ed7e25169ca72ae7e4e2fb25072607cfe7977bd13788473db51d243d3d3d165a52e2a34a46f06fcdde8dc07750b355e557dc4d89b726a24d08df440e26148cd90c2d5ca6dff7e531ae41955620b4a9d66ee2b2b72e8c0eeea02cdc27b5254604f84bfe2e935a37219f2a29b382287e69e0c241a824a0048d175443d937a341fc5235e755619d3c4b86eaa8fadbbc843ef28cd24b1023767892512119d058dae01459818fc550747d51e93aae64dc4d71a6ead5788be7c939cf0f123c33f2f050c817d85d0a8df4a409cb8b5ca0a18c8e476950fe58b2be7c9f510bc55c5a68f01b6c19a33cc6c7db8db850e05d4bb018c511fca56727db44a6645aa646857c8330706d233c46338716dbab0477e3b9645dabe5f640d395a48dadbd69d74ac05b30c3309ced7a57bdb826d15d54fefb8d9bf8c391f9e0a9e223ffc7d0bf0b8bdaa16d981ae6f8bb6dbc3a737f7ed6b8fcf4f599734d923691dc5d50776ad9ae0c47e669051d5ae67f40a56e4f3c7da05bdd9f776d8585abc69756a6b1a7cb5e02d2fc006614dbe5e39fd9cdf1ce237403db0e9d7022d099314593de235d8523edf0ad440566bba8f6efbff1773b415855220045156d9b0e61845194ada577a0e396b2cdc3640969b204ce8ba432d1822c7a9e052b8521535c8c74b4b8b8ea8b47ffe5ce2e76c90c88ae16fd1ec36eb5ea6d0b19c33d16f6643e154be9e74f3d4d35e5694ff7a693c4c930795cb1d3818201bad55510924a0727f1dcb473389422d38dd08da9a21f215bf97f6d9cf1b04817a0a060fb9b3a4a93e583cf728a764394d550f265021627b36f7c456fb375e2d37cf75297a25b79df37caffc6c76d316f832227c6706c3fdfa4e56c3f9bb0ba02db383eed3ee24ea3f23c967ba50fe70e757bac7a2cfd134f83eee3fce900d2dfc71c1bf1dcaf7669909187cd943db32d5b88f9ee6261b5484b5bdf516515bd287557035e5a2045ee38f0b2975184553794896961e92b409166a870d2b760e4129f3d558650fbbb7d275f7eb0261bb0c7a4f689f4af2fd41f1cbe0b4c398ec0b35293e4f4154d46be046300db251c1b42725c35799b9685ed850cba57c72c11c83f981267c836886a20bd1b1bea1bfe03156da1fe7f1e3a72865c584233d1cd43dcd67866ad82db47f199cf9da736ff10e750845b649f35f071bda46625b13268bf9c83c8ef674aed1002d53ef76b26064b58beff1438c293f59b42bd35732dd27029c4bab2e90a56f115fb5a89a219c7d0f9a305cf5f868c525ec3659f691861a8a84af0ee1c56539836412322ec4c9b589f0c59798b7cfd47c61e7aabe9c9f82d6447c11a70822494de5cf979d9b54dd8294a986b2029f23a34a035ee350a10a5d9815a41c7516a27dc8f79d0bc1c431803d011270d01377b003ff9e152c6b169ae356eb82197af6169e86d6412fea973991f44ea2566ce518c5d51266aa155c725b57e78270e80d76fc5c03561ec9c929066d07f32309d61ed8085db07a05a2e141aae2adcb09f6d23e7df6ed025c6937837fc92b24a07ae93ccbfbbbdb50fd37e7785e19bb802becdfdd63f3eca3b01868ee2a2fb5283b61d579fff194a4747a7bd94da0824a1b1ae9dc6f081a6a8d8b02c759f02d9a750c45ae8de157e25463955362e4f9dc00ddb0d0fae48f7b6e7fa454a4edd09ae46d2a85c8274662561e41b81efd1adf16502d6e0ba3e5d7c4f28bc766b78f9bf1319533a7e22547794a2d686abaadad36cd2691c3aa8d15867e63a60d19edd19a9f02d3e3b4f88cf89b59c6d99e0e85ca05e2e2185ca37c50e2b456890cd464f9f0db4a38fd7cadb86afdee4299e6b8b9fa2328f8d78f8372ae9cb86fcf28b789af804a069a803b669e1d5c40c6879d02ec2f965138a609b309a26be397c93ed8aadc465e20b0c501afce3c16e3f89eeb5e79ab0a1ac264e442bb19bc9ea02e307f5fc2c5b46c0ec1cc7bf22682ebf492251d3017d226ae1f107e47fdbed68933fd5d9835708ae8941cfb8ee2b0c02c75214633f0455124543091db15212b704fc28a34ce943b5ef005b7ab7fdc9f32e761acbd45186aec643313e0d5b85c2d2b0438e7428e1799d9f4dcb519ddfa5bbc1b3b127ecf1f0d8b5ec4ebd86ed3298615fae05424636f5e3c0ff509ff41f54363ca1019ea797721cbbd8807e82c44869481b4c6e3875bc2a5a22b962317a1b07dc77376c02c647473b0a5042fc34cf7bdb3fe127c36ef7c2b5a713c49a10966dfdeebe4034335f64a321ab38f915ec449d8a66506177ff6bd1e84da32494d42c9f002692d906e154a7dc7498e5b5c413a52c5851f7f07a88178a75154aa23a7922a1540f34c4f929374c09450866736d3f75725b36a84d4412082ac3ade2b84d1d969caf860264da573820e80883e354743528ce0e357016ab79abdf1d1f245019de2c4149a893c0619c1868763cfd904fcbe84c534fd50594296a8b770bfaa17d1cbc87afc92c178fa5e714962f00ad5fafe51bd54b998df4a1f8ee5c10dc0cb1842981f47a9e7b8628f5c2a79028e46149ebc927c7f6bb2d135bfa91cb4d34ad3a105f90d2e5562582e69353379f48c0277b4f4ffd1d7800eb3f34ca4df992e533a360a848e5c578cff7617141c2847a2723ab56cb82886c95cdbbec96f02bde1bc72d30e2862ce856885b292435c32e970b48ebd6886f32d23eb98c51347715d920f9a30472333cacfe4fb815fd337a1730609c991f82040b349ed84bffa6a868a4e8af58a4903a58ad6eced4372c40f83b6a8fe7bd195b98840ef11ce6a12720b45a71a75a6da8357e0f88f39de751682d8da3f78a010841552951346d29f98ef4ab610605dbadf2034ffb8a4134e987e233cc7fea3aa9c7c1a4729de28fb65977f8fee667aa17724dbaf8aa34cf0683dd18406e921cf14a87806fd0f9f40d4cba2630f552f29d8c2b0e70445182c48578805ac1c62f4166cdefe17b42427122bcd55f42ee7fcfe130cb6d0c427051a5739f905da8ec98193c4beafdaf79e85f6ba3d9623dd4d914f4260b5e497b5d66344241425319e0e896c4d19d6873cbace01696e689e722e763ffe2f03f5967cf7ef7841179ab86b52490178da601bc97b347770bee852955b3c6c0d20683de2feacd8d2d3932a564ea99b2fb3a5dea93ed255b197cc9572c0e441539f14ea975640c8ba26d60f4533a1a3b8ef020fe2cbf242a70d77a650764a2d4b48a664a2f4934cada9ae0a61c3bac31ff13998633b0da106f6bf9fab0974c8e48b71c71f313ed60346054e0a0621df6801a0a65fe46d21e442cff99e73317e3fe8c92cbde873afeb3902df26741a0d99b7ece42529294bc447fc27931ae05d083c86680b3553dba4c437571f81eb4de812814c97b8396e3e70d86a0c73e2f10e3567a574853e57bb2f7db9fb4e7883fbb4b1b488f079cad784434ecc94a4322a06b50316b23ba58af44e35e302f7b4f35221bc1159ffd59b13d1eb41164fd619f9896e1f315b00436c5341b41c838429a987da7ebd5ea86df60e4a1219ed0bff0484bf79502d66abcb5e880b66deb69c1ee04e3b1d274649d9761131fa5d59f71f88c4e35c1978ddaaf7b5e10f8f955bf013d12f23f34873458ddeec6a1079236e770eb1c5f93dba074b21d99519179e6f9ab0d1d81d5eac4cf26e251071bebeb301d6ef0509e65d14ed38a882eb811df330494ab922e22c7cca285d5c108a93f336e996904f42b2cfaa848624c2a0a6794e471fe3bbd964c14c03227dd4cccef13c34e31169fdec21579fae81a083b51be9e4166ec50adb6df7eca26c2b7e3f717d11ca03f5716baa0512bd7667ff3001da2ab157a6df11a0d883691f52deb0a716576245c74094e8a53ec21a45e7141ce107d45eadad3e7ef16edbd63592aca26289ba37867b32dbb7d643d427ac22fe091d99f11b8f088ed4624899c4d7c9d1142c77542896d1396cbb68fb0e4acc6da19e14715ebcd3a15bc1df79a2b281ce837bb9260a73c90a02b2e49916ba2bd695bf7878a709efa2dbe2f91564a36e65153741f03ce65bf75b1c052375b110a06dcaa048f17a3ca3b2787b03c41a882082fb306c1fdf3c884075055505e29b70d2b397105cf23e7e8bfb6147448a03af16169412a8cfacda4a90177a933845e822dc6125c5eb648da9ef499d99cd8aed20ad41a449a8005d7a3eed21656d467a5d0dd3b199f7631aa493619c24e2be7e913457ab9562ee1d087d6e3bfeafc762804ef2e9984f4e3251507baeec94ab1eba294ffe990ba93e64c6e9327084e533ceabe6d44bee535e27f690d41331e3fda778abec060dfcbd52ba8c4869d3c797eaedd11e902efb4e98cffc940b466a2485a74c7f4b72e747544daa2667bc6696151e1a5d6b205d8383b87e5ae8b1f1b2b41969fc7e3bc461098ed1135c0faf0807e18edfccbe02147319d3cf85ca4c91d176b688077e406ea817c99b109c8a1a3fc9031b4b2b2e1ac77e750186a0b5c4d691331439df754ca5d0ac2811618d44c1498b0b5bb04fe2fa7b8ffa65f16098ea83aaa0119700566bd060bb27d921d5931d931e3a3204c6cd24860808803de11edafeaf338e8ea87bb832a05a68c2cb7b6539895319ea7b16affa7fa002260f3a10e57955bf698efa4ddb93309f07eb8954a35132876e6c8f57f6d94f030e3ccaf7235e3878822dc0839b927bf25a5a07ba03c248c7643887893dbb1ba28954aa253403e674087178e7d8191afa845dcc1cdb8994cf03f4bb55f11077b6bcd749dcc8c39c71c39edd39732ed9908e89967d4ed498c9db6db2c3a4743253e249c0a49864bcd8bb17bfd1b1086b0b4e0938fd5711536c0bf03e2aa74024e6e6ead2899e611a369cf5bbf4e5b877344d4752e9e499b7732b347163d78c62647373a41ba29b58e2d7d88918e15520a4acaebbe28c4005b4c0acc0f0e1964aaaabc360fa07dad57f613c7028c46119128939879405bc16b4f7e2b71a0290c8d67396022c4911f3c17e226c16588a07efab8fc47d06710a4429e74db033b1885bd0f2dad80145d5554d351bb19fe96ffb417dc450ac318ea3296522fd3847f93957929705198f431fb78bc2f48cb5b91e5cb80188b6aaf1e090916ffbd7f3fc0e5f0e23d3b6cb14292099783136a4fc5e83ff624cd91d3146abfc0ecd4cb460ddf8e7ced8b3bb9c4b82fabed20d0a93bf94c1b906323b30528c7c71ff74f8a7c67184b37b5085f40d2ab5d82d0b22b5bb2f9ef41eb487a65b11852bfa79fe8c72d835c37c6f8cc6fdd020f30a7b06effb4ddcab6a0d0e617762b831fb68be5bf89fce4f20f9b45f2983c5c9f43d138d8f48834baed92e9d6356816a969b01aa47b7d5f79401ec5e69b24098ca4bcce9bd71e76078102d3149e1cdb38fd76f0a70871abe5c1c98be8e400c8bb6182e31b0aea8586c6979d65133af9743c3c53bba40890905453cb4227b82acd46bea1b8ef52215c0c74ba2a234ea200cca0b40c6263a18be20d832247ad93b7911066670f00f9ddc522e3ae268eebe214d41534e43fb6a6ad6ecf180d8417abe0f2b8e7e1d7715c6f1e8b48624352547a58e336fa9c2eb45806feaffc7205a130647b8d34c0fd9b9664678e0e88cb80faf664070873e90754735f1c94a63ce0d7d22d3e0c31fe4dccd41ea107b5afd25a6974dbec673027a89b3f7832bff4daf0cd66bf57ce17fac4ce04b555ffaf1ba69e7f9cc5d51dcba29ddb1b9aa4e670bb902b39736e742230a64ae124024e49d96533af95f902920107b9028d3900d0371b54abe06398efe73d0f8daaef4a365625e59cac8928814fd2030ab1488bbfe32fafaa2a879772732d2cd65445092a0975286cee7104ab4a3154e47cdb3f12ca53d9f258926d86a6bcefaaf3b3238f415e37ed8fd96acf1bf3126d3352ec9b10acbc8abf81ee4dd3965678453dae371271ece1c505725dad18e6f266dc1c54bb7290bd954c3b484d5d1f0e321827972b17355950b895b6090f371c3a81fca731503a96691f9c4b92b424a2f6bc342580defd901295e37f6146d12821b16aee3244b76b4a66291bcdf1ddfd7edde5e73584c2e36485a91dc99544991a2ba1d7600b03e343e56656dc51cbf9de914d2fb5c742daad849590c74d13c6d5ed947e24ca6da691c85477322b04a76da03389a7ffb6586ed57d436a78ff28d75eed1cca45b207635b7c8ab6399dcb4136fef49c394ab08b509abbbdc218d2496850c685458e3eb6bd6c0940dd29679501a54673cbec0107a04c6e93dc8dcff53c56fb9687ed109c60d0799ac726a825f46bbaeb351a2a123f01f01c5994a23ce42a8cc671907268bcaa49b7c1c5a13006861ce6eb351a585eab14501358a6b543dabc085244122976cbaaa21cad85410e2fd1cec20e85e2ba39d46c903ed7cf14f4ed222da6f9136a097b6e665d83858fc467312cab08afeeb0861f71a290b06c33958abeed78caa56ddb9033f926d08cab963d8d52b94dbe28e29315bae0a1911e0dcfb8a6247ac9a7a665a37264d7f9e67a6ca9942836accb6e1195d1d6f8e4c836fdab2631b62d81149dcfa697de6f6f73a0c0b25e9bda5699c1b5a80a488bbd699373b6eba5cece920b0685741b043b72e655be6c923354df3bcc72f970a9ca721fb94135d974e1d10f9b219c21eee2473691773edb76dfb6d37708e66e73a02d36499ab6e2777174c69af91eb50207b91eb0ca0d419b074d5555174c5495ecb8a9c999268db79583fa20a686f33898102fa72115308153691e67f0c214c7153cfbc9c2e3845f9c7c62559746e4e643fddd4dbafa0cd94a298699081997354ede74c2e4ded01ecd6c5bb887bccf1c17523d321000df50d6eee7214a51dd4eb50ccd00b0845137ae34f42d5faf365c305ec67ccc8160af8fa60d356ebf1282766f38479db93fb159fb17b22f4682e51b799101c165e352b475393b9d5b26bb9153758b3d5d5b32098e287d54e4c35a0caa37530f8d152b87983e548dfb232886c013f021a896ad3ea16dfd9a7096adab273278a7af25bd514400e7f2c88ed2ff610e60958fac4900c40153d28d79a8e0dc722a8fbaceb40d03d6c20be90e31eec9821757cbd509487b8e502b92449443340924eee081de8bd17f0a4c2c86ea5d69203b341e93ffe14cb240cc1d5bbf08d61506a38ea2fd248711703300be374d03fa936be1fd25974076d28c196c36598709578283f0b1117a5ca853ce426eb5be038987bfccabf21b1148d87df506377a94307c4048ec36ca07901b551d4c3b4af5eb8ce70978bc27fa0d9cab221f145065719765f0afc08d6446d341b7d27cb98e77e13aa136a07b62eb9dc6974acfec528c92676b40acfa0ee0bb856ed9659bcd583f8da56cdc3cd313c72d4288cf30611df9e3f9e7252a30bda4735aba65ad013f984b7f17e3155085c9344cb96c04c65e2ba650d6ca3f1f2eacbed08a7ddfe17825c910eb80c6bb29e5fb379b71ba11c84b7758759be3d068c9efdbcf57f1f063ac323b7ced9ddd919cf774f7c79ee125d60f5d6673dce0a2c5dd4d79824493505c522072d7a33b601ca41f6a7cd6ca67a69be12e9e455d9642e734500e41b07f1d610a70d8cbc89864280d005a034e588ac8f7b72c574632a6c309e86a23e1a8815301d973f149b0d244a268c1859131fdf0bfcc97fba8d589f02c38acdd8f13ff0a40e3fc20966a010a1bfde8a8305f1cf53d4e0bf72d1abeea9a3efe5bf9cb50680de0761e2769a30a8232501389dcc20749ed6057656e8bdcdd7cac0f889212471d80841dd644c5d844730e04612c9461bb41f5508ba50a9a5ba61f1f42d33ce70eec4b626607ee0cbae8f89adcac0b84522b33f5eb7fcd2589d8a0404be9d955ce4cc4308bb61ea2372202e1275da6e1537a3721113cdc16937e62b0462145372c15d76833ed26ee1c256cb96bbb7de43b0db98f270145786ddebfa88d7c60d406f2ea06813e1744bd7057d218fa520e8bb4dd6ee4871f082dfc47aea7a347e9d270b1ea078e3bc169778d77a96315e6df191d5eade69186e6d46709805f9c6800e6084c98bac9d357f5aaffc0ec9861070b4661ebdf980a47236d142f2070578e58e6e12ff3ecd1d95b79857c72b8da1c238affab855eda0a54dfee84d11ecdc9684a76f144f46899a7c86378e58cf299ae79a63773ec87ad878ac804a809c0642d6b5edfba71757492a1e8f7275b31703032c2c96a3d1831d5273e4acea6930eee041999b06af9ff8bcaedef0077712025d9a3474542034555355f89ff4de0474982475ab98f1f923a4a5194c4a83295be1f26ffb720a90f5b12095487908c73d5aae7ac1170e4c71d3eec2819b80db3abfdfd266043a851e8cff27482cd7e5695d324c9d845140463a79766e968216f9f09e0064358fde80815236de26c2f4569c6780a48aab8c3715b57f468d8f508bdea053569ae02a3f0f07c7564cbfc0500306a68bd4524ee6f141f9589640d086044f9938cc2cc9e308bc95cc5aa000134dc1964dcac9b36e77ddd0da2ad9456a00de0b14a8bd9d348fe2bb86bd07f36a2560a74bd580657b793a4b60820352878548a4cae93dd6095d5392b8c4356c60319bff19612c0d592d1655919d750ae025a51d17173140b5beed4e6780593506937ba3bd597757d96018df78b8c45871c8c974b26b4b11bae98b83148a8d17681edcd1eda16218f2dc2dad305a8e2832f640cc180765d160d1ad605ab59f7aef7864f63620a482e52cb7fcafd9d62b0ede571886a570b2423ff336a26a8d48b7cb4cb6a789e4e7ed4eaeab89e2f0c15ad1018d1525b5d6ea18cd7ad87dea7a63bd6d6b21e0f6ee42bf0f7026715781a8aa4f42e00b688b3617f7803107d3f6bc3c2344b6216669dd5bec1c58ce1a4630222b2473e2bf38b5f4984f40ef8f66e4218b1cfab378bb8540878e504cdfa1811736a74c37210ec978d7b6d3f93c04c192e4e9e6ca3317c8e55326d405d3e69da849dd2045233aa21526ba90f4ed4a70ac9e7ae0ab3039186300b82caafbd669d41e17f141fd2b41ae57ab4c5eafcfea04d80c0945069fa0344c28b260567c233f10b1914f8bd0304157a378a10b0860888c9d66fa7c9bf31cf81426165df121492a5e274357adeff4eb2531c72ac00adba658c08efb6301535c3b1a68607457f3f72a6443a5f822078f93fa55c0254d1d3e825f1a06466209b47add31668f7658374b4cc101c34f5a4ea7e7e459e3d2a0eab2db3cf65e98588f04d945894c816ebe4c6c5a4b8823571c51026a5f7302e6555c3db552cc884e5dc7c5662d37761640a842055e5019d02c424cc31bef5d08fd4047adb225b00e565aed6e7f9f44201e8ec0a0328c955f1ce362724711b652d4a8c6fa4a76782c04ccf13f2d65081dd2ec5e443b74b6e8fb3c0eb8f67b0cb8d0371ff782e26b9eca95e038b21d404ecb1fead02ca5ff816514ff468ba4d25f0a7855c7095df68701f0d0bbe73d7784fcd635cc536c5c06bbfce1f5f52126e14e2e2d2b8157b96ea0dd29917d6a1b16c243712389b3238714ee9119013bd023023c0ed750ef96bfc5b579bb2b232da291cd7a648787e52633f7d92d44a51f4437bfbb08e2451a1d3b5421572ddd46ba51485a8b2108ac54223a7fc2e1d4b29cd61ce8aec009903de1d8637c8d2f8b940e8a0ed8cb5227d209ea30dafeafc48297dcd2f6ccb8593a595d6cb8d17ea058ece8306dd41cf4045a1e24bec7fad86922c74e0584adc4683ddf87ec86133328240ffc3aed27d88c932819ee69e99c19ea80b29f668363777176ab018baeecb9b275729f45f1b76699d0a330649c3177afe0ec4146f25741bef944191469072540594783d476cec76bef09d23d2e9ee6fa58f08ccea5826870927220b906023107f42d3a5cfbd0a7f3e1908243af7076c9c383a3d3f8e9dd4ae43ff6fabc9b65382011179723147b5d9cf0ca7dd73291c4f297331c3326d3064ec7e606fd1b208ef8f3a80ed854fab89fe51e118bb9b130318b4692b49ea5e406d631a3be0b90cece50e038c3df7fc368bbf2db85892a54c3a2a6bed7067781e480bba4020134cd08955f2839ba5add2abf272683380b49e85afb43173734bda249d79ef58545237a2d385b99115fa99f4cdd89904c7475e005b286fddbd69e3235246971b448d47857b402cf1f59e80814a8cdf191af2e2094535359b335f5264af8b469f4148a21cc29e77f22b3fcf016d32d658b32531c6f0f26f1d83af906f97ef74202f1c6bdcfa1513cb6dc56c656e1e465689d88e3294af9c1294c62a067987b84b88b844f7cdc9cea6b55ebdf35627c79abbb77744661e8e6c9a17554bd97d2a4906ba2f9334d8604f5c96666d890bd10a988ae01c1ce6a69bc7af07ca51c21ed91fc20aba1401a0ea1cf295e4242d05896dcc29e5ac8341cef7296a3e4829442133fad599f2eb6173f4f3bfc108af2c0269692884d982525ff9ee36094671656fef6131b65e96032a36559343edd4ede4588585559152bfb59e83e7e0273b22fa2d18df83cf373f4da577f853544aef5d14329a6c0a03f22bc9629a8ef26413a8e0da5e224b3192449a4d8d9dc6fb149c9f18769b5a016fc085f9b33dfc47e2f5ea6719e10d0224e56d8ceca82c033dbbb923180150c2af4ab62736be3c993e79edf4e3be44c9156826384503893dc423fa822b8758e0c9e6f01fc1dbf347564e9a6344c70542bebcdf752bb83e4c1da0c550e39113de169778001f6024fd25f5eab4dc064e49b6d19acf531dc88ab4d3b380a83cc0ae8d552fd3ae937e18ec4d5f81f31247edf2d361c5b565a76c1403cda00266458077982a01aab3379255dd19fd66ec7de66a9ec255ecbfe2875a72f55a4836eb75adc2ddfa8371b8c4db80fc09425b7e87a04dfd824bcce69546567ff87eb308b34140d32ac72443691f92e3eefc3475c40f6a8f455de3e3deeaf016f3ea163237524ddb34ff93bdba6091c53f5e049793d31a1ff757acc3793bdd5a3787b2e328dc3f6e50cc5d960ef433a479d39d0528bec5ad2ed504126ce0213b4a0916f55a134a003f1e20aaf9ae41bb9a419db7031cf30663f7919cd253ce46a4c36276c55ffe86ab5883a25af82d1c6d3a293ca574fabce37a465a2fbb518ca4f46eb5dc79f44e5c6aeddfba607d5a30a37da295e8aed83fcdf47f18a90d1f80904c7a89ddb27a8a57c65d5b4d972f5302cb1ec33b7fdba366701e0cc1bedf44d7e1a29177de6413368a13eb00d7d9b15dc886e5d9ab70ab1be5c102fccd7ef51b4d36113ed3d6879729ea23db7c2c6e381925b80236706af7eef1b4f8edacecb8972c10ee00a6c5efbdcf20e3855fd6b3c27c18e712a585460c562fb5141d67c42a3022907b732c80c24d1d11f195c50cb8cecee5a75c2f061cdef15bd667a7120588b3e023f22c3afc6733ad0bf9cbad6c7ad9958d3f66afa1ad4764c82b4fe7523c5671880dbb3132d90f6f0b12a55cf0b1e110e438d6bfa40281880b4647d3b0772f1da4944003ffb563c28f4528807203e598c7627c66a31b763d3e3b6de6888ffcb7c4816b06286add1645fa259dfdba892f165668894fa9646988717711e415252b4b04f621ce91ff3c94f099c3b8bb4231be643888b71f22f1cddd865fa164f75df4976e21c97224b12fe54b5a55236e681e0ee8c89659569576ab0f70f35d5debeaa50005b426baa77c0af37977ab6a98a559731944e33b8424bf2e962d7a12ad41bfa9ffab72d006838eff9e6b800b0deafadbc90abbb3d71ed5ed74d087e6e57c15ef51eb35fcfef70f1e5b37501a56de0bde8e63e31a74152b584a17af6b5c7cc0d114928c652fe0d3e727a85c453c0276a76b1baa78cbe455211e4541303774451d709d787043fdd1ed642d9810f7d50361a4a445db54f8d1c087d242082b044480d148cab1e870d7ea47b7b411e3fd617240726fd1534515d6808dff3e2634955372648b2fa0268931dba30f2ff09ef5615f4b9ba5a4aaf59c30b5c990549310cfdd21498a2c859c94dc74bb91c4c4771201aa7e4b57eb78aac20879fb21bb955f6ccb5914c971c5d602b3953f7cb6fea35c465d756578cb52d4ff6980f41f218e0dacf828a9cf1e9597aa39891dad1cd73f73bf6fdc77d1ed1d1fc9c6f52b6a976e6daf6aa5e525fe9946de9c2a2d2c02f09d736ef193b46604cf33dc8879ae78d614734bbaba594d05ba92cd1368487a7370c4b3055d339c875f1b2a0d5881156952038f1dd553a82116fb918ed88b79f26b51527d434d8f9a37e7c113bc47d54cb3a82fcf1040ed6bc064406508fdaf74e4058c1b37a792929e54248f1b08c5077433852f38c25ad3908397b9cd263e1e7a8385d567bc04c8a1866e73697d3f7a50d71d28b3fe042a198490ba7e7b79eab9274b896f25d63f4456dc8cfced2a7fb3e7360adfe8a2e5e143f4a7ccf2daeaf681b3fff7cb71dfcb6689d7b220a867ebc69eee4cbdb610760f343ea11a78b951cd045deeea5d4385f7e9fbded043b2201d3d8e0106c85a889f13e4d7e2d8e3902650dc0ebf29767d10b29c173e1464a5565565b2aac9ea8f0bd50d1144794d389394b2ab18c6665fecd60454e301d71e86ff2cd4e80c213a0980b1157fd08e7328c55efbcae3fc202e4874f9b0510ba051c1318b32300c9ad8a516f66515b779490a360216efe132278d102800fff46b5df4bd57528291d5927a3bb81aceb3a6260d0e4e13e815088d2de1b41dff0f65bd1257a02df983513c40152f6e2f2e25f5888285294f95ef0f8d61711f27461d40ad6fda31c329f5b494770d7b8c9d637afa0155a4a35db393b85109099f2f3a6a3adc0e7a6f8523f6c2a14810d6b17c84531959abdfddbac97558e85d2d7d1ceaa615e3e12f074a34ecdaf16a90f8f759a9b285acee473306c4445beaf11dade59ca75054c58982b3c817c5490d20bfc6c6c65f7dad83cd0e822cf68a933ab264590e02ccf4a16e90a6e51fcca80815784aea4c4db678ad871fe27dbc3fcdb95c806070120c7e5f5a23548e9847cb5c10222384b8c2d354e656710cff70f44db761bcb728b2372096b18504abe4a4ff95a0246d1f5c680970e5fe783a3cbb88e71187381a36dcfc6a4730396e1e0ac13a2897eb4120ad3d794e097af0f0a7c1044409178cc818ed3b7f9c9275bde4fc6063d2874a89098544ec0173ea738baf7156de25b2f818a08b018992562060a378a07c1fc5362d953b28bea532d4d382c5d72ea843ab5322e6ba0c5e13bbc839e748379d712a8a0242d2797aac40fa52ac60c714f0ed336ccdc15240aa23d32a0e7a41459a93e7c2d4038997f447235dfb9d3beafdf8a5284b1c34db12d2396c5405e91692987b6ec668a0ea493e06f36690331a6f5a8f1131f07386f70d6f3d29356e3f3d1e82b321f9ca29d183346c5d1d8a648e0f86571b6781b92b45b5f43af1e98eea39517f88c011c34300d9948e69b22318ed5eea44f4e10270cb8cfd719de52f7abc30e51e92bcca8316388505dd4fbaaa47170998020c60a757f3ad84ecc44341ff0938cbc1f09044aa5b5c179fb072ae3f280b9dcd7bfe571f7e5a0c6f27e00e4dd615639019be2604ee3be1c309f5847cacb61a51152192abe906cba0e8d2b0fc2130d44eb952b1971d563874e8602bf6eaa753419c3871e6e389918b3687b8042b9ce7ee6d97eadd71f839d6f96c374e545ceceb63e7ded5780c582b0040b5e476ff226aba1290863fcb79a92df497dd0fd39abf9b275129bab1cd428cdd07c1cf32b0f5823efdfd3cb93706ec7936768d8b6eedbcdc716bafa06da389ff7a85efc737be63edb4ce0fb598da014cf9f96406ab48ede4c6b56ffeaa436dbe5cff6a1933f939ed94ddf1668c156ea8e7282ad555d119915d874f70337426d4adcb1f838b557421fddbc3ad9c6e852e767f3382e4ef0e6866d91885c1bf14487e13177e25e99acf035292fccdd6ae97d339b4541efa28ac7e56bc9243ea99f870e554567016d8431e6df27a29aec391021b4d2f0dcf9a0f5cec3e9ef324bacd2cdab05929591b70ba19157289c6f1cc000ab354f66fbbd83f47af89f9d066119d09d8273d1ecd1fec5c04efd3a5494d75286ae3e4bc515f562946bd7c56319576dedb9f2191a795758d88e629609adddc456e1f2302dbf6c530340406649c9c37ebf15c47544ecefa2dc04e50311d9ea446138d7fd7ac5ee21476c6cfda92f60eec3e3424254c40a52dad98c6b4dfb2bf6297d93ab3bb212476ffbced2b1f628c807935d8c1ea1ddfe7ce99dfb9a20fecf7ec40a7011c66922b5038b13745235a577854eaaeed5c73be5fd3559d98dab5c8e4da27003c5646ce80fba36767ff034ad58ee9b2621f75358df5cf8385f5f4826f07760de0b3e8f43081c6ba3ee3993f5a9cadd4070a09994e23e20d8502525746b6c19ca3f7c4dfe268c0cd6d199d01ab8f6a3179adc372c3ad1e2d0cd211a188b98f0e6b8d52b3d8e5f4d19d08ceef6bca97e6c1d81f8d60629348af5869bef362c215910b37011b67c8f8169f8307d0347a98462d41db1a7ff9bb2192e2cbee39ffd1848250c8d605087b42c968b8de4e8022610cce64395906dbb49939df2c8101534617f31cb3c9e2a749b2a79da3251abf3e353df1aedac3ae90258dd66ac71eaf9ba598551088eb2f839bc8e7af374d6685473532cddf7544136bcddc2b10c43474b6cd5300c8219cba4f7aad75ea0faa58fe90780e1a35d50d47adf221b624e53ed19f1253c8896ff3d989ece1567f587a49e692937b6822f6a432fb5620b86020128265425b1446ee5b098c2d972660c10c083b32a8e2f18dff7593a9f71e98d1e4217447e9ae8f80fc917ad8590bd34c9b16e91f34c1d50035a2b926c9253eca1c155e726d2f3033d3230c6a1d1f894632f976ecc3438b0f80250f4274d0321fc3ac13b3e2588c52b54647421c51d26be840ea208d4375fe5cbd3c740d1977e7cda0ebaf6830ca64670d6b8f8ee5d036a124b91d7f1f65ab676b791e0773735d05082f368f4eb2f3d155057628ea52fb4b4a0658c332cda383571d30fd80fadfe5f20232d259340c53f37d99c0059e0a22ff66f510a6a045a47b475d891f426808619afe3b022ca01ab02ebbdda9518571dede45d17798efb63d654b9b7bb5dd18bc564c076ae0ca3befadfbafe3a75e7d7381f480a8c7d8d8b867ac01e6c55cb3b315ddd022ec48002f40c2fcf8c3a06843ea80ac2a71bc0083cc0bb5d602b572959bdc5c26f8142d86d0f784ac1c4f3f35f9429e17f087231003c7b8adaf11d1eb47f2c09a0d8eb6c35fbf157fd5a9f7f5eb45c1351208f14971627fa530fcaacfc9cf5f9bf532023ed8ec003211c82f1229912e58bed92f161c5dd028252d5d3d84344cb1c9804b6351bd00b2e0f2423f13c30672b86156f2bf0be1918c176150090d573d4effea92bcf4871afb83ce5ff77a79837938ceba26e3cb76253ba56865e9f2ce2bc2151f1908c20572fcf8ba76c217498b966d1220466262672fb4d4b4ed433687103ad610180b6ddf7834520c81240f0d29c0927a102aa95c2e2c176b31d1b0ff13a1073f1c6030b63348d17b4de27b658bda8a5b22cc462dd8bbae5b494c6c211e58c9abd9090d34ce3882b47041abad60d5595cdd5d92f15fa3b948485814bbf53747debff74f58861611280e72326ac542d739d41b0ce746523093a40360ec8dc0dd11e9954aa186ebaf6f3ae11a600ee9aa28ea9195716c8227cf228b6fb8f1e7fbbcc3aa8e9b2a6178dabf454adc30e223bbbcccc8c710e0d4e9bc13348de4e4b3e2c22db7dccee2c9aa90fc051762be6a320e80e9972909930bffabaa6878db80a876f9b7daad297640bd8d5a2a97df8913098bae4af7607ff246c8bf24e4bd54d8b47e5334cb6df6e1585fdfe676a7592d3c450c4c93b0c1287fa74143a8bf08a6dc3d90ff9cc7533344744be1c7088bcceee990b6272e990a276b322f9a8687544b957c268bc71880404bef161712eeaad045a365178e4439da7429a83ca72b55daf01608101b1d04aa92caa63d5a9126f69c5da46cc00049d502b673c65cd58a972588a5b3f73e553b0731c8250929e7cf8a4ef5333af75f80d54344d34038bff998bec8eed3cd82998a596554eb0191ea6bcc4374bf0e647612a51216d082c0b9ac27cd0af8f1ea84ecbd288a7c8efd6351fc336e913370e4d4df836fb543744954ee29a63925f1e9afa9b644669714e8966373f1f2dba1239efef028ce0f8be13ebad2e4d2b682e9cf1a136eeb2ece47ef3fa2455dbe0f553cf9b07d7c155b44205ce20c677911ecd5b110098b6d662a7d9d7f3e21e6660092a7dc4d9f2201d0040b531f8862966a507f9f706e22880a6467efbf84630b84d9e18ca3d96c8fe446cd6f65f6ae2544d68f5d7c1930382e3cc462758853a1041c98d6fbdea2de0e2f78ac9c0b8f6c556923ba23d6f45a13f754e6d0f49ea0c68cbd3b9632e9cdaf179d3308be8e57ed0fcbcecbfe609c820a0c4f54cab87cfeb8e97449547a9bd27e1e2d057a120eca0ae3d65827313ab74a9720ae55cee86d038961bd45277fd28ac295c722e12446994f244462cd42e0ddff5e9f0d3ecefa02f38a734c4fea4acdb211c78101b93fb152204aa76733442dd35de48971f89e52cf2bbc23150cbaabaf26c7634212cf1f60e9221bf69b9cbdeb39a3237692a02ca10648baff9e7aba10fe95a07ea03e082424094ee49f51f8bb995cda9b0a5ebdd9c0d9fe143e44c9e829e6adde1ae2d1b4a14de6db5f2e572b493651a77ff7a6ed576a359fbf368b14e62155907acd8d52ffeeb26ac75637a3fe5ea38d5ae1b03bc590a8f8f34d7fb58e5ce836dbb5e23d18e406f470466aad65af83ba7a7d04ee21ea9a5e828bac9e6e297946ae043c4d8704445c3a851cc7f0f5faafa8331b6dedd81075b964bae24d3fda0a26f638821d400854501bed4941a0da392d1bf9f26132b1caaf96b4905dd02cac498acc51bf0ad714b242b260ac6849722d8a0edf77606ff3cf2c26ead9d45e632774ad7d83b364a3261b018b0def9f3569b61a3701d68dc4c287ba23c7e2e494a529fa2b64fa18cfee7573eb06c24b88baa24d7805e80b311aac13ec5a85fab8e7b4d41dcc99580201c653e15bfaaeb674fc0e3e27c3ac709f47ffb3f1296d40ce7e7e30a87b2f97e28c97a7a329a2d8da7ba247fe2376d64258672e785c9e3a76a76af89953090948de50a6f1edb1cab28d612e393c0adb85bf12ee1d154fcf769317d9d981ec76e247701f1d7da77bf4db143a91e7745509aab6f587b270b97e14560c2be839ba65fc3bcc69c09366cb393a178335d88471a9d489dc76b70d0d05e7b2650d5cbc12401c47179a2388e8172b81b07ca2cb6a0ce582640a3550cc594e8b20e408bfa3bf45b01223a53ce75517e9c5ff1d09c9f373645fbbec52215d96bf1aa23dd6399dc4513ba9548b869256f85c7c391d7ba7ea179c2e19c5b7dfb84b6ff00260dd4217f9e4025c553454601f57fda38755c514bad08b1f53a5c8a8439904cdb928437f731f8f2a1af76625a62faf4447a68ddcad8eccf53fbb953e298e8aa570d185a782993b933a5079720977fcb8dc532f265ab630ec66ae0485e5d5b13d41ab3ee82975b5e2dc0aade7f37b31f90e40425fff37a0212e94a8069281ecb314627c39aca13a5a951a9888cf00a5f971f57895392c97248f9a277d0f82f447a1284e438f65dc2e171115a0238667136c28fa38441e0cbb974269ffe79304f47c24515fda6914c7f63612741d4e368d9fdf22fe7eb584c388d4ce6edf0ac4ede97fe78c8f446a4af9d5789078f902920108b9028d391585e0ccce23f6a4120ada640de5c2007253b039ba756cc7e369bb10740ec7ac856976b9dee917a5927379d0e1a862960b97dd798b5ce02c2d4219ade06e5f2bedc100d337345d5ec183ebd0d49d4434953168f1b591358b0faf1b4f56674d509a9b990964a7ccff4c51a917afbfc332e9efa8575e8a1b24cbf876c598de17070c8cc658fe34bf5c6d956fca6fa5422733957b6f845228078628dcdca51f97155cd1a829d665c25bb1f44a032995d3d090de7289176220461d926828492b2575872cb42eef84a16c35f047996a8642f66ab7c2b966748a19c7d54bf713e94d1d1dc32f14a90101da994e3476485eb5da7ebe1280dc6288e7bb166295f4a200945d51cc5d17ade898e43e94da1199a3681057055c814b5135da6087bbcd8f68816c799f282953296aabd764a91955068facb835f2324eeeee137c4731b6d12ed8473e7b41cc35d07bf45ef7b4f051b5dc26a8bbe620722e94213e7defad3e1780476592f854089415866a1664595e9caea69067bcb86972925c3acb3d07152bfdd45b98b94479133a8fa5082fb4afd63e7068e5108e32897fe06aa97d39644b22cf4685b14987a1d095dad4cef2aaf7dcc93ec6c3c5c49aeda4ec29d28336f1fe76de53282fea6951d2eb9bc23caae4607de472d9196cb15c48a294508e3b3bc655dd38c48ba52a941c5c54a5d5682d2ee2a5e697449e730de6e03994fec4405b6b9cec199d8b257847770ce9fc3939771bc8de0d6a26b9f63a3656afc285e4b628d8b9e11646312b52928b96cdeb76dc1b974242c14a3030e41684c54d5d596f67a0df68139eb63557410c6db2009bfc5b5c7b47bf626ec81219899a6f1f7336c7d56cea7310900a6f2dd8463cd099bc2c35b2342719af67b42b4bc7bdb2a7b203c548f0f8be2a21849acca0f91eb50208b91eb02476512d282ee942805f867c05795ec958f21460bf49bc8907e9d03bca5310090a16762455c5beb97ef918d6d8d276f072a0db0a010c37e927be698b4984c82c4a35c02d0166bdb654721a9f2cb9e463c90339055da7f3be7a50ac9a29d2ac335a7edec92e5439c61b02ba5793555fc33c6f686a433064188208897347fb46a713d045b90dae53c24600091b2751c75c9cfd0f42cc8455835a27638cad91bb86668750bc925a4711192ed33331511c5962afa678db24a6c3e65d148fb3885754aff02d4a5ed609ab6bc9fc5a82668c001c9342bc23eca5204d773408ee33b4b28345cf1a34e772f32985272cc6c76e768f7736a8eca54ff65a2aeb474e30b154acf94acb41ffcfdf0dbb64e6ba19b659fee5345329aa702a60cc28ecceb6dbcc85db1f4d8d0f82af60efd2e6f5aa2158bdc5dcd4654fb9d50d0e762d371a43b405ba53b942f0140b2fdd6ef24c55194aefd5d33ec8672d93b3a7be9f85c6f31dd763c0eb695d94dbea16e75a4eccef0b1477591fde721d961e078baf304ed1c2b42f54d3cb1b42b1ed3ebcbcd9788fc2d4b90f5ce4591a3b92c388bf9b3f7983c8ca2b4b318702c28b610efa0a2acf959ad0e46a1b93affba09905601b4df09ba44269c802221d67c07fbf471333ebc92d85e38324444b8c4f17c21e3d10dad299581ff77054193ab705f4c4fc7ddd440848d86bf8250e3cae6af42227e521c8d8c21a8e899383fe0684da747645569fe0dc93560f10bdde29c97f1bb200da3f9d8e878a61c72c7e7b9e0a9fb73494e4fec6168469b8c1656b6c18ee6d3345f863f08e876426709aa430026566f8da684048a6c551f395ff2512be01f090ccfb54eb56d947a3bacef0f57b42ed02dcd260887ebc56363ba862dab5a8cd1fb201f3c0b3edb87de86ccbff80544d9b7e187045fee61a782a3e38bba69e19be95d4fffe254760140aa52b3117e7b39a9bb95054f1dffd128df726afd72f94662e509a89d2e1c8cd3723a6663b9d37eb57b7015b97fec36397477b03556fcd45195d33304dba94db20e7b0b7bae06d0ca211a1fa7003e4fa58a033df592a2909ad58d8b6e9613b776c61eeb753fe20380f7a9357631ec984dd111a472949012b5ff882cfdb326f4aaabeb9b37c7d5d936cf3f9f518ede3fcd1c5cfede13c08641346dd9c300e59657781352ebcad770069da9f918246ba04b3c20565fdf8db654f782292250c9c86f815fa6e6e842c7f231d5f68c8c394c1b70df5a851168f31dabb3658251420279239f817367f722ea6397666ba4e4f94c5f12044d2cd2076c432cdedf8bda2ed80154050ecdb68f0fb0440078a94c4ede49236a5b60bb8bcbbe3628f1e1dcf4e6f1b9f41509708d39a69e71150e53f3b2e9f099f96c6fde5551ff8ee2c317bd8630d2af83a1ce0e4d31d3a7afeaa3431f5ff55ab67354d7add84ae3e1852edfd36c24c692538c45cd14d2f28d894efeeb1b4be2f4e72e72caa92f20ad10481111ec8aa5c343d875353d90a32797ede8dcec9d694acbc707b3cf05267a94b971a4e9fd4bf6f4e990160d65d9e7bb59eab134a4f443f7dacc2785029880dffca52b50c2ac7e4c6c02684ae836709a7125c5bb6924c760a4547f5a3f35a21228f04d75b578a885e2160da92d0ba37a51fd6e6a349c9111311bc0eff47160aef9c476c972b441198a54f297554f719f7dc988732b489ad73b99d1b6f30064764e273a92d1d74d86c74ea91aaf71da342afaf9bbe1bd8b9c74291d8e3823d66da9eb137ca6af099d7e643c4c4768539fac51b8552e00c84dc6a0f81c0646d0eaf95839aa5a541db70976bda2541359d7c81c73b77116ce9e9bcf512930d721fc8f5ff0ea97c77bb07d5bd06d592cb4cbc02c81ffc2d2911466914a3c4db5915912fc1807c70c982f3f0de7c93ba7dc9f8f064db39aba072418d6645e36e67282abffdc28bd2e9b777bf9b3877ef1b76cc8b469c9f025f25d18118f9f59225ce1eb85e7ca48533a5f58fee6d6904589a124d8946ec43f6a91cb923b693c50f58e67a5fe8197892d86f594c0a7d58f3b031cf4b6bc28ab83a8eb90de278dce91a7ddb5ddd2b9f74ae6486203a98530619e7d218ec91d211415888c1e8fe8abf22bfef4870e8069b0650cca6a07cf3ed0d082ecbc969b545a0a713b4a71694d916dc4c1efde2b490014c0d67192f9a0d71e22bd947075362f7351334f1b338545b6f51ea752070ee13d994cca05568276f9f9f3d38a4b9008e0f21d7a4e75c4251a1a2a4666db9eafc18af65bd0d86f30a9e24f725d1aec517585c8931d5fbfc083e2714ceb1b869e45b5e520bfe8b6fa00b8dac45c646eadf226d86ec06de9b9c6e3eeac8b1665cf01084232ba165556b716174688510593097c4bf8d802e64af5096e320b04ce65db0656d8ac00edd08370b7271d34e29efab95f4db6e99c62b0f07cfacdc4105c04673176c01ce3ee60b39492ced96bf18dad60b230df2b773dc48df63b0d62864474b8d1fffab56d7086642ab4bfc4b7d6d5b78843b77fb464ab1fa6acee4a0f2a4bf3ae1e0dff7e6c222afa2c2467461078adafd22c8daad597ee5e268abded8b903ef8ef83eeca7fdc8713a1765a9a06ac06fc1ccc3b1909c26891e4910ab8d03ad5cf98c8b9593ac755a10fdbfba1e8a580287d59bbff2eee4484430d1df5969d369b005d252e39c202dbe2600e6f02a0232dec212d9b04c0f2cb403b9899ad0f20b8755dc503254b621ebd4f1bd6af171a2826879114bc4ce553b7793621f6d3f7b200a27af1f98535ff4027611e6d02fd1f7604f1d57ac635ec28e0ef90c4d0575ffb47df4b72c91672cc92906056102c7921fcf1e1cb253994d2c47cdda64c6b1c07116d93ce466daff9019f6d5f777ccacd9936164a2c2a76801be6855273e40b72100f2e8837debb744913b457b38e68fa80a4ff67ec05f673d0c58d01dd757fba6f5ff1f4f196c464d846be84adf1ee8c3b9ff1bd1cf9eb114c5c555899b2941a4fd1cd2909dbbb6791585aef39e859d534ccd2253c2a86d34466f47c0afe20356ea4770f0a250a4549b52f60d6cbe646130eb70e4fb597e421641d938a8990d80fc3250cd8b51083409edbcff27d15e9527773d9e2efda38a537c9568e918f530f5a7cbf520352f9e120e26ee00fdad1fb67e5990680d4c8481b0a7613eb64c2d1f1a9dc83a596589d9a57f626dd75ffc15359087cad1bdda151f81fa95b88de2ebc264d9013d04178666eddf8e77bf9c7705195cb0e3e43ae44fe4a72ffd5becd4c0d49ba1c98962796a850a85bd8a02378bf6ea76da6df782c48e0ed6cf9fd700a6c5d4d1cdd24744eaf2b547540e3d84783301b76492d879c99318df39850ca19db2fbd246d6ddb35cfa339517d6fa0cd51f2a2c34c9b32aeb79acf94884a5062e3b75df41374e769c69e91309e0d4a9d6170e109acf5163382fe24bb33b0d2e11ca0245c8848f078eb85eab53ca38e9fd9076590aa3840b4787c1e030bb6975a4efc2feb9ac77eb2bc08d12873bfa6ab3243ee19a33b9568a3b8eaeda46083994cd12de8b24a303698f29624398b8acec888f8ae802de25231a7d8c0a6b3e279e6101adabfc583f564299c5ccad94bf90c9735ac322f023a137a2ff5d2f65f6615d53bf3be1e3fcb118e449ead8a3c514dd8e9f8fb745f7bbc37d3e026566f34d522d9fe4b8d77b25b42c962a799b574479da407247a7ba9bece8308ddcbaf2323e16c85804a51b13624b12751ed696b4c46988c346c0eaf7d27909feb686d184cbe0821f3c3e9c802da763e573bd6e2353f2356a9fabdc8e56e881836d91e594b40849290d61584caed4c495be6d9863fea31139713bd11be3e5f3a882dc01cc5765d7e35b6953a95c72d585778f8093ee18db74f9afaa4b7f66b4ff11a7b3e9fb9d994f338177ecfc23e7c22d525427dbda78e919b4e798d7c966b5ac6a2bc4e2d5921485aa6a34ebc65c10cef42b8c1a1fdee0508058afc92b688aa6e59cad724f8b1dd5410a30e313e3501da2a99d981ba1d18a8b67a84c462f8dc8a0e7846677b6d746a6b1edf7dd5b2978f140b1133ad3fdb8a5f006d676ff34e39165eab0756fd7bef245e8af82a078016a2f24104a4ca7e7fa0432cc3151def162066fea0fbef97230bc98d0076c2a9b891f7415461aa6582b2b1c2ea2157e97d7453bb3607760eaab9ddcd0c54242a91aaced2d563853daa9917f5241fd4f2972871e37775210fbc3937d1cdd944fc6f8395df82c775812bbb55dce93293cbbaeca51f4c0fb1915cc25d8a5b361c5d30422530c1c292a9bbfbd9058ec70314223ff855761db5fd54867b78e21b6b33b36d2a264c7c2528de9ff62165887a753992be715d117387af1f4bba9cbb722799dd691b8aca9573a75044c13d4e5e1d24859e6ea6c60238c907c87c7a873abfafcf63d3356b19e3c3f230e191899fd83ca528f393e4647f1677c9da8988c42d26af362b4182f043c3a27aaa8deca1c9f1fa21c245777a681c110f80fe89f8296fb23b1d41d009ba1294c7647411f96008297d55f14f3368047ad0095a3d4ba34d25cb9d554ef49f0c73be1dfbb5318088c4ee54b4df04b1926e70b14901988a455fdc4480ab52734329f2bc4bb2ce8c30790ce499fcaab80adff57c3b4c7adca9df87f40fa64db2f699ef775d58d255a9b97eb8a6da2f51ab669683f6a6490890838884c2eeb36ad56c250a82fcbd19b033b3bc2f685ebcdb71281ea15447aafa81ad528a085bbb6d911441ca20660cfbd0a09854a7f88abdb53b5fe270b3d3aa6dd506b7648883d1763b2a4c241f30e5d4a9551578a4c8fc2c9b7751ca478013d14ab1118a089d473cc69055460997ccea182505c36372f7516e31548f92b317b27534f7af66d8e6a552807e90a4ac0a403f362c3f9967a7a3414f75646b3b65cae0aa5c712fcf70a7e2f4038db01b198efdc7555e222520219fbc616eb45cb203e49b5a065352e2bce1f9aba1d14ebd75063951f0c97ac98b9b0c3187d08b6c7666538e309b5489b0f36429ec81a8de096b97988f2f2db79a39e5f7ed331281fa8c30e229767f1657be0e920d95d46d53e81e3e1ef38ccaa74c012394563f8f13051cef6bcef0d6c9f6dcedba2c2c73b190537d04318d0161ff74b02fa466a9d36c7356ae70ec2b0476278ba5327d048d8baad0a28bfc422208e3d9a5e59e032931fab32e84dae854dc368eacd834e4f17e9397c303048fe8bad0ffd61476bc996e77c0c32ef0638f71aab91fb6a32164929770c4981b73873b5494a9bb0e1400a389ce6d5f2e2883a036f55e703841d8b9ce0d7b7d5c29825dae6661f7cf2bd5bd56aedd9a23dde4cd1308c713185333f5a90ed5e63b3794b8c32de4c5eee3278ed129cb2897e089c110dcc326cf00e35a03169e2e4fba2e00474ec98f6e20f1007c4ec819bf650762265355e89d693a7e516f42348754b648211cb81585bd66e263b07c1dcca5d39783e297c14329b32bec947b2cb2c25c13eb6d17024591b8c94f58290fa6d7b79ceac782ede3df0557b08ae3b90660d1641450dfb1f668797117fdb503b2f5a6e379f1011ca2d900c0ac6c6a05b542b9638e2c60b4ecc62c9c64e8b6addfa177e6413892b589bc2785888d5960a1256a3cdf1612d03aac71aa0c1ed21fd9f3b86ab4482b688cb8273bce2db1abc7f66302f34b43d6d5a69a348257a1dc1ef5b2a998bfde30b405086389cf5c7cff4fb8f283e8781eef178a9fa15136a088c66309681e0acd738c657df2442db9fd9b8a03f476e20e65c232ebad4bbb32e4da66728a7f71b63f76f8052012b176fb9fef0227ccacedc37ea04a3a1f3d0ad26c6dfa1cc277e39f2da7c12d27ecce2fcddc3cc197c0588a0fd854102be776d6c0556b41a67fc006352e638a2a16eee5db85cdc44b215e749402763c442f9c8586533d62effafd11ec242402b8013c7cef57a45a336760569a40ff76550b705a51137e7ad5f50464522183c2ec05f39b6b829c27605f74b70090f39ae5217c63b6b43001e385becee3f74211b18437e907c554aa58c23bd75a22bf1dc1db99b586183aab974f26cf8cffc674ad7257d3e69b53b708a8b1c1d5cb8dcecc460f64a075092b159d9ea2e8709c68e6908b30b4227a41d9ef13470798622065793e1ae86719e5e787846063c4bdc2f62dca2aad92f52faa14a3fa9d7c78fed9a01510ae97f936fa31ef539735fab8dcaa43b8b7ee4f88ca1ae924c4879e64265b2f2594ca86211606f293103221d7babb8523f6fa9eee5f08357d0a8e3806eb2685f3a760fac7644a05db18460c02c08c8e4a9ce5f1a7882cc96af5d75762c7627eb654b7f8c62c0420dd2059209d4b337a59518031b4584e92f5b586cdfed645bd7ee334b2b3735a7d3e0db1324e6d2911ee5b9e49ac0d7742af72c17ade91239deba5fd751e1ae00771c9d0294fd43658a4caa85535f4d721733fd08e4deec2a79e3eaac987be055b8a9f8e853703b8e6635277ef2ef797dc46222b7c2c44a2e23a01e8dac0e9c44af8bed295d77225100fb67e694947dfac68f8828155e375ad2f33bdc6ebdd6bfe31ed5ab4b49936c037b36113678e16a1a125f2c1b83682f8bc54d047a52a0557272d127531a0ed8abb77bac6a58d8dff8680f4a35214df0fa48aae58f7e5fd6a82e2b7753f32620417a1cab9314fca82bc980a4280bb70f5d3352953ffd0c54c52e5d4ad2681ba8b3b3caced6248a27fb072d073ee55f1fb67117e45e430eb9bbb0a8933ba2779b56f424ca593d5d1fa81b5d713def9ee7ffe6672bbd2ffc633b3b1e8dc51683e895df54ea40fa4e0157ef1d447193e49aac0fa362485062718348d06693a04863733691ee28fe162dbcc417476639558f1b775683ab880730775fc81dd82b610e514d01fa0350be0908aefbfe2131d954a727a272b0309281161e9cfe3b79e3e7ba517991d698580f622b46000746d7d42a528bf646839d1162e5d759a5ca3da70dd89cffa715f9a541465666b02af61f78e5fcb07eb7636579314a18ae5dd29aa06bf36eaf1ca4b0afa65f70406bdcd9af061518ed9e6f900c01953fb67b451580b7206902e1fbfd76d1e92fb517c79f4cb67a5af08ccd0b24f07f6902f6bce0258dc37b1d4d34d1533ef343c7efa732f2a7bc3fcdbc871442efc79c13eb7316558e622471e475d46330d21f0d163cc6060746cce3958f7fde0c184794d6a3528de93eca88f22fc704b49e438f72edc9fd0a8111a3be154a4fcd956a7226d914737ddd2e2ac5b4cefca6ae16ab444419283e7852323778a8f126abd8d2dcc0e85b0e1fc6f39d48830d324799a653a693cafb387842c1e138f9f351b4e7120663a23f7e986a33fa9d756e0ccbfe7596a85268427ac6d30d58f5eac10ca0c68fadd1e098a5530d5c27f6b087d3cbd8a1f457e41105931545d44eb23b7f7e1a187ac38875e4be116b32d68e0e69d0763d09fdec02b430b52a145bd7fc3d2e7a35cd33bdcc96c274e25968c797b88789eec44be2af2cc54b570fc201cddd99355a254db1bd3015170314a1230b9d7a9e99b04134db5b54e5071673e1e9833f0c820cbf247734e587493138b81db22dc2f03b4dc546c6e274b21efa2f08f7db059d2620fb4ed11437bc7db832052fc2c28a89c1842c6d883732e7aff361b7920774f4cbb12ca02aa89647efa16e3ff45b42bc34a1f36d655b19d763d528ad4564672a16fc1f9029598c893a1f84805d8b9a2f1fddb80cc2d705d2b9fab4d87c58badb20bf647f0f5477c4fb6afafad544a71279f70d28f6ca600fe9a769184a0fe53c6af4f4cbe9236907e661f8b0f7fba8ea73c96d39958ba5d5b0cf5d1bb173e918484d7cb539a9954071bfed2bad6ac8aa3f98bebf296566daa3852543b72142994f62cf45e82bcaeac87a17b26c201188bbae2a67b6680bc3b145d857d05b976f4fd48af687d32326c5b765d33a59b043176a230ae76e277a8300eeb0b5bfbb158694c18223bbafe0bf5d05a37381646fa6c7111fe681d29997f88984f89976be3e6baa6c762d272120c22d03c1696a45ce4b85d3715fefe703c6a661fcd9d68142dc1364e770b122e713319aa02869b6c8dc8ea5e1f745b0fc3f060167ac34fbe9099a26a7c79f0d54f3d5d98607c8549461d773911eb68aee1d17df9e550bc1f9c640ca1f06fdf84aa7a57e00390dee6430cd13863ee711290b51a46c3248b6e5d6412707765c0d1eb9ddfc06b517363323da6a40945e048c5a1874dd7e6718bbf84d981fd4d427fe2d6d9174fb1477ba299c49a50dd00e34659f22dd31534b74026db6e08dbaccfc52f196af5244280225a96afc1d58ab4cf1066d37c67d4b0b3e51599d420857152600dcbff66f0e6ff291de79f761debcec0027d5c9aed8d50f631b26696b410416cee91f32341c891412d58e31eb53f076ca0b5b8a833952a903839f8d4631900434447488d5566731c42ad0cd1579aeffa1bc781160c4b1ac82d7e6c4635a1aaf1b88835d84c22f4d9091951cd80cb05025d9ca6693f951b68b5cf6c17b51367cc181b3fb0df6ebebc1e51643cc63e50526514ec7c6a26d892b1a5c43f3df5dd8f8e7c04f6f99644e56b1bf9eb63f82ca072862247958fbaa4d953238f9ff696176df2ca42292daa83cfecdb0a835784e093920514837a87a0400d7339a43664b5ff577e11f8cd811b18e0cab6b1ec591ccf3aa0be77d671de2aaed7ee4c14b57b84200a0ab0bcf97886fa11101095c725f4b4a88490183c5a721fa7aab7c6097058c160e16567bda9d616cfa572a8eea93c369a8f7e602cbf7f4d1b1cb77eba6c7e5293a1412a0d0ac0bbb6d61473fd3d767786ffaefbf709fbd60c3a46332a1c7d8af40de373a493afb2faed6771bacf955b9563e12ba2b2282d9804e1a227066dcf9fefde01c071bca9e39dd9d47cb7a911e7006a6788fa9f9f596e605a3941cafb99b90bc682a4f81e997d0ee5b33b7b931fa36d7f8a84737af4f99aaad2b7a066beac9e066938892efc15d19426a450600aa92a704e281343932c29916ab599d74f6d22ec81bd2e1fd668a01b16eb467ad395a96471fc4d07795dbd756aac699a2117f4ada0a871306f844b49965780fce4a8d0b35b5993105e70149ff275cab75102d231c685e919e724d583c306f9ac69e5db1c0346e9c8bb96fe917c547e89101fd9432c742b2de5e9d554673ad87de4a17c5f78d4218ce7e158bec6b173c39b31aed06b3c89fff36df2609a6eae0a7a90d415707660d5993272c0c7acbfce053b95fbe3c634fe1698c42d0bb5d5e2cf61f55019c1fe5578960207546380f97a6418f94bb690e38583fed7ad634030a76a066b1be0f7a5ca8f5719fa39e96250cfd67cdd3c73fbd2f134b9921a5b16a324ae593dec91e2b4cfc2504c1c02265cadde68349d1139a9e016177ffec89e1c528470ae18b11a76e06f0c1ebfc410241d4e70fa754a5841062698841f26a773ca5dade5b05f6e975ed7e3c9905237ea465507128175bfca3bcbbab253fe9ec18785d7a4b6a30201e62d61532ffe0aafb5789948071bc4f5ca6832905a7f875fad4a954da806d94baafda6d1f5631a2220ada68a1d150fd44cb4f5873a62bc8768e8f595b81e75137a22d81c5b7c94ba12d072d5d3fb632bd11cbc943ee7bf8dbf6a1fe3d9569408a095a0b306f460e686aca1b0d4f9b32dcebe3b3c2d6ac64974f89e4b491f770a355371c04e6a45d2333bc80af674d50d63dec3fb20d22beaca57f986ea95d8541e548cc6afbe048877a333aecae2d0d3a4ad09896f58f5923035622f4c76830110d626d3f9b3b15e18d50c103307307df673a6029fe836887848efc3362432ef3c901cc1a4aef1c9e39c383d4ac2e52d9e88e3aed841e3e6fd71286cd9f11f8cf1a339531b9cf2606a9e5e7865831edf51e59016bc2cf273cd8c1b4a66e239f5c07647c65dba40ff0aae2e9d3d601858814f4342476f2018d8f98500f142a174ac847c5747d6bea2a1c24a119548aa6b1fd14ed1f909a7130c096bfd13b5ed762898381e0df54bb63f2baea7a0a96ebb2f70d185acdd555e26f309a94983980361efec10c0f5c5673827d0ae5d5c1779f9ea31dffba2e24c1d573d93a61b4a930dd4aef2f7adf76349e115b481fd616962d3a3f4623dca7e794090d3cbb8f236245bcf32e32c7794b1fc6c32dc37fecdecaf9c4e9f9149f74abfb11269981c983eaa85b81b526571f38006051f1bc6adac5b1c7991063a6fabee1149ecc515506a220e46828cf4aa90961ad9a2ad9ed96c945e89ffe397dfd03a6820a1e53f350bf73707b872d18a16fc73b527f8331f7f8fe9d85a7f99cec327526553252e5a630c618c3b225e833ca3cd786074f1f129fdc7af6d001436da09fdce7b52b52b57bc25916fa7bf6436dfc2bfd2800dae97e53dd4b1e0fba4bd304e75f58ee6ef47265c6757c5a7e43c36de15161dd8146cd49ef8929f04ccde931586a1fbaf5618c3452abf8fe460515857a9af152b20bb7d176ebd8ecbd1f5ff90f062bbe407f343cc0e73f61d853dd81990d93686a8a707955444f5191cace42089eae4929e80a2f9f4706a99bcfdd944733529c97de25014802e72b3de3256bcbf8e74ec7320c63b310cbfeaf0453f351d75fe125f68a0100b6274795da4c2997acc37d8c13f0496b07bb845dd34b3d39245a94ce753938aca082b8015ca08937ce78b4665801d75831d6f231d5dc618ba07ea8c23f1385db11c0f0771124a29e6defd90818a28c9d705ffe1aa71cda8d6f002fc4663823f575a262bd58d6037df9e62588996274d636a2ddac09e01ba98ef7b01ce14b3c4fa2e4f85615523b303a5d4d3034704a4c0db1cc7c89c963e4bcbbfd15b862e6aab714f47d53eebf10d038363bdc96e3182fb58a971f7bd641d6ff3c7ac2c9c67d8dff50971f9e59cb899c88958886e8af02b78c516ca092ec3358ceb0428e1e4795f6862f6f55a4d18ffcbccec266c70ffb5c23fb998d4efa746a2a6e16ac17a3992dd74422b51bb26807cf4b0186cb42034483de875855b6df16493ded317cc418271ed0b7bfaef13272dca1c624df8bc1302a11037cbf4a5ea620e63b618c7a3287f902910109b9028c396254e6f353ca3a79a6f8c966f2907fe6a6fb7945fb9845c2a9e61d1f484c3f2ade383a9df370e9ac276128ca233cbaf2d5d63eb6c83689ac58d120ab469b3684224ad61159704b9a43e18de5091df1a0b05b775fcb8f71a120552244546426faa1d2a8bbd8a3a39eb62d2dfcb4c6c1f2cf944df1f84a163404fff0a7d397ffe7b48861c6d30b6cc16f189832f3eeb04977e9f6131955d17555de12abd14bb6d99b4766243c4b860e2d468dad1474e585d4fb245375530bc0722842c7d38747700527aea22665f1c771a02868bee8f14b5316955599753a10d725ea6fd19ee7e87f4aecfda785360d55e994bcf5730a4479f4f1436590192b36855c3f4c3fa1a9c820328a8c4e2e7cff7e043f1bbf7727dba2813e6a95bad61d09e162b30e7e5689a88f78f27d5d13d5248ac627725cabe3ab98c59c7f6bcfb1b75da1548c5ee24a6e95b92a24263717e6f9154e09c3048c0cbc26fcec5bb8f676c18158df673924324b120b75c59388e58360a6f6973c978d59ad46901fd66d97ed5d737c7f8a553b7bd044f22e6cb788d40355d4bc6c61146d2c3a48637adc54490282c1385b498e56627d9be25f955150de548b51c2384e7cea70480b21fdefe72526d212fec060c43cc0efd33f35890080ffe0d7cf4535af38cce9a198e58911f4c7a808e3c480161bb62d87db4c91aad6da4e263926fe0aa56fe222bf46c41a9b5ec56ed822f789b4a8a23aea82d9e4dfb80e130ed4fe70d6e737cb608eb0f9ebd5eaac89ca5629b70915967775e8f3dd0950531a7ed94a44c80fc357f88dc2b3fcb4b5566c0fdf7a3b5a4433df2e27359d3e71288e79e29e5fe5b2d8a49f999d1add83206f569620995b05b92f53d604a1fab9568c0167d86caa5b9a55c23e8cca28ddddd4ffcf7d4d1093b9359740f91eb50209b91eb061bb95fec09cfcba90aff8fe93e451d554f651ce24b0c908bbde2db60a6eb148ab400632d0ce83c0944772ec712ab793881fa4957b0deb2c7302b8f75f3292dacf27452a4335ea26532088cb48413a00cb6376e485f537a2c700ff205b4bc5284409a5c28d612499cde6a877f4e3f439a7b3724a2275120e23ea8341ec76ecdb20dcd2e10c006fc1674944361ae05a6e49589891e386bcfc349252049dc4acc46aea191e4bd0c06add0426353a1e7e4290c8ddfde2c4559087c3e95ed8f8c2679b0b365fd7c31f9367844abdfd35cf75279b27714989b0d66315a0a1d67a5d11ee84c9d26d59228e2d10f75ae7262f8916d89735fab5a604a15f6e81a3de6003a679e33ba6d81f31c90796404bf9731441ef13819364858be3b4fab775f2d27cd230d26aa55b63aadbcf59ee965a0b58f01b86dcfa3c342dc96b3f220df26c63d5373996f0c7aded69d5bac746fdd558c4676781b0bebf8283fabde76daa337ff76a2d853c06334a84ae90eaf32b65463dc1a81d9565b869c46c965a60465e6fbaf648e1f46cddb1f09ac26bcb8d4b8f9dd265b60f1004a639014df5ef989c7e6588442c116c1f91b44b78b439e53da4564552a5669b1b5115b3e0bc77d2e97ef35b245b4d01500d11a5d9c0e5a91316c06504952faa32158961c17f9e2d46f757374ccd2acb8c537b1974f965b30d3157319491c7d41cb81f5fd50aede8166ce15b9929972d83fe9b352bab26f2d6aa615297279ca6cbc41bd42575591a688a392549a175b4406a4f991cef20c860cd9332c6eb36ea0f9061ea307873606b1471276f059ae03774d145b47f0ec42a5a0ae89b9858fe39aad31f21d6721278460eb8a5bd4cbb39436c310cac2428f8fa05e6f549533ab0d9e35b5729eee6aaf8a859cbbf3f8a9ebe109da98c3d73d42b02982e867677bd227ad3a79af506c635433c7850875d2d16c58fb10a22c179d54a77cdf42ed84b0e078b0d6bf0b93d05268282975e70ac425ecc88d2096c4dc6a46fec1ce9d2bf7f663613d65f407907178df2bafcaeb8e7ee719578a937d710a9d572833ff5efa760bc7db6ab79f9894e1e109358c25621c0cb37f5e3a103bf5d6cb4279ae5d787e85394f18e93aa92ac89a954318b14290e6547a238ffea08483972524dc4c9b7de4586bbd179b83f152ab37840e84b82ab451d7ce1cc1c0789edce81e630b3ee8ee495f33824d3f33561574b27708de010051bf2a589cb44173540acecf8c3e71e13a2f0f21d83c626bc88704d9560249346c82bfa2f71780602bffbf4957c96b7144afa492852cd9946c22b50793e2ea13e35113d1cef2d4d7ba65b08ad613f3735e687e548e74ca6be8eed53ee1c9661ab4052757fdb20424da3d37c163e6b5667124f6ec89764213997a7299794a1debd86985a6ed15bbc83caecb747540d601271f59a26f01c3fbab71f0566fc3e026b0abcb22e01f6c9f82d726ed8188a10695687d52d0b0621aacacee1385e6644a7f9163250ee6d8ca4a95b0c90ee6611ae3a6049f9be0b55d9884ee12ce38750cb72ea8d8b519a216de7bcf999576ac99bcada7545c937b3da8ffcbab5daed8ea5d64c79c07bfeee988d0e2b068e3cdcd3345eb66b74017fa2622cba375fe74ed7bb03b73b59ec07df2683e4edf2c8cdb6d73e9b1877e52e8f016b6b65da154eae396e0c06a064a64d17689b416e609c380b38b153edadd4e97e6dae52924afb3702b58f3abfc58394da806759d73027d0e38571c523dc034d15e865a472a9176c4bf0341c5de8b1bcee3e6dac99178f08ffd7a3deca35feca6f8dbce5dcc2f86b6ef348beffe4f0f6d65028b76dbac3709bb6bd877e280b3c5f108b7fd1f26e40b4bd77fefde9a2add35564ef49b6978904a0ce51298de6cae0ad16438d37fc20f4ce34a41c65001d92ff9aca2e7bf43b08d097d2af9fde68016f2aa5afcd82076af00495ec449b86f8e88b55206d69ce0ed1c3690961323598e1257a5e6d2600d5c0fa8f44417d4456dc5527e4b32fe9e492740578700e761ae1bd565ad255a40b6a2dd0f35995dd9bf5e68eaf8fab13512c9c5b986017944d1dc1d28fb119baf8367d5b301f1cc245ce96a461c8e02e9ebe629dfc8bbe8c298128b667f2f30cee38d0c190b7dca569df9d36ea4a1e4c34606ca35f5a3b65a477c3d9b1b25040b788cf7d2fc6df1c0c44e85344c82412437c638c72ddb9c9dc80307c8f71381906789a114b7bbdab6e5457a645f6e9e76b83561e06b189c637a7cce98838b34465e3e5f24496698aa9c6ca42e14132b57162d172db2954868874eadc0bea5203ea96f2ead6c12f27f69c2b5bdadc06da6545df4bb585e8edf4050227630cecce98eb34447e6fc1495be01773447519ac15691979bea9f8ca6a282c8da692f8df8f81951a124c1075da890ca6898dcc3bbc60ae83171e4c8a27cf1e4359dcee2f1070efb6d0e9d8043244eecba39e70be0aabb1c05bff43dd8cf7dc99e67d7502039d1d7a75cea74aa291b4c79258a316393fd2f6e5072490605ff37a7625f7980fbac90cea6406da99b935ea6539f7fd46f17fb6952e199d6b1c6911b1b7e02a5cd4a6c1cc7b089eff7338842ea464443eac54f17f5ea70ccfd21bb7d5f4bed0f0ecf2a3cd95461426d74c5103e6c8ef6ccf9c92feaa00ab0501c7a535f732218fcb93caa3060e5411619681926327438de71ab30bbb389319ec64b2dec0e2ec312c581d2624b1e5303a522b01d318efa762eda2b437d9811c013ea38449daa75140676a9ba587eda7673a3d40a2ae821738875789e03c47800834d0d478553a28e3dcdb194f1ddaaedc3fb4f940b9bc2197db6098d8ed203e005c86e75a7cd53566ed8534928433b27817034e43ffba9c0ad1c9cfc717bc0c3446bbccc73959ae133398aa405054499c15630f03156f136ec1a568675f10260fd3428dcff27699ed9fb9fd5299da323fd8004f710bfc69a05488f90758186a6fa79a46a96ad356af48d5f8aa7f4e542e42b12845c1aaabc4d9e5d364d1d324bd68b2b1ce85931cfd19bd1513e23e53cf7e8857aab4caa9ac357176b37a3e2673458acf1c8d41e2aa3b41d5988fdeea78afaedf17748a2ad60c443d895d74b481873c3564e70c1ab8fcf6ce344b447d55088dae0cbc2eb4722def9165b7fec5611ff529b493d0384183f8e1df24a5dca8800c530458bc62d2ce2d300feeca35ac718f88876d95f33d290ffc57c72bc7598334d8441ec24ab53f919c1dce2d1cf6df3fc7807ce16e29d7e0675440f23ce39d9193a8c7484f5fe1e717063658247657122fe6f01b9069cea4e77b38544e782fa55f0e5ea90f1c660b27b34fcbd6b2e0597e411fcfde03f1bdd3361a5bfaa38e687b70aaf35995ec2eb42bd64d729843f5f2177fc7a4b2289420c48db02003c4e74c5ac03a95a9a8aaaab710f091c1d49081133d72ba3231e3f39ad5a70a38cdd999344f0ab57d31d039cda3b9d16105df8e11eb1bac939db3bf93dd9c4e1c1ba83950db75a5b987105781d7a0bbfa0f81db07ffba490a1f2b4790cf1939e758fc8ec9b805a68d9bd40b43e2af7078ac9f2828d4135d2967fc532abf8e69526741b30bcdefe5284978099ad7a23df1cd8ff9f6d6bb23ff56a89e54c88a1444c324a404224802264a3a5f9db13d19a1b0359d2b0e514eaf88a51b4e046fdecae6ac7fe33aa7e5502b12553ce54d2ea80021fcf41b8c22d8ffc99f4dba9e249b6c298e61072c29df66e4f20edcfaccd4413625425ad23926304e56be1b2974b3d342755e02bfe644ea444cf5ada1cf77e0927fa55043d52f2260ce819bc928da7aaa80510765d39e126da4d3a8e9d964e413b7f03b17e7f677c3551ba08b3e2a0fcf8983a8bdda12a8284760885a592ff8fe8b79f46605d536a0e1b5c81e4673fec257bbe258360e65fd0a7a5ac50c647a05d2039103d225e715c428f03b67fa648aba60f78069ff24d99d4454c1893b5bb13aaf9c125caf02d295d077b0e83c65eba41ca24a83c9fa5348952d8a4414357c3842132c2a37cd7e96082046cefcceaa9b21fd92060192ddde965fe2c63b2f45f364bba9811d49df8539c820f7b54b1c2496277b37244be5efad66a1eb5881f9e35da938e0194511fc95521feff6beae6f16db7b4b066c7d6e95f4edd07b490563fe580cf321fff5fbec8feb782bc8d7a0eb90a098487e986655d0628e0c05428933fc56ba7bf1bc348b6dc6d6ad431b9bf70a684b96b1536792b2725cf7446be31c940475358af23d6622b9d7d17008b756d51715ed368f578b8ac0f29b8b685c0f240ffdbd2846b3900f97425b8b92a7b852d7d37760149a2f32f8021cd28a433623c344c9f3ff99067c6514694aa30926507dd2512145c632e03599ec0dc2dee42d779e3a4cd420411e23df810cce0a7f6c7e76a8a00ecc05c36f8088af82ed15d47834679fa580f95f95d7ebc6233a5300530bfa9537ac31fc79dd2f21bf044a705691191581fd605e8317a00829a4ce5aa41699771e29e2d9cb93a6efeda239220822fe91b4cf8d532cea1dc69f45c9ac528e1e679967f0f6ba546f77cb9b8979e63f65fffaa0cad0ad8accb1554514e7385f79ec717c4a5e782b8f13d70eef666adb82301dc0f3e13e28c504be82ed4761985acd3875c9ba8372627d9c97fc0e7abf6333b1fbef2c59e9c933acc524d91618a3c102de6656ad3cf40f676d2d97fe3eda6b99419a31906b921926567b0260dacaf96c8dc76d91601003c696ed231bb29dbb888250e00e02502141181f8bf0c945fff43e99a6add96cbfde41e1ed863b1f55130e610bdefebad7e08e5f13e7768c1314f9463a182ff03c8bcbde56664ed37711ac301e040fee33aabc86a46a055188168e7815e65ab0fe73144366b9b858bf62a5dc1988a7c1aee05cb741950494696a7e042f7482166082bd62711e3f73908a84a9a93ff55510d1988635f059a006007d0036f765ed1eda0e582ef46766b873de824876816909f96e76e151118f3d76aca6cb3ffdd6e2fada7b87c8e2e7567700bf5628adb65eb65a825a5ab5db8ad9ef9aef2467106def5acf56851906fd3a3507ea46f0164403665cc1f5977030e79b192a408fa042ce43c051ccaebccaef90c90c577624fa6d03e3a149350ce20089e47a286bc4158c2876653e1282b35941c71187c841e88b1521bf4222b10700e622abb484871ddcc92de69ce038f4e2b05e1536fbe014418af7a368625c7db99c625cb8393ae84649d00241a307ae0d9f2b7d5a5bfaf34bdcf9ac6e3a7b1b4c34bcf33dadfddf895c274788e654b831c424486e09472a1ecc863ff7a0811fae5417bf8b2ee3c4eb564ad4195c3887438ecb0619bbe6d07837d43be9709f68bce2f39bf747c3b0c18804fdb40e361515bd2141a67935eab796f7989d2f5e171697ea7777400f58016b78a57c49398d1912b96d0cac343511ed3c0587ade9faeaedb96b8f151ef38d332994be4a52f5f98105bc9d3375f1d64ed36e1c6015aa534e8669fa6fd335cbbed0da892bac98953a633e320d688d5fcf7fbb1a1af4b990a0c1b801c7af1b50a26220f79186b98e1373a3c57225d62507d01030c6ee4afa604b42d1bb170ca73aff28da2f75ea05e5a49a010c2783452d1e8df57866dfdab862a8a4e8aebf5ae745d5ccf6b4ebb7c4897e67735060c039f21a0a917587244f14aae5c07f915995e808ba49a6fb635f20eb753d92f61ec353041f47b66a989ac0dca62c9a39cb0b5cc3219638900d88126509043dff10da2f6d2934afaed701a5b43160b2ccd626b2ad07605a1db444c0ba02c3d3e43ede0ac2f74c55937f8bbf2c719e233343330f6071847ff00510ae93a00199c1ba8eafd35e689a7ecc468219e57a1d20ab8a5cd2a4b3ea63a2f9274cba9426abfbcfd0cf259c28c494ad908804b0592422cd247476ceb4899eefb937ebb70b8d8a9443b46b692fe3da8ff9145b862721f2c6ec43c7d04785481e9e9a4eb932ec6d82c8908807fc43c700f5d1b97c67570e7d1626148b04fe3cedad681d1e9a95940c6f8d264fb4b637eed0394ccadae26c93cf4de2b81146cb8a2ef205f5e07a561eee4459dc72a2a8d255f9f3a772d4c29aa5e02b11ffd7c09e694c5b473a3c9430a9aa46734a18f5dc5e6d60666f2dd325945df75ff5bf67f51c505cad96c76354769b0018ed73587b6e6ec0b788b1f0453f2e8c0601ca46dfb6e4d4bd81a529d6e4b9b5556d8016e7d1fcefb21384961a2b61c0e43932384e94c6efb4e8eee63d69c99bd85d8c327a7f35402de2ec5a765e6417570753a195be7f3d44f5d62197bf0056dc97dfd5dd649d746aa8dac6eec3908f05bdcaf2667d8510072c3a4b4fc2e77d8f0369a63b963b2c1b091bf3a7e2455184e1ec5cc247739f0d097ead561355ebb4320e5681fff29821dbc7a2cbd37a80c04bb0b4046cfbd0153e02acf5887696d37457b3920bc70d1f0928013ce05fcd5c2d309ce8da52412dad37bea7ff17b25494795fbcd63b40fa30d55e0668865f2cb7374ad597bfb082996c454ae669813479a9b79cf3e5b036ef65030d01e8a64bad010ef32de3f56d31c7ba8501c8a9f60233be6afef615626d08879677d29cba4ae14c9597581fc0a5df37711e05443e22fb34aada0215f2c6f6314a6865460382048a666c3b56872038c381c637ffeca74775c4bf6270c76e37f00f3d0eebdf739abead8194a96be6600014e50f52cfdfab6c620072914f7fcf19509461ee84620865398ace415615f5ae99c7a038aa469a0a0272d6017ab6bf0dd92172151ffaee8c73b2645aa82e8d28c38a98ebc705eb5dd61e83c1e6256bdba671bc0cf3dc11f0e4974de6b76ed81390b94c298618580e21e192f3bebac312c1eab598336856f4551e51223479b1fa83d1530ed86462b965de1896cedb7ffa05046561c77bfa927e34ef305dd2f1f09b84efef90c4925c79b75d14b88c75158951054efd0dcdf9dc1767cd5e04a22fff48abbe887c45999e694093bf9a4af72e47020f99cef82a81bc4bdd8e5e1ec271f89634791c9e1c7801b93dbc0f054d16aab0cea016c791d4183218dac239a4618ab2c3b650202803da0841968995a6f44a9e8de52a2bb15623dee8aa5ab0a35330ae925559aba5f289a0e568bdd8879753c95f78f109cbe74cf56bf2bbcda649e66f9b82ab807f97c12c55cc8bef4bacf8cd10df8502d58398049f5f3d740ca74df5febda6e588ff8bd8ecb57addc61335f3143e5d369786a05a5df0232f97182a75d608e06f3ab9214bb50fe65b31ef80e8f160dcabd584dff8c52e108d61c106f701272a63f9149e3fbafd20414d0c6129d32cbb015ea4838cd462f8423249b2ec58be91cfc41629b49caca770f8e8cf4779bd0f4a5a207ec9424c0b3588408c4710d545efeddb5667003315ae004b43352a066bf12ea3e5499099c8a01f84acd171a580f21ab4026c19d068398306f909ba8249c053384670d2af60fd2c0a486d2cede48af111758c54a3a15f8eb7dae9c4850c9ab98cda8c8cb33ab5596e7422989c3156ef9e7536a50422f6cfab7666f12a71144d52eabf9253ec66eeab0b9d093828c9ec3dbb624c0262078b30cbaa2167f376963080cbdbb01f2a5104617e1e57c252f89cd62d9bab600a4639e2e50618d49b4acfe4fa6dfb278acc3cfa764ebc91997faee43bee59f0ffacdc5e88f2df3bb8451e4eca128b0c54462595d3357e5146631e404286990a867bd1c642bd36ce3337c5610e0c0a715cae9df576ac4de7858afa1c86ecc22e626615ad1f582d1f52978a74af442921a0fcd54c5f3fb67bc1bb65ec0c36ebb8ea6273f36156b6686bfdc20fb7e74be32ac607c98303d32639b02549c4c9ae18d3d269e05c750e6422a84fbf8b7f586d9919080f43b35d375c73cf6e8a1da7d92f0be880244205e5a3590b697e477127c63da0a0a25c6539afece3f61d4e2492de48ee1a0c8c6aca2b3542581221ca225422dcb87f56f8b8022afaefa1a99dc23f1e8eac6dbce7b2dd1c1122defc88d1b73d1c725dc1575d54d17e46fcea2140753699a0fce929d8bd56e76bae80ce593607d5e74ddfff82099790d4f5e793e3a6314510b61445e4381e56d2dd2a2b7e49f681394e9bd650d523800dfdd1423326bf65ef9dba9bb07ed6b0aa88b7f889b6cbf83233b1b834118d986408360ae79e809bcc4df961f407780c4580f7ac1e0ce7d1f41eb38ad9c905bb6ee7bf9b8becd1d75adbff9dc7c8fadd13f7943dac9251fe8aa2a0522ff239ce92a4af55e8671869e3270777d36f9c46159028dbca1f9b0bbbe24e8cfc82b74678f214b2605765a605c7fcfe71b66b38c82539987005b3656b8198c452db18555fcaedd0827510ccc088c542a8e10bee6df38c087848912a57413c54e92e09128be60ca65190bd862a000ce9df278e29b68410fe962e708bc8a9dcc2a00fdedb963a12a518edf77cca6f07604f5e82015cbae5e127d07872a125dd1dfc7e3dba6ef83375a35b44259eefdd0c43fee29349bc0120d0316a3504449797e752a915111015ea81907ea769e4742cac1b4a35ee1f6870b1c85ff19acc22184cfb29e7b01cc8b60104581ffd6a55f51b2e04ec2a0799044bd4830a48a4d0ef99d0eade8b283aa306b2de4e98d1c94d49c914ad3346304f4e2c200e481cfea3456f4a2870e84643f10095c64b2d4a9e570cf4c9426650524accc936491962f74cb8333e9a002ed3b03bfe43c52b5ffef37ba2ec679d1431150271f3c393082f4139d8863a19ab500b85862a008e24a4079a8546dcf9020e03c5c8983b1e8a829576aed4c44853865019961e1c10c8728c3aa0da80fc4b467430c69c935798e06ad10f7490bcbf0cdb2b2ffc12dbc993e308e574b3dc84aa47b5bb2da503d0585e938080d30ad907752b78268d2998a670249a8cbc2f02d4a1bd74fb5901a9624313bd361cd26792ae5812186d66e7d12e76c1dcf7242b80680757ba7b9a8522e9c20134c3f477d11352999df12ba3cb9c66a543f0cac78d23eb9d654dc35a635f6ed28e2376732bdf2c2b4eab5f02ce76e465389f79944ca3a09bc29e5165113730e88bde0a990d9e0f9a4a7a3c782a2174ae51e5432bcf1a18a229edcf1bb6f01fe6e4e391143f3bb4147076d3f472b72673892c842054f16729051d0fc7aa91ff639d5c9d9688bd748790359378c8cebbfea099b6bce5a0bd7e24647029813366f9e967f1aa3779c2ebc8f1127ca116c1dcf33239b296b96f74df34c88039464e1a84d71e733958144e75b31bf8629e31ee4e9f38aa7e24ec81698b559c0e7e818593d0127d0840e4878a68a0b429f6ffbf5a2a63ee06bc350edf2c6f6fe32e570c6e7ba19de72b8230689e9e201c84e1cdc5efc2b26b2f3ee57f1cbf00a7f0541eb802e1c423a63cdd7c40963fdf2c8b65fc807e052d8ec97c061ae7c198e15bd0f791b6210adc5927933af8e35d90e554ae82783190a0750cad3549d82a9a20c1c8f89f1a066f66a4116a2a5a704b8ffcb2e0015c97d5f6fd64a39e8694f96d4494bbef2e8348aba8fb514f92ad5db7ccd4a17ded2ab75a10174243a5991569644b2ac4a86ef6ac7cada0539607409fda0048f30fc95eeceb014ee7161c39627505c06ed20dcb251074eadfb7b99044ad0246fbceddad2a2ec49503ce177a5e82c127edf9f31a25beec9d1a75115099c933a6ab8ed06202cff95c2f76d49a31c683f881c7a16aab3d30fe01edb22c1bcb8b2a7fb490a2d43824a8bb9c0e5239dd8e3eb31aeb6dbd1b95194af4c032e98056b90b0815738036558181e72773bc25f5159afc281831cba06a32e82fd1a8af78dc18900cdd804e4bb46f45fb86418e84a5852a36873572c43dc775834e94cab849efaf43d476bef2313906e108fef31cba8eadebf367f915731839af3f9f82aea23d9189d5caba9157e65be2416c3559a03aff4519a8f57e7979381b6c2efda2d82e5ec437fcedfdbdbe31e101b638a0d5912bfac86798ab23020b0ca2b476ff6f8e4be337a01775d24f57d921a758d7ee8366719a49eb52865ddd1b4e05ec972a96c026c71d1727f03533d28910bd97a1ef401ffc0bc0d88497da4cda6cbe8de667f6c5de57ec07e6649cd31a9255cb33cbd559ef33dca130a0ff2ebd95e3777fb01c9a3aecd540664f54d1e32842df39d5658071058ebf14166311fb87b5572709aa972f83531c8b3a1644ed0058a7501e943829e98745eaba4c6d39cba452dda479805338c84f905d19c380621e9e3fff1d8b78033a294cd3b7ac358866785fa74f0a12a320e506f237c67e2bc92e33f1be863846c5e30b2722847787ed83b7fce7fcd80f88a28d3e2b1568e0205b60318c8e3013007850203731714f6bf604eec539ae1a813df1d3f599a544a579d142e9499871e214b10eeb17279fd24aabc97b9e94ef27a1815ad3d0f18e98f37e39d82f36ec4aba3873239f073cb7a652dc30f62eed7edb0143d08572fb185760a9a8ec04e88c94328f35273e76596b4ed5bf21c94afb8ab4fa89877ad690f999e7ac2967e15e93a716bcec07078c58dafe79c1df03332283002d7cdcd797715792f5c8edb8b8fa6ee6ca80c8e6e122627621cdb7fb0294e7cb70fa719df643f280161f0f760240356dbe7686d4f16878696cf1ba46deb280df9da01d645c30857fe2fdd95e8358d18ce760e5fd7c7ddbb5b21184c9d72b47a8b741b469ba414f64ff8503056670b7c3babdf5236e37f65f486aa55d206341f8d82365f19d987a946fef2c3e48aa57dc8ae5e932e63107a025e61a4192dbd59b1658d5471c9a40ada6055bf4c3ceb1da99d5010a30555380627822b6691451f4f9401197027d3f203b9de87f717e57911f352d5a6a76ce70d6945879f0584e90599f660f0c4a3fa7103dd643fd77e821854e97acc51501d30a9f7e086b0a62a83d6789d84b2fcc802669526b602c79ecc5cb09c14942b5803a862cf2e41637d06c910877794bd4fbdbd34afa9401cc7ed9d14784260dd3c69550dea892eaa193004ff140684800b692fa5849a438002d35a5cb1ff3687eacf26ce4b417e422d5d6644f3dfde437ff79eda13a2d0df69bfa87385ba506fa",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x2a5f7b27730c692ee7e4a184eddc6c52cc254e0a97e056c3c33f7926728188fb",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xf73bbbd26a82dbc769066550d8d4585eab2fc00d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374af0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x0ac31070f73ca9de682e1bbf7dc037944de1b3ba34837b3dd3d677717e9fd1e4",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x29ba9217c209a169e32a05abc56cb0e4281161d35df16c5d2d5fb596dc424852",
|
|
+ "timestamp": "0x6ab8ef9a",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-anchor-20400880-baza",
|
|
+ "sursa": "2800-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa00000000000000000000000000000000000000000000000000000000000000000f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b8410f0f3a63786bbb6c535c3afc889dc69348c283eec1f029ff1b90c4beca70d6ea47d320c33ad6d26d57c47caa2fa273e97cc3451483f48f22d8297e4a665093ae00b8411cdcd0bba6c3badbeefce25c9f06689666c9c8ad05b38ccc47078b8ce68ab89111aa7711651e3f5ab197513943812eb8bed8ba05499d465fdfb4a9d5a1fd953b01b841f765238d34076309a80fcce60033728adce2b1e5a826817e462c5a05763e83ed7219c40cc9673b9f16cf5289555405c2ee0f5894ee88cfce06ade8ed520776f301b841cfd7522b477eaf182486ff13c918c6d8deb5ce0f02e686b7bddf48ecfbf11a757dbe588c2f733b57867dbbb5ae214742bb9ac068d1091ef7d66e6fd349f07bd200b84191277e4419a79ea8b9f795715b27c96f17b65204a47aac71cbd3dd22501c7a287a6e7ccd44ed514194e938150d3160fb15487ae1934cbeed1b6f0f6fc7d6204701b8411d60fa9887765d7b2529036a7b0045822aa42370e3570f4dabeb9f7e5415a24212987134b32e7c2b4773e4d3c58f12101e56854cc40752236b6f31f64034cc9d01b8412bf61ba6634a2b5c495c364f3ab9181ce316134dcf8c42aae26876fcb575017b275dc2e584d9946de35d2339c2f530b92607d0a3f463ee90936bd4d0bc7ea79501",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x57ca",
|
|
+ "hash": "0xc34e594c77825d2b8a6b9bfdd80ffc37e936f78dbfe05cc471b1cfc15c48809e",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000002000000000000008000000000000400000000000000000000000000000000000000000000000000000002000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000",
|
|
+ "miner": "0xd38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa2",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374b6f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xe180d37502de3fc308b45f073d8211d412230bb7f81949a252f30f7bb3483875",
|
|
+ "receiptsRoot": "0xce0fa3eb969ed8f3897c347d3c2e025343a5853ffca49d7214cfe0287451fcba",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x8fe4d2a3869910bda310902d74383369fce0b3eb119e33c77e64516b7c1ea45f",
|
|
+ "timestamp": "0x6ab8efe5",
|
|
+ "transactionsRoot": "0x3adcb302cceb712989341e0010ec2614071671b58b14bbc0df8425fa2d3b7ef4",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa012e9da0de9d3feccf7192492c17f42696f2c8de360dc0b984aa49a309d9e30a702be3f7f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b841069f2cf5e3f34b736df29420dbe04a68e23e7b06bf8bda19067c566e3891d47329e2cefe37d480906d16a1c7565910f487dcc22149bf63759d6b9a06eceded6b00b841942aef46d7b41e322d17141ab2d9529d8e3a1a9b8672a2dde056c1f6dbad022909d93d5761f51ca1570d35f6853aa237b0658bd95db20d6293f3ddab8432488300b84160365259b0d51db208b5bc780af6fb046c2ab48f6f773eb4ca0a728f7188d53b67873ba128c48b6f87b036010e5298ca5be84c88c4616c226c58afeb9c661dc600b84192a49b838b2feae348067c8631bd0f24946ddf25afa5211ddd572d2f85e013f222c282eb8e6104b3a1e9e1310a4bb38d041cfe296b455c4f102b30a43157d77901b841b71c1530abc84de481fa35fe7738eed1fb200c9e7fd151958ee6885c2f0b25dc0f9f6eff09ae52cb8183ea8d7611da05d23c56bab3674c85c03cf1ed83c60e6000b841591fc9b3fe163d842e0e1c3544d5be2b191b20fb5790f72fd4744675f73656ab4edeef0421ef5aba100fefab30ff2a1b74de8dc190dd59db795dd9a73d121fc501b8419e940b59fac2aa84ba32dd5e6b2557dd058d995ea7a3a1d1b5bd5ea8f21de3e764adfe84af19da5634b01518710796ad8142f10e070455dd1bbafcf997fc522b01fa012bca02fa012bc5f902930180b9028e39e13848b94183a641527b0050c3cfcf34ff66933bc2e9a47d1cdbe37a7181377c2990d34b44032c21e592f397bd5eada3d1a41a0c8186b56a654a0b05bac43e71e6f727a9e16602f27e7554489ece388426569e6c04b9e0b5992552369de5ec3c7d8e0d5e6de37844a394b5a729a77965c19358c49e085b517d9a47104ae1ab9e0c5335503608bf90bbf4bac1c24f1bcb393ac097ca24de93daa877aaf82bd1813fb6865ff0ed21d9cd33e47172ac204e135fb697c17032a6ed317cb25b3dfa273969cd6465c1fad6912c80b5dd38305ea55391426888331067757c281aa368b6c29d7b037b8c662a12077a9e6012ec265cf5f6f056fc4776bc8cb3711a134b7f84e5b0b1ed62c9dfedca61ba898cfe2109f66912fcec812c73f38af570c153e57357f0d82459358f5bb1ca10c4c7f7d94b25cb7e3f0c9cf0b3429cf729787eb547a0b54ee81bf53f32cc4dd05865d91973db280b275db67fe69f429c6e92a543ff994b28bbd50b44dfb085f32bbd997170d92bcdf6c6b44c71f0e76b06fd2eb3ad811d4247473ddb3203ba9a613dac6b285153ccbb7b6ed4e3e2eb64d58767d1a61b590a6fb90c6ec639d86f57143b0ba0245af1bfff5e77e7275f5fe4d930e6bb35cc7fa50b339bd2eefa18c5bd8fe3b6f707a948d1c3194bdd0300c57c08c29e59a64c9e4b98d248490b2c9b27f8e231cc86a04e2ea60af3689b7b641125a5699609dbed23eb5889bdeba7fc400c4dbe9044e3919f9202dba9ef9df3bd344750c6d2dc712c74464b71cdd0b204b51f2a12d9b93c38cd43f02b39980dd66a2867c724c7409c2be91f36ee74ba9f7064bbd1bcb8dfd0d89fdc48c47284ff04efd13b4b9fa3c1b2b1a2743ae2abb8f63524f43c0d5a2a68dca81ebe8f75a227ac46921efb6eb429eca3ca984ca0f91eb50280b91eb0b73f14035f1b8ee963f044afa3484664d79ee33b7a292eb284ae92dc75defbec3fe8de879a14f0c2fa2a466f8380f0b1bf28bcb0f8aee0b76b4ddc5074e37a02bb123ad8f6393b2e1e473b8d432c0ad508963851a073a05de0660272e7942c7b716ef92d2ed390e2b7128f02c1107902927182423dea67758d4d7e2b096ef0ea33f0832141646af05472ab132901b1ecc53bfdec6556df0c5ce60b558bcb9f477c93fdf79e6f9e328f9c9c90bb3124c1ffb1d68c51692c75c4d751fe7fd4b2b0cab7fe4118fd412bd7ae812e54a7ff1b5f7a4c649ee51961b8383921c2c6259aeb03f76bdbed27b1b6b414ff31ec26c71116e9904d2cc2eee082e551034d6ed1550fd3ad1d8ce02dca65dfcedd8629cbb378bd3df90af7d1d331210cbddf99780fe7c96fc13085e919cbc46642836d06b13ffa080f7d172987d1318872f73a903a352760f2c4a771233abc6a95ea045f62907bff238f9849d328997bbdf3e74cfa9f47093df67790a6aae37e80e7545a733415434974ce8d8ff500e4e52e67d6dd86f007ce0fde8eab4a95a9eac751391f8de3e10a660711472fd3da1a963f7c4541a94cec0395d3117d75406c1d471623751638b64515e644d8e96f47df7be8c2677feca0be1ca44f912828bbd8fd16484bca2afec747a04fab2dd74635f8d0aa5624ebfc8f7a03422fedc93d6d1c7089db92907f128e3cd8c014bc3aa92b24f1cb509aa755b2fb4ce358d4f4c225759ec4a6d8d5079fb18dbe171feb29f912ba2e78aac71820dfcebbb0d88c9b5e133829e33c09779548986c4b23f1be5e515c515638c318489ced1f5c5143cfad5bee429a3044d5f52ce17bab8157233995c3f97663c2bde92d0ee625ed91c4985eedea6b2dd4d7bdfba4f1328fe4fac411ccb283f96b9f12355f0b726038e40f4d11121a5d4f300e11530c07ac8c5a2fd47efb54e20523828b40f35840fdfb91f40b9c5682f32a15f0509d56e8ff005b1d47ae145e2e27b80be5a517bbfb6310de039e6be5390f8739820841ce6f387d1e3c734d7bf117bed8642af574447df9858379fe7143a5d51774fdd65dec450025660af18ba3a96eb4327edfa0daa1d5d1230f90f3d475c64fca7e148ed63c9d5adcff89e42c0a10b409a964b690295f08a39b0fe33eb2433c6e2cf0d2abd23cd53d20e9ede47dec45601697d7fdc31bb20ca9181bfd5bf45a98c74b73f7679f7e273f61e76febab27fd2aba3a33757e55484998deeb58c3ff2809a74a511d02769490d88d0037db1bd186b506ab79af956c83eb61ecbf9f39f9d00a9f51c0296d78b2f7e98bc331573ed8a436114506f1307496b8b17a4e6209012b9ca8b3e5e874aa6235aa84c175fe9b0a5ff7baf6b85a6d31e6424264579aac76dc5f2b01a36bd3e4eaa431d1de35648ede9c1176596f2dadf77288674fb8d0284881c8e1aa9cda646ccf2923bb1e91954810c98b6692623f857a70283390df540f527c6bda5f78844b813d07ba1db0b13da0566985f0dfe1c394c4fa8294ba3652bfbf60b7088404a22c3d517ed928bf79894e9d8d9b7d6480be57065dd6a28ef370afbb81b89b23e2276920ac13158b11c6bb3e0b1669e37a766c206597ddfbfcfab2b55eb436dd483430f75b5f0db436159f6aab0924da6a5db1ef96ade76ed0933c035cbad045ea7698a0675733a9600f178f9f214c628518ccb05b4a2c9689f0f8c4ba29b64a6b79362a2501d2868ce350e60b29ad21f329d0a5971bc48a6b8cf9b8eba86b1e856dd71bca8133f1b635c2081d013f2ab6949c571b73b276981b1ccedd8af7d3310677b5635c5d51098e82bec4d9dd39745b1cc6438d7d846cb93b3962f77a28d28ee89a68e3d2e560d5cf1a003d80909d2cba2b775d625e4ce65ce2bd676690c5b84030846370c94efd57ed4223765e6fbb083b8cc9152a9a13b7d7cd2a3ea135501af113ce07e6b6d7442578811be0ccac6523f742caa34f12953dc4b51a54b8d1220122f29370ea67aa33cfeb2aa8f278f287518f136abf3a7672a0d0a88f779208eace2f3df4f096355b1c9ccab794b514dbf9a33078573a44a8657027733ee108b9562e9f9913c93030af24972d44e97fe5e3dccd948e1d2c7f0ec0ab1ea9b2bf59583ba597fb71caecdf14462a2484046326b2d90e1f3a225730432ececf70914304f07ba781cbf5dffe3a01d322e3fb980f008043c1c5666243e8cf6ff4b8dc4656d0fa1d8371255d966d4de250506925c920db2f1bb7090d4ac03f7786ba26b034a697b72b9ec9a23a116d1b8ec8692b490912676ed266b2c79c46b391a9475a64bd0a93a6e07ce83cd221c3c7080e0a1162f7bf53c5cee74d9a9bcceb8921f6063534b3b53f01866866111463da7da1ecaddfee1665cc056f7ce447bbab3f8da58ac943649cedd63261c26701bf0a7bb49d5311fbe9ed5a3035e4e1d60c4123ef41d1d8c1ed79ddc01af34fd355d17f78129eb738889e3ba445154cb93af0675e77f581dcd7f2587a0e218d7f48f77644b8d51dd49207269a3c0afa218468b24634205d5e6b1d352fb11e6cf9b477c12ff4e707a2753d0285369a9822592081468afcc53993902c9df4337911554c641290b835b5d0e4e8fb5ffe2f6a57a0b9bfd42a3e8fe0d19e8ba3953560732c5e24963633124a2120f74ae019b30e9a2754261c017780213a0d807fc9a709fce5cf9a46feca831d1593c2a4a2fbfd8f918e708b3b7816bc5e2a46496008aaaa90e523bd4d809511d45e114835299c9518efe3a65490999925ef404828cf2a0c30da4edcb52cfd22578c46c551ca9f1e09c13a22d190a55f1947b5af4a4e2c53d0ce1c75515e6fb0e2df23488e439544de3fa32a56cdd1d535e27bf75604cd34f78af0258ee6ab41f50319ef92da93da6c1e611bccf51b289fa0dc95af0a8e249b9e22ded680f3c4616a0398aba81b784341cc8a210239534c53b07f6a5978e34452dba3a60a6645470451e8ebd3aaae7a53413073993006b2b2129c485d9b3360ee2f76132671bf04dfe85160cb28ad65cda2320bab5c6fb11dcebcd92369496dd26dc0b406ad4dce35bd947bd5d78eb70a89bae041df3b445635e6876701154cb0e4cd0f14ec61ef6a45afdf3e0bf01ac22daf59b3b7f596790e7b4644ebca3f18a65500daa0444425bab834aca0890f151efed084c87abd8c51b0e02adf8a975931176340733b73c780094cb2373690137fed43910fecc122a6f3f277efe0c28f7af48cb94b546258214d6ac632facdcba02123582ba5f9cb79dcc8367b02724bdfb858b29801665bca7ec6a7ea0cc6e2ab558edcd2ea701c71bfa75f33d53fcb1ebb7fa89145d4c36d0393200b9def43f9d993a95e7e5db769f6185e7d02e3ee46ad536bdca9d7edae46764fd7143fab52df49db59019c8c65b3e1320382dfdbcf7ebe11fd09b3ca00d65757988820b1e746f8533d4a9c2bbb16e759abfbcd845906f362670d3e5be039cb306472474849eba00cf8f51f0e68168f9d8cbb57d0e6d8e5049b66c460c380d7d0fdde1841dde5efdaa5ed983e87e859d283fc90856e51fdeda2472cfa251ee1226a8a744216f568cf1cd1c605ce0366daae581ce4257f6acf25e3249a346e2ee920c3e7b4cc305fde942ffaf5506b457b10499118e9ee9a222bddc61c9ba877b3f169bf1795597e44151d9522ffef0a172978f11911e89d878d38bc336d247c0465a160f4b87ebc7321399336a455f9300f70b6fe343b6476e61c3cf08b0b63d6d17a0c1d1118db234733ea7e7bedb979e3af5bfdb6c10ad6a625c0a6250b7a6b284f7d0fbf8f90be4724346cabde82d49edcc37a86378486bb649f69c2488a02b4d5b2983e6aaa6a97d58bfbd15dea2689355e7b0ed680a52bcbc4818cb12e3687ec737f12ed0935bd7882ba0fdbdca3ad6193adf1958ee7afee48c7347a6afbadba2716a4ffd166fd5efbdfe33786b413683a3d031765ffa3ba30f93f39b41b6d8994b854d9c3ff30072c80d4a9df154cc56167471656532198092569ba12f27e85a7b9d05f9d46c06aa467c7b9b747ee9bdc284d580d7635486d1a2b47062027c1768f8bac8f45a7d14dfbeb4d83a4abae88c2d2709f6cfaa18c825997d6b103c8be85868db4672d3a046830327adf064f4d535ea1bd46ae7e013fe394739f160d06744b2d94a4f08b55a3c04f6edd39b6b6fb3c5cae27a774838499a5f76bbb0693a14d1b38e93420e655cd8c69bfaea9266e29a39bda4360a8c4c00a5013399c8472d7308e30f85cb7c4ac0b6ebc01fac54d2aef318fc73111ce7c5092dce7d34a9fcf4836f0c97bcd95f79afb903c4a53f5698f3322d57a42ca815ec1f3fd8712e9006ca056caa845a6516bf33c1bedf85b3514c9cec8595c2445f7b6e5a71029a644c0b9a1266d732334a1abda74b66ee6e20a2f34766d0fa0910b2bb1e89f6d4cf93a1739aa1411d1e31af031c9c7b9678359758b443722bfd76a80209b5a6da1cbb49fdd8c117447ee36a918ca7729e1e6a24825ab6cffa201686c6b1fd12c880d71603211f34e0ab9164346fc8583ab8a834746ea92d9baf63cb5f968178cf2ba124303a26bb9374fc814b545fe54ff6c00eb1bb010b09302f4d2f0c3761cb7acf38109221bbf30b01a3325a27024a4d656edc78a7c89575b3adfd3d947e944cba98d26166cb48bd542b8d13e4d71210236e9ae460fbfb0b16e987a2b1024710f444c6e5d6d99a8330a75e31cfc7e8a7115cc93db52e9b5db01d9fa641163367c040ccd126d02271e923757a732496158e8a7d27db9ee2e22dfe38e783253bc4be6f37ab3f1d6df9bf90eea3594e1e687f50fce119742c52013725c90eb1bf48b95a0570cb69359bfcc37e6a9e7c2e0b3d5d5b79c0746b25b2b5bb05ffdc3fe18e0d133f11e648a2bdfe8260a5b45a7e0386475a413ea8640263f3fcd7d2bf2c6d13f8b87c345e45705400edf11e1df02f170e054a219fca6b89576bcc0cbe763f5af250c618b6459552b06cf93afeba402311868643a59f5a6c4252df7c8abe4af1388abc7d53ef1f923dcc1044c63a0a31615cfdb1b8ab6df06220835cd24e5fb8a8e89e0be18395bbe6cdb6d449891caf5e3ac9807be4a5e4fd6f00bee29eeef2e254deecc0a534c94a1f370f961e7fb3b4181d28f09205ab42760e9456b2ac62f2090eba9af1f4caeb735bbcb74adeb8c45f92934c95d332533eb243b5c3d555af4d78f25d76ab02ce0ba92d92acc0adab689473ea664a052e8df8f1c278fde5dfb638f3bc6feb3aa738b12f91ba1a352e6a2f155430f108c94295beddb19ce5a2bb27d6815a16ad6aa76cad118a37fee3d4b66dd3822a76eebf8d821aa526e06726229b7dc6462e08e697fc674663bb123c0195cc4a4f7c5d683d72787d52649fa0aafe9d0bcba3549d909cbcd9fa6499e581743560778996ca64abc4fa0dbfbe37cdb684f72d49e4522773354cd3b06e5a472d47c1ea2205416ac819c7c9ef9f2d877dc7f57c10da896653831c29a7928a3e52f755c375e95b62a2eee4d9ea402590162710bc9f8e7739d34221e8d6ef5e0ab52010af977bd580f787b3fff59eb3cdf38e269c90f2a231f8a3e438f28b925b40172aaaddc0b5d709d32485a6193354aa908b839a93d3f777f9f4eef47f3446d27b15a00630e18d3dbf54238e945e0b3d818ba6a3a18c364b1017c36cfd84f9b668d2b404b8da590d8f8042f9cc2de2a3ffe5a714159c45a12613aa59ca67680782f98e5bf6c7017dbb53dc96c4d0f3fc7003df467a10fc1f68d6208131b272e27ceb2f33b3790de134f4574df4d1372843591939fffb7379935e6f76809bff2876fde87baa0727270e87a0f8c491a866dc4ba5bfe8dc3145199e65132e1d208ea9818130584a5884bcfae9c2ba0029be74f54d7a105fc5c3b5bc39e78e124fdcfdc255db82a45c47700df6ce7f320f6527c61b55dd2450ada9a16463131b2a963a75bc141cb856c4f42753325905d349d1bcb6504c9a75a58cdc9c3a913c8d3fcbf11cddfcdb002e19ae22698ca480784e2b52edfeb64d33b819bfcef2f8dda82e669edc493ca849e2e01e346a540cf1dfefd2f5c9181dd31f985f1eedb3af18c69b0bc1883a8bdef07cf17007b9cd97a781d2e7af1bc764270bf5239b2beeed90b9278e5dc8dd6183d9752081a6ec695eacf74bbf6cfbc2959a29b2c3edae59fc2ed79ccd14ea19b29b7e28f8c79545ca3ead9947ca6c35bdba830375037bd78fc6f093357b44caa2ad37af7ae6a449101ad02d7c2843b3f3e8833767539bb3a8792dd771ce2813667787a510e136f3726e28cb29a977dc23702780b48eb301fedc51c5cfe34c2ffe66512595dfbf3ebe938b52750b54f25771cfbb225b60b19f74913906d21f9a4f203f394f09b9038542d003bc1d83bf0b35a743a510b8a5591fb5f4950012eebaf1cb7572c0fcb31fa2294761f009d7eebb192f6e738c1110b0164893ba19be72f7e284c1c1ae1ff03be4e3406ec827da0d27371e94333fa4f0a136e0ac8dd8762f6864535344d31f9ff6c647e19b1b2d9e26c22128b4c9184beed60007859dbaabaee7bc7b75038c94fa3f2ad4d2d3fa78babcb90e020966afe8aabb3f52e23ac743cf8516f4e1165343aa9ce112be400ee09ecdec091dcabcf6402a7fa3424544581e359c86d7d6f5f9682e89bbf0854f745a6142bf1eb055878c4f6d2c6f1db414705f724811b26847d3d4461d23e78f4baf229167f2ff83c622e2e65aa8aa9971adb4ec98b04f2634d0e4750f449954fc6f61799077a47ee6ded20891ae4188112eece65b88b5d9f41a8f59bfd50622e3b2d43cf5f4b1e10142e1c8b48890b0da276dc07c75e9e9abc16d6a3fdfb411638527278a14d9cc66ff5fcd312650006c784d242ddbcdfc49a0640ba00e177dbc68e259d86302ff467bf19de4edb0bdadf2d4a3df9ccb0f0f9eb7cbf1b1f959fe642fdbcad47243d91a98853eb4195f3f265b43fb47b272afe3537c74cf82e477c52a09f934cccaf17fafff0ffd8b0bb2761fce33d8c32bacb0301eef1c027269f4f373cb275e08be8346ff01d079acecca98bbd983769a1c9a290a1cd1da77d4948f5772e4f4d498e2edcccda820f1e1d4d9646c9ff34a8855970060317c31435cdd6ab99907a7f24ae7662ab36e92a84edb3e1e162b206041e7cca56a9ea1cc661b5ceae313d082968659a5c65e6adb3bf9b320902ad7b8deb0af8c2b9c194ab020ce10fa4366649c59e6562c6b5e66eeaee7aa4e3e87fd05e4c0617bdf23da5da0b5bb77701927104867c6376d500b5690ebf9ac85d650f8d688931878c57032ab6ffd98fe3c0675915438568d238af53efae37f8afa495b7d20da7f93f3316fbe115b3af40a9da29b3cbeb79f92f4bae29ea1c6eb0d919707f3f09ba597af0fd3f04892fbe9d2c1200056f5f942d86f59344178650f8f10e6eeb4c482fd1a865f722f59fbdf0d912af5f3eae841c4363bb993454ba43f7fcd728de233381959af012bc27a17d4f990b26b72f23ec178f2ba07f61fd35d85d4f518c6bf512b53054a125df92c23536e87713221b48f259ff5f91d3c59c503da89916ba11dfbb8863eef93fd1785ea84ce44be590ce6a818746509088b26c1f68ba4fd8892cbab0bfb29f73c7a09d03d300fdf99e71fbd01ca8f1abb9db4938bd20b1277c7f49ece0ac363252e61bbb4ecc5332db12522f15c2d197e2c06c98309e65d1e5375c0d212bf5066f973692ee3fa8a16a9812154f82b621beea34ef3cc4443f15e0d83b939c050380ac228e6435950df0a1049211081ab6828839951ff485e41ed4bdd89a21e7f4a44c1853a71f5982891cb52bc1499eaab51dd1e74c3058002192267fd61a9c44e7a8e3df38b185243586cac248937c42da1aa8209fc4a60b09cfb9393917fb26b6d41cf322516ce15efbd3061700cde6ec03ae41ffde5060f57679a59bc0ef840028c5e243c307add83bc1b4f905ec02f52ecd29fe65e3893941103e7c2c3d2a628358c25fef1658158eab540bfc976cf09208bcb36d6c23ab5d06d1707d1fa28e42c882ef19179a6e44a1aded458b600ad2904182ed0c3e523778030f56e4a294b6ca51ec23653f164009792b17f9530264e3e7d8b07191e283d475b0e709b7d501b4a03af87747b03ff3df32212e4af971b5bc1e60c527c741edf021b866c167c1f37c4ef50ed1ddbcc121ec7e1ddcecf3acea1e95a75004dd9b9864dd61f7f39a6df5fed92c99fe61d24cb80e1a4f4c17c6c12cf1d05d3a499321649998896bcca309d8be5deb6fc7ff2c4e7acb862b39bdcf4acc9c7adf9b2780c387dfc647a207eaa0ffb58d8667906cc5c4279ac9641590a43e87d556e65e300c00394a9434294a8edc1479d8a4529ddd9b0903789e943f774303144fdf0511567b4f3e5de0d07a474af48f952247dca6846ae227093bd06ae8137a1a61afb36d26a351bb8f59e584bdee0c5fc84491331ca7ab844d0924bbf71f1f9a7e0a7432f09e1741498ec569bff0dd937a01bc5548ccacc9f2f4baba9a850f6f0df34249568bc3dce09f6de2f91b151b5473d4e5881f3a2ab7e2c85fa8d5ff22237129e92427e125cdde0fa1606069b4cc420d569046696acbbfc42ae725f967fe1c87d6adbbeadc268a0f49e4f447ba5f17766004bc66e4c763158fa597521e80cba2ed42d4e472892f347978af5df9fac3dbabbd15806ce8b08ccca00fc97fdf258e871a5910917d1393359fc95f5f3a2e27758be8b79002c4e3a16c0c22132fdaededf6c36ab3c9764cb702e5ed3fe36d9564748d06771faf4251c68ef52e5df2a0ce212a7df861ac435dabc39e33d9556c3d60ab2dce8061fa45df904725fc96e7defa23a3fb4d32a90f4e30b2d69b14f2c1df691d63bf5be0918a80ee71369e9dbdd02bfbaf7fb2c14c2a23a23b179e7617879cc4f0469d6a6b8201d0d7ef53a6df42c1597875b55371213eaea4bf6a1748d8353dbdadd445af66d15ddf7f1d9c15d2ab8e72063595e6f8c0488491ca968dff1c21af9bd4ae32b162939610dd944a0919c0af71bf33d17126c37bfeae5d83db93e820ddf1a82b326098d6b02a1d84dfc8f97ab992f1fb56d938f040a5c3742fff1cf98c8be147201b26cb584f8b77194e5a461bbff9515b9c25b961d56e0f4d10fae75b9f7787af26ba316c96415c04f1766d105865428172f3527abe9360efc57be329f58a854a4deebeb1f710a4e6fe9c81832eedacc58e99bd897c2c9120b83aa55fbb24a670e4ff28fed47dabd68fe4b55545969ef74f96a43d85cc927d0de64cdbb2956f111b282c4c580fd5c4453a7d09926e2350b28dc2cf4c3077bd86558c45256026e15a684305ada632eff1e7daa08972bbcd200a76a219051aab46ce402372a498c988e00b3267c8db2bb5867da220e67fe35d44914bfe09d6f3f32762c1dee42d1ef4fbd45dbe24319af22dfa7588e06623ed90cb5f5deee86150196f8c5301cfdc9197daeedb878138aa6d13f3e1924cbf2761adc11e760fbe7c559f498415e5c59bb9c32a1f2b84744824173431c9e0becc10c158851205c92e0e4cb0ee4faf889d7b2d242b1d13b7130d636cd3a3806d81731ccd1ee07b906bff4b3d87064bd94502b248a58a13980ee05e89030a9b8c57ba2083594e3efcba548fe0c26141fd00ecc02e680dc52f3f1de3409a2fd6d7fa6b8ac0b9f9e188d86b8046e6be677cac497be89a3a9e388c3d2316d3dc5545e816204e78a090aa894676b0969be7d4aafd3e81f4f469504bd84dd85bfc068e9c2c9d620c8bd2eca8388c51ba7eec14aad8da50b42f126a2b1226dfcdaaa5e47f212d703145e2b381da2bb5483cb437ac68cbdf3324b2181c6ef291093e62464bcec06a2f3529b2bbae3378812e2b86524945735f8f8282bd1f54766ac22deceab91f7ffbe98f49f0f26b04a31b8112f33309a61c6e35c50f8b06fe5d5d5aae10f8dc0e8ef1e03234a27c5f31ecc5bced23e80368c36e9c97186e29aeea48f6e9e21edc5eaa827c0a2c2bd8e8179bf00e6f2e13d3344c486db1e8075d14a729dcc9e167130f66567e1c655272c78177b0edecceda39a7891d55eade3ebdc42eeb6e6a3747864d4750d15310c4429d145b301029634158ce3d461be2c8736ddbc4b49fda98c81c755425f7a8c5213e3154a08419ff49cf2c0f6dfacd52f742278165b0d317f3582d1cc92406d7bd5b858515ae4581c4cb78ea928820d3be638ebd9dd4a7c524a3c290359252b072e4cbb6bcc55a9798310829a6323cfc509939652d1f31f28348df9e28fa110415479604bd5d7a43dfe925c428678c3d4c0ac5b7421f97480562d25c24ace515ec8f572bb68d1aeab265e5690731831200a2f47ff41073dc0889d4b728c306f69cf82fa0731c37f822f76f15863743426ad6b9bd76fa079dce8453d0e69001fa8df64293658d7ac85fcdc34f456f8caab6481cc860d9bc4280d8657381162d8cefb556cc5d81539555cf46efcdfbc172069549a145e899e9bef498af7c01301c2cc213a2ea064d19dff2c3e4d50458d1364ec8aa269b7d8beea9c776121679ebaf5e28f415db21e8508af5e005d234fd286782f13c7b7f422c6b8dbaa169ec34489de90060c4094ad3bfcee94b3d58d6fba046a70f4488665f1a9d453d87ae5d37578ad706493f9f1bd10d32eaf56b1523580fc42e4c87ae9d7e8c38b9b0bad59aeb16125af1c952e513642258b6bc49143844558f05e6dd7a352083792e8d48f0d66cfc606e15caa0a6b3821948733f4718d7ffac3a96f5dc135836134d771e8204866109c469c0d5ef6520b8fcddcf985a4d0b1b6c0d2221373f9dc08de6bea6aaabb184326096e49896d621d677e45b6a262de8f0f3124207b35bb17345dce7a84b8f879243102b8ab24bf6140a6cee8f3cc33b73d1b73bc35fa1d490fca23604627609c96ee531818dc195a37e0b555d90a1aa240282f87d40b753f03e0cbc58e4be249e76ef04566eb16c7ae10e5b5a367012ff2fef27af72ad8c3713a89eb3d21a0726cc06fe91af4f77f297fa8c232b0425ec023bf67cdc27a2188a89d567216d534ce34e919b4e1e2263974bb299836f18107dfd4dac4809d14df902960101b90291393e1acc8a4efe1b50146c435fbfe02b43032cea6084a71cf489b8f92c9b490dd3f6b0c3b32f2b984911bdbe1952bc99c0f7ccd2ff8789ff48de156f289c780293df8c75ec9ee3048fdcf39466b9c0c3b05129f682df0659fe2350c4485cf8224d2ed823960946a93b2a902775831ceea258862eb0da4f4fcd1d537859be9e667acdb34e3ac43fdee4ee4339261ebbad18911ae6ff3d2f95a77c35ff4e50ca18a54aebbc4d0d82c9c7bdb0f1351ef74a86fe65d7fb29de545f341e5284cb665f2f9f4d9a6d623926c99d2755b5d2cac66dc9eeb72ce679cb2daff6ef266ae653a69a155d52ef305139eca2d3308633c8769b6971ba63f2d6b21dabd71c3ca6b59c3aa613f34699e655788f178efae6d076ad076c998de4952a4831a7c0caeaae58a9fe55885aa659fcc8ad1d9e60dec34d4b6eef606ba7ed961f392247e3ebd0db0e826d4a4edc846b50c277d9873a1fb6a1929216f3a48570d7e4dd04d150e526b4cff4b267a4cca559720c32d5a9f44a4ec1f7456f3196e2c24785157225294f6b2049f6c4afa8ade4a589a8599ec163e8a6aa73c1c1467b6de5de654e2a7ae50baf2ba5b8cff9f29afe735b9dae093a70651623650e513ffa8ff7b74d87802a4eefe506315a14e265e77063302684c0ea9df285b472d1d7462ffab01cb9fcafc787fce38a50c2bac5365e9bf839bcaa9194fa7d24d9bf4d22ecdf15489884a152aacbe910290c8b6653d674ffa8a8e56cda4d9b0263263885218740749d5faff2d19340d74cf1609b90e103e830cd140e76b2ed90be71a24f795131e4670d8aa3ceb9b3f0220adff4689e5725c73d4bcce5d99257ead81cdf46e193764df41fb0cbe21497f2d1b4b40e9619d970ddeb7d4e046254e58149ea62d8c412a1ab5511cf77590b5a281d770d9c9df41a4aecf91eb50201b91eb03bd7dae45db54febb9f71fe557c940c0c1bb98c24d8b5d8f51afe41e004541d3fef67b98a260287227308e2db3ea8f7601b6e3a0c4e79850ba28227a960c8f29c3f835646f0b497f8f95cfacec661c5bf39aca292a96ae9f4645c8c1235210b4719683cfc7339b5b512eaa526ee5e4b054f09599be147a645f2ac9d0acf9c45a28423a9966506db4fa918f24719e0c645a2c47f7f0642eac5ecf6952c8757664e0d009bf25decf35b3158ea5fdbea4af7f466f55e59a927d264f3b2c5d7f0d8e631e5fc09872e848815d9d9208583e0a7ece58d36603600c289a8737849cba44325135b3c5fc6cb208cc9c746676405fdbff714d73276ee3f238f5d13b37d1dcf631014810c506086328c7a13d76c632c0c162a8e558ad2a9642610fcb54f5afc60b6318d9e33fd49da0d79a7b01be064e3513ba3b5e7eb730d1f9324d254008c7de9123706be3dc2170aa336633ddcd0d2de55ece79124bd1fe5d38fddc6d7208f830c85d801045c78f9bfb4b7cc187610b90b12a7a4457fd73385e71ddce3f49bc06c5f10d98d7a0241cd269fdfa6dd08929e75f041ef78380bc7ffc319dc1c80f39106aaad01cadf9bdfdb3e36b8ba1d1fa2198195183c142aa9b396eab9f98ff731af5c9d8d7351f3dc056eac220b477f7e877b4957c9d58ef0bacb245c288f93c50f6d7d19d97bcbb75c83e78184d833fa6794437be8046df0d1bd87355be72782186edaa554fcfc26844a1ab87084292981382740efa13e22e8850793559ca74ee52ab66fc61395887e6df2bfc4af89d7d53dab8887941c0628567b7a6cf93087d1478831368eba1ffbadd1e41728a68be97d97bc6e82fb5ed55882975f80fd2512af94e9c0c9f997c04fa548a0a6461b9e536ed5b4e6e25598a7065cc49bedc399c17a9e35b1d6c33af5d640485dace8b7dd8030dd626847dfdbb1d1803d902080e753b3895d491067f6f8f83a4f47754e5c41c7cd313bc516779b723bca4ef592b2eee20fdec0028b506883ed35af2ba266c8bab2ab54ea51b639e4c2dee6511987ef5fbd18365a61793cf9d36f47c72b675adb9cfd52680cf9949efb33ef6e844bba3340e5698b5df6036af0e6c0da12b83aa7787f6f834efd2af760524df1e6c08cb1f3c238dfdb866274e0d4378285c5f6a8f706a9207e8247a94dc64d32e0d7419ad81a4c7b90282112ad4b35107c3cb887715d1585abb841836353ed8a4691528371749d101adeaaa98bd1d6b2097a6fe4c93200e6ba898eb78d0aad48bb2ab49a7a8af5190fbcad97ac7f772ea422da7e43a2e193ff845448f0d3b76132d36dbe7b7c838f8193d5a2c844aaaf7aae4ef781338d41fbf96ea396f8d8d8956ff78bd0ef380d4f541f9729c884c24d06fe1bb5e911ce87f1aff2436066ae5667150059d3d2036c00178b7f50af75531542ee77f89d9ddcec7f89ad9d66ff86b6c1ce8e2a2e199da8c65a5dce5099af956dec6f95a5fab1582503645f208dacbfce8b0f8eb1f505a72b1d5511ed777631745d39fcd28a0c3b9cc3b072be73af8ccd40c26165755f2268e1b69eb777a71d0586aa256865106959796e6ed744f460b80a9dd7ac31a398db179e4852d824a265d84c8c9eadeed624faa35c48e5d66aac24aaef16a294e1a10bd1a3843c88d7361d1611433f21b218925bae429eafc3adda04fee442b9dfe91ad119c97b87388a9b93dd4dba1322aa855fa94f89fe4e14170b38fb3031d9903c94a93a0310b17c58d1fb9bae5278011f1a64a8af295d63c79263b822d2915fe924a9742557ebe3beef117557bbb5eee09294de6db1550b41c193d931e0172a5117bfd0765df5c02ec87e0348fcaf7c457e0a9c739eec9c852fed274960db3c4d3ca27525d39375820f409087aa1a8d8eb18f87bfec30be5be074cc30b4e5dea95721945e42e6cc102eaf84ba9c0a1d9807e4619dd15186cd22d8a236470d35bef10c3bb5a6cb6390326dd51b486bdf14b87c245a3a3a2f47283106b1b0429e9fdafc98fd4b97f65a56ce02e94b6999539109244b262aaf78b37f8a3482e72437b34d577a5506f962b241db800c6682d59055d7070e1eec52eda3e6900ff30c1c3e03b15e28d21b28e1a1740cb450fdd449ee5bb6ed107c449a3c79226299eac7775fd8c59f3391c703d31d9c7ad76bcb0a5efcceca217734f37205fdc06d7fa97de6d31ada74a9db6951648707aeabffd46423031d5c9c6e98f2bb77a9cc1680a89212c8ae4b84465729275e19e4e5432633e4f9f94227b64719d99de13fa477a9e21b78fd41db2c43a9eaf183767a23d8808b8b206dd49c85fb1d586dba9efdb0d61b650b7569c6426c6e035030204c571ff5f58c4f470390959dd6125a6940ac172ea7df7d21c8a0383eb4ec05c0e2931f48f0b2cb42379096e28fb8f8f2099b45081789c090d920c79d24bc9c886ca23289fd8f5659b0d1a3f278411a69bedca99b8880d34af812c8089f461788081c8724c2fdcc8d45c1598c539236b4a98b689527123823d1692c24970a4b1df89fb98cdb485d8dcf6d1b76c4c5fd1d069a85fff2e0364c6caeaf04106f3ff62e1a520404ebdb8cfbdf891f9b505b646ac1fda2ede7536c61de0cada9ed11be51f4fd52edd4e06e636274b5f0e321a63b90f0a22a12452cd593a563f96523c44adbf141b128707e2b17bdf6d578bccaaf6f0de465f30e1474fdaa0057d93fcf56e83060d68774e035a9fe61deb9c9a7b801b9b06c70803f2c529ad8cb56ad4d3d82a4bdcbe4166ed22cfb11a39bb64587bd049d1132d8aa64dc52dcda998e059c4c9f3bab55b3dbfdfd96914f2ec9042e4241ac4886020b0dcf62918df0ffa55bb1a34ea4257289c7057525fa13c8fc900002af841e783fa4e4d17989f778aab822b4962357df591d16641e8b4eabcf1452277b0889aa72d830ea182ab065cf7b6aff9616c66fa2117e194fa4b0e1591308b24fdc06b19bcdc0f8221135c32ec6562d52ae6ba75905f71bd04c1888992950806f999e8beab67fd24285a7f5e64ed583eb214243e05444dbf096fca19c0d7b5ecffd0003ae392d411fd9ca6d93337f404084a11f5d923f090bfa6fbc9c665c1b1dfe920fcab2fc216028cd91353a9364c65992323474d70fa6813e6064d53a8e1a7a44a65e55e0a330a017d7fde85a07dab0332d6cf5706aaa67a8f47e5e5ac1e293097db4d33298de5b43433e79891e395a0bc5fff6ccd37f298645a07ae7482d480d43961e495e18a938d01d64d5145bc8bc1085971c063670643e180db7252a6a3e074d3caea9c6c0d41bc29dbe405d4deb8adfdf81edbe3b50298ad0885ac487299ef465c8d8abaee3c9765eea97e702e26d960b07f2d0ded1fe84f054c7988eb947523ac3194672acf162511ad402da7e4f42cb5da7860456baa13e9324d612b414935ec4db4f285beb315612788aeb3231390d465d01612be8d25e2c21d8ce52c3d50c3a38597ed79800f00517467cf753d20aaa26dd7c55be6c62623a49686972a09ea2ddbcbf57647a8c006e2676273aeac6e08729475685303b22645652cf361913cce419099c3d40a27239526a5347c59294415efe3309f5d21073e63419d74cea011b4f2b0d7c0034c0345f5cf2813c45b05df52ae3ddd2f401c85a731ea2a8ee3a353e928737772aef741d86b72f9af9714ed272f73fed25199c89c2cc334e833cb94ce2ec505b53df057ac59336fc602bba33b301c36359ecdb5dac97d4fc82e7632adb32950722dfe24de2ada1a9b51223b321033b665a2ce2f67cf2fe9efb38d768bbdd01e256aacfea182ef040e203ac726658a8b951f73e5ef923e6b8dcb0f12aaf3c23d9305d9938bce04391bf0805fbca6956dfb1eb626a2a02b227727b52fea1c6eee55a1d331e391bd6aa243fd6b105cc18874f8bae2335a75093d94ec24bedea6c499f62b64f36df12e0115bc329a0b5a530bf916fa3b770ebaa2c870cb502e1ad383329f7c446384c5ffe7dbb74b7c698c503e17e0180bd25f4f8f6348e696889ed7bddf4f16b2e96eb47b097eadebd222838a5c551859c8fa483eebbc2001a9d3bb985968b734c50005cfca8c5d6cc52c0196e20823c0aae512d500b0247022cf225b6541e9a3a2bab9edf3af5b343f37e6d11571d9b4f1ea00b80dacfac63d18baa2539f6e482eb69f225f5419a487d6a4318169d20f8016d2e60d8fb651c17b6ed4c9d5778add7e03bc963978639a099973b8389482833fb11a1329e9edefda2104d549b550a405ba467bc177398dea24fd47ea6136e9d2faf0001ea5aa912c3e785b66987a9b475134377776c326d4435b38e9d4ec0458244885e12460d90c9d51425ab3d09cd9d4f60d1d43a5cfae72a1222bb2001eb5bbbce647a6a677baa061d1bdb319d206bf02843cbb44fba07274fb77c174ec4e9bb10fa5c21b20f59cdb098e30867d5c1a695a9d60996589347b11817722aca99a5cebefabbe87be10d5fd6a82d9a57d6782389872a3bfe3ccc93a121bd11f81bdf58ce3b9fb4c1364b5d1c622fbc6059053e687a3f68f640e32d4a53d80a20aa64c22d11d4458e0f0b39bd95b1e7f665da48627d67cab661abf4de06a837746b6e939b45ca218d5c5dccb8d3a464b3aa1e21cae8d57986b1cb3f1054de91d9123553e5bdf606ad8fefa384444cecdf93123e4f0ea098e882a19b60fa5aaa29fd6047c4c419d59c6c5dfecd3a2238dc921b0225effeebadc695c96072afa4f55f3911eaf58f99636e1a55bfd0e5ae829d5178d530c2bb355b9cef4c51cd4606630e258923d33aaa8e5d7603b83253eb4f9b3167ecefc79a55bbad9ed09baecaaf3f777692fcc841fb0c41da8cb21c34c193cade277d80da2f930fa26f497edbd9dde555166497111ccb2b48795e09f80b721920ddafaa772889c4a4ad0f79e88e19ad052ef855fd6f9a2efbf080f5f257f5450ea1565365f47a0b6a30d96df1917859635ed953273429d54a4bd77d6bb1b8de92eb03b57d9171e80a4b1ea3585a70a474909fb0173006d68c87781ddd71265509efb86d10f79f96b64b59f4187a7ba934d24d16258f54ebdfedc22bedee95a2d20a25a22d18147aace7527b8ca592f85985b0d3835e41a6bdb171d3784e47efabfcf80ad7f385bdfd408fb2255d49c0308c3ec9ec3e7d60f29e2c71046e6e514dc23398b12c3f71f8013a5410497d7a2b235894b2fec5015381d244e1d16ba34c4a4a2971d419cff386b4dc92d520ed670ed6aa5344e5f7b2a1a2343e969fe25f2063984f6b246a4e7e7e7f7218ab1a0543be41ffb33d800be5cf5d119a6348d152b486d5cbd3d710310ce13c3884db79ec305598704a514a4165c3d00f068750b57ec4cabe10c333882e74b0332843194cd2bdd4fbcc7dadcdf8c6589bec331febc019cf3b824e77097dc42949969bbac1224bc176922b1f1b9c570d6d455954808e15177609f33978dc0d27f36bc6bdfcc41b460bb2522700b53c8faf8aa12c814c9c6cdc997ba7009a767af457feaa302565f76ba3685bf1925d5d9b09742708d502add5bc1b43a518f377ec196a53c2f81650828339d88f4cb1b3deaba024d180be3f176c38502343f8a99b15d3df794988222cb1f1d57cfe6755f592e85fc9351171ef664577047c1989cf5c204da8a4464e89a2a56efd7b0bc209c553b0e0533bcee1786a8d01a57cefb367e8d4dc9cd8f31be777c76ceb90e289069a1f7d6881ecfbc21c950e8563ab24afd1b9153a00996b4408a38621e90ee92b10c4dd320f932a94c69ffa2cb7485c8a543c3daff2df3ef48259014db69540f9d7aedb5a012814ad19fe5100b70a63544bc1af491639a5990d788ec7d22d9af32e3d16a0aab6c608868d7a838428ad34f48d3e48a60c4d81b933cfbfe1fd475e76fcd65d03d53ffcfcddb873811641cfa9812ffe92640978a4a80e1a9abb4604821feaceb5ee6f09d9ae563bfb7e4d670e7019496e346b256d19e5f1dfcf736c5f083880d14e9b5c747be2a8f21762ed0926ea49d6ee969ad16563071f5eeb05dd2f836a21638176db461a456ae27387b8fcf5ba9fef30360150c7fedb43e98dd907744ff69dd1e5463cfef1d4902ca501b0b0238a19581872c940074c080549df515fb67a784b969451efab3568dfa5a1637cf35bbda916b6b02f20191d5fda224694629616ab4199f228dffd8a3eefa1fe9ce6776077c65ce8c6e7f425b935a7c41f19cdee45dc99219b01471c1db433a8fe40c76b2005ba35f1f5622dff36a6c34b0b5da0f2f704923a9dc12b74714574ef796c8cb02ac77183062844e13a7f46c075e7cfa0469a02c80618ccbdaa69787cc641dff0cc397f728c0fbdb014719d907da52e016fe93573a2d8079747ec2f64c53a1c7ccb23018aaef2babf79d42eb52957857a0dd1e1919e78079a5dda5ff2f2a59a924a926185e2e874d01f7a32ab04446cb2198014e2b0bcadf8bb86474b023a636f7b5250f1bf97b7fcab24daed5b08930462ba86643e9f0a97b338e587672675e7b298ff86a0ffcbd9c934f8010449dfb2f1fbcc8c0f96de59a82b6d696a7e75dbcb912daeb15a8c8b550df7adf6d4f0c0ab9ccff2ad8e549e7c8f203a1c16dd32b007619282d048b6c463e2dde3d3ce06b05ae3df7b726ce9750300723823f3ef92e16e10512012656cc4f1ff763e1a0cc87a5ee51e72eeb1a2ed3c1e9563f1e152cce464337178c8dbdc9498e831d816a00c60e820f4957391f1429d59c9910507581970a8e4bc2cf5b8db177e517ed68f81472e1aaf3a03ff71bfa6ead6282d8662aa67eb88cc93119fef460709c9bc692f7ccdc348861d9941b9b093c35b2e53fcf7c3ef8f8ec4d955e84cbe180108315ce1cd2b755c45a6b18f2f1cbba0451d785fd924ba0a2145e96c9095a9b80da08aac5448900215711999d5adaba49e85cad8989631e0ebaf2ae124b9d3bcbe3324721bba7f2524228b842d6100a85bf1e61bc359fbebdf9cb5566d047334df9650e502d7e5a95400e654817c689d06cf19f6655ef2fac51c204b59f41f20d98d73aa7fd64010ace5a99ce9390b9e1673eeb47167f631529bdf97f24d089955bac555900d1412b439a77376f95ba4d043353766de9257681e633ceccc39d385972e135495dfdd735d0d1a1239196c34c05b4b8c5367308ea415055f22bc569e5449ea0f0658fa68aa542b8c4273839b6c6ad885436bb9d6f7effd2e54addb2c053edfe72828f3f3bc2f958363022ca4963d7c18aad9b223946201709f93f1d2b31736ada0b28db677f6128acfddfe04fd653c31c96f4b54e6a4a12897c589ddfa82213b3d23d42ad346d5a52f83006fbfe37893de1407fa01d5c1b8bffd98dcbe4746cf92458caa63e9d08819103f6d6aba2965f6707ab48e55fef1e301a6abd89ca92277a4c575773528bf6eefafdbd7361087ebc0b2c47117ac13952fd25f786af48cc6493920fcce796b62d14920894c55bbb5d997d000d48aa3e304aae9a6aa6386bec68a732acad6a896da5512e1699b32c7f9b7f45125dcc5bf87a1b9b41004055a0a20ab3acc304f15420b8e1f10918b17f505d5cb56dd45bd7ad8f80574bbd74fc93a1acdbe711ff21ed94277823d9e11f4724a9948ba5ce1b81e95d589de4f2dc278827ff4d7e5100c60fd4a94db9adcc9d9ab9e721056c204a0a8db15efc0f21dc73fed954ad6fd1088c058382a4816b4974ceabd69bf4fc295bd504c2c68a0769b79e65396f671d379d5ad23c11c8db00b7ace509c55f2c2f86199bb994dcb25a91f2f5ef3ce01fc8bcbcfd5952398364e4dbf6212cc25cc4671e09df0d30988ef2e6c8d7667b5253850e39e66f39ad47035685a2927d4921f0b326f8c9ce68c489d7de2584db0905d88a0c047d10a91caeccd649b2acc24641dc662a8c4b8b1f517d949a32b407d6b6382d78fd83be82cffcd127694f00a231c1ce6eac08f52d5864153e11f566818562cb69c1103011c94a9ef5ddd54b3eed41a8f654e4e8992a5ca435eb5a47e0bc2fc361716517c953d3f7f4a15e27375fd99d3c54b5ae4b46b90f2a43e3992e530dec71cc86fee1c7bc4830afe4130137009effde3ff0c531f715208dc508c5579130764470abec0b0074ac39490ecd17758b1cff3325ea6451a2c17a51340249923911509c7578bc449533ddd9a5d8da845706f45d96fc17c0cd8b5a0828b07b2684507c00e1893250478d13ff26dbfd9a67fefc849443134c7ed7853b47958daf686c6a4de740193576658125bb0648d6646a31183929f7acc00b20c7e65eff192ad282ed3b27903bd2f6a0b9dd80446e2b1965e9a6a5bb927481c1fa30c22bc70efaee7efd581335d0d7a17a8e9d93cc914ee7d8669489aa906f44cba7c24d9c5c3aaec2b008d658f29931bc7fac268db41fd15503cf1c6cb8e4f4d37312752931d3c07e4e9388097d1982274dfd49237cb3ac96912f9b549ba46bcc85c365c5110545fa278dd599b7694340aa81a621ec019ca4f3d30453512c2bda7f06a18c95b7f6ec6a29b77af3ca553a8e0d4ee440857f9fd76a76140b89ee79c2874be97af5e2c31885385c4258790a15e5cc98824d33e362dff8bb90652e0c2313254a241ed282f8b6199833ef4f292cd8168a14233346909817f44ff5b00892e4d514028a27d32c273f632f5628e738b1ab940c569b56660ccfb882d0e5d4993552f9b5f2e50f33c33a07ed39c4b900ea8db5ae3d5313842c9c92ec6b6306bf5d55233bcc250e0946acdc47dc46413baab2e008574babbca28f99d758946df1f1506b4670b1ddd1b8270e4af037e0db09b457a39b1c5b2a3e727509c9522eafb98e37ad8f92e982c58e8d3be99665fc168710f1860ed11e56a2267a74368a14812ec7e60c18f683c348cdc4485c91b681e481da45586654e480726958c33e686940e07f39f1e50a0ee7ceecffe21b54ea6fd1c961e61ba9484fa356cbb43cbd27f547f9d92d08143ecaec0c1dd9dcccced881b850dde390bff57476627ff3fff348fc7094463d663346ad6b4314ea880f69e8229b63cc24ea9d79ac19c49388ad4e56385eb676b38732f156a1d17ab795f2ddfedbb1e72a5f34fe7a1fe1867fe05317cc5dd6f9027f5ea52e5a14c032c1a68611bedde69283db8b515c746056da0095d8ad3a51e1e9387f6b48b86f2dddbee51a404aeb2a54a1df9e88bf1d55b4a0d4e6d5cb0845111cc973bc00fed1cd4d0d4d302e284755429033d1f85791dbd3a4192a33c272995ff0ab464d0fbd96e7861ae1a8454babd9a0370f4dde891366ac07509074f0b39fa86de6063bf2fe76780c4304665ba9197076e14e8742322a4ece9dfe2e1f38d5280f77e512b3cd91463d4ba2fcc7bb0534c348267b7277219788700482f6d269068800b421db445e6fa4d3a86735b7f67f2f8c6d7e0d0eadd9ab3e02a8d7c4999f91d283c8bbaba9dd323d24fad00fc331ed590d4090e933f0ebe34cf4d2adb0ebafa0a528c66c365c33b1b177169e9fb7db1b083ae00c955a5e57084a3ca70041d54a815aef857048cce4a1379060e7e96cfd9d7a532faa5148de322af5c75a0e7ca0f629ad8d419086315f060740a993ae3440c39686e4d4fa0c52d20a98ccd782439a0c7cc061e93e8fc6b0456af8dafbe11dfaaa3e4c7bd6e4e5852e2cd0e3fec7a999c5c1cb9e0367a25c471d7f3f7ba2362372401ba974f8e9c6cfdff26b8b4db0e0a555b7411a961fef2ebfa6e2f46f2af87993802bc9a9e7eb12a3086f2e8bd7c71ba96d7e16b5e8bdfb8f23b8c69a31632c13cb9134a5221e7b2c9082f4955cea4e8e69a055a280df554cbd1326492ba0a0d4f7d6f417074cd7361e848506f87311a9527672c8a60434043f6c65602d6033082fb53ed3b001866205805c733aeed419aee2aa598e9b6d48efbe6b67ec66d376fe3f92e6f18718e6ad4e1294998627aff30eea40574cc8a4c65c8b5ce3996a7cdd8a9d87c6a00f92a29d4b63cdde1f078de90378453cdc0c4c68d7a6bffb3c354618dd9887f2bd93007391ccf95d24d35223612dae5f94009a6a9f4f950522ef07ba809cc3d329e6c63baa0e3c260bd728f2c8eb2a9f5c949e070c9283ac1064480975dacb792a1effde85880f080406298fcf56e99e69951808970625697724e0077bf83c99b93b164369c65f1d1f1a3d80639372cc2bb9814386f743fb120cefbe141a2b75b7c35a170ae03f10770655be0f1e235e55136fce9a3ff30df1187ccb44371a855edebecbef582fef94aaab77b5b55314d98c850a93b27ce6dae37ef90b33bde1da170ff5e5a105b4d542688e3cb2bac19ad9d6942bc74a108916c16ba96f903d1ca0555592646e1468088b8f258eb717b6988a1f1a0b3180c14f513644185522d47544f3271ab96cd03d6677ce3235cde2808b13251b5ed9b277eb202ccbbe21beb88269c01db2e9aedb9e4efbe50d743a5e3d74786d76f90d1ab5bcf16a5385a9c33422dc493d7bf54215453b4f58ed7e680ec6133d37aff4f30196f3c5352cd213e3b3f7be08fead73313247ab184471c675fa81f98970f5877fcc5704ba9eecddf3dcda113710f1c9077fe277458b78f61a3e32c5590049ab2d8563ed41204aec80626765f10a0466988025d4c087f81a2488a4380071343bb21aed371e6db9aefbb1a18866810e0f851c577ee7cd87df574e1871bd720e592b556f852572eb915b84763743a9542ff919ab091cfd4b966f20d22aba7b8673ee892deb60bad4c71f52efe6712e49b0f948d11af3f2c9bf27d584a507896a506eb02e6fa56e94e55cc2b1b8be6d3e8c566c7d351cefec9612089a8c379897cef1265f9d2013eb4f58daf74bbf22ccffb01a47f06bf304e92246606ba04d86b69e4a7c3e5ce7c152aa06ff947512ca180648606fc36d9b77c787dd67bd1f509f30f4eff6e1d86486ce8e6d31f56938c608685a3599b76198cb59d91007ca71470c6585ce5e3b16b9b1f15edca458f3f7396cb17eb837b2552219cdb59ec5ffb9b68f06f77a068a77cc3e78d46dd87c5882e81bc7a89a83544596bb9a7e77e5ac668c7278ebed1f259fcadf4421d10275cd1c76b6732a1cf81457b0d6bb1d1ae57a3c35fcc5214e17673b70a05fbcaa5b0cee71f902900102b9028b398197fee9a74ab1d9f430ba4ce1cd038502229c4b8d48ba21c14e696b1f11d7be3085a3fb9907fb6c4c44ad1812904d8dac9369c7e0bb67c3ce457adaa5c378e9efab7af58311bee9e291e9b9bef6fb5f4c797e3f6ebd026acee1c9d60d9865cb734e8498951f34f1b127d4e3c09cbc7205a24e2a2b0596191291c6579937a48a987a622f3990c3d0d54b46f8493daa1659bcf2f2326e1a719ef665e8315c22eec0c9316f13e0f04cea15780e2a766f36d1bf047fe959fe477366a140d3b24972c72379bcf884e926e8caf3efcf8a270088122b7f32a7e2601337d636d9ae338813ba8a236aa19b2243e996635d4e9689818b4dbc525e0c646dbbfecab3e1d5b7680451d961254679069547b1aec5f628916a9902b4b3153cfd0a0aa27f25aaac7b004faaef1cce2b4c65a848f3fd9133257b40c25c7274cc21da470a725d40f4cd1b8dbdb7484aa3293327cda641d5cca273bd51372f75e53fc7441eaa82830d2df5023397fccab497cc8266924b4fd383b670d1c8a240aa18242630da8dce3146c7d1a8ca8215b28bdaa6d1782b294a79df0d465d8cb7f82dfe4b8e8665462465fb2fbcd05c365b2c1498e6a21eb5860adbca6d9e4c8511d2f254374e2e82cd8a6749b777ffdcc4fee531c4671517f5c5a3d2ca07c9f7c532981d5bc7f444543ae72de460b73b026dc66dfe8cea3b7ebd475334aae4dc52c834565289b0deecec89d95df937c69678d1efa2f3a5bf78b5abbf89d3b8d9364dfa6cf6cd685826ee1cff37770fc976282c87afae517028eda6a2cbe6cefcc0801ab3776249589eeb3fc12991ff9f5fa163e0c6e7882ca984c7ec32b5e8674da5f5a3b6dc5f076be1666f8b7d1a7c44de79aae2695241b6bcfca4986b8ebae941ce08bfc632acd162156ae48184454d758af91eb50202b91eb010d339e1042838dabd752315314b98703ba5449a2ad42e2a3aac7485cc2fd0fe84b0520a24017838fdb076ab479d48374aeec6f96fa58c1f5b52516ef8240beb749be9842330860d237c0d244076750009faaa0c84438cbb390480c5575dc0460aab3c65f7fcd58b2dcc8c533f8af37338ed95cd1b0e4c505f60d8ff457e0368e4dcef66b121c3a05af6c19edfb7fb092d42a5818f15bfb7faf3763b2316692c8a9b69908f2c9af5a737c89baf55af3b2163a639c7d239f85d4c0da805ef7954470dc487dfb25c16eb7ba020df4e41a17900508cc02adca083c71a10c881dacd6f127be6980baa2dc9b0a767587e68ea608ef03486d846e9b307b5df5390b6eeae9d8741ba9027bf96a11819bd8dee3b701762cf1362fa2a6bde5bc77011c90b25f447c4bfafda8446a98637e7d7e39bbca0beb4791a0c5bb3274dbde542445d4d0a0758b15e93c71273920d93962b3bb0083e54cda10e1562d9db6637274317ba9101ec23966f73af8a933dcd27d1e6c39dba4c0c4adf81e4b57ef8f0722c5091cd660698c36c9441421080614fc32b157d5902ed32e480e4a45cd5aebe2b0fcf88cc806211bd641a5f96709ecb63da142cd8eeb8862df02600562d315fd79965031ab9d63f3267d57c93e5bc2293779a374ce18704ff48e916d723abf2d0fd8bfa56fd77c3d0fdc1cbce0fbab13d0db2a01b195ffab9aff70cc3b6381c2fa688ae6ace287827850038ceb956f35279d3787a1890bd09fb35962f0eeb4174f73e010f438371ae8839cce2dfd967012ac87399a25582363ed17ffa9b0226352dea701356fa6fd426d7e8af9a48288b20682e00cacafffe7fc23fb59a59eb1971c2cd689145dc0c46884bee49e224bf3c8984cf0666590beb4cff395974fc0cb7f1018696a8ebb4df17f443bbc96d0cbb92114a5d554609695203855c347f29f8fdf8ab30b828383a3c428db870ca60b49690ab1efc870dee98786000d86b6b8539a9656f5db661ddbb663f1ffe0c4080acef47d5b4ae6e069384e269ce449db1ec24e4c1891e2c5bbba9a304cf10444238e14f965d3e7ffb901f2a7cafe0bfb6103c7dd086e44b76c3b00a63d2eb0282fbd3db21508edd99b87aeb2f6e895b2f9870acf7921d8e8a62760f8b887f994f45c59e419b53aeddfac0a58c5f96f369bf8df7ef921eb2fb8f47b785d003baffae5aff8fd418a05b692dc88d0d527f4d71d70566555bb4aa9a2d226df1f5c9ac0cb6f39fd9b57a255a4c1c8a862d5cf888d368e75288feeddc253c8f241bd2e7e96584b03e6e2ce65bb1d4de8d00a845449b3f9808c639b2872d8dd4d4894ad24c31f40e17075963a0ed6dd024bfcb0f74b0be8a1ff751a9ce73e1a7ce224a7567c52e8f42b5c050c13bc40db931ed686bb698386f8a19db1005b711acee784e7d2fdb0274d85a6bc2b4d1470dfc9b7da9484320462c0b8796b92c2ff2f3443a8ea9df10d4e776712a878b30f91f6f7525a3bab3666089d85c04129e16d57b36afe4811376f33e13a79bdb69bf733b6dd686cb83550d5944dc0fa5930c9bc0e5b688e800bc664314fb16b8340c3d2ab03a4a900cd10e8633e91527fc7a033e13fa7e24ec52f88d79a2f17c3dc815a15133ea66b031e524f8e6fcb9099744ad3bc0559c1858d8ba4f22323d50cb296d0f7c5969ebab42f547e3e9ac498579beb1268e6d46121893ab06c8a5e1b37b72233f1a08ae697932f790e714641c2fa8ce51cb9ebf0321202ffd804b085d5aadc27e5bff51c06912b890048b717076de635e7f8a6e0d66d00fd9d0de4715ee9da6583115555791bceea13ba8c3b5b249fe3415365f635e01583e8e9d3fbe3d3cc79ffc0f7a27a197f4596350e7e4caaba48bae112578221391e11d908737cd796384b3f91867173471530408c2c081aefe641b08853926218e32fe352a969d440481b7247a55c776f02395a3e1a18b048ec222eab7da8eb2d0e71e6d889e78b59d0afb1f9bbc2d30397191405a30a7e2d4a358f62c2a4aa226812900c7182a1e87061120596ff77ab20bc5e265441eb174d48d59ee5c06e90ca286d4894a12c690d11c2d2e0c6770f95120b3e6a5d38ac0c61ca7d4f20106286ebc783db93427f169a5208eac32add52192ec417cb9c8c8e9bd63623f0506cf3856365393cc523038bc20b980bcffe324ebc5898836b7d112d30ab077214dd2e8f75dd2f622cf8a9c23e3633e07ebb448193a45dd5fd7ca5f651d1a14f0eede0d269e967c2a717d9d93f3b714dc9651f66076ebc766658a2a07f76c1a88fdbd6221123de1036e016e618205417a5a1c7ce74f38d83ac303a4a28a578e7bffd771e25286737e74c47f3bb9e65cf377140a98770808f71a65a689a80a0c57d94306805f1220c64ec2891ccaa9119d2313a8a11b71cc5f645e2492bbac41998b1ba622b04cf887776d1d485d1e4c67836e2a8f052867cb80c20170be0cff2e6adeaae84fb7a6508b3a0f789ae3ca95314a8308206e03c421c1cb90f3bb67997ed14e25804febcb1f94c67eb42b236dd7120c1c9ed339a5e87a620caa4f0eb71d30f1f1f4a528a24485010e46f6e0b269843d114e6e02b905bdb8127c451db304e40bfbc2337c47cedecebf287f5c323b8bb8e7f8a92cebf5d4d530233ebc728da79612f06bbce04541ab7e80c24e405713b188dd92331f316b92bf14466a9466876ee0016a01303f9580e93ab374d301ad97eeffac1d5a3068be7af14bec12a1de28dba2bbfc6886f8d7d851691ffcfc09dbcdbf965d53b63710d247ee8b13cce05e071bdaf7d8887c3ce30bac1abc5c01f00367f3168ef906bdc83d941e77350249a19e0af211d45fdc75a4b3a3dd795ac2e92ab25d7b0c1bfab246cf3197a98c28880fe637f3f0393c7d45aae3ac37f403cf86ffa36285324f6e4a7c6d53f3c1e2d04757e33ce10520450201076bf4dc9592b64cc0fc671daa3ad454e7f94f0ef156456c63128025395fb0c35151c019d2a102c60547376f958c28378c6400ef1e2a29fb3e0ed276fd520206184f18d6f7ac65bbd41aaec8024048cb43f816ef1925e4c35022044ce0918071bf92891643a134ef42a0a6a65440f48a68ec26e33a769dac0c46ebca613249b40a693a88b6e25590cec6ae98fc89626dc9bce1b6b5214d7a97c4311a693b2c66e9c8003d0553cf31d4e90ea745c7b19ede2bab3e39a298e47fee9667862424ac99350fac9a3ae9fa365315069b102bc509e83254eeca1ee7a92035ec281307727a07fec27cc74df6b4e1c78cc101e8dbef2475339ae910330e47ea7f24317525f49aa62720be614efdfef9f02bff5642cf2ac866db4c8adabc4953e26a4277d50acea886a8f85990d1f5e38c8dfe3f59a99e79974759709c4689a7756613a43a699fd7bc83b5ede0590a7ee41e06b00bda1f76fac0e06da4afad4538c4092b5fe2b139b2f234248bb88702ab518ca7ff0682067f8cd6a99c8e657e1b1a1d42b518d49df527fd9069736d2c211fe08daa48c4981f4a0000c23a6c0ae4bf674e12bdc9be78da0c4f6672174bf644e1b5a09aac71754f8b785cd73cb8dd31c22027894ced17e4518981a9b96aa416a2223204528ed72ab8c51897dc170a3c261f61ded5730974dcf46349b4e629767d74f4535c56730769633f503ee9998aac8d59ab1fcfeac22693d91ad6258b93bd42d55b512b9ba52f63f793dd6d346d2ca4bd39bd87bfffe856b3bb7ce2e6b757d2ffc205e6d2b00892346eb06aacaca6627c326c0decb6414f041f1c3e087ea5d60cc17d624a43eb5f2297e7b46c5010242b4d733715b5276442deffc6cba86ab280ffa8d3f88c784dae02612e33ef3ab636967ad881e61457fa82fa741f38cbc365212788efe3bc79ddf890cb52111006941cdf32e9cf5231353680d8cda872e4898b0ac03612f168d9c817e73799c40e209c7bd663e25cd8bf9653f8bafa1bcc8082f83a9ed22e3b0b115a282be733bf38fec58410ef2c1d61ce13924cdfd81a014edf0ce9520b036afba8c02fc0c28a90acabcd494ff9ee5714f1f2644ab2be31b4a2f88e516ce94ef2dc1a4a96b2fc88332b1a79b03c7055dbe02f471460bc7fb4bf5efd9f288af8138af84673e1db61ff9c622d5f8743401aa0b4674bc1be40a8be88e612457f4011e60a8d5d5c625e2d89d7f7ce9bb3003da3482e3f546d29f7e1f1a906b4bee1016447a8c041865d72ad1a0a37c31d7b7e786a5b1b3044df0da12be7f6bbe609ef447c8b606e7c6ce577f54898964091cccc44b77326cf7c1ef3fd34c1d76e477bb17f0a89ab88356322217b22cc3ab9f48343bba60746289dcea2522258d8054e4b26bb324bf47a2ff923a621bf6c17dbc574ce0e2b1aa4c3ba4a914f8821559f7f0da2e8d62716c058a4c42d1b80d47661c2fc10eda008e93382b4ed04afc7d362f631b6b0ce6fa012c660ef818bceb8ab9d82f378edf327d88e2af5d1b3d7eff347e530aeffcdc0d44fc7b83245ed7d175c8071a08c7f023f9f78bfce65bf0269d7d9cf1e1d1746154ae1da7d400dfd21fcb92f7d22cd3322f384c467ab406376c0bfaf17ffa1bdf9586b0227ee5d64b7684771ea4c3b0eee0a3fe480de5daf97397a3e035a94144689260e69717792a8f188b05b2fa7bf016fa996331c161d3d33fadf33bb0f48bedb4996930f7f13754ec5ab5c10f6ca23d1c07171159d6d5de2fc175873680f91acaf600a8761c19b6a53a4fed7b6cb7bb8ae452bccb2b30a6bbc900fbf8fe17f02db02301641f3f79b5ed80edc3ac20d3b87a3fb1ba52938adc72ff1bbba3d5e2a4074894c701ce53982800819f89508cd17b34780836d804207ef581d9ffa6a5f294cfce53c399aa049136265b7a7c688ae116f4bf2d11bac07df0f7ae42aedf4825f418dbd4dd246bda3f6a40183d06c1821b1e183ca1dd1c90866ffd90c38609247530a1b6515fde4d8b594f4e58b71b013a9d027d78172055b537060ca956fe8190bcffc0c2a3f745e18e90d381c0773161f106d21c81d6e914573a26215bd989c221ac37b74fcd124e42d17bc1bc1fdb46253536df91032a3f3a15812501193e7129da4e6be86f8ddda1e9b3185f0b3e0c1f20c90f2c9c3c8f2dab0200fe8a5ee2dba5e4b013cb4caa67bd7d271d6f6a782e38ce56cd059e4637cbda0d7b4f4262cd4daf968f497d545de901ebeebe7b089f1dcba32b4a4115e1a807f70c9a22d5ccc0511c1dda1929033ce247c2e329c283d7c72280ad3be6e109538a9c49f4b8337d14af2810b3bd5b9d0399bcbd2cb577637cef892d8790fca423be1b3596fe2d42f855a30b6878c38ac9912ee9098abde0bac21a105aeb3539bab374698a5ef8951b6dff59544eaaad5bb5ac3531d4ebfa8061b8c3edc8a4ecb3e616135e40d1d5e74e2479a62488e5b07327b5d35573a7ee1fdb8679c5b8841999859eae69e80476f658e9db5e2c50edbe70257a5e7211e9f5bc4088d2a8b20f82595cf6a08e6960243a2879d1b419f1dc04ddc68ae5968692643344271e85942f33a377a017f2314e4818c9fce5b5dfea58720e0d21420798acecf0786b1dd9e995a0dc58fd1ea17ff76dea034412386f715f15f726ecb842122610cdbfbdbb4f609e1d9a7aeb7fd6f5ebf4af7617473fdf8f1ca252150feaade37f3f11151693e8b8281901e4efbc4675f8ed00adc5dc6deeebda26c1723baf34e4cb0eb7e6c7e799f6189f9a4960bec1214f1365ba5b2056d002cd190cb2db370e466dd42e79ef86880e13830cba04c716a39791f91d6eb1eaa7fdfa5e666a58fc57ce459726a8fc1f6e271e0d456b0b48791ef1e5d236e7f5bf3ea4cc42c81d6b9f2af524a84c4e98f75d5b4557dc03280e796b9ba9115a2311edfca80a5bdd81d12dc54339db35c81b28e6f5afad5a9808ab92ea0937f7abcf3ffb898ad6b7344c2ea3451d258254b023b87366f9708103b6df4961b83187b48743cc8c37177e8e4a6152a0efb37b0f1adbbc09ee12c211dede6c8d45c706cc0bb49a2806612a3824e58eb02fbb49de5323dc8f3ddd7bf6fe3222124c95c349a0fa0945ee6ec3cf073692f0aaeb4c8ea1866d28e87ceb3d82ba0983b3f07713cf061528e6636cef4430fdb9d2869012191d376edd8db4aa283ab42fce30127f09b5761c48aa2f942e3ca4572d5b48922d4d605c41690718cbcbf065ab9fc8eaaba0a8bb12ab8d13324f9ca991ab77997b461f7b80c53d8629818a77ee6de48518263bfa16d20c8b7b5be5b8119ee7a9e33ff3c0c3f09d4bb27f4ae9f0804c01bbb75fabc8d8c5905fdee48e8deede1a52b2a053722685ca4264ec95250bbd26527b8b4830925d63447f29efa2264c9e08e285ad12bbf0e7096805d6b47bad2cff233f820930e007a8c0c3b0a8b644f368b661e352e0e918be28366a86fdb8513810b335ea4c22eb632d29ef11cfcaee8cc4a9da6b143fad3f781ea958c42323db80037412212c95053f95b4fb24a3490fab375c8837c4903def2a94164d306087e96f3e2ba6ed15294065a51882dd7fe2543026970c42f7d1a486eef879d22a1f4c9f33441868033e433751f10159d77ea341a5c2d1674b038eb7f1337f5d342020d2a7a26ef008da9897986ddf147bd3458b6ce21921664c9d853367769c0780138e58d03159564390d014e2fe19e2eec5368afe8dcac4f90491b91ba4e737de4417558a3e79e038728a3e19801369aa144719389aeac9334e23a64b739f06aa3b8cf8128def2396cf32213ca7706e8042824f4c1afce713052273882c747feefa07bfff8965e4d6a64a66db3e9a613974b4a0b835cb8d2f9391b57f7c01a4fdfa01bb4160f450e4410c2114b33def359a47b996ceb76c32f4b65feb22ec9ce13b53baeb48da8b31b9acd88af28cd7cdf7ea8c26b92604eb9e54f4975154c2318164f831bfa99ea82cb26761f3c1a8eecb9bf079d085fe1eae6e3eda13e4719a777cf62aad2a5bd049a3c5b9f190960a0f64e46f5913e01e895f1577f7a38d347caf296d74d6a5ca10b3d4c29d56e20d345c777f3bd0ea5bc3e9e19335ad9ffc8521ec3f7db76988fd02761914ebf44b9548263fbe8ee166f8bedccf1c86c106239218adaab84bcfb4beffd20a4188d39d416ab0a53fa8e66c7c507bb3c70404d1a27f936600d1f2f62d6c29bfcfe8c7642f88db45114fe69a6136513c6ecfe68ef225e47f1376ae575393e9996fab23a0bf1d76c44269789c7815f6520ba283f67c55ad533f09716cc9255b723e89690dad9c0748b1851abec9591eaf60729e6fb79b134e564c6d663f035c516c3a102ae29a6f376e0e43dc2d63de1d3adcf00697afaeeafe5edcade5c025c41df9d642a8b2cf4b388ea02d2f8b753abfd87f3951b05f59544ae788daab9030b24362edc44b1b2429191f2c8d2d3f20c5a03bf5b4b169ab331d33880c42bb5bd8f110b4ee43988c178d3e795a1893c6be6bf88a402c6f2ff4e02528c21826e4019e589e8354c3bce84fe8897db45d04eda94fec5c8a808e82a83c58d61dc1abf9afd30ed24cabeaa6987d94dc52f5be0c6d923e51c5206e00ec9889103dbf4014e561dcafc51612ce4dda2f93cc7afab01917cb55437e5ffd4ee1b0e56ef03616abab22c79ffaf029b27c28027fdca29051d3e1b48db7fca76f01c27d631b87218ab694add2c2990c4752ce21c925e27ea3bb9b9cf34b00cf9da402af42636791bfa39227416a6328cda9bc5921bbb520ea488eb267429323006795c8ea0dacb0cecea87b9a128e9bfd44c52aa65bd99ec06c8447aa1497aefad2804399358f1a76bffa99375ee463bb05d75c0575ffdfd9eea676c2dd879a69fc1d9fbd853831aaa64b90f693485c7c603303d46759aea9875b20acdc558d856f5ef51bcf2b90e7bd09eb4a33d2f248bc1d1748718c1c2c20b56a2f6732fd78ead08c1aef99137e8156f25bc7445df635f37928551cdfc89340cd7319c0a11be7964ca7010fa313176de38f3bcc71527ec144955b58bf38bfd4837796607287d32a7a2631f1b57ab2ce7fa62aad551718a975ddcff32216522b4813998f8d5da3324ca7a3b6b72b595582725fe8087e89d550b837dcc51a685866cfbc58a702414246696c276f68bc6ddff05204bd33f1342aac4e73ec3f141478e514d9857130994b74d5869f1f821e5dfe915c0fce8953b0413fc6dfabf145cf3a6583d13d5e326809b5afbfc7dccdb2030fe48fa534099d5dcebaa81ac070e08a77809ba46e48a9ac177b2450896bf039e96e303105ac2b6cbe4824087b32253e5f06051a2e2bfb9493af8316e1bb5b4bf08b3afec11a2d85d7a37e3583f731b353282e3e34abd61a3065fb80d08d1e76072f67be004ee160340aa4afd909943ce09c5c70197c40ee646a0ced26b25483707bf238df9a9af4f7a4b2a3c4d78055d5cdd48c8eb06efa41b1fc23c370dc63edc45d9681b90858d7ee67aa5ad8559afff3a8726ea8cac92273718ebba9bd7bb35d1928aebd904befadb5c876e59569644bbba512bb58ec6f3a7b39fe54534b184081279c79b6d7e70ae6725d10d4ec9fb83274b2dad61f32c45901333ed89157fd9c66211cf0f78c52f11118580368d5aa67c1722e7e27b2927c455e7a003470ea17f3899299a6d67654e9338c9d58be92c7ff4024f60f8d34ac9f60f09470b99417de5184003bd83ac4d193ffec3f7130e8eca1331853cb5da9649ec5fcd62261a90492a515c0dbbfac73c34bbdcca99e35fb1e3670c6758cd062b5bd28116c68d5672791e1c0116507a5fa16684139f7536d41a1e1405160acdbc2888b5597afd132fb25cdbf9b167092d3ac72cc7d685773749cde6b73e9254f0695ce4dddce3a8b0a5a75867568d513bfec0417c34288811d12f02d5ce7ad876bb645bb2163f1f0eccf997ff0eee6863ac42337bce01d233175d3032653a621dd0b81d30c42ed7d9bdec114e74ae25212cfa6a57bb3e8720b2d6297fdb9d7716cfe30cce77e055297de6a9eb29e782735be3515741608f9a3eb7653fb35363cd16d3c19a3e95ca76110027fac6c3ce76cac4f2911933d097a34b893df2bd802c9b4592e6885fac2cfb2cd8c494abb1de7a5687de08900f073f5e0a324ad64ed77b4adaf82335774efe4b583e224db4c51e112221da313ce173a02561e20faef930fb55f3989905db9f80055b636ce9e132b6fdc3fd9ece4d941db356b684010a76cb771f3a47f99c942ce6b778a14b1a04956b67b6482f974e5998790d1179873796da1197abb099cc3976a8293dab519e11551eb2e898d44f02189512ab4df7f03c3e1f0f3a1f1b411d1328682a55fd5327668e5c99bae7472a2f5fa84592e01ca0361afa668084324958531ac111c9ede4590d5f135109bf7b68f904d5440bae0b462f98962edbfc89daea0c9ead5356a6b62a16295abef397829db75ceb422d1c215647c56e8009bb569cdc98a25abcd42a26ad79d13420c309c9e83b0f55c300df798464e7adca32e6c2881aed8b720bd1229e61d3a32283367c644307090d1f86967451cce6b21b779e60f6842f1fde898632c974a773ac07460e5763773061bd0cfc74da8880aaae027303f1925ec42efbb209fcb0c1a308dd0417a33869f4f3477529e8dc00aba9064403b6faf36f0a0f64cac94052f69813cbf18c89fa23b2571c27f69d09345b2eca5c567cd6e58580e1ad2bfbdfa4f1062044fe966dd9800fb70419b5f1d3ff9c50610a1ee3ff2f3fb90be31684d334f30054d69eb1cc92fd400b49728d04feed3393adc322f88528c3496abaadec94919f8675b1d923e8ddf75a36854de21cb0469510557091ba0c072ed8ee9086f5f3e50a3a4ddbd9a77b6e574658fdbe1526e55307da177931885a19651c11a29f9934c8b9deb0df6c4c6b9183025c361b2fdc98814c3d7cdd0bd58ebd4bd47931d1519ca6c34a03212874c729eb845650cdacdedbcad7ee9ad3edf679d9e6422f208a099ef1c9b83d1394071433f844013f98205ee91468598d8051ecfeae5e298946a34831b5430fc092f9182c8a97f641351854ed7e545de0c983b06aa9aa7726a67c276bd319df13fafa977a541c3c466cc663763520ce49eab805c74a744b6af287b8d60c77ade807683312b4cbe9f172b70a1f1e673d1bf6648278b19b01b8c04143d2464c382631d8c5f596eae8a71650aefb2b527f799dcf250b031cf949927682ab19681b967ae1a17974e9181affc8cc7933a38d8593a6e0d09c13de57cd983d4f1185d94a7457c99c6712551c71a3590eda3e2d4416312d488f0e8b7a96b758d3232572fccf28895d11b3c3f4b9ebc36eb844ff9eea641ddb88b1765da0339e9647db7ecf5d05e1315e022ec94ba5b99ba01fb9a2eb5fd8b6ee411cc3f7b3c2034c7a7c625c4dead53350b6d8a9ee5e572ab953a671ad11aaa00d7cb143ed5a6782ed4afd829b39d181bb83b7e03bbf03db85da36c03c40c10ccb412a808115e9e787e26d8fdb1ff97120d9426efc1b63e4be21908bc58033cd8fc334e8add02dcf8ea2d57d578be88b7b75e9ec734d04464e9a675e20ec48b2b4793cbbef7ff3229db53bf7276689137ce2feb738a8317d6fb47ff94ae9bb27d4054fe84b97426865baca9fc93d6b4012faf9b9a96410b37d6d0a245363ed1e8d2e7287948e881ef7e162ce87df38f53e26bcfe8f3db35af209128b07b9f28bdb119dd4569d0f275e0148b509cd51e2c4d34c1017cc7828bab5a8c7bc1cb3b75b1ac258d07283818931ba55885e99432c35030c50880801b0b73a87fcbbc49e2ed223e19dcc49a6dc47210db09e43583db719e2a2ae9a118cd16fa869f312d14b6fd04042b4808a58abf311c26e643e20c257a9f08053ea4e9943a849d0d867ba5df03dde2914fd648b03b24500e172165def82d45ea2148f1bd46fa82d774746fa84e0448eaa1c2ba2773fd9c739bd34b0f43e0cbf04c9643377eefbf76a4f6df50a54685bb4d7b1e880122de951cdc1559fa0a06099d8cf7c7eac98cada83c282e1bce0a369911f2968ac1c3f18f0689b25218d36d60c514456e49b5d00d23608118fa296aa334bf205e458bc72334b648d57df7e0a71f9409190573ed2b018ca24c8b61c7eb8f1a58ab8f5f902940103b9028f39bd28dc7d4ab5994b4f3afe156fd75ac8422e2e8159e013d858f4ffaf9324bb14d3fc49094788d92b33bbd9a8582711bf6718f45faa60a0895417e70f4c78d3ceb2feaa7eb9e7f7e18a1b0a1e0d6b53233d342a83af9675cdedda7fbbc23159925256624b1a09e0183eca323db4368bd927bab6f354554ccf4e953fde8ed92dd4e1b1ad9c477d3253745647de25f38103b6cdf3e324ad63f3d6bf907cf6288d66fbca96daef0366da3b9628449017d963dc3490563282d2a0249cefb5561a17890d40cadef59b1904d89ac91e74df7d3d706bfdca0f8b9d714c90367d17ec7c6af365806d2d25a77fa7aaa108f659175cbb591b0b41cb9534cd03a1fb717396a52e1427d67e297ed52bedd175a50f8beef6b24b8fa20b3162248b5b622459a4fb650a8904d73a84314e2b44b9ca145d61456c2daa3cea74d76c13b4db03a95a9d52e6f3a965939c9bd55e69cf183f9cc41d2f177c5b3c99a7bcf92e5db0d5fa38328d67831ab36b4c89a0e260d378b44353387a2bd884b50ac8cbfed5a66df65997b902f73d89c62dd28c574e9ccc997e7e0b16c46cbb57c747496b7cb8f569f936c1c2ea24175900ab6bb2ac84c6affacd40f87789ff730874f2f47f8a23edb412e85b3bfde923c85a0cc1b5ba5210641e9df7d756308ee933eabb14f59a22fc7d2fd98285dc822613f6c989c3b33a8c7e1a38b32324ad2996f2e47f048f610474bebc3c7265b68f47d221ee450665af7555896bbad07c48477232ccea8d62871a715faa0c4b36464823834b9c4df0491dbd705a744650af6c137b3daba139e1958b26d2c1876cbff4897273346377bbbe030ce92b186509b7f7f8d2f72f3f298aefbd1519b4fd0b735b04a70d39ccdd24f9867a14d8fd52361b5bb4dbfe1c44969282b1917c13de81c013d45080f91eb50203b91eb065f9f63c4190ec3df0bbf9075194d8cf31b1fa9de1d40a804785eb5d9d3ad2b1dff5d4910de63f3b72731603be161546cd2058cc2532f1b28a2f25a652cb36e607da76e24ece714f7692dfec258eefef612041cc1a907537b5941a39dfcc4d5069c88ca797a0e01e055d4dc208dddd6cbfee43ecb1611694265586302181c17ac360205e863ec20d4510fb882f4b14fb3c767aad1c552f66d6812fec5072f26a0b27850b82cdbb9c0e7ca3b659e0801661d8c76784f6a2af1b460ae0ef29fea483c88af13dc313de5751cea1a4b6119f7198628334482b9a9230d3c6de6e87fafa3b4101fde18fab8c17d7569026db686e1f2f4cf7dd72743873a64b19c38c49fd698790aec09bf8a01afdb135de7df7c9f0af34888f244d0758856c6ea995193fdc75a1efe75139946cff4a85be25a917784421aea5804c7dacc120842f643e507cdeea2856c686fbf99f920c15ce896237ad193a2e449e6cd45d9fed69bb7519fdac70a36b9dc9f89e641e45327a3868e5b2cec9983748e58910fadc98d2b51a0e32745d72a577501b2db30125c6c886b64e0648f30dbb397f206d521eae7b73b063ca5f5fcdd0723d7bdbdd52cc8bbfb86d80ff20ae8a721087707ade2931691d96dfff425d86f07ff9c453a9953866881aaf12bcc3bf19c67d719e480bb36108608c00f189041b6c49a1a60c4256a2b607f4292859a1bff9914a60ce5501291cee2907f88680b9d52044257a1c044b43619d1fa81a59ca3e554f3c09143849596f1fbee067fd32132ccceb904e8bb531759c15c6361943d0825f6c857e3b01dbde080438d97a63f16d9858520d2a2876536d6f05748eb40f7f97262b221c4573c6be12ff3140240181473607000bab37cc246ab53123a2a57ba9f70e743b75abb843d05ad501ec34e2d81e4a6528842217c01204dd2f1141ab2186ecf1880d54fa1b423e2d0864b440d8d71ab2cfcdefe16eb51fbbcd1945e64ee57d0a73dd6084b12ca55d65e056a9dc18107d06794ecc7940445ff25bb8d9b6252b9c0d8ee1976421e1e10f7867d5251e01fa9e1cbec052dbc6990685e50bceb2ffefcc339dd6607e961850dde1f769e341b0fbdf13247c3fda50200cf77818f08b2ec32eab36c6a916324bafc0bbdad32f7b48ed0066a085669b1a15091100ad7dde821edc6c19465c46221b74b4c034ef5863f64b547f4f106b9d3fb5d92b9d13cdd242aa5948d534ea95ad517a8890e1e663a997ff1fe633bf758aee1c8edde8351c44ba45284ebac1e74bec867c2cd2d0f83126972d1cf8b7994387b8d145ba2c9475f4e4eca0174bb14a5a36ee7f1f6a1fd36294cb18286f7058a5c680502ed786dffd521966c5b682e5c8325495495da061549386af309be0d6824a9bd12d24cd29e7703aa2e5cc1e7efadd1b0210fd29415e16a3f5602fdcef9c923a676782b10926da8aa6b877256c0ba1d1aeaea7cc1a785c460ff0c05c00207ac43295c4371ca75b5b4ab74fcfa603708c7bd8c78c6e15591f869606166d9187b9234c9469f3c25733636ccd2605d6d39f9538005e57e1d6d8dbab5d3644032e430743e6e12802dfd0285851c6d4a8028f5a6c0ee6deb75fc4a8c5ecb44a74e11880baf6e3e739768b930f3880a684a970dd68f8ad13c4e563dc28e41927249aac6fcff49105e6f6db0304668e05a8e668aedf779a4101f96296a20de7e4329c7107d14d405a44cf8339dadd06427ee31a74ea9f8f3cacf72be094eca56c511b1327c9b07e9f1da814277a851882fe3f509c93b126b20736ff1eba62cc4de67b44f4b10a34e83f955cef3ac137f40244c6177cc175b4a1b849a7057333df82e1c683da8a643cc04b761c2dbe887570b7c7b12a3c7625c80bb72dd05212b12365a802e7310c812b979e2eb043ec7f7d76d8ce4d5225d1958a819e1105fcce07f8fda5f357bc6c23e5a5e84ef9f07b0bc2fe82b3f7e3995d3743f2ef06d1672247e204624411593269f2b15cfc5d8cb963b8f7f3db78073bf3e775cb0fc53dac239902087038b98f98864abc0f04abae325c75e64df6b2b965303008b5b23fdca536d7c76bfcea3cb3bf144af3d69225ef5716e6b4daf9cd7d7d49fb6f4c1c86f25ef8d85813225fd5459fbf0edbb3714d4aa72fe550ff1b22cb8fa9654ec1a4fa37e422ebf5224604f28bd67cc1d8901fc1194c1d2eaadfbb02df737f573753ce99004ea1765b959bf30d2cf5658cd492d8a152ae297c8cc51a15801317c277e1ca2bef4dca862d082d97c8e099f09abf07a5a16cafe6ed1879a66c71708d0bf3e68c8f7fc42f2c94f43e4d77d375a9036fedbb705b683daf7d6aec51c9b61d79d7ccb6ec5bac4c85b8a747a02570f803b11ec30958a7649476d91f6ea20b96bceed71f9e0567f148e1bb0bf22f96f00a6edfcfcef896f785fe4c0ccd5a7cdd56e3b3823d27791ad81e45ba6cc968d4eb0ead81f33587cf4c652c606a7a55ef04e7b7b7b8bee050fabdcd4b6c39968e7fee2e741ea9d00531b580c21429ad58ef3e9604f58ea12155fad6d35717ff3403781eef811091b4413fdbf361d043485401e12391ead223b2b3bd2737ea311f878a06502f6792bbb6a1a9024b7dd1b49fcae88a8458ecf70d591b27a9c6d9c59b0d161f268cbda41b18976a9e874b972a340a055136e1f5b79e1bafc09e5eedb625c01f711f12fd4266bfda5c4addfeba1be4ac51e716f2e8855142d5209e5c037e944cf79b126feca72aa6ed27e1d46854cf2d8873789d0ac150d424499fa028d5a523073ecabfdd0e765978c441f41fcbde6882f584d0a839500165ab8c88cb8e1dcd1020dd51d69e19bbb13ceab405546eced68b4bbe68dec1caa9b464205f61d69053d9c9f8774693631603a4b80bce4eb484aeabbb47c4fe7ec8a190db7d51b0cf2f72e6ed517508484efe212fc8d89537299ece73e24f8e557aa67e70357da8667a3959f6ab0fb8e62d7b6fa5d21a5679775be84aac19d08dc5be8eac359574c38c937946984d1097076b37cb5f8d6c772a02b96532cf2a9302227a25d19dcb253c4859279090258b01ecd5be34ff17873fd926cebc1946b8e752688641822eaeccece946c23963f72d98503d1d8c90d5e04c7f2a4c4f21cf83fc6fe6e171da7d85bee7d3cc93a8466779a93e6bcb2a6dde92579a45f5c9cb1e6ba4eac3f548f3bd4e84a416a80f13379622c02806ab2019ffc68e6cfb7e74443f7f0aa19176eb7a2f533187a5c0042fe9349072ac11af6fa25ebded5297a8bcbc03727a9dd8bfa538cee607355eec863abb9884f5bf37748d1213a76c4da8a1c9183fa7fae64424e98befd1396c7b325096534e46b9280802b16bc4d2e6ac96618b1ed3a03dbc0adf80739453088b519e9e3119b3802be4880c138c9d8eb065370084c9f0c60c808f948bfd7a3ce11f5b52e33a893d4298be5b5beeea98e326f4cbf55a23cbbebc1855588cfc8e56b2e0470818c2336de8f94384ec27221013b1d258d3e3cc3b2486bb9dce2209a641db408e86b74d25b56ed354fcc9c2369c32ae78f7584951496d517ec74b9bd21a651da49ac3e149b66a59fc7b637a5d4e1d38c3e8f8cec14c4a0d17cb960401d9b57da3f86e1143ebb494beb89e5ad1c2af44bce942fa252e16ac54fa2cc07e2128ac8dc270556308f866df871831eba5197dbd184eda0fbe6a83ed60d98b530aef6e7f7f89f611dacbc92fd867f6787ce06de5e95d9294e7c27bd34e93ce3ff54f52888883bb2fc036a5e63b1d8aa34c5bf3084fd45a167924d3bc2a39e80ab58afc32acf49ea4a8fec42ef350338b44fa5df8ba760c87c8f8d79143c444898f9ef93364fbcda307400ef506ea4c59e5193f93f9cd9f2147b855cb28f40cb0571b6ef0842243e4e3966952e34fad04a06df6bdae1ca475f2fb8c8a82b42f927dc367080b3a6a4e3a87d00ecd629e9a0bc0a16297a2a198caac568bea233dcc5a34378d953f91a9f0b6b0227478a22cfd29ae52a63c49ab226307c0d70e624d2c4826567fe393c3ac9b23d4dcd8e7f6ddc87083cc7a1253fd31d95b82f55fbd658527055f426ce3d78b29e831bde770b8a619d883d6bc2a5932bcec3892569e534c94f232a6619e64aed6fb907d7cba68ef2f15e047e9a1769b1e098767667dfbc099aed60ad001546bcec5a98af3281edf4d0efa30264a18813cd8bd54143f25d189ce5fa9d98daa2a3786915f47ae694a2218bacccdc35c2389886b2b07d0038759f77073dc81c41ec8d2dae2b9e9538cef3cddfa3dc48d89fe5f5c045aa944246dd7136cb14495163314a5a84e763ead57dd49fffa1d56599cff92f75337c34c23a7affce520827702900d40deff25a5d880c7aa61191f967be6d461297f0fe68ab313c255ccf0920cc61a150a27e475c57f9e1a5b3ce8e278325f1e77d471ac1364e7b70039fdbe16c2ab0010f70cc621a089fb4852256591e5ad5b113001f40e9d9ac012ff0ed954b323059ea868c851a77488ed59b404b5abe503e8f0c6b5182fb402d3f3fa95409be120ba413d665d43453632a3843c7162f2431cf9a83912e1507c5ca0578cc99d5800366e1f71014f5e76878c679f0aab8b6c5dff327e103abd91ae74e2651bc9536232abd683610f626f035ba893af98cc870f2a575dc9bda59eddd2e5ddd1ce81c0469aabc917c39a1043b3fe6ddafc25f003eda344890948f55760fb94a212dfea0f6c196296dfd17cbae2d1407f7710d4317d6769d9087040d8fca8724aad9b995c717b041db93bc7046596be0077964a7e58896d36aadb071f7baaddde4747b11bfefb43e5fb7f9c69c53365eafc02cfb51c4e36716852f37d0c0b701dae48157e51eb1a2d6fb9027296212d76b0e4baf35203afb1f8536a06c2904d315692bce835b59edbf440a3d697bceac3e7c54f635c6b58ffe94bf963865ba17ee74ee81acaf156e522fc72817c75d2ed37a14018ee5dfdf1490ecf08c9b727296ed172b21c19ec5d529db46afc497b7ce7293b462e112c3174e8506f90af17de1bfa005ec9d5511f0c3d071cac17f2fb057ffe603be0a31180a2099d33d38ffbfa62685febbcdd0735a842e1798028a262cc9905397e3ed8bf32ca8de42b71a756d1a22eed4396037df377bf0822c6f4f234e66f2e2f81886dc66ef7db7f647f0c79f7589c11187d97b68a27616cf7d9fa66ade4a4dd2eaf85f9eeff6c883c2d4fee880db10cd27106443dd2cdccf4504d3684ec5f500098329ab5cfbbdf09da95ecd180f9231ceaea17b0f1ece3f7bd97f504bd7f01e1369809327e718251135b5efe31d853b02d9f072145f5542a3a6cbfc1fe4c301d5fb58b68d45e9e11a6907d57ed599a3d1885732ffb07501c72660274ccc8df716f0bf7f26bd021cfc77f48132ab3463d032bcbcd65cd5a5d9e11974eb0ae237336b10537203c4601676908ad53d30a11459020fcba6c21a8e8a3f1e16555c3e95c84aaa67f07e24a00e108d293ffbc4429a346f1d1c8da368a930cec1b9a51056d2895bbc1cb3578a27b6e5f2e9871382d9fc98e4eaf34e6aeb2242287dbf37d25263a31b0c8b8440c8b9b094d623022040adff202513b53c22907b692893b89f9b288bf648ec1d7f6f9fa8f8e64cc38853cb8131b11a4aadc825bbe8ce5e825df00bda9ad949bef61f5623dbd5066fb7f812dc264f3876f1d6b80a1ef4c7b89ed65030895de7148881853cf7a2cd5d1de1bf7733802510415e197cc1782e4ae54c707792cdd912d8ddfd18de75386cba67c15c2158819e8660fe0f57b65e48bd3e18a2724ab570cad5ccdfeeabc7e7155864b1aebbc9256b473e090d3c1d43cc71e8098b097620b7aa28a603d2aa4417777b2e005d6ec4af22e38cd767ddca611da7813564ee7f8cfae974c31ed91efe3bdee96ace4a9f98828bcdad8eb0932e02e7c9b31b46edf4f4930fbde31e02cc03b8f2d1083b8f4b2090d96c9b4fa04dcd11ce3b96c112b9e9a2ad03002ba1bb8c2b7173370269a8d97e441d5cdb9d45fa247767a6a5fbac273546d39ac50534bbea7550ea75cf1abe1cdd46605ba32bc90c5f8f6573583d14029ef86572d1b65422955599921b63a4f6008c9b263d71d6d89cb838efa39ea97529101612ea432da8c6cc203f4de460361e1dc9afe9fe5207b5badfdb0a9ebb9582b67ccae187f6d05179a795e1fabd4d58a6dd5e853f338677c704f550fe0cd4dc42a051766773241bce91f84520a3ac6b5c167b3af2e3b7278cc0c090bb3a7eb476fcc0b1589c40fbf37a7baf2bbc84e64914c88ef6754fc4260e87905fb848fff3d26e426072c1517f402820fbdea20e0ced5526f68e4c8c8501f27c3835215435cb7232dffbdaf6ed74762e09470f8c86dfa34244439f66f0eb3536e50ab3abd0e5b7459c625a815811e37dd07c9264531c57edc81a09eea5c686ca207a1420e7a23dac3eb1874c0ea28a43906620e9c1f563f32e37b81f1ef76732c2ad9892895f77cd51ec8019c7f7c4b2296ebf609303a89702f9ef9885f610a606f1d158bd628b7a10dc7b40ed9304fce28d9a1fe2c31ffba779f14b96ba31cdd2b199fe33a4cab896fe0d5f5326ad8466669581b5b36887dd9d2fcdc196605152cceb22eaf0bdbe5504a9329309934905a3ae848e53c629b23317b8a11529d15fbc56e87ea8972aec651f35842890bcaab7531171dbf3350b11ad5de273ec7f2d78f6ac940fdce38803bdbc14c1aaf2ce656e312b3546ecebe2c582fe3ea9f7fcee6660be157a6196ea9dfc077a07d9bc97bd6c76339515e2f8b0f20075e4db261fd973c9ba02a6c7dfa4a4b4f62da8b055f6f10de84a18a1b620567bfa93250eb79b2096f454b26b8937faaa0bc70f189ecb26ce9da22f0ff223a4b7ebce90021dab9228b38d1a405ff257fa0ff5fa76920018306eaa5822b75b65dcb2a0067f69b02016f7dcbafb5d45b845701991d51e8d3b0a96d3b516bcd2e7c995f65faa7d2db3836d3fd8bcef6105930e067038e618a3f50d0571ffeb4b70b96aacfe7f5e4a955880b358bd181bee46f81c1367c40f92a4fc2098c9d12b48318c63d7e77b10f758b8159f3152c9f3cfc67d5e6707d0746f9835017d273270cdc702b2486c056b3f68a0376ae36931b6b3e36be581f542b9659df0418a9ca6983c6270548b8fda41070ea0113bf9aa3940d59ca7d216c653aeb3a207767913a886c838a04c3f7920c24cef7987649c1cdd8a4bdbc9d4cd24584519efcef709bcbf1a3bb87fad8f506528f3e49326c05222fa5ad02d10ad2598da440fb94eb437a4ecaa59d962c167369158821af432cb43c4d652905d91f3d775b3eafa8b199be14ff57b98b35334bf82c0aa940a3a24383efcbcc781aca0f6e248065f5ac4dcf337b39553d471e854ea0f5a0726f306cb4ef6d156e427fa34babffd1bfd8c7d487aa7ed70677899501768a2aaadf82267488fe851021fc421d7b13be53e4c3a0993060a71b5bcd3832a7aaffa8ff872388c5212df9ea1661c980495428387849b09d95c5610d43eade55df4fc3f75b1ba144bce5a9bf4365ea81c5591f77f6796452ca21c6233b5d1ab36a6d0938d5140110db8c00eb8397ef78e3a4154473ab75d9458e5a24ab7af787c9af150603e6923c3e223d0f39ff6d0cfdd9fa7291f1ef5c2da936670c7520a1bcad1eb36e63e386de659967d6d98d618d1a9ecef4a973aebca05659b1d5fef5adcb5efffd0f3706aa97718106211008d1797c27aeb4143f7a002816c0ee8de489af3fabce548094e7124361d9aa079dd9274defe07e35d825cb334dd5926d5765dd3b1f59dfdf870fc8a49e575f7d19b621036d7e47c8b1c03f98e8d66ef41bc97134c546d6d725167bcddf7e19bcfb77a48c70ff40f264e9d489afd66578fcfaa6428cc51e7e951b51b8db22264a95aacf536482b7c20d168876bd4418e2a16bdc6d15b6d6c82984de47033fdc85bbe62d2bfb89fc35b17409c1d692e268fd1368f63179717f219becb4992d5b7d887b1afba590c889409e33abd1c0b267a399522f695d243ddcb5507feca60e3edabd80671925df2a566179b3287bf582f418621498af8f5b124034de92cb5ddaf499d2b95697baeb844995fe61628320bea22f855a58bb316c6c9210155310561178b0e2573d0148bf8dbd34607507fb07e73f858e4a477fb99310beafde834fc6c2ca444656d9b031a5e75dcdfa25578d4067ac1462d1b616935d2d8fc146222b748e8fe7789c2a3c45a8c245814b1d90f3e1a769e6148a36c3808c3c8e0f2e379d2ccc8922cbbf277e9154419558bfbc99e444b395e73a19dda1a859bf6a1d31c80a02b694bdb5e2ecf082875b1c5817cc5dde889556ea8f429e194bca7e05b78fec70e3fbc29536561357def00c0011f4506b1262016149c4da692a8c56606ece967080cde669c538722c65ff9b6ba1c9efb0374a5f1d485009f725b10d3ff9e3538f4d29628432de213e78d9336236a439affbb9b71611c6a3a6b82e6da040c2bf0eb127c3dfb94bc96c45a5a0f584ce67668e19296a59a305359b5ab15e5794e89c00ca6276072866796e50ef502f5e09c79213ab354d97c66077b3e0bd06202de3165258b4a6f48bf347041ee87db0cd902df4e9afb67d21cbe9b6485fe03b8c880b638a90c6b156bb96c957b04da18ab2180627284f8deea371e2b10e8d1740f2a0104d9210545037bd0b5e17b2d93ae6f8e7ee9a06dd217e39225ac2b06d6b7769911ca04329ec4391b3a5d8beae91ec9035e4a69437e1bd478012d36f4eb4d30239bdd34951041e87bde547dbcdecd4ae1b95e80a61bf07b7ed59710ef3f819396b5a812badc4871a1bf6678f1c37697ee8a8cb9b5d5850ae9a55a3fba28d7708348c33a6b2cf72c8e57265ab19abac0a90921422055709ae94bf32abdbb7c0cde36896ac6542daf304f8f4a88e9c21514ec6a6069d5e1740a9be1c7fe0b52aab04a499f7897d1f698bbc41709e3d4580ec6d35a3338b5ddd0b7be2bd86d7fe828ced99cb411b6d2a2bca4729d5ee5a5fd622d5318f97e720817885040942e03b520df85ee0b4a52cc6d9f4c8cae43965a9613fe473b7213d5b639b3704f7632f832bbdacd7ebc2af4569f75dada4dd0691c29374518d7f8f04f27db8a793cd816839ba4482cbd3103eb039e52322fa10afbb4485ca95f0bee2ac00a5dc101efe9361b0bf8634547d2ceb48fe7ecc1979d96b536d472b85b215977b06302a945c369640f325ccbea844f1d763f9dfcee11a2aea18bd1b956e979af2e4d2282f5808b5a4bce2a5ff02c2bfbef8571ee9fe3213ce21f43b30914e36f6184111c028f48307341b15e07939e2cf61410d6573133257b0eea1f7f41af8efb5901afa83ed64eb55e1f60e4fd6453b58402422463690faec2736ba90704f2a345660b3dd23c4970b36481ee96f26ab57fee2f30b63e021b25950a7d64e6163f539d68555d9f09b9af2230aefd6e63adb4c7f7c53c57900e233d2d1b9c2deea3a3454deb9936c968010344fc07cd86d71c42e78dd6162994d19986eaa08c6719021e166eef1da03ff1caeadcb62eaf849603e7258534fdb7238a9fd4671841d7e38f958abce30fc5e6cd1ffd29b0d373bf767078103d190644c5359f79d1fee4e9ab620c67afd41acdb39e1e80eb054a2c293900e9b8ae918336a62f522d30e88c1a7f9b2034770334988edea834502bafbecedff2be8d8bdde807c569e2609a014e098acf7a71ad2d5fb5bffbe4a3cf7f4b97327afece169b6eb0f9406d70b230079bdfcdc7e7c0270a5ba59f867ff6b70b4a47b804bd60b51ec3bc78d8a246aaa10c33d6a3f231d0841fcc5e2f46ee6bd4c88a80bb2d83fc559286873a8a5e6047343229f9c1753feac99d96344688425c0b7fbabcf072a71af71070d23866642d0ae71db0f4679eb3f423870e7597c7eefd5f4ad31413022bfd4b8a0d9b2b5788ac07cffaa6bad986a0c916efc0b05bc219e55dc98d6d675254843f45f0c80da8c1bcbc2541c9d411e7b66c4b95901469168669d047a122b2f5843fa5e14fbe26a34aed50860c64afe76b52bb43d406d4d6f72195a2b02d5e90824a044d8e3029285dcabaa55f44dba3b10c54da435ab07d51a17d9a7acaef6c9285813965ffa3400f4676ff92249729a5b6fc560b3608917c4fe31c3fc6d3f9aea16001592f6c28cb0c348936c3a85425cd6dee4ebbbfb8de3f6e57324921a0168615f590e808054dfe00aeadac84407f35090933082e0c638189bdac1b674378802071f3bf4efc1e6aac062f9c66d778726971fb6e02a12c579ef0627e155b9c75bea15f7ee39f5bb8a3e82a931db474f1e67c0ad8ad7d42d9cf94774452b78c0492c48bb9a2053b17509ec7c90e92c4275d1402500baad15a9f2ec672d1f2f9ed525800a9813c2cb650a5977a69249b11d9e7e95d310008e616c96a96f410108498dc5d2d257e7efdec8dfd7bcdb9e545d69b8780911afa5c3ea15f23690a7b9c49761ff0c8c1666159be64be088d13c2454212e753016e588bb41b4fdda043141d3d53442e983c8ebdc222877605af922bdfd5f836df4e9a7748120e98a823afc26526ddd4276648ba7b130f3e453bd95de10473607a93f15b5e8d95fae591876a2e48bfd6951b48f61b54a7f99ffa3edbaa4a8d3accb979d9b68f6054c27a89ddba4a9584c3a0113cd223dfcf281be94f1100b70cc7e24d83c49849c786ac67965621770fd7225df380a21ed1d770efc133d0d0b3d97ef16b2d2588878b56b6b9d12e92945528e3fa39be4da0a5d41ec948f3a85ff7b293bc66597313261a3e53284a3bc7f4c90edb4484450de039145541bf6590ff46647cb0436c5435441f90b2a46de78ea09cc1971d9a9dd3f3e93bd9f9e9c1771bcadda300c41819e93e7d08710dd639c531d94f0f226f5c8cbf7be7c9716803e7f8b48f110ad0aeb3955be6ce4c359f1b40d1c2cd55635afe89968a397935419e65aaf292301b7b4da38736267e7ba4f077cecc927b9ae0c6be0948aa4df1bf74c761059387d944e8fa9dc1947286a145d4d1b656ca7d116ae5601f6312d56f5ddba89252c9447826cf3511bf10f9780631e02eebe2be93ccee29eafcfaa77b6a913d312cf6af902940105b9028f391bc3d679fd6c9fd802c5aaa72a121ece99d4322eb623320d7cafc113530c98e34094acecfb1d193d256470a626743327a68af67e7d50e663076671a2c228e3441b41372ef17e6c1514f613ab3a8be68c2c8a631dfc6dec123fa2924c73f04d76731763697818bbdf69c77b28474c8ef5d22c5b0b7ffb54b3350f2d2da4191272b250cda393daa9b209b6fd11e61b961557bb22ea032d23d1354397dd40e89f1c0f6a4b7f52a8525c612a64fb5aeeb19eab90531ec8cf0b84f572d81b5f311b60180689edb650e4f846fdaa1a48f6c39fd5f3527ac8130c93be329ed626cbd6e2cdf4ea3bdd5370d8d2284a2c1cde42319a333d8d630282b2d81aa377324e209064d578c6127745b2c50ad99bea62d11671796f53524bf069f19f99021b96efe799dfbce1b1676787692357dec41dcd6a125956e5a8bb4f9f1cbfd52bd32ad83c6e0507ca62aa166902b31dce9e749a7ba88ab17c5e1f9b08d1a37a0b4731174d79d8b8dc06e37576ae90ab324559ff716bcf46112931ac31b4d927720821032aac83b2d77b5a17a9de9d467c1a09d2e68e326f1a8491cfb8507f642060ddee3ec2651c81fc7a90e39486cd22ed4d32748e626370886c32844dd95e7ba779e9c7c77b1e4de0a6556c3ff9a6b0917b2cff68f7aa3ecec80600e5a0ae2e656c5d69de462aab10ffc4d3e9e405b5cd71289fa9d7958f68bf0b275b9c4fd9cbb62dc9e9b20dce269adf4b2368b61d887374681387cc62a4c610895f1047859dcff8aafc3bdfba1dab865fe691569e4280ca9baade1302c2afbce7671dd7c6d69b9d3c83a892fd56560d7accbd0d7f3aebdb8a098e4504e6331aa81f1a65895ed586e902599821053a095b2ba2dbb3c339022f1d3912b14cb636a7b671719630668ff9d464b32baf59c0a9c6bfcd072040f91eb50205b91eb0e146852c72b9d021fa5225dc6707ea28b1c7beaf48f7c99b4551ffd7c4172689b5fb5c3d4192f4ec1454b9c88128cd0e7d16be21e10271f025037fa7561cd5ce7a22809217a883d31d00f0c0a4822917acdead64f2abf87152bd0edacdfca4279406c148bc3ae78e21387853329ce5e8f98fd5a372627f438360fab4ec36de2c42e9a1cd2b8a7f81f0fc684c998a30ca012dd08718c46dfa172fd9239fd91d5921d7325a784e7216eae3eae9ae3a3d722d360ba7a1a5e5054b69fe24551d175bde345a3d5a513232c79b19d5a46d90efb9aec0da7679f51bd458d86c4e320a0320db1727bb433400268fc3b8b5079af2959631c46f07e8b4043eb3f5b9f7d2ab570fce4d6f8f8a1f7b5e622110bfcb11154a480b662751585a96f90248256df0c456f42ce2f21304fd57214000fc5475df8b2b72380fb0cd1bac1080ae4e025f76b96aeab817db12ba7276b55b8227cdc29cde252728fdcb76e6670f7df193e3fc1be38d5e387942fc8fbe76267e23cc296bcb5badc643937845d5394ce1adfccf7026695393235da3810e543e32a6bf709d3a65258d0760e4176f5b9d903295f07e6a2b0b7f220f382176c8694f1558c0946bc9699c2c459fb2a3f6e999aa1fb6e2831f15eb8d6e2c7607a3fbf174ea26f05b2e83666c27a759ec2a1cb1c56170e99255b6c2d838122d958503c4e4d6c8f9ba993f9c0928fba724e5fe5227c8a7af954f88b428dea19aef207d56bddd37b66bfb9eeb488dd88c4b6162fa77f633448f5f2a914da65fecde7a584cd2794599df8c39f2959b1022336a3bc39382faa57d00974ffb22795e1ebfc1720437e4c78b11c3ca818c3e4d0c76e191578ff781510db25b42fb7d373a68253ea81cecb8f14aee44cb395c5f7c11a35ac4edc632b8dc880723e3aacea017a483a29da58eed5acd11c91da5b784b75d6ea18307e3ec5dd878408a3b111f5981acb1072870e9d33d3eebf89bff66303952c393c70967f79221e4fc723d08f82487184b50e9003f73003dbc3d081271ea597fe8b60ed412ae3d3d110e8ec942d5223092d7192ed0478714bf792a2400b9019662f817476ab4ae518c5097f29cd87a10b18ea07a8fe8c27a2ba2df297ef3276b85fbc6a3a0b0c2e2ad2c64f4a3818886728c0273dd122aee3a1c739c1f5527242c442231b866ecf4f2a146680a29375413d1baf2330eae0d6b585b2f5bb3cf0cc1840208fd3a0cc83a09ddb1e6099ca91232808e5dacab8f2f5581e06179772c6bf1c434e35de9a4b40d633bdad0f2636c7be40d7128b5347e6052da5d047177737a2e83389454924cb7ff39fc9cb30c2c01687ac2ba79dfe699ee16444f5b4fe8b1264f918e99de2dbb34b1f06f902f356fa7996db69c3a82ba07ff3c3ebf18ce5023df0ba90fc630e923dd85d6de10a6d458563ceed85484749438aba5793355680db00f4d4c95afa7975ef97ef9b13aa73eae65334630342c78798220cc7db54425345fbe2673af5ea151e3f88675673f8b276df93baad7e79a2913f28ad2a30dc7c421c720fcea7200272ee5024cf8f39911ff584f60cfa5bc7a7e3b19f00cdbe360ec0fb491933820e75a9e7fac8f6ddfc633c71dd4e8f8a1b63cb16399703b8be74a3601fd45313de28caf088312af64e5beee7bb8a219a002654fa244af9fd80c856e76287059000911b96c37de0876701ddd6eaa96c09b1e815dcea4fec4d8e54dd433dff5c6e22a339987eb41051969c5da0c89e718a24f5a1c397f52e0943661ac7c0a9b29c4a9c824f5bac759c2143d204d21da2c9c171fa6df6c217b87848f7e89ee3b340520b7fd9ed6a376bf696da5095ec05720e6c44980884118b6f1eb162fe5bbc300f526de0aa8fd977b59a770f51b1f92d53d024d243cc38bed1930e3c34e349a69a4993666515be75c0ef906e3c32fbe146bb785f4d57a1f8d5cab1114ec30e8e6ef84b069ae95be8d45b23683375c74c7cb8ce13ad5d8339335167cc3da995721e3e173964e9caa1da6c10a68e7e0a3b2b78951b97c4c63a27a7e8ae243cc98e4a90ceea0f8be0983b1ed7450ae9926cb19e1ce5b3e4d862147305176854844e2af99aca1c438a1f3db72ce78682a65521f4841c34dd457a5281f1c54059607c102bb31d750980fed3ea8e904e8cea77b4789308a320e187739fe4897532f1cff7195c84bccaa73cd61cf02971daaa10eaa647b99aa308c01f309b99c8f45fccba68929b75b32f19af11efd9485604f5250c55df2cc06012a526fd2603842f003cf2af39b0d87e943a09da32ee96d048d379f50db702836e4c8cb2f12610379ff5cc07dbbf0fa192ad89efd4e530798c5ed2f967e9b58fe8c8cfa27ac2fe7bf95ffd61147e9093c5cbb1a65b1ce64e2480cb233f60542b0c4ee1353fedb4639426fe8cd654350c7ff3917df3e764ad2039c042c3eac44a707c1cd2e059775f26c4333f18e594217b652bb1fb6d039a64308d70c5338bdef950a6c4dacee09dd524b9e728b0393143bd8e08e4503810ccf3ccbbf79dc5dcd3d897ea915c95cb877e58cfafee48e56e97eeb96b2787148bec27785a5cb3949a0f4297678546c6d2b5fc0dcd4c81d1117ccb620d1dcda3a42662839d44cf261e4ab0b25987739464c0b0fc28b025d051d9e97a367d6d7166c14e580adb6529e1416ddb5992e8ad0ea9bfc46fee0abf36bf0add4ae4d3eb259c3b3d30f4aaef35f28d6f5b45026d88081726fe2e96aa8d9dca83173ce9d1a43046c7fbee1cbfe35fd653f3f363e4d1d85cefb3c1f2f7e2b05857b2887bfd3c36ae79be2ab2fc39a5e0c17e8653c020b03663a65c327d770b7ad5f5dd047f6f931434fd86e95d5a9cc31109e6c4a2410041907d4cd3b29ee2caa8416adb32a58016e97d15c55e25c5d458d2b8c76e30e826d1c0b3251e114e173875b0005de690ca15ed0ac11e23f425501cced93cb0ca6296b9a400e7a77b106dcd486be43345c26d194b0cd3183a96760f37530cd1523a2d0b6c10e46ad0b948f83c3602914f9789b15fc6d669cef1edaa3d99391dad1b036ef4225decbf708f59ba297e58a72b7f27a379720bbcd51b05c640b62c9681b2e4f07d054f2c9c423e125b4610d055f45192954675e7ed3a6a8ebdc3cebe3ef577c3a20b2d5ecfa5ad89a15145cf3aaf8fc311ba716b5ad0bad3791a3110ff832a7dafe2d0d8969378dc11eab2b5f41f9917121da5b0f4f00e34e3be803e46beae392acb0e3c448628d1805fa2ea1053e68b0bd734813773c2da1abe1107c4f39c60c4e7d202ec6fb4d8c0f75bedf471c34b5a5e280ef914fa2240bb3858ea052db061fab97343ade4941fd952fc6553fc4d5df92702986d8e4f8558d63eb07c85ca00d99056c4688da78b4f21c207d1ecddf36e6d4c1d46816ed650a9a20c2214558ff99ddb9e02b89a2ca0c9c17d28a637dd72c4a7965a980c629307fd918c6317474ba9a7134824644317f656e3e897a923e0e1edbc92b7142eeb14e06a6a75f405b4929640e2f61cfa133e183a79109eabf2246c293236e5986f8dfb6965631d85c62e3665b466a3ecc51deb79f393e3b5964e24b0b30e2d732c660cc438a2a64181268357b7cc28cdff526656def1410fc8b0041c0e07721eeb4ad83369cc2770300c5a48d24b0cc9488f658f69cda491dc884e29b65b03fc3d8fc6f3021c705bbb2009ba83a4413940bdeed897569664b4d0eb734ec74ad378ffadf64a67121278ecc1f89e89874d6a27d662bb995b8f0c4e588c51c0e02ff8ae1843788287a6b38b54d071709c898dcd970f76db18b18f87bbbe59ed4f8d920a59667b98dbf8ec1a192ec354336a2f7b632791ea84b9885de86984d6c6e8865cc8c64400f862a260e2f6619265fecac6fe609d662187bc9b43843d6072078d47acd5a51f7218b9ef6154e37b5063940b699ce068515d158ba42d95d051a532e73e1028816cf5d1c984407d751374eab2830797d0db021f34f200be56193a00e6794936454796b850e456aae827b9cf447230a68fdccd3e621f305c8c64e6c4b60a5404c69376d133d6a1ee0203c66c659ef5323eb2d37039239ba89981621c0c1dd2597dfd218932d256bc152abea3714f6c257f682a74bf65a36a9b6ed28c985f54ac87e868d12353ec89c8c5554ae339619862f45e3eac19d26b1d5030f0155737849c82069ee3ffb3d70e48f783c74c96a5285c2dcb7fe1e163cbcbf89f2b6defecbff932efee888d9f375ef87306fc68a4be194abc023b31e04b1ac05f845cf97bfb5c7f88c853eaf17bdb2c35dba41adebafc953d8eeec844f5a8ecc848c1fe74d4591d28bebd90becd6dc9d5b4d2ccc3cce6886c1a1f1cf5664aa432dcd98f117cacae40ea20be177f911b41113f9d3f954f3be121969d4c65ace132aaab25fcdd54eb0cc98785f0c8e1f83522612a5149709c8cbadd98ca893ea1a8d5a0f03954e268f04b797a0961026553214f2719ff546ecff66c8a2a4b5957e3cf4d5a1aaaeced9eb6cce155b4d278185a9a28af3398ec6e7f7f57590c695442ed48ac3b3e34286779dfe64ed0cba8d081564ef6e4329d85427d50585764c766877503744fd53cd4cd84d409d9b5cadfb52db7ac78206b747549f8f37ab51a375839f028efff4575b7aa5821a73f6278fc849cbf8881df7e8c9245b5c2f47c36481a9cf3902036da12fa70cacad632d7dadea03cdc59d5f384e6d34ccd6a6209f1bd1624d25214a89a904381df1f84af6958f261668e9316e31f6e2a01cb1745c259bacaf6990877796493e0d85279ababa92882a0a87e68951775b8637a688fa31600eaa89db17f94ef7fef98e69fb4f1ca4e06da6c9d4c16acf8a4db52787e51e672e4609ad2e27265c995a4519d6e762385e58398f8986ff4d8a3d10c6738c2ebf53b926c46e577b8d54003f4341fe2cd75015cef4bdee9d0437ba7d39f191fde85aead19a262e0ed46d86ae078c94342c986455fdf123eed9530530e2187b6bc018ab9937955e9b88a87467368e57222af3fe37c525614e3464c1c0b7892c24a86a0c70bb7c0346adb65db4d17f07b6f9e5074e25ce5a4b29d22eebfefeb9e84b0b116005c3422145a534374056686d54562df7e02f8f1dda9df3ec990dc2b3db2822abc88edba6ecc1988a0e7d34b856f2227c743c96b0165b9f96b76805e0c1ac78ffcec0034a4624382c41115601c504f2beb8002a62054b2f66a2361b07a704414c17c3a02f81d3587f2f422c01bd21ae13881679623387a072d5fdaf91cc8ef4c4d556fd5e2736986b19ea23c286dca5c57c5ca858cce2f6dfc6e60b709f5d9e63ab66e99824f4a53dce0e363e221ff535d31efe4f10ac5629fce3d5589886f0431674fa68e9ff374c4110b6e1023cba02f64ad703e3eccad714c55df28ccae6c12129f26480bcdd9a9b4ff13e7b69b9906e293527df443c2f4603e69debd9256510cbdce6552e96a0f8dc8a8cfe442bd57d9b7e94f940752b9a7666fb00348561601607c49756f496668e5f2bbb3fbbc37191fbbeb2bed4c120493d50c262d3f71f302fa5981b874a39199457ec59038b04ca14366d74f2541f578c86eaec33843cf56c37dd2374e1419524387e32e14726f7586ce009ab4724f1e3dcfbe576601bcf1db04a8f5598fb7cacedf355f80850c052d6af7ace12ede58b6828b18fd53ce30d4733c3a57f539b5d4ae46063e9ea3493b16db3d9667162257c8eb88c7c67558cda6e4ea5cecdb2af500e6c4fcf052cc7ae71fe952819be67e7eddffd4ef1db490a5f6cb050a4e1fc2b33dd73bf4317a71a0b946bce2a0a0f04af9b3b0fd63a2cf7c25615cad0aeb74a8f09759368ace649e84bc59aab9057df2108a3cdeeb99ed38da38406dfbb509903b637a48bef8c6f20630adbaa41368cd182a68684691c27ccbffe091c30381ef9dd79bf402d0c2715ef91d990805d1d206728b043e720fbdea26dce9b70fb6e256c96ff495c975cc4c422da208ac7c7796bc338cfa8fd42f3e431e60317b4b86a603ba921cbe6b5e5b3d21d784ffe264a1e0fa2b5bf406b70eba5a2fe4e20a694e602b315c585773d27638a0e72b7753e48a9327f47fc8d2f304065e8fbd02fbd453cccf524f066f813e5ff99869c96dfc24ecbcf1d8ca78c1669e156e5928ed4b04a4e1c6e3f459fc761185d0fd5c28f4af689b0358d115b209b78f62f515a94a3b610844ff88f342df56f0932b9ef2a219632e8e6e9e6ec1176a6d2d20b18495ed3bd6d1bce7253578f7b9ca905ddd12ba34d0f6c519153418a04d880cca2ff4c549359caa097deaa9b392db3cefd3ce3c0f19889062bbf9893cc12cc04f17797cf067e5d7ea1cdb3585a2d9d3796d499509761b8a7be983525334e71a573695e2c97750e8e35266b48db1efa3bdc8ff24deca8a817e6a0a0c9823b7ed7e118a937cc3d8ca9bb4aae7dc9069aaf38b4f24a3b2a87418c278dc49e162f42020713061f4a708177b39b0037a5e3144f46fc57f6f6dfe2d0783371c359673befba743f274645d6f88e6aad09a53ba6f04a5291f92b11ee395e87eb4a191189a96f909d68263b3b2daebc2af12b164902c6b3e23f3a6a7be632623dd6438d7b9c0adfbeaf9a749e7a1bb700ca7e803fb7dc879d38a661e8354612cd72e60bce41ef3d07efcddca5a2e9f2583b080901fed7957ef93273392688de8ae6c43affb7543c64241a99461b9bfb51d594296e000ffdf2280bc57b7f5af9a6ef266034fac6c4cb5712892c88adabe8536d1767b8c79a768f6e880db56f1e541d2cae2ec5fcfa73e84741a8564cedeaa1528783007b3cb1970550907ffd898606bbcf549626147703a9f68264cb724c9dae7ded7a8b8a6676c3d6bd44ce82412ce3b7d86acef6855c99ef67b8c3dd510f60e267860c600e88f48fe96a23c7b6ce05582aa78277700b4c35d110a26fc31682767b6be0f125d606d3389c33b595e40027b59c0364094617a3a7179d949a6ff9fdd99ed9860968dcbbc7468b999a1b2fed3a1de8b76cec5ca1ddd6048136d811fffd4673381b1b031a0cbf910dfded1715683b1d01e69d3388002375954081c3332d9dd0ce32cf7784416f5e9e715e8814e3d5c3837f4afc8f6aefa629b110feda255331c7ca740724cbcbfd0940869f4771417ae33fd37a581e23d692d4b935581fd5688fa0f9f2f6368470f3b17f180f48ab529903584df5c6e1b5a3f2ff9826f2f1374cd33acffca09708657fbf258ee53f22b4d7adb172cf053d1b51014be90c82397594fc0f5d8471dc9c548d2c026e4959cfa81ae8e7bbae7b365bc30d6fc0a7c82abef33bae21d0b6adab2e76c7664eb5e05eb43ac61ed1683651b84b76885820cb9f8923bc266ee315fea9b5d197141232f94452eefa485fb21d16b0c89df04478bee546d2ff2519c9966aeb0096d60b5caa420b992b54bf28c859c4896943e09383716b335af639a81901f663b1cac44dd01bdd7d8560052bc4d5aee7f1135c7cb1b5d0d4a576b7c0cd41f529bb9177644918d465a895a313b8f77879797101a102054d72394f2d8ef775e6842d7c06324853d8e87753dfb792ddd8bd1f26abfea9c419544b8170a728e695e0bc830f61c2b735de1a412ad43c615bebdd46d8ae8fbf2cb63d0e990389ec0a1580d3d0014e911480a1a0ad1c8a83c86b6c56306f002262ef97578b96174987c5fe8241cc131b04d99c1feaf978ecfb13be4d9ef843b45179a4fe446ee61d66e1ebb19e77d9e1d31914fc64692950a0b57d76b019297f9e5a7db7e7089dec7c730aea3f767becdee6f236b25ce07732644cc87042242efe12c4680d9c8279530afe91729de22ba8068456a931e301ab636ce5f3578e48df296e7c38b00e68767f92e7d142944e1529d41e273f9ad4863479df096c2c69298492cb10cc492d7fbc240e78f32815a47ccaeac369ee225d2e8777be36e101cc78761d7a5a18eeed17e5e45551b9894b643bb66eab3a2cc5577dc0ec847865f113edb5b844bc6e9bc3ff091cbd8c7217edb60da6923ad315ed03fdeeb9dc500fa66470a3388abaea3d61f5e3a6c0d3f2b6a331dcc2643fd57492de900499310031618c1466e992651fcf81aa79df82e5f8f432038f410606db0d261202172b4ddb5f9951650b096ca4fe65a30019cb73c1b4fd6867bbb936edde6e52f737c490751cce03732357dfc3b0c7415cb2753dbc3acdc84ecbd3670141904ac480f2cc067552dbbbe9fe5c177de07fba0e525cba93a1fb25adcaa1b45bb7bf033afcf1e8395a9c3bb750547548690d8040262d14370caddef76267be73879868aa0cb0612773dbd867f89a3691d97e00eec839b14c7ac9a3fa0c958bf4eeaacd00cd85cd05ec18d5628832c73bb46beeeb41f0db4fab0bbaf9d190a484d1b6d3f1aa8056cb741f5cea207f6cba2831c5fa38728a5e92994303ec87ec592c6e661699f83d8c7d90b1a106653603296b764053008450ff02a163831955f164a82a7cb019310de8d0b765183bbd4725fe49987405a0345d53b1fcf5315a6fc86c97ff9a09f902fbc1bc94db622d2babf406b0418367083e1c14a5964b046fad9701cfe385d81ec07b36dc7452f746cf3e3ad24727014e3c9f17db8b7af671c4fb6e792e011da484094d3494715fb9d6057ffc874e4542437033c1dbeec88bb688064e92349892cb779f697ae9df1dd125e73c6af88a0c479b3732a20d327f0446ec7eea0c4e08ddc693b32cb7571805dc224ebcd3929b809a004c550a1975ace9e0dba6213ac506d813895c0d565bbc1e6ca73fe056129b0a14188f36696d647f61ef3cc794fdd7b49c0098b119dade1a9a6986318772e686e1ae13a805e435c32e5d71a05174c9767139b47749e2f6cf31e70759ca65898a8b91bda3281326b25d80eadee57ddbe400dc10008d90a82ea6674d2bda078e348ab0f0c61461032f2c61a0e7f186b13698b4565823e12efc7f8ec26f115a312e3bb48756bf5fe353f82374b7102691a7e7078b69c55c27015ddafdc9301be2ea6dab9917fcf6eee779bcb3eaa2657930b5c3c0d621c115de006b6483fafc374b3f9939ed34bb9bec5266e7d44a23496f6db1bd73d00e4fddb7e17fd84e3879d77464adb4765f748e4156c4c74ae4136df788e11ba7078ec328c9e3a9fe3e3d44f26ce358897f048310e790988f4796791d995a4f40786abf95cbce133595702b8a3c70ecd389572553367715e4afa7ff6d24853af3798440a9963de5b9c08dae0fc65f43a9637b731577fe0fd1dad6c8fbf6d8b2714a2947a3d0462efdb4f77607e5470d4b8ce0e28e86da6c886d83c69810a0b3302ec7a84960975eda7f6650e23b1864bf7f2f4cb08619150797d6ac28972fc47d6bb2630c8a3bd3ba8c59382449567cef45bbcc9ec8374592d8d8ff80d1943ac5eca40b706cc2e35a21e3f0c08c6814a308503959010fd846ee4dcaff0c33e7d800d8189f15f81522761f68dc6d44e0b482df80d72c4a212f20ccd6eccb3d66ab9a38b39a090ccd7f867d29a79b6300b8aa5cd34d3a1b7ff87922aaf6127eaa839cfb131b90c38135ae05f3e92418069677f6794393c7f2af27164d3320fd7bbff5eeb08763856b2055589af57fb5cdddef3a4f9e34361519734bd699bb71ff76966f819a27fd8997b57af860593c35b7546f6ee942302ffa7f7f7ab66941fb34d0cdf7f01be068641b725a77534e54fcd76f3ebb5c98f1c6ca533ffc9d69c49543e18e4ec42b9a589a2da97e0cc249473e4816e444ed8146989708bdde2336b6ff0a17a05cfb59b0fc06517d9abb830011dcc4f9204d4eee57758ba2f89291c85a834f18f2cbfa891492040d26536268f781032fecdbbcb6cad8a9dcf5e25684417414532083888f86423f61655239da9e0ac61e317aec279ab2da32396cfb149440f0268eacbd7a050fc7ed648d6a8f0a9927db057f47329703ce10a0e45ceddf9bf1795ee3f6f1b07b75a975c32ff7b0a5d6d4dd86fce340b51cac14ac8ec4fecbd5fc5ac762821b67d50cc8df1fd6c25ab83de5bd3e6d5e0c9217d9c9834dd19730d5758c66877f32f5a9a51739381e5feeef964ddde4e914cdac5a729b91c1d2267a598d87dff26c71559144ff75cb461cdb54df3bd120705c12ce529d611c31e7522bc215165f0e7d4c0678a35c6212ee757db108e808419f4d316370516a2a5932af9d1864d2ecd9d0b7af6313ed6e288c2d396f0878fbc8675cabae3e82e551354701363a4cbd9bb7738eeceb2e0c867af30af7677efcab492cb0a5d1ee95f65981a1e93fdd783e6d8028c51a2c8e8be675fcfff5f2a77814f49b3fee4faa1a14e585ae4391ad3b62a7668f4c7b442b941ab739f3de83b2c9016edb41830d500ba84697dab414463b35518156c8e71541d230639b363218face4fbd7ee9b77555e27bf13f7a2d650f6c222265c7d1559f45e7ea9d6c487b0240c29f9a506bb6435473efa6b117587abe001f135b6593ec65aff0a11d40a396f0dd4d2d2f9ba5a7035bde84580bd0b5d9f21cbe8fa62ca419c74ba9d0fd1ec7686db19adc26328a9b4f1b2c7ceab10d70d0a7b3434c3c6fc241aaa12d65527b72eafde3eac86e8733cda511c77d6c954180d16fab3dc06b0794bf54d3dfc7d85e3921d6412bff860ebc0bcf6bcce72f61ca79cd12d7c6783967e9bdf96965a95d151e98c30eea0c30579d3e1cfaecfaca640fe2d51d49bfd9068d2d5888487c131af1c8a8dcc8f7ce2ba4e27a857565ae7163cc7972f8ab9fb9d7152123e15a753b2535fe31bcb65bf635e9f3cba1993e3775aaf80e34cb3bea3e9e1fbf7a1d5322e8faa0f45e9f99ed3a4ca0701ed6731123c4a698dbd96028493a79d4f7929c38c343434dc0f9fe25bde88ed02568c9890d6565d821c02ffab3d882a813150deef8baef9a44e659d21f8f57a8be0069577d9b19b747ee81df3d8999506b7bbfdc3c3277ec4f81b7d42df7a433f77c29bf08704840888ed5f91f5ea1f962aae1271ef38b1e149520ec506689b105370f28c2a91bcd1faeed0d1e26b298ac97117a8be5469b16dffb27caa138ba1279db487fbf92c57561dd9f270890df6a3992f62c4b7a23ff5e40a039acd97cd73b1fbcd784ab1f23a02e500664f902920106b9028d39f81ce19e0223e808ff264759d0456d42f259944a3a8d2750d3c5e92a383f0c8848faf1d61c0bb494cbe26fcecbf92935e5de8a2f137ad23522ad2917d3b5f3851f0662089527772cf983b8f053e8c7c750b8a9a8d23194250f3d7ba5ba80236a65c3cf83f7771a2770c6feec5a4137454efb311e687d92f6a93243a64e5b06d91356b48fcc64debc2ee10e8361c8f68d129f607146e4849da7b2d7ab41d35d5a4903b3de7e92923ecb472189a1b4f5e2d88a47da9b01be788e7b52f38d2e551b872019b3948d96d6c264ce46b6d787ea9e62a785e520abb03d7f7455db8cdea31408809c61603026bb4fde9eee59242ef0c5505a2dc274da3fdc55cdd5c3b8b836a200489f29391fbf29ab8ee3499761dc1b2206601309256b6287d2d9daaeb251d46aac30cca3cf838ef56fb44efa306a5c428e43d93daaff9b38ce134a40a5be73285076de45387033c9aeff0cf74a24d11332aea4494675a77d57e8deb0321a7c81777290059e2fe1a6289b3695b3b148b91acc996297446ae8737ecd371d7c79d2d6aa466629214f6158878f0f88cb606ca922878a55bc243c8b63a62ccc388a9b66aaadffcff9a4a5811088256693b17ceef023299ef08add8fffe394645bc53f7afe642478be450f8bb43db65f1d5d79b9bb337e0bff39e03495fc6e8153cce9719029ff077311777dbfbd3c3e60b246a268fc257cdf269df72202e33eab6619cbac4c2433364a0d577f11eedd22ad639e547239d8c10157b3b414654a4278127fc4b937752e5256df27f95538a445a99765bd0edb4d75a8ba19a85bda794fb2d2b0a4cca53f812a4ab0093eb932a13591c4c308f7f7be11fb5efae1d7fa6c9a97c79b7b994462dcec8ddd8dc5215084fe8c8972b74e5dba44fb8d14bbc17885cef0b832014d881454f91eb50206b91eb00b5300d921f8843a6e05a2d18e2e96cf2eebcb5850308d1372f7bb7ea76c95c5861284318be83d09f848a9d709eac6ca49dc9e4240fa812f2b795858c205564106837d492f6a2c15d89e3b313ce16aa33fb75f972811cf80b54372d68a3d12765675de651394804abd0cb752cb49ef381cc01e0468be8321a477738ca35bd551d0cb041d312ce4c99f1ab4000cb03e66ae0c5cc19813ec3cf34bb016185bcb0e48018e3359c576b9a8b1036b4468ecfd0f2896700b3c2a5ea5a7af1a800f20a4693d421aa35ca5f5dbf1218e58821d640b6f1f201cb6286128022550ad4c2da39d1024adfea825e5b7306af1459f9dddcb2c465fc03b5c8b4a71c6cf60f31858a68f155499987d03cb4cd03f5c5701181e89150e5d9d0cd99f2a7cfbaca8f279ab96828c0e7ad9428fa4a55608ad63e31d2d9b0f90f57ab811ddb0af3973297751d156bb7238ba863a3ebc4246b83b2931ff6df18e875715fdc91fd70a91dce590330533bc65046f90dac2ca6805888789d016aa43762d3319895409c647bc6b28e595bd4f164aa038f87d3fe2679a9230d7aaac608eace231efe09ba88f5e58d1b15bea208c0c1cda3508b1aeecebec2de222a6337a1bb34a806740e5e6d769e62b4382b1fd1bc39269f98fcc8c2d2c9089cf72e17dbf49a6c1a0b68beb6e8eeb651218bd41665f883023482d907f88b2344e56e5129aa8fbd6ae9d006730a9014123969a798111b2def4a5f365726e3807961fe20cdbcaeaded62820f80d73007ad2989cc90b59ce1cdb86b2080664bcee09f8df504f6d55c2efa6a147546ac5a7e5e241084cb3e94307c5eef25f1f3b7c71ff8a84c30f7efdb6eec01ad3931e39bbfa4f0e33671db672379f96f975096cdf39ebfd17e755ae701821e0e27f244baa48e38b6a23c13803ae4d431515e3e3792f729bf38897847619e470582cedebed5a435ea9b1d823e48adf40c9c8d633ae7df39f71c63cc970985791ed1047e7113cce850868894bbeba35dd74753d8383f8f05fa027967dd14c307a9bb245dcb0dd7d9152e8aefb702aa7b1fe7d79659aa603d10fe8e802180eeacfbfeccd799839e8eddea4f099262bce8d1f5cd466db5962fad52fac51468b93b2f49886f24cc66b9dfe0b67576bf76783e967a09e063f5e849e4e36b69e53c961e1e64696f2fd4b854ed94163b2fbbd0e8906433fdb16f526d82d9fd76bb5771695029494f498a61cb3874c267cbe03cef70d06ca25092fba2d2b99bbac663ad34e785d5ab0e0e58a0f107fdc187ff7293fade3c9e6bb45ce80eae4cf1b59d9c9d9813693a63b08e32a2c89983df78959dd6a9f5d8ab0bd24216164b32b210e78e9e75469542821ba2fbd33b043a870384a8846cb902efe7f6f613ea076d535997ec96bf1c62379de8343b8e200752719bf4720def03ad13c4493f848129c505540c33a88b789c64e396bd1236a7e0a4da021fff5fde197dc778e15894538ce41cb3a68b1ddf3597abff8be66c09fd8a375daaca5a988f19aa4ec36378197d0172c379880f0ec3eeb75cdd1c4a5e949d98e714e1dd9e1bd7603210c95f6646fce53ca6cdf5e12a150c492681a67e37d667632d32c4fee3c0bab6ec394cdb4c74857b2c25fb9c75defa33ce2563484fa7cfe7d27c09d181e929d0edf5d6c992407c5f49c8550587362d338797e233bb91e51d21a97d384f411ec8478f97bd8f2ba227aff66dcede4fc19b33bc01cc9e839d5f208c4b999307bfb3209f7e5914f800e64194e894bfefa40cf1d6f58870da2d4257953c58c9d3ecc10c5ded51063f82f75f19a88be2daa4fa26ff4dddabc7dd4f8b67016c0f477bad7e7623a62d00f31aaf16182cd63b170df1d1fe27315c684ef780066a614a6a17863f946856c87fa22f5edaecad7c380efa16fc05c68e149f7aa9b287d0b1a5e8c96c21deb82fb38f6eeb9919514d80dd2b8a04a84728f37be87b05ed69aaa1dc3aabad6aec55e11b81ce050f3ed4c9b3fbd8e49463a38a7ff3eb55e7a05ef4a801aa67fc439c9d517b1fbc9f997f6bc0134e0d9d38d10a569f1cb3c7a8482a9178d0a67dab23a4a35b2d5dc2abc09b3117b6caa4a7af913d14e3a22279683ef6b0c582b696b89034894129e46bb427def99ccff202db11ecaa856f05e9ce2920cf3b09d37625bad5ec03bbf7af18ef89dc75e35eed86a94e9e89194a47eb3278f69a7b4b4229921ad60ec5ebd4e90bb1f4a7dd3274e87ee9db521b920a9f1d0b536e7eb8e8727b5e38331e968e345527def2acf0402516748fa1e9af4d42c1a73962de4b19b5e4a21ffa2bab7fcf9f10df10527b1da5ca17a49e8a36d7675986b351f124a2f483098c8859252481bfaa6defb3e0e9076468254cfd31918ebb4b29281d32b3417957ceb931169dac398f61a6c78898f80d3c9c081f442be365f22e2ff45fae535181c9243193362f3b128732a79f4908d6d1a1db7c3759adfa759efdce12ac6562d14297094da8546e6f7a6176a396042a171aceeda24248cfe5679ff25e16ee00cb5ae5d0552202ffe3d99bca00a48781bd6910d5dd9a83a020590825cfbe87a312c3758cda0d4dc9bdac9db8d81132245d65c7c5c8832c9b45331a92cb418b83a7c298bd0889291e118821ac03d24834657c2bbe193f06635d57e8653e88d536068e5c0f71f8f584a06228c9841041eacdf37c28c251b84b111877a21ddaa2b4f8f2102731e6c39ce2b7089331b84d17f7d4e5c31bff0106e485179d93b10eb2a95480f9aeae6f8ce7f445c76742808c518f4881354275b3e18210f7d8122f9aa884dd4bbd9517d534b25b3b870b285ee25da2f9a7d8a0aa14700b0d4a4cdf3d651c9c7f824e78f1822d71f2158894789cc51a9caef5f643736ec218bffa7a5ea036716382bf4ed5249d38f7eadb35f49a0ff885bb3ae1a82f93536a87f49e4532601422cfd63727864b5514913bac740e355601c6428d72f364cfcf2037828ae978c82a58130df7824c6c72de4005cd746eb602cf594c718e6877eaaa1d98f7185ef85bec2961b5cd880858e7f68e8849513914f16b576ea39263337783319b81a3da8efb541ffdee97dfca484f01aedd3362af2436735c42906e742ff86b5a8ce937a2ed55ed3d758bcf26a56c943b4360fe3a9afb1e1c6c325074f549b4e4b96b6458c22c1756213595c139224cab4a62d8d48624f294e234b5f8f589f8185838f113ab5b20732d90fd88ee0bd874c0015244a7528493b43d5e867d684c2343c12d09c8068d5181ef6b0b5970a838d8e789afb09ab7a2d31e54f3c54ebd88c2a7737ecdeec27107a9a78d9bd569f486f2c176e801b08c62ad27231cd779954fff03632ebd1eca7e0a9a841dbd6e0eebb59d2b24d25d2bfabb2e2f6172d60c3be60663115af26b3f524ed4755bff0f0bc2f7ccfaec8bce45e0352bf1c77eceb8502f57858dcbd73648aa20cad940f845f223884b369257af3de05f7cc4a3c9d5d6ff68186ad4e32a1dbebf6de18a1cdde31dd777fcecb9d5c02a1e80dd31f638cf699a0650467b69f98b96cd32af727d3625bfb237a27b707f9c1f741ee162b236cee840470ebb95e61a1084a3e946f36f5ff4761a358fe481dbae8f4aab2be1caf0afce7769b19b4b28a0cd0dcedd302a9df02bfed4ab34f9c24ec0eb19081f9dfd9cfbeed82c8f9b50234002742726bca626c2cda52aa52e0e7468c42d62b189132709a83cf0dd3c2a990d937f5287e0b2425013608c8c9128c78df027d67a73e1144e8696d8bb4b2520af4bd13743dd3254fb4081f1832dc7d5d22362e991e9e0eb9e40d9b51e96643d2e253ec7c5d7c907fe15bf1454393a849c12d271e17bb344650bb5a315e9f8be732351e0cacaf6572659eb13883f9309e57bb1ff820ad97c79234ebd2733e04ca2c7a1356f66f4df8a07262bfcc18079043885c4d0165e8f3fed818669dddf2cf6f8d2b399ec5b47f93686dc6ab362eedb5c83b564c59e4aa96355d35ecfa180d738d8014f6f57195adfd7d2a2fe86654a25375f723e2611354dad93ca631339d1ac92bb6d7fb88f4e4b3e2f67631a75684dbae20e097410338f9e73e1cec2712fcb86970243bce7e7a38c2471cc3e9c5398932bbc8f17304a02d081abb1e9c3698d954154a56dc06a6255314c82dce6f1e639bcf0bf4a2a2a9c233dba9c1948121dd7685ee4b41188de118e4b382070f45545cfb3d88bd027e01fcc8cf530b8bd4c72a690e3d522a2b1f5f93d5ff1667af942df03d751f86c0f07c8f291dd8056eeb8808927cd47acd50e58e6eb731fc693f7ddbbcdd70e2a5a1b1c83f05e5a8d71164763d2eff6c0fc090f78af120b9e1a160d46650708fdbb472786dcc4e560b8157c774cdb3c1819d411fa6412c9e690119e0e3f24c7f2fbedc43c87dd7a4b9aea149ff43430fd4f5de2541fad3704e9a1f0aa4cf76291efea587a3653fb14115abdf10e993e849a63302884a7c0b1f3fd04977e28632484de78e4fea8be06b5ff475a4439de7a64d1836594c7fc8b011e4eab58598bf21e4e519690a736a0d45b4431fd953ea683ec9f11dc98aa710ec5227303ca862843ad7bf2ce8a6a5744c9a54300f03a11006d9cd8921c5b2cb3fbede5bd552bc267709337af95af10b77c24633171b8aa34c24d3a0f29beb9cafa8ed87d60f4f3588b773f618f3d610043cee42ab7dc2bb9516073869f1405fad3b5a836e87f73733bcdc09ee372686d1758147b629b1d9a4cc2bcab79a33414c6cef2c290e2e8105a1830766a61c8e6e7352ea8dbd36bdbdc42455f21c733976d882efc1474c56d79c5456e63ff458be6c6ac05c8dc8d64bcc890b26ce02494598362000405f9dd98fbe07481ea296a33efc7d7bf93df57a72d82c758e97099dad34841b37ea42d0dad745502d213a6b6bf334ac115b177c2cf10d140762aa4f0b0112db9f4674297d4ead4ba721a3b6bf68ae6bc35a32e94bdc1544b424db758ca251df8cc006a5820b7bb769bae5c7814840e4626365bbdda9ebda805f080730ed17fe973f7cfc3d84a2bcac36c574ae87d77fcf816cdbc5783a001055b10407a27f1faa216fb6194537cfca7819358167342bbd323986869943fe6eda5f29f4f43261bd3eb76934e24cda6c269d5584ffd0c850a2beabcccccfbe515bdd7c98851f4b7f995e197c5e34b7fae1121fbb2bf4d86e2135ef701a99ffa0d3d2dadc1fea91046bc9dcad7783e6b16596b020f2d72589d78e65904f857b3c20c6724c3830548de0e92ba3f6e62b9910232611ad101a8495056b29934597dda1b246e542705a1592442d19bdd1c3a2465db7b97b170d181cbaf1d6e850ddcab58f06551c26c85a2651c3e321e0ef5bc87a52e07d0e89b7c3773256de93c0e98b46d181d6b5535c21923bd0fa2965cef7db66625b6dfa6ec5df229c3863c93fd3de14577579bdf7a4dfdf6b5d35ee6b794c1fcd160ce94c3d1fde05634becd2a1c1426ffbc9e9c69f1c1c5fb2abe9afdf68d370731667b3d8b687dd0ca3bb3a50fe9bf96ce9d39f76d6fb29720a61acd868da2961c9846fd50e1776fe38f144a02e85dd6cc32b72810042ce7c8150432f86edaead0385329be960bd43eaa8d71e692e95309e7f7cc52fe57168f86445db3f0caf6cf6b9688c1f1d78dee17293359b6347fa48e62e0a05bf73e6f6891c84394ae7106d6a2c3da9e15d660d77884fc08476331279d00f6b5a3b9896eb5e6bae37bab0cfe606bc719ad370f916a4d5f360041c9e9420448fc2baebeb7d90098f1a7be179d66224ed5bf2e44b9090615e1e73730db8141bbf49d3acdd5e7b8a37ea4aa848511d7fe89703c1de2871b6f93d0f70d81e00619c5febedf1f5414236bf43d82ddfbf4ff0673927e11a0987a0fdc2e598790123fa47bbda58ceaeeac35d646356728fb11a1a58bd33e375765d04d03e831d044eb2589847a912f249525562215f2fbfe2fb10db81c1466e59ab565aa32edc8c72f436cfc5e6081d91930e549ff68c0080131a720234ad3b0c809f681eb0846c8936559b339c79b014849c70f3b5e561fb14cdef52f896158572789e875ee86974fed6a44e9491afd672727a4306a873cbea722d0e4fbde3bd6f01ec5a6f4fd11ea213ad3c1cb95f0732e68b731faa685e4c4533e4ad2494c3f806800d136cb80a78ae765f23d6ca0bf6d4efe9eff7c13dd83fa4a799cbb51fc23a601e68e2372068c1c7eb4bb15ba0f1763e3a6f6be5cf38af8446c8c8d2aacc7c159f9cce8f7cc32b2b0eb5f22528ab9281340f4325008de15c81c47601ed53038eb7b8f870bf3b443669881841f19c084af5ff000f9046a253d1e28e035ce939b6c1073b0bcb0b46b973e4f9f0ec622f43324b64b1d27b0f9d6063fb595fdb08e6c58c055fbf1c0df99d068a6e66f71a2d2585f1937cefd39b50aa829c1eb5d159f1c38cc4f93796556d92ea0649b7329fd28a408a4f0b4b8686bc1a24ee36967b94823f95a77e5b4ec03146b85c93e32bd35c0aa624463e7ac949b5f76cba7996caad2e6fdfc294acbf3bf92990af3e57193a0fb046a0beefe2ae54d57be06b6f18a08560c2fee28e7df159779c9d6432cffa6eec8bf3433a002d4d5b0cf68071852a03baa0e1366cdb6d36ec3781c701e4fdedae1c197edcfde9b330439df5e348694c6d087ab00c7f53dca097b04d49491c880d0a13a19b1babdd020c8ab5736b909aea50a5dc9245308e90c7796c850f77bde2a1523db9a0d45fd68ec4fdb1e31c94887a0ce3f4c6ce4361932abcf8b1fc0e7bf9872bbfce66f37d7ec67cb98350f66814944b82c838197e1c3754ebf1ee1b3d8b1fd1f167d03ecbdb16edd9a12588f9df8e16039999f03635f219e22aa69c6c5c2776dff5b007ef8c2dba3751052c8313d8a2e9ac9605e0085acfff5a8464e1d139238a2225483e45f04b2ce9cbe35c8e6946fb423604f8fddc32964554a517792c7334072a14406b751254864e25c2e2cdccfec831dab1854231118e6ff15946cc5ff5e795d7445b8f6fa27e515430ae636cb70ce41a303514e6043ee41e3317c3b9b268dda8b953a3afdb0e271929e2e336cda8b8ef71dfa5af36f2857b22164b88593afa28b72145634e63614118c7a0f1b277b0cda178acd9a0736e40466f8fc318dc0f28be452188a6bc71f828bb503cb7053259aa9ce697f604516d8cf4b297ebf00e01d99e629b5294c838f9d488f5a21062afcad1a15e9196b422f83ec81145b5d3a338962f6db0e4598c260a7f2fcbdaf4b271e4c99847de7abee23c0aa5095f799929a92045d6ade897466ac784e09e9111740aa0108174437e98b0e5d1e48c27c2529e1922803cf0d4a79a57efead8ef08d29d9a5bfaa931587d85c3315cbf131919b791fbfa7e5da17bbf7937e15fbd9d7fd9808e42499ad42bbb6a970e23c1c379876667ad557536d9dbddb5f6ceb7248a2e6388d797af79e6991e6db4e7b664aa3ef0bd7d5efc0bc26b9296a0eeaba17142f278dbf342f82e133778f976648cea3c85b8f9e004a74321f3c119d842b315920f3365c4938890ba4643b8eda660ca0d4918d84ab65615715da1da7fdd3112f9a411d1d145f8137edf92804f6241871d6d045099a37ae5ad39d84d94191137bf21b9602879bf9486525efa77efd792e09621551ba34a27940d91c2dad7eb3cad8b2c96748f542d3b443a741d30a122a1a8c811d969d0a24331cfc6535534adcbe06d9ebffd3e8cdbf8db8d4c5c4484eed4a3e2bc7da717fcd808521831bbd7599e21d61e9d792663a18e31da11c4666e2e76454b666e9d4cc0a0ec49a401c32cd8c2a51c72c3aabb72b8e31b2d68094c9b7e1a100fdae2fd9ab4d322726c7622a8acfb46842a898312dcdbae99bf3c01b019808b9f051ee4d859d6987278d85b0e980a2c0f7009c1a82521faf59fd162055d984bdeeeb35d64e14a23824a2d105b2198896d25a712526b68b44fc4183ecca12d532497bf81de241f41f2d011e3f4d642c829276506b7712fee708dd3a1e81ca32519523ebb0f3daf66653d4d263490cf1ee78d68b6d0a585c282839e492bed982ab02efd99b6fb890fc780b0b8398001bd3b74a70adfaa40a748f01fa6fc2a12b221bf40664d73226fa482503c31bd7c9553338de1c9458ead24f9e19f93995c67480aff6ab217189e7ad9f207e60b5879cdb1db57c8a25965ec2036ba27c5f742ee5be7a03f030d4c73dac4992bc46e79f9f609cb2301e081394ee7f80b61644e21ff79e979a45e9e97fd3b6bc5f624be22ba72d7a231505268814480425fdb018b0d55be583c34d113c469715bfe45da2213a0da92df13e54ba3db77a7387b6bb8c1e3576bc9dc4982ba96ecd99e5b1ad6d7224356bf9972b26575d99bfb85bd24a7d85c5a052878e664dac316504b17b5507b44d47ce36557b694ae21dc32280441df0044011796b6021a6c99a0a21579dbad5d25bedfc6d6a925a43193d4d267f36aca8c3cb8e6d0257c572fb08728c4b0b84bd1771980868a6c61d2f23f5050829b289237fea73b334007ebf7c4c1766ac46b6feb13f130a6e0ab121dbe921980c33609f4ce142aae56ca0399b66359fe85c3dc397b17fa83a2958eea982c7bcb27a1823a7671977d3cae8cbda96a8e99d2c6852070f559d9086d9748a73d969142ff96fc7b822694f32606e797dae688bfb9022b7d4dd0641b2d0c4a253bf4df1f23c54c7d717cfa9f8cd653b90bf53a6d304869c22bda79813fc24d1cc4497ed7573d2e48c617dbc2f17534b95e773110507dc3c628f5e3eb6cbc73e613c8c9c78efb0138f50fc02a84bf0a22c6319c2ca32f1f83e853c540e5fdbf7a254027aed3530e7774b0354be476b1fce6f6e16cfe4494f4a006bf51e09356e49329fd6af828a7d17d0fae410cfa784341489eb535e3713b208dc63c69657c927d659b27e44b43b1de244e6175b0bec35f86b6e9a6dbd1a5e0df01617d42ed93a72d55ed4339eaa5ba061a487d202aa2afe7f7078f20cab904e1ef63a5c8dfbbe667834cf336c652134764063c7bcf84d275676ad9ae2c49108173531a9a7f14295f95f32fb8b5dd0724fd2671b79cb73db5fd488ea35dd42e4e1fff5e67bd6497b448c9b25bf604fa6a8a419dc39ef41f9f58eb4ced7bb5418793e1991f965d0229d56e5a6741c3022b3d41d8aefc796097dd01f268c46434e0aad2f45b858c0e81fbd56fcc5a77a6d2bb9456404ec7c8937aaf8104923049927ecff97b9391f62928b507ad81125a0f3be25301161b18b3e611ad6f0265a2e63826de9d7ed0b56a8970722a64e79a8df4225dab2187d3fcb00e8d80458478c4ece9feba6e193b2fe7ea55413c2b1bd85d1223e584d74163feea6b5f3575b359f7c51b910ec26b4556a86562d5c74d3af9e7886860bc8767fd20f25bc712930decf04fbde61317f19e11f2697623e9aa17527f65e4f031f66ce0c47d45fefe9ac463d089ed963b4fa4735284153597321f446eedf09a1e08524f4b19ca7046926a51a48fb7137f28e26863de4be96fc45be8365ab53621987fdca6c316ee14116bcaec385cf4ccfb0d389373d11698a1e67ae69df107c0b70858e4d8d509440be12d367853f082062b4d83cc52a3a97fa85407d05d397d43a1d9083f36056b3ff032a6ac221abf109a65e72bfb3ba99914e22ac155bca83a63f21f3d6c215c4b73f2bda3a94dd40bd19cf4ba1eb452270e37d0ba0ca1072d048974cb8c35b76aed2b0710abfc1071aa58df81ad914031d2a25bdeef881a46bb5e46e50966b14a29f33c9ae6ab2f79579750acb2d1297646a90946113a5588b0fbfcf4ad8e419fc2a1bd713a7ae6fd29256c3c356501f2bd651d3a3bd83c84e2244438da9aefe4c2ebe6aa7d1efc12401a7739beeea32ccc6aade79cef1df382001fd6dd539e014c75da5d9d4a346ab4f50b89955671249a317e4610806a69f4ac80795c0786e2ae13839deeef40fb357779d391d1ab243e27aacb71e158c61aac423b949370993937607f594e56b4bb9280fcdc2961cb2f76d3ddc6aa3c526069c6646f3ddd062c12bf77b561e6783da2c0a6619fdb1e5b75425cef33028b106ef656953ef8e359fc836424c1764ab835e2fc9cf5552dde314112fc6d4fa12f02b327c75d8499fb45ccaeb299c6d557dc6650737eb41a3a2c9750bbe0555b589781c5403e89c81f78a4617472da7d19051e60aa212fcd9de76fd6148e42479e8ae55caf5bb5b8e675d9b40fbb151dfff7a4bfd156ddbc97a5a7ca806793ee6d7d1f6474fb81b6ed32d910d874a9c0560655fb30096b6aa31cf9d3c5a02eee5913f5b665d28fa1866483318acc2e6e8f5330017e24473a635b1270f98e6925bedd38a3ef7fa06fb790c97e2202b5fab7ce6409cda4095e563342679e4c37999598c230cf9acff7ab7ed9a96decfd30fd57b9fc7bf5db5bbb09aa0383b11211faa859b5b443ff461a0e97b7aaf0a3193f9d0f8cd01f5673d9377f809a197629dc92b25c5dbed5c0a90254e98e685cc4f1698e710f17af5295452f9bbc61c9e5944c6e73908a82cec6edde906526b3658a22e6bc1e5541a7a3d843afb443c66ab9645e1e76a189b97ea1b3db3d79e24f1cd707e8a9da64257fd279f670c569e97cfbfb912818a168f8ff7c685c590f40435c029338f0ce4f1c43ecdd4a54688f4bc55b2e03356b64e522b7961455a767f9ed6a1d934496a8e3e1fbd0024332ddbef77ec4cb9a57b1c211b61af826cb1cc80bf13cbaa5040d86a56c6d5195e2e567a91e1c35030fe614564c6dff7da39c0f88f7e9d62bbf05ad608031b20db54cc1938f453c0ffa37c8d8039922da67ce93e463120ac02e492ac277dfbbb740037758bccf2c277a00ba9857730fde83c68948b72ca75fe9e4579ea4f2c528326c15f5af2641ae9897df08a719324ed7d6e46844816c9f6575c4b6a2c6bcfb5475801eac50e7878e18aeb75e270909d1e9b77c87c9d38670be22976951cee2abd685cab52073ec559a5a46604825c0575e8f59147354d21ca2d1a1234518056e7cda11d800997afd528bc0c1a42588e7a40575072d4d59896402e1eb7835a04d768698427faaeab8e113bd20b632dd0fcdc0e949ee90f860c65b6e3fbcd80ce01ff902950107b9029039720b2ff6a7b23f7088a23518da9922f35df2ffe6d2de02980a96def54034720054491aa34a5bee99dde1d5eadf35a9836f3b550e0b27393b058119c820546b8e9a37b38c2c36a69ac262852db8ef31cb1fa31ca23b4646bad09b9d29ebf17ce06ed6b5abdb3c111de40e34dafa99044881ba779e79077eeab4f85fda3f477f5cf24cc9a93996f65327f6c2cfcd520af1a9eb9fc4c35756a8f7be06d42cabd552d874e6c6566700e4461f4cebba58dd285189499e36195c4949d4dca84ed0571d0da5abf7366ce4b4b8546e108697fea777dfb8ce717233bf868188453308ca97f6ab2d366bbefbb7936178d3fd09db56b28e1a275988353276d64b352646aef1c8cc2c16b7d54144b06ad32b1f346ece9d9ca23c6cf27acc9295da1a83c45b91c07778a8b27865108d5ee60ffeabacad08ade1d2d84680f13fd773725c5d5605fe6ad149f7a3672cdb7bf054989dc333b924c66ac44bd7fa7537b0c9b9f364849108d54dd8a10ea5a9848a59eb3a3afc209190e52b448fed6b78f9c41f7eedd0bbcd7ef3a954f829316c2efa164b37b25a87accf6eec0a7aabdcc8347dfe1b5cde3769c50d1298336a7289b6a76dd39d3ed6b9884fdd5707f5bf52f8b8be3fab15082a59d6d210c161153c53c49fe231eeff662ee51fcfc2d9a2a8c76523c7fee29c98248e97f633c56a00898b2e82fd54729abc7d81a663f41d9f63c971d96a3830978f78a4c7fd38963b346575b5196e1b10c94c192d54f59b782f737dad13df1d2035c2c1348298737c5ab0b881bac7764eb6d53ba1c3dd92a15e93f06072c81924ae25ec19a1ded2d366b912f46ef4ce158c839d1982f7a99998bd3750dd9d466f2adf238d1471ed1ea606096b7c527229f079bd393550d165ecc51b718c69f169194de130d28aa5dd5d76f7a4f91eb50207b91eb0556f5bbc3df69c3a80586ac4ceb39df8914a7106970eafab348aadd15cbec13556c33ffb88867be09b8acc339750967d77c6d97c8ceec616a23f47f0f08077c1048c10377f3d2b4852e1329336af698f194d236e0907da1068fb34b4f995c0e4bf90f78c52c326eb2b93a71d21b99b3fdf6788dee586aa291aeb677b1aeb2631efaf773a9e97f208b21ef9a97d1d4ee9e5991dc133af68c50b38531778a70a0ccaa437553df83dd1193f1389548af994925a970980f1bec5b783e1b168b3fbda4073ec9464a4bd236f011b02e89765e67d6932cc5e95cfef032ed4b68679e5edca2da3ce96a02aa3238e540eacf47049755b3503d145527dc51ac9b5d9bdbeccf11a7ee96eccc2ace85a2e00cd2a559441d3721514b6313813a5053ee5d22c91cdba73bfc6cdf16b979c8642e0c3c60a7471e3253995d3a8e942c448dd224449a62f007a893a7a79ec66de51c33ac5b7406c499b42d346935c0ec328065e7641eeca26fe46a65f8b6e10a4abccb49873c161d895c80a17beceddf4cfc484b0b0dacad00195319cf79186f6af3eb7f9dc3c8c8917ef2b7dd14c8fcf5403721324f3c1151e1b627b7beb6cac1d09107fb2f7f71c82d3e97483812b767026f7db05eb33af6c46e57fb0e36888b0b2482750de5a74ae81fde24d14493e78d0195d48c7595a1d8ec582b85b1097bfb5a2afcfbf8c7e3ef525ba5177ee7965034ce15f7dba4270960f6d5ddc37bb9afafe626cdd8c70c9661e0451bab25b0cb73ca197d2671d6aa7bcdb7c918121d1744c83d5b46aa8bcd81ff14ae80a84cc44c18a37058ee413ca309c5ed780738ffdbfb64d2138029baf509c0a2ff1c180fe3d607f61f0ab8f8c09d8d30c4d7a90c40d4a30c099ba645c5d3a248f00c9ef6d305ac3dc841ea7cde1c5926d89112942e9d35e59ea1ed9058f368a963b04a688ccb91e818039360f3b4dd1f5f89f9ddd0b6a0e1d294cf5055665fbba057e84b4eb28460ad099eba3678fa6283335fa22639db117e786706d576cd09f8cd3be8ca07a1a5dcf0b4d5c3b731be35be0a63faf393b1c2c44a300bc9839626851b498354d2f0112afaf176cef9db883e499fbdbe41858fa655cb6597f6b2f7b6d7f59aeaadc94ac016ed9a58506b269067578433baa3544fae6aa46f7ffcd8de65f19be262f33517a2a59f97f55d2435341ccb959eb0b4e672d32cf3e15d45175a64bd3155ef22edb8d43204ab55cbc50ea80c4524d90b223c3010ef6c55ea3b01ff0d907bda02131d7ee563013772783173cdd86fb5f15cf26d2a5b582f9ee2fd8d34a073bbbdb49b71cd888f74780523552472e4b095c1467aa5ab40217f76877b151bc6bdfbd7935bebb30b6c5e17c91eff127f3cba150e6c1bcd729841412d73bfb94e92ee07292178e0ce825e47674183f6fbade1c207e268772ae1669d0c3eb08301937104b64b9dcc04e6c4e6eef2edbcf4a4e905f9d2db499775c4d7be099d5de72b8d6cc87db78857ec98b3caeaca7ab061be6a5ee5e4af2449f7cb3af3a73551f227712f48a988b01c5525f2970352bdd808d72ad528158a2ce648fd622db94cf7e1813bf414e75048498cb8fe7c1752079b12610eb4499cad1a8a5b5fb34b05b707644810b2e219ab7bb9ffd5681160c05c3e77366ca1abca7ddf2d88d5348ff44bd7957f69dd98500e124d5a7ff1b81b35663757ea1a3fc58db97b34f042cd0da7df77109edbd648817985d5d872b50f79e213e53fc4c1d8af1258b56b403070a72a7342c3931c094fcfae4de38d404348d3feb504b6c16cbf347cb9982442490dbb6eb755dd58ac8966e4c5f743b40ab55525cc19dc23637b68fdb710572198a6387db1205406f9eff0857d332669994d330204536d32bc85f6ba88cbd808e56d1db87be80ad138339449ce9b73e03b7b11ed3940a13d9f03aa7d96451069c882c6920767618b7c3888df03e29f420fd8bdb85aa08dde4c3088b922cb724fae04154a8b163528e3e18442b49bdee7027b1951dd352d59b8bea741518327403d8bae961c86cf86370ad7daac6fd2f14be03d99add16bc3811c91a10b922eebf3279c6aedafced3f65bb3c0ae98f60bf446616c3adb12cf9d50559fb2e69bcbcf1ff7780e90af01b7ae8827dc0229e918c20bace2679257a9c134ff8fc89eef9a54a4881cc852044bd42e4d3c1f4b4e1e403ef887a6b6ef1c5fff7e8a9c2aa3a8be8b20b49aae62179d63388645a94f9348fa45a7c9e75bd3b4038cacc24534b6e3cc7a783f08c031db18d501ba00585005864c1e6e791516253c200bc94ed8eaba2a3326fb121c334aeeaa1292197040982e3a25b4696285d4ad67b5eb33d98844df5e328be086d3ba9029386c80db5090da434b1ddf76d50b9eb60d3288e3d6dbffdb2a6a0bed49c87695978cd177f46f6bd0abb92cf1153db288810f6ad326a59f6da7d6f49d27ae7a675c7d0b8f7d854200c4ed0db1e97b8d910f1f3c7967f03200aca089ea63d1ceebfdfbc98aed7c2bdd91062dfb8d98e0272d137cd0c5e365021a5d98df9678f5b5478d1e5a00bfcd72f1940519c16923ad0b3542fef80da58d28c2c6fabffcc1053f7d019de8f3effd70b68021df3d0403ed23dc6b5c0d46198000e81b60bbc5c8c70491671cc2d94d06e21341a6948c41a4e6c3414d46b08beaa9fc118449795d3eefe33793140754b7cc74d37d4cf281562b674b67a9fdca9972633c543e30c0369ec52d4572f5d4e85acab10919a380a69d829572a9c2d611a7ed97e27a47771f47c081e84a3feb4c75269f03ed43887ff2ae548dfdd680d7fe509289c34a5aeb2cd3b935c04e27fee2ddd75ec959da0087f4d823a67f06fb1c43f345738eb6c85086b9e1e21e852b53a53d10698e3ac3e8e0bb5c697615a6c48c80da4e7062237be19c5f268e1c33592709c54bb452c5ed29a462dd77f4da3c719348822a12e0313e171ed5ce5b7bf00a13914ad53eab6d8901f976d2863854582a87a588da98c58c375d689bf87277b8644339669bf657c76813305902b42a5de5a0de8bb189521d091222e374f1a4e89ef72074683ca0564202659c8a7a72c6981b7dc539c36c1511b80b2d797f1df816fe6da5027b604ab454192a0434f1b4bb013b273d973f77d547eed7507e36d142fcaceb2bc9e3b8485ae5291bd93c7109f9511a6c046ab96b3c5727a2233742edaf241f2c181367828fc2a8d0d7bf84ead3fcf0b277bfcfafe1f70c7015160588cadef0a98fc0f53c711a92b8d04e8d5866ef73cb45f4fcf43aac4b011add9e1388ffea17cc8f2a2e90fc14dadd67de03d07ec2ce080a1988106a1c2cd763b22e77ee1807259f5ee5bc6dd4af28b873687aff60bf90284ab2662ae30ca4bd27e7cbf4da4dfef73186e643e388f560c7030b51c575d93cdd3ed986607fb9733127621b33b717381f7a4ff0d1d52c70984b52f5b7d876ced9821be3b21b5b9655f3d6ac68e148a9a18e0c1fe5b92176d8b909a6c218a984d79990fdb7a7c0d81af39ef8b28a9ddc959bb7dbda693db4540457ebb541a2daca63af9d5858acd24894839375af691862f823eca37880720ac050575a130f58047709f16b8973fa0a9d9314e859cd50f2c908053909d785e2e3b32b275a940005d2d30773ea95ccd0e561b473ed83950ff634935f2134f3801b4533a9d9ff8b3f286770587db195ce4179e187efb4ce17106217f391f2e8479028dae01aa1fd11746170f914b6a560ead6ae4445bd6947ddd25b0853e911a5fb73f768d339fb6b28877522feb3ebde954e842e08594e330d2d06bf6ca4f6121d28b4f4f507cbed030ee9a1d6cf2637d04ebdbad1e3fad8e38ae421a5d759e4756654fdff20b3322b0b1d87009a7828c31601c0acadf78cbc3cf443487d2eea85ed20bc713d1ea6bf86de31fd88868381395c68b9dd46d4f31e7cfd0b7848cff85aba60b7c24a37b7e53336c24ebdc19d742e8c8169f734e2bfb8592c939caa6c1eaffd8147a553643451d99e1dfb18ae3f68437d447fae7d27a67cf64c9213607ae578a661e0b45282dcc209e81680364be498e3d6d5d1ce81002f0a0f96cbb673dbd0960b94f485ddb026398a13b23aa0c44973195ca7ab4366a42aaf8196fffdc83219d1d5fd9b8426b632c9a8bacc1980f0dfee6d11dead6faa879ecae139496bd63d8558048e7322493153a4623f36fd0b8f359fd7ba012c9106bcc2508c59d84a20e9412bf289d03a5c4387affbd120cf540562a581484bde41dd1b94806e4e3b132b55fa81742f47f9ced78a6d2abc4a2bb295c1aad87817ea59bac7bdafbaa02fa6916c18d0ddc8a57c7806c404549a3ef5778162e98bd0a81581c1b0cd7ff2554f27c42894ed72b573db901454b9a9da7330673a2f238b7b9e09018c432f50aab81efb31effb0d5f9530c636d686aeded2530031307f38f315ee6d6822f79bc28dbe6d8869184a17044da0700801c42855e4f81d4ce2da4a9b611960b1c40364c8ca92595d219626b2535851780ff4f50dab9fd3d47678b3eb2802bd1a8a10e5683450474d5c7b1c113374459b3673bb0a60f051018fbbc30fa71003523794733b31a8fab087dcff34d913c9bba2652b1b423b12f84d66675e4b851ada564a2aad21d83e5c3ee517ef715996147869c9adc686d505b6e7e764028d1dc2a279c6573d11c18f1504a80272167944c8246e6613912ea3f97bf55ba9bfc96f58037240f17280e3cc71ee284ed3698fca8b936aadbd8469390aad535a4c232e584a51c9688f2313bcdaa513078beeb5ff6c7e5ef5dabaa170d21e165f3997398d6d559b169444211488c5597d687aaaa6effdf18017decdeaee9233d62c0f1630756da921858aa23379b311481c2736286322f5d21b499e0b99b6fa8d29b93cfa10769e7b67a5bc1d3d0cd91124e297774c847e8896de5647f055658a81b44f3f725d0075b13eaff138f849065efc574bea33dde7a6c0fe0ca07b3c47838e17a477568361ae71784f2a6508a5289736fa052f0bf1566b66ad3a79dd6fbd335f988f207fd5721ffc120dd4d38302dd05209aed33ddd55d27b57d619afc8b97605bbaaed2a989f35316900dce6d765abfedf0b9d94e5454d2978509359849f8f6d2bdf5d1d81a32999d9dd02ee3dad852702d631a1a7a3d703315952bd1930ab6e28cf2929a9b45f4934cbb83501521e7af3539c6e2a7f606e94286d10834a28d5fb8918c771304ada8ae40a5797b8806c6f2ba32cadd5387dbbbcdd89815a4a777c353a130036777eb584a64dac3b92153ab4ee2fd7a50d72698c50f9dfce144ae44830011ca1c76c167627ae0ee5a5f8d7934b9367b10eedf4cba48786d01bdde50229c179a34120b1b54c3a904041139d3d23e5f924b80cddb4e9519e5190dbbdb49a08b2ee117b1d031405df5e50b3aaa7176adfaae0e87d6a756845e7393860c43541414c52c22cd698f43fa38c095d12a5bd4e4d7f95251493acebc462ee20ca06b1f15c91421c94d4886df231de46c40e09953778ed65cc9c778b0bd09ea522181d9aec01d502dd677e864e9452a44ee1981039678258eff46039624d210deb0834030a4059f34b07cce0269e0f3e56904ee3e48a65c4d2fa8f005312fe849289389b78fe995286cd3928739152ab42a5b10b4d38195a746c6919c0c8d78e17cecadc2f787e9d92c48a1d132c7a5c61d656be541ea18788bf490355b38281c816c94b9aa684dd88b5d9512259aa4a1cb17781c0b278ba75b24377ce06d9a598cb264ca938b71aa841f5d1de4dae9275f7bed6122b12803cf1b3fee2bde0884fc8997c039ff3ea023d63ef9f890efa25b6c71518a2dbcef6516a0f56f523ed0ff2e36b59c30455aadf3123df224aba50d13dd8472ac8bd510e50f98a048ea41a54de0d1ae69fe51c462a8c4cd68f3be657e19643700fef2fb7970e196a02b24a01ac073b655f37468fa6c57bd2707004c54d35a4bf9e5b99ae2c65978bba9cd9e02ba45fab6f4ccdd99710fcd5250d7844f0ab6e37b86c78e1c806438de878b40c88e2eaa98623438ed91b3331532b9ae5da39974a44a9e14b3f6474930ae459ed087849e8feaa0b8a9b5b9e3366a3893ba96f69e6c663ba4632c6e13659f2ee9f0288fe4ac194cdd745868d421826abc54e52c81582dc7eb5cfd82eede5deda7156252abe75d343f62a6365ffe2f26f77b7b0b2c20c8c31908d08934d304c7f963d11e97cbcf9745ee570d596760e2509ca4f3238988876052f8dfc6671d851037986f074724602959b1a79ac0ae60cba58dcbc1694e1087f3583f3661eee6f173ce2757f103f0fee45684556a1b1e309bd1635491c19a4ebec025d3df7ce2daf197d6d5f5669e69daa39ca6fc8c61eeadcd29cff2c4adbf76fe8e10c85df056db35b9e21bab8d7f5df294ef38bd5327e516ba25ec626965401010fc166b9853b751b7ccb021a3272d7074aadcf70b38cb3bc0a9bb3b66171f1ecb1b51f287bcdb4b72f82ace9ad12bfb238a50679d92593af96f718c67a2234b07e67ff14fbdae0c77963a23db637c92253facfbf1a202c6358d77454c864a9ea48c3c10020752588035546622a25dbb4204953e4a30f27da6ab2edb2ca667e895061210e840ed875728589fc2d1d8d766229744631873a84286b1c2416791d4fcfebf13771fd4e4a64067f807ce8d52fea7ed1eb9b5642eff0a46a0c975861034953e96d6fd3e8ddf00b52038aac713475dfacc504d04cc3dee6e813e36ba6fad2f7f8323ff9d1678267aeda7a9c4a4e4236a6da0f05a0aac30faef8a57d025d99cc7d254e0f4c498a29f2afc55c5b1849a7a43c53bd0a7f140e970ae702a17440d389b3f2d8fb5c66d1eaf19af8db81d3cb1f5e818e4000515c58ca4ff42054095eb0e9751f62d36fc20cd55e200c8d615dabdd085e39d8a484aa48aff980ad566d50b4474698c9350b0389d0a3f17c1b69f7c13ceb6d20a44b26f7fdecf63714e9fcccfecf1cb80d02dab15a4bfb5c65354048f8193bf5ba6f7448f3a67f0fecc13299afb4c7ed05ea81e4e7103525cb31e19a37652be2d010d6ea5413aa50485c211e38e4c396030318c40cef816682cc81bd26d8ea0760fefe46632e3563fd00c9d8308f2fda7fa3aa87223a0d5635efa3daf5c71c3e86e19c03e94c918ae76bea6b8bcc612e5b3f09310ad7c452938fe836bda3e5591a9de82228908663dd9cec0c37f4bd19f13ba26adaa25ec11b698d3e1ecbcc432cf69c48f531fd3c574a19b052760dbb7cdeccdd46e1307a135cfef29c074b56e63d1e454bfd9bf462d7001d8156f8b661fbfe2027897ba42d0ce8ab9a6eb66d6f5147f38a13c60974b53a3970f9e9579ab2771c0b077543551d3c8fc22ed2a1d297cc3d3ff81ab1b7b0392df2ec37a06bc7f1a618004ffd16cd83689aa9844c766878bde968698837ec06a9ec5bd70554575a7f1978e42a047c58b3c6ee6d3795d57444a4dfb222f6e67aab3a1739c1c5af115be80fd626a4632f84221000a826a1a26691d53048f4a852edbda161d455fd1ef78c6b907669eda4bc72fef82bd4d1af66ce85a98a50aa6d10bab64eb238d013b2cb95da49540cf926e109386f31e1159741a6914966ce90284ef79c5f43fc8b832d17849cd546eaff3ee4f8d93f30e6def6a6fd21fce680b1a1fdcc1df6ce2c144dc6e10f580624e12e3db59be624b6fbc3ab0ceb60bc08a84cbff7e09fd7cf6ecfc8736d74fbb452cc5ae599447c3c76bff08e25129b0f35f6033b4a3a5b7a888748128d08b347835d428cce45b53d48915ebbab02cd7d6ade1c3955d6a665140beb29429b24b72768aff102f26a8547d773f50562209b8f8849bfa3addce50581afee4ab4a673ac85e9e208f894db4d8b9317982375a9fd0cbd9e22b0ba9750b3532642a004903cfcfe88922b8999d1ba8362c76e45530669cbae50163435eeac52f457778d0048fcb61abf02ed428e26e47e8200e251d2677f57b4ca1e5c4935b8ed0e2d757119d7329a7362394af0af1feef6a5bb7a5fc80cd12cfd778f29fffe785d22a4bea4e82576dade608da68e505174b2bf9d30d021518a17282d1f8a769359ebf4df2ae118036fc8fa4afcbd4e742ba828b068e4c1f5eed248b1e57b672f0349d14d208d288ba3485a73c377e7e791d5fde7380b768995891db852ebaf0d0f3518d09f2c56daba3cf0226fd1aa74c23fc5dacd82f8152f5325a15a51ff85d2e5af02535d047e806c7ba6812b9b31ada4d0e57c0bb759164b350b3827176b425163011fd245628276b8d3b46c215775b966b2725261cbe68559f869666f68a3596cf429b559e0f3f9c22d8b5851a8c59c95718607b0919a00b76477e0a72f0793532993cdac97d721e4696e43a40af063b68e72f27d9082c5f5bbdbd476a37118be5fc18b3001045218c0af7b418c9e30b3dd8d4a9764f28ffb7e00a461212c726c1835a46af9728ca1cec37efff08297a9f47a759bbebd1bb9d8afcb1355f1fa7b91e53d44d9534ac23dd90ed3e57c6bde80d2f8bb3a202123b3f0d7cecf5d96b324714ba1f36ccda1a5dfbb2d0eaa68d2df1ae68e2312de5edcfac4c0949f08ad7c974efde9b433ee872d78371f557b8c818b9db0acaa8fee3588c92978769b90657c7095b149d7823ffd57a08083824f86295467061ece058d45efc0fff0ec2ec3c73bd79a78fd585559701b248b57a3ebd4044755ee3183ee4e1d791732b2a97c982d333f82375b265398a215ecfb13b9371d1841be9cbb9358d1c28db71db83e36b00e4900d53decae2fd562151080eb2aa0040dcb4c68b674093bb5cb3a1b3473f9ed4857ffd2562c5796bf83168604fc61248dd00ae99991dabd75e6cd4a472926143f2c2c103ceaef921657a5eb449808c78b17a33831e0a20ca01f9f56c88e46dddb1bb51380de1417c31c63f5b57269627b0a38f72ecd35745ccdb95e06d60a61ddedcb4db8e3f4bca7e3373021175302fb09284f34f7ec1b7f2a52265387a1d81a6118eaabf1b4024c763e9c23e6cddae6e12ad70e8aa0ad81210ee5db1c1b5ed6c958f2e0a516d149a5f4b84363833826c7af4e5d6acab34e5b5dc66b5e552b970c9b049965361b55fe64b3f6ce1e1bd7dd191226794a89954093aca47db15b5312aab87557f1074e9fd9167f01f6d8c8fd7a63a7b877fc332d5ad3a68d04f1d883baca07af70733a1f55e3a28f7d73a304e65f376b53b7e956cc1191d9a47a3133a73b3812204e09ce595aef70d27dc06ac54095ccf86439d6ecc02d34d6fe710edc16bae6e6c2abd6e6dd68376dc04cd94aa58d30cd66560113391fc0f254a25467d79970dc997bc37b8d863aa7eb482dc57c73834e0aae0627b86b21292a12904b3f5872049a92d79eca7db5dfb67b7c7a53778b9a90473fb4c962cb50ee09e460dbf2754d7f7d57bc2c2c0e1b082d5b74b59e511405c8e62259cd01c57511de06e410e1c7311617331ceeba5bade0fc36ffd9a6de6a7ba586c66f2206e3a3ab1c8ad1b0cb4502725752042f01a7ab87ccefb72ba6b9c0f935cc367db072e1d4afcf44c55345117061ed33f1ef0325a10ae12c8aa334d5c45efcb02f515149faad0643dbae485895a0c0d704a9958e4ed2d3135eb16edf23939899c709fd848efc5ac4446b321f521e5f5539061a4c14176ce998f599f71711285a6fe73a84b2bd341f9c85807ddc77b655e131cc1acd087a106b022c0b0a0fa1a157d608a1725739a54146bb1873af9b595b4cc70d2da2ef7817ce99596f7eb00fa6de6de2281e3c3d7f51af55ed8b6a1b0db9aed72cd66ee09796dcc30d720d534b87e18deac2df8b8e74c9324520020002913bd77fd36280674710a1684bed41665b69c5a5925898aa181e5bc2c5f366f5707513310b0c888594d8d8330c36cfbb623fa7dd3a608815f5e53bea5792931be9ec536102fc476fadcee4aac405c077a12bd8bb0988e93edcfebb77453dae9835c5feab49791f5b16b6e28200902a3b577aec954afc2cfa71b6759cb198980470a8c48b87e030b696216e237e194f74b583b1ad2220ee4620a6089d0e4bddfd4266e4624e3fd0e8f8c1bc2365c05637708e684fb9c1b86bbd1550b368aef44dda115a37cac8fb3ba19f184db48ed9eec3ab42fa4d6586da707f5e50f5f369b68f2345ca902cc65d673bbba963c28de453cc536de965e8baa96489224196a8ef716eb7769ccbe87d9bb9ca1d67300a1c7631c0620b58eb7c104841f039b6c889cf68415f61a6b2bff908e2c6ba96a86e67934efba70fd535a335c5a55f474d0ac0b17afe9eee80a12640b04888170448ffa2a356139083c05d2616ece110c3094204dcad3bae10d74f2026d9792f74f3b6359a4262f9fd856f7d8dbd522b98fdf0c3b7d2ab47dff3e1cdca9341eb99ae7da8e7e63cafcf1ab4088b42983e868474fc63ab2c0664fcfb80075321017e8313fd10726b50f903b72cbfe4f51b9e1d5656518aa31897188bfa8d7dc44748612f563ed26c87b7b62ffabdd171a19b798a820c13477c4018a8c28b1a38501490bbbdab1e4be801838c035bc63226a4e8c5a35a82f396116a7c33c78d54451a0b22b21e7cfef2defae3b36acb6f7f38ebdc3d36d5f87ddbde1742d5cbe5738965f0c21ea25c0394b8c93ca5d5592362027d73930d9d2610f32bab58013b4966f3c500350cac19228b90a1d8b6bf29ea5cce96d7a4bc8ba91aee474c53b7e0ca709919d960718ee95e3f1666f3ca2b66fd2355aa564a60c934ac959fa942a3f5267eb7ba278949178cd6d04923a2aa2613d2d8bec35085a42dad682cdc04dd812f7c11a6e732ab9dfc11a3fb850c05b80729ffb059e36662e022393be44b437d8ead6e6ddc70246b7c9e27a746900e9a766fcf803f79b601e5ee6b2332f2d5de7366ada753892c11f7793f0f661445d1325cb8ceaa4b916e2c9cb9784f9147cfff8d626b6ae1c7838fe74cf4a0006f4bcb33cd4abcbf91cf1f4f31a035b53361ee3b9a8b5c7dee3ba09d22ce5bc68c70095af43d7a01ac2bb91f68f27a60533ce43a0f230912822b869bfb7ffdee387ac91a4f2a0c15b84e368d9fdf22fe7eb584c388d4ce6edf0ac4ede97fe78c8f446a4af9d5789078f902950108b9029039bdc83121b631af4a537e2a50b3452be85ab9870cb82eb36d02dd3997054e4dacccdcaf68104cb990ca39dbe4b1a34e52948c7c18c96e87a68f2b021dd0cae266d822bb6847309c8c1e254a56f54bb55e54fcb1a4e38699d51fdde77aa499d1fb9a2cc16892c3db78cd9b93a994ab521ec7c99b5560c8bbed2a11e75fe6787353cf93aaa59d567bcd9782244cfea6c19a93dd73240f2105d8411d428bd6a5594fa653053d6b7da9fcd5163618a4c622c84f736204b3f01edec7bd73768acb27cea32eea95bb2f31aeee3834186556953ad5256910ada5b3a3deba339118a67a1dbaa4a01e36d6def7dc788e5293bc8ef7a016273f251ec12867130f60d695bc5b082231385c329a4215c84f649e1465436f63932de893fac6c4f393ac4308e5a6fb5d92915b861f45df98747b28356c9dc08cf41e0eafdbf79abd2170c3ea0822ab9babe252f71fdf0e6ed9ea6c06d3f782a8f4de731a462d39f6271520613f7628797afbe3c89492e70f4b98019f9b69203fe41576daa6e37e4621b4592b9674f184acb523b84cd22ca4caea196d3c17406bc89345318188f9002a420cf4ac867e6ea3c31c5eea4ae227cb920067ec4862d3e296e1314fa7e35b4531954e09cbc536358787f26c8b6e0464f97ff8230be65158241d3aca45351518bc320c933d591e07fce2efefdcb8d4629693a2b4bba5ddcfd0131e6134544c6b3bd64c1215c261143b0cdf4b32c51771ceeb63096efe4fd7aa7bcdd26ac0b2695966c335b5f56a79795e12b60a51b28a1634152b52d0d6a4d65e74b959be14b6de2d09244b0d9dd2410d0c2506ec337c360d8d6c27897d8cdd4178d5040a0da8d5a79046a15430e9bf1b1062acf6d4b643ddb6d63d943d95d8a024ce8419b37d7af63d1c3efc555cd74742f69c1d4ab5da411902f91eb50208b91eb05ce141c4dcb0cf4acec17102e4847a208927ea398a5f362fd94754973641be060fe5295e50b81bd7d0662d6f66f8bb7243479e7bcfa50c6a228a7a255f411e970ade53b6854e67b5bfdd8d1fca419176d0f1792c24071c3089b0abb7efc7b5c7f065ac731b1d736261b45d6709b0ed0eb56b10186a97780d3f4b8e4e3bcf8d568f189a1750ae39f2800a3a10526eff3a468d9c61370794bc39c5dd19e5c3f0fdc162a99560dbe6cfa78981447486f501ac9d6ebfc8b9ca17e65d1ee88cbbb228416af616a6e975379cd6e112987d0c6e9b8ddc3e7c5e870c0d88cf0a7573094ceceb4a8c60e3ba5f73251fa5c51fe8272ad4cc9d716bea3f06e46a9fb03881f463884ba877013ca8f898a9df6c3a7035fb4d622ef9a3a0c3877eedf8e15a93f5e2fc2213758f11af53018555dadaef0cca1f32bb9cce690c1837cd82089ad60539cfbf93deb236dc164dcb9455fccc6b7ede701ed1c8f67f816783ef1dbe79cb7837f26a8e1e1874db49b2f1a2e6f91b9d1cc157e7f170e48b7548a41f48c0ef6e5aa684527fd07d0b9d924f8f4465c792372181170b78f19298617097ce61dad8dcfbc56610f8a504233b48660bbcb216af3909c90d600d797e61aa1577f049a99aed19b7765240adbf02601e5b7293f79f245945667430e38f6aae2d52eedbac30dbe0c636d1c085f7f441e3d3e682cb2ec8f0e6cb9a041c47192e05c4784f2bb66bdb8c2b01589ea2e5bcea3846c31c0efe243116c5f6034fbf8f63f81aa1fce9e7d4fe053c2ab1f173e0c5d8e9a658b18452def898f1e8e42b9b72eef235ac720464001041b5efcb412687097f90a05af1487729a65b01ea378c1a1d3f2491cffc415f08adb4675fdac2158586d426383277751304d0fd1bdc3b67b1cada0760e9bd3f23cfa08d1b697ce87f184898f5e8f5d517175f55e84048a0a92fe4510c7c2c58eacfdfd24343d41d0222fbccb8aa486b50eaa186e3188630763f3ce85a011a2a82b017689cc1bd398edc8a0dbb39003079d04bf4fc6578f092e874c4f422ca86e05aafcc7fbbac92f7ab4a21d2068140d340c962cd1d9e2881ae4a63869c21db3f756827aadc8a9588ed7ea15e5adf27dad2ef5b62faee74c38a79dbd0b00da2815c6abf80f085e599b006282e844bf9dd9590edac10441cdf14852d16de303aa80122b7f4b30e47d130b9a64a85f0a043451d0cd9ada38087c45bdfcd0d10a9cd36d9699274d39dce4fb1a1893f2773dac360002444f935fc1d1eafd04dd195439628e12714572afe8e0092c618d46d111fd041c4e79dc06dcbd3280f9c072b11255936aeb3aba98658271b2c8ffb95abe207f9067c098e54e909ced7649b0a09566da8d25234cc62b8b18e63f987507aab97022697461c51ed9aa9aac116743aaa6918e323d3fb0a2cbde273183b50c9615488c393b3d2537d3960cde79f671a2f1f976b921697e346f72d72da3335a3b36d221fa6acbace7c7d2a95cfb22ade9eb4c5ecece4e49d7317a59b9243dd07ac82547e6403cc46593fdd438428a97704fe54d9211dfb873499bb2359aba3235440f41f4d6ffcda65867fca257ba6e03a82d70b39a93ca2174b4748023e90996ea182381a66113d05c652dfb4dd92f1ef919926f73312061f9d6bd08521786ab0833665b380e7f8c3f03c143ae1fb95c685159542101dcc32f765da5c39c69b203bdf0ae8ec08b895603ba81b1ac14086de178c54d0e6481baac4690e7c7984161508db68df8799a6313dd6b99d6314805ba0ee45064483bfd570f7d469a1672363452b10114e8c114a7be108669523960a495c3304b5616d087566bcb4b0477335c277c6bbab0a1e472f3dfd9c64a8d6123855316ee37d04640f55175692692e5fa71dcac62177609e5e8a49fc81074ec5caa48a57fb34f545e9dcfbd21361c125fd3e97910b71531fc966c424e14620f78d5476d499a0323f61b702de123260c323fd9e5e3fd4d9f524042eee826525ef2637824da252dd2191d9d5ed56c734f08b15d7dd0cb7b78648252ce335ac1fd8ed81f7657332a18f418214a936f5279622a3b3a6d0af6882f836f388f383b2fd0cfed48bb3ff84b52ac5af4528462a69bd3150798587f98981984d1e756e2da9a35c54a857009a579a20019ce93c94c4bb2d8179bab98af164bfa690dcbd647910a7aac707a62a997f45cbfb9b6d6aa532f6b7584e9abb00cef22f05051160dc72b5262fa8bedd39f88680846a84b0cffa5e4157b1f634b6c7b4c104c68fb12c38f561f493ad3bbbdd71e149f47b816455830e62753ce7b511132dd3625bcc4a49798115f4df692cf7ac08d77509118d466f5173995f9ccd713ebb79780a2a62549e5fbfda3482cb0944c2ccca5d7b2e34d652acb49b1017506079ac43dd7f1000d23eff1c54dcd4e82b0470843ef6b771d915d22fd57ed03116c0bfa2501c3340e0d76c5f00540410167b0a8405930c7196bd0e3beed14949ef685854d6530dffba8573e359f414b19b8df3fdc7ddd75f3bfa0853ba0713d8f352ad396d8ce6cb55e5909fcc50e47fe70c33d1dac1e3a6300d48efbfd2b39052c985ac3196601b8f7e2286de1c6e924b627ac5e443771218d6222c119200d4037a3f660f80321db39db7a5dc4fcca8d3a39b50a9e4acf105c225f2b3abecc7c5e49de8bf2b88c8728df035dbc5b53ac964890e0ecdc60b0523cc20740214c89704ec7dd5fd4a9c82d6429761836457a8e2229ace2ea176ab46b0902cbd1b62fb22636fdf0c089790049bbc86fbacf292311957803e280c73e0c37ed377e8b9b71fe9aad6686618af90220dc5cbc2e278dffc196b333b21b839f6d1183aae5e7aaf107b1e4ec16bc5cde185e1f19b7ce320f6b4f7bac7104662d1ef365d0dd246f66de08fcebf2d22752c4cf212c376d8ece6f37935b184b73319aa848b7b026db4eee52ba95be0fff977c8438eed59693b905626bf53d1af04ca0f02c18616cbb3f35df2f5faac4e81e25f4b8892639341f00e8b63cf51c23e02d198c539a450bb6668a9fe45fccb4d288830b0a94ecdc7d377ef9d038e1478669e8536faf1087ba743176c1076f1fe4fa90af142ad01cda8e8449281db79ed794655be62724dd047a660d0bed0c4e7d455f11162e9793e243f2a551307e4ea2c32436abb1fe07e37a6cdcc4b4dc1dd67d8aacb31cc219f71875aaf40c8ff8e20aca94e7323182babdce2094e8ccf155f318e6fb8b52429a7d756bcc323d313763c6808d74add27ce095ca1c39f805bc7c465333d59a31ed409c69ea94d518220dc88be06452d3a1d0eb2a3f92c32eb6c00f63483f3fcbe5e5c05ffceddf366f36f54ba6b8c487d7d2577c416fdae7c493cd51321dbe8e4b911bd67dff83ffd7cffe8c2e7defab85cb6c95a3972a66ee151a7f6f5145d33b8e392f2de6abf6f42485f2eaad10adca3554b1817b4fa293f449280e90e43e125fba167214451c536881cf7e5f2be426d99a38fdb968ccfcdc304fc6bd76bcec167421177f64a436a1db03bf6547056a80c65d3d7c1f0ab926431a8936d9ba33d4ea5a997bec87fa93531d120a2318908fe368f5b9f1e13913dd619e5f33cb9a9e3bb138c8cc56a47f10c6baecf8bbf25ca53325d30f4516a535ee1bfcf54f73d5172f66f3a385a8787a2b4af923ea2125ab311585c33fd27545de1e296fae188f07b41294de76e3e24dfc5e52235d59c9f2c1cd6d8696813efc5977483ff103b877e02fceff507ecf85a8928d3f7d496e5fc37a70958da547388475af3a25ea87cc9a2ba18b04bae5563a59b63096687b13e13223fc4fdfb435957e47f34520a49f138620bc0e5257567e611546e398a8c86ef7d0dda203660301918526945475a9fa020af2f2e04f94c6ce0114d053581e0fa5d05afa3655cbae074d561aea989ea778b374315fb629cc96940cd1049ac4f17cd354f237e9ad58867307e2f9387258f784f85a679a05063b677e19ed4bc8a27dd47db72cca1f62576ed229ad746711283c4b08282e367bb19eb063ff4ae341f205f30897893dae573db996da490dd30b08d402e0f65d6a7299107899f93d4645e5f0611584a973867438d121e46098ef218590913444cd8758fc4bd84b2f1b3615ffd68cb5fae6043d9c1a6e1a9a0dc612a10d854c31fbc2811fabd5f9be8aeb04f82d26ca84c749237b56e234c187623c0d39fc1507d038ace0f158a22dcd7b917c4b98f3b78a5672c14f34763d287836322f591263e9c9db7d1a3db5d0afb65eb3ff9715c45db773e568a07e87612fb4e69f9fc9c9b21bd283eec46d1e64c21d755f97f8814b1597e935552f31cb8079d6b122d70e468ef6eee539694f4bef64bc1aabd71c7b0d46dd1e5ec7d77da3a8e687be213f6dbbc5c30781c8568b6e5df6db422b07f1b78296c4515eb9cdc6b6eeb91b81e290137521d2509c99f2fe7cfc454768e8f277ed084ab8b67f413b3dce44e89c6cbe4fe4cf905c8d0ef554587ce8cda4f64b3ce67ef9b64890d162dae6cd837b612233d85c0c3e05aab8ba86b42f12a394000df423f2ab1926456abe76901ed3979662eef8a491efa14161907eea92c2b3aa07a3eac79a74e02e029db11da32a10667f5b124bf8480880f160d18a7c9536d6c2163d295b593fde9b07b639b3ff5fe166700b79a030c81e96a77406425c1e6c2246837244ff4f58c9bd229f814ac11095e48cb858cdafb73c3e209eade1065c4dbaa5c783d6421aeb479056fcd49aa86a90abdd0671fb6f58c82e79cc24cf045d94c68adde98f7fc007f833351a1da05392ae0a03f39daf5fa743537ef40c9333e3181d6ffa752948a67875c0b742b243c212c4b73a4d615acb38f7b6c6f1493ed4901a8834385ca0841974657b5416e1699c8998835b9be38a31e7025a1fc499c6492b8719acd58df3676ba506d4aab2f74b4f9d7feea75688fa167ee93da075cba1dc2a364cc8ee2d999b4e7f361add30c0fe18917b10bf7885a1b54b0ba5bafdbfefd25d5b926bbe812a8403b2582f565b9943fdc2bd899bc13ed79b5004fc2647839eb45da5e1d1ec5dc9e21f13c1315651998249bbe35f509319a587bc9eb8d7f31a2d911cfdc47accb60a30228fe5438766e13e11fb30499a3847ae982b966547cb34462f384dfea19f4869b7e2039e13bc0e43e9e82fc75a39079300c27b513483f8f6c68816e716a6b418e77d3b6c85c68bd99dbf0b2feb67d2b321a339b09c664e3cf1fe48efa9366b3bca642d61a2c2865d1e6e2ed686da98678af1d176e73e5f0c8b4086c5f9b774fd1df9b66f05642b6c52e8371b4e8d37bc0638d4d9d401e46d3227f4efc2f18f999885be18813244f76ad266f4c7b301a7c6545534a4c395695fd248911c74812137339920dd1dcdd70e9a8f283be764c7ba4893e4e1ecb450f60f40948b3b1ff471bafdbc37baa5d2c371503b8e564940b29836f0e3d5fcda8ab3d0b327474c7304d2a93d1675b11a8a4239ff86f33be84deb9dbd05d4be1c03fbd7b0b9f0faa1611748f1f27b9a2427f6e28e927d38a08123cb07f9da9e61d034f2e80c0dc928a7a43579750ea625335cfba0a4b42158e2e0554c7c149377b6d9bd8e5a8d97616a6fbd5415d91a99234fa57eba09fc0f56556fbbd96e51e78b3478364fb3c30efbcb3c8997e4707343b567106b27ac3de426860fe019766e507893b243ff69a00964dfca665c07620521dc9d8505d4ecff138a6632de89c391f1297277ac35bfe7a46093ca47eec4b5704d83da27a61e1738856dc986c931bb64d649db3362284f96bd6eccf30fcff277160b44d2ed36b4c93876ae18ef68f171881d670c26f0242ba67b6f5c1bc15086a10bd393fbf293a92fc9c21bf19f34120aaca4f30cc620ff7b54575b490e86565a69279d16b74e9c06b544ecef76499253ad32164bee26597ac7a2872f432767485854cd5b8da0cc31ef171d36223392f83cde41cf4f17c5c2603af559fc7eb3b3b7437bba67aadd84e3e87bb12e0a6e01b976124a7f47cae1a44a39caf98fbee6564049b1476026ba4ec05cbc037469b80c4e0c1a493d782cbca85463d52b209838516a0417ad65a7d7763c545f7f875718a144d5f36eb3f860f4e108a1bd2fb52f92ca712d0de457e8274ccc19f07ea43983b664353aac91eb03505c999e642ff243cf7358a42c0de098d14d1ed0c373b6095c1d63cb7faab1e7e16fdd690f8d729f228e3963ea3c4e56ee965fc367df2f9a4e2954204720b62148c9c53b8d278932c41cc47639706a8cb2927224ad5ad931d9ac180ec83fb61bc92d009c87c3b57e888cd911a6ce9c9e2b0516d928cc8c8c3f50f4df5e5c8f8435bcafdb616b8ba0415aafcca06ada611fe292f3cc2c86fb72f927924264efb0c3b2b0edff8fde22e8e5b75b17884712bf4621101aa3b7c35657535ae1e746ad0345f908210ca67a602d25ddc0498d2cf6db8cd2d7595546f0a6868c64453786ec5f81041482a1895e7d9581dd1b15c7ac96c8cf7f003041159eda97504f149e885ed6ff524a39d5924e5f19c61410f962ee290f92fcbf6b9a7690b3f766d9bde60fd4e84e39cf1707400c8c87e8d52b781fa76f0281b26f417fd61a298aa861617144d0de453e864650225dc0d26747917a53e59499212afd9fc1f738c33b3823f00e0f2565107d03207c01696582bbeaba648b6bb3f75bbfe193a69998f249ec14ed125e77a5f5a74d6c91c0c80daabea3fa9e15135592563f1848a9b7fe93429af8811a615422cc04778cbdb1246e54079be3dca8e3553c57553769366af300656ccfe50a76da4618b59d1e7bb46bd653b9a8da393e4319911e3e83f2a952313eb29a47d406ee584e3acc77ff6bdcbd0b37a8bb24c7f8d32ccdf3f379098fa02a0e07cf9437546a04b3569ddb57d5940f3d31b2ddefac5a66a36a80c946fa3fea5341c3ef9e8b9d279729015c056bf12481d0c03ada21a481a8cc474bf252788158391faa385e0eed8154f81154e98fd6ea4f8bdcb5a549cc4369bb720f93ca759f1e2b8d53a688afb03571bb170d8386a7d975fcd243f7d390e443892283379d122d56864419b20fa49909d16ca38d1b678f7da82a1edfea821d8f3bb63acd6695839a6df352420b8c3e8281e08b8b2a7929fb0a1b109f8c79695753e284fc9a059083e0991947c52a711fe31a3080e17bd2bf87c15c106ee59722a721203b9f7f9141871ce143ca2d3785fa31ce33d984cf852084ad0cbf92a7473d69714a10e2ed550f0ed04147700eb8960a4e33220ccbecf665ea820086b865bc866376099fe83307235eeed3aa58169b6eeb6d600e89800861cb7c37d1fad0e9ee6d21da0a9b73561ed2ff875fabfcf5368b8baf78233b8f6be853b9540a62fd871a169b26543445e970d5b979f6d0cabe3588a47e20aa63f2c6e3d06e8f7a4f4f8b8de644b6cb19684298e1af9d920bb0dfc7844daeff1d427f2bba11ee7d4093e49ea86a34632eda6b2784a21d628fa5c9009b118b7d3a48f723247b204a733d367482af944e402e01fee6d5b89b1f4b755ad425a46763bab18d10afe774245759ffa3167b9c241088a5cb44f5dfd0a06a5c5eaf2392703e6c82e036c75fcb7a8ab26103c6efebebd9cc7f05370875007160cf568fc7db9a565f9248882b725be321ca95aa79d9b0518f2f2b19e55503a6a03179350d48e96270792c70477e33bae5ae47a2f54d0794c79247c92987cc173e91713b919193ceca329779449499ad7add391b6fa8ba75bf68ddce35d3a96d5f36cda2e411dda272457c7024bbb29c806fa0cb0b98f4630ad2a524fed0698ec30da7c6a63249678b8c42a801f04af9f4f7e9e8f8d5845dc4ca267dc32b1464917155cdc0edd3330f78ba0a5bcb559fede670d524d7176ee74284df480988989df7a4c4953f3fb6770bb1db494850af2b1aa607b2da42311620069251c0b6f6cfe288dc85a28e3a32daf49d9e3dadc283c8b7cd40a740aa6215f3f27f5ecef593ffb4fa50ce3d53c882bea7182ac48720a721ed1797f435953a2c372fbdcca261eb47bc7989197099d1a45b826a3ae094e47f4e512f18a6fb48335edac9c544a328936c8e9434b9fe843608e7637f0565d46c848a67820aa4fe4c73d6fbf10682923fd5c51647fcc4c5db772fb83c85db371c1fe9248e9f8f26693c812ef32896091cc3f4a65e3c909bfd43194707e07b3be42505c043ea199694e6b49b5a1a51e94d09b1563069cbe86b4bd79b088c0b6bf7779396e50c013845b3ea95dc28ed7993bb6696f1ebf947048cd40569b9d2a7adbdcb4967535c64a1bfcaa12115c56b81c0247a7f86a33b4d3f44799c774b1152db66946759b2e47cf392d81611f79cd0b887bdbb00d458723f9f3f9817fda6e29bdc62dea3072d4d7d30478b6a1a7116e62656a3a86f6631b79816071d12b4a2ee22a6c3fb5664ffb5418402e8e715abc190388f0a4484ccc936e8e2a9954cfd731448c9f5ba661ea707283acc03e04447ccdc4108280332ff1300bf8a2c64da5170fa6cb8e961302b8679bcf0f1f5fb01363875ba93517077bf775bbacfe35c3f0c46779abb2a07776af28b857804c8a9b94920ddef6e9a460b127ecb2a4339812755bbca0def867aba2599142408c239a2574ddad6ff87be23dc103f9492088aa399cf8f2bda6226226a06f50294b1e5eac7431f53ac79578e5e032626453ef1b08b4e04810ee66535055a7677544ece949fb2b776792b724b0fc54a15ab4506680e39b031bc7fdd553c721d37cabbc568e90057b111fa45ee3af84d96cc480ffe19f13ab2747b06d3de822f5d44e619fea33f93249c07d81062a731cfb03bcf552e3bcd1d84b1554cdcf0bb93862d45f3826ce7740f2d3afc2dfa4e20282b45dbea2939db9c35707a320f4b2727bbfc271cbf94911750ad6e561241a58e8ab2fcde27ca1adf2c9b3e987852b30a59956a00d9e53ec91739b9362ff9e52438c92c43e1dee1532e605749d3bbc521cf9e7570402f6cd22334500d04380ef7483192405f6d9e783f78025ce4611680d18652c267b2749780432fcf8f4bd91218cfdb78b8165bb3d545566fc2181a137a9c50a6f1720b915113eaa922de520b9a3fc273bf115b9ef472584cb46a908e9a351d3f5b12b52a9de127d5387522657bc8084c86ffefcfcc79528505f2e40ef31f56ad5edd954375b057a55b01de39afdd06e0c944c3efbf5fc5601d4cb4180076c7f6e8d3d3f2a0e6bb62de6409a336b004fb62809f030017e442ea59e7a3a0030673fa5dc6fef4cabad4a78e7cc5258e426879526d002f8f8b01856558ee46f22ebdd4a05887f1e06a3a72171346e16e663badad30144b34307aecefb36f79ed810ba25dbd08f28d9296447070ee34a59f846c4fbb7135f0917b23283ab956ed4185e0870f442985f0165f91f40b913b52222932af03d8403c559dfc114d2c62102850f20c48fac906c7862e31e397f7ca279cc5ff15dbdd7205b52a35af25c2b749e3c1eca60d1db416448a1a3b704e0c372455435aa9dca7bfca225be8e8fef8d5333371707df3045612a35c22d2e46a2321a8720c1de0edd0a6723e425f32a23118bdcb994ecdfdd7f5593ba9a9880596e4692fd25c9d663b2566c07c111e2a7bd1e3b2dc432b029ab0a007fafc634466e8c89053213f23d5882b4ae88386cb62ac534f8a89bdd3ad5adb20e2ff84427bfd5532363f1a17a98743205681be0d9c0531e8d32e3447a371ac586b6d4b062ad5c35bf8c9483affe88288e66be85ffe1f4cd0fb76699e16a5e81016097ffe3e2e705378c16ae41d1c9d69838f231acaff525aa778acaf7497ad452bf8f71b021965d9bd2d08955c84276e48a2004c29f1a23b99df09dc13cd2d23ba2191c348119b4e6ab3ff78ce52e8969f2c295995262e641690e68188512d47f87231ca455bad4f2bb7d24f02c4797b97cea6c957cb4dba04fbd3216c9bd601a62f143cc9d2013d3c433e821914e78418eb268f3f14505b68883c30d63b2bf02de6c88bc1c594e0a9b2a3c7ae377dff018bd15c77a1ab2778e12a2dee5f9e6b4ef4292431e201e979dbb5cda1012481139caf5b7ad76a9ec21884c4d68bb1eff1310d1ce181dec7bafc07041f20d438585c37e84222cf874ffb457f28a3612f054735543b063289861d75625987ac73b8b64a35ddc3847eba89472c3b1e89384a27381308d317fe2454f2d8a37939a1cb3be4a3e12ff237e7769cc56fa208fbc5df576d699191dca12fc6bdd97c527f6457e382712aedcdb095fb554d77000e59d64c87c0ed2e37387843b1b9dc319ee8f1246a2388bc3e4504b56d3ba7d44fe39d940b4012848d7405ef614620316ddaccd51b4c4a3aaf80de424397be352f5d6460427ed9145d09e878928b22510104d85d34f5f5a5637a4f4a39105ae580edf1b025665a62f4d4b5eed2296fe57daa470bc1d5d25b2cbf0046d05c670177385b40660eeb0b0276fbf0e7e97acfe93333434a05ad6ba87ec41620614817c58d42df88e97321bb265479f861512033497e2f256b2f1d874a7338f9625f1cfc212737f1f0599ea363c4580a208d7e53c1c25cdd114a434313f3b8e1bb85851a28fbdbb0d62c3703ee8b1edfc23c1f3af1e61bcb12db1d56a7cc5085b4ddb0dc8dc1040cf4382169f774a2a4d87e65af155f74e6b5ca83e819587fac96b3d14b3c6096db002ef3fd4c1ae4b751475936bdea9efc511319c4a4443f0bb6fc05f0e86be05e407cfe9210f89a1700cfc18ffae7a5602581fccf1e85840aef16043e1e7c2c97bffabad51e647ea97cbc4e04d4615ecb873dcc9d75998a5750215f867241d29d08b550fe2f6162c2185751dc826265fdb8a2c71084c941b83c8f889f9297b1ab7d0f20da8884c05b16b99966a86e94e97d67a5d3f4c8bb4e8c2e43596ce3ca10c6b1a777aebdf6b17444694ec5c34861e8e3b4966525ae881eac75a211e5fa4da01ebd0a84b0b6df9f34baed050388356d877b2634de5ad775fb25ae2e5ee18c09b519f76b87655c2d87db5f6c38d99da5c3c11a058a6eae0792e9c292c073b60f6b9eef9828a9ccd25ee9f8cd735d0821fc3be5d433587f053e8d8d90b7dfb98c388fee5fc205b5ff902950109b902903964f7c7bc9b007051a8be467af736cd22920e81f9ded860f204e09c55826f70b755f5360493012faa0e2bcade9f2f47c244db2379646c5bbc5141b7e7936b7a2b8e4af42851ab926be4f11653b660eeedc19e418cea69c872ef88229ba576e7fa7206cf4633520806b48a3b2e821b2cca66fedba91880a67a28f9cbc5d8ca44690e4babb1247618fefcd8f4b7f7b9fec21e2ad26dcb7754b284c8a99aef3db4a148e1a9d5be31092276e47152de507994f8d495deae6e215234d04fdccde68949cc19f1d85b273e32f7ac433b6ad721d2cf203821cc31cfde13a632e29d1dc44f5376b6ebd18bb1cba2c5022cd7b8e7532dadca62e8ad92b9d0d1addf3deb46d9e9d8deea6ab5ef1284c9d7a5b3157923a121a123b0aef33d988aa4cee22d84104154753672458ea528597a31496288d59df88b714887b7acdb2d9d6509d541baf5a0cc0b33896c087dcf4127902cfb25149621a8ec97c51354decd55cb6b36be6c08b4179041338355ebfe6f7892d36badbeb79178443ecee174a5d85d59f2651e4a0a574023cccd99468aedbf59d9714aef42f6241b22e7ea2b6cd4ea9055d11e34fa514454d84259872b9c6ed5b523ceccdfc49662f56cd5ecfb130c2e6efe4f7e66520abbff009bf0ed34190479b661d5cd2a0b6bcc22fbd6e55bc16e64f941ea4b996946b2002609b6a7c08d496a4e665d81922d698e064d779dcb32df353a6cc36cf692e766e5dc961b799b72b5b6f20fc6046bff182986e9d7342e372970beeee248e73a826c67edc2231ccaa2923cc2555449e158f20e9734c622c93c663379df2eac9ca6ac7c1cf0cce5249b87d6b6c8244456ed5d6a6ef66e52a3b6cc1b65d09291d441a74bb54c807f3b7a53ac5b5e2fa6b960b2b089ee2a0da020d0469cb238edd1012ae57cd6b7fdd2f91eb50209b91eb0903058f8b6a5a7511eff5849a1a458343d11b533497d0a7f4c44c28bc4c2f0e815c949716f410763c2235b5729234960e864184bb180d8bf3f05153550186eaf43717771c6bec96b00ae3772bad2ee6b3759b1b2e057d95aa5cd32602aaad2c210e13652aaf55c802a70c479ca70b5584c8531e8a18dccbaec6733477c4ef021c325a876252ac3247205ab500c75e833fe15ba417416a8c91f5bf36a91a2913459d1602c8d5de7f547b3a6647b2d9dfa9a8bcb7056c9f109b0ddbff856417982f65124471854135dbf1360250ed2eed8359326e70b570caa5078f0db7013887ab3a341f231115ad766e23dad6e88ac8e67a95ee5ab70bee159ee5cdd703dadc3d113c6b7ff70f37437d9aa74d21c4ebd8741390abf9148ed2335a4ec6338d6007c28258b986ed7d4f0c3466a72a06561c89fbfb266a967b08e95024ac8dc812aa5805a19551650352b8805b1cb34ecd032e88cbb915d9375279a9da642b5f8c3e5104e395090586ff769d2f8cd3629363b555c4c0108d678b956ccc5fbfa94bac296791a064d79c152868e1521d728520993d481ec0a79fd1b8230016cd7d10b2223d1f31afd0ad3106e79ebe002b3923a73ded717f038fa3b9613f6e01a435437331a45010e844d590d625ed44ad450e5c85d223219abfcea9cf401da4827c752891e4adf99e88a14a7761a6ff860d87b1862cb7563b468e90af112814f5dc3d7c71ba0dd41d5e73791ec1dec84b2c8805f355a433fb1901228503d94e6654dd84bddb377c191e47848b4d345d3554528810c55387e793a5574ea020ae1a70072cbc86fe577d7a8dfc7140a3da607d52399abcd9a990f901ee31b9c3814e2fcb1c87fe8f5a54c9085c097bbae76453233514756b55222fb57a73bd822cd58268c66dddcd802d538c1d73fbaaa7e6af79b59775fd29f45f6809b2fa36baa6f0274b6924dc50c0c46ba9a812938da6fe8b407b1cff16570cbdbc9d40b381c0937c64d8dc6d45f2dabf8cb59a47c859d38b0356961e19b8b5f6827a0357cf32d25ec49f4eff204796ed527c449fb54e12bf5635320e5c6b5c011c0b9c5dc463aae95734d2d9fcf9a4c5e8beb364be2711695ce2d5aaa58ae5276e822adf13c0cc9f50b3289fdd07877fd8d7a837d5276269a6bb877625dc7ca773af7a7068b688992bae25de146dc7f60e5fd8b5f153c44d7eb4c88b8c5ebddcc48f0f107baf0024fd73c2c651d608e7b80fbe3720d10488e24eb560de1774a4b75512e20ce1671db451bfb9b36c19a075cecea381c1df58566f118ea3e3b98691f62707a09f1a7822ad664b8f3d4b242572c9269418f922e5bed2f814d827d36195e440b101ebdf082e80922c96d115fadee7232bfd37be3912429d52811583d4e58049003c8d60a0d2b592d98b4b6475897252279fbf053a130be68a626ed9fd3dd6860f593fb96dd6bf48d3036062db80e87bf34bc2d20f6315f9fd501a6f5aef74dcde7a9cf5708b8e6e9fa55529fb2de2b166f8e3c3b5e0bf062056cf00770a10effdf6301ea1d30e46258db69a5a415e862b283c1a0f691521dbcf1caf9c3a04189fc72b0c1a23ec00c2637ba71d7c5380e6b0e6ca1ed806ba2ba50ec2d7fcf4aea78a1baa221072b81a9ada71b17c32c6c1c3936726b5283c39278a63c3bc10e652a38875e483326bcfdafa13e5a626daf3a67132f55bdff2c156a620db84a0f2a304d5c21add51454844d7a3d0aefab41e29dddd8c3ab7bc7025fe6f8341e0527e27b3b3d5f310036cedb870c0c6c2c39a738bf9747beb97e69ca6ab4d97fad987c4a736daa7065b6ae9a3cecefed52230254e132958196b9de51a6b4061fd1a31250f83787aed1dd51ab104ce7c48502ab64ecd791aaac73b0f510d473329f0839ac92a18100fad3405bd16cc99ea9c0104c41d505e00946189d1f293d30d8a2263f1c06bfea277b2480d2e3e4fdf63ac2847e7c7591f362f71c818f650f8a473d9230b346d558e770c330915e202baeef94cc7d72f3f937a3fce974c58fb817c6701db67181fe71ebffa247525b281d3b62788b77a4f019f2492d6d115905cb6ac45a016b1b0e3410ff2ca05380baf0b35f5d10e2b288c63e5e8271b5eddac1fb6af394485b77f99c37871b1ee96fe5182f2b3a366a4f657ea03588fec0fc1d643d511db766289a92697bb8fd403bb47e91c93e4627b9e12ce5e44ed8893993c06da7e903ef6f4d1740091eeb5a1c93a6aedc95aa31baa01a8aaf428a0bc48eb13665eb9316f87ed1bcccfb111e893d7f066f4a491bdfcf37f70969343ccfe7203388407c5e298a94e5c0503d5d79596983c981ba54863687b56e43446e162d20c6d7a6b180c573086edba64ec4989ee946c36c902129c6cf1314ff6d3c075c722411a2cc68ad7b1dbe9b568ed4795c9aa078650b83af588f87414fc12896c9e4e56fb2bf2b9b879cc624eebec79651d1a643d1b6e262663eaa14308abac48af1dee99cad090e08a52b5f6ea283b7503bc7dbc012cc2a7acbc34fd6b1e919bf10e9a352d09a31c2d8c7f9758a921564217dd69d9a0c185baf622f7cd2719468d930ca1294800e4e1fc9c323e1894c0a22120eff9b9fde6dc98800f4987bd825915749ee69bf8b41d94c9b5b6dc987d213f7f347bc2ffe0584f44adbaf2058890f98428ebdd41a0b1f5cfe45dbcab4eac821e348f63e8dfe4070009ff806b0c399eec98bf32144276ef365954742bf8c77981d3c8410b9f620224d77594bf7923192fd3904dc1cc64546a786cdba2c5b6c802833d18a34a41375db39930f04ef4c23ff303030a4ba4d140527a7c52789d2c45b4b0d8b3d0ec1f525d4637d5dd00e3526159a2375156d8e5b3bcc01ee3ffa1246ebd7e5e0cba6412d689fc488304590f17c1f5091748e02a1e4bf97b2efa2caa6b5c971ca2da44e6c72106d80f3d0ebf23b118eb703415f66cdc9967d4670dd026c4c714821bde5b2f9ceea66fdb13a508939b12fc9af0d4bcbdd1f1d8eaffebc16c9b6d357a34549302205efb3a65a69babfe1da8138093dffe8f9dc6d41a89ae4ab22b0db9ab135af4a16723b3b67280a9dd8d0c42370b6932f1aba6f0f81f0ae0458d22f28cd5d647b98ca33aea2031cd1a431ad1510974907c85338a36ac697e84e9b2fdb21015f394f60acbedf92763721e44812e1de4ab0e27240545e9266ed4345aa924687ea6ec86d029932b8a5d8005729214ce10fa503cbc6fd5e42e281a7f8180cc5c739c77f1ba656a310d03507fe6f7d015bfff68d7a2e1f999da67f3b8b29fa28e93f890ada666bc38df1988a1371e00f3b39cf1b6574b427cb3b5244b0ec95b9cb037bb20013ed27c930c9c326ded8be8b70997e703dbe5b54d43df91e4aa2f3bb9cbd25018ba624d782e8be027096c00a0ea301ce3895810addcb8a0d080a1dd17af766d25de5c288ff36c9ed80be6adf27acb9bb393916fe737a92f22de3a125347be2f82afcecb5946ec20e1c2af1e9a19d135a837a2cfd44a8b6db066aa25224dd8cd56baf2b23e69a9a95e64378cc05059ff8c744547a5b2351f0917e33ba0b2008324a76cc2866b0c6fe338871315b908c2c39c916f9a078e662c43052e34171adc8056d0e11b8268cb90f21ecd1a83a928e41a070b6e7e1be0acc2698639781a779bfaadabbe0e30e7202a75ea5583b1d493764a0b82ced7b46a0f90062393914505982f97e19695badd43835a030f56b5fabad06e78038342b8d9ef8b41d2565144f9c5f1dd633de1529087e382341c29a55cf0f9ca5b34b37767754ca0dad4726866b1375007fb14ec62dd8df900672fabe1c2f259896a98fd98619633687df9c1a2d665646f109c5bc1843a41284e93a95c3161d2e979d3c535f7324de7c7845b9ea2f1aab015729b4942cdb03f29b34c96344eee279f54fa4e7627ce5b9d68cd5334b43e5b03144476f2d668dec4f4d0fe3b33598ee1d12b3f9d66542286543f374dc7bbc84c9425e03962656b8806ba83e6068767426b35513685618c7b0c37b4e40c911c2713a84b7381c1f4fe84fdd44748836f17072a1a3b30eb98b3ed7da30a1211601972bafd0a2d71b606ef9828f893bcdd17eb23123d9c0073fb9dcc6541c25705eba6f82606328bceff34fa9f042ff4772fb19772a801fc6ff4eb0ace9da468133f50f7b9fe48b0299e62f86ff0576ec2466cc7122b7d9f701a0c6abea0bbfa2eebdc43f40d4143e6bbd69fb3f984c7719bdd2d9baa847f54c2c6a0bc6be5175bbe9343d3b0f10106d8b29058800934901f21f407c27641244bdd60599476d0296da87f545842b4d1eedb425ff4bdd9f35761778e3ef11443e5d72d35cf6382ba301f8b159a0f1ec46ad523616342bbe3d9673b8b5b3cb8d5b996602bf713a765e199f8112e8fc86e9ec0c6e8717924e46ee48337fba7f7935783dcfe8c2668b0365613ea538562f5ec15c874109b81ad5b29580a463f7020897fe10c74bd31c26d24fe51324f0d813a488975b5c9334c00288bd74d6c3960f3d22a14bc4c3a779115bfdbb51720d146bf00d0a6bfad5477cd6a102fb68288d31822664a6bff9bf157d5bb3670ca383c1b6d89cececc83d4ab855c08151b0b73a13f68ab3bb93c2bbf0e8f5582ce871421ebe4c1673b3642733448b9652cdf30717d5bc85aa2c9efb398a10bc6c1fa0c7ef080f74d386eaa6b5d9d724cd056e14d9e5d68942a7462bb22ef1e01bab615ddfbfd4f1404628e3cfc3fa7d03c0d1348cc51882680af350bca09944313fd4b52e01b703f50be24577dc72387aa503cd60bfcfc05c635b29e2e7a3498b2f8af36b9616d96711c0b916126456ff331b9211fd37b2f01c7b7e502ad81f6311fbd31fe659c33f6aabc33bd2cc01d41f1380886cdf41c471ae1d74175e8a52524a79b82b84ebfed3356fed5166662345dfae4d4a345606b1d005423c62c89f7473144cb016f24c9545b90954e461069703f84e19ff49a679ef9cdd1fc539274d1153b546a2925dff9b596e0e3ac9534f5ee1fd41f58a4f988a10f5dc5d7b94a78f82bb7e03fa49bfeb72e70a816211cf70ee0e9c1ba56bdc0f69462a1a7e3ea2efb36bb0320c93133b312b5d4360b2b91ec00b2f423c6aaba06becef4b6a3d8ef04867e9e8e72bd85c38ab2d0c3dbe73ae33a9cad6f926873c0f0edce80ed6a492f29322ba82e2e8caa05ef8cc9c0ff69d4bddef14e40c465450056092ce5280db96fcdb2ba9c55ecfe7ccad1d9e273fcf7dcab736301e706131a66d715d9e910643fdd145990ee05e789ca429f02d6aa93169eb6bd6d564bc54ae99fe8d313ef540f835af56c07f7aa582f02f4a382c00b60617cf15acb3129cafb0eed398cfa210d15a0e7fa81ffe385a8ee38fa477ec89b9720db85ce92f415610f2ab750e7085fe1b9a700b778cfe8cf49ed82a294a771b13eec4078cd9c1a27bb3719c52091a09c08b78a8264ef51d762e90dee658577365bed57bd22f88941d3974b1e68cb10c73537dffb6a7945b230701a7da560b559a60ce82084736e7a2287242adc677ef23d31a31ec4dfa13f396c4c9c1f37883907b089ba1ab6c7e1fc4c6cc7bf9a0653a53d19fc6c14995cb9eaed9ddcddfbf03a5c19bfd742ba56a4dd40924eb8c94b3b59ab77b98718c2185bc36e98d034860ce2060997ef7daa75fc8694fba850d7794eee3d576ef9bae88e8cb28c67890b9f77506b602cf9da692f0398e27d6cd27b8b3620def2a0ea476f52612f7bd92fe9bec4a9ed1f6e906a5b5011d759194a859f115a2c7125d1bcb0d1c49e5999172b53a860279c68af4aafaff124b7eaa43aec2bb4b24763215db9e4b72b665bac2557e6eb6db1f8afe33de55f3fabdbb9be7dec5fe0217dfdb3c536f1eba03332a6ad7214f48376af4f5cc62925786a7fe725c328d803b86bb179bd6f77085f048e6f0e1fd02644267d3e45f1c4517042b0111e1e45970ae3242820baa07b39f48478d2be874010c212b40944ba3a4b2216fa724bd19e00b9913022795528fee668d7f1859057a5d76d535e80dbc8c53f61ca81e4a8ee921cd39ef7229f256c1c1740d6198ebb5116cca419a5ed7849fbc36180264e83c8c44ff0ba73f76040b28fc738cceffc5de64e7734000e385e9de48a78687397cce25b594197dcb9dff5d197f89f31f75e2b9a20e825f6642c83d110966513173968dc4830468cbe2d0c995e7dd53b3477f9162129cb1747e20b7b3bdba0902000aa5d94333e27313245e837b4355866575f74c5ec6316388448cc26a179a53bf907e4c88fb5dfb51e9926563bb6f0d0ed1484b192dea49c3dab97b4fb5fca2ed903788300842779371268fa9f91eaf3071db2fac6b357f564f987fa8d3647797be77aab6f33676ea43f5659a5599044712014540dda5811bd59eb55e31c97fa1738194e2261bf4cfdbd6301e524fb15a0a823eda597dced5c0063684a121199e7ed5bfde56a6cf666fb5db231dcbabeb1ad9f791eb820bc13e95f137ec2c71cd9df8ab9837256f123c1ef1a741b790dea56d2ee1a21e0546a29d5e2257cdcd972b814f47d2e0fc3f2563d559805a70088ed81b38e22a970b411fff8f25088eba02463947086eaa8e795ce18c9cf92990bd66bebb6369ef10e7a76be2715db8bc51f6acf03f73abe672aa2fb1b542844689f0321dc4e19b82e048b32f93f3c0665bb02fe3f212cc6cf2615e8fce08d9af83868a04893d6bd9eea1e9d8ffb199b43bf5dcf99d15d4cffaf87660ca9cf5cfdf28cb104dd46a1d192e5c9a58a58a0dcdb86bf488773bb356a9ad489c645dde579e040d4332b67c74cc845811c5b78dca1c3b4ea49069037d1dce5379664a344129bac6dadd6c0881260492f0943c67600c05f8f100695f6232a2df19e6ed14e5ec73d42b525d1ffd8a0c312d3e897a1281e253fb4eda931a8f197b6270d6cc45c4a854a10b523073d72fac8b041bf12daca37cc417cc4122075283b8e23507b4f165296385c4b2a9a1999b559be93cf12139a094567cd0f9c3f8f8d1bd3d80a5d1b8a5bc82ba5103604da45fdc17decd82dd0130adb74215a75680cccac217d892c68e57612fa37e9f262c48be1c2132cc6cef67254ce15daed444253e9f6d1428f356e385d554597a3dd8fcca59e2c34d85fed9ada01244fa12833a96e17f7ce97f233b8d22e974cbdcaa5cfefdeb677ae690c7ed07b0adedc094a3c245840bbbe73f38f02b638b7cdd0368afd858089c35cd4013adc947b2c1278435c71ffeb7357780def079fcca989ac45ce28515afe8e155f97e3c08c219b040a311bc86afd8b0ff97d4ce5e795b6c9de9d6103314bcd64fbd1cdf74a6dc89d2cbc558409e7043f61953fbe22643f09364cf3bf7d2ce608c5ce771ca1c32e3414e1db350767b8c7ffeaf03e13441317c47c1e8af2bd1261d2ff74b8fa60c1010e87a51e7489ff566773b17b995eca6bc877581d0c22f43f284ae67289df2d1fcfab8e18f52be5cc01743e87075a943ed5a2eed91727bc1ef3d1f9f8dcd11c5e316d99651e2720914778e1a2afef9d8ae295787dcfc722996a9646fe8b34f57195b9cd74ddb49f64b98124817c303939541507b93f17849fa711fb0f02486750deeb29455eb0b0cb672de2e9b12dac4d2df7e17163dc2284f67d59a960d7e2489edb5f32e45474acb880c2ac7421589fbebcac86bc59d3c76e523ad218c743b25ecc02b2b6d638202a7007f8da470f51ef5762942ce891a610d6ae36e21877a2974d536c537abdaba21db9f7bc9959eda041fe1a29acadf3ca71bb50ef97709c2c491bf4d6f414f7b9001f0d3f58ebc31b5faa4ba6ecfd26c2745249e657cf5a1a8fcd00ab7157a0a7f92ee1dcc1f10dee8a994afe16b211d691b9ffc72162a1434fde68141a2a12ae8573a642aee92e2a2f175fc4bfb927da2f11de97e721aa7deca92057fe207d8b412b31e4e3380c5ecbff60493991361e5d002ee058e0ea4b7a6cbd9543642c44db5c34bce6320f3cc49ebba7bbe747a865a132ca53651a19d413ec22a30fa8f960f80cc5dc5ba502d54dbad9a7515023041d433dd7de9d23cc1e8a5e2be6cc8a670ea0050502fc1f4e0c64149b274de963412900d1a91f18ebea30f5dc1560ef4a64178ce9122e908a532532314884eaaf08863c9083baa711326d7f4be73fb61b32fcd8d961635772504ec39cb5227bbc3652e11ff7c018024dfb19f59bb338dd740ba36f9342493fc850c128af74a8edae460b41d348fea79c350d15a69e89ccbd4166bb70fd75c5ba49aa32f74f3733a312666a6ad57ebc67ba1c0adccf253ba6be820560acfe68c363a31988c2ac85dd75ab00c1a0152fec3845b737953773c12eaf00cc212285121ca9f11045773d06e378fe58e15efd84c1e2d9d5cdd0d7240eeda1b5ae761dc9d99f7684b933507b2354032a30bbb65d25fd042e8b7df7fa2ab9a5006a51cf0b25527055953c91e5021a75239b1a21b1c13554692f117f988d5a22caa864785561c070643a2ab9cbe0bf927b9848a952f511f340fcd40a9a674d75c00b8e7105c8c58e3e9cef9105a161cc1a7b20c55a6c4466ae8cd0d0cd697cecb7a6f0187605307f322de25838b326e1df78c3683e9928c3e951823b6e94922906a999fa52373bbd4197c487a6dfd747882610e86bca4e3e05eab61708b99788d8a47b09dfca2eb2f87f68aa996f82612a84f554c04019a1007418731ae372656fa364410779ffbc0682a188f37c4e3f0a9aac2561307df894a742cb34c07c52bb517714de793a515dd7654cec70f7f39730a9862668e7c5e5adfae479dd3d9467c30b46afd4e75aa42bc208e14a7e90ba837c3ff34805a92bd9b583787cfe2b6a1f05f229ae1d17d849cd76a4acb979b7ea56a45604b08df50a63c447e21e90ca4466c94859e10148824f5af7715534e19ae402ee893c0448c9ebe431811e05c12bca7de9506a523a50523fef94ce453259ce0887bc874f0f719e137b80e1d558509ef16132b5a68d1a620d180c871fefc493f7d3d41b1b5a84945551f03c3cb8d31676a4b72f98d43220dd0c9df72b686a05b9e7c880b7fb1c879fe7bf9bd58ceedd9f8aac284ea915abb69ce73318f896ff954843f6ba54cd2259038b11815c0a6681e878e10ba1ea7ad1a658375778c7efbac6ddd98fa337aaad3b7a08c3bd66cab03f0d7de6c2559cd85dbcf4a37a9e3ac13bd835a18fb8d85e81e2b2c9a1e7ccf9c89218b103124f40c560c7ae0664bf22a5b80d1eb5913bcaa23d981f4f80c2ef6dee0aa678f65dde74126e216567abbf20cde1da660acfc7c4838e7bf1b1d01d18689e88f62d1dddbf6ae0b80f71846dc51016da64631a028168dfcc24b64d34ccf0946618c184450797784e38f20a9c2649a5f1bdeeac7f04b6845cae83be662c2568a2d9acc220bdf1b76e291c21863605a24667343fa9d0a557a0dd162972532d6f269bf2944e1a026ba10fec6a24e37e60be9a286bea06add2095c2af35aba55b5095af5f4e5779acd5ac9ebebb605d50cbca529a93c2a0631f55fea101575f14519d5a2019be84f02de9883636db88dadd64af428b4a250bd75d120dfa8e4774a6821ae39af39b42a0cabda9817f54b2f3f9b0eb4602c504fe255e0b1519f81a377e56d588ec87f1f59dfbe45ac400c5bc0b88b246a2853fe0137fd92388d13072debd45de182f3b51ef10160e51c139429e0142d3ebb15c6fc4dc1551946417ae080fbe5e57e01115c664e229443ce35cc75a509691682241000d9116ecb95efb1ec4a32e76bbe961fb822ccddf89e111cf8493813e25016cb87112e12b24f76f213d6035f3be83367a49d07662d9d6be5441876a8937812e032cd5922406abbbbe2218d6e322aecd949a5612cc0e572b9705e3f6984995d43e058013e6b7dd76565d6282247fee713d85b33531762702bacb11f7be9dc2877324e7e57720f89508107b09e979a18e2e177f83a34e5df2e683381cd72537dbd31ecf6b46269f8e151becff7e01889d8b8c17556559d64e7caac5659987178f489572ec8a29823ff23045e4cd0e5e42ff74073cfa8c5b60511285165d9addddccb695101a3f56c5bcc0563e11a29cc5ae2b68d7ea203dc7a102c6323518ac81713d0254082720ba71f1290b2fe1a9fefb42734a8e87063c07aeb63988df762fa46ccf608b978de830d9e4823e347d97a484b6d5e8ea74c5eacfdc5e6161cf0136addf2e87ff90c568fe94029d53451829f4688ab2660b3287ec10073a94ae97385020adbfe75ebfdf32865d42825438fab9380aa28aafe1ace21a52ef8d8ab87a3c91fe393e95e3155c1a118b93858877352a4a974103128e46aac0eca37686368c930144b06c94691ff5cf877ae5f347a64326ccbd483c6ecd6004a3626c33adf620dd80e713160a03edd6c51218256cbf8020d6dd5c592849fb8a850e7f8578ebab622d3b6d3355310f204708501522ef853783a50b35d6eb6317e32e6359cf1e2bde705c952192d604e4252c0760b6b4d8cb6b6149ef5f39ee3a875c9fb065621cca96524155881a01a423ae4563b14825d003b4173b227af240af7f4959611657e792e08bb8371850299486585ba577b2ef26e1bba3230885400f48bfae720e566909b11380e815b51f7e70dd84235a9ea8bce7f9e79840f64f4d1a6a2797e048f416df24ec8af1e762cf1fddecc7e9d8055fc0fda5b3e70b01e1ae865cd62cc1603aa12d45cdedad08214ba09c72afae13bad7b24023bdbfd7b829c317edb75afd957a7536d05ba4fcf00ad488abeb141868c2b122782d453dc73421cb9fe216fe2816a541b288be73794b5fbe11d9174289988b99d90c50b049f56ee2e0d2dd45d821fffd2e3c04f8e8b0c2cc29fc1aad972fa99e54e9eb52be5bbfce9c06d460ed8b2d68d0aa9aba73a28b4f796be593d4dd442b8566b6644480d8f813795f30afea00e11ae930806dff8208207cc19f61c5ba16e73d185b8746fe2889a2ea247081c55a59ab8cfa81df6022bb62979a49df8efb64defdb9d398c544294a51b5f9542e7f8d0a4b38eca5bbb32578c6f2d223709b22b665713490b92cc32d71189681c8944c66579cf1b9145ef3b6b03fd002ee3f9989cdeb82f528b0ae8974",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x5998204fb9b417b0b3e9873fdb520a4afc66f8ee86a94235775d1fc9c11d649d",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xdf09b32c761620c5be77da398b97a64f03c3980c",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374b70",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xc34e594c77825d2b8a6b9bfdd80ffc37e936f78dbfe05cc471b1cfc15c48809e",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xe4e613ce77200d1e3cd649fdc335f016a6c72419e094fb73c514ea3820e35c87",
|
|
+ "timestamp": "0x6ab8efe6",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-anchor-20401008-baza",
|
|
+ "sursa": "2800-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa0626573752032362e342e302d616572652e312d643230333230312d7774613037f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b841ca69463769c181f5ce21cbeb42962518da4baa54c7aa7c54a5c9f90b2d3fdc160dc28e48aaaf3ef24fe4cf85182d0349d13958934f35b1801026edfafb686b5201b841bf1e4317718add16719484a4bd4d04f003f268b77d6f7cbcd7ab5fd0b8520e8265d7444acf7c430e54ea9f83cd63ad51b1c52250fee5e0fca74feb03e59a45e300b8417b61ca4656a57176601f73ad2be804ed8c57eeb30edee4ccd247f0eb1f5e50695e03134aebd724ada80a7e551469da2ca04c22ab678d9d08360bf533b432e22800b8412607ac5bc349e051ba93921faef540d0d013c0f6099450caa0d1e4d3b1c859be426cf6dcc40179ad1367110454adde41ff2507a5eb9c8814b024f5ff2e5e5fbe00b8413c7479c5c87bcc0dd916ba8957c6c0ee636c0947f36a241bff7b9ee42b3b359338346fdfadf5868f2e0a326a95a0a546c734c305aec204f479d41db76221dbac00b841db759160663fdac76d46e3b42d31d5c3c67ecb51ce5ed3bd79bea13bc2065ce47bff899428cde05278f947b30d44ac9d6692dfd861a50d19871a2e6f9494630d01b84189ac502ebf7ff9ec1ce71e2d1e8fba987c3f5e2101ccd6b9b185fe48137121ab126215338fc410c97f72a022200b100b2c9bec86281f6b0c919736e2fa84c92201",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xc4f0e949758409dc5ceb60365008c8cdacc9bacec4b700fa37e680a6d230a2fc",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xb5e768cb3117ea25175f51aa956b48691025c2a8",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374bef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x8dbfe0125130890949cb7b7f10a449b4e1bd7027633557c33e0f1758b5ccc52d",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xb6569de5715b6aae26566e63abcf24f1f6873af6eddab508b21b8ea71ea1745c",
|
|
+ "timestamp": "0x6ab8f031",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa014fefa0419c510a1eff6f722652182c0e9609c40616fde7e0a6bc22b4026bc18c1ea5b2f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b8413e9929507b1057b4064f458fb71879f2b530f16ed07cf6f90055e75451c424b53670e76de37474f6de1ac3535325f64553c591dadb7f4854555440e7dffc89cf01b841cc5a3d76abda77acac0484b5edf345f0292217809e952a69e94c07cc9e463b7a2d608c4cc87102ad5bec94e4cf46870d02fdd92095ef86cabe8d1e31271aead000b8416c66a9f513db8fad298cd5f005493b339097c875910ceb9eb5085f1f12df32ec79cae23edc270afd3ba122f7525367983250a307b3aa7b05efe5a04468a3513801b84153deb142eeaa8f471fb5347dd138fa4913ad2b6a0cdbd98944d62477578780dc751fc82c7f3e57b48456a224d81555bea860a3475366b83abf9da7ce4236472500b8415bbc19606ebbf4af936a48da7db902bd3368c7c13ed5aae9534d44204cbdefa724e984a926c3173d2d911fb39288c25b64862a13d04be9e37ee4a3c769120fba01b8413d9739957d9092c865646d923d9c2467a88b33b521c1bdfea5500660ff8b696c33db77756ff1d21221f7db67c2be477fd8f96f8493e201eb7114a21536c71ec301b841e46a4dcf2eb2d28ee45095dd136782ebb0c880b26f5c78c4ff1f45ab51db5cde6be218e2059e46d2b54a0a469b78bbd4e26077c5f3b3fbd6cfd1076aa1b9176b00fa014d1c02fa014d17f902970180b9029239356681f5d6270e01b0d83a22483400d14f3bb1a134f19239b1956af56bd4522ffda240d77341267df16e61eff377b86288492ab1fb360f2a50867ed2f79445dd3b591fa1dddf9d260157a672d1b90edf7533afd82a22cd5129bd9393469c9a188734edea22d8f93a7fde2b2c6aa2894b64b37a45618258edd0ddb913933473dd350c9561f0bab2df2552a31a3d76e163d167d72aa546dd0b61efbbe58a71b3dd6f90c22890ad5aac5ec34cfc2808ba4aaf62e359659298604bf503eedf4d4d022d8799223204f65d703e7922b1d5aed7ddd43909b7181c26d18c1e121a62da2250e1450c543cb8a8f0e82129fc61540daa0820ccde93d73a58670da33eb9fcdd2242dcfb6312140a59c7802535aa01f3a61b9cf78b15b674feb039e673f2b476f5525722aa91d47f6b9447b70421eee74d2fc4ed7a0ac095f0e8b9d5caedae2634cacd998a4d5de8e1a964de4aa615dc769b64a70893fe24d266157ad31ac4cd4b2f899285e3dda9253214f37c5929fe3995cc1b24ad68cd7554a5a2390f8e0dde891649864733ec7076977de3a71f85de955cfa04d65a5429c75dc6455d4b7e1119640bdb92773584be46801a4278c4394ffb1b23c3b16697f7dde3d78a23eb57d4437c4f674388f04786386d5ec6261ab8251456cbb59e5c883e65c85c20e93229925089e08efb0c01e8c9c6bd1bceef1adb2a87cd9c145a192751cb376e06c2c26088aa3aaaeca8dc5427a58d41748a05d1a67618162a2d658e99beac53489fcaa29b06639f82944c224e25331368d0ddb3be0a84d7fb316b70df15dd37d672a908ea98872a566e4dfdab93ef975232cc2f1865a4eaac663b8949270c9f6df820c6c1e1cf2390835903671b2a8a89a0423bccc372b2498e94571c8810f34b6dbdab0f520e20778cb0f7a3a6c6b45360f91eb50280b91eb051596e92aeb43fa3d491193c697fc59f48f19dc7052e68f93a5c452f95e5c6b1d49478fddf631fef1de107ddf42e9cbf6d09b7d071f8d4612bd70afe73f36ba0ecef96f1aa417184e1f6b9b8071910c1161787ae898f6dec1d7fcf20026cb79f3cb784e31c02b21e6644c45ce7de993813077f2f2dcc383618a19315acb82ce745bb71369bf59df796ab083c200097f9e61c7f3365b95bfa0092cc822b66033eb328bcc246a512c24e7e2675842959463dcb8b380579e36e2a7d984c50df88b10fc7e245a87679f54f78d3d47cd2c094b4d8b629d222952744a33854a08225174c563f99dc2c3593c740889261eee9cf784dbed2dcc14ee94f4d3f11396cbd793687bcdef007cd5f5cfbb31ffd5834ce486825a518f43151f53cb19740493d9cebeeed3b594667262e16e2ce4f61760aa814336d0a5758dde4b27e7bb56346166b46c841b4bcb8ed7bb3c44a999d03924af0dbe71ab6ea8828f0707e2adfad797407e127d59343ef46fa9074c5f20491a96178adce06a0c97598bd8f963052ec8f50440e69e578a573f64cb53ab5a27fbc4ce97f4862c8160ac6bb9d8eddf2848f432bbf60d4a6af578d4723e8710a28a39482c4492c311fc876da681c6f8c0a26389963b22f43f3b2913f69d49fb792fbb91a6b6d4f0710a91851863f125c417f469b8f16db2c15b80a22887e3b20ce31af38440378aaa923dc5dc1b1be18e4367ed16b29eacc6ea728c07ac3354f360c43f5ac782f9d737fe6374c6aa544bec157da686ba1d3b923171bcc95eb3f50d99539fea9b5307c5146b78a4bcc46bee3f5ed84983900fda61ff9381422276d46e0c17be002d8d0201c076ea96e4e8eb2e2f4ed151056537b83aae5c20d083936e576105652166fbda550ab6371d2f6d6a3db0add6aedc3ac41eddfd6b8e6d688e6d210e29fa9a2b8bbdea4fd43cfd92f64d582408f89b36413c230e936a3b646e4ac83d69ce005a610bdc18c22c0ec2f5d00d8f03140d0241ab2c6d2f78e505083c9941312608c87cd1576aa2b349ad8fc1e645b85a65f7920cb120da6127d7c4c27d781d8e083f82e05bdafd110c69c29795ec73b85f407c6f9c83b83df1cbcca9c92f4868c1c22fa7a306effc3edf1caf4f6060685b15f44186a32b214a708ed47584a6c14b9ddfb45590b3a9b6821900eb2c0e3076dc4d8e88ada6ac31d032545c67dc025638b440792299b9473d0addfbdfb7eeb26109ce08c115ef81976e440ab6f6d7ce934304fdde714aa4520cdf6c2f90615726d7239880ad6dd6f7a8bd254beaec727b5fd8de03da1a9d6d164cd41471526837306b061319fd2afb1e40d368c4dd21639d870e1f5cb2b57481dc272622ccb0204e842555ff1af0a07d1157ce5b8ee1d423afaebe2baca5551b2b8718606f07c79f88677d46a7801c455211011ad7246b958b47dba88eacc11815f4fddbd0793cb39ca8e5df8ac11c86751a17a586a30e0c0a7058418d08168ae02afc3e1ccb4d231606e65b29cff9e19a7b6ee9ec7d0d88f01e67d4ad588eedf8bd567e00fcdc691c3a0e438e46110e9a8af16da4d285f54495c3a3696b2d7c422fbdce61e56bcec6ab2e83454ff1d46dacafe134c2224324cd03b3f6ea85d446edf3bbdc0c517b3b8ac9e66b39a9eff6eef97c059f4cf7c9354a5d0b95210943e20bb402ea3347660ab25148ac08ee0dfde3d112eca87363f9ddcf56e4e78b6554c0798096878e0123ca8b06c48a8541166181e129e65843a3363072211df33b74e87dc9dbcb5636547a84a4a16a031b75f8ed370fc6cd0371f1cad7622c0c410623098b844de9791ac339f6390fdf921b471b5edf48db236420f9b04702fefed607337dce51bb9bd482b011b2a380210271cd6a36b8e73dfe35cc0616053f2ff785eb940dea2367915975aff1adaf53af49c610dc6d0964ff9f18d0ac1448773a3f023b17a8212e73f7253fc3ab2e7c94e30a03afd470229fe26077a703d8c07f039eedcb72cece2fb260ec088540810c9e80507e80fbe6e2f73fac30f92e5420022e34a6fa59cdb6e8796e71fdd5d0590063aaad2b7b21116576cc41f9f7584da411e03a7fb9ed06c56a1c506c59757444a486247daa2da4fafe51c1b42d38fa7ce042abe21198ee668f7ec43f30cd933f0c0f448fe18c4cdacb09096e2566e269855e2a834227f4a2b11cb7bb8d0d4ccdc8865b801cf0be8d10ec6e296fa66c2a26c299bee94444ad0ba0dd8726e754149efa31d9f72543f418815de852977ef21d55414553c061916fd058cc9075911fa430c58b8fefafcfbfc546814027968699f8801169a9e1ce3393dcca4b417cb07f66edd5138c083e07002d082289fd7ebc126afc43f041df79d8dfc61ac5a83d50e13b23a12e779bc13f131fc8a2a857b36bdbfe646a73d3313fb73d5e301cf9619cb88c59030a09946e8add1eb3e51439f31a40c395d93bd1be734a37e399826f497b03de315f9f12c0a9a5245c2299ab5cd4b81122c0a076c8432e2a8d668b7cac35396c2db91721c3ce9d1652d04785eec07823d38afa56287c9b98348cb12373e800dcbe2261ed77eaaa150b58cc81f674f1dbed0e15d4f7da43d4e2e4116d5914d4313ac7dc135e7e8778df7316a2d5b22b2bbcd03dbad7dba0084a66763a54d343fa8efae60d74dd0e7f59985deea8dae2d6ee08aa3b2bf18bc5f0626cff2eed72952e23a5508782e1723bb9d296a73f123d5c60eca90bbf68704cc5d8cbfd9455468cbb797166cc299f4a879092404d5d2caf9c7739ae78f62f5609d8ac7543b422ea234d733d8db04af711bf590e6161d5eb941534ecaa02ab2791a09c30a512562fac9c47a0c4974ebbeaed50eb0ea81564258a3b8d2b97ba9e94231ca21fa7e4463f952da544f5f1e92d8e57ab20718e0385f4d6732bb846203ea3ae3c8956b59869149319ff6f20217564ca431e169935fab95cdfe268b0e016b3c91003a6146b257c2238c08c33daa05a08e77cfd3df10676b71d56a53e4b0c95106f82e37f6eedb2f847f3dc3b219d5a5bd894d46073260386f57cb36c099fda287144e348a87f654421e6e60730110a80325835cd525695b869c458e4bac6eb0a733fc29935b73accbfb948d79152fad62984ad9ee3a0ccc8381248e3a8a9ffbce2d86efaf3bd31ee5acb3e48cb3fd5223f504abd5a616f6bd9082d87ce5abc465c1b3a94ca718e9f9c9e87cc0ef99d3d618c9260ffc89f14e1607ee252ad79e9c42f751122db8635aa7dd909916541434aaf8433b705ff9bc75ea84c6baf19ef2ec170c3b476511b72506b3cf0068958c5007197b0feb877b811945f691ac9673244302bdc65103302c7c70183f731efec709d60687764e01225e6dd2d1b2b3a2ceec3db0cf57c4204d9f5363deaa0054de49da33d7e29b6a7e87a908143330dca2f46f54c9d20ca31150165e4d3e87fdecb1e92e1f713bb749cba767765c3d3715b8a77854bee2b8284aa6c6ad5dded0b6f535bf1ebc81135ec22715af073d7243fd75007f8415c42e928a2baa9f7fb51476227185ef1f03f34bc7d6e902c3b41c922a8ee0589562139cc306fb620ae3e68ccf6c403e354fb82822b03c8aa89d40c9052a5ffce15ae44d8d7af71f1d9673d7941d57fb8a379cdc00850b26ca33d6d9b54c8eeb0ac9145029bb978282d8d8950ca44427823fd5aa2407432d8aba3206d0cbebfc9d881c25f00b237ed4643110324c6f8bb1f2536cf7ef1a6e44b8145dff427b518034cbdc36cba867424af4f60e0b33aa2fde427c410643af9bab803ed12fc3947a34fee06c0f272167febc663880fe14135604b9f2531d0f06680087b7707366e7f97de9c7d35cfcc28b90eb0860b24a46459beb506830775c88c12a30d299f1823f42e5769309ed79baa6d3e769224ffa7ae98a2a4f4cb6c3b058ea32db3e32fdfe34721395569797de01f74217117c74e070f9023e359563d046f3832d265a965302f10aa0682e448b405c616a3f17566ab45eb01f66ac2b9d946fc21a1f42e30f680fb4659b2b5a72bca92ebf41e754432137bd2ee1ca0250741063a749ed25d430cd0203205474b393773c27e7f7923b03fa7f224beaa04ba32dbb85353349a9c0d744323cc33989ef57089edb9d5da0ad23644639e87035ab3552d2b8a0e0e59ca4746e2aafe20dd2f2e660f862d4a738e9cbdd27f3829286a28aa1ba6400949f7ae3d3f8dc0d0e6d068d9f9d42f33befb022c3eceec9fa0cfae600a81c3f622cd119a5cd9ed37e55a46fdcbadf4aa7516d21a40186b8149e5324caa5d39c32da2dacbe543982e9042cf98e35b017820f5de83c4f96866916e56e418f2ada41389f45ae30d998c9c1a8357b848c977f36a97ad72030fe8ef1207527cd84146cc3db1dde1e4961370f9fe87483eed93b1509f1b0cf880fed7f0fc955aafbc89d18a4a7ad2f5b9e62e2396b0eb1831bc9f4be0aebc9fd735a3203c044420c9874cce4f7736ceb8ed52f23feb09e4b7c55e468e68c493ee4de0d02031c1a27d94f85bc2d05ab8ff5af61f8be54d9b74125deff95398019b1b5a4675871baf7dd3841c2ab485a7725522ed2d1f473dd6ba3a8d411168fefd676d51117e13397e38d471fa825c264f8abe1118ee8994b068b6d20be78ce37010b2f0d3ead22600d2c16188190c41749378786267ca3d7e4433edbba5218586cdc8ac329eea626eab8333316f8052d29eac31fe68153df0e433baed9b7cb8b1a9b25d722cf8edbc3916d7e8e726d8371d90aa7a06bd186326fc812e24c260e5882b1373689d01294979a2b835bd0841feb516c5d3c82e55c7f889427e6b712e3f5c75b50e7be06c45a2f5a6f873340bcfe2039245640d6bd7da53487394901a24a381d2c4ce383b1e98d245b39dd74a1813bcbb405ea01879e06ff5a71f4af61832cbedb4878da2a0fe1e81b0a1df11dc2f5add7becd43b446a75c872a7bd2943e72749dfd73dadf40dcdbe2138736f5be647c9cab792676b2afb5ef7a07d8f51b30899dd2a0369b5683d9717cbb2e031d6305453a31d163b2a16f209ab5a4d38889c812f1d3251bc191dcc9d3a100e605a3f023433251a971b0c18c25d14f3111328692088be74b98dfc7a4232c780b855b3caa1079434044d88bb4b78f0bf20ba21f37289da35cd53409c06c37bfe70115df0792548183b212347ac44dab3f5707512e953bca0935ed6b36e6f60ba5dc2d8b79a339964f84951d8589586749138dfeaf918859e4c13591437524bfc5d66db518f717e3401c94e30cea67a48fec96913b9bbeca5eaf7b001ff225fe3bfb87fdcd74208ad18d67a9df8779e015d5f8e79c48473cf229b32de11771fb7c89800e2ed73612e9246d0f0426e6697c34710b62f48fef6367be772310b57c51e70e88172a79f21ce1bae9fc8003aef7a1cc90c32f6d826261fd272271f7e51cab23329ea2dfd0d6a0527120aebd6309b20e522edfcfeac387bf4dd8c84239463088610a3462d53b73ecb212c19474252330ce748d7221e05c66c1ad1298cf36e5b0b639e30bc0da6653a090098c4f88f974a880689494c626de21f6883d388e1b24b2bef8943ce7ccb1034a38dc9c29902c2d7228574f2d947fb758ee28aaf1f194dad551a47f1377bb5ae5e10031831fa78ce2bfee9280c4c794b850688c85d43f13f312c0fa11663a234c6cfbd9d62989c20ee76a9a732cbabe562a4835734aefe6a920258fe919ec5228cdae111aae50e643b61d1abcc988b68c7299b11b5a7c5e52f17449bc62b262a7c8708895ce42cf432173b02c3e4089ede91f688c79fe8e2e6624f8db8b474fc700b2c6560e5ffa92328fce7bab30a9a5cdf55497619e8dbc1c6915a1c032f3ea15fd8ad339ead4ef77507bb81a5c3b8174bdd8334ce1ede3e05635245ae5d25c819a06c26ada57bf07e26a71c87c4e65b62ce204d52df906e5e164443f9d56365b3ac3276dd78d9bfa8f92a819c083fbe3de1a87be282dedfcaac8c774338952a375e77ac59c671363314473c2c4520840b9f9c89e38df6d403932911c84fcd5913dc613c99280c513c42b580c7cf927bdb048e17d33899805a6b9b4dd34244155851be8c94459d59245f6ec9f35bf631837423a0d5248eb9ec62fdee8957612198a92e9a51c222165a3450e48c1652846885acd34467cecd2ba480a3084c3338f5fedee99ef8e3f51fddc5ea66e662d017ee9ec13ee51415d653580eb61128381e79e0c58386f6bfeef8e362c02081b86456e9b9ad76c2922bfaadf6ff17b6ff371de2a434070fb07b621729478c37a94238681eac5b81b1cf5e0409bd18eaa92930d420fb4b6f585c12ac4d70dd12ffa283ae0935ddc825269babdcaeae790edb91e81143fd46f07e5f921823b5a861d8e871f426c2812dfdc38f3e1a5f2e35ed06815e8526250a0f2c763da831b4a09a26b78018bb1959d777a9085c7a8d9aef398643f9d15ade51640d2bb3fc98862709e1e13192b4e3a5a77a9589faab7a84615e3ec23c0df390f04093c0d9706d1d62e38f8a8cd073382df687e814f2066703130a979e37bf2054c8f60612aa39d03927394659d594f9bb3ccd1b5b27fa1d12b349daf05abfd261d7d51394b0300707f78b03a40fdea27b3370881d521c35727bac926ac0dce399278f7a72c5f4c323711051e28cb3d3990bc8d6bfdcb035dc87af75ae80207f9a0253a6fd622db1b342a364d1be649fbe8c05087b76833eff6159662584bd405bfeb52860e664fe82f70e3268e0a5c9223b5c07b43ba1c257f812809024bd5d7aa5cf6ecc8966c39c7fa3184946a6b7b6c50fc7f5683615d6f521e355a779059c86e02de07a751d7e1fe96d82a1abb7756bba8fd361799b6d7c8d0ada962821395f1a645673e2d1e53b403503696fd4c30cdaed88b1c47ba297f6ce3bf299ec74ac7b0f94beab6c051f911a12c2d39119396e9b9ef036581695db0fd04266838f232fc171439bbd92a96bd1e49991bce099368e209e4b7055ee20a39be9d97bb42c55d110d9882fdb6412a6521db1ec8114a19a3fe7f95efc6931ce0c145182dad037c8ce05831a2eb9005884068057ced5af1e0d2722f5b02fbbb2ac17760b7806d61f7279f2f7d46ca9bc8eb0bf8d7cbbaf43ae022de2024ad6fcd13736e6b3416a1c96e18fe5c28858502e514fa30be6eb1b55f8496615348a66c6670ef73afca621effb5d388546ede49252bf76701d79989a318ea6fe40af9dfdb0c6ed9c1ac33299bb334885d70ac6e02efb6bb4eca340426af1613ab807db0b1d2c594f3a66a2b4d50b9b3583d6b3415d9a04883cf3fc6f122b0ea379aca7ed8f1271f5a4c026ef7c5f049a33e25afe85f4a69a4c01edce3a50c23779814fbf0913cd49313c96e194d5c349d5ffca1034025660f639f223fd774e87bf0eabfbe4091a669160e6a87b904dc919981535b74313e91d10ca8316018bc7dd90d39328ade9be2e65c3a4b653e1a84c45b0937b319a18f59962bc08cd8819b323eb5e55b45f62c7258b0ea3d2854e3248dfdae1b4bf3f1173f711a0e96ef09d5e8bcd0e68042f54523ffc0b1091f33010a1893d8362d92e1d4541d59b74cf13e037da79cde4d42e55a31d70091180fd401734458f3bacdadafbdea8ec79ab508c60271f70bed2a59b933abe4fcce4f378a1873201cfdddcb072cb1134996412223beebb628db0bebf922dd1ebbe6467bb37f20368cc6b9bdfec6231804ee051f620f450e605b48bb6f6c340577accd6afe6e970caa47b977499aa80e25a5baed614a32a0ac42ee693546ea8acba60992b1f4317a9d09b3102e0193cc012a0d3bb9c956f020a21f6ed0c31fb09c679e3032320c93081fb8a40dd92edd476043625411ce57ee37ba3186c3bdbfe49f72debf1011ad39bb7602d976220961533020a4bd58b9b4b741fdd69a4c9f21e96c39b3b07e0a523e0540ba77b81644c4fb6ab69ccc30ba92851c3b4ee92a98c498e53bc8db8299f053c98657560f22a5a31b2b9342e74280657fc36d7e1a4f759b19799a31f4d97bba5a1adf6363b55055a1a969accf7e648ca4b21b716a84e9864e8498c441d74f831a874e6bda4ee174e9657f711357cd0c3edd25b4a6ccf0e4fa37f32523b590c7d8b3169f3e37fc84940fd54514177142763f03fe3b0936a6199f39f9a48a132d7b8bb3a9b9b63e6015264b31d0d301893dddbe20103e45184e6ed4e83418b3765dce340f1f0468d51df7bb55ac358bd53eba431ea941242c9103980d003caad8f4a74fe3a509ea2732e7156cd95a3bcb61cd1eb980e190abbda109804bd4ef517420dd841564a4f0a8dcdb3b68a449b48c27fa987d7e718ca889299304e32b27f93df640a1384a40d8e7e970eac28c8ee7329848743e80dcdd266dd5ef21485084789a4f4deb889f94807e33889af4ea476514331a882fa1c7d1e65e1fa26fb306cf9df03fd5b13d38e88d28c110d103a08a62aa69bac376731f02db815f4e6efc063cec7964e50b1dc61210aae7e9d5e652e1579a6da44b3d5a5aacd6feeef6cf6176b42f382c2649c97bdc8fdec8bb41994abe3ee3f03d7567cb7e3ce0e33637880eaf811b5c9fda9042de50fb6d79a9b44a1f487b99c0afc41d3294fcbb9001caeb53be050a5f4aa068d847d9419e7c8395c6f1a09ee794dcfc7b0153a0e6bca0ce218d3f965a8b3468ad1d63a4a81403f70d6e40bfb15300af1c9985df043aeba2a443f5de74ce2b5eefdafa89ba4726cafb81e6a8c3e851b54433a07ecaac572be8a60604afd4f363d160e4cd68a289f75b30bce8acbc7ffa8aa2193995c9381b3595e2d0e2c578448793f51599b04135e6659f106607c3c0758cca1aed1c5651c4b8c04a8b59aeae99aa6a6bb2ed276da8099bf67466fecf98197ea44eef449da4ef2cf26940a790de2965b478cf10b768311abb9cfb803869cac6f9031f45ee2e5c556455a66e324115cc9dcce288e25ef59d5439a0003de14d2ac6576f13dd843493256aaba99dea267bfc3662bff8e40e7f8200947d23455e8fb5fe583522d010342b6274ce36da2639c6cc86f8456d4199ada103e48327f0a21c5994f232e59b4b9ab5034fd9cfbb3ce2381d562427420620db851cfdc662dc88c34bac04169a83e7107ca85519a307658ee9a56008a4d123be3a299f680916b30dd7ef08d5cd49ced58222faa96d9df6a37e0adc5ee9ce393ce3a1f5b105764c4b44dd78fba327a25247622a2e559df62f954add1115d1c1d4a05a832f74e2cb6c54397117ff2b8f0d1dc793c4e1ca28e45490789f7d3f89000cdd2ad905121ee0d242b7b8dc40e366833d778467b3a9de9905af0ec78534edf29aa4bf5485a07882ef6bc543d729229c43b8333c3600ec0b8b7511adb6bdb72ba9e69aa908ba1942ac080318890602d8105e7a63b494a34508799cb65cdc210f8a67517b57e7f6f448564c693ce60bdb84dcf7b449c896f3c3bdf5d0d9c5d8bbf97976769e74b134157357155c6d19c957c36b70989b8800a538d5b2037aba0676513b8b4b1f7d6464869c5a1b7af955ee92e9b55c94140841871832bab2c1c4844f471b12fb3cac738b821ca131748c08ce67c8ac28fa6ce97b5751ed4acaa14eae0839637655991c9f4746864938297ac29a954cb332f9fb31f115522c632e6f3796d3911885e6b5d63e0936c355180191c308c6ad615602b7c1451a03e72783dc44dfc1bdfd2cce36fe453cae3fa5da88b703ac916ea8b8f6d71b584003cf9f7daf62f23fb96f5b296836502164defb5f9a511b4eca9a1492fa937472d01b3247ccb8950436db3bfcb6a52e7969d8c76993cb71433c5a6931d7f7656ef5558268c391200cf4fd7d70e99cbcc3d406c5b80d5c98309db6f08c8c378bdb66075faf9421347ef74e5842d892f5c952c64fb66acc010591713527de3a1b3c81121925774f9d96a4084d72a9087e4bf5ba814df0bc4e75d12fadc50d316e2f539207d0d86d9ea4334a47170f71349bc152f9d4e101b2e12d13940ead7889a4716ba4b213e4a0712e7986002f3e0350b608baadf091f817767e593362c2ea27cb896d9f3abd9ee7d361700197bccfa66053d1711d1221ef9b560a1867a57416a3e8a3afc392ce209689f043a55c5c2eea535a0e1c4cca844bcd4f3cf6d0dfa4dfcac9bb0a7ab771102ffdd5fadcf9c4ee6c33db13050a2fd5c23110a5fecae01cbec98d58e781b086d851aaaa5e4f71ac25f9d9078ddd122ba2a9e83735cce04b7739c858d27de84d1a9afb0bcc10c71cad2b186af07010753987deb3d60963d1df6073599d5220d6c2c8cb202f6860a23e0178c40312addaed5861a89d99e0eb0b84f8c5e653476005ef98272081e7ce7291636a26e042c2ebe3b4d21f3f449db7583629725f95595e0d7cb244728a5799b6eb8365d147cb2c58b31bf3c4a94400e1c8cbee695dbee0e64419f5a6e2ce4f4da886a97405a59039cdcfd5fc9840a7ce31ec5df887f9a772cd59158b59d456c66b08fa9cf693e522571199baff9fa0e6c912b71690035cca2db3ee6bbdc84bd0fc56206ea40a1872230b499929033b086414f03c44865d835ff3b8563baebc72717bfe0c3297d5059e829a9f0e26ac7d8fc40c9e3341188a0e930740e966fbeadf5576ac5ceb74bb862df25ba75b2206a8fb3bd5836528633f55b3f69ca59945d9c4cdb5a1a76630288fb7ecea3f79e8e489971ae4219e07daa7347dee1ac1956f7389c4ea0e983176ac13b602569a986b3b8537f41064cb1742df1552d64dfe7b26559be72315ec507ea61a6bac50aa2077200dbe3d0589539aecb0fda31783c9905e376b7a9e2eb83396c25ce9effbe2e5b82e5d9c895cda56c10d572b315bb53dbe1383de6393d3837719af00509d87813507680b8217e1f5de8a210026c8500af807678530545531b9ff86688ac06024514ccdb9e7e737e3607c0e05e3266d64e29a66a716fb3ce7e53824c2fb1ad05ec7e4dffb32c9da01fd800b98cfc179a299b801f51cd3107a7fc7558c703387e1295e0016a6dc6e4490a8a983c266296ad02cf4ca48d3f1c4d053bc1da73175b8d786139a66b95243865cd82a1cb58d7d353743ab3814329720542c72c30e7f04e27686a4ef7c49c1f902960101b902913958b8ea3bfdb14428e45e36427d28ac6246d1934f1d8d88e2dc1197d3bf66926f04357415989de8a0355a60b5d773713e8d1959b6e0a9ed1477ef0d86218d05421585c53cc8d25dafb84468336d0a49b33f3057254e82ffdf725726debc1af572b93acc683e701e074f8fbb65e9799a45a6e0b6716afc9ea6053f32e51af38ac2f565187f959298a936878a7c5f758fff4b04fda2c136de1c9cde45064555082160d0e39b2c4cc60453adf65b462cb5f82569af916b7afcd99eb9dc83a19d75c1d197c9d4bd60b6f0e27103acfac9e25e942d787ba9adf46695197c3e1279d36a801134095f403da6ba0cee12149a52ca54a0e984aee4bf7de895a4fab108420a3bc6f5f2d8e2654f654adaa64250a44d0f1fcd584627fdcdee7d6243d2e8d49634e2d953b649d04d5b04fd64b1c97f342df536eaf22fd116da2af4a37004db52dea56fbe1cee299eb62746492613d7429e863b9625278f06292dad1a3eb4e05c782562ffa4b1c96e8b2d998b61a4f2c4008ef72e840f26d7ff16543504529c2e6fd193799ef775c85cd8ab76fd60e16c0e5b8ddc4c7d038fa72eec2569a7739f3a5ccbad54da2f54c65b36e5ea72fd69c2e917865c14088d26949dc5d08b5cfbc28bbb1d2c3d7be77a81ca640cee7354b6b304e350cea46c2a6fab21f6257a6f6961944ba4db1ba66bd1b88bada3aebe9c57a5508529ef16414b52889e78c914f67e82a19ba831a34adb2644a5cee5feae8ca111fab04816892392687796495325bdd0732ee878d2959bd62d69f099f71fdd2069d999ce82969a1db8b9aa62a0851d5da1eafd7b1d6ce9a18e146ab8dc7089eeb1dabcb7c68336efc2c8fb7b3c6e9aad92786cde9c846f898ee4b4c803ab552182322b49b37d68d3a158352667d73989aa4c23e681de23667fff2e2530f91eb50201b91eb0223076bfa6141864f14d31987a5f048428ac2ea89cfe73146ad6c9b41295493175155845657d8fa988f07171e6202f222888d2de2da529bda5ce293ec901275dada4bbb3b11099b8024769a0baf0409743ae59a1d1c9b0658fab42df8f616e5873fc284fb5979b979dc5f935ca7ca727142995c752d28dfde8cdc9cc6fa8be268e41f519950db743007b9c45f154c129c6cc7223cf4200f2b62d344d0eb42198791a01a4651f53f907b3877b5e95a7aa080053eb48be9b28286ca2d3226895a99ba585f39bb61c63dade1de456b97961cac7b0bcb3fb5298580eb2b9a5a78a7194f5e48e8c3e8eca1caceb4ae4ceb050ed88b2a03c3426ede135266d14cd4fe6c1444ce22ba16467e266977c46a99413e386fbb72165716d9a3066c9f253804a3bf1cda575452130b210faeded17a73e2fb1f584451900197b6bb17d1af1f51314e710ec1d39281a4eff2244d0676f57727422bc45b4a3c42d4cbc0c565fcc2ca1f1bccea17b03dbaec11844eecc61dba7035620c5a26b26d5f7894b2fd49c63ac743892ac58c218701ba951cd2801bc3653e80e7e5b3fb8eb9b93365dbbd0577d05b8ef02393c91bc8f170e2d5677eb3737379590a20c81ee5d19c3a64fe71033faadd97f4497323484a4c11e1e4a73987ee2219cdf4271ddfd7f478f52be6c61c2a63a9abd33990c8cf6db27b65a4685d818f9da4e9f522f1382b80035ab74f59fa6978b24de5a7916a37f7f69b73e34babe6c0f1135021c2a7724909d274d205ca169ee122adcd4f438024c4a53af30e21f53a6d1eb7405a9a076ed5f914826c370ff23a77a3407bba283d94f2dd7ada04e76ea9af02826a0947a5303266b69ba3d75e1175bf9606c8ef70ba466f9ec220a9b8025e30e95c9c677ce7412431da8ea9179199d2fb19636aaf941c124483892fbe96176bebcb9754951fd76804976eaad18d1fee1d796fc87f3ec7ae0a0e2fd8108debba045e3409988190fc6e6f331d369ff96f3b23861f0fdc6e3f562df740163af63e55cdef0877b2ea027d1cabe35be13f30b911b26ebfc463c6b242266fb0f047bb416455316fdc6e450d9ed55429c925d0b5d5fd91f3f3ec8745c27a6a5f6f649e501f150af4b239441c40ed11069233846f2e97ff962eee34a6546246aabd3e58fc49ab52e000f66763f94e940512afd7791bdecfe2e0e909475c67b11aa0a66fa8cd216f82a39881c82383265cea828c2ade1ffcdbac1fbfb6cec93df60aff80a31c1b009601386bdc0307eca790483b616e6d4dbeba03ff2582c94918dfc2d648790ca59ca0b0d813b802a16087f73ee682bb9dda2aa132f788c07057161683dd8931f70a880e8854dad105bdc7f0d918d715adf88dcdbf23fe25dedbbcef4a5d23108e2ad984238aca335a20a1f850182bc456d8d03fea00f48740752af0cfaab1c927ef884168bd7429234f582f89a54ac1e7fdc660becb0996231dc37d818aaa5d7aed54c9a90eb842c6ab85709384c8d75d3ab6743991fcd1e6617db2a387905c7a6de42c3dac2bd983913030c18abc14f326b976d297d374bc732a5ef15441a7fd9830e2bf7191b8f3c9ca66179eebdcebd37ae838b06b460d55a401f60c19945f6373774b279cce476b1e1e8eb2b0c814e5d7cc23e779d7177551e6856fa0b4acce5cb1c8d209b84ef8cef421b7ca330dd801f5f75981ef1d5e5cbaef1c501173f7890cf15f987530c0e467721e99ec288ea0e1208512f015046900f52e0a327a51fbdb5c597adf9f08fa60fb17e5f3a875386e23f7632383960dcc857061ec7f545164de50f8999a2951b7b5cae464e57887dfe80f9c59509c4a77915ce899fddfbd66007f95be25a23337529d8c937a6783f6c7a656e2dfbe0be52c0ed86988cb16fc77ba352b8feddc204e7de6ff4fb164a5e1a9c4bf83bd44874935a990764737758122d2091dda207ce5aae6220727181932c8c6ac0f16b32e17913329715a7993c154024656ac83f52f1e9c50d70b272b6b6cd332c461b15979ec0ee3f59b8e4d78d90bc3b1ba815fa731f5e79d38240c9ed15d7e14b79c15e839d638a60591e328641ade09c89a8e2011ca3e45255ea542497263e42333759f3b062c6243bde8ab0e732e1b470ae95a610d87f9c1ee4880b77ddf2b21a27ca03ecf62255edf77bd43b529dadc7c75cfd27a6153e8ca903d56857122a78a9941a9ca9e0db2457cc21af91567cc92938016300d7cf8806b55e1d031a0931982b2b8ffb80f145b3c17b4749cd441a87b6241ce87f269f3f6d96394daacdf7fa79c235ccf3148f7c297a77715a5b6164c7e2cdf9659d3f9cd6606ce6ef6fa980bb21d1c371ad8298a579e4505af7035b9da379e4f5ce5dde44ffca9192fb5fd7ed2cff0ee301bb7dbf3c980cc2d7647149623c5a0d7e3f8e59942bfcd9df520185b90a6aba684046664b5e2cea3624ee463c9fc54a82576b660c92d6540e93986356efa4a8236b0edafd9187b50757d58e39014e3d04d5d3f7565abf0b4bee8cc676169fe6bcc9e3cdcf4ccab16f7937cf13592b8ba5d912b573b066b0a99c1e963b77cd2ae37b7502e4bda91819418f5cde7620098197c30b90c96f259e056d42ca7de0f4cf78e1b1bd73b5edee4923659dd71bc7e33ce6a31cdd79b10c87c7841efc65fc08562386fb49d80db0d4557a855b9f88af7da6fee950d047ad94e1310a6b5d30bd01c3a280f8935e0dadcb2f2854df05a32b7595528b05574b27aaa62eaa151194799c77c7a9b39e77e097f38732434791a891806ab076009ba6c4a37f44734a8c5c18277209c4b6d04677cdc24dee4dc99040f4190d9922328ea134891a17ac5501d6bfe466abe56d050ec8999602434a8e34809838616bf653f0436d7bcb89fc5eb747cabba0e605e5fa5b5d808c272e695cf717b16973ace8d34ff02377bfdd6593a5ee3a57e9eddb3d6f61784c6926d0041a5228de71ce52fa1c9112e7d620c673c339b1fb3285c3d6604931a7dd43bb60f59d80c2fb76c330f53a54b4ba90ac06711b8687f60e84714f8c02c2591e54bdf08cb532ac01227717c2999e0eb91031a67bdfedd3969b686d44a944411baf452ad644c940e2a9025e7fc24ac1a2ac1249795967b5836dcb23839ecf003f5d5be6de036467aa7f3461253025c15876edc957be59a275b94dc5be5d2d0186c4bae947607fff3e1353950865731fa550924abd1edbddd2a05bdccf094d16ea1ee928d7b7534b2c48b55f0c19993c583c31ee31b9a528f8293ed862730d872d9430e4781c6d9a399f74cbcfd52edaac717275cac578d5357dba0ee55fc6bd3cfbce63f8422be8e6fdc41008bccd4d064d1e6f286d4285caee7778167a6ef1c20188d18ba2b588a6de774ea5ede28d47c1c796de3eb81d793af704af6f5610f947136ba81f24ac59708be3952468c9b4ea608c4691aef1e83e17e8cdd12e7dfe099ecec31f8e7d54308ea02880cdf472600b2f6744d3016b1441ca97797e7f76cf21c8cfe6d3c62c0c21f6231870f3460d64c1e694fad6d13fc54f82f4a072812592c2565dadda2dda6d594c9e17dcc14909c7ed18c69d0b2cb168d9bd323a9dab3a271b966c9d791b9213db72340517aaa39c155308745446e4f46bb903db5c31cbc992a7a3f1959f547ef8d7347fe5667be977b6dae6a790f7c84d8cca8e596c78fefc252b4477f37abc68fc4927318e6c3998e84fff87859741a5c0ddeb72a6a687766d7a3ea973ef633add81ee824fa193839ef7df52310c66a6cd69e63746bb5ff95f3a5b3cfa6b1db081c1c93253809fa4586591dd958cc9dcd804eb6e30250f23aae46b4afef199eeef4ccac66c305915971936562934753f6a63267b0505b549fb8b62a4da48cd02793ffab9c8ab99b104e75dd4d4f11966283a9ea6627b5d6f4181ef88dbab453709cd2e144473906a740bf28c9dad11499b7132ed312a8acb8bb0e2d4f2ad5602351d7507eec2f321ce77c7abb15d88a20c417693844c99f2b6acec8977ff8229645228bba1449b65e124348046878c01950e0b553d8c536df0eb45b1e75d9a57095aff04ae2fc02fdb35df957947a1e29ee2cb81cb2c024b1f93934d4f4abeca899bcac5efa10bbcec29985a322c1e1047f101b58fde4670671e6becd289290bb1d48fe9648c5fdf103518c61dec87b4ca60bddd83da0bf065c32b5a4652383a4ddb4f8ab5c80fadc74a258ee43d9ed0d5492bdd4eb35cf88f1ae00e27ab55164cabae729b6fd8a7c84967a5ef870f7ddb8c52a7c42cfcb3944abce58f117ad4806961cb3887e8a0a3356e82bdeff69b9bb2f4278a2f2f13cb6dc84b4c32796a577542a8a62e204ba12c82f5f85f2e9bae5afdd184cbcc9ad915c3fd01b9093e0b6f777222c0e89e3cb961fd6dc7f2806d1d5c247642f5f0812a07f761a4a4a46c844b49308ccf336c94473bf7f5fdcde8a5089aa913a2a779f79fc4047d8a8c7d2660e5550a7d1623e942ef99cbf192c616f4130fb981fb8a284c778a6f9baf0ecee32fe9ebd75adc6559c5497570d2e4c0049932ca98d79fe6eb8d26b9e87ddca436048d00dc579475eb39e35aacdb21a1c96a12ff848bd80517c85d4c6c937eaeb4e87c1b06517b4cae6cad96a333d38d4c01abbf7ebed1b3af92eb004f5d9b3e69ca934180d56d22cc41b9823f76fe5a435af33813b179b92c7140433b0bc36bf5b75f9e4aae825e1671271d38c0f9fb39cf34be232d614bcff538d699dab8daef075e40136390f15ae15faeff699d37905b0d035a3928c79cfe68df24bfb7f74560a4c9c0d5f59f53aa8a1155bcfe81df0d870290e3624b89e504aa208ee335b5538546ed0d29930f9536600a05100d4a69b6e5b928f20c5d30e29908b190b61a7cca7c64575a3df9a974bbeec309bec3842790ba70c9a1c81cba2d079b89f03ddf9d5671db7c7b3ba649d4711ee8a8e02fd624c407ab94d1099589f90c393e8048c35478a9089ae079ccd6c5509f8aa85c418ede95bed5cdb4342f4d25d7b11be909d560f9c7bb7e67a9731974f7ee469da4847b26a3c201c921196f22177da601d3a6f4faf41fcda2f0a4a5ef39e84ace9252f49352b77b1a3782f2bcb744c25d0425507928698a0645c59bd5a0dbd4c27028a9cfe854e57d261b38c43eb71a57a7efdadd6b4af8178f6471ba700f52dff064b3d16aeef3e846f8d1316b794108bd77b17859a0efb2432679a21921adad5e5797b37079b8bbfae4ae5887ae18dbf67492d4006b1e86eddb28ed5d3e38a38e8b2ae4a5020181ed0c72c6c6528246ae3e6cbef90cf9f3c14f634132de7b69de3d604281d39994da83c27d809b8afb7c62226572890f864a3bb404e66ca65476725fea9c0c8da7e09109d7ea2ea092298eed3d73d5fe00e55d4871d0bb080edd1c5c9b1b0fb02eef3f7cd725ac1f87c97a302eac45ad22842733a52192681e5a97abecc03f02c3824c48d5b2cb370bb86a9ae90fb5312018c7dbca29166fa6695a79a91260e29028c65166590d6eb926f9bddce1dcef95d566867cebc5ca01e6997f31cf8ed73f3a8099f27382d8f1e517cd49280f73d7fda4bb4cf635a725bc6e5dda9d59c1619412daa69324fa7c86fd35e160bc5fc1e7ec3b034ee6ae33c37c2b0ed646f371646c3e39ee06a3942c0d547a82f6a986a1df8108635ea8d8ed5007d290825393879cd293b7ac0b09dc3ce2b2f5ca702f2e464b80644ae82bfa584fb6e96c0f35f217e4262c0a1ff296098f661cc182eb5102e520b047f8401caa12e5a926c2d559a88b58233099ef5c8b5f5783bf9ec0e06d0ba65e515c5c60975fbbfc126ab4ae0cebcdcc2973dd0519609823fd12618a853630b5dbc991507442aec18a52a40b965c5d4d0a40f45218df6a0e1e61c7e184214cf4a4adf9d544db007933b45d664c13e6b3b2fb3b116958e4334cddfcf8dca93af0a6b81c6718e4e073fdea6fbd14206bfd08296914e23a10bf86b578cb4d103615e408e291681630e04dac227809ca324a5ba4ae02035800719da5cbb91bda1b4c0689317be348e4a00cc432dc45e241beb7f94cfb521f9db4f5c2cf5cc505326a2708540195dfa6e5aae1f2803b13bda517eee4642811a215bfb5cb8c8a902f362eb806a68bd17c8be7b478a4b47880f333a80fa1dfe8f4c9f813f2b4e9e028c9188c090ede7659d0ab4de27712f6e4f1308574925b9d6e32900df6a043dec448f5c2dfec24c5cb479ad1e663591e61cf2faa3ee280b1355e066870c0372dbacb1c8b1b8cb249deaa6139c406804b47fb5b485003b650a550f0206ca6b4a80a928ae36518e0d2bcd1497fd5bd5988588aaaeda5774a2d47a950da347bec0de559820b912fccaf6ef78c751de7d93d57f9751462d18dc0fd728cc026b01f27ef932d0e447840e57e19bf194dac140e82e05e8c228ae9783937f450c6b474e2408ec398554676c90abfda7531ce15334baf073dedf7d751464392c9022d456689c1ef01f1083d79632882be2690624059dc6e6d281d658cab8ec523e354bb872466c5ee5a1249777d81fdc22a81474fa8a4502659b08bc0c2bf731174d647716e468781ec3311297844d32f3ea1fab043b65773113c66ef001ed3df3fb2abbc941aaf655d889ca230889c3044c5ff7b34b50e8e6822ecaff917b03f6f4dd7bac5e57021aa18914e02dafd3ad2696f6da735ff4e2456c3117b8902e2036eb8dfd323fcac02491bafa6d6295c4173380e6a3248455a019a12279b1e27a7ca4f0677cad2bd4186f9965e9ea1113113a74ba195c901f773ad6519575e558edfb55a6b9c6a00d7dd555e2735504c535af75d588b2a963fd714c03837cc7d637d7ca746538223937cfd3ce4d318ec22b707b076202e5bbb28a13ef9f0e13bc93f36cc89999259c84a4c0fcd34e760aa335f2d8438630784576e726b919d1a32ea7ea6f4d6d0e38ce5ef2a1933bcfefbe594ca44bf49b609e4ef4ff42fe5e1e80b71bb10e623d8283762798e3836e11c6e2b771c5d6b6d06d81121293d6175185e19a26761a867917b892e6b7da075499165f6107a7032291ad7f45151af47bc53fd7098c1af089dd8b7d676d4c3ae698f33d3503f1319155c271b32990760f08e6c869114537496ef3b887ee8148d84ccf57c755554a1c4621c4a3d332bca973ab108e78bc8b74224c54a5e47a952f91942a07d98d62d672f65fc6178d296d9667a0bf448cdf62a7703cc92af5a83ace6a19504abb0a3acfd72cede24f74e9720a2923f3eb5e729aa6e96383fe026e6e173e659efaf18461bad38328a88a4295b4ece8d423acfb40ccf8d48e31f8fcdb735871cf577656864ddf577a0ca1f89bc3676cad180df7238d59bf87bf68bb7d29de2e6d4059b1769ffc25c79d85d69562b8770f75ac3fa49628b25834849e9515f41210d1c6c782b6480913f1903505456f207cf83c794c412686e3e9ebd41b654ff1750d1bebf088a9c4d182fa978dec457f38a38276e3d8333a0dd513304107601b99b391d48d960a3850863ce55d2e60cc2c4fba70e3a291ff2170e6efbbee4f63e15aea8dc82ce91c8046ddc1a2c1bcb7c5ccae819cac917b1750fd1142c87529c75df55832b6e31959794b9a964d5bd57de08897a5b421aa7edc5531a3df8a00325425d1b80dfbf2f28b892b204da88a30eab57db87392ed57aa7330f3385501e847cc8fa79bce1544d8cfbc55b657411b4b24c2e97f741ac7792a1b46dce9d0f2723b3dcfa68ea8ca5d72a29ccac3fefb863d44df3068f7aa837154a90481e80520147c49dd459f1eb3941fae177163e809c9cc7a66d606300ab6a0a997a7c6a049008148faa9d6a8a701ae627c7659658338c29428ddee97416c3649c8b1fa0c7b9a933b4658db75f88055ba8176d148b9330df62e93b918d83828b199a38b8cd629b317313d1d3b956c1c32f94ab4c4f6ec47bc91119f79a6328cfa164c0bdeb5f04b11909e31ce05585a7ec47e00e954f4911af0f1aff30e29d183a23d6207a76f392d4bb091daa79f17178de04949d83ece74af11fd86323676fde5a1e42b4aa8c1a6730724a04b8309a0482d2cef14d9e5c4fadacbb05b8c1b56cb0e0591e0fb1ebe5ee1be32ac1bc91ef360cf15fcdaf9e2d8e1c068ebdb3853e17aab969489a136cac9f1b3605f770380d4f579a8edf6476b9cbe9361568226b9f3f8dc993f57de78a823509b90613b1b240a73bdc70a9071372b4de65bfd357425262ab6113560981369c62357ce30c596676fd836322a23ca8de27e16260eced1c7d83396728fc0e5ba14f32bf77ffe144c65c8ff29695b20e10ac5bc74ebca3515beaf473397b25b90594ca3ed912ff229b83d9750a8172528b0a37faa32f8f1d22054a2a757258839332460eb1e6663e4cb8f8280e0af4611a3a8da632a46d1d6f8ffaa7d4cb3721987c546d3b6fd40962607ef55c14d87fcfe95eadd29cc2be3902bd6e3c8fa8eee0b30f0f52e89e8efd6edf1d0fa6e85a31fd853dd8574b80aec3180e7515cb8f73e0a7a10bfa262b358480e7c84c85078a8c6f1f63edb9c485e62566fb35440b464a292ad81bc88f3f1f0ada303ea18c8daf249c7077a9566d30f781f6f63b92b5c57b2ca5526b4158f972353b5822ff5f67b005be9d9708fde81d5199ba16e79416e338f296c92f97592b354d92fb200509c04c573e98ef04982adc4d7f42e5490b67c88000b44afe5a4003b336e0d4d998c52e769a9cb29b970e379fcb0b58f4062a5ab357c4567edf53cb9a833176c4a8f56f891bcc93968cb3e5bb025ac80feecc2a9dead397b3d916ebd70aff00e2927959d528df50a40707e72a2559e550c1545a1aa598a0615d1c6bea5e31a3a086dd99a4d7bcd8a499e245a97d90996232a05feb17d4e016166fcb399174896b757a5dfe7834389b181701b9198695ab1d92e40b2314c3c10df5c1ad3ddf3aa8c51929c73a29ccf100e2fc45bf497f80b47e728af055b88e10b82f2dfbb107b67ea1489111aa967078787bef912e95094ae149be262c2d6a56b41330bfdae7a6861f5099700fa74618a857f482dfb5a5ff7431ba3302303d76f8126704913549e83df908828c5cbd30d7a80c219890f8d36b905aa7585aa3caf63302d15fa89d71beb7d9957b0af3ac3d370c2c8c3c6172f70e2b126645fba89c637c3fe95feec25301e38c4b6bc55fe04ed7066dfc7d4601b6d6cdd2c1d0b9bb6ced1c4da6c682e2019b4ac8a6d5165b16b0e52fef96713ce597711352e6f6a35f8912b930dafc8464085d36eebb5154ee46059e6a858eadbc055420a059f2ae62941107f0e4891760982165eb6a97b1ccd00f6cb231c62b577b154873fee4391eb40295a05c8444e41356ea23b03e70ddfed863e7cae21049b0e5f839373d02baa8cfb5d2fec91389c7db4ccffeb3eb1e2cd1574f7e2619e457219734653e877b5bf1d9df5e86abca918f852ab6c42a8c69e20a80b9428afc41b706bfd548545b0a68f6f92c40070bea4e36f8f676a5c2a261fb584e8c76cea7a025035a4365bab1b7031dc3beb2f760837ff0381a05d5bb4fd6fd8313a177e9810a8476c22b12342b49004595c2b79dc59688b3a506dc0578fcd5d67e09e898a141695edb5b77c38be5469d46c3f147138d9172b41949a1493f4b61a1d753e954f212eb787b4a08e6828bb1dd6bbb267b424f92373c0186d39b76404045d703e208d177f9b4346840a0e0b31c7f305e9ad1974892190d266b65186179fcd88da2ee68ce6758a3624f90f11d5ec57e0611b3968b43c41e535dfbb1ce31d9e32e8493b90693f0692371c6641d648f706a2a352fd2786587f49552f6dc2a4a54b9f52aceab8dea19c26984e442594fc87efe29beee49508f4f5c4f6e81acf783b24cd62fc20c3b573028f04ab0a1ec2f245e3135b9f970eaa0abd6846b155ba0e3ee18b94f0fcafca92ef70d645ca88a757ac84f40890ae8d9900c117113c16d8ea1fe9729c73502913c887a05f718adc8c0a4f84f63eb652604e7172116a58474d0987d5aa3cabcd6b23a8e8dfbf729e08f1259c08c0902bf69a21e7e47cb31640a71c070fa3dff0bb1be487924af95e84132772182dd9cea57e7de9bb289cf76702332e67b507a2667a17b0b1e201ba162d67c9cab61ed059822f481fa7d7000cdfb46f55c0465d4c12449a324e377195de195d6eef8f86240fff67e11c06cc34e8ae851a066c7712a0cce30e2252d435deaa89ad4e33123148bd64fd19820cdf4438f674dd342003bd11eae88211f6abb9b6d8ef038b88c3fdd4c5bb76495d5d7f4cd0f8d5f9e88ae74c0e57544c8bf0286bcf661294c57933ecd7fce851200796ac1e05eed953718dd61cd2d31cee648bf875edeaba21187e770800f5f4ea42785630ac118650e705b932a249ea933538d0804d20ff19720a276b88181c07c30408ec99edead9d95616d412d0c77574ef9999b642fb6976c3a9c61a05d92cbb32bc441b977f0a6d04a444712e1c19c84790716e4b960725f22a114c13e5f4cab7ddaee3046d9ca224c82aac17c55f56ccc5ebd2a893d12ea742695aea9b55c149daf4760f9ff253730cbcec591c28e4c3cdcebed374c129651175a0b1fbda9da1924b3b646b633d6714b8711fdf87a9c77e44e6a9652775a6baa26020dcd990b64ad523b62f1345897e60cd87a4ffc2e75d11a67bfc9fec408c4956ab96df31b0e3b0459e8d4b8059d916127aff5def8c178c5623dd5625d5339b19b4a1676dfe1199d0088e6647bf60f9344e5f7ac3f7d051ce630c7024ac6c39b5e4c292506b1930dedb1433c7636e7c36232ba9a9079f1a9826340e79b0bf1c203855533dcb765f05bcc2af2c52cb19cc491edf98e404b8a49ec6f897c77624bcd342aee25d053b06291663fe63430e4918633e9e5a6ffe21be050f434e05ee9618fa397a1fea3f1b5980bd47edc3f02c52ca3ede4c273982712406ec6a8b376391b38905225ec9a7167f27a44dc28915e44dd4a1fc521a54eefa9fb9181e00dd36203df27f6fcb5b4406b9c7bba88d92642092f8144ed4b3b2152a6b4a1b7d4452433a04e684ee9d9b7f398d4a8f3f8d37b57a5dfac2b56d96f8da1496ec66bfcc5214e17673b70a05fbcaa5b0cee71f902920102b9028d3933d0b90b4ad1f4c2aa8924b9eb3dd7463f9f67c7ef48d13c1b1de3c101252da603bdb77e821dd303ba513664f9c4505df8a9188ce070f821a5f89b33fd25c1b5315599692dad14a196b868e3942e4b4918aaf36a3a1ba46f610c93f767b15cf1354e5b039113ace10a3358823118d90ba3102176e459dbecbf26c250db63252c4bab7db1fb110eac20c95b4b44ffd7eafea82afe57002012ce15819f50f6e86b46cab028b4c7d1bc8893a884cfd15dd75d79254bc10373f729bb03c4334a520778eceecf770391e952cd56137043d154293be97fcc4449a678f3182c3e861a53d39790e3f9122d09b3c53274b6df0a8a7df325913dc54053352d9a717bb989f206ae525ca207802a99926eea456db22e73dd264f71133b5e2b3f84cd90926c47d623390c79829d2f807c7247f3f1efb47edf1a7a8524ee4621f5bd3af8bde568b65baba1d9b5eab3fb48137eb2a607aeebb2506bdf1d19931a1bc38306605528551fc1df4288849df4d6d4b2f42db3a4cdc054d832a64f13bb7adf84eb6aed9d1c1b4f2c172d2b5aedf4e248e59604cf4937b6cff65f0221df06d0b7d1b0b93c5aa5a36113938b46d9a8a86cb1a68734d0b408f2e7d0cb26a0d3c2126f7e939a6363621fda84e9f027e23db4f0b1d8ef467b3cdbcd214f19ec714cad0fbbd46948132b6d152ea5891f2a6e8a4d5075a33b459b9972517bf03d2959aa2091866f2286c2d9f50163823852a957ab898c27654b1575b1b4cd342a3d1bff20e9c67fbf6fb7dd70dd629ff0d961edeec5fa36268a6e567ac4b25218a5f2dd272b52cdad43e3e2dd4da1958f7d49a858b0e93e4e2cc1b9fc965b1f93fb72feca1f8a91789817366169ccbca99a36c110882bed40ae551fdfe4b3a3a04a0d09555ddecef792b69f160ccab8f967d428f91eb50202b91eb091ebff399c09b58d5138dc6204ffb52ed1e0c7477e996e2dd376089c7ca45fc42c86bb4a8609451a3930bc443f9c1157fcf59fe0c7a143fd88cb544496d163dfbd7dea1817a421b57b2c05c6a4459474e58b9b905ebd2f5c5e5d2878256acfdf82b5a515b3e95d01293553742db00d4bd56821f6626c902499c2f3c3730a6a5021063efe6754a108e87c2fc10fdf3e901faf710ee4dbdb13d65ff5f07f9f8347b8b6be024ce5a195dce9f197d9fb6cba11133d308348d1cbe21fd94ba3545f0fde7c71daa0cc099e108c2a8b793c49b8d8ab90d79bcf793ced90d701793ff91dd8f8fa2d7f52a96a0afa2fe05e8454aafbf40cc9cb86182de395a75862c9de981c782a8d846298df15982e8f8b3a2625aa3a21e1919487f77357e4470591915651909a876942a93654121150f7af5af7ffad7f51b100f67fe2c9b0ba1e45328f7347cd568647453a84d68508e908f1194a3d3f3efd62df033e80b20ab7c43ae476bf47e420c82c539adfae2dd0a6d38f06a811b3f7f67b50356fcf15ec785babe10967c19cd289841751a76cec64ae4b1b56975d19c77f92625dfbbdbcc382b2529191eeb32f4a6167897a3c6a51d27bb89fce22fb72055edaaaf63991475326090f3019ae842dd9ca99c6fd7fe7436280d4cb90d9bf9f8960acdf2c9b98e2063a3b29c375a452f67d1e524a9f0a9e0b709d9205069344dd9af8444fefa2fa9d214095311fbedcc1a5b0c042eb9573a6054d97b8c965f8b6ee8dc1856bbe553d917c6ed49e9fef2a4302c6ff2eefe2bfd675e3effaf19c8bf16ff7fd84d66fdb76698fb36ffc7c30cf0d65e1e25a483d2867c83cde2f07829b7d3eb8f5996d5a592b43b72e3774f25fd23df960d4caf584c5634146e5034d4d2adaf4707b0dfcb78a0d98d5721ac05738102e2d02e392871814de635997c5e164d7d613245df6fd17732c0e18dac32ef20d6be8020ccf329960c6cb8ba2c9754761a2b3a81489c83cb09690b238e06a5105269c0bec667c588092dd46379edb8c331563598a26154519af4e5e99820d4c306ed56e23f02eb69bc4ad7449adc4413d698c9fc3663083462ee20c423477f47ade83cbb6bde41c77e103abf6b6025511f0b591735db9bb1977292999eb9c800a22a954b62a80c70f4299f3e794f4053cc57ac7130a106a499b023640df8c245ac77b0b8e41f80ec41627ec1ff0eee8be94ddf8d3ddae8a4e45d41f43869a6f54522e3fa53a45961bb086641129e723857c1d0be6720563656eac303083f529dc5549342d40942f098b30fd9a8fcbd40799ad1b04f55a3711838c09b338b6f79dcc8b4ef7fc289d8c918f03ffc33f457f348cc5a6698c81860817d8e52021fe9e5e0b3a6ec51991920d5f79d2562cacc6f90fd804b4a1fb8042bec013e6f3be5dfe50f64c11fe0dec6cf8726e2df93d37b34f3e1e5eaba9eb05d739b20eb7924ef0539320ab94c560adcb60fb88ec4264d40be3d7928f1f996a59b631f72e2ba5560cef3eeb25e5bbbc8b736eabd8e7635adc4f0487dd5d10e5f6ce4470af8559972ccb9d55015c1cad2f23c2ccc9cc683aeda6421f8e3447844a0547ea26cf01daea7d57980beab58fb9397204a37f80704d85573974f1e2c0b9358d2d6006ccfb88e34df392bce02947f9231d5324289ad3c655402b454ec2d847a189cac1cce2251d7d69229ef7287cbd6d5cb850ff51f37e4ddfe293c87d5f64c44a1518d63b25b13737162cfc73e19c43a27c223ec6649b42f8596f5e5395b0920ab6598cb461591c023276d6e0e2f99295cd977304797e24402da46d66ddadc088f1fca4223877cc3883a0cd18c52259a318667b0b376374e3d948d917b32ac07ec76573330c3041b2aff518ca235c24eb7a326c6878c26864de113a8f44308881dbba22d8fd24e7b62bfe52f2f156ff2344690996c862b6e3d0e61329a951f61c792337ea43887718db2251679354f16ba689c4fbe98d0668b7960ff07bca22ff406da81f9378a7bc418976175687d3b89251e69d643d48da00a1a78429e8a79bd180af0e2e6cf01ac401f51fb43d331e0c65f901554ec6aea1c20f7df99edaa314f1f0e6c391608e4af24888a05305c8351ba7a92909c81e6232e674a86c77cc10fd5b23fb7d71f40e4f80ff31373abcfb1a208ce4e86a0d8beb2835892f532277ab4071bd3905371890da53ed6e6e67779178cc736801e97ebf305b6fa6fb4600967a1464cad071b7651b218ac6c99cb5d6dd12106223923463879fcd4dd7fb6b69d2571fa834f45d50c11479a2db04af7826d6cb475d141ebf23a7bdfe7663648420449deda827709968aad411b6da3a83f775b9b59a4b80d810038534e9bf04522cb6d6b57758bd7bda97ff13e4c764bcfde14e5cfda56affc5602e8204255f8c728d319819d2db9cc48febfb0b3b33e6b639450420ddfa80c52b78fcee80ffcac1776841b48ff2bc17a02eeaf12dc98e94bb4efbfb109bf79f25fcaa571256bb1e3fb80aa088b723a3d8ca7ca0376aaf474d31c792448508505ca2c77a8141f990798c1c6090063b4cb4ec6fbe91e9c468cc13fd6307f39d924cc2937cfd6e8579fe62863538dbcfc751c3f2cfad1bf3f3db0ad8dff723c3f445e04ac1c66c79411fb0ad2167813e13a7328c464391c2490675fca6df6d20fca6cd81fe6582a14558425ed5aecd0b1b6c2fc240a1d7c110ec59db3a20a996fbd2dbc9c3c4c5dc4bcb399f5b05a11b6569da1cf0ebb1251900baad03333eeb80003f315e2ca1b5e20df5bfd158f48b18fbd6cea96752188eb3aceb18443351d4b03d49db29e381ddb09554bb955596d1613c2fbebf8a618c3eab615d0fcdda0ada95bb5120a5c9e5ab956e0adeb594634432bb795d1e008cbfb3a52d89f4c0d0e00b21766a2d30c4c4a78efa960fc7f033ac9e704ba29f8fb038ec3e8fb0ea272afac49ee9232ceadb07331b1fdb553b5c0bae205a89c4e499cd928aa4d5dd0f58671eab71f7bacc47fe078682972e39253b46cd72ca3a73cc9c5ca070bbfe7c988368eba92e4b670ce20a9022c47cbf012395bfc6844805a2a265ae6dd3b70268e896d6e4af09b609bc9af73edaf8e103fc27030410e27f6ba81c8d911e38173100df66f94f0bff42bd01a5ed2af3eaa5832fdfdaaf7cb6292c4b79ef8674bce0805d052619a90b7f44be7b1f4136967a5e05a5a6cb916334a6b1113ac1bea3d2dc82442d9708871b2fd1931218cb0212796ad96538848b31b9080ece0da5dadd379dab0e089d8f584aab6c98d13373c31dbfb18437bd3ac4b861b36a21d38f813b10df8606dd18832bd790216f92f55fa331f8d0f3fa3b8a8d573b9a0ff9500bf0cece2fa7c447ba439c1d1b66dd52ab0155b2cf756b184570ed8a4696539d82a57f1ceefe1ec497d0adb4298fbb5d828319f4c5356a56fb7c789c55c95df13584a2bb311b48a6446c22aacc3961f929934bfc37af42461150809794aa85f069ea90a66173c546305545673e0b32f214e2d96bbc9923a2204e4f4a05b758985a162d23386a0cd141b72e0f75b06e09b99a85a063e788e563f1b8908f75f83e3ff08774741f1b690a55a17d7ea652e719ee735837f74c248b3eca0a2121f6ad033224d00a2f23508f4371c94c37295760cef9760e6aebe22b734b5d79a092fe3a4bdf6a1cdce315987af05199785ae7b314abdd0fff1684063dae742b1cde2e32d001121fadf546246289ad8cc680a6b5723bc0b7a2bcf847d402a715176b9b70ac725d87acdbfd5c239d0217fd64416eea915367e97e0e6b40657913ac706304129a99f63bb27b1c114814ec23a2786fdbe2f907ba6859c8fa6da379f18ffd3d9574c8ce7bfe58efb4e26b2c28db4e918090fad43d904ff956409dc971adbdb1ecc5f62c994d15487007e7c150f1fea8a362e173f864e868df93f07b0ea098cd487271536ffb74b79e6f401bd7dac4ff92b0f588393e64b40d8e81d0ea37e929beaeb5e2137be07915dd8f674169edd18bf95465923449c9f34d4c16d15cf0dae0e2e93e1dab6465771bb197d82c861d697bb8e02cfe0f1f8ee499e56ce040e50912dd6cd0d31c405928f5e15c1f2bf464f0476246ba24052c48d23529dfdc2acaa9c823ba10869c779813b9876dfa767f3c9f4e704bc1090ed13243ee3895170428f95ad41fc0c6cb8623a6ea20cd4d84667d92b4b042dd80789b484a1b3957c3cb2357679b151f66990b797b6d24232ddb523f02f7df363a670c5acdfad54164a2f1be5a3c7120ff8d35e313f765c5022422f6b5f4bb02dc9283c034b1c78940e19db87074a0257c47804a4add3f2f509a9f6febb3807cd34864f7a36f35c4d0c4c74bf8ba132792d855c7a97983f72f8d9eb5af01df3809472f4bafbb4f8be068f1af46618bf2e273d2a69be81686c5b91ed7054229cd5f7a3f764c9116ae31bd30388674fbd3db211f4bc6c0e6c5567bbcc80cbb0e0c9a528d37361d6806d0fa8b9beb1706b6848972518c148aacd638e33c29cce65ec615cf6e3d4f58b642875290814477b6805bc2cdda588e0f352be592cb91a8467f8255e9730b170bf9b6c75b613e721317e30c760a6da65059708789aac49d32fc30a966d99337f9698debe7d02b0fb01f8c8873f8aa3923ea8c08934a5bcf9597bf81f39cb27e7c2115440e52b24ef4e720605b789c17f5209343647519b921d1d57a763845f64c2eaf8f0af05a7929bd379a86cc8de904ac2d25c4a53251f6ff021a8759be180774ed6d92992261cc76ad7eb7e20b104ec12fd31ae9f67ee5bc5f3351643b450cd658b416b3c6a9d49baf93ea55dd3c48db4013a92d1ee51bc34e648af875a7ba09d4a26c120f1b7acbcba072660ce6f9981754ab7ee3568ef3e123e507c9a9ef39dfdd3f84bbed77588d79adba746ff0482ff1e6421009d489bec74629c023d70df154ed95f2714f8ec49ebd782a863787aa5fe01f36485730ebe2e19b7abc42e8a955999b3ba1e8d9d471d87554044d2cbb25084195d5e637be8d5f591ce76fc4094def9c153675d46e99c7caf94302391048a213fe437e4780229fb58e7162dd84d2a7658e857437826409227b01a349f1697df2b54a1593c47c28100855d138a3ec6e4080b6af7618a50a0c8981d4381e87d651056c6fc81417089b1eb7b9ba6cab56b2f6c4d235623d19df90c2fdfdfd061fa740ddfb44fc7156b17fed40c540faa5cc81a3f42105fd961c5733bd7157ac226ca9d206d61a16e623b0603c6981289fd1f196f0f77aa66833cfb7e9a6904e44173bf34db2a6e404b53f847183abc5a397765ad205919a29f60f44423cc7ab605118e6638c35fa5b0bbd6164fa3522ded6b3934f14cdd68afdc79eaf35800dd24a66a441c410344176592f0b662539f937be534b9a2f68407d1ecae92152bbad8985560e676288a4b295d09a1508f3a9643496cd93bbbf3cbff204e3786fa220183fa12327e5fb8dabe13c606490ca2e25c2ea96c5d98d522d0c79442577a5d0c69ce534cda8d17411e754e1cc2b64197a2bc174c43f2ab110e63782f38cd1d540474c189a9e74fcd586e5696dec63a16b8e4c7c3fafebe971168475d55b1f1824741f8439c0cadf73de2625da6c7261a14087db6906817889b1e50043e8ddde86c4c9fe1bb28bda0a35980223ec12308915ea52f780ee3a1b37ad6ff099c48387e36591a1e7163188770f03f37084221db961e387b4df3b46203cf749d444cef32bf2f1656670c21d0d5fd9c898c6f91a84476105349ad78b49b53570e4e6123ab5734a41113792956a73ca09db2550fff5c2ed5dc40056d0d123f6faa3c091c1b6debe16a864fab664c84ee5faebcab9879f0f6054bccdf7b89631d329c9321f51647e64cb245e2981de15f05b0ec1a137ee6715e83385179bbb2cb5990b682088b7dc70a164ee8acaab7359f2afcfdf2d94c3d0813187624cca8da5f9022e3b4a76a61b12d4e71de3dbaf00865dab6fcbbff66080dd5f95ced8cd394b4d65412a835bd9cdbbec84fd91a21ff031bc69ab905aa0c9989246e15439b38fb2faa0458238cbd53ce4214e0712f09c65edda50c40cf22fb852abbd973f184fdbbd16f03dace2c03567e277cf19ef960ab6dcf2c669193eaf7c75779043cbb0731202db6d284a0951c545b3d89bf1de445af233ce538dc65ff29d35ad3888642d5063e476ddb68a3c67eedcad3344ee53c7b154d99a57741c5650b1c5983b980d4e334fec4d134ee9d1b96b35839ec44508ddea40e5df905a778affb77b2a2e8c2cc696699beed44f6982bd38ffb0fcf3ceaa4a29b62358e100affe2e46124c77d83d7e01b2e39bcb88bc3b2ecf48907e65f5a53f620e0473b87d8c36bb194f32277efcf0d6f7598b73eb605a2e9d3611700cbb6de8b85b9154604c2f14d97210aae40f4d1eb6401f6449562e002ab43035535ff67db6c968580acb0b06e3cee6447da8bc7ad46598a26816150cfae58711f2106ca809576a2c866221f7148183403ab91546ff4ce48dc23aa3719e2245360453e6b18526373e8fdff39da21629f458787029c951256d365ffcca7ef4fde11ef10b80084f4d09e38864ee423a306d10b26665960844c158c082c795bcae0cbc829bad0e67f86de7fcb56bbfbbaa7eef93bb8e7c991c5fb1d9893361246457bb7e63bdea1e298e17209e5a6ab0e456b530fdc660abcb1ad670f904c8599a2e2db992a3a6d6221861a5f34ec6cf22a0c3dee952dec699b5e450061f03a4f51eed0a199fd7cb102a0c4455c86640d870a9706a61f532ecb8cfa7196c2cfa1cb80c573dfcbd47dea9489ff20f10d25148eeb27e565f438d6c3fa90a9ebea0ace2db9e601b0a3478d31796b99573b18285d854b05efb20b9cd8ca1dc45f8b0ab0f14542c4ab3686abc37a57327da5451fb1a67edb861726d6b1069940747ffab7693237363f2112019aed1016872dafb8d0aade43a1b98d0b98cb0c20f90892e1da46df05f3dd2809a9e426de52ba2f6a612ab2b7dcf2cd94ec4f3eac7fe5e7a828363356d388a8d6c12948663bf0b76edc63b45886b9a57ac6f41e9937561fb766478529ac1d5f8a82b1020a7cd1516decea57a5de0c4b9fbfc7570c8eda0d1ba272a2d909b8f10ce6ccc3a119cdb079c35f835ea00815df8110995cdda315d6b209f8b78e0f70d6323e0b0938ad059db583c3dce187c0d9c2cd94fc8060a91672d01e07a9ed90b735d298ea81c02c8e014ee4fa56c86262d8cb62f72d1e889365036df1d858e28b743190c6c758da33a0cb9868e961bad131ef739dc506243e17d3acbb76bf247b1782d4adce79abc55b62f95c235e6006fa04ffc7b981f3dc4077410355da0ad85e3fc34e1ceb8b2b3ddb722ba18c51efc30ee47881bd431e46fb5ad6111a3db95d7c74ecb4eeceb4d031bfba7ea5a13e53679ead281cf11a4f98316b70a5bd390ba86cee7b6549e93c89164e012f8e7bc2630622035bd730a42e7645e46f8189b3860bd67f2449f9074d767a500a51e50d5ddad82ca94d6a07e360b035c31cc714507e22c51ceb4026e966b86bf84665657249970350b3efe92ed15948bc4e6a534180bd23933bd887437b3448e3c58b5c07b7ac4ecaf3a1c27192ed308009408eef4396239ba675df3edc616624beb2e6f2316b04e7e9ddfe012ead062d9505455e508d67a92825cd863f6cba32f5989611837d9d99740a5844d3b03edda21a8f133978276f13211cf93803989126d1ee1c4b0bbc812fc08b3c384beec66fd8871ab9efb886184399139b52148604491cdcfd274105b4741bfc61c8e4601f78902756ecf85dd2438b28f4aa154db393ada4b313acf6bdcbd8e0d5932df779e934025bf1d953dbf3e1258774f3f8260e73e536f7bfd2594cfbff30049e1b3a63b310cdfbc7882806a0d7de3e73e0bf7b2f3e58edf98a2dd4be22391dfd87d554b374fef7916dc129f20eab48f827c472d0f962b5bce37f30cfee2c0060335a273695f64971f24c6c0fb66103e310328618c98fa1e721800a0f40e3735f92fed861ae8e93df3ad315eddc9c3f872ca5bfdbe588427997fb2f0dcab7363dd01699982379e296264f8128ac471132c636527ad3cb39e1ffabde3d6f7938f0dc19925f74c22356ff4d908b48e5f70916b37a9c27edae03142223101f45c46ba9b9df5a6422a8acc2026ee602f53e45de8efd7b3780492b4dea01e4eee54c1c806827cfe8f6c990a0b387a4a6d58a284c4648f5e35469784fe58ba92646fc795e2d3cd5069f7ec49b5267b9c55ace6b2e3314e1defc24503a72e6587d807ee3b3d416fda71bbce97bf248616b5386ca662ea01c76d16fa4b799aecc37aca216bd5b8229a3ce8f9ce675dc0867d7c6dfae2c52918b68b9f91fa9d46ea67e0da9f6edc374d1570fb672ff38fb96a5fa13516828517d4c0ca053f46670f1652e9c79cbc86a99b45fb890db4714881c26e9e3ae5d41ddc8fc0a4d0757c3b2d4b80a93580d3bbdf2cc8c817a7c5882e7416d9dda9b5b060b8eec8c27947c6e86fc26ea8a2ee379910194293bfdeafd2970654a16c0fd83e157446c30ab6f45b8823aa1b2704927d7606fa3912e8fb8f9e2ae4fc6e4ebfe46542bd1befcd3bb9db4cf0e0e3981affe8a1aa2e0ed953fca4e06325445d98b606f9a650a8289938638a47ee49fc4f895cc5d9ec8233c9ca8d2221bc05f9cfe242f6581b60b24199f8b11cf64f253437d19869a78d833798482a0e8423d65abc4877b67b156f4514a52217669962b17c3c65e9296ff4d53645dcfa07f73765cd4f25ece0ca8036451dff09c810f7e795d63ebd2a24f85e66e85d7e18fb10d3eb74086087dbf3320a75dab98655961f7e557400db994c0a65029c7aaef4db048fef819ee6d62336fa2353b359c82305a90bda89f13751f56e55cabffdc0507ee7ce04d33ac6bc42d68cfd131ce4ec04c9091423994026561222db572a69e01a6695d0f2a33744b19d4075984fadf8e38b6231a85b8987ff9710188d6777190ba826fb23b6ab93771ca96c2ba680e69ec28293dd2a0b0fdd7801c8f8f1602217d63d6f78fa8bbd9adc2d64a2b36245e63717bccc408c333fd88feb10d3f9c3997f8fad3e12cd98f81d46049c01bd0e0bb58779f264398e4a3537b40687024a6f609be2d387854c230bff6a9e8248d47a8bbf200260334868513a21ab571df68b6593fd448d5d41b9fa49ef4a0fde8c23201ce726b9a632fa5076de2812e0a0c292b6a1fda5dd81926bbe4d95e499fd741e05ffd89c44e800c197a7c7c04eaa49d2110428e459f45997cb686b12218c62aef9dabb794ee84dacab6bfaf0a609d848cb3a43eaf077d9a2cbf33fb3949c3ff83e7430cd17f33814eb44b25bb7412b74610bd0c3bc3983114f079baf2575a299c62869a52301ad6498ddaff7486f7c1e6730cccc6e94829188d66a00608f9a65f0d4cdedd2db04faeb80f0cfb438b354e352842b022b3bbce66d36422b4aea880e60b8f9184b8e45db07327dd15edfa9ca1cfcc90e6711d86032f3aef9dac3a368f2649572b82222692bf198c7562a41ebab13c736b674f6c98d1e964cb563ef34c6a842aadf33cd81f3349390af35022fe494569a21877bc3aa74fe49f17b1f8520df47274e6747d00c6cec0ddbd0abd97b6979222782521c11ae7060b33251e2f419ab7d6f2f91b474f1d55dc737ced36cf5cf14cf19b4c5e90d9809de7aa99c211b43aea14dc08ab6f281717c207050999127d5174e9db37e657915d630d830e9b5dd052e5bb7941c0a27c4be6e0c94823f339c2df74a47a71fed1f8edde87e8a3ead3e3ba4f81921e86df85013e3ffd824374e9aa9cce494202105089a2eba34a4c2817b47837c2971fcbf7a3889824d9cc773f07e8b8749c03a84f942dd2a34f0b046017834789dc733afdfdc2a7d9ec092ae6768d3674117fcd8c2a349ed74a3b989f0845dee469eda749e2332d1f2b95b3c1e5c820c3b05bbc5ed7b3a533817ca1f570c8c4d5fa934e568b0d479b42835ba38264bb0fb289e4f597f9a0ee6d2ee3380db37bda229151a640dd5e217032613b6cf9f3f79aca7ab9963aecf70731deddb90d161ec249bc963c59801ea91fc53c0073cfb7d6df7a60de874d2cc7c7540078eba969f1af701d73be72814d04da322e15e0db1f7bb1dc348edf6111d92a3e1688a24e913ffbf047cf542aa4e5bbc7aad074a46fd77880e0fbd2831acce68e97169eafad840151d74f3c4a8159b2a99575a61d45cf0b2697c9de387db478cb2fd10df2593a686f9cfc7beb9fafc44cb6e9ef04803ee65948a9964a77bfdb70c21f0bc4a6cec826fa43d106f569d3034e6799e20471ac7dabe687ade9cba82cb03f60b6c4d6682421116a80da21300a4afe20c9f1131a97ed24665e7269c1aed913ce3dfba38e167e99d7b542ec2fb145d9ae0e553b603454684a495bab62abf921637de6791613008fa69166d429703d86fb0381c51dfeed26702d579c5cf9f3817ac39058bf34c0a58f84c68b903ee2a938a95d2c9259bf6d3b83b1e3852be1f789830426ae5c451e86cce403dfacb8fd0c20d53d611d9d47572f92e2e8f0268edcdfdd493aa6e60a8647f289642cbcfa368521184c33d78f854c63bb16590e2a7fc47f8b4e9ddce32b1af2bf74bc6cfbc0add919d9b184f477a463725af50a67007892765cb88820fbb123891ab9d7121fe49321c85c3a0c01d4fa3390929f1e7e48dcb1c9623d6d8fa24c5b9c017b3d430963c123377e0085290237aa2c40715883c79ede08522eb7dcfa7f721d9b86c065edf0dd49a7d887c382d379c80860322d365b5f3963b44357e9ef78626b3a118d63d9fe249c1b6f4a52040bdd773ce27ea2d171b596c5ecd6eba8745b206b5253d7fce30964e5f4b1cceb66b64d223fa5d0e30250239fb18e889fb2126900a8120e8be2df3de3b1f9d8f52950cbeb4e008d871a146b35b829598aa3d236e5c22a8723e46ae966025f204325e1942952842f4a12aa71c834c2464baf7a183d9382c8464dca824df2b5e61b67b0448a40f02089f70a83fb6594d470d71311ec972c416542c1a655398dccc6143019bb4d3155ecfaf2dcf7fb1e4b7af4e21eab56358c00721dff902930103b9028e394ee779c8de702a60cc457844b3703edfcef2050e83103dc98ae936bd62882bd7fc77fb0f2207c872cbbefb1bd65e3dbf525c8ac31dafcb324d163454d5baaaed1592510ca2159d8e2bb45450ed51a10dea911cfe114b9c05e2d3455e14ee274bb3a76558f0d6d45f9d5bb572c2e9f2d5221d8e7d26efa69adb8cbae26a22095b4d8ab3bb6f59d8cadbe97dfd3148b248f9629bb5c65935848adb5169dcae7ccbcea2faf3344d01996ff813cd92ecccbf79dbc2ec8aa2643904d74499fde6f3b23931acce52111a633873eee7fb8ba59ef936ad81617eedc8b60d0f44a564df0c668d457bb35cc720032c54f37b785fb6eec35aba3523e9c5b06ceb18191c398f7df68d12ff30b47df81bd730945d56cbdf7318322432cf5081d3d9648f5e5638999da7e625092549f2110a96e244a9297ef38b6a452230c9eeed0b5c5c49a251147751988bfc8ad636b5efd185336dea495524c9fc51053b048dcbfc9ab2510b90532f285b246f3fdbde832e85302b1da0ac3fb972f9e3909fe412a4c72610ec7fdd996c490a251f8fcf742642410c8d4a2dbb667e6510513a55feaa48a7eb5a0236746accae67efaf82b1dc022fc0af24fd24630248f19a0b5316969c5c63425194c9bcd50e5f0def731a499d82aaf6e0606672cde0cfed1437974b23ca4af1d22689ab825e18360b4aa3ca722fb67b9b4d67a8d32bec75a5a3b26c27cf0445f6db583954da733f8e0cc700684cfc8f8c2b18ba4d5f8a883e36ed0a53104d2713ecefecad7aefb8b268c4cc521c6e130d123b18c2890fefc158d64cbd57d5493c53dccb6d6f51a927bab93a511eaab53b448b370486ab42251b2a5cadde63304d336552ee4bd2e5cff0b9ec69a48979b0190a6cd9e44a89dbb2996aa99ecfcdcccaf09c2d7e57ef3b4249856af91eb50203b91eb0de95cbf946484d3e465368cb759eeb4dd712c02b4e01cbdf3278d2622e38789afbb9895d62c8e268d455ab3f491bbc7c4a2d39d93691015dc0d8908d8d6f38d878907d35f86ca4c2e222660e676d8b78b9a611c8248f1bd20ef7fa242c6865da15319b8c38f836c76832112b146e8b641caf12bd27984b1d695bc2a78c4ae4f91b2080c224a8952036ab431462e86308aa3b30101ee63d4fc59680c906b4e1960e946035df953316fcbe719f9105316e9aaabf0d3eff8ddb48207a574455f6714b7e3aec7ff20081394fb5dd8c0610284537148b356ac5ea2647d7705c884faae7f072f41393123b9e9db23e9199f01f19c3b71eb216f20dbe36fd89eae7eee172c2715a8c8a85e13de93b0a8457c43245c60b935e9c9f49d3d69cd49cd86920416a9dbf184862287ca5020beb3235a9caf2670ca72dc6b38cb0af84d4bf7a6484a984c3c556e218672c3caeeb0cb332e01246217e375fc1b64638eca0a46f8d4f28e8347751a32ea43184a5acdb897b1be6337c135594b54c2a9adb5c181fc8ce86644f790235fa9937363856f5177560082c0effb7b382eb12208b968ae62c96db74d1a2c0603ad317a82c5fb2ca2458043e8334ce431f041b89d1bf45cdd64ac422c637659e9bf3583c8dc3e69c12f6058e862bcf33ee60590bb785d2330aca2292296a4cdc3d67578a2a08454d2d113ff13f3a8fca8c08ad543521f6a5c8b9f65130f6d9aad7d2cb42a8b140fa6abff2383ec216b5e1540f5ef65d6df9dc7ee3e1b42e2a13d085fe54f5f2577e81a662bf9d5df42faf73a5e553ef6a847d88e94d0fb9cbefb37288e77b0d53a3ca1bf6150df200b2d49abaa344623221738ecacb6b08eb8a5da25f5fde62647793bb175056c63b32c26518baa518f8759d4a364b393f5a98190a980e593d1f14e8e8e26a4ac1e5a9d89fe91773176a1c590f587efbeb2df1314e79136a2105a5c3ca102bf5f8661d924eb24f12280fc3ba0359c82ff1393f86914af0e7906d0505b63d573cc8ce201438a9a8b240758dbac0887e357b0ae8b3b790034763494e25919b3dd34186edd04060bdb7717bdc64ce96fd067c758ed57ff8527ed33ded2ff0b7e0020f4391661e19effecd2b6336ef6a307ca8090f0e071b25ac82a56b1be8f01f0a2c3c838736af82eddf5afc3d18f6b873598f81a306bd4e95c151692babf6a62ec0ace16783c4cffd7688f9a9f805b7eb7a716f878a1b1e768645cc5cb07c2c1c2f918108d58d21ee12ef5a73bd8516cfe7b66f9a24377f42e149ebeb4673010f24eaecc6db548b1365130444cc62075f34f18718b4d1a267422706a17047ea688d2da82c590571322601ac7f3a657716d2ffedcb415d9fd5457d15d0707e57b4c3976c94cadf2a74049f5b396a97f4251bf8237688d2359b15509c486f079cc1e6aa4a9b2ada6f8f858ad04f77bdd59a2f510146cc9dcae02293b633cbfc0f8e2e9376c101cd8966a84b66bf5344e79c8a7ff7bc93e725937ef10f2a7fbf62c6a86d27f6ffa7332b7293e68f69a4cd58dc6903ebb4703130e48374837eaf36d9b0f5c1ea5b9a1c7ef19564670a53e77053dd6de0301863b549ab19def71124781cbf0210b0d51d0381b42361860482c9de9ebcff9dc7860cb73169fb2bf9b21bbe5fcdc50d62c500e5754f99de8df182e1c9d620f29de32667bcff5a6b3e76e069d0b873d6ddb0ea633ebedd48d40161f0bf7cee7fc4048471463b83137ecc2b17c98de7071c23b7c1bb11439fbecb51019bf93231102628392edd47b418c7011219ba7329230a32812779f6d5c95f07a2f6940c0e3f7f0201eaca738b9af01e42aa8cdc54b22a8cbb0e152fc0d41c89db41d0fff1ecb1a33bf1c5c2e0089e6fd1099cb6effc0660ebbd51f5c28250ad56b4f556aedd7206049b4360ecbc64511c2048aa24fad7c07a503932a0b92167143aacde4f0e94ca82adc724a777b8a318609003dc2a5a2dc80a726ddba4a7b56608c4862d822ba4d4530c6b8529baff9a8879c421ae7ef482caaf1b08fa4741f5c7ad89aad2376908c6cb8e1bc943c3b740a00cdcc713c6563ea2f77a26cc3b795e07b932336b314209a1a1ea21b6c47eaa778197e7b18bf59328ad78c27d963c7b3868cecba6ad5bc1c4704d32a88f1bfcea2dd44b6b9a67423f3c93f81e58f24b9c8c2b8368c589b25aa602b0d25d3ab081eb2f079c9bd0b89b9e6f86067677d079ef055081c15477f75c43f3526265f8d1b2a9b67cfdaf90493e39de3b8f9457dc0105e17912a792dda12a5172c02b9db172f4a816df6c15352f565c7125affc5316bfe3240f1eb32c384ad54dffafaf2b11e686195114ece68e6b05347423f8f394fc32b1f2d5c5b15613cfb193503889f6517ecd07352fc3b7222ceec788a500cda309eb5354cad6600cc9ef8b2b53b12711a515f7bfdfe5eac136e90453ac8f56564e7dd08bcf73545f1ca76816577cf9d291d95487872db9fead1b9d06d8fc06532d4cd616cd25c09e83b8fa218853978198a349232f6a2f82fc86a2fd9cc5b0d57fae65a81e6bf1b7aaecbf7efa977ab559eebc169222a81edf539430eac335a336f7f59904bfc26e952084a8e1c0c69f9a2a5693384b9fded40d3b777e3b5db4f6db882ddbe78c467c68967ecb9d57ba0b7597438252c98f6733d4fe47f42ef4a3926fd2857fc2d301574a48f516e75d32e643e49397969fe9505987976f5e4e2ea52ec193f068d36d0acdf14c11b06bf6fc688688930498bde50becebee6d2e08bb0d500c93e9f739113f71d422ed34c0e661d9c115614af814126fc5729eb810c566c3b0af7b204642845479311dc4d9ccc4375142cfdf3bafe1c9d83019023acb8c4a7d57abc914c81f3dc1ac278203a95b04c59a8c008cff14cd8c39cd4bde673c2bcc06c69cadfe55902cd52d1c4b6ad9a173a5e2499b8409577e1546b5835047dff3dad6022a4da89eb227dd7985d54e493fa2c8a751cad9ef4f99ee9168a42b99597899d338858af9aa205d358df0d5baf0de139ac8d2f418d19459b6cc53a17eb5327219e8af50d3ec74d1d83061939fe629dd519d0ae32b18ac5892604da10d2b51721b775c1fa336eb759a2e9a5470c4921ebab18d3ec663a694a39d6aced7b1e99999c9393fdd71e4e92fad7a3b526789793bcbc0639cbf0d2c59eeb062a61c956b09ce3821ba75c9835b14cd8e5dbfce3ad96e3e6415283b5db09538bb50b30e675de9338de219af2b655182decfd3c79f799811064fbe2a4a028d5563267e8934a1d775a934375a87e84822cc1e7f226999552faad8fbc576ff914630d773592011690e8de281d013216f47cd47dd236f3d1620bb8c80d682cc8dd350adafd43b7db6b66836c4513f2a454eda8535d92db5e402daed3793bb156ea18e115658fbb86bbefdbdb4f4c28ee5a4f5abd739eaefdb0c828b8c322634c3d7935f3cdd97384f621e7246c5dfd72c33caf2ff8274036ed70eef5cfcb93b59577587a684e5909f9faa0c99331a8491f854052832ff43587363f52d97134c47e34d7af81d272b7340e43babc003cbe0a0319951fdf2ad58cac9432065a2849fff5544d2af54b12b77edc37162f180365fb29ac74e1c97118ea2d0f93a519e02747483ad9e4e87d15ed190d68d20230391a74b26d7712a2b74031c2775213fe5cfc1347c32cfa0a21e9434d1508e4a75459228daf447b2705061926ef9323c397ad1dc37ae50e03867817b02bfb09b20ec4276e1e85cda792a4066ce870a5703b4f120f8adb66bb5a826d4d4a13f421df0195f56abb0cc434218946ec04d0cb370eb73f80e31251ebcba7b8dd64c2a1370df0a7c04bf0e22552fbe328065afe9ecc3288be3f4aa7090862620629866b2b04fddd58607afed09b320a3f4ebf0971c299e4d3d2777460af36abf453533629c66b7ee4ef2c7c984788ede10954749c42c6e95e36667ad8023cd851c32e6dabc93097ab408958f4a92a41d5d601469c68a376b6495a16a834dd91df3419952262d11e4993bfdeac753b18a874c4ddf273065eedb609a3faa92287463affdf94f9cfd609ec3d27c0d7568f4919afee3a75a286619067f7d91cbfe54f9a2eb8858b523daa2d8866c804b31b469c4f8ade159111fbb1f6d236cd6de2c696d88088c6c54364323afaa068ea01fa5329a8b0f39cfaf8d490745ee012cfd1ac77ae42e859f4431934d03042c57f86333c7d3530a07ad196dd27811c5fd18166fda7115209a9a276bd3f519ecaa0cfa31921d2eceed2c0376c1cdcc326e05d8f53c43dfc4923e3b3fe57fcd2e4b889b2ef95ea36d5b05a66863975ee6930e0fc398fdf4b0e16e524750f0c530b593dd94c4394aa600d219b85fcde71f4da10283ebaca9497fa3a7b2e5b9503b02239f2c57faeec674ec7b23ed44b7a472e8b10f922e170c70b0d1b30ed5d768f82e254a6510e6e3c33b7683a7bdf28319d47f21f0bb1db2d176166761b1982d5ab039f4299218cea8cf7dd65cd5fb934c5ccbe0fc6c7daa2643af3f76d8af6cbee19a2b5a1be93a250ac01e89a91aa4593bef6fbdf56145108a2445306a25c992f45172df4fe48918101c3b3ddba57cfb1923ca15effe5765d7010713bd4c75d94cebdb447dda7019f26326dd22399824a2d4a07b9cc5326f11a4a6a56bba860e85076f031b06752976cda18d63e68c7897b5740d4f146d121cea2c4ef45238b51a726e0a98b49af3cc490dfa52a26e06789d4916f1e75a4389031e7eb71eec950f7a76f1e3e02de70b7269658298592b885fc97d1dc8c029b49e87069af18b2e04212df272690e03ee64fcfa962d23e2a504c074cbcd8cd275305da2c3687a478c7a31bad1fd8f99d8df999c3d57144ab83da1cc38c6c74c01cae3962b38d9220a86ecd4cd8134671c8aa9411149cb400fc34dd4bd67c952e2ec4de1fdd6c893ecdeb4667c940fc8259407910e369534e8abb1d9c897e28a023613ef5f194e2c3584dbe51cc2008779567b4bee7edda1693d92fa71eab6ab151fccd87deec4ea9efb2d6a434e8533b60c584725b6ba58e299482967152e316459ebe9e941201816de02280fd6322c9d2beeb47e9949995aa552dfbcbfc045b60c21ee54181039566e9ccba9779b978518ab9ddccb1cfc6a44639912443e66db4804ed2da64bf819dae8628242cd14a181f61a99bc1673ab316a48748a17c87fb4b66009753eea50234ed34cd75381f8bcc7693e63399e85303be2e9f28a0a9c4d8432b74049da400ef13f3e5127dbb8b5e5cd64157a7b8cb2bb1efbbde3c4ca46d2dbfc17bc251bcbe5449ed70a5f115e19a7f2c7a0340734143bbadb5ef6c56acf0adf0023121e5dd7b3e618a09e1ecc08e065b843d286f681e3fe77e81d3c07066c0dd2781eacb111ae0ff1682d3fda0bdd8ace5529b853060bf620b37d86fe79347c11aa2c5dd5e5c7f79e3bf6c0075e09c4865f345f8c5675376fd3877563ef008cb957a3c3466f2e93f99908cd6b98e4317165b3e0a389c8d9b14811c9ea9aff08edf8b7d09d3580e125d7ebce95448752f23a38ebc4b7cecf5461f20e458d8d5e1002d0c271bcaec28c9aead3245943783d505620cacfdf46496c0d716c352a27a9f32cd771c8a387b69baac9e2ca5b5429e39a0dec6ec3028ff17d0e861fd3fa2373c0e0736d2169de0ed397e61ffa9ec9d8cc1413ae6d5d0eff29b711cfe4601b1408d4edf1e87b2ae7b500c9cf9bbe6661a8183571582c8ceeeba2fa7a0cdd8f90d40c551d3da36bc04f1adb74a93e1c184ca508d414430ada15849ae81ead8ce9a7d7d4d714b4046477b2b4a22f57215ff359734a8fff9d172bea6630d7f2e75ebbc37124337bfa03e6c108ce00fc207cd138973de8b6f0af3115dd595be7bbc223f91cc19b13e6d033888c9af075ff2c5e33ebf32fd63c58f93b59e3d362fc80d08a9befb26602f8e678580122a9cd7b01d4fc031bc3dd0be2c8f4ddb1bf87dd07e61f8f18d3f70689e357faa387bf6f23d6c7c6324b68cc43b963a866fe4a497d60a99f9c60bbb5be0d1304b0cd61bbe8b10d532e01fdb83459b8baf2722891bce738e1dd371756d6596191142e3ffb4c7b627352b14d30e317158eb9f57567a3291e9edae38f72dad95033675ec2f4dece0474ac431f560c2053ed2e6a0849d0ceb6c9d32511906d421b8b379fec3c6dabf957530b943ed3c535b6d03e4796c4463d2accaad91f49c1ad83cb652bf99bf49de259255e39d87fc12707acdb0bd6b71272c7dda16445cc36b67db13684d8dbfb1b8e55518c10d669fc1c9594fc61b7bbfd0bc147a4224e751540f9abcadb399068995d273ac9375226c8c165d9c481082a6f914d435123187a6cfbdf46d1524a0a5a598bdd702e693390c8adaa7e75c3e1d533f91af23dc5a44258f59934816a381e8dc3b39f05f501e0cd1aeb9858d65f063ad62853d33edef8815674c13b40d42f6ec0e3683fc3f0b178eb77251633e4d2915ebafe4a234974f131c99761f96882734c54da0144d697bfe8f1f16ce6f28934d0a7a4d4196ce7f2d4307792ae4c0cf2febaac5424070fbc5b7f3852cd1d68c3832382a4ff37503fbecfb138c068e2baec06f87757b4700e58c8d6ac9651e6cc3599658d6b574792c0cc58c96e5b9eaf50352e2b84a0fc0a051d18aed5af391272f98abb88ff14c88ccf6aea9be3cd05eed68e6f3b7f497386e829610110449f1001d850d8b1941b38f57f2f09504a2f71ce678a6d37de2315d7cba5bd57370106e461af7f3b208e13780dd0b2a801cb265ff8df0a0d1e043dac4698ef5a107445f53b236d3853175b71a6fa48f6da15045a3aba07d74caf33b866e53b053b270652c01b3df0555edb06ec660d0c804c1694087dc907e5c9ede838877c1d4f71bd6c45d4c510c727eadefca832f212e07d2331748a357930a2259ea3a5a192b654f800f00a1e739fc42f504fc90d24a5dd7fc2aabc8e247f703fb57169789301e62c0ee3c4c65f0fff5fe26fc961514ad22214cb283bb3648583493aa1721049c49795d0fcd2eba174d09a0871c6d6f69cd37c873fd945ffb9f1996512e642e57f4ca891fd9f9434499ec502593ec9e282d7c7adeffb369fa70fffd7034b33063aa112706ba4fa4885c64446af0b24f2d3cdf0f562a325fc7df8c0dc9aff17f6852118d5e8d546bf14c40b9064d29b9e31a0d61159e7e1e60d3a01b81c80f69aeda597487226b967ddb2894f4fdd50e0c6b564390e514051787d7628a84b1e2c30806527e8cf022542cb24d618a4904c78e27cfc79c2b395eb5c09ef4ac2dea476f77aa31cd0813f4c5627b3fae0adbac82bdb7fafd871794db06f8a4bbfa60f1c86d98de17ad2493d812c468291eb4221ead96fe74675980368f39c45c649af3786fc4fdf911574186ca2ebeec4d39c78fe1ae960ae318e62ea3528a320f0ce4e3a98feeb6edbd4449c07a5c7e589ec08d0309bafc558a33c443c0c1acf44f4dc16b995cbbddc3650e7870320e73202a42b52d352aa77cd8e08594c8105c4d30304605a6074fab07300f9669b13920feacb87a28b3a1ed0833c49b9c6fffef94ead1ebb544c6193cce9a603f637c291c8525aaa0f8cdff4f20f916f8d32fda271c521b80c69aa33c33901e044d065c5aad9a11b1820110c5e19fc34cbdfbae5b1fd97225e06240bf5b1af3755459a931931438114d6312b945a97ecc4344384e157cb254a56c4f3d889bb1cecac08d244808eaeacdd04335b43a13047eab60a6c878cf0710e7b6e8a710836a24524e7596f1493fe92052b6062d8af49e234ac2aea839dc9516787a1f09b1f9bd3909e3c3ac5015ccd3d19d7e7777469653d6c39fa3a8ee75a3dcfb740824777569d3be5ecb6431fd2254a0459b4d65bc9fd98516f3edb1286f12c592a4db8ca553ea23f6d227a0a8ef97faacbcbd199c179477480e66f09a50a96146e98754b17511588da3c9e012e6559fa660098cf0b61098a6106763f121b920468df33150ef907da6454ce9fb31f9cc66b4a2ba5812f958c1f367748aca38851e2978acdb516a8a5862ace82a5ad618b478aa14cf1b679e03f0284beba17c32cac5cd677925b050320136b0dd7de234bd1fa15f825cc89a545a6a03692a32ee8ee2ea49fe539ec4a935afa5e80e68b7fc7809fa7b674ecbcb4b3e9e78fb59397432d328c12eac53ca0a0546591b1eafbb443a914b315c63eddd8c92422c1636b725c7e5dcaadb25d8eb7a8d8068274933ca2434b1660df090ec54526409492677f2a55e248d08cfaf9aef7050846021d20c143dcf9809abb171d25771d452c5ecbe046cd12d5de0b9ebeccb84c2dcf04c65b641968e531e9dcb03c934fe5e7f1e8ba42b2b7c2395456f751be54bf4f22a89e1e90b169625b5d2fec6a8f8f457795c9bdd216de947059bc290d1164bdfd7cb1ef0e04c26551109b32f2d2166e9eae65b6080afc9b9a5876b2de31e0009963c72bc2390a8ff020bd7749dcdf25119a2796495cca1618109fabbe9beb2c8659b10f764bd99088d80be070703735292ebe9410ffe6c18a32f1dcf58a615707fe7c05808c968ec40f5f5ea3129c73da72ec04acf694ebf720deab9687c57809089fce3577fee37e6cd1d9fad91e55a69923f5da40a767da4e09d55859c80867699c1ea98d0dfa35810f9012dafcb11220b4ee565264ce0a21da2f43ec0083df5121b217bf1da5b6bb928bdf1441a2cb8cc731504d46365067cdb9b9d285071fa794e244cb82547902e4f3de57b9d01d96d2a5a13d5c028ae0ca6e0f4bd91a940393a2a2f491f61e93d4a4df65099870f465e6758cb674a43b909ff432c648245aa836d7b283e7905dd5daa6970469c515df1ef8f98cfc7f78c702a3491a0c735e9671527a2f69556fed7d1e77825d56521c390dbc76670a33bf09bb355a4a3286b0e2fa6e34e0b7434b3dd06732c95660458d96bc249614fbd6e0e34aa8a72e8593a43fdda46835d9bb85be5cf18248255663338fbfe60bfdb9cfc01e3c1e658299b0dd4d531c92ac5e138a05f15e224e88fc4f6e5df4d2223f97c25f6b4d4066aa517af38eef80e8c3eaaecb5facff02e254cbdcade504b2b483c9a9370dfca41b9bad9bdc795b65cc180323366fb9423138d9856f31ca7590a08bef57571ba0dd7cb98bce0c1ef055d8a631075797e0eb770d53dbf26e0532fec7a8bb7d186e6fc354d6af986e842115c4600c24de3de8ccc6a6a1704fd6ac1a1b064601fee4928f41b300556d9a3ce70bf1fa4b30a929e67e0ddd53db276946eebe02c53d869a66b7e03e689ab3170fc5af820ab9609fbbabbe14688d1de70999a51ccc580cca4d1cfaabe8e96115657968b5d25b1e25442532eafb7fb5f2884cf03829fbfa4dab5cb5d7819e21e6b24e2162569eab051c90f65743be33bac90814b8701b25d257a57d984dbae7096a740c1e28f829d65284438446a74efcc5c01f1052629ed719b628a06a43950b7a199768a6c720607e3c74386bd827661233a045d61cca7e62bdf7a3da24261cecfb1c9dd2873b75ffe0ef546872e4c7ba8af838b61c762a63d1cf3efe1d0ea4965ee1a637460b6e6d85dc5a0db524ecee1f9ef95eb54e13dfc62373159ad86305e2ba0671dc472946a72b5cb37df47fc093894fc7a068d6e7d85d8e5ea181cec47d514a548ee4ac6021b61bcd8cb615b53cc2351d30dc9f44111d932dcc2ec6bea0343f993fd6f6eba4ed01b3ab559cf9becd354b2e57a8d5eb150dfcfc648c9fe5f3e921417322eb6a1fa6e74260a1fa39ac5c48f4c94dce11d6ae191cbf3253af8b7c1e6344067e94ed134fdc88ac1e2402c9a064a22977498879c1c74a090d7c0a78608f40449f4be0cdc7799583a304f6639771018d5f1762560c3b97046511e6dd624b705d1a248a871d48cb51dd0efd20420405f0188aa07adf5ebb13b6f65f65431f06a2481a7111e1d1c2b9015e57a46dd5c52f42a93d9b2c3b148dc55e1cceeaf042ed81b9ee00fac636ed545625951795212175793f7591685d88d4b60d7d396d667a9b1c2d39e088e7073427441a7d9e2ce356f5dcd93c056b0aa711008414e96332dea7199ac64e762d842773a735708927e1a6954af56396540f5262214b13f6cf333a9d0235fa12a1b606eb4cb762a17bb3c9199f54b9207255cfbaace3b03cdbc643b4f72584ef3f9aee066e5c7f6d04a0933c6c61fa2e8c87902283f4d1df4cd45867cfd726df7041fccb42d451741c523ffc4c9658debfa5870f12ecc7407b677aca7c74bd8642e47983dc58910d92f36f131f0a879d16a2b5abc3aa2908e9c446fe61c0fa67a42aa4783c8d72c141abe03d37a218f8a7ecf90544c3cc14512d043c76f03e89ce5f1690be0158398294d1f46d8012eb3dddd00019289a9894da88814d6f77dbd73d1f5b183e1472d66ac4380d9672d286c6776df2c93b9a66ab762157e36fe96a4c3801cb608cb4b2ad52eb6cbb5f140c92ebfff109f4fdc2712917ecf0b7b932f2735524c973b05042d1d13a632a1fb5f505ed9ddc99f26c305d3153be1d1967a011de3b5c5d4743b11fe45a020a403fcabded9b723c0a282617425649948f191ea2121af1935c6516ea120cdf7d2b48b31447485e1bc6bbb12b6ae0f64cecac89ec73fc9089ec8dd7c34ba90e3b371d3b7d1ddae7953a22526ee8082b86dea49143c71e32e5e8ef6af3b6057d9cee5073f271a20d2e7227870b82366286a53c5dee0ef18d8c31176e523d44563a96d85ba50d4910ce12de9ba0e42a335d7520bb62abc374ddaf576e307a902a07f4bec19ba46ab1a3d59dc51f4b38e74906f955169dc807950898d0acb4de2784dbdb362ff3f4ed1a135678cc267ec7113c5830cde5777e501e240ccf6bbaebdb66fe9fa8f83008801303f9ad4a91db476b7783a8a5ff7909a89f607d2b70b7140405df2e74f8552b3f3a52cea257e8d13880ba49a86f5bd25cb0af174e855188b117477c1f8bd9a0f65a27cb5d711a8d562176c0adae0c6be0948aa4df1bf74c761059387d944e8fa9dc1947286a145d4d1b656ca7d116ae5601f6312d56f5ddba89252c9447826cf3511bf10f9780631e02eebe2be93ccee29eafcfaa77b6a913d312cf6af902940104b9028f39d7adddd1d090acc1ec128381557e50e4e456f230ccad80c5cc972308e3973b45e89c59c6045daa663ed25d5c54508cf81c3e1460c630d2cba188b105029b71d4cc2d8c1a04d3f6e0b2ac117171127ca99512d1b7a357d3421903adb6424bd19c79aee82a7ed1239db618cf6fa97a45a125c84c4a1e669ff7c26d8dd4fdeee24724d973290473320c8a24c1a432975a67eaecc18efa62bef366ff85167179e265577768f8e35f661630d66abbc53ec50d8199a282eac03cd01d7ef3f191fb6777b09f13b06a75d79882c8c466e4128cfca75ac9c9796e95d671964afc760855f6363e14a83f793677e0cea7e51ce96854c8b27ed7cc57ce461b51792a3bc98ba94482e873bf85f4d8405025a101b3e39c04aa4bfad1d00d661364e1a71e980d772e930801875ce26af451fb4a99ed7bc482b7a6665911f72a1be8aa6c31c8f9b8c2e3c8a20b39d42a14aaafca36b4b2a4a53e7752d56ee2754c8a06885c3a112cfb0fe8e849ff732c86a3a11aaac9ca2d14c3e3917261778237bbacd90abba74f62fba41341ecdd954dc361bb6cdfa9d1ad53acbf64ab6af81b649931b6ee7cad7477eb42c989dc6b98b423502c75c6d3e880566c7849eef65c98ac6874617d7608d984904ed319c5cd5d4fa7b96609ffb516398fdd00ee44ccabdddee14b55abc6d789942dd39faf0a5d23349f15cac5bdb676dc3975ca9d9cbf98529c87979dd74f205ea349a5b397bd698fff1692ce54384d2e73ad842d64876724c39a57363f3981a886737bddce71fb16580ae10a2027a4d5471b9c9240b2bef9a73dce7cb17c5b255af26aef7833397294b0c798e59922958cc348d7c64379369e99499f4734ffad58559680da497d2bd502031870ffd7ef9b6b0d8f5b5cb5fb4272331cb2bc6a6d85dbcb28580c1ad9ff80f91eb50204b91eb0ccc7b75a9bc21ee384a022077291b929d4cf8206318ffaa524c705a2e5bf789d7cd7dfc29d4c3685360492ec21a42b2bfc94e7396f516523b222d1b7dabc6bf58c1544996469e6bed53df1aa5ebaf200a80283e04e4ab646d7414a7f729c5e4c93acfa482a64dd3abc7a3aa7a4b19fee98a225e473aaccd30e50199162bdcb2f17b96a875144e4be80a0594d47947cbfaff82c98c7b74578503b954ea8b5152977ce66f6e54fc83cb42e0f85a374faa4c6c9524022e1bf29cd66eb28ea80c142bc03d0a00580e2f79bc31d241e99e88cf86ebad886c908cf2f615ebfdb1ce4f12974770b9a6c78f489079a8fd74ceead956c238a276b32f4b683fcf480afcb8e348a1b6a28430b91372d8054f6aa7d53dd2f80cee13c8eb2c18e3330ef1bed8eb0c15cadea39657bfbd2ccb790dbbbc179f080d3cb6c3dea01498da3ebbab06b9b6705b64d6259eed7a350d77134b4b2dc81f72884d1316732af3f8c6f7204bd0f01c335b2ecbb78123ec69772198bdbaab8d3f4a2c90cbcdccb60211ea138d78cbf3cbcf595c966d15ff079a2571b54367cc0fc25f797c75dc9941baa0dbf1369b713b830afc9e091949caab27e9e968fc10e58ac3c314e7deec1b6c4532f0e29c3e2b7eb4d777a69b7436b87e8afcabf5ea0f023826f17f56b5bcfd2369c1e47fc0fe28f2f81bbd79c97fba06cdb7028f4198a5e514079c3fb23ab943f1cd3d57366ef48e038d7889cb26a7fa0c7ef41e3070f2d28ae4ed097a92d00ccff58578da44c574f4d4b05d65d96c404f39f6f92b69b216fc2ed3269b945c2fce20716dc41f8cd7598b0810d0a9383c0a002506e136f7e2e139bc475ed34f4c36f668f79ca11b8229873937fef330d20abeeb6d73eab5e362590d6c79ebc33134e181c7502a8801200f3d65baebd748422ae4d53778d4d321d51fe0ba0e53c49d4fa9d26bcdd011252d9127994ca83889a5dea100714d1b4a6a3a21cb98f796dcf4ef8f74df48bc26d7f057771fe5f6c130790c9a5b3c5405a419ec4159254a9764cb852d9cf30498cd2dcb0386dd459ab2329d4a959ae48735fd12e8ea150ff765f9d3abbad7196b5c26c3eb993600bae0d566e18537ca30c3824e2dd3a4c327fbdadcc560a0b98fbed99edc5b8df5e93f11780f528f30788430850e2c3c7658d611371b2894348e8f7d2773b0795752e7b26c4aa6a10bc3b4be64300bbb54eaa266f30d68cd4b590011db4e4bd25e0ded67f748d396d39207880e6b5db392ccdf28711a4f705c3be70f5ea97bcea8102bc5a50b7f61f0bd2a443b47c44367242d0831c468f45e25ef855c72b5d2877285250e813089b67a54f2ef99af780af878f85427c7361ff69484fc1a0c51798d40d1f6a2bea4744f209e3d5e9e0763a9d091becd9e8bc26ad7fbc2b4a8cac972238b6950dcffad039c9970cf91896928764c259f30c0740522f34eb3341b734fc7a02990209b5bd5723046ca23ff547eaae43a4961e7b520a4f6fb104f24ae7e4a854dc58c65b9bdcd6b6477a0d6e71e78b9c1c377a150435746acbc7582c6dd9bf37a2857b1742e9c22b8d70ee4a636318196efa7996eb05a7d9b16606f4cd7260eaa506883e2236f8e8120b650025f970c7b3e81705585478f10fa24b4c9ee669c400b8e169c6288dd708237063e16aa92804b813fb0b33587c3e7297a21ec0eaf01b7ea22959d3f8ea07d09c2d745b73caf3f47effab23632861acf241d46a5370703d3d7d29d94f1f35aa720942157ab893190d95a5ec56ae782b186e4ecf289838dc5d511cc887d2e638d3241b3e03b57b81b919144afb956067e70ddff1c91cbdadddccb9707b08910f6c38a49dad5d9e63cfe94381c35c1bc169c5c00b053d955cc48406f4b6423db9bd85636a0a29c692f65713e9c3793bff2b21d132091d6f9c1a9430b9de24197c5488f203f4b144baffb58d31a49e2e9e54cd273352e2ef90e009ec00dcf13922986a84703cc80f707f5ab1ff9bfdd64c1f08fd42f3f43b69234ba4bfe6ba971668fca587a87bc5ca61f1e39731bb2ba88619abb1c96fa48b9e83decd416dabe0cabf3f09201d65a9e2c85e009c8f6ec7e1734d0c360a82163eedf67728a6f20229e735750d0c7211ebb0c0f559725708b1f7ceafd556a0f254919ce9847c90383ce95231712d97850f9536061c9acd9fb7461c4067c39a642df57c93f0f7a05ebf9b8b89eb2bcae854a33b7ae3d7431f1f08d8d8b745b0822d4622e4da202eaa56d9fca17beec2a75d3ca69d9c6f6dc8a7cbac3d05089a01d3baf70f3220b625bebb223e415f6a9631e5f43bb85cde4044e51c82d0bf7e8e4573e2949ee7a8cb4c26dc5a2e6eda86a3061f29a7543028463b42cc4937c8cc7f3feae2fbd6ea98a88a8577b94e9fb7285f7747376acf534a704a94ec8294bddf8306dbbc4ec1d912d49765c401bc71d90ae7c2636af58dfc03312bb27388b743954fa4943173636cd35aa24606dc6dd39ef55fcf0dc0f452aaafeeba697d495bf208c03b35ac4e0c684392916a35c165e0fbf9ece4bacb43ef98adf1f2f463d447a666c98678eca181ccd6a01c271827d00dd8c3d9b2a18718ee6d31ee3e2ef3ce3e6ac2c85da1c1a43ad60d35b7f2d6530bd6e5cdbb1ecbfea4e8b46720927d73b7a71227a38c6d40b6a51b92461948ea973be62acb2e49cd3723a7bbd021ba11f9d48ef690aeefe3f0c599af6163c738f8dd15ad8037b0316c8b26f01344595fa2b9be72205d7021fb4faa1e841f3939af37aff459d24c140ce209656d0252ee971f66eb323a1744f6261f2a396df1ef2767fa07ca2dc288f4a7b272563022d5a1a0ebbbf71f5950f56007ebec6dde6c091fafc8899ffef3c3bff0f42f298e6a5337587236151eea891b11dc7eb204801286125727e5bab5c692892be0844359e866e898f747cb724b4dd43deb8ae2c9106246c86be6d973694bd2b0162d6e4e1933218a69d436db80f4fa9700d95dfa96e8d110075747451541a6201d92003dfddc0ddfe9af2fbf1b8e1bc09538bc89e5c7095d27e05680a6e253a94ca79f0eb331c7ed0945be8b5dfc0005a62fc752cc1ae54bb0276404abfc3b82df40ebcd1ec436ca474ab2e4c66a296330f5ad99c9e8c610fde5d6ab6687fe6513c623f7b109aeace8c61e5ddc4c4d34da707319785dab0dcaa325776e0e1a5d3a4c09810a0e8afc0bf7787d6ba641f6681b4e26979c00a8dd8d360b545c99cc9bf5959339329b7770ff9e425086806df0f38c334655136beb4aec05bcc659fab87c3139add56e8c4ed205fbe9d7693087fb344d9b75cee74d0e51910e53016fad1dab4bbaa71deb99d5d5d662a2b27cd6303b7b2933a54eb11d40b49092d6cdb5baccf9e9c005589a9d8e275d0d8081f794659bd613e450c4416dfbd91a3c931c824af77e2ff310070b4175df8cc78528188753bbf097eba3b683251b5575517962b01956ca5dff8dd85d96492ca58b8a557aaad0918be7255ff755b4b0280efdbf90a7e9a875dc48b24139d66488e0dbb73380136f66cc8d3d329084fb23604e583092754f47e8deb9722b577a56cc5d92abb857f85411449018e5b4728043a7c503f1b82546aa5cdec225ada477a042dd279db1515ae2fde9098da95f27b0678dd282d1d3d2b8d0408fd9544b060822cd14aa2ecc1c8b1c60c9a54f74bdf278db699ed49d4d2f1d9f17a179ac9a39780ad96990db28fa9c2a46a1d43bfcfa207bda6f66f5acf3da529398c24109ae73d1ec1de8941a352f351d4b09894e3039c964ca7408c3f552ab391f957cea67ee94f423bfc8e5ee8b54ed9736501c45061b5837e0fb6f8a17eddcaa2bbc310e38a54b0c90d9228e2a4876c089195ba61d1a0c5da0db3c4a222f822c1fadcc7b8d3d9fbbe7c1b11e629897173311400f99d2a4590523f0477827bc6e6899e888efaec60b1097ff4153834f5b711ac10ebed19901d1f977c8b77960e377b82a1e04dadcac51d7c0ead2b6ee75e07bd9c77c63c8ceb4d1e50e6f4873195de3b012d8435c1609becb26c7c7cba4394070e836ad74d466f9bab022d4ac160a3941fe198011ab3dfbaacd2e4f6256f9503727a52058e574406d07b5a72406051635952145c28681e98bdc3920cb72d904e26d9cefc63f273de4f8e6322d3285a4f8f1770924fe0e786ed66a53ff15ea76d43adc32e52277bc4f68de98c4fbb6c8f44966a0d5c6032f0029427c4c28f5aa2ee0229bc9a4edde67fc4a03a2d7b79346413b9314f67ef912749a90b5e7bd92ea64b870c912a8e89b818032503c2850af96ee2b6ce2db73cc502e6f83401ca28a7bd2f6c052f7b9274b2b57c1b36df99fee8cdc6470495511e107a435dd22de8be541e88f485a670db978d594d43557319c96cd01bb045a54dd452e46117be5b22eaeabc63945bf52f82f214328271c6d057c199c616a6c17dd91b08525cf3b4ad04a86d9220ee204a895b9ea0e56d1631e95a5124a83cc96b55546a1d9e8211eabab2480c6c8005a6528a8dc8fc432f17ac87aa8c67ed79bd8632c62e6eb72a98c6092771d5696fc9a96f3ee3760aedd463fc4e21d29b91b3acd6ec70b2489474d65faa95f1baa7a82b3317303f2c8a2a9cf1616caea442c871dbc9d4d748bce4f7c0a4135b0145eaa857455317dc8d861dcd3b671fc71cc3ddacb76a5a39cd3b5caf68559c171ebe45dd8e6e4f1f84d21c63ba4e9dc65023fc0ab77e3e1914eeeaf086e246a45294915abdf15d14d7134f9fcafbb5c526ee4eeddc1276a01f9cc9ffd4e1cc78af09b1a84df7adf72e7d7fa30190b08da0d1e1ff3b8a48ae85da9bc315a99a54f46156ecf3fe9bfbd13a534a3605995af51b66e15882eafbdc1bad782d98c1eeeac4efc0a49c108f05e0aac3c3ead65009e2e303fc7d45f1734c22a4047af92810fc149c0ec68fa9b6830868e57a7bd3c2273b37254ac1d2c8d6b877629289015a5ccabd40c06f4703053f95e1ee06fa059bdf87eb5925a0c2882f146f30f4d08beec853b14c0c8325974f5ffdb5350254d122310eda974fbe6e37f8576a41626b7c09d4c62115d4eec7b44c8dec5a5b5ed92a9015605c29f6cee25f62c0920049950a41222efe647177006a34dc539d471c63c516f12c71273fcdd344e9532b315526f66374464c16531367c99051f7258089519ed89571bb9de36caa0481a7011ca810e76744027941f18a03211b88a1cbd86f66fedb2a0ae2b48bc274cc49f84c9749d6d12ee3d85be0ab03a223942518e667253be23a4ee154b6e0583ad1dc2932a9078a0f0dcf5e26e7dc36c51dda3733d94376ee289c233480304031de788950e78e828afea57b854c3c3a72069f4a706513c4f90ea263f1a5cc0ac8719bf47cd5025a98a287a9b15d1ce3503ec305883b1048f2fe6fcc049bd5fd2518b2da4d72492aaeaa057ad2a8f2f7581b912e10cdf1fc9ed928aa1c9b72def323b14ed8cf8d42a505c9dc267534b0738711eea014fead18f4234ee879ef10a2b283b456965f031901b49304af48a4bff0003c65011f3c4711667e5f449b213a93cb4ea6905e5e70824227e533d1340ba22c7ba98a305244243a2d28156581b69da7a9ae11be4e22f75dbad56006d6d39325a1c6170674e2b5c89a62accc7e8edf6e4d22a4fe27ebbb80a7f49654e131395c4919bb42962426c1697ad10efbe52e25f44760a749ba06a168743ea3e6c62bd485c4a2b46f75c3f316568fc8f1bf23cb148e80cdab1bd70b87e0bb55dd9dd77bbd7d54aa210daf74617b88a80acd95b8f57e489b198c1bd59046088a7831c5b426a724a3c09bdcc21e72ede32ecde4482f29a4abec3265be51a780eb20a421903a59d3d7488b22ed22703417f2cb745b8a846f6dccca6ad301d793268bfc815d6bf543b3a868f3bf0bf70c9601d1d0e49725eb841e22c6d74cc1b3bc9f19c263dc4abb1952f731646123ea6625c04967e7e84418d8807eedf5935fba98acbb13ca93f1b91739958243314fb5245d3ef00982950f466b18bbb1c2435f688b66eb8ae723c258092040ee965427d851fbbc7494ea51ddc8fb5bbbba17f2e1d3c75d0f033365e2bd0d3a0ef78d557bcb435e266186f2632bc945b09c326e3d1352ec11b2f48a8ce1fa12e3844bcae8880b83ad9c019ecba11dbcebcae1553c57045ac8a5a8ee7a3bc85990e50a188e3302784ab477274e0184b9c0bd76917d4afc4b23d86480fd1d5dfedcfb8663f3795840766a2053f91c0521a32996d62a9966682a6cc749bdb41c4c1e5197f3957c38060a18c53abed40a4167affbd435ec5926a7c2ac0baa68f3e963c8eb14973539ccee90ae10caa84478930f2d022e36672d6d79601ab24b26fb52b8e102bee68462966f2bdfa24f896003156cda17e7b36b54a0b82dfc66ebbc7a8789b66df5e9435a16fbef1fc68c1fb06abb3003f3af9901c99cfccac02e285025bc274b45259cab4c397f27531c66b1edd0f84b3f8ba103d39b9af9784fe5aafb4650ce86a427ad731427ce9562dd592a06f880eff3ed51dc28ff97a16b2a38ced941922c7fed5c41499b542151407aaa28b332c1449256ea76f6f989044c19a58f6751209d8e23577f9c6faf1cd0fdb7f119ce8540fd79946d628417533840dc087f95642bd912bf61efd4a34a4b74614065928858c5e155e18c53ba792deefee41aa8e15483c0d313663e76463d4379d2eb89331866f8a9180d2ab37f728e6ecbf561cb01c2f30e5f1eb3e06af783229fb457349823e4058039c2197c4bbd62e2af0066ec5182ae3f07ca06a1d61837a087222d4d46305166c557c22a9b4ba51a50252aa249aecc055f0a277d71ae64308622363d199145b20bc612b71a005459c166606b0ed882769ff451e04f56ba1cc4f98ec5f21d6d59b40e1c0b0f0841610a8e71dadf7506dc4ced12fa22b4f3fa27a8d08f219e2e731282ef8cda486eb6b5d06a6a4eb18e9aed15c64ac2dc79b306c155af146214b0edaa496b367acf705f580ec78b32bf3f54f8b4c5f8642b35d6c43e474dc767290bd77e187929177f26abdc7ac815120ccc0747f26a816db3aff7a8174f1425e6cf69f22268683229c4997222d98ca3680bbddbe0b9d2db092030fcf326dcbdab38578ac9a7f2753a14b79c2e88ad5ca029d6c6d3b46f6a9a60a1d6661c2fec052caf269acc54100c75e1d7669876c8faafe7c4fb0577462d08bef6cd31283f451373e8a39429ea474bf38732583e85fb97afc55c9bfb42c41a1aeb76bcf095fd74700b4807abcb8e599e18325a915f2ca28f2e2df8554becb37ec25ef9f0b604548d00f35172890bb26d1cc4ffb4164b9bad3b55f4c90b533fa5ba32ece17e739e6f054bb9c1905b58df037b765a74186741ccaa6ffb516b02fc9396494d8d2c73d3bced06f19b97db9785239af58fa7433b952f168a2679fa690647eebe7dc8c44474065c11c5855a787cf3d5d61402f9231a9364809d48295241a7670194d0098859b2fdaab567a94c59a73fa60ad1986aea518cccf42a3a44fdcf3aa9a8a884d0931743fdbee8d7f36052b79f79ab3c43396a76930d21bd18147c417875edab3424e28b722f173ddb0ac0cb7c59d6d9f5a0ee6dc6245fc0691eb7af42277e0d9811a3077e1a1e06538d7b49afcc452ec7fc47ea332fc86ba5b9bdc2e37d2a2cae37e1495668f70e55d2f818626058e092cdec2156b6a81405ffde62cc184ef46207c9d435d57503ff02d24743aab991e0974085c59a8eb0fd4381b1a99d20af54b7b384a621f0f489bf100ef282fd93cd4388001d30108d274a0d618eccd8b920a5dbd8480da8df35c9d3750f2de40bf68c3ec18cb46b89f1102956788cf05f1fe58f66e64baabb620a0238dd2ce54dd012d40a9e6dfc7cb17ff309ae063b96af0f8e1dee8f67f219cdae406a11cf3248af35e47571286fc3a74959a9ceb3219d28dfb788255f7ae811442e0f51a8580ac302e7128eb2e7d1a0869013e21b75cf265cda5328142174086f5eb34bbc11a4e8ca933a7c89ac69fa51dca1fa42fdc1e7838239e66f1a318fef79307ff551ca841f8ad6569395f80fa32306335962bce3c2a2e5a50d7f51898dc4db4394390dc0eeeea269cea1b64bcaa1fad7c8a089ce0a2c8a9916e3d0c575c0381f0abe5a67c7954e699cb8360f2f1232298561fa53ec03605e388104a2fc5426ecea3bf34e5cbf7d3bcf4f224c1e9e6ecd2f3eacec2d9d7a52cc0c4f71a2d945a7d590f4b3d82d722679cdbea607ad698cae0f71e308e7ffef5bab5f6c9c49c27ab4a41e237fd0cb08be1a6db72507834cece0b2c56ab809078aaa8e25bb0f1d082164e7e8c2e07a18f4052e8f3f0f285ac3e9866748b79432def9113b79b7ae9e4a0859cafacc5a8eabe73d1a28f392712b91bcb06ebe110cdf77f66494c7f57bf0323f75be55289bd4c66567b1867a55651bcc06a0de861f541fdbff7891e49ef0c36649ef065ad77b166eae4a20d00bc8ae12b69a472eebf4bb053a9ffdbade328828eb482daa6e9e3ede5116fbab6cdb5f2cd0ec619fccf88d136f9e3f03d10736a24100f051645d618a446e95b1428fd70dac34ef0dd1abad4f99fd1af4bc0efd1016389f5543a1bb515d0e142b8ada49a75dcb6ad89788ac43a1f1cba374ae87a9b720058a8bcd191fc410ee8862026c344070b1f3d71cf29f77f0e833e2497ece5aa852854db73612feb7877a5b157504c91fb34cfabda7a7c9c9e862a2cd05dad8ea50dcaa3d45854f1e73d25514f9a83ed6ef9cedabe610ae127550f26a1449e01f7e2689896341e8a45ddc19847fa23b6d2eb8b6024e75ecebb1413040c0f4894b6881dba7ceac1ad86be6894df0a4c935ffbf425185997608322d2a38553a1c5e18ff69edc6347864ce1b2adbe2daf1d9bab257d8bba03ce1f04f1ddc51cd73cf887fa0112cbb4d954d7db9fa09637bc84070d3d8dcf491712f92c963036af0ee612fa7b0805f8cab26e5ab01b79e9c63460cc10ca9d6519a14f8462256cc38797a3aa366dde411deac603637203b169faaea8bb0d1ec8fbfa72627fb120dd24094ba8dbe4b2fcc7805deea6e09433a4397ad852e05100ec0daafb7706723d55f09d98036efdc0ebd5f71763c1146d21ce4a2b1ec66eb48fa1cd6b6af573b46ad4b95e58de13945b6ade141a05fab225733b5c356153824887a9e731398a34101ea178e4608fd9f77fe54107d97fd80c6f5cea5241823452b4794c7c86b43fff087ded47b0a33b4a8ca2e8baff9c68696b81a7a7a7df3a44180f3e1412cb24568e16c8fe354ff5ae000c258b89a3d6f83d0f1494035523739ef38c259394937ab6af7a2e2ca1583772f3b6a4577ac888deeef2785e20f977be451c40a78af4f83d0c718addb15efa44a295db51cfdb83276bcce61b218d65849dff6bb7698d71c0f61480d1ec425ebe545bb9da8b3564b4add4babb3d0128b9c4bd75ddcdb55ac5ddd9da5590ad8f9d2bc4989e44103dce32a02ca3a9b68f7dc563533fc32046cc9ef828fe81c76748fac19e82dadd8cfec66f730d492b0e7d9f03cfe3fd23c598061a372cad53e987cfbc944a701353214377c9879c2889e3ca80fb319878396c277af4b038e2d8c12332e89c41bcea47d9e6977dd9dce9661294675bbc2b5e6dd91f9dc2471699fbc30c633be12e3b99e556d87f17674f95533538a4b162d1f5f9c563acb41ebc0dc44d0db42f335dd023203c180424960c195b537b6d2b3265e03d112343df793d990b06ca4ec7af79860c9935cf94541a83467ac871521dcf05c4b628ac555f8e7d00f5b921b9608a4862490faf2988628834dc8389a0ea4edeba1b71521ff37e0d0bddeae78d1bf2ed8ec2d3c66c88bfd81486381dc7e4dcb10525e25df721905a9b0f036748ac4d4e4c7efb042cdfe8f8ea151066346291a1d449938ee85032c86c1ef18e6f3def667fd3a3d8bf233fea9c9be28cabab3707e628aca3fdf1db1562300e7d44343716be693be53851adb9c1bdf56274c13911ac99e8ceab46cc7a4a5ea467b9a68856362f64bae7ce0c348bd62b9934fc3549bf600597707dcb754d91923c126de081215cca3aa0d09c6d7dc125f3d68050f706d298f6ace8968f6814dbc22f47b9a5ae6f3e8a688707c07707ce23176821fd9d80b7a896d72cfe0948c8891929adc9e0fdb20c3131860bece2a5b1b9347cd8aa0a3fc8f4ebeed397840e23c948d29ce468298a78605f7733cdaf715d0b5755f5043d222cbb8aae924b637349eb42e33d1b07999184157d73b9e5e15d87e6b28e128303da4d5210a7c5dd78dd3db7a23cd7c238ad56ecff2459ba1c7bab82ea267d4e3ad7156dbdf7e1c35411cd26d3bc6c43da75bddfd59aeb27b04fe7a0ab954d930f332d09510260bf0acac1865fe4b2ab037f5a89c5de39f8e2db62537e740ed6be85d478e6d264e11ec98e570c2b1d5e1cd1303268d433100b74561b15f72f992ecb548a1d6842a6a5aaf27f300708b2451b7109774983e90ca08aad1b64b5ab6aceafaa87973df19756fa3bbdb7fe1c73ed3fd935016b1916b3c6030bc45fbed730f0eb6b7a2a634c9936d4cf66ab96f1429e8d2253964d09e889d28333ee0d0ad61ae0cf2ae351208485d5956f5ba7f74748b4535533cdb0f032c072533665a97c2d8d1d2c8b5a8d609e0ea036fa086014e1eca313c4fa3d4ba7e5bdb0b753f99a215e9080b5e365d1b4adb8d3e11262636e8117f3245ce95e7a18deb66254f70ba1e6536158b2f37f7e17a914b543aa1c0d157b9221f4c6fdd3adaa5e9e8fdfb7cfafd87deae1058e76b93ffca5074a7cd5e64411577ad7aad6c1bdf01311890803f30a4584b10aa3c08c1957a7a716789259615e3400c84f1a92c8b0d8d568a9b26c3d79661e44d45635d43d51ecdb56850292654abfaeb90abde4574ff4b97112ec5048d6731718aa57aee603350d2a702ac1410cc50a56b55629834d02bf8b161af6c887e99be2bc338a88f3f6067639b87dbf4e2030b8f2dd5dbf9c0d3086ea7da45860d4f9137e74c20f9dc44fdbe11da8cea0370f775737c0af480fda64dd7b006e6a5f9db4f5fb1ff8f99ba67dc6c71dbac7169c93233573bc20304a0161b9ccbf919b73dbaf036ef902920105b9028d3935a02116e918b5f88ac8043d3de559242422d81abbca6ef95251f848e0c5f2119ed1bff9ac00f9450940243da5a0b3974a8647cb927153fd3fddceb117b2b0743153582a9a93d21896c8d1c5f58f91b39bce36557f14926fc2ce72b247495a82a0fc99f208a964ed2aa74acb2e59a9b4969da4d268f097dc3c0fcad45247575be4a87d5b067dd327c34ba5c946a11958fc8113d120831eda3ba26928e231d2a66fdd2b6b3112a9497db9427890ccdcc9b1a35ad0b9464cff657e4fbc362ebd3251a76896906ce7b77b44f5c47c25690a62171a8a6fc1f7a69cbfba63154712bdbab71681aad9d3302351d7c3c72631e83b1bad645bbd2e139be61bc66b44d2f05c5c127ca566d3d56da34aaa8b1d3d0efcd3b269fe7aa191d03b32825bffc0a716f6bb3b32e3250f54ad027861dd965635e72ab10a3bd2c86693927d079574bb7bad9b027fa59339494f42f45ef82469575ee6caa3af7f39b527ffe8d866e245cd0c5f9d7ee263b6f35ac6f9f6e8c7a7360c2cc1cf4eda9fdd68ca2090fe3fa9a0407b271556499c98857e9228f02b7e1082a172b2a100561f053f5d29974892f436bdb450449e4b73ae781b4ad23482b988b2d1e1c1262a0b9fdf5fb071bda6329739c6e675ee26ccf94d67c902775c9a1e8d0a567ed3da14edb8e04bd53b14efc0c4c1a34e250e3eefe061b1f4e5aca832c60ef3798a4f795f4c59a9cfc023773bf3904e8639f1b5f0b0a95d7aa2575b254d388f651b1c1ec9738b161c1cea4db2e568b53f976dd26be49d448e91ffb0192e833dea93b71f5b4539d5bf4beab25ef495857b256cb6a5ceb4db50485cca9592cebdc89b2f0d4ffbbce3209d32f34e425c76d63ebb33d0e0ab8c7a042cc5d2bbde673f3ed31737ccb478c472a830640ce4aa591282f8d67688f91eb50205b91eb07b8c6c56ebf08b7ae2ac978bfc79b0a5b884ba578bbb7666406e1b86be6fb431fabbde4b68124f4b8c645c983d33c7c3b90dc1774e1be4f704b0e5418075c59e78ac5b0a7932142d0336b78122d1af095d8cf56685d0ec0eefc0fff9f5deec87c5c1ec0163729d3002764a7003db02b3f7822fcbeb37c920b168224f931163d0742c3bac76ea1b1041b0a24cf209adfd29d68bcde86fcf43abfb7bdfc9673eb035c89374a38c333dc7287a4d98a33780bef3b91c2abea5e23d95fbac246b87e527a49b2e70cec2a0e66fc01158fc5ffac8a9604dcccca54c56d646f09dd456242a8ba399a0f7d8a2495316fc8a8a060a8516a30d90240898920355ce858d71a2a6987b525c8e45b723ff1080e5d2efb76ea5f23e374d4d3cb94b64e1255b6cd3493f2eee1c8299995335d6f45a308913aaf38858d113165ec35d2f922e80df26d0e6d072094d1c43ce9eaa81da3019b0ee027a0efc611a0a062d39fb6b09168d741663440297680c91d2249adabbe51056d0e930dc0aca6ff1bdeec28a9d9df991702e404671b6114d31f330b8f9b6f5c7fde8164a6e3169cf779b5ca004cd3f65702638585a20ca3088f1db3ca25a9c1f6eeef6f17c695786ea42d7f2993cd533e07c2191bb0e39c767153ea93964069c10897b1e0b9844a0d67d002081730102b80765a7e3f86b800f06ca7275cc8a80b9e39e9e9d07c3cbef337123ad7f601f9855ec737ecadd3d838707c92fc73d4909cf72bb9b1be4b29ad230c636b10ddd3770513c89fc40724dbe41b58de789ac71f5c377b199746844652332b18a51789a32e5394f4f88ddeb3c850966e8d6733800928db28e026249e7d2e53d0b3b2952a45f326b325d1b5af8a917a9f7c7cef60c2c088c957de2a38762db37bf5d04337a6065dfca763ef4387466eebb24f40e08117347c87cdb08e835072d5bfe86f4e4769add04dac310a23bb780675344c84e220413971a050690590a4f587219cdcd00a3a84383fb0e1ce0a855bda6563dfe8146d6b0464ce250ff0101dbd81e49ec84078733c60de6c2b5cc10836a75d090b604e29ad20d851576b432dc1ca48c61c673c8db5524fb84dd19a10d3d072e40ac19a1e1c3778aaa95825960bcbfa8148d2c9126addfbddd1b697ea05ef26990b28842d819df45ee9593a713722892ffd46b5cedaf1c2409178d1a11134c78fd7b244417167d718c4ae12143894d2142e5e1059982a65a2a1454f6f1927d99ffffb3c65df7298f99c01b0b0ebe51af4a568e0d7387a2b80aa991f55e7eb1609c1b03daaa7d89c5a17b7447e3559b8708675d8ab88d3858d56052f05374b6f0eede711c0ec6ebf1d628c50a854b5906c8e56ca4c2ff785940d28217c745492d28c2a75acc7ca8b968674b78f2eeff2b506dd6a0c6830d11a442ed8c3fc6f3a7120000f49393e6d4cd919812a0d6f494acbd4a8bf4d584f7ee2ae1b629b94878be78bb40b3585efc1e0f5e881e99dc1e74be4544d6c297afe2c2005a4b0839cb345349b00890cd0843f9f7ba4c3db666232f6b0a8aaff5ee8c830f4d8fa079e0a622ca17b8f3d6d5eb470bc1859b988d4d5826f1694fbc4eb5e4f5ec4fe92212d3fa48d4886878404b577f01e59ba688e410cf9394966be7eee37f8add8794512aa1025553d9821dc9fa3e0f421a4459ab7a796d6104cd09173c91d7b259563a95148c7abcf3db79e9fdb20e90f269e2710878da30c263b9cefe2563d6b2c7408c0d146b91f919829182bec7931ebd0d5e431fb72ec908390f448e27f8260479caab5d14fc2f96f35ddfdce38a02e69c74aa0e2633a277b55e94fe89c1b2f7bca5f8612c498c972988ece83a489112d509cc0a9c450d7f4809f0a54f088881ce9a0ea35617d224a2ef751225e8469d30b2e6d73d4f098e3c3e7fc40dcaf2ae7edc84c0c825d929317a90f785b7fbbc984f597217f612c265833669ed2137f728f623dc29f4e004349e55c2293e5a2fc4ea83caa7596954b99e5031ada1fe160b18dd23286a870e2b7938a47fe41bb6be1b0061ef2ce057f85c4c18374ad120562c852d39c18dddaa9f2f5d56cadb23bf3cbdcf7489a66dfb33365689423cbd6947bb4078eda9c96a0ec10b070d28f70b1fc00a4c5e655f6c3cb4bafbf21161db209b3712d80ab7fac54c69d0b2fe0736c9b3dd09c7a42080dedcbe97c94c3202e5032477b53d56af010c52f20e1d66f245d86033c06a0eda9ee088bff66086e4b64153500c37f4a588a2cdf2e0787d70a85f66009105d12f1ea0d6575440fca4ba4c3020b3820b6a61068ea15b2bb7df7e89d6739ce16ddb050d9459bde9f79bf4d95e61ca10067fefe5f1916c4b055671a4d8ce7d9c4d7b13851e25d330b4c345ad1cab719a26544297295101145a9214321699dc9d9a988d8150a932d29a947defcf7f9890ebd87978900dd89f5a3c7f4870e53a05b4ba87ac3142a095289fcf92ca95aa195bf70e770e031d853d5cc206d723a96e38d34bfe137353607b666ee6dbe850cfe0541a51927c5223ad7984e4cecfc4c827c5cd438eb37de651c9b0a00f09832bf0e0b6e5ae548041bfd5e27fa71ef681c2ee78c7cf2ca652ed0941db6b8739d009303e22929601322be83c334885804675b0e8017442961341e95521e059e0ed293c47697dba16c932cb49bdd283895d9f3641f0110f4ba21eb11c238870f3288972a173fd28e5ee6ad58bc602f7157a03a6e88d556823b053f66426437837ddc38e548dffd657fb43ed355106845e04d5a355e929f6175d348821467d8318e5a91a0b49efa0e74d5ebde71f059273b36e1969ba01798529d5fc18941b15f661c340a3699be738e5c4e1b3d52587f66baacc5775408dc69c130669038ee087f47b4f405906ca3c20f9da4279c3e7885574298548794f3361a534ef5476414823ab19a4f75006299e9fad22049f3cea387fecbc8b885285d2f26fb3117ae3991d5ffbd8e3de9546b6a9775f01aaf4be08704a05f232ae0539d36c5333f1535b10d8e94d9f68451395dc19611cac160a9eba117a1458e0c21491fc3364486c387f0fa2525dadb81b8253bceadcd872f65efc9d2e9c2e5214b57626a39c4121e518e443773e607d16003c914b57ded33d3d356781dff7d7d49edc0ad3510da76b788a16607553613ab3bfa0052d33b39c230f2c0459edd108888589c65b3d8254396788e5d27705672d78c2f3eb4cf83804ea96c491fbe01d408ae29718812cd10ac36d287bbf581f2bb0bd6a4992cd2c7358f985f84b9d885174f14a922254c651b3a97642355437de3b56dff206a1c60da9bad0be29cd093be270d70f98c518654717d6891c7257f3d01dc4b82945116a35dfefe06fc7e9eb7ae90778e0dc0390156f03a98fa297b1ad45fbb00d37d0e04b93ba846f1d81756ef1ae3146e70ffff8bff5cc5fe6fc8103f42db6d85ff6cd7b7edd89d0852fa7fc6a345c99fa7873654831c1436d9d144210cebab0974ca16e1f6b8229dcdef547d0b3cb37dec4998f574e986a40f27868624c9d23e0f921c54437635fd34ee84bcbf6addca07cf4ee6a3fe17e5ff3d4809f3d86e1cb83924f48539b785453a71a59cdf53aaeaf012e57be0d41b9988bf3113526bd95f5bfa5a560a89caf772b5c600892c8af74eda51f90999e9477d5e11eabee25d63a1210b9217e50767d73b755bb22d5ee4eb542bbd6866755500669b2463ca8609c31e47308c6f28e45407eeea11b85480ec6b13c7f94a31a369cf759f5556709a069e95dee5be28637d39c74cd211c58ab8c2dc9730d03562f4544877a48c602ea6de4e52bd8620432f695a57c55089ca411ee433718c270a5f699ff67f8b442bd184325a81783eb1ef327678328f472d5806180b65d6ebb9bca0e4f3319452d1dc3c6659219665375a7e0bf161272c8801dff2950d11ec3d90b533098fefcd19fff0c69f4fd6309a8b7b609ec62ea690cf97dc16be871596eb0b37792f89bb66f231f8ce6bc1be2969c4148045cbd68f6e25b59a2c529dd366ca039d2d20a3c4a7c5d636cc7ce6a1e0dd1a4d598839c1fcdd111a0da191bf22ddea9f79a88a5a197f28932244a05bcddee80dc56e0bad100c59a939bbc010b1a60fb0639e6e455e6b72fbd75f7ab0493a44ef1c5dd9fec7d7e1264c5f4f477a7d0b40af62c31e9dce3777d7ca2f90861ba5e42e599cffc258e03d01e577c4921e2317cacc68e077ec252eda2afc74ee4b0382f4c5dd0d16c549f49a21f614dad7244186d95cc49feb0a81fd656d8ef3b81469fc70b84ea20760ce1e2313219a787b75b4619e592b31610a188dcda4fd55518fe9f62711acdd52902d86221aa2ab32ebdcee28dc3ee6bef2fef8f2e23b4fbabd8c67de3b4a0063ed1ad6c68279b7336f71f9cea74e15bf32447c0f88395887c1b7f6e6e19b4955062c680945c0ce7c1539431c20c7030836cca9faf970a58c48817667469b01ca82da1fdeb9309d2c1e20d39d77545f8b567b9857929957a019759dbc83bfd64ab0d70c1022ed949f1b05b7ace4acbc87a5dca2cf561a68f18b002a302d1afe488aefd971ce37b0f7389e01f25db8a5dbb00b739e53ab6e8a1eba41c5320a1a59ba8e98f8265ac81468ad4636060d6884e8589db930115f02c90a2eec7c8fdef95f1e26f6d233326b642ddbce0838d35dcb10064977dd142520a8d408e4cd33351a137500119747902fe49512f62d998df0ba5565e0420bd5a1d0b97fcd7e725ded9e123da4ef8517649af32083eeb84a519f226f96552716051470c8bd5d7e43443721cc2c50959f75962d7057d6df821cd8d037da615c6d0d07bcf810b7b71924ef02da0291fec80a617f6e6d6c374521f3c8fc3a5c2e63a541ed1308ada68362b739e4d1c5097e8e62b7b3c4088547b2f28db026866360bf4d88fcfdc0e2f8a0693801ce8fa39f15b9bbe0adf841d0c63371422de80ac7c53fcc837fa03d135f52e4db9f7be8c346159874867a519b16222af72d42d3b116d7cc6801602af3981bd937d996be51912eb0961723ce6ba3476d2df2ed866b065cf2a9f02d21ce00fa2d1cf052e7c10eac6cb691e38138775ae98ea8f73b34f5ab1bb8f8dce4a3f96e8694c4363ade09df3421def056cd22e5073153decce98f5481ea8dd0ade3fa7999c202029e9cf9161ee7305972eb77d96a86c22b64e1b540ff8004d4d9636e14a18a64484c462b301ee38d2965c1302c64d73e39771b1618fb4dd469cfb2ddb0114138721a1001df9a6c41d864e10963e9644b16abec8472597b83591883e3484afaaf65c6ce0018a8911f5631dd469fa6e72d625b36545787c40f28547fc138a4c67052ccaf8350c8698d34da02afe7f43d0ad415d44f00955d0463a2b73b720d173edae862fb3bd1557e360e46a9af8eb5a62f16d656d2a77935194c958cf55228dddc1824bebf7f3616db4eb3d60a8a97f2a387105aba726434117fe0516a1d0e26f55f54b55450ef3163df889026edf208193ac56553104219284aa74a982bf105b9f3c9d7cd9e5d0338e3ec8185a5e1fe67ff264de432a9566f2c0a185b42259a1fc58e05b9fba3e910d1a74a3cc31c61189ffbbe7baf6811f5b50c0c20e033a45f7181c866bbeb3a0d4c2075bd9540ebcaf4f2f075d7f8ec1862371cd68387d23c6ed24c1a094ef373f0da123d1cf80cebefb13f28f726483b0b2f6d307b56f6e4cd8a4dd1f50b1c9f53194449dda89b97c15048743d32a65faf7af16d306ea0f5750c57a3ca14796b5da2a5d1f5a248b7d6aed0fdf4bd98f1a4706b111fd7a954c9d68e067af42ae3a6ec5de7f8963dbfcd667a73bd02c93102df27c206a4c785f62111327f8a3a0f29e69185b194fb89a86c6724d97c2bd0b7909d933bc711f1bf48532cf0b1e87299d124cd72f6d4834162a402578981331618320865ec2fc79b5617de8d8ea93a3e3cec073b943e6701d4e99cb2366a384351c316a52d538ae7b4af7c2ba1963fe884d2931b67600eca798460dce7c11494374b5723e63986a0ab8dc46c086741e1c2a05bbba17b7b127d083d6da334864370d726dfcb9aee6cec0863a42b1c74e2ee83dc68971dc1799aae0e07cd8a07f0740a758edb8a5039e73fca03a65d9688a7303912f90f028527ad5a25f1d6d6ea8a2a22162d2fa8bbece93e9e113f48fbe0607f8f816071e9dff6eb902fc076d10b2089a5e26fd1ebece05d2785d5cafecd08a9089fbdaee64e11352413b655d4f7992b9a3df3f311f91b03052980cdb7bb707b1ac08325acc59d9de926467b0da7a4112118e8ffe6d8623549c4df50f0796e665a34f1d0a3eca8af762c9d5f21b32a12e60ab78456964dd4e1bc9d86304bb299511ff3246916e78e65f15f1611d800b9881a230e7517cc7b495e1c1f10eb7808707cafcff31c88569a8a6dfbfc325aefbae4f4673a490539fc1d3f3fd287a543d13baca5c8e1d04899878eca72c38416dfa619e95b8ec156fd7fd9c637539948092492bbd6eba6aacab625682be6d37cf83e610794b84d68e995940a552864a8a728b3bb6a6e032e032972da742ee228f16b6187be574150afd4d4d47865c892c63de0b3e07cc281114da38839730131a4c3f2972ace594f0d81a2401f376c6dcdf8f5192b51c2f630159f24ea5ec3064357eb5b6089e2be6a2f95a08cb2b944430167bc0dc9c32b31058fd6c1f82d1534dbdb1fbef2ce6bfadbab1444568977fc64b0bec233f55351e6a60f728dd6f42ef110e20def1f7d1847eb5d61b13255a5ca8b39cca71ebb870d32655a014f71aba86ac328a0a6e0157243a34deec5b7a1aae1bf186258a7a8ca6e9538185222ff177d3f2cd05698b5adf904e13cb53766d6b74f0048682e1bd4063780198436d13d8f4dde177d54329ca33aac2d462c2d05de5dce82d84e8099d15336bfedcc91c042a70ff85185a27c7aa00b68677e50c969d26c7bc68892b5f1b55cd563ce2440a7fa3f83179893b5b003528c4d5ede607e85fe50629ba6d03cb3d625848c024b62f9cdd97b1f9817ff98e2cdd99f393d9106529173c492c99dc22e06bcc5959aff16ab7c275af45e4316297d5c229373a88ace3b1c5b49b6cc8006ff5d91c37ad68e43fff71d482439bf9100ae38fb509dd18e24a6b0835898a40e2ce77dd7cbcbb24bd3741d4cef74f53be2c70f2cb680f5c190ae73aa17c23da71b5d6dfa9c42b7712de1572d4e2cd4f10fa73621bcc17292eef765705b749028884b5959e05527d230ebcd569926948e3c733120d7b2252fc364bd461ada777886fbd33e0d096688e26dca5b0a1993e44852ad39c40f4fca5c7014c93d00662afde6ef3337d9037ca318205d413ca4fde8b58b3dd209e220b8e1e5f43bfd6736bf18cddf08f9305dbea5885533d54ac7c17ee3510d8eb0a90792521e5961db6b9f8989bf4fb6ba20bb53314ffe6bb5b3e2cb7cc361e8962c99d3f6a93d94de4183f18ead8b3a04ac5a45793db8bc0f50e205547667f3b38965e724ee5e4c7f1c5273631612c56d3064f2b9b4908f179decc8bd98c315748988a6f553c0164accccaa6a86fedccb4aacd7a142bea3f052a8fa176d5ba8bb36f4d0632c1c71971d964d08cb282042ce9a5246cce44340f5ee48c596f532610085e6973f16edc88cafc617d59accf637d0002bc57aa8690d7d0c9c2ed043b1c733c89dd96ed328cd642f700eb22e6dc9cf481fe4f695468a8018ae6069f8421e816c33ecf791ca6a874eddaec7cffa85e99db106f5686c0b7dcf0a9604440dd294fe40b726af5a18c7dc561af13b5513920cf380a8e05ad99701573c9702499c8f12c5a1fd9f0e183efd56c701e9aaba15930699ede126a76593020c121142abf96b46fc488b689ed0a5600ac6cdc0fb0aa8069f71b751f7b1b94005afe1cf49c7e201c323107d62c52fcdd79c7ff1cd2039f5c8133b08ae5b5020391cd6f35bd8ff02aaee717dcdc8ff70a544bceb6a893e4c2dde941b9047cea3a1205b4437a94afca389346c662fb7c9e709d3e43eb36f10c180580a286e994b3e23685c2734b5e5df08c2a1e08e74ff740636ebfd1f85720d5617ed0f7a723c81a2ba830a1b08344ecf904684e9b24587f1a5a7ec6c594b1f61f9b1dd2255cb2a85f60cfc472cb9c5b766f91dd12bca56f580c1f8e58d609ce5ecafc7ef246a352d3d05bafcc92b5cd6f33602024ecf939df00064b873cfe8bcdc3820391007e1de41bd5295bbbd0fc24a9d2866d8d2dd806c240846f02ad752770f4bd5f9557ecf492080cdf8342200c19461ddb494dfea255305eed7faa5727c43d3a671c22d8824f00e0daca41c2110fd987d6a7d3403109b5fe750453cce0bcf6c3d08f43513befc17e1df4e100d90d6869664d2ce270d66b935b6528954840e69c1f220f6d9dbc7d3c859b57d769566f5f20787d7f764e5970667f729422b5d24a05ae7ffa31a7704e60fef185875884e07b57c799d471ed978fec0a9eb2d7910865996523bb478ed4056a5ecacb3d5b3666c867849e1ec4e0f6a99fea5ea8518b4b213695dd0d801fe50bfef29e108323ac8b98ab1bb258f928f547699c359241a66337235cc71e32154cf7db45a0303a8bc9c6f47e327f2d2dbf458b5524e31a3f8aca3b99bbfcf276d5a57541424c3f79764a53593ac12d41ac76d3d3c4bf0330256ea4fc498570d37f16b83e23d38ef9ea7c1b322ce91795c6275710a0a0011241bbd3f765475090d20e6e668180c807eb3be8ec64690ab566ea3485fb1f86fdcad3ab5878172e177461f1ba71f9e81e3f79240dee96f6097d98207a0673f0ff344a0842030c8fdb5c58c0371d2e0bac0b3aca7b835aa5a631f1e744ecaf85e5adf5a35ab073a12d91070ac72d01cb3c69d561d766d851bf24e369ed721934c5ec7b57f77d66f13ec3cfdc6e638ae0b3094c6e4ce8277c005fc41cac0fa07c37d7d7e3af72d5b3ca5741fc4518755df836caab53bff092eb8d62a158f741b14c0cee47bb593a046a9f13d5fac86e317f57fa50b9dc982ba5786f79ac5b8773a66a73b0fba153d1eed10f72d8f71c6e0d2c892da31239cd6f70825433d9ffb97356df95617202c1d51530e3383e3fa80f38a2aee229b1cf9945af09e9692b19c3f2af93a4903bd862d93d8a0b06796be7ba377702b6bbf139b59a3c2ee70c31634398a3d57cdc43566081822d1e8fdc7098922e8dffbde075fef10f93755ab8c3fbcd78d4a1c4a2a2418a9d4bb063bc7c9344eae48cd66fb14d39e962bd37be6250372238c75233c0c81f170f9aeebe76a05bfdb714a580b2b5f72e62725b92ebe30ef27682cfbe6b486316dd234a101f1de58d04d351d824eddbfbaca87c5bbb32eed0743654aaf2e4f5892ea294dd2bdd5019d2026cb09450257f170052bd81ee727d477e99edf85c3671701d3c7e78c49f1bfeb9f83ef4e4203f56df0735a254ce2118479cd42965ffbe0571521d7279c9efe83fbbeb312afec5365b476a1fad08dde367a449cbb6a0445135017acd3148c84b5de05f91b6f5dfae0a2f697fb40f81ce15f82b9f77fbd59769f4eb2e7e0c7fa95413d1fc3675b69c7ca42da89ea3abd09a47a4293f60e4a3ed6cd22f361a5c9d9ab7016dbacee0157a5d9872411ae780c55f2d7ce0b4259bb1e1b101daabba8e2f0dab9b294c3946804a42f48b7816fb218f426db7d4b503bd0f17be6dbd524ae87cf75fd039c2caea01d28eb46c906cc6982c74d12f5bf7441aa4e90d712b4c746aa91501df523eab23288d028d42cb3664ba28ff3d8cac5fad6178bf73f0b602411748c459adc7bc06a50f172ea23e3d4ef37e16b85fb524c08471dc8cb098bf455893597da7518ebf120a0afa8307123d4576130696ec4a435861ee9a72e757ca2d69e4056ce2241cfb144d2a2e62e11c8a2da9d1220d1d6c48f73cda83c219b652f62dc9932ef8b2a606ced7a252f67062f1ae1ed41ed51e36b9bcd9e2d15c22db78942dacd3acf7351df7ef116e8f5670a4f558f1e53a641a5374c24e073c53b1a03e0e15ff329090fbbfabcd3680e137dca757adf537769508a547f9e5c893c576cea70293dcee2b395bc86321118cec1232a0d045a2936eba172304b2994ad2613150dabc22e8f400d8d2cfc7336b2ddba93d9281fd4bc9fb61783803002e4cf719df9fee90879a703a2787f92916b7eb40471e9316816e12a0473c2734d176d27684fd5830c2774e9252611b5e2ccf9684f5d0b465fc45cc48de894ab2799e2d850c874332eb1a17beaed73c769f6d6be950455aff8f590c579221853bfc676813b56f92fe9b2cba613f007f61dd0d493e60bdd2a09cbf9d9e2e06475861c3bdf086a8e54f60915598437a68b798e7984b633a4a580f8416395bcd96049329cdcf14597ab22c26258a8be87a47a1e993bf2517b8f67feb2c9e85bd77758025a48d6de416d93b0f13671a0ecf16f358faad9ccd7e4914be9d512eaa8e84fd5d199493682c1b755a22ecf7d6afb26fcfb438330cfc28a734e1cd64e075db77cfde6773afb4e2f78a72ca4599509a70c86b132d160bd38f4db4995b23f8c7201942b56b98339c06c73a0740bae4813b05ca65b1888df618bd8447a2d66c8495a3c71fc22df1c02649bb29811af8e51c6d2f6daad6a10f24ee5dbfa41f55e8a9bd34a62d0b0f685381eb01f4fb439c6a7beb9e0b745052e35d16a9698c2c692adba8153c88cd16a17f6da30d923c09b575ca72e2646f955b00627faa2ed567b3b5e833e5a4cde69aeccba4044aa1312677a23fae111b0a5a99d99dceea95fcf2ea2074027abf64d71e0a4e756057fdc6351d74ad79b581aed08a94f46b4a5eae674e34a4dc1de28a916e44f4f8a5638d10b2f8feda0792c99567801175f4b7a71c67aa87227e9eebdde57ea9e8c4e5f22022e056b11c286ba8a0b47340dddee29e1ae18e6208413dca7955e1d36cacb405357d96d7234a42a0a4a1437749832d7bbc984d9d36421248fe3ee2f1678a376b125b53d7f28f596d6e8c8efb98d0647ed9b1babbe693a169e097a392f2d8550ae888681a42282209bed731510e9de3bd6812e0f0880d552e134c3195524b6814bf503548ff8ba38696bd27e26b9b6dd97cd73b1fbcd784ab1f23a02e500664f902950106b902903965aad5ecb250ead3b09160e7141ef811b4c0c7baec4c509388a2af9547fd0e2ac520c5f8000a8459c0a87eb93daadf453a5311fba12082beb99b67293d35f862069def2e3469bb194183fa2069a6e2772c31c5e360b64d754c0caab5316a2ab3c3209ce111a86136559c8c6a8a9ac452b2ddf7b224686ca24e9db42b038f0471ad508615913e4a568a5882525a776fc2852186b71d07847edda6a3df124665bbf23591aee076ad6bb3766238bda4f2868fb23868cb8687ebbb69990f23eb0ad7ae84a85dec8696c98645063ec7a48cd01d3f5bee98f677fd347f07d369c9489fa88299b648377a35f763f675de1ef747398b0c6d5e1118a5a84d0d89c0a022088b9cc1a6f4910ca3fedc786dbb494bc81e34cf9916aed0535b724443896be4d6c9f026f498e6196543056cb6e80c6457ce7a3169b336713c790290d1a3ac4151914548293842d524097fc818cabf35baf3c450a2a6a577694e12eff38d3737fbd353daa0f44b3b6cedc33b8a9d7ddece524e86a6a304d8c3d3197a174fe222881c8da663a95574d9f87dca7e0598428d18d90857ec84a43e68e042d54b17e7e4fed9248a3b08cd94753a687d59074decd7c99dc8912c6d448d96cef592038ed754fbbb743a4b4ec5969d34833279670cf5169ea0feb55c624e60ce5bd9178361e956540933adf6b5ccccd788ba41e2b12cbaf140fc466a0b2356409518610ee329be6bd62519856a3d2926df71c0ce7d51f569e0f8f80660c9298af76c5d63cf050986c7b2aa596ef55fb409dd24c27b7258982b51c3d93946b34bec8daaab4f18c1a106063d8ffcc91b481af1fcdc2afac812b55d9cd5acf7c992f9035311195f32782af9de3cb7cf34b7dd5a98462a1cba24e957a8afc51a49ccd62efc64308b8783d6b9a0fbfc0218c846174959f91eb50206b91eb0bf48816f3a16841f88fa1bc00b86f4d0a17ef75479962fc2e6408eab34af0df46e9e8c51e49820560e9caeeee69afc76bb2159982832c97f2295c9faeb0d8eb529c34b23819de6d8af2a988939247f6e57905d10ac8054bc4ed2a3804944fa6380ad89ff2174bab5e3d8d4039882cdbd1db80a56947430c480fc89f10a6b31d19efbb0234bf40fd1f3a28931bc1e3b8b60e0cebdce4ab4ad5c06fd02f5186d1352c5079421974c3a3f36718bd4bdb2bffba8ebc7e9a131a5dea3532a0a370947c87b8b2c9d7e58887550d14027998c58e89434052c5dcfe6e4f905d388f14c98994e7f25bfebe1e1ad308de8ee6f2ab56789fb7d7ecbac2b8beb98adc6bcc9a0033bb69787afe2426617b9bdd6c6dbf07fa5b20f82691ec8cf2c1a2b3ba0172012a98e2f83feaeccca5ea4f9c4f09f1739a34c72e3e83f12c73baf34dad31f12ee9ec235c564562800b3c20095895b28fe114f4eccf7c3ce395d408d05a81eb9f69f3a13e223389579290677f4a967592bdd0574096436e932f1cf061aef523d8336e4490bab56244391cf237c7d7f3bc996be38ad611f635ee90b1ddf47f48e8bc49ad575042012f8612f1a0c7bdaae73716cefeff85f85207206639bfce5a2dcef018886abb59d50cdc31516954062128d9144095e32adabc27244a6975d086996c337ef136f1d9519b2e7eae5762f39b2eae80addce60f048ba6ced961b678725a5ff18550fc77c1bae0ccf76c3b0badb88fc1f36a9393cdfa40e5a09a0303e9b86b5f396319db00a9e975e37a29ac9ed4e576ac19f8d0e103a88910f63bedd1c2087713234a2c88f32ca9fd6c442da9fd40190d21670fdd4db3aab161573caf6b47d91baa97f82d5a8f72e7869afc1179c6e59258c17eeb5b2c6df51704c7961b79c641ff02b0c3da9773cb547aa10cc012726f72e961bd8231cf24c69372c91886dd370e8d9e2a2d1706fa57b5dac458166fad92f8970c2ef57426402c0899ac407ca8d438ccdbba78619292580fadfd94a5d4306fc217167bde0b734f9fa0e02bbfebdebab4121e04f2689a90f8732c4147fafd6016a4df892cd917704626c4d28d4d5e9a600055da9282739ae8b3df3c2bd32d5931f06ea6e2ca74a295ea6d1fc24ed1ee8d64b25a66fc8217c746d5982b1b2927936fbd4e3e3f19c8202705e55ac76afe81ab98a2a46a33c9800abbd1501160cde82fe38d0d6ebbb7afa903a7be2de4af0d18a040f43367597e4bc144473841536d6f478a1ffee149948ba89c87cd5223687c2a523f9e79a18239b0ada38fca280b82a0563700382507a98896dda41a3711f279974570acfe7c2cda8b0af0e28d62e1d097c0364a117e97060f329ba28d850b39222f4adea764c16885df4aea318c3f8b18e1ce31c03937b2d8cb4b36b2f03f7f5fc89abb13f9f7cb5b5c58dcf599aca67b04e0162870e1f816344737094176c30d5471cdd44dc68ef453b24edaab2ba6bb25f3e9e285b5dd81329d53a52ec67369ce198dc8dc8a0be67480bb6af0dc944ff5de075de769eea828155e0a01366dcc49ed5ab9e6c17f55810517c951f093c3c602a4fbdd8b0c5881409a00e1548dcdf24693131cf8747a88386cc82b3be14fffb14386670ec93c44a4cd0de62b32c88ff3133a3686a89b2a453bc0c2927ea6cbddea5e1624a925033dd856532f92187fb09208f7e96dc9bf43f277b64c8314c9e1a49c81bdba4c01bf4985e76193d334297ac7fbfb0530a9b819a029ed4aa2579e5dd19883c247574190cfb3645e4359401c774fff4505bbe81b1df4236db5fa7c02b951e34a85e4b2818cb89e1faaf2ddc271b1d262b313a5977ca7d0031894c34859c9deb6306165a6332bf611b91bd95a666c15cd74e5fba912f659838b2fde88d8a8ad49ba899e8dc36748c8a7945e5d607939802f6aa429d795dae51ddd5ac5eb88381b7e62f5dc4108bba2a2b1f67f8aedc4b93a94fd5713a40b2fd7064a7adde7ff95d0519034b5d4b50754f6eddd1acf613a0a76eb24731aeb2e0949700ef0e3dab831fb0e9a451522de86018ff584753915f4f480e7b75ca79c7aaf9f641167058e7a73f142bd578a08791a5b685e9af70e52f22b616d76c6845461e99f1fd629982cda32a515113b2aa56c881a038bf3e8d3affe15270d4d0885fd219d657ade70723822377622c3991df8980275f4a01353b29101bc50b2e3b4f4c35bc37ce58fdd83ec93d7474b063f84a5581ffa7935c50f7587dc8d409a1a84f0c32592f563d5c747e24bdce9d92be9677c0b3d212d1c47d2dd7065d9cb42cd58b7dd04b70d6eceb9dddd3e123fbaf65b3305b6df9c33050be4dab191654ef63b8901aa446a34891ba77fd09a5df3f80b6e89ddff93d4203d4e0b25c20a449690af5a4b05e5c15e12558028f33c3d60cd570c18af38a4618befd24bed71e4d3f33fee0d73ba2e2f1bd73dd18a13c744516d5c7c210df67a568fa0ead6cdf9d4506156386d38483965b861fddea7803b65143abb8f536064262301913ec30c01242ef9dd45afc7ff0a55c86c5947aa7b78aea128b4a8a692ae27459a6eeaaacc72eeb493d4d4f10379a64fe071563c17c5df2a41b9d7e34dd5bbac00e03c0aedf5d9330d94904882a5f5c90ccedf0fd613368983e09d43c45534021ef9c39a5d50ecdea32de2fa7b79df8f37ea33f8e7f25a66f90fc8cde7a52d243202c95d48d60427d6c8c185be725ae8621c152c3634e54cf4a707879a5d87e68bf05c104d65675c417e53cf465bc22903ae6a4c623bf0ae4c06ba194155f8d8861ea379680074d1d18e339371557de5af49f349b891111282e426546a5a117ac377e278e4cc4b8ef5d8bca4b65b980d4cdd4bf2f6f70621ff55b94dc476f1d7e0e2d09cad0caa9b3047b42c9e7aa55ed5ced61c011a397c446504fb2d020f7bd808141b1559212b5faf8b8d1dac6cfc699794cfa2be8bba8bdaea0ff9674c9c5e46240bc744ccc45899ab391b91aac955a0cc4045befac2213a0471e8388869dc434678f5972f2b7bd7c23f5302c2a9a01c92523ece2e50458b654d2174e516f2e2b65f8875735583d27b856ec998690db37fb57736d50ce36b46e48c9ed8a807ed972ae6e7c2441f26a95ecf29957b99e2227b43ab9e5326c2f07bf39791b318934c415a1f0a62d6a69276c7f8c38b7a533c702958621ef89017be4598308a93827cabcacfe8c94359c79475ff6ad364f4af8524073436a52e86a95d4000cae7292e73ea7d004c67738a4f7d409b185224e15bb74d0b29d1a2e09a75b88cc6cb81d7739882d5c4e6c9555bceb4afa6f6a28b5dc3ef5818891dffd7150813ceeb102fdd77d248276dc70110943d906d1f0e81df28efadc91a04400de02efd1133afb629230f9fd6a43c66e935d7ccfba7a25785f7b5ab177516f19da8a8199eb6177bf2ba9662a1d7379164648a24d644224e60bae9a0c1c7c4db001265d050697739dfb114f620441fadc95db54441cd56b1ad44f5ae9e2da0220fe7231e868b118830f0605045b6a9ed7236d8074693a0b74b7e2c918e93dcdf1a952c2543b470f3c2b3b91229497e6710233d165b3dc2b4f914c8896fe03fd4afee2fb035a9c286b2a397d156f31a791f6cfb3642884dd837e9b0596b4b66f24f3077d03f4854d7fa9d60472066b987b581284888fd01012b143b9007658206c388a8554b41a998fd0e6b9119f170f06d08b6f543d6c090791989f676f98f247d87cf774264f712f444a9fea87814f39907371b144b716d23ba29a80150d266abbd8e2eed4eff86b2991329f0b7c7c22e92cdd215350e4dc31c949d1634e30b278a26367dd460c47d880b61f3a13fa14c55ffada7e367cbb021515415e2938ccdf1d74915cdc903b650cd4995f47520145b2f56d36a1ed5f454e3169ca41702e8e8661dc7ed74b6673cf35dba7cfc10405000003c7559c8edf787241609bd95c84a6ebaa2429726a58bb26a2b356554cce30cf3780c929b8f7f7f5b1fbbdeda6a924b2062f58cb3f39cb42ab80425c898625274a6ac6c0d0f9e95105791fabd3d0fcfab18efd23b25af858d1151cac4bb7c750c2987684c21a17fc92d247fdbde503901ab65465c3f340c4ee3f31c3b27e373fdd13cb6d0624216b8cb6fcc0709f5ee39f7c7e34273b99b288fe38008c27d24414cd807229b47f400df122721d8ce8134d3eb3da074d85f4d86465740fa11229e953464af4b399495d13d035ca78ecdd00419d4fbd3959e76ae55dfe79f49695605824356fc55eeffa95f9e66d727f826e93409f6f25df7a6180a1f99227306c5a364605304e164f3aa8a1dcb085b047336d81e0481635008c3cb77f4edf9c0c9db51d9c3cf72612dfd5051a141d4fde3084a55ab3d683fb14840194d9a324d7bc33efaeb4579fb2fc65c82bf91baf303fb6f7e883fa51c7fa631893497d8953a4e4e3f4ccff8060a562c863e6fbaa5f27a88dc041b7c8e3f3d5e11f197e2b335f7fa29ea3050423230ecfd0b6f7ec468127ee9b47e774e32c82948cb3670bb7020e6e03fe41b5c0ad421145c2a52765c10e1a651d0beac7738cba4c236042bed5bc8ef313f13b8b741ca25449a08e9645a077db525c03813d2438f8ffc05307c472b3146342e55a5176fcb34ee1218d31c37031eddce00ca22887be5ab556c21f2a9fe6e7a660f4aae278a82176a1a4e42fd5cf249393eb0947788917117876df79ffa3f56c462246e93f8e727d141de3e1c40a699e4b2730f82d609cd4bead174ab4fe4140dc6412fb4eb964908dcc67e4756b77bcd250282fa78b17094660d3387deba6f39f3f958d00cbbe198f1783efaf454389a7bdcc221fbe6fd37fc33a5c958f9d8cbe1b4d657e56301f4e2e19c534fd0d206fe6f415d6192efcbe3b75f5267361c09bb8cc44732d4946171ff81e8c26bab78d0875140d8791cd2020fa30a73a81b2f5ac475df0413797d145f7b3305ecac119037fda7fbcdd7bf37844eefae17067288ac88e945137b4b44628cf88df9a6b43861366a9eff08a4fd73e404d882f52fafca1c53ebab8cdf1cc4395b92b2d7fd7cf49f70ce0726e5c5b92d5a5b90ee835eca7f9bc74d37789a9a5e6d7b8e66b40c03f7ad924811070d1e3d40b28ff412dc23a9c105bdd8543377eef755784aeb4b0eb08d000582ab48a35748988d5651ea6298776bb861d9d4611f2428d8dfe4946f93f9ed706a647ecd79262f7eef54a2a33ad654110242b7f8ae2bf6e5c74e75b0881ab71027bc53d84a4fb456b78b7f357514ce0bccfdff8fa13b5e06d94a08aa7804c882fcd9788124ae1758fa76ec9d84d9d0d553a1c773db7f81c77061bbbdb3427d30ec2ba274327024743ab4dbc07fdaf54d82f02e53e95b3aa97b2dc79885f9d90b102e0d5ad3935dc76eb4dd7c482bcf60473aa5a2e708afca6ea737d75600ed356f2de5a07f995d82d10fb0617acda70d70cc874c94150b5b97e7c398d8ad82effccdb76818d47653f6f61bd4273921fccf41ad079e4096b10a5d896271f2be7fd4660d2eeab1a0afef5197329a7e80ccda59fbc112340a4d905dadcba415be50da3824fd89814867c86e2f9ab40462762a7343fe5049bed31b25f32ed0a3d6bdffe85e54847c37ce92fe1689dbe596e7e0e788c610fbee52074c10a568c5db6c00dafa4624fbe55e2329f76ec09e5f1665718198a31368a3443ef0bafec02900f1d3f77cc98ffda556c8da1e6c34dbe90b0d7490f58222e3c01ecffff13785a2567e6f89536f5bbe681c5aaebb479e2d089078ac5d1d64fbde9b6e70c5cfa59fc86bf5927b46edc797e1eaedb121ee4909d444db0592d5f082babdace69fa44fb35a8cc1d097566ee0265f6ee6380d29e47b1937f82fa95b84e401506bc03c5a56fdfd9a797ac83add8f85818a82ed73748a2eadbf83c5280dee32dd895ee20733344a47500df5157f53e7add7c77bc95a6b2c75e369a208edf54613c395c1a245bff132a63ab3a0e6ac78d98b1b42fa5573502bbe888cae8d8faa70d9dbcc8d71c611d53c2ac6dbc0d95ed664ba267f23411fa78eb003d8237d3cc48cd50f16b86622536a54f31ffade70288aeac1faa07551a58f1b065048c80a74c3cc6aaa995ecd50ead773d1d25cdae457a85d2c6afad5eb850daa07c53dbade9514600a8f20326dab6704675ffaef11a32fc2ca09437b1210c346588eece2881fda3e08aa92221c71a330f93a711dfa318c9f7f08282e00848342cadee63581971d27d968bef389e54b932d8674d7e48f79664d319055e59ab7061eeb640be535ee302e0d8cd431617c06d8de0b13ed7b4f9230ebc155cc4fd707bb92f1042d50784f482235412c7017d288053b12a8373db62134450b10f3728e716547827b2a717061987e5cff5a734988bc43178e42d614ccdca64c3eb6750eacb94d40aa3b212dbb38ce41ab2952b8e6852426679846798240c987cd47333c583a56bb9f6eb98f42f5fb5e93605153553538ad9e0c631d9f96f361f7375385f6986d2086ff07c104e130756b733a74d89033c720c2490d7ca3e6527b25942df10d78d9ead0fc07d54691372cc12213f59075a61f9c91a66496201b8a16e70b397cde378815b564626d056acf50e8c68bb218396bb3ed6477d455c73178c25b1582a75daefb62492c8d472510427022091c48ebf754979997e054c59d154403965f9ae9238e536858302fafbc7dbb45b73506bc2ef5491d0bb00c7a9fcadd11c3f224b86a1fcfb8892d015f46159f07f38a8d581bbae62f13eb7a4513b03e1cb9d763a578a290761568583a51917e2c85bc3ffc849bcd806103cdbf7ea215b79a737f2fc3833b7390ae92f84a54b0a5250dcb65783c234f4e7210f9fb200cac4cfa7c3a96be20c133d4216576684c67bfbce6bee3c60e7251705823a6bd49f06a5ae14005cd099d448d990a25687c9d33672a79e3a24d65c5562c814f5b7df24e9f72b00d7f45dbfd118a2aab3e8baf8fc871499e6095d7cefce74ac10e971049d18ff80545f43a7cb21c98b3e0820bd0610707a135ae49d6b3910517ea2df95897bab291e67a212eaf0523950fc545d0c7c4c11905e338cab4cd4ef640e79d576ef77e6176dcb43cd03ea0d5d97bc7654a90e721c92e15868d84dc8f2885abdde9242e078cb8b62e40a480e8c54d51a5a94b8d296e2bbfeb2a47752d12c3e3a722f5f82e7fd74dcfee67cac6e75db0d5d5e9462b56b77b30bc9118609fc443cc9dd81aacb20ccf42b41603c0a82e316859992999e5f4e035eb95e4e0e7c5a730b3a81c95e598f661ad63a8cbdd238a74a3ed0b60e02555f6382928f9128b22be7cd10a1342c7fb531825ab121dbe6f6b57c6854cc8bc69e3e32f207ba9294a1a67b79a4d9a3c407c95e6ecdc21828422939f71e4ddb2aa51a972dc0053e49c27141e0b2969f1fc822d5c27c2bd585fe0e1ccea921e3d7fbb4cbd1d788d8fa8dc32816f36c42d3314a659292b629e689194af3788fa0cc6f3bbb7c28ed0e4ff97fa9d293d557344f6b7c17c759976bcce72b29b01975a89d89b620269a27ba47ca9e8cb648b3d2df8a4cf4ccbfc3a402994f294898d479fb59fd93443f74dc23fd924c089ffe2a9f99f278fc077aed33f2eb37289e3f06427105ba6206835ee4c97f0bf3559c2e434b040dd404d5d63fbc7c496e2a540d9e51bc3d4b0bd3bd864e9f1ebed2ca3476d15067d358372e9a21f640da208c77cce8f31f0db9cfead7f6df8274ea0f1040af519e7446607bf0e9b5c11fcd7efcfa2dd04108d23493fbdfdd0d8dc58636d20b08c00ce6b8f678391acd2179330f6f4679fb1aa3a677657abc471c10a106c9a1f570a79aac1779310b1d36f32ed0dd6cf17078dbcbfb81d4a326d4474aad76270b4ccb3330d784db0466d5e6389631c5d8f7de1f587288f029b38a2ea56f8934b647ff0da51efc7b7917369cd42a914f7ffafe85967ceb5a34ad45b8972761fab32383f80d2a9c4239e9e4809bcdf19e65e3fa38ea0f8c5fda5622cb0896d17cd6206d5d8de38ee0fcfff3d97f0ad29f5e4e53a1f49e8d82a82267520319667de16623939f7ddf08e4600487111b023efccb36ca961f3e7592ff4681c6c399bca5400314f9bf2a487c64e1949caf1e7317d1bbfef859854787a9e51de0eb8e71fae917ab032433d4552269df033c12019d238606ed757007b4814154c44c8ed2033df5987aa117c67f52ef550379c10ad121862273d35f647c42531054096153d71d5f48e2bc1584362d90ed475c821e054a35b3f0201cb7fab4b7242cb3b8a1654dda769c5885d051eff2beef6e6527486d49cd2244242af883a19d33bc83e5f5f4f89294d616ec0a1388b224ec5805ba348361ed70657b6837f5037cf8a6554f87e6596a0351caaee54157e760d50fb24907a0eedbd5da2ea2f791445012ec6b6f75430f676c3b0c2035cb4be36543508c50c40c3056bc263aa3be8c73d558f1d332eea6bd184dd22cb9208c7b87007d80b3fe553199984d5188fc7367af064109b42ecb37fbdc551e8fb58651eed3e45f08d7f6bed751e46057783710006d23d7080b7b2edf09731cd471f27e6b2063c5782a94efcc3606b756961a7496f602b29a3aeeb13f4f5cac589913e5a06fe570c6d888bb6cb34567af09e6c343936b2f2a4929386cc977d5521d245b9c8704ff3c94b4284a0463e69231e0cd56b358e100d6b879df40f4980d954e083d2a877ce45e88217e2f805da2556d504aa89c0851fcaf8f6495e19c32dedd5b224be4da1c3421434a7587f1d5c22fd297e0ea18e831fc18bb289e2cfb7f4a60baca461f47b45a119f38c3afd5c240f00af5e82f7f8602215262f4218c3c76326d74aa766fdcefb597df18dfa6496eca1b68fda93fff1bded5c4cd6b7f22ad2b121174782d35a615c85c7bad29385df0e2b345f99175f58d600e79e3a90d622193477e17eb087ea2d25d670b17535c4617c02b54ce0e7e05e90fa1e5bf130d9d7e4701400d09545aafa00ddd1ca3ebfe85fb02743418c3eab4140c60b2047f3a053b02bb5c364cda0e860386b581dc29273f4c970b0efe30633bfeee29c12c37eaf55429c9b641f0ceec4c10ec1f0c29481c08fe250d745417ccc6452d99575eb1407b22c5400399a06b33cdde745f1ac22c34bec1f797368de3ccae5eb6abdb323d8bf6b9a4c9d814139d2a7baf2db11e4ae58dcc1f076cb54015b2341eb0f347dd6860ab530cecfddda836cae73d26c51fc0b49cec1833db2b3be1d6c07da7479131a0d0e4fe6c070e0f74977670ce8767e0e9220bbb4fcf87e9b40b393419e8816420d057fd67e9b97ae3caef35bb1260d481ddf212ac216e4d06a13c31dfac91a59aaf1bc60d7993b2677981c3f8ad454d7e761e5babf3584eda01d3512a05d130bbed9b32772af896630a2761d9ef53261a9e94536a0121ceb88c91bc98e8ebd2f0a645111ec055feed30362f0953acab09b9e48e428656ae417b6dcd3c1344ca86071671c8d7adf0ced4874eb3e58d132fccb0ac65e7fd02c94b80e5bbc2e8bcfcb3f6d1805f047e2980d9bd31e99ceafcddbeb4311a5abaab86ac5402d0d4b2c2884167926b1b899312842068ccc0573bf73ce89db0fd7e09a2853d76e9835eb8d75cee3e2aeae14a23eaaa54f9e42e635395f2b65767342bdb23691f060780f9a9b33a7904d94d1bda7ddb7e28cad41dea8ba338d4b90086c53ce03234cd6ebbc14df04b5045fb45eb1cc0b1e1088271cdcdeacb7e0dde48df237bed9f77d3bc21b2233fbb4280aea2dd6007a79334cfe8fb58bfdee26243bb000ec79940f61910b2786aec3aff21c7e31fc974c583b6ede95cf50641f66b1f94b14d32fb274f079d5d544d57f42c82cb69828836e0484d4c683ab805ffd74cbdce0d11588e853b0303b4d1c4fc3813eb677174d6e30c515888737e3e250b8bae6797979b83d6901444c8375abe42e0fbe48563c6cb868acc0c03b4a956c71639c43cb17d00a16690cff996083381c29b7bf085932f64272c263729e3838a3c1e90c510a865cb3bd084194b8358781ca5e8f8ea60b8227b05893c08d18b9d05354944a47e8d27a04ca55c67a4606b5cddc8a5f31296271cc74a04cc9770b7a1dd2cb9350f1af61aed1b6afcea9007b6b2543d10657068e0c60b86d92b434398f94c46125d8d1c6c4009d86029740aeea32289ebb0891adac25cb7dbca9e6c445be26fd3f48520372203b979a91ca785cd74f026a2f3ebcbbf3b54ded3f3df38ad73eda66da76935ba53b1193dc7727c4ad9bba831168f26437003e67f257d3edc4320544b700ce507998b80e33c86166324625b2e0ac7b238e608bf93202472d5cff56e9733e6f7e8621bef1429ee4d8b4ece0c204fc854ad893ca47855878820125cdbc583ffd046eff271872fd3ac7ddf04693870c92b484be53ae301973d4fa29d193132e1277de22a76b1dd2cfd17c02a00d865192c42b952842bac8e8cca306d4d75287437e4aede4c2838229d41330de1092377f29cccfb7918808953da5a446e0ced499061c1033f6e84e79965d2d3f5add8876f8497d056d13483841f100ad15a1d00ed95450389a681df04b00056eb6cae312aa32fb7419d7a4f8d4d26bb2c5fd140f36d1d40382d99042b5488bf77534e64b9b7b407adf88a600969a02a1a112827a867e76ce453c351027a2de2626b132a0c27070e03e39e9d70707b3afa8f75fb63c3a01e457878afe62280338c68a3556753043c812621e49277c759b040cf930e2a4daac67ac59f22c898e3fe8b542751691266f870a7176d12de1a2e0d2d7e3cdac3fdb957278e0ea553057995632e14fe4465f17105ca9540b7ded623c6600058ce089eaaf49dc3d3acc748066dc86c5a4c0f6aefb4bb8076f4791383b3ef7b233f3b39a04b3ced7dad10cd962ddd63429a5d4e350b66e7685148051d8a8bf80054f93bd67fc1e3eee45c72f601fb1b62689cb70b2b180bc613340d3bb2a67f3af1f98c1751f9cfc688be80406c41a3532e491e2706f0a202d441c46ac27d21a433926b5d36b0bf3df78f61aabdfad9ac003aebd0580fb0764a8698427faaeab8e113bd20b632dd0fcdc0e949ee90f860c65b6e3fbcd80ce01ff902970107b9029239251572a5b00add5ac4e9843be1fec8f6f08c387593d02192e085b36eab203a56ae8a2c0eb75ee3c33e136dcbe7bd40519713fa6427c50387025562baf5196a99189a52f30a94238c3ba555d0d6d3ca05e2a8668f8e6d0f8dcb67ccb26732ccca92134f0619c60da5652fb19e3f3da391549394ca2675ebfd3dabd8a0494a52333d12151f0ef537cf53eaca439849b67a1899c1e2551eb95e62497a5663995b56cb892a8f39358983a0c7245334b9476a65b5f215b5521e2af6f144bef1d9692bf3c77c3338155705cbb088c9ac66755097b888527178d54d28851686b1bdd7c36fb26a322c6fcb37288fba0517d7a0efa304ea99056d48c29e8ecc842f1850aa48fd3add8598b6286b7ee422e4099526ca3e753aab2a1bac0bfbad98b63ed9770f13d973142977153f932759fdb41953e52cf026ee4d38e2b427ad235064ce16ba25f6824b3348fb30721e04fa1b1fb3c0cedad739fcbcaf935ad17cf6e4e635763a3e0f0b2519200df8b23d58f7275f92f9e4ce165151bb27a85ce5e65a51947ad3c6ba56597b349e3344db3b1c571caad0935c32bfd90dc6c9c06c4ee4d24d9cdaad277f25f6e7673144ddd0b5a292560da943746d22ef4e229d37716ab2f47164318467183c09fd9e4dcdcf5f72ebfe31c8bcf89fc12af279cb02aab668df25d3c926dfc9640534d462a6e945b70364eb27b0b252a36f9da9b22fe370634bd210999e338bc2dae49acc1bd92387c6962d22d599bf18c67d13d921d2e4cdc2204f76b084974879c285f6f854978ebffd87c2ee79f31def8f22d03cd3772d6a5378e10f300b1e51b59f1dc83c117c7b9d2fe937ea3036e357f34736bb062eab419cbb886353469df03231657d044615b34b719daa486cfb384f2dc3f31012464eaff0813a7421469f5bbc15b4572e81c0f91eb50207b91eb09fbedb2c88e1bc7b7b251e890249b6fc5ef553a4d3423e786162225658517a6219a97ef7cbf594203159f2c289c5abe6376165a754c9989e60e1991964f4de8e061780a412c347fbea222940bbd0b3895a00c4f6cc33bf0cbce2e33f0c2b48348761dea890bd5f9d7aa082e1f2d75951a9dff0bec3d02a5d0754a2523b16ebefbccae15993e51b4aaad9931f9deea554ff8050329665e8af4606baa43217b1dca19621137aa5307fdf8473c353a8607d7d82a44dd17c3959900db2dfa574b9fad14438a53cc6c7a36a01c1a8a983db72bb50be1a54cf5c6c1b1d37bca15bbe006e2688c2de5f6905196d96282279eccdcc40ea7acce33c2b66220e216a86cde9fa8916183544160b7c45245980fc83250f1d1b8a51811276775af60abfd0a2304dde25e77c35bc9f47a8af7a7ca4453b9bc00421049a40874a2a907269dbec61d953dc21611e86d05fa5323094f6688fd70067fb834b8b405673ef16818fe1d8168c8f5f3ac6a64315ed85d8ad1fb09390809459de4a5a137f92c7be3656daabc1522af10dd7c3345a7e8d188a900aa6e79b63eb6b357c0b11bafc8283217f12a923ea1aebaf416afeffaf6f0f1d45ec729fbbcbb6632aeab1d001a3653384e2de9d458a507f4b80b8cb4283065651d1f99dc5eb2e7c5129e347f2952b0e88738ed2b7b87c7753e50f24accd3289f8b464c8fee54c32c3b7def0b8f7c9f280c19c2978074370440479cb9584d1715d7ce6164160c996e47fc6b4d85dc965dffda8ff9735299d584562d48156bef8cc7aa1f41e7c40c5034ddb3598f4b0163883db83f35f3f8917707dabaaee932e184cd73c45dee1d49dc86133b8e63727e151b75509298e83bf4c13866bcb88cf02a73cd79d675eb31ebacd3a07d4d80dc5bb2a58ec08f9c24f737eef08ea4d6d0c290bb21c811a604a88b99dffe8c8237a438906788f7bcc10aa820e94844c2251c8ae4a7ef9622c2ef6ba052371bd4c4b147ce216ded062e698157ada418ffcd10fece76d75dce4338a33a5b71cb623b7c1acb34b21ba4721895abc51e6f28eed2e1b2652c919b81c223bd3bdacd0e1e83469083d31a3888a0ebc09e34de42e9a93da7f5ac8d90a7b3158101abd5173a94745baa389ef941c4b899bf8963b21478877c5910a49337af8ef6f15a8998c9ab3a54d8487b994edf2a30a7bebca10ba3b799d717e06ac1d2cea10e4a1f22999899f3b7601bbbbb50fb8ff906f43931b4d9a6a1345c9a8770a4991138ddc0ee1b642dcf33598aaa6af8d7db0e4d6fac8e33e350afdc8f5b7e769aa1c14bc115f7ab2bec6f4490c8b68a9d76fa7c3cd55cd14918284de5452c49603f94d1c871af6d3bd919e65f845e0fdd8cee65978bd5f55596c68fd8277e2c67adf1f8b3a4c1b844384c2eb9755d0a59ca330405d312f8779c88a6a9922b10319c4237e787c16900ebf7a30508ab4259278a24cb6b7a87f9f71cf0406182631a0d5515c52d90301f9fdb001275ccd57708905eb34b3a1a33495054fc3961fd0a90073b1f33aa8ced7e43c52961d0604820f9dd6160143e5500ad1c24b46044118c29417450364b22ce7fcbf7f98274a1b5ff481b9696caaba31c92e0693302d96db5aed287ccd85b1792cd83f60b24059f15ce2cf6bb4bcbe3e9302871ccf5e35eaceb888c91546601af2a504ed94665e0796c19b0536920316a06b261c12660b9c861848831c1e8e816aebd40f22d3162c46189e2c9b69dcea7921d68fac3b3cb76673b231e3658b8fed8f58eee66d47231c30ec27a80f60c0dcd19c305a9d88957d150501cd927d13821402252467d23e86e388aa61360fdf943b5ae34c4f4b22f43f36c29126dae1faf0b5c2f83238b7fc171cc13b234eecb67108fd0b226f7a9fb684cf7e6c90e61037df22f643885786ee0dc336c72627d7fa6e32eebd8a5ea8b4bddf52b1bb4a6cdc0d5b8c60f4f0e85cbf695c5f97977da57474c2c01efd2a21f16a89a129655a8f1ccc53591f5b6226a7c0dafd4038a5caec7e12e940b74721b888046fef3391fb1e99b766e3812ada78390029fd1e20ab51a352cb40e7b271c92b2dd50ef058988bdb70fe17d95c0ff122919a44aa9da1a2001b6c27421575e57bcabb02795905840197fcb38614a694b63571b23fa665f1fd806d141658b1d53b81ccb04996a9a5735de5d77df9b2bf922ba6ab865d1169d51cd59c2b58cc9a7bc88a5e9a3033c689893aab2805cc3f068d9c075ee4a452f45efce1660546df0a7716960fdeb859c3c3a75552e56553a03e80ecd6eedd6689c65b32734216879f3257739fe1b42e86998590750075c4d324208117f774120dba771c8a118704d548dc95b0efcb311b90662e0abdebff762873751cca6fddf318518c49d2413065fb81a9f9fc0078dd0ea0457f5ddcac9c5d7839d481baf6db98489c0fea0a0652183216115c59bac3e6b6414c41d9de96ba5148d6421cd44ce61efce9eb32812c11cbff22f3aa15d22c66071cea2c85721b1820883930844f46714f92499902e23bbbf52d5d929249f84950693a5dfc639620203e844194a133f40eabbc4e893337665f88818fd7b09fbe9278ad248df77aebf373dfd39ae85e5d647c70a795a21e6a3517db275fe0313f422a76d3f7573907f0baf89da8e93d92fb6a854853f07730e33cf68be5fa941c1f25092fe5e1e818fe00e8de302a62b39307b138ce8803ec95fa3a570c2b8bb47446fc04a90833e11c6f014b81011e8e102bba93cff32ba6fe3b52ac5a9dc1a5f03033b9df634d455ac84e943afd56669bd6d43c339bada852fc09b32147222b9bb05ec45711a023fb5e83c695c8b44fc44835cdffe8a998e50dd30aa0a0819d94a1fc4366a8c4f1dd0e11b53f83e83798a9fa8907b018d6fe540073aea93998b0d1a0c310857e149b668a6bda4b856797a9dedbb4c8b5a8c2b66edd4a839090baf22d4dc304793e4216885880dfce92f05e8f838cd13e5c22700a8714eb50fa87893dd19b5c65e8f9d500a7743088925141386cfe5d78d035e746e8b4d577fef0fd228ec0a540fcbfb40cb2e0fd90c6a0835213586110a8ea7f60e452cd65b9e6d1b82f2e87db12e61d189802278dbb5fc59ed1010fef3ffa53e9c08081024141d86c9ef966aefcdbdecd032e605ce791b87384873f0e37c4c9dfd80fff28e70b9d1ef8005fbe02260a7a23876649647e33aa9c7d361099e5fe08b3233fdeced99e6ac917e40a39068b7eebfeaf80d26117a0611e0ffdb4d00bf14e12e9ce2b42c5489e9bc70e739ed0e814050f0d0fed211aa58012cd553fbaeb85ad18c77c3b12ab119450e20e041a983eb2095e996d3f14da3723fac084cb3d7abe8e8ac8090634bc8df753723b6a97ede18936cfbb9d287e2eb859029492e0db1ac9f04bba1c2ba2cbd8b02f4656cfd8c2a019cc6ffb393f24eb5bd982253a1f0fa3c8f7e30e4feb75d785dc07408eacf72a657964c4b6a9e9fad1e056feee961cd20bbfa9a975d826135947148d18f09101516174aa1e8d1a797f4e0b9d64e15fc0dfe2f4561b4518f0833488f44a870e038c3d92951f3eee99d571a9c60ef04eb2ce4ad3f5fa74af348278fa18a936c9046b069f82873654e6c3c3699ab4e6ef5aeeed97af7f824b6f83567bb69c79cb46d6ce382294315718b24f227a069c6ba938b2e23d0be8fb9133acae2bd9d1959ac8fd30fbc6f8ebc64ef9fa719b7e262f869349587feccd3e13602800e1621e8fc623e82208e5a9b22eb3ca9c246137b4042f6ee4af8ad6d15e4ad74d09a7d5d89869b5495c3824cdcfb4f4705bfbb5015f3d8ea9f658cfd13a6948f9159ec4f7051c49d4a9cc04108fcd0f0a205db0cb4148a015334f32e315d259738e021d1646fa389b75d02a07975cfc69a81fb330ef515434dbc26a750304023a76f1be6a0d77bf71f46377171badf859186dbd3d07df2adcab94c18c2aa84e484bb44e3378f01343b8e4f69b150d9475c88f1b62ea3601416083f963ce4f28286cdf25460cf26ace16982240d7d93ac9ac9295f641dde72aa6e6f1bbe6bd5f29a0fc991d0a3ebbe9ccecbbfa10e6ae1d5c47d2bc9814d95ead9e154b5361549eb80985b598f25786b773bb0df3aa82afb5ba8165e36406bd81ebc418e50d408ac5d4e3d80ce79387dc0bdea5da1c7de3e3aaaa7baa4be6c6bdc4c0268495657e41b8522b2d2494aa4016c54a98c2678b583712095076fc2f42fdff22de914c9e11b1d8615505a75f4130401e340986ae0644fd611fa4339f858074acca83f9cd73744d97a2913f92af25913cf557bd03c54d12af1d5c0cc4a6ef7aeebc6aceffa1b8fa223bec5b6b988061e7b059cc0427c14575d47b3dd3bb2627edd27051aefda735bcaf99ebd3fda82c0f7cfd40f9d4a06ce2ad53aac067d826169fb58b494889c40a2788127ca93a5105a5791cfdaf5a890af09544cc377625e06f0d74036366c1ee45e2184cb038a89d95b9793f84f9921c484d955a8d86b968e27a75fbea5b7d7267c6a59c60510b419dc6d66ca5abbf202b2e668bdde90ecf176efc846318d8585f7b7b736e03fc2f2ec997336ccade4aa2ad2f6557258cda9160094adfe6f1c796ebe737147c7d8c08fbdcda9425f929e6306f3998e724fc1322de26100ab61cc2f065101421f5b4e8b63df135351b2247b4757650b476d87959770724e9c1d68131dc51da489310b25e93691ebc5c8513c5be65d1b2cd081b0076a53de028aff6ce83f0b6ace1d1ecbefda5f649fbac96d09852f7d3048d68303e64bb9707a635d3d632e416d0de7afb36469611964f0a458a572ed7375094285eccf97baaec371414b87047fba7a6d468051d61cfa3aae8d2baab4588b3a47047f76c1351f00e1c22a9693a61b089cc51e8fe01e540d99d24c0a754fea390e59e987dd5ea27b9bacaf02b5f27bd1502a325014be8cb1db69c0962ac3ecba5b3e254991cc5a213065a7f43b67a4c09d721999b9ae2af13e32f99fb8843f9b2f9d2bea2cef06e9948970882a41bb579983a02623787164059da753db1eff13d2578410d7c1ebfc9da746e45edbc795e8a1591c95e20d11a812f7bf87d5574b4b113aac06f9a1d7530d71799318780ec40c29f37e633f455b4b0dd01ec329f24d534a447a698742e83655838b55591386da38bd184e41fb5fd68af9f9d0356b4bc3bbcedfa20b07ec050d2f40650d88da799626aff9b444162c1e28bcad651dd14aad8f555153c1c275f89426d21524a55b368359e5180c3ef8c3a161bc620add9103a49eec8d028534830e9ef93d353f232b527051a600e76519a4a2563c5d777952998e04b6a793998ac0e047ba3813a79cd69ae34b3831156f9e66930c9a219b843d79280879a982c1a79a54b8befa07fb04310f338d66b347ec4f1db53fe84acf5e4107cb30519a643e0953e85273429bbad3413c76784194598fc43e4fc0d6d3e72d10e48faf169581b10d4a292eb051750d54ee11ee0d180ff379583f551ddb046bd8f8ec5f95c208ff9c52c74933e3ffe0e6b3b2c8a5835557604cf175521931cdb27fc001f209ef593635a50620a55168161fc6ac8383049ea5d3e27c679e0389a2cd01ac0c08a55fd0136ec50579a58e952cafe268d0de7e66009cc95893327bf8f16ed0f5a92700d6e7cb9ea4d43bc8ed998b40c954ef63adc7bd035df9f307f1e3eef1243071fd3f3a6866a86007a238a8d4dc8b3c48ada943cb3c2e4736a5bf7c10f56f4230f17d095e5d4a85dc6ca1ab7f85df1e8bf22326537e48c7c3c5e5bb06ca43843a7ec5c8a26d69f8e7769cc2d36f1614f88b195be5e4d3e8c7c6fab969fe05df79a4cb1cac0eadea6c99802898ee1bc5ccccfd53ed44b5efbdeeeb9b3727178caeea7e26fe62af47827e9826ba21f32fc6ca453837cdfad29c6dad22979b76a58ea0533cd99ca855d14ef0c6b02fbaa2b4ceac74597186e004e8bf9ba6c1ff9dfafc94059bb44cbde4413122f565b17bcc5191a78b053d27f47ee7c3aa006187984e809278bc494b243b8124d4da4e08796a5d64b2ff6246cbf36650dd57fcb9112aa88207c910b11bdda716912f2cb63b7b80b5b4421d4a664f1b930e0456fc4624b58490369005e1f2a1c8058cd1c85b64aba81f115bac45192130bd750e473db4c198e5a0ed71dc05b8ebe64342eb1d3c80f0d72f1714461953a039382e04f6ffa12903177aeb8ceec6b148c1df880dff128ce91e7a82406d5df78323e5eb5c82a710031625209a800255de5aeac8e37cd3124126f5c924395d188a53fda950303c336a1638f1e030c8bdf6ab0e9240130a8f43e936bd295dc58ac3c10a047bea2ad793da756a981209d8c0459a5f6c096f6b73d0a568a90103e675249c26e0a9b86e54e2a163f4f92dabb4563a6dd4da20ad53ec7c5310b74ff612d9df655da16d6c11f52d9869d1181a5a481983f42793d13da759e741f802dfc23af72509b2d4f3043ae31dc14dc008b7980cfa223977567226a1705320672bf625556862c4a3b4fcb6df54aab20646f7ce819a5076f90c6e42d06db8f176822e3480065e6c85512a4cd68519949b9a2b8ace298894918d30438cbdd7c5926d46d069b69a7aa3f858ea75a22b92b589017435213c0465f4a122f437f0ba44b7a17490e55e286aa66cd426d5686c8c97a40e5442dda10d3a7fb0f5cf1e159ef22b67bc55d72cf67b051886f46273db20c9a91f82701c4ff37f3d1de2717dcf0f747390a3229f8ad8874d164345af860d36cd93ab48bf3b03f5dad3020be6a61805f757b9b45340ec7f51b5413121a9bf9e7d0e144605c215abfaa909ef78a7c06d1a999a4fbed66e023b617ba3de41117f9bf1c95c215a65f1ae78851c7e047baa22ad48c6ef727f92e2a8ee2a709aca0b1297c9fb0c86fde442f89f294fefa748ef1b42e1f75889433ac938437c9841de5f9a6cd5debc09c5202209362c84e1be819c9bb7a87e2ab4725aa696dc01b66c6659bb5172c54038d7de45d5d24a7fa2cb4f3129324ca1e6fe38e56d56b951eb8dea068c676443bf6c711bdd381bb328948d80d893ba57e80a7a951d65521de56de61d8db1e1a3be8c86b49aa686d43bd000d5095df4e58c71b2b4f89b87f084d2a50c95484a3ce8050f148de1e75fc9f33f6cdb125772818089b57575c281c7e578c2cd533c1422c8afc33c7b19eb1358bb826d451a4b74776d6d6e41d21113a9bba630ed4ac9fd0a21a82c2f793b307415df3e41fcf61746cde7903ea5113e55dc666aefc889f5592e92c7698f519f25551d18eedce6d056c6b49b939f4ef38004a1b3b0c180fc16f91e7a73339452ba049c8a42764613c83e8855e75cff9e00669f8a0f378686cd083f4ac8e7f3797165f7d67471a9d760a1f9a6cab8e5699e31ae79bc2a44d3a0a23a27a5c904a324910642078e7ef869c21a0a461ea460ff0d0c194f17d89b09f08cebc383e298d6337910d1bd539ddc78af97bcc3fd56850c231555762b817960f81339de428591ff60b1b040c5c445670af46cf652288c9b12a818401e2ce3672fc07632a57d4b96601de12e54ead75ffe2c2abbb6c167bc82439892475a601fc46e05798bec90b8746539f651935e3b6e7bd77503a00f2399214d434f41afdfec75de8e2c08d350ae34c50cab609255ad0334cc9cafc2bf15179572549a6beff26cbb43ccbc9a6fd0444b6b248dd081557c7480e8acafaf6dec7edc587a0e1fddb41d7a36de15f01d0084c6cde38a1e36eead61777627aaf3f73e8ea4dd5143e31df3c3d65b8345215da5d02e89000517eea8e3053a09a2eeeefa70baf96e58f80faa2c8dc9f362e5b9d1db7fd5fea79204315e3df2c345c2ebbde8b56d9aad1b381e96b7c3a933869022c20dc9c24f94f41da94b81911a0de92c15219551d84c747a273ad0afde2c240d751080c4741d5623ae715acd7586f2b31df96bf97a95b00e9cf9315b6b8c64a737c99c00a6bc9ddf8b70aea998149a8d6235926b47ca2266a94352e9b54199abdf3f1ee8f18e7ebf29290550d0b5b3268ee505060d438d7c7d4ab5b006699a1ff99db2202d3f5367ad3f62e349b4a17cb9386125bcedb22d32f82aa9f91a9c7c841095e1bf8af44707473482d6f553ac567cba8ecf892c8cffc1fe01b90a5592907e59f0c2a5c70a7886053986f1132eae4561d39bc1f51d1781e61d28053870b95eb6c5160d106f4b44fc7c18f6d511836ccdb514540495c264fb9be6bc9fb1eb764e268496200adccb8e413985ef6fe2bb0a47155698a72274ddfdb9a2e6ff09e361a51076be5222ee753880b7ecdac136404208621a927a1ca3a19857ecfa10e8f4bbfacbdf26d8979abc524d2f26715532e71b85b8934f4c53ca713823711a06b44e753177f247eebcedf686cbafc130816e2540c60accf7822b02a83d72ae14650b7485b9c93919f0b4ee1b58c0a945cc1972c965d6c9f7ab92baa419c517f854ce99dba1b3afe7906abf1c42e2f2312aa081152e15243a7c0341401618c92871390ebec0a730063922dbbda7c306dcd348c62308bae8a9585f71637e0f1936bf4f6a08ba0d4763fb994b4c38ea93fbcd31981a7433d5e822b3a39dfaa3f079a54027190010a41889434c0a9feaeddaded456c3a11a89939d7207f65dffdf9f663be0b1823ecc267c2c2e709edb6665dc695e577445a55332e49b30bd9bea2f53f51c6b298b0e88ee2cdb37095720eab0f76f27dfddf7ac0e7ef0f3773331e65968f04e3c0ade054b6970f9c90cac26a09dc2287d2bca435ea38e226c47f2eb9bd4a614af460139ff2711371832f5940384869786e2073894cc5ab255ca15a441bb64cb4e4eb46f5fc6fb992015c7f35f51e0ca2949666a3455151515945c3e5e6babde82ab56fa6d48090f3e493c0840bb5a8decc9795ae06d59a573b94f5d65e7fc31bc7a17049cdda133fbfacd168603c0300ff3e9022979eda7602cb016084b2b7755cb311a55f98cefd0a0a19dac8425a406339386c92573cf2c733d052ff9dbee649d43f54754d5219b99988f9ecba5f29da4fcbee9dc8845d24c2b26d3df7a2040f054f9411e9d959ecc792cc5a233c04a7a1747dd8f93927f095f16db019aeb0beeee00979aedb953d94672c73dc45d88818e3171c478e892b6d3445668521e0a3afe3a379bd2c88529a5d2252f1b1d1f3439c984e1df56c295dff35e0dab7e86bb801019787524783f83ec768bd85c0a4d42096c2a057acd84f775c80e52c36257d177137da7252de752a4a146c49a2e69d871920de9953699768888288c13a6df881b624eaa517dff2f4b9475a8941745b22308cf2eaf566ac4f58fa60f095a6c8d6eef57dc28af42f38ef7420862b2070abe991ef365216a148823e6585f8494adaaf8dd1b039acf3c7b4c9b088b87a6c7780837036eb45c9e1d6266c26d8f6469f8daa87f7f6e0715d74bd09f64b96c1d45eff0bcc6fe01bf2ec945111b74e6c3a208e697a99cd2a91dd2445d6fe33ed48bff93f3cc16b624402353444f82b4511574688215c8b80b4c42e09da2a69ee88c5fe00e931824cdde788223bc5b84fa72c9ba9fa5e50f64396a878f1722fe62199a27fa7da9c831e8c7de44b2e2b75b64b4c961337c975b17394572f481c4564434c4e90e2a01a55122a264f04e4560c2775530d9d9db5486eb7f7d33d36246c137b66adf0af1bb8b749f07a88eff2048c8fe0db9935ab2a9244adf65837aa7f936fe47aa3303420b03c73b7ca55a2e34c6130e5fcf836c62e114fc6d98a2913a385c13de0513ad548b1eca6193fd11ae29279c09032e42c932f7bc780cafb9e5afad841f2b5cf161adf0ed358dc66fc7dfb574cd635a657d7164332ac9d451b4febb1267c55c72c7c34e64b194e923c7fe847fa25e4f857b2b9aad81366e7941bd68675a6f2e8762725567711af99111b1d22f2459a7b5cf0f47c6a0649d371a22ea71927aaffad7212fa0763f44ac2d49929a9db1bad77c1782978be8047777d36d1da4c3406375157c09d63e45cd76d8efae82910c9aae45c442d250e642bcb2f31174169a7cf14f0b97eac9329f260c82a2d678f888e0a9fcd2162f44c445cbfd1e9e0925222a62c2fdf7542a5f2059e6ffee0b5cd5567f15c9566b91adbe72c59947e75e9c33956368d7fc6b5c41965fa93e02591412806dca5bb252cf79cdf3cc7c7b323f84cc841c58b9676bf3119a92fb6d96095216bf1008bcb60a01de0ced7f840a12b946cf1a504729f723127702f9aad5e2b457f2c31baf842dc7d8f4040f5ace1d44149a319ccea6ff1385c4b5411dab525c13501f7aa365fee5e066de26b8a41dc15db41841ef6a5295b9e4b2d8f8d31effe8da0d4f045cc4483cc2a0f727a708cc5e773726a7c1635d7f61735134bb01390b7d1939cc569177b5c28b9e5b772d2f267c30b37c10f22a8b1eec0916a0b3a9f1f3a4caddc8023f5b787ae3a4d2595f6e788e75e3f02f68ecd2c23be2a781337ba1b2417166f81222ed5748c71b07d26c59ecb9318f7d7605ee251220544a3d89c45fb425d9179240db512f12f724a38ce93ac4fc7d7961e3bee0390683f784140ffd79632b0816a595eb336ffbb26723925e75ab19d34ba5a5dd2ff4c06d8fecf1371757ba96cc909e32bbdd36f170b1101692bc07d4441f9741b9afdb0b3108202fab8691782c0050c91825660a058a24e7cbbb0bcd8036f7c5923a768aa68a08f79e44d8d3bc7e8316e91a163c51436595a21b7e253c8c62f6e073809b19a00bc0d60023a8a301506c093133428beb50d18a9b728f9ebe169d22b6076293af598c98c4df344548c17da1d1da9be9f1b4f8e01038a1228e5593d30d4a15f8bccaf1c29ff67167bdbcb972f42e2f4347983f6352861900fa6c0619d4820369d2266c3e92b37215192c9de96b116eb517c5b5353923fc7a082fe5b69e26bece15a1b9e8b93a660a9f3f021a62660d07371731a8f5d8a97071b90a73c8d46ee4410bdef920c16e2f4e9919c223b99066e1b77fa4e43de90b858d2bd92d95271585a934ad4a8a222f2d93e130ae9315142392b869bfb7ffdee387ac91a4f2a0c15b84e368d9fdf22fe7eb584c388d4ce6edf0ac4ede97fe78c8f446a4af9d5789078f902930108b9028e39335989927375e976b7deba7bfcc97c6223489076cbe2b265e86e1691a74ffc66b62a66e3061254bb1df57eaff93ab236dc4b23fbad57a70b8043104630df1ab177501ca361317f242ca143f74c2899445143c77f50f3fbf8abd192137f0583263308aa454c61a3936de9052211a3471e774dbb1e65631a9c0f62f1f1c7633b9c769b719cd6621465769e79676b1f5206d2a07ced73b779b34e5217470f5a43a410e657d5e438cc0f5358885b26525a2618c64e93d47e3935d9b81b289df9264e534dfc75904b9f6db18c3106592ed72774b8d2798a966c2247171d0045741c4fc5659fd449541bb70b3c89f9cc8d12eedaeb36a926dfc29aca95f317caf644a03cc44dd4d38d537d81f91b1937f5e1d820da2a53e7ecd4b7a6faf7c823cd811a4377f98916f4886314373d65fae2f310a5c910f1ae14324f9c4e29ba46915fa5d7baa8d99c2f9b6b36ac5e148c439916eba5a9f4f9a7692427ba00fa3d66a5a5b64fb9eefc4c8763fcfa113ba33f70fe8cf920653e5af507bf7e6f1678424df0c86a99566f2c5de5bedbbed9b1aedd93c7e04dfb1898248d13c7526b4c72d90b71593ecd1a91ff775474aaaeacf9e0251175359909c45e2b12d5ab2f82a3ad792d35896b6cee525bc91e819871dbb8ac2a9b12a965a928c5f19a5330823bb5a59a687f719674ebca2d3bd99e4922d0f30f65cf471b0a0338926f74b73fb97f70162fb25e8f117aaca4c76d33ada0c22c0fb5cbae9614f22f658939de2ad4ae37364d8551c5e5e899c3b2e27267743d6650ca1ea53ac285b10e379719884c1458391c502b134a248f67b68dc925ac86b9b8a9eb5f1fbb129aa02a8ae7d5370a563f468baa7a7719a8e96c7f3b46a1ed86b81524a3a09662d5141e7efcb8747974a4c99444c9349a20cfeb2ce610f91eb50208b91eb0ccf24e7b37079e1df57cd15453c1e3717302fecb6b67a8fc75fc2f32beeaad84695eb837602387c1a5a324731bc2de0f4119356b0a914e3b81e9d6fd5b899e3159a74c61e53fc7289425751135aea21c826289d10b000dece94a4ab38f48b470cfbbd21eb501b8741132634050960075d585d6ad981fac552ff8fd8a4782aa99eefc2f8192e5ec35393a96f8498beff5c9ab23cf696d10c5488309246c26cf7192822cb8b5aaf2fb33aee7c3d703d6c54a9bd79df710b5818ab78fa9c42aa2edc9b90c51e090008860cf3bfc8c2fa4a1680e4a3657d15e511a29bfc4dcd51a5eacac99ad8b8c98932fee5f62f0ae76a0477d9b6b30e54785ea8a3073b4f275ccdf1553e13c0f2f467c22c1c3bdfc9fa43e59197b2151177d65860ba1be1decb548a1e16e22a4c95ab1cfbb41ecc8b8e23809ee2cc6e1026a82a5dc515a600bf9d048b1fa47987db1b25ee6e50350d3630628afa84c095ae80774eb64fb6fa777aa7656f94ae4a8bb79175f528e1bafe779f27f76404517310ade2c09e59df44484c236b7b674b3ab55aa33336e09a7169154c3dd3a3417d6df53d86af3705b970e262f0984b8c3dcf44d19e7afdd7a1f6675b40ebcf6cd66b76a72570357cfa5abef34f50d6f47590a82a7dc83fbad834b6ef930690b39476b346cf78fd439505e2dd55e1ebaeb04a3d32392e26937e3af5a6c7f1f5a35c333c96e71b352b6811c1fa83f1e9f8200623ea4dd502942151832a36179ee4fa95b164c9ce9708e136c6990c2e33d62fb497a34d96882e85c53d0f0e049d5c2dfa19102033c7274f829f89e6454a81fab0694ebf661358ed1f0d2158ccc849655992e989f70fbbbf62114678c40b1d6e10629ff5243d6990f1c7591b84fa622a1d6e3a1f32b6e2d7f440f13cfbaf9b45b929f2ad7ed8221020706ba11e9cbb1e9b8ab9ff8d828509ab95f24f285422ee8228b5ca2e200ab7c2dae523e4afe256f14bb801628ac0c79947a2be5b33cd713d3e07d2a23010ceda1750255fa41fe6ca5bbc37ad22d722cd210303a0a62b46dd653e0d7d0a500baddf990c4150db2c8b6331cf8e6d5634407c67b9083817cfe3af2e663842b5ca531c4dae8f3f2743cb839b316372505ec1bc3a6b903487e2883bf9e397c0e2ca44a40df50563be76bd6c552115a5ad4f21dfc75aae402c12be8969c6593aed9d72e7e8699e8ba7c82bc43f63e47aac7be4e3e6b71085d507e4d300728d0a337670a667acdd31b9125695c53694663838097d84c2f4588297710f953464348662cf7fc837e62dd129aa66afa263a2984095e1dc0094bfaba8e97723fb963ac57b6b13ec59cfec626f2454283eeee9600872cc2a21f24967a6c4f12808f4ad11e05f4bba419b0ec73879f7a1f859663c9dbc54908a0ad7de036a07e253899d7e516c36b6342dd442eaf3b196a8e352f7f2d3c614ad4147f8cabfcb7a250dea8118293a4bf8b1732438dac5fd9885941941b4e2da6bdaf3ca52f8b43c88cad5097d2f3d2803ef5aa3787b9bdd672e00dc9acbe14a637af51247c63fb064984cb60ac81c900686d9323f1d23c3fa07b548d4c9180d708ef5e9c59c8369a16542643af1f166b2e4f1f05e7caf1da141c4595a545b2cad3029df84ff28afcd39420c347558ab1b49c4271cd8fde44fe9be3c7afe5cec40e052fa6eadca05271c7f21a18d42f7db5760b15ffb706cb3c0c70266e1b7c816e054d09a81748561f53fbb583664509df0cf2bbf2f5f96194bd7952c39e3902f41fcc9273d07007faf0af26995d811c1c3bcefe147768508232fc7a3f35693ef9a12d0fb7141475623aabbabfa155812fc66c8226f6aebc95d3cea772f58f15095b36865ea0778bfd8e2f4cd6a3958295fba57292fce10885b4bb93272a24d267a74f46af7cb50d3f28997caff64c1396af4343a13100f62f47ad8bc9063701c883045b2a5a93d9592424fc1a0cab037d2334dd3ed19da2dfc265df6d21ab0743fc3bd6496d9fdccba879c81080077701842a3c6c5fa89e213898437f0dcb928a2974b3b92dc85b43bffb5861e023ca48178eb1b1749987b31aaa43b0f277b8747783f7540bf241acd97cc2a0572492c4f9e5c1986dc2fb3b591b53b0cbac40d88584426e60a07da4a7e6ebe60c3c47ea7ffdcda2a6f0940866f61fb6735d349a3109d1361cc688acf874ab0c3e5eafb7acf1cf5c8bd494057b424d0a1924085d75369842894aebc4b8535d30bba16418d2283eecf41d8efe0af942e3b6d6fd5b84aa17f34f583ac4debfefc81ebf8c73734692fe1634cd3541cc862a9a56f0b17175153ac7801b88ab17322e480bdb02a86a598fe9bfea45d0c819b8b741c8fb55771ffe87d307d7e2e9eeb3162d727008b8ba4c9f05fef0ad2f331c6dd15198d26ef222bb1f0acea5bbc20ac6729bf2c858a24bf593937fa0d9f349f3d99bf2e55de9513700b11825813198b38b23ba0081066711beb0ee52cdddb5be282c38db3af883ee320d87a1f8377555a79a998481838ec53e13da88a6ec42994e65a710d479ce93ab7b2bb0cde2764c7fd4ccaba2e6444e3d4064019b38708e8d691fb96dabcea257972b2b8141429cad8276e744a7f69dae5e0935c2e6b3addece4b482b42f5494812168bf0076f70efe18b8052e5575ce0b80a3c67590a523926cc795a96ca7b52f8ab2bfe73a45a3ca7830cee444cae37c9427d9331360554e9842cc8b6cf127c1c9b275adc341df060a0f5f074c57348b29f7517cf610aa5695d5d6e289619a9331daa9958005ddc34e925b24996bca56bfad29a3b873e274a7400182ca30fac084f34c6b5f654b2e77c1a5b1664e95310dca4bd88e9203d5643da9db8a0c3d3883170d4cb97bd58dd818c97fd10aeafb7e8f5dd0c5dbe1dd3a9df6c9b2232afbc01cd07124cf1562e2eddc39db50b579ad5996999a6e440033acb1a6bc787750e04d0ffb5a7b35125bcaa63e1b6b9fa32cb308a4bd3ab2a63d22ff8151795fbf128910ec5c4e05cc930ba582c3596d8eeef2340656bc03a20b43e5d81ab05206861450775b2a2eaa626356e9d1689895c1b274cdf5a5d580d09f12f9587ec59c32b80dcc7abfe6c76f814e91a121bac90307ca14be524d513c87a27540be2e7b2e2e01c6b4eb9c54550a8aba7537f6232893301aed4008d14a606e7822b0eb03d6d300d268548a7fda113abcb9139d7d696def85f7701ab9f902d7f81d5aaeba30fed1dbadf375f0316ebdc7338f5cb83416df839d2a428619b3572c0dda9da0436bef7744d70378cc2e749d7a542fb07c9371553864d2cc81228f7d346f73b6399e3ac08b45d93b42e53cad0829e6e6c32946e7532d9a0c87afaa9506730f1abad41976b3fdaf8aa7ac467430f7aff856f1e266cfcc7e1cec5d2bcab12b7f189a1d31ab83aafec56892bc397076cd9a7cab575eb0a119bfb08da6a35158c73aa15a5eecee4c1306f340d2e7bddf067b31539af29f56b9cbeb809d0f9fea2425415f676b8ba0e855465ce2c48c0cc2e441bdf674855984e0e4f8ade035003e398d6fd72facbc60608ff583e16d1a11567b9abe68cc8da850743a91afbdb40ef8f7fa5a81c4b4a7aecdd03e98378ae43d33f9a15dbf3ad20f0862a6101d7e30f3c0f22a02629cdcecaf7faa979c8d8bb5f221e2c6fcb3634e281c12e7423016172e3297c528a7fe7cb8aa2c73c653b499b06756d72989ec5d970dce9f67718f44584ecfd36c8894e11cd47f533b9f35becf28ff663ef11cdc8a778acef6cc3020655684bbb60e94ff52b8d1b4b48a9cfcdc700d5c408012c5e2a13c51ba536917ef9356fdbb22837b81fbffd5397e6e048b39974e25e8b5276cc22c452964cfef1901af61b082046a92b5da87418adf7fff12843c65afc317c49454af2803d5b47a43e1d31ea45ee633986d87fc6246ad7027f638df13453041a0babc92d08a9b9d194cb013ad56f0bc4e8d72380bc0d5518f751874543dce6dafd0d9ebb069d3761f615a422a044d86cd38f6e2f4917c1b55b8fc1207b14ada9f3396f21106d416d75082cc6d44dec0e930a557e1bbbe92e78916e46c6f1344717f4b43a60813ee49085fbc947305c6329bdd9f43aa6ce4e7be8423c604ce5281b700645068c516e8fde1aec4d7bbc026f2d01aa15720b26ddc7db51d33208767ea0249175bba991171860b7f6c6b04fba94954eac7e227e7b6e22c507fa01e66064665fa2632de4f33957886fdff54ee6448b1c73a5a5ef354bb6cce6c62589252a63fbd88fcba313c111ccfac49bfb7fe3d73bffe67f635d19ee2d9f8cad1a135fabd0189f5e59d8ea39ef66fc2e5a603ddd9764e3cd8f047a4f91ff97c747d43e3f9eabd41a9e282e86b8b001949f435485cb28e72c66f4432ec7ab20314a231fbf9df46e3504a0bb805bf74e6ab1e0d43df1bef003ea9bf96edad6f4d752aa2ce2f1deb64ccd83a7c7e7ec0d8925e294ed06a1652f7567fa5761024d21995fc673dae8d62668e35aa947c63d8d07484332e3473302c94123bbf8463298d5c1feeaaed452d272ca2ea90b961d3be3fe272d0cd5a3d3c8e2ba74c8cab768085c63949b6015645827268753b3078f8f80bff60bd09c061a088c5e0a21358f8472c0ea68cf78bef58be2af8aa1cc363a311106a65a8b98cf113c5af07bde8ed668ac230ddee786ad3b6ad4a439c49c6120eecebfdeae13351e04db307e9fdd9b5fae46d8eabef06ad8bdad652f37f486c9ce4054f61c21beeebd30ba62e0dfc5fc9f20988fc7acc7942b6655c5ef8d19ad242daf9aa8a9fab1d2f0df02130bd277c58cd15ef91b58e1074ac5745b6846fb9b3dfe94892f26b143e5cb964e8bd82f42675a71e34bba577b67b49e7773dde69d379a119f71c9937f1db5ebe9f93c110002d079133d4549c033f345d629dd4ef33b2cae240d223f0c07647d04eab02c3211ac73e37a47653c2e0b47866745635d6a6dd4ea1396e8d67b347718b548a29d8f0825b8764f2075c4581e4bcd60f9780d8918bd5021dfc767673acfe356542a13ed2085354a6619c1810ede01b62f62c578fecebc16441468e3b3347c8968d2fe928517f85540fc18f5fefd49eb08a13311dba1f23d9faac0008b6dbb6048b7596477c285bf12999df91e6f08be617f0a2b06c3bfcadba8c19415e58625581bd5081321387c970f396994df8486939f129b8e60d9855f0fa11aaeb964c275ce86d24e335bb15ac8b689b3ace8a42a1178b851831322489ec5680eafa9260b93b57108bd7aa7dba13d51805feb7d049ab18e64d15c0f8cad8d43f13ae967e2d05d33d2d3ef86cef1cbdf8736ef620b77b330122cbf42341065876df644e44fc7c1ac31c6ac17e828e7634ddf6da801578b2ddad602cfd68af941a6b28cacfb33b836c009490981c9b00bd64a471f42e227f97ea4183d178c82c2ddc165f58815c396e4e488d2ac4f154e3df4fac8ac6ea88cb700f6089af2b756a25d514fbd3f49418e8cc1915b262bde0ef600fc66148a4bfb6402856ab6cd609bb6c7bcc3859377cf54742f6c279bc0af25e88a734eee71ef6f64dc4d9701ff67aca182921386281d70d672a8701a03039a94822c732a748e73c91d4c8c5401b401fbd7d4cbfe41c3cc4b8708e76e0eb0e22a442e229fdd2852db9580dca2a2bc3a548ea1195479530c13897fad0686b2b43a6d819946c32444550105e1af2c917b4d725810e9e2146df832f5491a5060ea6cf143c0cbd47f94a76aec06670da73af284c500e7bf1b4d30c14c8b25b330193411a20f98d55d03a088da62f5b34a0b63da3fe82d9aa0ae2ce9f972b074fd4e101bcd1c132b4b369e7a9a82808a6e518cff774225f99cc65da63ef7498294ff63e43a123efb62550fa26bcb8027dc37b8a711aa15de892658bce8e3d2ddcc8021eb1968b12f939116e36093ab6d0c11ee336831489be301365bc281e8bc3b5e9189d0cbf23b3019dcd5663b0adc29c8a7d3bd18721f6d442df3cab4c964293f59dc6bfb44da18ed8d3d578ff865ce5b220c1a5b0b42c6a434eb6cbba9948845d133e001e6a8ebd1c368c06ae630cf60107270b068c2bace71742010ecd048dfad741cfe1b4e408f858b0abff7179a3a1862d1be9e97e79fb387f63aaee32039e8bf208b2e060bc5db44869fbecfd533e6916cd6158c60f85ad9fddfc8ff42209e62d11f1ce86f5d1a9074045b302f5ba4e028a6b55871fea82a147dbcee825bb4f811d80236b5a6905a70946ee97968c0efe1ef8599d4ac8933546480a117f13ef9939342e23ee5e2e833de083ac5dd44bfcdb2f04493cd48cdae7c6b613cbd698bed317ad5245981bd5b89c51377682929b80cf2a38fae3fe1a5fc4c581cfad593c3b21505c6db66fb6fda2997c116e55093e7d83bc230d458ccc862187a866562cff0025ca2eea83072906f0e646051891bb6800d7e5fffcd57bdc3a2da6f1630c7ab6dec0174bfc52f299ffabb7493d59ce1a82db06b33b76db81dbe6b13ed7af9ee94283aec260d401537d6536554d13e19da9b0bccd3bf7ece129e1036cefd68c52026e6b6fa6d2ac373b186c61cf7ff6f8ab102fa7f3d55ce4c9a7a1104a2d27fd8bd27369a1a3e24143000c59533d0b8e3242e38b60ef8e721dcbcc177a276cb70338cb8ae743983d88d8c63d9c9aa958b2581f66f1d398401eb5ab63a10f097956cf9864e5490ace165157408673a047e3c07f8445d9edc611b12cf8d5ec977cbf3990fed8b3a8f319d464013cd87065b38ff6ee74bf52ad744b2e1d929d8c959e519479abcaadc3e5d31ab9d6cebe51bc9e5d783d40715654deae2d7a3bfb0f7dd3f0f4f4fff86df16cdf476f70489cf40ae65b8f8d847de3698fac5b6edc3a130da7f63e0fab41a7bb737fd0cb55486681146b3c10cdc6f8d7f881fb113e05043378b14dd603dd09a0fb604d72336c2e007a38139b12472c82f4accc26c83f9b84176fd4ca93f975b27235571839a99f82ccdb5d0573a4558ae41a2f1e8a346c9b606e8b4338f5a7ec9b6c430b4e697c9d6bc507b71c1b7664b178be7775ead62095d447942bf193a1824e42b3550be5e1eb4cdadc4749f110677568ec0175322be22a943e3b6d7f06adc06066d29459269fa3d0f9f0324f6f2b537856ab167ccc3b7e4fd68738497ccd2852e2a908b49c66ab26f8ca6acc0da7b5b87eee4a545bd14639ce47f30d796dbceda8a633c22725906d2771d8b66ae28b31adf196da4993712364fbf6d2349364f181e2c12b160de5571a0c9bc57f1106c36f3a961fba0416543b42a5c3337402c65f6e00d4810b1b6f05ec943d7781683a3f1cb50018f535616c03819804e239c8461d245784385a74e37b5b44ef87da2aeae66edd051f167e42f592b7ed39a44648e53ff7622b34ae2ba320a166479dfa1313e197ff63eb4f91b30f0463f82cfac7ed48f4de0745bb1a6e90c27e6cde2675e7e13bdab17a1148cae29a430057c4d420422f4f2931ed51638bc24ac371c028a0d2946eff1afb61b7fc8e520804abb09364ac64b540501ed12a31389e5243cdc8c724c1aad31a0be3ba0b3c6969365420a2b3e4714e5faeb4aa6c79a13d9eaa751188b9f3776e185cde06a37c7c53776f1b896c9dc32b474c38c486a76137062b11db420e5e1260651bdf9e2bb3511171b2318c01055b247419285dbf4c6e38b35037788cabb6933f013b7f3597441473c06422c502a17c84346e2ca0ef57283d6f2ec7ffb1e98507eb191463c184285cd58b249767664b7a1a3d8d7089619c14e56af8e5551958a18c291836c17ac2054c117cea18e5f0b60b45283a500d1e4c67487897dc50eef8e6647a78511e6dba77459c0cb3f9cb06d5fe772a9c349277f1157919fbb7d218bd826257d2f65377014c1c69d62dc084321d77e2316ea732576cf112e5ca5daae9bef132a860279c9efbdf7d7de009c0f8e68a50e5747555f09259eaed871c9a081929c27a2536bb6344fab9be4d8aae99a03326d083900b739f45d2f19c9707245ad482a356731d69375dcd3af665b20a4631e00eee11e9aec10e4af154da66530ce5a606ed647ed4ee01e162fe0f1f653f2130cd533de6c44cf508faf815074a46d2e9a7ba92595a32b31c003597441e95c259cc17c909549b44dd6a54cdc915571acb76db06d5b127303da835262a61d9ce3a6215c6f5cd712498ff64767d0c106effbbc36a9df51daa5edbdb02544842f13b0942253a34240f3463af899d904fb8da2899051361f268357bfd471c9c4ec25831768adc9df9dfe20f41fd0f233e2c0c6fbc5a24e1ed5984f7e4c5baeb281b1ccb6da35afe9548a0f71879ae816b2256c00d2e9c1ca5226528e7fdb2d6728062c7863b90d02f1d9d38be42589443fa473eca723ddd2a1cf332407f434a31aa805b7baa38889b1515d5c01d37dd06395125a8e28d55652c0ff502b33fe29cd13e23e548fa974a90b0b93caa4df1e0906374deb818d44558e3a6d9a080c5c833e4158dbc72350198f0c2ccbd8390c8aff73841a2d9accd3345ecec97a5ec7d2fdb73f578fdda005e6ad766e52d1d032e79eced8701e910d8aeb4639ebe4c8c237d992b4bc9b9d3a375d8a21497e13e180e46470e782a90e6147fa943158091c66bbc63547e51853c84363889bffa93471ec31c188f0477d24b19e60e36b18be8ccc0a9a14191357d6e9f97c562562168a351ce082d352e37e914aa7852dac3d9957f1997812ae8cb5e9bc70d25ba4ba6bfa5be6446ba5f2e24ad090db049f5a61dee07850dc47b16a99acaa7164cd33b8282a7c855f88c5a70872a26f465481c16a6f6cf5fa5a00ac24f2002c639d119d85bf33f128f0078eef0dd7ff05c45a5b3a4f669fa529ab2fb8af85bfde9dd898f0fb9581e3c1f0717c04405ea3122b36373ab6e822ca1a66d0354b902153aa7d51282a749622eeea8d512abd7282af694415878fadd45c864cad210a30af17127de4d77c53c15695151f4c3bb2b540c684e23031937fc7d4d4c1f98b06586c7a8c2f6ce71f5f133d68aab27aea49b2242598b7fb9552eb47166e4d212c08fe590e17ac3904692821414ee13b1434374b79115a308d4f08d752901b06be4bb5ef6cd38c509f1eb6cb3b7db79491239fe0ebdfdc40f275506c4961f85bf117263bb2cc74510ec0fcd4dd3a71deeec5c9548532b91dd82607c55efd11d3b61d1b3975b8c78c74b4b86dbfa5c9c27e674bee2a0f25d8a8179d0b4f41746259567edd640041b16f5384ebe0ac4d41cf28ff9fcc125995ee8d3248679d4b6d4bd1b8f961cc99a5abaf31387c12afedf4c64c9ca19320585d14e2589caf298df75ec654a93baea33a17d289f92f525b73428bcfc09d84b35d9408cf4e5769f09642a8366483d444b78fa74aa25f5ad49396cf64800cdf0e7483d72f401c1c78b63687108b7c887e17f539a0efdc77cab5f94da4e299488d5cb48e03a6953d3c023ddd7b3b569217ffb83adac29de1f3cc92420999d6b87bb52cd26c427b35cb7efae864e6a26b6022b22d5e374fd43e915d231112a35a8efb01205588eb2f66dc803170086444b4a110f18d1ee9a5553f7ca6fd439060f1445435f016953a2017dafb2487dd21aa6e8d30e9236defb12e1e392fec976d63b39719a56ec97024c5cefb720403e686508dca98cd1b2c9bd22805ed6c41100ffc48ba15fc185043fe0186fb7eae4bba4a4b480dc5c34ac06453e4a1ea2dc4087b6efd57129651c52a45254b33f40081cf671a78f93fec04519e64696dd5247efeebeed7418f5fc312e688dc09c636955f063fd852c76069c926ec323ed7903186f699181b8d91cf05c2ebcf99a6cd676935622b68b0c1b79c7d03f413bbfe862f34f559f815684cfe018509e763c56a838ee9c5cd5d6b4cb125f6943cf69358675c37e3cbf3d4ad141aa59005f72c806a85aacc2cf8daa09f4aab95dfc72953775c4221b5df1a9f35976c5961d63d013e7715ab2f41be656d565e2fdc3259a85c8494af42385618e32ef458736c645b5d4cc35c8479f3773a54bfe149e0f61bcd83b52549cdee90a93c0e1cb6e5ade7325c5c5b681ebd382a52cc4e09b05482ca8b9b22cce12eac7ee0d152430a0b6de12b87eb5beeaf77401cbe8b52b1b42a2c834f4faac702d4be6941dcb6c8c75a35514cfd92f85384f3ce1f9523f0b3a9a7de3cbf8044dedb9ed6eef6d7d9fca18249d76490a1a2cb3da56d21be9ed5b9c76f1636be24a62ef2267fadd6b5a16586edcedab80fdcf84daad5e702acf95151edc075a517f3e479d0485b63fd4f9d179f7ee7ab548f187002d09dfd1fd347d394833401a17599a7022f10db1bec47641b677b4ed71171db021c9b997759e90113418ab997af1376426cba39614c6260b05dc974eaee2876a991d3d986f0f1511a56e66fe9ee9671443e86fedb1b41dc0e92342e4f8ee61bfb1c3098ed8d2929098b15e45cef8f0e0a7e1ddda456c40748daf974198e43912faa093b2f63c7536f850473dc188d24ab68e6ada78b76b3338224f95a1dfd7705983fb0c0d87ad69a19de498e6644fcc3dfc34ef7324604e7bbdda3585d901cda588d74004b6c0ff6181c62f3d7b76a58a25145b35c272e1c473e36b8057b843b73c5e1e4533dae8755d47744193244d096a1fcebf3ea22a20d7bae904854f719129e796b482d18b7d61418488bfe053f572be97886dc7c73be72a123397c462dd3fece5f8c5f4af3de8a34ffee59894f3603a07fc70131129c72e5ad92659d8cf44898ea83ea25de2961ae581aeb63c2c685c2f95f193f6164d8c48fc5c8f18419985c2ab43dacee5e7715995cb252f036dbf5bdc4118b500449f26b56aa472b4252462976a9d4fee3683651ca58b86921dfbb0588d3e37cf23251d86090cafbe8116faa1b8aa09ce7e1904f372f6b332f30cc7f55f2a752c6f7aead2ec4dab2207d41ce80815d11320fa1b75866c9ff5c91f6b0d7a7dafd266244720013050aec1e2c7a64df57c8dc1baae2597689f316a3b2f0b87b0431dca359d32bcb8149afd74422b51bb26807cf4b0186cb42034483de875855b6df16493ded317cc418271ed0b7bfaef13272dca1c624df8bc1302a11037cbf4a5ea620e63b618c7a3287f902920109b9028d3968ebf361cd03c3ac2dc3a7836e225845a958d22f34c507ef964db5d8a962aa455b0a3849b78a94f204ee51b693b5c67ead96abfc3da0290dc714be4863d69bd37b967df387df0e79a35a6fdbb3d248b3c4652b9244a20cd6cb6c91b1895504cc491baf66ff4b2592bdf1c75280a0d3a896e78f48ab2ae8af2b21408a713f292cbeaf81cbab27169fd4ccd9222fc2096365faf3c9af947d19cde49916349fbdaf0552d8cc34ba47972a6947f76f58de9bac337f308b1a237fe2cbd77bef5108ada717ee06c38269e38e9b04bfd55e4d1ea926f9d45fa8ca3725d2ed27d0d5b931f21bbdcb62783fd21e93a57546b176682391facda3fefe845af19576769213abbf466f2ffe4114963cf274c0bd78519f65cd8d2bd3ed35070ed9c4cc494ae2d521deb55f464c1114f253d734f98df211df7462cfb55e6ac22f4b2c59d841c873629ca04e3e5e07e6862e5cbea5f0c2af3965d6525f3670debb1c81b15cef44a3f73e24edab94e0c3b935491a66f3e5b88a2b2048156cf22e67c5bbf2521f580c18f16a59763698c0949720b61e36f56493e5a1c9a6413d49f9fa2b4ef60f26287f1a62b5aa9d384beacfe5fffee6930881b10817713bcd40b9ba754b973089f03f8c5b03972ed02993ccbae99d1b06a62bfe925b6dfe5d8a6d6f881baed552aabc749ddaf5151a93a2db56186b30375a75090e36ad4d35b9113c15769fa39631c881155e3f8c778f1e9a11ec5495f25723ee89bdb9a8f4d496eba7a8dcc791884ade5753f683ac8b249ba30145b6fb7d2c3c5b6689de7de47450b6cdc18067b7b9232cd0f9d6c7f2c2ced1646c9c715c713995f66199972b89b3cfc9a2b2856b65f5d39d3bfbabd44c36db0fb2d5c0de65a38f9f90c89136da18dce5161ce39d7e8c380a373612ea5bdec834f91eb50209b91eb002033ad0a3f22997a5a6f7fa6644427676cc3f5be168f3d593ad838149526b8f6f58eb4e30c45d7553422d36493d0001c0c56568082508a3ba9342c31736ad631090878f646be00e598a9338a438c39aa61b93f83ace110478ba58913c33097ca28c72b079d88acc13d16ccaaf0fa29073eab4a26d5da6e1dce91aa731fb388c03aad5fead4fe237d41ad9c3a7190e60cb85a401b01cedcc285c17d8577c97878c68cda66acccdbac66d3130640fcad425257f4a28c42eef99b0b6ff89e9341482cd05e8cd3db16a112364c077e4e8e61e0f4a93de84ac0cd9bc83973f861a41d3e0da4c8e8f59567635c80bae0f0e3240f19caa08fbaa40c44e8e5cf822975745ac8a4a25907a0bef3c0ff669c89aad6fbc88dc1a4cae195d259fe267db297b337447ce1b1b2133fe87a7902207dd97020e7d7da1c540575324aabe03cfd21d738ca7aaee94348be7b9a8ecae1411529b8d6e4aef6f4a02358fe8b7f59b37751006bdf2b7e00ce384aa7f24e2a583a37f5b8895a8cd61aa71ea7a0b9f60d4e85a4846623b502debed1745eb44c3a7d571c04a434c005d73c831d04ead713b7f8ed055ba8172f7e7d8c51f1530bb7c90f8b7255228309359189a9a48a1f6b82c1813b751f1fb0ef671a77a12dcf66a88bc8bff47d92d81dc3d977aa6376adad32417c6966e601ede06138443fb7844af415d7246089db984283f02e286916ef8610dfeab69d6eb150e43f8cc93ae40ce432c1b0f96d975b082a0e3dc227f5a3689e1548baae90465faadbce7be65026f51a7959fdcf7f488de1f59923e054018a34aa120ab4f8ca835fd067d51277ba9bee4f9c5e8c7fe4276fb9244009361094a537061b6a53355f1d2e2dfa7c882b2acd287ad020f1f2055091347d802d8b647a7c41ec11ec547a24436e2b19e4207c4d9006d2b665a8ac7ab9759d6ba3433776abeeee71da7d7e4d1e2cdc2dca897f7b9da57d5c1231f557aa84236dff390de74a4aa3d2c65f507814c667a3a522292775a940521516a7225f372865b08cd26be5830685d5d98f6c4cf4b92fd419d1d3ef203401d7f2c43a450bdb85a4e575b748fb8c37f54c73b13b2a705f2eca95daf538f3ccdca9fca32a09ca3c5cde0df1484691664c7035aaa1e1ee4d1bb3e4424c09be866d12cff63d25cc3657be841c2b6f2e37a2c0fb09531c80f0e96ba096be67db10f25e5cab7521130c61090f6ca3bc25735f550e94c00e99bca9ccbb7da9167540d0a23258dc2fce75dd980f382a2c716d7cfc838a91232ab02f8dfb9deab9085c536c456bddbb7a807047f1e0f9f62114cb7aeec9c962bb9c69a951acd15724639349439a91430a3ac9debeebcbbc8d623d9f9ab1b52c2a593f4281f23404508174f7db5fa42fd392e3aa229060f9179dc065b7c04b361f768c5546133cfc1ad5a9a51b5d4588a71b35bfcb20020d5ffd1fdc48df63c2799803691140360d4496cb8ebd3c091ade7eea02d5abb02d8e739ddfe066105939831bc0526626cf2d84e078949b593cdb22a000d2e31448013f0916343a93b26dbac1c4201ff3bedf80b798c2154377e1e163b9c12033f011b1712d97ee4e4125a677dd3c92df70806693ce8d2c5a2a35fcef588ade15d9e7aaae65056c669df8c604d044d5d3fda0c12a84f735e181ae80d53bb73b706f5086d4bcacec81cd5beddf7a1422f0ed5166589fb2953638a570fc1ac1d05b7f1d3a2291b552f997f4a5f6a51ab6540c9b98901753043f89f98ec763001b15b9c968e8844784c1661d10498bf009b41e1c46da3fee9423bae7a1ced77e026f3f604c9c6bfb69eb2123ca338af9bdb685538cbfe0f970860eb8717c8268033a60438047d8b382780d5c523ddc4f3b3967391fc29445c9cc13435696bef7679c9cb30eee949fa2492ad0b3c3b2e1c4aca0f085f60a9ddb805e5372aa866ec5b2a3a312ba647660476ad8b9742462de3d1c22c6b987c50edbf767cb637106c92b369c28a904a1cdaa0f2cee0c57cdb72cd70c623336c674a56c6ad88cd077e53516895b338a8d45e7761e3e8ed64f5177bba92ca045bfc9e691317cc537ad89b8ef9235504f8548263cef111ef6fc030f7c601a899f5c26e8992c660678e7afacee543d260c8b6728067a9bb2e40e88a33e5d640713984cc13343f759432fbb194811a79ab0c013fb8a3f7fc3c85d810e31b92d946cfc088e71c9cb3089c1fb789bbeeeb2cc18f665e78847e017dcab8183c692fc4960fec4f5951225672a9c89d1fbdd4a3726734075702dc47ec17f73cf3ecf8bbf2a56894e70fa637ca4dfaa6481d981989a7973bf7e0d58d12df188ceb8a1e04eb8811813a98d41b3f85e0519c5e7ca12476f9bf9ee735734de9aecd407e3280bea75578ffc8e1d8f8e71f1e8efaf35edd35cf28964797abf7ae70afe6cc56bc1ef9a884a653970aa383e683b3f5cab9435631362ad8d4919828bf4ab2e127a41b4ca9c50f3e775ddfbb07178f6608563acad75f579475bfcf6ea9941bca5c47e5454847629cccb3b9ac6504e21b72f5208a9beef1fd9db625f2401c48cde4d66353a15c4f60012cf9d45e52fdadeb204470e333fddae9107cc6a0ec5b7798adcb4e9f1d7e400257732b05ebdbad4b5577208f26a126577da852b0376b247e331fcf51bc81a81ed13c4548cbdfd98a86caaba62d1a20dc88b86228b78e5b5fbed90551298d4fbd9eeb222d4aea555a6321a1cee611dcbf39b5f82f32ffb6594a2f14b56fe4c5382cec41329a58acc8e7b3289cb936365732836522eacc696801dee01b8c2d56fa4a8d86395101df868895b142992e99b9d5c85817a71c22e22ab853a2966cb62a710d3b359cbc19917835f4f3528c0766ff865da4f7c0c8b3618b9a5c8267a2b2a4e3dd3d4ce6890e1a3a074da1b2274b9a3b72724e9f1812e175e2a6e6dc1d25a195b5d31386f796d7a79c1c4c35ffb32eaa159ae233e42b26dfb2bdf1f754f008c222c7ace6c9f00eccfe4dca7432053d47526dc28590dd2d503ff36168db1b4766fdef2d6bcff3c134440757be64b706422b15b90c02300e89b8887648dc1faef67e0cd989337f15b311d8d4d7e1691fa5d77dd74aba11183c1c1601518793aaecce60dad5e1af09c67dd1836394125037dd7419d8edf615c07291454ff9216782a28d0577182f748367d466a689008cd1bfdd167aea2c5e4a9a276e1a532ae200df1759c471d94c8645585848e83e4b3b59cdfa83c4264116a18ee86abf76b8c0fdff963f79b3d2f36d6bf65e077e20802389a4e9b4c12a85ef2f20c32eacd0808701a57d41f0341626a2ba54c315c411efa3950e70b3c15ca9b1fa65935695d222480bfef2fb043cf2d4cafa28ef6443c00d7fe2974ebcf102b4ec6e2971ed5d72773eae2cbf2149dc1cc1c0dc43034a565ab80bb962678c4a41de0b4f70f04ed8c9f16030361040b47e1381268211d7c376c680d06b40538d61aaa4eed6da0d258db5e6ad5af0b2ae75e53fe44e244a0c0c887300da48e8dbfd5359246412f4e069b99591c292e9e750082ca9117535503b5a5c4ba386194c57fe55b618fd363aa16755d08d1ffafee4ee2b48429366241bfcbe093007eb9d746ddd5ac13b228e5e7356b166fd49433122a7960a71dd827ffb80d573e95844b0dc6b592644d965886c90cfb2b5fc792e03166d52f02026202c6b58adc02d88df3a6f9cf4e327c080fc3f0faa2fa8903a44619cabca6a5169d11624c71c767f8a8c69f7c6018785b7a6980fc082b13888876bde6f6c0c6adf155dd83681b009fe22bebf8c7eaab01d334519d38874716d2f6265505796602bf8b96e13bc328dd828b7b861c9f00bb88b45780a858f91aef0dcb34c32c380a0f2132bffa85fe6be10bb5e7025686b4c0e3f19865b40da58c12e7eb9ba82dfe19b330e662b5ef696eb10f0ec888db908ac794bfdc72c84258f4985249f9df1fb5cdf8d99b39d396bedd14815810593eb7f794e73dfb6c519dd33f0af9b4eac308ff0a90928b20b3b75e3ecd88dd28032ea32ef91f5571864c39d706ebd1d63bb5d34c2c9ce24836eacb76bfb3e870da28ed57531c76f8b716165fe20c95bce90a32076246a546c582b31d9fbd569974b697c491b4adb98b0b44f596ee2c2f3993bef887f932a20e980179c1780e8955d872da4783f12c5cf0f34f812cd3f1f756e920424f4b063bd774613d02d2ddd324f98e9e0237164c59e32b0caa0791dd7e41914184739dd174ec7331df0650815748e0fb48d8d7b81c4ffcbffb858107ed916aa6384b1b52eba836b0dd2e1df6a83071b8d3e13d01a413904ec8bb4ae7bb6e080c89beebc5f8d0a6c5cc0588bbc4fbd3f047e51e5daaf5336c24c61b5f33d1bfcd04dd9f0d68c64b4fb18dd723c8d1abd65be14863144ecb5b3587ef67dac023b9136c8f990764696af53b838815626789097171bc516382d46fe38a6a14a383d05886a449f9143cdc06e1e154ad7161d9bde6fbde274fb1513a71e4c69698812d5b228f43870ccc7e1cbb630208855b340c98df8c861ed2050ce396b5314d3636ed69b375309a0a8a83b8b03440796085649002e1099fb33e0adfb3c0cb213a1e57fffd186981d02ea9199000e02ae000f46c664efdcf9237c24f95edc405876e8d6851da0234530641ede63d05d5da4f1bdca0ac16f41bf65c33ead94e0f50e4f0c8cd1c79f7829eb8f63ec87b34cb19614440295b12dddca5f2d22502783deed1a33405a1fa80a5e45881063dc1612f16bf0cc2eade5fea7734fdd5049f35d486565abcb2011c7e63ff4c5fbf59a2db8242c09a74e158cebef3aa8d1c2087843f8f5382a19ba78175bd28481b1af97ad1dbe419509e7752be649cc848772c1231e9a0b846b6eec6e0ad12af2240470ac583de1bdd4e9a0904fb508cfcfb432daa37ee4b46f1182d8e37f078d8e79478819df7f79630a8cc7c637dab6a061bd97aee3c20a49b13ec72f5435d01ca4d23de0cd7516610b07de8d01cc4010d1d9296a246c3c10bbfb7d178f6b8769d330d6f0f488095b9fbf893016a1356393c16efa70634c03ebe9e1f8799ec6590ebb262c5c94e82dfa5e143069d734ac445ca18d279cd7a942946464434b6c097dbc9c25b0f76f2b8281ac3662fafbcd99ae7e8083efcf4312f171371cbb45c6372503dfac2ea9ebb69c81048cd559de3b1adc051487abbd81e59ea4b44177b9e9f23d6f153fdc79a1475490044c290374db741640dfc0a05b7b527e0ea009ade166bc67289a36a868fd0e6b510aa2caa071dfe823218b07166ea573b9d1c021d9c7f9f40f9fb1178843eccdb62cf10daa4e36df49d8069410bd2a6f60e4e8449761690b43a5ffb8acca3a521c090de4bb20fc0e6bbe7b26e82497670e38e8a24d5e2d6d60399fd15a275a671f03382b32fc9618b8655fd4480102814b2ed264ddd1cd3d704914ac509fd9455be0ae8ae6de90a46be8b49c977675186f0273058f3a03704a6d226fc041b3aed7f87aa34b8b0c4f997177b3850ad4a8f6ae4b17e9929a4236e28b697ba7ae0f3c8e7d16f75a98d77ee9a1395c8857336071774246b26951c8cdede903c95e7916e0b9e487e468308cff1f9316483ed8c808eef6d0a2df646b17433f60dd1190623f9e3e05ee28067eae0483f64ac84df1898027cef5c5ebfd37e2a6c8a86db63201942020d5a21ecd0526b3ad810eb81c0f0172c7b03927cef1622af72ae3d9c49e1ffe6efb41bdafbc7d0e0ebc6d700ce3623227fd39deb115eb6775b7efadc7df127dd2f668d9013be98b73d6620529003cc7871ae857f090b18d90a9345667c96eec55fd5a2bf40cf0a10fa5e0fae0108f7593afffa481517d4b2c29210a5f6a05c47424e5b7a658054b1b51857929239d4eec717b9126ce949b13f839cbbbdddd7c9e4b0510321d016e068b515ac334b849e22c3a4d74a2106cac70b46b36a5f7adf1525dd99ec541d4d2f01ab42cbd3f890c84d446095d05dcb510140e1cbffec2870046929e20ec192b7f301e73ef51e81c24d08121650113727c4ace94de2a82e1cacc0f3b6b81595b19007b9332ceb4f7d6841f29d9eb89ef30621f0707643df42a2a0d4c1647ff2f1adf2571f6d212043f855b5c9f12a699b7f16a277bc47c1d7b47502d21a465fef16029bec52d0db2601a5a9a5d32fb6235f1b1b4638b6858ae9f9d1bac0711e12bef74b787ffef4554dd4c3fece076431165178442c1421bd4b0bed5c5278af28f4df95553b59ff8ecc02b21a2678ef80b1c371fa035474985a6c9ab71fbfc94ce1ba51bbae1c016b2f1152c8f4c7412a03dec39cede711ef119d783247a7ac716796a306a87e68d2779c2f211392eeb2f61cc3d8dd5e8a92f5357972abf31b17a9494a1707d4408fea325eb6b7d0ac091b42ca3f8295b0b790956e0d35fe958a448961ac5f299654dc15e3e40b2e8881286166812a1a3ae40ebaa97f952f4fbbc6e17bce1c55bb0a1e56e2be7930f653089cbdb31ce3c480e5b8b2a7f6b152b5b8646c4ce1f6768f4da82d10d424722d77581dc28d77a8d22444cc6d925a9e51c40624a7e3f219d25e7af4c1b8c852be5a63cf3b250cbb6d2fdc2c0264ccfaa0cb2b6ae5987038775835658a0cc8d2016adf7b5b68b4021a1d83d9b045501b503de4acf04856121afaa13ba12f8622fd11d19130858a064a6fe84c8a435be4dbc6ab841581402fdd0a5f668d8e3d403b5a27745243c2d9c6d4efb4b7ae424a31a0d55253314e62c86fbb654bed96ee71710da1e0faa38720c75b10c120961a4d64f4686f6cc92e28dfb27b897a15484d5deda10c30746a36a9d20eeb4faf1f1f84127e27c8efc80d7624b14a2a4f93205c567c2866790d6ab0061b3ea7eaf60a5c3e171980184e3ba9668dbce36a3e9fe319df8b41d47cc9d38eba8aa74b32087ae29efc929eb3df03bd6c71b18e18a8c20153a78da65b8ccc9e174aaf8c015f27193f0c26055d452aa5d6e2e39d1a87b5d35e45e7679e960a27d1f7262a8dceae551ca68035e21c07a01bc8f4345573f6b7a1df6e97a1958fffdf0711127b65b7cdc34901bea9f4a5f6964ae7eb91cdc5a169ce33b7b12931d4b5854e7ade53a99173ff8d8f4db3abc09fb31bd2fcc4651b3ba9e4b09dc59447335ed32242d3ebfb200f0e1c6c3c39f96f1d2498835404b4d5057ee39b98a8a0809d86c2194640cfc8b3a010a03038092c62083da6b605e62b9ca3ec7dbe42b127d22a03a85f0a1f72df4fc8a757faa003c0741440673d49f89cf329b1871a30b64b2311c3ba11f3470388328d285007e692a3763dd6327517a574320aa02bed08bef4d94d01522abd2c6fd4632cadcc1ddc18a165ec02dc5c7362ef010564c8cd300e2b923edf96a4342202a3c514c166a51f8f839fcbcc3809371293df6b2e175737a75d878e8185c1d3e2a0dd578e782c779c6fd20665f17d33b9ffed07fbf79c4f7a2bacd7818098f7e684ab7506c1f1285ae914717714a351f10e56c7133b491f0eda84f02c246f74ac45696ccab547b54e817757c7fa9af76be6c7d0b26843d6284f2bd5b2035a35e179807bd720ab3bb18b8f1fc9526494dcd047007d407755c95531170c88598579044aec49a3815ed0567b39f42d76fff22f9892df82124f46e337049d37cf9cc9e6206b74847747da3446c6f493f90d72e2a892c013c633157516ce56bc8b84f736feb531e8f469ea50a8f7536babfdafce85490b200d9ace796bb3c86a837e52266abae167c83735cbfbf4b62228c8606efd2f3c411eb607f561fec165bc28ac9da12c3e5097927a6f2427d9148b8c836e08516d1bd0fda3b6428461b60c29b5eb7b927991ada7de939e16ae89682dd45c84dc932e594906dc634186c8a232dd8521ad796856d9405062907a83a5cb3231ec469a6ffadcc4b8ec011af1ba64bb13405efccfbbc1fafbefafb4d8e60fc88ee3c7635b94caae380994c108c2d4a09e2258f9b820acd39dd94f870340d063690969e69792f9db2d34e1a9f7b6ca42a7be5c56ccee8128e0ea81d794156a0c0c165f20b9c838dc44a6ac3a5ddfff94f898d8171bd4bea571c56cf6ada0d119d1e3ef3dfadb69845daacf5ac9a983a343ed94dc2de4cfedf26754a4ff424415b5c9485b165f8db153924a8c6de8de8e506b36f3a40f1b6478b5c7598f2670f866c7eef82f123694dd090f91cef21f224231c1224fa3c7318dc928ca2e3e94eccb32665b09e3a71f5c46416355f6d14792f025dfddf8cf510894a4b46458947db60434275173461bf7733ae22c77f7e899c554d9733077df7dce7ff3103ec6246dfbad268042608298dea9f5327bc95776f5cdc1e223940b94bd70f65b2d3f4954ebd17f51c174821b8d4befeafe1910973b79494ecfd76971c4623cde189106d8490e991a2bd11499d5c89fbd2f1720b686a874229cc0abb17c43fe1e8e903a88a7f03a8e0fdea48823e263d42bd4e5048ed1b771b7540be0604801afae98170e32c1ae6e61dd646d73fddbb6185c6e3a34b180de3418731df7ff636bd46263c6de11ce48209e49aa858c44dfb08efc282830fd890d543c47e493b8ee96eeb79283d4583d4571dfe39e07bad9135e5279f6ed7e6b4ad34bbede3017c1e164e36a46bd1f12d4ec5c4401131ff187828571f601f6efe020367a5746e6fd180da2d26b8a89abc518b89572d090e73a4263b00fcb45ad940c4e198ea1264fc55dc779fef17a02360aabd73aa8e9012d70c70acc678bf097eeff11e3abd98e555a917acd8311ef7ffd3ab26a0ff4970a21a1bb7f4e6c4fd903f298669af2c03f4331a2e571ad29792a5a10252cce263f3b38d84b0803b04cea22c72365ed611019c12541de413428f9fef3ec3d653f109640759390bf1fd45312e4909ca56e78f3ffa86d80ba8e0f22050a19bdf81e060dd40fa595db2250084d83ca27df5c0012bf4aac299a4ad7c1b9309bbf441d4bff50ea897cce6cd5756a1169e95a6115fbd39b5955b66f27dcec1383a4779c1ee02cbce2f83b4272f15fba3c792fc82f020c524f6ea31bcf4c1abb8e7f282613dd29dc4f7c37ff60bac10b70613d80ee62487b2cc69ac3b705a4cd7e442b9f760508a63a9dbd673890a134c3440020fee2f7a8cc42b1d588cb591ed4959213d04b35e2c86f9b45f6e5cda5913547741e2f58e86d4d0f7175289f8aecc077ca545a3edceccf19f83137e5f0ea6866985aff3b1bbe7addcb23b3c063a31995390f3eacaebb6418b4b2e1f3c9b054195de5769f471999233c74649c0008ddd85dc353f5afe4c6b20e46f25802f9942d9d3f04527ebbdf6bec675c343bce665843867750be667b4db0e208342616ed8623d187b121c8212e111bb496a515bbb238edc2ccf11cc8a721e3474d35f570ceae7f9e01d76da3dfe004adf0b9c4efe316df58f3d0a32a2df872fb3db48af6fd360c070f29a43e8e899756ac4903e591bf7920b5bc15671c601ee721c062c3653cee86059932d660e41814d73c9aa432b355053ab39a149025b0038d55be9c608c176f0574d268a221fe059a65c996f0295187dc69d35b0b385f38724d6a8a39e4c98ef9ee50d7fa12ae4f3e46463c8afc7f098f3dee8df2f8c05e47151f48d9f8af152d1539def4a1cfbb2dbed000a834759e351cac16d455c0ce238a65f8bf56aa4737bd9211a54010093e3a4804eb97b1eb5bba82ed09fd5b0fc66be0c905ae368ffc4fab08efe70eee20edbf3bd9c7530ce93b41aeeaf5fa2a135fa1891d5162bf4a3ff45b9d3bf8501fdcc58b14cd062923e4287f5c9308eb67df922a526a77b11d8e7be56a208a4435c10c0f19c659f60d26cd197a4cd1f26f9f51f08d432ad7081f424237b9784d6a7adbb368fe0b45ed772b9fa41c09fd30136d06b6d9659fa97fa13f345237b0daedeec4e74a9e3daea0ffffe820fa5b4aed58e98dfba48efd514d7bddbf7fe153f4d20bdcabefa1037ea61f429a820720d3967706a835b4d91cb3f897fb291bb0c7796983c5bbf78e86ea32f0d50fbae3918e522d25886ad1923f46100569ac550e66ddb13f33e1792217d858d22c644e0fd25ca51e740c887d38397e15b0ea16ae972d4412b52c90c488878d84c7fa4bf508a5c2208338062985f7eeab6c3d7ef189d512ad7c663eb8231d2cfa448438900b84014a68bcbf6f645c8115ca8b92d1cdc41fe0cc02babf565abb37fc8b8a641335ff5f7fdb78996c5c09e96f5134c875ee7f8abd718721e6acc36810aabb5b04ca3bbda6f7912c0932680a3b170380397386262054cbef986d7d7891c020b0c77e73c19c3e6c6599dafb49fdb3351c4bd6db79291f13b9ecaca52ba2d3dff1f9125afe9c8ceb982055883d27dbb56aa858cf068fba506dce06aafd4b397900b35835fce700428b8dd2d7c40a48a86f0d7ac708cdeaedff39695d5ffe0d7ec477b456a60a582aa9fa086795113235ba2b127de10d8d4a4e7a5e0a882427e8bcb8e67201060d35db32b481bf7b4839b18b17744d68b16b2dfc621c96813edbbffa5cc28edfd3e04d2eaa69ed02867ef3345aa4a75a5a18d0331f65badae320d639892c45f356032c7a79cfd7f65f9abf2827401c52c674aacf5dea743cc8abdabc486006940d33967c863b3ffa65045372c8927f0d20b440fa0114d7a13c5a1569ee3a312ab778eb7bc3ae8c4e4264418e3e1674b2c17162f0badbe5cc0618acfb81df7960799663ef3da80d1bb75e7ae66f4a8cbf2de9d91f46bed8c56fdaceba4b209178c9b594cec0853eccb12b7e1481a640419c7eb92dd6c3f4d472399caac60bb2ccaca0b517096e8d42650eb32cbc194d05ca0690faf16701140d61f0394e4176199fc7f718c573e0709c1223765a955510009fe7d6515be19de0b38cb6a31dba43d4d051de3f010f03f98886ba4cb146bbfd2b5d0e23e9bd3ff9af5859eb8cf7d4773c785ce3c04928c9a1d8451d13b6bd802cd0c74044f56940a14818c21ce8e08da604b2a985bde08e8d7b7744fb384cd3df2bbba5060112b75355f4e64627be23cd20b5b993d47b4cad1dc0a93559616e11fdf70eff348f2fc3527ed01f9c6acf26ce4b417e422d5d6644f3dfde437ff79eda13a2d0df69bfa87385ba506fa",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xf59c4170b0a2387a4f754e14f365692f7b54cde4b171f957d05b9131a918eb9a",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xc3314fd768bb68b986e80c0a14175f6f72630d7a",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374bf0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xc4f0e949758409dc5ceb60365008c8cdacc9bacec4b700fa37e680a6d230a2fc",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xa04f3ceca6bc70951302b33633bc9e023b39e7f03e8d73b99492d0fa613cdd41",
|
|
+ "timestamp": "0x6ab8f032",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-anchor-20401136-baza",
|
|
+ "sursa": "2800-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa0626573752032362e342e302d616572652e312d643230333230312d7774613037f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b84174abca40844e5f6e97f36b16f18475456ba27dacb7dbfc92765087e36d5450125a7d612f89cc9aa1fc38461b0e7c9efa670aa3be0e77f57ff1ed4e8ec187f59f01b841050e2e6689d2971dab064b69bae6169d461c6a770db55318549b74fe257dc8312c6efb63199db66dc0270c633079edc6e32020ff74fe86566705a7da82e8ef8100b841c1b473bad387d349f76ea51cb4701ca60ab979f901e5f9f44387347d78f8e05e3b6076a7ddc4c08b0ed162befa3d8c79b22804e6fd9565da92fb439555f3fa1501b8411902dbae1331be84919b6c0c6f5b87deeb616f5cddcacdf31779feee8a8d90b33b5279d6aa8b2ebe666419b7ca92c3360df4d97276b114cfde910d01b376851101b841f34941e4e30b0745449e10e1e1702c8c7a6cf2eed92fda5b5a509383cfded2874335ca24261d82586eef2aa9015ee6ebef889694306c13fc1be953757e4c7a4600b8415e742da418a789d51e7f8f7dfa40cc4605806a9f070db66a12ed147a82c0bd0c62b48ea634184cf0ee0cf05a52adb5f92ba6fe2715e645f14b45a5d03054aff701b8419311a0b2093b1dee9ceb6c2af27da612137d52a000faa0184d0f481a33a1125865f6efc2c1030267196a30aef45d988c10c79c91bba572b71e04213861843f6600",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x733f3dbfad1ec59c17a23459e2f1233eccb75952ca64f4eb7e48e395e674ae3d",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x5f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb0",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374c6f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xc1d23a1610998074d538583df67c85c95ad3164269759d2cbf020f5bb2462431",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xc2305cc2fdaef37fd8c40052edca482f74cfa09a8384917cc9f4378cdfa93563",
|
|
+ "timestamp": "0x6ab8f07e",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa012eaba0731782700ad9bba930d74865f14625831f7cea9225f44dccc5ec9d9b24b29aacf8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b841954a54ed19dca4919fad5dbd5f54294b40a96275be4433bc378bcea7d712e311551bd6df038b67709fe64212fbf4ad8ab01c283b567f729a9a8d310b3e44898300b8413cae161c5b537c5dd3fd0ac8ed626d67f5228477e2dbfab403dd312885c93e132e7c3b03c684ed90219e727b216ccb052cc4e7739c07297d6cdf7db4bdf3a60201b8414f320bfe756cca6ed471be3c427fb23395b90085aff26fe35b2468748589e1e33a741aef961a8220b0563a3ecb07d3148509957c45dc91c75889c75ec483ce2d00b841cfce071ba84b7ea53299deb2e9174fea3fd7471f95ee9b58728b57b250179dbb5a1c9693d352cb021ac6def2ff3e23de331c32e8f75d9353cc499619eb793a6200b841af6b6d51e8f2738a958fa42bcd1c4a7e5a5e22a6ab37ce25067248c854218a8608bf8671d446e15e5d9ff633dc1aa571354d02391cd9fdb41974142ee3bfce2201b841fb761d0382c25d721dfdceaa0718f5eed6a6131b6a231a3ff3dff8a04c0b4fba742d22f503598808dd4dd7b5cdb58e13ddd9b2e8675cc27454635d7f6656fb1c01b841f3c44d0cc3f72ef6a21af28bfef2589eaa8fa4a42e0dd0f2f00a29cf342fa4f32b1eb9888b7a743d8d5ceb1980a304f192f2919664a5b7979c7b61e8366f116201fa012bd802fa012bd3f902940180b9028f392b1a8a9c76addafba31cb88ff430a1df8392583f426390c2d65a63e6070c700313bef0ead942b4ea493dfb77e2173b7676ad3773515093d49e42a4ce59b1cede80ff5a2a4e8581a79c48bdfbe4462cc188ea473f8abdc42880d0d89b07d70447e18896e1b962918125739bef6cf6654d28d1fbc33cd4e92b7bed4ba55930e7cdd65570748c126b927235dd984619c26f5114988dfdb0eebcfacd3be36c0c9665251b56f771116dbd513d8789314b0d1e3f5d39b0460dee772a74be0afa7b8a26cafc927707a877e3db5ccf0de2bd251a48bbcbd39725b0d6bd87ff350a37ede1cee5c4bd005e633397e515e372d0e6070599d734763c446726edc9185e028e77a81e69127e4b661963eacd2c117d89be2fca6944466a505f2c7e27302976a28104db49056621db60745a5f267887c24400c665f80511452074fef7ff151c8ae0875a2e122f4c15dae19844c4998e5db59012b423096259689abf8a52c1dc6ec6e0b0368c013cae2c11413a61fa93db1eddd9dca0b7989f6676d2b60aa72b71b03dd8a5cb1ee72ef7bd3ee738fc4576064134f562f16b0ac16b558657229b19d4ab7bf8f2a81fb87a54fe7516ced5963fc4a940d0438da9222abaaaa36a08c662be7952db4c4115a9e5ee5e0cfe3271b265059b0adda4538fee92c59e609cd2d1479ba42e0ad7f4bf6759431c809dac7aef104b59b96272acb46ab47dae42bd4f9c5f6b9a53ca5f674917a95049747724eb90bc0996854be1435381621b79a1d5ed72d6fbf34aef76a08f46a46d96591a2c766e9eff4bc2d4ee20b47a8420bc7d3d79f1de924e28a84f4aa1a3a92c15fba40a072923f189fc6c40652c8473888850f19beb176620c66934fb7d070966f1476e1558774549c63099a47a8b60ce6b1dd2bf042530e497f1b161321c78f91eb50280b91eb0b26a59d9da05a23731dc3e3761a9a4383a16ad96ab88b5a994e97459f72daaf9537aad5b0235c214bd22b6e01de31289852fd94cfb05c5b6238423a65fadaea28596714d08bf4210d1499ff00c0f7972611d2a59614f0f301e89989a4de869ca3cf349fed4b2d2ffe4d54e796c81d564835d19b5c46fae893d18420def228dc070aad275fe3cb31f730bb397faa8566385c23f5027c7f4d5b274d6b7892c48a2e5ab03fefb589603cbfdfd6b0dab47df3b9a54e7d5140d5fbd3cb25ec522420f660d05c21f3990755978b5d007dcb704962e00a7f3ed0efe08551078960d4e01579f71c3252026f6f5b5cb1209484ebb94a6df58a0be6096efc5eaf9be4278ea9142f060cb73adaf2e525ce18097e9cb097d9f36d8dce841af959a0be1bae0b73fd223c3ac9b28587a2f8e59f8dba48ef9c1a1971d0df723eba760cab2a09b5e22c7d2449484898c5b3629ab25a48da4cb4342dfc4b8500e0f332576f86ad0e8d5cf56eb6f635279d47f8351cd048436cb297fe8a2b0f7c548db474605d1150d83b3807d9851bfea92ea6efc40c07345396decab79d4fe1134af54ad13f1384107bc349b45a57d47643e684c037d16cf6b88e30495909c2e92d196300b725a1117062a32185888bd3f886997c4f8c7f9e4bdc1d11232d956961f6a0997f4127414083dfe0300dfd29a75b8b87831c97bd2e4d551570f11038441d80322f36c06e804d0e55a22525ec05db8908c87891bdbc8e70edb36456d3af7e6ca001c2aaf1980a7803ef2d8836cb1c0d4669af914e7d4dc2a200e8d747e8e27381b984e33d875d4a3653499c305aa30461d3ddf30bb08d443b016fc66de051f6a9a905f7627609a0c757ff9a0c8c541a003b8d406af2380f4e44d89fd3ee0340d9eeff8830bd0c050dc815fe18be4c515b781177d3d0c0cbb55d6d0b2f24add085b64a85e4d640c5c482bd401c3cdc20e3d3e1bf86666194178f48d7c3d575c74182efc3ce1d2724c5caa96e8e2657a61836af8710da36f5879fa03b70ccff467b4db8cdc597670c77b92b31617c4b2015c8d64a7f30ea1a2bec46f0470344a3bbc6b2973d5aec6a4fafee8fa25302f01d8ad3a33e4850e0acd250a08c4265f86fe84c29e390a92b5d50516012d282e40ad2bbd53b4926f9e1245627788acee119d06fe756a81a64a238a6c01d0b73c7d9e7e6d4f39d0e9da1c7f85589db1833dd8219cad11fec69e9ad79a11f43a95f1eaf30923e4c1a943cb3e9afe19589e1eaac5abec3b17e2be6522b9d23260869b95aa309f2e64cb8859d120e227c318f5c328a791bb96c4f49bf4862c3f469cf5b7b575ab277e95145c9981243178b7bbeb010fb8aa570aee32f5c1b27eb496b274ed9d8346569d73a9df34d1bf8b00bbb1ded1e8e7edb5b46472654826fdbbc717d846d00d54c081d0d8d841802b26f67eac6a869b23236ac0e4a5d71756d6e03924fec0dbe7fe5358f1f825bb2bb1c54f96d80f5f2317738ce57f23648e13850f8ea73675a49b3916ade34bee3875e553131156a94efce92b72c1bc4890e70650769de8667f536fbfa5996d65110f9a6fc56eea14afbe0574dfbc54722c361c4a4bf071c7d33329f6e9eaaf9581d7019d69a5a2e4227739e6fe25d7136bc1f9c7c44ae243a1e4741b2395cfae813112d5c334d3ec3a9986b474d7e97692cd7b0084babcdebba8f6e6d9a625e589a33fffe8da9649f8169d51fffda4b1c06d5eb5922dd2403b2dd2c05abc0e3391731abf05811b85cf85df9a22f0783327ea905ae4c9436930a082a98e2345c4b6b01f04d5e868e5da776f5e87e5ade931a430bcb4a6d29cd2eda3341e2d6fe9d4fb6636176769d086f1c55a7c908353a70be9c4d7c9668706e1ae4f68918660468287e95b59fbb01c34216c2b4d3bf0fc3379afff8cb99270f36185fcc50da14d9aaa11464ec0e94edf92d93128834720860ccec6f70e0c4d4f870d19d03173fec80d11d94002cf77e0bc6e683d213ced28c1b14f133b0848b101a6259607ba9604365bd7bc93dbf0ea430362f2573ea149b527378d03b59984cc5aefed4da543c22dba34e9730cabe93330feab8a33d4b91ad6e35f7fd2a0400aad2e092ecf5143de069b2ceb43cea7db83d1de1780368a73ae5177fba574494033744010062a99be5a997cfde02ab2f20cd5f4529459b664aabb038eb2524bce7a28604ba76c62b9cf0317f9b3b5c9cbf12e8b8af1ef3c3677ce358f39f9d47d5a8cb6cd8f9d7b390d31ac43ab44e0c3498f0acc6b4b4c73cacfaa11e90c2573367cc64f765128fc0520f77feeb608a0d6a11a27ff89efcc96891c6851441d4cb628d45f3bf11e41b38ecebd5a1f1f4ca656ee6da9d39d3b830d9ed8327f47428a120720095c941f810d074da4070377974332481371ce4d160eb8c84f08ee6bfded3b2ff9244814b450b272626df6ceede37cc94d22a0fd5d383609962a5879cbce9fc4d524a6d625a4df7552014e97ea912c74dc160696ac896c38c295a15a510468ce7e459373bf5037a694411cefcc9a0beba937549237754c05a5c7347a9e0bcfbc3a3c6e9993007eb78d849671e6d55f5535857c906fa1b7e9d68c4d3db256e2bd346dce5bc555853cb7d5d18018a43ed7cd066d10c709613b93d3616e2f4c628e12fd65b53d8388d2121e79c243f3175fe2c8040cef0e18b3b28432e2d07c028eedc4622b5b18949df9fc1dabcef37a23fc028ad70b206411dd055cee7d0c86bdc3964cd613acb616a6ea025b2475bf22afc6646628e7a9f26d4219db5faf6ff7b2125908409c9e00b13b3fc39743df324587789238c75b750db0f0dcfc18a9eb01c0c3fa695d77b3e604bc461f25a9ea0409aba13a2b943745cb07592eedbe97e573274a237216f6097cb7a7326b919e6925ba8a556ea983418e121475f7162722ddc25965d026656e9c914044ab51ed97d2a9bdc32178816610eedbf01624021f4cae5bae877ca831e068fb101432782aa87df760ba059aed57801e17995a5760fa98febbe0557da6ca10ae870c0815a72cb6d56fd0aa435716fe641b6532fa19f4480f79eb0ef4678243e337c17110a0ab4722f042b6e2495aa9d648c554c12fb17583a36453c3e33419d8565326ccedbcbe7d02e10eff9ba512c77ae3c6c214a70ed26fe10d75a145fb98a6cc51fb2bcb5e6e816f172f22addc26e314dfe9bf51b6ea2c90a7eba00e86e3fbd3529f8249a6a540c034c0c51dcae4280098a463156250785b4aef5d3330b71de5544bfa1f15106dffe03f6645630c09052511fe07eae083000e13beac9c6c6f957f3151b33207da7a20b7461a064fcd0630ca4a1c167a70b034a4c102a3e50872355b759fcdd04d8c9a754007e06feaf842646f61bd9b7065bfcdaeb45083c44a6f1c7d448cec504d4eae4a605fb4c2ce05edab7a8d95da4191d84dc0263a975e606615c22cb82d8c8e2e780d736caa2face04d92329a752bf730558fa4f2eef2b7ede0a45aa9944f0ed96922df10cd5648bbad77e32d98e097d9373209a14b82279a3b991290ac4eb0bb35192f3b3793977abcf9877b0e415cdcffebacc68d4301647ecea69a2a18ea7145f5b69109f101bd74cb2d1d1fd3b6e754bac5acd9415c141181327d189391d10f43717fea9389f21886ceab01d0e62aec86e1ed9554484b1a2a90ea2a70cda6c12f0d33f2aa8c952f4a9b1bb108950c40e58322923397c1011b3b59dfda344955b0901770e9dbdea13501cf3f794ad108e2b96201d2dc1e85bdc71ddeb9e89089ebe324c67611489eb47ece699000183b78525432867de68b5074fcf758b0ff5d48591821145f47d1f5948d09dd98a0171cd75be108281d618ce451ff74bf217a6ec6d142f72289f3e67765b07d0dd5ea43e940d23d4721669da7bbd3bb608edbcaeb4a98a1a232a46c5a9837eeef7acaef3bd35e4597da68f80d00156df8da6db753297874071504cbb68533f1b22319e3e788271ebb1228d83bb99f4472580274bad1c88055d4f6415d6b6397dca4596434830c24f07bd187856e6cf950644cbf7a7cac080a40d605d1cb17d3b6bff6f8db6b0a4dc08331cd0934b8db85e4a9b73e1a3bdd110c40e5509c24a918a77a9e57260d9246bf590c373390bc6a6bbd60654cf66048dbb0520199224bbf48f98f3d84a763538ecac275205d2cec7193b65a9ee0c260ef2ea586bf27cece0b78482e466de555043b7cb4e849d5f46225dd61992d4ece219ebf8ffb0edb09bd87ccadd4c089844fcfb0803ad7b0cde3d4da2adfdfc2d0662b6b8242af0fc5f646f3224e5cf51214e55408f45b37d295c63344a7831857c560246632b721445f7a630297a5b63a9f2ca4db20abb0594e049da3caf467c2d7fba42922e91048739f56aaef961acbc0468e4931539bdf32efc264555633f81e9fd640f8b7ef5e3d1a01fe34b1f55094366c3e90b7746b5b4cc38b897f4ce96d1182aa3a379d6d3e7e1d1400096de7f73f78861dd4d423d61e2a6412be059db53e028448ff453e4f3d244bba746332ee8a70ea59c75347a6ebdf6d9959119bc12527282ee65409d1402adbbd111873fe41e3576ad24f0715e8bff9449979305b4a2ff242f8d38485025070e5d6ec8398500fae9b25a25a54a1b9d86bb1017accb1e8f5ff9da66738bb642d7a8b7e1fdb11d343ebe5c58ae87e0b42df9b3293b26bc6a6924cec4ac8e9d2642917850dc3ad7581751f01476e98d5f6b3111e6d52d9275398f8c63ad16f96487251a49d24c3043c804690f4c0d31fcf58061e536a5bca45a1e1b795d570bb0b66ca55c6194e59d53a516049e8cb8d9e72b67c1dafa66ff50e975410904dad9a7a80053962c9577e4e1d8af182f663a00e8fadbe211fa049db176e7c8ad67353b81233e566ba093154a9101e53758160f7ad12bd5df77207ea918af26efcc5f8f25f6d2fcd4201b2aa81eb4b4f98fcce2c492c62a92030797ed122f6fc44138c5140d5362a3188271a47d76cc29f121a9c8f2e57fb99d9313fe354abcf734f0fa68697fd29f7518b3eabbd925740ef7fad8494a673de22fd5f1332b98dffaa30f7d466d5e5dd97170ee809a89338c0059f8d65836ad5f2740ecea0f7de3a7c9358b13e62de0de8ba8d9e5b5b6f9017fa7a9b5380f899c26111a4affa11684f5945035a67486349d492472992168573d194225316f81dced0a49827768233e12bf09bc5fcfc3c3cf2d9eb9253a96d2a4ce9a976310a998f480f72bc7cbee8b511529a32593555f673635828117c254207488be28c5aa4b8ed29d8286190fa6643476b9bc124002c3bd3f443a65c6e601283c181aa619990ddf4f18f24da326b9f049cab0137c0947a32fa44bae3b1827ced06c7deac9e04a414d277b45f8ca9a683bc8ff4b2412d604c06c9a48ead7aa24a7f1579db97af881e4de9b9b8f1ca91127166debbb2da6b1a7a53418d8c1853467871dd1f95b64ef63854ca16cf5ad993e27929704c41bdaea83011d0e44eb29f39d4180119261e7ef51b574e8923332bf26cc359c23ff90bffc16adb44ca0b587f25a48999069c323fb6cdf2bb6414c2e8d9f75da341992d0118c9c74ecaff3c272b8229e9a559c2465ec4af3002c89f8b7f2d9221608aa3a3ad2ef5d900e7efcffc3ac9d4feb56e64e0435223085d4b8fd299b4cea0d9e348ac8eb1b892a2299bc58749cbcd22428ec2ad1f48ba931abf18e2c4d4d57f09bb9de75ff6bc1aeb9d4393582cc6ce362774b93d7dba96e8b45098fc5e4d9c26b025164d42ca9645b628ead45e1523efd3838a90fc79a5c0363e18e43158b06824b57d3ffb1bd294530f9b798f6b542358d1668d9fbfda83dddcedb94322f405b9fe7c70b59f30f97bd817c782c8bac91804eade0fc0f9353e906a8bb06edc4dacaca18afa99c9463194e060bc1fbeb55f9c8d6b5b751dd90d4587dbe0150451f96025b1f5e8706ed0df6ecaecc4720b7aa5c9a6ca814c3faadb34b366b0a47fd0e3e3ff3ebc88884cdbe87634b4339316dd3850b5aa0dca03f653b01e8075c0bd2ef4e513b6619b602313d0df308859012e1e517a57acd543e8de22355ce24409fbd78445fef4a022a0ff53e004a7300789b196c1b3dc0491f7fb6445a455bae20e4e11b16fbc1b1ad131f663d7256e0f26f62589887d2ba08f87ed675d684a9fc9ec35c6096ef457f3314d7fd536c841d1f1ba194b6f44a8f14d8e4a0c99b4bfefbd100c5be8838450d4894e816e3007778bdd21dc2ad567fa055aa49f17594e14efcd2599c53d52cdd05098cb3a28b5e091f7167cb6dc8f06eede8dd0e428a8c2d8873ac7c1c42f3edcf328b34d933b6941c9ae73e8e502034b673b9e444b19507ebc24a1d516111b33637b88e1ef5432a5077e8f9909a8dac4cbc1965b32306cc9a4d84e62d268d26fbb1e2aaae437177f2a4b2fcfd199e676c04c608a30fc82e51d68ddadb112e6de70b4b7535ffe1966b8f0cd5ebc7c1fe77dbb71963b39ac73aa37c125356f59f7e0897f7db5534349e7a2e762df4297013251ee87621905f6161be2e871604026643d10f898f4660d35ef7cd934f2a43d122a233ace8574b33116337f370332ad7f93423485063b3e8b112083a3c4e6b73f934b140ec209454ea5f3fad33b15010e7d8ac8b936baa752e47e2e0a19ccbd5616aac2591dc258dbbc94a730b7a658202da53569db9cd74452ba9d3e62f657e691b4a299cd7afde2e54dda5226ad092644d64b52cbd57896d4194ef485de7d83e766364ef0862f72e10e13193058a6c7e8545e002548ff194b8ce4444a4e0cfbedd9b5fa899466fdd2ce185bbb8af7a4efc0fb3e1655f851d39ee3b66f502cb6857ab2b61be9f22e24a192fc82efb46fb6b82fb4d384f1e73a62c9025915a35da54ad457c4818cee892e807e354a37e13d79acbdebdb8b77d393bc9b6d79b30beecc4d9f23f205d9659aef5faf9dffb05103fbf73aa7689c8cc8a2e9ce6f9d323afb9ba460987cee1a267d8780d6ceeae245c56a04da4a086656fcba21e4cfe1fe24c5344ecbbc5f1198f1861c2c809c8079d6bed657870e7ca14616b1a69049f43ff8423453ebda213fe0a6e7036538a019dec0f5f523afa63ec373496f3ebd313b1961f60b44f3b3e7ed487a702471135e5230c85327d61931c9ff9c1d31cedf3c5571112ed65ca88311fecbeeb9235aba4aa104ec59214318aebbbee6ed61de58fb4ad1c3ab22fac5546ff1e41e06651ad477d87784246d03e0458117c25374bc23b044ae0d158660d23a7192cdbe0a7ef32977315cc4abfe59342a6e9a1a7a0635ec886dc6198e775b1109d37902438d7517aaedc2794e7cb1180b748db601c4f63b1b3a53866a209951ee3eaaf5a1712b9b0b3d34241b8ef472b72c39a0d5c3b852ba20a097320e49fc0167c14f0d57b79ac0c705bc17cd45e8f3ead308dba5871ee8ddaa01db59c351c558ee52fcd9328ad7eecf57ea47dd71f97365e12fa297d22d4456477c202aa0d001bfdaf72204c98c644b8d2db57192a05ce909960f95e2e8f8ca4f79b08ced99cd1704230c054e724d5d4a2771bbff1c961aeffd9e8d22ae4ca83e1b372a12a146fe3936d7d34d5584084458b544663619070d095d1534ac75cd41358b5507aefb6cc6c059b9c118f9c4a42cdb7bc367853519ee49cf05f3b4cbfab2fda5485ca9ede7e6cfbae5b2531207d5db8908ec31d2592a11ecf69157953a38356ed4a236183694864525d5ee531889b0c04528d9516ea8d04eeb9bf4eeaaa657a14a2b704cca9e4920117b1bcff4264fdf572a58321ca2ab62ae449d9612b9f06a1bc002c25d8ceede934ce5470af8261fa36b37cabc05b7da1fee10f78cf7005767ffb70cabb0f5f65a3c9eda98ebf01d243b8ba5944990c95dbcfc390710e53c31c112d41da940b6afa97fa9d48df69a3ede49349928d9c0a9dd36366623f7dd2c7138a8f76ecc5599481ab904ea5d85016093236e1a89f5c9036f961a9ac638407ba0b45ba0060aea448debf9bc49d9417be4b959cd30587ffb8dca42a586a67460d5a84a68f4765d475082e37e130fc355cd2182ee6f41231f09bbaae6126bf9c8b70c32cda26f27b6337936fa9997a79b2fa3bd5c4f0c7f2d5aa5b6ff530ca901c476aea366be1ea46d9037f1707ac6188eead215e0f61c93410ad603e2c9b4613939dad65132aa60b29a9616691c2486d9e779142c060035aa438bb81602821458833b97da27ff1f58b02d13772321ed82268afa3902e867eeb51589832b9e303a65bcc2cdcad42f3d58477828de4c5e986181c18e336a0a4cb19918a75ae34c4273e444d224964c0220c25cbf6ebdb5ed19dec8a257e0af9ed65b02e4dbf11a3e16187f12958bba39d0818ed98094b57562070efc102ef176b07ac77540728493a1b0409df0b233198d129ba0ed0b091ddd11c9884fb99be0c7eb01a9193772994750c1fcbdead62f16cc24181db5b31c03a84fa351472c52dc570f9eaa4ad4cd5711890a3ac4f77bee79d25530d0a2b5938bc0f75e1b8be525e413358cf1a9ec9a68b000159e8493d7499f2fc16707a14eedc60cf1c666f52d4165f621b19f8ede3abf746ccb81b758a07bdfb4732fbd0af2fd64c3f8624d0c36fb6d82250c0e4b971527ccced61c11dbf711e81e31efdabe6060af0efe19f6c9fa786e5c99fa4b6a4e874a2d931a72d9f961f07ba55c1fbff6dff45f32a1219b296f91a570f8698db0caee646b2a60dcfc7cfc4a305278258669cce4ad83e85152318a3fbce9d9697ce7389424acc6fcea0983b9f83ade2a3ad342742ffab32790330e9f92bda404954cac00f489f60a6af631dd17d17775406abbe19a054e73880bcbfa09486305521fc2e4eedefb02f79194e499437b3569bb8d433192575f20f6eefbfebd532d865b9047f4e58fe7482ce96655cf664ebffa60cc8a940e1ff320765253cdba06a742c7ade9f9bcbf42ee8831989b4d096cd68761b28f6e18d50e9f8592f765787d700c6265bd2b264ae28d470c18952043e995e32c879e1798888087085c5802f4c166f8620498408d18d7db8b46a1c3cf4a84b1a6dcb02c3daebb888068839573a3a6e596cacd69d54216330b961e929acc0a324d8653bb655c45e58af9c7d1090c5f9b85f7f09db65255d02f710f2d7ac27316ead4d29cfdf964536b80b35021a8b13ca9b59005edba1f2f0d0295160e84ee3a493cbd0e9c56c3d61bb98b935cc5d881f4da971d2fe6f2afa407ab407a6d29bb0bd872d51913bdda8993ef7708fad76bd4a4a740baf031db249339875706b762bdeda5f664aaf7bb102ef711662c17aa4e9561df6367337a03940f29919f778521a4eef2ebadfabd965d3b70cec8a8d67955e0863ab713c1f01cdeacf7b3d7bd37916af64f9ecc1ebc303590d2e150d8192cc6a464fe95c54ece30da208cc6896727192938fc74e89a55b3690fd6ccb4a394bab0e6878d38150c5e833192252a01b535096ab72e025c4aad57af56cdf841f5959f073548ea717f0fe8462b1428a940ee583fb1e7ea4d52694c954c9b3fb7b69777d062e18bf6e96ae71609c0414cec59605e0c594913e332d207f4633bcfed6d089c7210f842e6876412eb74da19318d0155c7bfebdd78830d4118a7e9cbdb54fbf637bafcd936cd796fd6affb0f8509129e25d3ac38d0ca5ea122e7755c910b7b476ea68cc4d06ec8287f596f7810c0df86279bbf40b8b4efadf324b9a1bbcf968752277308180490c2b601c6a3ae20d77b564cfc207757639a2904cbb47c20e40c0e03cc4eeccfff0fbe16114635f389740c6169a27856f01bc9b242aad1dde4c07b3e73625f098ddbf390525ba7278117435f1d5d24b7d7c9d9acf73eb72824c1a06b82a5ce9e9afc8d726119524816340fa7cdbad0da5af1a8f76beaf77485fed58f35804b9f4ed1b9189a9ea3bfe32a5812db8b8a665db38e1f9ad499c0225440ef738754e714a6ee52dbd476a4c94cf8dedf63c2b2778a681b8fe066f1b83550fa7a067f5ac2f63ff3cd1433dc7a9d171e98deea4be5f1e59be749768de31b1dad6bf67b09dc44fae877596dee48b8f46f06316de251af7c8f031246f9bc8b059bf2802b3ba29e03d03e97167073a4b176b0da66a5a252aeda09afedd2767101470943a5d1790adf23418f30603b182f83340c2aba37e49f07865ff682535475e3b30b30e6b3d990c45c3efeba1e8179e4372c2c0f5d184dcb57df8d06a6f5ee9949ca03d5efdf7f527601e84cfa072383052cdabb521a2ce850e954ab39a5d638fec7bd29fa6988656f364f3c153fe070dd17373370d963d68ab4f081d2f5e9db073406ea26e05b63995fb42d546a816c0ceeabf204bc3bd055e14623715c4c7fb0c91fc6ff33147c94cc0929b84652323aafa5fa0cb14b3bf982c7caf40a39964cfd05668dddf207e32acb15636b8f98f4b554386a328201b77cb33ac547260ea2e5a4f32b67e3baebca7fce18eb1f367fb7cc386f4846c2b692f2ed7c6249bb91b44c02654e1fb898143c2d2032a6d60c0a410e860138784f81f05278df7afcefccea068d3110bf7a65321de716dbf7a4c130d4646fca1c7b29de8e8d1c3490baf1c5ee4b413f99a8054a4bf54edc912aac7a11b03753b5f10796236980010651ac0fbdbaa11564a5eee166f06c6376a6f79e31b4072be9f232b96c146167bd0610ac9261c145fb8fb3317b597f71130686fc384fd212e9b3ec429a83beead17380854f8a2237d174338c8c68d0b9f68417aa364dee625ea3ef012080581f4f8578a4388c8e157711f78e917a25b2631cb05633761e0b496b8a4dc0da2128cee6a3f65f153ce393e79afa5fbf3f9f69ee6d11de321328c1e284a28f85241e705c0757026f6f752891c443932d319a11d37d1cde076a49e991a2389b4bb7613ae9e7e2a8611221c700a90a88bdd4b8a5812df68d3e66275464677f07445c03feda88235935c7aa9ce9dba6136bbe3b9b94a7534ec4771a4e2e4bab23d9ba8c0d992107c303f89a4057fda510b4a528ba7e41818887af5a6e7378a3d61497fa8c232b0425ec023bf67cdc27a2188a89d567216d534ce34e919b4e1e2263974bb299836f18107dfd4dac4809d14df902950101b902903913f5be0feca7b309f97d1457e543d7e458483a7edb3e8f95146be47fc871732d846d9c5b0e5cce35bbe6997f1f3088157da6f122349c5ffaa70e4ba155fd0bb582d834f73f97d784519469e7774d9168cd0f3e2de2fdac38a9024cc4581846a58fedbc321d06e19ba57ba264b76b106d631f2876e4ff736aca8582d51fd3a54e949a2058d9e816b524c9be867989c2125a0300ad335fcd5f0d2a9124eb06d54844bdb54fd46cc85c9de4ab07208dc4cb376f86706d5518b2d4a6a4124f54f8953b348941c0ebc570e94a3dae77d721a7f5f5470b9cdefcb3f38d08a85d598651dbd1b949646674ab5ae54eb934dd2233340f20b9a62f0deaef6e55be2cfd3062203cd9cf2572c823f2458dba95e952c391a31ad8e84f5c5ba4ffbbcb85ed220379ae7f22249cf86bd94882e370495b37ee43eb20e5cb7fbbfc9b4cdb86d5ac3bf80f7a27b46a11f2c258db758b31bbae4fe4288cf5d92c584b2d773135647f6e254f858b24e73ba43396efb451cd54e89f0393324983049de9d3b649002447ee4c8265a4f9657aff4172fb50221778cab3fb7333b18e31ac62ef25357e86df535dfe4a6c841660cf4990a09c95bf547ffb0f5ae82a1123e85ae3e32870361519467d86d337e8444a0afce56bc57940a5d3f11f0d1fbbeef1cf594ab4f511dc4bf924198c79374bc48d99ce3de74f8ce129ccb435eb6d924800ca8ac53164c3feaaf13d41ba99c5f7aa1e5d68a3c60606f6c6418d4636612d64dbecb3bff280bbeaef6ec5a447a0d34c9bb28f1b851e755a6429f98206e37e530bd60e2ecd3d1d065d37cea04e2e930ae23993741fed10665cce4c82644c3b99669e5c45d160ec951363b848ab320c7195676599bb222e43a449d7bb050c553d75dc245a3f9e60a915e47f9fabae71a8aa3f7f46b2c0f91eb50201b91eb09e9c182794cc8c9a508e000d7c2d9dbd5ad0cfb27f8bb9feb80b2ad4f4a902657862caa847af2f1d079e237a86a2f40fb59011c494d686277857fe107277d80fbd31369ce3b1769d8e4f45a1c6ffa00296172cf45946d80b8ed12221d37590e3e46d6677dafbe8db44f5a392f2b73fd4c35ef2566bb7f38266cef51cbb925cf82177b30f5445402fc08f8e6bc68f13505cb2cfa8eb8ec7b2f20f755b9c48eb2a8e0baca489b82df65ec508bd60301c684fdb1ac86f74d8be63dc3e7a2aacd1b061817af7cc0d36d446933238a9393a9e9138cb2a77d8ba46185c52f06b83d3cb579cb15f0386e032d83fb34e2a1b3bd86fe617a3b94fdaf7d2df48ce6fc0922aa07693f231e5635c0899f3520c38139589e88f94da5b5928b76d5006d5caecea1202944b2aeee32ff2367942e96677f2c7c8eae797d140a2c974e988cdcf3122f7228de8bede94a1bf068f31e29ab12d8846ab8b0c5f27d653bda946f08dc7a6fe61178598f0f69767e71d694abadb416b67cf1d854779152b9c14dc31fad1ea4d51d15bb3e72e0a462dfe076024c9da286f636305c533049aa0b994fbe081372bc5a9911b9e6495daf4179d7dd7a1df90ac054d9f999422e9bf8fc49497ad405f88f2da1863f9a48782427edf81ccf18475252a213d47b012959f749d1792a19c4b688a9c9ea561a3018997b96c752e48cc1a19c9701cbd5cb9de0eb3352080364e85aea930054d93dbaaee061c33249ea7efa024e958f6fa54217de5d1851d4ce61a5022b00d4b4f80eda901ce0871252890e59dc2974141fef5ed81f831e65dd45ddb143bc4b3e7a89e39118cab11c539bef88dabf89f7b251c73368b51f730503b30fb7c44a4b635c80d99f4bce02cb2dc7a4b0aabef2b6fe770a6d8b80163998b09f8ae743c1fdcf60cea220a36ccd55a7dd07d77bb892da2b437c69cc7c33650ddb4b903fc59757873f0fe91414d65f046b22e9b2d2e537aa5612a688fbf3df2379965f00b88347818565d51ce64629fd169a259534c9b6d824d596ac1faf16445e3234e58f48a306fbd51b839c5d65a3dc3507811f470cd9e2ef32f17ee582dbd85d25e6fe0633b5525262a7a6e4a2fc73eabc4257b3df97127806726a1b781790370360f980e1c5ddbded62c4fdb3acfaed534e0d51de773aece99cb4850b3b89e9be354ff0b8ee9dfa89c7d446f7ea425270a236c8f321042b6cf8eebdd06312bdc2d1702374b9d4e8edc2aad2adc6908d1bfda412a93301376f9a9bd811f7082b205f95a8407cd9e52c141d396c2fb113b77e4c6ab8fdf181be881ece2e5369bb5ddf69ae2fbcd2c2577e76d6f73f1c17e471fef47ce6dd252f9fb1b1b01b7dad2f1d9d7d6b855f4baafedaf3a8075ae34a8b21a8ccde082c90c91e755c57ce3dd1b85eddf60d09e41591af4b4235360034377bdfa1094ef09802dfc67bd039b2349cea78821edad2c58d5a7102f1ab73c883d49d7a968d741ef78223ae3431f3351e771e37a32e4c75104210e097d01388f60ff31a20fb9363e4e0895ed30ee0791978d3c68632e52a1b97503b55515145f0371fa41f6ff552dc1b3d1a95c504b92248284f31029dab72b343db991568c022f3a8fe402f410a86dea8e612f6702b883033a28474787cd4f3b5d2c4834edcea19ee82dc2a4ee12db661f57c7c1ac5ef258bbd856546584fd5ce54ab470269d9ab8f56501f7dff607e5ea277aaa4c399fbe75eedc6826cfeb001ba8b82aa0ad20555537a4b8cd47f11c711cde3134f262597a336f3c8111bf4eef654effc764adc7201a65d58f70666c2c62b740a95dca8122097ce09a9feed7c06f0c97c852cee8d8382886689e75098f2be67c5205c79c791ea759ea28052e113b2a42d797f3c052888c509963afd5601f0490fd0241e2640c7b4614ddd08e98e1b2367c4b2ec9ff38af878f6a7e70ff0ecd51bae6f1a12a2dab83d408f129c39b35d12f6fae8e0e507d029590558d642e407b1288d57d002c88a1be4c0803de0c587c43e424cad4c809521d271f31e2ec565435409afcb4b0afba24050e29bcd3a8f330657dfbae0ad57b5134f5e53e3407486cfe34aaacb35ba7451f97d8c29ccd64f6242f9b0f49eea7e74c0cdb585e9702a1ae77b3dc9e75c69b2e78bbfdb79d5f18320db26d7699b7d41ef8f78a61b9c343bdb4c00c619f7026569f12b7dcbfd716da7151ccc6ec9ec7853cca34ee24617c11a39b1b8f292058a3dd66a2549311ce60238749e99904c34d606d1e35a4ce25b7717049f1ae9ccef43c7e6372b82c2edaa09de60855826e1ee27d21afe8dadc0ee6a128b2773a7613d510b04c7d33987669fdc3929f0461c5cbabf943d45351ae80f8396da1e43e503ae3e237c59581cb5d94fcaf36788e7d009f84f80a4753ba9488cc0bad0dc946fc0ae56b6452ad846aa4693742326bc034195372965b4efdac169503fa0d4edfa7d6481a0444e2df3c9cfb71a80799c79cd8b5caec2cfdf3fd04474e5929238d193d1e76741cc5b8a63c8acb079e84418459b2354d667ca938a7de46bc679b79dad94c3aa7b11997c2e8b2243bf5b7817f0fed8a4207a847e4fc0db4c4bffe4b7f3a118a812b8742a2ebc07db1905a870a40c9dad9591d4d3f201b9c80c3df972acb0f0b8c06a67dcc22f4056daeb5d04437cc75c097e50671989bd995d8e73957ac5ac43ddccf8eb11915ea57386cef7db6c9def58aa06c939790c00e09aea1cce676e171a9792e41b9d8bd125a64397ed22339cb029dabd1c1d4ea01197ab06659973cd74b7a94ac4a73260f88bb3afce72d52fac5bdccd26d6d22fa2318c9e5a6ad5be0a01eb1b36c697dd3661fc117ba6365d69851c1266e185bfac8641ef2b50c38b3f2e2619bfb9eea63a035e419334b1ff1cfdde633eaac9593af0db196d5cb4e91e06dcc59d99059992f9c1a4063fe6dc58d98aa7063976424d09a441499c31ec96281a5508845ba2a7b52d348d8f1332243520bdb25616a4d2be3b93309af49e20b6cb7b7e20aa237a58d1818bafdf113a28b1b6b84b28384751e86444d030adc14f914bf656e77240ca271b00ff073f237eb6bba89d575de5b152339e6986b6999134d37a10a62c7beaf10c48056636aee86e64e19f637a5aec078e5be7830a91a390018e9f4662f65680339c00784416b699a2d8b1467fde28ad950f6365feb72b17ca10a3deb7f039f31980665d972e8114766be63e46d6011a8bca493f9891ecd33992315390c023c9a6af139d74d6e9da7d05e6bc3b2a208b76f64f3b4c527c539dc7886a562f089fa2fbb37c2ffd6a696781ce7768dc336490f219c8a53ac80a81aa6263963dcc92cc8a31c1577fde94d553d5a4e6257d0ad622a43b757dad7043df8cf4b93c2642129b0bb56f452db401ea2e98d2ae8da714de148be352d326815958301050e308b686e6bb7865bacdfa2a9ce0acd66d900713c54929b6ff2a72aaede0be099232352e2f8ff4a3c1dcfe6ddd5c621ada2bbbebc4728ea0107168ed075e906f3c03f49abd6f73ad32d6626863c27e3339500fb7ff92e3612780d4d6a74cff414672f47322fce1424c3244bf005ca63cc331cb76729cddb1e283a9b04c478a840b75d8be6636da2737892068a6071b0f072531354a0fa4c49637ed09bd2510e24a03b9b5187ea938fcdffc94443fff3203c19e8acbad136f044ed2fe6d6da3e1cc9c30c78476e12f470fe6c33b21873620e9244d53c0fe60e364b4b5537ec0a9ef89300e2cd276bc20031e0a3d77dd534cc3772feba16e2ed37287301438fcfcb7a46fbf6b70382a17e19bf51a88d3910689df0ac7baf955311db42d171a530aee26d29b1856767ec7f7765dc6cbb24d1f03e572ab835c83deae34d8961f0a64758cc9752e7e5c6a644eb34b3ad6436b33b6698327397b8139c55de1ea00165a7aee0dd3e4166b9be899260ba53a709175ff204f7ce199c1f8c3b19ad70f04d4d3f82f6837e5d565f60790c184c7871788f5cb6080e38371799a933faf127214d3b10fae632d9df5f4b0b0469c768690f74f73d22da84644f224527b2a3083185ffecb567db3d78dd17f0945b93785af544da196ef28d614b6290677236527e7d5b369d23d40d968ec37ed90559ec8e36d2932e28e7077ae869d693433fee4826a0c7bf70d7a20a8e1c36cbb198ad16fba62dbe53a5d7d8df17351fe56ef2c473d48c3621eb00012bfb2da14e699dad6d8dc52efa937e32d853d4e3e30dcdc9e22138425a0a539028587917d8362d7f23ce43b0d3c8d565146b2150793324635309743bd44f3702eff26e8283cab1b5874b91e731a292636adb621097ea537964d71239303d5a6f602e5af9dd8df9f91ab01b50958366cb339714319b86c93e0f1c15355f0a3f1e14f973cb6579b7c3a542bd9411b59861084f69f829273771b43ec6fbb7aace6730ebca8edbc2c0d17451d3135e6e546d8056bdd773b944501fd4ae1a423795cdf575c5ff3a0a57b17bdf5e2e0cd149c4c8dae365cbfcddf3547f34342fce7ae2c61fba760da91e079ff74f4574a1ab35f359181ca9472c182004d7ce8bcdc661122ae00752350f4560a386bcc9d41f3c0e7bc4d81f638fd9a7c28ddf3d774e0cbda77e6f785d923f75373d370e5e7e3f4ccfc6b8a5824b971710fc73990168c165fd7eae248bc28a729113c769e8999d97d160bacddb16823c3ff76c4702439d3c577a16ecc33561dfa0f80f92ddcb81ba9ca530c3fc7e4ec0f127100f10883db3d816b543d1222b8eb97b6da1d653a2bfd7d5d0a1286c0ae96b52baab5a3d598760f3b94d3e4373b80b37802f0505efb8e4a09ff61bae32996f4189bfc9e2c5d2463d06e32f0d2c56ee62cef63c8dd1556e58dbbc4bc644696a50d0ad47ef1d63154841225f7ef19a2bfe4629c432d75eaa5f531a80859db530ef284bb54b55405cd9bd6bf17af49dc2e6ab53d4e1bae7a1e6610bcd056a458bd34868563942a0d60d8a13dd1be2608da0359c8b5b060e015d08557ca9edae1f11f1a9746b2929c814f506c8226a11f8ffb991bbd34d2d98ffb405615020a106a5a94b1947b4a67c3763a907877f4cbf99987518a889ab25a97db292dc3c058562a5e42e1c26d189977d69877fb9e679af9105399450604ea8e48e4f5536933412f647a14f7d97157eacfca63911881f0072d525bf1fefa3cc6b7c694f7f69e40177b0423921d21d113e11129efe3d51e0fa4762da3b33c6aca9013aef0dd0b03b954ee347235b43afc3eb744ee41d051e808c67667d19926ee97ecafed092732ac6e6e7e235fc7543ca0ee1f065759299cbd726851ff1e9f9637566a87f80f0cb50859b4b9f99d23939d6860c87a87ea000dfb490a823ed23a71db25544f6f41263b4da19d59df11e4ef45f2d400b5b9da3f66ab7a478c47eb30a1e91e8650add3459070e41b23f9a1a6350abffceee469db26dc83f04553873ba81e9b6601c18e62aa2b2050a767911966ff8c50758d7bd011fab0279159f9d84f43c442bac53a4003be2bd27b8fdd2141809e4bcbffe2feef20fd4e262e34bc3c5762c3e7a66c43b28a5b9db8024a5ad94b62d0ca5703aa8137d02e3ac8f6af5d50ab3dccbbdb5075cc2b2348a09181a1003a74f17abda46cb4d8297ef3771c9c1024a1cd25d64675dc6b14231ec3f42816a5598dbc49f91964766cb751bbe1cebc9ff4fe5ef289a192495ff505b653baa9109f469ffebcf6d7df1b0d8d9d6ea44a6869bb65fd22ebfa1d595ffea4c8a6d818154a16d3151309f093bdd2d7834d015280b4c0e829af44075d7f843638f5ca924fdd5bf9913b7f9c84771034b83e629bebea7e13bcfa70f6ae2550136e09f685ccd1845b3f8cc3870376117d87a4545d1b53f49fd4ae9f03b3293d1aabd8d124042e43a54e1439f658e2fbf91dc842c164a2123755bf76edf38bb3703ce496a9744e9be7a911a7cfc19fe710affd14ffbafcffe958fbe53713b62621a0f7defb2bcf80b9c2e3ab47a5a8e00972000cf9d838fe3eafeab5fed0bfed86803b22f9bb8f384684a6bbd7a4d4765effac5183b7f332d71a1a45b92f1494cb38dbd430d0a41a9de20539b0e4bc39eebbef60728442f0325e4cd8ed2e7d25b6c57a1d59196b073d74437cd3f75a73d776e8fcc88f31d347d2635596f61b8008c519ece88e3a6338a837a59b6787891f6d8edbb2b899756d52915f2bfeb68cde5a042a9794004191dfd9c464b3de3d420b53b372499e0d93fdfa09f1a1822244499d0bb02f6b497a4ab0bff907f212be0415e9938e5b75455a4ca78e2fc208519dc68a6a5256498a1fb998b9a7ff8178eab416dd5f35b78dc4d5705f492d28a734a92ab123a11483d7befd54d258a6257ca771cc654cf71d9eb938d18750d8af309e09e1faf1135947865c770e33bb66ea1f1ce6003e158d2efd48c18307f711930873b965da03a50b3bc61bf65c24b701bc877955e867364158cd4e2cf874fecc7d8a55f66038ee68c1339663a2ae2dd23a9246fb11107b05db182081ef8baa939de0ce7bf726640c6dcc507f13abe7616d7ca04288747d2686bfe2bdff990ba26a4be22581d4236c5efde42169005d0e961dede5b0cbb742d1a7ab024bdc44457097f25bcd47d533f075c78225948396b6e403cf441d5a73aa220e31eea52d13e16980f362f73ff55e5c2d3e9da3d2a406fab65939951a7c72209ab0a3371bd5beea7f21b196fa0821eb757d8ea21df8e91f82b15712a36338f465ecc17119694c213c917b610b92ed20a9f9d4a76d2ab0fb7027c5ea870007b674a7354a582e95bee5b666571e01f887eb4258108f4977238e73b89b4ec5ec21aefe52534f864c33c6beeeee3289dba1ad19b0538406f163d6874e29015fa5ab90e7c33ebad06a7e2309c6aa48c5c34c142a38855ab34e4a5f4e684ac81e6cfd92ecd76594d10ac8a753ade002c2f2e501ce68da54ad6b6a03e455acf89c1b6adae5dfba63077dc9a686376255f84099fcf6e57065e5c54d2dfc5dc91352f6910b96576363710998737de16df1eb89e387380834a8540f353adcdc9a59c4aaf59d3b3acf4015a83484c2d37df27c94d4ac893d81762738a31f503dac5ff98a90ef6b8436fbf0edc32786c8696089dcdb8fe5b02eda45814a28390da2775ac22ec01d5f239d53e4529c5644037dc3cb370ad2b8e210413c0da9adb273771c1207c559b809787846f412baa012c291254ca0f33a54b7874e8bae4bf0e29dbeddc1819f52971aef625fae6e726ebd5e62e5614d72f6201a523be589684d8d5dba2f3184a60bc44d8c329ad07b3b2f1c21be99244768ccc8ff50b2dab58ab65225bbe4bba384865bb70eabf35d68b805f46d8fd49fc76743eaafcd24bbdb45798304b6c610830f97334ff280e7f153c96c87b6704682e50aad4b87dc2d620d487b3001f7d79936f1463001ebd3b279404f47078ec4584891846a416073016d2adafc8572789b6f65817d14484d45a00fca49f942fb0bb7edc981706d6c0b991be2ecf3406bcb7081ed5d98843d21143f99d2f3e6e79c3976014d5f9c3ef00bb8384e760cfdbee23179173b8e40f18c7a393db307c6a5e7ab7076ed99659f9eb1523e425ffe8cc45f0a0d2d89504653c5c9cf577854cba40232989f4aaee472a099c5f15c598161f932513fce0add81d1ccc23cba696119120955b4295458517a5ef32ad796c8aa91452e47437893900236d54134d3a037d6cd2e818233a8b8e7d54aa75923740961926db99107549f4d62300d6cda1f4f280000202dd0c0774f968f3d6beeb089a97748d416d1fb24adc6e03618c3cff4b321d53f46434b85cd30b9b0e1ed12e51afc8feace0910775e74194c188a46ef7581a1db95ee19294ab7f401f3543eaca9514d086ac528e3eec54b828ccd3bdfdb2d37f1ff82226a201b8a4ee8a0a07628689f33d440420a456d6b6081c70e57645d8943383f1119b761c1d6c3c65e37c3c8b8d47525b19fc784a3579c4a67105af85700d656bb6b99507132b50b0b93146ad687ed07166ec279faa0a25c1353994e418798d451cc52edda7c07ce84c2f41a33790565fb4d93335eafa30540845351fe099046640db7fb73b1a8f41fd09ed54edc92880ae76c43215d234a4d2d13d98129e6e520c2b7c9486a895e5cff1c8554e145e74a0eb9ab9ed3431e3c92abf2a767ef2a4b902340b88b5145beb61db18132d10e46c76b11f7fd287a14eee9da33f778c6e97dd02b25ca5172813ea8faf303dac1116443a0e8b005170db679b1ecb15a26ec8acbf812bda59d56cb585b92eb8a4afe8a31404727ae2502d7ac05f9e7495778db0e03a48cbcd26fb1f58d3b8eb52fc4d4e35fd3c1005c92005a338d74e455264828a7c520f6c8e22cd5694c7b8685a13e8bc88a8c87818a5d0ec5c0e02a886241cc525b017619000918bec0e543c196bdb4a0fdbbe8e0daaff62d82c989140a37be5dea45be0a076a43fb317575ebe8eae4d75677a63c283236ae7568f4c22e57d9cec693f1f0205369e62bdfff315515e7f00f28d79f389445dce4bb73346eb46bafb4cd1b6bc395a448f510db367726523a321c4a45a97ddbdb28e1cae969c0d8cf0b186fa88a121cc15e34300b64fa40ef82f906377c493369878c734e9ffea75fcdf9d3cf03fc27ed544f7cba8672a94c51b8bb62d4ffc69b0e4cc302142c0d905b9736cc01ba7a82a2cf6630094235906e46278d3dcbc23bc125315a18ed6a843218b0a36838ffaf08b17f0876d861dddc6b4e7133d2d0b64128fdf21d2b22292d39bacf7cfda078e438215451ab3a3c6e66ba8cc34fb77cd47b51ccd1441f8e81d8bbc5889e27ad7b82db2cd0325731754d683e72dc7fc999a7f5949d8f707642a974481c60e473ce51171c3036f6fb25e0953b74b6e4d249d37542128b72e30932783199a90c0a422189661acbdb35e28922776e2653f629ecf2a3ddddad5743698e0fce12ef0adeb54bf465154a0cb50b42a171b289fec1023587e6d71b7a768d9a0ddcd3e6cb8964de46342ee0ccdc5bcbd3446bd166ef4ec31851a094a347c5fdc193498b36e67ba4aa3fd0ff8de533fe075fd83b3e668892e7ea3e6dafb111144938b7a67ed876b3642c44a2df21d394c831c82b47229953ef51413e38aec6cb20ff1225945575c2ec4834329d15e13e8f1e6fc7e6d979b270d64fab83e62d05b80936d40a36dcf57a0cab0843d8f97524ce305cdb5b382e193b2b15c3ef83cd29ee5a9e6afd54477f507502f6c9aaeb045b35814a6f35089c06de860d7d36634ac8c13ab207a52f5e795528090afc10fb9eacf68f138d43e8150b66b6920e508a3968be217f0cdcdaa14d19b2b9ffa0eefcb55064225783d205f980d892c985c8be0f9c3d2c4c203a50f6da76d06ad553eee3d665f498f7cca9dadee8e83e6e487fab172114767a38e0561ff77ef7e250028e44de4b6194f5790bc15574cb6964236ea7c0a1a839851c1513e85e5dba36a1cf81bc28e635f06f1d8189143fd83ddc0a1c38abb18b49baf181f5f7e872d746b943182f85cee969182e515941632e02ad51f5b88d92e885715b38fa59801139b26ebfc894859d76852c6c92a95ab2e6a692f750e87733901826e5f58475eabee08a69a1bb280ae09319e3a2a02f8475fb5e3faa5d08cd761a6f33d2d6a1827bf8ad133b758cd44f52b26f1f92f6778ea26c0211d1c05b3cb8ebb7035369879df5f930cf7e8156f09d48e7eafbd3e9635bfc700f862568f7e80cfe6c206ecd596dfb58e42732019aba3e19455d8e0ab8f3b03c0e4149675dcaec8b56fc94fc837b1cba0264b40d30ebda9082f0f41c1ca5bf05eb07447f81e0dbeb9cab132c6f4bd98c1f6653a9201a5a156c01f2317678ca38e29b1d3c082e8b283885b67e57c6f89c2c47f2389a93adcccb6e4f5fc3a674977c24a62b04b1912edb7149ce2255260eb1d38deedceaf16463fe08441f558909d656924ecf976fcc95a8d6a252a3dd65d4c53e09267804c10b7fa919e334c1d4926adff60e920c8cb3d61657256317b95de4d640f98d4ec4322d8d81be91ef8b9baf9f4e36720a8102a2ffef13260c89c404e35e6591a1d69544917cbfe94625414ef959a0a1afc7858a623eeaa12d7fd5c41fcb6143b8cded01e3598f7407b990dbf9b40f839c8c997932e8e92dce461ef612bb0d615160e3f84f58ca3a70684cd14a10de71b9110a6473805d30cadabf3f82588c5a153f8cce9f5025309edc2c0ee330392d71af114308448c9b50879d34d12a710ec36543abb99cb1f2fcc9923105a0661d6582c6cd6a7044a333034f9f0c8b1f8a9d234abe84a1f97f58a47f8d52127df22c7bf184830349f5465a8d3efcca596f4e46d849cca58440f66e0ec2b54dd5f0fef3196ef2aeb3ad3750d80091295a1a063fee4278c36777a202ce1b96829cdcba7154ba634c54d7af2f9261f4fafabfc567a7cc23ad261c31e574ec33fde1a45d0321f1006db9f3cd3e071ff9bb56beb1c1de9a55645b8c5ba9d609b24b5525f70f8681554e70744ad60efe0f3d2a72bd2377044ed624c1d3479bf46cc7cd1c9627a015d319730cf8857578d33c5c77ab66533ee4ec5974b95dae6f6406326134c909d91b5e5b6dd23566364465e2f37e420ac7cb926346d1e89fb31c0ef39d5feba90d66d8d5563698ac9103235b04389e0736964390424b6c35d10023c8dc1e83538677a2acb118a90188d8e970eae1d972884a6905e6489669ed7bef8d4170b4c0333dd0198e993573d228cddd214cc8dfc145c69e8da8708342ebb5536f064b0f03a0160a4c024fea9f5a3195df46fc4fe0c3d3f53bc9823f061a4e802c0527b91a38480b1153eb200fda64ea753d4a0ad6cf36eb0ad76ba070d1c3e7a15cdc68427fe62f35e59be5f17fefee099e6056a91429ae1bb43f41e489f4dfdb8b04b7d1b8dcdfbe9a72a35e8e50ff6e71625eb3d7fc8c6ad4cfa916cb7e1551f30ba3214a1888e8a0a5dd4d476abeddc2f022b7bfc72ae0ba7738ae7681afc2d7c3a9576543bde8c0fad46f5a5ec1a968f3609813b97d9e9e094613d39fedcf6de8462f33a4150c01afb12b596d266d7d4968af93baaee277e7e60ed1e9ea95af902950102b9029039b8030df8a2942a2a8ed35c4073887d29e30652b1e157effbf4162ff047e0565f55976f027b434030afa7d3246c311f50a2ac6f6da77ba287758dc444528f4e5b6a6410284b3d8b3ae90daeafd649b7336fa654acc0dc56519cff0688c2342801916fdb9f035334a8e97902daf9c6702c1c1c9119a681a389dd201c6cb08459998adcc150929c8c7bad609a0b24adc1309b853aaafc505138d57ffccfd90ee76711d0b1cc047753ae66cf14c5956b4bea263127aa671a8d3bdab4635ce8d858d3b7d06735eefea5754c9c562d2685e5266f2dbef73685c5ca7b40d1486a598dae1dbc5091f8722c60cc531fedb56223b136d25af2b906e7ff5b8fb0448f99cc923788f591a5abf4b82499e3f3fd731c1b824e84ee5468cbbeaa45398c81f8ece95656b54c5de5defc8ee30cc3dafddaddd466d13a89d8b8c8fa1662e4d53d8f4393a063716f8e528643ca7348b451668a8a987ce27c077b7f58f4d62bf10cbf04f060092d6f728b12ea4af84f38df54eff4e8b87b0cb9119c2e9316f4d9e918356981c71449c597bb2a42e8b2da6e55951385c937288edbb47b12f291a58a3f3045450733a821537bb4305874a095eebf89f6f5d78e557e946641ac4db11dd9342a704d5beaa6e953c869683afef1684091b8a97e555ca801035df16c9e0590732d73cc5d830ffff9b88953ae4e71edba9b4ad362363482730ba6b8454896b25b6b924449dfc6059959b2aadceddbffb4c7765339e4e9ac93cb5719506f76d308a24d69ce35bf4b71c125ffd847d3d2eaf1e3708f0c2c50c713f19212333dc140f89aa245e1c3d958360cecacd0560a2cd2d37c5528ace5964b3979a49698b67b5ffe6e97ca9bdc7ece25d7bd86f8ffbedd064d9853619befaed6b88b9bb759835db190f8fa72dc5291b622a3bcc5a0f91eb50202b91eb0651701d7104951bfaea266ba83c0c87c39ba301a97bb80363365cb43e8c7627b7b6c691b0d368bc0804bd234e51afc1264fabd47fd0b17596d0cb172ec5735a6db334a17457da9e1c279a5bf61fbb8a1f472469f8a46fab3d406c81ce09f4206b10c2a0feebf6bd4989ca4f68896cb959649382790896387fd201fe73945d8a8c6f6a73fbbd69e799a800538dfa6583ed1012703eef3bd9cf9299274573c312952187c0d6f0d3a36ff2d6e6c882d352e69deb705a2b50f4dbe6fbab9816e60cddf02eeb4c2a26378c0de65c9e1141d7fb2fb4d292cf90fe1b73efc9fce96dc367ad7114761f3d7216c9a63e2227a6a580a6619df4a22bebe008a96aa1d97e5a70126be114674082c4622a14a025c4e2ae0814629881c57ba3044e6ad8bc3f9854b163ceee148967e6627da8d708084e39713bd0e98560b8e5e1c9509cb9b6607d695387d52d01579fe9c3c02eb1621bd1fe1209f727ad9816cb622b12e6c75e7039b05633bfc2589abeaaabfe8b2f3a17b6947138d453d967c582e74736bf428545ac526a96c6e76630344ef70ea95fc18da313eaa4e7aa180254a8340491f1a4bbba25c004e0e23072cef1bdae8e3c1f5871fd674648dcae083d4c366bac338ae69994c5bb4bfb42858c2f05e4ebb211866ce97710be5abea63f69661bbad9b4c4f6595cd7fd667109fe72303bd8d2e9ed5132b6893b6ff5369aa78d7a2ef8a56597f55e821704c0eabcd8e231a724381026a67854730c8273eb1fdcb4f3966470acd70203c4f8f9f57ff26a1dbd08759742128ec9fb23087bbf15ce3f6767efc2c151a6c19bb00fcb7be8258edf27f2ce4ef8980d2f7b4879615c6d933d700b61c413b3e8fb30eb88dd9c0731fe4903a551c10a57c5d12a8aeb53a6f1d3ccadf0bb7c606c3269b5bc2b6be7471a5f23cd062963d966cbc006a1e57f207d87e131299f39b7b6cb75d857bb635ea7557cfc86163bd1ec0a968913158d5e8d4fe174dcf2c14a0bb7fe177e42b7f2284566b5f936bbac0b6ff25307d0ca42a9b1c1ad37481bdcc0cb78beee2ebef7efed4fd9b485d991bbcdfcead08ea706ab07e7d2e83dddaf7c74160adb58ba84836a3cb7d684848366a5f0a6dc715b46f78c1ec1b1b6b824243d3a708b8e81cb06cfb37dbcb1aa65f414630335d46ecce89c8475a582d65c9c4a1b8b2f0dd08fbac2c9f8430878ab7cbe2b46ad3a747ca9bf132237c3f176a821f9a80afc8d3a35194961f5d30ab53293a3003ea900a9b4a28c7504149920e0397487e24e0a8ef2975b0c8de3b1b46bc29abe90b704b35142c55df37374087838c62cea448c9f050959873c7fb6675338faf5e7734cdca59391529ce8ef97c8ac44d26777f311b6307168e2bf25d9fcf156106188d40e1edcebfd39a8ac53eae9f6819c5133eac43c10ad98e56bbe3e8e56abb5755692afea91fd592c9b1131b3bb422a904fc9f04add0fb46c5083f8167e85bab9ee1f3143b4c1ed81ca54bc3b542f0638d96e929b6ee396e9f0e6841c649a1060283a2548dc8ef462dc7baa355d26958e03aa170d8ed9910b5dfd262c3a1642d297dbb029f5f423ee12f3d929a3e9e85ab607b5e59250fa2e3c5c682774197f9e85b3f47ff75e32df83117702c0d55c34eb0dcb74ec88223e79617f9f6d971dfa9089ee3f6b0b6e1dc7705bfbb7460c236c464b37d9211fa8ab19f52247427755699046e249abf2afaa7d6be3ded2a9d33801ecff840f90126a382ecf9bfc9c53eb920ef9558ec89359a3204fc00b14cbc88fc22e62e6f2e464efdf670cec1a2db0a1777b1430e4714ae06371b217cba6cc1557feaee02c1325e238dd4e9920db43a5a2b94b2fbb7bf578d64167cb5a7778bf54565c2d9f4c55bd4d8a046657fc6b3042eb3b986d3d74d997ae95e8649b19b0a88af4bbb46a1274917f8b3ab074ae480137a79ff229d7a2c632fe455fd92070fd20dfaa8ad3c17d91970c4d9925f5ea26af007d0f4c2296448b2bdb2296f673cbdc5db05e791ce9d94a52423b488e75d9b8cefaf23cc19aecf6fb95e1da78f95cc1d8edcaba1fad6c7d475ab033b4870987975afc460bf8738a3bad4d4bad166ba3a25cfc4a37d6991489bca1c29ebd686897054a684c44a9534275b4f788c10c0f25d08dc92caef1904c34ee77431a8ab6851ecc3df9c655e2de05ae3f4901e9478d8a1ee67a9714b8502bb7e142dd7f164b8271dcd7456c29ce23b3bb3189cda4ddae02463d6519b26761073e8a7409edb925e243cd92a1d72917bd7a4edd0d1decb40ef38fdf11e532e4636d5a9fbf22e2b2897d1fc44a8e6ac9d550f95e0d369bb832afa090927bc2bbaf37baf7ff3730bf8d62a1f77e809182dbebcdfb3cded6c64266eb0f86a6fc0641fd90bca9df3e302581a5394eb5389daba80ec701bd0a8d377e224ac476feef532a62a1335903010b7281ad6d15969b64e33d6e0aecde896529638623764e500e12cbeab4123fbfd19fa420dd8c77121b4cb1ed3957fa7af1f681cdc638fc2fa94dc888e601943d8f907530750e9e8a67166f4b9170fe020580adb292483fee918832c939dd49f7b4dd2b50eedc76cae7ab83acaeac3a9f7bf221b40431feaaa5f5f4b644435b0f1fde59ce9b41a0366fa1cc97d846c76ee1397feedfe5943b0059a759ca4f09c840353845fc590ef6c80c4da03e42bbb40610e989881a4afe274fc07b9cea2472b7e08c1562ff7839549040f7b9c644ec891de3b62f2b56dc3ecb7e00be77fa731c52ecbe161603a66409b244e6056a74a8c17953b1d18a83e6f826e9bd4cf1462773e5065484ab7dd49dbf66bd4e732eaba51dcb05279acbd5f216fb043b61563b7696455b33c37f96c35d9d30e70ae8fdb8887e9ad383cc985b8bf4f97a4f56d46603fa49df4ca46b61c0348628ecf96461a1118fe5f8a79f466243ee798cc938f604279659c6fe8cd21a6921b4429bcd7f24b2a49cb611ea021dcacf1b2730cf4f3f5f7e55543f73cdf8ff0ee544fa2b73ce7d4f557e66de0b4e3d8deb06ed75280de729e1b2e4552365ff30ecfa0e751311782244d829e737351a32fc168cc546a4b70e3886d92ced9c8ae2a1dddf569ad2024c34413695fd9375428cf40e7a7cc25d785028ba1880233c8f1a5808ddc369db04549ffaa8be14cfb949df39d7384a0dfc409a484381eeacd573824100157b1210ae786e6fdb31104b5b1313d9b0df00384de1b6f4ac3d6066f7cee5f88abe9972a5bc5d3362abf3513b1f66208fa7fc68d60bc1c22c87b5edcc9400d17f976040832fe845b07c7ef9b3ae8f2f695b0d184307d2060f7232a6345640c136cdc4cb2637623ab4d57b11b3ce7502517d2968e6a8e239ac5c87a728750d657d1acce48543a5b35917a84327de93827129cab987db4251a68999826470d6d8bc6f31926dc54bbe13aa370f4c42f8fadae568ffa5c9bb5c081d01505102a14edb127e5139defba2b01a328255ea44bf7109a78925df4d0aa614526736cb2edd5133c47d173734d93af181fb77faffce08e9768419291f0d67b2b5df011444f4665c18871fd8a94fd8638eec6520f9c8b5eba4416b92dba504327149069b9ea30a47ae890af445a033b6e3d070443d65156a924292ad87ca7286ff4171cdb9fd5a78b24d3882b8832d9f3b8d7dbc13ad9bb09d648e16f82ba92187235baa2128564cbeb3bcc3e227aa0d53e54c7aeb541fa799926c6b3e73e0d06285e7b5390c381dac5fa4dfcf530ad281bee4f72eec8d9f0d8e7fcc9b5e21a801ca1c22c11ca872aca68611a442e0bccaa8ed3d16880b334f1ac4a41cbd1bc3fb59f5a614dbf8ed2c14a81f04266384491e62a4f7dc3d96ea16ad7bc4f31edd5b2af605b3be71e35ddb7305b9a0a781883a7fbb0fa2c461a5a59b22c522ba213a8bdeee51903a28df067131803f7898f7d5b9efaf29c2f99925160606876c9e4cfa773f96a28b241fd68d83d2f3850885c39d1cf6c9679a421e8217706e25fbfb78765de814907f41d5dbce525d7276b9ce7674b3653fe4ed26d1bd43aa40a03415e2b936723122b6ad3c5ba16d08fc18f6744fb6e0e9b0fb34dd980761869d5744a438048f73714a1ad0314302fb9bc5b23c5b62f792f1329b6ab3a33606869f97c17b8bec82936040a7ccb4366b813a5fa3e592d5fd96eb35b7694a11921e7eb3f972c18cd133ceecbc4f7f7241fbe95e8f6906e440e84a15515bdf407aba331ed62b0e670b0341fd616fe3d24f0acbb2d3c0129e4dedc7fc7f1ed4e4fdb67829cd135edaac1db7172385351c8d32e10d517b66ebcc4d6fc3ebad46d8ecf5f8d679a538c81e17de8c442f61cc9c6ca05111d6723fa32c3fd5e7015a6132ff88fb8918c4aaa75715841535c06e823856d59ceff40fca128307a029908b3c712f4b6dbc112e6acdf5faf8a0bd7a9eae18188e1163bb8f42b08ca0bcae8ecc6b9da95b0e41e89e7c28271a7d0ded8ed38fba98944adf8820409877a5926bd1afbadd226002521121bb7b0140e193bfd3d3dfef6a997c76ccfee47194c9c6765d7d9f0bb987b8fb1ef4e2deffa4775e98930cc40aeb75e68ee34f6fbd03b69351d02c39c06e94c6bdac9f718a4573a6cf701eb33d92dcf218c8fec9fb44f6b10f463f4df31de4cac29902a3dda00b36f558f37866fc1249be65a74e86ef73f7fb4cdf03de19e0e7b2e1a7bb84682d87f0974ab5eefecee8bf7b1a762dddd75ad4a362aec14744ab2dbcae38be7766f5306f4bbbdcf863e14cd6f66325af0ab5c93a4a29893530c73b6fd75c356d744970fc4464cc4b933116a7c09e8f5caae20d6c86302398e99bf8f0e9995f05ff92da69e092bc7b077b79ca21773a9cc894d1efc7ab5bc32f235573e526a6c602952d9740565eb0cb935bbb7f2c5859f6e81e28e2cb2c57cdac6b26778d6d610fafa292e9f7a1916da47d3ff84c7c489280155a5287edabebb06a54ea0889b14b030f959883ab6a04e78e8b72845e9b36141b4b65a43dea6a8a18586af79ead485ab24c2a76bb8e39255377d449ad31207624594d80bb656efe9748163325b1aa1d4bd376b1d29c92adf9a2493ae09159bab65d84312140d7dbed5f640a92ae882b6eae1a63beaf268cbf2a61ad819e54849f8facd96c3b92f22c6ac0cdfc3f937cbe041e8751f3b6ace3e75fea51ab07fb2aa50349d25d797fda2f05118bb7fe916b2212879ac1c9aa05c3b080bfddaed506818b504fa8b3ed986f23a1e102d0e29b8578af3caf750105dab15ccd91254c812bb6cf4e6d340fef107f591fe3d4e957cb0846f6a3b7ab5d26dce678741728690dd6e33c6b2d6b2945b7225300818289c9d11442bef79ab2371507d03bc877a769ea63004ab13dc80bf03af955b47727620e36fa698f2c1871df5d5cbd711d000fdd95c6149d5ef19bd3628d98ad739882a34bfe7dff8582b5e978d3a52e9949e51b5abc665a573df80ef3b8dd1b1d763ed3b85d004272f7a3d303ab2e5723260e972b9070b4e9939bc7746c70b39ea117a665f0767612ec5b63465e7efe4d92b057c04d6202badaa468a8c046bdd3b2df37b7ed8afae020450b8a09ac8e4304dbf76c0fce934b4b259762a20b9b7f27e699b8c730ebdf4f6526b961536bee38abc1a63500c1c2a826f080c21a10223b00d5c66f4e89916738a8a164eab3754afd19d50ce476b35d95ab661070bac04afd8f0725ea0ef2b83775606083c972f817478793b603be23cd6237a6739f9e854852c1101e0d056bb2b906b230053ba5d7a3d9a870810203da854f442786d92426071869ece21a409e102ba0ee90d5a8623755c01705726adf3b3cd74c88e5b564531cd670f0b09f60bac82b9d8116f55469bd007b2c0704cbc4234eab035a2c8d41174f53bcb806e4e1ad863dc076db26a1ab769a82cda5fb342db79ffbdb701decce9399d7d509612a587784f57ae43f0a674d94cfefb1d107285365eb45308a29caa98ddd9c331920bcfd33854408f722724f65fdd6920f0cd9dec2df5faa58af7f49a5f7a581df685bb4dfa395d42ba5825ed16897862643aba788469b145b3d6a47d05cedaca680278edd0f5592c05971e8dd82c9546230e59d26ee5a18e67e8c4d888bdd87437e9a05e9f269d12961963649ab9eb2f20aeb37888b949e35db6e5c2dc5c17ffa3891b6a34da8afdc4bf1c2ff30f7d2be0076e465bdd3e3e9e4b8f4942a27f2b8716cb3684b75ec702ce0dca0648c62ad61857ecb9fad11b05235d07a77100fab68d419ab1e70b2a0be264853b2e81138c82e236da7dbbb28987d130ff2825d89bde538d6ab5c4b11c47a3caba765b25becb2aa0db5b2e25c985decef37977662924ee904eb7cd601b1e4ffa7736d028e643a43c2ba7e0ebba5d655b2df1fd58ab70d30a15a2fee3a4c0ab570971a68a9ec4d43732ef83092bf6a7e0b84d302dec8543220defad675614090d4d9b15d168a29e155a314be456cc74e3b6a4fdd91165c7fecf9f6534f0c9e1f94b8b46711c26cb907bb33bb08e116d747ed79903ee09b3a7587cb6555268dd19fcab593fdf8ccd2b149f22e05836e87ce138efbf60ec6b1fc523838af073d2690ec48e344ec2a37e6ba4787a17e61bf237b2963f9adb8f791c03febbcfdb4994c9591d22666d30afdfe1ff4f90dca97217c456a8302574cf6920ba2038372bd4893452a2e43cecd02cc5de3b71335c149549ba4543a688f6582679989eaf700a8ce45d136029f9c0d1f130a058cca68b3403d3528d9da4b6e9e50aaf60f97e298bef363517816989aedb855c3c2d55eff6b7f0525026fd2472305431ae2ad86679cee239dd683a038d0347bf12595cda30f21f7c3cca35404cf35200c2bcb7c22dc8f4115028d9c5005f3af71ae126eb50f54bf049f7db56e649837586d3671832934f72aa645f097362c4ab54e9e5768892291dde96adccebfe8f957725ccf75fbac0103a838e06eb013c75c8482fd50566300c2f4c8fd57cfc6cd54ffc230862d98e3ef8ae2ebf032ec22e1e769decd797641a64e0d1e9ae74dfcc55ebce8a7c6b4dd73d2b65ee45df9049a6dadc7c91e7a1236f07dcd739959bcb3ccb8b3cae9dcb0de9172caa77e4809cb400cb5b21a25b0bce74c61c0377a24d85d5521c9322f656c432d256cd313ddc8f08ab3fc420874926bd83ddae32e7b0837a46ccf1ae953757196e0669b61d7727ad168d8de0c14cc39280461f4e94e4c2c3f7bf1992a17981b7af4259f91fce9319c3ceea371a7a516663954f2344e63129c1e5c919d59b33db96bc1e2a05faa95084c478c306b8832c6eb10258fd6a3c2041e1a5b0ab83c936e000ab415e4d6057abbcc495b0d317d84c67caa1a429ad77310423b4ff9bbf81657dca3ac11cf0fe4563b1dbd27834b622766637fa1388d8177a473ab3c75bc56002d19aa428c5dd4e29ed4ee388b78fe343a459e239a901f54a73c20a55935006a15f6a320b42ee84f71d4a9fb6111712853045d889c1213229c892c7b57dd3cb8bcc815b72704a903d760321de580f0a6399246b664032b0fd4afa6af6d0fc17cc3008cc8b1afa0cf529c9f116aeac03c12e9f2512fe18031c5b304647fba33512f0949275e11a1d1147811b068fe68c98cb9a629c00f76d27b1cf64212732764cb7403892a0fdeef138bcf3618928bfa65335e5ae46054e2a824ebccb437157ee0dd4eabbd67e19b30286ff4a76580db72c8d086bc7d7fabdd21cfd74b5df05e2c5b471a77ad123fa93a29b403083711494ec2dd83b14143f629e0ff6baa63b5fb1353615db3c03ae8a2d2e0a8eda1e65a72eeff78497e02206bb6aa6bf8f68d5931a498b61f247c277460668364914396f1e7e27a82e55fa94f933e2ad44b8dbc8bd1dcafc672e7c97e6bcfd6585589efbc39037c28c355666bffe20686ce82c7df23bdd8a29c3c42374dc9cd03bfc541f87524ba82a3ba0270edd0cbdaa53b3bad329548e3114320e83c0d05bbeec4eae4d27dd7e9d5d7552d74911873f0473ed1b06e4af6dd97023a90d73cc5d3d30fdabdfdd3d9cc179168de028b450479aec6d368f7a1d70dad59477059fa3dd8ccf0d72f21c720d9a4687e2a3d2651c74f156af5af440091695653e331a235b0c65d3fe90ec01c3ceb4c81656f0be0152394a80abe693cbad148ce33785297e6345f9be347b9db5950473253cd6031ee9a034c9f6f660f39d2527b0f5b8f172c00d34f8b838349f99115897da50d9f0009129ef5c67d0bcc3cf56564d46d5e9f213142193e35c54651338c5e55539ae26fad32e9603fb46de3beaad3ac8880cf17c7663c116bc25b66c38d981e4e05698ac8767daeef0f864f0d0950e896e043f006a012bab4ef415f988b231749b84b0960d92a2035e6328a9dc13c7b7096a9f75a64df42829b987f5a8902f2666f9760aad282b3e6746d43ee81b332f33767d85969962c9c79fdd9c7b6087a69a6492a99410e18eb4bde779e49b5075a31136fc1433d4d4ed7791e30960b929cff90a054d32271ead61e6dd2e3fb4202f3b160762033832338aec2184ddbd0102e4e47316ee7aacdeff49de8b6f29c20d45fefa0180e770753cae280a3870872dbaaa19fe1a7caaf16751a1adb3a37f28e463d1687f1ad3464409643d57ab59bdd8e3c11de0bd3f105958124c531509d075a7730305c40c5f9f4c8f0fbf3bb54f8a7434fc7a8fe7f6d9bbe5f915c1f9b36df9347c9e101176c90bd79c2bda9612c6d1a4ca74340ee64419af81d64c7a960af542c50d902953e2bf8408edcc6df95e71d30bd22e9649cfcd38d1f4365ea2b7eaeb0d3dee4788c646b1bc551d48f8ee1f86e62dc2568eb2689924062500a061d32561a718496af1bfc5160020c9bc4ff4653749309941dff0bc5a27f8872316d28bb136b8d9f960151baf048b2815c0be5499325fe5fc4963bcd241cb9cb2fbc87f1ee943615a09a179237fbd4847ef8ac32e6abaa58829a09b498c05ad87f81452a3ee667aa97a8f741db3a038a8136c281407d1cbbe9862b740144f4ec9567073e902c8f5b78654628f4ce6ef51b347fe6aff733b50552d10b34fad6437ec0da581651b11dc16f167a53ec7f532550bcf75827bf8cbc64b78cf80f040562a970a85eb11a3a26e0d1f4d540dc66a7f7904ffd92c76b9db496af27fb5bce5416b21987128c5840b5eae5e1e8c1268c715adbd8f21c4ac3cc7427c217a6d7e40cac244c3b96e1caa9812446305fbc07e0cea70de07b5d692728ac65225d6fe4908acc1f58c1e0dadb5f7ef473a37ad5ccc4e230a51dbca1c658b8d0e6f4b75db666f7faa36ddf19ad45d5457ce82212516e2006837bdc36006e90f8ee20a376fbedaf2d020cacd5862faa746a342b3663a2787529596ba0f894269ddc7134949481891d15a267ed491fd10370e86a153cfc5e3d29dbb4312a14931001d0558262728d4847eb8a2cae15f07b6282489c797642571570471bdc24dd93c6d31a3274e86e16926e6d491acf2ded9c3be1ff5eb2935e2bc6b4c40163fd0d40ed637bee90333b834ea38b276bc947431a8de43e9fda32760aee80981c34db7c25747ae3157771ca39be69b327ae6c4c3ea9e4ac2c0882d8b8ee2e447791eed67cf624b3f817d6b5c0cad585e771c72df890da1d83dd622e9b7fc51d3478b323efe1d227e818e6d8b73baa2854ed207c4fd0b07b177c7619ea2c0de314ee1ef9623d71b8f3288e42a8a52ca93afce9a0d5b35bc34be8317c69488535c2984473ea047f45d655d9faa77a2981f457013099d97d583436ff79465b963742ab5261b72466926d44156f2afcc7bd5d1abfaf95868d948844875d4d0ea5b4c088524c7a639ace5a6c49284d6bf3be5c627bcc50cefff3a3d388442d5daa35c55a767644aa165d625eca3fb2e9188e52dc7aa47192c9071495274260a2a1225239be466a93019d032c53ed050f8bd36b1c587841439e5393e1ad953246a6ef6b128d04e544a33bc1d938b6398cd1f353843cdb7bb8d362be97dfeb1b5c9360c16d47bd60978a1f6bd05049ea22ac05b4c130c943f3e4326a87ae538d02f7251eb91186c317ffc682af1981f2a2810104d2c60c4f75edb2523026c6caa6656636647bfb1bb742a2baf0b6afa446919f57eb1b1a29d96b46ab0073ca6792117635854356c38ef52395e979f8507b5939bea71c0699a8b86a65719ae65a6e397063ef79eaecdaabf035726ae26491c74f1f88ae18d1c7e6ac35cc75f64402e41c61af0ac6b069e6fa5131ad3a4b4be924e0093c71428c7befea7694a59898c899d7d8c19a129e6ff783a6876ffa6ac27a56a9a904b822e495b162d9127ae50b0da4b77e4833aee54943c38ccef8b5c93d89fab5b542022606da4c55c9276d53ee6462968c605a18503207623efca2ffc98344ba6935849998bf2f4aa591913519cc8195c56479474283dadf79b98054ccd3cbe2339a5c2a232372080cd626a565672d5d7239f8cc5d416aceb73234c63b31907aeae710b23352ce005f724437d366f6a5dd81fad98bf117c150ad546acfc7c157730491e778053c84ded8a664806c6e396491a944b00918c229f3a6f6160d97e6cd786629e6980e652ac93d413ff2c4b254449160720a225a73658f782ca91a52aac147fa28e47c9895b2e003838ea05390d3b3aa1b9a1effc63cf4331cde735ce7e809acec5e26f057e03450c5c3929eb79f7bf2b70b8ae0039c3e5354b2285970bea246892a27ff9c6060151fe097b0b9d5a0f64259bda2181a088986527fac471ab7d09b47ba1a31a9fda8f869e0015c4981bac911058ffae829258a5a75ec78bdbdb8ab07de727522213b7bd42ef4933c7c2040fc2f6e03572a809c0347875b5fe2206ca607aa9ad8586009f4f75ec6cf8c3f3835bca2d92d1283d2fc41487f782350430ca9378d764bcaf62172077f7ef8873a4d36787a26597608e8a94ff41dc16749bcda05cad6ac738e834a34d8073a1d9cc99356b45ddaed7043cbb2299d7d7ecb88f80f3b6f5cce704b97bca5b9784de44cc97fbc1ae717562092c829a35a8f00a9ecab104c5ef5ddf7106e3438436a52349e0114e32af2abc72334b648d57df7e0a71f9409190573ed2b018ca24c8b61c7eb8f1a58ab8f5f902940103b9028f399c5b4f46adabf30305ace401798f19a30362d6b77cb52d7f563700d30be9b075ffb6a79bfe28cc32dda49f1bbbcf1b34049a6199b318462aacb55df4045c2e356d729f478fa6a92e443f489c6efe5599360450f34caf39bca4c92bb9334900df4234a9b220e3fd1b5d0d35567e2ba4999f59b4aca9367491e84ba096af7a62fdea490912056e33979ec3210b60f4121a2d560386cd1d5ef609f8415fb3703357f7a6c17389c248ee13b079edad4e76e4a1d7b09f1ea203346d8f63c56e51334beb1e7b4a816c50448642204a2584c2bede0ce4e7899d3bfa79ea8ece77100c2cb526e6e9f3988e7bc3e07de352f94a48c978316afb8ce562ed3f9638cbbcd68f19ea8f65a52a4ad0d72f7b5b496e45f3d1c68905dd4938853677ce52220875a2e7caf8eceba88b9d6dfd48f0a9c151d5f730d89fee9f69963998a64dc54af442cbe06cbb2a9efd8d8895aa2bb7154cdc589a9eda2f7325b989cf74dafe5a5c62f22d8669d1e03e650eb6ac965ebe49a68ebfdc8446512ae529854c85548c4a3d67a440196c63ff8a8066dc5c5d898a2864a1acadd8e56d42d29fa03c6a1b7de6a36b3a1acf5d837e6c1526be6b90c0e12d0d954d5da31c99acc2ac8df01c2d65fe5799e6ff4997a6d0d5aeb3f7462e8076e7ecbc22a86ae8baeec27fe3815171756f5a430ad14f5096342e7006d66ced7ab1bf44fa80e6c309e787933b14ba5330ef983dc434ee47d706eaa490cab171ccf41972c26ce1e4c5194436938d3a307ab44f22068cf8697b6b095b3ae80318f67761393d0d2166b56f671edc6b78b33ef965260e65644dd407fbb69e5bf2260112623bef7d279281b9f6bf69a7e1111b24919332a4fa2f6bf42b5868657f97657aed52494e33bd9f66b228be16a50a50562783d1a7ac50512ced525c80f91eb50203b91eb02f73cb0ed209b16460eca8f5838cb2bcdad37d5e9cc617510572c127313eff6f13fb58a96a854560175bda11131d53a855ef2475ab4fd5ae71cb541f267bd787234e6bd6876ec8f84e29b4587930aeb8e408e1fa2e343ce97a751d3c6a90b5869b9d313185e56c6cccf0836ba7e406699b2d48454634a1c7c491000b2754a13611ead82e5381e9d50444e9a7f679543f28411c79936ea97307d40477aff38290c01b56c92b701c9457aafc9f78b67dd1854af1ee1dee8ff820f0e318e0486d8bac01fe194dc920845f3b4becc86d0aac2d85f8b64d7a0420f67196a8b4f06a2a57d24ef030d997d436cf4933ed164cfc70687b41749d40f470fa6b69c537317d9bce9970e91d39f8a7d45f6c704f9fba23c6187e4e7e8f031c9cbf3fd1c83f8e0b1d0b41619e435dbf5df4151d42b3944d116f2373525006b481544262e72d861c64d30724fc14c594d109cced8b161b22f2de264b255a36941238e869a88d39bb2317a677c5523c00a07b3169364b7a620a3ea8d7fb875a4c24e362946af8c2b77a17370a4c54f42409d6d0aa0b475221cecd37a596e368efefe4c7fc2bdebaedbd81489257dcf63eb1d2eae3873444b53787f6966093453d421401094aeb477f599169a7b6fd54425682db7d0cf3a91a537dd5148da89df67579871487d64afdac29ac56a13d5e98fbc5a358fcbbd9dba4ce5358c2c4c924d29f713538d905e0692c5f99c1d0cde6eff28ef42f88edacc1b452818eae429109852100af453ad9682f5e485abb7b02784b5f64a782af3eff2a9d18e62ebd64f531b3e07e0b5781ee4f34f6fd6361728188fe5b9b7b4cfb76e2715f3e8434252f2b523b6865fec5143c1dbe7ca7843f82d7c2aab64f20071c7088d8dded21fcdb97fce14a56d1dff98f67216a6952f1bdb018a352fe42e6825c417ef22b94295ac1091a998ec58b04433ca3e2165f846420a255ab2e92889002d3c6aee4ee170ae605a2a09424634b5fcd4d1f81bb518ebea5c5bb7d6f4030e2c7b8545cd4a534ab127a87149690aef597e35d5f9dc691ba7da925f0f339ea24b244ef52d690a7e6ef031c9ae164ef50a29fd3ac93d2c44c6a4336c63f91e895daedf49e7f85d6384461d2f308e32dde4e082ebc335d52a06e5e81776961aa029c1314141c01c9c7920ef1afba452344c836275d42982eee73de2445a51b5ee14fec28ac985513408383f0b0dcaab53774dc588b24bf087bf91a78466d290dd7c1cc1cebf8119469d8bf0b6973c0a2b4a75029738d299e0a4ce3630c2ab319abb384898b6ef207d598be7999fa844091cbbe8b2d49092d56baf2a6a2498b141563795d1fc6c75bf8b53ce8326fde471e2d9bb2f28e35f84172e9fa18cdea092e2369b40c83eb694dc0a9ee9cbeed714de8f21ee1b38d5fa341cdfec082dd80b5f06d466bc094df0aa30983a6e4595d0f449e4f401d72691634401936cf2a57e3f1a8a4beecc44a9265df502c10feed7d7e41ea70772854e1ab146903269dca73303c68650b687d8aee4fc8940a8223e68264b316a594a2ecfd3c0425bc657bf9c7d7a4661f2cf0e9beea4472edf8b545e2948561d2ccfc2fab275bc5041d15850a4a77cf1ffbd3cc0e28c3e6e254fcdb988417852418e5e30d39c4d138b97729b80baedb61c2a07b5af080bc0e71a7b364a970e9b1b99c3a6f75d5a2e6fc29a933835ac648f65954989cea5457382a37bf6a5aeacc3a2bddcf97c652029eb65f050b9db5b93f1f7f851c56750cea96f357374ec7b0426038e1eb291de6c6c8f0ea49c14c212435536df954948c0a2423173e517f4940016327848663fcb72bf5cc3237dcc9675b2b02bf5ae428663db9a8671929563cd40879a7fd8820b7e330ee28432070d635d9906c3d50ba1b3563f7f3f74bb5c4bd91cfd396be45ccd1b91c2ce8637f1347151436acb46c018556fa846a3db2c2902694aa4b40a1c4877fe8933d46e6a03682fc7a8160479eb5adb5405c913f6a33cd98128d4758634687ddb4e9756f2f965f0bb0dcf1f7af51cf90a72279ab8513698bd8215bd19bafacf9b8b708ca1c519f7eef1d0164d12c141c1a42693c32a71f78a3dc1f6fc134be375a421541264d355d395531f0fd27c3c18e29399e5db794b6818b457df7d1c0310155eae53f9743e0e889a5b4f8d787974316565571d12405aea42cc4646d5f9dd76ba02b4aebbc16e38b4985023fca1cdec870ddca51da0414b8eaaf7f8592b9d2de08cdebc25026edd39973481e9ffd765422a238d8990e99ae5b1735e5457605e4ee37c8f2b09c96be3111c4fc2b92564dc23679d41c137143806610ed53cde6037a682325fecc74e9ebf9707530a3e025a263f0f08b48fa79997bdaaa0388d484318586c3bf960aea16c3e671604e4ec22a4c40627d286f3479745841e2fddd585dc96b75f391247f1fdf9ed8660dd2267ca4cfebc122aadb6f395671b5236fb7c9143486e49be940832afa179f346abd5ed327fbcb2feed531aecb836b4a549a406013ba5d8929fe05731ca6dcb920fcbd4adfa30519169f33714477a2396dc8127367d80473afbcc87304869ffacd17b76f8fc6f47fdd57e5d3e045e3ac698c74cce58011bcfa5b19db4253ce3ee633cd36984b6104b1ba20190876f5fa386111721245c155dd860bf67f8e170b21f3b6145397f3ea15d95a83d055200d1605103cb57cd5c6903ffa7d2073509491386cf3dc2745ec1da68c74fb8ddc47b73cbd771832ebea34ced7599e82ff3baf53158b50cea28555dd618ad4155196513fc5b8057d4007abf5f43bfd3455868e5455fa13ee9ae68f40257bb11a3895f960627b77854a3b5aa673e24697ba2202836d85093614026f5ef446911a59bb21d4219a9caed54f81fb9a06202537964290b2e7a5b4b76d87b0a5ef951a5afc8a586b0b6f37b28fcc27fee0353af155864bac91b8a1b5bae0f39f4ac34afc6610d5dc2c22e968139f8260341de4d339aebf7e3ccff1b576419ed64f58f60a56deebf7d421b13a140092519615dab6840f39705108fdfc53bcf1b5044049b44b54eed18a1fec850acfd721356101d1e05d1796d90517582e6a4bef5deef3352fe6c7dd02193020e7bfd8c20901fecbd744603a0344c95b4de76052ddf520db4bbcdcaafad5fea4c39f7e58994411f576d58b0baf1801294e864bb1c9dc6edd7b0877bd23cca464d7859428f6ab38ffa158c671a08dfad2ecd31149973584521950cf6cdf1173a7e3c98140a99b8453683b0dc3bf75177fa943ee94c07bcc18b1e2effd20ee4095e028ac3e00c38c3a66d66133b49bf88271e28c404fff642ded1fc60f175374736825638d9b1bf9fa84270f37a41dcd01e4a91d2fc4d774eb53c207962076870144734f15246a3d9f990bf0784162981df3331a9a3a0783c0a3784a9524eb52cb826c75ed0c8f8a674f4878c8e90b8066c9f58d71362621ddf443a3c2f3a5ac2473298eced467cf0a1a4f2f191a6483f310f7303be2e7d42cb78fc8baff6f5223f7a5c4e35554089b539b0e3718a7a24e0f120d99b131eb1ea70170666edaab7bbb6968b42c922c6409f8b5fa90cda755dddb5eb9a115f6f183a43b51a92d9cbb0c5742a843fe12a522b636c057bdcfe4601e61b5677a9830309b0af15a7c704f54a3c2b6a9eb7f99a99efc2d6c585d6034e3a5dcb2f8763a8c4147d1f3af901329fe9204d2373e2e7142d341aaf87429f1c9f47a519436e0665bdfa04afa9c513c983a04901f9ede0db92d256331cb88c0eddd1570e5b9ddb9cf934229d458b4dc39c0fbb56518f35457d1e754126c36b749389e54bed69855f06858c9c2491f2ec544502e7d5e39d22eaea8d936ebe850483d9006813124c47fecb7e0a041babe1ef8102e1f1478219c75a369003b6f564be0ad1c40f5437a7c7204483f0a65044cf6de57f5adb52a13fc95b382f896a66fbcc0fb78e4938ffeb59991f90daa16aec6a7ba13a23542131cb1ade14e0aff5ad3ba430a5d10274fba444b226a1d5a3519df898a3c03a2aa6429d7ffc15b1016f1f4d5268df0ae53f18cf3b375e0a2cd980c178a1c1188fdf1e96778312886dbd8ab0bd30cea344e02fc8c314f54da51714a2002b4d646b41ccfc88a86f9f81c760da8584eb8eff79fa5631bdea7cfc114018d7939edf850af90db45cb920d48e636ad251cac67504622afe315b35c11e244dcd13443ab0c4ec52ff980ff640aaa9818d19531f83d28f8cf23c65ba04fb33e20d55b137b7e908f12aff0bd1d2d3eb09fa2270025df64c427ee62915fb63e9cbdc98ea60d592376f21b5e79dd6b7612b31f56840e7d4c94b8a758906227d87252bf003e8c76400428b145b9c5a771ce86e4f05118029cbfe45eb5d711b142f2bd8cc26b7fafe920e6f8d186bc60820218351f4d8a7de57451dc7c29bfa974f949c12d07dec302b2e5b8a673e8cbbdcd5759ce29e4a1d8d8e75f3290a71fa213977cb847684ccd95f897d7ce4e9f32d3706b862783197430dd42209671e60b704d2f2910edc09b31443c5f0cf2a44f56963a44c3895094daa485a7cac1f3bab3c85cd605c88341a91a9052122304605ffdc28c7950cb006ca3abae2d466f4d0037075f4f0d7dbe5475df17b9f8b537a1998fb9ff9f7bb31c81bdc39fd90cb73a2471756f401f7415dc10a8df3ed3cd50788e211e5afc745c82fef125ac2194b654130301326ff06f63322f538b5460587f9e8b85b7109a119834e00224d847e28e4ba745e103d3fb5e44f63830605811f2428f2af0a245f09cda5636e903422c5876dcaf1735b403f3b00814124bddb47296598dc3454cfb3b97539b9febf7d00a6a9caf04bb66507a5bbcae6044824eba653684426ad6983c8447792882aff31067843f9ef0d1765c70167e72a5ca2ca6494f63130b9ca8e27104792ac835e4619730ed7fdd2f14ce32550bd77f0f5026211bd52ec85b346883e1e8bc0f3864325bbd0d3321e255845c316889b91214b6040557511513bf562d2b71d572d1508c63a367b9723277d64a9d8aefe6ec3bdd446b2196e96206116a7b990111526546ddae8bbcbfebb2546e20fb4917d30be526d406ea1112df3ab519119738af98ade5813983506b7fc589ad29c23a66a8561778a0d365da622bcac526e49c2e539bb45eb2b297ad201d8c4b92ec0597aa2debf7a83503ddbf6cdda63795d476e0fd8bed2f059f9f88fa06a939d88a8eea317381d43f569e8fd28ed25499e30d1bfdb5dfd1a0b21111ee3e38d6135ac9d15c9fd8a0832c5555d2ccd37a4b70bd085651cb4097d016187153dc10d0ca819658ffdf5694849ca2f45b954894dfbbeed22ef65e50eec18adaa99bc3728b19db067b74208377500f7e4aa6e87587929f5d1e08cf9f034c2ec63744cd1e058f37d4478aecfd5f1974aadf6e1ecf9f3f8b68a156f40442a9d357f9ba0b31df5c8f785f9c3e74d8dd078634e6c9ccb0a82b05fa4019f3b2bdb08e69eb5f2d605e7a0a31920bd3b90e9037203b62e1fcb5e1a716f8287266b84b95e5b19d0b980e44daa9e6a986da7ea56aa22d662851bc72c5213cdfb89cae62924e2b5b4be5f85adf46eefea35cf7e2c2de747f8dbd1fed4990111310b9411de6e5411ccb9516ef6d0c6e7e490965e2bd3cb2053f3962cd62a94aaa306fd4829b427b1038964b1da11103e6b0c3d96624218aa84755fd5abd9caeb430006925d59fa56558eb57859df18db54b4d584c2c2e72f47cc52dfabbe8a07fd96cf3ff84bfda8f0e599234237cf79c5fdf531052301577c9c50914b835467e33d0038f83d6c2d68c21ed345ad522872e1f63a0c62f1b447feabdea15f9cc9bcb51517c9fe9018e917262c68c68686b37a5e4ca5f838194a152876e463213f4dba948e13c28cba78d279fd9c34fdd3b9e2dc6fe2d94f6e2f20fd9b135c6d36c81504627904de23c7beb04fa98bb5417490c44d8d58336a0b781ac3bc3ef243ff53b75b71c29ce1213c5df21276ab679b969ef683425eb99c10428195ba6a2dc63a80dbaaacc6fbbeb1cedf7eb4da9ad555accbaf8210ed05a9ed8db4e2dbf9b826c131dfbc58b37d68e4c77585b2cd4c96877cb00aa017541ee0792636f33c33e98ef2b717efbdd1195b714d18f7fd377828af619972a52f95d5762597f5773ef6780c2b8490c394d5369705c1646fa53c0d22f689968e2baac0eec12f0023f3b0c3748c915c18fe2d7f04e695ebb0cee2eb422114d3ebab09724b15ae65aa9d3315c526f8b2098e3ffadd14aae636e9b7fc7e95fc9d6d7e348f31bd78d3798e6fd3447b14e72f85decdd01398eb0298c68ef02db37e0f4ae627b2b18a76d1257a54d8169550a2e96a31795f10081f7273acd165b08e2e062cb4e1f3ee3f7882fda1d88917a6538e69da1d514ba07879ad31fdebc6bb96846bc861b2cf337558a54c2195bb3a3ae97cd660d7766bb4713f03402601092b136108f0d946b14cb98505fa5eb7145d98b9ba0bb0cfed0091c70a7a8d3efbf7aab18f6ac870b2c475ce5bbc4744a4051212f6380b4a6b8da8340e5baee76273567acf227f7fc4832492a2d0cdf97df5584b8e3ab6daf126985b7bbb5e7104930b97e4524eef884a20d0229f0bc8b644fc2514604948c1b66a9cb7ae1b7b8d7c8b7573e413969e6f725ab34891d7906d517d1c5fd7c3a49d70cc0baa6d68b66e3cbc09b9349fb16467aca4b94a0b282cf2495ecc3ecf7396302382463fabb151f25dd6a6cb301145ca142728b664300c52d703e6322f4cf39dec3426b23d6cbf6ce2c9d3a85a1e57ee63bb17921f890a58676a2b15f4498073fefc0a973a70439b1bf8e972220007d0b2a93b3c4fdcf313f889d63051ebfa85c5ce337073dd7e0dcca54f135b1f41e54223683fc887d26fe6bad4b242316d0db651b1adcfa8dcdf5695358e2797d9eb3cff90234f419836b4c2c4793230c65dee0cdab4796b837743d67241afd3bd08e4bb8abbe956e2926cfbb3b25d966adfc5d3475a672966635210e3e6327e9b697aa75f5b014557c843e72840527fab700e68a7915e401a8069bfdce61e5abe282ac03bb08d61c8166d1234d84ed8c306d503f6658380faf332123650fc4a1cab5337a12f3108924ffefe6b8651ff5830adc97eb4c693f3ade100fe69f5244ca2827add3e816e01a4b7f51dcf0958816726ba41f038a5c30d3c5b4e2b8c7c93ace5f22f8fdbf9da47e9a6a0c00870120f071988eaea72762551b7e26d5ee7147ddb43cb780a3cbf4589eace4dd7d1cab988883683ce0091fd79e0acc61867b4c1e7ee2dc973d5db53df43e09bc093b290139ec97fa04641c208aef685c3fd5405e97f799194222e0064b758de4e2b9d8d8077ddc2a92db7b422453e8266c5fb584c82cadad3cd4613500a9450006ac5381d74fd0eb457f6bb8155ff7e83ccb8663761878c5a2056aa340342408f825f2d8be121b6c7bec9f17251fb9a2f9a5efa3a07d416c4fb9615ad0961716b2a07a85a86ca3e5984ccfd997839825dd153195e60e97de3cc7cc329bd88dace8fbfd5cf97065e8914b4b0ef5a29967848ae810eeb2584f3a16c25f0da4e292fa4663feaeff680031f4360fda260be2e4bb526d37a6c73333e0233f06b4fc8b1c9f64d97f9b7444b1b0b9154cbe8c6330e82cf5858638737e4821b960fd97b10aade626745e81d8c93ced49a5d57edc939e3973219a9bfb1724456d389a2d4cb4fb96d99507917d32a76a232b74e0fd2f41b4ff6d10dfeeba49be545cfd9442ca95f03d3334d6296a0b160b4767dc69e8fd794f6afddd0be2ed8887b23b069491b672500745ea14c659a2ed68ce7150b13a00ddaf4809e13ecb203a593dd969b00ef3c4be37290a43fe15fb564c7169b01d4db46bdf2c65601d56ca212a70d80f9be7c4d50ff48ec7b319d9b1234d25a7330003ea29385af9e27a1550e277a2f59518a751c2f0b51289e9d39f44f043bf28531bffefe0d38088e5668ecfb078e8f58028b99267fcc937d5cfaded03c58e3cbf783557d1b6c9d95151721ab8857922aaa33ababaec59da1b43ba40e0e4815b364366057d3522d565f29c40d32076cca94901bf996072d4e0563a1fd6f21c84590ae3d10984bbce09e23abafa367a0103b9242e2bd21a06f2e515013f84ffffa6e56276fdd92a28d0be114577866fd78a5a73a38d7b45a1375f362d316dfbb79f6314e34583a1168cc7a98687a6bf43ba58a710a7f1d227fb8f64eee00a8283ff956c5c00d5b8c9c97a5f0f5be90da895097b890b9a487e7fb713f9c571cbee710d370fa460f66cf31b07cca43957f2f81c9ccbbea2c641d66ca30f90d2e7391035a7306d224cf04a8c789325d9b2777ef36b8f05802ec40975318c0f709162c409e824a0eb73b8fc06490aa3d1da1d0792fb82dd205bb91d6e8c47c587f688b2d6019c64618d2c8de95846a07fbd5f665378d30601738f2b9840d66313e26b802f541f72b17c2da8febb2934e13634838db1944404e74b91f678983ca876a6d620061628175fb77cfb25f9132d58b8c664fcc3cae624e64fb0be94e6512b3a42b059fafa89472e7fe3e3f6d37c3c2b7aaccf59d2fcb19921870fe2d4ba666c434d35c194057dfc11762887557ff80061cbf6fd8f4881d81a2218b1b7d8ee271508e7cb91a792b2496a96083530dc5ca3d5b66a704e239c362abe930305a69427455c742a063722464b4fbe80729866e130891483193f67d97ece13f3593fc13845047994f617dde365569beb2301ed2199cc7bfcf29d7d150134ca95a777ac3f41c6092adf0d1c44408fe2dcb8fffa43e85199b29b8875c209ca95937bc72cf852f056b291eed4abb7cbe794110dab0c48acb5da265179411505188f19921b9652714b68558db134b00eacc2321f154811723f90e7d5f710f7ba7b2b2704d88ca69b23d453cb7fd55bd348453ea37cc839ea676ef42a189d698935d4a68c148ea8249a19bd1ca66739013aa5c781ed3ac793b9145db1ece3c108deb1f3529e5bede7b7968fb80c8422b45b02e1d0368084dfa9e777ee0089fc50d1dd36f113789af964ac9038872d1c02ac8cb42e80ff7419476f49a70a2aa1b719f39a5f639d24f569f03b48cbfea0408826f2f56f84a5fc7bdc0db90a4429b0928444f3c628c8de0b4340b6069262335c6290353644679026f918e3b1abee7f8151d51eb464a53c0d8af29773c49cdcdaec160f1564b18851c3bf9ced6760c6f54950b7ebb15f05fd492fa36c6871dd5934e5981907ac1ea07e29a881e4d8da2f30186460a4bcf08bf9b051d14c89304cb2b7b46c0261aa146d8fcfd287476bcef4d73637745fda42d60ad93ef129fea9a5762303524714a73c7e15ddbb65725657d6020d7bf2fc604638b040472e2f0fd7ae62011bb34d7b39d7dfe929f38a43db3b4b3f1bc390cb3fd79c57a25562f5ff58aacdd019a17616899e411ff288960083ccacafb111e46d63f441ed4c755d6e2207ae8be7dd5158439cf6efe5ed7754e2839c27cab7f4e9b799b3326e63410b07067d493221ea7a482858ed07f84e971424b567c08913c2fd738637da4ca7a468aa641cc0b95a49bc97e1331efacded85f66e8b862d8860fabff54e2a396fd5ff5de869b10f35034772930b1b1545aec2a0a124cfc664e4d8f4b529ed22e2b769b28adead19b122b4c0bd1efe98c950498de7a3739c8034b96009cbe2dc3807a4f72a86342d2bfec647275cc0e3437dbbb6bdf4457d237016c54273ffa2603cacb9a72604328b9b093618172ef4447f184210f4f6df492f9b2e2d530dacb30a1c9c0db25960913b089ba77f3b999fd288dd11d488aa08e88e7e03caddadc22cb41006f25885bf6b88cd386d64ccef1bda0a3670d4b1413f7cefdfb557052ef365b68f6f6115b1739fcef115ea60ac95d8e9caf9cd65ed368e5adce043adfc6f1813912b6382cf741dd600e7665a97a8098464b05e3b72fc38aa7b201d00820768149ecdb1da9cbda715518b4d6c58706761542825feb09b5630a15285fae016776ebe3dd504b194b320fba846b574ca595c5013779ba419458dea6f0b334ffd35445ba28405585a58f877deeade03d1586b9d30e1df6c86acea6a9d8606903855bb5b79eab49e8165f59b325d8a903ec031c143160450e52ba0fdab393855622b551f9ba124970d6b4f444fee15c4f8a6339dbb59ab9ed0d82418e69f60da1e7b70fa981991ccb9b142e0070fd78732ef48423fa28dab3bcd6b72ecf936baf1d694321e9053dd222c613c9175d1588ffd65bf8f266df5d0368bbe3644a9a1c4ce480e4ce9092d727c1b3bf9f131eacb5f3baa82a7b8780e15c1c48cfa3102e862e11839feba4f724495856560ea5d2861425663b80b7a42cc56a759f08d6aa215d6ec9824bef3540ea79f4f485e5e87ef2e40efaa128fa179989c7c82b2b5c9d8c80c25256c406d19e96f7e0ebfa126fa5c3468b3466925f274334c8e856fb76415520c7e204f4534d37450425f19f9db4ab89dc97690651c7d3a6844bb17496215ad82d6d61ec4d48a289486079a7e18e6527fc61f00f44506ddb1afa29e1adc21295eb382eeb892baa6783e8a6bb7c24f6721ac9699d5a7e848296efb01b3dba6208ae61c223da6341c5643c206a571f8acc8ae8167926ad01de303431bacdc4a3ded49a03eecfc97595959ce391b8fa80de773607529047cae51106ce25c9107f7a5d73995e0a8d5ef688e1407639be4c30d0f6207565c28d1c350f6c34f893b871fb1b2543afdfd68eef5392a36fa7c724c0cb6f7483a2b553145e96e9484fc5b58519fe55713c801568e6249dc39b3af0d598860ae0e5d78016c4681e467411f5b5453511d90a833b62338ef88605efcaf9ad6a4730ab7ca27e634b26c7c704e5efd6854b3370b006293783088106e48a5cd0e087b02d3bfde9e9b340648263c79d352e5be41f7a1ee503ded620add3f2a23a642ff52cb916948d061c22d6e1797f8bfcacd549b87b35f6fc3e5fabbe242f4fe68d57c4a664971d8f493a5a997691858aab71f9c1458b11901c8842299d0e13d40be763ef9eb38bc4c3762f582c0f1f6991b4c5468d1fc60174233450e57cef09bfcaacefad667c98623fdf902920105b9028d393051d6305c8d2273d434068459df42fa68cb097113c83519a235d914e63918fac7b0ff6dde05a1d920808eecbbd58ba3ec206f5949e3990ace46784cfbd72a6bebe6e4db46c6612fc928e9d533917d9a4855539f8e62d746f10c69459e1ad46772f07b356c840e5eaa36b94022d2341adcc122db547713dba5227126539f05656c728924439cbac611289c64d357ff79560e2b7cfab7f23a56fd44c93b3f390d9e01c3764e8c2602a1905d71e19c486a08b94f317d4d0ebe1037fa561faaf36f337c3f34320c630bf70e543d32fc0c8991108555b0a94e5e581bb2e50dd21643245c755745eec93545f7c16fbbc094b83466111181c0080c29de6e90985e35188db42ea63cfd3e53d8021de1665984ff76a019f2d51762e74993fb8d61842d24f668ddda110b7dbcee5c3fa1066b9d8d8e96efd5644bf50ed17ad01534b4a2409e6cd8e73b9b888703de800db483b5e042e1d437e11e321a48e5d595d8c70eda1fa356983d8429d0ec7c3afe0b5b3673229eee4f5504b058a0eca3db5268dcd8afa6d2e55670b2c55e771b94b769f18f58f6ce343498e1def6751adc993481c5c371e944c4d813db7a132040efc6576f71b0e30fbf36b2e9c41b89d445cf2307016ccc6da6d9b8bbacf77a68c40b81f7ca433b06693f9db7ad29f351b36fadb9204b340acd730ac148f2685b04c0f262faab146359cf4c4f2524447172a30dd8d9c35b4c9c5243f6ff558e2a6d1854e218dc3e4c9cc26447de8a447e30819441a74d323ed561543c563ab5e86a68f87adcff252064bd7afd1e9718186c9cd38a89445a7a49f3dc6177a9375263b8f233080442839b6f9f94ef28c8e067d74edff7fff64f67e7f9a3dc5db3199bbbd16373ef9ac289ac53e6b8233286b376911338c84e6b579584a790ffaad1f91eb50205b91eb0ca4aadeb30eee89372bc8766ec330c6664a9a2534c0d3c7e4fce437c75b4a70cddf7c37a30c803e9604536232066697e995c304d3042d44a29a88eaeff6d4579e6992bb2bb13cd7253b4d11263e41e843c7cb9ff795d84643894940675e5aef4a1f2b677d50e2fe5070d443e7d1562f68a2de6e93dfae2d939c1aee77c16d7c4d543b3bde0cf07cda5c96b66e3c9bb5b343105f8c3a4e2105da149ba115624d2963d64deb58d95f52fccd740b561215f9fe36b1a05c5960f3b9be42106350bc0c19ed617aa427c62c01f4102f64ee4348ddbe86ce3a483fac2514e56e2f809fe32e0279d18222148499ae1912e3c1f0971551d1048823bcbbd90d6d231b236a45b165a3cf2c20df97de5a1fb624e02b1869066bbe0c67ce851cbbfcfe6160707ed62c994f4b9e3ac0d84387d1d741cdb3724488a7c86fc6ff47d517a5e45c9890e68b7e068cd30509e37f7da93c8dd7b0fc1e4842474272e9d705c217c975045a2ebad112365b5ad37f53e8c0590559b593dba331ae2be6e19500b81f289472ff31db15944f530750d167afe616bb513e75b787a1facf130317b78b66423938b6e9c1d4ea06aa244d156c601557fa6e4cfd05f6860388a3cbe0a4f28454a3f511374a6d3e57e67fb58f3c9c9721b4c060bdb09992ef5fe34874cd8991b0f9abc2a50aa78a66d33bd4a234eb5ebf15e7269ffcd8ea92e125b9c2305f6e8da79723ec1526d25d0f1bfb3ed02dfbf77b7cf81d329836f10876e648dbdb49ed474e8482000289a689a9e5dc50292745e5f23ed59d6822ffe6a314452e62a3d019c1e8a45f854a409a861429c2b4be81e787fa9532f5e125caa1dac185a3f56c0a5950624e3ba5ff4b2d51d2993ce5e2b6efc2d6449a21ee3f130ad5265ec9b492b09cf03577f0d62be3d7e7a799f42944fe702afd26bb9aa0eb511818e2f2ae8b7ba3ef25b29a630bdc27670121ba1cd95ada7f6bdfb7113b5d520c946cc6d01c9b49f497cbe3ef2a49011e82c9532695e4dccb8e1397f8db9395e4911e6fd959fa4eeadc901d3565c2e0f3e84ec0b416767a79370e579536d2874399226b2f027a7c8d405424d9ede1c168a8cad73ba4fb9c27a79c1e7c8f788b8251d25d016b57215bdf6b2b6e5b774d3cd17f809dc468a3677b831e9e9ecb300f57655ccefff516c520e0190be348c2dffa8023543699a7f5e81f2750cc60a26170a8213a3b945d946c3eff84c37c0f321906a260bd94569e2a6bcfa863a2a08e1a00de840e01159c6d49031d2d38b1490856e561e20bbd1c8c0902377a722a43d2692f4c251446238bbe73bc67fe8f78da25931cc20b6140fa8d601f1d6b0a703826ba1745c0616603d2c32d8aad7c783e9893e487a2b15cb9edf9f4125f0d8fb26104e5f8212ad4231e79ec1ed57b5585d22b6a2ebcae019809a6715da33111b3a1fe7fb5117d2e4bd9d3295f9c257bcd4c20d7774cb2f28c61ee56cbf26f3c687f966f40ea6626b421c7c0881e9d7cbeb9738921f0263a8d5e9745deeb6532ea2c8a5314f3d6d73fe31e9fab91c8256a3d55b71bf0fa5866ba9d5eb20189720053921dbd852e764ce42c1266cc572c8d4d8eb4e5d696e0a6af0deec81df75c796f86bb21a4abfb2b61a510d1ffdea01d9b9c6c5e97c9682856922e5c7603ae3005982e5bc579dc60fc30bd281d98b3d8ec00e68ab69973ace745c6f823f4c68228e5a947b49cbddb74b69e7df29f19183a800b954e9a3de5af1a4cccd003c472d8a64f20e5b2f3ee5dc456fe59ecf8b278b00d3cbb3e53b5c202108f124703c52170dde078f5c9556f2df9fa3b7fdb011e389323d924f9c420c59f3ce8febd2723ad73097ee3e3b5c5e65cbcee320f558cfafe361ab96179bc8b73d619458d0dfd153f23d74c51533657ff97d8932d387b684506cafdfe8648b2edede2a8089fd8ac9dd66713c4636ff6295885ba4d6bddd7280b8ab89f0640ce02d8158e5dd95791c0c1e00d14ed7746e058d9befe04918e7c8de4e3afc143ae44262834a4bf4a34ac7b9a4b7bd5af78e2c0b915acc66d9130883954d610f15e5225ce86c88e9ecc0b48c499a9f045af1fe7a285473c565671d88a11165252c626996d29d4174c51bafb1f68b99490f96526c134575d7d292e3ddc2c37dda18afb26277f0082008a0f512228edeefb5c3630b3a40d76a13f793b09391e947f8900b60430052efeadb197e5d8de3baf15de2de8b0c85ed085dc82e2f79f3d4d7715d9a53924fd88801993f8617242a5a45653f15b852e5bf2801fc278e1a010e8d17199bc18d52ecadb4546b68d91f863612fbd6781a6d50a85800a60a73d6667877aebffcd182ef1814840797d198992f67c0161000bcda571539b260f173b0924c9e017643989ee6f5fd7391b41cddd9635c9f2b286a38a3966e30e92f61bd347f09e1a4fac3ccb6671bb32d35cfdb0c90d270aca002de014c0f149eb3b42fc77d28331c53b912d29e54730a5e6bda3e68a3c1d00d1179679891fd4c29728369cd209590653d2a9644f865d3aa8de47bd51c8e64f5111189f2294a19f9ee880c7ac8c88ca88a1dd234f7b788dc16af8fc1ef429e44cdb5bb3535935d0b3005af06f7aa499e6de94bba37f4c606fe8b5c94a0462c64d1078cae3799b131b442a18690dd3ec7b258ce76c56dbc574062641bb31bf898b83c0649ab56f08a21476ed0c5318e7ebfa42a782520b8ce4882826dca5a0bc362f73f9e4fa27a204c0c06d54c2e5b4511f6d5dff1afa82db760044936e5dd867125b386e8e83566a75a38c6198da7ee1178c2ee239c785933e4b449af9ff4b98c03ebe184204b1395b5547fc56d4ed42ca6b426c8ff89088950c8bb4ced7b36e26398448d5e159730ae58918d7a908a883236698248959c23b63751fb3233e306e7d11dc1571625fd291e956bb8c0f68317654ed8038e9eff0972f5d8807935406050fd942a340bad0fc98057311ea900af446f3e6b06b6e2030147f7f4e662b9e463402f791716d035484fdc299a4dd181c5f79e840242ed44ce2ba86f86fc5f3dbce4e08899494ca2f0b195a6998b0f340166a1306bd94a999d3ae7474ab0940ce68eeb3ce8a0a1226c433d67b02c4253fee115723f68dab2d29598b309e4a75fc94ee492398476f44141ee7c5bc699080f03d3d42b1352873680eb84fa7ba3d761a4d3c5c6272383aacd7670d20b6e2519bf67fea1120a07c7a979e9189bc79af2dd264caeda93a6a655bd9db0f1bf844333b9029d34374c8f9491305cab36a53a3504d726c17af4f51b1196d7723dfc3bc98b5e0b7aa89b3213ca3b3c8442f2b783ca2f963a9cec28acb0010dd2533c15fc422da25efbab0606f95f0f3d6a223cafd2edf02024f57e6cbf621fd7881b2a067b9fd5cb33bdc2902e8f0b5c5c7d7d67b30b1e1f221111a5a8aa530798eda2072630bbb9d0e96813667dcd6c041ca782efe8976bdc2fb8278ca1e884a5e9f9d595b7b0c5afa4980c1c683bc9d0140cb1a654ca676464fdc521e655b3450ef7a3dbbf1d5272cc2eef2f9fa1df6463644cf823991358014f6a419b838b19824ed3c4402facc15b32ecd5ee335b0e20451dc5bacea48715d343d37764f572ccc573d36926432e617d9c5aa7dd0bbddd89ba7328e6f6468ae3fef1f5e910c57b971e55b1117492ca9420165f2c51de4ff1ca47a314967f81467bef66a0742424ab9c1c927f75c065a3545b6dcba0f4a9e0a994f572d0bc7630144dbcf364539703b70cfbc434336c218f805a332d2f5713116cea0210046fc331dba53089bff29947cc0c44315b9376814b2cc03d01522bf03ec4301ccfac62a1ea8d7b1f5a98a6fe7f9d022b14bf0af6007e0e4a00167acc7b5183b2d89c090fc6507ae4a94b11af7a49e15ab7c86699ff69fcd55f2b25e8f01d3aef2aa2410b8a5adfb9768a6b7b4af326003f0a22cce18fd384bad923728fbd5d19714c450e40bd4b3cf3827613bac5f9d67864e9d8b2c6c1763ec3faeeb3f05e8a97fc1f253c2f9f9ee8c5da01be126e28b8bd693897570d07e45aa887bd630c01b2090661f368f2e76b00249acbe136eea280db0091e5b9e8e2c72c37bc9bcee317bc33d66b193df653497025852e1a8f3cb4a2a9a652baaae0498f7d8f13374cf52931b50f884e0dab8d0c90b3e6933b1220ae2628b075ddc5c17f8247af0590ed3d4a550f16e833837c4cf14c12b01d826703b9eb15cc7c577e19d5b9a6242d4c1cfc0478644e9f5d8e7850c2f4383eb385b2f59d45d8459486f61a0d3685f81f07339ff74e9918d0d22f5bc35123035046e08838dfd7e6bf0faa4e38d344ddc06bfe4b21b9b395f6fcc9ce716f1894278b8e19cf2946277668547a317bd9c8e6bf30ec61e1c4a1889a3f7d4ace4ae26e0e19d73af70b810d4bdf2bb439d7a1f690530fefb7be052ef14cbb0308a09fd9d878201961cc666dfa5a48c80c91a68a9a3f6561d08a01d26dd4bc131689862999db43e64adbd2bbce59b48f7ca841ebb22741c824deed1c5a662f4d5edc54799934962947ac43d1d137d4dde77eb0a9084194665f16b4398c9c1e60b3d319b3b9851c0544e14ee3232bbad665e3b739a98065d1cb4798fca0b11fe24d606bde36ef9ffa9879bdc0d40dd962df743f6e360995d1f5b2c6b9c1b90dd820de228927d51574fbf2616cb150142dff331eac2545d6fbe006398b9756ad4c99e234b3ef523bb3e637c3a46a3ba205b398f7bcfc50973ab43536abb790ab6d4207e439f1393792acf462c4fa3cf379d19943f910f37985a7dde6a3305e8329f24c71a8fdaf3f297d56add75b0bead5d74fc8ef0365aa6af27e14629b6ed4f31a64eeef88371b7338e14d77381a2348455f3ff09e35891c66b47161d4e20fb19fcfec1c2dd5f293ca9e55e5ec5556051a30aa8ff55f2728d8654e6e41e49cf653c0f7e1e1b9d4794849a02bf9401c529c95c93312f8d01242a738f6297dd5d1c9923d4c1d9e711f95a105092d997439b5e3798a7889f8dedd835afb040d7227034aa1d7b45aeaba04ef8970aee1bb2b07e950fbbf66ec3cd9c811c8353311ca5b6d0e91c33085c67b559956c0ffb370b315458699321c4e403cb1c5dc08a81a1e532d9b27443c8b89824fbe08799e3524f29181e1d2b0356cdca111c7c979237b462ed3e825de59c3d33931348585c6bc73c855dc8acd9f2f33d2dc79c0c1e17b45b02096e62c057c9e75499ff9f4be2e9647b05cfdb94fa70da6cc2d0f212b57ed4bb24d8a43d25637132977df39c02f069a96642fb8cdcf5570299ea2c83b744485ccb961db3b99794457756687ed59ac9dd63313d9e74c7f274ed46a5c08d2ec1adadc7647d50a89fdbba54b833f6427155f4e4d2fc6b427177decf73b4d3353a280c7aa6765b47e7d5a4406f1780d9439191bf128dedb42e99ea00a43b732a641ab493c9afa49f25ea57ea9d823b93c0894ab872691b3a42e3b1615aa521a6a96252153c874941b3c2cef8051aa6c267ccde4cda03e3f0ac27ee5671e80c430d3e135b1421833f1c712023921ac7abfcf35cad5c81e2965070b15315f368575871c36ebe0b1e3c374207fe995b4a302eb170c81f95a54090ce65ee6b14f6fed1a9b3aed32cc552f837fa435236baceb8ab20cc0e2cbf9610f2310b1adc384108e51de760ccd54198f251e8bc02ed2d645ca38693d368cd28b30ab1ccb79e6536cbd195ab7a5e0eee56b7cb57c33faea3f49e191eba57a03ee6b7290a2c7660202f3bb49f509a6d153ec1835f1359c8418c5df673e2b0369dcb4d4baacf94bbbcdf02cc8d632d9ee3990f11198260397c0db3c17d9ebd40f5acbfa3f2ba0f8a67409bd7f9829f8b28d3596240bae9c4d38dcc879d8747104b3c65d180a2861a867207060d918c869ddd82d71aba46a7d288480f67ebb66e2c6a6dc40b7c12ae51952e2aa6e6f5e886d81f5ef1bfc727d9640ac4fb9ee6880af8d5699fbf7d4951f439c990d2b4155845d2a6b1ed3a83dec42aafe3e887d6887763ff33eb4a739093c8d3e1411bc38c936536aeacf1bd9cdc868cdc967d5eb39ef28c1a9fbf0ada1f63d6f4095868c12ad1ed2219f42d47058e73ca37e2346325265fe5c4f35b881d79eb0d864fc63c2e9b2bde5e2f0b146d4d3a9d249e08aff0403b05b6a65fd09b5ee92402ea0a470065e0044d4aec29c9fd23c444edec4acc12ee154479f86c100c4a2a465a8e3060f231d167e5c137204f96c49daa37b5ad792ae2b9d29f93aa3592a31d492aa9bf69b67f3e4bc2acdf6eec27e3bb84c0b9bf988139e7fca63cc49d6c058dfb88cdd88bfecca73fec8c24af773bd9b41349d1016ba3734c7344b8d16f7b14934b4e04fe75924236dfcb2a1d87b3f7efb5debb04dc16b4bbd20d0143a9cb099afca1fce87e3941a0cf77fec06590f86d1e36b07e09d45241541c92291c99a5d0fb2f6dddd9394bd7d481e58f7af44ad91fcee78a449c7850f66f6212f5c4033201c1b2fbb6450a028262dd06ea9e752a027d993345155d87ccdd71394406fae8c3d0f0152d0fdeaf05335367bb6d009c238bb36bac4ad4a67374136b3941a1bb066e2bb69d54eee184d1184c72b9aa52d2a743eb944426a3eb02fef036db95f106b00bf959bffd5b04c27f21f6f06891f2f45f7660669ef548252c432550d2cc7232a7ff24d9036427aa660d9fb9f870f794f486633815703e7b64c1b8cf4166c5f9c4f8422adbc98da1d8d4b637d3ab82956b27b50f5fd5e40173761fb9dff16959e22d0987fc0f6bfa8e7a41277d6597c270b8205e938aae686922d45f829558b152dc98854316189805568c1a1c24bd88271ff1cf924bbb6104b2dcf9b15eea26988bd427d76136ee5b6b2e2bb0cd584ba7644a7755b0accd397e06b55bbf333eefcde01937e32a3b0e135bcd40b82a25a06daf89338a154a0659495f0ce32ab2626e869f1b6b0bd856cbd32a90db02db82744cc402bac7cdd300f7c4383472300158201608f53e8e9a1ee0a966b076d378cf49a97822c9080bc319efe96badb553025973b8f22330247367bc5d6159a4a07e47f69d7c071c8a8e6aae2857fcf7da06d9bce6728d880a6e4e1dc9ba71e712b8e1c4f19bba8dcbbe1441b78591eb5fe2bbdba4d600640d7b07bb56065442f8ac4d8d6cb45d3d15c6d481139f26bdc8dec92f317a08abb7881c9ff680a4a5fa661e4ddb3a71641c5ad00445defe73b18991522f4919fa82be24ffb6df54d10efb99f573275131f4565fc47462eaa35efa2777107c0d639031076186fed74ba579abff29fe953b1c47bffa2d5ba77381ed0f3124f05b146a80ffbd1bb1d74379c983c769d316ab66dfef7547902d167e52cf85928db6f42e9fcb7b440180d67308d3490e5a9b600611c8e34c091e7e3359de0af21c5a4bf915114c0ce416dba4e04ca0891e4cafd2064e3e01fa92b39f7f30ab84ba8ae6e965afb1208cdd700478ec8b9928692397aecfef2855bc40eb9ec638a4790b5395a68c95ad25645a7c89aafffa1eb33d914647bf4d7373028d9fcaa6b858493f9c2b1d37c90bc52da9176a7373540460624b5c69d08486fea9670fee8b3521c6d18a158d66605fb3e5fe93807a93bae931ab7222d6819c36532ed771dbf63bfbdc9a2a091a6d3c489adeb9f2494fd6386e98ea5057f3f761b8181f7b9eec57285d48fab49eb10decf8866995dbfc07a44ec3548ad7f97f074718b753114d15a2d90ac7ca92cd1d85096109c265f1081735ba7dfe229fd3f3de63525796f12323f1bb036c5b861cb45ac474b20538a17c9f23fe0ca55aa89a1dec60a3f01866ffc164f2f2f684239989f5743358552096be7d18addf2d487a4f923fdc29a82b3187f0379a82b4d71a1b8cbc9d1bf1eac1b93da6b3bdf2d690e3741c409fb22677740e031ded13364043069879ac2785eb68e34ffcb0232e73d5109741a9fa07636d7f7579216b3bc7961179cb06b7c159368585c770d090eb51aac1f183c357c0bd059e1d80cf8596e90a72f6cf5846d21b307545d6d0edcb99f21e7c24cd499b56856b29fb01b2da60313a5e8cdeef697e56b2376efb1d53e6933104baa6c5966f5e3aad6fd247de34ee8d363e99fa571c6678e7d7d0f65118776faa562cede43afa9d3db6cf9d040906f5dcd562ff62ecccea78cab584e4512505b5ea8e71e9069093fbdc0788935c2f12e5bb427d85d64a67f8943ee13c9e2c6b0d1f25f652bd77ac19a37be249e9033e200c1bcb39216c8de641cc7133cc549b2cbcdd1b42ea2dc2328ce54525bcbde61973dcf95952115c508278c96a512cd6da576313bb76bdbae5f86290a6fe9dfc2d6c79029e8a0de5af5c6802ea5cda58fd6295f00bfd1e95e65ec5bd3086cc7bd8418f6da6db91901beefb730451249be7bfa30059e9d5652e40c4ff4cd68000a193a6234cc8955234449a7be1c446222e135499588f663e88ad97670871db1b58574e5bccd04fee499e17bffef9f5d658e3e8093016f427acea2ceefba8a6e6772b5de671e5ca85d02f346c969a908a118e4aea40c8b1bca1ed5f28333d9acf62d745d1049d8df37ce7dba2e3caf80294f64e5b47ad24abfc834a424fedff935099c7f04e7f227334e1c542c3a98bca38a235beb4f28e78b49009976cb8490206b3b6218bbcf5eecc9d1f789097e9f31f59c80dda81aba897a9b45d020cb6594d923f3f249ef3cacc0e7351b1d226a5b7472b4820edf4d3cd78244328a6277178e540fcf79bf84ef7858be838c7dcb0b8a448c076a9ee43ffdc0bbc192bbeba6fcffd072e90d9ab3b3cfb1884642a0992ea8a18bf2e78df480ce12022383855326e8e6b68beaca24ddcbd034cd1a34b86e8b19e1e591d83c1b36f48c5cdd3a03a2feaa5bad42dc778a781406eb67f25e4b95d72d2f63930172043ea6d244f70328239945662c015c87d993e579f22360726e905c336169c87ee812fe56b67ec294056e05c5c7a67e5ef28f6d4ac1f8eaa9fa1bea600820873412634559ee2e76efeaea3c7b95d1f06978bfec9d9e8e8fcfa08a907c6bd55089aff031abc853c0a51ef4d1f6f47f58ada4422b8e59daae76eff8aa5cffb4c65b1203cb1a31782b9d1384f6d26bf7bb64e204892f31542d2c689ed236b94b5ecb1d4df81cbe6bd253897fca2b3817bc445c2d8b53fe98eb945692bc996dbbaeffc7c23b6c817563521cd43cfeca8470f2a0bb95d46bc2dbf1768c68ebd09ae33bfa957b2f62fea51feb7fe463ce940fbb6c06288f15107718a0af109d066879581be6a4678a8fb958bff8a40afcf5cd630fc2d4eb7228b31290dc564ace323b68bbdbd9af0fc74440fd75abbc5fd274e64b67ba9ad8b7d434f81394ab233dfb6b8911ee771200f5fc4f74fd5dc85ee055f323537192335396b1d6e2c0c581d3b54ef29856f7d8d51d0fd27d7ccfaf48939c132616d851eb0c407662369003beb51126f05aa1e1483e739585ac67e19cf8ea8373d23aab1ba1484412ea0343a9167c2e917467408ca2c0066135593861e707d00ba1529b9ed3461559da7967abdffb0fdc8e653a5fd9de6375adf82a37032c72b8aa9fc238c3249b24dc6eeee571fec1237f3e1da22411e6d6226ae24a013e52908c9ef642ef3e5b13c64fa11d051c940bc468c65e0f20d6ee51532f103bc80184c025e90ea7d3575bdcf0f5abbfd1514a4ccde286c77697e44b6ce7ef552c517777d1d6fc2d1f8c0fdb8b54a0eabee0dc0130fd311a6a01d09acb7abde019ca5beb2b7cb48cdf6caea8f89abfd9c06a6015982ab57d7bf2aca40edf70fa3d31768a60b8a404b7659c0d526f8f47909598043d20f532384c34fd774e5a3cd2355b7f81885e3faa431f39e7d983a891593d3a84dedeb3d771aa4b9083005979c98e2fb5c67a2cac917a41928dc8683be7a2523742663da37357826f9af9cb78cecb4c8cc443bc438610fa631cfefa9d7026ed19b973a9de872c5dfe19453a54ed96b84894b388bec4219599587173981d4e4f9e884529e2e1c84c90750298c114cf9f789e3eb88b36f1a338ffba30e5a45f6b870470c1d43d35adad54817c160d06e681c5119cf0f5ff525ff92f9205fd4f95e89367823194a5dd5887ec376e394d2c21448fd315c6dc1d536ccc78921ca270edf6463c16e4e1e6fe885666cc0d26f2ac434c0e98936a9905b4fbca5d4b1fba4b243699809c5dca0f66c7b1ac270fa67cce4e386503db15e32be4b27787d7aae060c0d14512c1f9e428ebc9d05d47a5eea91c680f3d64aeb29b7cfa474ae9a98e18113870c9d4b20bb5553ba0029cf96d640e077e86e1861870ea9ed6e9794158b3783c2732561279ff1ce4152c7fa07e3fcc1b97a7df1867a1b74e03bf61547b5931a399262ca7521f2fd91777f8b8f2b4155a78e08b1498839c6507b6d9db658ae8aa463f73b02266a3d47ddaff2e4ecb7872fa4c1877a22aa06c5402957fe3e81b98af31d4e93837e2d03699ffc7df0434a5ebb29eaa9a47ce0e36d09a5560b52914e05dd10040cb7c6e650c00ed2f712373d53b63a447144dd3c820fcd5b1c3e7a42ea8b0f868d677b82534bd5cafbf35e3a216e0d504a058142f033ec640a06ae3f9c541e28c109e5f8fb1c2ce905dcb2ee2384490c0b393c408489d236db1de257fe6d08ee374f0cf8857167544b539ed57f832a29a13656343f8286b4b682b5866043f26dd518aec3ac25e3430bf08199aa695949ea8de2feebf109e85cad432056312103fcbe3eb44a45c033fbb5488db3bdffeb17de082cdc33e40ca7625b284dbb6f2103f2064e7efc9debe8501088272f251b64eacc1c32510c375eb4f6789788b08003d172044cf5b8a5670b32027d26ee028b0211ce7a9f60d0b37d955d331cd6bc7f80f6e9306fab863970ab41d7cdce03345b518b85846aa656f437d45ed126f57f8538527e0f9794cc09749a6da3a065438fac1bdde6e696f2f1506320a16db8523ec18eef37d218fb5091b011abdded91efcba6fef4ef9f6a70dcb2e87a43c7bfc6726f2bebe55e14fb87cd8e6071b61040dd9794f61ac0d7f14cb39e23d671e1db51967166de7e7fc0d1e8fcb1b9ce4c5a948596e56a1dfeacc986ac80ffe6cadcedc9fb975d58e86e1ca29f902950106b9029039be3c06b2ba1fd8b8c6287011cbab73108a2e82b0e2222b4c401f4dfac1aefa0ec925d35c58b0dadf31c0951fac41ba60914d98e0e6a50c6e837d145aa475a4016db3236b555e078154535e2497df09a432842d5b90538a0a81f4c938ba5f6ee736873c6e7b9d18e36199f7692fd2a6a421b797d40b5cdef59e6b55fb0769198778bc6ef2ce68a799d250b5732718682cc117ec604539464f5b5af27358f2ec273a675639424d9efe110a60a28c24a8d79f32e8b067f951059c73bd544556388c0e22dd5648d8c7bd3361d35ee11efd6add925b6fa7e630ef3ab901877e2c090e273aec97a8220e611931c2b4d1f5adf8adb5bb247eb9fe31cd84f7057ae43578e823dae29e77bb8babcb795a68636323bfc1b985ab29ea7af43b7e2600e1332c7b6307640832878d1a0fe59a2c3c98669cfa5d66b24a09e99b5b61112face56da6a3cfa55b415c4795a5c29c89255e8b93062c783e16974ce835d323259d8460e01b084311b0fde633d2194fba0fe58b12db015eb750b7ed6fe5e343aeceb467ceae6404cc97a12dafefe5ea92a49a458b4857b530191b9d83ffcbf6fe34ef67116a0e62a331fa590904fa6de0a3e1e5423bdb64bf0b9a80d6354fba07ca5d6369da47204db9b7e8ffa1a776d8d7dab3986b59df42adaa52f636d865d88534c605ab84105dfb3f31566934658ff2cb307cbb3227f0aef4d9b5a501fbce158aa1421c1de2870651c8f28cb72335725b474f3265439160742ecc0b6367c44173e9cb150a8e8902d7ab3ff8442d0740a950fa5e39093993ec8b85487e4c896b8bde6d3c2c7b46d80c773ca77d2d0c8de24ed540084c14d6c85edeafe91210768d84405e2d559fb6ad2d55c9be4dd63043b8cbec3727fecd3d6498c6bdc09ffa7c18831c8feaed583c8bf4c425ebf51243f91eb50206b91eb00a3b78d2162969f334bb78756c03080bc31381d166e296ab932c87abd98e55a3492d60847e10a589bdb23a7e4376149b221194ae08fd8ae810fa3444013545e431c714d4698793ce3a524f745132624d3089146079a25256d16a9e8c2ebddb96a785fc5a03b81db2d423e1488a2a80125229b245199ec553dba08040ff64ba30865b63b2b888b47a02e313e8bb86b43f50dbcc7ceade1da620b8f99c8713b213a717b71baa16caed4451bd89b0fe6d24c247b67b24a6113180861865bf925e997ec1b051524a9754e6bdc1febf1083181365ecb7c345114cc041b56579b2eb10b47e9a53d511df3294d2bc5c5fa88005cd987bf21fe5973cfe165ce6b1910814dd75bd62e16bc9027286910bc46c58b349afa2861f7e397253fb64b221fd90a78b2ec1fd9eb06a7739f618b4b0ccb206d32188e7730ec57f8ba0bf46b4c6da2d5a3a85fde541bfa5b49b65c3cbacf6c81232dbd93eca4e1b22967bf6e35483905e046ed35490fb53aeb2d02557f4cfae645e09f6a0c8f0bc607189682d85df8bfba0eaa2c63644f7dd8849e1dbce0c72d30b1cf693b2ad9fc0907a45eb491d7e34e41c5564e389ed5dca455e2093d62695d9980a65a358f3963c31930c03dcd386cdc6666a5b160fb588ba666234263c49cce2e12ac3efcdefd4f1b6a36fbc3715f3cc1aad9f55585e3f00eae78461b0658f8271805a017b34331f657379b7b5806625bff2902567e20d6971c6810d8cf9a20eeda6977db674c0683ed763b0e47eb87428ad4b66cf13cd09ce92e32ee1a962f732e2e672f7331ee5d0b774b70d7de39d1b73135c5a21cbf01320cff070b73b837ad7a1938cd004b7823b7cadd76f190a417f9c5dbf044a0960ef7e7fe9f39b4214448ef4aa7f9c71692e3140be61098d4908927015f9bcbe61b06a01d031b11fd9a57f2f42d23668f14cf3a6f8145a63732f33217fd3188199d4e40c6960538f7e39922d8a14b43bf99c224672302b9174dd3017355462ecb46349d9aa445521d093ed4f29fa1608053012cdfb0510202936ed8427cfbda5856ffacbf74537764508d0515cea932f0d03d72e0bf753c781b60bb56efe5688796c2e0afdbe3694e97015c129f22ef6e9bbf63be4d8f6ab0d8d0e666b3c2d86909dae4b0364bafbe4326b1289cd7bab997c492489794dca17b113b7f1a0f57656a8c324d0ca74bbc4e399cb8cc085b5698277dcfdaef9b78bdcc992e5fce94b1228444b5cfbfc5708a1c4ccaa092b95769e0f5369de15ea6098782adee984f91c31f7ef43522e0bf7e5a828940865eeb41ca068769bb579d152e48321c7c90f0a1fe49c5180a476d55c97b3a6bafb2335f946edc5559f5a618f9c890f0d7331836b93c6b0fab951e15ae3b45bf682c5c98d42fdd3bbbd1c356ec6e408026151d029fde76840021a41ce99bd36c9f7515859a2a1316fb3d355e33983463f2746f61c4699650339b386da71aec526afd78329a0a1fce10369673667de46e8ed7174fdbb6255f03f1730f6d75b849f408b90fb7702cef48d172079b61fb832e5492234ed080bc76ddc7e15db4c385d5773f747f8e984733d8204b52585e7dca6e71fe101eeb848afdd952031775b14bea53ff6bb98d0f3f8e42b4fd75e8cb5ccb88e27da5bd70ddb7064a9aa69d7a67ca2ca150c78b65edc3e6c1c02474724f6ffe3f00f5f2867aee959b15071b4781a06708a74a4dd0247674f200e816087ecce041c9cd345eb1cd7da4ce52c10135bf6a9d0a1d322f402709c66641ce46db9164222fc37d2ce1b45cd1dce6587bccf336f3ac3383b8e56f2056404b628e87152e8965b104201bd62ad420476445d8b2e1c0c764b831e4dab8454a089be96a98b7309575d9fae125a6bec13fdd270ec9ea8e1df5f23f4d200ba8e2390b8680498d146ce84be6e96038440894d69f5b35e935f238a85dac1e468c2ad51ebd4bef08239d117aa209176a05e5ef60bc79005d7d8876269fb5c8bf75787fdc631b8624f3d44fd5fb1343cc139d90e6a5dd5cd1e6e25891ea3d26ba0200be12ca9d1699dc94d827e5ab7e1ad99b9ca601622142b03e8a470d122b62a85dcbe00a2942735a56ad7e13e7b2fe8e529b658db2c71e0c08481cba12af81cc91172704b17665de2180f00852aa14346d10e9cb1aa565baaf04b2e1ef163449733c51237d45b71f62273a4f1f0e10323c09ddaffa5f07086e7aeae827fa7da9264ccda7da563c062e0e79cb9a992c866f06da879d2006ae1101c3a75157b5a7d2e64da91ef04e14c41f354529b5029286c31d882c5a486ca61eed5bced96af76c29289db8e488438d09be4bb84bf16ec476e79333d3e1080443d39459051a4a90d972ad0a02f6df0707f6bbee4f8c3b73942f63c551482b10d47901fb5208cdf2693bdbe82474fab79253b05463e408e73b1362d8689f9af8acf1c16f4344925e8e305fe44012de416a7ab65cfc647700b1856a6028e5af4fffd136dafc0678a893418d07ab4ec56ef2d3ebf55c2d1649c5cd7464a8352c5c4f4ae9aaba200240ab1e1e88129b0317433d47f561cd9162745ddb7e77275da9cb0d5097d6fcdffdbece6e550306354e776bbceccd143b6b602abe4001d62987b6945f0976325b92bc48eab486e20979584f78483899254fab176548ca8dc1ab5156b145780fca0628210d7b726486e3eaa0d256513260ba0d393cf060a4b190452999fd8846611dd36acda01390da12b994262ed4a473c25aaaed14b0f1ea1693b0056d221b4478a6a92893043f3c8136537372b3cad994a9a9407d24ae08332858ec09bf3432edc7b7c161c70cc7597f0dc781dffdb6cff1fcafca76038c2e542fb37a2045b86eea6de9695d6b13cf83481f203d474ca1d105f02bcba50a1798ee15adc737d839f20a26ca5b42a9852715fb507c8a7a432dc549c84aedb0cb74d3a18b77691b35216aaea4e5b14fdbdc5f90ec94651f0e3bb2acc54e036cc1e37355984925afd7f20ab82ef8752a2faf56e07a6f893604f692dc51d7a20807c7e634f7efd20a77577ebf943ccfc814617aba5c57f7c64175ddee36b1dabc5844434f92eb985d69b98d6f88ca1922f1adcbda401d2b807be21629c440052f5ff9d0ec15983dd808a8a7d1d013d66e5f95d7ebd6b5b5dc0dcba95590be49531b10e40cf8aad917af5484bae890c2b5e0427391649bc0d1b2ddf4e0a8f091969f1f5f8815d2d8ad9b5764f5de07a9aefe10bd64de9d1cc880cebbad96e72bf62ccda5850107ab79f44b7bdaab7934c32993f0086fe1d087423edc22c00b36fbb806e4055c16f7c8c90ad3ef1d4eeb61c9032f8a95bd0f7b3fed7f84caf10382e2c543fec27e9326f1fd6e8b9954092c22d9c7493b51b170a07a40ca6606d8d961ce814c6913e2f9642048de790bf4317734d23a64cfb9c919090ba3bf3ba0261a51446b9e93d5c76cb87178a4a2c5390be4a1a1c63dc138e8b0f4e811508e66b391cdf8be60a46b7043998f09e13b63effae6f9cd4f907818309c47c08bc6d3727609ee1928d069b4a4aefb95a5b6f78a1b7f4078a74b5fa1dccdb362d2c966201c629d8d20f7483a795ccc5d552346e841ca4ea54a896eb2acf09562995ae91141e633ce1ec98def0af565f941be46204575c43aaef7c3ebaceee2e556b0215d2ac4e0cf693f4872ceee6e0b7d70848d315ac8dc78e5a3a7c0e9d0c086839248cf0606e957f1163f74027d403aaf950ba4df705070dcfd9f1a1bc512160f0771515dde94ec1180714f1bdfa3a664782f987509d2c57e7e4c64e08fceffdb7e4558d798d079cb70e37644a06ca0aa45d455aaa072ae65cdae15d79e6981bdb7e437dcce4a51040b39ec4c723e034879082b62cbe58a8884ef0416cb13199d92d80fbca45f3e5ca690d4dd14cf7c43297e5561628bd041874cb8a022f8d8fad6e0158dc57f720077e4b6e4e60d99e729af24c73c6deeaf0a85efbaa92dafbeb4861cb15be64434db1c9102fe7c283b371e1894544f37ea691d645941e7289dff5ba32dcb6669a90de3d2d5e0965586270df3ea5f536e78842ce76fcfee1684bfbf7c9567c4bfbadcce5937ca110f65ac847d3a41561b4a7161b8e26f5fe6bb777acb7a401bfd41d8149d21fd5dd5e415e93acbfa375d34a836a3b5a1a7b16d58de4481323a84443923866a2deb4bda4976ef999c65f75790a1fd379c1894f35229705b6bd78c8d97a502bd6d42a27fbb0fdc075f725ef7c449dabc4765381f292786656806901ef851b0ddc4f19fa6ccad26d55e4a0a49b9867291ad6d7df6121d3dbf6c7e4905303e1627da2eb05d33e0ab7b37abdfa7674ddd5723af050c176c2e42eb126971b509f4bf72a08dbc27f069d9bb7479d60a4b96a945622773a6536b365bae63385ce539a623f0c0de91294351d68cf237eb708d970489747fd916a4c33045b7c1088372e2da7ad0f4a683727f2c1f8fb36c002e2c90dd6991996de6de5a37959f44fd542e3e258a252ce9674cbfe9bc6f622db3d3080fea5970894faf34e1bde482d6208b164ad93bfaeca8b338e4d1d6559f57a1c4be0b11aae29a2f8810e36c85f5f76e1bf66bce98365587ed4cd1375197519ee2541ea40f96815c5f1ab21fbb884d4bd9aa1dad3b6bd7e1cf6add2b10027cf7ab7d0ac7e81412660458bdf7bd693b21630b6d1b74a8395f494209d0144af2a9986ea3e8411bc699c6c8119734e254186dd6baf041985ba14d485b0e868aa50b7112b1bacc225375608ccb87a587102dab266ba2eceb18dd64ec1eff64a98b6be13e351fd3fe07720ac86a2fecfddbed43de4a3e3b45545464b824a7a9598587f61afec00a944e90f43fdb1e22909af7eb883b75c0debb041409c558aa42dc5241b52261562c3b2106dcf6bf7ccc81fb5726bbf66ad150a1aaa7186321753e80d9a0a7f8c0294b8c1fe5296d6ed6830e763bb0fa0de1be4a776ce85e195b1529c23d0539e4b223f2cfa747657089ca7699e00608030131a7c63c29d35f5848442dcb38c516178841a067695c489bf1b9e77b7ae2e00227ba8aeb06d8aff44bc930802a9d742cbfc9ce87cbc9424d66136939862deb80897dee0ea36949c28f1e9c93b8ca69ce51179d64ba7b0eef248969fb6a60ff7c63751bb794ee71f8aea5ca03910605df91dc1232ba37b76783c1bfd3a5d24787c7727de59e1352257df33507bddf21e0b1a5a5540b9d94596c3ac63c761b7e7a23e99447636ca5c4c7f0d1d0bc8c9e3afea76535b5983aab318a60bde5be86ea21266a7d254b6fa4f250fc172a8e87ab5b298011a476f3575650ba980b5db8cc2c569b97100de87c2669f2e8b706ce349e13887d351dbe560e24a82b33fd8eaf8a37b18de8beeeb716130b58decdfe2c7a4cf2f9bdec14253392762c3d2929adea2c97b8a607caf63d54f9b639e219a5ab2095de3860375e9415107f1478256360606ba5dfcb9c9089d05c0b6564480899b5ca995db1b0f5795259507833a053f56d02ffc90a1489638eada77c10f6ca7cceb3223ee50e11f8101786c592866600b01c9992ba9d68e5b6fba051a2a4381208908d813d187e574123662b3dbc9bb6712b227aa05c4a9d1c2104f9e30a399815696172c0df8b4ed28330182b420441ed78396902e6e4de8e3cd51c7168c0b85c60f880d2b1524549eaa622f33c3d0535cf7e59c7f88d1f1230fbaa324b6fb3ce1e441cc693b57fb47c9ce58ac89bee115736db2d2855a77bd2ad1bcf732e85366b9865a120ffeba1effb4be5c2a74c1f3766c8b0f6169a1ffbcdfe880c8ddf2905210f2c7a096139be7e6575134b982dcf8d10d1e13e9efc8efe4b37008a1873b48a173be19f9a1736e93982ba72979dd5320b1a811baf2320dcb06d7b6a171084f7ceb96fcc1aaa52ef83d165d68deb09f2797095e8a673782b8abd1abd4ccbaddf81736084589d604130863219ee42b56e007630c3ffd505a4226e7a7fd11129b4fbe87bacf8a76294513e6f428be8a4c6a9973dd1caa503255c345731e372cdaa4b041a69119b0beee1cbbd1fd3dc60641cb02ecf7e913312955c5f65a2b15c95f4cdeb856d7ba20aa77daf40963f8f55dcc0dc45eb83b7a3e40cb3b4d50a401e79d5265312dfdd3ecb626316d36a0881aafdda5b50fd12dd906d2c527c2a45f92f1b8162099028743339ec1c96a7384fb7ded56921c33853ed561aa1ae27b9293d93c0e7d5c7021ce00ddaa85c398bd56e2d59de15e336e0070aa4a142dee4234303e69f56fb2a2709e541a9a8e997ee0ec467a49827a45aa6a38962691c1a4b5684067f30e896a7e739b10b20d8438b85f508d4bad0550c0b65cacf1a4fa702104fdf6fac3503e1f84911bcc641a97205aa6ff51136e1fb33b314fc45dc19a582dd7f1f70f634636923c11c5b06fa7e1579cf8d434bd61ef92696cfa6b3503b31335a5835a04083cddba3f3c3000a8b502c2ac4bf85feda89c8f1c70feabdd10595951e8d572d67e84899349d24a6572bc12dfa9288a9e5fc20df8db2929eebf9b6dae3469bb07fc8868e166c0edc032f6a2bd3dbac2c3c0b5952425a7fa5b0dc41c0bfbebf8e712830bf6b853c2128e81577a274dcee17428f78e06f6047c90a60351cb2c631ed93db4f41cb301151f0a096998614adc2869f78198c260398dd8aa5cd43ffb5fd779c32fad61f3dee13d96f2480d6ee57174d3a512cd8bcd00cedb409de011fd3152954521f28c3a1388e567f2b4869de4cb7ab1b1a3b486935217cab63fe4606fb2098ab9c56b9360936b51d015dfea98c1c34758e042ca13e2271dd23f20b04f033c28d9d4da5e46224b603d5d98a37e6f0c09c51f86b06f34d80ca1080c8fea8b1d3a9565705323f006323016b9a9ec79875f2a22c668b4fdbebd504c372fbb371abf5c03966be9b57467faf745f0aeb6fc5b94bd2a1250dd100c033af760f74944403be352edee75a5426fc3689d65d781a5b9e87fcdaaaf0ed96d1616da3ead82b6527b2fd36818fa940d8b5dbca66ec734c19cb390af1bea4283b51a9e0a52b018306c5e4482671e10280876692984dd4e5ce8353208690503f3206e791cdce36573843139c36d2c18b542d5d6b43011b3f9baadca07fe418fd4d6a9f4e95f6e21a74dad3d32e262ce4d16bb324b8f4ae09b1525c1971e6e6c523d1c59ea1d8c139076e035bda4984e093e914c630412a14111ea4bb9685714b60e27f3e9ce7ea3066aeabc3e6de0a29e72bafed467ce5875c427a73bb52d410640de4ef30b5198ef951828bd3fc5254b6ce696d7827004bc1ea5c53148e7b45088a8e2f5b7fc663af339913e1c075eaad813a034c4e001e2e74e74c449df4d6434f96e97688390d80fb9027526e11efe16f2d3398aa4bf8d2fce45e92a4abe777fa78e8ee0e2ad0b482cc9ec240ffa6530787187cea106bf473dde6fbb9ac6acac8b35723016dbe104aaa82fff8b11931ef47aa3f131cf84feee04fb6135ca3622e8684a36e0a3bd936e9b467259b0e71fd858ee6ba4b5a608bc8b2c525ec66658b8c0321d429dd08e2c69a01f3817cad5f41e65d57d4b0ca7a6d4bd53a58e0c35b54c1af238672164244942e3543f8683b104dc8353444475b2a830c88af1f2c4e37f4a068727dc6f6d48c071fb84881a82ee0815400558bf0ea31852c56bd543d45b0ccde01e41744ac35427a464e5b60fe244089a92ab3c8ab5684a4d875cb9c95a19e3664a7d534d7d8bfdfbae2e749c76ac67bcb86cd73724541326a975fb1d124138c3de2c8a44837af546e82de8b8f1628a7a11c83da8d8589f6ee3425c624a43012cf7ae85bf1040fe5c9e76e7939c1369a78ca484647350986cd276f9ed177352f1579dee41d17bcd55fefe12858338861131fdddd2ba95230a054b515d061d1676bc98834e2f6fe83a3516573e9661ed0438b605057eed3d3868e354273299f67c261d03da401ef4b649f781e47dfa100b7827d9744ddcaf91564c3fbc2bff6ce679a047344f3c31f52d1d21ebf29f735be516d86781008d01bdb10a261b2294cac33de3e38d09edc2d8300e35db47e9ba4d9716b355503ad5025a91e9bbe8bff8198a1f8b9ab5bdc1bb4465e27e356c27a575017c0f05c037bf87b9667a4c65a94a6312ea98c1e6be31d96aa03460278d2bbc51ff4227c2ff6a57c39cef0172fe3fff29284abfb29aa967b8127f6ccd928529a8104677c6f039981062fedfc08812f67ac9907fe03204e99e80e615c3e9515957a76f9d0b690b7597226d080c36f04413125e4bc70d6c4719de638aa7cbbcdbeeaf2937e019300c700fb3682dfb10098adf0a35c1c54c1ca9b79fef8902f6197e544954fc4b97ab50c95657c7445ce09109306b910a07c53137edc145783f415fe562288fbd7fff4d3bb3108f57d3b14e5c8e3f7bbed8bac168150f172a7e7492eac0429608af1b771ec8124822bb0140a392aa35baf2f67fa77f47a517bee1fd610c8d6784fe030cecf433e492c342fcc08575e456c4be4d6aaac4a9731c16f1f7fdb9c519763fb2cb3c181b263aaf8027148869821ffc791cb3f23c33b3495ca5e6ae736241741513ac698f2c03719d8d868569588de7447a7d7eafe5c53dd9a47fa599dd39541ca88898a824ce23baf2b4572d3a4e159ca8ba941d84b23b020528cfa9135de14bd3c52f7a13669cc894d7804d1ff752fea3c82e38b5a6becb2ac909bd6d83162b3f88dc6b65de3eaa4f5b15d6fb67456f5e2d8d887084ca67696d7d56bd126d4fa0855e8d164301892222bf1c84bc86f27aab251d5530079c35ab708fa6f0787c694172224556ee5daa926d5e67698f1d56c8bdb6fec51484ea3f83e204e2feb2015a97e29b580cd824fb28fb9c75c1bdd653b4b6165f34f616ea79eaef1405da630e47b59b22b0fc092fcb2637ef6dff04e5e868c1f486bdca5bc65fbb2963074775065b2e900b8de3778268bb5040552fa5fb1638a81ed07cbb2176f607d4c00bae0b0e369473fb148c263e87dd9de31d46a444b9bf7a76f8d0d6d08104e2802fad614eb1f946d9deae9a497b7896e4e65ac3c59a1e34aa99b99c4f0d16bdf8506a448d22ec45e6e6cf7ccabd4a7eec4761696fa37d4b0fb9aaa182ae64a7ec00e15e02fe241de87b24224f2d3b618d98af8325582086cd2ced628f73c6f99292f8cd0ffb31dcc97c71b32931031473cfcb951f39606d273e7749318d4abd23731777e9e3c8e2ea7177f9d9d6b5c0f0c862b8015aee03d15a767ed3150607865c4f49d45bc59a0410d6819d8d02cebd0dceeb46a93feaf6f402d2e4335014066f5d43ce44d4516a2499b4e3fb20f2e3a0fd41bd81d4df144ca356c2860e3ecd39e920a8883cf643688dfef2f95d69a5eda2df741a5d05c860ea8364c9551f3567a6f3f750cb2a11d700bebfc8fb0b299ee95589753fc042558e795bf6b8019aa9d6283a2a89661530740f3e02ef6233648c202d1bef2015ab9a15699f3f51e4818dbec33682545cc90a9a5cb32a16f167aa55f5756c293cb9ed86b710ab70ce95e92d0d9c051aee5095f41dd08e17cb9fdfb4481d8197eb92a2964f9e5aaec84b95c27f73adc96e08415ba4254df54864aaf6a04f016267d5eebd0af6bfbfa7b79fe9af710a394a0060f49dc04cc7d55691e11613bee6b626263acc0a9855a0cc483a32998777c7fc5dac1cc738edbf2d3beddf3397265431b5dac6e48ad7d5f5e2b7c099d81bb61d3848d11a2986a74e8120c3bf2831b2a3182aa0f2a9ea18149fb9d2761da8e393c6573b42ce6fb14a70a6f997486e258cd233d34f417b91a0c473e1388d926b8f6bd8e5e5f113b9e2762fab555a86caded26e305867fe1ecb2a453290857e123d0b12f4324e4d7ea9798973b33d3a79b43f7887ab7ccca2967f47e584c2b500b1b44d50025fd2fb7964b7dde8fd69b899a82fe5bd04a6e574a3a22020cc1cd17c7acf25f06c31fd7730a2725af0d62547a14816d4fa6d4ac60ae0abc9d5e1326f2e57d8e0bd644c0c84a04137173e314e03d137a2c8adb72ca5b153b044387e39099bd9a6341f1dcb9965bde89a6e276cabfb4f05661d51e5f8987969487b3c0dd10f71e8b51b025af2598ebc9e4b8e956adfd07a168403b27c02311d6735b55c0709381bbe8d151558e5a80e926490686df640b7797576d044defb0ad72980721bb7cc78b990febc3eb9ecefa8ac9abaa40c30a845304393b72ec69195a1f87ef9bfecfe0102e158e533a395feea2ed071fb76d61ad6d2e718a1b4801cb226c68fb357cbc5f1b94200e5983d03623fea2ce3c0f5ab79134b32ce160e4bbf107ded9269dc11305289ff449e4409677a87c669db3c9a472cf6fc419a889b83a94bc4136894c253910a242a1fea2e902abccbdf0c643732c15c0ff482cc5290e0360a995d440761a574d3b17a49df5457dea387401b1a165a8410272b47cfb206f958c6421ce095d832b8721eeee973b77e2a7463fa959d65b67f669424f5a4b3aa9531a79ee69d84417de4c6a79a3b09f6888e1edbfc4317e0e9da8122088add16a2fd0e81f71a570fae2a35ebaa885fdf49a4e8cf3e608c8e8fa5ede32951bf6e7ddcf18430bc5803e91e2017db4390f85b14af2f349b2f6ec53e7ac4a88e03801eb1369f0b5e2e4445af70c9796c2408da0b3c5fa99fb7288c00ca66ab1e279e9602327b7b98fa9d95237e3b67c720cadba3dbf67c4a87f49fdee062347b062989ce61da9255d1cd2fee90cf634f8ac5afc01bb09ba22b000281364e09b3ad883f744c375513d4759c089ec09b355a9372e25e507a108b8499b3dbae1f8b66c855df98e8d0f1663fd6f41760f466bc516f03a9ca9521c3502fe2dae3ab60e435ecac0ea48414a60bf094605de581650221eb1e6cc1a6db5e240c358b5a075d0631d2473cf0508288c10743bb1eb4e5ce65d298a2fbe4f54d032a61205f414b856136b366c05bfc1a039bb4d60db7938f58c9c4b50f8a89e2b6bd3676b70bbe7b0f455f28ec0e7ea8541253e3473a7e2c5a94b6e8ec6ae848792a3a65b0a9ff8a4ac37e98617115f48c9319872d45ea50d4ad4e90018b351d395b2cfae2deb7cad51dcba29ddb1b9aa4e670bb902b39736e742230a64ae124024e49d96533af95f9029a0107b90295395f1f1cf174abb1f7c275f76fff4935274ee2953b6fe975a5a0c97df79beffed0cde4784dfe46c56f0258cc9abcc21abcc626879b0e0eff5e513a7a5373dc35f4ee25a7037b4a7a0d532f11e7b77be7faeab85c7919d49bc13530b980e44b9751d8c142862acd8678f999ecd67988415ad936f19ebad8e1559dcd752e37ab4dd3eccbb4ec82695168f13a44d1bfc8ac274f457086484ab132b4b72d958fbca3b10bf1fd5dd866ed09cbae2976f0dbdce5ccda7ca8dc939363222f08e90c68225d9cadf3949179b939f71a652f33a45dac57497ee957635db5e51e94d0e2b6682cda2d468deb61d8fe12ded4a1678a6eb6ad3be96af0a52c5867df4ee4371006ff7797490d323ed120cc3bc171d79caa4e570787b5106b03679c51103b8d899024ef6a04d3f12e0ece4b58fd302ffb1ee8719252cc4d2212b3d3c36968335b1f20871c2dd21884239cba23d31e224f1abd091685eafbb497b0edb1526eb504dff1153bba9d778a357d92a15a9e8c1de37ef1db2d169d0dd93f0b94ad51405c29b2b72a70d9a81cf3a446a06d89c82c707228c87d1525ce6aa315071651a6dfddb0e98f2d154b25ee07191ce5eae5edd7b1bf4494b819bc199bba00c2d10c26f7ffdba6f4302c0b5537b8e451f29b589a621836b521843c2eac66188d6f1893a3345f72a92faed723f7e74e4308d142d3440c5f1c3419062cbeeefb8f7966ea59a2259435d4a97a066b5c4477499bb54ad9a76f72929404988e68d68f1ccc7faf4ac6939ee7768eb0bc94664d8a22e4a506ff31ed0939cf40932358f11ec92cf9d4485e29691893bb4f2f7a5f6984772971c76321ea248f764792a2326d21c3629eb60ad78ec0d6e2d773259ecbb64d0d4d3e6849f9090b4b53821125324bc5625e4dc71238dacc1cc71b9aa737b10f0cd96a923c68f91eb50207b91eb072622e1bd0db36ed7ce846ed3f13b3de16a7dfe83d781f196d402dfc6ca112d4f4fe9ef468c7078eecfe320edcb1bfe9c584caf10465c0b400d14b5e83b4222c1c32dd6101a340fcd3ac94168af2dfb34d2294a4de8ac578d6947ecbf001d497674c176a441a0ccec7702d68e1e4eec0efdac9e00d1efc4eca865dd3745954d4b76e63505aa4cf5396f39cbd03dcab0819b8d6f1ecc5802bafe177b9b64d98fee76574949779cf79f00776ec579a1c308d065bdcca39f4306eca33a40d53bdc3b36957b6cbfebaa0842fc362b63c3e91170221e4adeae4e39508226b176c899a088a57e6607797f8d9a8191d68a8789b87bec3314263c835406ec73c0817830136b1282dcf7308cef3dd50843451ddd96f624623e61109f2d1711e7061cc73efbb3d9af19d358626476d03f26de366d851b36d07f41f754bc5d67245a29adf5659f91574e309d7242280a7429089e8dadfda9f2f116fe9d145e85bfbedcab8bbb0f5b9f7bfcb0f6c873de51623c6bb378bc93778809e66593e60df7eda453a4af0a8a66d06ac1bf5bfeab229cb6df9e5331f52a9c6d49ddd90b94c69a61f007fdd358ef6dac22cb05c615ea69644a1a73067aeb147c8ff0420f1e5693cd8c04d750466f95043c7193a62af563fc18339f2a0b7b24369136885d961b10c1a7fe9f542613e711815b0ca3395e8fec74f91547dcfe3d84f4802251dff074dd351ef7c558892dffb9cc18b5f89a015fd438067529f00ad68c470f538047faae93c7745d4b6747312330b80f5171a93a70957b85a5c5a13e2c3757b0f01691a32736a68300ec7800dd28cadd532365e7084cba12a995758d71d69d3c0694efe3e8df6478198edaa9a427ed8db592f7f4a6e9475d7e199196c64c2ebbf0c822d77cba8aecf406ca3521a212401152cb07168c86595bc5c6582c57e4685060d88e72807816df7990462d1c08b4728e2d1238984ee97433a18f8f1a6c78ec4daa826604c8d8dc7264ace14a2f1bcd639468365b29fbdd11d498c5d417688b32d8e0bbd7ac89ec936b405c05d081826d8c58b73a9c1cc3708a37108ac442e677f9404a3b3bca1a1a5853ccf8b1b9710c1a94495fa5e37e023b33e7bbaa737abd66eacf20c19db1177df50307c7c92496f521f798317d97387dfb56dff331def4609e5c141eb2df78aef9339193aa1a03ba1769194f71939fd59486e0c8ef48507464f545f97e01fde6d20b143adbb29b2b6d1cb9c2fcfb49473f8ff956016a1135db4c49309329a682eb47e49add089ac4891c081ed63ca13f0ed7986dd9bd9ebd4ce24697f8e15a6145ad48296b3644e57fac88bcacf9b1156fd62829c04e15aac2aa606b0f08b12236eb6c8607265d21930fd2c3b7ceb8d0e979b6829648280acfeb9be62279ab26d516a2e4f9b4a602dd95f1b6ac4df4151136b826e6fb40d7210dbc666cc1a99ae2a01884416bdcbaeea5d50a61a47129f36d9aab4ecfba6d21df57e92f32d54d8cbbb9104f4040590f94f67d551d6cd91cb65897fb7c976fa9aec670d6155e7769f5a3c835855219b72011abbd0dbb53c7e5a1adf8c52597037813f119ae8a3070a6d672952e0a6aabba27ab0a5de66b87a5b187a7aab80c5563bc740e9e05cc7a7b7e49fdc02d62a4f73b6521250fa90fa94943988ab2929466cbc2e0c3104287ab2c98ec01ac23c048c78947b08c35bc0d7bd37daa41e84e8df1a3633e603184e58d86bec04dcc6cda38ab9a914068dd0309c4022c339f1460cb1c4ea1f6c6c8b1f6ac8ffaf6c4bd428484283f2443234fc9484f5f2ba87259b2e1f1ae433ada47ce210bd1baef068cdca010ec06913787ec8a31c3dfb8c4958bf3083eda33bed17a5772f731db22218250d30dc4b72b4684685bcab0c711a79a9a10fac90095c631627babbd1a785c5a39a01909c039df632b40ebac2afb75a30fc635fdc51e1e35143e1be40faa4fc521ce8262763bf2db8c75a720785a9f278e02615276b23fbbf86845e534a9715cb9360eb2406206cbe35687e2f9ffb3e7bb31e5090096a3a6c3ef099d3aa914a3287e0272ab448d36e78e9031a331651876e65be3b1993ed9c30a2cec271c9e037966c784b01303aad5fed705f82757b42b0a523f16f63cfdbffedc195f6e71a2bb77ce8a50e1d01874bf6d7195c3314c8fbc2ddaef4b000764eb7eea65762ccd2f1590b996a6d5dd4196710f32ba361567369fa348377ecca8782b0f2215819f3ac1e31c2683c6132172e988494efdf79d62206ea2c8aec5254fa65f69bd68312547f67d747c7d5f869efe7dd757e2e5741dd7dee9a7677e1aeb6211cc1ca303368bbbe9663466eb25e331e3b216b139c912e816b157189122a05651bd34cabecee9b0c931c9beb2ebfdb12572bf9ce30019f343d1e584f1bbd0d2aa5f6e5c2e02793224895865b453e5c8dbe8a3666acbe534b4f1ddf766bd180bc4e976b1b686a3a4cdcc758f6e8bfb7bd2e7867d3f110a041c937e18fbcfebb21c152ff6f4ecce75b6ffbf6b4fb92c7a3fb18628a766e6da1d69208d90b37b23622ab9f47130d75776f89841ab554487068e3201c3029df3ab9ba66f3cd8558adbff0c24c73be3307bd288cc0e067d2bcd6ed141aa1fd8fbc44320d2df2402d987c6c5a29f52b0c3f215c8ee3eee5637bbdf26cfd555d916bf260982607191cff6dce34f671380b0119e9310c016277b26a3ca85c7fcddf74e794f8e43271196bd52278c9a0c0d52645ee498852b60abf4ef480aa3a811e157bf6323651a8d5d3fe7a5c33fb17cd88d02f3db1487fdc055dd18e06d0cd4444008b137c17938c78d2738df61deb1796d32aae490548cf6f85bdf0c18237368e4a1f6db8ddde0839eaa21268ce93857ae8f94b2b7cd68786a0170f003827c5fe3b25a8a0341c80ad2371eea13d1c76260620c05e493fb49e3a7dd015dfdd90e7f96904d68a2431cd837c298b61cec975728081ad9cb17bb0990aa5de34c2886eb1c2b8878c7228ca9fcb904696f688bd709d339ba41517f6f4f8259c61dc3b115bdf1c663a2cb448bc910349c62cd7b800779431dd40a86fe758766907799cf3bd26a8938200b640614d0d6364be4058e107f921afbf822b5678c95af8e519c6ccbe3899ba550749e8dd8df69e47e152c4d2363ac44f58e9b418983952650b999e0cf1cbc9e27ee252d6be21730ddd77cafd6e5396dc876ee22e150cf0569af3bbe2e16f3871240975540eff213fd802070ce5fa94862d809c5aa877160773058cfcae728a64a2147c76ef6b57fa4c3a1c07ec48bc098cf654a8d19caf058ad8696c19aa731b0240dd41db93c40e9056377ddbf7f59e2dfbd5963a42e5f39c898eb17f22b40f894fd0244635ef1e2320a10a76a2ee8940045f9114b95a068da73ac474d77b5f82ebef4df5b3512eaaf7f568584ba9930f7f9fac48b7e45d4c8d9721c24cbabfab067f44912985f3a7aead48e39a22454371a8dd7acdc82c07609f4a589995f9ae96dd9d72c4b9d220a1d4f7b802b7b527b0c94b8ead2e7dce8a6bf1aec605459b0a4a4eb5fed16c983279428fa999fd94ab18119a773bf6d40c11645a489a9828fb8eb47c574a1377e9b2cc650090c77a5c81fd7e0b9c1d0c7fb39f4dc68dcaaa4a0330e152bdee96c8e871e6590efa9c5a9da2c0e56384b625ce1837b527ecb069423e25455ca2f732f9019ab8a3c0db8dc586d44874c0a9cea7044f47ea4bcee62059515ccc6fc2ffb3854db57120f84b7db09b571004d327f3aa962c16cbee370f2463505a789977823db1a91600708432ec0d380ecd5cb105a3147815ebdb03dfc7dabb7702eae8ce86d9c1140d31b8d1810d71d82c4cbbea7b43c7c12ff52c6925c0d07f0d51bba959287cd9e530b880bcff7336039ff5a5ac1abbec2ff7264d6dd46c3eb8952d4c3c7640294cd8383bff3999897116427e24582d3b766c32b10ba9ca4740c5da84dfe03ece604b805da385dc04efe7db369f112d5b818477f8a20778a78f6c4cd1f98bca120966dfcd25eb69cbff9d6c57eb55653135314e6b48baaaf14f45c3679af4b5ee10a7bb2aafa41773052de6d1f57c372618afe9eaaced16a42e4d75c1c33514d44d09c08a54d2167cab16b6916788b825788f646dbf8a3ce598e46b87e03729313d185d183fe6ba634ee511d3f63e2f86903f9c210ea4b445ea48e74773bd8a671dbca47b2b5699298223fed760ba244d8c2435b63536bad07b9d206a82e554bb265078a21055df1ac7dcbb7ee7424cce522d22faf3989cde4e45d6ab509482dd278b2ee209275dc90b3897a4bb4e4fa7c1f11a29ba876f15ddd29166397d23eb3c0364fc575bfc045a2a9289f746d6ee29bb63d337675e8ec17daee75a626456df15be3e7b86a05cfb8ce1e242f31a1470ed63fe13c4c1e8e2ed12d6d8a84f46cf144ccd2d6918d6fb9da0f094449122ed8754c02594756e93b005a4af8f3bf167c50167c9010c67c70e21e1b13aa59435ec96df31037a0f34b09820099ce4fffbc73f544db3937e337ff47977f6c0681af0967d3449208cfb82c0b4054f50b7868865599a08366672aee59567e23a1c838a8485ac6a04ba992805cdca410584591e3086fc2446f1c26ec0a2ddce619a0c195ae80599674ff253991af3666563c36fdb56496173360471e8657b284a11aac167d982a389167faf1215058da6d88bbe39e76b98df7a377f66a4948f81dd933761a904077f15911ddb928d959dd7b49f5f6b7fdbb9250f2ce80499ddb7500cfc3e09270306cd549d9562c269fece12809c67b01972cd62797ae0dfc79d74db533db7b53a2b9c98336338cf41626622f7e94141225414c40ba5c0f283ea381744e56dadfeff6ba39a34f80ba125bc114b5da25111e9970229eca3504f3f616129835a05a6b4c994fd52e6741b2c69c717803795f0e4d429e7a52759c9fd7b58a62958de5f724be086f0c18d0634b54431659c587d4a9fe7c997d19991875ce0a8e9a0ebce59dc408065cc154400b92ed7a39d2a7cf9710c84c747a1e6343525ba41ef65394660dc88506696c4813d99e9d47dc8a6369018e621f65fcceca944f21b5fd458ca582b78516d263ea69b6ebddeee6d71d6db158f64660ad211141eeba52333e7a759664858e14661417806c9dd0930bf0b1828096600f5ff69e16a7c5f5aff07661379b1c32d48d9c77d886f03fa2a7a26bde4db2a2c39eaf296edf059c0258b75b1b67453369b6c5ae5527b34e9e77fb15f48358927b316511cced3d0018edbd364ac992248f98320b8ec10da9a183b4b345bc02e5f46752a686bf4d7dd7d562e24002c80e57ce8fd4a4a845194440752ae07d9b7e051eed83967fea8fe971ca75ac760b712f506afd8a4cfbb83e35ab746ab76d3c1790d163e92a2b228fcb4f0aa415534331aae76fbfbf3b3b7169c2bc8f2fa415816e527f9d8b14bf912867d2ab1847deb8f1653f3da954c121df7a060b3273e55834e355bc8a319ea8119d75d453654fbbcff6f22b4ab407af8953e71013bc29b88da9ad0f6ff2801d87a053aedc7e44f0cdbb63ad8369c596fb4cd598791a7cc89952db99ebe09dca04b5f6886f101a62faf0d3ad99fcae44cbfdaedaa1177569da7ddb5557f458dfff3db288ca5257c795b83fa901cd87c65a4df2818f7197858be699a6513e370727e198b5d7473792e4bcf30195815b43f3b927ca131d31042f2fe312801234ef909e8f9729eee8d3901744d63ba7e4134502efac5f37c77a18cfe46acfefefad6ff159eccb10a2408b7c67672105b56e18612b37fb944b629354b33103e536b2e4dfc84c5b5e32d094c81983a09784b0a89afa1b50509e1a22904f77697c92c36eef12bb520943de4ef3c6d76cc62938388765dfb401b639e8b4628502afd9d228ef39d0c8279cfde7103381e766b2be62527beab7ed6eb0ae11f30ad77ebb1b436c0f1540739cbff255263165330eb33a9016fd5a74acd8291914ad7952d4b5141995c20b9efd377db36d47d92b0ff0396dff34524f9350897b0a716584549ffbea0e83fd5df0e0b8e7318f6c38cfab40613a42694fee4d4c0d03c0ddf89b3f04f4518daa505a723b73333bc601281beb4e7dd907cfda98f86d0ac77da44380cfe924aeb79a002be3c5e0383d581980503e5a1a49ed42929bca188b95177c1f4c080a62dc7719ecb9fec3f7047507f9527c27c1b060803d493d38c2b7a89a09481bccdaddf19b0afa9677a24663b34c7869bd768114814255f9a7d8631a7e05a34b26fb2b131532950829685a2d72e4b73a00770efec35c299d23cb491a4284bafa228c10785cf820130dbc3f2d90f86cc6d965d2ba2872733aa37ed505636e16ee1c2e3ee4c8973da3ae1d6ad91611769fe675ebb193366f14e5be6a8a332b40af36665316a546f65d470a50b0228785e4a31a5d2ea42d350b5f559674852537387090946ea0c34b1544883027f9bb1c56da5faae325f1e570b1edfeded98c6071fac36bcd371f991fccee481046adeb7161926a49fddb22aa1eecadc55ca5a36cc65dd1f3f0139d497a8aa869bd4f513e439939113c564c6a732b7620aab95a3dcb50c084450ced624b0adc06bba3a22aa2701f680bec0aa79f0cf2a6b7d9af0308675a0f6bfa4f3ae592832374d037446a52406ae159355786314617a7a6fa47ab6447427977bf537358028c4d0f61f94b98299925decd9b7b6b3a3590ac08a2add3ea42966aab5ad0f56edb3173bf826ab3bbb0a77e90e2ac1871ce12125d1cb99fa2e7d4182648be279610c7dbbc093350abb7952fec5496e798fce5eea112f75b1d57d176143fab8f34491197bed9f794e5570aec350d77a23499a433584ff8faf28510f191c2286ffe86dafd721306c44db9940438fe51d2a4851fd741ad79c6e1daecf453fd0466a9c1c02370f01bd70effda8a1cd53c59256d0b31dcf1aea64a228b9492a5e51eec91b3c90918b0c8e9ba10a954757b7a59bfacfd2db8105432dae952cf4e75ce04a3b5be179c34a10478c19f4b7803ab8e341575e0a7c1a6b5e448de85709156f00348f4b27780780b832729aaf1a179f6b006fa51262a2fbb0a4ba60ddbf6ea1d05554e2f62bf4ba787173890314af6295e7ecca1c7bc219c7704a1033a751e6404b939de8e2e0787678421ab4dc52cf8363730ae05e193d3383f907d220f69d70458dfcd20cf7609660266a349ae8341f37abc89ba2bbe055cfe1fded02c02be695eb9468d6ec725cf637c04d9c035a65a08354c4e6525bffcccc3b18482ec352a84f9b64ddb7e3a85d3fc71cb1fded1869fa2a2b49fb16417caea79461fed5aa7d28a3b93ce0c5aaf27a915e9a950ecb04e1526024d60f4e2e3f42232fa01a92cc0c06c4c8952738ad7e56b5f1c2f234edba6cf26b7eb4e3189925e56bb29b8ff9aa4adbe39993ae44ad8c40ffdba0261ccb6044f7aad964ce310388d7c2b9c7b1f82b7007e25716db68abf7ea791ddf0cffd23dd5012e99e93748020725180fd9ef0e82036602f2524eae4d0196dc5de7d0d833730d5d954d1fcff04c6ef1dd3ac84229a253c9e71dbd2d76f3bfcb6eef0ba4023dddd7c80042c7b8d307fb8604070abf82813c0f5a4e518abe833d4a797d05f596c20cf19fd2424962cb2d14fb718bdaa6911f9ba34ca4fe2eef29dcf52fc7821e3bdb121570d06ebfb428792a66e7f0c7eec4a264b2e09a1454723499d6423d26a0a34140932fc5c29644e5660c3cac1fdb0df1fb75da4070efd3356242aae5f15ed2e320fc26a4fb352a6cb44a351df05a72c240e483fcf1d4dd0d4b7f7f1ee3eef3ea292910f6bdef92c03a88174ef4f16cd8811d7a8ade2d8a7976dc51b5dc76bde24dae5611ad8c27034ed1f4d65ce0e541de0ad912faaf6371c62e74a566c235fe22c3626c04b559bf6ac9444527bbf11e68867e2078e0b3aa0dbc6136871ca66ec2bad8cecba6a62c0e69226f65ffac034bb03e6e69da218f7b4afee8e24dd748f434efd1035def3023bcdf595539c40a12c8200e1fce78fe027b1a3b58f676edd07caa9981e025727bc6220dd00df9ff54b1c1ff4872498142454eef37721bd3a95cd1976eb46895b33cc58d684165f4276dcf754a986d5330654db6701943205116adfc014bb7c6e6ca0c301e7b1b016c2354c4239b5c8307f819113ec590ab38913251df3151ecf0ef4e16dce2b310f33e4b90b67650edc55a19ded2bee93963fa30e900b805ac958dfb49d089203c03a01243435ccd7af30be8188eaaa746106fd21035bff56e480bf47de28a36aba44c6a047427ee8f69a4f33ba7cd4bf103ccf53c7dc598edb51621ac592bf4158b9b95325ab798fea2c3145a074ba36a590ce4e9e18c1be5f060692d265e765f6cdd5b27bdd2ce3fa0f542888b0beee23d09eb67d15ba4e7f5e07b0fbf8ce09ef6159e71bb9610962bcbd1ae9fc9bd5ee0425dd03f1160f5c91c45e2718f86cf454e708d9661bc850a4aa7da8b052a5dcc8976f2a77a68d4d47d41f7ebda20b1fd71844fc4ce8ba58f17beb3b9e44db2cb2655cb66fecbf99c7e300e00bf07794124cafe20fb4cdc37674c9949cd6be4fd0c053d12cb49291c46e92f3a0d883f52aad6071fe9b99ae059063c735122db8dcbb227c308dbf229973b10b73ded608ea63bc47517eafca87791f9f38ed877cd4a96f7c68aaf44ae8ed5a7ee81d71dbc0ca4c0d8a6b1eb48e2d0c54875954f21cd5fb4bce84388b4a221c7cfbca60c2f4a504f225354963f69c55c6f91dedc4411bf1913f03ad5fbb42ae6c8e38652337b4da654503798edc41eeb50fe4fe3e3270e3e2bb5c77b1012effa6343360f9e6856745020efc30996d817b836fef8e1ecd0c1c4f802e274953f7e2b5536c4f0e69514b3a86e41722e238177c809a5b688d0e9e6c93fc95b44bfb4abb098db21ec651c6248d82091549cb665fceed1feed18a3da300d9eceb2c5b8d2a6e01c3ca1475cdfc3237aae2462f84abc23218849c68460bbc482ba73765ef2a33148f0a2236c978ec7a17991e8eb7eba4671959d6b29f1e23bf40f94718309c86c7f4891cb5aed895e36d4873d864410d3caaad4e6624ceadafa10b3652a5c70f4212abf84e260e379a5ef053f0f2a6a54fa4fe6a356731e359a5dc9dfd292340c27a0284cdd354e0c059df28a7bcb664e41dc7419969861fec6dcbaac14603829b7927dbf4d26bdbb07ddaf840dcd0227f44ec907fe775beb7f0150a950cd1579c3002f69bbdcdf3bffb657d60adfdb57c00bd6eac52490a07368cd71909dd97e586a6698441efbd7db14ac51713421d66ad5b4c880b1b0329f35cb9c33fe952a3cfd2f1c2aed607b144271e0f9f7267c49d78d67f0257715f4c713551bfa5aa29e9628a7062eae4fa0954776a70a317a8c53feef2c1facae3aa7e3ce57eca9fa77ab37f595301ee215dfdbccdee9bdd2ef3e6d02ac5a9b0f4f2bc79cac7a1af91fce245fbf46a1fbff33f809bf617e65bfdf9ac6ca7ec4c566312a104d8e436122d7cbe98097e085d06383bc15c15f44b4740f659c32a1a3dc7a78a7a0a11de453e144ab82bb8e8a20bc4d4f09e319d035d26acf5c8099c0f7e60c2a36da876953d7c96d7d49815f2882f35b83c266df44c42e9e84fcdc9b8a73b37902d1b81c836da322777ad289468cbceaa054dbf5325210ea76c1f2bdb77698abbb252f2cafab9a11a777f4c1af7abfbaee9a04e19cb9c29bc0ca2835401e8cdb4ec5a33ae49f8af93dcb4fa69f5ded86c731c13e74d2958323be1ce4f2ad50a46d775bc4f625b4a2d9af9b1aa8150bd7fa68eadab50fb1bada3cc8a7b5cfd04ce050662e8ad84d6c67e1c243c4f137875a2eddfcac8f4f6002f20a6e951abfcc651510b5dbcb9941a02f630fd1629f16e4e28d44926738db046a87db42a121771d9d45127fcdf2d4768c55d099afb0f5e490af84e4a11d19065e38825804dce081055daf3c07e99501ebe3e0a1ea0e7ea2d5cabfb1bbf813e97f0ca34bd9dc96b323b099df376937d73055b2898c74a7c515458131d4308841645dfb41c2a5d611e9e0b8f4a4efd1b8a9138fd1965fd9207d787a8e24f91f02363c73269bc03625d4e9b485c3055fbf698ff656aebe56c8ee493fe1be1c7dbfd034296845c1f0e77159f7309a53c8eb8dd9790ea155daea6fa8564212cb49cc925da65282904934fa6cc055e24bb1074e8c63e1c4f8b2b40a3a8b09f699107f92e2a340ced1d1c8a7c600a6eff089c79a14446db163b12dd7b3098ef0db61cc43de5c3085ea1526f90a427c6c9f11efe74752915142d048574d82027a8fe6fda15f13b35649feb746aeb1c1c2911a9ac68cf180c326201d12fde0fa82dbe98ff779f3385a4e9b1b0a69cbeb78b6864d0c658069f9ce6e335a1043c965e70678b49f44de7a2abf94e78a77d3ee27f7035b2f6582c12984a4c1e52705bc82b5485fe395f974afc66c8e18a2d7d3e47b27db630e581be788b7f323269ed70a6e39b2e93adf5f71e330ac4304f7b5cc6e8eaa9fec9f8582c43ad4fefdf31b940ae4527b0615d5adf95cb1ceac3260ba6e70f72793a385303e8e84601c06bed2789804cf6db2f5db1a592b87e0410a1118739b0310d2224bbdd4ec2fc331d4ab80444ad2f2a6c6c4de30e50d37db1cc01893326e4c2f2c6183f7a75dee607ab38afb7247f06bfa69b28adf841fe3d36b38d9b142981cd58f5734374af998ddc09104cdd785cb5a0625e75cab4877efb7ae1e75363b86cc0a226679fb1d2cd158194e03cd6db4e13382640198ee597677e64cb6e947d9c75201b128d4b8c0822232ccfadbc9060a17c5e0c7151791005c07817948f185e0980dc179e0b8e76ef50e3dda14b895a463691d2e30c7bcb02c47e25a8e65bb28fbf6bf6973176b210d72bd2ef2ea456ad6373a7b8d58a1273ee5d3f8e28f286642c95ba0cfc4131b5d6a591a36e0b3307491b1285a182bf34fde2fda919c7e5f03978eab0200a5f971f57895392c97248f9a277d0f82f447a1284e438f65dc2e171115a0238667136c28fa38441e0cbb974269ffe79304f47c24515fda6914c7f63612741d4e368d9fdf22fe7eb584c388d4ce6edf0ac4ede97fe78c8f446a4af9d5789078f902970108b9029239fb31b3a922a5343c68ef11b6241013d80c281036238bb2dfc29a90b986393e67bed0643c797d37be7f7cac9d12c69eb0ca243208cdf9209b4b774fd398601b9b4401bf14e6bf0a88ec19e6073cb1c59b5f3e51e58ba90c7408cfe810628c67bae599c1b366b99ecf168b7b1e89fe20c325b9dcbad2179768440c273e6b12d7a087092d59df0f4320c1a9a5e55c5efd69f473be97d4b0a6fd8d60d30252dc5fdc57c28a856a618bd1dc49f609e1557ab2fcd3e48415b7011b71b9b85b2f01f4bc3c59242aa928425337c6f701d593c491a3bc72db3c0c6f1961797f6bd5caa79352d26c8bde5ad35227edf26b234ae2d8635a78bb22a737a8dac2709454bd03c86851e911e31868c15ab736a4a78eaa7078b898e4ad539041a32c9283ca60a7898a4597b062f0d4ab7a5b185cea29f55f045ef57b8d20c440f4dbdda31a8f55f85254436bd5b1a3caab979378ae9ac2f0dd10c6874875307077010b51dd15466c8baec81987e7b7cab9b42d157c6d7cf034a9c0dcbed079174baff3cb58d4a8fe2b43095a0bff90902b55fb9d9b17d795e8901ebd89091efc42b50783af4b1b82ce42845d326dd33471eced9cb9b289cff3d9b6523db5e639e8bca606256ca1998c36674d6c39583a7cd13b5c32ee1c0dc39f6ebe12f3524b726d6e4507d1bc53761a89ec8be48ca49ca428b22c39f66147912594e15f99e4a18eb5b0d2e7aa2b40305ad6cda9a764b975b525be9cb4372d5fabc507bc6a9035f78d35da713330beb30c885ea104d4a8ba62186122f04a0a8e859aa567470b3b483ee6ac25cc4b0aea1164968f0d922e4c1a07858588a4c2c91b61b50a9292bcaa5fc936a0e2baae4b7dab63b690e69dda42d0f972205777b5ee3595e2ee30ab4297cc90268fb27c4290045159ef3eed67317bfd223c9c02f91eb50208b91eb0e95cbd73c8c9e9628e401dd56497e98b5ce01ad038aae2488ae6bb61154f8dd65d7321eafbbcdf26619e4f5129847077e9d3b88fe3e5cd07e5ad9b56ae593c27f08e7fb7f491b6ad49a08b1a4efcdee992da77b63c793d05c48a87bbabe855b6e28e12a9af0e5f0f6418795df677a16b3d91b9112d0e296106ab8c4cf1d1eeee6270d50c9e85c7415b04be887175fccea2d70558b288e1f4afcf681f10348338a9b99bddd490a0c57b7a0eadba5b6690a832043bee3f8b36f16c3e8461c75cdbc15e04cda3057561464a9e497fc2d8f80d6499860d85b9eaae14988b9528cad3c5a2c83af56cff1fbec1e02d25f28df38a16195d999c23b08b5d69d8fd3ddee35458277407f14e74c1103b619946e1b139de4164206377cea4c282cefb8c8f9a3e0c8866cca538d4dc4a4ba446d19c3ef622b5d48a163d8d7d39a1f886ed26403af42c88a57edc6052bd7bb322e1c27f04c5c5fe5087cda1e62cea4a46ff92b1bbe7daef21b5dbeb0b4d49301c6c02188a534ef922bc44b1e7792c4388bf43872c314a70b4aa303faccaabd8c3b01d0b1da5ae1daf709d3b531fb569bea7e6ca1fbe522aff18e37768b7de6403c2509ffa616d0320347431dea7ea24fe27ca17d52be997a8c5b6e2c853a66c88957044e8664ec9fc035f68b3c9a732bd7559eb9364ba3b08a5368481f9bea79dac907bcf0d7a6a19058df91ff37fb4f3025b33c33f4ef2bef9b6d151e598dfff1893c186f77e6b3d1cecf79e051bda3abd74dc112be602c39bd5f91bc17e9e2ac3781b328107c58f2572a6f4ff36b750d95ac24957e9880a411843f3849fa22e93fa3d814805bcff9825fdd2cbde61529de9c10c3b9b54300117e523e337a72cdfe015465df804eb5e8936ff5aa16cf0ce193c6f8c223d414c59364b6a31df10436d398e49b9a568db69d192607b041877b038984712b87aceef5162298269c260bf534f5cda5e8b938fb3c802b339dc9f6299ae55acd2a9a0a9a6a9da5e71d3f1bb1506ce4cf6a713c6bab28c199b8641d7603d6688164070a9e07006e097d782c6d2e0a9b27ebe5a98177d8a82e5d3273350b5c30207f640f575f99c74601ab10c5f7bffc02d12c48d1e23fb46462bc83f76f6c68181f922e339dfb2f6ef850b1fb20674f196aedf4849a81253124c21969f707ef593ab847ddbf268dccd80759c18620274ff6cc167ce2feb01e5aba27fff7bc0669b4c565c250b4ae21c5ec6542aeeca388ebc37ba1be495bbd176d5a2fe630c729e81c93340568873faeeae9f66064435e31909bfbf350b4698b6be86d84c98e9ec263a0569401870bb22feecabed04ae9de8386a28c705cca2a680f39ab1cd1f67e9f80496b054bb904606eabdb6774325abde588c94327a42e5a1f6e3a65e0050afc1c6b44031d360fbe32d1c79a2732c6bfd62b82b12f5de8574fbc8bb7f79aee2076b59344ed16ce9bf6d7e789bc11f2d4a6ff1a157c0653e96c3a3ef0226e7f95d52af3e9ef95c6fbdf526fcd7747e7ff999547f83f610364064d1653a45c06cbde7c02e80be336ab83ab4168d09ab0f972524352b93236ec433df77fcadebcab635581d0cc85acc026bee62f22768c696aa6c7385ee807833ba1f74a55ee55c28cfadc475963b5a71f8758c07aa4294ab5ff804442e042ca6ecefea1b5189dbc140ace7698eb9713496688df2b4ce080f05aae72bdcc199c35d4f34ad40f0ed3a6d56e599c8272c18528d55ecc46beb325896060e9e22bae6656cd228bfc5e65473cb4a850982ceff0cf992d132fa0961cefd81787c6a7f7ef06296d369bce18a5a673694a147da0c0ae4f1a4270be30bc7319d668d2a116d4a29a0824ebe8eb918f35ec51f770ed0ca43856bf6d3e3e94f488c214d2c8ac86584a2190f470cf86564a9a400d31bbb2d0d333545485f76bab2e856550d566df6b113381b877eb27b6063842efd2a471ec2e7d065302cbc1ec77260de4b3f24e5e51f8f4bcc4f52c2e7330dc7195162394659d77751459164eb47df814dcfa6a6f079c9a133a5601727e32877e26735c81c5d11b024452039273e024b9c161b99fcac4a69a8615d82dfd39de7ab4f055bc71eb0245847387130c184733a5ffc797df31fcae8aaa64a70085955a9b720db82a018e1a25dc05e7fd69442770bc7afa157ccd93eb25eaaa990516536412fd74d252c920ab06429a23f4ab45fd224931633ff4012a9c7f778532701a900f2e995dfdd5dcc4f7a9e432393f30aacffde6ae0c96e3e36a94b8f170ee93c1b2974fd8b9fd5f1ce6e1b3ffb6c5f03389f726e84ba90f10b5fc19ebf32089f8d5aadf22d8f9e58300b78f1230c5993db51e5f558fa58327895fccb9d3ffd67d54f28b40f645379511b621f447173cfeaa839e93df413be294827d05ee24397c3abd563f85aac840d7350b5af16d91c58e383ad829f3291ad5546ece5ff945139063b80d63f8646611339c29aed9b55ed980557891916b7825113318d4bf4140ff80ec0cb5844b46d6bd4951602771e54eec4aab78cfabe5558d9ec177289ac90c4fdc893bf40c709da62b4dd3f3ec9e4babdccc02b449c076241865653ed812b2085ee599cfeeb86f6cb642e9274dd495c00b33915f0b4e676b4221482207767a6b7ecdd5cf41e849298fed4b3763158bd548990e0a84c96fac466dc8b14522a3d277757eaa0260a3be40d4b4d23e2620ff33ce7f1385974a536cf6c1aaba800ebf01506e93e0d06a79a6b19010e652a76fccbb6d1deb6bc47cd91d58751e785c7566c8658d1940c3ba22fefc279eead2b3e0a2deda23479851ad6f6c736d85d6c8e7af30d8692e0a914450521337e3800f5ea70f51749ef34ae8ac376c66d5aba3f42b5723d41a8ad704f6a0208a9adef7d8edeb05ab2bb05d11c193ab6c8a3047f23eca8d58b773f2c5e0689a8b49e7554b8aeb4b54a2aa87187040cb91d628814a7a3dcd7f0f8d9016e1e16569910e5c76086c7c374d6a94592ff9929500784e62dd54e29a2906b29949a3587cf08767f51f64adba85e823827dfd625a22528ae40aa6803c95a872f56b2132aa12026ef7c4bc21194f75bd0d2aeae832157594c075b9f3cec3ad393955d1a95facc2de94d1829d2697f190c123724dcb69a102bf7ed39f8a9c7f98a1e9bebe72cba70b571e1121b8056ac35241ff72a01fc72e71f28f4cb1adc98912c0963e51d67fecd74d4f46e055f0ab38cfaf1561cadc20edd4ae7ac8e979099bbf7611d1d7033bf72dca41eee87147395b50f44541bcf10bc3aac27604bd410bf3307177a9a09bd39bd3fcebe62c0d5d9ff13662de2cfb8c6798f5cba9abfa8e66af5c97461c2e2e8ed158d906cfba4b06d3c3115e0a5c2fa8c0f971eace36091f243b8f9e2db9121ccc699ccbd1e67f50271dd3dc263474cd65a20cbad0f37c92db8509c020807fe398d902f965367efc696716353acd26f029c356a617f84a670d2c5a1a931115685f901aed9b5c35f9b70c098259d95b7940250575ba1be3b33bc56deb41dd993a53392b12793463f4cfc3129213b6d67c12fbeca31591c8e8884287f13cbcf9427fd1499cba437e6549e088885b36e915d62fe5fdab04f37e890217c90793501665893c629a4addc4bbbf3bbc4a927981c2f5fee689248be80fcca777b2e0adb7837c25f57e0d20840e45e61a44458441ce3f4ff9ce7add6095dee2a7845c06fed662a010f9948539ea23d182e2509a4201ae73b08c6defef69153defe79919feae19f6bf29c5d13df7fe0a1af0e502a757d62f0f24d8e70010de65bf448cdc0c59eed17851b69a4a277a11ebd38e717c675c4ef652e1aa6144688ed1353179bfff3da11605976d8263344fbd2deec4ba9867ab861c889794d11f47cd1fa7edea39ca91c7152429bf625e26fae46582df4961f515c0b67f8d92b8bb243536a1234ef75a168613150241257b0641e99c78e38d7d3a630299ccdcd3be8a8b0a44314a2748b9cd997c9f463bc9f7d3c04638a527f6026cb511fc184285394f6d274821584b913751324ec15dcdf111f8234d9d7ea73caa5ce63e0493c48e3594dc856cb4e09e19b9da2a62bee977b06890a7f2ad52208afee1794b8725387556786799c739a76d3627446bb05613c93454607a61fdc73c04f0d29998a10ebc78216d3a10bf7452025fd3c8868061d05a073b0109233fe2b5d73fd4905a193142508887e946750f056ce80a376c7b65b3f15755f844d1c67c8b2d9d922cd9b76abda6a91ad2a5e087983c9b259a759ed022cf34a2b67c14962d343cd30d23b14b7d1ec3491b2d2777835a6a8d9171351428ac3cdcf485bcf4fcde05010f4d66864af4dba2533e0a2133e357881588208cff633f47c814daa170ea015bb6714154c5aa78007cd90af6f3bc2c2575cafa3d977ec91d7f3fa5912b16b465e50413ff5757efd3dfcee5f97f5cd7db45a600ec1e34b024c9d1a0ded77e7006804bb0608742800d84417aeb30ebbe14eda5b549b25f362bcaa121d3a980ba64556aed464fec5cf964144ae9e82273e7b1b82bfcecd0714e95e1a95a30ebdcbf3e0b31591aeb80723832c7c286674e5a38fe1a61e7b7f65a46502cab7e9aa0201cdb6b631b71ab12a144866e759906a2c5b86c8784f7096357bec0b7efe91d585f0982aa8947497c0ef67f229ea638b5e4b70c709d9745eb2078cefc3a1f0a396d0ef85f3f37c6924b40b0c95b71644b53cc54a767fe987db83a5f834231639216e3de44df1f4664841a3a754eaf24833f4adb2feeec18638884dc252ecf0a2329a85239f78a74a5316bdf8b0cd1b7bde3b60d27a999240e2b77c65dc77de61186d87be153a94a50cd9b78bbd879e03af4365e7c706546d1deea48b448fbeef60b050070e6dcd0df26776fceabfbb35f47e0bec5918e52415fe1ad296d6fd990410fb9773200ac15279598218aefd588ae3566dfa0fcc7b1167f3d100d02cede11ef0b32840ba2218b6b539588d7bf0e0ae8d96ee2aaea9c55b2fd4272f0278bf2a3d8e6b8b80a2af863b709dc3a94f371ecf6ada7419afadcd9ffb587cd322cd8cae8bd61a903812b1ea6e91f6e550d814a8a3cd524af4f92aed080cd61c7919b85e52889bafa25500791b602192f2f235974cae2a0aa45968be5811492818b8ad1fb30ee391a56210f5fe2940f24e0f1a7f632fcf8b4a2815793ef433bc06cec0d41ad3ab9cb20fe0e5ae21699f7ef03fe1ea6a5dc940883551d83b3a3f6ccb4f5d3eadb9858f3f596886123a71ddb1f9e64f8f5dae37dc308ea9ed8a02484f219bf45934328063697d06696de3907f4f17b57902b8f475ee3d140a3ae67f6532b909ad3ee66d7139a3e108a584c52b014484b49c804a9d3c6d59eb47ebdb69ea36f2e2a28c979dd1207194b77619d56ecdb293cf29c36d4d91b0228c8f43fb9a3634bc24c1684c82cfc08f79d2070cf37a9cf91f7d8a65abdc397a31742fe108cdfc31d2409fe42a7edf58a8744255de96468dc98cf0587766a04f96f225dbb59e89cc294073934001b4df4282e522dd728d92ac162f851e70d9ad4e38cbf46e835fe7f3e3b4514df4d0e992fe5256d9e243f4be1e8f1b85684d0534f530dfa30801471e2148238ff9c54252051fede84f2609786277000d524875ccc83f963c707b37ab58f8baa99cf426db3fb3c80f84f85c6a18824f861a1455e4551a324ea570b8609645332f4f63e2dad76b460994f4a62082b74e0957962b2f21abc3e36e45fbe1104aef1a1404996c84bbba84c1c5b2ae97c35fecfbe7d7ded6aa30544a5cd57e0ad38545940491e4254a835c3a8706c0adc95af67cdb6210bb527c1fb9b36dcc1b813019586b47232cfee144172df597f7745018ab0dac87800ce50c7b6750f187caa21cffd25cd92c37672b912e33e817d08f2bb1f5faa0834dbd089e3e0026baaff398e12cb6e5fcc1af9f9968fce997f193d153725276a1748df8957abd1585d08b9c9e5245ed6ca1688e8e88b40233b16d3e2e08d4a65c695a9091a2a593d9d1c3142c230f2538229f5aaa8cd8d79df71c6d5eb86733d3737f402cb9921e383af02af1af114716638d0814ff09b9ab08c4b9569dfbf0654ffb0e7a042e1468fa1a92a0dfe162222d87b2565e6d1db38a31c95be59885dbe3ce838a4fde170d808ac16eba899bb49c76f408548720c5a9b39db0aa5ff793d353ea0c597c4100b7b3b44021f8985ad637cc4ef7713242a595d6262851941c3c7674624493b175fb76311d99a60878e46c43eaa21d1f8d78885591a8f6d9a6d4111d8e1f1802283eca41618496f528751e1555c94d6a2a4e4bbd6d96cef55f85105a362e9d8a7337b89fe4ed820b5575cd139fe48ec6c27fe0e53f1b6ab782e800de3b4a98b8b6ed287086388e9bb00b221be4ae622f73526e0a52582dd7293e4bc164fc214af4c805a5f7f1f0ad976b81d1404009ef6f9feed6adafc0c3261664cdc3f6121123539d05ebceaffb2e03c68bce65418bb7da96d28f24c41cb10a45c76d471e1a162b136ef392e1fb7a423c971a9aa707fffebe026d78c1b66126fd77f3288fd0cb6d3d1ee2f7ec973d89d24d04999ab27c22b74c434ada425b2d0df81640b8e58ba804a4864363998dc4e02d1b3a209cdb2c49d91918baf3189968eb87838d5d59164993bb996926da2ee0ae34a460627361d92c439e2a120c146534a2666165ff9de207c43871a66faa7d057272db5c07ffe6e77f473f08a8b55d3f4dc4cfe2d337587a4debbfc049a3197fa5f83bbada35d3249eec2024d49be7cf8d9762581462161c8326c67050eb89efd91d957d3593ba42476d2dc3cd82535ff88caeb4ec55ec4ba10d6d866c2950eafb6eb5b2edd52438660540bb84c7b56112c49dab946f622f61cd28e46f81231a8861c77e44589f72927ca4bf71162344346040bb9fd7bf1c6d697388ab890f38a352390432eeee937199d29ca03b6d6b8d55a12295bea07f15c61482dd1d1a7db2ead57e62446773a7b72f4f40c689bc21c869e1750ad891d09c6d957ac31f016e2040e38c6194c289e68285949bb060019f542d91061a226728f6da354ddf5caf4962e1ba926a2747485d1c72e6e39fa7439c32d8ce6a49bcc0de0693126a1f1b2698739b7601dcc05fbf38b67739947a83d88e09dfa678221d98e64c794793f60973284a09e674b3bdc8a6636834fdfd621b6d490e0d164a46d0a72fc0edc131b4d5bb1afc8659db0c668f6614f07934e935d7fcf9e0d0e86cc39c0446977e70038a9f993e6eb02cc8a44fba62ad4e95319a47ab24cd81004dfc35270735d158509182905699635342344de0be0884cb9fc8db355d4cd47b9ddaa2dc63c8b22b53f51cb8347648496d8b3d52993a1619ac77060ce87e88845da9c31f93e50c2974a962d621ae7b35f2fe9260baa85e8962193dea49a32d35401fa8f08e3ac22e4e36e7dfc30286ee2a982418c59909b17147a1119afaafa32b397aa7299a961cac07b5475fbd508bd2828de542c90f72d98eaeee7ff6c530a617a7680497304802eae2bd5f86ac41288ead49aeac7df0e466a3fb98fbf6ec043a0f60e180b637b8b401e31c51dc8dd13fdcf8694cddd90a1035974955b53491a0c9fea69a13ad88a76f9e6d0d4ed28b9898ca31a4b4f519ebc86f8e5d4265b24fa9c705937123fee4c9dee2c2eba548d2230a62bd1a4f26c1a8c3f3141e6c2d2fd351b3ea72adae2e869b12e07f3ae673be6e9802081f160b13baf9694fd8fe6a11e003d257d98bf5950d8f65f931e15e3cf221b96c21f0cabb08c8df4c5107f6d9a58f4fca4ccd5db4227c3d5f2b64bf003c394f1d42a43825c52130480b1fdee09879480425fe82ee8abc58c5fb6a093532aee21c6211fbce8f3cd2b7dfb43a776b350fbd788cf99ff4683955a99f95842c969883bbee1f54a7d912adc8a0867d651cdd90f10c6b8e94cbfbe0af81ef607a74795c43443086bf7849dfe22ea608fda3615eb74f6dd6f64e5fbb6051a63f590ec969875fb7c76f970964eccb04e8e3fff5e392fd17220ec9cb8dc73558e7af7ccbf5ded5c726cb27a8aa9c12d50f317e9099f9b593da5d5af4fe34aaaba73637a0ace45efdef1790d188763566519c30bac42886970a277ab687138c6bb4a16d683b6891484e8ff84779d5dcf2e62bc3a4f733a70f41890efb3e224fdc19da4aaecbc19065a836c38326db5a356f32035e37c251535e14f51a22694cf304a45c39ff14c4f716a2872f3ccfccb2b44b5054f6c2a29de38ee9952edaa7eab885bd23053d9867c78cbcb934019059022f6e7497bcb0a77be424cfbea4bba1e629f4ce2e16f0f7ea8eac3b7d8419aeb0b4b16d7cf90ade8ad00af2fea67f0a61e29870aae65f871614be22fc0c27c2569dcd1c3db23912d19773076f3571a582cf1f64127f5a2c3a07b08379c707b675d60e56c8e1679541da50dd3668e4e12bfd8d00fe1ec9b7172a49a8132d915215b441df2d12505f677fd668ef57c0ba1035e82dbbfd8ec808dee9855a5ba8de45dce73cd74aae0f307788134ea8134cf7eb5bf7817048e4d29269a006a0c5a8407c991c6cd05183ad399148579cb85a0fce29f507fa1e8d7c3a70d99a543deb9b6ca972b6f78067c62091dcc1919a7cc5e9323e6416f01ee5783973ac8a641a8d64fdc106bd28a8f5209152bb47f4567ca6c2810d38ec20ca793f71edd2e7917da4be813faf6786b1f996d04196686c7b4b26b72148791ac2ea02ca28d167f5a70afa8ac29918947ccc45de8a0dd8df74c1104f929adc948f7880417f8dc90446d98e6a3f3f275795159623128b5d67b551aee11c4bcf8dc4fa61d996b09a30b6171570f52ed567dfc540294d593b6341efafe44295f993e4391f06a862f331deb8d2d60476647773ae655f5fe1fa9a5ed2850cf5d2b849618a9efbe9fed95a73286d916125dbf7bb0ee71bf58dc5eb98b841e14686606a1e44e02f2e17c5a8df69841715dc492d12327b1ddbe71a382e2fa9db70d007d28ee4ea6663c4b3685ffa3cf8641beae33c115614a1bc9906b13b1c9386d02def9b66c60aa40d70e288c85c2a0f3154fd13f1b85afbd84f9684fc4084358563396bf105d8183bac45d5da97f6eb86d1c8a7915a4f141bee17390df72ce14085b073a07f5b3f1f73655a6acb4cfc8fef3ffec53cb885897036112f71b756d0e41c1c05ffc01fe83ed5d9c97b8e526f55def77ceb4441ba51e972746bdf80e55a67b42284fe18ba953c8577e1b53622f97a3bc8f43e619cff4066e3bfd9be9ebf29bd7e8aef5965005c43e8e7ed65d2369302e762411623ad37359e84d1b72c9f3a5c69a65a8527f40f51b870f01494ecb585cc70eede4970eda7894efe93e7d20c0e01411aa31c9d9b1158599f1a7631eeda9c39accb775a879aca616ba515823ca5e5026f764b7840a25aa1fab31974f4a33e27de27653b63cb616f304e11f442400d9d15a86e95228337e90d3ff6b17bded84ba80133ef29fdd2de9bb0811c65046cdba17070c8b0fc4df0045a845eed0f1bf4a866fb0f84d391e5e8afd3f8a470bd6ad21de9e6f2dcb0fb65a0d06a07e9d5b16f11f403b9402061f861a695b7ed3c8457e184127e2a027870eeed486c6e7d650d5dc0dcc8b0074eee6382fbdbc44a75e928da8ace22586f3be7a89b772d6ce8fd3a8eab98898e3205431fbe9845107304847691c9f3ed58ed5970b07374098bde49f831dd4cc7f88fae987a641525ab34260ed798e5eb9a50faaa6a54329fb7221522372c37ef93849507c2b39cc0033d52812f01b7ebc2a1be6d484da7a49fd808b568cd4603ffd694e55601540b3a6492af1aebb1dca3fc2e1a2e03a92fa0810a1cdd3c0f85535e99b7215cd1c9b8993e4cf703f6c57d9751ed260f55659ae1ff3a8db8f5b24f434927b29e3b6898463e4c558b81a18d4323a90fc708a67e071ec99f2cc3fa6ab906b9aa425961953f45fec9906a234e8df426b11bf6f4d8eac5fc786b8b498a563e90996b59c4c2985c45f827c645821ec17fdbc10f069d244f4e6c4950774763bb8c5aa1bb07a90143fb95c32b751e0dc980f80bb9c2f474ba995203cb61afaa2c2ae451eb980cf601f32192924b833e08835b5bed1f772703fa0a45a0e3416c92dd501a8743e2306f86d9d8c0b53c39706100ea64e060a9d10b73c5f077defa903212bfed0b0098168f878f0bd434b45e827c0aaca2e0b4dcc20a3517aa3804cf74362dbb3bb147d35ebf094a4c93c492d328400217c8481ead8a7fb19be88b3d52fe9716da71d4060f78d868dc667cb4a501a26081a7af4c1f0d84cc9ab060b39118710cf7f076cccf563f4ccc24ebfdd3c600e246969dd074605927ecee9d58966897701fe691f905617718a9a72a32207a865fbebb156bf6a47f436deb7a4f45f69cdd7e9f6bfab7cd2504e8e90c02077db7ebf6a27dd281f61b26935d070d283de779122066462cbb12f71504bfb904fa46ca36a7fff8de4e653e98192b705db3f97cff5886b7ac41c6ab89984cc09b38e97a8f99da38f4c28409bd52f8da50ab968d7eedbaaf2ca4931c688d3d7dee30c5c8f119f4e7caa90c3a4305577ecab3ed73f320089f30f0a69551192b2a492034a7fa5e9f5a4ce25593572c183e52013a18c0fe27fedc577ba93ab779e592867f872aeea69e5ecd3f58eb34ffec4c7865d9fef723553480a5838f39ffe0b0aa58700f8a6b488ecdd58e8ae9298bd29eabcc252b873eeed6c695d77025b54bafa25841c6fa63b1ca6319e7fdad2a6bfd1cdc8ff6036b8fe244443b3707a99143366fbaee39abd6a52843756553fa23cee7e00a98a9f199e4270a91bff24591b919aadd842ba05f4e4e66a8093d4ff53b2f956e66c802efdfd6ecce440dd1b383355b6867a0a546ce219d7412d956c13eac5abd9e6501495fdff4eba84d64c94b0588d9337119dab08d5b649e482ed147769dd6160a5640ae3ed895d17913abf736836ee27b954b8c54bd94958e9f1ed058ba5fb25ae2e5ee18c09b519f76b87655c2d87db5f6c38d99da5c3c11a058a6eae0792e9c292c073b60f6b9eef9828a9ccd25ee9f8cd735d0821fc3be5d433587f053e8d8d90b7dfb98c388fee5fc205b5ff902960109b9029139b2fbb28ee17cf0cfb3092021b71ed48da5e2264bbdab79967bab39b878fa1ff39ea83f69305ecfb2b9d73abf6d89209abe3b8e534cf1f952cd1e61e1fd1036798c6393438ffc8425116f936490a8598cb7cd80326be74d363af3325f57a37bba31cd8ba14df6cb163dd12fbcd6e9fb941e4c4ad0d45886a9f0e7f6ef8f5076b2f6972916c871713119aa5266a8042098dc684ea2ececa74c02ca920834153ed92dcf16756abe6353e3f4f24c7518a8125b5345262e5b0a794d24db4bd6d9e655151682b6e53c187d2b5c208e15d6d99ae0c99903297278f4c3696ec0bc2ac7c7329db864057a5b2d3ed9c78e2671743feff4a392949f3c26290f8eb2a9dd1388df2b678b1d41f9c518a6aa691f8dae6ec9a5e470125a3340ec6153d2f4976118bfba7d51254a71aee171dcc86a12401ae73f7dbff5e9f109579543ccbab3e3d690b59e169d999f411ab617232754b40e54a3da9ba7a8fa52d766203224618e4be808595afba46da71f106d9a0fcbdbd475d95d9a6467e51149592130054b14b225d6a87b453bdb2ad909568aa29db5082991aba208dcb32b9573becd64ca6e9799773ef1444672dd7d7ed12350ba13b6268fde35c6e1e9d1217f0932788951a0ba287d2a2fa7b7cd9e5d6ba2843663fb9482c5fef202d6b579ecbafef547fdc26721c5014f54293a539dd2e332723e0fcb7cd0f762b8ab8f10b4a714664d1c469c43e9cede3f8d69a3c3b730655ecc9e4c559438617db8f4b1656d67540350e4e48985eef1178fc82e326e08c6b3fbfa2f9fb38ac5b41cdcf22c93b8c562e8dcf049516aed1ab387a331f3f6eb4797ff75edd9d67f24580dbeadadae5a70dab6c8c239b7bb9d997b30c8f9bff6716bb021d07a1da26966a14474388535dfababab511843666c6b005e4bacd74960d4a0f91eb50209b91eb0019d3b0a98eac9aa0e9dfbe6e16bba2d2f60ab5f79b467d7383c98fe0057ad4398c99d834ae4c04b8df0d2a42b1bf3c806c876f062725589f07da5b628b978930b4bfd394304dacdecbc4ca4261184dd630dcee2f5aabc90532d36f40c4b75a5901924f6893f981ceb388295123a8e0e234d74ff1bba80f7a6c97a14ff77a619de320f3bec0552bab3625a42331add1248c395bea3bd091df8af6b55e6ed381b1b359c3c38a02d31f7b9c17a363d0fb786ecec13eceea6535ef8290175ccb69dded2ac5ea73a4bfc136bceb17adca4886fa73a674c0355af4ee0b5d629dda6e0e07c450485dd3d2b112edf89e96097c477c774a424f64ff5a806e575975e09abd98e3b9cce8ace71fd12948d5d47e03c84c7f25349cac51d87d34a0f58db8db94ba2572c31295af0dee56106d52788a4c335481309978f77973ab49d1e5ee1e19eac7457ec070eda9b34dcf969f4bd2e561589e760912c10f91d40fa64768732281dd7839fa82882f7b962c3cf51785e4b113785434d5075c419a2e49af21055f5ce906122fede12b688ffc0d1eb4056040191cb416f09dfff8785e3985090b21038a4b8715fc4630c88c3160e6a8d1e1d554524903ce16412672a9121f7df95ee56f36c064efeec98c518b9658be1797bcdd10f7c779c558f3a45be35fe494b1e10e2d5292b2f23f094c1fd7ed41c8e249757c53baa1404aaac22b44f97a1a5a7622f84e5893c6ff88a169ee8d1e91b948b86e7200924e0925aa33aa67483e86bf6a72e7b2538a3dc2e268843bedf65c3a55c71967f25ec7dc2da34003b6810bffbf4159e6a6e8ae4633ee59ad534d638d017dd9dd43574f4dfe09f65768c7f74fc89821ae13b6bb5c3a9022e84a7e160a3a1bf8ea90e36288ef195e7bdfb551b7d8f8286fedaeb17c8212c41e9fb4b8b1f2893834a3456c83cca6cdef3c361ef5e5a235ee9f268c6ba2badfb702c6ab7fbb3bad549d4b4f23101dce44bbcf02fa3177274b3c708fe7ad1592430daec53255ae47f2fc684821109467ccd5b9214f9f757209d08ed07398473d6b39d46a249bd07bbbd96a8c6c9da79a8f58bbc88608af88a80d09ddb9ee1b7afd2f8b151ad883b26f161e6fad65119569cc48288643f998cf16596439df8182f2b8460c8652171c34176a73f1b3cda7bae2c8371069973b9c5323b6c284ac5cfeb358c8312b8ffc6b407dd35a2b35ab8f123f2bed18f7d2baa405bf265a7be2840d21468887f1bc8ab5635de589bfe5a2b4b4954b63eb844ea28e3e3c81f9253fca8e4ac8f719e02a4a979b2ddb0fef7a52fb21a6a5e6827fec893d314e00094848afae6c3984e5b13e770c3cf19883f65db2570156a7c2a8837c5c9ac584bfeb89499ef22a2cde9da224bc97a107f79a00ce5abfb655e826a53a35719e8c01b2adfa8fa8947d8e9df7e7c61751e4f91ada981a9ebbae8051c6a38cbea7d9056eefd6c6e87efe8869a58567e399164dbada93ee48ce8f0c0129b6cfca630485bbcfe8faaf0ca1d6bdaa68fb62677527f658254cfdd87999199391cf6535dcb62dc25bde4bedeeaa63a3faf57240fa63b74f82ff51a50ed32a931dd960ce3011834f345bad9ab8dd0dbe28f71cedab1ce7f58da5f3c514f50709ebdfe8a4c03e0b508e1540405289bac718e0727e4893c2399dd72acea430a6ff55e5d82c8fd97b85136058e74a3861bdeb3cf2a485dcf0363c6c92ca4c684d5c81165c25298269411031cc2f8a9b1bb441c22d38afcd4f74e2febb7679d217f64ae0c0ee8f39bd4583fdefa97a52553b3bc7b13e54706cf0caa1f64052f773c03baa6753fd0d2c7cc3ee75d38d2bf3af9375e15f79016945a8caf2d556cd1370dd8326f403349cff2d54f38bb82ed499e2c40b2f5cf4512fd0e638688a87f712a461d4e29335dd92143a0063f68f551bcf95ced4202bab8193f05caa328885b9145a390afd00db773123b1115ca07563feee727d45cbec7269de6f9804ad61ec2aef411aa827ae82c69d57c68be859c6d11d74de66b05bc3ab7f59c9ed89c482c360a918e1c5c565867df646e9124f0fc43a947941a0cd4263ff13a1c4897780b57ac9402fc0be3163a2d57f3511df293c602054b7b21aab9982ad954e19042afa81cc446f6621a84e25cf95e80e9198a2c420656a64f41fb0e7216cf28fbb81cd35f4a1325d6d72688d226691783ce35e1c72fd98f40eb65b127e68a7a41029ab6b6cf2fc2092269914803daaa607eb0962f74f6c8fd3a036ca3d37a89307df0ce2c957fca276504dd062d3c2883ea80eb45a60f9983e30e1708f0965d31f51802ef39cd6cfd9c470335c5544fb02afb17c4e4d74d0d54891295d20ad3c05d15fe844ac7fee6f63e6cdcbf18a2fc83fccd846a0f275c1bd9f6a1167654267198f178410ddf0471e7d15a0c7660226fa4fa471fed3c0458c75ac457d9e8527c1c3d2aadb8c40483a057b94a3df5d2c6670da2974e3d26fe34cbcd96ebe12d6f77ef1a8c44000f14e4059eaa216d73f1b294613a6b4efab174446d20ef95232516e98be7c0e2116f4c463fa8814b19db1c540223acf651088c256fb83c2696682c2bea053664312f3e27f1cb47f0de4282d5f54200f22da293b8abb0866025c9b79e4b886003845e826ec824008d4c6cbd25985d80315f0897d9282b6eae45dc9d8eb368aaafbf390fcf396cb3ac86c65325d008f8240b4787cd70d86768a29573a97c8105b9d5370c2df9cbe2751336be43d44a8fe4cef013ccbf77dff1c5a1865b08b9021b0dd4a7ee6951c2676f2d5c1025337c51b657389b90e8d888c8fea8d5259330ce491238fc8f20399c99bd748cf2285ab54ada69789d4b9171b3c22aa5879818cf1d08fb413567b21e22dca531b9be7e107e8b248b127ae6f44b8f5800b4839fa68f2a2376c41069fc981b11aa418f3ad8fbd517de096e58d1afb27ce5123a954fc94ee8b0c97453578dc9d5a9244a6a45d5e0fcbe1243bf00250b93209b9b85be12fa16bea8bc9ec05d6b99341190fd39ad180a29bc9d95e3659345d5d55fba7fe23571dd75a069165418c6fa4fc5c812f4f4ddc3d099bb5f3d170a2a1fcb9e726e053723860b930d994dd0523f029697b1bfeaf977b6affbb2b8cd4185bb322557418d0cdf05d946e5a9d45b63d52f9c2683ddd5057c267736dadc7acedacb425b128028108231b37307ca8f76958843a02f9b03c9499ddc131a3143eb0ad4a2ac460c773cf6385b0d01c3178eceb24be5257ba63bd34f088230247a9738edf194eb73643fffdf0f80743f72ac95dcfc6e6686a9a4ca47598ec91ca1f2c6a3e575c09dca718a94d4ead8c0ac36391bbdf0ac59a3c8dd5b0bd25b6979ffe01e951b53952cc0cb683b884a977618900566753623be3c51c1c86c07694190c09f0bb4a48574dee8a264ce9c0db9d835212cd06e7995f9e903af0b1fe8919e4dbce20beede0fb4417f04f7e6197b557acf0007024edc8716bea0c51d5ccc611e42d6e412f5571f32d59c5f0492a473c8361f04212e0a40dbf56007cb9035f9daebf384fae1db24d78d0341437772f9a02541d347013476691982846d4d0b824d7f087ce086e40bd7d2e881a5d72a158ff59d79918b4083f0db732bf27b760a5c3c5570eacf9e5ac6e74d8d4a3d82f33f0a1fd0a44222b250d353e3169e72c9bd9188589e19eb8898c1298705ac2a317064892f71a3d673e9f841a3f437fbb97f67ad7c6f96369de1b964cc7066a2c28f8266e78cd097aac86915ac647c7847275eb2efc7361334d78c3e39e829e6bbb1f0867ff5f0f30bb826d968b74cc631c616da0f63ece379dd8c7237820080867bfa7a0a04928d134b6b3ce6dc1fa848454ad607cf0d82408a7253f0c4cdbd0a0fe3ffa1e216db80cf4f8ccbb8fbdac40ca2c28384e9e851463c4cb0527ff4367553fb16c990befa98ae42b1a6e7e6856f7b3fa702559c38ee05e5021ffc4278d3267486b34aa6512a0464124a98888a0ea0da30f2fc56e3aae6ec3163423bde3d1124c6de6b585d3535e66a7923750bd985f6726877b7fbf373dd177eb95cac4f6795108f609a86173b774a1862281d1f5e7470cd468cc5d2ab71559d81351923928d42531fd8627c96496177b4e67b12047cd60c5c69549d8fda57aa09d7ed6dc6a1d7d0b99d2b5d9fd6830769041ac3b749511c26333c9e82f474574c012d72815c4dec79df0bf32979ead7d3887a08d666c51de81abb8b692186aa878890bd26d9b3f7619180981600753c927565089d7e6c52cf589984ea07e3ecc087b45dba66201d746fe1b8fd43515d023a26f1ce719cbee7d4c0048cb07d1446681c76d803b27ea946cfccab20dd4e27797b431385c01cddd0058e6c54a08c5c74350b24f45230e45884bb2f4be5733e24e6bfb6a066c7f87209b96d0f1d2145224ee35544356bc3018765f57e2e8c0892f87843482674df5c32fc7c5f2f80de49ae4edc8109adeef9fe4d6734ab59f4454989d1bc1970b9b5a62b677744f61ca7e34a60e909a36032238cf7b4e04bbb4df9ae5b1b3ea8aaaf9ce4709d06daa6a99851d975238f590bba763c14ebc6577e1c27fd4f5f7e579c607360a994898466cd2dcc4877509d220f2f4e0d6c907c550db7575a2c2a205faf8007daa83c715047f64744cda7d359347f6702d654c761c98e3220058d97abb273519897e3b467a977851cd15a112230731547930527e579037f41081d10ca87d422a0990189d3d4aa14494080e7b9080fe58f0a90d15b6dded038a6c2cc67566fb5e7c19fd49bee8e915181b7ab66f2d80e718cd82604695903b303a06ddc4c1f8dc4d9656aba5175a66e48151ffe4d0e92db936ec82c90b98b1d339f4f174ee6da1987ea21d0cc16cefdd04f71557f613517a7f391b41a19549486a60fe518ada87898ae8fd35cd453fb1107a800cd8085f687d173f76a16a4c655b28cce80d3a28ea41a5894dc3b457a0908dd408bb22ca7ab6672b7377f7bd3b41f0c4c3d0c9019ba2142de1bc068f6b0f190c11826877ffda6da5ed8ac5fb75f7d954d460c96c24a82a5defdca4bb5263f5328c992e372f09c8a5aad78182027ee3ecf3653ae869b7b7d3bf3abd23f6f7f9ca2ab37bd5303639e59a5aebb2f4d1b4845c7f4dbd20b644d2b36fec100b9635cf9eeb5a2df29b2b741721d3322594f899b73bd3ec8395194d4aabbdf01e837e3cd6009e9d196ef480b937186ad944c9c54171aca7bc05b51ec587d5c849ecc5bc7de89c0d1bd233e3edafb8d2d1c59deb2f5584fc752a5723806ff302cf46e2a9984a9615e1a16f20ac20b5291502e8089becd08d8facd09022f2123a5c789c29dd01e651be98a65a93674eb413177e59a3d726fed4b0b18ec0e6ca84932df98782ef16ada83c4abc9332c55ecf672fad3fb05e218c2ae1852fe61077d0a5510b3b7f500e8c8f49fcee1c45bfd9627353bfc77c32f5941dc8a1ee85d704250c1c0c4a02159983181b656b7f8ee5903a17dec7494da1bef3a529343e880c7bea5db4f203575102d937ed68c546b7cd697bc4fa9cdd51b19b85207335fa181ed33f038d30b25a232717fc2f93dfa5962b959ab754e22cebfb0a62435c33571990d65f22bc0c85c300e9c91303b89b18ecf265c77481b0192a3ef08a53ecf6f2ff19ff66213e5f6f41dd0697c0be2e82a72cea9c018976f91c62cf9a6cffb4597827c3a8b14f51be464524093eaae20afb7f3945c24187750d14c5c6cb98e50afb57bbb815e4309e7fd228bba796a6cfd304992c61cc9b670cf6bd08ae6ce078b1e3914f4f87fad3cec5d308024dab80b9f98c96452f805108103498a48544b43aac6a3299b06cbb09ad8a7870bb4204937ae9e9e96aa45ab0d85c6ed2c3fe05d698831ffd72931dc1843bc93fb783a0baa93deed484d4b058ca19aa0f79a1aa20f24fa64d6b10636d953096f15fccbcb272c272a36c46d9063726d685de33ced5f4a51b8dc247dcf7d38f3e3c81ec082510c717dfb917b22d82b4fc05aaa159041ed42f37015cfabd0100f2abf0a45b30e96dc4bfc6f0b154ee2d3bccab0a6821e85fa9fda2bce4a12aa7732f82ea9d32e7aa364e3663a37061a43fcbc4f210a998de2c399c0a93de089f86319650a41b67f39e4ed67ddb88d7f401a6e79987cecc75528f7ebd77aec42e22665a90ec9f35c2ea0b79beb238075850e3645c6815da0016281661326b7120f5d597718bc22e3b46d1f2cf21609b370fa723fb330de15789e305361710a783b68b14c0464099789dd93e40d29ae208d078b3336eb3bfdd7a34c8d42975e2c0f756ea97958928f9a71dcf5e0a2a04c68721190663428bd87adf8389da584f2b3eaf6f00ae00aa8d82f424a7bef8cdadf82e51e2d2834ccb853f2020dfc65aca0da27c607a48bc67495d8d282069c923ec720b9f0d76322586e902827b6e56476979d327b820020ad72932e8cb9ec7e58cbe4bb903910b0bfa0dcb488d2df44ecf84788dc7be0039b32fbabd7a41af3bf79f883b7b5ad3ab0dff4d9ad837ba10c6e90fc0c9d2af5fa3b2b5562707f4bf77b8da35f561d7fa6089812453c1406ab61c331d8b76ad732e598c1cc14768f6a58879a94e5fe8ab2c96a7656c2ab5066bcc29f7b82a27a7304cbe4c9f87d701f69e1aae3d901a66fcb55403bef206ebc9d4be84438820ac9ff2c6f47c2bf27b9ed0cb1832f177f59868b0f1e8bfd30a161e9998b6339709690c897645c6366fcf1c69674995347e7ebb59ab70f092c75b64276d1f65735949db1157a3895ad9a1902be5145feea4dce3728377809150df572eea89b849dbf667ae6f40f11a1d2c03f22dc9de7acb4ff6c6b18f683affaeb17b02ab661a3b6b3596b578ebe0e82b33a54d5db507a6741c5e2e4a4559109b4bbd26c7f837c8601c03448db41c916ad97a2c72ab03227ba954f9ce506208bbdcf5b8e36833ad50ecf871a89720ecd35eec9bc0793eb9375a0d7134451814d883613ac4e1d7c4a50e7000f93f77b93fac05062a88c111fb558ff63ce4ce80339c0d943dac16033a0c4ce6df076581344ea2c55c531b8190e347aa139ce391845d2eb7eb140a309de126ef5883cfd6d545c902582662b7dafa97f40a7d902574d8b59ea62489f99835e488be74fd42d927821c57b9831e3e83ad937256f92893d1d4b4893c8cfa729356bd95d41f4f8817811b8123f5577ed1d37920fb500b2ae7ceab7e8f56ba86de1b693e2d2b4d0af7d02d322308a29e041e423aaab87e0429c73248a7f462411ebea6e4e67975dd603cd438267a6104bbde82ed254c3e6c251e61949e255ddb0ebb61494f8aa23e6cb4885a8f8d3bf6f4ee3e2e214c6327ae2bda873f972aaa2ee737bef618e6ab62acf105d5561f0a0831e7c02aac0434dc4b03470e68079713f0be0938769ec77f4ce06c02d1d36dfcc9dd245d0e864b94443b62b2ce2b29715f448899b6ecfa85a3fe960e956b097aac864501e7513b6d6284fffda4d8ee4719ed8a5dfbcf571c4a3dbc7c6b135a2073e6d03fd390a4b14700f46477f6305aaf15dba1d56176a8881428b8f5b90a760107c0f34db7945bcf63b0264f40f59e362f3be8bb998a444f9394ea551d90855cd33383eb566e36db2243bec3f2faa550d5f60c0ddc8d8cd049a7e0d06d252d30e5bfe773067173f0593793778a95132d649afd55f1f050e8b27249d44f41b08e95bdfa094d3b179755f2d988c6dd3ea01605c792fe2951c6da26fb480da1e34f18b3beb685b7e2f8eb7c61b8ff762e53d98f372eaf8be3b51ef647dc2546e00642440ea9248a84a4d230b6f3e65c44b256c59ab269f7eab5e597f01372f20880ab0f6b5dd3e1cd6ebf706a21204fc0a46e702a340c2e6a4fc0777d1555ce22d6502df2bded7b0b1373ee95ed1b195683af6083a0011c741365251bd11073d496e49b321d6900f2df8ef0949e8b0a50a6d49c34c7a2580750d9541a6e8a78e9986c1a21134645bcebe29a000d6cfda51dc55b4312b1779b8e2a96a913d563c3ef6f2e9a5e2da00ff1bd21afd2755a46c3ffc95d617044049b15463865ab5763621db5440a4c08c1f9b81fa92ba99454e18427be2549aee7edcc6357f7fabc63378c7cd839dc51aa27842e3662871b0b5443460c247bec5d711ae6978c253cd950d5fb57ed57ea9b7a2da6ecde4db0c8e8322b80604e1c71a4cc890f67910e2bb8c8971d8f866476d774c1aef3c0e8ed0a00611b6dad6eb76ce9563c479ca08b761740c2ce1b376ddcf3dbf039a1b2b12685f12a4d5bffd3f0c57bcb8622b7b5c9dafa5adf0ba0c990bad070f6763620b1f806704f1849561886f5a21312270d6ade278a5d85910f0ef6b470e10d93d8774b6e31d3b2759ece2e8b52885edbfd803f3242938fea918e35f81a4ef508cbced0dc2d9be4b86973fd3de5e224ab33823e5ff74d64e23513171afd0036ec956a57cee54d88d4a04e95451cdd975d14b7b929fc8ebe0c4af202a135ff94970cc2f8f9f8a91511cbfc3072c1151504780acd1310377b20a5aaeb0ac2f5604db0c49485c2e8c89b2baf3e1bb1e2dca5f67ea73806bf35eb627cef6099e07767ba18b83115e807a361cb447448c67860c652a394335fbb6dcf43dd4d0bc2ce9ac12c4bba97c9fe63194663d18297ea5bc620414e734e47b5e50df67497f0d83aa1fdd34f5185fdc4f1fedf3aa86bf6523cef28bdd03d5fd5d05f286b6a2fd343606c7e32e09d701d30a981817dc3497f894c689ac85e37f64d23b13cc4f79b7f93b8d5329514c38264e07bd38e6e74edc8562077d40589be19449fde8408454b9d2dd9c138d4870e3621c79af39e8abd7f88e835df119a53868a65d5a3acc0a5f7cf3b4742f477994b5b504040629d5b99bda6f3d7b8af3052ba756842e31097d5047c5e09634b13089f0afb04cc2a96df48d6d2d6f8ed7668e54bb26c0462c8b8cd8356c0b9f27c8b3a5dac927f96abda733d31224c83e89a6fc87eba1792fd06670bcbccdf4852163a710d9a807f9adc3585e70a7bf75d015cf3437349285dd4dbb38271421b5c1e8d672097114dbd72375f702da9c283f04d5257e81d2f12d01d140a29d8c3621b531b929e186d9f2e2ee36eb200f59c8e251b5e35dea0e688723bf616ffc7302f786478359d02b01031530bf95504c5b7308d3e03cc428a4ee792ab53b976e38dd21a2608a3001a60fdb9d21312c4d43fa3b46f5c296603de543badde1f94ceb0d501d9f1b0f1f81ba942794254c75bb739e9357e73f48f2d18b54a79a4be57b3fef8a89b9cf8193322adc1a9525c7145dc5820713b5f27a0c5d640db872d99efe1939b2c976dd13077565ea78af4c23d7e87680d8bc83a4cf27fbb26a763b38c379635b5f2d1d070ae48e3e877b3c022dc09863cc4887f37dd0bf162c597d3d596618023dde2f08b88cc5051bf687b956f9c355c963209b567d8e9604646dd9f834e2e0f4ad1d8e8dd4fa290b43e21dc3e2bb99bf46ed219115256f8e33e56618bb451e7b8bd493421f705d9a46acd2dd660df4618c8a48c73675083209f1ab85f641967ae331b481f7fa0f8925c2220d760fc15e975544b4268112842cd31885436b48f0d768081f653c6fa83f5c3856f18717168183bbd9e8129eafcdf9a949595ea780503480c04e2aa49a9bcdb4808def9a095d215afd3bba7540e0b5aafd221050d98c5716ec09f347277a48c5415142e74a00b682dac1bc346b0356ef01f970796a11398e9427e05de687d8f47cd9e93f6eafd22a439ac5be1eebf5527d79b84bae0d455446b28da8788ad3439d21fd24863eee3fb33db9e8fd71121d582eafe60669e13d653fa58ea3a2ac027d9ec55efe2ba9c3684cfb61141d670f279436d91721f881c6ff09fe91e5a0fcc1e3bfb246dbd52bb20c40dc0a1117fc30af31464b506bf4464a019dcf3f91de054ac5bfd9c113dbaab6d0ca3f5705ce4882189d0de46a6fb198412d199fcfde9f9598df10d6401dfdc61fb7977ccd52638510e219e061a6b1928b5880a17f7cf630ff5071fc6ae66822f54254a6f712a713dab58045aad26a6e3428bdf69b0950e7ac6d8be8228c4305e36646f6254c99c83c72bc4b0b0edf29ebf66ba493830bc101c2649b1721fa732cd37494b0991c2db59a863467bffe68de65075e7b2df9f907ab082416f4cfd92d61cc71dc248e16977b49a93879708a9831fe5e0da2a93990fe40c5cb9b2608c84841c648fed4ed5580508ff633496cf9b045da98d9b0a4e4c0defa87b47f03fb3fdf442c530bfdbf193721b8a0029b8c00bdd7c195179dd8a9f3c68df9800f516a68d9c01bf3a21c362951b26f141c2c330f02c1ade24dea65579d7356cc0d1f0595327c6aa4b9821c7118cc0575522b403620d8058b2ed417d6225ad0f2a03f0d0583f7c3956d072d8a532dc0eb1f1c0825a68f9dfa07ae5987f81333a96f3436f8b1276435cc7621c43dba2a495c64b64c0e4d3d500d7cce1637df45c58ce742b73e5d699fd1859849ca465b784606da5d05a4643f38af9027806999df465e8a79445eaae4c02dfdee5f683527ebb44040a9f608f483728b3cc1ebb3f2bdd2d44abc5e38047759ad3db8d19cc31ae609837433cc74f6d82e2d21a4eb63d23f961129a338bc5bf9b2199a38887fd3ff150b23d962eba790f12dcf879550dc4b5674a0fbf9c63eb4473e6b8da2d1cddfb3d4aac1821d87c834bddbbf855f6f8abe7eb4803bce1805e07cb034882046e4c77ebf0b7039f92e507e1781bc01aeabf29bf239b4e467f00acdd4a04755bfe50792511888b4dd6799f6417a64caf3074ef74773be96b96c910c0215fce623a5e4a564692fa8bdbb003551ab684cc4f10de401367c9c8e9d2995ef4cb2c5389c987a89af462c936a366cd0a1c81750cc9111ceb06817fbc70bc15764ff46b762e57afbebd6aa90d25ea913bab698a1b198f787ad471c91c07ff5397734dee782876759c8938033db0be390f5ed2710dc5e66a655336a4e706373c5b949fdba9eb95c7b585ce00e6ad57ec425f7a1ef9a663a77b59aa9a0080a64aa5d6f028edf898f751ec931a53e14fa7e5c4f04521a95586ed20dda8381852c45ff79eda13a2d0df69bfa87385ba506fa",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x23ecd1356bae513c691ae7fd809adf46cc4400cbe7eaf462615505af44ba4aee",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x97473985d04723299559f49b856effb47d7abfad",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374c70",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x733f3dbfad1ec59c17a23459e2f1233eccb75952ca64f4eb7e48e395e674ae3d",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xf034925373f4eb5e3aa5f1ca885a68327ff2d8e125506dbffcd867aa2c699b17",
|
|
+ "timestamp": "0x6ab8f080",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-anchor-20401264-baza",
|
|
+ "sursa": "2800-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa0626573752032362e342e302d616572652e312d643230333230312d7774613037f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b841f0310f89cf5b1638b9cbeee72eda15be82428e310ed7dadaed280687cc86e6d537a87410543dd5be912a10ccfc16564f0f8f4041e264df51d3743f4f619c5e4700b84189b9bb9d7282ee830ae0a312802ab1327ae356699eaa002c4d1b84685f8772992777c72c48d6b827df3d812667a89ba26cfc5b78fa7c7959e72134d50a46989700b841480fdaf856e9e454cdbb9774429332ec3d3fc0e57c6c330d7582fb74f89f54bd459b00bb680c242db063092c865673df550fc698f2eae7372c93143193a6ba0801b841fa84be6fe42ad06c0ae56f38b10b117514f5124325209e96779890c3d8dffc093135ef51df4c1dfbda126dc441a183c42b581f7809dd81d20b2d06f4dc0df4ad01b841154ff440830a32471c8df7e3dd62ac2e153a19e6fedef98ebda988c1f35074411984a1372c31ee94ef10f89857daff825b1f79d908d1b27fdd3a3559e14dca7600b8414c91b9d0905ee26e3d29ef95a5ddcc97b4bb48fe3bba66459c001765ff7229d957e6fa1258576ef7d0919dc6d1c82817ef34b18d2cf03d61e7cfa933293a541101b84196004a05daa8d49f0c8e142f1660d49a89063a7b65d914f549299fd2adb8fc2968dce90337856febf530860eb186439561215ffc08993f669c2758b78677d17601",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x75d60a0823ff144d7b2971d466cfeaa28d07d585b1b4d372801782195d6638ed",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x1bd5514286f5602a6762b0075266379d29af1c9d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374cef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x14e42bc23501e6112ab9fef3efabd40fe411af7b9d68006f758a5a5c78b70dfc",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x035196808f46b0a3a926a03e4100ad59ab71bfeba7e64bcb100b360dde9e6e78",
|
|
+ "timestamp": "0x6ab8f0cb",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa012ea3a064e02c4ff17622ff5900bfe3d8797ffe0c9328a0eb556099b0f792ada2de0014f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b8410d145b4dd892a9ea09b12a5f954990ea418943326b6583c53b5ebc3942ee833d0f4e185cc0771eee82bf9d2a947eb78e39a8d4d7f7bf6fbd290fc8393d3f523100b841f94bd272d5dca5e018fdabc01628b9aa6c678c7da21806e7e4ac4afb64f70d79192efd099ca07e2e5b26b4c4eaf19ec373b122eedf35695e4962984f206d933300b841d5ffa500a6720b9a2d370280d1b3791b9ac935075ff24c9d63e99035cd46b8917d38415cc708cb3ee4d02af98f024eac253948bc8321c7576fa9a13f3ac26cd701b8410682dc35828e5a1cb1fbcfd6ebe095dfd755e9b017713e92387fa78287c8a8ae56a946a141ce60001585bc55e688b8a9bd91fa5d62e7166ae54641f81b04f3f300b8415fc017459359a24bd036aa6988212c4ccfcea46b5d7ad5f0ad3f2252069adfb45d082fc36c7ac6aeb47668009840b048d68e59bd97520f6a92e527dcbf06c16f00b841e4a06d8d0b390b1632b20ad82bf40b7378e19036efaf3bc91c55a645bcab32b7424abcb8cc57214a68e575ed9910d47e9719d7fa733dcca04a3b57b880dc73c200b8415df4f7f2ec697b2dd735f08337347accbada265e86d0898333c08799136c535b05d63a152c02837b9d2c0924599b2b808f490d00bd6d9b7d361bb363e36331ab01fa012bd002fa012bcbf902940180b9028f39134448b48e2b70b90d20cfc07025e4e9f08bd31e9e13cdd065d7be15c3ab9aa705592b2d1714dc1e90dd62cadc467f6d996952d4f25bf1c7562a295a0c84edaa64c7f6c1339af98651a083669a44464046fe741bfb1717cb1cfbf438ba62ddce51146e0723155b65ba1032b894a9c4a20a8091e78c9cdf39fcca4c8d6b95c3679996693f8418a919cd8c199a9e0d9edcc436ac45bd5e9696a24b2ca8e30961bf81cdb02aba889bf0d313a2bac6997993ab3c8671e337b8574ee723fd2652f48fcb88bfb94f9587e241241f88926072991f9161bfe42b574465f264e39867cb5c94ff7536f368ca501305c73a83b2e49ae16e96fd7fed46c492e5385246c6e13b6e8d5f5f0e768844d52aa719f3edc6ec678ec9a0f758d8f66e44c7759fe576266735e6e590350812ce90ecd016109774609118c4019a7de572db97f63740422333a59608d5fe17fa85eea36d5fb8b9451b8fa4539f76e07032dc1a445ccfa423c38b83e78a1fb568d358b4bde8bdcafdbfe5c3cc03751acdbf664b9ae571a0ade73504b8595065751bd9e2348434919bf313a680aa5cae3c4be960a264c8b8f3beea931244b611ff034596cdd23a6a5119f030c8b08866178c735ee04d0f54c0ee753b4a2e61e3362bccf32f679aeed1a560dd4be00436db5987ed8d7cccb1a0d5a4a1647232e9110f849b9d82c314b26751e5e6eea3ce62a901c884392914bbc2add5db76a7b0a7d7d99876b28f9d2ac205889c2bb5fe96d6b24b3b7e122fec8795d8037f86e1ad2c2f430920653bbec6473ea82c3577f67c4b6ef3679300881151b0d9e3ddeddf21d9fdc695084ac39732aa54a2f3b494e131b96e42c26d14a62afe593f90ab23af3761d62cbd4304fbe93ad3fbc523adcd60d3b657dd603892d31a802dcaeea59f34acccb6bdf91eb50280b91eb069f4c75101eeabf72a1765cda2f42cfa883237aab98a50cd0be21c369e2e15f0d7abb741568e028c143bb012ef4de2fda04ebb29b0a1f9b410c0ba613c3c69b86e36d792bb9479b197d1dca4a013b5236d178e74570cd0c10b81944fc655d1a1a2a4a5ea972a4eaacd2cb1d1cfe1e5a665bb5678cd1e489b4e965f2a780ac867248546d2c564684b6d9744a812d9676c33953297c690e9cb22fb1f06322aa518a352a25c8d96f85d7e2c0f40cb0a02e3363d25871d6a0deec55be6db7c21ea4ab19c54747b7752beaf10caf1f3d31c29ec4f8f647f1a3fab4e203afa721c92267b3bfbfb6dea4aebab0e650fd315882f6f8a14145e654084b150df2ec9ed2270f67cfb64d601f1f8e1683c5889e8f8ca91c7107c74e3c3194f5ede38fc70d0881f3a09805725c9f8ae153a353c82e9fe7f5555308148b25ab536a171fe2fb1da59226587eb87e2bfdc53b13b2303e8ebe97b6449049bd7d79411777eb5b0b7ca9d5800335267186c45a74e6ef65d8e9b7c56c2288579f68b3b392b09cf7e1a6bba9efbfc011a75a3c158c01a5b74f874ffbd464e5271313a0e74998a73bb339b19d05db1db24eec9e18f54e99953c10ed8f91dbbae2024623ffdf4aa164bd29a7538519811760c8ee42d76f534fe903a47b802236eda95b3024f15cebea4ed93baf5e8b31588182c60a088fbde64faf476b131ee8d4f9274b497dee197651465daea1de4b14499fc1a8ac406bbf3e69b8aa3cf5a57731a4ddf586ce59954e6a93e8904415c66b304314f665a4a145990aa4f633b33509a4fce6a13d765176f5ec52cc41191f8fdb48c9bc7ce956310d574bf39ffbe9e219e2e6727f03934e2a4eb0d629919571f77ac578890bc7e05b8c434e589b09fdd99953df2be7c0adecdf6a710aae3f365bfc44c02569fd534b2c253571fc903ce68a8f24ea04e0311ae88d6c772dc88b3c9859c8974ced0438eef1370eace60c70a22560311300342b960d35ed098062ade47afdbc1445b4e71e2bc6a1dcc8ed06789be88a9ad88a73d00ee0215bc12be131491a7759a74f230808198de498fc505630562b8f6f695488b87f6c58380f1b91347bc308e5debaf6bd7a2dd36622397dfc3fea80839f51d8ef27eac8fcee68d1ec37ec7ae7aba8a7d4a738609b3129feb557fff3bbedc4b83918c1059e877aad833f4ce8d2a325fab8a7db32151747f372b1f434e2cb0ebd3139bdf2b2af5f3ac5998ec9a47119c26191d3467a5d5f45ac160b785287319208de41b5b6691d193146cfb37b6aa4e6a933e9c090a6b28d7e9f72140656d5cb755161bff1d25c9bb4400c4e8489760d0ecc7e2fb7c22d29ae519c17c3f29a0486b5ac5c4551eaf0a9caf3d8e70f3560a835331f619ca078f255b522912ea66ba63a180e0c90258b364540af07013b41a46396f3a20ba9dfc9fcc49de3ee6da93e7071d976d5143eb6aa77378ce8783c97a8dadd82a9b5e4534fadbb11423f3571d402ac1be0e24caf2b8fb98e70942bb94bfb2960cae80f977e741eacf581427d14d6b95f7d5653941926d435f89c0dff8536b291da38ce00d5098174225a4adae02e0e4e4b191fe421c277b2c2d4c0ecb35711df03d9dffddac0b04efe4d318461ef9d75474088799d4484acae68c48443dac647f18fbbe8e956f1b29d51be7dbe475bc9e11953474cd2cbc230a979729f10b0b3e0e1da1bbadc88b01a18abf836ef7a9c949bb1aef6cdb47b05e1545f73b43ef83b0b2741bc342da0f2b8eca6d7e6fcea38016912f00f95af05a86896ca4b8b3bf300938f85828d2c4bc8a5a6d64a49c7690f81a257aafdc1bdfd871434dc5a26d0fe5b2034a1bfb702ee6418bd3c2c42fa8e7ebe781af78fb37055aad166ba6aff9250e0c3661567ade13395a2d214842248661869b781ed1a70e38c08298ca5c2d51585b5be70e85d066d67195d19d311f89f1cf0c46e49eb1126b3cd2f8450b5fc352fa396b7942daaeb713f51d00459dd718519b80e443609e57850fd576e15385a6799b3d08ac1bf8ee05ce976ecd18f5f361fbc111fac7ec0984e837fe5e6e3dd3c88ccf8243d666847d715a0e0d4471070121dbbc7557f12aeb7a3727e9c1833a64141ffe6d2b50edb3c22e2538736b253e0516967b880f19fba01417236ae6d2e2abc079b562596868dd93d9168879c4f9b86e4ca300284cf90d3d02142dcaf439e3f0ebb709ba11cc8a1e1db27ac893c1411eb72cb803762c0f1945888a65f6013dade1f7c64360ef8814a213f83dd3cae2883e565b3a9204135118373b45e23cb04f113a2f6c9a8a5b4eb3f0a10d4d0b2e543ca1d54b197e301e1a73acffb2259be6248b3cb66bab8bfa86a7ef714f3ebe9b9f5a880cf0aceb84831e0e5b00f014dca466060944e45c88f268512ca40fa90440a4248b5a78d97ff837458659178503f9915653730756329149771e8cd00427c165ffe036995220d42d0f3a5a520dba8e6a76b0f1cb486e3e6435bb75b2094bfbeefaf558b94cf9ff11bbc5404c3b8ac27c7a81c463727ae85a54f5f3019f38e8c3979810859a57371857be172cab79096ab8f7e862799db4c291caadedc39509de59715507468a04a08a256aa223d16fadfdb90ae77b63df85bd94b5c807feaac529286cf50495328e2266f456fc3661029e5aeb5bbd3c24111df6e0e81822bc673c7867d53ae247c91230654bfd8ed3e5773d60d33c43212a664940e41d9fb4747e1c2e1c19afefbf2f4724b7c7a9065159fbfe9421379e47ba1f4a114c09553a7f063deca5309e4fbc2aa9631dd715cbbef6401d0d26846e6ae5f1583b80a7f421b99b9b2ab25cc5afc1230020823854e18eb4665ac5abcf70b341a9f8696151d1e24e64abfe2f96799e78812d5814d9f275c18ee888ce66aa199d575f942bed94fb37c1535b89897dc3e0590a9555ee3901de2999cc8f8120af0c695b092dec61e8397914b146c2d844b04e3081239ce1deec741035f116379488fc96a0142c8ecabc01a817627decdfc3a377e54267d8200c7c14b9a77340e28306da58ac9e98d09f248377d87200d6843ad3eb628c97037cd446fafd8cb0053aa7e5347475ac8a37bf03a50726fcb317e11a5802a485d4cf2083b2c7f8cf99c2e231875744e0f84eaf13ad984ba080a47b496aecb549ad46b1ea862570d33674bfa1c50598318cc5125f5870e14d35e9003e6f76e12bef50c2b613567403754be278cafa07acc52a05d9345afcdfdf2751eb3273d5ba8e2f915e41cb79fc08e258411ad08fdf05752cbcda56a92043c58956f43c9a5d435014bd24d7e8fcf31e4758f9a69a478a0384238d4bc7ceb2f01a60e91f457ea26f0abc7741e2864ecb4edf365aba1582b1387f24fa759b6a3d8c7b8b24ab0e5ea3fee0d81d27eda003adcc7dcb901c5a7816e7c2880964c92b82cc2320695e74bbbc6ac482c5f9d74e331a263aac28d8b7587134a2e585535e3b3fbc74dbbfd132323c4ffc96a56d14d5fbdb42dd9535284d8cf288602b1b3ab94702968e32669f41e861bc27356fc015d83005aebca7e13fa51266775263fec22130a924af12d3e2df1c4afdaa9a91b12f31003870e07325bf1ab79564c1a488a501831fef53fd7748d47f17fc8a60b44db8d2ca2b50ad2f549b2f0cbe212ebdb411bded2f721042e93ff7c5eb7edcb580014ce0dc801daf15b03e83a89eaebc94e4bdf6d0182d340569fdee3344e8071418784a055a9b6f27cbcc5cc9a1a3a7c177d2cd90ac0d4fd90fba9cb6ef8c847f73be10fa17c32e0326a5323aaad3ae11eae0ff77de59a676f0290d0736d502f0d861907e7d38232e24011736a17f620297d75d9f54a2d1e20bc9a7c0a8d4810295770f0133782aec4be17f66629cabe03d4c7645b92cd656faa5eb88ebe47dae8b8d78a5e1bb9a4a0c519c0156af7ed4a882df9ea33da36234c6553d7f579d48ac454269e551324804d6d20a4de4e29af4791c963e3f474a10ef6cdd7beafdd780ce19b1ca904ce3bdd9c2687f1f50a1f4e0fb152ee09252185ae0a5bed76481e4ee334f3059e1429c434a9ade07340ae6bd706fb3907980398b28cb5bcfdb450342dc28f082029cada8311d1ef30b0211ec37f5fc626fce09b4780ecc8ccb3606cfdcd5831ba3f56f8bc2071fdcc7d8fc4839283540d5b33ebb70e3c34937dcb8c82e1c0e52d6b9fc54abe415f841498be974fb57b3ad5c6b50c49e4078815a275a52b3104144ce6d3bfc93aa56ba1fcb314b0730e8a6b97a95d7bf6e74ea1fb74c2d61724938e63d6e7170847de0c8240818dbced37f94bc9be2e1178c251fc753f1a0548aef9c3cf26882a14bcd0aaaaefad4e4f498187a06da130767f001569f2625b210c14d3417734018698da873e95c7e52c9369a91cdbf8b3aa01af806082d9ad42036eb27155221c985bde118d42941442596e8170ea675c95147a0d698aa1f6dc19bf5c24f5805a0d20ffbeef4a1809e499efaaa0f08b8ffaab5430c67f5b93d211e846be52e3e9fff715512966110a165eb6249e7134dec63e3b21b54a3e0b80777ea6576adad7462f7f234a86c95d2841f1552100c5f0675e6ae4b5ff982a26a53fc3feb5641018ebbd139e64028cff5cb74d01763f5670c72dd87ca6247e1df3614b4a323bc4e3c4fedde6565ba944e985fa598f039e49cbb6efc0388fc6cfba930484c32c069ac372fc5cefe888c5e001f542f5b9f98f1efef5d30ebb0ca6b3751602a1ec2116dcb34fe45ab711a35176abe11e706402071929e220babc7d2d7f277a7867d6ac89a36930be0c3cbc12c0b307daa8ab1dbf2575416b6902d8b93dec7e6138fcbd5709f70661775cd0a62b81dbc1b00587cc46304a5d74dc88df1618bdfcb6d99074107098c6e0cb75e0107413f2143e1cafb3293b8422f45db6ff9c3055ca082d7484fb2ffb589932b08545e1bec69847a3ee12d584b9ea2f59f9b5a68fa0a6bb7f2ed20c6dbce8d798553fbcfafffbbd863733d73f05f03868ebc7aebf85a5b26a5e000d78788b475749dd38c823effc8d9fc5c23e3dcd3bf12d68c60bb393c2fe4d7adc6c29ac870703ea5fb8730e38156ed7dcde5059adfd0259da3e40188ae71d5ae4fc1f702dcbf12f44e817eeeaabd72a18ec8ce617499f41903162f6216748c8ebfded1bb634e854b9ebf04ca8ced48dd49d480a7132148351dadbf7e01fa43017eb8bbcdb04f0fb2d75789197e72a33f412ac19ce8f666acaed6a4ef4cb9a1742674cb2dd851d3bf4a4cc04182749e84cc4d4bcf08e993fff11d6f1d03e6b8bbac04a85e51b1fbaa4e6881b62aeef9644b74b1f55beb2f4c5a52d0e59ab9c5da3e7c82be5a08dec7d43f4e4aef62dbfab25da0b8c47b9039900698b5efa5ffabc859ffe43d13846559c64931dd86d6e98426428ff8147af14b95402fd37be8472ec96f72b3f33295631652f004bb8c6aa540d57c288e0c20f169bbcf622f2900322ab586188c18f110302c0061e195b1252f7627d47ac5474fbcef6eabab5c553234e07fbbdbceca50ccae7fbcc5b876768031b3ca8aa11084247c169f0cc03d260f072e0228e32fa1da5acba49ef9127b5a1ca7ad56c1a1f4d94e18bdc91b9bce5ef5f43e4ec56908b01a94ef11b0b2b83e1b8be2a3d98e1706ec076a620066edaeed19754ae7cc8c2b5d6a3012c1de54ff85771940bbc34f18b4e987d61c6007125328795877834906ea5cd35e16256cf80148adecc555c58f613196b6d392a829061f66551bd3d2b472d19d2c3aa3666e9e2068511ba1231480d263915886c941933a486ac02dac5401b5f53933480d651284e6c0acf5f3c57ff1dfa262d57b1318a612838476b843a0c65fc56b9b91ea32b8966196e13f49461396182047ec669a66d92b86130d42c83d5c53fe9a5275b4103c9b1cee54aae9ca42b7826411838b8f744426aba844fca60657cfc9fb33de61a7dff4a3a68943a7cc54a9fea80f243f350a2d3f8bf46c8338874cbe9d09807f3c613f04b39d0958c8e688b5f4b271d2063428504876684cb4bc49bd52d10871953add1abfd82ef6fba557e215347018793245618905afa0f6d8d68d823ea8b6f676410b2b163efc7c1197355ece65eb01bc6eca41c33dff948d20ab09508388c1844f444ad689cca6b5033720d83ae363a5c79777a07478e11947a9a846f7558053d5fc581fa42235f4970179ea394c7a854a318b034c1d5e5406949e6d1c5eaf85bf36a7aa91ee8ddbca424f214dd343321b18ebc9ceffa059c8db0741559c536e6e8fca85135834efad4710ba944608f81c67554820e303f2c94dbccc269d9bdd133ff6df249b4490c6d956dc54079427f84f2b5d0a2da57dc07916a7d6f54a7fefcbb34a63eb3566ee1820b0355168b6ee29ff2f17ac55e4902c7592cf4c053fed6310653feb6900fd71d7a13c71c024f83b1adc61ead07440376cc128e86adc4e4670be47df17e27d007be8188def3bfd5e867c74c9245caf5be6fcba3caed16c81991a1f81d90b503f5bd9349b2bf42e4f01d0587fada0416f4dcb234b41cd31d164bc9cea31bb0b8f4e32b0759570ffae2e92ba565af9986fd9e5b49a3b7dfb85a16bc78c9ac94046dc43ad56c90cb2c9080bcce582a9c863789fc6a12972b7e1085e24a9910fb1a5d9acee5837530196bc73393c5c08240f193050a3313b07d7735852c7f5504dfb2bb493b1ed041bcd2859b89e95d4bfeee5a49d2981cd8a10e2d6f6b6e552eb8c4f29b46890eaa25fdb055ce5471b4467ee3678215afd2ad0803400ac3261079942ccd3de1bf105725c7901a58f1e85e4d626beeaa366c6a66d1c5937cd0427ef3a0cf4d0ddfb7d82b6ac2c1310c536254d95b93e382d7bc5d33d4ddca7d8dccfabcb79fa4a785fdcf4c88e71e7aafff46be7bb22a5198256281d7768a19b23c33f10a57bd038ed9e96624579ab4beb067217470626aafc404bbd1bd3922a1cc1b41dc00a9d65801ce3d496af95688f742878cbe0c9d73c296424f4fd01937a45afa2a28c4e58b4b6e72bc289c0b3e2d159a2ba727d55c61af3fb1a2a82e1df03bd4a6c8f62117970b1b0edbd0838b1ba412276b4a0c0e09279a8736a9e4319c6d16a070f0ff661d65428746fc66174dbf6a07dc28cb0138a6dc492da5558040210edc7283ccf2b544660b19714b3e4e2c2fdae102a6592dc0b0df062e70a61ddf7255dd52a17a1fdedfa6aa9c5a56d0a582fc830898935260f8b74ced5686997d808123ed72e64d724ffcbe321fb58845fc35b7211258308be33a7c62ae5719fa617b9ba9ed539145f06fd1c741fbce5bbc951c7e5ca22063ea18fda6abcc9746ad392fa84c8ae7fcaae20061c04d20ac4d73916f56fa28716d0d41f2d33940b077466a976d3eadcf7a461f97170b40823cdff627a2e8b9aabebb5576a7ab9432be0c3713adcffcc965f51ae6beb87a72195baaffc1daa39c87a7bd821d10f9ee293cde98d3a54defbe427a6fd848b04e7d724fa05109143597382304020bd7096ab8d148b65d35a007484d7a2f45d05c19ce6987585f2cbf0e6c972ca764df10158dbd0ab160feddeaeae0691f67a604c16bea75d70b93671be18f574be86ee6ffdf692e7f173ad19c08389a530509329f9410ffa10b8ac9d748c1e74282b8fd4e86e075df1514b21c97a23dd0f212a84cbcc1fcb68da3c06b035044279155f32916702ab6a2feb086b25a6bdc2af496496d1a7ede1a0950ee348a65a9e89eb3454df26c82dde29ad1e1ad2b6b02cbd8de3fe8cc8221a38666555fea557a393dcd72198086afa78a44a8a38ae06c7e37c55892b7e7a019db4476dfadfd6ed654f025e365849a3bbab1c51b33a9318a4e84c67a9e30f08334b2562a3875cb4f35bd26b8399d9247a6fc4c4ba14ddaa00f0c904f20da0c93539d3d19e940fa19cf1b3369271c063838544f9bb97e47e83583c4d0c85ccf78b858cda0a80f74cc15f37866ff0a2a10b71b3d9d7240dcec2cd0fb1fdaec15e4e2cf0ce8acfc6a1f235604659b3c1a5fb504715edd1fd59cb1e23505f4d88763215c49b7b5bce2ac80b6113a02275406694769122bd09ea1747eb979112df3e86992c0e8f059f7371243a37db2ed3e778a4ea67a6da8a3801cf9ecf1672328e02bcd0ccc65fbc9102ade391baef3dc277ee319850440b06d1c261d9e4e7ee3991b69c0f15cb0f81e1f84391c5f6693730944e8300756fe78f17528127b778160e550f598160669984fdbdc89067a782403e827bd442cf04b2f94c3bcec14f8184c1e2ad7a721a77dc37aceb5efa530d6cdc3193c4fd83a55740d1eb43b0af4a8ce10045894fa8dbcc3db7042fb17b182b7ae45c25df3ea1acdae2d206530c30ea56470aff8549015b25fac0f02d1b084d2e5dc0961db8ac911a14a815246236491c51431a0a6528cae82a096f645f0923b4463cff64f6c22c650e987b3b4ec5b7ad7380f7c5e2da4016637f632048a13a7a2305fd746a3cce1c90b45ec00dc165cf1ebb67a5b8f96c688ecfe3a25dffdf5af013982611c517bb658cee1da9f8be04a4ffc45c733e59e2e25e2322ca9c2a45149318e507aca992c88a9f7a80b6eee120e73c103ef1839ddd6c2dd870c24cde390b8477667cccc415bc84186dc5fd8d6832d046dc0fea0bd50d3a4f26427f2f8b0e7b8c3e084396db3c47552e3e1236074dbdb4c7c25897d011663da2493fb7277e3dd381a9a32a2b624a40c6587071562b1e10e16674820dc937b5eb3893cb0bd9bfeecdad95c898e8fb31a75c79d13100111b05dc2f470b8427f0a385c316d1bc5098beb4c612a283540a3299576ed751cdf9f87ca50c6badc18c33fe003da2a06e583fcc847b46f0e2f1684ac1efe2c4d8786d0bbb3dd75f3552c302f47209859da1278b6bea5cd708a3891521dab8852830f42757104c61c797fdb47d2ed330fbfd0fc44dee2bd55cfb431ef3de83aef3dd85d4a9943ca4b2af6c8b56035a8903512cc6ecdf542678c655e724284e9ffb894144a76c5c354f3f723c5b12d18a2df1a193f647457a767f18b4e25c3843c5867327995ce319d334514f2c6801e1080ae9e2ebf7f6c7afc21c12db57d2ce0737e61dcc124fe2b08ae278085e115d9918346c2e91326c4f7a1126d8f7bce65a225b83b5cd56de59b1c0a6de04033682a60c98b1db1ad5da4916eca457242352bafceddcd5c79ba83bdca10337b43023190dfcef340a2865c8d14d9b9df76ea43d57f9a95bda6af9d74eb0621821fbb263ae081f254a014c748506df89bc4af6abfc227b6414cce3c795a510a7e2e86a3865c5f24745c9261066122e22e9ebc28c6b52d8ae359ef7549b81b8925daa274ed1b2dfb3d690c75f2a13eb8eadd168c20dc1fd78d9db6985c47a936a996cc1c28d1e3071ab7ba7cc7b88ebd0a9a8b34e7cc544a1aca4cb5c5154bac6926c6369e8ebcf2e0b8bc5170b409ebc4de5b0f526a1d1ccb14a1b59ef6a710c61185aaca71171d29378517252997a758bb0b98f430907d064b4be46a27866801808822febc017b86be1dc67d94bfe3ac15525c2d5f37b60bc237731efc8f73b7b29e8c1946f7d7b7194d17f66ff97fcbdb9e52a3f29ce93a1a4a00910342ae03af8a18cebdc58f90c6d6ab2711157966caf4ac20b47d54488bf774f10393f91a4d2bd44d462b50d7a80a28229e83919869efb3495b9725d6e9dd1ab8e618d89b32d78b591e875d677ec23cc3b48b9e8ae266f0b7001cb499779c01c1b45c87a188d4a2a4f657944ae053f78288abe1b5955a408eecea72e5cca7ffa9918af2a427c217281a1202a20de736b3f0000f58a5e00b57d14f985d40d9bb0348e697b8e26a700c21615709196deaa1039f8ea0c573e3c0b20b908bcc6f9e1d9fe0a44dd4fb46f00d41835b392a334ef7baea8096a456d2a3c9c666f82ee6a2e40c64346f8d7d5c36ad6e5afdbf91c17ad6067050498537d8123a17c9560f7164af4b17bb263ec65b0f69dbf014fb164b194e3d9f727af40619fed62d6e125f0f54cd58a66552041e55ea7ee0e67201ac600dd11bfef24d2524d6210640aa35e42521d05c8fd770c254602cf3af691f6a100ceae3884d9be6d91c2acffaceda8611c4cd1361df6972cfd5889a293dc8b3afc14544ba6d247e44d086806dadb8e7e4d11feda495f4716f0f048739016f3b7aeec8b51217fd311c4e5e1c09db5c7f4519c057d25401e78a2f7692d8ad635261af3e9519a157574056dd75560710ee07f6e60fe58803eefa1516a8ba6418a7972afa5394ba4f80dbeb6afbe8501efbb4584137ba699804ebcf699fb8a08da4ac968d329eba12fabcd2586d8c7bcb755ccf542beb118a9a779e24155be68444ebe0e0db2afeb553af5d9c3cb5a3e9ba44132853f45f60d123551cdda42977c2164a040eb036bd290b5a644328c9cc7f6168732dffacd1288a9e91be47fe21c78d12165aec37edcf01f06aceb180749c2adde1d14e3e5ca551a4c9816c7b41890fa0163d75d30f744e6f86e6b883fba9b857765748979fd7b77d858bbc6d2208755646c2c824c847892867c5362bce6212039b53aaaf7fe3f430a1b196c178e022fd639b761ba9387c1f06e7e7a9fb2ff2e1e3df07767200e54bab276cc9a3641556ab46a61a76ecfc84d60424da83b018f656dab0103958231379a4032811627ebd987ed42a302eca72dc64e65aec89289aba936114627bd508fc72c279057551acf1eaa6b87d0bd07d0682599fc58310f3f14190b8808fc5b9afaa9634347e351c7ad35da4b92a7a2fbba7a596748a169af7f2cbc93db84147d15515a0690337e7ca5318de7dac73d71f41523239abf5af7174a89188688e6f63bc9adc4304ca9864ea7bc901886a06d5fee74a193a51c4e5a613e7ee4a7d12ea27e753765c69af52b6219c819cf46c9ed19806af5a72ee2c9fbeb4b89579d789aeadfa069edaefb78fbaeb0aa1acff3120485dab6ef004bcd86325e83f6998f3b35ce64625c631fe03ec951c5e6d63ea3669adf386a27dc9a1135ead6bc4903c5cbfe676dcb6a215a6753415ee9362936fbb014eae4928879de1ec4a33d395ab283809053b309cedd75c26a6d6830dcf4051e20542c72c30e7f04e27686a4ef7c49c1f902960101b90291394e717ba8890926e5a23c63c16b3af7de52e04ce531780b254fb53ed5f7aa1e37d67fbd762e4fab361e9b32dc99cb731f4590561313b5c17fbdfa8bbc7d8b427771cbec062cc2359d955e4e5f71ec3711fc58585585ef817de5d687cf8c927b5439d6a39b2cb5e954082bcc4ebccbdf3a925ab0d6ad7458e1eb53e7be0feabf2e848d26d0b7e43a490a8ac7e73582c7a1ca72da7b5d6fb10463d0f44b43ddc79d1394b8717567a0a1258e111f74fe688c755bd1cb658d3419398bc71cd976e322d58cac2869deddee097ddefa3315e8a0f1a975ba2406729a7753aa3db95f83dad7b59ab887a2de4782ae5091fd1ea447318993bf0c98cd6b0862aedf4d7c92923e99bb88b163d6ad769c5caae51043c33dd2e6a60b9c694f94b79ac6aed3f4a55f730b9dc21f604b4cd0afc78ac768c6c1c8534024c89711ebe4628cb378efa36db7790033cb1bb3e9833bc96e29f4afcd4fef51eae2a64f423ce752276c2b308f3965a1b822491f836995675f9bb4eb60e7ed0cb4594040be8c9c13a7d4ee18b6cdb87584391a15a7e1adb93e1257c263ac61cf0b792d7a6355f33ef1bd79b9b755e1f7ebe0e60af336b65b244cd29a49536fb65481e0a748b71ce755ee2dd7afc4dbc9987b8ca19790a97ec81773fde3f64025fea7fd8e4ea602a5e9d633b7b4131ce6fb99f64278a4b111aca2334be69d9de15eb016adf212d77d30ee8a470e39e9e1d2213f6c72c6e43068c2c9c53a194355246075aab4469535d7d3d0c391fa6ba2bba98c7f0ba2ca33cc0aa64b94af57eb3ea37bd39ffaaafba218d77aa904d861ad1074cd09336fc32f61f3c6ac6575c72f3c2cfbb99377a8e6cd707acecb7cd11df9f0e26ad94e577d1ae6b31f6db58adfb3990b5b17de6e6aa9dac2b69e8f5d6f390cec58fe4f232bbf3c08f91eb50201b91eb0a98e94d88016b88d377712180d09d4e469f2904fed265f1198a1c6add0e5a72bcadb7755cc7d653fdf879a1fa6d6e1eb3d14951cefa57e657a18c6a29656d66997be54a15863b59de6dd1d69db0c6c40863e9f77d93eeb0c3e677110d13d5dba37d350f09b46f3c151ff3263f2870058507c3268160973efbd6cefdea2f9be934f569bc6edfd0c7f2058b363a196a3a208244f104b58ae1105389337a1fead856e49220f3959e8ca14e450403ff67a0b0e53d0f549dff9c34e722488f9fa9c832989599a5cb8038b5dbcdebbdc75c8d2c8f7e05481ffe89b31760d8fb3ae02e950a0aa5f33f104dff270f8572a4b77098ad6cb004ba28904e8b470e1bdb5cde3936b029bb6c1b734ea8cfeb7a835ce07fae4b76a653edfd1d1c2581e90d456591a8574f52dd46765e6672e3817b7c3ba3a38a3fc2b1a4b532388ad2dea1dac1850d3c2c7d642182cacbfbc5dff8f364167fa7991182769261b20bb12d5fdd4d4654657f7f855962665e4a60a85f72e5dacbe1cc9168899d366643ec7cf5e4b13f45ad8d6c650f9da296b17a03f2b1593eb7ee7eae3021a3cf390e315c0ddd8477a69713a1b2de2e8370bd1bc548950671952e602eea3c4619f865a90b3c1b4bb37f79896103b74690d0f4b2afbdf56aea8723885f4d324cabd19ababd5ee975d2ea9ac174a4e6807c8f0fd50f1f2bd039b0c79d20833f55f3138b91b2785d379e21ab673962841d85733bc29307d5f5311a23046bce14c3c750312fe27320e64def4d995f20c45eedf2c6b512b9feca0a0f711302f8965560bd912bdf81ec6a8e1258a970047547cab802a985f302df1b65921d6c8665e8b10bb04046543bb2de94323075124cb2c2ecf084fc7d3839aff631c7590a17e8d53647577da26a9e1b9940c0f8f18bdc57fe8d5ada238145c4a479f9b273cfb626e48a52bb04004fab9541c0e94093119b16d5891458e7c11724bac80fea8f71c20dd3efb09782405b954dda2290fdcec3270852a2292feecb62025f15abab92b5701bacde01177a290c357fa8de9dc4184937fdc10a41b967ea721b605af6bd3dd243b30c62613102f61dc75d37695c5af87907086febb61a518ef9582ea3d9653f4fbcee8b1861789d22869b4a2c2cf4b61b5657537560f80c876fcd2128deb01d3463eb35f10e518ef279d227b8b09b2f8876981972d9cac4d02e174f82cd783f4a4f0685eef249f102367c96ec8a015f7b186b748418aa546b64e3e904c969d8ec20e9feea8aec6a6abb655768106e3674854ad3f355648a9565f6f5c2065f0b9105e11c21a5b843bedf03e4a9d13d31bdb21990651944d866f3ee09bd63948829192ea7c4bd4a405ffa65d32a8a8b85e90b77f3f99dc7670897cd3e82500905bd30822e99ef5a116f830eb16e209f322c4674c57e379b29aae9fab5bcadd9b9006dd30c3024a0913381ee54b09c3f24c10adb6322d361487da18bfb0e5b5d59af4f1b39f6a79044833348c98d5aa62ad39e72e8c41c989c44b3e9d2132237c8e63f370c1bd342a87e40b2a0727c86b82fc5f458540f9e15972644b7447624977399b84b4f6887b9345062e56fe19b5b55a3ac8ff5085c71b1d60b6a37b5676155bb6d41d7e9a11ac6fab872fe26b565960fca2f5eaab8354dce2ccdaee5a0fca219521894c63ba35d0b451f5cdaffcfe400c0fa7bc528b3318fe9f047be8bad11eaf9e938651c062ff9b7967818bce3be3f13ec53812b480583be6127f2b48d369d46fafb374035eed19cd24c58fa7675f66008f8092df8c4f6c7169a79c38dbd4e12b3b9a6f14010a2cc0d4be68007c0f46a3137ec6783c29e3804402562161f5c844f09cd5edf322a5567b5107e729e99b67eff5dc163f872cbb1edb5e9b07a3f47fdc5ccfb8cb991650f21a084d1353dbb5e0f75c205de1d5c5e7f77d373ebc1add8165365c834348c3ded49dec34a23066197a73a921eabf27a4665cf5899876487c12ee1efef33d6e8db2bd665a776a8ffab749aa795371560a2ffb8682151a7fbcd23ec8ba5cfc690dd9e42ab1a36cf3e5da9e5e93e4b189069032cb094b7f014672908e03987bc8a04e13a297c7a913336317155cceaad4355c147274eb8affb1a4a1c8e6a658ccfe44a7fb02bba9f1f7c652d7e8dd0ff5fe1bdfaf86457906ac5c6b7019cd28730698ef4d63a64d6d564963183daa82fac6562a361ac1685b6701f5c12651ce7841a3bb6d448a370e4eaf6af9fabd7e7c6c347f0718c9588c502c5c7f0ab2b713196e7b14ac9a876f15a9231189878becbd198d6f9bc199e29c083aeb7fb29ee45d6080396f13b443a878aceac6994a1c4630ee435c8d78716ca831c34ec645175fe6063a6ff83d4b891e13ef42c1a76bc5ba17f6d44b86ad03c9cc467894c646baf2f85e9869e7e01648b506ef97f7c1111b894296cad89951db2dfed635966ef842018910587504c8e49d24b86a25d8e3df35df52aa4bbfb707463e7294d90aece0c5d6521c0551fe3aa78133d68f9027fb8f04ceb13fc03ecdb809cc09b9a91bf16fb06d1b92df846a931ff6b966f85972d47e2d7c10f557f32dd8d2860ca53af73296a758aa20295d722d1dc71a9df952ea8afe671eade9482a7e7fd584327385635b63ec33f9d1915edd205a9d92f65af3cb976194d62e605201c7bb4605fcf23aa7dd619c84779290a4ae9328370962916ff37b666a0c872391efbe2a7c426ee7a2dd5c0d6126363ab2b3b705c265bbe441943b443781bfe2d46fcf823f21c05396e5ffa3f1bfc30c7f62afbe1e82811444220a071a0878af0b88c733263db2f8c1173cc19e674e3398f9af89066369ae4c336436ead81c660b73d7ae78668aea72df5093ccad89173a7dda74b5dd86dc0bbe625815991fdecd09ee0b478d3cc770b7b1b41623ff4f5625cab0a42bb4c427bd38f4e0a8831d092bdf05998e7d11eb6854a16d6b6b6179b35308ded022ca3e85b54c3ded756bf61f80e48f19ab9187967659d17b979ce85734d3b456f4ca7e649166731ba05916fafc788db137999d0d17dd1b7ec7ae25b2edcea225af546f2edf09ab48f3e055724f2d6736ec5cbf86c9d75c8276239fea741688f4f8c7a4f1811615f509d117b4c50fcd21ed30f9663aeea6aafe08a4a1765f4eb1e6522abf3820c6df565e0f947646f751940a616cf3300be40f146ec2a8ab1c7b554ebfc0dc221613e3109a2ab8f7aa7878d5cbc5113c684f9b092167fb7168f25eed00554866989fd4c6551e96dd4e9c8d1b04492f3bc5fe539571c12105bd60faff5e4a6cba9860fc29d00b0f20f70ff7c5541250e1733d94b6541fc59355fc0c9583dc8615a1ee9908190a8b5dcd0ef7a78d32a5b76776aa5fb40e55dd8260f157357c4878cb0c6bab4d8cb3ed57414ce7415503a456bdfe5e84b5f8dc016d1fe88b6721e49285a0cf41238dce068e0fc5d0ac9a27f7e25ffd732c01beb2cf53e31446084e17cda7b690b1a407ba9f2ce3a0076a5a5dc5102ab8551c2e42fe858c0a687ce360025ccaea112ebb0326bd56e0251bf0636a54578030607db7337a60cf161158d8a879abdd2913611c235665d4fc5ddd40be699de59a9a03b232c86fb9557c6bda134216cd7d9574b587e09fbed67c1452ed57dd30461e1cd0bad5034934e4626541e5e3721f417fc6889d12ba21b48b087e9990ec7bc8eab06105981faaf45dfc0303331cad0207d0c56eebd061bba9caa85a0c176478641efed21cdec28d5a3d90ac8962c6c56dc2c06d071b43f7b072a4834417f7cba89d79de00c775229284870194b230988520009f88fcf06a5a4a24c7daf8d0c8544fbe406ad9b7931d3cc56287975a5db4b668448d5f236d9d8a8cada033c61a7968094212963f0a2ec74d7eb1bd0e76018e52bcdf5c223991aa283f4532a44a8c89b001c814716ea208f88d887e861dadd995b1023f1e0082410e2a2bfc0272781b88968cf74d08b93050dd7818276b541ea30c639c9a4b25fff1921e90180c80edc7fbc249ff933b0189231045b8b2da5d6cebc7a0346529fffeda4ac22f782bfd82713b6fd0ff682b65d164ae0f4884444a73f00d103ef08368ae194702ae435401a8e57006b9df0a4b4c862cb913fcc58e016c1d167b267dabb41c4ec12e210e345f2faa103e3524e53a2982c0347e19a12ee3981c5f2cba738e70b5d88c01636f3825832c36826eb3fcc01f992794e3be2f0af1bff3381baa86bd9f6ce8f9f23ae561086ff8fc9d44629cdc4cf63cff00be1543fccf12f824230727df6aebca6aa532e562d316e0e7eacaf7f2ad06530c9b8364cae01074c9bea294e58cd196797db7ef703877cbeb435fb70400b1debc2553265995ba0eaab59b1676be01a3f5544857b85e4624555693cf6155bcfdfe037d8fcb9de2d04e9cf99f5f65a08cf37d2d6305a0ce312c0f923124899633406a5e82f0ff67101cc72bb5319115a1068be877b8fd839696258ed749fcaf001b524d385f471fb90dfd1a852e38181f82c37c093eaa834058131c33324f80ad5acc108ab76f959d05e51ab1b919fbda3ee19bdc846dbccdaa032c6f4cbc312e3b3e5a8127dc92692bd38e903faedd995fd4f65de47fef3596405d9d8937fcb401ffbb3923ad9ad37c90a0a6ec358ee017c0282be9d48768133cd08fc716480bfb74ffdf898a2bf9473fbb7eb47dc7939e608a2781e7445aa1ba045b36d6cbd17eeeeb6a4f33930a8ce6f51830f70babe2d84f9c397c1a0bdf310a104f94eb27a6ba715018d8f6deb2434179166b3d8bd233db868d5622a86cda2352d5fe37fa4c1aaeb9d7061969355c00921f89692c1ae5547e24429837f21713f1233dd681c6f567958b5d524d72ddae7149448f073d5f9e051dd2ae8fdba330fd55323fe7fca7f76df35afe630f5897d3ea746108186adfa4a9f330362871d0aaf8cccc924c6ee14bd78c5057d5826812a10547df7e3d830b1b5361ae3c6c90644fe2d3734ae8dbe9f969ac1023c55eaae415bdd979649b1b147be2aacb4f5015b84281607fdf10397b6e62d2d94fd775386d94c72e4814a3e71d21b8b3ed0f53bf6a3788f0f12f25a2b3c5b2ab0b056c3d71326dfb2073133d352071ded2525f4bea51248212be4b247ea7eb5550e9b2f9c7d3ace7886822da3fd457d9a723ab692513edcb51af0bcdbd7cdb4ed60780af66078471721d9da3f2471c1bb3614d9988e8009f8479eb50dc9740dd5dbc27a32493c378824aa37850236b0b94c5e81b82597593b35643e8a035619d4cc0e188d56ae8f6be917a4df1f0c87e2db28b624ce1b2bd5fe9f8faf3c25c5323a575a4150b64267a66d751d7e025485924708026e500a6bab473d5af0e440d155042e348783938ae649eed688db35554ca23e3d88433e0b888a7415ccab9cf4529ba57d45e46c2840ec96450cb1da72e1a0bc16635f6c612bb0d7fd1cd4348b28a0ec23d52c9a3b6c2dd49bac6a156f0beed79ec72e1dbbbaf2845ccbf9b5bca5676d20ea37e174daecd376097b3a52c98a1767b5e22a4e967534d2f594f17a07916d07b3070f6f9cb90dd81aae775e8c65217f239f99d5d770b3066d48967fe5b66f98a29a6c3b451b2911bb28dd8bdd6e52d49bb7bcccee9707028ceed70767b034b168e0ec9f98369648636def2844592ce8e278f603b031442f71ec5f86578ac031c4afc1b393eed6aac9a0bd4d51d9cd4376ebc8527ad5f20b63470aa001e3bc905f6a205d7dbf42f6a0abfefc0b0942a19097962c1cad582403a35c09249d78d036d48365ee9ea11b9a1cbf634a9526cf5b107a7fcdb39ab2df6b43aa77fd723b4cd4bb7e20ea38035e4cfab760711df0befdc1a2e5bb1d3c5d033ca9c1861f3edbac90e89d06c61ed97c84fe0cb93238344f0b496d91a2615bde3bf9c729571a70d68a7896f7e59389bae2b81e05c4f9424a10dce1e76fd346570b4faa0bc71136069c659306ebcddc5473b77e6cad0360f727b1c6b67b50c3f1ab4c065c265c153b539c22538db3b1fac33c485d50eb4329e707166752c90ee29c7707e6d2af2ad82c13f2bad974d73be41f2c7c5367da6dc629e08db288422f669627a4f4d188a9af6524f1cd77fe63ec9cdf08d28a3878540af5dad243f413edc83c7c18c52666b11324b7cbecde283e8e9c9ea8ca51dbca1a87ca5a9e0711277e5cc9c8d5dc4b7730ee020767ccb81a9d20d66fce965432b724e11599d196760458d0e06aac537357121ea5e326a8444fbc28a5418742db75044f685c55cb3055e3388b04881c5a587ef12c70dc1548650c6ae659c04ecbc8c78b089a3406e9984d737bae4f073697d3f771de7750ce1c4c11e04633e66bcb65c4b38a25fc16bea7c668a99555c34e65eb2d0fddde8a8c391c892c5b19a6253cafcdf9fd6b78aeb4fdcad96f1b04f61535e94ad2089f80df5d1c1fe86988ec9584a91044c86acfb1261a35fffbec624bb154f33b4302661115f7e5690b2a6081817fde818f8290d11145f17ae7a17082b0c868a7ebc53b824db1e853f10f4fd22ca0980a05fc76b02ed13f2a6fa69a4307797d0c2c6463635a0a2f73e71d532d8b8e43a494f4fb835a086191bc9a503b855e3c1ded52bad4f4d13d0df3e527a6fff2957e7fa58341d733682ef8ee3f16a83f59feac0f7d92fa0ef5d04118889ff0975981f65d71bda5f99e1d3bdd33b7d24440b294e43f9b5fa30b6363a0eed334820c262118e762f698b63d7164d4540d36e8f760795129e890b7f54a81314a3175e75d318f4576d131a3c8a8aba42ceac5e9dc1ee6b4cbbd03b7db6ca1a8d1ebb2ce78c2a435d6c4c844073977746b6a052e14aa4687be951dce405ae43b8472721467db1ff39c277aa5c38a9f3e7a613b72fc9cdfc16cc38d70236943708d9df2b129cef55c8f589399d3399624efcccb1a09b0c4ec07f661d9d1d431ed8d736c57beb144638613a25e54067ba509a7cb3d1e9c53f8736434fed52220099053e2a62ed2669ce25d3b5cf7cc760b653dc6fcab2085e3f3eb7970e7cbcc258993049f0996d3a0257643e50a25a26774b79687df592155567e81590795a1522c5a7e37912253051a3d030b2901660e0a020ffc60ba4ab07b5b7ae7814d55fd187c72f4252ba66ad60d0b87368fc871e10ec2601603420973f284b105d650da20864a3cc6e5ff4636169a0dd07e45923b8cb2f6f0c59e7611833c4b8ed8eddb22a6d04c7783211e19e45b66da8a4d18ff75a822b8ec5906d5eb4f6e1b3cddac2e11df548df6f25902b7c434c093f684367574e3b6288f478aa42e93ef025e2ad0446944ce1cb7de75907d74363c9dde7535c919fed8bde4d9c385bd4d7cb2b7adc7e1fb713df1cb277ad3d8d1289bf06c2a198a42c07ad3a9e71a7631a5c0f92f05149ef9d30899789d46e4f6d23c5d68126ca647bd3d6d28f9cb028b13363a7c6d6f6ef0d2422e1ee09c1b12d433bc1b01f06a9ea4e89367714fa1e7069217a030e22d7d4fed09fc629e2439cb6d453d76002473e17931b2a0756d56f3ef6dd7750abd228d509d8f107b64758314ae0a03bbeaaaeb51eae43ca29c9467c6686b341e559d87b67a3456791fdcee986df41556cce20f5828c633a79fa59aa2d59094839a94baac423784d20d41c1e584d62033707ab28482b953ff3222ef95b2dcf05842a85833b8a00927670b2a08062ac4fe2503dce9ba4d0a00232bbce2fa9d81d66c6598b3b1b24f96a851dc6a77c321847ca3b2f13aa74c4fdcd93ecbce595797b7d7687d2dbfe8fc6f48c4b0cf2c079a13b250c068394681784b1bdaa99d85abf26e383bea387c795c737cbc3a24e3a44468d06f5dd42d601e00544990df085026db0269a9c3e3c9bdc1970e4f1ef0f0baa82597a57c3fd94272efbefaf8b77b5db11a811e195fb81bedf9022ad4432f9c83a14cfdb964a327f6a9aa4100b42038d7adb4c5649c88b27c15192dd52d31222d48f588463bcdae824adf24c7e46f633de1f8d1c3dc9c5942b37d4627925f0b2ec2b39005392649bb560388b1d8cb862d4287ba852559ce84764cae796cecc4a2f232bffca163e3def75a9e23c9d812b6642f9ecb743eacf41665a2001c9528befcd688fe486d4ab197f9735789dde1963e145618952692a9a6bb50feb05e5a40a49b405890587b991abd8d667b4bdc2788fdfe52a7a7578888442695b640cf816dc6cfeff37f0499c669465551947ac82190bfc82dbebbe9a97175714665efc1bd811996f062f363786572f3480088d69c85419fd1911e6111248b00cf3108cfc16aa579d43a32432128faf797be40f5c6aaa3f39c655e461cbf31786d8467360c537aaf93a00b0430718ce5a11987487f7c9d395afb0e6f29e179514518cead5c2a4c638fa87b3710019f39ae9ba521dc1f6278816a0d69706650b701a272edb9e32a5eeddb864d5c0eea1bb1a554ad29a1eab28cf1a84bd120ff030f0e7a02b11fd4cd2133b37f44498b9ee1b3b5c08601064079653a300424f0b8a615411cb18329d68a0c4b4afebe8bd94c1c10aa9934cda4975d3aece5fab74939b37cd0ab005c00ea1db9ea584345702450e61e9fb261b682629c7f12e365afdca552bd3c2647f8944f9daac1159e0c38b7779373f7878b088155809870872e0432c2ff70dafe80d7b7f6bb4a5f3a7d52d2ab240f5ff08c611df90da426a489edc6266307457ac86ac76f589d45bc11fda940f187c1b830e11c6a4a392a0f44c727769e86f00120cd250faef1bce8f2f81d761dc2fa88b5a56f98ae815e66be43adcb3f54fbe305e298b6a195978debfc4f15d61d2f8d6bfaa67615cd6404aa002bc86662eb59709586bf39bd0c82a67ab151e74bacf72ae3fbbc8f32146cb93bef043249cea4e81374197d16ead56897cc551f0abe48f5b418fed859e3462bf98a3d80e8977110708e2a11ef009be3e7e75b4e849b7a0330877f2da8f3d884044f49d2451583cec706f8d9009db15064f1b10fc388a19daf64daa4e6ad81e9684cacc880becde7623b88b30c8139088dcaa2422e47c570706834e020562b6617102cf63d68fbd9d6d98846e2e4ecd88dc7305738402fe1c1a99329b65357341bf6e287fd8195aaeb6f7844f34b2558e380cc4e68eecc8eb8e6930e1d6ded28f6c23967877e08a6b7a795f85c144dfa417ae22e076564865c1c8f5646cb67e1a3c632882bc0fda8fdcad9c4dd2ad28b55f342cbb8033794adc3c23282c46ed05e832b3dfb0f144a718db6568c4068e4b81eda6ab7a4f73bc612b57545bc6175b6cc5e679e6cdc747694c554f99251f5f6526c930e11c93bd24035a10bb2ff3aff766bb467a7e7b91e4738ae8f9e845e99b5c366e673903d048dad8b67ae7e35a7110dd1e52849f2adbe11fc687c63f20e2668b344af0d9e6b26491e7f48fd5e4ad4ee853c792e368cfa089cc87c6489e8bf758ff8532b0c61403656ab5cbb74a2eb20f16c5b1356086e7ccaaec4cc8bb95d9e1b3320f6eea7cdc623e59b63e36eb533ce80905ddabd3c1100b8a96384c8bda773ff86c7f3bb9a7711426b50e957a4a9831fe4fda9fbff0a9b16460354a9e9304e03c1ee1f3fe288edf2d9ee6118ac828bb66261da6f3865eccca13a11fa6abc33176d5fd6d2aa297f4b806ba3764d536e27f9a0c048fd6154bd922aabd05fa46052466e6ecb046eb4b421c5cb62101ee80935901dccdf93152fd9f83780ac1599c06919821f95c97432823467825b41416a46368c2800909ce37f99796903ee82411e7e067649185446c2d9e77a4dbdf21c0dbd8697ddb0d5b4a769e81c7ac6fed7d50b17caa4b54b19f10b5cad7a8bf9655bbd55df1ce638ee4568ecd93027d85f40fde00c12a17dd36bdb36cdc098099a3c539bdb3dde96e67af4baa0e5024b5b3928924db11c7503356ae3d32ffc3e2e5815719cf134182feeeb9e87e087beee4da76ca49118c173825d5bf24235d24a293be2e7d904599f30b438aaba6f2b439a07ba068017af6340addc22c227967c4443a0246d83238bdc69ffc25e6685bba2e43e1d9dc9a0c89a2f6d52a94e667ca11af19896f5a06362614343f9dd2e2b49ef15d447200ee32e0ef133a20c68dc7fc31db28f661623e03ad87c92cc2fc4b5d1ac5662980fc5891a8d309ec7a4b4bd62b417ff34d26e12f67fc432a9cca5925e7c8fa217c1e862b69265b7753b828bbadff79aac556621ce72aba3b41ec91fb5ae48cc43735eed5c546d66e74eb3ba28af53a45f6d967d3a361aec55e4cacb15302ec205b654205ca49df70a4f550be120ee18df242836504c4364e2851950dec37b884776cf521a94c0f09bfb21bad848ad20b85abba2acdb4b13a3b32f51cdaf586d6ee6b652801728e1e03cace4a34f1bb4ded84db7dcd0efa319eb152d241971a10a1bfd33f7dbd5692f33ab086291ad148030e00d84afe934e444853a877ee58c4869143c7375ad2c2b27a66eae8985ae7cf6c858fa823e8bb9184bd3ce94e1779e0d0b552681852e5ffa887105a3519ecdd2082c7d80a501ca59bbe99002d891cbd93eb183cd9d243fbc0113bed2a26988bf2bac5676eb712990f7bed95a9fdbb1184314c73aebe5fce2c6555a9cd05495bb9c8e53c95c325ff0020201ef83becb6a4a1a2ff8c6efb12ee7083d66f76e385b163a32b0ad0ac1e559de95003d515884045f6d63399321cfb544b3ebdd11adc05962f1c1c12c4f7dab25f14c65fa1faa5a3cc1b7f0b1c139e27afa5607c32c01752cb5a8de2813f07a18dc485a7ec323b545c54c190cb93622246709a0fb6473340f698bbcdb218ddcb6a29955b28e32bd6af53aee3221fede8ee8e9a9f33c73ad9a03ae762d86fdcac5226e33ab57626e93af4b14cfed4867ea443db59be89e7820a2dd21d193d6a0e2667455596ded592059d112474e5092e833a16da8a3e121eeff0e9e2db347dbc4c327d52529cb431e8bc0dffb97aa113cdd5a8d547fadba2b224956bd21a911f61a2c45c675df8c17b8bea5978565fc3fc36d40efb4b3a39cdd7598e41ebb4cb8d75cdeaaad3bae37d971d7e59c6638d8c0e024ad48da0386d48ba52f60a5cf47634a5b6732a1cf81457b0d6bb1d1ae57a3c35fcc5214e17673b70a05fbcaa5b0cee71f902960102b902913983b8050576fe7cdd3344e338030c8858a24bfe7e24a27127c49ba69afed7774b256bba76fc77c726e5dfabc86c533224ceaae995c3200a6fef1ed59fb6fcef38edae457772cf8bec8439f9a8b4d48c5117fb35acbbdaf8464ca7737c0a657b41985fd42f3f27008718e21a98305437a60cc3e00c8b4ad46a5a4d4f327f6e7252b83b45ce5a1f9c31df46d34d8234f754f3e3e2c6531a66c90e63ad547a267bcabad7af8e3298c2a57bb75708d0c41d8de42e23c8aee43bdd4622f8e01874f0d4f198f1aa465c24611f629a0c122a3bae1ce892d4767ecceb97485635ca85e8e00e4cd77dc2e4b8c6ecc9acf0673692ce47a22dbb82801b96931a865164900e920dd7a14ae66b0402c301a1972941c53628d5cf85678e1915ac8f98b47370d733164f67e95fd8267ac3afcc30e686d792bb318945e3d55b4db1cb5e0da4f145e3af1caecad21fd6bd89d68a0f0938c17facdb6645891e79d2955eacd38b140b57895a1a1613978e6fe66e56069d61e43bd1664b20255bf6addf753d6c1245d074b7c87dd315e064f71b54a9f6d2bc7722b3d97fa6d9917383667ad9eb05897c8a5e5078d19088bb99075b03b063ec5e6ed4ed59c2c4a78f941b3cdce01fd917cfb924787cf0b712269a8507289392d37933c357689165bab0ef7326676f3970449024a2de392481e7aab7329d1bd7585d4e924a7da1aceb8fdbf8be10b38cd76c9b268323a2b8462ba84dd900826ea2a68a08d4d249ac3a259665c4d938883aa8b629e1b0cb95c4ac536659351e3118ca690caef60f084ae64a920c3e73793a554299e7e82885c59977b0fe140681a7dc7a29fce3fc85bcf4166f8f90edea8c615ed3d419caba1009d58dcd8f4eb9af2e574bfba3324e1e41cf8f3a3449b41a25065fe77d06ce60ca9d529307bc359bc2f91eb50202b91eb09cc4fb73a4e23789a281f975156768d72e10811ab216ac482ee885f17cc4a4ab96757500fec9891fce210153a71c2bb806c5098db6600e9d592b2fc44915b1cc793758c397c429332cba22d23b2711a8bc2074082f057f5b2aec07c9c97a97539ae2c0c6c1c09c557129d35d7c2f81d546f4f7172de6a91206c0342ac4f60e12452c9ae41c89e7781b3b1293b0bc0fb62e19f836d633c11d1b75635b4259bb83face25cad790e6c2224815d2ac70454b623dc5ab379c6ab6b342d3129bff8efed33d95ee4f62adec16498712758548ea2e00cb1cfd327386836c5c0af9bc882f0bf4c5628d109ac29c8562442750446ed5b827267e796338d1f215e092b89ac930e885e7850f4723c19078f609356d08743fce88828955f90a0b037450108d20209d5b4fb3e39915b7b81902154bbb57d811ceee6fec21cd76790c7cb6a13afde7dd9f3e10a6ccec79195ee31ff8772dbd91aff081e87a51a701830d0a7dcf68ee6d28a0a7fbb22c22a904089f48d8404106c58b96c1f8aeb159b324f0e2d5b10c7f418fa0de89f6a6c0eedda5ffbe01683d4ad13df9db5e1e238241ee727eb94f770c919dd2156b22e9f8c7440b389737d68ee7b6b366d78ebaca90b324d0acea1d43cf1f76f83ce39ae60d4428cdfa146a12d18eec8d8b03c58c4559d4990ae490e35995c8e30d34ed0d8bb2a131a041e656defb61e49e92994b56bdd62cb86910cb924e98bb34296abacae46566e886bdb69fb85e052881cefad0d796bd53cde1e4647b78c827ecb805b143ec7c62041d0d2eacf61ec6fc3f1ab362747f7806b8702b44b026982986a322fad97d8781725bbb8907710dc1c157efd9ff938ec200778ce05250dd26c62ca86966d94be136367ae59f8e819f8a7cad87d7254ce9f3b5606555c098be8405969e5f79abdad7b2fa77fa3ffd13b6cfea2590bc81a65a8bacf71f643b95a3dc57ee5e9c329e7a982cf143aa383e4f87388caa8e4ceecd64b63f6427467f52d640ec080dd5c910e41f639f5d2a548939637ecd194118a2f7fd0474be4b9aa50a7cc99645e3b484b1c8464dd566fd992a1e309a4c60177a362b8591691aaa04598dfb22a3d5e9c25c389d0cccae5ece2c6d406d6dcc1888d23a2d61f4b9ecd5e51c41ac2e143221f35d0f625d19ec9fb1fc062d6194f92015eb3ebba722b733870d479b17f67677d747a442eeff191fd40d4820438e34968e6577d75cf388648ee31d960d3c630adf6f9902d2c2619d7aae1a42f976136aadf08d6b6fd54b841a23e65a18296e4183ab50601379e7c2d874ab507fb97c40800d9aff7199eacca6a098b666c352cc3bc817960e9c2d869130152223ba3d2dd46bea8c45893476b755fb3cbfef4e77e1d388eb13134d12e86c1207a1b033c59a0ef7dc579d1624cc4b024c8ead2458e9500f32e4a50757758ebcf4160b61daae118cafec48efd52455e3293c209dc86051db0d472f4deb4b2f400cb11f7997d3830d70e330f4c5d97d94ce888aaa5c4a1d99aa6768228812c681a08cae20ce2d8c1dee7e77280557d483335066a858f395196949d1d0c81216fa667fb497c5e73f99a8d635727e23d13333300175a06c9bf88b390cefa803de5d2800b9b66675cd0641ee4e2399da482aebb889c8b45293180c942e9500ca6977b0c5447f3f2572143da3d74541d9ff791a8bcb4cd901559ac8c3050fe7e3bfbc1ca294ecaf7ab4ad080191ca9d79ce37f633bb3ebb9189be27af5f8b0d7a604e5ea15462a854af4e6794c0062c97c77de95e904be7d6bf3dc7b38ea825c3f63ce76568db43018e68a7687816e0e0b44f71ffcbc2388ac9ea6ea02730e04f9edf22916a77061291afcf3cb20a597b08b7423ae180a3194e5b1124379eb74277e01a2f420c89b0300c785ef3ddfbce569dc25830581f9e733744d277a5fe177b0f91fc1230a6daaa36749ce0289e9ac63d2e3b7edaf919ce6813990a65b50c674ef0494e60b0932ec2798c6fd2cc4976dc7ec62bc49fe577704efc2e441e001faa72892a3054821d0415e232c65f6a1f8721b6a820384d48689da61b85bcfb8008ef9d5f8c71d2eddcbf20b5c3184c0a8268fad8be6f93e8064d056fdc635eb66236427c46f41b38bd224e64a06e7c6856c9a6a11aee499d7d2e8ed146260b0a0534c6e09dfe9282f4beed92a42bedf5cbaba12c8531f21ef5b210d29bac6895c2c71f4b58cda37c0be2b57b36707e1e6d7fc7bb08e751d996ce8829720cd444880e91d29810d1b96bd58591b7a0dcd1c7e244fdc577f02f0c31a9612208decfd2d04c35656b8ba49ec971c027b447167e6ea263f028a08c3fb7f193da6dd190c80e5a11fdc451849512b2be92646e0a6790fb579b87493dd1146d3d995758e1ef28efd05f631fe0c46d773463bcdfd45ee6086f07ad6db0ea80d5ddbf7acd6cd5be4c2ba81cc217b25f68fc6a47f2f4dd2a08f6c3526626af78d219adc4f3966977d84101e08ae6e019d96a944e12c04d67557f06bd2a5428e4b1fd716fb8fdd65a8a468dc025adc33219eb5bd850f3d94cbd13502713646b7f2a3b916ff728cf70dfcb89aad88fd980462d438e49dc62a4f908017df4a0caca1432ce0f1c72c8e04e909fa42a8532d4613dbf59a935dc2b6873500e078a4ca2162cbd3482a3e3676c26d9fb4208a4397e514362e87e87fd68cf1b41e9508eca31408b1bcfb3f8230260fc44f7e4f40806bf1bc433f613dc10bbd3cbeaa2273ff2e0a6175d35c1f06a6a68b6f6c77a721d2d78a18e4843b46a10eb93f9b5dc420d162ae534d5d5c28856fa1f514e8e54b342489951b1d01763596220989b93538cde6b8ebfaa47f3abc90620bad377da6fb5a7ed391706a00273203ce0af7fb77c0593878cf7519d377f1d70c96d26ec4acb2f650a76189f53c527429002fe3c57c5592927659110f664ed49204858bc32c1522fcb19973d55668fc74eb3f494d3199f75f5801d6331c105f879e3bf00a1414f66e90740bca766d4291c99bcbcf0937ff09f841193eb05126ad72ea1463387deabc56e21ea4b07c5a682e60de9e0c6c72fb3996688f214a3e187ca95ce9e61e324adac3e09f4725334ae58609e66c2df2c94e00cbe0ac7e21f78ea8b3a508f0b97e771491c817b5351b57a6be0fa59a5305f220381b769a3f408801b7b34be1c1bc2276f70c079fef1bcf03d549499df12615fe3181cd6fce7327e5baba8687d611418f797c3ca2a6052fdae42268b81b5347e9934831f5bad00c2b011f1e7febc16d138d0d1218e36757863daea872be3b2bed7ca0e6f280f9003073b1884cb55c7a2fc732ada4eda1d5be5f506e8c5ee30e951d4f9de1399d47a6220255440297cce5d5714a3fe6db90d4914bcc669d9aaa7724c5e4dc17d22b3874aaf0c5ec4c40a062355920c1479246d69855053c59766a073dd448acc072eb206ae096a30c636bfc77e42ceacfe1f0295f1dc4a1f93826cb3c5eec457a80a341bbf18b811adb2e70a01080437b3301c90fdba666115ae46cbf0bff90252378ab090beb0a2551c77d7d8d9b08324f0ba20ec67c375d8dd280b5c13f3cd80fc5778a93e4cf0e40c6bf76937a854cb30fa13f4b4e4e51d6ab8f44d74c0c575a17b17a494c6cc6e5cbe73df6f77ffee5cb4c30916d81f12142b7b494fad70a1497656aa35a63e533bc2c10490f50a68a7aee94be60806c8ce52e9a8eeb376f1815d024c79c7460bde1ffd3943ffbdc3b3fea392a8e191a505246274f42d22efff247af6dfbcc8ac282b8ff51449f535d73344ac7a971992473e84e33c3312c8a977a958012f3d6bf0ca83a2152c2f856ff7fe0d7a3327599deebe8bd0da71efbb44040c7c09e3050ff3f82f37e12738d17496143f427e1de4f1622e293bf07b6a8b79dbe63f0a980ec897caa484aaca94f9131b32c2e15e0b4e2aa840c4a4d89e94ddb112ca51c9402a9f970517308ece9743b75ff6d8af0e253ef0917db3f7902414398cab039f508f77c65b02c084ef8c120db6c0c2deab287d746fb7d1878283d7ae594b18e98a98abf122a5410fc0b1228de98638bdb298f4106ee53444b385432950c9967b4db729e80e3f261a2667f2a1d505a1912d1cc5a58b76b59296eddcf5d83bdaca37ef6b866ab423dfc9c3ebd2e6e8c80617fbf00c7d9b988a9da4d5e865dd73a289312bef9a21b92eae60406a090f03786dec9843065d725ec232196b0a3ebf5f5a23b8eab35a9b9d036bb2f2d2cb123da8e61f7310337f48fd07319c896a3f7c2b19bc3f64f2f661f80b9c4f2e59e9d67216c9fff0412753fdccc1d86a0434a7a28db43b24e21430d5cdc41363351186578f573279223a80b2b8fb2ee93a23087e1889c9caf903c1e6f126c800bb517cf66eb46622136e574d2569015598cf5a465b174991819c66e2ee162dc6890e202f22d6b8c757ae505a67c46c93d16c78bf423efc514dc45b13fe0d86e6e8e2dc95652212f9e8f07841e37585ba386369013e4d7dd05de6db9eb15a9bbf5916746df547567f09446e444d6726e2bf9580467d246b7ce3c8fb2d007cb6a547e87e4138515076a1455b284dc4d7848038ab703e8e9217c72c6854904ff164df16128872c960eec89088f3d852b9cc7b1938e92fd5b01eb6f88d27a4380a983988557745e524b6d1a3c38b3196fbf7800002e10247e02a336eeac239c26f70b5728ffe977ff9f6ed4281a6775bbc15f09a49e3564cb3cb525f8bb0bd6d54ce5f2e91fb5cb827c5b4b2fbf4ee7fbd7816e9febe1efc2a739f7f508acdeb4212117499d567308402f5a5781c64e80a045eede248460ec0fa0c4fcf13fee6bbc7928608de541025f72df5811e3b86b0f7ffba556277f0b318b7d8de6922ae1ef2e57b1a5c8cb09f3901d7db25bb9874324854934c8bae34f12457c531f0574a35fe35461b95529ee5ffc9be076aeb3fbe2f54225834a963cba3d6537f32247a45256fc175fefdaa5a3a46d47a264d801fba5466855c0844b3cb042fd50471aa2eaec2c45482e07aaec2ada6551d37b1bf853e49210bc6cf48f196b4490f449094ee3f34bba06d87f9e10f561d803a5917c33ad04ccf98f04ce21e5c4fe87328343ffdc5d4488f00ef5580db0b131b281570af16243a76030ad4e5d732d33191ccaeaa868d7cd850c11a0a65394fac87c3308861e6438385c0025409ddca41ed90685bfe374b3990050a326944d8137d844a898f4b33295057c3de6b87f27629478166a50b147eb3a7cf907468c23f5c6cebddad95df73bede010ff9a8198ee1b2e4f221fabad90f8eca38733087c262e61c73f7004844919c8fa4405af33034bda965c7c2aa232de37b3655edd3af5e0c01152d7ed21b7044a8e2ad2a410a93d6a132ad46daa38f0dc18f697e51834573ce89fa2856dd49a24006c31838231b8e89701e7138aac317af3d6432e5a3d42923c16d937a0f32ea4c44054b68b83430183b5c90475ee5ad1b3b87f59e416e08c4b5e1acd9653f1fa5d661b9684e657cf10e28447c0bdebc31feb490254b9a7221d0f1222530376834a8213c8ce76ed1437ba27c232de6a0119376efdca4a765cba2163948fe34aa68f5c99997f2ff45d5c432b039cd1b05604920e230a16ccf2c14998142e41054c7699ffb100bdbbd8ccbe8e752d9d16368ad3995f35a07e47e6402201f9125c06b94d2407734f3d2eaa4e7157c8ce10d2cfeb35e4dd74cae324faf525a34ca35bca73c2d5ca6335de8f023e32275b508f7ca2de8eb504b3f2ff9cde76f71f54c309c5ee2698e34ab354f979caf0116f43bb23129c64063b1c317fa07fe00e5d9889f1a670b3c0c1f09c2c7922395ac74b6b7f915a28265e5bace85426f6be367566c0a031693009be574e7f3ef9287fecd9ecf3e5a55fe79b89a2ff85fdfba0272bfa53f1d601d08f0f1fee02d8d4fe731a0ab198b22b4ec8bc344b6d744f41a180eb9c0bca477307f0b314cfc69184631846bd3d0bc06f8c91d41aa844f3c341a031ec4a75716f8fc6ed835f2f5b069300829240b0244fd21c35a07456385b511f585fa9480a889091da3a2ce97d706cd85f4127f8c240d3f88ad7f92ede597cdda09ee1d792fd64fca137c3aab137c70c81a311db8687153e23a9002d86f24eb528451b0b3ddebaf0d312d7e8ef5c8e5de62a6d3cf31e025186b62874077c890995d8283e76c2b081296b3e53b0cddff62a5c6c46471c0a08873d84d5e13d3e039d485cf63713dc7fee0644b71763c295539129045e555ab7822616d999a33862991082601581cfa5d3c3f069bd407020723bae8772271fcc601e7a5dbf5c4fc740267db7e5c90f3d1798dcfe54f99dbd51e738000ad87c6c1dc740ffb6a5fc04d2d27a4778ffdf9402778ad3e4ba5a1cb44ca710211b777b706b5afe466e29536e70b4e70564d67bba0304b6d8b1e2b42ba1b4b6c80b4fef2f72bba792ac2479b2a7c5d73c86aa4df04f46c60488842fdfc11aa82dff9e0864e7daa377948edc925797cd28528d17a12b52bc05fa7dca5b650a1d3a4488765e8843264af8a598f039cd6bd9d07c8ba4067e64ab19e7559e793f7cba48cf657bb505d9e7571f948264e5e135760cec50dd05aa076e077e0e625983c4026f893a3ee8160ff23a575e36943e1cc429bbf5b7e6dd26ee8a9e0e7a5c0aa52495c16d511e66c87db7a96345420ca16554c8027d71275b46da5ae5c51107d77792518cd301e3bf43e344abe19ee61a9590f128fef8c0ef62d134f6038914c0de290d394d71df8e4b4c3439f978561177101859de5522e3615649dec2a84a92f07827a93f5201b57f6764ea433cd1a7eff47085928fce12442b17eacd67931bae154c589056d09a70aed8e9eb381ff73f532237d98abf0e51795b5d3594cb3303bd8287914888fca1123d9c1434c5a1dd99798007cad2eb77523c99d42ec4aa5550e1691ebe8185b60c00b8f3ac6413e387da8f0e49cc33870e7cdd21fff3b12d235c20250f7db8887e5b828274ee4a964ce46b1d83e375f4c45ae47652dec473a2738ff2c94078aecc2cd84eaac95914efa29fd118e69529bc6b19ba05aa01b38557ebcdf0beb00eeeddccaf0be08e6bc7718d7b458d6acc471a1527396090a15eff80afdcac0d248520d374117296272fd3bf9e27599451e244791b02e93a82cd656cc39983e25b4fb7442d21d14cafc058f7e4c642c26dc327d2cb1a61995c96ada2ab7c9a7d433631109a6c98271a427eafd7fd88bc725cb4b79c681dbd1968a6fb399dabf1215cd51fec4ae0d971068333f0d111bf3de45458cfb86318bfdf35f81aee55a29412c55ee36cba8733e07a5d38d5753e6484f01814edbb693152ecda3b514d428b8f00a8dd4c0d1f103a689058459319c16cbecf3c2ab1f9500169856125e053c90d3b096837e72a97548b9c0c074aeacc8769a4a923937a25f4feb0e99f9d43844b2e1ae955a547f51b6c566a13d4713733968e6ba9a1f9262c3dd92998c0312fba5392832a5794105e55a27d306e76dfdd48c55cd9393913260a256276576be842eb361b0cf0ff8ee66d9ca547c0e94bdb0346d9c1b60ddec807076d37a1f075b6b1bcd965ed1011582d54228fd833054c0472bc51dbc2a1beb414e65bca479fca9561fffdc97c192923d132ee991a062213a9ecdae1f795e319afeef52c44b078826e16a0a42ef564c89bc45af91172e3bc5b7d1e340527e8a3beb528922f37d0e14e1cd2ec1453c1da19b15dc88542ae0ae5910d8db4ad256d01e2d9f4bf84ec53309c0c10552f4306963d852d032b1fc231c2bf5fad7e05709226e631f46b7ab5a42f17baf14d25bdffbe24c4eb08a2070a4e02d44114cadea58eaf6929fff1a2eeb817a4169c135b4e07ea13c18056ba4ab6d0ce56831310b7a7c4625fa323f96fee08f4a93e20d3aff7338ae130b0693375953c963f3f95e2d8443c77839a31bf95c376149e4e8371de0e3dd7cc146f31caa85c89464030ef352df424d79dd93a6e65311d307d3674c4eb2c8050a5ea5f1cb647534239a691de88c86c754a72506210d181a21250807df049f4d896ae5b354e8f5d859ac706e2563dc4f9cf124ea33a17c697b17cabd95a3b315c01a437e404087e62aa0e92d2528730fef3259f4adbd198f61a2178ee165e15ecd2118d496c54936a776194f0141193a0126fae66f6c43372cc2c7d23deb5be3ae5229aba728e0865a685fab023addd47498ef36e23d49c32bb8d850c21366571b786a02f1b460cc8a1f6c266c168235ec126e2dc5fb7b427e9e9caba5eb5ed5221c18c9bb35dc154ec3f8d6f43c00d3eb78e2d120de6bb3e6d207a99317792aabb956e2e3c452f8bb0f0fd99b98f5a197f5007a1f7e2507365943fbcc516e2df70bf071845946fadde674732c3b6c5cb507f409a49f54e17d06f22201e0e3dc3027ebb63777a60075ce4bd331b1df26735429a730e10a166e0e88fbf539048452b123e4e84262fbd621eea3c9de717089828eef852ceb5eb6a844679b21f8a6157ec1b88c490f2c31036a085eeccf30bc9d998b2cc494d57d96694e8a08833a6774b55a1be46db08b2e514b3eb16ab3f5cc99571505ff5866104c419ba2f12b7b77a5478bf9dfab7efc7749e1d915d47e48351bf384e0938509eea067e844c30f9e9ff37347fe802eaea9ca9d8820d69ca24c6f392cc49b563bf82c255d3d9c04ad7f9596a127096a54a6422b880d13cc75224ec82bf7871410cdbfa3417084fece2209224b73c504e4fe024cb8ac1daab78ac2a9f7ddbcae359e41c47ce97418b2a504a8b124eaf172af21279946369ddb5d7f9abf283cc53ed9c27241ef46427670509c4cc6964b2712d1cb9bd9933321357ea9f12a12c8660fafc97374525f4b8443eb7ed194d568d19e7f9a68421e2da712b76681ccfb20a885555ae81150b7bb98b13219324270694766990d81fa7cee12821f49a4ee2b9ad32cda0770ab4a9e21a7a3f136f964cbbaf6817cc3259fdaa4930d6cb8066deaf35c738921b47201cdf241898e99be9871b947f91a54204a54acfc26ddc7a6f6e924d1c8e47e97dca6421abe8c977495c7177ff854b542b0810fd034fa9062c9f11b7199ef7340c25988af49bf244ab4be538726735dae375822a5125e54ec8d86b924a2f94d6fc993bbb68a66487c8f6f60e2ea93d586176b949e72fc4c87199ebd34c3c2da9f0d1904d7b090fa3121a3be1b433533e01cb6d91b87c61a55e001dea4f9d4e0155af029e63dd3d01342b89f26ebff86f3be4ccbebfc0f41a90e3256c0a81468928591956ca7fb5774843dbdefd0ad883162e03a7c993c1fb6594f03beab49d7c7e2eff9af83284075cf5272f27a5625696b8d9e7c19fb1052c6bccfef13c6a026bd33824aafbe5ab1e1d0e42505a08fe0c414326effa47b5006340683d290439dac7b37bc790e6c866f9a3b30753a9ed135ddf71f1d046e7d6f09ed6086ccaecae7e97cff00edb7bd61e3a6e331a899c35d6bd04e63d17283fc1a4320d534703708bc4c9a33e965619455e65e418ca22af8c33c84a351542fef802fe81a259ec3f9359fb304d160046b6d7c8b848d4fc25a6f3f7f3632cb6dfd4686f5750eb8aaaa688738324e063fe8d6c20914f2d83c2e2eb67181375cf6a9cf28fd4dc46c5cc2013a803dd851e3a92acbf85f69d9a3b6fb56830d6d2cb207b3fe57291028b8b6b96720af1214703865d03955f148393354796bfc024291dd129878737c15f0e33e07cde01d8ccb40458cf492a6678684e17d0479205b84178ebe07b266a1af01f6a90e0833667bdfe4cb6f031fb530f3da19dca4d0fd1ca74d3846f65379deaab6881b392a8940fedb99ee432a85ccd1d4f939d19d1fc5638ee8fa61245811255480f336ef33b7e0b058962ea235a9c57f2458244c7c9133abfb2a6be1d05bbee5b1c3e84ae7d5d57c3260c76c118afd2f7b7177f1e4269f6e10213ab69074b63d1756e5a627560cc84db49b4c2854cfe61ca0d108e6e0ed4bc54193537fda4587915de74dbc0931ee083bb1682be4c4946ee0855b4394781053805827511fe88e7db4e8834e3b1ee33cbd35cc7fe8650cf8bdd3ebd0446f380ce9e09f8636d948d8624710f5ac5fb9a0c7a3895e973eaf391d0a7d07249c3a1af8940610773bddd80fc6c73f6beb3d47dc04747ac8b213327c4a7d83b3674d05aeab476a8a491c76a91abecc4a98ec9c1ea7daeaea4aa31ff74fdf5b06cd24cb36c0d348d91a2a95dc6257a22e8822fd388a50ebe74ddd0261c8a1fbb2c6d4f0d515a3d5b21d4e1184f960a3d2221202788d9a06bf2656e8d28394e1209c5b5bdc6fe97c005d8cee05fb52ea119854e93407a594f37b165db0b70e7d8b71e00087f0ba7c0d8e0ebe58195287b69b1169c6c8d5011898b59f164c43e33cfe6e7311e18c3c9fb3b28f1b19f34bf1a1bd20e55c58cf717fe21892700a7b57fed5530300a07aed97679ec17c0ec12f5f72b459b43955be112400df9c291824085b72af06783adb919cf8fbfc90283f02cb16b69ce7bb2db23b5b139fd371472790e3973ad3d60654fc26e43c412faf79dba9ca9ec1c816ccaeade29cf7bb9df47c6c39825bc70e1bf94079db52c92dfc5d3f138efd7716475c09eb4514def37b6cb48b2ce73dd8ae193d6a4b32c654ccbbb22b373eb9e880dc4a2eb91e94253405d35a6c7083ae4e1fae2bb79fdb94d7d76b04e612d40c0ad0c569771e6aa11cf8b6a4781e3a277c3c2cbc5061f5cd5c0e97aba9c96a591154fb816b3afb73c7eb21294916a282923e6aa4bc944c74b55b0443abb77e31c07229531e23cfda6de889dd446c2ebb18f0037c1aafae6b117bd148b6ace7fb85bdbc31f6bd82e00e8175e6643bcc551a5f5c95282aaf91a7a68d32818e8c3b428d90d9579d5f4cc885fbedfc0f40fb558d75f80775ebfa8019d5997af4f2655ed983b638259183044adbe62d2d267ba8b648e4372d97023230d400f2c1ae84a4162019f1463fb4023796321bbb20d91921146969b12574ce587abc150b9078c84c95a9ac4809ffafb480df50145a7435335a0d50494f1b1c59b518b92cdcb0b743e2a4fb1ed1bebf9008ac34ff843ed2b018ca24c8b61c7eb8f1a58ab8f5f902940103b9028f397579c77189d48122d20d6fdd860b3052ec663562c8ec7f9752f54c030c1712b13ffc429468c4f90897d13a119b0248b23118dbd45cf19adb91c0422dddbce9e99b539c0506d4dda09e8e7b1789c19d044b31f39d271b443568a894d26eca2b5f093529036535ff687750235af6a465b188fabd4f4f98243561f04674b9970598cbb986ee7798549c399fa3754fca9f44ff9cac3b6a6e0da16fedfc2a027dad21594e758d2044ba1437b3abee89ad990c7904323aa639cd7f7c5e3a5ee2e8beccf9f5acb1ed68149aee4db270dab25ab669263b0db90068050a80d7b92e99856ba66ba6c24936e2c232b278cc0e8676a64a863216787b793688703aed831895edd14802ad0a423d17eacd5333a75e74f3a539705b93d69d48605fb6852b573575166e3b7b812056ea16d48f227286a90e85d2711d54313b52ab120e9f2e6d8050b411923179de47a4144f1f4d9eb4b6767c51dbb3529d83251f65e3493557ff57e00c2c2c4a1d69da5fa59748ca3eb18579ab47fa3f3155ad2ce997f1a14f8d910f219746470b076654b32a9b6706c1b8e6c9101be29fff9ab2f16273da80232ac8fac83a14341739ffc76ce40de3c4c612ff2f2b2a9f30ae3b4706ed91da1aeb7bb1b30e7315785ed268a338b7ee8da3a5c5de719a66edab677bfa534bc26c5f7d5b758a7a38c295093ef2eb5de4dada718a1c6b9be9a9dea1fcb6c7745ab17827263d617374b977737d7b5c3e378618f191e9d2c7ee4373d539a1b8694bbec60b5465f79635bd46307c2851ff4d3f1b5dfa26a774bff5faf606d2edf5d10bae09a9f7cfdae816f9a5d8e834347c91def5d788ad2e9088e62ee4d662b23f91acb2f58ad0b593debce202f895e9716da5aca4667f22c7641185fd1da0d83b0c4525d8d316f509bedf9e54ee2c9ea0f91eb50203b91eb01b788e3831cb43a27fa3d3d407982dc8b9e9f70f6d846a821b14a9d74a47841d9609695c1d55a8efa33510cbe84a53fd16f51a0222b25a2adb88de6e27c287d00655f3d1abb5bd14de657ba391fd7edff7531b821bbc22614f55867b28be203ddaf48b120b4312d1cfad4d2c5c9d1692f933d4b0d3ef996030d5bb744315d6e3517a287b0e6c97af8802e199ba33d86996c826b14fe80d698008ce7aca3c03dba1215ed6e3550d90bbb47c3f3a84a38c9270fe465465e1793664596341cbb465a2f377bb9ccd13cf2368964502630645f3d8c7df5ecd14f62910b5425bd6ecc7ad80c8ffd5beff8e4bfe84733813ce3c85ab68b580744eca4497834d68019c44e5676fb2f58a71e0c64f31463c4f8bd70ad4dc6494fb3d351e178d9546db3dcf5a88dd66e8aae4f94d377174b8c17765e2eaa46c8ffcf0d98542c544f25c619fcc033b475fe9d57987efd354e04492cfaddd6ce30e9dccea1221f5399ba5c304656aeb4cf41d976823d79e240f38ad4f84b6ac4f461581b99c40eee8159737e155e33b13142e86cd481c9f82a6b3e35ae0ff1f0626466c73659cee1b8f6276c8b267b865e73cf60ed5d138681c7d862dca7f219aa678c8c347f853cecd7e0ab09f3dd62bcc1cb286388d9d110a0ca7bac2091a8c0107943a6e1bb709156646c00eb812701227268cfa46bcbb1121d2cc2291a983f8791c7d0965b2945c01085106c812d3538332553f225a3d7fce75539c99978dc894f78e20365a45341d862f69d1a8cdb7405b8a512e0d611c82148116a04262919ff330c7cbe3c950c2813fc6feb5dbee145f1883e1ccba46a6adac91d8e825d904b84ad94001d251ec445fa0b37aeb1033bbbeeadc3a8a0087808931ae23d36dc1d54b96fbc4dc1b0c0ddfe1264a834f9ed50e728fbfac0e53e5ba44847228c341c4b16e0d018985ccb9117d35f842ebfa1fd4f664b6ef4dbb61bf843d2d8c1913bfc2dd6ba94cfa2ca3f8b30e07189b0099a837a5c88607977fd1fd3f8f2cced81e0aadaa118eb83135e628274b332f145500348f9f15f164afa4a0dd21ab08da0ae9125606de02b1095f49042df59a97d29e85385fbfbf281993e6d9bf289140f2fefa45507407a49cd48c7114b43dba7c7230ba65f3e07cb9b361a14f90a27aeaf0d1846a30cbfaf2e991e08572a19e1cfdda03959673ba6ad535e5c490160f26ca93366e120ca34f70d094012e64c116c4ed434ec9aa88e9303b5de06ed43a87a8696bc9ba62b56d7c3f999f47b2d03f17ec5fba86a197bc1891d822bb25c09b03c626158e6742bd27b82a6847aff64c1a78708f7c44e1fc36f7c6b9914a046632ce86f671136d0a68ae8198f8be0f08f7bc5ecaeabc3625dbce92cbd1138d41a5f558556d1d1b992dab2d3b1c5ec4d4252554015553ab4b2cdbdb0cf71eefaa8ae1003dae3a5fa25935f944f46eb34586aacc85a0b0785eb6e5a44404128ba89768385617da818036d3a5f0323c05f6e948228ba45c50328d0a0fe192a1a038709c1357fd5c2186a937d4ccb2ba034c472fe37cfbfae423452e908e41ae2c906e617203ef8ed89eb8bcbc36811257e2c1db74ef2672c2669d3ecef73d54053d386335530e6295bf53226b8782b9e56c607dddcc350039cd8e54f1c8a533c0d621c0effe7c30f2cf47123087b9cd5763ade81d6ff55a2aae62d15661eae459fbb6c935cf150d7b76ad9af7aae510c22eb59fdbf3fa7b8d669753b35066db8c9e9b22550ede3ae3acea0d57ec734df2c7c703c9a1ffcc8783f6424d4b6efa760a3931eb2cfb8d815c71aa8093a616d5d0970443d9739be73d76c070cfccac86384e91465b23a1af64c02a1dde7651e174a48afdcc9193253ddeaf6256456db2b804ad08383503cda31ac0e8dca0b3eccc3821b7110dd60ffdbc837da0d639664d56c3ac5bb0f43b030419976d4b074ab0dbe8952adb278bff0c465e882eb4d8e7be29e34d6a2708fce5f178ed3e309871a0a9fd485de547330742bd276015e48121fb7deee3eb17195645f9a90bcd2da480a827d08dd5b9821527353cba1d2b2c84ebd0ccba61f8ebeca42fbf72409d6c1a30e91a52f192f3de13d3653c8c3ccf17d8d121dd808f2a20736b6e478027227a672f099a025bcbe86b8b22593dfe869873289d781b225869fd40bb94242dc6a5eebf688f5d8b99d689d45f6eb730f08368d20fe20c91c3b18bc4597663220b94f42aff709657fb843de8d81e8e8e083d74d3891cad3b1a3a90201b260219c82d9662f69097e18603351a79dbffc608e0ccc742f5f132a563ebc53e2214b1b6150188d04dd90db951bef4113722a0545c02d11a62a41ed2021a29568273391afa258c991fe6860d804390c72dccf9b6a4dfa737b7175ba1be588af81ab1c996daed368e71084701f0fc97e8474912f99b0b2f94164a925dbaae22ef1bf05a54e0f6e1316af7c9645e2b063e8a158e7b3485015d3f263e2ce49f50b0136517f5577999f7c60364ddc798e14dbeb32ef18d56f4376e8b86194081d164f3ab3f09b43c238ffd856a85d1ed5898095e0a6f5290fc275ded8492c335235739a2794cc94adf3abe16432c51021e7e38453e21cbede79cdf8aed34a7c2bf2989cd022b902fe7ff06b660c76a92a4869df7b8fa877abc623cbcd646915050c0249623cb9e2252bb1cba785a67b3b89e3e87ada5349e106ee67717a3a8c862fdb90b6ca6bd2c197242487226e80c4d07051affc8bcde5b1c6c15d30c389c7cc0d5ad3108cd590590b99196cbd9217c6e34408e2e8ccb68becdd88ee19bbe2d9449fa15d0a37eac9511ba974b40fd0b75be730510bd8d2a5baf672e510bda36386c582d4b0f613120a377d2106e244071a8ca4ec90fa1a2ab2c9bb547d40c3a1f2ca81914259a8c0f29b0068b941a5703d5dafe8f70e7b29c4aab4469174dbcfc4710eec5ddae2262dc0fd8acd8a2852314c709d15ea4a0335f2d175e8878417929834a80155682ea3b31489d06d8be9aecba48d75be67ae2111fde4d2c9cfe54eecb1ded235c5f78c1461d444a6d87282eda78284b59a2b503952cba43287797e197a7b94deb6685f705affe2b882a307b5c79f2f757016577e8f52b321eb54e244f029c66f37daf38f31392911444e30687e373e8d83746b4d7196f8db9f1f2f7db5abffc61571ab912a3f3cf58671e623c242339f445084435d68c707ddca2b3858407b7f89e16204fa59918cfcb93d7eb32215e1c704ab543848d9640069e1edc551db3ffaae60068488c90dd8218bb415537ce0a9c72e3ac456f373a0238886fa1d3b54bc4daf8d6be0ba013406b340adba86b6f55370b1a0ca2e6e244ed12b1e739232108766929b386f7ee78d444c8b8aebdecb1943038f830296b8b9380840ec3bd0f68a4dbf3117316d2534cc7c066dca798683d1715c3eaaf5258d3ea5f212486b9830fbcd91a1a0b4a683752489c13cbce50f95af2f288b606820a9b173cf3f8916af67fc0bd10aff74ec7f2ef473b98b67cd9c60f9f9daea24fc35c6bab4a8dc8a7572397aaea44a9ba0d8adda7b3c26a54e7d9f1d342cd18526b55f93218a9c587551e95c0372f56b9accdb39d81d1d074fa1cd2f9793e376f41892952b287429cf8115a7ebabc8c0116aaa7178a629f9b6adc3082d314eea2472cc3a44bd2482b2dc27aa09ed2632aca54403a7dbe10e22edfab37246f42a8faa3e78915a46807bc09e4e241e335a78b7aea72e2cac627f11d1068c401e0004ed4de75e0779e7bb768f5887019680eaedb9dd0b2d81ea13795f6c0d18a95a3d8605fbfc2e2ee832a14cda65d1bfa2cffbc3d057af9e68b78d580022d4957ce6280ef5ee3de277a489b78a9a4e74970aea7078ee872f779e72d8f3150135be636a8b7e58dc109455574521241e246e1faeab8d6739f01ea5069f4560ff0b60d980e9010e6791c9a994c8747e155ad3c6f455abfb64fad8bd0b1f6b296c2c22b17d093cae2b5bb8ea1876bbed826fff4880d9bf23830d8e6763e4cac2e17f157a8ea87c243611610bbe141e007b9347925df51fb7af04fdd630e9ddc1ff5c74e91ceeacd658cd960b0d521036e7a5a7cc1d4ee35ab410d5874f98cf827d1893e4dc140668e89fa9196084b6c00d7750b29a1a5739b9b9a7c04ebe14ee198375e225856ed5a358aabc81e794d0a62844e96eeae2a667d2b4d4d9b5ea073bcb77b441207d64c3939780823c6e32ba5eb69f39df91db48a7857384ecbfeb3e544060fd58033129163958a039e24a21401962373aa75a9266fdf6068f273f29dcece5b0139a12832c58a6b2bba127fb61509d6af96d0199996625bfc6daa1ec70a868cf07007da27fa752aabb16b279a0d8b9cce21031d4d66efa10ab42e311c8882f7b5ff4592e703e093c66bd73e88286fee778e39391ecf549a3b65c01246b1a517529b44e49f8194e770696557fa317e8ec93543fefbd14d601f845e435715c0f7d5b7b8189cd9f1b8ef073b22a0fc4cb8fde2a56947e5f18e0fb552bfd6a5c69fdcc11622369abadba91b220994fc32bc374853cdd11b85e780a0f8db01cd97d1a7fa78cc890287ce2a79e1a2b06d750112f51a7f8072208750ca727e838858c3fa2c89aee7bb2def75681746fee694e1f29583a71ebcc7d527df793a242ebcff2a5c9f4878ae3123c8ba54054033964600cdf9d5c3cdd66facc838efaf5b27315771348df3e5119e26b48fe3ea328aa0c2e742c1d6d7d4d2429207ac42a9ec86855aabb4fcc5e651995af2e1c539d711ba082baf677b73456ece3e3f0ec8386f757422a9f24197f2b24f63d282529b2a8725d24a40c688ea8f4caa8b3ed0f636a4793ef4115a737390d9cdbdfc6a3c02138804eab3070173c8e6ae30337786ae4a4f6aaf2a33e07e460104add54e0189af37c3d2d50ad960361c5b32f4956f7761e4737796bb78a5d2142690174efec46d7f81cb0ddc047d22c20ed4012f23d36242c7fb0c474a68e0d391f952c3ec84daeb1a3be7ec09a1a5711d419cf72400b80d1d77203c249323c2c1d99c2698c138e1fb868e4e8f528cd1f78f84211c25db72b2ab63f73fbebcb8132a50527b59395a4e9582378fdc4bb415f2a5b3edaf1a8bf886f183a3229b73e4de45fd2273d34775d8679c66490e04f7cfa6b2d66fc49a3730f89ef5ebf7dd51c3a3b91050563c8647e937ab8e3fb92e0b41b7128e339633906c0f6655031162345c4e3479c74a4cebeda8fd814f61b9d3862be5515f6ff5325b61cef085376cab19febbb21765f8459ae76c98d1cbffb4ae11afd424493046fd337fe9c1edc7aa915ca88ed9dd786d7c7be951b31db54005a025dec6ec448976e204613cf95e87a0069b7027e65592f19e245e475218091de2ce268fb3b987a79381396a3f4bc7ea5f1c4b9f81bcacc271b25f466f372dced4d920dfb3a2d576b4ce36e9e92001d0a5c5cdb3e7439c40b2b8cdf1951eaed86af34183041a3e5b84173f1a82f796fffec67fa6b814d9cf597415c5b823ccade7bbfc6b5a7d5014ae0c34ea1185fac597f39d79f653fd2d8e73871d853c4a799d4edb70d49000f1b77fa0e10c0905bdd24c0dc2086b4089181e22b58fff38a25e36e135ad69fc8774163e37f9d4c9bba9f899391d70041d15d0010ae50b8be6387c59ba4662d647a2019ebda9ddce7220a3d72aafefa391c5d9f928b1e4f0350fb665cdc1ae8da854df465609d3acbc7cf3d908e91fef24b0730ca5734f5ad26703525df5caa8f9e8b6b9d34ad7f123f99778603bd0337011355dcb401ee0f319272d0eeabfdf94aab447e24c7277a6d594ff9de1e0fabbf26d747f0b906d520ceb4bb913a6f2099315505f4f06fec2126f291e96775f9abcec517cac92433aac1d3203b4620177a1013faf24c4f3e965c7883f8a9383a9e74d4b9ad941066792891c4d769e3889a0cec630bce24be1cbb66ad20d70fe4e6bf0ae39acb6346fbb1aa21911d5cb6e52c9b560046cc171b4bd08ecf5d274d7d8c967bf4a7891e41f25df7cb1589d5981901a5a9285deb29ea45941834251e3d473d1dcdb3b9211591eeada7e88f05b4e3e963f2ba71a5d237ed4e8a4f4d4bbc88be3dd69686111a581145d7747ad6103dcff5e015fcd55bea89fc313a880891aa0d69674ed026b49ba01a8d42f0c3db89f4046301b806fe67cef672038186d1ef957ffdb33ef4a389c0276fc5b0b6e311d3afb2144c24fececde59cf849d9081f03b6621d78bf6eff40387571bef38bbe3c0d3ce128b1916899629650a444b19e3dc190a4ba6d5f0e7981298131c31be998a6c87e1ba6fbc2d80ec2629aee1a40a52f6e7ad7d87927f4ab58101fa35fbe4ec456f237313e8d4a44a25d053f6fd2391b19c563e892f1a916a832d79ffcf89e508de8dcc0c3b5de01588c339d590b1ce6a602573883c70e3349bee431faf83ab118d669f5bd012de26f5067df53b7d6c5c1e548d6f1e749b50389f6de2492322b002056c75d472f5d28372bda2638386ed9e980608d5bf2df62a01ef797f3dbc096c2244eaa43dfdec4ff9f14924a934d7cad611c56fc4d8625afd2274a1648a84c48050a882d8f5ec8ea19aa4e761a35159b19304ca8ede8c93d1dfa1d03fbe5d76b9e57a068b454a8634b138dd5e53106b0ddb7d61fa0ea09c08ab40c2ef1bf7cb65a571c3a9a3cce280a4de3b9027e740ddb13b4d4b6b27a2b3eff826a18a7500d6e2ef695d3ef67d4b4c945c566b139b15c6bb5c3aa361f35a37684d30c4ef9afdee5a45a9b2e58839f3ddbf3c00a0fb31864032496bb0f35c52359fd2583196e72108144e6da1c02e8ce43394fb711cd771bff6e0af6032cf5547f0c232c1116f0cd64dce1d7d363c7714b0acca085e3e7ce7775ddd449a0079d100e8cf5e48731157154e9ce187150b2ea4e90db89b00ea13ba9a21bca1855c032c2f759fcc2aa78f4a72c0b73cb5dab91897fad26f9ece033d243b87caa733d61ac621d070fe4afdcf43f78ecc838417a862a6b1cc8c9b0323bfb614efdb299ee11619a8610dd1fdeee7e9bd6f3faca7259baa291c55c6fabcce7c9267b9e2d81f9cd39500fcd177c842c2511a2820170299efe1400a19ca6963facc5a7941a7b2c862d2e580217d6ca8f4ada96908ff329bd483983cd56979122ddece0d245b96d5d70aee71649f4961a72aa8836ae32b37d66968f428c6c1f889abb3f107eb3e24a36bbe568be30bbc54a10086cc4b1a6065c3ccd3eb0de41f6eef74ce4f6c1eaa94d9e03550812b63ba059f1851f6eaa1ef058e35dd8392471d670ba3e14992b55265c60a0b62bb8caa73d812f815500c221709a46dd58d518d1c74924ff8dbd9ecb183c6cb5f16a859f63651c9da23d3cbfee79dda0da73e709650fde10bc9fd6c656617256193d6c072b5002b7bf2db022aec5763fb484fbc1e7211d5c108279061603cc9876321594bd5ed7885512a838ff6a2b2600a2ca06bc77829001f8d0052967984736dc684c5da0e08ccb8ad89cae166179f268b4ac1e2e2bcf7449e6aced009a583d7052f38029ea9e922c8e5b037d3a18427701ffc60ca6dd56c5d2461d2ed9c1c8584589efdabad6c8a5be443d0175c1ee22c97e04a5778c18d377bc0d9d84b23c1833c09ed99741ad64eb47e68e15d303f49b9f402756f8f587e928e8f2aa94ecb18b614f750f71725674427170b29f8e13ba11b00d92f7ae015af56a6eade7d879eaab055920db72109655ee0c627911e6f2f7822ecd3255c5cc33f7ab41c04b36855c9156d5d6dd11a0406374eaaaae09d705e3429273a1917d80e75ecdcc010d5ffabce01b071bd47fec12c61c9b3d5f78729b0d89642f159f60b575dc2d4c3579756c48b0944248ab08603ae11dec76f93d2884593706d63c737037ad3bb011c4686e4365fb641c43dc1eab479a03bfa7537fd99d3e7998e17ab0f678ca43910bc0f544daf1bf0eb6782c4dffa8a383131b420a3a87af92df1a25703dc0904d2d250cd4d00bac1b89fe46226f7fbf644817e0450fbb6e8b38d1813ab3d8559bfd40cfaa8027929df4b45b2224990c8d99cc0159a802442aa0374b8b52c5c08ec9ea4c06ffb3b95e6086a6ea4f08ed2307af7a34272148160badbe524c73b70995cc1f348b5e3ff84f2dbc22f60f740a3c967056e4fc74450d546036bf7a967c79abef661f5b3ee3e6c2bb21edb582d0ca87f11fcdbcd96c7135ae568094dbbe8d84faa99a8167113e9b3cd6f4b1bf90cf067665c94fcf9ebef226da36b5b65b7dd5d9389d71b5f40e34f344d72d580aba5aa622e888b1e874892146a1d88492bf2aea5e2f3dad3bd62b8480175cc2257448855e68d511d4f395e7fee939342bd6779fd4183e8057158d37845f34a3038f51c84885b461cc7ff7ecebd52568ad2729ddb27294afa12ae62c2f204b5d83a9aab72ddd16c66d1b416072b1a881110ca3a955b8ad2d9b85c218f3943b972c8b94ab68a1a0c55544b7c57dd4996f68c0965b5f2d2b12adf52031fde0eb2f24c943583985c26159244d841aff5b303c42529905144659c90a869195d0724cf39e660fc987b68414363e9db166658c6e106726b36398127a47a23a07b0dbf51535c9330d8543ce402f33083e2ffa739a2b452bb35bbcf71df6c176a2792b652ff589f76166b6d8ac5f5a1704114ee8802e85f9c58b8d195a8456298330fcdc32d022e529212f1c4f85c55993a86a1dc17667465f6e5d5afb3a1d0e4b1f32d2c7d6b23e6f5dcd5df5753a15ca274d929f6dd4c17f8d4c7f5a936a90226512ff0384cb6c5c59cba6bf3c7a6725ff2d7e8789119fb34a5e2bbf528f55d405d42d85f5df2ab9e2ccc5a0caf05a2b3e4532a3082b7e6d057dbc23d83b4458acc67070d5fa823187628fc95801e197fa831cd2513f16c40d360b79b0824397641bf5a232c0faf91d343fc848be6cc73d048edb32da4c0d9f3ed51104028fdf60edfcad8c676e1dff0b96b644ee73f37bcb23493308e0f4782cb57f3fcba650a78105e44e3225d3a71dcab1278fece0a1c4814e3ed3c65d2af1e329c8b7cb402bd3710bb056ae805a133f6a06ad8f7926039616d44bb268e43b545d168f311ed2ec3d7731b4b0dcef95274ed77477a7289c7dd96281e36acf56b2b8555290aa8f01dbcc82e353fd7163108758f63b8dc6d1337a7ed29a596f0154191661a00925513800878256152005c2451b22693b593da8edd86f44e9f5a212e4ed2e711cd0443a41ee5558e20af39f3ee5988290837cbee835d893f607fd9fc3276d2c95a4004fdecec98eeb3e7c9a51bb35fe3d9e935e97245fa4c580f4d8020b2df126b3d3dcfa4e01d3506fad9d5477b2118e86b6555819fafffb73a794cbc381eb8d0a777094b56cbd9bba5177f805bf26ccf99746fd867ca6467762473682f574f6c20e60b791a5a63a633cd57e8276ffa44b3c665d873517083ddd778fbbd05676ad5a9fe5d99f7de7f7f5fe226d2062145413996c9292e510797c71fde8e36f6023a1490aef02e6dbacf0656202e0fa7bce483fc3aa94309edb610e41bda48bdb02041ea85fe7c4cfbd8f3094e29e7b0324d9acf61679d45bad5201fb7435ebaa0c3eda600602f092649281050a8dc7dd47935b4f7219d48e92860885545367c5288115ca3f8c9f8424da709496817e9b3ea63cc2315237d2910d81752a0f7fbc4cb93190fa238bfcce198b4cf16b7072208908e4e2eef359b284ea60b4349304bd89ed7685f699b8679d5000b1531d3b3ef17a005d560720726bd2562270da04464adb19e9a8c359d9690c922e8ecd6b1739ab33f12ac3cd08c27e0aaeed3a58a2530fa149004e68806660dc0582e07df634b631a5a7e33513462b86cabf2740942ee6d2b446f264227aeafb6a723b9155393e6c0ffc267596aaccead250f32b7ad2f406d5bc419a76c0804064361c700546a445da4d6b1c9d62a9f679b31ce701ba4623dcc3f133b398862fdc932db6227e0715b04581af88544db206f8dcc671950ec578eeccebaa2afdbd0de710a7eac452384d9e5ecdb9b506bf714d9877d6e4c65f5558905a41420f095ff3c850d197a2eb0eaa4ded3943547a3bba684c922def605cd6f590be1cf58cf7c8f1473e092d1ec8e5a6fa1bafabd134f8632c4b3932eef97da2f05a1fb8ab5bbba2dee89209e7d3e12bb2ee16a88e0c30fc77482fb3f8861d6e94cc9bc3c760eb2b8a990012e9799296751a38b23ccac7e368afe3160ba54c4f1fd695a57b1ae5693983d7a7e2e09e16e83bc8d9ddc6e48fb435f5647c5707ce7d13ea93028e613a2dcbd8743bf5001e480f78383da487c7f66254dd7841008f866464db248a601dbf4a5a211fd5ce4de675313b98ad44db43ed252015bba52087da738c05378e0306f1b70b5c051d6e41528d6c08c7ac67196a90a3db53d2e8d387da6e74dd0b3f8995a751d952e51db1378c079025e9d036bc31d70af9a5e7b1f941690c0a17b2a16a4b8e958fa4bf7e3822a8c83aa0b13262d4185e01f3cbdf93e36f3df04e40636206d94954fb5d0558f8b57991829452990da95be0b021549ed4a4d787055cda477a25467541fbe81bd4aedf2126a9a219771e3856dd90f08c60b9d2e345e9786a14a5cec1c5efea00628b1247336f0b4528bcd00e93a67b4cbfd6cfe1e3c175ede25b46352c37cfeb32b497809730eb96f624efd2893fc76366b86f62a282d9685ebcb3732899f1e4133be83e7b175a3b646d73907388508376942a74bc36a35cafceca4240f07424f69ab9707a99a4e3645116d99b453026c65e1f615269b1c57673daaf7c57bc9682aa171b7741f77747eb2f214af8795a543f9bea12a69112eb193cd1e22f503ad9ac4fed9ea360ee61b6f56d3e44d575f4c59e48c914912f325d89f9e056576621767d801355d1f4c2dee70b24a49d67be9d133982ba0351cc5395f5ade45d0243fb01cde619b0a80c184f613d427334ad5c654e14f5042ae9e70c5f656cc0488ad7f713b6d445691b730eb742663a817a5207bf429fbf742c8e0f47638c52fa2594b5dc7a546692903ab66d4367a3d892c219c6a71f8fcc23ca00ac1b987da76729edfb065a59e0367e93ccee29eafcfaa77b6a913d312cf6af902930105b9028e39f7e5ee7f1224f27d9268773e615ddc98e38c64e0baf7a1546173dbe346ea7842402347a13a62e9e2b8ef7872d9cfa54e2d425320bb1de2a9ed92a40c7eb54eca2c44484b5f3db90c98a69e258b209d38d7c817de54f0f21bc8293e5a6f17132467ee99a6c1b174930d1e8dd2c1a3e5630771f7201c1183c235e62d18c893e200d45ed68a394c96c970af87e4c2ba3f2a04317d9cd21e4db74b5edc943d32b4fbb899a5c371eb40f195d312d2f83088cbc6efd1d585463a546968df9f3c6f7385ae5eecaeb0af348283acc65553874b00b6e4dd9de61fcadf29f4193e2f42c7ef6caaaba96cfef455d7c3d114cf6ad336577eee46578e01147ab4223188d3add09622d76ac51276b8e8cf8d423eccc175a6af9789176206d04758f83bbf59a532f50a0fb700f2eebf08ee04d9f12a9de8c40940959bb4ab699eb71549ab19e967d172ab822494695e721e9b5d500bb7e5ffdcd0b13cf80db2169f9054f499b1e4f6dacaa1291483c17afe6990827a4aeb6d2ba4b07dedd2aa95d2edcfdc32ec02b6e29fff547e330d6eea6e23628db10c2e394c23f0038f449132d77a65b53858b9cb7de3b3c48d29b72cb53daf9fa656799358c511ebaca79b8ededc7f0d4c8635a461d9113dd0e0d595ae422ab0c66f514baa5c1929c30f29b77dac3b42330e705e0cdb911e75bb5d5658bbe2d2ec0277f08c3f457d8a5a5c66988561ae51ae4bd141ed67d3764d006ff0fa862d47b0b5c7bdac6dd5e730af3f5212bb962f1062c7cad3b9129c5f8a4b7cc6e0dcae1241d3220927cf08b262f239e752eee2efba5ffb8c35f1bfd6e21b4535a4e1282526e7508eabd1cba46df56aacd3441bb3faf43c8c912e3ab368dd3356f17c2cb96ed4d157a130b27df1576e625893024061cd2659d56da7823f91302e5cf91eb50205b91eb0abebdea96595d1e3ea0c8b001e48f6bb81b15474739b847cd60f8c70e631ac7cb2e8f124213be2d7b9f96b0354210ed7986a0e026b35579901cf5be31b335bc2fb3f77e6a1cdfcd9eb00f949451d4e566af9d66d3f98e6cf53be10aedb3e274869de2816368f5ba8bd65127f06f8f10059624fbe5f4aed8ff1e072fd9e663fc6b561ca377a248b2ea117cadb706c5d092ff3186aae90de258484b270407ae89e6361a30c78729aedcee3252793fd32605b16801057ca9892cb77c9c170ded318b3c44674679951001767507267a55b5ddef1ed492bea11611271b223e112364780406be03f07a091bb87303f70f44f8dfd0fc48984aaad1426aefd852dedafb1ce84711e0d47ade62c35d0b548e1ee335c3e469cee1426721afc6a50556ad3029f6c2630bec9f61cebb377753c86e51e1dfb3c8e47c4675d4b6b309f8a3db9de3d2eb32682d35c7d2c265bcc7b3855d0e9e597f893de80a142be3f2f3a5066d63834d9793dcaa97886d32ba5d3aa1774ec1c52777393ac61c8dfe988186ef713aeaec84c3ba00e84665c68500bad19ff1c80d0a434c91d4cf7688dc5418dd8ff62e0b7ab477c87ab2c08aff82178420542fc206c60068d696d2621be831d53581dae7d7b831239b4e8d24eec5be2bb106da1c5072359ec52fabacd4513b0174763a3f61cc17135f70ce701754d719c6a3322a4b015fb85b6fb721dbcca0b724155c24090c86f965deb509a25b339bce950c0472c9231d1d22851bf2c945a0778941e3de4d98978fb90ee5f317120ccc3c8b54a140f5d5873dcf929e19323b4b542cd5dfbad6bd708daf6bad1946f0175ba67e8c305f9228dc22558c28199e3b6a94aa9873584ceb56fc3be1f674f8ef0f9411c44dbfb1062e1dcc284ff822fc29986b146d01f8076e98455a2f49dfd1098e29f1f29f4cc44b68cbf6324a5226c617f56557c63f1071666e39d6580565dd3d5c1bcfb3daac05c46986e7e49311f576ffef91062b089db715aa8b957cd471392e1779b40b01c720d6aee36a5df5282fb51f034693e71f80a41cc3729f08593ec036e7c60971a5e45961e3814537ee5b226840c9d1b8d1d3e2608d3418784dc4486bf342226cfa6348170a547461ffcabec02979320ea4061f05006d44a767a841927f7eba4924869e6ce32aba9535f754b8c0d6a71e04403a40ef3f927ced28ec1c866b6dfdbafdca6bb3fa365babef70ed40b999e9ae9279aae61f272ce736e51f2a8b84a2521063a308fac4e36c571ae262874b788fcf97034af1f7ed04b01e5335c908ff8127b06b2f6c290c820abbedc05e7482a22932afe19e41f166edfee51b790d7e90c18124296ae0228897bce4c5eceb650b0737427f724a014165abd2d27936e944f3c6739707a9d5fb06c488f3f43378e91a0c6a745317e006895e94a3f5002f3a9137869e325789d89651978b48ce03ddabb838f40b29edf9e5ad18f5bfcc595d52f246b5eafcfe6c58a95410375b282b5f7d950a3c682c99c699b90fc6a43c030b379dcb8f6bfc2e5168bd36dcb5fbf56caff6871b636c20f9a727f015031a0e033fd8da94ea181cef06908f7aeb6a2c6e518bda240b39eb07d5128dae76b58b3a820a84e8ff270e0e650d5069c3498e792cc133078aaa61795bb63e680451c106f0542376784081d35fe9348f54211dae6992b6632e89e1cec736c62a3aa83878c2a3de5469e05abb52f09fb43941cdf0659d66781555c6ef84dbe80926f1849fd2b6f896b38b501eb61a6d63013a9e4a6744770d2fdcb6f02e6e44137319208422f6ccc509717775ac4fd4ccdf96b207b16468293de3939abf700d3efdb5a48cd569b6b282ee45d58c8e3fefa51b3150391fb128981d3300d0947c0e1c2e5389a839a7a858616b1fb1b1052a5a083eae987f6c8df5009c7871cb908e2c7ad87f2cf4398611c6bd0c3f5ac08030efff9b10028f6d6ee982fd69f6ab5775dd56fc7d05e0486a6574af89c8911063e5fb372c2b956dc89a978104066f6cc2a9149a5435c8ee999f2efd7edb1cc28d28429b076a38822dd6db8f9f9c4390c6ba0b75fc61f6cc5402486d4284042bdf18bc21d69c06ccd4a53054b23536309a0a12bdfc0e541a00afeb7da969d2f38c9397fb95e86feced1f6375e3d3fbc402f59406914798696ddccf87639b3f6d7c488433cb9d331abb9853875476262a497069edfa32af163ad847e5b00f0083f206471e630b45767b0be2b262384105c0120b54555ee38be3d37c187d3d7d73accc92a4f1a348329b7f20aeb39751fa163c0e5761db5768eec5a2ac1a6e63d9729fd2933c9ffa3061869636a4c72de9c46056e3b300f7dea2d09a5675250c29d91014d8884d7610527ed2c677823774ed0edf2f008757b33c489bddfb4f4d6e6de748a7714599cf2c97a69c8b4e7e16fe4a3bdec036e6ae552cd9bae87fc2717b7781624abe07480d85d49a2896f6d0dfb1c242351983af888e4be495fb3e70df8ac21ecd763318344810effdb0a462077886a7ddd3603a209b528ef5b46b43ef11b454705c5a21c0ca6cb58a1805e22fde6727359e5dcef7de78652d198e49c2f0ce7ec2a105374c044fda4bfe12d4210a7a9aeb623f1d6aaa26ed22e20403ce020c8ddcfee9bd1ec18351c25495465263e5d9037c1ee1c7694ba676c6d326369de0e6a381663db04a89335acc52ae175c8160ec123b1c07a4772d4b069d918cd7c074813637064da57371aacce1192e7e9519d8a916780b39c33ae4e6fa9a3ab8c4e579e730e51adf19d910a107a5d0e2d9d6326428a9e96ea6a65d0e8b2fb96e8ce6779e846ffbb5a5203a70f39dc7a1ab9f784d17550a66630e5c60763a8f242bf9a83fbbd21d3d142dce8b9445a808ad47d72fc2c61f4b3e4d5569b2e781d40c6cb69fe867f3b9b4fe5242ca17c8ca6ac46db5273dab199e8f33255e59ab316dd54cde82db348987cedf4eeee0743d7a7c149449e3ad55b7eb9e4d99442edfe0ad0889d1c04e8251977091904f85fcc57cf0dfd170981f79c3171944d87728b5ed572287b3849a7e996f2eabc2f8b78d141160d36a2ecdc0183a397109a009f41f04b4b80808afc7380cf6e665f9870048e0cd0e73ca192649b2c12ab28ef7e4fa827f0b5f81dbe274ca429495e56630e3f74d914fb98d6876effc8a736ddf29157dc31a5398a1f273ba6dbf26a16b603032e9537dff25ce66bff6c4493aea81601c94aaef74dd5e29db07850096a911c473fb408286106b0b895a85eff87f0afad9415fcca82f9b2f63008ec8abb683897e4a58c24a06012de2e3bdb4ab38b582d22561534d2a46938af1ac4d0417881ca9091f676dcdb2d74dfb6d67fef398c7a1b49b414c39161b70d95833d22b7e8e4bd6b22ec973461af3296b5b47c8cd6449cd6808dddb5f4338975750b4b020b9873f70a07f5e8afb47490d6d153b768db3bb4e5e51f4fe8e83a24398dc12e6b41c0c76af24f2de4ff58290cf87cce3d9ec3dd0dd7910de9b065365628506cfde44a139f6ce2836e44c003973ce4328fc6fb3f72a3650bcb3938cdb0c5b126fd2b381b236fff773db3e1ac89d2f4d29698e4546e26980816c164d4550ce1fd3c7d681bb3f4497a40bf8902858f45cb704226abb468e0020878c269f53cfba465b6ca591d99f0b1196b3f54ecc55561a5466975e4a6a5b0993907d90defb88c61d96dd2cf904956e3b5c0acb0eed35f1a1f6867e3de7fc4652d8d67d0d487b210eaa1c3ae05733d800965c2a51d0c8b6e7cc842ca98288b14d8657324794f991ae7eae9570e661bbdea65140f9aafaa1eefda3fd204bd06ce7fdaea29350fa07b19c9c37665601b9a4f27993fc75dae54158b0283c8f4d3c028fdab092ab82507e7b4337981ab2ddb477f9d4c60cc691416611eba1d036904e91b8b441a44003d031ed87b2a1fcbff876d65ac03fd7e603fa8dc6ed1f9887b69f13caa95f749bf972322a8c20cc8961d46906458fd106df80385ecdfe4a74712291715877305a5e2a2cdede753f4d97f162df524df3f4d0fbe611cede08c5dd6e0388a1abb27feccf83d761c4705a28e4eea742ab4845b56463a4ce9d78e346df6d66d27fe3544396b1dd6f29e3840b5896bc33f65de418621c1e5c4c1723674e22aae6df6016978e16df0c24efef64454e6677011ee1c839294ac0086125f77d273e44e097d8b7ea1104cc228122fa24bcb5105e163666ebdccf5ed9b694ffdcea74ac0ced28fe2b8b97b4cc91d15ca300111c886ab5341db90d852bbaea616f001f2abb993260f85cd1d893ca454f7c92fe41c6dc30f6229d2ed672a3bbd1b5794a3a19ade9cbdc3b42d7c8a90b6a0218c1e9b3ed51315fdf5a19ef3e36e6f8e14f11691c6641d45e797538a5debc386e69987eff66bcee7f0fe822332958b3d0e88940d322f5ea529cdf409e0194519b9eb7361a0396686646f58c17d22408d55d755676ddbff3e66fcd53727a6a638bc4ce107f9b027273fa0c97d78d49dfe35e0868c64d0c0dcfa30e24847c5eb6ccad396147d40edb99a3f2c94e8f29d1c3f6124526080385700af6a03c694ba31a4ebf78cc224fd3064be3f1101c5d967d41c4352679128a565ddadb27cc27959a47d4b630543910c320d96ff731b9a53f35ee8a70e23b6f18678fec23e3bb0ccc82aec75f117271cb1ee274a20fe5175bee39aa561b87098b5f518cf3812b2b987646faf32ab7c4d11114b3b23958029a03837e77e901fc05ba19442d9aa94c21941014502c96965bfac4a59a56ede6d85d60a844b03b7800648691ce726995a6036c00df2596033cfee38907e51ca32b534c742b714927c858ee8e845a3d5b8076e60d3ff111e81701e2922245bfe8b996779db6967e3183830a581c98d8c4c2dfcb039f6de78d47e7a031f836574b5e979ca6ecbe7f8fd96602bb3af93277758175a4842ae3efe55c36f720184bc3d90e37999a8e34ec540b952241d30ebb712d302930ac0e3f9d35e6393d4f84560d860fdcaa00a76b33157472153fb6b6e665e5217e7cd31586bfa51d3fee798e46df0b79c2c9e52942732ecbfa17a69c0ed3f595ca0cf86c29985973f56110d4bbfb2fa04c2dfd0bec383c4bb082b6a10953eb594542ff6361c78363675f256306ee7ab5af5440fe399342db71c4cff6827367d0f04bb75143a4d9995b2a30a6e6bb3efd7bd7972d80809b7bbe7c4ed127db0c7548a7ab796013d951dbd176c5a952385883eccef8a9f4934f3f659d057851980cd6de928757e7826562095cdef45adc741117c94b4b97065e337588e3845f4f271be3902c2b43e024143d2aa957c8bea8c238a341d75f89044f68f2234bce0dc95102643202311447fe8508dc69e2a47393981b5998932582b96e2fddb1342ca1f83c045c455c209bf49d658edc5ee957a6fda7c99099b18390e68272914c8080c905322daf9d137e84c405f85f96eabe6541a02446bc6dfc16273adb634efd9f0eedd0e672043db6290da0301bb4825bd7efd6e711e414c2c4c5815d2ae3048bb2e164fffe5f606310639953396ef6aeff148ab7cf1ada311f57e90bfdde80e094cc9750f7420e93e935c1e5db3ec077d07a27bf60c2d9d53373ca57a8954d9bc7fa2de75f378660f482ad35f1bb19c861ecc86254da1b0051fd27f8ef33860fa016ce8e89d5d6f8e59b2fc2e03c76f77eb4906a025302f89bdf44c604caec3720630581666746b98776dbd26f144052c1a96cf08fe933423abd014444bda7cea9b5744ec4e7abc8b68aae2ebbe8567b1c12ca3279c2fbf83e1dfb867de965092d49255d99a2f37557566def52dfe3665e6b9eb0ae526d4c17aa5e505058b275638f07af104b479c07a4694e4f88471e9d7e4920625d63c3ee2460767320edb51f72cccf74ae77707a32e02f12bd783776de466acc8e186351eaceda66ff6b74258fd95748a282282a0522d2112385834a8f4faef3bc0c1d6626d9952e32a8313bff84a44f3608cd7504e9a02c0afd367e198abd371b9edb4c84a6dbad6eacaea21a15af218e3f73b14e379372b2e1906a21b07d6440174127fbc559c69c64168fb49687a4006f09fbfe0d499d95632346033ed78a3326a677dae43eca6820fdc6dbe645971ee64f70420268aa296f43b006595b2d92120889c72f405110c313ebeffc9ff03231a3fdc54080b11619383a031abb22b128aed9a3117374567f945bc1eb0b78255864f5bcad97dff99a43bb56fffc1642eb20757c0263496a24f7e93c54cd348dcc82f0a15a9996044a0b6c2c0dd7262b2369898a7f83c25053f53db64dd3d09ea57d02077fa8e2d8967d37dc7769e438f64d3afa400a5f2922083c0cb752d76a805dd45dded850370e6b48ca7b93d95ae4664c5e8a885fb00cbfa3c7c5e98c2876917491e1a960600c5b88b0097257ef0f8b778ef5ad9b5e03777ee551f8bba372a0329db8e6e6e3607a6b5501a12925e1d452fe61a77787d1229707607777dcbe884771d904365d37da0dcafb44b1b7e4fb60ebea956069f8ecab18045c60b7915e672c4f04889aff04a34e1bff3696214fa36938b1ddcbda40ec7e96c8ec422c095b34e1ed191af8e052e81efb13ff7983de0d3f85647fd8b01eac27a0f3fdf45185e45d453ecb675b7eac511a41e1a2f8831285daf61a9a12f40cc935801d0761963fbc16588d3baf28fa82a553156235ce56362cb09f9cd7e11ab1d0dbda8fd505811d2a00cc4eff22573aff6e5a37f27fa351788c63a79d34842f4e4931964374cf2ae723000f88f604619cf9abd8d5fa5d81bf4c19ab06454437809fd56a4ac91bbe69ef876fb4cae5d493bd707d467787576cc3b49f1de413e241a46b00df7ffea7521bb95bda1b396d4cff625bbeef93ca2459ad5187612a39b787ac7d89d27eb23c777f770cc7b02c060270af2e2b25ea232899fa9ee497fc9ef06745dbfb9e8e6cfb839aa22eb81d0f5d4b2d7c0ffa2cb4bf00e6851ed36e68e4be9f906de8e902073a14204469b254374bc55424bfcd2eacf3b1beaf8e8b4160abf9441c4bbe355e1e8d553704d4c43b0daff9c1f722e8319f758eaed7c5fd1510a38cefdba0132bf535729863b6ff123ac53ed6e5e62259d5a7e2372fb227c43c60790660a0b6710e10167397ca3839384ca9e0e6c1ee7d88dc4be0c42c5edcb9c72ba1a91f99c357fdedea4f21146b31caadbb643fd1f9b44640683ee200fca19a0afb6653ffde56004553be359ea1c4fb3c3e513a2597b596240751e8094526439d9e32cd21c3ef2cb5cfa3558f6bf65756a60fab65eb29813311920a7eada6398e4adbef67fa5c523436dc115090ebdb51ef0aeef615fcc7a5cde2e50ce00389a7ddaa5ee12c8fd2445f9e1877afe20c4dbb0ce3e0e5cdaffa660674b4a9d3dbd4c1307cf0b9da096d01eb811f54ca49072cb185a2e112e910e49d616282ea4bc7565f4db245ad3c34f57ebd0a9d318cf94173acdf0c67afbf8aba6244d5b68ce0fdc5efc5941d8a1ada9b5543ca3c15bd064ffa205743e418ef3a0ab282c1eaa6a43c8ce37f853c81f639fb7787f992f88843eaeef8b43518b721cc22d690665c92a08dfc28692d84affb5db45a40d380d13b649c84e1ca525b9ad49bff5cddaecdcdfad156181216db742676725b43197b2276291c327a62eaaaf134591f4911687887021b2474054e01716868e371618c5fe49e825039bb94c467fccb8dd207bb42dffa5d17081fd5ab09eb292a948cdae1ed50076ac211c79d5c3fbbadd78c66f7e5be79c0be2f083d3ba388432ed15c6cad6ae7555a01ee3684d9df753dc1f9dffd8ff1ce40746d6bbdc7af44c453932b30d85bf78f99ef0d7cbeb7c4246fd283e010416b1e55e2cd7a10ddf23f37046afe559c296c807512f6b2336c599e05fab11bfe69a7266e18f0127e83117b770430cd667dd3075f675f68a244f94cd4fcfed9e70fd09e61d90dc7a4f47627ca1399e98687be2c3309b508e1e9de9a7f6ff7faf3c3e29015105db2b2dd374382c2484d9b02f74dd4e8ba0cab1e129b097ea7b0b278a50c30d255d4651a871fd80fdbf1156fc5730b5611964d1ac0f2330a8efe3179efa6f90a31b0312940c22a125b09e99572b2a66e17de5da118cccabc9b3b0d5320af5329dff876644dcde99a0c17de8679319f76488ebca80c29e32a8de67dff909c8e3f701405fba7e2b6c99cc216002c4d29d6145d38cfd7d6f833ec19f7232310b6fc774b666efaa7eb9606cfcf378e29b06ffe894fa9fde04464ac48fc0e5a5565262ed6fd67d345cdbbff671f2216127961c1c4dc3bbd690787315b187a31dcc60e1bc185423e305ba1e57ebf82a42c473b3f4b1f0d9966b721a95af393afc4b35d3ab18e29a32395ea8e0aa4c8830e926f962036eb0b049bee78d21555a559e99bea66ffa2534707811ad6cb36e77ff034645ad2329c2482ef0ad9648193b1d2c528d06ccddca549da7c0afab665aff0aedcd291d980410f3e01a24631f8a8df2b546666be7d5b4b71101c4eb06ca7f78130a3335692589eac4634ebdea0dc786340f86a3052b194985c808df7c63db840eba10686031d2f3a65ab599ed8ef0053b4e27281818cfa5e3392d23a8f8448b113fa12b56c975e903f00d6d0472af12373852a8667cfd08744f6b74acfa287a84864b433309daba5b5cf9176469e9fb2ba64bddcc4e82f4c99bc75dca7b5885a46159422f0c15f75b6e924af4060462004b42088f9047a675ae04882000aa7bcb12a91a87ebb724854876a43a17103b4acff42147c12468db0b68f14e4b1e4751f894509245e3f71f91719a12c1eb1d9a3248cf0c5e03c7f20e4cca5d196e133c30813161240384ec570aeb9928385743b105522feaddadd2d5a4e3c86554101308c5d083e5069feae44c5115ba47b4b5d15a2fed746fcfffa11cc938f6cc2ae59a70be6240d32ef49c867a56152646752a50c7c2586b5afdcefa6ad9aa6a5e5731c5b0c879e28d34f4c85d4741924fddb3426e76c560b606065bb87e1333b3adfa1d193ed0333b97c9e31f5d5a282c80a6caa2971178ff5ba9afe182765c0348b6ea78c38274814920b9b27073ba1e669946bfb7a076553f990d1ee038d4d4aee7b5f78fa45cf310b60422926ae90cdd94a1e52b02f82a791923c8b4bbf35816559a53c3ffbad84b7c52379731b0c3e792d186c1837da56e99762b340f23a09a3089bca67e5770b1d92df6e4f7304189fe069a5dc560ea368d4368dc09a8afbb21716fae43069d955b1b23f50854960ebe47de22b373b4b6425f4e766bc2b145ec919b99d47b2896b9a1d9bd528bd55600ec26e6a82e6f93c5013d91317e01c429c2ecec59ee408ca62281dce49f132a633a564129805da35584b121f954fda4ad3ea7470fd0e6ba43390c8b82b77a7d6999f4cd75bc12d11bfc3e2a7c77d3499a318c5dcaf254343fc95f11f3c63a261c1b0c81f1e9b50aa448cbe4f679063806d702b2e3348d87fee32edd7a13784691ee93d02e3ea71af51b7280f6eb86bd0651b058965aa3adbc46bbfed953eaebadedc2e3863763d42f8323d875716d1a3a7af20b55f23762b782c7ef89044d8536bc59343636135443a16380370dcdd59e37e7c4be6186a8c6fa19ae28f76f633f902c8d5894a2da374f6f0b4a834f1ce16a11c60bc363328928ecb01997e9765be739983c280a2c17c1cde4e69ab64f76f0b75b38c82abe9c779a51ac0a54e7786db283b964b861c591a1cbd6e9eddac18c134102be80b16bc8550c62bb5346552ca7c10465e84cc5b38847c26ff528748366e47eb992f3e05da9eb1ba826b11add758e36ba7ca957d6f7b360efc8a9808d64ce8d724078dc39008ad17a3d07a441743794f42182a66240831f32e0804ed193f89609db8ec0f3c8b025d5761e01c855938ac61772c82ea34c30d5626a40ff490888a792bc375cfb4a836fd1ee2b5a22455707cb2d85f8004ab3984874af0350b0babf4cc9a65bb3fdfb2364296c61ccd0d8cb6bc38528dd5fa56e85409ef5562bf1bf29a0cf4a55319b9bffc37a19262f99791b727c8e7d0a0babb4f4182a8ab6b26876c62a23a255a8a2d455d89e00dc05ff9fd59c3eaf7de561410671070c4d8c3d1c7d39b2654178f36a178d1d9207ab6d87e7381e101c87a9f91083779d2c7e5804dd79a19321c19f19720847b67c73cf9a7944e553dc36bf6d032f1ac137cc803b7544cb5da561c8f1c9d91d6ccf7ded1024a98805a5eeff10c2a8bbe6a70126fafede79da6910c3f209b96abe072be4dcc603579312cf3ffbc41e93150e254180501e52a3a7b2275085c1caa0e398356f2c971289a93938438f8136db8d9b768e077334d7b1de2265bebf767a29dcc2bae78145ec5fe58da5604bd86abdae26f4566346da340f130d1cf85463454f5d4badc9b5d1fb02b7bbaa1a0beebd55d03974aaa64c7f79bc13545e6f7835d1f66815869dced7ff023c4bb7cc4ae920a6490fde67ba80a508710ece49579b7121aa67c83b5752b57834657bfa3713fd1b83c273e1790396b793703e60fb78d293e1b5c54578dc06843ecae9a86e28dd1b90d9b07ed9d8f47100cdd783dc7cb45f2242d3f8baab2412e9be9f26a219d50790cb2381a7cd14cbd5f4f36bfa7f6783aa93bcb1a5c51997aba85bda95c828455dcbc35655885a0ee7c7b8c745a6a4cae94f111ffbc53de8dec2f64cd1ea670e567f2d58496120ace73e5abc7d93f527b51203957be27de856ed4a57974d5866e8065904979ed0b152aa02eac0868573d45cc648023bd3951dc208b5ae48ff67b7aa85e21ce76f01e36f776b20a3c16b6af811247b53c62492ce6d8e87be44fa9c88753eabd0a4f16b0707dfacebee244d288b77833f07c88cf7cd2d170d0fa860ae240d43315e4d9b98c400af41a7efcf8459369136aed6fd97876c878d4e0c359dad9d5121edcf50b86c49f33485168bb2a4e04adea33ce6b1d441b2e5082238b011df63ef5a2443c92f76339e23adb387a43c7bfc6726f2bebe55e14fb87cd8e6071b61040dd9794f61ac0d7f14cb39e23d671e1db51967166de7e7fc0d1e8fcb1b9ce4c5a948596e56a1dfeacc986ac80ffe6cadcedc9fb975d58e86e1ca29f902950106b9029039d47635f00c36710a61a5df6806f5a13e1931ef4e811335d7cf456ea20a315ed358a7df756b21381bf9d76472714b1c27f652602cb9dc13559b045749731327f046d799a3c6fb1c88e6fa73686ab9897f4c39579df395b5d452519e2b037f5fb44481169e6298e65fadd281b2c5b3e1cac1d29a1407ac8d64915eb9fed661f2def56d323e8de44fa70fc3336dc654d16490c2de7bf2fcd12873d0bae3e5ae64a04c65c745d2834c270e248d31eab8e8ad367fc05ca2d376cea4e15d27884e5dc9de205346079a5a59e4d4f038f1b6d0f0b24c51f3fe35713605b4f6c0d3cae77d1976551c84537254399ccc793b25f8c9f5d1deeaca8f8b5c916a6c50fb0a17b9cd2ba2f684a0885c021cc3cb5ce7ce565250b39749ded6f29e2a662b60db97a9b1877cd96455145233080b02824994675d089625ca1ea7c9f7f574b9a4b975bd473db29d03e2eb5c0c0888f6badab380894e75cafa20887f0d19b48358133f7c1efb98eba1f1d2a70ea5f8be1669d2bac8c958a51210752accdafd11b5327e4f3d748ba5714dce9a892fe695da5aa4c9463c5fff8adb63d6302644cb1184855d68cdd7be365ee2f42be609f1d8f891b693d4f4b5920e579dd7aa39284a8caf73975a1689d578143a4a893c6d75a562ef099311aa8e3716318cb26eabf9e288792e7c2e09b65d4daf92a8eff3c944569aa72dac4facf338c39113d7dabaa49dc0c8411a4863505a602a25d9f5c1abc90fb851dd2cb354eb89f93357206ae447fd265728fab57352c7cfdccbb75a0b6e8b20daa507dc64c638a9648d4991ef20de95a70c2111b1569dc6269aaca7ef0283a896ed8cf30df6e7cad106c3c05a255b6f269377beadeae66d6ba784417383afa586cb8f44fa49ffbeef9aa6bf9ae66163d2e66f37665ae6cc24415cccb344f91eb50206b91eb035057185c75e0dced74cc9079766caa97ba5147d6e03d2e0ee3a3f0d43f22daf5eaecae8449ca045f1ea3bb8158c1e04928a5979db3b9af4d0dde91f61f4c24569fe635b10418492e6b8a9b57f61bdd269394f4ed77f1e460ce861442b48776e814159de3608282f67f11a2efdd841ceb20215d95e86ca5feaea6f6167deaa400e742ca4e4d39370e99f86cecf824d1ab4726f82d112096444c708aff40c0ebbef16014a94a9ac7cd7802cd47ab293f961568fc386dabc614455f7084e17ec001cfa0f01f00f9f2b78976e82e78b6c5d839ac2ee7b4a98023de929c6d5268002d1091054078ed9f7b78a6598def9c6c1519a5953ab28e154c0b39864e0dc11fa14dc582d8fc27d8e811b3f9f1026a52ffefe72c3b1d5b7c3afb602e59c22abacfc1d1433d838569cad8b150698f27b0b4b1337bd430ae3837c05fb9941bbf38c4c3de7099a52d6a2552ce4fb2d712c73d631102d52dd52ded8ee0d0a917e48177b1b39e92f84c5f03c275c46e00c5ecd6403263b92b101344d7ff6ec1f113d4a68e7a7362933269fd943cbea3dfd4f57b748b5d137bea27581de5f2fb433ad92858d022d3b7b8913b42c9bb8b15e2f186b1feaa3200eb8ecfbee3c520cf97dac1b0281c30b1e8277d4ec6645c01de72a86e8f2034392a2b300e995c5be2778480c00885bf0268bc8d6f0e9a5e0b1dc6fc2f1d9d0e233eef8aa51fe122ab0f46d94dac8db06990d37879a4d18e37073d1d56a96f8bc79561e7b1c253d80f758ce39b1c5d34aeadc301980e55b80dbeb01475f9832a8061e47bfaa76752be3d8559840f3b0a3c54e18f5fae90c81160f5a04f41b7d0d9f7654640024a2bbe94c109f57a1fe6d24b713cdbdd5815a58e1c969f5a2888adf0179a081436abe035c022e116b23b9efab39303b786fe32961e117d96c9ae3ecc721e5edcfb887f44d4917f6ad0bc6b3919b00c3520992a631de29e2f57a33807114e3d4b0fbece56b73cb9831202f5a5f6edc5d7005e561f99398f6fb61e739bc1537e8a550f97250183eb0de90a0796f6e8e4fbe3c49e1e0b09ac40d27ea764da03c354a1a19ae08ddc81341c17747af09aa6824b0bcbaf53214554e2d595f2a7852a4f8e4e60c891e0c955a0b4e259693fd41414b469ff3b02eb2f8efe55ac0448ce0bc23612423b36ed5840af0e8c088f6105c7f26bc5053d1f99feb08e863a3bbf875af28206b8207c234c29961dddba96ecfde23e08aa11718531d6a8560c2b36ee6791b1ff4d96344e07eabc5820c4af1b0046106d2a8c6fff48f95eaab4360283c1cf4e5414d983b7dcf3221eb0668aabec7d9a7492e8300c42fed5b637aa3a45ffd4f2119589c372d4dd9c83809acb931bd1b402c3536e3a1842977ba7e3594310fb292fc0063e0a84f74ad09e8ed8f2ffe03be156c64eba465ce44ec32722d124cb0a3cabf32d1721f50e0376001f3c6b346bff9fb9ec190ea7faa2893a566c8aec6575a59d0bad61a86886805be0cef1d786a0623ea263f0ec6c51612654cdbfb7eed579a9ed9b6a998d29d89c7efdfb03e7f2c6e706f4bb18225898ddb573c2f09f6c52bbbab75b625aec3a5bb54d3d5d350bc50b153c8d15b30bb31effc467abc6e5c4fcb65fda4d18966d534e8f9a48b6a07d7841cd88f8015b201203ce4e2ed744b66e9b6a31489d93a8f841672cfa1c63b20e8b40ccdea4e616cd6936a1e1953d8abbba505e3d265766d12635688f21ed2d1471311ac4e3dc8a59c4b8a66c2b07615e1882f8c8935cd2efa1018776f5357d3cef3bfeb4019d43666bed58253c5c7268256f3f313befd29fce3fffcf79ef48b8394c7314291f8e0c11d6520fefdf0adb501b8ead372176fd3412a3288e7271c13ad73a4770d43b9852886b7e0522b23d263ae185d7bf79f98864022df42cb9ced387cfa28620f65ec30f397a94dcfc088c9cea833e13708a7ed8a35a270f1e5454f6578b8e371139b0b650eba349d79a7c8d2a2234f301fcb83851fe4e3ece2b0e7c12ee3cb5aa52a0996a616219a4666bd41b2fd16c7b2808c6758991439644f5677644bdada790b7fd9fa7ec598eb4bbdde687987f1ecd8783fad4e6703cbbf631b5f2eba74588f5e84f4ea0f91dee78c6cc2469f30211ae7c693b105f18ffc2aff2826380914cda75b623ec779bb3e6688e8be538268b241aeb45b029a915431c7946633cf6d62436f3398d8612c1cc2a964ef39665aa81f7abbd9538bd7bc06a4b81b0e1794d3d1469d3f1a1926ce2707b05b3bdbea77328051475548d4c42813d96390f6e7c7dd93215cabc5467466f19e1db57b444bd93751aad842b68e413d24dadb20a37bb23fa6866608db3f5a99c2cf4b57d4b514e8192cf067624b42acc269197c598b3df58f958bc5b66bbb3aa9383faac3290a3e28d0f58fdb643b5c19c568ab7282d0c779743421f117bea799f06e5617a4295d8d301690fb978136eb23d834d529045c56fa740fbb82e02c030e6f6ea70263893800e58bb56fed0d615054e05fa0ab662390a270a2a4b283ad990e928fe9ba3d51be0415cdbddd430afe914c426046a28194f9d2b7222dd0156d5679a718f888546cba9801103bf40294e665080f25f9ca4068ae42d82932be8445f9152ca70679a75678f765e0c4ccc591d4c650c92084a1905420f458adc5f4d50de0d5139d361720d9b6cbf75e291913ad1c3ebbbe26457f9c7b0fb85f5854deb42d690435ae1700eb969704b32e34268d669603c7457378270e162be733a8b5439f21abc97ef1ca18a8b152f4445fde166b2a6288aabfe535283ad20dedaffbdc266938379f110e87d291e6c3649bea69ca1d990803fef49254181e5a6f60820a73f55e8cce9e455e1e925a315550637d8e95c30637f113f62528475ba8be138176828883a5069953d41c21ed231352dbef626992c30f0c26aafc66dc9b0248147812e2498e4853caa5976bb3dabb844fdb5c9cdf19a45376dd20241b875e833aef287755b25daed25a2f4cb1325d17a8a4b4d2e244d56b9e7081449eb5922bc7cdd959dcaf0be789eaaca6fd43fa5766b20676cf28e9c465e14b490dec1def6336a496df7ee79b209eafd52befb72f61a2e0d94059e441e60166de85bd8d045efe4e2df7c290b82d7ff0dedf1a055d8140b19f5b8b9e3bc05861c2af6d941fe03e07a9c282915f37b1dc7cc38eeafc2ecca43f6ac6726b40089d99be830cf2f3dc5a9806e5c94e911892da6531f897271c50d107c6926b3806cfe20ef7bad6217e84621b2024f31bf019cedc4dfef3e0173882f036ffb7cb99efdfb3f4424a21c8103ce94c0946512ce59009c1a4f9feaec8cbc09cbf0cd6b438cf69ea4f2ea6d658b60f9225266b36fbf87681518b8e5972a004215b11712418ddb3e5b1d095854fb79dce09ddbadd8d5c3c6203868dc2e23a854de5df72af11ced55c0388941782884be730b24856d2543fc81b2307406e6a046268f62fc93befd9b3a88d26102da8f1f7a354dd9703d4650c997ddb8317fef68618868e9085101c1caa0a43367a661f81f48b12d2911e0acb0e1465d73c7db400d5067f8285877f7507c48435a2e79da7f7326d448523605d41be02656d38c6ddb574e5b08d063be20d857843c76de4c7d52f550dd9a9e47cedbb75d4c93ba47c071983da28f84aa8e96f2a8e9409f1d1d67478ac45071016752717eef40138e1e39efc779287f0f83c37852608a946155b85b2829939b76586889371750747d167a8227eeb35c11fb3e1e72f3374275c8f322676f31cbebba202750745700592515018d8f2d02d331c251f0fa2b37c4b77598542705725e7ab2e1375d4d284786b1867866e26184fda9029f8139510f8d13c838ccf00f84eaeef36bcecf6d3f47a4d15b4bbe45353fbefa4fd62448f0fcb3e075ecd551b192f60a84fdf47ec0d7d445fb2d012db8b0fcd280eb88e9204acb569cfc14599f3bd15d3911ac0247974d800057b811345b232ba3551c6bb28434e5e7d35bba53330d52c3834701a28fe06d4341c9923f3ae4d2cf97b6d702cd9cc7aae0cf2eb936e4a64396224622bbda759a4968fbc33cb33abe8b88a9f644f2d0978bc3658a3830e512dd4f9b25cedff80ba08b166403bc0075ac68115ee9001f7d469eb85788163eba8111326d8b5a1dd106a065bf7a3a727d15bfce158a203a50239edc119f3356ae0d5512bcfa1ebd276f5da2477f4490804bfb3ad53106213f98b90552cca9960943af2aae9dc4e239b9f8ddb48f8cd6b3105241ef5e5db9a74116809cccceeb753877228d9adeb7ea1a379b3a104fd7520be9c1c1952fde8a0c5e87eac5ccbc23fbbd0b6eb308b79432d54625baace3e7f2ec14807725469d1cc3dde6887894cfea85fb925bf4aaf156d74b25dfb1bae9b00f1876b18c5ae39cf72eabb3f8fdc45c823a529f51f97020598a5cdbb4228180d27c2bb1569e428735b4501a9d323ba42f0805b0840293e2fd8da26dff8c5b90e438f42a5c90cd1570c3260323fc4d48b9f25aab2ab2219710e25e09beb7c987ef9387e2a979f81122e6f5c428b917032af8c3ce0dc13f16183079fbafd329eaf64212be739669aef52563d73d9064fddb59b72ebb81099281b08acb2c72b156c54aca02727cd70f52739a7add8edfdb88ab35537ca57df8fd4ebe6c3832ad1d4d61ea0c39f563ce2f5da4db45bdee5a8bd7afbed725105adab413daa4c2478f6ac9a462c415b20ac97454c5c8a1642275d64f5786c510db093ce53d7dd4729729f82d2045055f5b334d0aa099b29b526eeb3b0f859b4fd8e9a41f75e0a851775af9479bccc7c6bd7817f67f6e8321b2272fafc2f7bd7dd9a17e403677a5284e25fdd73b20fabd40200708f1a6bf58b842c049987eafe40bab60daaf03575f4a65dd6e97e7ff521b1ca1d4238851941b09445e1cbf9a081e98b6523da7356c9287372cbc9a7aea9bb1a7f7f2b2e5e11289f041a46d43197a992519b0b8993dab80c07c0d85265ac124e3b22640a6888b4a74999958928f2253b2ebd8b0f56742a035374b2d31cd7b20b1683f7fd3166bf7c10a17d5733ede59dd950ae96ac3bec5585a670d3374f68c21d990897c44c0c019e0db66570a1b4ede93ec69c0f181eed770af93e6799d15ea3f0d0ccde5431b6a5721faac2d31a7e412ba054324a92778a539922dcff4bfb3894868b48240c2869d6147e8e374b437fa33715ad3f5ae383538994efacd2d2116b53e2a670c9ed151c02be5ccf044269b4027c35bb0e0aee73515553b8590d43623b499d6e5c068eeb590f6564a907eddb8ea93547a8febd37b9c76a690743435e4909c898e102e0f84daddab6c6a9e9dd321650dd1abdaf4068e63ed201ed63a8b25c96d51b9d9cfc75338bc6936be274ef269710f4672a47e251d24fdbf730366892d1dba94c89e7b01b21204e8ebf9ee4ff3526c759e94bcf1711e5dace8aba6bac9da6754092c92c0b3719b1d52a07b1ecf405eece7d6902db751e50bb52513af1cab6daf91643709a08890dda887586a026fce171fa40fca39dc8dfaeaa8ca56416dddcfcd6ed750b28ba8c2186aa5a8db920f72758ef358ef4d7520e39ff43c8947039c0b374e873b3398977dc9ca2dbe2c21cd7abba8a001dc36850a2f12e6fb13f1625a916258e1c2b428fadc082d9ac17bc53e86c296171c4f7227393ff3820aa0b65040d48b08034845fe5541e3c556f608517823eef721453c118d4065f9a8c6aa8fecfb9193b85d28f41c66f89ecb977205b592ae4f4cbfb5492ceb8325df736d7a087c6d9c5529aac7f89d5da84a905827aeb1b933dd8011eabb7dfab19956e195a4f7a946f74147fac90b1ed066584465d181b60ac3392d5baf3e397187fa2f2bd8ad687e673661b386b03447cf317a6c7f7dcfbab6c3051454953f9a036de8db698cf83f9f31b21bf247580c36eadd1262f78ee5a638bf0340d0919a6fe6b1c50b97db4d3233ec3ef6675f70f6566a287bcb971f068ef3f2979d605cc07ec6161a3d5bd1a0ebdf7dc661cc5389fbde1965b0773fe51bb32e23db2ef0257c90cf24b1ab553979fea58eb2d98a79a589dfdd8c36cb73cd6954e5ae2abb18f325b7ef49ecdb9e9d86b1e03a5c25ee3d7c930a3c61cd448916be961c210d45702d7e437175d0426493b176f7d125253a0b6799951c7fa74aae640b0ba3d355ce6c4683aac4bc017de1940985b12ce2b7256a0fb0c54289ba263730fd4331148bf51b4ea69463230d7a7583caf53ba3a81cf104eb33580f0a74b90faad560311964372e9b73cf48e883e3fe49beaf453aaeae7c453f5f2fcc7b48d1314ecf78cc64eb0b7d1bbc2a6262021e30a4cdd86de4eb2cba97b0fdfe3ac66f452955295a7e02e979ed64c3513b161e44cb2b06fd381d911e9a7287f14b60b66de4c166e4fa126d8b19b923e8d33b72a6be22f629c5f58b93aeab426f3c8bff97b4eb9152f94d11a05fdbf960cb850aa32e8ecaf667753d381af45dffa701f4e028ee5742120e6beab3f9dba0795b3448c9d82ce9a2fab15e29f65d03eee633412cc9fdcf6198c5ee6814a59a1fae17aaf610373f26a31e864954e5a99096d7829e9059498c3b0cf935e64a53a69d7ab9e309b38036d11df982cbe5a8822cdf8f94c22c75cc4104b588852491f8c73d6f2638772b79d7bbca5a8f77021fc689cf02bb28f56ebebeb6936281bfbbe5833fa95cb1f11e792337f8a0fb5f91a18751aead752569f9a4452ac051bbbb2b6ea1856ce61f41a000fecadb65b3908d79af2ba5c62ae617563093dc4dc4f47fa4a2a69639dfe5b3f3db08d1b247b9d1ad3b009cde78162a77bb677780be2c2fe246c288dd84cef19c7311f1e0cc787df0348ca45481117faeb5200867712f9e8e64867a28fd51853ca60e47e86875f9131a5f8f0cad79137eee90eeeb499fa1a6ab85e9c38ff5b878ac04c3deb5c3ae3f120df5a5f3453770557dab9be0037052ec0de7b779b00be1a01b44862b2af3dd9490519e809b294da1b24c69f61c501ca2acb5dafbf8f8b8b33b3e360d1fa23df80a21694e73114698a976d455dec9d7a31ec8d3e1a63160cde1fade2ab6c84c3b415867af337fee6178695f0a2d30a2f066d37731169506f22db676ddbff316af1193c51aa4511f286525911d8e6ddf9fe2e19f5e425af4faf458153cab62fb96d60b8dcd8906dbe176653e4d181980bc6edece4f1ac1816690648a42c59d071b06f0ce02e6bb6d85fb03bcde8ef91474e8e857355151820a7214e6e3dd3f0c46b7b0c342e173223027875e556fea80915de7ae12fe5d59b2c60d62d44492b7421c6bb5b5ddf997ac6efbfe8c707be9f96327e2cc3e2a9e72daef94ba76839e5cb8d49d6340a30ad130c619d6f43f49683f74bc34218fa5502d52a3060e940fe5c6664b285982bc3850c5be717e4befd8bbfe26778ad81b2e189fc20e74519206242607771269b225a83f3e193a74e41de99f1d2c289e53050421701e479f79328d2c831a80d750ff1b708f0a0b5c5e07af5db3fb393aac2b6ada372f90217c7f22cacb6d1593ad19742120af72259de69cfe8bf1de615c06252eb47bd18db334045b4844548e4af9abbbe09637acd8551e0cf2ce37644d685e65c012dc6f6aa7560763c5360fd43fd083838fbf320a5cfc4fc3901400fe12f6524db1d6be73fddd81a04a11d8bedf671441c6d650dd816c1e262bd5163ded6101a664e07f606a58de72d247e604da48b00b4c4f96e5d276570000154ee669b6dc1c12de946ab650aa64beb8699e56b25259c658fec354a7dd01e6f3f4cf89045fa177c24acf1732bfa6f13f4f2568b43eada3ed4b8d8b20eac3df0aa4e51d488599590e9b7808f595959083510380566770f902ed2d6e954d40a6f6454b1cd14ced5a7112145aa284fe37b069ccd2decdf5a44eeb1eec5aaf2c9baa441cba83941f204bb479f20046f157c25ef1c3a800bcfe6d8c81d65d90c05271dd2f06150402ddd59d1fefc9a645804e92acb29b4256a9197dd085cd043979ae388f61e2e77780bc1be9ded74940892fd101b2d2d815e185f5bbac519325aeeb6e164914d8dfbbf474490739a393a2006d01dcd5bb02de857a53fb8ff6559ecc0e7f1b37ec410ef9407b94608277d22092d69e40019c302055cfc31af9576782ab112daee4b1848a060ed1ac3d810e7df7021fbaac968bab797eee272f4fb6a440d5cbec5a09b557f322642a862494c81107a258d86d6c0a5528bb0ae26337ecfe1209d781cebbba20805796961f87e4baf33d4c3715009ab0229fe0eaa63d748aef201aad586679870138c908b8ca8c91b4e0b6dd78842bf3271463c83595af0f10d08420dc2d521d24bbc42bb46f01736f8541d3e58287f5f5347269cbb93f978401b2edc8343c0b44e9bdd1b04fd5cc15f5972753fef218c84bc1d4da6aa663d0b7e54d1c3ed051a6288bfe2cdef32a595a6471039b09fded618360cb75941d20fed736f9676801921c9cad4f37a889f353662ebc8a822e355f2cb794979484aaf1d0f36781e5d1a7f14f11e17a3d534c4e91ac5492ca36875479bbf98498db306a5322151ea1a312dab42921a8d8395282e39a6760ec20381723564db60b09ad718b4b14b53956defd99d2459ed785d4587cd3db93c784f6af72c5baddc95707d9c27b32b8553476572b87f1fae3d651066fd5030caf8e75569ec5fc53b5f7749eba3b00a859701003b152380d864bd4696416882770a3c84fad3d4857c93d1257ec95cce60cebe94e60d533e27989a6424c00b922357022bf049830550fc4a0f420fd58522f2edd10cecaa05f16488495be5cc4de43bb8298bdd4e073676e8a06446e47dcd5593a0262ed55044e9245c31e3a800ed0271e2090778466e855a342ce7ea5861f5db47d6fbe7eb1f2933e08ab3c92be1ddc373d0aab5d2619867e8434b364b63bc89cd7a60637c8141e7081fb4e2d5a2e77dbb4ddc9a9e4fbef58b3ca4fbe84ad6dcc2858c63fb99d0df10bfe742607296153c1ead3fd879e282136b83a322a2f060fe5346124d0e898abcbf57fc1fb370ca9f28ca2a8bfe89d4005d6a111bb4d3a8729ea1de60f13f06148f0e48f1357f3ef1a749d2ea99d53306c0fb79cdfaf6e8980ef2526c4eb84b9cc06d33865ef0a899fcfe0d0d3a51028e632687ccf6543e5a35aa017e54874c0153a791d5d51cc5c1253f38081e1b20311a9a9e54fce69ce3ff8a7d242e883af02ff113d4b0d71099eaebc6bd9b92b274d75c936b631c491b200c920c8f68ecd3fcb789c40fec2709ea00bd3da2b97f01340f363412e6b85f32b6d605409f552862d2eb3d81e398c112a665e6ddc011cf9968708c9d1752542903dafc4c8f30141c5bea6729cc3f591ed7d0fd4d83efcb6c4d730c2ac1630c7a1fbf8cea9e320ebec524630d9b309f353f97891f7dd56aa3b801100ee382c24630232972572a970996a62d9787317dc59c69767097f0bd6189febb1af92ccc5be373d75f8f8125d12afe4096377439f2bde2099ba1340bb5614fb463b8cd2dcac2370bf66b2ce7e741ee4e7b09f639f0333487af38f5633c3427cbd0e8ea5ecc9620198bf5a53c1156d4c383e1295b54f155e92bdff6595d63b19f5f012da05eb415966eb530a2231677d6fb0c9264346b0b477de58c8b571a2437c94d8ff2dd3ff204767dad36bbb83cd3c570fb57e3ac1027906a71778c75e20cd464cb530dc3e9ec62a7e44841f4c25bf7a714c5679634903c7dd6b83067171736f2e68428533ab66dd878a7a2c072b70bcd57ea90a1f9828958ea09f5dd7b3d57a9e3b1aa8949c6d909b6c27ee65c98078a39fc47ba12383266bdfe13ed9a2816555f2133e93fdee0979830f42e3df8cd9462ee8c93247cf8e95689902c2792df919b062a8ec88738c389d38cfa48cb6856cd52043306a559739fe28ab633c2ae84d61658a0d95787ef0369d64edc7c4cbecd99809587574c53620e3a642b15186d3b49dc7e4f03ab4df4812bfe82d6bb3c0248237a1cc4ba0fbc00cc3f920df5dc7290f107b8fb8a3ec14bc05e62bf25c9a7bbfe9b75d78766d4d994887518ead461866a269ba906f3adb3cdc20ba6a965345c1a646c422ad7f72a7d0ce72247dbc2d960573da3fbb9a39f545c5e602c25408993a75382d9083dd8199dfa187bdeebd38fc3f27cc0d0e6bd5d64e28a956fab9bb025fd329f1c4f8262a8bb4bfb72e5b26a9f4ff0cffb0687cb6df71fb0c70225ce084feaed131655455c953c2e1b38cdc4367a895c1504acf8ea3aacb01f3526fc5d8b00840e04d0a5fde013e00b593a7c3cbc717a3a86124e96f44cf906960cc327241a12f40acdc799ca7d4fba49c07df9e47a997d74855ce0edc5d19cb4fbb534fc042288cb266adce51d92f4d6ef1d3c964d1921d20a2ed5e61f6c718ab31c7de6a8cdbb0d5ff85ee2b263ab5760491d9ac52f7b2ee7fff06dc8b1a6fd6c96b12bb53d9ad05211fc205b51a2544e18b16ee3efe1f3c776fed6a10b3732c41e9cdca8b451984cb2c7f56486bd72025e6063a39bce80cd842589e4c465823b13abd83b2a111da1643452d47ffe9a949716c256fa43eb036af00ce07022941dbe64af686e46af0a7b3048ae0ae5fc37db911bfea4b4c8cbf20d392f512e56f1e48630b03184405cf44db6dee5ebed5332178249361e9e908c03b1a73878f30c57d787a1858126f4693f00a69bfeb89e1467fb0bc14cbe6bf168d5859a42fc13e3c67c3ea3fb62de01a0409556a88e7d02f33e7b02f76e0764e54ef2cf38ce69a692d9c083eaee25f346882a473f67807feda868b03aa4b0b98d80a3ce2863616fb407deb781e9b19039afdaa3b1aef0fae88b24c4f9cdf4753e6feddb109d4901bc3a1352fdb832b8f0f0c3950c692497684166fba5286cfab67378ae41bc57e25cb755c9892ea0b62657fc3b09630530ce22ccb7885e9006e909ee5c72f601fb1b62689cb70b2b180bc613340d3bb2a67f3af1f98c1751f9cfc688be80406c41a3532e491e2706f0a202d441c46ac27d21a433926b5d36b0bf3df78f61aabdfad9ac003aebd0580fb0764a8698427faaeab8e113bd20b632dd0fcdc0e949ee90f860c65b6e3fbcd80ce01ff902940107b9028f393f7a70d069a06f262d7355f9d013cd4b78b0e6e480971a5d60ead9be9b7bb8a044c6f9e47e14c933075375ccaa158e81e26ac75752b0c1720c65b1006809763766e1592e38ebeec586f69e2e82279b49129d15019263567a6e9891f2f2d0f3afae81e22fee3f9b8b12fa901914035705e23a8947a625d0545eaf4dd90e334f370e04c77fd8dc18c2344f2792318a228529dbc1ae96976e3df44e5bccb386651358942e18a1a533457a0896623f1398168d2443a13fc9df89e75c38fe162d6c9b36f91e1b3cd4d563f51672c285cee68ecbfdcc9c3bcd94b30de5f639442e09c3ad65a919545f17bdd0ac8a0eeb271fb1903906565be86321c5db2585dd3039c5da9f6be4c159f7afbc8e54dbf868e6dd5da558c61e8e170650b9403cb7fdc74ba3bf920a8afb7d206cff07c901ddde137292eddd23196b4c8afaabe41d688a13835db4582dcdfa14cc912cf67c49e41a9cb177c42a937ffced064bd994504098b55baa4a3533a4cb3030fc5dc6e9c6dc387a1af59734c4c408036b1d4c5abc2b217ee8514f8fe3c3282f88f92581c60e05be70399865be1cf4b0b65f2ca5efd612f78b1052584404945a5456fa35749f78e424d11b97ca640668d9bc894d2defa7e2072fcf2c93aa1085dde0699d06a93e222c13807ceab05855dd38afb54887610057d52593d071b2eb66810ebb2a4a863735aaf6aa44ab23b1dbf4f6e9b95083a7c71eaa6c08864b9e79226f94c1239b9ab256a21066dc396a493a907f227a6ad1b6ca4311078f5281c9a0097fde370c3bc87331dd34c63f5c391c92f3b6f5726519a4a3049bf11417babd448fe46f1aabf930cd55927fce1f391619778c760a13dfafd35d2f98a8848ef121dcb82ae589cd4e96592950f4643579763bd315729e8866e13a3b95fda48693f380f91eb50207b91eb04ab41ecac9cf878295f2afb2c7d5790b8169e90845e74ed0dd04f6418fd40b268c289b2248e633256aef81bf817c02e86a56da10948740cb252c20abe7f707af82c6e960c7286fc9f7695a7c91aabe012a48f363c7f55ce5d0887a02856897a7370c6466d61e6a04f3410d6f37ef2cdaea1739555ee83f1b8a91bab9ba4c463ad412102d5b52ed308937e0a704d49b023db4747c9cb71127fc078216a5e898ba5189e2e563e7d5f74a9b9ca710b74d17eba25aa3159b405b9772b99ca621c302845eed9cbdbce971187ee87f51a950127437039db36bff101d4884dd86b9c7eedc12d3fe2f8560c885d0d2ea6b6eddf2e378c0ebed2f05d9da6f65f55c30e50330402407349bffca697f470e12cac5cda63d93620d6eb48b757830a2efcb10e0209ec9e74fee13c7462a3c271d03f84227de5491e54e9d939755a55eac32f31990c0e5426acd4b151803625ce4b80d022251a7d1d32aaca02b7693144f28b183b6022bb9fc208c6d333392ac9336c0e9c6a262a2a19219b0e578af3a6e7fbd43744b8a4fb04f3422fac5d8fe1f77e7fd78a9667b58b9339871b9f6612d2677513663eef3a4c6aa5c039cb179584354dd132f633ffdda5510d0acb7dab0b5919a37f6cf0dc5b37ece5624f3a475cc71f7bfbee1541f2db8201d2f63bead0e0fc49ee64cbb4a3b31c3ce87a9dd7bf8ec8b0dc9851c69b5ea76d8905c36666837422c4496c0ee7fcde6918bd21a2dd7f40c3624e1a7b63e0e668380ff671bb7a0239a3eeda926c3ab95dc26f14b0e18a3dd7497492b2b4adb4048d3002041271bee6517a5047d8ed975ac77dc5739b59281269f2a8a03e25d8a036714d97e365138f24feee0c98e0c20939e5d6d41a3e16c385ecec5fefcfd37a08c1110c5550ec2e001cb9cdec1a1d790fd69807aa264ecc3aca90eccbf17b60555f069c7add77a9750d6c1c42d084e4a1ae4d11512a877ad5846cc0beac39d05fce8830760b28c639120ee1a5a07bad2016d77226764406e66cbcb80605249c243650cc6d237f3c3e8e9e204da337ee6ceb1f08921f001ecec63dc999f8d513b0ea075fac57116ad810838922fd55af9212fc936c76c4c5e538936019df61de2c1bcde49ca94866d65657e2164198261a94038f49e586415ae58408b51e2b372d0ce7d3749b12057b7e007267e6b929dec1ccdd7f08039ae56c7776843661aa136c4c8c943b859784b5b4c29c24f8873877dd8407340484dc6aac228a75264f5503dff6153118c640e692f36f8ac4fab50823a78417fbe1b1e8bc1a5ad33365426176a9d683ac295b79217ac6dbfe20c803f41af767d918494e1bfc21771bc84426657b16408c320929ff821cfaa63673f59d35edd1ed2d088d25350a192485114cb70888d27708718ee96532b15c9e347f32f5ef1504797728ffa065301ee56ed4eceb04fd326c6da9d3342836b920c7931e839cc5b2e3610c55aa8c70d4037ad7ddcfeea5bae85311935283e474995f16cc37ee1068d833c8fe46004b50a620e36a9df6f2517c3502b057d2f988280519411d559acf872d06f6061a99b1c6b1dfecbd537073559dc82470114f006913f9d2a7c3a551b784aead5a44670119b561e3e9e2c19ca4a76a3cb325add08cb1dfd5d65883a2dc151b5aaf190784690a741240e9fa8796dc8a30eb7382fd46a5264ebf0a6d706cf0b99dc75d55cf6a6c2b08c4fae54bfb75096d8d6340fe01c684fbd4d816a95d1920d51961e01b3a64d89ab805c29422ee41a039f88eab886fc66ba33a831900808a9c05ef08a13ba197eca05e08843253ed8a51bbd2af15488bf8f00b1e3af0db59c74994bb5a7ce6ae9e49cc6c1c00fbf0b4cfe1be578fb612ae2ed8e0619747130f7d5f33bda4b953a083ae18f037c414749bfce01d60c642f492f8d2c30fb8b2f2b00db46e4e2df1b4765ec766989792158f637cd8935eedf10335995dcab5aa4a2387b2d896961eff9fd8b91e1e9fee18a687a29e8a5330057f69ac9a7b1b4013f1aa93f2afc823c2f823e2494a04946f56f0c7d38b35060dc91cac66e707f9857336b90d27cb7caafae9e4a33f9d82507356ea6e81322c19b8b10c543ce3728123bfe919cca3ee3ab0d07f82902997250cefeacd1d42661d3e53c2f1dd56d5c0c84af01ce41edebc99d23373ea6d54e5bc021f26f63534f12a6ce47300d846d3b647efd694e7f3c222dc94f2af6371cc9ce5836de63b22b6f680d5698aec2e1b7bde5e0278de9236860a1c760b6d1f2d0d48e98f7508392adddae77a135a6f0f1ad67ab198d044a85b968786d63ce041b83427118f92cde6370ff08d71baae713d35b5e0024493145ad4b7662fd7123d8f21f134374b3ee20f633fd256fd5f41005a7600aec1c18d70cf119fa1c9fc27dced1bb9a17d8769b396447a9a36345ad92c094e3b56ec0bdc9f64ac030fe09085e6d938759b490b34a600aecabf277381a28d5a1fb549ed1a8cee207af67655b110a3eef0c215a5d98866dc3ae7f0a23ce10c157c92a3db2af1fbb55856cf06a9e82633ca51d1730f4f7e40cf7616e3a8dc8ce2832b7ecf87799f6df1167be3e003a7936924c568763128e3a96a57656ca5b58fae820896f1076c52e2b3e569d40a7dbda01fd577251009299f2fb8337b7afc4b7066d95a276cfa20eadb5fa867d72ffc3a199ad0809cfea847e224eea6aabe59f64272137688a4a05d7ad4d9f1d0f29c8d43013aef1eb85f43d2c75d33417bcbba6321f095a44a54dd5aeb1d75320f61f28cf97dfc4be8c91a534597c7009994c0558f0671711ba3beb9c658910e0e02b10b71ca5f147b821011cbd248f3e527f1011e0407527a1ba092498869269d1858b3d61ceb9bf1aceda082066005b663a81009cdbd50dab3ea686de7d6b51d58715b0a79a228a7b1244a7de7e6c4736b00335b78505449dddcebea8fa84d6c44444231ad3c893ae951339edd924b862044bb343db9f34f281e28ab4eede9140698730de9ad84361a68cd5f0c88fd4b88e8a1aff570270921d6db69b4efb9164f30d58396a17d72dfcbbd82b53c49f75534e076c7c17a7fc143dbed40704c6f89e40ea1f030895883f991e5bf37ae08e0eca59ddc65e7f8df7b5db4f4b657de7d1c5f2df9a162da5bd692d780ee96caae375ce736d0aee670f15e9ef70d2969cb3e3c35bcee5d5c3c71c0a708bf28cd205bb9fe1577e79d5ac5b09b07696831d8ede6590675e9445ab957777e5442d9e39089e39f0ed80df43747c3dad16f31364de3e5a7be808f384a153546a559ec8a2f64cdebe7b710d49cf9842e24b03f116fe41dcf4c8e9e413386cafe8125a69c453fe4aa5f3387583014518a9077ddca9b681d01719b3c5c6faa7d4178ad106769bab01a79c8881f485febcfd1293a997c1f74dc0754a4a4a9f542c077a4cfb9fe3cbaf68915d1493e2b1150d29a3eee1957fd4ef6f310cfe853d8cf81542bac81fc4b8611e8a60d1009469040df41daa34c4285b018ed1877665fbfd6b28f288a8b32909cf581330162475d16b43eb404a2935448cfc1d60b8e2e54b6da8f0de1a3ed3eb6867e6fb94ad21739b1f2bda78668f97fc3cb53d56eaf0089a7ec57839346ab7f83e5d875322994ca68943b767669dbb3095de8f2ffc7f62254d91cf69f21577b1a644e9c1d55cc34759c65c8fcabddcd84dfb183b398acd6a94c20205f80b8b2fe610f41d46a53833e52b5093c2c16e53a624c0638aa55e3733c940215520f9730774da862a438a13a886a3ac59d20bfe7bdb94d0185dfb979976ed064c73671aec0a47ef57eda6982802982d2b8c274ad32474abd4be3b1b037e301016b9ed67820352ffd325c457876c69f1a2d4fa79d52829b2349c28e9aebaadacfd40ebd10c4d80c8b610b1982eb4866d2dc17dc45cd9d55391b8549c6393dbcb17244725f182762848e640e90b88c74e8a3b2b3424b2fe94abc86a6da9dcd053a54e13c906d12be7fa5b289b0048cb34414ed51c3924c81c178f07c019cc6f7a090ff86d59839086df9888dd34cf6852841e9097d8360171d4187938203d54f6a880be03be54adc350be7b0b289de7b8f9f7d49e41482144960c0921edded38f775272055d626624f89d6fa5d96bb5c359fc6259be3a46c06dca5e763a8b1f6a5e986e16fe554afdd68ebf8caf4f448a4f35428dd2e89456409b57436ad49083ba48e849112a1106784c49d29c307ef7e335e848f1dedb1516eb479c5d7e88833481c3d8d3aa830cf922c6c550efc9039a9ccfae96a6d3164271d4b7a2162e656df616a7509517d689df29d9fd72e278495f60be7be5707da029715ab3ab1fe4b2a1ccc753badd2a94046b9880260dcea4700406d98ee0eeef6e710fc2cc1530a1bf325deffcb0c8166cd7361976f7c45bfc0fe7b7ca0b19fb05ef326bb8795e97edf46e52d44188763a9785bcee59152e5e4851720c1ff5b1eda2b94746217829b5e91cf3ea5f6e7b031fe8a9972f5a621bf13ed952baf354b1a5f1c41d0f5a5fac47fcaf5abfe6b856524489f390b6a2a1b2780092fdf57b6d4512aea0aecf96b780bb393c4f627c21f1787db7d2c56fa8e053705e86f4a339e882b724c3713f0c89c2cfad4fea8b0ee45bddd8dc2cffaa277afacbd40f4b9facbcf60a8e25663569915b8dadfbf2b43ee49a1645238aa1da813bb4bf07bff7d8e37a9ff6b88a5b5a54e1935c7615e4c90581bd71a77e1024db7eec606ea9723307b85921352ab90d516b47bb2afe990514a9a22f0ec49b27ca624177cac1d77304cfe1605c0c3f185013a043f42fb3f0d4b754c2f399ba2c5e5ef1f713e9fcdd276863bd51ed99f0a5bd746342ebb03b72a0b6788072d1575431a12353bd70bafe530f73c98f7218e0772716880861acb90fd690ac8afd94b105e5da3ffbd7dc626b8522cefa7c0090266a3f860c6a6b396399d110cab6f731bf74b2f21e07bb3dc683c5f1b0c3ed16fd24ad506086efa6a769251989eb3a58a0f57ca86a67e7efcdcf0bd278c3876bfe2958a24e0cfd2527f323e0f090c8c986d8e012e14f99f359a6cf582ba32ae96670ada3f98d06a042c7a41583c330d3f285e37fd9cfa0d92af80c89908961102511b217220c06d7a625b5f2618656160ab0abd0a0adefb559dc7b0494e73244a2ddcbfec92ec743dab43c639dcff8d3bc3e01eed179aedda0c093f2a5b44c580aa98fcd5c501cd51607f669d716dae9a11307b7ff2265e33d35d1d1ba6103dbf6f5ac82644532226e50753e4fa9a7a0091fbad62e9b318de07821ac4d9fe0765bed34197483509f29c21ff60025ff2624850144dcd6278d61f2972fcc1062e5e2e4d9143c40a1ac2d70d61f283590de113874e33a2e0660ec7f79822ae0d61ce06dac1f0baca04e079b1a2833063275f71f47a301af5a6dce28516f91c44097f38005dad725f4d5490a8160b544a1de893bee73d53b02862d6ff8b365deb5bd2c483c0fadc9fde1f35d62076d42a39d7c7b1b2ae531777a8325b707301751a9396fb9c86e7fb1e80903b5eb5a6a03cf5ae4a791b2f3f1e81e7ccfd884f49997ee8d106d68aef4cfee6276a5da8b7e25a7fc20eee443d363b24102d58537306b032912b35cea1216aebdf37a7647d19ea44fbd291f8a2f019258422e8cd99491d6f854361557315017b607e540b760ad3d9b0689d652fba67e30629549528e8b83e34d1627d1d6ca63901c4851fe2d8196f610c34097fb15aaa1041b723c3b6ed93845354366a4863553b2f5611ff6b0b321ce3795ac243e65e92e52e528e46258afb93aa6bb13218c70e05870edaa9fa4489b8d41b663b8f9699bc90558cf48c33e0b1e60e6620928c5cc7e1d35ce28d9da12643118042bd7b48c33691db5bc536ae685b466b1cc394669d32f94fd3483d522dc9a4a5f3881bd04742f83bd194153a0d2f638d75f6f99649156e16635fce3b539e5a146c4bc1c194cfffcef1eaf9a7b619463cc48ef65b92d4afd4117056f4f529535b7b808b584de4a4977874c87d0f21de4decf602e72c3fa6916dc9875f2b06c492f99de13905950f3afdf8840f51c284f4086b40baf790bffe4ed591504d56866e77437399824e600c0ca72b70a2a37911f828d1291d19b685b557f41c92201e3a9698d655a8d24fd30ac7a70a7bbe9968d43da7c125d8f7e05ebb711442e10cf06ceebe118bb7ef4336fe15e54e5018a31282a87113f02d2a3a2a0f18c3c543471f798ab7d0684448694d8053e585131af052ca6ad93c40c89f76398f941b30f267c0a6f7caad89b6766fb210e282bb66c2d372de3980669ef24952e99220cb51d981c4f9a8a6ffd02eb954ccb198f80c7d9dbf0bc140c846d80f00febe6d9d05a2173492967202152cd0de20fc1c74ce75dc35d05737e7ddd97eca510dcbf94088044e60f833620a6efd77e20a2ede4591f2bdb2566221097db3fc298af8fc2fc96bc77717f90b9ebe6c9bf33458af5686897f42982477cb229071419048cd5ae0e69c1857fd603545e949c76494ccc3c79f8b21d0cd96daa079fecebb4f131562210f16de6dd74cee720e6c978cb0bc2d494cdd17fd4069170d739d0d3ab6107786550e2d8fbd796c5b578a53d2a368de92a2e9ee03dc02eef1f356e07458d1f63b8c0ae0c5710783b71f6d631f57b246d7e11f6989afc362a33f737a17a04ada6aebdb9ad3dd3cb6b795f6c752f1ea7489299cc0bb9980bf534557b04033c7ac933bbbbe248f188516bdce403ec842bf794349465af1e3f53ea272b333160cc7aaadc02ce1183be02d16a6ed370937dd93313e2cd12c1457ffff4263fdf2bf70a0e2cd289a00fe5eaef8b656f7763e5a7f928d27a117768cf6114bec4f57bb98d3f0e707460d86331de94a794618b38d35e137e17e2b346cf5384bc9ceaad646aa773dbef01d2557c014803fd1ec9f6d6ceceb43534c4c9f1e23c05ff00bc524b2a72bd7410a4f33e507039f8a74400d30dd43b7f5a59be15b143c396ea722748d1770c2ee58580e9269253473f10f13b6b348ede8914c155ade647fa21eb4407e12d622be2b1022166aeae83e291cda121dc6619a4eeb5d39d4ff8b2e2d2bfc864176ea1e8c9e55dfe652861734e36f41a2b8ed4b2625d810e7f0398b347edab920de8c55cda3d6788ca4c3d53cfd03f4e0785485fc95c6512fb6e362bbc1e7a144e7ed896c86d73a89e9357a5c0a0ac8d0e52357f3d9cc28aa98973dc824023e3bb0b2382bd275f12aaa2c61c8954db73e5b59d8aab2068a3b2a47c1e46ebe3ba5ccbc0287209bca5245e4d49fe6f264206414f377e02a0c7e6adc717a898dca91f6d23822e4c35b91450f4eaa960024f5ab612d70c857d6fe3083532011eadfae7695c33451e7a7f413097d6843cbf94542484d05b6c7c9033719d8efa893196e70fca255eda89d7dc7b73508cdc9e7c5f523958717524cd579175b4e575dac566408fbb85cf884b0a951cd37e47cf3ab0bccf08f37a7ce2eebfc3ebcdc2531e72a0f5e6d44ef43f6ab1331cd7a49101b711bf7f4b83c720f3294091ea03c807a4e5402b14ec998fc272d6d0d13815dc1c10ca5c36e61382dd06956d890e344c31ac51f7fd82cb32ca3a97fc2270e7ec9c509a0abfe7cb485baa41f68e1645075ad3430f9a0820b34b171d6d92be844fa0e2da1a0b89e7f6b5ef927209b91a7e243bf4f318c347b75f46bc956c27afad88911385536bba3746817f964fa2abfdc15866f825e2eb10c068e04aeeba2a154c761fa4745ad515f502b948476ed96d75b9e0ab2117e2e9d7d06bbdfb6ae060f20f642f15f0727638c424fbe6393e96342723ae2ed2067264ae3f8ec42e7644fbcf5b0fa70b670286680e235859709b385a39c67a4b33405098ca7d2c5e7a5e39760e8ebb09b575ad0b719403d3cdecddd056961f02e6e3d3c7b1aaf60838f5304b7b9a182238c1c7a0930716d03660887ed72394e525d6a6dbcc6539fab4efbd469ea717b2cd09ce5e5300f725b8f9e9ed74ff3ed23590fa8973511bb37dcdd35a55d448e1bd440c47786a1885f82c52c1bd80cdae3e34b78efff13a888036f556c072a2cb35fbed58e4460d3e16cb5439e2ece5d07d0e7a9d98ee2c587b5ab7b6395b9f203a01ef7e98cd4a10eac0c3af0dcb61d4411569500fbd2e9b8142f0ea18e7520a2f178fc83f962ae4fadf1e9a8c4db0d35155e135bcbc5d8dd6c1f454f86b708b0ebbb30c4346d6ce433fdf62850110304c115604d0af8ff12a15c4e8e05f1f6156bca3c223166aaa7f3fdf0ed75d408b78cb708faffa25cc6684a238327953e531536e32e31d292ba272b66ce91eb73d80cd40cfd6eb738512607b3728df978300a694f010fc138a8d2f31e446a4de90b79993de652f7a132c618cfde67de07e30eea68dc7c790777e6ec66798f16c7216717cf71263cf1b366fe7dce4ff72aaec2c1e541104dbce12e7b1bc2f80a3cfdf729be4021c277330c5ca63fe06a4040cd55e2cc59a9a7f37afdb83cb6c15602a3a089c2a6a8df8cca9bfde06099edb283711caa2c9367a3f4ba64643aff1fd361da25bbb31cbab4cc67567671aae7b96b3a9907b278478e13f3ec41d770b2db07305a5f8cea4c19e3a09b047f8b6b9e90c5e9e2185fde116c2969ab4b80f47f4112cb00a528feab27084aadc902a576d86e49c848e4e7a463e45cd1296770e983736224d758ac7cb803ac6ccd84488d7a105c1aeaaee364e283cde066b1983da9e1ba5f7cc5347e2829a03905a558ed117536ee3a9c3f45243bcfc67f538c038e540546d03bf0429db496a58c9ef252abc49f37e9ea951b29da9dcf5accee896fbb9af656e094ab37cfb7e847a8afe7153387b21c5ffbb8c67ed916b7f0bab79d681c67cdfb9f1a55acc8d3ee9314e09cb7599ef11211b3c023c1f9976fc2bc57e1961256ff64e5d90c98b182ab335388d981b08f198d3432cc82bff7f22f566122dc01603928c51ad74fd85c8fdfe5dd094a7e985f6bedde68ee9e3709baa7f64744a135f2bad36930feca6574c09238413eadbb3e3a6cd9aa11be6fbbb3a648f9c7c0f6941280eb9b0ce2f35af2230c7290565f7f847b1ec53f1ab7b0dec5bb6daf2d2181f9097d92af4bb09868a2f7c57b68adb2abd302bb4a899eecb35fec06752f770492785d4559999eb628813a9d4de4df7dd46632583927bb3f6098ad088cfa86a784cfe1bafd39f1acaddf5e01d465aa30d57eea70193a084bb46683e446f7c59f92c6732519f957855c342e3ff9a9dbb214ac33a3fddcc697abf31e54243a3a5d0ab78127274b2b36ee1dd5d0634cc6e9ae04dd2e5aad8f67723f7493a9986a40d9baa20a48279c4159f4de8a657e28cdca347efc263e1abf268da6374d9540a04d8bc0b2b8f4a3a798967aff4849c5f46a2f1823b8f05be7e841e07caae29c436083afb8f96e34564f40b5875c6e9a5bd288a3620e4f5d32aac77a6c16b2d8c745c43b31b3a1c54655bfc2bf9cdf84e366c786a3b5689105e2222b1df8972628dc240813ba7e30d4241391c8e6dc6c77f7beb5afe5ee2ad17ccfbeb300e92daeaff434c11e713c65e0897a132fa751c3596f6deb1a55654cc008c07ac259e83ec50e8c25d01d0902403b14fa7a3c8ac40e246a6e68e6656474b7b20d4a2c3565a60a41423ca69cf9df1948e3e44bf1824dc489242343dbb7cada7dff2255831d6bb81479ab05eabfee07c35a2a105899bc179a407136c646ebc0616d6b6d158e7c41e767acdd4e74590833b8f29ec5cf82fd135ad6d82a1714bd32a158b8192f39af23a72f18b05854b6a3b0e22a37e72477ecd1ef404f3374ec6b08d99ec60b3eadc46c09c02ae3f29275b3a6473e86759aa12b7c14b2bd54baa9ec295d0fce5fea628720ada195dcf62ffd83df85082bab3f53db979dd80b03eaeb4e547c9254f866111cb48ada65d0bf66d63febdea261ebff86e5d700880cf93efd6dc05189dd51b19871360f4647303483a41a086ece88ca42e5e0e48f7049bd3daa349ad5657481397a0bc2a3f15e9d55aad41ed5087150dd3b1d6eff1eab2c30572f5b8b19ff206de05c850ca0d6478313253f3c22868b15dbe0f1fc2857b823551276b60f9a3166f9a9149eb69b3688f842e593d408ba8a797dc1cef49231b1a08e43736ed0fdaf442bcdc7723ef811419641de33fb8ec1643c69cfc68b2a15de47b693bb529cc509afcadcb015b55cfa523333c7d8176b72b700eb2278460e258bca3d3392f44080c1ce72e49e4b672b03f917be4017ccc568d37b0c1dff051ac613e1054ba67f62cdac9edb63af804338f88e96248715e04989cc771349ded8187eb9315b1aa833a00e86cfdaa93073fe3700811f99f7cdeceace1abbd7f30d60a9aeb517cac8cc6fab96c209af69925a6986fe484746d12a864c79b881c7d2a78dc9b565caa0fbab5b99d62195b08172a1d66a093b64bae1f37d82afb8dd256b19d485906716ea45b1798c2cacb8ff6996f023f2a157402ad0449598d13bfe417cdeb10671375c91c5af4d3fca4d2a119eedb9c60b0dce9b559951774c458fd62b9bfa6f5a8c0ca162fbe6538fe00f60fca183071974ff4fb014d1645d792c7fce525bd8a0cea3883cab435e335a6d7cf7f469ab2207d79a44c3bc2330af4795477b6834bbc74db768b1dbdb0717dd77b5d5a2d28890104f6bf2a66886d6aacfbacc75886ac058addec78a6bd1a27818f988d772bf4905477d83d7e9afbc8d3776fe808711d87719efd9a49ef793e32ee08f896e5799dd09b1c588eaf297cbb26602aa704d994de54433044b0cf33e2adab5d1c1e14334585d51bfb52ec6cf1d3b970f21e1537a9dbd6addc6c55b1e40a7358ea9571f1db0e9a9bf0ccb347ffce9ecbd11262e7b40fdf3139b0f74400fcee84f076225eee89956bc6456cf37ca06e8a48d8c24777e2baaa076c70b2ee33f06975344a13d7bfd4f677c43cb65909cce439e68184a904f672c785a6c30398716815dca264fd5e94f01b6fee2fa836826b7eb1ac93b13af3dee30ef9e615893327283719672df0cb96a899f27e439b9800241aa0e29caec8e53793eec99ded734df4ab05e866a5f991924d99e7973bfdf8deeb95f4d7db1b546cbcb4e8f902960108b90291397f944e373fc87d72b0dd9db97b8abf2dae7facb495f1425d35ee0b6290b02a55525da2f72fd10dc7bd87435496468743ba615dd94999fd40acb074b3bb44868c4c21342145bf5d8cf0a28f643782df1bf6e3aaec0a3b1b8445901dfb15b543fffb3c9989c82c0c4615d6fd771a661f77eb3e6c55271656f8fd55b92f205a647f7db350a56abe2e178fb5b4c8ab3af4db3046b9de4f0fbf8e91bd9deae61e53fd65bd7e27993f63d1804b138e15ef1676cc4f28baae7f4d5ffd2e963e345c40e4c58dd5cee0631ffc88f5b1933c84f6f6dab1b5c6d6115584ecb4d3482699e62003b4f1663f2885366a857415f54f0aa0265ae32af7bc1033d2442a98b708af4462c974298b7c58028cb8f71fd4fa2527a999015e8ef6b6932241a2e648254d4b30521ffc4da69048c79b2cd468b74c8097526008f67e35b25c52c6eb8eadf3dd2745a6a1cf0ad503388940916ceceabd21e515c7763bcbfa248f9d25fae7c1ef142b86160c88a03fdcc770e62deee78e0c2db4ec0e2492f09c4661d54e9177fecf84d7776433f93920225c13b973e9b4b1f46b3ad5b6b6240130426971121171cc3e6bf3c373b3266fbad3bf8f3df335222cf240520ba665032478955559d7bf99245bdbda7b6b4a7cca11248f1a7f9bcefb44fe9138312f4a5d2fa6760030c51af2e9390da3c2f6efb2cdd31566645ac2286f0230c9f27e8fc730f9b79826305689765fb5182f4c3bad2110534065781dd6294a845fb3913d159e539c70e31aaed6eba93e46c44a05928bc37dad7442304ee6d049869b3357e705493980fa256555b858ba2b22badc5dce43745af696cbedb635eab721106cfbf11c330c26360f5866531905de08837037f798afba9f146bd71ece590a945923281b384be94287de7aeaa9476a92a56c9f3375408288f91eb50208b91eb065c62c7066d8eab25079fc25823de1a8aefb572db38ead9f1cc6cdf57d8072d528ed847c2d6e98a1637408a2dca6151d11b42b5413818446890a9a388d837eb485114f1b04dc9e0fe299df9957dd9632eacccbe67321a745ff56803ff224971ef993f7999a3d8dc59f6fb9c01115a153f1d5cee5b3d818d3900482288251e072d6a2e7254f41eec069201bd85daf585894b1050407c4040c9e75c8eb43874c23fa57f86a929c478887feb2fecd9dc8b73f443e2b9176fd52baa489c94e9ae1dd9a162766bd9c232f796e41958da330b23db1b903b193e6a34171009acda95f207793d069aa48950d55db29b2518c2fd085d4f89459dcb0e222c45c8f848fa1c4e065d710c10e709a9e1961cb1f68ee41ccb9e3a0ba364a79bf4a3061919d1eb0440d40e4a3cf955cdc246884f42e7b50bf69727fd008b500b9de1fbc58b79f3ea899a3ebbfdddb66e9cf04bacb7021e1dac22b34ac0db0411d401de4ddb33ff4c28908bdae5047bca45248f07e24e8504b21a49289d739106c619085f87e758eac6e64bfa9dcc90ce692ea29ae32111409db2642c8fb9231a569e77407a228ba2b555e3dec8308f21abb8ca386439e1c72287cb811e8268e77873b4c17395d783f7d2078ccc57954c8593e55d334f5578575c1b5ca92e8c0e54a47ee483eec6af6c567e6d874c8954c53b7cee95474f5cdce01b82483d969307bc9d5f35bf47d8d7db667955022cb60394dd82f0851ec2cd1988b95cd4c90dc18c43faf7b295a3e5ae45804a6a378fce0613d5c4c134e5e065cc915a77a8d0fd15489471983be2dba3dc423b09c893f82f490f872e1d816501192bc3ff06af197307913bcc583997023fe9662e88449e0b35b361a970a27ba642b6025c9f83b98ce0eeaf9c68106083fd8f893c216b47a02f76417a0ce3aa3dfd87708d2ed1767489740441e19902addb9b723c0cfe055a54d8e4c88bb3fbab92bc7d247051e7a48882411a53a727225528ad21c496a8629225cbe4e3b64ec7c5f6f6f1762dfea20bb0af3bb908c6da06fa63859e6452b2df5abe4b56f35a5af15b9526f7c75258f93d414762741db9edb691e15354c24471853c17e96294c9b7f85476f36a4ebf8ab7cd73cef0c894d578ae6c39638a3a08aa6965efe24f2f0be9c0331cafed8b9836e8c1728f66f7c507cf2d7f7a4561f0331087741a44fa5acf446bbf795b19a270a6790f0b81ca59b2333c0170af0594e37c3e3cc4e0d4977c98a9fbdf413761cc4fe62449256de690ee24b92abdffda968ebd296b6d8a9bfc6cb55dffc2cfa0f91bba98b8992e544c1d78c49f499d566ee1c8f75b2b6d0e4f0a3fa26401aa985c6bc6a5523975a6bd1587975f4456169407f528d99392b22bee5ddbab6822eeb83f9418044fc5ff21a84fd9bbbaac7e878af7f2e1d4b9170aba2df34d4ddc8c955b800ad0e0972e6c047fec7bb7aebd148660f8015378057ec3b660550924847b073862d0746f5e31c0c52e52095e61b1446273ed29246f3204a2e4c36e212a3d8849ad88b08e8c8c4ce0b7bb833221882256e2d00422158c87c8bb697e27fdd7e7a73b03a9d6fd3a5d87352f7dc501d4e97e314176420b4cca63c642d84097db03757c8080fc12a3bd67ba3e5bc5fcd59907f3beb05b887af4b558871b77efe3e2644501b7bc01f0fa3058270a490fe2dc1cf82ec042c37a634425b9bf10094f1a470843d9e27ec978112fdd03ac84c8ed1d6fa3a1756878eac6a98ad560978ccc1da3e27aa68d91440c7c4f41901dc9ee07c2ce3b8d48bbf331fbe541ad581f76ee91081965e5143e2ace6b244e19be1ac60e7a7d6ca7f302008cc2306b87236a5908c17825406788366f08757ad6fd2971e00a1d7181caff985f83aa33dcf1cb2191d722ffa0f4ecc9311e4d5086207dce4b1b96bf434bb2effb79af7655ccd4336ec1e23ec3dc738b029dc05e401f83aacc484e31fdcb6e5030f715ca507dfd272197f6ffafccb49ec05e135c36cec8739486ff497f3f6ed2fe0d3fcad37f79b5db7fe274c40a8f474d4eee25ac3c227838c740ba696896c7f54eac811ae13ccc0834419e6876ae33446c0afd0468a11a158f9fd73885b8509eb0ec63ead378990a80516bb645102e5b5c90314a374d93c779c2a2a1838ee341ae8dacdae93adc4138401ab47b6e4b85d38adb5274b34a39c33ab93eafd9ab8342e9451c663d9c201b5f969075a43303f9bb3ceb14968e498c0251d9c670a34225dfab91f0ced2b4cd736b719e36474aea9c62fef495e24fcf7f32a18deb960a1cb61d96977102fe52d6e738c5bbc89b4cb30ce5c9bfa078bc43177a843f82a98f72d1614c2da25d66a3ad4a0838313d63ca7ec5800018d006d317ab177cb240c5049550d6b8f89bd44c918ee4762245bc26e969f1edf8dac03a1b80107d6dd674a5f9e6139c1d557caa4b0c1173994e2097ab1dfa1248b6ae96670b81a9e62949df9bcf7cab9e51754a9a27820d9699f3736fc875da822943e6c9c7a66b7f8efb2411fd86c1d8d271263e0d08bb5116ccb16848b79aaf419e8566f6a2bbca57b0e1ed4d47dcd4dac5089371910d2c8e1054ab658f516abdb7f0831c26cadcc8bd14234597a04ef53096a322210c4212a3bc5d4de24fb3c5b340de5b1ab4a36545a25a076958929fb96c38815a9f14527d8dcd2810c36400e0c88543ff88c4d92514caf7d1dfa8f8078f29102291c4e7d1524e1dd36df88bfc7a396795e0a5e3640ef045069bc52f0b31819e1e72335ad68872a286b767de3108cc0c4231c9eef49b0b8301663ea00e5c502f610d838ad8f4c96259aac5dc247458b76d76b6a083eed5b78e75d2f3dc8d0b88561e0673d9d8add51dcd8ba4969b257b4fc474a17fd9c8e07e25ffe29d14d295423a3f092349f7a0066f0bc6368e2d868ed00148fb1a03ec4d609254fa0a019b5bedfd16d03c11b608306c58fb1e2a2ee8040bb6e261c6f8d93e6953fa53e9841d27810e532d4d165c04d677f3c4f3d21320606c50cab14ea28bac8680a7e082c6c3ff93f0a59e44a4f7a6a7d07a487dacac15c8bdd151f82daf17313e1cd32927b6e71d93dfcc2bf8d66163d9c83061b2be9d0034d2ec6d11a8d1a43606f3b3eb75103b929ae1dc9dc7c4821d7ec36cd1dee275ab0d2fe6c374c4f8d8eeb85f5f2a1911c40bd84a5e672bd32695f2225aae58b7fa949ecdad4f2aa8b52054d4fb3dc2f041899708acd73a7dd339449a131618d585da3a2fe54e2ef4aa8241e505e573a68aab0121a6a3f0e833f158dc17675b196319464f64d4b296867dd3e96a82bd2115b5fa0c575596097c92494c3651d2d7a9e4594e77d0565f40e4d06634b86ddc37452c9db5acd429596f4012eb678cb334072fc5791bb54fb464a72213f6feee6dd0bef0bb32fbe8b92b16e0fb319515a3c36a3fe9f5d7e19da6d652fb3551fae3d9d9c7a340cb51d1885debc2ddadeb54c313eccb215f096cce72db90d816113e88c37347c14d31332188fa707aeb81ecb5a55805c2dd70174c2cc27448bfcc49076a8a358ba7b0d27a56d660b6b599d37b3fcce93383c6c1ab3dc9e3ab7d123912de545298b714329a3d62e2ef164438201aeb40ac0dcda2891399fe74bacb419edf09f60774586dcab9536b6eaed025417ab1ea2718e1825d7f5a2faef3000e0b651a1c3881a51ded0279d26363146718c609e0e6484f6881ae5d4f5633bdef04fca9f8232ed68a0bc90d993f77c7925dbb85288b160a98455143a5942460f13478c1f302c39089a7e0181c3ea304f8bc326480dfb94303077b50640b1874be1fa8ebdeb6e1af2a27cf75195fc4ab06d8f6a77a59b7af340870a1c2da78dd117ccfb28063b9411948fa0532cc9ad1e78b8ceebe86daf271bac4900fb769a4cffcc6352680c6ee8ae19012a5488a99ae2222a982bf74034f10421476c84e57a0778482eee92b023a9e614f5352d2330f6044920c0f8849fa40478da12402d533c10f58be92399faeea55377cd63dab47230fc43a0437540a02df056c6b3916e437d930b6a8e1400c4a83d5af2876929238af344342160cabb5a4a2a0e173509dcdc4155bb261052e5efe575d2865ed4d5f58170aed838a2de6d8368dab4afc8e77da5f6893533de756803c6bced0f2375885d98a288db6656175599f20ef52a3b129df862601b952e42ae29c119b1cc1e82d5c13dbad8aa7c8516d313bd3fb850dd562fd1c5cc3343c2b4cc077bc6ce4b795c83d0e3255ea1bde5fb43cb858b26f2a5f247e4ac14ac422d002505b71794fcd077111039a143af5f751ce64e6537cf8a325c010bf0df0f3f23695e905ae915879970afbef9819e231191f1b491e4d8ff09adf3b76003a2b9ee55e5120be4e5f0e6974466f04ff49a4d49045367181387f6aa1e62150a3717569a10d3cd20a9d1ca7edda48f4f6ab5b1f804ad5a0dce835b16dc1211bee965e22cdb346cc3ec4cc3174e2ebf770479b23553cc2adfe3f3069f3fa65432e9e1c02e78d48a407dc6805dd2025362469622bf9137f63c024f036ca05200750c73c4c1807b8234dd7f9bb0c3e760560881ba845af81ccef190a8c5f5419b2efbea68c30c2ca580ff460c7bb73a38e56bccda56afe7668e43548d77eeffdaed2e004b34e1a65f72710e57c8f7deca2a7f03ecbfdb2be4c4755f9fa8f4766f5a52837142bfb054a0a602ad60ffe940d7cb5bae651233c47dea7b37e9bb9c4923bd24f331e3bd1e056ef68fd5df4302e369752d692b6a540e773326baa5e43cf2f0d0b401a3a038cff1e1591c0174aa7910bd9172804cd87c127de4f2f0d764a97de717a63fb62bc2990290f6ca97c1d514374629a3a287b7dd486396297dabfc8f149ad20b3d54ab9d739bdb87078d4431a14660cd10b30cb3c0a37624108a13e2b6fc3435be1a5902922547c411c59b0f272bb485dd2d0a36cff20cb2751f47e4584cb726befc59be7b4c55e3a2e717f68c4f8cc442441fefd2fffaf8840fb837d4c76a343217b71552e2024730cc6bf03ba4428c4f9d720c19921bdd28220d32b979fb238cbd24db95e8e911169a78cc403b06854e59d52136d3af72889e69ef1e60d4548c73248cc2031681430d4bb99ce5686b16109ffccabb2af4202cf4a9ee6598e01888b1176c70e53ca622d379fac56fba93beabd1dbc223b294b1616e11d28b2a547876b9f9149ad94c3a30deb8eca940bf9d3299987af1f1d773c40279ab899bcf7c02d8991322060e7c44ea9135c16ad1455b6c02eadd6f8817c71c903320f6b59cd0ee509492a019f17e7dfc34be3fa4227f8268f06637b9c13446d64df3d5a23be74d85a65684668fee1c6e3250db9d28bcdc99ebba69315443030bc9f3a27e7b1354b2f2446ff5fe0e48098839a4fc6e4c607b0331b638d9719b3922aa343551130bcd0704d4609665e62fbad487dd0d9cc74155dd6f414b2fca097c79af697149d2db1f7c4bcc1e8ce0635759bfc1c9e99028ed844459bbbcf21d4e40d48d6ac68fadc3b53062f5698dbaa13c45c3ace0e644c557a782df2b493224945e3681767564ea99b5ca106251aa01eca7832eea3933100bbfc1612150d79dab6c4faf5ccca51d0561113e8df5437d2691b1c3795f7e2f7b76a38e19de39dcced355976b0d44bb8a5bbe636e987481cc041cae4b77e7ae28ec5cf5644ef6d53aa2bdcc395efdf1047489484d7db6bcc002902e60f09764114bc4191073d90641467ff71c31286ed3d8919eb8e4b9d064b4cccb992f2505229593234193023e60dc1947a0b43fbd4d37ecf235f4ecb05f64d408ca67be148ee22d21956df13af9596c6f8bf46a93706124406a945355c62a2ba1a0746c269fe40cfc30ab9a41498bd880009bdfd7f5de6d3a65c2dd5860b05fd836a56c195d8eb712f12dd1caabd448668662cfb80549bc386509f0e430ba68552f144d47176a2c169a476c8c434216922c314397b34338d82ed0f106f8c18232b8a61895723a568f893a43f72102c52d3f341ffda05da7d5b1cc30db8830f930d51fc6dc532c2ce8f9d7817f34465ff089d25b5e2ba3ac4c13dd132d43d2e26d1585a3f7a29355bae49e86fea73776411cb53b52ee4ade555b7303c81940a1f5c10533abc3dbbb661214b2f27eda2cf32ecd06d428b03fa40815712d1e77d67b19abf4a17495b7625f4070cf8df799ee8467559aaeae67cc15d631dad8d8da7a093bcd41abb70a87933dace6371b59eb61f7fa78ee5a0de3cf485654ead3fc00b99836c9a4cfe3187dd04817aa202db4174db4ea65ec54121bc34c058e6602bc7636c54a11676dffc44ea01c192c78d760795d2d74baf189626b7bca1dfb181cfb0d4ca79e356c803a72dfc6b5c55ddb512756cc993ee3e0e9eb5cb585d4ac49a5fcf71005071bd51f5480cb590b6efcc3617187e8e7c67fa2b7708e1e846eb58d59453a5353035edc0cf762ff3107060c72c4b573301f3787cd714b7b2f423ecc5d0b683527a17b0645a953aebbd2bfae0d50bf7670f1e5dc63e29fb762bc1f792678d5ec00b30fe58295538181241c473eb58976757be2790277ae2cdb727205a707fb1f46c464dd0285f17200b445e604185880351ea5e08a45b8ef00099b7d69e20834878f9422212727ae17d8a1c1cd65f45c8c27abb26afd318689e0987cda50f684bf3941272447450ec43007408285cefc44aa41fb6b01437bf53522a6f2878ca0481dc63408bf7f4683305d620e32a9195c4dd50c36380673acce4587d11de13d3825ed69e9613941965442a8fdf434d6436a5c7f28ed6c2059f2a3c3f3f4081195cc92b56a60c0399ce50c8b68a22a8f28919864014539daae47d4b3a3fa3f591abc26ade0cc79134946d1ff7af13cfd93af5218ff43ba3a49c3ac31e654a2777a4cbfa681bd5b091e6fbef873c6174fe98774746a71d6c184cba3a247e98207ff8d5c7106c008c3b5fcef1135ba5735746750e16ac66858765d26fb4df1a8403811dbaf45f9c64a0e4e36991870ff9782d4bc69a87d7d75f370abc92e6161492c901dc8b12ae4f386df6685acca3f71d2f5b1a89d39dc38a44f868ce289a7d4d4ed2230d1bdbf56a7fb16e02f55db477a259a192f22e0424a07ee56ade1a36e45bf32401bcc893049f632bb665ca3aeed17b85a3536c80b538571d64720152955ab9d0ab6752788e97ef0941d86c2904f3cb99fff8c131d9261ed1ae60bdbeb1f4cb445c0fa0be4eed25170f90e90c487b3dd785234ef579f2644ed8f7ce587ddcd26c33514cfff46da16b5ec63404d98609bfa8967fde319364c55c528752a6db62dba91fc8e30247bc06289d271bb049343d1cf24f781bfd1d3fadb20f3074457234c26816b13ca46c5aaa05fdbdc030610f7488c582adb9e6a581de329a63f13f1dfea774920ef39c754f662cb827e7cc9c5a1777a58a58e0fec72f13d4091dba8a596e37a3453ec9f97dfaeab5eb826d79df2d23f5dfca23d1f52f3566be97a71f285efceecfe63714c559892dbf41631160d5d87e43564f4ab5dc27369cfbb643b1a2e5ab1481f05b8cba440aa085d90b79c2387aaaadd30ec461abd1cfad523e33aedf7c68f7b4d0a910a3b6d8bf024bf0df320ea524b600ce7de029399bfce0f5255217d69b47dc35e0db9aaca388ab383036731abb232b0ed4142e6076e6ff6925ef2c4bdd511f4fa923bb8156f303c80614d9280e828755faec0f906aaf911b8654a8d4803418a907cffce784ba2a1482c0151ee7f04c735fcd52f0ed6689070e06df0275cd68633c783cf906cc1a9d6a719681a33a9a2823f8b1e8dd8c32a21f976c95afe78d0709158479b80baca2cbc03a3b99666e198a3c4c7709d357eec8fd68148ef6f8848c2f8aefdfbf73ebbff6105bce8e00c520dfd76c4391ad8b0a4cc6e40049ba9317692b7933e68878da444d0f66b98bcdb93826065d62ef2a54e548c33e966a537cce36a915639eed80c8db0b18b573057b0cc6a5519d7a58b92bb715aeeded8773b4be9f5a4b80fd3dff22a2d56595609cfabd937434467efa2ce9ef7986547f749a69f923ad2440c053b5a4533960db17cf661e7c3dd71945a08f43c4f84c14ca78bc0df42a2007f3e180f089ec3088bc3706f95c8027e6e6f24b11a463d1b8335a7be36260353c1e868ab97061a83d5d27406855bc23026d7bbb9fed6bcac2ec70b36dad3c675d81c7cdec4259e21a761576d922d788b59cab9eaa3f86df485142cf23b3da7d90c98ad1694e5ccc2a860777ef73246bc4add5bf1db8dd7b8ab67febd10e1245c1dce1b979a2c71ddcf9b9b5dd4803d16a65ed05f969a61d5dab2b0a6c1aa62a2ff2cdc43c762c4932581528c4849327630f90714881b5578107550b7db8fc0c4faba7c0ab16ddd44fcb55c7a72f771d17f314dac1067b45566602f83e5ff44ecc1cb6383b8d82b88a81dc765fca3b268f0b656b5ad9d6bf12ba5dc2e5d39844702ec37940754267a7915d7f4babdafb0271410f0838c5ecfe9cac140abf481383a83a39d71ede1042c64cd338a2bafce319173cdf91d28dfba619ee98d1d46cb0fd2a20e0d6f5fb126db8da389e2774a5968befd970b6ad402c59f5333e81085c670a75b534522926b78b432e0c148da8962a926341f97c277ea311d7b7464c6d96abd69772a183df572022e4a9cee7162ebc6ea91b87e5010a6ddbbc625446fe3568a51eedd8ab59f387b2075a7dbfb07638dea4821e3447686c939bd58072e034c2dcb21a8280c750ed88c22b9a1d5cb5ea03021a5d1c6ba7b3d24591ebc8ec019a8d55d7b58272e3d34e4f03df657abf49c37f666d9a71ab81e0308460e8560e70cd715222454c292f4f85064cd067e40be9134cc9d8feed98194c701cefcec1e6de99eea027c22ad115321f7a25e9f1b3ecc0772f074b1d6cad2bcf0d555016175786fe912992a00a19621ce8f1db2dd78a80190a1d00565a5d43e4010ac21acb65ae758210dd2d3b919aa3e1af7e82c242c72d9e02398990247a4141d2a1310a4eca84e81b5c80930f4c7b317dcae24eef6d024c40a1439c0286df4d2ea124fa5a4d611f10cad1fd3b9a3856921043dfd03e2d15aa628edca341cae602b46d4533b85ed9f24e59b95db88d96d77697c9c5ac28b056b6a2a8fb2a8897ca7c08f4d7eb9050c9977c51af72363e4e5654ca7a1345ad426ec6a56962a7cdea83748fe9a551d3eb349b6664c5e148c4046333dbd3d92267996019c0997fa44f361ead1a7206bc45937dc78d69308a7bb11901cac41373e3a9e2c71d706ebb9ea75eb6601fa47ea6a313c2aba70e11e10586edd562b8a4383e3389595adf52cfe955d4f82318b4586634834d04f2281bcde427909ad0993b6fee269177ad510f4f1d0b65cec9bce022a8bac7ca78338b4e5d6723b787bac2f5f41879afea4dc988e4a6a25166227fad71134313e6c05f267eec38a0c61b227f9d7fa6cfde9d30e5bca9580cd8d794d5749c8bdd054985b2ad7f789eb25f2a9726a2b0a600c285c64ca02ddf86bb5f90cf87c3959716c21ffd27bd82cfbbf51146d5fe1422013edff6746806900f375c9d9cb14a7d9d51aa49db86b5b38a8f229dabfb0deecae08b5fcc27bf45126405d24179c0174ec593cd5ed6bb22dd51339c57f6d2c5b478df5fce3eee600605bed4a8ef26ea6151b0aecec908bc3e113bd839fc66f78641c92d793919d7f031e34ef48f8d3710dfb51b8c845c27cec86ba1bdaa63b38afafcafa4fd93aa5a0adf59307cd58bbb3463d096bdb6842873dfb13375d6101a361c90bb6f27c5e0b9923233e10f9112de9b37985d84e9267c69b3b42659b700e66c01eed5abf087dc9eb1cb5ac673cdf570ee67a4239015894da870ecfe605b3fe0c1cc1602ef8a7a37ffcad5cf11ac58ee90de289ef9b1b379b915f6ec5c9ef1f5f89ff30302f4f391171d5de7cac5bebd3821228265a150671884a4844145c0f754ae506204734fbd10c98992a7f012e13bf7500d50ff443c459598b518e2e089b39a90ea3175281b8300872361346e885a925ebf5ecd3680838366937b72ae9aa2cb9e50732f1c828ce3716b4edf664d9921b0e8a1ce101933aeb8d082858f467f8debd986a5190947c5d2299478eb6107c4aca30baf7d947249c5efe4d22a1f7cb1fd329fd5666497502e05f02016547b5e3c1807ecc05d5ec0617fa5d629789460bc3c3844148ba65a5c20c2960d99c7c1ac45b67cdb672ef1ba7f653ccb724ac75ff7fe7687eb2f887a6af6e6c2417092b900e3c3f6ecbd227277870a50122e259e50e1fe4402d04ad3962b4355b18c65eaf6ef4c35537134a93202051fddbeebb5ecbc0505a3ba4abbd979888bcbb2fb941df24754c0d4f043ecc3ee0cb1761b6bdd0168f68f6097f1e4a98eb1397079a9ce4963b955c15638ca1d15257602143ca7eaca253f251906d186136f223c87dfe427d8363306c57fdb7ee27270af180f92587b793b1fdf43e0c90a4990431f184e6e89b93d90a0c2511d73ce404d896fb105a6bba10b3be7b9f25877ad068cc0042392246b02325bc2da8c14f0529a78369455ecaa6ba3b99c75a809087c200c65aec3aa3c82b6e4d75e42ad7a1051e7670205c9621f50b581bea1173ba63faf5cfb49206149d185c1969620ffc7a5d386b8e7107a70aed88874a2077bd3565c17cae4302d7425bc823d7f821406b9f9d446b3c8ccdcd8c25ab199a41e1f633d8b5a89ad7bc3231413bea6afedf8819e2fc6ad93c30999fc482611a76b4e00836f12acfcf7047d76aca084247876083c54386003de8553077d0631c1bef885323191f5561d913071c9c3a94fd754b30f607b4cf573a236d82f0eb583e4d040abf7c460951907a3920fe6d2c6ba775ca374a6bf34269aa7e5e5b94407639f08a3235c705b47f5e7309473874fe992cc18b422b77eea92c5a4f9e050c57db7edf35020fcf1ee99945a50bf2c16f902a68d4fbc7b8041a9c2a061d8df0862f6f55a4d18ffcbccec266c70ffb5c23fb998d4efa746a2a6e16ac17a3992dd74422b51bb26807cf4b0186cb42034483de875855b6df16493ded317cc418271ed0b7bfaef13272dca1c624df8bc1302a11037cbf4a5ea620e63b618c7a3287f902920109b9028d393d3824a1088fab8aa874d8367f1e7ba5ac9616f5c6b2ccfe5e2bfe573563c4714d40256ffcc48d95aaa4a81aa9d38297e8d9bd6d511cf82c3489f25d8c8229d0373750f2f0f478c4b084345e69b93c9c5cd24a07578b3b5b6078ef5b9116ff4aa9f44d37778e8c958b4db650a321309da58231f269e892752297322ae4de0e68e0fa086c346676f2a64f6ed79bad367ae0dc449a4e695bdeb48318a7c18f7dd901bb438b26bbf678518352c4914a0a6ad2d6a672a27879cf75e36091186e4e4a0ac22a59050afd9b6ca87f88620d932048d23922f1a6d2e27dbf8a7bf1fb2415c14934cd0b026d57a6dff4d32715ab26ca79b56cec5e9f233d4cc56d3792cdeb88fc3c1e5aef61acc28a072bc3aa90711258a64f8d154f350778cdafb1bd860bf39cef3b16ac933e74a112d5810c408c5248cea4c4062ecff422ed2f57a46de47d1f8209b22f084a27999263f1b3777af730df36f20d7fa088bb56728af539e4097c40ffa2ff3fc51c78af07aaa03387425159412513d91469bb29551bd5cb3b657f34ff2d2a979540e55dec6d895fa8cc6bd9cd5f7d26e244cafc60c322314a832b34a62e9b182fa725a15f9babf65441c8e7457ef354e8739572bcffc8e5280d6bd18ed8ecd7cb3c0495a051c80fdfa8a8a6522dd61f088515b6094068b155ad056f4585247b8b6edd414a770c141274d03bd9dd4b5d498622fcf51795f9826acc5b05ca4a8c5be5a0b3e2d901a374bd97bc42e5bf935b7078e343142d3aea16b1073c3157456685728c59bd6dadf0df3a27adc121e77cfee0e9bb076996e9c09232b5432606c9693312861119eebf7a0eb71db759734eab2c76621e2abc1cf473332e6109f38ceb5998242817921fc743b54829995bebb1b822e8e7322eace11051e0865eafe1c826fbc8f91eb50209b91eb05e035f1e172b0c44997962d53e33a736537c920adc80c6ad07ef4fe63d18c9fe21737a1463c692c892e4bb01c88ddcce2095476c2d70141d74847ddc925d06d5421792b9a9590e4841c706c970b286d7e7dea74fd640f8d176a817c11bd09744eba25e120fbf4afcfe62cd8ce50fb520b0d80daef5ae854e0b9556e98fd0684df62afa8080cc99281a56ecf7d65036a6a6c269561e6d57cb14908cbfc597ed357896c3def4c9eb6735b09fd8f5f60da8d187b0ccbbf7730b01926b0724669dfe461ac2edf5ccce9496575fa19f1d8ed9e09e75fa9ad2e664fdd7ca190b1139283fac3ebf21e7d1289e27a2ba4cc6ebf26ed13417d6b737fbbc02f11a075687d1c606987c899e275365e96d78de0db983646b39064dde56249109625326b09a42c1517a37f952220793741d555c09df96d1c645d92bba536d7ac39a104d80ec6f441f5196a7f72c9e09a6f008674348954f56755125df447059db39e0322be704a8b9f9db75865560759df449b7f4948192cb14f6dcc0cfcaafda95e93e02be9c29b9f2da7d907a7c1fbf86e0e77fa42bb1568e3940f3127b0fdf1bdc85fa97c195d7a5a91d869206b22f5b45e13ebedc65d65125ab86ef086c7e9cb71c1f2fbbf7febea8d198f24d22beea91ea7bcd36d31b565c4bfad945c0949a9d1453176b9834176536795c434f7fc12aed1042750caca020baa169fef87e34139964355e24dba2b4463eb800d2db0e4155cf73b39f2bbf36b6312d66cad0516ebc964f62c6ba44dc9d93ae9ad8cb8344d8ce13cb5277da774107014ff55343d294118143db6a5a68ac2b163eceec1d50c65cda9d3b283994285abf4a580383203e97d29eff122fb21f61841a582bafd42e98f96782f995ab9bb4dcf93c459b94a5e9fa4bbb9835fca7e54c379ceab9b4b5a4b499af43f24341b44d361e7f44f9a8a5270032be9fa91a61c507cad5ee844997fa2ee4c3f90768bc2aa7c6f78c789724cc8db0c580d7451183896183ae3bb328ec3cd750dbd401a57510b2a1ff7d8974d734c79de58a2214b155394509b0bde13d73cf06464f69004b9912e9a81c25e494137f6d20489bf97f8c77e4e824d624dab2aa2e0ba3c0c3d817d2e16b67dc990140c2d583b807341355add02e828b51267fb26715ae907e9dee720afd559e8c2115795000ec03b7b2af225796d67487644ffdb10ef71090a63345c2757b6963af6fad6d9937af8b3c30a53bf9e904d86b97934b184127e7f6fbcab0b366dc90ac5ba48fc2a34c68ed267d3b8cf0e934a8e4d3d19e9442dcccb7b203e1d09cf97749bcf4950e0e107c2d75572cbee73d61625c1d7770f4f4c96225199d21c235f0e2b61a803d44b71f651af2bedf6a4964b5d7edc780be9edd20050a646a25270df83b50df809a7adde63c7b98ee47befdda967989272dbb409fecd4268aa56ea5ea37d384bb342def57aa9b86b8bc481d7ac94c98a323adafcc266725ba3bb8b0e2237a64236d8628d52ffd727f1d333f81feec2e9778871b55dd5dadfbade83c47f7f5bbd2709ca7e355b3cdb5c7104e6ffd940b25b5ef522afec25ac771c9c550dcea3aeb9cc48a48a7eca8d0edcc6811514a25928206a163e55dd83bf32cd0e40eaa9e19d8d211804bf29b753f6f805000bc18887eb4ece34e2016bd90ff39f608e26ac72f44b1c28bb3fc68be0b152b21ede12bdadce32cd3c5b6f496e31bb51c5c999fff54a10e8d48299e18c6b00e719b3e2c51b89b4f4439485d4c835aa8fd0cebb2743a5949c9015da17a08cc3cde7aba0a4826e3fab8afac2c35726b8a4916bbbc1af0b2bcf86251babd9369d0e169b450e2daf17390f9522a499e80515b637afcc61ba62575d09ed66501dea79e70707f0440605fa3bd1dc7c2c4355a4c0090dc8d84c96ce2d4d73cf5693d8027414530530798a97b16a34d29d7b450dc5445dba871b706dde49f54f747b08d0a6fef5783045d4698427617a4e30c84df34091f3391db5f828c2744779331adeae9bcdab83ffeba73a0ee205af69d5a7444d2ff004b12887d08c4ecff5deba2cb9a0d7e52059ceaff862514142ed10e3f705723093af0b484aba5cd7dda534438447978112ada38ba704cf6f0874d776e031d781dede33d76ec306ffe15e11849c6c56f688ecd2e263d9c92e627387944d80601f96123d98714c6a6d023ed5dfda0a768b8145cf30c4f0e930635a6a1e7d1b6366cd4b1878f4ddb65afb6fc2fb57f1a4ca25185ba076aa8cc39726e4e416ed3b0fed87127ade06be7f60f416183a07a844ee2f3533c32984a9e63bb366cad9487a1de244e860e01583ceab486913ec650df35e1fba125719d9b43cf60d0b4e250eba8569371e75786f8a201b830620310d4d907d3d173c068cc4b773b2aa978d9364e3c65dcc5d0f04d9c4e5ac9ec27b6d39c8f438f39437bfc2ca22fb6d7a20ae9f837bc4a4dc6d9c894190b195ec38a8980bbf350229349e9129cde017d5a97b5173b774fe30a351dd8e1eec691add1d260ce94b35d496af7d8d941167c980727d5b22dc8738f9c61f9d8cf1880ef3f9b21ec5aad210d0162b0b2b644e73a92e735a73b5bc340b55fab445adcc42ca4cf3651430e7d6ad3b05e9fbd5237a516d7283e8c22efc29c712ade0b4127c29d7195a183e70049b5ff786dac92af4009b8b921b6cb6c5c20192ad9a1497c040e2f2fa5a8e26130cc109cd5acf897a2e75e01fc6891234a7308bc885ab6d04ac880a577a6307548b23c49bff63b5f18558e2528c5978878b91dd2f657744d2655811d17467e0c0da2cd3d00a3fcfd01a70b062484a614ad3d5aa499111a598fdebfc27654464c333ac9958e87b1e7f6cc3f017f5931b78e27b78337f3f5b825d7af6dbf9bfa1f49f8a5376efae8954009a503ab8fd50e61dba3c2fea815f5df6a3642b7f0aa45b56c21d0e7f24dc60a7836ab0b9739a879db14ccb23619ecc8f585511efa3266baa7889d0c5bf52e7184b1f50fb39b869ab871bb4d868e866d1c3fea45518d40b338810f9407f23f3f3ec091bae5f6d6ac2295418962bd875699d7fe64bcd0b98d650446248943f08233c630aef2d43169467f040c30a0888186efe32ea9a0ca48e16ee90fb3ace6df474d14b427aa749f4911eb4e212654564ef74539d6e070b41a1c11a6fa83e20705b8434b9fc5354ee7c5b87755d5653d975a80995e4af6c8ae868d2a5d601c687dd39541ffbb61e3afa0c5f3f99af4239665a1714498999eba6ae62e3e1f7f1a21ae819669bf20e2d07cfa8d142381e1d950fcc75d91ba914c6d75a8321f2ef9a350bd2590e069bed66d1be486dc065052512cf4d6a99856051253d5c3c549c0120ff01592b79d831726a90b6828f5b79e13a15544db024bc1a509c982a8befea844fd744b4e093552c461ffb5486db93dd6b3e9e8d0c74344cb66aae827a4a29d7a597e7739fe79a30bdbcadf305605d427eea62f26f46d5e0bfc17b63d83ecc285fc06dd9591fe99cb4a1f510c56eebb850e1a278268db2bc1dc0a6ce1ff6935fea59a8ecfb27a15f2532431672b923343798a421f9e5178ac55045984dab869ad37cae3023a5bcd69451e15080e205a148e027b6b6a3e9c4435bef06cae598708bcbd02ddbaafc97198a665edb61ce169ad5b33f06fc3f62f908b39e0005edba7463e82d1b4926b5436c6a1c50ad98bb2e5ff002cc333c88102767dbcd42a7ac647d4f5b61ca9838f14035e90465972cbec27693336614d38ce52cd416c40c16738bf9ac36b245c2acd55fafa7b82f56bc43d85aa877d293a190c2dc74be6adb5aa96df2b0136d98fd1ba591ff35fd119d319ab59cc604c37db69693e34a7b976fb0fd571ba7311dd8f4d1cf93e7fdaad235f22c94120450ca0e558382bdb88a182346b37956a66725ecab3fe4fe40dbddba0e4e8aeedbad12dc05abcb2c4efc4571014143f7377d9b6b201a20093e581f42ed6381d81c130d8ed26a19055a40a84d7bd571d0ecfe0510ec4fef7bf27b7565c1124b24571a3196641e7373e75a9f7dd6f5a8f0d4276093d442d09f412149770fdd8ec314c6855f3a4e3652581cc26d269c3df0d9b55b6e27c6c6969e63a67e5f21b4049cf84d60e76d77a5701d6bfb40abbef8e82916136ed33942d6745a0b9110bf179489225758c0c97ff821782a6a0ee8a8f364fbd062781c83edf8c48728152082a45f0189bb54d293fcc982794e86282dbd0c8591ee5bad8024dbb9a6da4a50590e2da22b02e82710e09214dbdd3aff9f429bf0c93a714afe6fa897375b437e91b6e14dd1077e6ebfa9b69703472d286af86f1b53bac5a5af738e5d10e5ff9ce3f83bd55b6a193e98880b85fd9de8fa2a82094ddefa88fce7e133d41966ccf053efe5c60806f173036c8431da7a64021aef72af83bb00c48755f6cad93d3b5e60fc07b7923585c863679045c227bbe4ade13f5b783275a985da62c6696a0530dc5a41414dc43218ba10bce0a8f1e7a4e678c6ff773bf0e238762ac35c3d761e6fad02b695e3ca3215417e1cb6b1ad6776f36c43e1d086e7455e995c6f9aabda1cf38a873dd1f7721be01bf6b8a721201bcb0478a774c9a8a47822edcb5465f29ccf5cc2aa4528e3006d472eff5e1fcc3f9599f82efc28d9f545371322a72c2bc7ee6da29abdd60d3940a3352822b618ca82ee5c486b60d745be585f4625b180f7824e71d573849f476f49ff2113cec948434ca7121e497a4dc56df8e0c9c64b848ac5f9ca86ef7f610afa77a5a4b6d876f94ecbf7163bacd33dfa1eb1bc62e24b4dd14a5bbc13607abaa5edaf05f3bd079d2c161a601411bf50659541fbf12f45d54a9a416b800e3c3b086e3ad681bb9a18446b11020954feda8e14aaad0b3ce70f6f06f21696a44d57b589b99031ac753e2be26f87044995826706f79f4ea3117b678a86b4e6a9918394166da37c6d01ce67f91a96dce6c98e6e22e2e8a9dd445585b42fa8139d0abd45ae369a74bfc2b08cea5b39283cddf29822b7898a654d1def88f8ac43de6fc4f2380a101260fbc57e3cf329977558bb994a73e17b6c43b2b3e429afb0515f214c0d17d57fcca8d03abf8783560e2008152723385ace81714056127a098909315c9073d47cac134d811407a4916b647dd31dded269f3494933ee7fdc1069a05704744b237be0c7b980f053692167a5908f6e3ecf0eb04b98f7f5cfbfb6ed43dd8bcbbe7c22a0a56a8f221418cba0407b76d7ce5e7e47b8aa2e0b8d6e76457598deda8eec974071d0187e7b6d56e045712060684b5db34d29700d141aec3be3c510c31f7fabf8ab17c23caf2eb5b64c26c21261414b2431eab3f0fc43b0501b6b2850e91e7f3fd8af53ca5b906177c93e5090a0ec5c74646a7ca3f96a28a67f7289917379d1678539bd5992153a587c6c6e4962efb30f141aa37ed98eda0a6d9efc14787c86168f490f61a75db6a868b7d6120a4ae140f3f5834232397fd8304044a2ef3b668e3ae6cb9ea9b3fc9a6ed9f5ab0e1920d16bfaf75a9f7719d1af14d6cd11793d1e6119975db2949ef58021a57b3bd207f3201a43e9a6cd6bca1ac99cb2aced9f1557818f7442c34be7279c80ab0354b864c866693885d59f61d86a3f0bc06eade9683f60eb973cd77d7293cad498fb32ec0f7dcb5451260c4d382c9eb79f4b06a47e957182f0b366610b47db4cfcc27febbfd89ab937e0ecce61d91cd2fc0d6dc43268fda19f1a385d572d1551d3f27e427be76e97d4e0dde305305d742ebc198ac12d3ef89ef8983228748430530f1132b595ffa5e3397ac6bc855e7c774abc9c1a4e1340e00994c7ccc72d706e1938a2ebe25b89605e6e43ba765ce058134213585b541391fcc93bf88d785ed22b1aad364edf8255f74b94be6e0f0913adbb13ffb2d2bc1c177adf068aca7107337af4f5479b456452bae182a551c3e0e0ec7bfb45f4f42525bf9cb902f1f1d7e7314a979b29c6eb6d46aa423a9b07a835365551b98b483abe2c2d89ba65c23476e1c5a9d7b8a5025928ba591f996fafaaf86f4cc686bbbd31f52696850832be98e1b9db7d133a8f9b807aac8030775da18db710f4fcc4128e18c21132f86838f11d70995608befc139aaa14b057e0d12b6754a62a60140debe994cd9d800007c38eac8c8132324a75c51d574aaf4c70b81deca425790066627a443df9e100a871e5911cf8abf20408fe9f2c9e3735c7af06262c2dfd39a8993705f58f42b6ddb3bd20e47cc3a57e2a4df82b0a31ae6063c4e71cabceb2c8f17a1ddd40b7426c1d5a0a3e0bcfd660ea8fd4324f25c282d6f506e6bed3887f769205ebf0ffcfd4f3c3b33f225e76f75a5bfc51c5c784bfc5d4b2ce6b4dabd394210a7b6f852979ea33cdf19948172e45fa694f84ffc14bc803cb7f6c6904e49514acbb9a114430070c1a5b47e57dcec02aae6e45b82ff5c9dfcadedf54894a87dbd047600bbe1866e96daec097f76462d7ac1bd4de1f41f38690b60f7db9e3ade32a4a637344a9a78b6b69cd55abc074a0233ffc7aadd0142dd90058c9f69282aabc78e908a09c4388e26e3bc2d8f6955270b0d35753ba56814d4e79638fddd7be451590f4adbb397869ad16cc3bd469d521cd3b4481b45b66a588a74d890df83d56cb30e829395c4bd07a28a6e25d724ba6a482f1a346bdd9b3f9a41610ccd1b8e25b13803e5f307e338d09b6942634d12ca05090471c401c45a1515c83245d41e3eefa89ba13ddb5b3f8938cd509e6eac82b99d08535f88655ccc61bdd74ff06f98b61371c2405e7bfba5f19c4e1f1791fb3bd2eb7611ce1fa49d202b60a6009870fc8eccff2a6ad7f78e01e8e59c709261d6be4cc6cc207710f000425e6c2f75d7b4ea82412ad092e2846a2d419065a2ac9c9913edc2f5b71ad419e3faa051943508613b16bf264b2c9945d982d83cb00e2c38a76c6edc37bf4fb447cf0e72792570e04b53c61001d1cad555680a4fa361d746b205f4f56850b79d405a1de6f86dc454300e17e7d0d0d7fef3176e8de1acdbffca9413d4d39c2833aa3d83bb5b4ea7b2b273056f37cf0501bfd89f50a1dc7fd7d9557849e6ffe90bf93c8ff09bf90076a257869ca5f40b1cf4e6423f73dc9dbe24c3e1682e870b4664cd6686fd3bda08e644994057cff1bc02d83634d160ee964fd124e11fe31c1762f42d78026f606fe97a6633464b38eeffc9504fad7db604df2c8347cedcdff6a085fcb82b46ddb385879ca317785f30d2f278e84d2ebb0bb46b01ae2bf7a929e7e1fda8eb051f18fd58624591c0535f04de13bca1a4ad7ba0bbbb4b2ecf35d99c3b99fe0b630050932b0ce1459bf203b54a9c44eccd5301dd6593c9f47b7dc0aa094689a191bba757a5bf39abadba803e06ef686cd439cb481348b84cdee43c345a20e71932da22d4ec909f3723496025b011e25552459b4a53680932094442ed7c7af8c323041babaa6816f37161936a2478d099b27353a1164f383aa133a9d03f799cb4d2ba5029441ef330191c98cc1cba2dc16d75a54e1bec5ed4ad5180ca620f3ce682e83b51db10be55b0c0d7af680561cd68c83e7109343554d5101ea4473a7d0d515d0c5617028f4112766f37016d4e86339c966c54b8ae1de01d3c17cb38010414c5ab9ace3e1522ba9130eecc0917d312ddf4e6aac9de624164a66ff79ccf714106b2f664112d7f164026a0c0b4b547b660e112021f217c23976e9f1d12219d13040be5e6094da8f248d340946b212c2121d3d92cc51e4d73354c66521a9c7cf76a61e862188b4bbe414b7acceef80d205b3b9648cada784c2b6ba24cc6d4ede0b7152d3e0799f5e0ac863fdf76ed4bcfbfed97bf09e4e1262fe367d89a8e03305f40f3be78f8e6b96bf2aed3734d80b07e7f823540c4c6cb1be2a8cf2141a8c519ad46c469d3781f03c4c03e45db2fa1cde5679e8ed6870e7e9df40d41c765fb36a3d1633cc6fd1919b63c27d1f8de68fb55d58c811dece0d05a2e17eb99fbb0ff9c0d6e325685e92ea6ec9b2617c1bc3ce56516779aa5e4c9df334af0580561e7b463210bb4224d22c41b4f1d51f2caec040147188c6789e6117c7f1c462b5f7ef3f3287558efdb7099edf2a8fd437897e23794898218684c0e05f68e17172a07caa887cf4420deb2aebfa0331036fa3c99c5505bca9b7b3d87d2ff80284c1d1a4549cafee8b16aedaf4a9d78e55295d4c43bd71e171adbfe570a1b83218e23b91a0c20624fb776808c28f283ae546f2e405e0b61295027b772a2e9d0389413139acfc2213827f0f5f9cb3e584af4d21e5bf5f49685b07d59946ea3c6c6ff6419150e68862ac2d1b94a0eef5a1cee1d25ec198c6dbb676eed56af5717fb650c5736824d5a1d1a3f8e025133525ba3adfe0af26f55ccd017a4130fd2ccff4345bbdf78170aee959c893f9aa63ca9994eba50e7820c14a131901661e8ef2ef6da94b81289e485bafc5c3664e172d8dced225c38a042da4c701d1fd556228210ac71910c063fd85ad55471bbc1a987aca4aff738edfcd85fec0e05592de141b3252e381ed069c116cc070efb6c85fa2fa284fc0cabc175e0f1c67edc4000f844ea5c801f8a830a9ec06ef3912c6bdfee1b4d98e36b1be13aebdd98182a133ddb0a66d5698ead169655ea25a62cdd78a6fef03e39f59b0736ee2214d2ecf430a68d853003db4ffe28dc72aa7c8efc41aebe5199af0f315e20d1032c1b039d0fcc4d1c8083264e4d87263c070e7769af7ae53295a97ee4baa974c7ed633dfa326e73fd940e6be7e9cdf174e3d75c9233246ff360b2753d94c3a6cf44f4c2a0a499a4dafeed53d12d0c31a3c96282d2e1a71b117f7e50aa2cd39b4b1dd0f202014f8253cf574718d9319040cf0843315d023cb058ee741ec788214d03bb88389c86d75ef9ffa81c0d1668d08ca24d06ebfdb7dab45088468c930afebb999ed6e4ee7b976db7aa8fc3b06a0f3ec63000f63422de533a6e9e38217afb6e88f3683fe9b419178d0fae89d9c3f155eefc8a19e889a69206280fd5bc32ab9589f9b0370a00e3330c1c84a391b624d583f4a42ccd9dad01d65aeb8e163daca98c1dcbe83060eb4f99618f49ad8e16f1e04c84dca4dbfcf1a6c82804415c0d92040f0152cb40a38f74c5436e4152288fbd5dc5abf1fedee3b77933c24395e03e49c8e31817282d1e51538e543e2b31a0218ae7b9e27d67009b51cff44f7c5b3ee584499a3793e31c5c3f605de6847435dacdf10321aa4f6acb923d5471f6f2d0e5aebb328e675fa6b992ea3822b6c9ced56c54bf30c28bb5411dee0b07e3632167117d95df3528746b89af6cfdc0a5d9ddf8687bf16c70ab438e441e4a162c520d5c41083b6e3bbaf41ddc7046fd17ba6189ee729a34da0c9642cf9d1882452c3518e262ce4ea8291fced8a0e5112c7e2ab3e2dde66e3ed9b580adfd4db5f88be5158477bd9b12b76d462a0fb56f28a95b8e6893c0eb79b8c6d56d95ca70e1f4a6add049aa18665b752e8c49b14b63802f147fdc4f254a962d116d19f608b7f3858ad23bc0d31cc7ce1aba9aaa8d7bc909c41e000e7860b222534a6a9be33077c0ecd6ad13aa1875f876c6511225bbbdbdb44b63c79916899e80c37293176738acd276542879b81f67c28f1761b22ae308fabea3d74a33339d77263ea8c14e7ea73c2b2f386a52d0c43b4406884d4fdf831ff5e4619adfd9ff161b8f05425ec512561504ef6b2fa972ef8ffa5c41987fc76aa14820bc1e1b0701844b85d72ebf30e527e89fcae028050c203c8840fe6f00fce8af2b60360e1b493c117290d9af45c52ef6479542a61addd87ab7f29fbb9f88ab170561352995ea05e809836a3849197b0a78aa66bc268b3469af4603e77d9803f4ff6adae9c6cbcca86b38d61c615fc3b8e6a8fc46a84caa7763920cfc12e68818bcd8dcd48ce57081067f0109d7b226a0174ef38d7bbb12d73fefa1caf61959db463d27a8eaa2f03227a2c1797e4737afb15171607510227d89f19f4a8db417603e21061929c2f7d070e08f5329302c782c9028f1f2546afc2f5cfe272267fc9957ef49126a98987f1c1c71474ed569c5c3b680ed641ddb0dc596f6aa6d865a45f9aa5218d016b293d4dc9bc9bbb084a1b7ea6aa8379b11c1a8858a36c468db4dff07d56ea6a379d109c0331f09e381d691f7158ad2594fda0e87c53800923722ca54554e800805c6206b558184aa3dee588e9e5f1b5fa7275b16898805ef016e21800c1187c6a8579008cd9ed10e9ea4b2c9c27a47d61e11f459afe8bd7d1a69a9fef58acb2674fd9ea3fb2f4c9685c171ae0b95f300bcca6e83aac95ea5959bbb018396f0ef63e6f069acbdcb46a6ce1db956e8610385b2284ccd7daee58001370ae181505da4a4f58498fc489079b9a12ae67cffeba13f07274297027f4e78d6c4cb844183642f999a13efb24cfe9617e6db96cbcf1b59db8b545ee35179479e0972c6b1b76fa89f000a9d4ced76a6a85bb9de74e0e4c55da8b02f2d58fc1f6ee34500d40f41b129094b857a157985014a1a67f7253717d76e1381e67bbc19c37e0c34e11d62d4a8d53c04904c0b6cf529e298db0d3d5d2aa5bf80add71d0e1abb290a2677df5fea29da0812dad187554dd6661837320ed765be05c85d0432f52ed9c01a71f733cd0898d8f946f3256f504556d8ad0d5dea8ae45f703c90b3f4225813f5317bbc90349a241ef8bfb002d6b8aad3fb65178be17ad8496c1c1860b7a892f228f7352329aeb1c4d39b8b9d65d80ab0b7aa77cdff55cd64557a1b9381d25770e2887695d46454576f0aab75e6624e85960423c488afaf593be1fdbecec237772680af58dcb2be7b1e17249dc83278512ff58904398e5c7890ed5fa79f54594fceb626bb0e0a4d9a98a13d97a6745728737ce3c7678b35a82c611661c014d6427ea8ac1a1123be898e8a5a57135326fa0dd1eaf8bbf94cf4783daf828d661fa4d06ea83cf9ad12ce7f0968cee6ee7b199507cee6313e51ef5a92fee9f4faa6d81275353b8ccfc732da8f35665d41d56063490326de7c2c22c2b6c35d6f028edf898f751ec931a53e14fa7e5c4f04521a95586ed20dda8381852c45ff79eda13a2d0df69bfa87385ba506fa",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x58b0b93c79bd02fdb88027328e38a84732c2f9368d187862c618e292b9bdda60",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x4bf6f91d84b37454544279cba152581ed6820044",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374cf0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x75d60a0823ff144d7b2971d466cfeaa28d07d585b1b4d372801782195d6638ed",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xf31905e6743b1e4b2f8068991c8ef58a506b03fc6a321af8a473f0009ab1ae35",
|
|
+ "timestamp": "0x6ab8f0cc",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-anchor-20401392-baza",
|
|
+ "sursa": "2800-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa0626573752032362e342e302d616572652e312d643230333230312d7774613037f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b8416bfcda9ec12c0763c056eea9f680be1ec147f9cc88ec5f921d7929abc2ba284f0951f62680a8104b5efe4e586bf465cf6611c4bf5b3184387f7a32db777edfe800b84122a400f6adc6460e3f8d1801cbbd4541605925248ebc1a1e1c3c5752d81c282b2e33a2ff6872061f3b4ef0d987dc851b2acdf98b99daf6e475969f2febfdfebe00b841afb40c083b41cb1af794477e4476cde0004d7b6824d0e3e39820ac9f73a813225b2103b3b770e9365552194a97b910f3b080ebb757bfb80ad451af4fae8502d600b841d3b2712150dcebfaac2375d2c95d0fe86da287a8bc772b90ffe740f0b98674666c72c322cf19caa22f330ffbf7459576a9bd641bbda7b7b708082e26f0ab72ff01b8415b7dd4a4a14ba79b18ba4982a55a880c6654e80033dfcbd5ab64313ddfe4a4441f41a29e3c8fd3f5cee106e3d3010481201d0f54ff57975ecdccdd70ec1ff35e01b8417f660e4e738fcc9f106c9b6a85b4d11b6710ccf7b17ffecf69282ce9135856a1536fdb3c65592d44514d110e0987e3ee73da0551273957a3aba24e4436885ae300b84158013d4f8535b60e9b96f02f6bdb64de34e3cffecc0f7ed1b8286655645886a837587f78faf6e674afade8f82e660724f0b68be090b40e9fb9179052baab509501",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xce4e2f5539b35acff0a0e011d489b89f0e1c3a3a50bd90f38e9952f396b275fe",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xe13aa491abbc1252dd714e7ca0e55717a2143eaf",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374d6f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xb944e01e7f2ec1cb45d8250b177a810220800242824a942e7dbdb55c4d79f3b8",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x3c2c12ef720f88fe0eda0d9d0991472f5a53e79213bdd5c4e6d29ab0be893124",
|
|
+ "timestamp": "0x6ab8f117",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa010d5ca0f4fc057d63ae848673ec754e2905a73434051cf81d567f8bd86af91abb36c961f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b8416489811dc3f74418d845a63b96e341093911747b6011f8ba74028bb2fdb2f419422bf3f25b1b24548d9818e9c901a09eaa2f6eca9ffdb5bd198662ca285e5e3401b8410ed2d465d5e2201919a7d07d99cb1a4b5a2c2f757f5f44d98588032d56722b3f3ec20642fe576d3c4cbb382fd9941fbd41579a70cd60b77d85b3342140cde34e00b841fa365c7442e1841d1fb31d7febd6383c0da19daa6329153f312b1a51fdb3710d38595298d9c85fef7a758f96a67f28a325dba464905713710aac1ec1c4320ecb00b8410fc62d806bea429216d317b02ca6a96c69151c18c7131f0e642b9bb24096bab624be0be16cb0d1abcc2075bea5b2b4b8d79a3bb650c791e9dee6ff0eebb0015a00b84128cc4cffcc2b6ce2f2b4acfd0210dc9015e286d359da46cafcd6d81166f4efd42cd181f73b180c1517f131c5b48c598e9fef93d30adfae12fffeb6ac4c8e0e7200b8419f56e7fef06d4849269b70477a3b5aab2466f65d1289aa69b7407c79a7db07415bf9d54c95e05446566b7f57656f27052282dfa2f436516b5b24e7dd0106c43501b8419c7d7ff10141be181c4c2a12c07499fdcda0fb920a192d756584fe6a1b0c79102c85084ff4c11572eaf1d791e08d5e5374fcd1407cd03f69312ed285b1a0a04700fa010a8902fa010a84f902930180b9028e39cbc7ce3b1200799f0fcd49f4f6103d020bf97bf26512a359101aecf791051e33f4a88d1c36527a553cd453a3f58a542dba7c289adaca57b6b1faed106b67c3d924c1cd4954a09f6de7fdff5a4676231159d74c9b5e1ab8b4de0064855983dcb9fcd2516026a9f259c36354db3b0fb8d3aa4fcf08cac159165ea35cd40cff25f3e154d179a996701c848950d6a51c340bb74976a6d9b9a7fd5469e146a49adbc83c2b578fa739bf5b9b229bdea9ec7ff68d41373faf3791d0a6da2724109712282688b27d558d6e334eea586ad87626bb4095f8b12e33db014dc916593475a337092260b53fd2a4091ed837f2ec8518e0ea86553472511bba4d34ac0855111de2f04c4581b49956b7c93b8fc2b77627708954bd0d42eebe674a0ebfe060bd1b8fe3d6c5956cd4165fb998b4a9a2151569aef1261ca8ad3ce6ddd39913a86491cbd3a3559a5df3ec95920cd735d8b52e4ee34af7d548908d36fa1675235d0bb60d345a0d2b512e84444d5cd1426af0c8672a2b31a3b13b09ea23975a1322eb2c48a3e9db44d6b99b081af31f54b3fa4cd151310d2e291dcfdfa9d6440e8ba29420e91bd186bd176d3b2699e334b34c8269dac6a1fb868e10df937ccd17679a6464455efa37d856d546b95559a6f7448e100bb9bc6051a48938d2e10f32531cc5171444455842118750eb4a55269ed3dee88c97c7e30a92aef206ba09358b495154969886ba6f2daa7729a850f5307617b775d9325cfbc47376edf66b0a17d9339e0810ecda38e5ee2440e4aaae388ec4fa8d9d4bc82f719526d4ace2483ee71d297858fc4a1724fb61c9b89041160452ae98dae9cc7c5c95f16bd60a7b915675f8ce2b2be0866cf5cdea08dab41c9b23409bbb12ffd994e0d612bd977bc0e32f79d629f519968937fdd31066630ff91eb50280b91eb0ff379064eb86382d7b87bdf90d0c3684f9377bbfc4b48c6e8d5d6dcd37d8842d0249181dc1dddd0ba8e3f94350925a91c2cf918cf6d7b04e7fa084aa2a6317a72cd2790ef58558f91220acd59e00f1a1bdac1502bfb97efa2d7229f0d905f7603229dcd2670432d7b8aade3332eb33a5bbf9285038b039c8fb6c82123084c6d5cf7e4979e3cd747be260cee6ba8aa1dbb72b453e4ed7a796c769376317b3534ad2280355b6207a5bc962ffd847d82630632fdc4f770093d5c9f59481d7903c9bb1cc20e43c302649137ac226b8a77fe18240ff175712cd16317c993fa5f3f3500592c503d9d98958a8e472936c8702b23a37d29437c34de94b4c085598615f47e8ee60ea6643432d0c57770ba7ba35921f93b6948448c8c65fbae3186a48a69fe10cf5060f6ef30d8218ed15cc46b5899c343a9e90e5679732149feb88dd01ccb867ce2a7f9c21a49cf0a34ee1db3205aeec5db740a164730d4ea6353ad4e7e31f8eb2eeeaab32140a16941828ed1c4baae13cf4692b92642520e0d1f9b1b27b6fd39be1a629d8dddff2a47c24112d314efa14adacce1e01b12b331e9baff76f4b36b93b7f2f56660fef9af76e14451fefc05fa718d08f13368242d5cc74941b374918445c7570637e89ae454d41f7001c3b60339074de5d62aa416f41ae29ba55053620e1f897850284317c35ce6fad15cfdc65fa2ba1f34972d3db0e703cd01e22f914389f60829409d35bbd134a32c1cf75756956ec324885d240bf5642d3a82453c8c038177dda6662b20fa96b630de1231085dd1768010de3e9909957ecb95fa65cff6ac8fcb6b3189afc4514d6fab48d8eca0de6bda4f441b6f9ca87300b9fa2ce9c31e56edfa76da22e71e7736f2206ed35ca5445f537dad21db978f38d78edb109915ba59b4ecdb768c35f9dcfe4208af594b307cd57799a6bae947fa7decde5d9363352bfc9013a3c940f23f73bc4e3d6d5d20d15b72220cfb3ae8529ec9bc1f45b40c1ac911e559770a3d3913dfbd1e83da1f66088e6db29e788db4ca0440dcfcf587e21d3e5ee1b1c6f17e730e5d03c08db4f80602f1f8e484df084f06d04e37ae45de0d53f49e310007f0c49064f6f99d39639a59debcc0f6eed622683e3275e3a20713846d753654f3174a6cecf0c41673ca8a228ed9a5e3bfe089e617216a64e361a7a0aee8be2e1bd1e9dd9b2bda25be6362c9fe685d3d83ee36e17f476fe4cdd5ff75032ce79f16e8d581691ca3114e9866932e385e1c648db6bda27522ad67c77ed54ab5cc7005ce5cdd1df301d5984405564fd7c72bbc1dff978a23b74b519c36f4cacd4aa20bd1f903f4c34cd0233b9c7717c18c29cf6eba34b4e81a003fba2855af6da99494b15ae8f66c153d37b5726cbdf38e4cf1ea11215d41fd6f7b90ea8bdf1d56050ff99d5a7e1a777a818e2e692fab7f7eab13d710e8702a224f436e0b231335153a304b4ce9d1097f5afce579a44b2a68ab913d7cf9648447ff04fab5b45f8a36be82cdc2df2e245ef836cf3cfb4fd4cff0a0e928e487fe569050450c07f7ef943c177b615f019d4a06b23f194fd2c27da2a928b73ec2b782e087940cf4666ea2fdc35c53ce29fe706ca621ec99190e640ef4effab91298ec6c1ffd5a772d6653dd7c0a8f6305d3a4364023c423139b5e8b671968a49136399a17088158cd4a78447856896d23d0610a9343365ee8f731f03d332e059f7780f57f90884ee16b61e29a943102e3fbbc25cc2c42f2e5357a560457160f949e07473dcc53db64ffbca9903310aee38f7e89b6357555ae9c2815d4c3925c49c8d5da2677dca462e33bae8881ed3bf3839b7e75a34de670ea623afaf4e3e5c67b37a94c18be49ddacbdee13a69c62e19586971ecbf9e069004b1a0c0b4981936d3fc2b8316940ea7413d07b5b123d004c18f9e82a489708d47ebd38bf80e5f8e960c9655a60315df9328a65516488b972950c1570b352d0d9e07b2c12eef3133f4dadba52f05128f21366eb9f35681d38f915f1226cd17b635b5be38d03c55f56c7b4e02503849d49de1532284674bd3fa89a316500b704fa50cd2ebd4d019cfd598a8eb5fd87ee145e42996847ec8c5161898b6fe47d12839d832dc0627949e679a984a08f0a268b3e61d8ae2313cb3d2f54107890fa8dbe9aff9f1b24d56b85242abf32349c38e5cbfdcaea29f716f17c3a0c7d7e398b6931f7f61c97893307ab127f374abb49ab97a3a3a0ac11fe75eb758a45995e26789adfe6ebcb7f42b3811f9cfb30290b387d2f902baca779d4b29d629722e965779661614e2b6190ea68b06f79c732b615d2e11687b4034418351e45b7da5825c9daa9abcc60c58810398d4253a102f29e1e0b9c46b614f1a827339f0cf566ec7270e2a9e40881450d4e611213de5553455ec2524a8871d68e4e85a24e601dc3eef61c0ef89dbad951ab37e48d3caf4aaef18760bfd11e7c85f2cccbce016811f5f157e025143b4460013c027020891c74132de18d48df89df4a4547403e9af12eec57a98924da43618070e0110f799616ddb233a1d2312091bfcdad073a57e75f8281fe53cae42bec4ee608d2bd90008af03c04b042a157d73f8ef040133a8bc3b34fca1d3d46f6d7121f2585e9dd923e06e8eb87ff820bdf689804b4661b60a740f85c11905d5951f32ad47d3704ea61e7f47a83234ef8f85873485969b569126c3b67de682e6bd14a5ce0b19bca39ef8c5d504e388b879a9e3aca78e18d8fee4ecbaacfbaba25adb1570bc8c14e87e2660b5a324ccae9cb37019732caa2bebbb6f750f761dafc193ac823d89e848b36040304f6c72292e57cbe1aef7cc78a6eef3f52b9b2270bcfdb8a8c46175f4808fae9a26b2e350b5291c04697b2493a055d2f8d3adf3e6bdc4e30bed8ab48056063f83c833c8f0d0a6a4d322254f9f54cedf6211af45c92df290f9cd82f3c33886666a4ad438726eebbfd06f989e9b943d37b4a7879e8db6d09b99171f37033414aee925676b88a90066784b6e5b1070fe8dc87eb88edc082b2bb1a5d4760ebacfec67fbe841f1373a96309c8acb8a9c13bb4aab6a3d7602304908d9f002e223befc6c59db8e4b5a24fd6aab7380055dba96c3118ac22e695c71c19ff1522c627e299678e9bbf8830882f2ba4de92065936813c84499d36886d659ce7184a960b0630ca352258e0a50bb454db4512f8208c9be1e23a54ed92b578eaebafe334a16cb13ea13e19ee1669d0b3c0e3e494379ae30b667e96a7064c0defe1ca936e120ba81b7623008db3b64b4b1d3321d10db2dddc5a6b458f2b2814d4f3eaf16fbef6feff7b430a0ed8f5b198a20c8f5938f9cfe2812677ea549d37684a7f43ccb5a54e36b22f0931c62cfbecd98c371cee5010af4f8dd5663fd13ad68d56517730a4caa979744cc5f89a360982131302522de299afd482cd9362dca256e3a605f02aec4d27340172d68376558db4eb9d948e7ca467e57a8849f05098acb1d5f0c2d434f2d1d2bedd4741be753f6e26e0db6687b18e20149327ffdd87babb73cbd40db0b2329cc2e1875cb66905be8e1df6fd553879053d9a82eb99b75292640d79e61731af11e7640305be42143544a5df4d7523298e0de76cb1b390e96270677b005b282ed7551f4dfadf8c3e91b883f770a57eb0df8ff2e2df51fe2a957a552d23ab192a272f71e25a0074ceff8e533033a454b6fd2f448bf743f0a5f170bfd99dea870d037dcf9f3631637b9719559a45397453c26dcc4e91340891b07fa35a115bcd5eefe7d985adf9e42b4ecb6ce0d1e2434a4447c8dfa4bcc82dabe5d6b5faf3e33c9ce8e46c181ae46bba78469175022fd839b7d65d9b7531ef4285febbfd0720aa0968a3999d064d214d2f8cc956a4ec65d9e2d62ade420d2328025f54331d2cecccfe9bc4f1533f225b3e364cdfaaaa6672d6e6ad28dc57c875143d23186cd0356544edc3b42ff6d14f347f1cf66c200ebcb8284c109e74a38217378c4931c4ab856775a6d8c3c98afb88f6b110053916ef6fb8768b71b23423857a3b4a06e9bbeb9e13f2de605b2c621a7c5ce1c6b19b64dc1e74b0115ec8258d3d6da3710560ee286f0b74c51813dda28743c155133198612f55c94ca8f8a05b170a1f80f06b2bc727b08dfa0054c8f1bb234df7c2c3c88158fba13460e64313a81e24024ef3140e9df012177713be8fedbf3731437b3e2281b58093ebfbff697af6682d1f0066c3b9df1578ac38803f8326a4e9288c6def932f4475f2cb69b462041e608232ff680105d6e88a1f66f85af4b4c4423791418e0fe1e2a623c7c2675de4a38e39cd72883652878a7f758991731ad4f6bbf38ba2ce5dcc34c710e37aaa9d3d8862fb20397bfcf50f0b9b890b4cd538cd09962d9aba4acf3001e1dbe3c2f6d764d7c750fc0cb28e38492a58a274af73dc86621f6839b3abd55e35bf8414868dabead3571d3e04f988d61dab99324077003c3d32d0072308cce912a5e391a4b2c09b2a5c54d2d7982c1d33c1ee8faf4d75c78acf539830a27cf617c100600b3b4e9a3c53933c8e6ba04815f3041d589acbb9859c827e081e4d6081cd91aa3b647805e81a210e048a7ccdf5bb450104aabc3b9bc5d9bbeab0a4b17908cad5b18da20b76c627a1b468b076f3b6ef7351f74aa9c8428a62ac786ab16c6f0252fb739f31e0693a55d7bed6fde2da1454a99ccaef91197572f25987344718fb68e7ec2ea11edd89ba4d4ff931311b64277ce94b6dcde7c3212b0a3e1385ad42630af822c97256c3d3937a48ad61003f75c9e0c4e7af4e004c46978db8e0804865324b810bd0ee8023a8d44d7ada18c359a0a97d7eed8e1ea9d1b5aaa4774e92167f901bea0e5b8191ef3715738052e00a3eaa0c38dd7e28d2641db9c7668440d9a97093b130b40dfbdb2b8bd9b4968490ab5f7eaa69697e179f28f8ab404aa333aceeaf156d6d3f935f2c48f631bc6793076e2641b3e43081a77ca6222cfe704391b1ae8ff2c8173845197be48e82319a8fcaddd1eb932cef1e090ecef07a5b2588a89c2e40d57e426dd201edadb135e9f9f4f50e4abaa895b83a774b41bd913494f7b5207cb5b75847cd981d23fe06ffcb9705244874fc10ba3d25f1376253289fa1efa2ff157045fe6f816c028f5d6e30a04b1c3da1f66abdb3d3b2cd69f7cf62765517764c1f7c93c92a8ee35d9158b092c2bf900d9e968cd972c3b7694d9fa4fce929ae2c44882b39aab0116e8cc68eeb9c573c9624f56c5c8c06a42ddfd8f174a20bd96a9ee67135e7e58a5b0538727684c33dcfc3db244375cdd7965554cc67f4cf15af4d3304b43e173c6e15b32269a6ca4b77c9a9e3ef8fda5dd943629db536cd57c710ed0e2fae8ed125f3dd6dea1b1f7655e4d71f2fc415fe772f12e3813c743ce10405b5247203e2534a92835dcf4fdb353d4c910ee72fb6792a7d927ff6a48abe1461b42f7a77d24c8a640b6418db1e8997c1d785c22669f670da2c82f911e0c31b9dfd74dfaba8afa4e945b69eac0a049e43008385243a75c1664be1c2520c49f367d8fdf846fdb784e8e467c47ec3f36356280315fc5386163be6f0a999c31bc9ef172636cbfd84a9058648ec435fdbc2b2550ca84b9f4332d6ccc94217313e2de0138205166a7aef1f6030a4463a3f28b7e8dc9fe411be8659a5be26595272f2e2cf5667cd0eef3308b853cd1868184e877b8d908a6ae8af9de9fa42ff5009794f3f37d6b07f088fb113cf67be675d0ce164b18a5149f23a1504bcac3e50508ea855232b914746161730654a5577586fec129c1547c9a42bae94d38ebf73e4c4e386aac36d7cc38edd7e9ba297d601847fc9e9662da736b4e9fa5575b266a40e91c2a1dc3fdf13434d95cf47e296f02e9eada1b69704065abd7749ea9a41616c210d8c968d613ad4d2734c2bb8ff7ef2749974be0d8412ae811c1b2c287195e8a2056d50673089db72db98a09e984e0f694c9a6dec412d8246abd89b6f8b87334074a674d043131a5703fe249cb67525eaa2f918b6f313635620b3b5260fc935f3893d449f904d7e819941266102883f0eb74d77eabfb8e5802bab0fff6ad449252d106eb85496a61591e2dbef1147533eb9bfc0fee84b6c51247f48572709856bd47bf36af36f3de3de3ff3b34bae3746e1651576b7aa0b83eaaf0bcb8426cf1bf73d077fb1b96226c0b8e0ea2098b7b5ff9e731949e0857ddb1288d5aaf81fa914e0aa5b72fdd1a0661bb7576f4097ae3e3b02e9d704cc7815f614bdc8705b75d26b3a4d892ef5cbc195f29f1512c4ac08ee8c70b717640488819dd005909837d6ebb2207cb7f9e30b6df032e89e30b69781c6ec20bb7168da61fc4e9114d0ed03cfdd1c98dd9871245b195f7ad351deeee4e17f82c7aa0d4cfe01f44e56b29548aff5cb0ae2432d296c972a390335ec7f4859bccd72d0080f32832f95fbf1e4e6a360b1a5646d94aa89a376440e0bdeaf296def5152c842c16bd8e1de45c98c5d1b34bfee9ada07ac2f1b0b92548c757e4f718b55c73abc36ac9d5f43d7cd3e3e7cf8fb0f76ec3a9d6af1237cc351b51733f3c7b5dab0eab13dd764110314c75cdced4b5f6382cabcd13dd81ac53a7e9f1d4c920e5fde2fe03dc1be3235c8411ad587430c4bc06d4a2faa192ced254de3d5f02d6981dbd52fa217b85f02682536e38a98593394dac3cdaf39663b9668d72860a6b6845cf84d332247824ceaf2ea605846fc1dff7515b8c807582a12a2647ab5a7a3cf16f459f1ff5bbf87faa2059249d5156eccdbf24deb2ef00bf52e6ea3b383c6a4fa37d0389c22e7fcf91f790a3183ee26081ecb6b0bd0d482ae87b1a18755cd1e09f7b7f5acbd3cd01bf1452fd422182c402de13ed8b599970e3ac182bc270131a197916c3da3fb905a3290a2b6049ba7c7d147de3de70ec0618fab1a15fc97e3800f7c6b5d5496e7b591854285f3a997be56d4794c0bd68955bb0fe5811ccdcdd6b3cd59436d4f16dcf5cd5001bbad280e8d044910114a3e10fcb35ab25bcededcd5c5f06113a76f4b4a284a9f24c4d7a46192b5616456bfe48f16eb7c45640751cc224faecce15ccb1a3caad9a1eff788eb2fd49c927e2ad7d3d8964269eb62d99267f2f41f4a39a6ae9c723fa8a48892edcf6695922c8b79f830f359a70828e5505c99076be8d51765a38083342858e680d792fcdd2e972b2587b2cc8ff8d8dfd0438f3c1e2df49d34b86f7fcbc2eb025532f47b5502af097527d5e6abfc985c35fcbb98fc76e1be097c223e371575c8a82746f12edac61f962dce9fddf8510a995c646c85e336c29c4ea3b8a40fb1fa557eb66ac9d853b245ed6a84ced23454ef107373ebfbbd8ad880c846c8373e2953d93963a4712a5e77d9c1f59461f1025c66500e1f7d3070380dc2bf6f0e599c838a8daafca97794e3b7d0887387a2856633f13046da33940854c2b8483ad6a221e37b6af1ed6c2e0f1675c290e5fc3085c95a3ce9fdf05a849988163d1c9541f667594f8a0bdb22052cc695d75b8119f16467cbd16c5936d17d7e898bcbcae7036e24a5b23a7b7bfec55b71d6bcf9c917cb29511dcbd1d57e931982010435839cfd20c8864725624ecce8bafc059ab66671db58980ac2b1a325441f88da9a2677d8418c4093a73744935b008dbee943f39c620ed25ccefded28a9ddf76bcad8a8ee175babbe68f5cf62e75ff77bf4efd4a87845f5ecfdcf38472cbf74b403f1653b0a7531544b753b5ce399c0bc8de6f493852ff82ce4224ae75903295a1669a7825eb61d547755f3b71426a89f85962fe4f3bd59e29b9e0f262811276319a96003b8bd5722cdd6ca6b0c357ebd335595c44f76e23d2ee8c79e5315dc71e50fea8af728b425350c0c2f76aabd77432c9c72cd735be048b8aa3d10dc473b3b17974dd561e98573a605c600051d498e5d54aa6da9515914a73363cc2243773b8ae57822a17db4c8c1e74edda05b55460fbc017a7620188a97364a2583d11999f61f733954b7ff0d12ec1beb70011d1359e1ae05062c94fbfdaff3ab9b8421dc476c3fb2f05da3a2ce7cdd375f8537433a72e964ecf7dce7cb541d255f1981ef8f16a797867260d22262e7ecb9c056d0ea3f69362f4e9d32e5de8eea5319b9b36016351025e3f9382e63f1ed3d42a7ee1cf4390e12b359bcaf1fd2466b127d4c69c765617e9a646cb1e15f81c837d98f5d88e92f92724d60a222cafbbc92982da2f8a074f91e057e560e57288544d1ddba783051c3ee1fcb3fb2979750ba9a8d326b90bc88b41a8d04687356f15af1befa1836ce1dc76dc181a9c3b78f1130af7fa957ca2985816f3db16d843ba2e1aeb3d9deba86c8902b222f5a5d4f1cd2edef9b3c1d0cbaac4847ff9758d4b33ea2a2553bdace70f30931e4e184a00ec0fa7bd3d0092891e0e84e2058c54f8c20b3b459e968c16d06c08ae7100993aa9deb2e76acbb959a3d29ecee39e802597dbfc254bed286ffd950679a3a27d42a22a881a62119d44dd38a0e9167100eae4642d793b15b18f5e30ac2da1746cdabf3ab51fb8ec5555b1b595ed2f751767f61604759300cdffc79c3c77b13ee79264b7f236c288643635a2cfe0404ce6b483c4d6835919836c8d5945170aa8c6ae2671c9fc521ebad15d2d55ababc24a0590bb3a0cb00042d4376b6ab008ca3dc986c2f3c5b2ffcd4395f243d7c763d098febdf2a027d09cde0d2c027fe9a7454af8404f280505cf297e5d36883d2622169e254934c6f7b31bcd514ef8a3b26f2f59eea00b0b6cf6d9fc9edcf6692f1a867ba314ea047d86b8e945f79b8966ba362c1e52d1b81755167ef6fb597bd6772708bf8c747657f30104bf4862ef721c3b3f66e1ad8f955f7b201432c8cc4d95bc584aac6074fd35674bcce49bbfa68ba86dd12087c3ee5625abf98754832aef575f2c4ea6e3cc95df6de22aa64eecf0d686ee7ed8d61b97a0ddb6e1a798fd2c89c8e9b9674134ee65e7d6e7f579ee4a2c16d633bc4018f28f0af1ff98f9b4c931c80c19f9e0a611da25473f7257999ccc027356c86bd9ce3b90f4ab387f50daf9b7471f8127d98e17896d213bb7d951c830b8c701efcf416352749ae6a10351e1643ecb8bf296fad314cfe498e44524785b808e6acb9e625ef4d50e2e80a54b59f335126ff53dc739b5e407014518eaaac61b00965fc186350e11a9a0d019941ba7db97cbb0e3fd8e3cb99d98a68ba2c4e82bf46d6a783a87dee2bcbfe6770984d53a29555e02542cb16b3af6fc4ebb722fa1520ddff60f25060407bfd11a0566b432dd6ae0cd4f5c06ff16a0204c40d8384d7bcf80487d5e3431aab1d1a88db12aa3bd81b011a253341be30e0f30315896ec6c9e90e3f9f3014f45097011e51b55d6bc004a48a7f57bd5369c55527d7e4968e7e5b0abbcd3917521479867daac76ca39a0129f62479504b2da0ebac3e0222d70413e35d7d05dc08bbe8cc903fddd8db184134625e82d632ad314c8afe786d7fb94d6f29cfcd4d05343762a422b9d84a015d9821085debfa31639721c414c74088d6ddca15772bf47e7e22a77b7c92ab4b4f652da47dce75481da928ab2106ec1a4c3588ea9598e1892dc1230c3018505d22e67822268e97cbee9228c4c495b9354abd3172fde6ebb6c7669b383e3c214a85274ad27032a2e2869cde3ae26fed9a9b877788fafee0f1ef2406ae9aa1f8ae609ad41c54bb1f0ccc0b2545c542c6c6d9e64296a14d99d7c4f2848f5060f67425647a1191be4423008e439cfd5f4eba3259f57428f263ffdf1aeb0fd240de16c723c743d8498d0bed58da577909e492b65938545202d5f2d11ccddff37ef1fc363babe8f3440526da90329fc143c882be2f978bb398e4cc52425bb9ef1a77408cfb1c5b5f1b00219db1abca5bea26fae1d6251b60e4e9eb0b3c15b3aea67806c5a5926a2dcc7e6c02a4fd74ca53ccbb5f5f7b910e6957829c525902e6a11461906ead63725cb4e186979390477a57ad12a3459e219440ce56434886d25cf1d772991f3d7eaa12cd1f4919d5dd2166c4cc77c4eec8b70532f858e26943a3cda7909199a47696e39ea078cf2e9ad9d5a5a1935ac7af259238336654f4a99a81772591ce82a3bfac362561c14661b7789be8913251250744d424ec6549d5deae89e93b6b818a691654431c60e9a442584c53c7ee18df72533343937bfe2fc9bf0124dbabe897cb0472f85fed824c618878a44933d300f3813a3d620ae4d20245d2b5574fba55a11d0343ec240262f8c466282c2c99d808e875463584629ebca8df38c1fcaa49b6ab643fa002a8f7410016c673cbb277da49b0aa9b2620d19c645778be1135e3076faa0a81ae58394b5196ca90680919f43441d57488fb95e3d955031e5932158cd098cc5b37a9b411e02d69afc5c428f0e67802754c695d10c360e23a7f24778fb6a25b179f9f32d762a9a64a6a6975d07b0d1eade793de38504ebea691d57b4fe117674f6bfb8f00afed1f2999115f13ebf1543f236b6b639a880c50d0b5c58ee3bcc8d5981b9fb74274cae29e70d59957b9785e9ee41394ab808bb356f9452916bc447a9b13616c73f3d16f4ec066adc99fe40f47d0b1efa8572500ade316a5364da9d5c5d432888ddf76a581194aae88fac5b95c69c5664b1934691ecddc85f893465dd7c5caf914e0f0168c2b9b9e064a7340e927fa9ecd5c91538641ad364452f3b925bd09c0c88e414f2e6bf8b236d8ceb7378d4aaed3043d37512643bd1fada550eb41dc2c0ca9676f115578255c40c861836ea99ee4ee3655f715765a60d7b8602f57832ceb429d4ba1406d0df2cf1240bbc84667c64fdc26b793942ecd3600ac87dbf04d5840c73bce91a6e368a76496c4a51f582dc12d3911ef3837e9e8e43dc3c0135da62f541f57c55e4c37f407d60329fc1535b42ae7d642779f55ca8fc60bdc57f74f88b314fb060d01f4c5b6c4494bfa31ee1005a1a56027f94b3d25bc95936f314c99b19d7d67fc7558c703387e1295e0016a6dc6e4490a8a983c266296ad02cf4ca48d3f1c4d053bc1da73175b8d786139a66b95243865cd82a1cb58d7d353743ab3814329720542c72c30e7f04e27686a4ef7c49c1f902950103b9029039e4e868d838f61a043de3f313ee418bcd257c2d606e72148f394884edd41f964730959d7cb594ba2ba1aa5add46da0d00adc2f0fb051242c4cbb758bf9c8d3a80b705096fd1a328b3453d6e55ba948d2f1859b0fa52714eb6611267570b328c820e43b2b95fd48e3182268d6148c13cad84764c613ec9dab7e47da09ad7a7c10c833aca1def87d997da65e7eeac43f650f76e344ee7b29da627cff4b61b389a328410d900f0a60fed4343c083b49d5d922f79b3caa7ba1ab6557e35fbe8db45e09eb5d9edd4318a8148487e4db868dc1841006522249c598ff22b2ad8a08c02159898f89135aa47e2926a1c855f2546411baecb4f4bb342591caa5ca921703dba8098da70d6d763227ee208c40a6327eee12e5e867b512257f549ac3504e2b755af64359cdeda66ef9761b9e2e1658cb9d46b132fb39a8fc4d548fec90e1d891cb924b1b528ac3170c1f58e6bdc5328682ca88dc73162c71adb3bd2d50a38658d32dfc4db60986dbc2242b7a635bcf4af5bc66c3fa36b8430a68e42861bafea5d4772d3be55027105c1e20b9637d1247a963d489194cc1fef81b8dc455aee3e089f6015aa854348943538161720b04204af0562b07f937e4768b934132443524ef6d27eee97c91cdf17fd8721e56c5e79b2167624cf2f40df7fb7e8d77d697922d3c5e20493a0ad6c75a67cfd5d29bceb5d3eedc4153827ef4d6fe2bd8f6aeaa0ba68121457588344f23b4e398031a40d2f6dd98475fa9aa817130fdbcdff34c99b4b35c0a7322cbb48e2d0e746c3a6cef5a5fbcc9772bf0b27b3ffdd3d2d4a59a75db0eab849771751b74551fe2e829d206a7b78655346c4217895451e2def90c3486ced3219517512ebec7cd94791a29554cf3ba82a0f6553ff99953794cf919c9697223dee0da774e539063c9490f91eb50203b91eb0cd3dbaec562f91c975f7a8637231fe2981a561871d9a36714325d6aa9aafefcd944624a94574547bcd2ad09ae921b791518476d5d06d06784995934ca724875ec552521ca6d41b28f959890f83e363a2717532e6cd5e773392b94201be904fb5ffe1e775a78acc4f77e88fe2501724eb62019bce4dab26da699fea1227bd16083278566f207d0834f138aa65f116e626efd21f458e71da2f9a8b3a2ed81373a86e63cf6d9e69ecace4140015f4aaa0f167bdf4ad700dfeffe9aa469e0601ba61c964f6b70366a10c87ee2790ad56f017022638fe552ddd06a4d01afb7e9d1c0623d46ae3b3249ce3334c7580d0cb067a77102aa681b71da92e98a64a185d34a79077b5d36103cd6eb4f5dadade980ef1891bcde6504e8a6b4025f8ec9daaf1b9c4820fcd96e061083dda5e6e34222fcd21596307f21a76108736c029c6cbb4e6193422b5afe0e78a25026e55409ccd3f9fae4d07cdf25e5a413b841b79a35b94cccc8e21578eb7144c268c0ef86126f7f4dc4adf5879737afbca365cbf90c1ef15b71a06051a0b7671ccc59075607fd712310074c1901f79ebe01bf174b261c32fefe04cc3f5247891ed1908dc462675d0cfa2dcbf5440b483847022fab92de93ffab1838f6d7acf3030919b471b0c1a09539b7331b5f67a34e2c36d93c5e20a13804e5ae1a408984d6c7c7e66adb299f3434e61c815b65c839fb836617a4f767f79e00b536f19303e0f3071508275dcd077e5206b5794cd5eae87034604aef1ce66badcbe1cd375a4e845dbea91ee58f2bf56a0c4d030eab9a374022db9b6c7203c2c166fb80e4f8b2ce081892906283ffa229ca6af8abc9ea623a99d274fcb5057dd999e0f7f65477d5d1d2369c97a43d00973576e95cb778cf95bb7ba884a68d3fdca7b2b04914e767fda51551158ade07587b76b868f0746b36a57552ab0675b94cefc912d030fa9cb9513b04e7eb9fd7c79a2a1df7be29ccc1ae457f61fe0d4b7005b479949efd72b18bd3eb291440886cb4a66ab3fd823b912f06edfd10c22342e936c4c41df76f13f17ada8d32a0137d23cb0604db65866545086791df1f4df206ec5584bd19e5d15707fa5dc2cf95e18f843b386e045baa9ba795006e36dc4d544fc710b9488697277546720f052a77171d902dc9dec26684c88cf2c77dcd824eccea0cdaf5b6b66f456dd4a2cb7eccd27787de14fd49217dce1434046d0636f2fe714f34c4eead0ea6607de560ebb2823c2eb1ea65c15952fbc069c5c803d2a2b6f9fd90b6eabdc54f445a5fe4288985dda10915b1f818ac133115c5eea38a68e7228dcce2c759f58d7bc2985a9273fe1ca7d6ce23a354a53065edfb401e90b9d10dcb3611ce9f3a8a2eab8ebd06a58a80128b3343c9d86966b49a675b1c2a74f18463514c78cc245ba9ac3ca80b5a13ecacd7b801cb7fd5676cbb0d443287e56d145192daf631e58d9af10413886399ce9f3df444897a89e6bffe6a27887858882e1a3890d541b4fc98fe5ee0cb6e0e4d82116ff9a832bd38b3f25c72bf8a0839408d75c860e298b62cad44a77b604133a9abce39d2dfe49d0454cc5ec61bcc2b60ef08c8242c6330868526ad4b808798d7bdf20779f4370b708da8ddcdd9221635a509a326e4d37b0f1e0f2781bff6e9cd23829bc79b3c985d182f0cd6948a05787395772ceed0c8598bce8b092777c23c8cafc7b1b847af82ee5a5004d15f361744a83cef0520e6b05d6c1b6d1522eacfa4038956ead8d64483a39123dda4f9f7577398d8dd14ede67a437c1e66ec58f2ca3417f26986253a0d087aa5ffc52689ee62e3563047209c93a2b594c3da4bdf351d4ecde7eab35fc4dd8daea6f908cb53ab372597c2d3708faaa8063ad3fc331168736de12acf582fc10d44efa4c98f8d475b26f7a356b4ad9d80069e13006001ecf114f8e4d4fd294abe6623dbbb41e65d6000184af3e4f7629844bd8a569de508a4f20a537592ef04c71e3e035398730119a66274c02cdab041ec081dff0181253c29bd2b813395fd25133e6c917c607552cd3070ea1ebd7ccc88b027e7de71dbedb0eeb4b05ac258479f00c084fdec393f035ae59398f44f41d4ba1839a248b8f0b867aeafb8c830c004f2f85974d2f7f756fd1870c139d238b48a854decd407aa2d7016f2bf7b3b4523f2c471409d1e68bfbbc39be8bd2f0b838c95556ff55dd2beb090ce74c05e008f6f13b660d18301546817e28821ff84ae28918b3824d55b1dc5226c6d91c304a4792197e8dd51dd12e884770371dbd399b897676c9bed191928fbdd5cdcf0336fd2008e52f7e02b61e1be0672f21dbdc4c002aa969f489d7dc112fb350172ac525c97f75a26c0c5d8b4cc0b033bef8f92d6738f81cc05bb44d5becb9240fdfd1ee5177ddeaba3da81294df4fc72259eecfdd9e02067454c9d6f434802e882fc8eca8cc5106d31df6402c6fae06f90ff135dbe0fd18880d0f0e9a2edc03be08462ee9afa3cab5b46a9932accafb159aec0a481e45f281a9aa3989a48f23f0941060a13f53c7fe83072457d7f5825f7d80b0484a466623afa8bcc95177a18213828448186be63a02b6307da277c1b384334d9a275ebdcdff32b730ba4dd3a7bb22c71e1ce41dd2eba0bfce308d4c9a40797c8df5a2b60a386ae0d260e9a2b87b04a074d6cab826c6e8f10218b51c20d72feab1b14a0a4d76c959536e1403e9dd40435dbf55f71b7d7ea6d76d85f973248e5804c1fe34e0fb918c929260efa12918e390a74c7b2a6be69fcc6fdfd4ecf78c1936e296c723c4235b799249f7f50c9c84396929611de9c8a656292dd14fa2b8bc94457691b14b09a1f4589e5280b41c1043a9cba771275dd6d8adeb19a0326247ff907a990b9c5cf826c66abbc95117f0a9be2fdb818adec64963826ac33c72872d6cb3d7bc799c335dddb906364fd45293be14569335fb17791a3469707c00ccaecdf4c0f661556220b6e24ac99aed281408bbdf676fe61491dfbffbf4e438d57681c48f1f63c793bf1181971bc7f727ef224c6531b51334a00eb90fc20ad9d428d79980df88b27a71f424445b52d229c5de7852c02eed48f9d4cd02425204ed092e3ef5ffd2ba7107621959ec976fac8b12f54513ad20272e7531d07394ba5aa01adbe85c1376acff7350e2bd4b4260b569ae67e2a11271852c36179ec906ad8ba5484dbac53eda7baacdfb945a27f6fc8c6073b18df1714279188daad9b952bb1bff6488133c1fedd14e1c777faf63911da8a73b0cd5e03d72f447641b95ef860409197d0269347f166a1d903243e5b518459503bef45bd0a047ded748ca0ac24bdecbff4e43845c938cdbfbee444a18cf396ce9ee00a2c77b7e7bc34801f43ae1674536a0a5f409567f08a076a4da9598676516cefa6946c531b1aae62ef4ef0c934510c309a6a7cc9ce4689fcd7c345db6a5f65362af0bb30343019a7871032cc77fe75d257196fd96032022f600fa9c0c9db2a7de296d24bb7d68ca6137e5fb3158ac6456b7642a4946c6198c9b39c2f88c59a3f8a437fad4d33e8c28ce7c5ff9ac243e3eece002eb13cef86311f8a2b9e09fbfc14878335d92c61a3c7edab28f1e41e208d6b8f39aa661db8ed4b2d06bf8438817c8fe3e820b9b65c7ae0dfcbf394dc72cae5d06b4fff8c8a68ad154198910e7d2bfafb348eb9d739b84add6b2ae8b854d696a1bc2ca0ac963e6642399787c854545a34047577c466a5084921351a95748d9437a2733df3a0b203e70406a56e86c8875a79ec54281f1ea3178a7de630f03328667d7660c3fde87dc78bda94106e6fe27fdb4265c0be22b2aafbc12a452dbd43e2d62e436da625024e21b6f2cac7d7f6c1bfcb16cbc4bad4e9953c2203651b8d789b73bc53c827dc2e95ae4335db2d482b1a18d475e61e3ac5c27d6d4477a771a30dc49302675431283e614c32744f0936aecfa794dbe418a7fe2b4425b98adad7a9a0b64d38512035728c2df81bbac307d3a10ea20727da126d5f57598d66837ac6cd4965d6c8a5bc31109b9eef75a07bfb65f378df9ce6b9c0805efd5eebca3cb87c1b047e30b68c863f147a6d0a1bba315282e54c340a9683d9d8a46ddaa22ed76cc626d5cdd4e7c5d8d73ce23c7abb5f502c3013f22cbe37a72ae4eab0d888ff3d94ee57e0b50a310a135075ef9427739ba48036176f27c78099099fa3d7d5db055356ef7c8833adb0c075a6370d8f454ec653c81fe236c5edfa2103c7b4a15b9439040b031c3267be86c8e62ff5725c0d753ed06f4f83e2512e1aec053fa791ea96dfa79c0aa0e8b7eca79e313f24c864bd2c3b1efeffc34c13ac1a75329a3c654f0b6a5f6d6dfd98580edbc237d703808640ce3ebbba22bb8abe3ef2e77fc8fb139ca34cfa8a882f43e6a84611b7aa16645bf5b640d5232cf4c8b8451d4faf3c0fb74df7e71288600c15d48979a015e7829c2af7a2e97c736062ed46db869ca5d1d612998cacc2c60eb23800c9293f56b070cb06dadf2b19766cac85ae31e432629a5c0e45f79c53b5f0164acb5ad5ea269c6704322d8c5365e0fc2bb7291051d4dc22724ce767958a2019ed7e1d8c6e28a76aad27039e86e4f5aecad4d25e08f10b89a323938e6af5d55dfbf32d74d152c60ba21a87bb0d092482010e5f4168dadd48fb4af872cb525e0c4d326bfd90a5c3dc9c5b62a8e195f41a26d294a78ce497d2a707dda378305c5a232748c28c63e864aaa9de5f6a4951dfb4d164a93e0087b621b828c1b8fb6aa07185dfb568df0c9152a3ce182266c24cf9f29c2f7d6f1e16a008bcd7a9a80481c7652c829ba6027712314c8fe20f9aee430960b0c5f23daec13af83ed4a05aa5d18f36c89f7521a2dbff5acd939a221d9e706287cffa65be90a29e437880ea69b6d1c1719fd37be89d48c954650a3f6ba53dd8d6a284e1ca003bdfab3917e00bac0ddcc929b9c3429f8c4556d6d9894b452acd0ca3d3c3ba8b2c458722b0f1f0e6677eefefb0ab7eb372510c132f4f1bd4a74a23620ef3879bee642864d7105429de462a29b21386d28b2aff4fc78f35ebed13d845a9d08799804d3ef76741112d7c1ab263182d8f673fad298ab6c6e5184b83c0efc403949c7999148584670a263ab035f629bdc2ebe5c0b2607792b0b27da771e7615aa5c97cf10a4b0e7c0bfdc6f9162e0c8c23e4392afea5a61986cc289586f8304d6a5c5c16a30a94be55869050215125a400074f200949f8893745617bc3a7addd58760b68d3f5a65a68c52f672a99c0d1e41aa9ca9c4f6a92ee35f83338ebdfad530b305303eca4d0e6c020439e41acec2ff32fb02a28d89e1fc9efb430276690f1b91aad1220ab65a6a41b24d0ee846a0233667612a049493204eb6f74e82b34dcbcef166762e827614fc8c9479d3d94dc4e3c256f0e6ba7d0a035d4f5cb98c53d09c33ff852bd8922f235d101856682f25625d6f7b8a952a2df7711a8d855d0b396f29fadd67c5573f516c469e070d3464c39a26f60c179253e72ab048bad36db3d09e0b9260a0c14cb6c3fb523c36f821e76d71b47e83de33a104f34581cded07d4356af0678165519ffdba7cec17a567f0370ceea1ab3d3bc852649357486317064a1133bcc6b99b7e5ece20f64cb58c9f8710b6150974b334cdab1528a9510f6b1627725fa83913e0130af69333db863d1796a8931e1e7e443e14dc93971191aecf8cf33c266dbc82b0fafd38a59ffe60f64cea9fc7afcb4cb100cf9cfdd00f1fdf71670acf726fe7e3b586acd6f9653c9e9aafea3fa3f706947627bb860641805aa6e44b71523f5e4641dc9bdb6e261859099acc3e1d32444ea198532391e7ae3845db803b4186557bf2cb2be1ca71ca2b8b75bd6dc42edeac5000fe10f5b1d7e8f4540c742052f3e93f799a111dbcdb367863c1d8ce7a0feec95a275a5d7b22bb0aaa2367bfac79e3a12c5d7a8e060631280775ae3d989fda432a87d21b43de048e31e923852d7f1eaa0dd1648ca56775f7bac3301c7b7f0499087d9a46c58df00d659bf2318fcd69ced264152bcaefc3da97f49701cd09a00d881271108909599d47d5a5db06259881212467cea176c9e265c1974497acb5efd67ecb6c96b0d539fc3f208056ab8a0767fc0114643f0d1c255ee105e902ee4a25c440cfd8989c8de3e458b21f7a16100be32c97663770a6a665bcf345779f91686fc64e56bcaec2f5520245205ea73a5c7565b0d352ce92401c4c42bad2d484f7ef7e7ea5571395efb6e6bd8b16b0fa15a8856da4e06db02005501aff5ca99a56eb4a61550e88b21a67d7fb806002c148e8aa6ff220a8078e41100505e18b0aab74c63680e3b82ce6ec192b04658e7e338117013f1cb4eba1e4378c125bf00a20b899583688662653c373219d57ab094f517e044e8ec802864d2ffc2531aaa125dc47d7d67d9d54407de94b00211c69e2bb29f16cf12a7a9b3a9ec008cebb429fa9f27e66edd0d8c0f6440f1ba9bd8265f6c0974269a5f9330287f0e290b6cefda2c0aca289644a01783776d7631ebd3def9270d35a8971d6acb488dca38030b6b1999a06f59ba273c29409696108db447198fd76caf92a821ea2e5bb7a33a98c45b0d31f5c06c28b1af9eec1d6eaf80cbbadba55185ce761b41bc1bcf3fb104915700848ba2069f218f92cc35741c26228d3fe2b2e7e65012ec52b8e4d98ae0fc47d8d0815e280dca3b3a4a6b6d5c3be161a5e9a67d513b874a951cdac52b0af10f7d5ca96cefa9d8d58a099ea89bcee1200b0479e952c192796079fed7a1d2b21bf80aa9a085a733ee666643f6353182cbf3578b4f89999aa3591f3be8ee6d11edc5c24668371bac461209446cb6f747dfc793c8253efe6870f7177cc9fbed0ac2a54bcc2c8694829b194da1cb27d41020425db34390f831cf2e7299863f989cf2451f9b356e7a6d0223a70a7aa6fd2f309a6c5625de1094446c929ce473f3a2629581d288da2f4a0f2acedb13f8a28d2c7db5823e2f104e5bcb8cbfd9d783fe62d16259f097f1b6e32cf6c3638de203f3f95dcd7764006173759fa18fa47f27144cb78cb041ae550baa6bf9a015b3bb8475d7eda54d9ea4b247a935884ba9f585c87231208d82e7ff5ee844fd5094d75ab9105c54aca30bd6ca0476e2250ddfd20ea9ca3ddbf1bdfd77ec219f3996bb7611c19e7d054f1fd62deeab41075f461e3f7965d1cc791e1359ff1d8f0775c506c6a06a2295c1f56038bd563aacbdaef45bc66de4f584c4ef486a09d3a3291fcec06db68ef68f360a715b4431cf464cd99e4dac3b6b67e45c31c59e36827436bec0f3fb30be6921bec0337bac1333ea02d06a03a59e7fe620fd3cb920d1c12e8cd5a375c1e9c1b7d4da86f0aef0fcefc81079f28ec93e28019fa0c0b337ef6173727f244a5c68e2c8d2d7eede1dea6d056ca46a0bae614babbab85637576c6fc862e6e750197bcaedb482169e02e61d18a7416b0122deb7ad443c7708bad83dc7eacdd2cbf993e7e4789183cc43382d20b9a990d5aa7e25ad28b14b3c7abae28f108c111d404b28fb9811067a4ca24068f9b58bd3f47c9166d6c652bc5a8252c5368292ec75aa4a718de35bebc8e3f88c7371d7b3ec39937775b2eec1aed1eed46e7fb0433c47448ab4b54757f949c0f2bead58adbd632cd93e3fa2e155cb2fcc9184933f98f885913485b7c2913487bdb4af682322d3d520dbdadc3ef6a18d3b7c16506a2f491d3c1a6ceb82d8e83c159007a1d2e5eafd233d180b883ce5fdf3aa018235800171ee3c5143aab7963d5bca1a84c6d013cece2fe123ae8f55dc4392f579e481d147c06ce5adc8f8dcab92f35daac13a22a480adc2a67118ab5509c816cae5d648a0449f2f9a683ced9c179d037062d864f377c05a2d518f1f22aceaa7aa5db40398ce6fbbace898195f49d239578d9b156b73095f96835b146c415c6bdb164b4b5af7cd29b109a5e091c468e753aa9e47879a6c2f45747eb9eb662aafed1d7f15516e5fd8d864ce9259c00418b2bd566db1b9434dff8981b45ca3f57eb0c3e488190d806a8974e13fb042dfaead8e82c4766bf1f17863888de915f7a0b324163106789bf5a0c132db168ede1f0e8f9562ea37f9cd0ff911937b3008de714eab31f16211ce7df60419194a1a085d04ac8a9ae3e93301e0d1738e809105f32a593b4ffb900a2509e8932b0711655293baa7b254306a9086321f269c19f49f5096cd619772c7523dd9e61b3040660b4761d94bcfe5486dbbd79016d7f028aef40b4047933a5ccd1c63ca0b8969a058ec3c4e4fb321d0b49de63d1ce334f65b2e47be40dcbea033584a0259e63745ecc455e91e88c59f7a1d3012a8196368a8e6c15e472819ef8fdcedd215861860825ffd6b2aa18116745ae33ce41036a77b290ac8bed7015cd1d5dd19de88b3cdea50406b59d434a30903643006fdc5546d9b93d8e9a0880a769e431c8216d967e811544182d7eea0fa40abbb7fc3bfff1019a4ac47e76eb148fc9625205983cdf84d34ffa1604d5f5170a0ebe25e274186f834193466799a721f12de788776620ff593d1ed97bec2d927745dc9de8539580e7bbd71b848cd950dc468b55670f42175d162006a6ee0d6be8236b6a6a8436efa4b3576bed05f05e2666ebd3b717443282556e4dbcbd44a0c24df3492a609498fdf366250f24804461d203f2bb2e9136fd0a32d86f1fe575ab2fbf9f6cbbee99c47931e3fd63e51a6f2222f8601eab92f03ab80b0268610ac4395e9e39642d4efd6a8445fda144d11aae064d2884b832370ecfaca11eb9a5a05febe583464dd010397c0d1998853a5e13b00bf7b8352c6987cad312d980928e9dbd289dc9133b11598145b665edb8eae05dc36d6665a9d9bdcad8cb9753c1d5b966df31ac8754169aeeb0c4e08d04b7044c01228bdc3e2f4df1aa3a89f5934ad5a5d71195f6de05ca65916cb69e5b3b2c6af897173e5ea60291b04647eb8514f30b088004bc1b6fab7e477d13f1111bb4a29459fe00cc0127940f873177ae2b59d0cd54ceaa4f26f78327ab592d4892f50f6a3a23ee169f4e5882ca15972d9b9aefc142ed524683b1ee53051527654666538900ce7b373cd5376225ea2cc03e917f17511164d71d0948e95c61a736c6d05c67174ce623c0c9c003a4a68ca1a2ffcfe493e3bb9f1e75b81fb2d3d7106e7053be75df55ccb2d860894354a9a2c00bd58a1b699fb3d45262d16e5dcf7a733d409baa62914def7a4833129d2ff4d0f29f8565eb1a1d26510c98af0bf15fd9bf52c632da2771ae83511420a5769dbff46fe99f96e9dbff3c5122f46e956fb422fb38c067500f04fcb8df6c8ab3a081a92c7d9fe01055d3a8bef1bdd6bdfbe02bc699b33a1424a7e717a6eb4faa4faa158201aa1800d1274cefd80f249643b717448fcb66b5541bbcdb53d2127e637804690345b5bcef144b470a27bedc5f5117c7c81350da20bd61a40df7e863f55e0efb23ee0fc458d20f32ca00755426c3b23a1be7819dafa032e3ac1d7b7d517409ba05e1f95727391b06db6fd8ffc9e5bc54a3b9e96a9ad290d0680e2cb8ba395be42622dc36dad008f22f85371f6f4ce3d7ee9bc41ce95f3aedf2ef9d61885e46e4d4724873b3e114c533c4bd4a588ac5974d8c677c5df7fae4284c2f9681e0f6e13da07a3e9de0e32553f432bbfb787e76c854a7bf4b3acb6af2b3345cfb58f83135cdc7501d938cb49dd06b40bb04efec915fa421f9e5062a1ac37a7aaa2d7cea22889ce2c870297141678ecf46c8eb52f6a0b771a9eba7283206184a1994c14556a220fa4d247a249e98edbf9eb17831b07a49abbbcf55f89b214e357b4c44dcac17321a38d7f03c3a50e852dafcedd4c4808718b1a7c6b6a52a1ab937888b7b1d7c741bc235dd6b6998c6b8a6269e21350ab963cc21ed64749b71014042a9c06379b40ca0c31c5bcd1c0eecb658e74ced049b8b22e6570bad27b85d2746708a9a2de84a448a01fd41dce389dc0a6412d2301e05592bf07a0a22c9619cc0c0a83d95a3eb0622396b356a13400ba957d33cfb70b963a2757be2986a5551e5fd308dd3fdcebc908c8448b8b62e84ef238dea98c70b3282d744f153b943a0a73c19d188f9954a638cacb53e244cc7e6c15dd3789b4c7747f29f49ac59f4a14db5c228dc5f44291eb601b9e3740cfbff5cd340d07a0cfaceb3855489317208ecb83cff5a3bcb2ea441a6ea8c2c3f9cb1334c70469e5809ee75bf4199a2029f5f407ea0164fd2002785e27d5ebf717d242a95e52740f393111cb5f5c0b0b466f9dc74f623d370dcdeba919ae9a2e951926cf261bf1c99add5e32e0d60cc5c13e440dba4278b6eea99ce36c346017a0f15bc6b82fa5fcd5aabbbef0e2e61b9604e372b7716e42007c5defe5fdd2ab2a1e7610b76253055dbc8ab5f584d894632c3b5ef7648a2b6281d267bb0505216b2786b8b626806985ed83c8a67f2c0bcfda9cb2cea9d86d106ededac6fc3af9ededb82cae4fb2a9de2303edd7c86f3007ea8caf2ffd95d2b934def6fd754679bde793e9c1074e1e9006c2202fe127d6dd95efe0b7ee74f77124b188b19ab95a89a47cce9b5e11d11e2bd7e4c74fe627356cbce48b4007444f15158c1df12a4791fac387baae485971d92b26f3982208b62a32de6d8de9157ea47312e7d4a1a00aa67eed1cf6dc0b6115e4ba7959835332584ea894bf84883b8b945137fec183344b224a7cb61f0f16783085e78ced02e19d28fc4eafaafdeb6b470d241c7351dc34381d20be0d7c9c59f07ee9ed573ea61fa69c2dad789ed1f11f2eff1bf43e269d176540ac338179bfd0ca190024af3fc61344724a10a4e124849f68dea578f22f78a131bbb7dc97ef9ae825267e34561c531d9cc650b52ed570dbf3d2e245fd0d984d83c544f1ee232eb36cbbcaf1a8c109f39ec01341d3b93fc61eeb122c2cb84a6830521175067e59b3983d0af0ec8626264546e7f654535ef7c703073b7106e6c594889eaa245cab77827485c74589e282f5553dbfe1781d78529392482ebc3cbc5af5b238d8a184bf765fba90cf8829f0d1ace47826cf3511bf10f9780631e02eebe2be93ccee29eafcfaa77b6a913d312cf6af902960104b9029139cca781e5b7bcb92dfecbbec0218777c06fe5c1163f411efbdf6e6d8cf57273ac3bd44571bf88383989ad532e45ae15bd59127a922ca31109efe76ad62271ee47861712c86df6909ecf4a08767157c718d72f39691419babc267e1a46ae4fbd8292cd83fbc0a9c1675d66a1658dac97f5af024d0e528945ffd69f39434c24d39587b286397e6a6291008ec299e53b1f686ada1996a9216e1e0cb270eae3b81113310563532aa3ed04a3a5f967778e4826f34e4a55684ee510a73e439f32bf0cb25c792b7bd7ce11be6f23f23302cf2bac12988b3cba6967e8838c7bf2d6eca18a05e758dad3f5a8c478fcf031484c2d7b9d9d48775d57553f881708669bb63fe9dca1e12e3c1ca69fb2fdcd137964d4d3b62ab5c5f35cfdba569788d5c0fc7a48af45814152fafe45ad2888a3c31588a3423387706158d6156982f82df2a86cbda145c70bfbf2c7cf68dcd9a565acea665c8bb54d062472942fa6b658b87038d99308c30b9a454a6ceecef8c0070a5d2dab3f13879cfbd97bae16eaa3c842479dbe4a92ae1f5cb84608a2652d431cf2d3a35df1d804b1b16c1883577d8ea19304a774b7adcb7cdbe8c53955e5c54029cd9dc545cf15c4308b9c844a79ce632ce61e10a3f27f9b35831ab4ee3df1aed943429a5556489c38b16bf410a69cd6e08188a3a734a7f2396fbb10e968d69c1ab6f0eedcce67db04c9a46ecf6c7663a84d1113c0966fec2d66fe4f233dd6c4f1eb965ca911687c2aefcf1d526e5cb5845be07c2a8c4a55e49791ea7ff53e4fe8bb4514e2bc6769b14ba66c898669df28b18e89c6a106a2f4e1aa0788db50945e6dc2a941c6393e3c827c232b75a327027ed8ab6da7c1d767cc166ceae9e68ea403fa8fc249adc600e00bfd7666b879b5a5391177eb8c15b97447680d9a26496d88f91eb50204b91eb0fa9b695f93362b6ba7a8729b509c9085d68cb3bf4c789c0634661f821b06262d08e9af9690d68b8c00f08c8360288f5396014d60d6a4d24f804c1a9f8b1c460d0ffd7404afd924b18a20322e240655b5eec4d6c92cf214e9db8ed6213e386a29b3c357240a2d8cb3df268c42ce0268035907a054a57abe67c84dd1dfed59e27d66495a92b725e6c2428d516f4bd96b34c1e4a97dd3d35624a58b6818c5f6a517ad970b7904869f6fa47d9674fdb8cb562fd0ba555eb7d1d6ca578e1a4c7a1bda78082890d2700a824592c7ea24da4291fa5ee5a1e9c3a47c11ce168caec4f289a206aa0084a6d8a01eb9cd02171e6249024a78314145152b4bcbc3f4dc6c550a2b581f51884a8392e4949499ab534e6f20221ac652b81bbb3e6d69b2fe9a59d2f36837b04100d7298703d43e3fae2f1069ee8c06717d54f2fa14f4d6bc6c3941a6afdff7fae9cf991c0704a8a173999417449b0cf0fe7d0e645484c53d78d850a0d8bef5bb923b7dab6dece9ac1d1547fe923805d68cf1399f66f840e346ba79e3fee820a7b212b5b91314c21a6b2da653ee8aff3b233ce6dc9ea2e2c913db35b7e8d1d1e677ca7c97d3fa3498603dcf61cdf69ea1395caaea7d268c8aa9af90ac670eccb09381805e1cbe254cbc19ff315d9b507022289ba31b477e4b743c580003a8f7838a7396a3a2fa02284fef76da770bb19d790aa97083ed6d2cb8094da80ff31d3cb87f6167bdb8f8c4b13a4e9dfa212708502a6b1b9d72d2d787ddd1df2ae3241746a369b09892a3ea8fd23308f7a2ce45b219a61fb4436a3d419ebea1368bb9b7fb80f3a670503d5b4e530a4285b86b4dc4f19b43db7ace6c451066cd2326e40063c242e99933843e8c78faf60394ac713bd5f14d6a6133b8b550277d5977a16e62979bc9b845f89cbe0f6853911ed61ec03dbdd3d7062ed68ec48ba2b55eaa41866bf822962a225cf7cda69116d875d0576710291af4f1e13142f897e4b1d6b32f1ac4c12906827f6ab379198c3d80f9ff82cf56268fee43dc76ef39ec2b4e0a0a77a015efc231201e1174f41bf5b214c6441f0b361b02a1e676f45c6291cb22bb7caa4a79bd3f8c80c3e2751218d193266b2d8522972088c1355a582d29185cdd27044b18bdde69f03a83944a597da204523deeba03cf24f6f1347dc3e107a54dba249c7df0816e3f94784c933a7dfba14962e39e5c6e8d6d7314635151e09004e8b81fcc0d1ae75d2c0716cf08f0e6ab1d7e13dc8324223eebaeddeff9aba8445a58d73daedda75156f879d654428572ab1f5e20d4a09dda4afec142a914485f062225ec79d97914bcfc680429585a4d8e059f201db2f2454b921348dee4ee1937ded3b46a53cc15d81ce5451443d525e79c3623ca825e872f2a42bb930b402d381b3ec8e71c4ee0d680ee88ee6c76ab31589424b6878d5c8b36411e7e2fddfa83f6c9e1864493f8dd115a3fabc75da9962da39e8933cd46fa2e2a24a457b48c4df162843b945d47520364dbdef74c2550b7badb38d4c8c2b6ac9f2d2f4aaa8179ed916850290bc2bdb6d7f91d9a74265e88a0e0147ef2511eb3def45b04888d62421b743af96767bc8254315d3df6860a3af7327a678d6afa3de9ee479005185d587ef7c62e76ebdedc66aaa96f1a8feb5006fb67eb22657977a44275aeea19a1bb5719cb8ee92df637a7c80ab32bd1a1087b26cfc33b6b37a37b1ed7b5bdb22dd23eaf7be21c6d39a309ec5fe9a7d51b5a5ea0515d208bd204670bb3733d2496fef122565ba87643e44033489e40876b5d7115ef256cabc2cad6a25771e770882d5f726b1210d8cd4b3b00c70062b289c43db701c0e8454b4dc21aefa98e8e1453164f61ba75ad85fbd003ffeb60967fba3b9223408b629585baf93027f5091a854b019a1251262d5e64e3766ce4f51071f4f95d99aa1f41284ae43578de72a8d9adaffb366cf39e4ac4873956ad638ef3a80983ed1a11e7b7989846086c5fa07004b6cf135a033e7d86956807c3a1539ae4d86ddbebc1858bdb814fbebdfd1460f260e8188b33e50facf0e66eb09ba352c715995fc77e8ff83aafd2a9b3e04779b28a70d236434ba5dcb938f1ba9ce07dd62b8cd7b854fe5ade56cb95d0f083313f2d7eba7faef22907720f4f5dae34edc9db496bc224574b22154961b9c822a87e4d882d9c9fa46390a3b72b5730eabb2936a4be2e75fea707561a9d2cc0145189f7e7376520959ef9f89b4edac2ee13849e01d4e63d8422807c4beb3aaa892cb662c730241ebd12e2aff7316f067597174a2bd8085ccc7eba0cae411cd7a954427d77045739ddd1d22487cbaef81f8fdbe8012af4ab2fda14ba16b6b61c3f83f2dd9e2cc5842a54973d23b6708242ffc9cb4ed8f356e7a4bf0ea6a31212e7530fcfeebf8336cc05467a14a2d1fe79d5ec59ba293fec15f31075127d5185d517fb0f538ccb6b797c8d5d379468d7e2aa71a7d4d97c2e1e46d4d6cb98168897b0e66a4b8519deb805180b293e848397ddc761ab414df11ccc588a39d2ce3629db1cabb2b7e43474d140b869b5f0ce8fcfa8592004367af4c20c1a68b3b405092adef0eed8c6b069843f51748aadf89fabb67c8da1f1c1fbdae9169d385b0b5d4b3682133535bcc7cb83f41609b057977d17039784a5753acb140a9aab0e7302945661d8073f36fb90e5fcbc8d4871529bfdc256e89bfe209042b785926d61cbaebe1350d7ed94f746144ea190e30b468679206ccd8ab8445914b805562880ad70d509c769fff440a79325342c542a7d8e0729be3492a81cd425c54afc1c48ac699c9d91db503b6259945258da5e3d53cd7384392bfccfdb6ab417ebe5f409156be4338c26e13f69fb8957edda4bc8514f20d42c3ed257c5122c27c9d5c4f0b1d3b3cce34a0e2220a6ef1ec5fc124281e23975be2599e28e112950fa0dfefc700fb12c5993bfd1afe80d02ef708db1f6d67d447f4e8edc736db2fb9e0ef27793b604f795df3a6430de907a0c778c4d7a43cefe7f8296e7103def6927adbd7e85e0afa7d2fc41e21ce338a685ea11c53373b5c79577a74f53dca87c9c7f22be8554e8c45c803dcd189c533d449e5dbd277bc24968dc228e343299dc4292d875dc37cbec411beeeeb039f6dad26ef6be5056549b3e0381d8b183cff7a034094d1e166222895460e018fa5ad79391bddac765484530a52af85f2d1ec209424d063ae4c2db0882c0102966c2af76b9ffc00f7e99d1895186447bbcfd699c2c74fccdd9b51cf0646993ae1bbf501f40ae11d53f4b7b8715274bf3065054fe7834d0e81e73de338c009476f7af148f8efc210f896d9c1beded093c964fca6d474c6c17e42da671f6c9e73e2531e6ad9bda1b1b43b837f0ba4b185db49d37e5e495428d18e7d789dbad99079633787db45035fc1d09e5aa1404bd9a07f75602a2c02c39c85899cbfc66f9279bc49d50d75f4ee390b3d81eb5d40b6d97ea5cd7300a031e1e26da216a0c80d3f8a68f918651d87de325896687c427f26643d8bbbdcb7623088b36abfd8429f7a46969ba749515efba2f0527f4a62a1f80ca195da0a5fd8f7baed49edb72a895ca84400a1d54b4fed0b25c1ad594f4409fa3c5d2d5869e476f857fdec79d5cc05db7367f7e048331cd3aaccd0a8967976515d919e406c4bbe0bb1614dee56c344d850a1b919be1665b34fc98e4ddef6dc8b4000195feb66c5a88848dc1c80f47613d4a2f4d73ca92f29689af9603cc2d045c14d92c99ad498780395fee49c08699171d3ead26b211a38d8f30cd02ececec005cc99e03f90a7b6d90b72cf87e1b3ecde508004904ad58f466fb0da7652c685312d749e371e1b7b8fd443e3926304d9ab0e53e2695cedc139da7fe4cafb60336c5c6a57eb2b1336425882f92bc998c4f6d8972d4cd4c7932c09901aa2b18ff9281e6db7b6c9a6f0e4c231fbe44fe38c4898159b0ed04c8818c13eba1c3b714f6eaf1c1d88c0cfc3d716d8a7e2130471a4f3aa4cad2c2b2109251a7f93204228489b2c63deb1f2c1a754c1a71c2a0702efc27c160b8075ada54bd7bfbefdb20c419c6a81cbf4ee0a854b0bfe3ec05fbb39d88440cef50e28f6d7cc9885e9ea8581dcec089f9f6e90594ea9220f1cc8aa00c05b0c7be99bb15bda80f9504db8f47de8a4f55c58a669671b09197465f8e4f8be8c9f83d1d60f7b5b803db01166dcc5391590b5ebc37f392e696330e9619fbc14255efc9e4bb1c0217f3e198864f10db812aa03c05fafa122da6f45892033aeca2e5b16a6f50dd63a64cfbd840050c27fe37be5fc2cd141a9a0ca0e796fc14864ce4b0372d7c8ed3909e7da2e938693a89d6e86fe9c41d18f4d0caecb1a9571cc543646939122b95333ef2b47bf8171149523e9555a3c03eb6b98fbfc227e638326433bfdac211c33af1fbf61441ebed09387ab94d7e0ded3347f98684e99d1db22d60e0da363ca73e6dbd31156810ffae3c50f4ed752471d8cefaeece81f85d2a9c71092debdf2f472997ddc8df7350873a20e16249664253185c6c0d5a83a4cea13f40d3911fcfceec16dbb96b9d62364052267c3de8fe1a5ff94accd65db93d327758b95439aba52822a0870d57cda866dc753e9bc530cdffeb83cac3ec0a8033e49e54c7d79e179e3773422d60aacf03368d52a929adfaee887d9215c1fe44bfc7734e63085871fb0af1ffc7e8060b71a4cd7e783107dfea80c1f96baffe3bf42061eb8d3736173c96720cc2f82635d95cfe44c3c7e8837535fbddf2f9211de25dcf49cc20b7257c56793e89ae411d6a8c0c9b5a0b681ae8bb4a8fea4e3ea5ab8d6e169934b192e0a550cfe95ddb60b2c2d5733d444b1d32170ccc2c8200b9c58613051776b56ad1c98f37c3fb82cc72727c94d13a65af611527a17e45f8355faf2d337d13be01ed723c24ae25901c1e0aaab30502367690930809d2e2358210aab8afc8a8276f5a84842b9d8aac0fd4c915c252971aae0b1e3122e80c1d3e8b3abeb4b96fd695000e241d8fd75d882dddb094067f260b368a99bc04a494f74df86aefbd6957b1edcf85409e41d75a1c28e63892fedb6c4be29a3dee66e7899b29e4f387a47a8ceec9c0faaa4fbf6dc5114c16c9e0f601a8bd77e1823c9f72860b5c042517dc0863a4976afde1ee89acea7b2e76a7ea39090cec89a3d3fadb9a7be71aa4fb30d4954044d66610dfbb6bddc9c1bf85f9b76116045fb9db397dc26b84b59a17f1c8b1b2db1b23a52fede7fc91b3aa1f3193fe0a110d6095cc1e41dd56e39cd4b2de6f2473302d006b706fd48ce040fcb63a20788e717ba0816ba734255b0e8aa71dbc1183ce21d1bac09750c52b3ea7bc0581c3482bd1893dc6bff14131d5e475a13f5a13c3b5c5b407dd79adb6188f01f04cf6143fbb51b360f437beb6611a20df8eadf191ebed3cb4b39a4ddde9e80fa5d2330e3b70cd4800822c8ca9fdad8b8a2ef8c3785fd48498d532a7a16728e17481da487bf231d2acaef103c6d90d7f4a06f94ea251a25b49629cc6f717dc0bd3e0774c6d0debf6b1281c7deb96e2db1a711e151ff0ddcd13384147b6421b78eccbb2dee7e43084821eb0191d565030aea5f2a225ff1410b88b90637127481fb799119dd2b366991b8d3a6c553a8c4157980ba26014c6d4220662b68cabfd6379080de736fa6fdb13d7688bb950c9636d9eee1a6e0c46c8ac6ea51843f00beb5177245a144e9fe3e36d52978595e9e5732af16351e8237067d2eb12600e2171a47709f1abe08c9801f6fb081dab56a8b26287b785d68b96dbc9be1a26321ec6e9ab4c1054c0146c78bea7165e791df71e2c3e042a22eef42e8ffc05d0ddd4b5c85831cb6c33bec3820db69ef198a3648ac0addcc7f8124e13c1938df33ce23aef97ac94763503d75af2c51a2408db8bd1ee0278de7b6db9b9f7be0cf4abec7f0c92e6192b91452d4af9578ca906f28f424120e52ddd00fcc5f90bcda663ce1e67a5c4ef4b111ced0edfff1d0ca0397adb3ab55d2fe60ed3fcc8efa48d5f0749a27d43372fba5b0f282dd028b13c9a3dbb51fe862d3466715cea407b3c7a28117ce737a42137d11e9466e601ca81693657eea33c44b5e61e3ac8359c73ad5e7a2b19a3548e9a0efc7fe8db88f74004b6150f5faddeeb37a7d2df860a6ee0a313d42271e9ae2647de42f77d68cdf84b07be0029a7dbbb3644474297ffba58dbfd2aa35118fafb61de2d83cf83ebcf79c617aa966e8b564169b2e85adf3a2831bd4118cd94a234d7d787a83345e53e347d42cb384e635eeb3cf2cd9879b0db73c03ea03c7a1bb402e8ddde46e66d9e9df274f9f053e0be42353da58e617c5dbff125f69d3732c74f6c66bfa28c5ee49f8dd0ee22aef33771c0180d9b29f32e6dff9c3361054f1091a97b5da7814a3304358243e04aaef6b1b8add3a5ad6d04ed215f04e55f4e41be00bc74daa5edc864fd34b3a19234f67ce36425e84dd9bef592f9f27d8a220ed03f82a2472598f018ae4ecc864ba9cd81c3bead3c035a8dd28764b7ef0b9045179dd4c9f537630a64e7e57e4f7acf39d2dacca9d6e96c664e073cb4818cce25b4f998d479ef2980169c79c5f46a3b4cc4895cf35f76420e13de90184f4bdc29594fe6e71ed21a4af07f611cb7a9e7870e3ef780b543b80a4cc3d1d98df7213d58a3ec4f1a08e5b2d3be74c91dac141458c09f1e9b46c27b6758bf6002f631e2e478d485dd1a615737e1cc80c337c0e3fe64863c271291a0ac2f131722211d26545010f74632b39ba8f70177f1d1eba9d8c85496a3fc10a1ac38fcd8c557cf10f2e44a1664585764c6068ae1fb2d8b42323b82100dc01318ea020f1b8560d6460d890f73749b15b9eb274ebf007bf4745bbbacc9091e8d0485b220ddfeb7a2e37fb445da3d4d7fc3f1d1760e60d051c1b976e9fde0a9234ee02ee4f8463c8e05d9b90a7c08e8da5e727a6995f7448724aae2c50087acb14742fc41216f6ea21ecd4707924e9051c6ddc125c805015e3da7a4e5a3c77c76e9a9a5bb850596ee312ba68ca49aa38cbfc49337295aeb396e97c06ddca667f6fb180dac24d9a644e3fb10080762cf34aa14a6e098d16ff4a9013b8635203ecb3f7938fc4c9c46ec003c1396db8b3ad8aa9faecb58aa853e970094734765749b852a1153deed59ab657b069b6e84575a058362828fd8c7f313ce5730d72ada48dbccc68d93fc67246556c31ca2d6a0b4d36325512370b44d6e85caedf5534bc0ee7e1fd8e98cf10db6464dbfa71a1a3c1cc528e34f050af88dc8fabe66c3dc676e2ae3aa32ff029c8cd799007376cc0a340468f070d0275ce63b45b8e8883cc8eb2461f449920141f9df397582b8f003da8acf0d74c8be6f113ad10eeaff94d9f132275073dde541fbc487a660f0873f38d6f523c5a41054ec5584727bc6eecb7c9ee13ac2096dccdbf96adae19b28e92f1a928c9d87d76f69f4b22869e361be2e6eed773d81d3ce7773d37d25ec02a45ed13e14b802db0ee542f86404d4403c0e64dcea574f6a866acd515d7d86643d5b8b2641285333206afba5d6b60e4d2d5aa33adee03bdea6cd8f46eb724a2b7f988404269618927f1af41520f980eeb560023d53856964f9eaca5f6f117ae04281e2641c373d18a9bf37c83ebdf35365716908949cfeb756231746354b3efeaba21d304cf857fb6b6c8252735865c800b26523162a19324adff936ad867800b7a9261e88af47e39313243ae6884dcce686f27b5ace13c44040e49a4f4c279a10dbe74fac1fae51c57b07d97934ad3d17888fb0329a0e2fad069ad74198a83b1d6edf9c05508cf331118f16b16f3528a4e1403995a6adf1afe83c754c7db2d357b51c93a34210fd44884dff8f5a6b66b1417e40d349e23e6a69ff873a926a74513c003dd242da202fd91b2041be08adf3925b4c346148c1864b2b9bdc6e1bd557d732363e932e6accf1cdd73fadb480e02c1314a184e6d80e132c2a5eb80cb76f9bbb0a90bfffae697fcd72afa8638970062c1776e085d35c9a901d954e5b73f5d26d2f87f7c9f8e83ac7ee4b019f528c9ff69ecc49905a8566e0252b4d32542b36ba2fc5814d400629d08e24a88d13ba1688ed1f396f10d1bde5efd75a3179c930106159ba62f80f942af71f0e8937f9d1f8b4dd1a9db4c6edca5491e64034468e4b878c5a27b9084af9ec723109b0620ce0977517ddc5544e1eebbd09891fb67238de6a3308e3e6f319fcbc3c316cd476893b9c5359b35b8c2448a493caac28e1c0dc5a2e6f3d8a7c1fb89b36070b227ff813c3b62d281c722d1afe2cd723dec13dd75c468a0929f5e3be2970fb4446e4abd8f55b60882fa27af84c0acae5dc2f3fdd3e0090915e5943d1eb621c618fc5f95b30e237ed8a5c45d702dc476e8e0684cb654b46fabb330fd80228a0ec3146fce8e0b5ab10434cccf7c901e68df7e4af606afac275463f8b8da126815a878be54602ff6962b7108ee00cf8cc02e0fc172870fdb7185c7f91a0770f01669b057fb34b1385337a9afc0ec9b4b2c77d10a7c104f6ea356da39cd6028d7576115336204801d2f9cbd42f59ee4f9c5db1f221ce54eb11f47e53335e4158f5f11904412a56f4c625da9bb5484538fc4e98dba5babfb1d9dc881798491af5788e6f447758178a8692c83472440935db3565da02627abc3b508b17107ed6854d2572903fe1456afe5e07cee42de46f1ab2bf4c3b0b17eeba9e771acf330d6abb2d9c37d0e673a69f9faf0cd17a79a56ca6ce40d6411c31417fa647d84734fd694ea50b69b5f57bff018a33f5f74121051996f5f3042cfa69eddb6ccc11d70d55128be4a1f33c699e5ab88820ef3d7e0bd4f9c6bfbe6b1d315c688d90e52a1d0c18231da3abba39fbbe567a3797611ebbdd0f710fc877e32293bdf55d74513dc31d76862eb8ed8fac5e9837fe552908d4c27b4f3d7b6d92a11ff3427d38145661cdd01473b634e894b4390cd1b9f7f7881f234f961cdbce9e8244440118aa50b80cdcfd371a6bc20b603c2c99091bbd99d9bc34aebf28fa83e532b1d6fbb9857f4e09bb4e902c0f975c7f414f341ab604f71c338efdb2d242cb04e394451c9a576ae972ef755afa1e162d265211011e8434530afa781c00f799c8d26385e96cf6bcae9ee81914a9f447f864c7562d46c246120848029e933ae1b3faf8590ee0134e90a6262502471769dd4251431bd868eb84d98993c56291618289673a4a0c2c3440622753a8dd224dc561ccb336f77922c875063647f38f0f2622c98ff917861435e539b0dc01fc920723c547f3dca4fa2be7eb8d4e87beafe3d7e84a34b8821039cba23e0930c1f2acd4fa64abd9d0d55f1c79386ac0378271a8e7f7a5345a3063f3b68d7975b7f061376d6480c0695712cf6d4ef1ffe266b0c9f586f12b1c69468f934d4713082de2331eac766e8363d8b30d96689d2364df392c112fcf50116cea1b9ffab27050bca125b5d80b66bcbeae628ec8e79d1035192a5d0c0a7e44d25261badb2b65588f86d3cb721fcdd76c577889feb3b6706e48f3a8df063c69663b3f098a0065847f0ac93ffe3a98d21a9befac1161dbc1e7bababde696be61d05119209c922c8ae464fea026c25511cb3c634ea27bf40b78489d1a144ee3a598bcab134f9f8dd5b6184a102f798c603e2c9098243bea078a18513d29efc0e5f53d03dd575be5a8f074541c362b2f3df47cf9bcf7f8ce8b328de1c57c4b9e2d7a588fa55bf0951405fba275f38395b2f44139a5c8d353c56d0c9836ce55f75267d8fe5dde0eb36e4e4c5a3a9e0f0791ebccf12458b600312d22e266e0467d4b92fd47fdbe9c87c8fc6fb84c6278e16e404214a37aead078d37d6dec8acb88ef335128179110589043f4186b8274808ab3cc7c59a129c3e9b1aa7678a3523f822b6187db467d7375fcae1efb7b171180cd9cd0ef8112da7197dcf8a914c216afa6005a65fc64dd09e8af0e38a5f095425b205446fb40b90f94cb103b9f04ad31f94a02a85a86c64f0a56991ccc03d44b04ec75c611ca6bbb3854fa41a40e56f44f9c363b3f241fa7c6d5dd4ea7596cd35d2e06672ee6a0ce99eddbfa222789328c1981516ab9efac49b845886172806213f3961af39f7a3ce424a5d14f3af803290266810f4b800fe5e547a527290469891e103a1d980e152aee6619df050f592034b776f7884b120211343ed51493a50d85be44f88e70dbf7010767a000357125d4d71f8e3025770cc76d7d2c7d80829cd5ddd56b1b90a2a574e874d6a35f21c4c654ce8de63870ca5bfd373019f61a32256b1590fe8aac432dce2ef44681c91671032ef8dafa3eacbbfca3d10cd2577da502515d779fc8f3e077f0f21dc54910f6d70fce4675be5aea02b61daee8f21ba5bfc4a6b1d3c28e29767a431d43c3b257b04df2ae61c237088b3fed9b22276edc4a094a1a3b30769810609349733dc895a94fb22296b63be8c94c648949b4d993390ff7981524c7d6ad5e52f13fb7a2cfd56defaec7311b58e90390bf32627fe54e548c0719214e93cbb07a7e205441962ec3c26bff55fa0b44a852694f1aa35729021286c27fe2d305d594cc4b2f1ab2225b50168ac4673ba26dff4c7e76fd26f1c1500b2670a5cc41e005ff7088a260e4d231d058f1a40fe767735c1abbe2b1f2e93cf94967fd7496d0b4ae3cb0b37152fb2a2a671b43c7a20b64d9dcb23c0447457f71879f23dcec2e9f1258dcdc61378c678b7b6a360a46d83a635f163c6137d39505a3e6325cd568ffdbbe20ecaf914792a33cbc02da70ceacf101a7dcdf53375770bdebea3b98979bb3be2993006617bf6ea24842a508888cc2bb66c8b892fd203f833cfa34ba5dc4ae3f55916871336187c0a89c69edda7fb3a810a286baca040f3e83061b30fe08ebb579b9fc46301fc359e88d16c2a567ae23215faf09bddbe5bc8a0e696f968f4299abaaf30cbcd067a9a69b464ffa35ba9b8d8b6d0828bc9767863822c61748c1f6bf47607f25f2526a25448836a684475afd66443cb14d4ea34dab97bd96b2b73a3a2ad33660b7d1e866be16590aaf4c595467e7b1302eb4300c09370f2349d2e1c3081879ef3602ac8995f7f902950105b902903945c254213a2f708ef0ca327605ad056c564e88fcfd4d3a96619a985cf267ce43e1159485b506ff02a665e364a20eaa297ea9ef155460f1d064a3e1111bd7f2fd1f364a93c1cb19359a01a8476405234ee6c351e815f2a1fdc8b1fd2e168923ddb393c5262598c8e496f40112541fff793f8832794db32671110a22089e92341206df14e7cd7149df9a7bb9b47b2c78b6b0695014b15b75179f5b5444b1f2159d128cf3e54915ce9ac0a29817cd28d14e7866e8df35a6b8bb4ebf8dc4d337728698ecc2c5187a60243a0b18b43a6fd575a592be1ed8a0c39bc60d62624842afc183bbe43d0bce59f6fadb359a91ede56a4abebfe7f1c453a66773d448b3945bd10ac45a5118cb54d521fba3c306eed5a1946cd3434b43bf3c244711c673f4aefadaca112b5759d95458374fc4cede3c4fec82618efa6f891693a3cca41f72ae7b5ad80e41f2d6324d2eb9679d27356d7f4e4133fcdc75323389c2cd1def24172741714c218af040d1377190abda5c37fbee753cdb484fe2297fffc45c865bd0cc15fae112eb7094890b87bb47ad6a54991a2be9b30fe38968d6220dd42948444884ae672077b4364d8f99235df7c9463a7568745022ab2cd17421ca956fc879f99ab34fa559a51c08d3e3078474e69fc6148e593bd0cde1a9eda111d631bf18c99264d20a4f29964fddb9cf26afbc94fd88c61d6b41d06e221dbab273340f060f78a12a8a7eeedb1bbfac9a758e51898ac1961d3a0eaac8b73d0e8b99464086a33c78fa70a61b8832c9dfc20b2e936566e8c665a99237c8652ba85bfb8edd9f6243abd99ff42082b1a95f96d7e4a6258e8dcd2691a5b1bcaed65ec252f039fe34ad40b4b9c96a60eb88bf7963e85ade89b2b1d749b617a314981efdcc28c5683de22cc42c9ac893be8134e89101e4c0f91eb50205b91eb04021368f309b31c2894b65af5d78390a3c5ef155b2aa708ff90ff8ec091dd0f45d6c41ae2bc84c605150ebc18728a6616dfa39ed173eb9f58362fe483ee93a5e772b9ab7b161f2a4b541ceee0a368108a543730a133e816101e6ade089568959cc5cf33e46fe21cb181dc113f354f69199cd0f84ac1650ac0b98895c031f2f644345a664111e3b780751fdbcd11ef4946b555e2f2d38e3f1b7fe401c743335b65b41e04eece821132b36d80d9e80bf355661900f1644d185f624d769260d6ea8a94f125fee55f62d70f508c94851fdb9d762ad2a27a55db07826654c5206bb264099c6d4187efd5184675d55819ece1e513a0a944152d8ae25428ecee8d2b6c80eea70aac1f592d0e534aba10ce7f86d48ed01e6b0a67646e20c3cc224b7f4a47a6647e0fc174c64881bfdadaa1267b23a824b56dff6a0876feb49dc0f7b372049bf21b468c502bd52761c600946d0c4197730ab067a6943b919e11377573a29ad0e428b2b14422b822f7da774c08620f7e8e0ddb9fc2814fe99df7eabd429c67ede9a83558dc0fb3e921b49aacd5a46e4cd0f427acabaf005b1e6caadd7ca39962e7ed87adaf5aa630c1b78f4dbfbe8f21b3bdcb57948663b643472032da470b5a9b1a912ac291f4d3c6adb27bf6e448e581ad184175de2789cbf1ab2026027bb713c4ec61547b7fa0a9fbc3b6db5a1685c64a482fc5b4f1959f9f175375f3538190d563f0f2967ca3b8ea9ee1844eee03e318ff758c92eec87ec765638822e90b848ac6af61d834172ee788a5c6ee923bdd39b3433a82e054a95d0ec59d432923f48478698294edfa928ffa79edde545e05dfc6b312ddd34e6622dd8e598ab25b65f6c070767cc6081ff88482ed586c87e3b68d05f2dfba3d5b8a49599485011a67de951ba22a0c150a1fdb983eedc50ba4cf06ed5447c68b03f8d93c6b63b82ea9e3a96773241bb7f9f012e023ca97c3d5d189db459b19b9b58f2104772f59e3e19bf2c885281e6b541d0b03d37b4e30075df4ba763156db0255b3c354ad04559036c897b73fc64a61fed4190d6afb9a86af5a127bb9468494c899d53fed927fcc7e935394e86850259a2ead29a368d564a649ebec231138bb470bc4bf92f29a527c385721c02c54859a935e2089b6ae93e4e4b8e29bc56cd595877e0bedc438f46a9e9d8d6a795556ef2048f2459bb9ba80195cf8cad2a2f0125d49f4e6e85d0b1333d35c1c9f00b9ed32d105538664dc720a0ba6db0863795d0dcc5ca0a4f45d67918dbcea8217a30aad84a097320b07e8f70d338ebce3020d180dda13048fd0a216898ef81397a273e90c96851049b2d8191df15860f8987faea69daab3049cdf99805e42de86d9d85746d9a6adbc5edeea2aeb8ef9fe31a4af70f4ba5a8a487d3e9911240ba1e28baa261b76d160e443474f6a7614039fcd6ff2186f329f4f4c2d7288a39e05a9b94aa41ef66ca8b4737a93725672423ac1e5eb5f36e94f47ed8fd2c0c9f33a1a1009a4294cdc91bbb84c89e6376b7718455c2ecdb52e252414ac7c1701a284b95150c6ccf310f23c88a7c57d53f2166bf9cc5b04af440cb7a7f70e5579af3bbafae6f2aac02fcd049f4be5107d5e23865fdbdb431c04d843b07347a8e70fd0173b4fe0e2cb1c957d9728b6bab4e47097c22474de234701bce870aa893d8bd1608d9c69aaced3ab6fbd06cd9b9ac4741fc50052aae2b1da4712f1344e9c5f8d473d56236956e5f4004ef6235ae56de67313e7d130d3f4256aa5314ef765bbee477104f521ef944b9cac6296092f1407cb154848c86c7c1f8ee341a8759b14fd5fa055c06b18629b73ba8f5d0a22fc4bb3287f9f91a227cdac1b10566ba825a8c51bf7bfb4d4b7db7b2a0497db78013736f50a01565e85a45f175d27161d4dfcccacd146a5f8f8eb0b91a5fd0a0642bbc1b87aff6602e3c6d0a4ea6f6302c35a15e1767f3239b97ce0750c4c8bc52dcbcf7f259f12906fde1b01f119a1da87cdef7aeebbb1787bd91c1b512e414196c2d898a53c4e7d80031316fbc4f80bc86a12732d9d19e449f0435e6e99c3386d8171fe2307cada7c5f729e41ae402464c1e73a49377c169aea2f7564990da7a8120e0800124b34ebd9a51cb088558d3e9496a0d146d3def6b72f2fc78263a2fe5c0fdeec9a899b9632dfd6ec9ef789ccc7159fc51ad7b0a366a55a4066f9754a3af6d091a0ac3f0b6dadbfb58c561ddc9d0e27fcad3e3685ddb446c4e8a95397d52ecbfb66864fe44d51660097c4d7d9c7c65e7ab487a97f96546ec69baaf5fddb321d50551805bef285f06a60dd6764e66fcee0b5bd20ab5803b20a82442a2791837efbe7d60bfa94eae39410b19ab34e9981949092e7b19806b5c6cbbda25d34f18389d0a8f5954d3a1b7237b3628b9964879b0c0e68de0b8310a3809be17caa590d37569c2fe5fa8b91af9a91ba9793c9e8db606790c83310c0925bc1c0d9a2238dd2dc6a80331a058875bd5e22451c1bc7584cfff4b49849818dcf56e08312e622e3f49065e6189919387426fa63f9fbe4b5a2390fe36e1f39d370dedf6c883ee381749091ef9a10d2ca7444cf8377254b549fbb839754665ee18922fa8f9120b47101c519217dc6ee28bcc5f9c29893db5c98a7b58bcdd1f957f5fd8280a2bc6ada7c3046fe34de9972714ecc8511ba395c4e64712e2dc4b59f6b6e1a0e7206c3719613bd4054f4c815c28e3407f8845deb387f8b0f61405f7192e2b4423fc396a90c6e32bec6ced2c447feddcc33bdda11896c0771a5351df5ed3fb7dba7c72a191d8e410da1c84a2ebb872a75b0246148ef12ec4675685d40533042db8c64ea7c7768e1de97012a6f783e26fe8a9abcd8a519b78709c9300e61be657d20bd6cfd6b9aa57139ea52c2f6552a0e001aca86fe5df9342fd0813a4d7c764b48e4e0c23fab6d6225d437256ae16a50aeecb50e11e7894e5a1b94b5c584bcaa1c59e8950ef71754253c013e781285ef99dd8c8a705594643a48d0fb2013a5455b61a8f7f68a19166e1bf59bfa2c6f08fd088bed855ced3d400e402cfc71fd4decface3c9411d281a4f159830a47236e8eea3f71f23270a9ba17bd5d2b56d280775d73018f55e3c6a760f92fcb19a7f58f18b4f89c680bdac1e55bfb0183d56d1dc654b19e132527464270ec167e6bc136ec30c7b78b64346e79acbbb59933ac83cae9f3e424cfe933c17a1e5745397a72512697eb58c71afb32044cc046d0657ca3ed8e6565e7f18543b682cb54357cb7ecf2f32cf4937059a5001f5156365b3babb4258d39762fbcf9aa3df1e61fa601cf0fdad149a6799518d276c1f9e60497a1169e42903078cc880370c31b0a5ec5c0e1a3b19232d3c9c810bba64936179fb07e5f89f3ef01edf686f3b598e2bd3d6da5d3f8fb938e34d427a2088408181360bc3dd499443f3be5269afd0c9ed4c765063d5ef28ddfc35366fea2b09505142e1e496097e40031e7e2da775f75a06aa1e03b90bd025881cb67b415ec328a09a4ec0388e97353bd4bda669c9e7c0d39a6b90f40b6bc8b148af4a15224b5044c0f48a53690911e660edf02a1f8aec18395adb52608986ee8eaf2dfa1ab8b5ff765b86f1445031ef974271f460b46f5f1918acd87b24c84063d69185dfbcd9cbdc7fdbf04a2b60c995c9f3e03a846346cf3b1ac5d605754f78a280e571c116598ed3141ca66a8294db01de2ef0628b72c01e5de88fe6531bca6590fec49e690aa82316b6af14a841448846e06e1dc17ee4cf28168c002f6cbcc69fd560b4f554904c095ecfd781af776563285596b101b84cce947f6f2edbe7fa635004e4ffd9e76f11081fb88882fcae2de678004d243a7dd3286a8b95834be3eddd47d9f1e14566ff4da4eb2d584084ebf590e012092a65b7f8a5e64f9928f72fc60ebf82f796a59d1b579af8d49dcf8c7a55b46da62642d8f340512e4929e126e156aef833cf540ff800f320657c5ae16f5411ede3a5d749ad79fed26ec9d830281c13538523b1c951b9ac66f881c05d012ce3b56947b4bec3803729d4e0a7f3f82199a02e26b74ec8175956507e8515498569377694f34a2b9ea47c1371c1497d0aa92b019fcfb4f339f308588cbe9f43b16c3afd59bb1c49814bfbd13e1a7a87bb75f006c03b9c31f9cab226579652cfd310e020ee6b2bbe0af46fed3628c0c4e0b2df560d594cc9407fd4d26b71fee78de2170848b16a5db42134b9f204a10c209ac9e1e4ec4403492834edaba71fce63d51484d5fc9db6da3083cbdfea4383d4b689b03cee7cc054bf2e17bee0e59a003aabd4c3c6bcbafc64a767bfc1b82c25b9e81e3054171e680258c5639e0d2057f74bb850d209564afbc18f9c1e3c017f6cdb88fa92f323ae11713f5477f94f3b5e5e9d2553e7a3bf8dc0b19baa3c93dff64956e91894534d326edf1c52c0761c61e720e9e90febf1ad0611103b3aa8f695f952b02cb8132730b4fcee7f56db57eff7bac8118cf7a8bb584a16b97b6a37c023435d4f5381dc870d97a36ba81717722e2c6497f1c75d1d009e73fcc614c6c6417dc7ac3d62e161e6f50ac37cc4a20124faa1ffa3d22f03eb356903942bee1de434a4fadba0ef0cffd405f3b9af3b752c986f216c1c6de31c0ca6173c4e17e8f4f8d48564313914f963e7ac36a2ce9a578b9f36d949f4b8fea9f9b0b40052e54e3036d8ccabbe7e003867cd0a2c96862787e787bfb8666990069fcdfe9796a6818757318d6f98fac09c5162d2ab5827d7e83221397a6998f1e342a149e49d3e0afe991a2e1a144f3f11e0b3d9238584db696660b82d2b2783e34127f457254da257957da3be02625172392339ae064a677d3066117b4cdc232494cd707004fc24bdf3b6658e5a13b43c95edd1d765b5360a0b36d1f7ddbb07e4bc64f8844728c5f3bf735ef0f988e136280cd28e276ea07848845c0be6e42584813b2c49c86c04165e4ca955280f2c7b4e12c5d5ec9ba638834859a7c163964479890a6f6a2bf879be91ef813cd684210fb2da5d4a2a29c8347df127d50ed27035074eba43cef37e74734b845e94c5f1bcd9a75e83a501fb34827099f928c7a238ee2ef0f4e37b94d38e743a58aacf77d91db19cdbc500d556baf7df06bcc055a7b6e3e043699f36323c9c631cfb29ece00c75b43fa34117937afea3369a5374acd8c7047fa8976fb1344151895d119d7942f040e15b2eaee2c5498ad153072ffe70da799761a642b2c8c9c215dff6312c2a85f3e989829a3a237b20d0f3eeb352e517b6ff971f9ee9b047b2cceb3aa21b61dbcdd171f016641c1d6030557e73ccdb0c0441dddde28b92136db1b6f912950035774f88719fc2b0b63d53e08b2ed0ff3d9543301e8e055e55376279b8fe644de5bed3a3be3bd43f0ec292d50a0296eb120bf33c3aa26cecdd48a138eca148dc6f0ac7a758efb0484db555eacfd3fd9e3cf56fa36035179589848cd6ac309c0a8e89d0e65998a66acd3ad79aa96eb1ff8fbc91412c77bd3025f7aa870d2d78cb7339f4157a6cbd2fe71aef0773e43716b0245b55e81ab44aa4aca48fd22bb93449e28847192158216a57fbf0639449c753d7d470396879108f4329c19dd9842e487063ae190f8f3d774406eb6783f5117b150f63b41ac61b228e19848343b657804af0f76b9f1d670b0f6e316acbf762a5c945d0198e02067ab08ba61e4cc9929144595f101e5ec481734f80e9548e0d03eda528455cc2759980724f564a0e4c54a25c38e374e3c3cd67a41b1191129e96d98881d8713688b96f298b341fdbf990d31ac8f1137682b083d507001ce0c5c9cd8e658f593c5f7b849b4a9db575543eea00082d9770c938bcebe978b592350c696aed5a81e5a4b570bd96a4c82e486414b413eb07465eb3d44e4d50ca423ce8df603922dfba7420391addd19721c6d401be87034459f766da67c7baaa4ce6dc85d759d1113c2d45c70f65bdf5b4c517877626f3babe5dc0439b782086b9c98aa5df1c8670081998b7cd990a06bd9c00f8cfb2fd622317d3ef2e91e852f5c1a8395de627c539e2b72abce27e84aba8490d0b484c3c3aef1a54260e786488b330c1c0875a2dd63c3264334c4fae723670ff63d98b13a99a3bebb7beaaa73f7684ea8ebb746380e3da70effe8c4d8b7aed4f661cda71a1b3b2226ab277eab98086e648ee9170690aa5737108d5c9615e24d1d2c868f038c923be5cb6de31d88c2ea1442a1b95a9b4055e7633926e1d5663c848a218c3d74eb9e6a36de5eb2fc7e4c86ce334da7c8f5131bcb960c25f2b0fcb5b79269c952759cd798b10d929df27974404a2f49c158644218193e55665e0663e37fe016791ca0479db8a40abe16c24a451d494bdfffec6b57910f479948b5dadc532dbbe23aad14d3625b71d534f96af12115bd826c2b46c69923d2d1d8b2637318031ae2d598e8e0bec1986c1a64051a0703769fdd2cadf65666051ca86b8e695d7716961f1cfd94af7f7e81702d46e7c7ccff8e492a2fc577551a6383628e063d52b9d3e843a6f8a13fe5c8591ecf6fa2f99cab777d6690b0f723a2262cb4ca5dd69be264b2c6785a29e82d598403c453f47ac74b22b1e46013bf3d0477210b8f199ccba64e476841f2fc02791dd4fe6ef3a7df24549269eaa5e00e45209455c45a0d775bd95ed356b998e1d68c87a15ea251209a6409148eb24e4a80f8544ebec7d500ad2e01f850b167db1f4e4d28a3704b612c654004293270035e36a4cdbfb8c016885489ce99e2fd2e963597649e7242d80bc230ad8a6adb3b404cf8c6c632ae62f4e47b390c7b57e92a001db67c4a0bc874f75b3fa4cca416496160e4d8d2f17c7c7346e66db23dcbbfc3beb081e1a6845466273c30fafcf9a96febc96e049f017cdc881e6059a62666a5d2eb6604754b0176350deba32b9bb267c1cf46129f63c2bc38e413e63b17991e55dacb4a6dc4881ee89ae57af908b9b44baa9f52a4f8592dc804468ea0df9b59a239b118976c74c6518d913144ddd4e98fb384f656022dd39a1916b3b13159f80e8d79973b1a572d971ef6293949eb88d06656841a5b7543c7e5e34a2c1f9fa83ce6e177eb36de409adb7afd4960399ea353a2decb0c3c9e48224e6c6451cf66a9a17b141b5f5f533372cd80001a0c9947e94c9d770f7877e74cc16eca0a5ad03cc55d34de27c6d3f7d15de365e3ba11a1a92cd9b0de7085b7f5f8e496988ab53bc2f88a8b8a2242375fdce126e7d1fb4dd0c48fd0219125328801b4dbcf71ff43688de551406958649929618df07646a539ee84f3fb02b783fbf0c0827d01de895345f0292fec2d028f5eaa7e5d43d1060261ad9316aa324933417e29cd60a6ff6dd9cdb02b7421fc0dce70c582885b9adccd74b982f00baca456d41c3925d25cb28a358ed6398ba88f827efa2ae60440250a87f838671f42b148e19c14b412ef96d45e8e4c23e1eb456ca2bccc62e5fff163938090585fc1278718fd7528ed715c57265248589345beebb1c1e357cf0b30bd0e62410d422a50e1acbf5c32a8a0a109a79f885b3627488d8ff7eda6742486e11482f9776f1ee432440900be392dabd853b32d08091d05fd7592db24724f88581959f7b6ea2cb1ee228bc141c34d2cdb2497f61e851fd96e9f385766ef234192481fc714d503870f5b490df0f6d81c00b64cf20374ab33b7fb0e9885c984d27b534fa02efdfc630a4bc42c9a1b364cf587d5060b9af9c0028332448cbebfd41629e961fcf32e0eaeaf8f521dc89281515672c2c4d8754ab89a33281c4d479b520b42c8aca91617fdfd41e581f5f01b08288695cb10ad76bcb6b63e4d519e59183a3d4cbf3154924a3519bcc50f20ecfad2646c167fd321e8b349c20ffabd3155422044df85de9b118525a51896970e2275e0dad560860f47e8f39f381ccdbe375c4e00f5e5513c1563045c1bb88a6ecb145a85bfca112949521cd7ed795a8c7e1de18a04fca7375f67883e4324621eaa54d564fbe79aede4d2ed83dc2bdf46b81be1b43cfb790ad951eae08bbfe588f2883c09aaa11812bbf31575dbaaffee35e91eccbf5c1415fa4e5d9b5d8934354be3cab847241323388cba0e89b1bb15393b386cadb352f5bc27c7c16f1ac6eabc6515f18bd2c865dd49c509d76d0ac5eda836f69f288be6e8bc755137c03b3c81b3e30ebac568a48511ee3d24f928a8353817ab312495a10e8aa24e3a2a255bdc28a5c0a7d590ded1d3c69ad25ae3f56efbc36ea75ef194b01c922fc6dbc79f969529d5431ec828109995a767e8fb7d006e7127cb365e46eedf3a1a5501b51f1bf1a3b9f1ae3ceeece17e4f2a02094848a3b0e5eee4fdc75c09049679e0dd6e65904008e593ae6a225860a1931af9f0bbc28d505bbb8cd20d69da39324fb76bf15912fa5a0ddd70f2d8353f0cefab9ee8a2fd768ac471970fd116b549f3e40e0089181ae756c7a868842e28b8594eac0e24e494ad93441fa5e67f3238e20d16d1a39732b53b012c2341a28c9ef3128be9246cfa559b4feae17dfdcdba23fe2eb74dc2d15673987012a27a9fe6a6ad592cdec7fe87cbca04e0c9b09447ac7ddb5c3c84655c684408c54d5a3282696ac0a7aaebcb607225d67fbe70f2840f7e6edee1c628047800d56741afc992ea940c96b6b5b04c17c40fc281802ccb1dcd1eea9b3ea27f174807fb2b8a68ffe805f142c731fa7379030c854b603bb3cd5b3fbcc4d3055f33ad6477b172163a9b6c8db264e774ed5ff20358348fb4cdb088e083e84ee0f45932b6c37372b55a495bfbc702c79f33453ec755ec7da07b567bc8326240712ad5821d18bc2870a7fec25d87dc7a5a854d8a487e04d4cd371d0c8e645da035f975e91fe3a9b25bfff6c5655d9ef562f5f103b077e1ce4ba0b1f7415662f25987e156a047a05592cf800ffebb88a178ce9ed82ea6367f17625ee7e9f259f18a28f536aadbf71291be108bd1834bfea6383bc926eed8c4d22da3209c2002adb71f494ec1196e39ab518c117e10bf90fe9d8947c369a27e0780abbd5132d04861c65b0848a27a8573f520fcf8d9bdcd5f7417514ed34eb318685a95161de24a9822df1285141bea8073e09699af95755a4fd8414bdb6d4b155851af05323bd18d9b28231212a4b9f545ff88e5eb19c025c9f788be6427f8f1e8ca23440757aef275ca10c0f211a20ba9d3b1ce86986657cb18284f5a60b6b0a107b45649381b48892d955cbcc85366cf6efc03367fbad02183da0ad3d15022255ef119dda896d841248f287de776512623fb9303fdc76bdf900eaf83573181e000f44e46c0cf1f0a5602f171d240e91ac519318239cab9ea633e0db2d85cead8d7b1587839fa314c895c02578e5a2defaa0a620931899ae736e825ac635d692fafcf084fd4be1e3747424ee61b50ccc9b7156d7154ab18199b0e14d41437622ac4490e20850083b10c6f7d8c1728703da4c7dcc1844b8903dadca537239ccd38ee641989c66b4a9df8e0ff9bea4dc7d117284cd7a0098b8fe33da21d3e507f2d778800bca4aafce38692668ca8912e45cda709a9eec3d5f0510a4de589d78cded6bc808a4d5f06831f27633dd1cb4ccace581135432f7a94574b620655ccdec16ec0e2e07b1e6d28204341daf5e5e0f61bffb31e2df27e1c0c05ac7ca404bd36718fe1523fb4ff8d49402cd2fee8b112b1e7d3f7f96ab3fb72e9ab131fcbb73b8a31bbf836c7a073d4a77f1ed0d2b2959735739668be9d746415bf86ec55ebd3384a21b0ed84ca15e6acaae2ee610813fe552337a321de8eeb2d2d37a774aa0df0d69540de84dd2b3f70539641deba2a84842a3b6d1f909cdbdfd59fd692daf915d0865a229129105dc4cafd14e76d772602d78656084607e73115f5849e4f08e1dc54d249f34eb48b88d1bfbe9a28e5ccada78a073f1b183ffb933af5c3a1f82ee15e879d4f5bb379fb6663a2bd1838d42bd292ee991546aa72ee168e54d1f230e5e587b3b2573cfdc5febacd090748799a62151e7d302d07d761c92de1b6883ca506594a465c6d4663ef3414f5292e3ffc365f58d6bd93f691c6fa5d813286b92c70fc10f4c5a57e6f99653272ee0b096a984d859590b45fdff0f619c77a32833d2136f5badb577e40c594b94558e9809ffbf479d2786d7a0b5d3cc08f5e2494afafa170cf9bb36217d138ac6fecf1e5b63f5776b05ee00a14f154cb4fdc7229312274305c5644804eec004507e39cd94ff831ae1a46b6136411207f0e539f063c637d75674f4e025fd6615c81ea7d4345c629de782413f366f04e61a8acc845aceb1d10b468df18378986b8887d8f68f281cd4f54e56b74991cf5d8a076270cbb898bf97c0db6489d3cbbf428cd49102d3de4c5678da3a3b6195b511db40bba866efeed7edf0e96052db67ee1df5c2e4395975331472240c3d8d55657b760fcb23dbe8494e177a2d929f86a5f0632186e909bcc8f6e16d87fe324b79c9fffd7347a0ca77bf4f4b9f32b86dbdb4e81377071fe206dca487fd4bb2cfc13a9d8d5b6ec5e71b762279be58994a9b69723e17a8f3323a4e4c454cf85267224421efcb46fabb13d835cd7bb8a98925da2bbdb29465e48036e9ba9ccc243939a3256cf9ae1e15217bb5a0a72a663b4ba21ca54ed2a3c77754e895841063ffad8dc29a65ba5a3882fff36e165bb4abe3e08d3d09f21cd1f41d52468fbb1a7ce2987d88b97259a1ac15045e04a75b7d658de5fd8e1093f30bafd5b18d0497fb7f609fa190aff75afc67f0e9eced07e4b1cdcefc5c14d3d621665da2afc0b63b4eeade94e471a11a1b1541a34b4b18f1f4ec05fac47a19e8b523e70729ff7df85ff6081b3e343d2124d0455512c4efe069ebfbbafa713d4e8b9234162f738406323cc71e40f5a069531c848d06036623f2625ff7e5feb3692c13780bc4badcfe0e778625029994e07cb831af60aa3ccd10592ab9d57f2eb416f3b1d32f6e449a26119959249480505ac7ab680717830254321bc637faa1fd57aad185238cc5ffe98dfb3eb2435335d889814654b5fa6316dbc8fcf0c2bb53f0e7f793385447f4cb1b9ce4c5a948596e56a1dfeacc986ac80ffe6cadcedc9fb975d58e86e1ca29f902960106b902913971bffe6491b31f6d684d1e2847c9804f90479b8d0bfd87e37365fd43f8e3a27a6f7184da612b266508210693d786b7fe135501638111183e35ca3935ab75ddab3687db0a8165118399e251e77f6cec1107bde79e598630a8fc7d519341ceca686d9e3c0fe56bcfa753073508cc2bb328d18042fb59e394aeee12f64dc0d0f63a4ca270ce66853bd9445a50d8c1d3ec403f0e0c1172c5d2f5fb6d3a9116312b009542b0a53b6c5dee08cb50a9a16688c54e10d791993477028f8cace5fcc5a7726198ea9276302dfe504a8e3e7bd94b8c6f907ffefb09b511228aa11b272b18c3c56459a7c7a241da196c8da1dc67699bac5a1af86d7642b68ffbe18246817e9325d30cb66ad264a958e54832d979ca41625b2a54e6a6f4f66c9f9d536d8e2bd4b4a5d4d193070d86d43b32f5394548f13a0f75ad0080b368937fb24ba5834af84928c8da126853b121ed21d72c24cec6409efbbb6a8eaf159b45f22cd0990bfd816fd331ab9ba9904632d8f59f9b04ed6a77f388e671d672799104b30622a4d59745f46d5bdbf766eecbe51b4ec17aece957de0cd7df3c8c53270e410af6492c45e0148ffcd44019c6f67ec9e0530e65661ed9e2a1e4a16159e27f94493c9e5e9939325db953b0af59fdf3d83be5812ea9c8ce7d2f189843c98d3fc3fc53d58a092be3595fb73758d2a511eeea96c607598d65ce2f2a11a2495caf3f42dc4c39f30da3ab586ff3eb221ae9cc3ca8120a83f7b491034f7edb351ca6f9eab812df87aa2384b6b97b94809014b2a3f0e145390d3cd20eabdb9cb96e1e54202a75038f2acbc18a73bcffb63052994bd5d3f7700312516689ba5ee710c6d0f8afb10ea61540a14f65f517cb83ad2f4c4dfba7f69ed26ef52a953d9853b4fdc9bb09e299adbe1bab5feaee37bf74e5ff8768e0f91eb50206b91eb07b8df2d404ce1cce5f08f344cf622c99930b1331d5958fbc7bc878dbf7374a49ca819283c0a8d95883d91af0365860b3f7e5bd11a46ac3807b3d2a47bcdbb747cef9b7e835dd7393cb1fe3c9ba4d92b8b322897ce6d9945337be128ad33bf09d2f2d3e12cc1730caa2548fccd7bba3743a90619e229762f2f4991959106087d54c635b3846a1a04b6619d744a77c99ff12bd28cfb4c4f321cf3e6354dc6a565e0bb23da51235888723ec934c1ce9250185de98438b8eda086e779969dce4a5333f376b7898e8500b73e31c55fa53d72fbbfd7318b90bfaf252f4e03fb855c2db5c2f845bb0d34bd4cefaeabc48733e72ca0988f2a7ce42a11bf359493710e334b585eef79097127d46a7ba8511fb043d684c44bbf4837d73c78b6f745eec684a9ddbc1e4d2a34be8c90f6ffc17819bf281e4c08380bc01457afbebe778a03360cc6bbf0953a6395f8f540587d2c92a8bec38e43e5a35777d2c5b7913be4177206cc1d33faad282ee860ab9678a9c2cfd8ef3d48414b0810d668f7304ab9306cde9dccb053eafc9a34cad9f2c393b28b0e0031964f4bc1b4376a173166a8a505993e2e6795defab82f147ebdd5d96ae77ab9b02618c096760ecd98863ca05ec899f4b35650e6865af8a7bcf08885995f00374c1e5231401a75016dba19e7a833d2d4ee7240aaebe6be0804a87a47c9e81cc34f9c1cfb157c61339cd2c130c36eefed4d461666f8705782aefd43499600416ec0ba7ea8de21b96cfdde31246a33ffbf225e05ad6aa55fc5f1254b54a95416026ee3e3d484e0ed6c00533e15c2ccc66bae55e8a969b1e65020a788da794a6711bf4e27c45151ee983faa4479b0e2a5859d8ab8e6de99d7642ea24bae8745e978f318fd7b6b803e8a570266c1765d85922167495968da3625b5d538ccd88755ba45e3471ccff87f70daf2c4d6a5bc288c831f672764e92296b0b10e15bf8fe79898d38a691da020046936c9a264f28d139b6b8631e9cb724bdb415602ac8d2afdfea6ad7d779bdda43756eab01f6b5c8c73e09f7d73855b08ca7c9eb5bd7459cba2f7c324978d09bf39e867e96f776117e43ea4e067ddc6695e9875ec5c8f14c1abcd497e755136c5fa4c3cdc206bd671f79898ecf572fcb8e468fdca2a2248fdecd09d6f9a70f3743ac16b90188fdf99add7d39bc54bb4db37500da95942cc17b765816cb77e0bcd9764b46df974f38ecf6b29e4fbf7ce71d42acad1ecab6e615667df91a5ce71c9e169d366caa91b899811eb32dee01c23f50cf7ea42b248623c0b693492fef3e756ca5aff832e93c711f0053bc3ff72a64ea7da37553b674e02424aa687383f5058629344fe88e72e31dc27a6d579e0625faa11c950d061d094e511f08dee95df1bb89767f2527e57b9e159fb3097774aa258277714942e3ca23d6b0f85706863d7d6773ccd41d0f44dc81f7319ab149b380a24da22a8ee34e360c570941b38af518bdd2aaaad521d5975de872cae54d9eb3ecfe54d0c918742d0abea4ba522d3e88ed4abb1edf89669f4e59dd7e495f287b7a422d31c5a157d4a665f115774e518a323a334cccae5ca812990ae7e106fa58f9b35cf1a0b86d7830bb088ce653e0303d1d6284f01d42c3732436fe30f1d3bed9114b4eade5e99bf18ce7f189d7b968f15f586a907434cf415858bf2b442ab76ced76d9b24ac494349e05d6b5888f2ab0be48bbeb38228cc400868eaef8b2c5d07ca7afccc4ba94366916f49574249fcf05cf3aecb10626dcc57b1ffe3f27a2262fccbeb292cb8436519448d315525ab1a6009191802567080988bd632c32439f20585d77819076a4a5ec79d799b5d665f30951f16a1f40a017594383c9fd96c139d87c5e09780afb743682bcfbafc7428aa1a291789768902df188f37797cff8e3f4781ef543ffe46d785e3bef383866796fd353ba78e35907f01c8fa50ef1fc83bf36a96a5f26c395303874969277e83d9979ba68c2353d4c83bb4b9c77ae10390e12affb4bff6b12e68203dbeb5f3216104e6db776865551283008ea20d86817241c0b482e9af48aa9bea2163ff0502d4fcb082261ae2baf2d00272839bc210bde2953e604f8d7153cb1ecdf7459018a7cbf1f0b5fe9a0cc19e31f24274ea75268fdd3b9c3840930d3b38ee343262c1a47dea8375e78309b21db9541d80816b2d353440ce630a555dc3d99aa2cd251544865d5a423dd230329e89fd3b98eb4827ed49bcb343b14dcbbd10e8c1ff8cfedc9417dbc3a97d1216ea08635a7a698bc7cacd660a6adf3c16eba6c7ecd1ed847d71757dec3d056b86eb7d7bc1bfc2387c0cf5d4d8a2ca8a738c32407ce47cb9d7fb5affbd09ec32aaaaff72494d1f36639c5a01916337c923c3377d978b0318e5c68242df7782108335050fdde134170785d942c1d3ed8712e1bbc8e64aa0751f7f5cb194738e54edba523c3f609536f31b29fc0d0c6449c4f4d286e3fb760620bfd6aaac04cb8c913c670df84257397b629c09b1e39aa30ac32fa69dd00ebdce8375a4376a3a03d0877db9201483909429e56a2535be0907deb07a9b5e7b66f5778590c2225d82713a12237cc938f4f4a8a4f964da87239531876c67e860fcb22cb3b4d98e0264e6524027f27e31c3f86422c93b1b331e55c720639a1bcae62b76a137e3557101bbf6b7a08a5e2d4b17aa0fb00caa6597c4519236b725c1e8cf478a3718b9ca20c503503e377f37969037b8a3e74270b6cfe640e38a5974ba935203247b0e1f9c07afa5a5d68876404871c9316d1ed08c9e5a975e4d94cd3ab81d8bed2027279cfd9c73e1337de49b764533c96b86931d2e980f08e0979f8e71302ed82f124434be63ad2f89344935a52978eac521e1fbf98e4b4d710e9cc1597d59eead70caf6da5f7843a939395d1f87d5b239482e0c34fc13f53d2acb800d0bb2054ca4ff37cbfed29a71cac5352cb7dc1bcf4281eb8f519ac4fc0103a8a74d95fa6e3b914aefc277c82a1598c1c8ef80b9e174cc43dbe4d33ed3ef8562e4c8086ad8015a8964e12be8245cc1fffdf1e9ebff2bcdb3d071c1ea5e838e954798572f139b8d6b6fd45b8fdf462fafb1ab870a7524aed7a6dcd08a0f71dfde6f6db473546e37b66955137cb14c59438e60efe8457e03907cb38a04f22411da6d23c1b7cc842518daea7874b815b4da82c2da20a686676f2f3bb3e327a700a3eb1570cec2cc61e63762234c51ae0a5e1d63a9fbcfb7c48d9b6901824121bb1793f771d9c0b66a916271bb86e6c9f1a3f0ec1948d9cbd8e98edadce236fa505c0902a2b94bac777aef9fcf40dc0ddda747938f52c83994bb646c89c7f0fc55a2a70b327b28528fba00f6bdaeb657b18410c188b35769071f32ec2706c30e938562d5d287cddda6203a5ebcf2830e0ca3e9ea49ef505684cb2450a1c7bb747b0792df6c5818b73ceb3836b80ea809a95fa64f7fce0b93ea8ee5ed7538c994fb47eebc07680cf0140d960ef0b4bd561cf97d58df4df72a3c733cc5cc4e64c65624c3ffdd155cd5b6e5aac99a6fcce0227fb1e1932a7145aac0865f250d47d8ee3411824761d29403c68d7f9a3fe00f3fd9d1882817362a34037578b0387004318819c8a94a4bea95d82545178a5da34ce33f653ad7422a713cd395916977e889ce0629deba06662c7bcea7a2db4f3c912d38aa45032ed75ee998932820bd3b1e0541380bbad6ac54fa3f24c296abe1aad9eb49ded5188c7d3a816171a2c2b6d2bddba38edde1125f65f8ac5e1b1b85d6b6e853281ee22943184ead05e1d719cdaf5aa878de233b8def9beb9f7c252cf351a3971d915ebede9d2bc10dca885e64ebd58f731262a97b115f6d4b9e2fb2605bb770bf3e5c6f76c124abc3c6de289d645f6dab747b1d713e2ec051c183f8b8307e3534aef26aa8b6910dcce8d4a0a8cfc0fde050abbc3cc04d6d342fa938b68c1019a95158ed6c62a6f0c745a6ec3271a46730670e652c67d011515a04aa5dd9541e0edbb65f133ee8dd88bf21cbd0b05473228002256856a7b8630bd591d29cc80467c1f52fbc74d5dfbba682dbbe4bb9677e22c161e3da93e19f1db594f5f07934d5341fdb81e78265dde9e8cb03606e10d611ff95573c1473a308059aa0e57bfc0cce725ab8c432dbad549a9bb4096a376ea7dfe6b3b0383ed15345eccc642bb77739c7e97c2fd813a722d5ab4f88801be51b16254cb19e37fac2bc631778fe81d953a083efc5263f74746e6fbe14d824213c61e513049b5fb9c5b80ff053b9c5ec354c992da7e81e8ff47f197524f5a3ce8d9fed7148083f1e7aa8c5d5d9c05e5ccbf9382ff9e8211a7e31aec510d8b34fceddc5c0e595bf7d7df59508ed9413c8a518381f3c87bdbcfe1672b97c9cee811b1497c489c355f1fd21c118771a72899991bc5b6ec3b9b6b9c507d30998a8ef3b2c583d3279636ae149856dcc210fb237b85677176005a5f7b0f25517abcfba173e51d13e79964a6b270b24726bd3497a38fcb087415b8b66bf57846688fafd0c507b38fae04528c843855da05e98a694502c30786aea100e18b1087917fb6645d569ddca1d14f240f261419cf4961324c90c227d3f1a0d43e72daf96963ca9c0b67bfa3281447841358022d826b9079916040b80550364502785770e4f8772ef500c90cdfa7c585afd3fde252b8f34525a91499d7f3eb63b6fbaf2c2eca1aa0041c638f46ed14ceb2ccd2ecfc419131262b1bfbc32cdff290cf8880c66ba656542ad498d82739eb1489be9d4d0f23e8593e989d9f8e8fd95774ba8bc0223e72269faeba31511a1d3b0e28b7d5551adb89d165cd251937350f0d9d6f3805aec628d162727dc0c92af9462fc1b2756c22b89c7827392f539fd95711f232eb9a716fe7ff2fd6bd76a640817c6fa8207a0e8c2ee7fd4b2284b6ca66693b13e8904b5d405ba66d62db4bbeb66fd1131571a23d26fe456074c682d1620b6e4e4d917f2989180c892007723584d70408ec586683882d7ab04174c3951d5f6d968cf5e7dfd761ca3e6e579fd638e943debb3d60cfacd5f74b053ba7476b150167520fdfa75307f594387980b6a6928231ee4447458c6a5eb2b0e6cef698ab5db1cc9e0c3fc7ce6e2414eb502fc1f70b811f5539cdd47be98f09f6c030b9b147ec140ed8597714447265e0ae2eb97edb7142f9eda0b81d6e1919cb5ce85a73ff8102b8dee50a6e6f7a0bc9b1eb2ce109886f7fe558377f9da016358164f4eecc0eed55ee2306c0c142a075c3ca95d61c13023efe50d03d046f338f3fd1d6b902011dbde9deb3aa320ea285aff49a564c3f18b2d94e67d6ef02c7f29cccdfa009d6d1f2a6468bb54be4a41515fb2c2d2e44e8df733775905ed966838a154625556d741610e5a473ec9deeb3b112c4a5147ec71b525005a5282ba01c78cac3353d889e023ab06f5b477b850030645bcc5c100d8b83082f116c333e83cfdd8a77ee686526028db7301607db86a7ae494f1bf616cdd21191a6a985007f6050c17fd1af8f53fc5d74777270a5844be2204309bc39f5e097b12f555171ba6c2899a3ec7d04a693857c83099dbf35af319eab3c86b3c79285fc8e5001655eb6f85265e21b3bfb23c4d3234f486940793e3c5d4a6a5c313b23e7c434428fb0431328adc3dde9716fa77f65482c925db48f3e62484687f75296a0aafff90a456f1e1af8a33ef897f827b5e70f14f0673588dd6ea1903f018969f343dd125634d4d840e56f5bc7d2103ccf38c768f09dcc9e8168567c1e58778a19fe8e5acc8dec2771c0ce1812cd6cb8410a87f072e943d5dafd512c92ab93f9000ad933addfecfca7465048d08cc9169ded5241b7db6fb3505c9d99d1710661a993100c73aaa7ecabe794d7aad43c2778c977bf3dd3830bffeed997f2dc4552aa45f286bb34bdbc32592ead80b7903b88e7c3c0fe5b5904fd7ad88574978d6c459528f407681d2e81503397cb5bb7deb4cc28d0574a0ac9e448f2134ab59b885b1efec5b1c27ab85993d3e50cf0f07df23b704117f9018e1c40fa2c6883f749cf7891a39cd08ab304b58a2347b9294cb5c9774dfab72b0a737ac1456a43b5bae6d8dddf8330a6bac3805f72a9768d1519b9d7093024889957269267a3d617e7c801dbfc728fe5f3d25778b1362d174046d3da8993b6db2712b2dcce4eecae4e8727e9c4e88684580602598c14bc626b1d12792a5517029c4034140533a8419f545f4b1be8b8979e9b94dddc2c5b60e0c606e0f74acb43b710dba1b2a97ede899fdd2b7ab111a24ee94b67a5165e327f0aec2c772b7514ba048853617871146a6c27fedbbe4e6b04397bc9bd2494c44f9469c9e99184946c96947c44c217fe3d0a5d0136557799543976ed2457e6c5e774d796a9bd4bad3c3b9a6a5e97efef2aaa6ce9bcfea2d0cff7784a95ed561faa7668f68cdcf7c504145dc2f8da9b94019cd5bf404b2d976bc30a7b5e7b84641837053b6f50ef0e3a5bb07ed36681b6a651cf7f91860a711de5986cefe3392e06e6e9afec67e10be563eb8e40231311e6f0fd94c302986be672444b135cc601cec03d825f79e4e99270a815a9763d6afa81a20dffe460622c621fb38fb81e57e89e7cf17b333593d0cb8548078bdb151c201da4b2805e36d2ee6de4859f72ba659fdfae30df5459898e84f9d52cd2c0991d940fd91c22709f2c1225549ade4d7045271e9e0e886ef72687eecf90b29971e9f63f098d5645d130214da211dacd08a297703278796ed04cd64e67494447590376b182fac75604d6f4dd5d6b37373faf57bbb5e75e22964d79699357978a81c7cfc1d5238882595c2edadb7d5b724e00f4ae9310563e3bf32aa92af3a848bae983252abc527293588bad50a1e2e794f2018d477d8920c4195cb2fd471b63918c680e9d8faa3801a6a43b1914863964ede73eca25efd6c78eb5633d95cde292cf3424d4b22928993a979c5018d28d3e96eb9977605fd4436f5356b38e808962e454a169eb10c9ec0479a46c78efb04e60860a55b0a2426fb08e6d86a46118b624d52b86b4379a3fc475a80b0f3989c388f607d5a175a6cd085af6735d18a619ccb315f85254874cabea8103c00c5e2a88a054fb27ae5143b147e82e556ac2125209fcbf306476db9709d00c3e5e1db14250ab4a802adcfed1a2dffb2d5e1cf233cc59549e8127226a63526a16c73d4f7a49bc6355ab036e1c4bf169214e36aabda97802d6e94a877f6613ac250780c4cf3ad095dcf2449a46459ed345fc5d02e58d8439b64c8f6ead0cce07430c3f9f7a644ad81aa81797f1a18c0c2fd9b134fac4fb09035d7b6b91989d0592ec6db3dc1c4349fcbe46a8a94b18f54e56d8df7d75b7d6cfde4999cf5a9a0be9dbec66aefb4eb74de364ec8633e44aef447a0701b8149fdfcd1f48b57a08334ac37275402b990233a27adf778b703d356c850246df65e30db8e832d8f06e26493f16694e57f6a402ea8fb69abdb3a16b9eb612ba4def494b0221d3abcf182730f0c13cb800522892fca35f9509df68b8810f0a313263e8a98025f4b38a336a1fee416e9d5efa771a79bc5d8224b38f87d5bd63122bd508e25942d8f5fb73a5ab38140d410912b42f96e58e7110ec1a1a595c69a1fddb375fd1bfe6bb16e4ed7c0226d3dfb9dfb17d1cae419f92abe3be305bdce7fe59c0ceb4a1737f351a509d832d804f59e15987c6c8a0034c560d1abb4249bdfe64b72eab644a153afc75075ac93e7f39415e25cabb2b3dd7e41b05a0f276e7d446cc522cd209045ea61d97984b397e202a665b0ad295a877cd743a25dbbcb4ceaf9266f740c8a9518b67ffc1006195c5094344c2a8e157ddf8600b80067fa32b8406f095e7f58c400706f5b62dd29708e0fd8ad3fa73bf7935185acac2d9f586cb94d24c4bce3812f849a52c43959a1aebecc86d6162794311e531d6292036ae78879c711341d18df558c748914fe77ba9e81ab6b37e3193a2ed0d8d94b6550e4cb6c533a6fac23910db934c06f1dd26b54c048a764f56af10849e264837493df7c75b6d9b83760c3e33cab0438f478e5cc0d9dd250fdb7011917647b71206e999694270290d2a994248e7e506eb154c0c9d857602bfce213a54f69c3b476925f6aa26105e89fd0bb3125efa0b8e237ad7d614bca705abe6dff05fcd22dcf09cd2a3a9953c78a1e41aa69fff71f83f399fda5d829b8ca114fabb3b0d4607330cde904a6f901a0437031115c678b784d872247d0445b2d8f67876969a7cc0e38edbe6b9b28ff2f878759f67fe986b6e7dd9ebd3e1290584df570aec7119282078af4ba31305efdcf5a18849e7d493f0c0b206098552ab022ffdf91a9b8aa636ccac73c825e1736628b24da6e6799a389c4531adcb95065048c1aabbe49498b2a103efb72e3318e840187d125b6dd222ac70bc20f79acf84d0966c89285a6d7d15ffcaed41c2eb4701a234931e296c4645e5f802025e859e7b4796290ba14b746895d39bd8319138ffddc16186d13ce61e3521952ae4b6aa0f7604ffbd702447391032df8706ec6574dc52cb36f140c58ce8a9413666cad97db80f22b844a249d816bd945e71cfa790348c153c5b0ec226088a417481c3a0f168191cf6e9a2396d7ddda88d6f3caeeda42cbdcb43796fd725d16ba5a86d4c76817e5392be659f29da00f352d45bf1ea1e5f8013bd9bd835f2eff88bf970196a9008ce732f3ee0ef62a9a1f84e7f5d589762220c3557c3c2cc962c96101ff6cf18b4f74348e0a857ebf6e767d8ae25434351237c1ff3af1dc01594029b33ba6386422761f8f46cf3a7d264e4b379d5aab9270b817b7dd3131e5d565dcc083106ef168ec6be18b31c9c48f0cd08a545f4f1785d66e4728148965dd0ba9f0a93a3a59f182e85501f2fbaf34aec133e000ff4735787c35480bcd4c274571b696f4c9635bb41559452f1f85ec435b41a4233a41d017a1a632a469856e70da9d6f1232e17fc44c86c54fe31402df9fe2f06f16c25842dea829840bb4b7bbcfca03b1399077dd368222facd06e8cdb6ead51164da157a1000912f1f82efe369e47641c8378ce803062809095bc77034f4c3d5bec89926804f81f509aa82e9d457eac2634b17599a02ede6529369db80d978256d574f763b97c27f1e4d3bc28f893b306ed46b98acf2bb59724e08552100a529359c935218f06df74d8a353c4221bb84e38e0b283bea1c4d1d293a28e6ba69abf05bf45bbef461f4c47bcb7f6e063d6711cf3162261a285f232e6a2b7aedf2843ac7b5f6f2c760904bbbd39b33995ea2327a68faa6915341e15fe2b78bb051253eb9b52c2fa841e460b11916e549f6f9b313203753296db76dc564ff3c5bd12ad2d087fc53be89c3924d97f9f24d23f6f45bc6e768ea6ae5653a00044479871bc4d152017cd9b6c93fe7d132ca7b777fc56b7775831800f3f87a6c3fe4ce0795d3490da771411a378aae7a2645b7513e49fed36cbb8fddc7e4d860a5ac1f702677c0233c757ab1b0ade25b22f141de668b53c5ceb3f169b9c977ffc57a56e10592ba10144aa5a33bb2392618c0eb71b15b76611f92a3e16345e3eca1088042c09f0c7aa11e7d74e8d0e4db05b5f445a7b0143eb90b7ff4ca6b5b1b209b0a8e820bf8ed673082ae89a1fd8b1abb290f39d171ce14fea5d4f2841ae73214c9b6b2e72b4cdc7cc0ecc06ecedbd079b3aa25b7ca5ffacbdbdc70254c84b7eb453ca4ea22afd4551498a9503e8b4a56817f2dc7af32b2e83af4562890e4be94b7dbedf1e837596c46d77a986fb4e211692b922b94d253d4b5091da927599c97374b6753ba8e48d247fe3a1fc2205c15d8dedca8c8e2227530f5e205ab1f8d9e071bc1ce2ea61d645d39dc0dbe9caeddaebac4c790d5ec733e6718ba9b87267bb7d4b4b72269bfa7721eeffb189fc4207e574c7dedd70e491c66acbcaee3cbe96703e418fd2c220679f74e7e4b02f24f2942ae8750fec387abdfe9c5244b0c69d2671b8ba464d8a121cea20453e19e46a7e81e7eef2323ba2951ba72fbe3d22290dbc9870135fe32ea5be4385292c1b0d7102a11b4496f8d2d7954bcb0ae5e03ea9a759dd9cfa4fe32ab76b785a82fe29a138947c581a5bdf3433592810ea8e9d4fee6ed6816a0d4af53bba72514679f9bf9d4ef376b4e6695d55308a13662c4576e2c40b1551badd95f93e452fbacf4faec500ddca183a3ec0bb445cf301899fb24ab84cfdb320af08b00ede57ad186e43c1ee3165374088b4f179f0f0ad4c7b111d3fc22c060f0b9f4e395afd58a38e2377b435733ba2671b010e45205128e31db6b51c2e7b7a4a7311c4af7a2b2db81a06d63e7ef0d9d6095272af12a8055454b8505621b6eb9857baddf8182f7ddfd6cbb8961e47dce43bf33d72ad2f50d30c9ca7d189f5e313332e5180ae312df95071a3b36fbd0424631e2d8dd8e9f8c4545335967ac1dbda89fdebb30636f5a4afae2c8290c24dc06d8aac64298a28224ac3555598886950067fc3c03e0f276b4a8b359324cd0ee382ac4fdfc20d3b5f7422ee739025abcbdd9366b32e3b6c91f8f8b4c01752897de0da99950ace60b7b89db1f235c12cff724c48b63476e575ab2c85f44367c2b6082f870506288b981f66cbf5f7e47c6059d5092ff7e84949f12cd3d6d0c42ead6f5f0f32fb55d3fc66696c766e8d5ceea6933c338ab82458b2f9e2acabd01bf20c73779dcbbde4ab251526d785a00fc9934ad7e5dfbdbf7607b51ce51878830525545b7929eeab4cb69b1944ea29eab8992a10b3a2f917403907f29e561241b2dd80c045ada3fe88d117abb3ae958b150e4f3ab178f615b6ecc64ab939ab060869dbf9150579decdd7f526251c6a860e86332ac8369555d3f4e7f6311a506fbebfca42d92b60ce3dee67c5cc0cb9dadf549bfbb52ac55a549db85aaab1ce75b55870d4fd3fc69b5e5906d830e0d72a48fac9207195d0919d2600fa55063f78b01e11a014341842928b50b199121a58d3be80406c41a3532e491e2706f0a202d441c46ac27d21a433926b5d36b0bf3df78f61aabdfad9ac003aebd0580fb0764a8698427faaeab8e113bd20b632dd0fcdc0e949ee90f860c65b6e3fbcd80ce01ff902950107b90290395584de37662339e3ce37ca3f6e594a854bff382486f97b2e3be054fb9c1a6b1ccf9d43de77bf3c325774d3aee6723289e650d2e6d6ad0d931e6de6ed81728a3adc6f79948a50ea6bfc330d9634723d5ff487e70946e7916a91cb48d89fa548a101f2c42c2a3b9abe5bb6ca45790a94f3b1f23e2fa6d24bfd77892be398e2f90cef90b4145a3108f2ab9cac4e4b9731c7306fb6189442606d262c8d91fcbd408c91dfd6c55f619a5554c3b93914f11b354de68b1888dd614bd38e80f14a7ba86a559e4763128f54e578a6913fac592f53adab1daa4b0c5a02accfe90e1dbd495a3c146f1b0cc4186c5a57e6174a83ad30d56fd06ae2a7d1bf90171384e4331e62c84f60c6728491215047019a8f11c5012952a407676aae925b7605d25c0c898bef609a663e80f8c9632caee6ffc9f566ef1f7f527ffc5dfa5d2d3fc7aeaa184f152eea872acbd8daaeda877a3fbd425bdbdabb64e3c88cdc824a8f2f56189fe93ef54338d4ef9e31dfd095a9365fbacb339e4af561ce9c10827d8f6e7fb7aac262f7a1aa85c63b3b3407e5565ebd7a75f88698723761b750aff04305bbcf29f6ee3b273bd4d409efee0d1bdf3ada67ea2835ac624e445ee91c2f65e3e27292b59a308ee94f0d3faad27931c91a09336e6ffd7f82a5bb25ee842996d36b33d445aad928e1625814261fbbd0cc66956e5e0f0d6564b850990cd605b8e9fb14112b85a1759d9aa983258df679845050abfb7f57e267b8a421a42ea5f35b1cf660d4bcba21b941976ff283725f90fd85f9e736d3326a37c8d37a56674384fd7e53a54b3ee9e0891c27ae944275ee03e73798651b1e93ffa481130d2cc4f145741f9628f8ffe170f6e49027508f7da2044891bf3d766a8cbbb3a5a20da385fcad37db4981e266113c1908cee8cee6e07090f91eb50207b91eb023f6445b2e5f8b1388f07f603a3eecc77d087988ede65ca6dc21dbb27e4edb0f84ed4d88fd6c761814aed07006c65f2742b45b1c7808f7ecb6272efac34982999f7857196bb82bb613523d60d5398ded5a5d88fb17aa83faf6f9652298a081d91f06083a4ca3a37f2b32e4f3d211ae9898fa2ca72882e1a8d12eb00b63a18251315dde340fdce3729afee76acf3b2534369ae55b4def5a1c76bb96fc32172546eb6ade97519e0334bc3e4d986c5c55a622700e5bf8f31e2942cd26a28c3fe95d034f02ba2d96092c07579544914ca73447d4a8364cc144af41a170eb33dd6ab596cfea57824e50c9cbc3b10c19c0e56f2a479632c8313ca10b3405cf2245181134c5e691b45e84e29b145af7063f36d9bdaf874e53d37c76359a071cd8394169264e24cab618cf1f07ad3a122a2c603c21ade85dc1c8b0a4b04eaf505fb3e6d46306599c4ec43cefc75cf624885791ea7934148dd0f34a50daa52d7cdbfd1893b08c0d1a1d336c855a9234c383593d319fe8c7f0d99d258a54aaf8d53e087550eb930be89108ec44461d9fcdc5e13e59bedabc3da4394daa61c136f4a2780c5f3793680521ecd844f0cc76071f929047b1f518d24f7947d1ea4831d8fdbba8419e481ca957433836acccfc6847046f5fac5cedc6f9fb808afc4341c1c8fb1e0203618f46eb08f3edee1af9c9a6f583f08a89ff0917aacb276cc22c0dc0d490f18296424a62c885436d60ca5639e8709651983dab2e3f8680bd041d296ab7267d5f2f7116c383792b993bda55580cf9114b03fd9623eae8985a43ff4c7b83ede61298b448d1b8d2d17784c6a417bc7500917d108f2b0bd5aa76e8af0b3c45966730b20406d437a410e21a05bfa844ae6b94c6d02b408c3a7485c64d7d189509e8ace1b49eec1ccf53d376de3c57114c03fb8f871e5be4d4d88705d218ce19557eec8434b21da863d7dc69d7dba3fe18f21b9388906752f421927c9c9a8b2318048d4c4ea0e2a40f2fa253e98cfba7264ed60a7603f6b45b87dfb950e4c25180b4ec380e2b692c113e5b0f38f4cc61971c216e76c83916213df38f61ac2db26620fb470c97ec923fc86cef407f97955a0cd82f3bd103462ba85b3b68cc2f5ecf834e48706f4411d1a1932d044d7c4768dfdf59809857f0765140e25e7a1572e953db65aba6ac8ad37a047790bc9acde1aab58978a7e373d9e06bf723e6b63ec7bed7effea6d6a5665f2984f05d10db13428276c12c7186e4c4986812bfe41a5babe3fd89a50b0826502544fc3cfefac3682e43e09231ff9befd827ce168ae39785187029116d192c49ca5224766c5fa21c662dbf48219b5e9012d8383aa3595eafd8831bad3a0c962a64963b9ba30024046984d8dfc6fc9f2bda7ebe114f6b7f58dbd0851b27e37a24b3739f6c57156fc699607631206c1bc2f9efa4ceae5e3004c31eead4eee2ba3c01fa201ae6cb22bd642842935a23b5076ec044b3cb0db75874b107d9de98082b197fc874a5560e309a789370f8c106b405784d86f0444b2888ec9637ca82057d4da0477ac72e441c66e6f9ac03956a370eea1f51093d627760a73bc1ec59aeb94cd0fae8188cd4dc5328216af14ca21d1e07c9cf513b6991f2251f2e78c97bf05e739274dc2b4776c78f823425bfbaf56fbbb9b3cbc56645df7a3862e06beadd7d1dcb288ae4407253d7336399458d4603836cb0e965acea96092501b236a3d29a0f182764f99587721caff5be265bf5fffb1732c161d7458225666f56ee8f7645024922c0a9126199e9bef2e24b2ad8a7eb566a1bc9f7fa61a2b93a5ac58404a3129d313ef72ca887565d09f76a8951551e49ddbd78ff8d6e83b2ae06167503c992d5437d8277766cbfc0ae2e6e84d79b14a02782a534cc1b36d373b16e2cebd749da51ab8e9e834da6aa5f713aa2c982fe7458d8d1c94b0aea09320cfd73c5c6f12f4948e696b2704008e5fbff77bcea46bda4fd7778a094cacf5eaa7477c3eaf73b217ff10497b34a7ab0a697afaadad2e1d232d8d4311c2ed3bf17dc8a8eed33d216ac73e589fae17f1cdfec2a120d26a04de550cff2ca6b1207ed3258ea06fe48e6d2ca12b553f79393bbda9cfd80c2c63a0a9138a93a9995f42c316afb47e41e586fcc6875a67637eaad04c6e8ee6a6b2cc5ea37bdedb2414a78014aa19fb3dd2a813b1a31d67a6b1780d8dc9606f731a8448edffde5da5b5d87e502b0efbd93a06e4449a6a323d585dc1717a458da109729925f3548692da114021224e76c98f38ee2154c078929ac6093952cd693cbbfa9ecaf68325f596cb6ec333f99ed5af2b17701afbb7b52c1dba30d54f2f8ce0edbf0af5d8406d04e2ec37c61d6949c9215c1a8a16c6ba875c014877becd08cca35441099a64eb2aa62de9a1f7362dfdd292dd63497088e395d1c126512713ea6f34665b07b13769053530b2c8835c5d66126b9e292cc95daad1431366f3e8384e71e3085976464e7252950636834db0048e30fdf61d83a205551f62a6183e3f935615ab95538e7538e094a7a29cfb143d9fe5800df20fe252bf70596c9635121c504b07053b17fc7ee43a59fc330f3aeac3bd17e53e3358baa569e5a8508340be0c6b7ea7b2584862424187e4d1be38025bffcde45e6347880fe18422e204b306f80b7f106cb5df5e90ae68181b74aa30ad5e9591d58078a958d6d6c8d949a0b54db168a8f70aba74085fad8ee439afbc2a332b66e89446d22364244c956689382f10da9ee71ea9034a9b7e92d2e814fa018fc98d8659b8e338cb5a95badeb363981795c85b62e4ff7287b5e5165010138e5b791a77e59ae39e4f7c837f7f4b22b53b758edfc54bbd52192d00a4f901119799d53c5c1a7bd5a9cadbc21e09f61774fb1c8e2e8ee7da1bb39fcbcd16372eccb9dc57fff2e4f2f36c9d9fc556e3ec2f05c9a4ba9a370704f6ef8600a2308c36ec13bd3f1f283d01c7c48d0fb1380d72ae3decb638b86f5b313e71c6bd9dc66253102edb8f809a07e14e3581a74e83b4f6066d8f2b2f4ba7bdd37e7c09dc19821280fb1a4549922c5c29d190f803424fc58c4b923019914e92cc6e9c091aca8137020d4ce2279919c7b534bde511fc753fad039ee4cd9b691ae9731f44d0a55b170b63c328ea4c4d36f05f76563e363942bde5f8bef44602e2154c681f3fd06f364152e64dd36dcb02b733ead4804a0dc22e2d7abedefaaa760ce2a6746250959aa177f1b37f3aecea00c9ca24a3cd10170a83f17118e0391a598a250b9b73a339dc76beadf35dabd5f60d6a658e5d690a9bc82955fd2ee16029122c941737424d139adeb705556a36100211748083c26d4711ef1002a6a5841387a676483348ad2b5890259a8af592888ff2bc358845bcac150ad22caefbb4bb7dc24dfe0573551f7bd1d11a66b8de0232a45d20dcf2a216ebd0d105c1978b1a3351598e70c931ca3eab234ab1ba1ae35cd3e87eb8910f5b4c6588bf63ec1adbeeaadea60a08a9e1955659703b33d800e45aea11aae8f48319bb1a3babf7eb14b7d9ddcb70267038a0456a1b68396aaba5771f0a3bc6cedb7360f93ed151acc09b0940521d6ccb113bf0df8ceb62ac7676fb469b418318acd0ffdb9c10d0949cd37220d7c86142da0400ddd3734ea963bbca2daf9b9aa84351bb7e59df69e3afc35c180cca4ec440d9ab454e9a5928dd82284addfcd8f06252b0296f9d7e40fc07d3e84ccabf7aec735dca1a81d5c7077d408d2f51e5c6f79079df0e850012ed930e0eee2fffcef7a668c97330817658054769d0fa513c48ea6a862444e556f1090adbdbde982187b15f4a568960b820f4fd7a4e46306a6b555fba7920382eb74537b71660d94404f3308df6a332273edfdb1b7cf7e78ea51a1dd7db1a1928353fa284fdc335097a51407cc5fa7eca6e348e573f8bc454cda3563a61fcefe1fde78e246f2b567e1883fbdc343c2e6a784a257b3b6de63e89bf167b36d50d880bc6b7041e4afbd6b3024f4ac47dcb734357dc11b9175bc8954d16d18c57c1e176354b16e402e25f476f7ca0afb65d7ffa0b420e037aad1354133e38d274c9eb0e1e0c0fee0bc6d1af956eb247636810da5886119be8fef852d76f7e2aaf9fb0bad3a52831c7c30b52d24d4e4942d91d276c3938925ecf223a1d05af4c41e784411453c84874957c1cccdc2e5c788b454680bcccc061d9c78c8df3eda6c2f4c3fa8a3aa0d7150fe6b29ffca4452acfa71e637680b6cc44d1ee069b0309272c7641aefe67792b6416459e56c1914747fdc204967a9eaa89e73932c1aed1291926b88d0b8a34c5f0cf1c9aa7f353beb9b10ca3dadbf763f73150c8cc769b09856f1bbf92891f112b2c25d2fa8208d3b05636f2597e868d7ac42256a87db9c221847559e3fd9212e5bf308f605835117c02df3c4774bd5dc0a94b5362e16636567ebeb4110c6ebfde5f715c0b68e9924a935fc81da8764d25674f90b4ff45e67593a110948e0cb3fe28630dd387764318e264b0115b3929e98e52e98376f29123acb54f3ad053d059d4c21832d7ee8adac6f45fd655426969f24ab9e5dc2b1920c7a9e89af981d98d215dc5282ea2d0bf4820cc8b4b270ab608ba997fa6e2645b295c6bfea3b6205ed0519fb5588acb6c804299dc59cb376921e231827c92e3f59b4c89cf1279a04144e203cad330ed2f4c177d5851662397aa15f80a99f81b2dd309117953aa3f53a66d210ea65972b6ce36415d06de9f62ff66e9b05caae46df70345865aaa543b4f97ccaa940a2071ac5a8ef99d51d3be4dba26f284f519c281720e17768634b2e7ac7e3a0b85281e3f7a6d4518525ae06843edac9dce4684c8dd752555c22d7a38ade8062a53ae7ad52e6ffc258198be057131c46513df1678f83086abf657a72baaa485f6258c7c28fd87cf9cfd077ea6733f951f5533e2f4f008734f5927f0d5b00c8de4f751fce7050f56ac92be7349299f13f900f987c6993c322970990023a34592057a344923ba35a9e4487ae95f8471b9ae98a58b39af9780eccf085931c0e7b100dda9b768a858db6d3959a0826fe5e43fde15d2dd391efc0c4c3da522f4fb55d99d2294edab65d961d386650fd1afd5eae951b8c2652414baec629f50a79dbecf5153152f98b37de965c4323242ff7e3a895e907c2b5044345bdecbedb6882ae73e91059ebc8b2171f6d19443558fb3ea1a32f90816c79d11d5942b3831c0475012d4ee416976ce5bf6eeb68bbc3ae82fea2eae7832422e03211f0c73648a4cdff2e77db1a3a7077a2be0ce2a7d7b95703084c38f31380c7888d152e2fc34a7838f7d2a2c5d4ddf7bc17c55c8d7fbbeb495fd567ba9e9d9854bd4becaf6ea224598ded6e1686b9f258522cdf330cc36bd9beebc192351235e0ef96feff38fc71af06f0c5c581d497ea239e7756d6ffa7b56a05bd0d5a907b8b07ac80e7f0097ae35f323239524aadc9d002d492d9109e88d6696bd2cbf3605165b4fc819e253800afc49b00e83e4c8a08e1efbff5926af877e09d93b78db2da70e777dc82828630b2a1a47e4a6ec7ecbd61c7213c2b2198087eea404119fb0f83d4c76e9f64856a6b53e6b3a02a22661180a4c9730dc8dbc4870a631b958da753b24b0c5510943e4c78495479e71e96da0e58d079e3f2eaae5c632bcc7bd43540db61e15edd0167648bc17ce7ece8a2766058e9313eb2ea3113f13ecea9bfc8847d102f4d6bfbc5826058cdcc572b7a4072c355a983dbfde19b8b4b49f38a78ca8d75af0fc16a2cee7905853238dfa88a5a0e87402074251cb0ce9b731075620e0273abcb91259b6541e88b64b5191bf1fbfe7da1cc9c4afe0a00ce67a52b0cd3417b99b32f157a3f1bf23e4e610a3d48bb8748374d740ca33e72b0480877ba730b7449eef90dab45572c0121701146c8af500a633e0ec006986ddca757298ffd284cb21e921059a494a861e7fe600ab3d890d2aead0fc5258394365152b2deb4236188a8a18efa1363107fd28170be4ab992ff60d878c6045705cb626f5922adb6019898162ef5185f202b1675ba7ed5ba1a57ff9593a718e254d156fd9493e44d23845d614fb03c62050846140350a69fde76432ec266a3886faf3472ceb7567aa68374e9dd787e262f4b4fc10f96ac1d5b5ba9722761c0f4f7e10a5a4d4b65a162086c751d3cf13de2d03db80753c27647e25d4161b4581b67af24c159d7d616a5ceeb76d4d198a024ee59d332b9f0e4109c10356b49b5fd5986b095f489d01e0a628aecf0335c89ffa3180ac5c84d5d72999234b711d4a0df91e0e3551be6cd915f00b4f94577e2c5b5c01e4cf30134b1f48fd28a33eac58b607d8f7568aa4a927132c3988f45c51f0e32d93ec4e167bb81870ea7e5e1b421dbf584e84d31fbcec65e005b3de2c57797109f3b2af0e20c5a2bc11264d633f66d16849a7b51bbf566b153ae5edd3e57afa04e282062c3870323435c813f1d77b78073d9210d72e432c8e57d601391b2b374a4bbe2bd713542350ffaec6fef4a3e14692305c0bddb9611b0511e6f8720eec14b4d80495877a6e77c60f91ce161ef447da033030a0257b3287fec04d3364c262ef280e78f6de5cc88dd3de36889cd6caf0eca78918c5ee886130652bc71219b5a26ad3fbb57625fef276e65408c7d1895f96da22dcd6475955b4a0ea5fe54b697a8c456894b9d5ad6a37736ace2e06216f32c64708b733dfa6e258e35c3ae5a64ecf4764e5e7b0c89969a281f6e105b36b28ee308d976c188de544a8c8335de4ecaf75c9de9defc894ada65141ad181e75d51b795897f425a575bf0589a69987719cc26bb95815eddd8d55c2b684b5dafdcc6a9f453b9dd999c728debdad21abf5de8362ee5e1204e6086aadb52e665bf852e1183f69a002a52403d0a40c9c790627eac3bcdbc471b3badf5c64137065a7489384e16f4f7fa552b5b619eaf972201a903a4a41cd9d954b9ac4cf763321fcf9ef10a09e8e218faeb53543dc54e82742539970c6770c3d0c31d46098dd151b5a77c680fbe76d7c518923093147707feaf8d3771b897d3e4581c446b28d1703721745aca9b83c95d715ea64287b0f2a5654521c228c7b3d1f3ff4a3215f0cb71048f86eca887b2780a04a02da763bfb561405956dd940963434b0ebefffa67d6902afe04e89ae8b7852db2cef3a1ed8d675353dbbbe2f2eae0d7149365287429f0a3c7eec74f8b9d2a6fef0df7175d3a54e842c1d34696eb1427247d13ebf7bcc8d73ba28ef4e579a4e3df5df7d3f8bdb3c1f4b90a6c4ce67ea5817a13d42193981b41b971a32b4c15f4894150d72a98a83cd9c9cb079bb986ad78f403d580243aa974e988677e877bf81336425265e1fb34360faadde0287b994d5ccc88adf669260eb0dae3d448d4f23b9808b4a2e305bd2bf73514e4dbb04628c8aec7322a5d003c9c3019656fb176c170037584211615db1d826ffb13dcfb5cdc9ff8c7f0f64bfada119033a48edd5c827df22504dd1390b2aa045d72121af0f8cb668e5aef0accd6161322b1f226c635219b901a65e2896e217e487546e4d01eb971b53728db090f00aed1bcaa47120af767a5e0d42880ed76840df1bb9130eae68e740b4df1fe37eb7fb7f5a3418b5a5384b517afe82bd23677fe7ffda7e5f90e1450423bf328796d5598f9fcd8ca8da1bdd467f202727569b2f18bea9eeace1dc506d1a6da1e52e97f5c8f82dde1fddf1b4a9df2749289d61500966580bb6c07123dc1fdbd1bac3fc0a5f4e9d3d9088fe23b00c42def541ea207f0197641320783bf6680e117f8a167f0276e415a943739915d7e3f251c04696c2cede4206e248c90218fffd071babc7a6e898e725a1d12bdc1e70112b8e6287eaaf191997ecfb2da2c66155e46e499379386333b8443e253c926d8b9645a6c84387734c99c86f6a640ba324b61296b3457141421643460411e24f615130675897374e6aaafcb39dc3b368ca1c3588f5022ad1254cd1fa9523148fb4935de2049c9a7fad3f210dbbf2c25012fdf20ff9c61e08432f79cafe2b83d1bbb4f7e5a6edb9c38f8e749340d60eebfa558781f59932c75e535d692b2a6b201a1e9e2e16e23368e74180b6245b35721ef378e5669c17621fab01dbc0ddee83e1791c8a699e78075822839d3205dd6167910b378f46bf9cb0d03bfc6f0f3fe987d999fa42ffe7118b826ab1fb33e9a74130843423725d0f3133189b00d57f1c41267883de6fe95387bda8242214d90f5593420500951c5d728898a1dff4b0e87c6e58d668d23ea7edf3c41f68308fe4580a9260bc69b6d517242f9dc5b78b2ec6c23c44f8d09c3e9ae9c28d4b5a5d5dffcb354652daa731470e568b0e767a7c62d7013665f121bde4bd4803a681f872f75f5ed05a2be9f8a467a07132971394e4ab9bf355f29b6ef5c493eb560d059b7dbd144c6af5ec502953a48847f2e4f389e907c221d3f217ac09e98ec8690e777c5bc61a1e534b93dde0ffaa5b943630b6460fdcf3512e95cdca43d0188da4beeb227bba68d9afc5483d02e3b6feda9f3c3f553d473ea130ca3038c0533f3642c162c2ccda143f0aa17edeef5c45da3606a4b73eb090bff791ed65fd5a7f8f48c7d300cac7e9bd4b3a4dcd8f6f1a3f07478a07a196fdd2ccb438b7070ecab69d362b04686429a007911fe5a219d2a98f93e1cd6792df865f9b738ff4bebf06d3e63016440a376a64269598e5c9f128e8095191f0173270402c2b1d8296d707d6baa7ef5b8df6b0d89023ed7db8f740ef68c49d83230ecbc3e84fc3358171d055d9fe81f880a241b78210d87ca5fa45d829ee5fed3727f2b58246c78b061cf0a7c6c7d8d4c1a0fbbeb394e449ed8ddf2e5a39a828e1c5bc3cf219039c7bbedbf2ef36b79d129f24204eac7fd42d25476cd5403a284fc99f852450e4e21e222907dc68d6f21024e71b90af52b4f32df6b9f1b7c1f665adc7e1d536664a6ec0b3005a57cc4781adf717fe1ea7da21a7e7007e4185d519364ab28e35bcfa717601401c8041d78cf284929fc057c918c04c2aa8a12da9282a0bfc8f15c9a23b066fffac6fca655c61f07fff2725d3739a7c199b8ac033aea40bf87f574e49690f18cd32c1579461c819e44d38232f9e651e7518c790c91068a3376f83474dd3c1d89e226965e78d53d4557569e60e900ea5abcf6abf00feb505e89507a27abdf02b4f2b2d97beaa4c1e4b8d0fcbbe3e9fb09dd5d566063ba8a1880a0c4f37b9c854d05779ffb385694b50bfb3912ea07a94e8e75db602bd8bea915b90abeb3c721db27cf3ce5af7ba1f20571cb497c0a527f35e0bbea0510c7fba6e86c92a0a07bb221f4e452217c7817a4b43cef4835a266011ffe58acba33363e7a8890bc62dd334ac2111e000c394af1534e7f2b8b9fe000da5ac1f665b6ceb860d86a7f6cbe65077142db81330afd7ae1c53f00b18ed8a50fa09f0176f52c831bd7753068421ff9034d2a20f229316ada3c1b348bb94d3365348c32456376c8436204befaebaad950a5f199fce80b10256509edcc61b0332beee393748ba64623ccaec3fa547d85e0ed0bf66b18e6cef0fbea187b4b34b87b76ee23ca2530f94bb9beb21b53b88172483a29439cb29dc986516706aa666bb0b2f0ce150c59287100ecbefe71d564c89f660c69e5887c405b49efe0761d0ed0511249349e90ce2a7eb98d8c6c0d0319c2dd7c93e54b7b5980deddf09a4687b3899761264f081f847d5f7cedb33df1c538dae207a6762a0db5be27e17af69df7230c1a889066f9926934cd58a7894cd562f791018786b72d542e66960a0da0f96f57e4f758a36bf5483e8cddcbb3f72146f658bf89f477a36d03c617730d9f62a799da28b0125246d7fc06c0e9fcf15326dca8ffc0e2560c5045adf143f6d30bc864120e123169818a61d4b5f9a2a5acc3e620a5ad21fe165ccbfb6dd5a958471c0ca2fa18c244fdd9a5bed5f2793f140b041ed39ceed13c48e205dc8912d4df3687748e1752baeb34f7b9b9b6857e53f8abf894bcf2f19e1b3b7cd97fa0dccebff434220f0f059c422601f1235b89e8c714cb7c56f63bfa321cdbfbf59e9524ac2fde07d16473fd94b1b4d9a00bd07a065ebb16145c3ae61b2ac00541eb05745e80feabcc2d651e5d769b4ba4387abb37b01a275b52113a6cb260e9f653aec7d5f7a560202da06e84c62560290d853328dcfcf90815292780152f1301ad1976fb4196ecc8f074afee6c317c70b9fb3ad0eae11d0da5633aeed908d5924d02925c67e3837c0c85386910be9d20ee15d1663cda626ab43422a86923f6cc27610a2e97c4a0dd13e354f74ee07f0ab620b23cd911b51a299b90cc460b2c28f6e718522b82dae059c390d967ff666dae18db77114d6eefd6d40847c7d4650853cb7ac0bd3f3389ec1115366390d842b5576d350321dc0705f17987b4e725548df859b85781b846c6322181262a7b003c7bc7623fcf631e3533956ec01ec10c90e94c7358625f74504a37da9d1f980b23ee57036688510f3aa1be964463001fa0dd528864c1ef0828e2f2cfd3f4c64a75e220763dc7185c2d1118b5917a03997a1726e3281c3b4721fd61068288f96d07a625b220a0e398c5e7096c11dff077c2ee326bd177493779f2df2a909af381df8e3b1ae5150a1f274ab6ef2fa65714e88ef7a299e4008095e665e9590390d72cdda1ce9605ffdcbd663ba01dc39d7030d59173d05ac1c5b0d884a99f083a9102073cbc0b6a27c54915d0c1344432933536741d53369b919886b91a2c63deaea1f669c0c6f6afcc7826876626efc10a464a5270e21a1261f26538c8ed8571457ba13d3cdb09afc4d951beaef444827730329322edc094da79441395f1cc017c8dc6190ec90cc41ae6ced2d1032edea3d32b8bd7a6963055a9d67ec0599bbbc6eb6df6f362ff7c214be010869f2f4fc557da8794d237f491bab4312c12c4420ba39e69be0872cc9848a080ac13bba4a621bfbfc0d8083f28dddefcfc759ba4a2ddd11902cf228667136c28fa38441e0cbb974269ffe79304f47c24515fda6914c7f63612741d4e368d9fdf22fe7eb584c388d4ce6edf0ac4ede97fe78c8f446a4af9d5789078f902980108b902933936e071a66a7d386a1a975ed54a86839228a711986597b78917a996e1194b18dd05621f714119c00b2d30b60e01a23a9e1d8c134cd2596e4ae9667123526241e4654c1f90c73d71365ffc9424b9c667bfe0d136a62886643a7a930438d8591e433ea0b06d1f6e0d025d206ea1e32c3eb72a69c0ddb9b0a87fa527552c9687c50a214cca75bf64d9263712a2e9338db7a927331bd68eebbf61b0040492b0033ed5277b0387ac55bf135bc243a5f315dea3d45876619f297dbb633e37f0491c4fc45111bd2741b389b393567765f415463a8686b94c1c48cea8da04b1594519f97cfaa76f8bb09f3a64358d4c120221c15a53b392ac43e0949e83748f47ef46d9af802499d208f09d4929a6750cc410d9cb54b4d111c59c72710c8d3075a5e0242b2f9e92b03e8e23cf227bea7d2ca26325d13ab82219d8c478f1f80318d7b68d0bf1415038df1bedfd996ddc3fe6ca5e9467a571a46a0d8662accac6847ef0d475107af5bcb9ff194439e69dc440a1304c9a11534317f52267e96ee6d0f9837b9d16684396ba50e3b7cf72b8ca69f2675f130d438b51fed5308cdcbf584b1e3649b5af7e71887d877d034e2746bb9f43c5ff70d0028be37b322dd383614b732e46758861953eab085cff667b4fb4195e675f5a7b475e97b2c76a38eaac0d2c8325c777556e854df88c57ba838bb34c2c6d018be9646dac088e8eb385369bf168b2fefaf9449c9feb556f24ed61499f96c5803068bb16cb3bfe1887fda240a5d85f646f6adfa1a585c55c4e0b2aa85abc5d5600deafaae54b788aa7088f97d13ec39c9cf12dd5626d7c85afc78a799e9e8fa1b881e85c3d273f3f3b48e2a859726b49323c9634282a3eb7381c8510d7a7703d965532431dcfa3615cfffdd00af44063473ccd2d7e0a64461d09974730da699a0df91eb50208b91eb0e34c6cac925776277d38621de99e22a2e560853d95ddf7d8d45e2a9cd8324bb79b159c60b5a9808e2e4e2e62140c60f29b270e19c62e26d8304bedecfc7e900172e0d1300d5d2a6091cac14ba7ab7bd7ebea9ad15faa5601a96cd4a859753511d22916e04f82fd8454bca285b9fc06facf4fcce015d2c3d0d7e91265cb30d7ce14041be4677db40d1dba8efabe157e2beafd2601927e95aa447db9b36fed6eb0b4d9faa84bb9ec642da598d01290b13b3c2509e86036e2769e6a28c6915dae03d9c0ee6e5f6cd2af10ccde8c9eee4c84c2e0b0064605792660e8aba35da0c4b84c1f21c832d184380b5258df913caf3791cc30f21b7455390cf142303d634f3c4f1c12bcceb108c85c4ada4ffc2f02384e50636163b2cf2714a3fcd3ec9beca48a3af0474331d42d122595b52979c047e96d987d3e71b8e536ada819b0dd4ea6d1b6844583473d950a3c92cd27fcfdc366dd21a3a4d6d8463e0ec28368d8e436eb7fc758db9f94b45c5264e962a1bf6beee73d6dad567dd98a4f5564885de589c41e3dfbf7fea32ab270c202cb0857d7c71c6408b6219d795e731910f0aa012cb22a2efcb23482f0bdfe2803875261f1f20f1f56c432b548b2b6d4691d22143927dda9e52ba38ae9698ce6fbd0d0b0b72b18ef701698223a6a9dd5ced7ff4f601aa1a8a5d9e024dcc308e93c51f9c0d8ecb212d48d13fcde8d2ac6ca708939c783cc00114ccb66581932eda29db19b0d30123399033ba3b201c2bc2c655e65812d3e3ddca3fdad75a483d6e2df1cf90bcb1c13fe58b31b6662b9c56e64ac07f32fdd5dbbf72b166a19f8c8de2e722f18cef6eb26e2be6612e9ab62f740104ad3e0dcdc6673a5f87fb772562deedd558aa78f5ddf7b16a63621bc65a196337d2409f310a7a1a344577eb24d2cacda99f4de37300fdc0416ea4f34ccad764ea104459bb9cd45f2bc17063e6c9099a553ab4e32d114601cf870b6be3aca7a654d4a02adf8024fec40120fe2e2beb27518ab7873cbb887581f0155a263242b3beaf434e7f1dce39367aa06eedb3ca0648e4dc78520ecb228fe3111d12ab9dbd5b5a751f74ca3dfd2e0ead7b73b65fddadef28d5055f7b02f56e73151061f909ec6414e9920eaca2ec21032ff6d7cff954f5cbbcc6e7f8ddd8421c08621f09477a3114b35b492ed56fd6b6bde88277846f0c0f3e878c0f2bcd4fcf7e26ad9c993a8a534ac49d89c97e58904b686e839f36cb535313427511d30ba21eb5e36cb5d4db7c9d984173f25513eff0c8a579609e5a542ce65b02768af4a399a9cd3fc523d8c2cb6037ff05d84f7d0e7ed1033e77670b7bf6e5d67922f120eded0b36b944495e9347f5ff415955d13fc12b6e1e8b8fd7d4d970466868435c241b64744d4677e1380c615ce1a2081f26a7480592d8bcd83fb2e9ac6c75b64b0a30dc1c68f2df9915f62a46af6ce5fb97364a5ad2817c5922c42162a9c10d299876e6b53ff307cacf8d9d0e0f9f7dfa3c93c4aafc6cdd81a2b15ae06e42e1adeffbcc14ce2515f95dd0b9d5c56f0de3e162e5c3e8be13d27e9412e93cda26cec390bd60b526b0b5688dbd2e116347f1e1e04b0b0ed936a51ce88a60114d584a53a56b9f3adde9b32d962174087994a5d64f4cb8e9aa3936f96d0477a25e2b095f4226d0bdd724cf094bbc67c94d6c38e8b81296621c4af70231663300fbf074668f35a74cbbc76bc1a99633df0522cd76b34e0f66a75d61a1ebebac534f4105649787c0324be02de9fbea61e9bd9f4abd91e4e4718203d76e8401001940639814169c612b8d0d16856bc8421a57503359c2c8bb386b0dbf1e405fc98310f249d1ee4866ea4bccbdc36da6b5a54483b6dcd652d9f287e38a5e6eccdceba8decf92441686112f2fae3d3e26166c2d24de76f97adc206775ee2cc450e2628dff2668a6d5803b4ff1071ae4c96285bae4b511331f69229b5f98cc71eaa5d07bbda0f0143b666e4abbccec2ce819088acad633f30a7591dcb7d0d2015c70f0f0382bd4d4345c393ca1756c91bc1704147e09eca729c5c04cc2c60be4ba09e7dcc7a8885955cf13e1fd22f0d1ca96a5c7be67a3352f8e41ddef64f46df9dad730d97ca17a14d60833487acf79f97e4e6d12266e195ee7140762a0bfe89afaa55264ab500d082abd4c9529008a584b9e9328eaa51eb7be7ed591c783c3c4a5183246aee5f0f9d1eeb3ef410158b189877b6101544f0fa02eb5452ff94678868cdf9eb6232283ad24e0dd63a05e57c70bffb78fc8902b9e9e3eb3dbca13ebfc87b38e59ec5b3b516f74951f40ac5f35b1ea4fc7f78ba11f95e521801e139d274e7aa4e229f3ce9cc3e265245e45682f8a64bc56c3f536d501565dba7b8130aafe659da21fe089cf83c2356c8edf63b650e92e58eba0d1033a6bfbc1870d0f55a0dda721a6712cb9bb62f55e67e7befe6f66a5f9e1e39aac5390bdfb4e79a179e09afa326eadb7caff209bc4c24a4b84f9cee9fd053cad460bd51f6908e68dc0ba0692bc950f8e3bb5469b18767ae8ba1048fb07847175599adbe82f090f065fc826591c0e5ee3e2ee596a4ae55d2884131c94bb6e91f0c4a6ba35edd7685df59eb6cb87fe031019c3473b1cd904ec96428b64e11cf553b1c636f36e07af4e1abab1abf526ab54198e6c2b7e42d7ad5b44acf5cb43437b769cf0fe8e9b88cc28d707aa8627b1ee13bfabdc07e4751625afb700146fbc2b22364299539460b29f9b1990cddd78e16254042111830ddeb8526583f96e266811c757c517196b40fdce2ae527f49aefd74dd5104ebb9575db5f03f980dc975e2046ca06079c2aca6b40bc0fa0f351885f23acd70ea12125981a7c16c0124f56413055bc815d7a0b129ff66ecda7cd29da7291235f9c35b8a50f0120a5da9203e250dac82e4360bd6a4259836eab7412bfc2a02c9953f45ca98323fe83492f405005e8bfa96cffb298c286d9d23ac4ddcec4e3e4806c9960278eb77fe7b68a140e2f562ba4a212a3e13a7c75f55e78e8f66474180f31d1517ef561b2c14086d4960ca65e31a825695858d6b68806e71ec1f650a28867d06bc70b4cc40f9de893ca6d656e7c9837a875c95ad05aa760a0cb483a8ecd3d78bf31d22bee815589b95d251e1aa52f9692153afedc5d993fd86841128e53ae4ecc24f419356fcc32bd66277e4e6ad918ae8b1d06a1219876459327e4592bc804c7e826ac768a9aa9059a1ede9da95e66852cbada9f0ace6b41cd991f8e982f3dea29e1cd02750a0701a8747482d1c8fbf9f56ef75ad9f2434c6acdf7879885118a003f44282cb18dc04f83c51e517ed3f3bd2e5d4d409f62d78dff76e4a93457a99ea0484e3bf10578e361e40826a50156e6aee9d0780b0f105a45977ddc0c3796d659f51b156f1a0264a966e39ff1b129177464974a89c72da9a7d263660205cef6092df9d8a43700bf52c3c9d950b22460d3ab9d4f4871f2f94804d07279cd0a4753d9fa7ce9517b9c18807cd8fe48776ff73276b6f59c48a070c1448f73a60ace06f95504e2a36a5eae2403ddabd707299982cb323f417e371049578cc87f61573b09ac91d6d8ac8f41eaf48ca4bd53a52418194b90621fecbdf3caffa39c3ccb9b59451162e21049bd0caab6cee485d417ba39d519a1b51770173f90c64a2f15cd6da599c3d0291721dab826fcf1f0c0bec74efc2db3e81ae1096aa786e6a542e20435c7a3694d2c1ab3748531b7642baef4cb7d7633029f70ec50a6c0d6ff09c6af571fde812b9a77eeac049a4a0bc2d33b004411f43801f275678e2e52df3dd5f2ca5d789585a447a31cdbd4088276f926643fc6b20024b10bf8aa1044b048e788c4feb2a6cf5fdb94a4500debf1b8994f753067a210c3cc3d2ed148822010a2100ee454c4c5b179a2e153aa3dcb0a0614bf7f99d046f71de6d4c4d86053da7c85f035bf4e69cb2513456ba2b9c623d116378a081acdd72f602268071d5f18ec94ccb5011855e52595fd32ebdaf14db32041bec6a3553ca40e9ca956b6bad3f40842d84d1bdb5e6e13ac45c68a15ebcca1eada38437b072711d658be9dde64421d92acb230ef58eee793e622017fde2093bd4af7365a39722c997ff214d0762e19e7c3b5336f7d378831b3d7989a60761ae2417b5f0eb18b484083b3920f0e7e22dc2de61ec8f3250a2c2c2f256a4d967db5287502d9c99fb6e591cc58d17fbd5355fd3a875f38f0204e8ca1b049c4df68ef2ddf78a0912d8cc93b1b158e59ec09f7c4a9d99562d11a1e910edd480dc7042f2ad5bb23c7cf5bfd5093df5425699db554eab6db8b32dd2fd1af7103dab013c6c9dcce5429109fc62f1ec0a5efcc916372beadc25728ccdb680f4fb2a3c1c19647dabe3b5e5d6537ffd2d5111753df14f37674fa001771b21cb6df07f94ea48ae92a059310da2e477ce6b5993f9d5b01ada7ebe501a6ba9048980f5ef02e3da717483878bf93895554d3874dee0a1e2a29550f67e63e1e9902f1b969979f3466b7ec5fd59f657cf6cc400fc1c4d6fa19fcbd9eb9e6e3206e0df7bdd2ddceb89ed33895c8feb54286b67ea20f5abaccfec3d0d394d2300d2ad49d64616b1791a283dd00384c3aa71762da4262266e380dd242908391ce092807a72f738bf8d68e18c6154dddcdaf487075b02de252e96feb9aa187bad735b492562a5ce237810b26c14aab13130653bf593f4d7dce0d3e2d2390af49a8db4ff4a575a6868e8d5710b843a81dc7bd4455ac9241f6ad4f9d7d80d9f6435c1b91ce8ab11505b91edcaa2920fc50aa1df4b55f4e9f75a686016337d11e3b8050fcf192cca5efc8021e8d1671fab935fd8ab0cabbc91f9eae0d7bb072733362f04df8998b67f8e8cdf9a8bc99736d1c68e8cc2e55087a3e0a7f6bd41e7a72829094d8fc42d2c32a85c1a262fe698695756ece5d0a78d1b55703689c7ea435503b06f5c7902112ba8e03d2d89baa763d27f4fb08c78b4a349706122ae7c0754646413dfd8d468fa69603ca202eb4fd65a35f685578586bcb2a3a937f34c6f52adda6a4aba293fc5fff0f75e33cff034914319da9e1b409283a2fb0dc1fde1418ae97da23722420648400d64894ebaeb5cbad56c54675b1341c55eeb977f8c64838ea8eee69d50954090823a84f6e5d30f2e1a2763257850ad5a41b419d81ccc8337f175aae672ab7430cbee0056f0615f2217df512e63e38538af9c583b21ea0137b2b180126661bf96cc1bfe09b2f9c99b6886532b07f1f95da8c5fcb3d9866bd44937eff64ceb250fd49396a4a9ef5b867571f8150b2c79de83643fc5aa3500164d89e7f5c8f13397d1638e2ee69be777868e5c71144850c534a6cf760937c1ca8e501a49e4e49f0169506dd008a18a2328e6b618ef92b47fbed7fa5512b1a006a7d3ed6238347b78f8e5f60487fd2e140cdfe836b9b4fb909f695db90b0348908ebf1f2f092341a42e73bb1a2d716e48c4b5e51dcc82be37a16dc3d509124fa7834d1d9458d4aba458eddbe276e56ad046855784d21e26897c6f0e6623a49d30472cf39501a08971565007da6ff57820309f2440e627fb0cff1055747592ffcd8e102bd76573f3e556556ec692a71bed7863a288465b87f3cd76c24b1251e709092162d833ff796475f59f9dbcdf52567fa10c92d6a91ae0f626e8d616b3c65fdf5b91ee2023c14bfa00f99f369401fe8b49cf962973cd1fe3565029c4c4718482ccdf1207435e0cb27cbf3298c8cdeb64b8e74be6e81d671e30ca10281e5560c9bbcc2c0ca645f80106285ad8dc33fbf4293926925401f6f03b4d9acda834f69b9352c6e7db89b11067ac70c402aef9a7be720ca1e33fe938ae4fe9cdcc37e2b87e8450824c9a1c669c96427cb549a2a268b8d878a3563d0f97cd1aceb3ae1afcf29f5fee6e71e541d35174aede6423d4c4d88f7a271ade1b9a243142caa4a4f1cd1c7bc5d5c245fa1b9dde5fea83db56508419e99045d5c9abaa1e4ad1e5e419c7623ca0b17fe4d4ccf06a5193cc5745c21c819130c44e7648a56296aff0c77f66b057af71b5fafd76fa5c381466bee1a2dcef3a8f57f8fec6d104d38cc827835d5fc6b8fdae63425b5d03a86e0a30cb7635fdd9382a8e7b16918e5c821840579516426bfb50a59986eb638820aebd9683d78ab793825d21032b3cd7e797d5d163b9a271d1f5055966c51b4bbc49862ab2d79dc596b1b7805cadd44cfc213d518ab3b6a6b1fa2c918095f5bd0e56412e4eea433f2a5495a744a67b443287bd7b55a67eae467e9a207a55753559ac7728f3b310ea5ed66758932697e70f9033f7e4a6be8611b07bfdf3dfaaca6233136088fb9c974c4e7181d086bdb924bed9d661ef031604694311ae09eeba5dcfba63247d213adc87eb4b1220ce7e26c684b600d09d8af56b80ac9622c3c3eb4d653b1a83a3e64177f5786f4ee527933650a0f9ad4c0ba4a46c9cf5c44ec78424e5bea468565e9f6a8837506c0bc45664373bc7ebba718a89d390ef3686ab5512661689f6984874c6e8806d3a37bc1392dac933ac36f92c1a7b5c2e43a784d18dd3df35b8393e0cd9abd854e66daa4f79457bb9d99e6042f628bb6c33dd28899b6444d6f0d31b047256e786fa8bed6d01b003b8a86d671ccefe3862c23f8f47280ddf195aff64e22dc00acda7c5215144fd63fb8bd95685526b3f1bfb0462df231a622a6ba9845489f9ef2eab6eddcfb83b4da2fcdaa06be739a9ffd596eba984b50acb8d518b464993c5584b1f5451be3dc71fe9c3a0d52dee5db38debc78b053c535c4c09b9e11801a40fd2ab53de3125930c70a9c4aea6df266973dfea2b27bfdf8178edf97e27c252afa481ae7aaadc3796e4bcee14784f4b45749b65d73531e5a5acc561ded12ce95ae887dd205cea500657170a4e70125934f0eb682ec9a515c591092f61f9af900142c6469ee31a84ae7a44ff46a39089a98c2c201c66e56eba128e7d7dcd6042e1bd76eafb6f49a597b153aa84cde6b890e1e5e11110e4c1caac4a82fa5c2dfebf5247ed1001dbb14a629769d08631d131cdc933b75a2d6947199a32ec9cf624e492cc4bf8357763d2fc4a2011366f1fcab878bd1e61704fb7e67f0d61673b7a876434a13933d4625b9b7d8f7f3e1f01cab007e6e7afc19cc8ba4124c182b0a5a8a59063c538ae2f0197b0bc687a8e95b0ad23b09720b8b189dd72318635444a554a2e6fec19aff4d31fa9fd9a3b8554a31527ecb89037ef9b22496ba2a9635ba60eca7042b24f546eca409ebb74c14ff71fedf5b4d0a05d897d0afe5c0c234d628c4765a2d740a919c1786a075f49873337c5200ae30e0fde794368d698ed6d8f4b5eb99be2db682949eaeaa8d380824d29537d26b33b8f58bd0aa83ecd952282d4bf2d9e1264bd5be7040c035da1373b9cc7fa9704c28e0b41bebc8f894554da52027b2b4794fc751ec48b597c963f9c98ac072b13d362f9df446a3cc62bfeb07cc03dde47aa1965f79e7465a0019d9efb650a91766a68dc989cd46b6992262092621cd0b82a4602101b0dbb71892a2621d1341740a6c77b5bc30259672434d7cee2b9b41c65d23dbafce11cda2c23cc27f08240e68339d281ed038b855e9104a9542534e8dda73401cda3a45e0962488090344e961461f856e4a65b46aa0cfff510cf9ca7c8f838a632b60e7d089c3e010b202cc10df03428022ab9a4c9304efe73a7d8e750b96952cc8abc8df287d46d2ef404fb679b565c18f9f80d58d8722f525623a914eaa5a8d44301dabd4d9c945f28276ccbcbfe6c429850dfdfde49feb86a9d73043202f5d2bc3fdf961d4c9b3cd84b1ad06f79aea01508b07ca3a678e3b71afb1389d13f886126b6ef4408fd631c2f84bf7c85c35a1a13650c847e56618ebc7cf8ba8bcc8f402cf8f54b645d336beb64484bc69a27996ae34cdcbb99968f491a73fbaf19c74813de8edde5e51b987d230b7920b20d78a1363adf6ac51b20c72162cb8ee485e17b4030a7b59de2376da5bca9a20e915535a69574b4637522b95eff3944c8836320d8d1f5e42b4adbd58084720b053f9067e60e609f532778543b127d0afbb035b45bb9178ef25c404354b070c48bb6d906caf69872825c1dc7464ea77c53d5da0a236d39b5cf824aad206d88632a03047a94c5f3a2638cbe3dda9f92c0fe0a833a37b3b5eea10e8e6e2743231e59a30f0191d7a4786c828005dd4b2fe35eec7ca3eec9dd62318913d9a678f127e3e19fec0f493c536097a68e2203903b9a055be48dbfe87168fa06c6328372723beeb1a40cbbe3bea04baa011e5696ce8b1f72039d4e0642ae127870a00f3b00dd9e4d12ad7ba7bba075f6e4915c5f5397723945410d42f678adb529b892c487ace9b00a34558477ad09cd49be978bff2b5732ce376e2b6d24ae06d8bb25d8c196f141d06eba49e8e459856aa1d6731e2f953e31a45d0c992c4dad37ba60d8f24c8a2a19ba2cec4c981e10016407072a53b57f6810638f42c282ff254e22492165ab2dc2733ef340333cb923e7f789ba1af5eb79fea8101f1ebee07b8dc6949354b21abefb68cddda82c6f1dbddeb7b80a9d77b27ca26be032a69fbcdb2f88086788e1c14d15e31c3de79da7ab069a36dc537dda21024b2206df4ce3c00e35cd7c1d25998ef2da5d696997ca34a66c61e0a10e386f58e7fd14d7632eb0cdad0796b9a67010b13c575c30f587e30cd38aa468dca8823d780d02ef0b19c9668c667595b7dcac01c8e4e3c1f070115a53e62c5821ec2e7d3c7ca3235eee0a9b6519c292b3aad76e6cd36c354665abf8e3e8c46d1992f6067321a3e1f08c4d756b479695efb784b134fd45dd98414422029690716c980804972389a3e5e3852085cb42fc60db88d46dca9e520f4464082f8112e2feffd24d8c898bcbfc682e7f881c97322cd6f21352824f27bb827e812d76cb7397213c006732edd50fccfe8e1c759fdd6040fd658be4d296be8df8f6d44f4418cfc316c6cdbbb3a6a234cfccda68bfe2252170e8af45f30760c4900eb34da5fc900c9e04dc51daaf29e419ec5a87d5564b4f299fb799bbaba563a39ba441a810031c88725162f1da726de7872fafc58acfe2cc8ba764a94cbd34d7cd6e407345d3dbbd2202513caf9a67145716df5251ae957d120f6b77b8371bbd4e0353ae4793fb22a8a4ea5a12a9d31bfc8a812cb6c0dd78ff8710ed9b0d38b236d3655a07326aa259da4a41dc0ca08f08a6ff05e8bcb868bac4714bee8ef05ef7251a73945dabbd032aa46bdbbfaeb07f95477c45dab147ef8dedf42ddbf0238e3865892e3dc0bdaf91fab12217a8f41de1753b5fe8d62ba34d03ad7c898e4ce82c58b2a23870c0fe8896494773ba06ac0359c175b1c6ec1675ce522c945a4d512554383a7237a07e5883751de242482a8f1e0908cd77071ea397ac54a964f480317659f54ac15a46605e3986289327dccfd46702ef046031fc8c2a3e4f06b62c6616461105625e7888b521f3e4156bbdbe74cf92901ad94dbd5cf4e945fb3393feb99a96ad7e50e352cbf72e4a0cf8d4c98a6f5fec2d62d6d0c06e333e19f7e68905a133d7757abf4934eb179e045ff1481aec381427d7052b147a867091e431a61f0e81b77f723420847830b1bd9b7f51fb9aba44956b64823daf9e4ab20f2400ccceea1cc722c26abd4c53bb1d0754901ccdca8326671ec2484037ea2d98b44f49f3060a9124d172ba834852c04b2f4d04d7467c6e02e24ba8fb2f11138d24ca3022e0b7649ee17b382f84ef5f29025eb09c9a729a3c5b7186f6171359865ddffe566dbff8d3f72f0690290c4981f4be8b700899ef1b2aba064c7ae14cf8a319c32a6c48b2bcc4ded441062a1dc03f395282b26e7a89b18997dc1626ca9ad718ed5f086979312385417630ead4407b0ab01274a197f0a77c02fb67670b09c0f82e14278f852c284030a415b52be764c94c5e8c825a02cd42fcd3f701d8eccda48e7378defa04f54843bac5c47c857c6bb1365365cc459be960b1d653de83a7dac5692dc19dd7f8e5f7c227a5270be254d824822a45aaf7d35b4cc9f38b90b047c069422c1927e33688905811bf4c2608286d65fe5293652424b917191df9e27b0207bc4fdad3f8d1969c1538884ea65760c541dcbdf406e77bc34421fd9e0fcad0af2dfbbeaa522a7c49f7295cce4afb075549837fd5751caa7a76383282e5680511af94073e47bd4f7a7bd76df4179297562e8232e38bf207c8d6c243185442e5a7d1e0234901c8b28a2143092beb8c931e33b924146b20ad95ee291bdce543dd035d91797b214565b6e750c378fc67a87072b463590d28eb50a3f511de5b690a1256146a54b82987973999c904211b482e6e432adcc01b567a2f817d4efdaae0f1c1f621dd5f118124cb739bc5d3051faff252d370e23b970729c2ce219108e37f0516f6c32f642069843f098b47f5ddb5db7c1e556b60136834c0a47016fd569c64d40e9875ae1360a7747920c9daff2000c67f0c0356f6bfc1d4fd23d53e02e3b4b86c458ebec56de9089286ba61f00faffccb92eb4f801f9489334ebfbab2f8d93fa2c849553782f46928102663c11227ac7eb39e47298862c487b2c42b524e39f4e16dc4ae46504dbc73ffa10778e71a96b8e10556efa8080f3748729152d1e28ea322f4200e222edc73ec3f60370b988a5df17980b8b638e5a3243d290b71a958ff54f34772a239b1ce89c19664ccb6982c14fe47d0bf14cad99c5f4db15596ee86d6cf28058d569bc29cbca0aed3e1280bc2557304e5b847adbba209b0807b2913f708f9a66b4c98b0095e4d6c4890559604e385fb68c49f872734b3b4b7335c853ab4ba3451b7054948a25b6bc854ec3a5e09e527d6afc0bc177b63b8ea7f1f6ab0c0fa82e7f3285db3f8f430cc7fdd3c944ebcf000d664cd5becd2912675491379bfa9687a011bb7c22a03a03c1ad8dbd66e18af3c70affd5b7e62412f09951390a1141226f67800ca2d5423fb998d4efa746a2a6e16ac17a3992dd74422b51bb26807cf4b0186cb42034483de875855b6df16493ded317cc418271ed0b7bfaef13272dca1c624df8bc1302a11037cbf4a5ea620e63b618c7a3287f902960109b902913961208f4d3e5e656d880cf2057bed48c7a60647323d559dbbbcd63efdefcf4397e2a6510ddfe4380f57f3ac9b45899d2ac9dc3a10a69c1f7c4a61565ad3659b554bdd9ec44ac75b43087732b561681719ce65a3e1333c6bef9bfd9a287b56a0d71b9e06c91767b588aacadd7267bf5ca2b8fbd0d831ccd5bdc480c9304dd2e324b44f1143275b532b84b611d2fa90433357894b1eb65abe54dca3cfdbdfc78964155be6e975365dd640bcb617c4450d36def581e18a25a5f6ec217b5954858d555fe6ef9654d8e766c5f6d32b7c7432b0c725dd16c118d210ff9f52d1d4e962f09af6a547d4992810dc52192630c40a0efaba4ebc0a7a4e9c96240074e0ca7add77a62331a1b4f22250165460946fe7a7b66aa62c7708f2f87e37d841304a56275b91b5eaa9c487fd25a166335f680703b7ee91ead8113e9d13642a25a6d595cd4ff3f73146e6068ca74825707847db05bdd041d44e8aafa8216bc94781eb10ee3f61e3c98b5a37ce614a564b0abc558b644dd7c945d07f8e78628a42ade19edd230e491f395be78a2914d0da632ec20372df351bb9172234c434bf0d1eb21b969d47be973962c66e762da753992dab4ad83d5e63cfa492c1f82aa1475899398c50d862d5037904f526f525e32317f3218a67f72059a428b411428118e9d33c6c5c8da7277a8f277ead826663e4b19bd28547eb665c333f94ffa87ddc4f752571b124d589cc31ec4b4267e3cabee3507b1c89ccaa1e85325c29430a5f3b25b69f1a65364d2a1ad8e289d13d4d48fc620ed81134a0bf76d8a72d56a2f2f4c9eb86d6cd725b58a383cff3517165948d5bb53a78d3b44b10466611ca4819c326ba78ad7966dba9825bbe5689adf23ddb44709a46b500270ec40d5d7a522e55386b60d817ae1a31d9f57b49ba805e964f4e0df91eb50209b91eb046063cc0655327c065a26be62788fb577ae545398f2bafaef751c08e709a3f016a4d45e95cca0899e67901597df6c037b88f8e5716cc0587eec4794473ee691c5e3af4596e472bbb947d30caeae356fc0299af90fca7fa85506dcb6fc4b143e21d61db793d680ee1cd014746b538dcee4cdcf6b709afcf7e318e837b146fa1f737634b43c29c3f1703ddc1c18cf043c7f23d34db6e377425acf0d22554a4787550e7dcab717489808f696a104c03f35f51d7b4b2aafbf0d07e48bd9312b4a33347b33264bc06fcb2b2f7497d6b89e721b8401d3c24667f4fc8a5aabf4baaf18fadc5a28377a6bc811752c731d2515e569e745132e28c56e80e325b119de502bdbace9ba5d8be37393544eba41efa473646a2bb404a048dcde4e39d5e97edd830fd77f29bbabc91b84bfae35cd3d34297a5a4bd0b9d916bbcbb940c78b141fe3f0d36d09bd1796628780eab6849c75570b3d35cb15f32e9fda5972231454c2b8107c02b2ca1e5c7f60b1d6c9917ceef53b3f0b4ae3aa13a9c9e8b99918511238a9b4f9da2f25d2e5195ba14cd25f2a4169dae0d26925a04389fb40b66ec6c05fd11b1e28f9e73390e1494ba1f2c692c4f33964cc022e67e47d8cd80c2b72541fb5baff8dabc135099e0775e5e7f1d0112e49cb3c30096934c8e087d2843b2e68d0a2c892a22af0b147fa123f325097f4ee006b8a01bd569f1e6f7fbb1fd45abad5bc324894bbf48b5d8434e1b8bbaea9eec00e06734d429028b6f90d8a0db0222a40f860f9ada8a14cca3754bb03107ce22e3ee32a8a3a382413ec8c292fcbad2de88659580a65b238990dd98633cd111d05ed95fa8e077f2cc3e298954724b6cb379d33c46abab74a82ddabfe93e74997a4cba03b682566529b9c9b6539b588317cfe10cc21f837a63956fc52e228a0e8aea18ca68289e6d7313ea6da9e2debd280fecfa178ae2e40ac9d340f43ccab00f392dd990a98279d427957c3ebb6e48b40379026fb853302d5f3a5bd974c40504ffcd2394493dedd6fd2dbb0b5fcd4ed92ccf5c056017885e0eae64690ea86995eab9bd81b07ef283bc52f98f01b1b037c8cd3026b13b5620750487fa8486b758ff95568fb3d70c98efed1264cfb878efed99733d4f657c36cf082cf883bd48930d11ee73df2aca4be5c4e6bc30b0ddbcbf86baff874252e04aeb2d4fa46b550af87a179b556da8c8f479fd510f48fb8094aff99b50a5a3400f16928b167174bcfc37231158eb0394f30d94be83cba6e6b6440b38be08b9b0b60900af06afcdbc39701446e21a2fbbafff18ec30985acc3ed3864f6afd864a7e8dd406378a6f050732e503bd6c3cb7edc2df4c3802a7a8e0d322e1cb81f76bec5e162b52433fe7ce19160c9624af3ec20b8c20f8d3f0387c55986cebca92a5d93dfa6561582c7832a9d349fc7ebc180572dabce18f6ae362e2359e51b94420a2fa44b7f72d32b0fce49a01c8b15ce8a16d720bd0991554eb4a67cd3910956399b28a85a0f2ccf95f5ea5ccba19462808244877dea1f95c1f9e3c9b09fced694d7ce3fdbd6a4cad7443c56996273b0c8c52252065ae50627174cce93b4b0c218c5776a4cd2bb1f8c2747be2ed3f0b94cee0db4fff0209695875bd06e61c286ba0deca5300dd13205dd908aa8f9fbfbdf2cc2f056fdd51f9effab91fc6d539f7ad60c971c160868b6372a9a4c06bac809fe751b60f0ef1afce10544872bd8db5b33f20a6c61a9907868989155cd8152e6a632543453c1912923c7188b72b0380ec178ae7068347e468de126521abbbf5932d109e8ab775f525e95033534034d1379c7197e37a0e8e950bd68f28baf4afd79d1497fa90455c6bcd714e4350c6dce13376d3dfbdeb26ca69abd72a5c72b56cd99dc2723dfaaca5746e636416c8dad4c2703b30b8d7e6451cf24abc56ea5b584f8a4f1969a4bd57acf3f4941ccdc287489646edfa63a64f0792af51e4fe0c1932f6bef594bcf9ff3cbc4aa8cfb9fa65a3e85ccaba6194331d112b6fb7b02a5b6918ec55c46c4bbe3b6d290b18859c8d101aad92e23c1a1484e3d5d59b4dd5bf7420c7541616f9d88e47b84ae1b63b1aa8f4cb8b7d448e959e7ae3f93821119dd3aba7ac2a7378b4d208a2ac155398075c60947cdb894fa615d050bfe477912f8a7238b6d86673d550eb8e46ccd9280eae91a03a5a512b49c4d40f62e061fd1472ba5877b69e8437457c49f9a35344cfac6244b85bd5516fee745b7707f307a4604dc8c76752c4b50e6ecf9b522cee1e6b87f1387b69297f70ec925a6c860ecd905030499e730ff8011b1d2da6ab4941ec3513d6d5447ddfca4bfc2cedadc9af013c737667fc023f5a685d9328443f66c35fcf888a1d32afa7a2f56136c1fff02cc1f32a18b7b1868c4085cbb106f2b4fcc058f9af5ea2ca2c23a86ae150c42925e6daab4657b1893d0dc0bb0426590a6c207a81e47277c69e01632c6fcba9cb8883c89b429a59991044d59e21fa2d9cb7e45560f8d606663344eb5af0c4d0bf309d6fbd9d8acf699e8960cd5fd2438a05ff37ed14962b0a481926f353ef9aa27a9ed78e8f4bd47d70df06bfca70cf881039c01e31d4d86b1b6ae35555e3d7eab5f35d20da62c4bb55a794f6a0d9a3fdf5fe0b2c7f4bc1e5a537508cbce059660edab3f1d96f89d9483eb6cdcb8ed5ddd54a9db5da571dda2a9fdbf9be1cda62dffe68886d7e22ffcf10f50745a7e9d6e0f61433f0c9473aedb6e6eb29c357464ebdb2091b323bbf8fa8fddb1f04d359e65321bc0973782bcc3fde4db0f3ec17c6d01c32e36b766a0a6afcc59f3fb61ffd99b23e48c13a5728ea3d94ee39d547cb5a0f2e8dd89853e9c5147b424bdd055af39699dda5705a79077836860dc3181bdba01ed39ca722029c72903b7fd2106aa6b6df5ac3eb7b727b17f0533356fae330e035ee86031a70cf4e4c776cf39185b20e760a6553354b6124a65f88e7b4cedb70d4ec52b43a89a936e8ebfc577eaa60fc080e7128a03e6c917d72719caf5b293787a28a2b82b3d3879f6e6f2b0097a1e0c33d88c4537fed8d176234694e43317a6f786d9df0cb59274cf97df0c134501d48490abed80f735be2ba1b16c5c6d971140494b9efb6f658671daf412ad08f9a27bd122fedcae33d723229ccf0aa5e0d78225b1ee33d41bcb74fa63c2328cc75baa24d6c883d64c4afeccc06f19cd3187f731ea5c26eb675cc5bf51759cc386ce93eeda266d2d6001af345786a41dd6f9b9d4e0d99661435086405125bed63f3839622655ecbf31ffa047c9e0cf437cffc9aebc3111c25f75f0cf0407c09e89351183028ea39483686468eee4a04d2d15c8c06ad455fb00ebb5267277b5e02b88e170db3fd2e83937c28cb9139963aa88ade25ef9b2a1fe4061ed89dde47088ac3a5fdbf7fd895f98a91772878abd6e4789033855482fdf4d9db0ad1f69d9a42391b3018e4f2f4bc0b0a4e92874dadacd522aabfc87cb4aec556bd629b9967ef3994bbee82ceb058769e37c0d9d892a10a0a8d69c8e43ebb83ade9b9f0c21cd44c12965e32658297ae4c667cb40ee68759c6da0895b8947ab77f64652a319d0b7512ff1662f406cd023170cea4ccc9cd7cd32b48e00371f966213bb8b8df7229f1f4582b39ea692d5207c6187baac89779e5b8570a087d75f64c38d15cc10dc6eebf4a9278cf0367d500dede51ecbd84b6fb3fbd280e39f4b064c6d617dd12d72c261256894681ba1350496cc419d5016dae5a585b360fbb339acb36b4ff2fe0dbf1fc74a6b75bd822cda1bf06de2956f9b617cdd441f4c879faf9d66d031ae58f3665476c1f08ee1e9a8cf741bde27fa315a56cafea28651715a160629ba134bdd9e64c0e93ac6a598740d49029b6fd78dc6ea1ad08e77b91ff9006515d2676487a2f51daf2863addbf8beea6abc7e4e168d569b12bf73b12fad1d54c9141b0a02b9b12043942030e9e73672ce4f8185c086a2262e7b1ae07df07e526d9153ac52bb603a6ec013167b35efa61b966a1d68c92044bb9bb58bd55de5f551d5914429ced289b7073e6edda1c74cb49b484494b315f27935198a16576c5eee8d07f1c5fce908423b03d2c0f71ac8c0718b0ff9e292a8f006011e7e1dd743bc6b2a32cc3ba7779f19c69c2e41601f9f5fbd2d9c39b811a284d9621e2dfd746b0881532c4233dbbba37eeebb9f6e795e1723170ea726c49be6aa56729dff2db9d421433c750e5be2b86def06d81e669f30f2e73e73c0e46813c6154cefb47180e3b276adc4390774f51f0f21fe0759088d8996ffcc8a013f1e2db4b82a22875e7624dd9bd06398fdbc38bc78f59283c7bc27125f01afdf8d9906ffbef9a9f99425a5b29dd32e39319d2287f99538be0c98959fe702df6364fe46fbabb29798434cede09b328a3c871d991a97a5beab10566af89d2f501ed655686c674d9a86f7eddfbad8b37ce0c8105f984343564df428b5591432541ee2bc20b4e3addf43fd627d286a1529acd9f846ce48b1f9a18f42f23f6082afc3e1c5ef3dd943f363352bbc82789d0724579202ca795abe0125ab2f97f27d1897ac67e853f61287e30a8dff99a31f518742a9452cf0edcafafe2b6b432b2222e1a730b153600583c58c5ae2e1fa2e1624a8962c8c9b1c04ebbdfe6c62ac6f69f8a1c380ef1ec3702e2756b2e9b3b42459a3bd423663f8ef3d6e34fb59dfbdb9dafbbd760e157aa927543db931e5dfef5eeba28a8785779f59c359df89cca5dae213e90b651b4e952d110e3c05fe853743bb3706eac00d95825b07a0cd9e951a820a104d56d12ab7062bc5cf7e6acf52ab6ab4750f15d4d9862901e3434ec692152515d83b64f032e41ef1d6fbd77e70ebcf22a9b91aa553c5590d42082daa4c5b54a8e4d95e22943931439259b676829cc2ec6392fe21e0d1dc51eeadb102c7f8d4d447dca0862712b35ca065f9641e07f821e0cc08cc9e3d97d5f21a1b1c8ba03fd7c1b9e556157f5f1b66494a66bfc7d2cef08f483e08893eb4d6899edb09705b5c6d374d9a5417f76c3ca198dbcf08d3a8705a2b81d5921af71af2f7a6a31cba886d8ac944c5e5887ce64eda2c5fa400cf013d6d70d2757d06ceb59a56c4821bb1c488306a7154de48088b634adb7bd7d13cff614615b691ba9be51c72f9ae2aa207e5a41f6b6cd59485ca04112a7961737b914c3bb1a611088dc6c05c296657b53fd90cd3408ec39b3ecd4bce625f170ed035abddb6dc7257e7f1921c3d398cbcb51de9cb7c83cb276165ca352269d4225aea118d413418a11c32a7f8b41b02ac750ad596ffcad2b376acf301c32fe9706795b784e5710bd43d9e2787116d7fb9da67017f71f122cdd3e1e16101e85e2385d4739d27a37396e28a5691fcfb0c04458e0a577d79d8403c62a63057a3b9a89c97cc3b95e8816602e583f6a6b87116084db0ac0e0ffb5f0cdc04be6cdc2c07ec7d723e2609e6c8a8f110f1ade570c5299b300e7aac9684aa898882c3c4f3db2e83870ab981ee72e6b6359509a20177f425756421297d796393f978a027300185205a2af49f1e74fe2f6b6e2adf8c54b9b48af77cc0feb69633df49081fe585dd242ee40db5bc3e2f55ccdd783d1613359382b6f517df2453411e897556479fc72fee8b60b9e807b03fec7c7d8079ef86573cd1fb4a833c9eb1cfbc4f4d17b5693e2d2fdb715f745e2313308042991b420dc8e20afe5fca372a6258737c93b7c116e6dc752cba14aab2c4a37769493036480e3e4d7d87b97910840a107af6d10eae01ed3a216aaf9421dfddfe351904bf8b30c40e19f73f5d01a6287e302abc82be171d66ad5173f775dd0c87f221de8c11dcd57cc040c127bb57d77300e698c8573a7b207b7374a9f2987ab93d202b1b4b2053a8329130a75b80d067d65b952b9265633c1792c40282b55b14fe8a0c368e8c14ad2109f29345d1497badb64a23edf23a1e7a70b6125caeae4464a68328f5afe59446611c928f97c812d59b70bb694a94789fe7ce6c1c5bc74d69e304848f3182c7972e5d88715f1b880c4b89e383fcdf361dfd0a1c70ee4b21a22c0425e45d43bca1cad6250bf735c4d7d16445d27ff7cdf69f8f2863a407970ad139d02f79490b4c9fd65887d4c35c6873ffc036bc46ef38ec786c3134bf214e33763cab5ffab07db4ae6354f72588bbb4beb55e2a2671559191f270351b23d096e38731ecbcd8ac312eba0608bae78a57e2e025bded23f2e36fa1da60e538d75d2df10584808044e7f16be38d1dc8663a7d9c559703de7261ea33e07e066437da717f7ee55e7e2072384ea665a02e4e5571774ba5adf5edac37cdd68a44a37b2966846b09c1a97aab3b9de5cb76eddd3f9b72130911139d1158d79ece8622728dc404f4b3adeb4845197616ceca218e16d772faea08c9ef10ede6eac2da46264bc39bdad3178d1ea2e3ef21c849f2563c400139e6854189853b65ff575fdd623c44f1e49378c1a4c7eb24879f2b817586d7fac47ae43ad5bff202db357fb99288f5a7963bf158e0bd7f1d31619a33a90005d29b003046d2bccc82d1d54830491f9ce72f90d013db675fa3f6891ac6573c5a6ba9c6bdb82c0da115ab85f28bfeec96641e4bc21c654564a24dcb072743cb04ddd97ceafeb07a8e7c8453c561d23edeca37e1761e2cc74e8939d1d9888bf6157c42c2dffad45e59515e9afbf16a3f6475ca05afd9ef3860af089df32e85295928ffa8f1c0af2b208121f43d6cf99fd60019aa928762980b151cab67c8880b2e66cfa82daea68f38ceb41234ce4638b801cd98ad0e00323160e6e824c0297c3bc634cc2b39881d0ffe089ecd87000ac7072b372021362607ceb29420bebc6180f1ecdd602426f04016b54cad38b8fed7c541318aaacb5c790f5464b5ac7dc6fea49e92f8f30c7f3ce0d37fa7ce81b3b6d3f1eb9435413c6f81789f21eaeb87832817b13d1f4b79e29d1a9a37629c8fbf68d4e1abb05a449a0cd1690357a601af023f28518b96c9494047fe30fb03c808734e649a21876399861890ac83c2df488caa9f61c07c0d7a44001e86f963cf6cc25b6bc8a79251ebbe6662f291759eb5cb36fd14c88333504e8a8362a65904929cca46aa71fc535876fd13f90e6369347337545332f48380059b7e63ae0005754334ba59715fbd0dcdb93f294244cfca1c70fa0e0abf1dd523aa4fae03d0de940ee11e1eeee1769e10b7e058e552a27e05bb865400e0eaf41e039eebabe30ca636b6165545663af96229b07ab0976176c2cc5b88622084375b30b9a8d185e6f06156a6d42201642fccc76cdc54e8183b59228d6fe227a5fc6c6c2da1042ce07350b4312dc1f024e759be2566926d5a6bdd832f966acfd9099e548ce8aee8f2252a8801385552c47c5ebcac8bd47031b1f9ee3d458470d03c5643a268320374e55c1458c83660cdacab132dd53d8f02c5c2677185e909c6ea5d042d20dd516f40bdb961c632517439a6f9eb232bd1e958c61053088e8604804026c960cc4922bd580c9e0e92cf5a862bc9284e6ed2844f8870ffaa220dc56620ca473544c04bf4dac222c188af7ce5646a0c8781744636eef256c6fae52163922c21ad3131adc0732a9e9d86310dc72baac50b781b1923a708bcaa00e5405280a019aa9f0256226c6384cbeac9a3d28cfcf6346d41cf096b10333ce6d5c8d8c13b95c41543285d5dbbacea966af5720395cb658cc4f82cf1d811846d9061a9ae6238f3951ece04b747f566d84e46f9f5c76e9718b556a9a56fa0b7d4bcf49edac15e3802b0fcd6db2273f1b30490d23982ba339f69d4dbad5aca8e1972c2ee8149878f881c20e7ea0c7b72c4222082a4b96666e650df173802de4adc3422d18d467da27c473c42f792d39cf2b2a770b8822310fff9968464f2e518b0d4b6c342edb1677fceb50dc8e9cfe29d58806628970aa7f44f13c9926e61c16e883ae95c9f12a5c7aafc9207a6f8541a7dccd9262e96faad848d175f556c6e94210a8c1854578e5a26e3e97cb79f7a181e30933cbb4af6881b210e1c57dd327db307f8e3043cb392740ef53eaa6d444d5ab16b730c3bbe3155ff244045dcb1a0f3bcd2e50f2e740da1372f6cc6c47feb4ab5abd3cba6ebc377fda958f8d01492fb327d2b3e5ab16668f5e6c9ec403740f6d73a656e3a99d361e8c432bdc25fdc9fb33b6a95e3cb666b94b0616239669a9871cbb75c7cc39594d8518f84c99251f8495aab454a8722644c52a45f82879b680ec277387191cf595e7fb526a7c927d212c8f613e3d7b30b5ab1a7ea3d80b49cef48c693c15f2485ea6ed2421d2a354850ba5b538a9e2b0016e378d77a9c7119f162c360f9d0c9555c4cfaa5412e4ed2dbaaf7832d723edeb405151239eadef4fcd639cbb31e3e5b895248f8a3427bfa634b0b946dc484087d83f76f7024ad8cbd026703a64c3e93d2a61a7819faf0442381509b6ea20d3ea59969d1688f1ab31d43f1bdc7d06c11205298bc33dfdff5de77a7c3c26cd1203d8f4bb71a84524cda016fe387ff20dd7952fb228db2c79af77f23c24b5feb840297a249522b05fb53e7d4f98d943a1cc546ef52a3120d53b49b6aac384b40d2a4ab5f521cee17025f13b21bf6c7f05d6311fe29799929688497c9f3087adb4bd064bd511cedabf192f71cf87d6b1a823d31a031a421322b1d8728f2833ba8c4f4ef4e04cac6c404cd17ad13519344f7c85065310dfd29240f8a32e90a42963dea45a52d49a1e134d0d1390aff5ebeb52895ba041c8ea981ac5e045275dc19cfb314f6eae0d1b94a5283629fc9d3b8a6fdf932992fc700404707887367791ff7f7cc7639f88bc711925cc8492dcae6be04a5e57221cb100a822f7f637a9de89c7ba91d882c8785f36737459b51b389291991591abbdac8c1fdea22d5b933f8637dbea7983ad88951df627949e6b4ef27bdc614c2db300419227a8f2130853bc8a3b15c82b793181c59b864ac19a3ff78d7b6e7141f90f1873bafb894b8c7dc93f21d560ca464db4be0d629fd0d42a4ae03d9f4dc8f9746a5d3f14fdaad249b3f6bddad112062ea5b21ef4418a748c4b373a3bdc62f954a46152d110b4b8bebe02523f97d6d478ac01ccee2b2801337af15817525496814afb0f5a77e922a941bd3473a4db5b2eab5a576647a963a6c82e9235c0efbe3475b31df77e9012f4f52165900505e3e3bd8e365927be3d0b80fd751f9e20d76a71ea23e9bdd421709d5b9819f26d83410e3200bfd200b68cf0a1f9105cac85834ccb615306f1e2438e29c8c65579f617680199d89fed236805c66a573fd8b0f49f1ab9d6aae26da42ac1b6eecd131a3d24b4b430cebacf3aa4fed745d60d789a97bc29512a21923abc0f5fd2fa02d0d413dfaf41a8850f1d7139e19d580aeb9894937c0144d325187df58670a73ef221bfbb6ffa4b431e2b35676e88bc51cdbf45dcd301d2ad6f526b28c07d22473e77afc1b2b19fd47f86388e40fe54f70ac47c1fa70a26d510d37ddcad4af699eab0c8d6fae9a174090a874bb6e92b55f39330f67fad3a4cdf970f64aed73c8dce8d6462540577fc6ac17e5ede69843001a2bfb896124add434370108638e7afeaf69e2a87e02dcfe263bfa92eee04213152ac393e2e8a6eca8bfb6cfb2d7c9fdd36593014c8764c83f4a0282970ac535dcecc946daf3f9a64887b110181eaa775596a7bc00a8c73ec9b34b5eb858d4096cb1c03a9e3338f17cbcf47e40b071499f45f21c46f01ec5d1da2cf88a4149503a1bdf40066e70de036356e574b849b3fb1cf46770137418121d0dcde847cfbe1768ad48e57f1185147a8592e8b35802bb94a13680e289bc0f0261b8207503a552477d40ddc0aa724d6f6acef65f6dafca9910d2bf493a5c218dec4b8dab1fac04dcafd8c7773411ff6fdb92771d445ee991f55aad5c3f89cfdf9ca6bb2862e85ce939785681174ee2a87dc97d2f9fd810f72f216abff5bd465942f3540ea1ae259acfb389df33c095a2c80016979cd49d4b27e3f2dab5ae748ea72b011087d06b00184eedc6b5c4205f02b49091c0bac4de1ec8a7d2eadeb2c37087509c349ff6b5a999d92da98e75a2a64a90a69c31b4becab1a08ee498b92818d67d001d97a9e8c1a0153b306a85ad9e983834f2decb2946dfb76cbc69519ef88561a3fd3001d20c7075c0ef97303ae3c696a96f90bc140d948fe4bc9b9fe19896b2b89a2665b68fa8b214bc9979dcb75c4b7eccf74feb0710cff0b8cdd61e0f37a246e016ec209e7c9dc89a836aa37bccc8eb218f814fadf25b5fad03be40097b9f19496f11a38914638e371353b0f548b68202596b4e975f031a3a648e2803e58490185588e179cf128a5201c0e039aa447e2a0d09a1196aeb4330c69ad83c3cbdc58ba8bad19b5f3c0c10ee2dfa02717b41d26ddc35ef4f0739b25a9ffe6e1b8844709d7244c6d1389d461d3e0c7f8d534ffed6ca7106e8f294088cbeca387cc5ccf29fdbf5520dc6db880c648e71b318fde0c7e7062e82c77d6789cf52258c243fc3b69694d959ca0f64a3de209d1739e722d7383bedf21b7910d0c1f4713c5bd2201d132c3ebf8eb613e5c3e197f89cb7ca287d51641ee783476005bc0dd19ed0cbcfde0d79769c5addcc5465b130e09eb08d30e5ea192858eab862bda3c90d04dbc286da84a8fccae9c6db1c8f97aeca57c78797667dd7c26c502ea506aeb92c3a076efd6b70f84741992f50e69a118c91963c7ed0395c20d59b0783368b52ef6ddab69242d6fa9595678d8f9adc664ff3cede481c295cf5831427a09c935ce38eb865b67efef0c29cff1739ed3b37c82afbd5899cf84243765eab101efeec9f627d6c841d4836964fac5234d0ad4dd7593d91eb0f6aed317eca5d282237855a1c786fddb94bf1e4542769064c4d927f7019aa3cf71e06d174eacefe80578f950afe948637c49a0a87bad0664e9ab8adf86e8f5b1518d8a932575e14e37031418cc28d2ebcd28fe3e61c4d4bf315198eaf24a6439ece6128ff95b71e23cd20b5b993d47b4cad1dc0a93559616e11fdf70eff348f2fc3527ed01f9c6acf26ce4b417e422d5d6644f3dfde437ff79eda13a2d0df69bfa87385ba506fa",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x4740dcdabdb15afe6acf4656bd983e0424f840a5e6158970f0baa47b277b188f",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xf73bbbd26a82dbc769066550d8d4585eab2fc00d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374d70",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xce4e2f5539b35acff0a0e011d489b89f0e1c3a3a50bd90f38e9952f396b275fe",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x8a7e749d412752316cca35a14319b3e89be3eb8a5251c26e20065ea7290e0544",
|
|
+ "timestamp": "0x6ab8f118",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-anchor-20401520-baza",
|
|
+ "sursa": "2800-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa00000000000000000000000000000000000000000000000000000000000000000f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b841c0c6b19539827f665e617842b3fe7d3b4664e75bc63d3de0356395c9eb3cbf9a7770f8536389b854149b8393331884cf32e0674682d4bdd5ef4df17b237be8f901b841d105779d00965712ef716d7e9c2961a2c5413eea53a390ed4a0ed1d6c137319d22e37eadb46a65452819cfccf5e5aeafd6cd2f1a53128b1f600e89fcd75d4d9100b8416cbae2b8abf089f98147f90a2b241ddc68a00dda089b391758210ea653e1df1613060722ea94ca4b8d089e9f09b82e5efda7f3fb8c54b2d0a0516de071535ebc01b841dc1c8c635d9c9d9bdfc00e2459f51b940fe290518e0bc0401be1180735dd089159c185b14a80174e1ede59838bb58d94f01dee8b36073fd49cdab4b08609d8ea01b841c7619b21e32b48a146c0ba24c0ca2af25afca995fe34e2abd695265c6c32d34935267d14a6dc8b3abadf289f30e85b9161de6c81aacbf2e0b1f15972ffd22b4301b8417705c4663a635b2820916628372848fcddb2359c78242f0a36200dfcc19d050705b155009804c1f0a2b7721a71e9883b86e0eacfe3acc94196916f109337711001b841670946d3f6f29d1f23b03739420338571afc9bc14cbd6c758dd99879770d1ac26dc08dd68b24f6f1ff7e3544385d3fcb47b9974f61fce11ebe1c0fa3e60a3b8e00",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x06eece57b68723399deaceac1a88af6125fd78922c86b29641e02be756786586",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xd38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa2",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374def",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x04b441d0cb5e475b309e9493fe965431fb377059ab1191ffb778a010899b894a",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x42d0e0a5d0153732a72aad6a3987219b29f31c17b0113c074f1647324c8fa373",
|
|
+ "timestamp": "0x6ab8f163",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa012ea1a0d595eb18a90a824dbb75fcd601d0f1f368be62a3ce5fcfff67fc46682ddfc9e3f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b841c2a29466f85bcf091d48c85f2e26752b2def2990b70f37b998a005a8025cc0903c1a4f0cfdeff26acd0eb41ebc35ec8ac4497e5041277ad6ec2a83855f8f966301b8413a2d12c8c6da65b1ccd7bf09db65f235f74ee089b2bf30f0aa24be621616a03c4449822742ba3ec790f1f4eeba0356ab5c63d5512946ede9b4a517b24977eb3300b841f514fd307ef807a5ff3b070ab9a7ef4b35d52e36c7665e3dd828b5c7da5938b1001283a766e6fd696c88be696b896f3db2a2bc3ef0662a53f25355b452b98ee400b841cafc79a16d80e0f34d5b6dbd6298373072e42177b6805d63649e178d4e8b08ef6b906df533b785bc9cd08897efee4568514123bbe504353cd89507dd722950b600b84161ac869e2c9d899ca96c7f1166782b2964b260aa5f4d5b8aa6e908051a9114f54ada0607a0ad1a56be06473cb3cb1a3eabc333dcdb9576bc6c13f7fb87cf338600b8410018422832e4a2ec035b5d0b0f6b35f175bba6e03a46a04ed08598ac64f26bab2334e0cec8622d955ca0d9207290d17c0b8b79ac4ebcb15df7d6bb2f40db4a0001b841ba4a3ebf790fb663ff0a8fd357bd87e07ee990f307ed665c3de90854e55232a15824d4feb2a07bb837bc528274957f0218a958d47cc468c4972363f548a6186501fa012bce02fa012bc9f902910180b9028c39d2d077f8407e100acbd9ae1a5501c59154fd15c18d42891059624094c4d829b341f85168364486cb89e02a496a57c7f55dbfcf47f3397141cf74f3050ccb448cbe4225c1b2f4dd46bdd95d5f2d3a05a26ae34519b0a16ae752b52184c7e74b54568ae9a070c2dfee79d237626b33ddacf999ec5f035761891a78bd96da04a9e2cbc36baa87364295e9a416e456d79237ab7f9b77a1585e0799935b2018ab3bd29b5f21505b358dd5b8796f0fd91cff248c86726557f3ac508c21c340fe7d7228a674e64ece8636f1cd1d2a33d660590d53a96178f6b5adccb9d1da146b37366910ee3089b57b63355590fcfcd18f807c321b02f8ac4978ce2a9dc3dd98e6f951d4f22fb991ae23669c61af90620a4e10798c2f4beb4d28335846921b48e631e431a8abe524dfa886c59887d53deb7de85db8902b946d12dfc212bd2b459897e99ceeedfd0a6d70e89921671db5b24f05a8a6c95cffefea6b76db02d50c57fd6b1a3642b4e6510410826a283126e50ded5571244551541f46c6351a76e20d2328f0fb2d6c75c784d823d9f6ee3946dca78efe75967b53288b4d2f630f44c1eccfcf310eded2316d5b30cd5a737a6490e85ca50bda55297c89fbd3c0491f7924a21f1d22ad3208c732e8b7ffa8eab610a7db8f43aaa3563c69bfa6e20f961b6b0e2af5dcb4522309435c6e8c1753f8e6b2decbaf0d59e05bfe15edb9909cd5abfbf8db6aaaa146f56aca9c4d4e5de1eac29068b2b6f1bee9ae0666ae7b8abe2e1b099a8cf45882296ff740ee642c757f229d1ad118ebe250b5476414ed9bb32493999639949816f8ffca31bea0771b29925b12b6f4d3e4826519edcfd748f8fba0da6647bf11219bd69aa93b964f2ecd1d2dba69dcf30fdbff799a631c38bdf3b1eaa0e3db7c7c41e996c690f91eb50280b91eb0a1f665bc486ed995f0c6de3c1b89ad76b1656948880eaf5719e78e5029487c6a62193c33483848bffdf691444b187088123c7e57f1122105df437ff9ddb8efea1085eef885a1feb11ee9ec6322b7e2831c8c63a37e6a3bdd6328a1a0059d643438e01b8142074bdd75e29c5c64bec1f281dfd1689251df00a3e521537f92ce567f2f7ec97c637e6e45d4dc88a72b7d9faf48c202fd6df3d128b0656c7bf34757d821d740f75d0ac6e4e2f18d0b9c219c503d0ea20cb76ecc1d93919321cae13cc30fc56688d1832c4fbe9f8af5330c178caab410bf35f668141ffcf19dd5fcceab701bb6d5fb9ec08e0f52beb0453dc4f73a797993dab0d7816bc871e89ae5532f7e1915bb4638bb644f6d6a796ba5804532356343a4cb6fcfd84f089ab89480989bbe19dcd8dd916e3c1ad502dae21a1e694067fcd10453c93e88af73e06de272f546d56d2c0391e10a6c4abc4266fb9deac412469dfcfb49c99ddbc70c46486fa83117d5d9f4a760cb3a144fd95242b193dd382cd16ba62a4ccd772f5c524d6e799bd775ce60a0297ae63d65e1632b97d8f3a94a0be00a84288eddf9ec974c54dfc363ef1bbc4be772f1f4b9e898de2e26710ebe3fbec271c81dca7c71b6e0e8bf654d0480e3243f46182fd2eaca4e3631173346c2f759ccb0f1d5d70208ab6b1575e8c90702d786d84e9d4865926663dd33a88a8741eb5bc4e9a0054e66fbd36f7f3722ab39b3876488953d19b3b8efd7efaae7d0de193fed402bea2e825dcb24bd2507fb43cfb073f1e30b3ebf7e9bc93570247c7fe16a5403d3aded44074153fce46542d5f7f5b174e97d21b7025765fc5c85d4608da08657f5e1d68df9e519a2ec27e00d3b27bb253de04781126a347c5d09acc78c2fa94c3a0d8faf79f4728b2ba1b536ad549800c7841e9db9fa0a4c7f461c68e2675fd14f822075a781a5392bed89b78e27cc1cfab58557bc65348223b6127305a6b36de48f9454d651319a2c872380bc253554a05f2c91d74bdad56ff44c59bbcb7c21b0fd46d882ed52241289de784b03b4e48499db19d820deda7a10092b6323a61b9e357ead18c038afe23a0f60bd3c4f663727f939f6f15e6053f932ff388f9b48543e9bf10c5b332130657f04462d85356bda790389954b8dee27f97c133ddbb561a7ce81e4dd010b4c939231cbc70145b52d01e1a48d351eb13a7eada3409412eadd8fae1c887206281952efe69882dc3b09150aac2899cbba4a9d43f604df8e0c694dbd9506498a18193997c8f5a3d45f642263d25ebeb8f9882c441f488dd3232b492d8ada70b33205272bb30a2dd03fcc712a6f011cdb8fef10d92ea1de7f542d94203e396838239eec53cfd24906e5c398985066c472ca18bc82bdbfa3bc2f59d9f9f1b3ccc394b1f68a4c7a2788d9e8f49695d810cb00c55bba15950e5e87163a03143a984465f607663262f276a2827f540502c84bcc5308c7f18bef962fd0ec95f9f65f0514c7ded52d13840c5d90f40f7bf631739493383795f07b33da25f6ed0bff23fa01c1e4d5e7eea5c710bcf1f9153e938087c0a34515c416f0907c2b286ee795d71c5067748277c05e3ba7f4054d578b7d59f8deb0c72b05d24faa7a262eb9f6dbc47c49a93dca32b64dd18c05c42a684f7794bd34fc771a4761681613cdb1f659c8d5dbae582e23e4015a831b2da93f7d01b06eb2f41ec47bc675b85049b0c83b7f650d058143806368b6140dc8583fd73dbffa926f34cfefc2dc77e9415d56f27b121d628e861bd66700a6966dd20924cd581adb5a56fc42ed3df90e699bce35d3fb499cc47faeb0843ced040f709935a81d540cc30557751cdf000506df2aff8dfa371a330cd2d8fed123ac8a6030c8a344dccef807681c66fbb3893571af8db446b75ad0aba9988d03d098782ec36df8d18bce4496265b1ed00e7a95378f439153223caf9b93f57215efc2e7bf7bd628d7c0100d0e47984c230d19e33facf1cdae4e3d74651d5fa4f67e73f7e723e4d2c2f3e0b9243f9ea66f05cec684b3d7593326fe097f591c83ae3724d6ae4b767b679be718730290f42d19911f0c7efcb2edba613038d47acca21deb25a8ae74d14a322cc392f777f62ae34be6542aa6853686f9ed4f8556b4a58f9600d8fe6bd464a4e5e762310966727a19e2d6f7329ac5741349eb248dc9b1a4897bbaa51980bf77be2e5556a445463fc7723289738b18e2a52c3e7d800cafa159b4f583fcd7e14b592a23eccf2a1b0cd462d4961f981d474d0cbba87b39f6f01a1356f416a611fecfdc0c7347c070c49f9b5e530c27f98cee5d61ce845be3d760cf61f88b3d5f6952b2315f11e3002f41d28a80433b86f39dda8666f778cb609e04ae57ef6772579f6207da66b55661c92c41086bff3b4bb2362b35aa1018cba05394080d810aaa866b42ee4219f256d69a1baa3a83121fa5f8910ba3c3037c3aa9d7c5ddf988a027d49094e88dabfa78f68eff9c7dcd9b603d5ad275935fa19890b24fea079d394e18bd6672777271b0528a89eb1611b0f1d6f4dc3f91b8adc7115cfd03ca9d4dbdb9e81bcbbfa9f0517a8d1efcb093918152d416fce10f17af479ff7a9a23f5d848e243dd0f76333ca34288a1f14c541ca421c9874631d70579e19f4f389d63139f7839389113b93fbfb2e22d16232af1b1a553df90e451e7e90c2dedbb17775d0140000b18573c8e8f259ba9d628810e75aeed85c582a4260b557d06a51c872c81d006e4a69db72a4af926ee80c40e1a4f3b3785496a3bd7ef92c815e61c5bf56ed205b08315e31f5c694a2922e009cf53a9f3599f07914b49efcc4af88c8a687b8cd6d809e492d9724d48afed4cba25f2ead6dd1dac4f0c0a81292e464dde45908b5af553d6b9448dc84e8bdb0bba708db116d5e3acb4b9bc9f46a96dcf97f65e232a1eaaa429a90a211cce4137c5d46a964e7bcd5e6dbf5e897779b7760e906d6375f83f3b1e37a5824ee252dad1a4889b62415568ca7984c60b33f560213c510c5dfe4736faff2b3ba1b4bda58563c50237675b263b47272f9be98c1c7f65930b21f1a7d80df449dc4863e891558b3cdeeff69a35d129b44e722bfdde484287611515e71371b8c01f94c4b4d1a446345f3c7e2aa37af1a1494f111cd6ba6a0bde0e8c0d6084da7ea9a00936f49248b22f5572526dc82254609f32f68dc95dfe7498c547af73692621a949d4546348728c295f4254ed139c543fd578ee8aafbb0c22303db6734fb0bbd24a32b025be46af236f32ee3a9cd130559f95a57e9d8eb2fda61bc2755d1c883e8db0675167fd952baea977eb7f1706152d805d6eb85cc17b1dd4f38a91fc1c40513e0a50e15ffd56351a1642ffaa35352e3e97dce77699d00a0cdfab3ad6d06339107e60a8f463fd264aabf45881548efc2373670051a544836d1a84b949b41c4cf3317a609489411b4162c92d0c269b2ce1fa8fbda4ae5274aef46d91f134f96a42750822cc1a13570e45921931e3163ce1744a590de4140b5148697a6244d63b60361a3c325e90196aa119e7310ddcbe455436493089249cd898c7baed75fb0eed360944c6f147235e0d49179f9e487105748d850d2fd261e60d6cb4f5a75ae92b44d65312207e0e7ee01a4a51ea661a377a65bf8f5011522dd4274befdc811b3c408bff85be38002e5ffbaa9f8eb2121ea9c09e0787d6da3bd987fc47c05a0526ae32df65d106cf884931ebf1f23128fef206f69be65902a20de3b6fe32dbef93a2d2cdac32e5090d64a200c00dfd26ceffa90acf14fa318dacbc0d29faf505a4aea33a15a3d07bcca32c05f7d2fb43c0a7e68368cceb73a016daffe2629481045cf6d2ed5d1c81ed74afc9644aa12e4de3658ecd475865204f9f541e1214a6024035587dbcfe76cfbf91e35fc601cbe45290782b7370bb71293392450c136d61316e78097ae3a41f0a1ce62126b162ba2ad53fe51e354eec3e254fe55163cc6ce77519ec90cb0cb0c9b4bc9291e2f47dc37e4734b0d37fd8a4b7e01cab5f51db02c79e1c825bbea3535e0716edb6d2e70dc0a21298cfc9c0a0a4c790b2d7790512be3729568aec9ed27acf959751f9afe4912763f29406beac4442e66c9450e573cf32146895eea00a979e81dee46ca107271c76a9fed560a5a05e5371b9e2aca953952217d2ea83ba0188c47577829a420ecd7e64d0c97dc24ceed2ab34f4d02ce000dceb98099b888e9b2f29454a1ffce642f9b92076e47571bdbb4ea1d070dafeb26304328b9aabf73faf2277c791488e9ab24304d1d645637daf4046e5b8c3671b4654901763c6e0ac820d39f3104286e398ad59b3a6055a273c18ed18a6a5f4d5488b2d576be39515362d8d81968c1e6b0968f81a1b2be35b8f9000825a8cc5c5439c2bc755d5754fba682f543d5848b44bba2b3d2d9ecc941b881d90256607a8eb7e0bec0cd341efc3a453392a830db41fb14bbac522ddbb3591391e61134d83b93ce3c28232fd0bdf7bf89563a3553d562ac3f0903c5517b96514a3bd483378b426a93e1a213423f3d9c2a3d2536709b37877bddff24b05ac828955b0d1af28114f0b1386d7d7b2a9d175e25a3a8cb4ef57f698ecbf0e8c77246283bb1e9538d5a9460f88b7b7f9c74483bd028fb969375b4013f486a28cdc59e182f7f7d12bc0f6301d9276482a6368bf55c7c1ad5c8ad8335f1fae695ee5859be706db8115f8d865d3d8c5417fd073c5f0017a52f81c9057f831a644787006208c62e1137fedb69997f0b190fdf3df095b8c0a1a8d0cc4f3763a27168c2f6d79a372859e5ecde97782eda9facbc4c04d08109de443b8fe96e733faaa691429a670294979947ed57ef10f65451b7c932760cc2014e508e32907f3e8b19b2f5872023825874e4dfef5fb7ca21258c97233527a0d1282db0305b43ddc7a273e729ad59c3c1242a5e4b4313cb5b6449058f7e3158f3968eba348230efdf733de8b64ba56977bb6ed9468c557dda1cea89fa7c0e6845afa6d9eb4aa17d73e986f3c3a21d16de89e9fecc2b5c338485acaa6e339818bbe9b7404cd3a86e13433dd2e26f7a157119d085fcb09802a6874dfe4167e7b89e4dac0dea185dee5d8890f906381b4cdc393d09ee71c2adaf2aae8302c82f6c29ac9d4397b59bdfd24bf6353a588a924c175f6c5b9630e7d854b851929b58913cf3cabf5c879eb2db1f199c2cd9a2f590c9c60a62b18de99e1a310977789f71ec509923df11951a1522caa62d76520741920d911ae6d55323faea13afdb58a6267da622f3699933d434b366ff06b80b0898f1f99931ccfe6158622e49fc3cf964c210c4176677fd75d66818835fdec88ea42373c2e0ffa51a4389a1cb3eec5dddc4a3e9edc4c1e53f8ef577cb077cc32cd0a079831ea327a43c5a1679be6f2c45e0dffec8323f387a1406dcd9c980186e941945293dfc952dc0d1888d481bd2d2cbba952ab04d82f5af2120ddf0d630965bcbad162657d4a77f7a00b1cc990d977c27047e14e80e5feec95a0bfcc4202cc0df93f72b1bd27baa5a00d720307d2f8eb34be2c51eab83cee5b555ca815dc7a401d8639681d9866eb8729c40e3e77956fdc51210429e0ccb3731c58589d2c4052a597c66657aa228842a7117220a136f98fddaafdedd9ebb29c29d42dd93ff6241270e0ea1eaccf488d21d26a2d908654ab504f386bb55b3b2204a20312fbd8b67a47457dcb60839606fb3333bb8d35e1d74d62dd96c456927aeb8197b29b361371e0a0cacc8320542668cceea5e17e6c5a31fd0cd39d51dfdc261873750f7dab0da52d73a85ed02ab73548a9c9e25870a843307057919a32aaefb9b4612e59ce486e417c5a8c5f305aa98e181586bebc74438dd77268fcf0c23291da301f0cdbbba4fe471d4e26881eca723d1de690af4a993db6289bcee9cd638bd6be06fdf768c386ad436eea2284b96be2b2ea478efb9334dd6b4416ca3068826caaa7fb7e51170a03b1fddc7c206670f998c1dd28c3d8a5ef80018d79efe43034272cf57cd8a9f87c04e0db59f139339616a94692f6ccefbba39300ab60039af2e0315f0b2285fe4f8567ddd1513fccc729d3fc270ebcb57bc9ad10df176157d84db50aa4c7a69711426c740ab5e179ed76b4fb5346be02c021f9b8bc8d2c53f70ad71987955a549409b488c3c7e16f36f6a05c9f697a3a122c7b24e21e0dc36e3a5ee61789e7d82bf5c85129d6c5861dbfb7918ca9fad7db3990da0e0d10890692fa7b11f6c4d5aa7fb68305d37a7f5c7bb77f74fb2865d57fb1c4e480c4d698b3263cc3c4498bd9b01312dd310ef526b7ef11e735084ee51931ded30f177385db4a1851e2da3a1f43cc6e1ac41c005e10d5cf3f7d2c793e67ccfec64e2cfff3edf901e879d74d07d63dcf886441441eaddd3bd766807ff74475ec44671f3e9349539f2bd178bc673c0503ce8660b2556481080328f28bd88f274013491a7e819792435c353f7b789c5520dd180241ee6e65abd1ce31c50fe15ac2831217230da6c893994c4fb4f2026c07bab02d4601a35801a390d3bac5fd5c0867c229346447fedab4ec118516e175d16b19f210fcc3d14a7e9914db20c54f01c6c880f4ad0506bcc364595cbe0ffd356771473a2b55deaa7409998b1d22a64e7e467153d09c8faef5b4ce58ac0c63795151e4194bced9538d11050dd9e1f9b4936b8852b10db49e4c0cfc6b2825eb322cb4ad894b9bf07f69c9c67378bf454ec841ff30980edbfb3e83e0ec394414ee9b98eb26b63e99b5dc29ab1139ab1cc5a8efcbe0a9175a5ff27f1a19189effd656447cf3a85991efe6e70413a9a1578ac070f1d5ebb5ac8180278f83ccf98a500d80ba73c68c7cc841e90daf9ec919880fc6e6c383fc604b03ac3f2a59c80b484a974751ed58868c3033eeed1ff1d8ad84343e6b13652cff499914f5ca697b325ac65d696aefd0c1133a8397f4c5ee5c3b26d29ad261ee921bfd6de7514890303808334e200b7ff8b1a30f059dee3564fb872f82bb8ad748eb42d3690544bd384fdc867d12b890cf92648c567d5182fde110a0f8448343e113b964abc28e6191764444ea032b46d7bb9fa513a8c102e962089fb17ada14c7d2755a7ffe37a58961ad764182fce690022995e49e7a61ed8a3c6c873ff82f4a9c890b19fb6da871a7eec40bba756f685f4947234271456ed2320f37bffae80dd8afcfbe25ac566163bf640b9bcd353e400bb32fa5c973b20a9eee5a3e4949a349516f0f62f6174623312c88005b7bc198bd04f1410e65a6b48b58bf66aee2d811a81c0d02892ac9a53cd9ec7810594f4c25f984954f6df0c6b6295a0705f92b6f5bb85359d699ca2d6e96a6439fc23c475743a04dfa1bcba0cb06f4b9571d3f26d40a6b3f234a98bc15565fd52c33edb7098275522cd09acfa3ad5046fdf96a1cc4dbbc0b515c59795bd16d613d0833da17d440a7430ac631fc152779e17bc319bfd0a4f70ea7864236d5ebd4464607d4e03156994669f072424ea97435e09abbb2991f8c279e97866e7025c87665672e6d384544938ec1ce3bf256eef049ed6ea4f3e900bce219757095856e47e5073e0e36682547201d1b266ad012079d435917ce8904bb916d57d3027fb2b34442d808ab452817dceb2fbe8b372039bd2bc5a01feb141094b5a42dbcd5747650e80f684763f3aad085559e123eb38c09c4dc9c4818d05f5d2d2d91ea19f8a96225da3caf3970e0a6fc0cef857ad2011b1257be09a5d893473f6f74389da3b852da88b42384fcb3cdd3c5019fc40366f0cb59c3fbe437d82a92e739f0cef0a2ee5e66069fb622cf4c070fb4a49eda91b4fd80bbabafe78bc76bbd813ad5083d51e6046dc6dba8533aff349b0114acef32b9734ae3970d9d201a338320b61771a406256367eb7fbafaaf5b162023001d92bec20eac3122dfac48c76f9ee79440147a775ad93d3983fbe686a05305ab4bd23e20f88a0d877fe04ef66a9ec79663ec6b9133c0b36d59e52bb944a014bc6074ec467685e82ace8abe57aa50f590797c45267a11949062de14668080ab551e5a3dff86c9da77f0694db6dd778e232f29e68e1aa9cf75a58d3bb4ef7ee76c553b2a43326478d624fe7a92c9a1ff45cbe9e324f2015729554464fe855e30df7630cf08a10d2bf4b2748aab53cf87f9d0e50069101a34cf1e3a34dbc05bbd89d50f271ccc40d63b100f5bfa85aa57781f98caf9d3c2ae0a32b67a5472583e28fc0173f44272ddd9385a34238b96a51ea90296d15203c7e59c178a3af605bf9cdc13ebe5bf4456574b537a9d83e8f64863520ac222d5722e7d00ced8aae3adf6dc348dc42995cab7578a1d2a23e00d9879aacc26c653f1e48dae164ad0a498805694412e7360e1f2182a4472d0150d5fbeac2d566f6750cb0a425a1c7accb59d3332f1c3f2606020adb6562f8bbc0fed93ba4496fe90bd31d5aa94d8909656f5ba481bfbf7431575ca43faca42b99edca691905693630222c30f13566b2f95e8bdbc9a9d9b88c9f26c2734e61f045441f696d95c136257c935998e7d3d0e00d6af5f0f76ccbfa71313334d1575564f5e7e1aea82f941e1bf337796c75c1d9be1d1f550c733d659af886f7c1efea6ed611d8a2ec325cf9dbe222c7095b6d95f656c5c450418dc8c8118b8959670371341c6076e1e7ac12d2afb1729d398aa57243a62146855ecb3b2fe040d8dfe60bc069eaedae8c7671c619a68d9608f8bd078ffe75860b0c2efcde2f186b554df40368986444fea1386cb5f970008e3ac2dd6db964f9f10ec3cfe9453c60e6aca78edc65b50b6f075fa7e2512dd1de7c88be0114087f4d91172caa73e817a8851d2fd46d5737eb3b72cce010714c4bbab1e9b923a0a40b6caf8580f20d662b226cc74d251981a14e1288c470ba52b95652661b717a00b19c27013226d9fc6afd2a53909f558f7033ac0da0d05eaf06e7b1e7ca136a5f45b31230e6c4b919d498c57ad33d71bda6c8ce951b335122f531e40e2e050c2326315863c2b5001a48c619593d22246d3869a16f33f5cc3dd73368d5916a9e98d57dfc4da01291a21c525f8a7a88546f3f3debf9771be7f4452304e8d134b0f3f2dc4cfb2d6245a214a88d96865dff2379410bc4dfe904d3ab34c2f9705b1ee6b3e95d33ba4970159a3b074bb5a215c3eb0d47f005e6fce14c22b15613ec7b695d8a67ed34835d933b51fc1725c08e1f67eaa2ee2971f6cbafaf186097f3162b108479639692f5fb99726d0a36b5f580b85e78b8dc74346479a93b12849efeb5f804399930b51b10e8655043558c920e4fc4bba2a545d61a70da10f20b7156d6c8006a2da99c315acdb52a847446dc98727f9cd5e676219b4845f57ca834c2fd1470c93687e890d8ca924266b3b3f01a3b9162a8b652f1158d7bda0a328ec3b22d422fa35fa0d9acce12a4d9ebf4257c170c867f3e765c792e1623087e350ecd5665c54a9cec88791634bb5624fdb16590b3932777b1c27ce28039fa2118bd06330830b90cc4a4c1d74f15338689492016d13b80a75c689c13d9d775feeac8af7773317eb8b62ec16cf5a83932ec59042282ba17968ddd5ae5117ead692d93a2d98498322fe5affccfe621549fbdcc0a7119ab251d56afccabdaa75df55c21db6dbba120e98fabbd0548d928dc081c4c79db8764f8bde96b5067282f2f706f9184e01371e65f698186a7cc022586b84d60e983a902e72418055ceac3b85afe2fc819ea54acdac49a987bfa674bfc18ac3e45c6588ffe103709c9a4d56a60d2ed1edfdd8b8c969be2ecc588d32e6f5a6625faf3c10b0a2d0ce30bf387285205aa5ba9139a11f58585963f646941a17cac3c39e44fa3fcb863d301b6b0ce92a943176948f772de56f821e7e94ab284a3b7af414bfd6bd3b19fd39adfdcc0fafea76a5a74661aef3409af547559f9a3bfc49d95ea8f02b66ff1f817e9cfbd6bdd3f77ec854bdacd78c0c80df666c66008396f9703bfe36be7ffd589ca1f02d970c3bd44fee9b84e649f71090129e08d7bb337133455f789998a6dcdb40fdba4e84f9be6ec29ca68e1ab7425c0dfa234c210180b857518f15635c3bc07d931fe4de065f118c33bf06cb6435348e37328799832e2befebb6f72d63c6d701b544b7d8100865fcefd0d682cfb952804739a9e6839ecfe0c820c9eee6ceef2864814311f1f121e2f46f05721884a433751220a4af4ec5dee4ac1e4a837e6d1effa2e9a6dbe4cc40fde47f7995faa1881e1f60535b21a1c0da0086d5512e2f824441506951215b625ddd71f3c530ada2d3b907641cce428f53c8414c57a456fb73eee263427186e5807884c639dd1a03a050c984bf483d4e5a3ad0f1c392050157e18ad9f19c0a9844a3fea8ac1850375f225e8a188170d5392864889443ed86b97ba8699cada78835a4a36e7d5b278452eb686d601da46950618af4675534ad39f3c14703e62ff306075a6355d211ad4f26222dc0c8e36d8a360e005d896357b9299f630754b1c3905085cdceeab025f5a97fd9170e71129b57088898ff50f36db741575e0ede8bdd7ed6ed01e609e5c39a344a09a074147bd8c6c6449c46a890fba1e56cd4dbc2d2dc7f81d70f4145134383b970a3c75ec81a7a1b79d19823817d436dcbd422c1b620abb87e518d6970a91f9dc8470cec622c6d30e29b6fb2e6132e9a5f6d70f021f2e03c2492d371bce3de3a0bf74ad6347fa4bb4517ba87f891b2615ec74cee2cb4bf873b39a27048235b3f9290fe5bec385e5f9341af713d9e36928b86b5b381fa654cd63e9244262d807f7332bb843550c666514f5f1f548c9db69cc6da18a56fe93cc3c8477688bc15f1b3a386995f073e3f374ad25e5342c62b432aad90cae6df390c7ec73faa01f05541c6a0c8a13959f02c77df0de20a8bcc1037e240565b3649d9d57f55285d499cb86f2ecafd4b8f338291848aef9cb1fb75903557c592aae76e697cec63cfec1633ff22da539c7f7160fbcc0188d3334714a57affaf915f3e9cdaa34a09aa70e2a36b6718665c47319531792707f8c3bd3ed05af4a3f7db0fe09bc35b08d8b52518b4074b8e81956542d3a974bb299836f18107dfd4dac4809d14df902940101b9028f3983908bf73d57bae24c88f33c703b3bea3600703276863c9c357477c1fbe15d97a1afb48b99f7379ae6c3c0489ca3170e5d6042d62b93b6759fc518d58f0b7daf2e4cd512b2b1f0bfbfdf86bca040961e2beca9614c7f43d77191e7dac6758e303e7932a4e721475311d0f3b9558c95594cc1b9e4d317215994a73d04adb0e8921459f9710cf224cee0be1c177fdd0b1ebdc4ace3e31c5bbbd94bae36f756f328eda5f72b6f5e05f0cd0601e17e38b87bdb3d769ea00aa6752c6b9ceb5219266ea38ce4e62894c193eadc019fe8e11908ae53704b52aea6a7af497563c5f4abb1eda6daf7e596bae8c4e331d3704e56898bfa679985f5727158ca2a238e396fede9a429140615468b73a219c51e341dea0f123ae2b73ace125e8c648de162bfaff4ed1b42694e1f8115977478ce1ff310e4ee979a3b659f8427ef33116a886546558d52f3bb561f0889660afd5e2a94e7f1ece542d15af9465fb4db9baf3b088e0d8acea20efca9e3c7bb91b4515edabaaa94ceb1a6ec57a46d244bebc2b4257422ee4c0b44492527b1a170223b173f1dcd551f36672eba555c77cbfd093dd7f8bbeba3f528d0eefbe38ae6fdb8388b1f820efe9dabf92acd384dcf73cc20855f168aba33c808ed2b1d4cfe17d58a6d9ce703af2649dc39dce35cec1dfe6c57f1f244751da823dcc6c5a91b7fa2a4d89b48da577f74b9b6688651ce2d68e761c2db54506630e4ef127a43afb9e243d0c4ef0468320dfd95308ec8798eee5b27d0d324b315118c547af3247a58cf291fce8c588daa1613c28dd233c9ee152786fdf15b23cbdde26a9b1a376ce47620ff6d6dad26eef6e66c5410f0d06a4c28700809aeaddd3407533ca4ba39c77c5d92282bd758b2ce9aaec223172103c4d896d6b67071a3f387fb1940e7f8fc71c8f91eb50201b91eb055bfc837b3863e8a72f341960617800e09fecdf6381a14dd271d0e086962af937468bb39aee875fcc2e75b2a2f27b3e9a9eb8115c6526d6ba01df65f0a92171e0d489e4c2dc5bcbaab5e51f9cf5c043b95189a245847d23d07f7dcec77757fcf5b19c65dfb8a07829928ebba5dc9b5172f6af07962d031aa7fb908be7d7c9dccc9de0b7b9b8954b15fdc01cdfc6fea97ffd870dac8fe468b59c6194be4783c403bec66990e43f2840885ebf2043b9df6e6dbd447c26f209993f2e85887ef303725e8f8088ad3e8c90fba0f4f204de417dce5796d78152a5d4dacb24277a4dd519477ef7c5001af4cb7aab9c7ba7d0c57efe411f38b402c388acb71a55b00fe0b9aee57566a3b3870321d59a95e86edd954e129f8b37752a2d49463bceef7256e03e7a11f34dcd6fd42d43de7799f2c4a6a075042fb19b781f79ee7e9a672a6304804efe9fefcc2965b8a0c88d4e198f070686246930d2e03ac91888d22e84e3014ed9bb96606ebcebe3df87c99076ac752a815a0530269faf7bba74b29ccf4cf4fa29e40e88f46745c60e5c9a6d0b9d0e015241ebc64ae5672fd4029a1dda2c52306d6b8c4424856b3c2bdb99285f7d7f827b7cffefb57f651017ba202f43b727c8382c84f497ff0a1886bd0fbd296b13203a36a8013dba3a1256038d1bdaf78150b25aca3975a5d8ac26991119516b02e0bfaadb58570e950d00dbdd30a2b08408834c4e99e9c578bdd9e68b1c57c87e837c0aba61eee5467907e6bb61675a74985ee2f11ff0ca67d3f2b15f9e69529f58a8c5ee321bfdcd643c51ec9036ed70dce840633dc49c186bd237c33ba3bd5f5cdd32e07e71e21fd0dfd503914498d8f3392fb31b1d9d553cb65909587f7ad38f004ccb1c7aa48632816207acb87c77c3382d0d29491a27d55e7315e83e0635b685b493deb549f0352f2314a3634cadec785c922a412024dd6abe567cdc738b75c5e1dab8f089e5dcb777cb0a1ec2705e23950a9b954e20226ffc58795265c24943fce7026ecf86f56fca1a5fc2b0e6da1395b240d02eb338e8507ede52d5fa516afca8290932ed66900e5818446b0738739134cf815fb3dfc990605b75a2aa9bb9734af5e7e406231ca0270392130e9f5d7bbdcff669dd72c6d87794464a6cdc1b853822135555e80df0cf17b53713cbe7c5130ec98d118e8ca728901bcd50a3c62bb3a5d162c8d3b1f8b86f28e0d2d63c1cb6a6aecbf6b2ea40268d71992ba17b23a1b72e72a511efdec2727c7a4a818e4c1105df1b08d067f20801feeee20a3eaff31dfc67c3f48b165877b8c06fe4475e557fff365962d04e511331b7b65fd021eb222a8604ecb732e4c602c6793d5d3d8486bb0fab51d4992db41a25330057798093963abf96a44eedecc736aabf04391c63d32468034cbaa2d55b06f22baa034a11be8691ad0bc656e519b416a0d6dba9539534747db8b7bcc95cc3007e47a3cd8c49b3cd9055451c5e88058a2abcd799cd83098e4872f8629f7c8f32c1ba33f6e75519b6164c598823db524fe4d8dd0b23881cfbde4efb25a9e48cf6f62b485de49b2ae8a3d73c2dd3290f4eb8419d3bb7998d2983752e7c8bbc3082dca22df9c8169c8726fd9953def3028d658ec102d20301570b9228b015fec416b4f1d6661b408014b85397897299c9a64d92a04e020ed91ce892d001982c885d02f5b9d94c7a6c1207973d8d9f4fa5773bb57d660a9069f4aed8372ebef9d7fe275d10dcfb7de5e9bbee4ad2a5945e3cb09e953322adb20fb76f51944199b080cddf516df3ae053121660f22ff6d420a428a530547b08ba13688f354dad414dd749dce4e80972c30646e0eb9f177d98621e6395981b9cf8274b8f296704cdebfc667f4d8b59995ab2c5747c02e512a8788e685c3afb85587d51d02964aeb2acf00c16251d0b622882c61ca621839f140b4b2075a57fd3de696e23e993e74397006d1c8173537f0455b309cf8754319d3e0accce7b859ae18ff84437628b7b19bab782b8acf3a39b47916ad2b50a1f1920409bdc7182776aed91209c47027eab5f23d8e17a002a3640b8dac987d0049acd0445f3c6d7ecfd823928e7130969023b940c4b654d88d74d91b69664ffe54c66be5072050b5a28b20d80261a6aba97323509938dece4baed5e2b5d1348a4b91b3592b7971a48e8a23176e820ee23a24e06b9e96e96e6472f50d2d0cde2d2e9aada641f1f2c07fd392b8afef5a8b811e2eeda877a91e67542565fcfe68629b79bbbe6faea82078d0c59c41f1d63d3af583aacf334090f61ec4e05a5559bd012dd8f496d20afc4db50344e7c47022c0eec5fec90f4f958e9ed6e6267da61b78222551f236ac7c134a48b9b2bcd1afb402fa29c9d1c449e392905dafc4fec4fbffbaa1c699ae68e486852f5822581aedcb093a212fe8f7faf62f482ca9ff35ff4ff9f8780d1289d9ccaac15849e01c6bb48f5b50e8862d95e50459504950ad673991bedaafecc8ffffdba24d6a5c6d5acf07814cd02a60cf806c1f01f6754cc247cd69c71292acbca9bf4ac29923123a6e8480f6c642c426fe09cc2bff7115011e69700008d0a9a962b4fa3d4a82b0d538105c5168cdb50e11539aa5ae6cd722dd484bd0760364fd470dede68066a1b7731379800134d1a5268e797f8f69906fc5a7cfa7d8528d2d11246ed0d3553b9d43dd24860227bf68813c14a477a11b015edecb5a26798dc2a92b8577bd592f59cc65c55c2a62c3c54843f445e99ec9a8ee544db041fd73b458ca9c7b977ad8379d154060197fe8b7c979af720ea013cdf10988aeb6c80effdab2f49f1e6e12d23d438b134c9e72788a51da1c4ffceae29476b38c7594fb7285324642b66d8e113581244e77f4cb51e0d89bf38d33164acdc05368dbeb477415c8971f142cb9ddb4ded784c443ffb9e3965b00a169de2337b4666c1c6a3dc3d6c60a82a003621bdd857a7d6664901f521eca6e846985eb8c01af96dd4ecd3ce47192dca1be0b3425e734afeba565f3a217597c1d0f40704c2c36ceff4910101d1be676cbe0da2ee2be5a33665b290f433798385d0741f5a8249199ec99c3c488d4d5fed34d59be069ad84bc1f7b692caf17685c043ca1d8912496064b7e84321856c42bad3b61798335ea573c66653fd88c736dd2047eb14ffb37eb4d351bc5ea21da927f9b4eab9ce7130a02276f916d92a56b11bd51d9147e633d7a2e5fac8f1e282890b021d0453ef03c4889a55c26b2cdcb980294242b14284f6c7f90eef51dfdf0e4b6ead49a30e25d57d5f53f6d8d96a5262b870f96e8db51d10220dc5c2e13dd239b6e3e30598ec8b8f89ad1ddaddd12dd2d531b1168436e324549500fd625b96e9cb6026ca44829f67f95273aa6cc1876572e24627620b8fbb11ef391cfbef3bc67192ed40ddefb775c0ea2d3251bc2fad0f6965d64ff69283751c5f3bb1bbc0311e5cb93ab4045b9e61d47780f60c23e396f00097a17960d71552009d652fdaad6636d9be21aeea714096a1126a03da3f8acba96afc6d30e5d7df39e910d8bad71c4cbab98b44adbaf7f7c04a88e7756f62673d43e4d47b04d89bb9da32c30c03bbf1f2c8ee03cd385c327e9474afc5738b078856005d122f818ecc16d4110d42e6721bb6fbe61605c451a9f25d090024987b4ffa2bdb74d803dcd46d292285e450d1a3663634a6381ffcb59029b45461df76400c6d8ff9db0aaf5a626f3ed7a153d0197bdaf93c412f28f655c54a44b9a2ee324557ef8441146f555ef64a0af66af59652bd771977301d349d62fc23088b346facb20400dc2f4b3f49746d69ad66ebbacfcfb11a730d57022a6173abc35374a7b38242013258266bc47a3e9fc30862e7ac1fd5a3cdb70ea045d4e3352f7513fd3a6517579cccead0f98b0a86c33516622072d0c81581c88d6578b3d5028b1646ac84f1ff8418bfed24c001c583e31673c89876af9544f97295afd822304ff71c1add1c45abbec92d3d20271a318b4f731d8dcb9b56d8b6f51bd4edce62090ff9ccce36b92e26ec76603d82d9c07107f1047e7294d85ef92bead14057ea7fd40589efa57797a9453030fdb8859084ed245524089afb8d9d9daf0cb3f2850e25543ef1fc5f34ae715eb75e74d23f98cf920a3398bea8a7145025b138ecd12d69d89ee2c9f239a8981cfe2f9332d28b6e86d1222bd6404910f0ded5840255b223666a7b7db858d38ee5885e5db1f4cbcf4797c28e09cd78e2eaa2a2e8f8d1949a76cb0e0ff99b40f8712f679b5ce002c6872edb9dfe2c9edc033a9fb780d11ce18c14a45b7e19ece97817f84b7647549504cd00bcc857b95871124afbfd81f5f24fd337311f54b27df6fbc1043106d6c00c0b877deddc1ddd1a5b9e1c2ac6332fade39d9e49149412749e9778aadd5ef1c0da31601d203f7753a1cc53d7c375073b60eb4fdebb2d5b41d654056de204b977e2902a267dd569d65cebe7c5c6b0b9e590fb36f2d8e112c5dfbf2ab00f9cd82bc84aac2257dc34a238258d60ba8b93bd4e95a069debaf4d88ded679b4144b53e555ec542df867eeb5de184dcf281e93d793d814d023f7be57826b7853ec46c77536c14e1bae27e512677c1a57eada6882d60844f6b016ac556e9311091925008a6f20a4efa943d1e59b239ebf9c3417bc60436e7e0cf3ea331f328e7d175f2ecde0956dad11608b2a5288db78edcd31944eb6a3703aa8852f01d78231dc1499745a83d622fd607cf136c46a3229c0bd5f1687bb32ea30a06c1eb883e68da66a3b9a0477ff8dab762316ea62200ca27dfa31c89b6ed700af0eb2c208c1c711f8acb139605282590dcadc51225304788e120fa73b5301fb66d1cb21c30376fd021c8e970016cdfc09c45a1e24e5333cedce3b6b2579a4deda7acec0ed27f5f74042be9c3e541c213c7a8c5bcd72b91308b93849fc3ba55f77b6a5b54fbd06687f5d67da173c50ed336e03b7de911c447f3300bd907d2b5080d128d4b94f249af9f3fbfe64a495a38f2fb4d080219a03937eab9cccd7d24c77ebfae35941d9673e19be3f8417cb13caf5d795c83f91607cce85e6a46d08ae425a5a903e4a495beb9fb2a3f8e79aff0675de312672b893656623823fa5a0bfeae4825bd80769352f0e3bbf29c36679363d1c406381b448e5a9a0f604d3c18065e0d76622e36c71793804e2f412b83958c9f1a82e2f8cffb815799a687f78f3358c469a1166952b0095fd0ea1c99a4fc54e9c18ae6824a573236517a0eef6488339ee58dbf90fc43afa603431d47a9e8361a3db85f668d72e878641ad70e0c587775a5d5317fc4f76b0cb66d6d74010a4cdf551ea6667a9542ee3c2849d0d96d1b42b34babc885153f54bbd5e83a55b44a184b33e9a9938e4c3c47038df0691d6ae42cf1df31e47fa5afacedcad6a88b6a0c56372f507fe15e59ea1f3671913d24c67f56a3cac3d9329e8be4d59246b216126846638bb90035d21335a4a9610d33dacd7f6b75b539d6f172a4555d367ff925cbd6f1c8c9e1d5b6ddcf5eca7077bd255987327e62695f2f47a3655dd4e7e57d5b30966a2e686cea8bd6c6dd99c4f43bda893b9f174e60fec77bac0ed059e79fc0a46dce47d886f3ba77d55b4d68287e8d6ef6eb10944df5a88fcf01b8f601767599708a0d13bb7e4a2073165572af0430fc9f11fa976ea24fd277d026078e2b2e99f1ed4ad1f3e09346b250200b09b557739e0e71689c6d6c6f9814b65aa601a9b0f263f56f2e633a6e5a7d1f50ea1609ae01a30d7cee043fb263e3e16b9f1d91a04ee66cd2a294028f9f0081a665ba64931989feff2a628422e8a8b4e192883c16358146a31db6b98db409f892f28be4232d98b8389e5c58772cf38b4449d5b6607f375a344932c67c3f5a3490c20255a70922a69d38f05e91ce2bf29b171ecbcff7ec79bb4809cda6038d189dc0095acde2358ccaa7370d01653cfadba3f913181f7d9a8116572a7522fdd86b603405a13c79c6530eee0c59903c8760156127d623f848edd78d2569a73c98a472d8e95118d27b1f8b517f8ac820876e8bf0085271b66964d9cefa475c85bf6393d2f98fec73fcb112330bc1842f02a6f6ca1e5afeb1ff4d9b4c16acaf63d1f9faeb1a07663771a55a36e208551b4f61b5655044b18b1019f0b7cc4a2e8fea3b22807e201562a61802e1a17979dbaca77536770c8e1a72e538f18edb7c32ba11715a8bb64f305febd5a4f726fb99f9c802e17862a906fc67a51bf4fd1826be0f65a709874af59a5bec2e328bbc2d311e472585ca3455d4500c525f83639582a785361c459376619afb8ea4d19a8a7f9c725a1f02b9f9fdad988462eee3a694ee1b567b88be55873e6d024ce4b1f3fc45604b2ee0daa35e2defd440257d3fcdfc5b111314e04f6d87fcd7a84c38b5b294a41f37a91d6e082bfa4f42f3f3db27955a7f9a933fc3ba4b1bf9f092abf62044b8c7e14f5dbbce5de62edae0c7de9a150908380cfca341fb56798538e1b64b0891294443faba986afb160d5f4eee05e4f59e38109eda99e5cb42b327603bda85dc3b055f2bbfc35caaca1810bce5cf8109db055b765ac01e97a92f96af3b3d730528abbbc328a84487f14e5a08fd5f0cb2c990040bdf47eb062ab21489ae8b64f2035bd13d47da46c51ebe4bc9f40ea9d64812692a18c7de8c76aa58dcc9f42ced4d2c0dcf574bf0b93fca70090cb655fc7a4354981f60764d6ab002c54a8bdad2e89de38753f4ef7cda594f14d9ffa04c6abdba7e5e86ac47b671b970b1c01c21ae93604da2954fb9e669c4d51f2b22dba5197e04ff3cb70ab9e23ec860cce60baaf43cc1a543f0704b00ac93893874108db07040d84fa28389200ba09d8a22165efbc7e5d2f1e3aea21c06569282b2a278e9bb6dc441b5c56d243a669e6a4793911465a95d1d292ed4966fac82d47e6118c370f954a362707a7276c073506801ea7aeddfb9bb70329c6c5521022824007672a1e321ab9c25b6190c7aeb63f17d762608c8532aca2673cc1dea8b483eed3484346ba90d0050481ffdc90af80314b3bad8f3b9619483f5c43aae3d784d6e842fcd0f2bd1f668882b56fca917ab35180bd346fc928d1020b493c8211f670c0d02d0683fd5cd942efe522436f05c662352c0dc6f91c9a6ace29a9b5bfa4c009009eaf74d7c97275512eaec6c17a01d90dbffdd8eb15a9e0ef816d3a4b51679d0f1e308aa9320d8ed85930fc2f9f5c305143bfd1ad7fe366d74465239ca81b3ee868aac81dcb109fa70ec756d0318040bdd8d50f6460004d13c19320fdce1e47bb99e8176101c0328dd8949a95542e73194fcb58ff2bb37d41fb227b9a0f11ce20b5c4a7ce555793b173d07047fc8d87a397035e337ce4c6696feef751e59e861b66683d4d09fa02f3a7b2cb80af9dd227b52cb8e4b0243c153cebedf594d329a8f20e14bd4dd8eb1b3b9e94907801914accdd8aa89e330262e27fee5867b31da2e70197d85181216b94ef385a5a64a30b2be56eaae03d845265551dfd9314f167692262614f909f95831b17d4795ff1c23ea482e9ffedec491cb17525a24f521660f8dab53848bea113f2149e05b98581a9355c836ae0ee3b0bac7960c7ffe677d839bb3c706873e000a012c8ff973d7d32adb559956d49f96a45cc488f66e702b45eea8068ea98e28c4c8c43ae2def4147b98fe5ba0ac584a981e02b7703cf21d32fa27289ffc79511ae5c6f0686687762f3f0525b24eb3bad6f130b449a3d9a51237b92b346af5bfba6c294abfc218fef83e5c2ee668d89d934cc2789ba346ee55387d0ba30aaf42703992b1ebf95df3a66ab9ab036056e4e19c65bc89bc39949c74eb0bfe961ea6adef7d9527b39c31133c95802f2c8b0cf3b779e23dc12a2eb5f1dd8d87c88062293fd264d5b34d20a25d6ddef47d9eb5aaaadcc8ee775e45a61f89d7b9135c45abea8db12e5edba026e86784f3cc47033f85de5ef1e38f0cb989befc6af39bb52149444232b88def10b0c19e32d7d0dc3bf1740cd203fac1ad1ab889d0f0b39dea00ce7e054ef2290766f08b6f302c7a62a15217fd5176fbbf9b5e37f1cd79f9baf0835b6cccbc5b84c4b7ff2a4771cc7984dc18e8e52d7a7aaa47b228ace1b2dbfe2bc9b10dcfbad581dd911ebd4ba3945a8d49d5459be66aa21ea1180ed6bd721214f9b59add1dc5e2bb235a996827ae6585633cc24d76895398d9cf365e2dadc35945dfdeb8aec4e5a87e6e39d435860a82a60d0250267995a36bba8be5ed1d0a034c3a406bd0423ce6b489c00ed5e229416ffefab5e742da0ff0272fa97b9228ea33331c80bb80a2c60c39422a18b8c3e3baf33c3a4c887146dac492ac4b80c779c6d0f195fa88b7220e5e2ad19f3ed733f79c1c2a5db1ff13a85f8a87555daed854bad376cb37cf0860b6b5e64a916830acad08510c07e0453c6e4b7ef6f396e2ec7e21266f80ec38173fef0bac655807b3ab6d46c79ee6246551f87e3b5f8852ba874d280bf5cf78680faa8b459a8dc0252d2077533b36cfba7dd757b09b28580171302408b47b0b898eeaa9b3c0bcb81bc6163a1f8bdf695453cf1177c2d0d015d2ce009778af571222866e3f92f3cd4aca925f814efee8c3f1d293713f672ae8bb55208f36d62538f93bc5d269c55ac293d3b28f6f51150315ab55b6c33b419c338950f41c0782f8242b6e5b2aafa5726db6902edc673029f6fc3491541a1855ef6136ec761ecc31b3c196a0f46f6c0cbb4d19eef5a8edf836a7c98f964f913235abe6e291d6ddb67f01eb3aa6a57bb22f45fb039e3ce37317bbf16c3ef7b063abad4fed3f3916b05cce6156bd3d65c34406ad12c35031458b10adcf45f67d7b6604d4c7fde9967b4337569ac570ea97e32657ef61e54feffa57196ba34a634d11d876d54f8ebebafd9b322e4a5857426fcf614f94d011489e898d16450c2e970f5f80952d5ac9f72e57a9757855bda996afdae622026e7cc9c0b981fb6204f81b4b8af470b9199d29d9d214a090cae9b9227ebe7e2fdfeb09c7487d5c94c9cb729b99e6e96c2a2b0d16244a47a3dbfc104dc2abce8cb33b468a22713c494aac65b5b7484a5bf694becba1c5487b3a48d149470506c792338457f9f73ac04acc45fa6ef7bde51af1876cdc1fd5b011cb4fb899c9df3161d0ac27a85e71d4f2f726980d5ef42e37d11263961e21226ad8487a2198a5b32d00a583894926b17b44bc2057f38dac797514f623c3319dd649ffbc22f06cb4596d5319ef4964e7bbc6c5643ba586835895bb3fd4550222faadbd3134afc9ae829e2df6c43a79f87be4a2957d8c4d4de02f6ec66ae9f92b9f3b6e8bdee777214ea8b7ab432797fbb7b2031a8d0df0e319b48e691230909f9f33f1f730158f0d705ccadcdbe022fd68f4d443ae9d5ed028ee55a8ee6327fba8ebea810f49b30b1fbcc3b02eba5197ec4d31b1752b480b42be7900c09d6dd455de8e45d4afc126ea719ead4d8f7769c777664ae7c33eeca909f1c26e52d260151017b4d4d7173bb6172d5b2fe34e3f66ab1e412e8630ae7f70f00925d52e4e7b7e9cce4131921b3185ce09fd13cfa246dc728d2373c66de62341bf3cf7e6d9c5acf40d7260db0003296bb4c78dd0d50b25707978d3929005e1f2dbc12f3756ed1acfecbd4059981ee536fed47ab1d21aa351e562d4d40161bf52c9143e3d7210b84f4c8181a2e6d0f6555fc65716fe1edabb9bd8c590b68c31a413899d2c2340ac165e4a6c01bce8d2bef120bcb89d954b6bdb1be4d52aceec58a63d8e738e36a302c6f3d4023e13401eaeebf27c0ace08da164ad4dbf67bab754e092acec3bc159d83609158b8ae86ee4324b14c7685fb66d3311f5c4a84dca5a02e17748d875e11871b16396b0adac6c82eb1393e2ec165efe5a4d4017dabe17636dc14f35cac07894601b035f986ba34b041787b9a8796895d2f6b67d44c937b3e29ece07d02124911c541c4ed775c84f6110d57e6c4fdf549d04dd2c8fec37dedebde449334e8ce7410f23d6f42b3f176ded5355cf79d2b396dbe81c1eb038770476a8d8f5ac7b3c2195155b0929308f2678cf76859e593b1e55860ce3fadfcbbc8dff46c6900d34088803e0d6b06be74f5df7e110e53960d327f0aba5784ee7ebe41ef0bd72ebacc78e2e8402054c60e176c1d9f5cfd5ecb69d2db2ea86120316a67804a11c1eee49693dd391f7e774b7b0092c342599170f7ae0ae5447acda7449b8e1bb6b27c657b9bfd85c1c853667623cd8c85fb427590a93f79cc648e040f6eff7ebb58a9e795d2c5377554b4c73581c3a332307b665a9ad8e77372d03eb5714aa36a7d707e52c3928ff3d7ec2043c49aa933443c407e38989ab105983c3c9df4ba89c9ca6babcf292c217bfc002b6d5b41ed5ab93e4a423901cbe2b8a54f7036b8fb1f448186b8ead81f28ead757ba4b6da52bc4f880e2a15ed320217d9f642917580c8aeb0b532cfcc215401d9dcafdd77a0859a0eb7bbef015bc1caf3a7e73a7f9e5bc5ae3314fe112e8fe0dd2678ade83e32eefc892ffb622af1f97ba6b9a6351e4c1d7206106c2f454b8679c05c43c5429e7d0da144d475db6ef27013e74dcd83e2599a6addf46e8bf74e371561f35faacf09910b69563ea655f709de964244da9af7e149d7f344f894aa4091c75fe08b694292b261f903e1d63db38551598d8f45e70e23201147efc5caccf36115cbfb20648a2660b0e53eecea34ffc21775a2b265d28661afa489b258587b626ad06e64287b638a7bf93f58649b6472e2ac48c4126e4b5b29bd2aeac2f36b4215a111d9cf957cb1d8e91488e2e8be8225b0934032a52c95e7b5a32c857abe6384f3849facf8796a8bafd4f3b28e4b809c67cab9341c411bb0cff83a2b8491ef38786d7d1a435e93769dcc89c62b8a0212007f5a7b6a0957f070dadd49007ba83e005c827f55afd8d428974c229f4159015a1471d06e0909de5f81f275ee5288b540d79d75cc8364c72c2970f77a068a77cc3e78d46dd87c5882e81bc7a89a83544596bb9a7e77e5ac668c7278ebed1f259fcadf4421d10275cd1c76b6732a1cf81457b0d6bb1d1ae57a3c35fcc5214e17673b70a05fbcaa5b0cee71f902940102b9028f39ffc0b2bafdd47f8585a35424403712c99587e0e7926824127522a1d7fb8edf54063fe29ef1fecc37d5bec0a635eba983253d5774cdf22830ecf97684a10a030cae4e1a3a7c156a84398f8bb2411c9643946d6ec7473479984294e2a5189460f4d9da5eac4b1d5d76b1d1d67376a6630de6d91f5467ba241d4f98ebb5b48eed7e5ca8d9a4014f329e36432b8eb9cf92fd4e15a28ae1dca9ae26d304e5c7b26a4fad6d86a46ddd099981355f76e157559c49f652d52629499b473999f63076dce4fe42542a88452fb5f3eee898134eded5563ae127c692ecb3d24fbedd5247289fc078cbde8edc5eadf18c9f7526600e4d7f6fcb8a4a8d7735ebb84ce9f89447a3f63232b43beefce05bfdfa424f1bd2e0caa0f8935f67f37ebe15fe067904bf9a96ed7729b38c4e78d3f8dd1a873f74426c34586a0655e7e659ba93491863fba39958b9796701b6d7e660e168a7d454fffb3d069fabf96e47a34d5657f2cffe548859a6e99370d0f8f6a929b913dc8bdd332ad0cc1c4a153fc4c8b1a6cf0b55b9530a3ab3744e903a1ce6dc273a8c1e5e66ba30bcd7b8e115528709ac78dcc689a176304b2ef593c63354bcf45d3820c53f7edba2d1afa35cea101408f058684bea0bde8f4873fd69256ad48e583223248863ae154bb7029b9859b3d8293fb2e327c1a6d42c948541820e840c4a5142a7c68e539aa6172c77106f4b548b258a140385bda2d1f9334d299e2b6ce1f78d5efff6551cadb569af809a364643b8463c85a7d3b075f5ecce2ce31c8f3d01a9492872f5fe8b2ccfb70c9674cb5feb8481b547a56916751365be249ba2b941260c1d2a70a2beae80edd2d4af2c37ab86761ac17994e164d2de9f1aa0ff3d90968fe521aecf1b95122500370ffead77c58fe4ae86be4e343a7e737ca0b2ebbcf91eb50202b91eb0fd4b81a86bcabad099cf5aba87f1d97c70ae1a07d3bb3414994c3c7d0f4af6f8c377c4ea5febf282ab6215c0c2e07be9844bd2931fa3c37dfd4e85effb7515c8ce15ae8f1b148d11eeb4d2550ac8af9e25c063076b74e51551f9ff58bf6bf04d85b225f577062731e63ade7f992596bc8152940b6167cb719948109a16ddaad9055fa15f8512828603ad00710118212f071817277d296f3b5abee643bb21bfa343ec7e0fa315457735cb985cee5b36b33719fd36f6184708a95ec1a0f507f9d39fc570553dc56041562157eeb1820f76ca3f5e5c2a8b12d3cf73df17f1d28cd768afc88f094fefea26b8d03e2db2fe226d0ab21107a4c838af43a3ff69f64fe15eec5911c720dd715a3add2317523e58152af2ec0e81dc6a3fcd03404147b1e233a551a56db41d566d617cc6a067503314ae84369252098fa0ce597c57903daa9d4bffb5cd0cf65a5212672ca932a4f908a56e8ebd0257feae168b16e7b2182e109e94211eef5f804ad7b7f626ebc87c91d7abb09539250ff0708e4b7761cc3b8e9b82571dae4867228dd210e7e58000cd3200ecbcb535a75892d535693d59520f3b995ffe01e351032fe3eef8001e61c06282d77540f52f5e62ef30e03f652fe49dad9162373f1741c5bb618724476ce1ef3990ec5bcaa1c0078e893110fae3ec769f86b7e29606ebc22fa251490c3bf70d6952c78b5279e4735d643964868890232b70408aca381230fad13879cf3fb206b747510ed699be0ed9ac569df672949046da044bcf0019365ffa275a635498f6ac7fe3b8843c302437da2620fb5668a18cc78ddf67837bc9a657bb2793bbcc3853217215384fe7e500917a035ace10266c708e50413500e0a0ac7b3a1f92d2f8d34f905cf6e8daa86835f3bf0a965a4a99af6458a9710bbe9b9a7eec47a092e613bcd5477f3bcfa015ce12b2626c8fb5269c6c2e41b606b6d0fe39d80f3aec90289b81365437e4bfeec050bd3965c476832712c2745efb0ec87cf846f2b3e59809a9700b3f8c4e9b233b53a8575168991a10db0389008586e5acc6904d5d4bd2adc1278ddb9ed3fe0df685c52715f52176154cbdf7ddb97ea66defc9bb5e69a6e41090b75a29213748baa4a7e23539a05124cf2262c17d3a41b8e075f887e9e2c3b5826263176eaab6ff6c8054a00cb22b84677ce974a05b87917e41ccc98f177e2ce8e34722d5cec886aeedcabed4ec99b51dd2583b265743cea98a6f10d65f98e9ca446c64c10602acdf2b0f3c0260fa37ef6c0f1d82d9c870f0565cb508b8af15e5562f5f9368f2340aba983c9478b6eea386900c157ba3ac298597c01a746fff3ac94b4785ada67622e4b420f684dee13ae154b21f2b2a1cd6dcc515120fc34c32fc6b271aca166817533680775afb65d62bb7b6568580dd4b3f491364ce1f8530f25fc894d3f0e464c0ce1665cfcdf07dd592098b019ba3b9298e0f3f5cb406e0f478aa2fa1ffeb3569aab1b37e302bbad320962b5ac649fca297fd9ec73cb4167f946a28b3dbeba1641edf12e6a94cfa0675addc44599e48472093b590b553358ef840862314b1380724b859f4375e8961faecd46abc8e2ae41e62bc77e8c8419297154f1fde620863c11276030f92e64808fa7b8ac27cd546401f91667bc1cee5b667dabe850ed70509c916ef738c982f8c8f958878bfac0532df38adabeee3b17b8f182af736c807b8260c1878edd0e008d332e4f41f037361eb9d760e26bbe094bc3c7c0b89b5eac3fefb39fc215b68f2ce2594b980c07375cf8f46cda10973ccdaca60fa96e57b93002281ea3c5dc57f7c6d2cdb142fbeb3ac835cef960983cf179703e0a9a4aca2b084274e95fb5696de743db052bf38fcd1f1a407c5998a1cc4afa8529cf1adfce48acac36a7fa78f080bae5f5bfbd402f24ee8fbe133e87e1f2271f85aaa13c75b4eba80d03cba89c05bbc30cd18d3fd4f70f20d13934e71f06449dfe61ff68948e0351aff047d122ae3c62e8f470b066e0db4a8caeafb25da871a5bfb31dd8ebab7c6c7e29a5426b2f08c78783feae22125dd8a426047b4c82894ebb2502bb556cabd65c6f3c176a8fab1de2303f5250a19c179c786494da54ef0f751004b3b39b3dfce2a11637f3f0a283790b3a910da502ba2bf63340c4561f0516095e09f07345c2a17652c497678930aa8edf2fb72a73b6df7a5c6a088e32865723262ae345a584228027ae17437ba142242932367c2cf10215af785aa3c9d319f9bd11714d0e9a8fa6620d28a628b56b3d0872de9bec3e1f86e603bb8b0bdf5e1ed88dac21306ff996e739beaf96c7451bb3bd9e7bed6247894d5af7e898b9d7e510d6818a4dcc72a1040be9506aed0b155929eb6c9dab4d73602032fa76ad6d5e7985fd36a809d497a38dc9ed38bd8592aab4fa3fc300f8befac9f61d441e439bb94ce584ec41462f37182550dc20bfb068cdac2ca83e43533d2ec5ff3820f6d40a101e2f75575032a208d1b99ccd62b65f526a7cdd367ce4841cfb1f7fa3e4dc46999098e23df4a16e30dfc8ee41df6421515fc7633a7deb2571cffff580f70ad13eeacec2287ccb049b4b7b68611c4314cdf3f0d67b5c09102b3ca65ae37eaeb494cb1d4f1525dbc02ae806610ed1660b93e5d319441c1f314634cc128fc9a5358e4610b9318feb1161d319cf588b97d9081e3fada586a574b2dc6c4b72a3509e4ed81a9897f66f9ad59d86f0f4721cb5be7821bac8886926518a10777437695c8e5af1a3054369390d0bc0c6d19c6e10a097fd2fc8dd478fd032968741b501731fb7c795bc26bd3c43fa9658db36e8a7069a4ac083437c77e2ff93fee23e98fb788d57239e3d76adef226266b69f689c70b4ae15bae38a811aabe95167f1259a510f46468d3fb47160c5d4c3c960b2d8a10358a6416a4ac1b83073bc1f4619382a820ea30cce98775ae6f1e7e7f28259a315537a19f82a7abf59d44558412916acaa2191b294facec67be90551056b75411f845391ad9205036dee48651e406b7a4b269201d12c4230825ce744b9ced3665a9b44e32c72df77bddfea8ac20d39fe3b4b4d59adbed2d8716b2637a90885fbf58e602d80422533a6eecd107450f20b0c8d1f004b293acfc3d945532dc1c9f71da2d229e8e923dba6fb2a11a8f4f94eeb66b9ba1c316d2fc252e023d6d505831d5c2a404f00691595d5dc3f504841b4fb7308224ab91bf17df61249de5568e4be260e04fe95d42efd6a493a80880a4f688629dbc59177f5b3b0d62e42788d0895c3962fc3bed0f47c25ee217c2349525598baa6c8a41533c13f9bc2ff76c9b80d229ec2f838fbb7cf7feef16a48cc9d3b5fec3fa85be335d011d67bf0662c4f5457704f2f365a6e72bfa51a6c5e8072646cde9b8d0ddd890915bf669e481884b9913c3a9d71959e7d59d7b44090015f6f67d9bddb5361ff70fec86c3ea5d704a513579f0deb1ced32b73c97b71cb6b70740e129d8a6af854ac8b03e9ff7885c85d3bbb0c44681c66f5c3f0ec98fbb758763153d03310d341497c49e1cfb8ab46daf9b96581eea0fc23c240da09aef1418cbbf515813249f616c4297b23f22975918fb2971ded6aeed5b92b1bf8c87a729455406daf463acccd2027c29e06ab3fc88754f15878d26ad948866a2226a886138a3365660cc737eac6fd31f6a9f6a06cc412dad836078d2e18cedb202044ecb727757a240026ee2c30df2f5d5d9b86764dd9a33d9e9dfd2202dd3280c072022ec1282faf261ba3fb1d0123b1c2f04ba8c06b82a5f71ea3d904bf4f5a562f62f2e05cbae3a01a3e3e4d267832fc0407510c7d73e5d4e1a1f081bdc449e5f735805f285e8abf072bcfc235ec0d416be86aa7354096620e2c2f1fbc1eecc04b8dfaf90c5dc631a028a8ec0af478ec3f546354995c19c2cfbb761f6e704c0dd63ae76765c611dd7880c9bcfe96b31d07934b9de2a3e60afc911c0af5f0322b9ffd4244c20259a4c7f4bee3260bb77047a7fb469ccb68f86ce1e9d7e15141e278c6c6301a86f11a454ed494a6f37c83b34519fea60ba96d97587303f6bfe995006bf6e593d1c89965b457d76b94d6a6db498e93e8084e71db9100fcee55023303d4192164faed95c8638425ebb082fe14cc20a446942537f03db3c1fb6e458f50b51c2d79f7ba28fe639b6b9dc7b4b1eab16aae42303e091fdb8978fced6458d674ccaad2e037591e7e0378fbf37a9f7ea6aeae28b256a9b7dcfb414d4542b5fcf9e39b271d87f9d744140115709e497edbc2f84882df69f23131bbef6db30c638870088be060b25757ab346780e4f931fdbe93342f33af6f9215ed0cff7f268e858fc0174bba06bebe5c577f52e71631cb70fb21a91a39c14e1a28774cb64071f0997d1c2925d32e41a37483e591f3d602554aa178fc0f8471e343e3a2f969a37a24417160723e2bd23e89b9d9a58f128f22712eca1b3bad2e063caa5d5484081ff25c82a54a0ca3cdc865a43f62c438a335f1b3218a47fc3bc8656552f174264876ed8fff1a7007c72a7f22a41f7e98c6f6932d48dd8b939a55c3375837879b8f605f35350456bf42ef4abb035ca7bd0796a1d1cd08a9d59e6636e3acd68504a0a8957a4a45ab39cb80a06523ea95cb09f198216649323057d8fbdb42e1d51aec4f73f0804b54e1861d6e1c77972f6c13ed594266618d5f03d6ecc3850eb51455e1c03aa9a8d742fb5b287f3b1a17cc48fa7f0fadfad12d37af49ec551bdc2e112ef5115782d80ddf09b9d87734d014c69c6ec9be3be92e78157dd01cf886b979f4fcf0bd3346911f208f5b85cccc30df31801675630de73d595fda1f5d42263e2fb5045c9da897cc8c5a529e35c672d2a32ac5d7d960f4a309b79d12603321a11341f0c620931ae30e60dd5edc1826efdaa8eee28164ca7c8340a7317898643dbae60a61589c7989b7ce31e7d9cdca09d46dad12a244a8f106b7a61ec6adb51ee803dcd78b6621c6243edb5cfa30935686562e253996f2c36598d94a040d9a7d7cf25b00efce95ecb4dab1c0ff57eed164c2017e5188d2be1a3e2ce7cb5d475c141650829b6c079536efc986a10db72d4d96ce1a81d156a3677a8445d4920cddaae919d251466852052aa3dfb0b188b6cfcaafbdea546bc293a34075972d81f17bc7de74468a1d90f22e32bd4d8425e717795595addee075d0068411ac338419075d9016f1ba5bdfb654768e239f56c31a08f22da74bea7169fb7a3fd7652bbf1775f13b403838a04b22dd1c0d59feb4f9e05b16b30df907a72bbc6aaa0cacac87870f7e93fa7f800abe0145192c5ec03c7e352fb8ee37a7fca3036fdb6d9daf4c4a65eef6c0d48751693ec1cffe23f7813f83fa24f6603f46e58282cc0a87ada3f11325e29df7815b4b50933bafa77840edd7c1d6c5b73b1463e993ade0620012d3541ff7be3fc2f6fff2362ce6d8496b9f103c860c895bfb866189db69113bb87dea7a2f9f52d31aada16b601c5fc1a279c726323ee636e6a2d1297253ebc6e641537f06abe2c976e92b4ec1d05b3e8f1177713c40479be21b161bd5a930423c7fbf470592805b1a27c7e3cdbc9ba5f8306f4a08650bc0e6b59dd35fcfb91db7193f5d3df10cdc341d1c2b99b7c4cd1f1181f8855d744a4d37fcd5f594d67414f4f7177891260078da12a91174f4eddc10afe1c79d42b3bea2db637b53f3383280d5947b441bb15f217e9a6a91addffc09e325446d81d7516e3a9afa98bc5c2b2a058215c4677377a94e3ddf6f9ca269e86325d2bb3188a954dab986c62188f654ace3c01b5c69b2f62cb1b3bbee0cea42b4289acbea441317cdeed679e8112d6b16ab2ecb5586f6ee7201b270c4006319af3b530603bdfa00cf938b2bad7f4dfe713baa23d0d1aa2a512afbdd44c0848f58cc1556bbb5314f4ff1b1a4a8fd38edf1cce9ab8e5aeac34316ba2f03184c02ad1d655c891bdf9b3e099165fd8fa5de21e232e213c2768fdd3c91f0cb403b56715b642d0f351acf6ec2db282e093965d62bf79f48f3df710b9277b95d78199e5029b036a74b49e261d60ea6f601150658c79e8df894e8a8450a6ef4a6b3ced132e93441097afcba543a17fab0174aed3baa4f93c79fccfef02dc309a7820a8a40d44aea5221ae723780e97f1da364b100fa82141a8d86a6cbc2e29217b2afeac09d8d7beb9fc435813beae598099122878906f0a1d800ade1082673eec1abc3f8375f2514153d3d38c7daae2aeea2bc68600f0a0bad6bce05742adc67611e737035d83e8d5085f43b89796043d84d1834b506c0c27c00781b5af15b68735837269d0df0b7428f83f21f8db57dd5319c8332c22e15672510f0509d9ecec362c4447bfee11a4021a798d7d4c088e3eca6ea6f1266ef9330b3084effd1977b6d2a832dd41dd9aaab03bc99353f5d1f537435899db5db07fa22fa31180a47e519226a9fbb779fe5b3d1f6c401eda6e60df05093540205b1d315ca357ab6432a88c28597242050e816803d2c46ee136bf41e0c3a00fc60695727343c6789ce7b9b7e66feb75ac83c663d50528d7debcf7337aca7c55d011dc8f6eca8f2029d16d447fe0fd808b4f025841d42d93e22703e615c1db2b3cf62df3493b93b99728268c7a044cc044f1e2254cbc30a18e10f66f6f59d712b05e1f3318eedc9bdcb15603d240783b43c4d5b7cf24541a457934ebc3eaf3727ff93bb0296a1b282997ace50f4024909a0bff344b84f1eb48db154e79d2c5eb84e7e1ea39fa22c96c6c7570bad03b6e7d80dfeb46473dd54906e90ad802c33adb49485a3e28ddb4461a2d6460aa5fec0bb36277733013f56f079b1e393b7efcd8d238e774163051a5952f1e793f69cfd4a661751aa1f09638c945458b240d7a86d5bbaebbc6586cce38309e55309189c1477d4f83bdce85d0bb3802b5da91f7bed3c9e68065a1fd50dbe21dc76891bb5a827cff8f1846d32b20099f27d478e649b1ffe77e24def6e052546ade40b96d2c19eff0d1c81b0e513a476ae34001f0095db99d5be8e7cb0db5513ca94da415caaaf06559c4ebefc66c9de4ae6cf831d2618a203b884fa8a3ea6c1b595bf10ff6c756bda22112d7f50e5ad671ac040c7aa989c212d1c63a6e03cb58054ebcb1f6b1c54a1b531a97dd045bd7307a148cddfbe619349a8c277f3dcf6df3e65217d355d366cfd92f956b05404d55ec65554395ae0d2de9a269f439b29b8bb36d0946fc01dbdc315924b8197013f72235f56ab9f10b83c77132feaed9f6a1347b78049c81318a59b84581f2db9f15b7f0b5457d95757ac2be733002554814f067a72e1db1e3e34cd3df9cf445c44b2b7230895d19abdb134f49012305ed20abab6d58102a11920d65364e2a3de33acd08df4e2bd145d9d83f155776e9716072afeefc97cf2f9699a1302851779555e78b616150be535cd304b41d0b7117883cba27c17b6afab102d3f4173e23384b39ea8a337ff7911427967f21da5bebf4e831569ff5d479b8dc44717a982a24d0b705a18da717e41751295a2262d13d973f4c2804e5d174bac535a2bb341f968d93979a05978bb455a010d82ef46df3f9f89220dea581d157129b650bcca89f0ff96f876fef0988e1c2785cb9860ab9a9debd4fce691a879c3bc17fd0b6cbfbcd91278137089ff7bf0cab56f3f0a0cfd41efa1096a694900e0137a3b6e7e01b74f67a8e6b2371288f58e16797bf28ad47c1d8bf89a55f57ece2fa2110b23d4cc814b093a1e5a33c796d55ab623fc0cb3220df82c344ad51cec4aca2b692b2db95487ebccd4dd27f8015f6afa178518595ce0cc23a97cfea2c33ab2c67a1d41513cd8df487157c6da726eb9d87021312c6e33f1b64acd36aaecaea2696f39d1fac6e60d71d15c7e70fa1649a027cc7b096b319c3ef8593b69df603f0539cae84710352eab8295177e74662c49cf6f2bfb6db404d20f90e79a65489467bb673271d9e112be367a97deaf8a1e7e7f537f310ee051a299f1eb9ea56498935f63dbacd51750653b43eaef4a71ae2808f3df8841cd45cec3a9cf44d81a70bcf2069a69eff1a9a798a0929e6eadb455e196eb36cb6dff4f88cf18f44c711f2218b804681d5833acbdafc05dc31468ef3e2c23bc82374652a871f4f2bbda6be75504492b8bf23a0f13e1cb1f145297bd4916d9d66d53f28be747c384c247aa8748bf902c26cb302a183de0342728c72d1fb226d9d0a0fbd435b13077a9bcd87fca54f2f7196c0192611ad55b287d5fe87e5422d1579e6a9c70741d87be5694ce8951cc72f7e82953585d589a42d443a3c452968548944615d7201e84600205d4d4722ad57a0374aef39cc38b194069fe9e2f51929b7b7154c1e914528d8f15618e14f15d0bc35246e89e39cccc059d452531d3ea36593a77be48bd48dc273d9ef1518c61dcb338987a9d8d8073f4a55ca026612a4ba839fe4edb4b8c62d4059b2bddb595f148a2388dbaeeede9285ab2241ffc37edd94cd8f0200bd6e2a7ad9903bc63098e51dd7f60dc524bf4daba630f7b15ad0cedc845570a17f0f0b572221beb1eda03b395eab53f7cfffb9da554d0ac63e1c5866391767cca2e003824758935a426ffd10432dbf58fcb134b7cdcc50acb5ea93364f4f3edcd428cc259bd151f752af89e57b9a62f088dc087c542b1a2fcbc6047557111248c92213082a3a76165510e6a475830165e516704833ca82b07ece1885ca1e16de104151f905e66b555cb234b60a0682f8e76927757079a85e6a069712eec38d91fe6a4d7faa658143267f78ad40f56afc7cd98372ddd19825f0b5c75e027b42eb613cbee07dd6554c916c5364aa4cfd0e56c8aa2a433a2d5319f628647a0802b7015b0f6fd9f9bc04a62e779592011870c476c6ac9d2f077f96a956b8d1b9d05276b0d24d8fe3791bc1998e55dbb7ea153adbac8a169fa4dc95e1c1391ab88e1a68f06d5893d65539b45aa831ebfca8f7eb15a1f226904061d646162863d913c4842ec2e080acfd0527a04a2b8f07b8fb07bd7c2d3afe0b2b9ed15ba5ef0d61d0f8072a58a08c88f4d6228f53ddaa4f2971c611617e043cd782169ef2f37d642400ec32d2426116db58ed314778e4a7598c34c38be1e5e44b13a99b14dd4d3ce1db9633830eec9d0d1837982c2eb2feddae1b868cb361ea06c86d9e940dc281b8da59b1a98b5a3371466bebf00f414ce5be888b98eb81c3e94abda5cad7b4960bc041197690fb8d3a32ec9aa9a7bf03e0fe39448e40aeaab0d1557af0e92c569676b89edd8181e779ff5d6092af7be6e9d676deb58d02474f797e760f44011f87447c9b4a94a9bc970135a373be00755d1cde7e4facb11e97dab95cfd64efab7f53082e1c26928537fe8dc8c07bc2d435c539104435598b576ad5c1bb8ec3ceaf25f8dc92afc7b3d130e1b00d8715646f7a4c16b7cad99c370c52c330393f87c80629234cd9659c32001948f11bfb47175e0388be8cebdfe71fc8d8e240aad9520a3716ebe146456eb8957993b666c61700ee502d9f880332243afe26ec0aabce98382881892ee1cbfc6bede3260c4008a70b0afdb22eba506eed7bf8222d55fbbeafa88016759d826ac5397e9ba501964e896b01b24da1bd0b5bf7f5d8d19560814e76f6ff9f0efe2896839ed57557fbed84f6542ca0c40f4266bf30581f4d30957efb52555d0433be22f111e8d84fdf43d9bafc9434b3e96e253144d10071448af2e8b5e635251e8783c51f4a8b4cb6945ded1504ff22a76604cf4f90d9979bb2a65126012c533a22069653c087dbffaf3e4299899e755c1f351256f4e0c1b408d966c45a4e0069dd38ed5340144853367d400e22ea542280b6ef5d248586ea9e519c2414dfa04ff32c60f425e069b20e245d2939dc10be0bedcfa7e321482eb570433c4325463fdd18d93d29bfc8c52502b5d3866e3703c30bca268c7421758889f83f5accb14a63fb94713cc7663c1c586553c6d55ea82e72cc90d327d0c7c6fc5aa96db54b4677f722e34acb8f4bd34320a5382fa69202fed4e6b1533c16fcc30c8cb528d966f04f62114f2e2344c28fd0adf04983bd786010fd3556c7bd3d774a6e0e050893531eb7e52a2fb2d96c0eeaf2f91f5ac9edcd7089d4397cb93ec1e8572757d6640f954a51fd70a11a7666278442bc6db9a74ae19b4bdc6e0a3fea13de68de932ee5f104fc732e5512e704cff2792d7e387f38475e4a1e09b37e07436448aa8b2096554a87bfb5ad014c2fa456ed672a00c0852b56d9b5dc9d21cd89759faa9c59dce88bea81e10dae75daa08167239ca685bc9fd5c6328a9d0c45b1e797be3548ddbd9f184fe3f8e99f9ddfed7ff907bb8f195e2fcd2292e1eb88c61788bb4f368fcbc2335d6cc878ee1ef5ff94742e4922ae3f4fbfca778be264f7c4260b6b452c737b409fea79eceec655217da08b5c1d2aec8a86424e1eb2561e6544a7c8088f994d5ec5203e9eb30b96769b0a61c41e61b8d7ea45a6d5221427ff4795094097b24126ba297a1cdd2009c916d8b1b9addb01a4cfc1ef2dc5549ecfb650e65161de5a5db91dfb6ce1db6dcbc351c4af751dd30b7ee70a61031b0425bfe5b2cd5ba23d048aced73914d9dcd07044fc0aaaa2ff22557083d53d2fdca355b82b284b0d4bea3e0a46ff2fb5b796456c45e1208559aa94ec2376af50ce33ba9ab9ae81ac26396d4b2b46fac60d9e0ef58d618228499e769c842cd750529ff2db168cb4dd0b432795d01a1d8d191731388b86a5b3707afce4139f5cb6bd4dd58fe98b3087dc81af944db6e341e4ade533f026a9552fe49f142e220caa546f86907e5a816e7205244399d6e30ea0755bff7554158bb5eaaa7ec8e77fed623f327f355318be907a801b1d5c6c82b7d5c18be2d2c22220298a3af36c5a9f19e3ba613a9ef4eccf2ab92ff291eeada665fc9e5c4585d12848a7f872098bdeb834eb2bb12ee45c562e533c2a5d242502b48ecf02e9e320419f49b3fa37f8b2d3653fc4580fcc274d9637fbec9959f12ad68141886cf4647099b698bca89443fe6964b5f7173b1da5ca26d169f52104c57cdf307746d22d4b836963e022aee714f9cd6da9e90cf7fb1e4b7af4e21eab56358c00721dff902920103b9028d399f1113c26c7d0990535d026feccb23ca82e3959e5a8b55603a94247950fbf15c605c7af80ce1ef8e1678be5e6d20ada98d264f3faa8762071169eac1b94db323e6a5db0fbca12646cf3bb3e17436b9f4a57c91c10e05990158e57eee9c77a59f89a92425b04130b70630e9e5a127be6fafb5904cccae8e58ff2876ba2c5f65a5b550a4a95ac9b8d20a13e07195ba429b75b6e5f712e6df05f3b315cdbd7228a26adae982dd1d89e5629a5af4316f7dbeb1c84ee20a5920b09ffd2e16baa44445e56d347297b7d0f3f520dc9c912d6c338414a234f0823565813e48138fbe2c1f2b0da77ae76914849fd39d9938b32936050f95516e15471773489d909641ba6f6e8a23232992368d0ae18932e4fa84fad59863c99dac1aa7f99ae1cddc2bf4289d425bebf11f4e5478aef6eb06536c0f36d31b02ece91a7de620990f93e95ab0a91b581ca56a2ed1a5fa63911a4c1aa9c47d395ceb9e6103407677abeb6fe177456a3cfc13173f67108765fd6efe52fb698f8e5332ccab1a1cbc75018b40519cdd4bf9a6785245ba0331c0acddca45d6a716d7a50416298c3b92ed1427f77bb26de3308980d1951bc1c4a24199c29343a9cdd034392b2b3e420481c867ddf46389889b4c9ff40ec4de5ce033679b9f403c7f0c3a551cddbc0d4279248eeecca14770a3ddacfc7205f5a6ae122df320513baddc6a1624e9370fd33be6c7d7c2f546112796416469bc522bbddbbcae72dc2d03f2efb97408ad96cc949418bc9d8ca9ec9c8ac314f5ec248b17aacb935c39c4965be5da2a31e9ffa44e949e13a48d47d92c74199e53ed09abb31ea620b74ebe779e4b2e3bcd511626cc22f7c1d6d410d92330ef90a47ff2f8fbaaa7c79cba50ea988e2d01c9ed28dad4ca378726447ac97ef6b7caaba779419b68f91eb50203b91eb0041f51e9d5151f76ae4c8b4931a85b299e297e5e001035f936208ffe40304c5fb45c8c0c40b96f3d01a129321355a2d3b97127e736b69c65fa6a84875fca2df86191bf60d3e0d34c56914ef668869daae540df3b4e955c949ddb0effa3663c3a197ad76418048f417d2358338423cb91abf1d95c0cf64b88f21c15e0b9aa5a8969ba66cffa26468728089111f51b87d8ba1269581920af24a8fa67b4eef208a70e41096c5a0f09c6fa0b264e35dfef46f2eb1f40ab6d3e442da5c9ba32417df04525dd41718b7459e30ec67c253feee02ba0e522d361b1c2099c6bcaa7bdc801dd37a138b15ab6529577885a0e29bea6f3d8c34d095907633ec38b1a9c5dd722938792561546cf184c3b05870e6ae22b8fc09db08bff161f259572a8c48da97fa2da8d63771926d9a66226c85b088624c0bea714aa480870fd9ff59e4601aefe84b4361731bd886dbd983a270e4d3f7aa445bc20cdf18e14054c2c69b3014bdf5c116efa637ca9163fcde8c6309420eb35ca256b607f3f4b9f7c02de86467de47bb065ea07cce61dcca4f7b15e2798f30e472635ce5edfec50487d076655a0390b6d7e4c5bd4a308cd1f0a1dbb805ea5772e32fc4bfc876f2143a9a3e77e536c0c67edcb0e4c89944bdd9ae1aba43ecd2847bd1f510f793a2197f7da3ec9758f5ee7d61bde86114ded38231ada0b60d33a602d2c72e65f0bc193768579a60213ed50e5be55342c7d9771432581eec5afb7b64af8fb2bb2f3c5855a96b11c2855f145f30d6eb980069fbfb03bbd37001b06a85753d75085f96ae5fde939bf7025e6da61c6f5e45344f21c12fda89be824fd5aaf1035d3a8f10a790d81ff583f26ac209f83fa8f20c4b060ef1bf13645d84e4ffca1acf384d1613abc57d889f1192fbff7d6e13a2bd2270fd03f6bb0aeed9953c93cd2dd27ee9bcffbdd6e000d13f00ad09ef4ca031e3ef61731662fcfe9726a288f7af79f92ef4863d744dae03b82c6fc2cbdd488e01b5e145f41cd6f5a67df40f50acc1dcc9feb50807b8b175016c8cc5b10f361dfcb2ddfd0bd8b036740c86f478ca92519b49138f53f381a78ea156ea6d145a57afb5d201dba7b68f05a61096c217c2390aac6d0ca07e847194d6e9af368f8478505dabea600708e42f4f091b5a85546af4dac3501afe5a41230bf06d79328b1486517f9a7ac594060ff11cfd37c3422af8f766f4b07721f076869d4a99fc00cbee2903bf1dc5af4a85485452ea358008b899b992f6fd80a504cb4036386cbc11edab76122d6385d3537f3ee6c3f761df5e97c2637cfc05d621ad4ef87898ab67d3066501d873a8bad6fbb337f4ba1a033a9d4430dce7322810ab5b8c613ae26f9452b5cf494d4bb9ae824309fffd2c06c9148befeabbfb032c2a249fe02f4fea756e91692194d3e70a2bea9b4d1958ac27c44c465833702213c439140354ddfbac259ac34880f1213f012b82ed5482a34a2f8c4dfdb64254645c864857ba75e2da39e1d044f1ebb843bc0dac4e8f4d3ae0400676e5b687710b308aab496fb264619984855d92059c8416ee09af4df8fe3fbb3e5b5d194aaab20c4df10052c33af5d44afe5fd863d48abcaa295c16be05fef61d0bac575c9abf7d9a182b303dcf34317f42e5a64d9dd3748438d4de44427fb1935fb06c3003b605162f3b4aa43d4fe6494c2dba9b7c8fe8ab6e549f2ec61442a7cdb5abf51e7d228a86f9d07b8cfb741bf04b9cda0c38ae1e479599628e72f1b532906bf307047b4dd08d6f5c1308e613350f03fc23824dce3457584763d065900b02ff0c126e5c0b1d83baa170fdb1717d0071e256f84dc15d3bf600796daa7558177e59c7ad6e55c7e6208830145c27fc19b1942ab8f1b741620369ad509c5393961ceebca6e147a47c3134409320e30ede612b4916e48c039ca23a337f0f7ea8e610c10703ab19de127c3b72de716ff1e344a29e4bb1f84c66e201c2e1b6f77984e48719d1e97c23dbc8a7c4a71341d76f293f5c628769b5ac65fc3e2cc2087f2b5332b05ec55831549595e03c87b697af4f8022aaf89433730347aefc6fdc5c5703d8bf18a8691c369d60e43b46d8f4d032e354ed9ab9cde21cca1ea5d6fede3455f3cc5fc5ed755d03b2a90f6d327a439a0963a4c23d16a37bbfa4759ad8f09a8a33c8df2d1529e68d33c9c39f07637aa278f63e64353acc4c37d4c1945fa65212c5a585a76a2ecdb0f957126a217f198423408d7bae2864595659ca7bc34deccc2ac247a22ec6096959ce3dd529dfd5c388337fbd4a139ed1d8f535b03b0aef0f259da51c0b880489a036b3d1d2d7c079af26de31282b96acc1547f8c16e5485926295109fee36a2d8ae91f4187ab36bde68db0f902bdca9993155dbb34e0dff37630360d25a9980d7841ffbe31796a0d90f8e3e4d29db00c149411bf17b55fbaa5607f02d8d40a8a365cd2d96b47d4b0890f27a8a53a64393f9392838f1f9b5537881f9bcf80730004d82f03a288b377569188922767422797976c38cc08a7b8ad1b68b14d40ef47eb959f156ec95922dcfe1ef813da7843d7c0283674455fcad928e1e084e13ecb612de9e257216adde0d88718b2448d7abab35852e68de60c50a47f001b9afc471df72c7c4eb13e617cca76eff7d96dcb8f3fcd62238f286589ba81e392fcd773b11915d703c5e60d4113c298af8d082a84234f3a80c296838bfb4360cf221500f9efd9de184df2a16a329c217c7fe9a86bfb1c1537fe8f44d1668f908aadad8ca47eb8e0cb2819f986bda3177d23f5ff3a62ba87e6c415b4e428ed3d567ca6284aec23a405949f6e4da380bde9608ecd028af2adb087a151e1643bfff0af19d01a31cb74cb4b8df057bf54b146b29123f3934180a959dbce9008763ac143460b67b4d3bbab254972076b272403e06a2fccc8d58391d3c460b7990f1a3f42e64bff57ea64aff1e28dc4bd236b84a7e7e0aa3dfaada7169301344e914bbb40f124f948225434e20c391ee2e1045b97b4a2516fbd31dc445b417ac1bac3db6f0a4168dfcae83778885dfc47766848f761f5268a14a583110690e15bb79a72b9b62b56e54ae9014838e4f6ebe1eb97dbca9e9e51342d61f8e3b0fe856fac476653b0e0e12cb2745488d66ddda42261efeda80a11f72df59e2ea711f57d04fd971a400f6e67a2014addb36bc5a719fb2d7b1fb1499299cad98714e3c7153a96ca558d40547acc50c56f3c3b6ac88920beda4c7ff81cb4ed63979822a9d39240abdc43090a96d93730ca9e6ae88651c6a95e2a3d5bc266f1688e31a0da847a30181ce5d10427c19fe5227ab876b5f626b33f490374e4df6efa8e0de359bb8cda059a1649e57f6f7c9e8ca86cda2861ef69ac632aa114f6508fd0e392e518ea57258881770200cd230f3c918f53de298b9bb491311ed8228ebc846a369a70f6cde1b265ebe307d237cdbf474fc61a0c61d5cb7f9f635827a1ed0ef96586466c92a715f3c8040018cf6555e78bf22695f482b56268a0b476ed118ad0ca4ed35b5ceed8dd2bf40da51fa3156675367de591bcab0d4caed99241fd2f7990a389d4c53ac17b2f9bdf8a0a52f795f9c739cf7c786a053512644267ee67982113fbf8d4857ce6d78148254db6eeaeee2a26f64f113f1e00ad8a23ffebf2c6c2fcccd19ebd97082389076a4bcd8ebadaba359004b8d7d6e36986e833562084883c9384f13ec7bbcc008b6adaece70355a5d3658b355d4b1f199701d428db1b261541d523ff43468db859f61da47c9813a7fd5383a67c7802be3392fe44eccd2cd4ca7556a733dfa9c968badcd72b013a7a211f5018648c19fcb029b97a0d80cd0d1adfbc618a940981bbc60084582feff76d0315426799766513de533c1e394907a55cf6dbd53442f6057c3107396b559015852e0d2d8ac5fa6a4078cfba507ce2623b33b18ceb547652db5221cc6378d970610a12e0ce2f725d4f3f0cacd831b72b45d019a4b1c3a846995efe1adb09227dbb97ac44e91f6e410db6170cb4d3ca95fad26f05b87dbcd8870ac6c5d6f1ea725043ce8d1b46481232160a6891540032204d4dae0a106af06a2c4c2b925de8374d742a07823e088060ae1ed1ba5c54f7666caa9df2d0ef44f5b41073badda3e3428c947e6ca90089a76ec162ac0a6f4ff19473dc66def4f24909a88365a44252c5d8243dd9966ac4d0ad4b5a3d037921f4c7cebb2e73a3fabff926995bd960c9d4600e1588e04b32a986808816f63d4b7d86ac2991bf1241de271237399af3138ee898efff97a8c092ec6ceb7c8f4575e11aba397a7dcc87ebf2c09b555689d8000f628f03edb5a6c95f289d90c5f24b07237d480cb7358439130dc42bb5077764d1b455786de39e7b8dac823e3b04eaacf24efd3f0e4e8763ad3c9d43c3e56e0bad66f4fb9c32f2772accb192d68a5054a320b56228d11435e106ccc08ae4d49662993983fe0adfe27d8249816f89ad91d4469c97684c5746a517b886088e8ce235398405dbb622673b456f39ada477f8ed21a4eaa3ce8662b2929875fe104063e8eec6564bc76dd2f076787f4e9a388d5e8d3becf0196c7a16eae6e757dd8064b232ec97244b9113d03f7559f773d213f50ccc4ad4f2c8b851ddaccdd12bb0129095671072c5a161d1463cb49755d933c02d29ab550747fe2bb6369cf10184777a978a3aa3b49c9b0bcd8d4ef4528e7cd9bf0473124ca4f8c914748c606f580ab2800bddde17b0c93cff7f2bcfda7a4e8c8897c9455527c5ff65d8dcb0dd9a35c220648bcfb7441e7db58fbb87a298a9e74150c4b461e78b186b17b4da98b988e64b645b7eda54c814fb6c0351fa6fd312721cbbff276438f55b88efe8dff2baca748de457b459393803d099735d280ecd87ae671a80f8ead96fc37e5b7b04990cc81bc4f6e6f907873ba6ee9956500cd5c35045c08624209ab449357c49fe963e5c028a4ecfe6d3a246a99525a2b1b80fce919edc553c307d128322ceb83e108a521ea3224077f913646d8be72054fdade019bae64e5485f12152bdc00599bfc47ca0ae6a54ede427c449623b50358092e87fdb041165ef07cbbca39b324776fd5c2cc5ab13e0d8e1d5578d8ee412d7fdf314d83df5505c98dbaa08c1983b38ef7905dcd574d2c16abdcf7f8ad0b18c635d9211f05153941c817a0c56139472175e97910c73061c4c1612d754c7b885494662f618147e9955fde325e08dcd595952355d4ba7ec3b5e09afd10f2e310687a3c0d6902a4b53b9fad4273ec1eb84181452cdc2f274e6900d65e7e3005c5a00e05b7606dec65b20cfcbabff91c5e5239bd388474199a1dd6c37e9b744f9b104206448d33ade607aaba4191018d51f2c1d7a46804594914d96c098f4cc54c21837306add5895ef45b48c7904d6f11bf3dfe4c7deca3098a2ef7be73b8dd463d0af34360a656e2d9603d839f6db4fb4543303086a002132bf2c2ac4596ff7eba50fd4de7294beff43a6d9fade22dc47bfa7f3d56ae864643ce3c74b67123bdca7c38340858aa05e6ea22205db5e5a474c251e1a8059d56c8c6c19fe7400abf7ed036552b478ac512f5fa2bd2fbda86e9f4e95da4921d21490a44c2337417cda29bcaf801aee35964e8b50488cfcd82bd3406e8ce93cb166ca50e0a5487ab710aae890dcfb45f82da33f8580561240d3cffa6453970980ec40f07a3124b9dfaaae42b8cc525f2ee6a3f6bc1c4e39b205f4c3a781adcc85f95f800a8b210ac9adae043fbe93c6822f9a557a3528f8628c3d56c96daa5c6ce752bcaf482ad9434c63325fc89dabbf687ecc09093f324fb99eb1ac2bbfda429b6f8eaef04f76590d9963e36d8f6d44345163a340880f72830e6ca49a9300eb8a33561583c1acb5ae753251b68d130f011bdbab93535ab8589bbebe1cdfccf6315bd78331611fcec90826afaad726c81911a5b2ea60170f3644edcc656a9f7c7c01cebbcfaf0f29b80fc9133f70589ed030faaf12cf6d594dd4a91bf11211a6b3f2c356ebafbf06e365790950db0593b8a4ddceacbef1bdf20bb67e2f62c8acb83a4b01e9e5250fdc3a44d6c294c46e64872130b22db2a4fc7d236c89348fbdb498efff6cd54760e4d3b5916f854c605affa808fb3e7ac47f60d91cda98e42c95c649998d27eec993f3e18d86c473f7697355d2ed36a689954ae327c994523412623313bab74d8eba1d6478721372668417f43d8202f890e3c4367031d8a48c42a2b61ae6a86a6a9cc6a5c88679a6927da281114b2d18a2b7e4836c5d534cc5456f5de096b07297e47c4d57b2d3a7ba161f4776a13f93bc11d1e420d635076f38b0627ab7b11bbe2804d3b43501fc74cef1ae7cd7d40c96fc2636d5d980b8b17012e4531e5933da23d383358ed92c654e9f9c25869a3527b56e0d85acf288a4b8f42e854577539f3407599217d7c1554b99d61ee089825b2e2e3e1914d5dc419243e832fda08e55ec683afbe6d04b235fbf6c1d10a44b92d819b8d5d682e08d438ecc5c018b12cfb9b96577635729ac30b9ee1d498c1e522d304ae8651192096f88ed5a2e0555f7c160b178b70a8839c0dece3185726a5c29e330665c9220902e9791746672ce4732fd4897fa727b9f94162ab12ea4725be9e6153c0f971e2bd99f29862894ba4febbb34c57adc0cbf978f3e2ba57545b816dd1206e494921ab6070d96e9645f04024ad2d19ee0350312faf623ea8836ccd1cea778d46eaabd5ae9777f73fa652b4e978cfdf3595c413516f85219722fd8c98096d199302f922315a648ccfc815bee49f63037e63057eda63eab7a2005071a25853d656a009b55a1c4a865293a442094843f2161969e5d80cc63bf1a7319ea769d995f82ee5c7f058ee7d379e9a86017c9c64028ff071bbf5417e0bb32f69b9327d843f2007f14db68f8f89366ac20d2db690320785bcd5756c5f7d63232675b5473d9a6ed35d10fb746fc39bf7fd4a0d44c7db23c9242d9a49e54c2b794679a631664e7669040829286d0595329b42e02ac638a9dcb9958ef39f8f85fad488af84085b2ccb50a45a5d1a5304bf8cb5a4d8f4e204c87eb89a809826c0db8746ad7222fd3086821959ef8af888378a896a0fb250faaebabec95c1ce156bfda45c0dd465eb26c1d39945d4b3732da3505f467e0fcac9f5e840c68bff57030a774f00020b5e634b4f931bd82f240a71e93d37b6335d9f957963c0577cd1f7c77e50e6b8edb53655a1d730e80fe91910d8147975a919c9df1fd87ea6514f81567574942aa04717f2fcbd65f5b18974e2ab1cd742e5f6c324e72f8c80b1a20bba6c1c2644832f2d50ebb1de29812a80283e4ae04d70a63e031806b884c1acf4aa0a2a4e03d0e52eb2a62fefb849382ab6b74cc604fa9e5662e630b813e304ff2f04e89cce0c3b93d9231c4f0e64ab7d4fd9b47d7cb96a2479c0bb9acb852a4f2526918c86a54f393c01d14d0bf5fab20a31c23721864511ad1f5a68ff80774454f6afd5dedb5b6396bc23949e1adced5e85aaefedb0253fb9cd669adda06c725fe0d41991bc6ccbe420371903b6526658920500a40e29214d5d27ff9722e822db3f6d15e17b17224a6b59d55d91ce237b7636c7b3ac7263f741977da6b9fcb278979319762daaa7642e9c9ab91d67235aa5de38180e52e2af60d1bbd946abef31ee506de1668a19228889cdd9e35fdd762c0244eea0856d9a87b9f339c1ba510aefec53fc0d5e8b092452ad24e436ddfa54b7407cfa75f95345fb9b8cdb685e0472fd76998cbd05330791689c0ece039f2dfacc2ff72a165f5136c9a996a04f663465060823643a4c4c3ca2c1147c69cdb2226fe4c82f2cb0007f278c7e0f8ffe2b71bb599c40633fa50573cd4da44a13d86f2fdaac58f527998060e44267870b091e3b904e9cf0bf2d72678ecaad1f58a682ce4401075161f84921f55725fe0a29a2b531139f3e776825b72f00e6a2d4ae4166a84e3b8c6a55369ed7dfc91fcf90b754742339274928abc44e0518647fa9c23482339b2386453c1c2d6e1c0302bdff63f0423f05276185858169ac26fadcd5b25b271a6f788ee31bdef2d9166d792287a134f292169f0e7d8e22e366772281d60edb329b489cdc4b767a0e52f288ecd765fe89839bf921c01d01d531938253746948033a6934435feac51eb55edb092adfadd47cf774d836b3fc7251ed0380fdd66b5d84de80945d1c02ac49940f629b5d8133d34c373bb0399c73d9a1b1201ecaace30ed2541ebe11cde517d00e2d1a84793fcee5ed988076f5451b87c16d325c40a8fcf97b4d9e77598100835d259fee28a375f18021617670d4b2a17b3e518e77f76b368deb422ca84db6420d203e3efdad0f0f8961db005a1865ff4f90ef60c23cada2d4f9bd943f729f3025af7bbcd731a8770693a3044d1abf9fb15c9ca6c47560f0453a000fadb9c1a94220809f3b6de693dcc8384ce220ad04be01e6a54c3a0661dbe7d94872af7bfc8badbeec3927819a345d2fff6ceb554eb1d54e338f3206cb41cf65d9fc5cd4063673e153dd2ea0703812250894ccb78ced3725a725defc4010dbf59da2e4df15682f13f20797c4ca1f56e7726c10c09fcd2fec63d5a5652d49d50a2e8572e817f332a956965d8492adccada45d36343814df6c01986101a4e032b3c76524c33b1d266ebb8b028be506e810f66cb312b24b843e0de4edb20238d7708c4dc3a3d62d1ddc303244646ace65b2107924e2a9f3174ae2bdb7404119a0e2fe7766f5478b5a486ba0f886a0bcec705cad3a83dcd910a388a9bc60a33ed63b83bc0e150fa7880cb303e1f5fda69b2e502b90aa64a300b2baabd90a9c97666b5a5f8e8fa781ae7c6cb561b1a0f8c385f57594d25ba05421979d0544a6f67097713be68b909ea79a7e8d5d74a4905b3c9b7c27e2e2af0d18096899abee83090ca97656a0a02b364c9563ee526ad1e77e64f5688bbf172aa76b36a887817bec106a30c06f10d9feaa78c30c650740f78e8afd70ad775dce0e706899d3a1b5bd134080c1b2d4b7fa522c2030ccdd475fc5d9fd932eefd9d160fedeb145d82deacbb82ecd041ff94e154cfe5a0293af00e600a20da8abbab81a7c6932577059bb43f58d61e5d231a312397adddd853ee5f50436a368c5fa5e382b231eba96323e8adb626f17f37e6d9290484a04c490af434af249acd43c8b26ce4ff5d945a4efd0775ff3970f36d5365a14ebcf507108b1b0183021787e2f0e92d9c3ad0ef57c01a1a46bc34af1847b50ee0988e0c60f4e3f69305d8e7b6b9f50acc3aa59110378b4a29f6a0fab577e6cfdec517c69606fa0c78fa69e8b352e0eb17e322eea2405d895c5370d5b4618d395ad51212ff9a4ff18238f2cd24500fc9191a5dfab40e03637540d136f889b193475e56e562e5e824fe26649a072d2d9e6bc7d146faf9932a111cb2ba80d4d271cc246170cc52602c89ccac4a3ecfb2c92db349feffe6b14c79dd70c1609249c4b547cfa49752679b2624a8636c5612df84b26341da103078db68a89fa52a4e5b3a06842d236131d014dbdac282274a5f0e333579db39ae7dc7a3a4f821fd79086ea1b6c806265c17114ce9682406aaa11a0650c95551485c476a64f519d2eecf9258c99b354294005672e937db4a33b30269b12387e20796478dc257db77bd96d4f2148d99b59c3522208b3304697a133f80451dfd2379ae8deca55fc555f7b94fa886df943c7d92fd59e72a7477e3f9393b0fd5c9c65d09189ed021025b75e6b782632c406657b690dde7103283effbca538f08dffb7a07de9a8f40fccae6968c14bdd0fb16a095306a3c6685a7756f4a7d9a3ab97d5018ba92474c4ae3b5ac6676787f4e969f671467d9e8946f634629f191cb65e75b1eb16481853ef4b2f53c6b74c72d0556430b6d0335a5cb8cf40cee9ed9248f8d9c44a162ba20bbea2d6e4b7f39af71ec73ba2540bb1c005537994dc18aeace38cf975820e2f146d0a0cba01de09dce2ad2d76e521eae06a52912ab1f6c30801752ea7ffba38f1e947e1f90a5e6f66fc78e6a16547c17aa809165bce70b2075e2496a140f8cf103bc39195f96ec1b3bd474fd3eab7ae35f3f62142e19126fa77c16fcbe2f5536d8e9de92688c498494e479b50af45aadad9c084f02d6e67190a316cbd7b60dea0ef366b04a1b10d0467097a0f956906d61546b9a1416a6ab61867a97a82822a54d94bb1dcb21459626fbed0c374b02f5c4442c738564e561971c1fa51b7cda941f3ebccfc809fa2a8ee231f54139c65828aed0a3dc227ecc1bd8512031afe5f1c85cca9da2f1a3af797543abcca21121b4e7ac50a4c0e726b861020eb722c89a076a77a5e8c31d801c1eff4d5d64a1e60bd8922b6e6a703c5547d03dd9627821a25e1e5b4239d6fe53f79e64eb26cde660f7fc2dd7512840eddfa88eaaa52fc29a9916aea2e885a7addadd7608054e32cc083047270e1a4c7d7debd17e8b8a24d0ecf98a08714a94f8de1c8c21f458be1df01926053b75a004cf504228810b60c85bc28e5981569d28d4ffcd0368d836eced802129298096e4c83445f25d3a75e46ddbb81202461b73c1696919daefaf373c33075fbdce8b5f84aad0f5d33c041da47b936bc7bc100b0dca423e069c9a22f6ab7c818cea7a8d3fbccd5200a7aeb16ebca3ac8ed33b9959d077f8210049994d046ee4500a85ba5a3f5225d96e7696abd822693862b6a78197065a30570713722b4b597d43471bc4a9c04325feaac30088c7fdee6db28440e002f05111e247b2420964f1d3a1084324ef440170f263615f469c682b7d87a6e697a8134452e3739fe33cb8dbd869ae365a163a18c437d0a74505767624d06641789bffb41968b6e1ebc4917ef8b9485342c0448f720455b2238ab66a384b314d3dfba933332da411c0115341f788f60a53748585041e1075fd89c7e340117718a8070489c712802f3b3c6d00d297073d484e41ba1e985b9751a2ab69f4627168a82eb8d4f757e111939cc0503d27039ef539bee0f47638c52fa2594b5dc7a546692903ab66d4367a3d892c219c6a71f8fcc23ca00ac1b987da76729edfb065a59e0367e93ccee29eafcfaa77b6a913d312cf6af9029b0105b902963938ff89cd5d828bf95b3df7dee5cdd3ea196e6c1e8af562d4d8b02e79f974cd90caeeb14b57bfdaeb433c1ecb658605d2cfed3aed8b2e9f63b194698e2c90625377046614153cf3a40839ad4fa838428b2d48fb1a0dd161559f543724b042cca65210a8ae77d48771944134cbdb70ccbd4dc561fa4af296a333176ed506c512640fbdfbe75697f44b930d98851b47f728d29a6647f3eaff22d2286e95ccc7b00c56438051cddc0d9173bcc8b24fb7322acb6faaffe392bca2a084c50c6785fba04450b312d513d401acc74a19ce04557bb06bdc090a0ec130b4e5873707367fcd877e5352efe6111aca14238667f36241cd4fc14bc0292707c7cab2ec319324e369a768b4e58f10944dd4e57f1e8ca1e86be45e443cc357317b1ffe5f7f6e7a1476d4829b65af9bfc6fac917e29a05120ee446705455390535a2a54f6414371610a293b3e6425b5c570da5a5b9ed23ddc7e162a3d1350135c51006aed4d72f1e8a8ec98ee8d9554583f559114e13d91dfd7c7486616dc5c21a5269f1caa3b565aa893beb33729d82e5e7bbc5669b88d485004cf309990cc41b258e6327356622bb2b7bdc51914f53ae0e95d3d6a3c2fd7edb92b36144a831987f319b53752c12e85b5c58a6cd12411fac9a946318c72704b365872f4ccfce8fd1bd411a6b1b096676b33edc84f9e7831e7277a0a816053ee374fde0d6c43a18763f3e98bf58b952a2ee0e3056b14ee2d088418c232649090f114762d23158309dadd70f2fcbc72812d2390b6baf491c0963446539cfc38d5883af6d46b2549197c5458f27465a812ae35fdb08ab901dc7932fcd38a4030d41e864a0b24b228eadadee720199411a458f0c89e95b295cb922e247ee90e1974d488d75076e1b5acc2fcb084dc8b0a6eb2fe80b59d9832fc6cd5278b5364401cdeba3440f91eb50205b91eb072a8b09b3d6d766f53bd24061ba58f8e7cc4064c9f1bf01d9640f180e34c58255792bbd52a6b433a6b5fbaf5c9eee7e03f044cb2238935e6723c6e6cf8266acc68f6b3b23a7540d7e68c42c6b7de8ec187a24462a034f252cca01024858382a0ef09733786e7785050aced1014aedd74886837ba44f6ae327fc8c4ce1ae3ee2cf4fbda0393d151253f8eab378594b7b8aa70a93cf8bc84b97ec6fbdd79cdf489aedefbbb8ef349938bc3671fa91c0017f14af6243bc53eb2880e269802dbbdf0c2f3c60d2957befae23480e1e26624b28837bd98348990e74991d39aa33c5044cb542a43f9d61b8e55327b2bb7132b089b47ab79a8276e9a6559eac77507665061d85a59e1dae4a527aa866a25fdbd1aff64bfca07ab3bfadded2c0918b414ae4356f5db3647d2a11af6df0a2313c25982fd38ddc5e4944c62f684a99632baa51b373c4a1b2aafeae43402751c7f9b86974190993b37318eee65aa1f7370c14921d964f849ee560497277c73334be6c22ba73e9569fe117efb5026e3f1c678cb03aceca6ad9dde01cd31d68beed34f2b26be9258c5ce1f332c7f363f700b1b3cc3760c9e2029bb57e3edc8fbe06306f7a97c9cd28d64b0ae415d9d76863bef950a74447b09cab6ba9c9fd8846a159f2d140790ac08ef3e8d993b7ba17afb14130f4df2cf42051a4508b3328fa54011884f9e7e7aa76473795352fe42d1a421a9687c715fdba9aca58dadfa23e3913a173e5d4747a89c3f3d3a4c8927dff82c580290cd1b39b9affe22c2d8ab4a5af88dd6d1ff2470f431a307d088367ddc20c9a51546fcf9ff3cbf84dc0fda1482bcbb2247d5e8a92f74423653279d6b3051b04446f57015df48ce1af9a34dc4f1fe4c6ba2597e296f7b2c02cab70c866cf0e8e67d6f46e61358b2b9074009e5bad3a32d2e32d9c43068f45012acdf53dd0f8b66f7ac24afadf44aa18178d22ed360f0d0ad1b64a3488e355e9dade104f40cdb7b06bf56a276dca4b3421d0b76b2194b6eeee65e9e060f1917e9979bef5865e8416bd231f2dbf0b89b0e4b8225583fedcee8ab9970dd441999d9f306f6f28cc9813915c034f3cc3f3cda6ee48a8700df23cdc4374b332b4ed6aec94207f5be76c995a45c864df412315e3dc0997e5a1089bdd85dd480b782a2c3ab81704e957760dd7c96034e70c2c5837bab8b1e5259c93c33a4d887034e72ed492917eefe29251859cc6206ff2ce2d31fe47fedfa2906fdac8695967d2197db953a1257154c9d2ed95b92f39504200530c96a55e037e5997d217fde5ba0c077fceb35262cef687f4dae61768d3ae23ae7d17107ea156b25fae92bc503de5ddaec0a930a90ea5e19f997259fed179a95553877104a635044c1b94cc0c8c37529af82cd1a5e0be1ac4732a628a922bde67344c319271072b13db8a623018ffc2c2a135888deb3ee3b38939fd1039415124646aa4a54a632648dd506d2a3c972d3586c6ec63bafc7ccd02f1689b0d05a4c35511758a94102709ba8b49340a5e15eeb5d5360529db2ac0ce31e8fca0c19a570b04746b1bebd7fb1b7c01f452d10cd04923c5d5c147d27940a09c999beda406b6fb0b2e27607633e84cff80b2fd7c90a0aff868a15e4acaeda7ab744c89d5094a7a5a5aafc9d6d15183f97885c65eb20588a76f8103f54c7ea12e2384bb7a1bb02a2652f5551a86677614affb3272d9b635b71a7eafec6cdfe6893ad10acfefa76fbe16352ec41de28bf12ae24781c20910c9bac277b69e9bd90d02907d1dbf3db3715d636c7369177c1deeb8aac57020d954b5b14669d5d22da63e5fadb9afe4b4332dfd203165c97b18ab62e816736e15de385d21183582c42f12d667448912f3e74dddcb1352261c21b2469c69f458e36e030a7575430a93128be0b022d92a5891b01d6989ca1b2c86b519a14b39b5d85bfdafb8a52f8d8a995804424dd2eb32f5b48f6ac5938f245f2436ef1dee21cf5f8218ae1f24d517d6a54cda9f1239701e048a150703a1d15df869fc4f3aa9fa59e8932ee5a6f570a59078d7d4e3d0cc5a0b82bb7fbca9084178706b5b3c376b033d686f1006d129630154be934e7cbf7cf61102ca1058b308813105d0273439cef0f3509ef44722360001f7c7d37b87bc117a50c6a1ea0047b7628a55275ff50b33e113346c0d1a316c880aca07ccadbfa91c15da70d4aca4c639608c1b5a9c34ad5147d93d3ba53ab0dcbb22f55250067a147d7e5302bd0fa21ede22b1192e58d2eb5a80138235c5fe20c01be4e6b3cc98858c1e1f8b7a3b21d66bf404ac5b9c82efbda1d3112ed7c90d5244d694c4aed88d7d9fd422f7704795cbf4e4b25d2e3ef737c4dd7425f7157bf0cb073ad089e3d844349531aec0442124efb96cdce5eb4969a3ca943ab73b8f6ed1b15f0727670343add65bd307fe765d2b2a1b6b239f05ace830dd2544ab30536ee3289366b1b541320b8d7d95ce04c5b2272c5710296c229b87b1076e8034e23edfc3b9bf61703b3d9fc047d1ea397ba7760f02efb6eaf83fa67d8c6b0baeddf504b8d91cc2a0d0fbbf2aa0b69ac90f8396b908bb2fe7214b700d03d576448c8cbce2707f0fc65f64689c3386b78045f8eff01223c9ea6d41807d9675c476dc9a387f29303a64335227480e0db6fd751cfe151366431ae8685f3c594c8ca9e9180be9f06747564a883dbd54e8c7bbb2578ed2691bb6cbccb7fb0405a3bcd8c4a86d43560c829268079125c457a83ffd0e9cbe10ad2317f26ac5671b20162579f0a4245c8f9be8c61c37cd2b6ed72bbc46252f5e0e1cab1b4ed6ce10bad2073cccb399bb66ac595bc4c6d452fd664b9ccfb665fb694dc80aba5d305071ca9ef5d00ff697e58807ef994f9941ad3e17179aba4cc05454332fe47cc67476f90c746545fe60682162e52fc69e00832eb0f0acff62ef626ffe1354d35ec4fadb4fcbd1517a82e8de212be0908a9504b5ed7c3309a71d1deca87b85c4ecc26956c65fd299bc788afb0f4724384d1e809e903b1148dd9ee5265642818346fd49fc3b880ba471d2b43e57132019acf8c02b718c295e6ae450425a352ca62c674ba650e6651cc14fcde38b7e9581fa36a7ed43ed17b3b7dd74a4f90b72d2029cd1d02d185af99c3cb930550bf5326a048b652f2e6ef3d7e53aed606b2b28a7fbee576e91ccadaaf32b6f96c303e4fdf64c0f2dc579fa88dbe439d2dcda4f84020d36840dc7faba7b5c7a48bdb23e12256d8293662c799ba494084753380985c32531f9cf58f29a83ec808b4898657bfb452a69ccc0235f69687dca8797a637ab58518f14d3b6c71fc8b076c02e4069d1f70dc75e80278b15397d9a5a224d43fcdc872aa86daf1bd40d70a33f9778b46ed904b23fe741c7e10595c2da3581049146444e7a8409c14b434246d61f5ae6ce83b800d9dd16324cfb171a646d18cec0bcaed499ac495aa165eecc3e8675f68268e2436d35b04f41a1256afbdc2bf5bea4d9f18071cce1998ee788fd90f20d2f9907976b15e1b2e0a385ba07201ab30f26321a673f990709e787d147daf5d9a24acd2769bd1234b21b04c3472738a61d73af34b3d2077cf329ce30396a80d91a30675ca2d07335dcb7fba5f84d42ca3d5e0c6f7a66aa57d4c704042d121597ef0663453f483ff86781a59620d9e3562e0f4d5d6d90a4e0d30b9f3dc54d0ff651ee84292b1c7eb1ce95ea0903fcc3c41e12da15ea202a5c0ddc5f0cc6afdf753b66a2fee5b08bc0d4e41ecbafadac726990364e926e9c82627bb2f00b9e3baf7c13318ca3baf65684b4f4102652b8aae1d2d97f82419fdd1346a8815d74c407744f08d89146b0134e20a178e41086ddd6d38d18aae75871572509a1a0c73980b4691a9ebe6f52a94157805a0cc88ee0b629cc4f6a7caedc7ca367527860b04cefb2d82a6d4e77a63feed8344c3d9f7165b219bb72746f0416a2637f7a58fb117425edb65949eecb906d4042e1bf689cc0f02c088987431702b4043314ac8702c0fb174952b12a30a9a2d9d25b9a6eeea1422e83a4d166d9d78a805eb0ec0abf7379120ec0fd492ba052b46a7e73152f37391b9da145047f6df7ec8f518ef818958efc4953df654440fe7808b8189dae9efefedbd9089e0347d25af087a09ee9b268d06423a5aabda258067f6d5e00a22aadc69145f5976cb756757868e082a8dd30a9bcbc58151f857827fc51cd8f0e557e484bdca3e8089436b8cf5f5054153e25e807219d09fe0cfd61f80b6c95d5485b6bef6fefeffeaa7e1798f35e727d95545ff7f4222144eb3d4a934e3a8da460775f0b74434535370b72fbd680a19c9c9ad3c1182192f5b331aa01c8ff8cb413ea0860b45c5a7a2e61bed3e9df6c7e82eb35b485dbd54c1df0b1706a2ec4110c80a6843b5db039a82e72846b5857db12fc0fc58f131f5ff40cb52d2975bee242b27924c107af18390e4e11f02313de7de2828a1522ec6a6a76c6d817587d8fcbd65136e549b15a70a565de2a8e7b2c1e67ce6538969756c8304fd54dca726086d1c05b54dac7dd6f6d73a2a02d866eef370b3603abca69e139881b820fa24a35e49081b2dbbfdec2cc5aa0b06db68f57fa2b71cdfadb5a7ee40031b80938b3de582758f9f2cbb40ca7fb816507e385b2512e67364d520b2fd243500d20cfa4b38a478690c450fed49c17e9c88b8ef3340eb20a190e4296239a894a17b95b629a7bfcc3ffe14087ce365508e5b07380edba06f3d26ebbf57eb349aeef833d68ae266ad4ddcb7e9ef12767a77afeb58f6430db492432d0b2f4b9848ae45357ed74fa6868459c06f0dc636442a8fe0ed7628b4b292a1a7d495ef15928ed5bc1cff35155fe61509210d8db16688d1b4093167bbb654a68d51f1be30f414e48172036a8544ee008236bc6513ab94b0239214580fa25e0d38e7d506d56ae5b383bf99b4e1a53e36139cef32e9e4316946d23e05c0f30dc749c208f13e7e4d33ebdab4d9fb647409ad62a67bad1af1f739f4c15b1a230d68552c7985fcf1fc8044ade4bc0f5cb70e2dbc8a89d667b075fcd6838fa95c61b5e0b74cdb9809a1570fbd4cce9145427f9a7468e302b38333aa6f8496ffa1bbba81f19ee05a394e7b2e5fef989365cf190f76b0ed6ee5c38a8628f3533e9807d7da382ed296a495117ea96f53cdeefc732a50927e354cb59d2e81961f837510358b96074db9283d4164cbc1ab4feac0ec3e11c46fb5d94cab61e66d83cc35327d39b99d7f101966732dfa4b7b33f4d7de1a3bef027382be528777242d6c4885fca049abb6c918e790e7cba3c1878af5b6f2465f6b1c678e9df7b6b0a0a89c814d58a79e13fba0141c218aef5b4b36f6ae04393a120682faf7fe9317342ff43473bb52e2eca60b24572cd6405782cbe414f86e4d2ee2aa87e00f3a7cd7e7bc5a00be9053ad958815db26dedb7b12a011e94f5d98b408003a6fc72e0a86c6fa8181b85d73d1e92776a58277939fbb2f76f48df9254e3d12fcfb4f7b5a7517847743479a1957aab300eac5691e1beacafca32935da35420c770196d7f40711e68568f3cc206809872277dc180eb578d06b41d34200c882ed691fab0d9be6d4de86ff1968b87ce620fd91946d75d27ea964714baf3ebc3fc744e65641a3e7c37424051f28b65b69a3c28fd9e39e751bb20d7787c129991cc2a2b7e800aa4c26fdaad9be09c67677a189263ac956c996e1baeebb5e2e738ec7ec1d287f0112fa24c0b617f75181a905033436f6adc05f313bb9059e4d99648abf4abaf05c71b691d54804eab843c8152e55c2a31f9c3176b1ab823c58ab8aa31ed86533ed43925ddb21d67920c20140eb2bb5d34acbbf043d1bfd770344d9548debb7808a3d900d001ef3604c4ff1d4c11c36066c41c2ba728f031af261021a863e98884c0ac07eaa3fbe2d165beec7a1276aa26224d4e071827ba87bbe3d33a8b8e4d3956ebf589d819ac8d7d22052250dd0bbef2ece21f74034b503d8eab57f4489e1acb352139a58d027d7845ea7da2400476937c4f0451ed0abf9d25c250a2195c16fd190ac11dacd668772b5dc6d81d03601be724e6038edf751fd785abdfcdc189be0a76d7e73e80b226884bb3e332d17def129b432161053417619b2c0d028c6eab169e23301548b53c411e016ce2f66d63e97738deae08e860868b1c49fb319047b9b92242d1a4766bf09515b162050b80349d2dd9dbf475d3074857b388a2eedd92826bb2f84e02251831d82508b0fe5d782768d7978a8ed09d0cfa926b9b0c41e446c94bb3f0ad8821b8e8e4c39a2bd0995c1303c24843b8a6a9040d1bba0892fc93b931eadfab016d9365b56be1c7ca0a8914156af0a8b53f1d0b02251eccd7ea7350de6d4716c61943f2968a62da32cb551f9ca33a5c10ca1588c8bd8ab8d20d0ab35c28bdbb3e9acd51e38de3f2ccaba85d938044ed7f42762c760db50c227edd467382fb63a901d4d575736f50e61ee9fd14d08807cabeac46353d475aa8e027ed40eb69905fcb6b5ade58c88997795f0dbcefbb926e904808364d86b417383d02b30e53d964cdd0042ca937e73b9c94fe6c9ec17245fe70ed0fcbea71f9176b56b4f066fe44fdea3c49b43d56c2d503bde337c38f0cc32be678dfbda97a32aafe7b9588dff8774b41d8a8d7a6807eb0ef4f08c25e5c789b951b4d604e997e5da7c90facef149c378ab4bb9463f15e5f736c1a87df483199b2ef27497c832694ec58bb3b7b70e6c2055e7ec51f43f93c6ece555dabc4a320e086117d3b1f6f8ef3e6e4a49b385d0e1351aab05146fb08ed147cd72290bf274a528e31463f4755d5d5807ba630eddea99c2cdbc5e12afd542a4465245c74648a8eaabd15cb7ac923ed60a499f24cb2bdbb9117b29e05f1693e59333357f97d7ca7ae9cf44feb4807605055a6b4e3d815df15fd99faf85994d76877c1cf5643bd09d372b14f5b63552647f088eb4f5f84a6713d50f0234f36695ea375da236d1db8fdb76c1b5ff8978232fadeff4cd088b97229630e3dc446ff5aee81f013eceba6cc448ffaff189e54066125c06b0a41c15cf743b1091ee9e04d63d2931ccb14633e9cf611f2802b30ad4e5919513be14d950bb618a95ae9474a84579fc5fbdd1d5a79da532c029493f5bda9c4d9187e703d48aab808ca6cf7e0ab67c1796c2cb430ba8f9dc14d44e8ac76432a55cde644edae82d7c38c5db3060598e6986b263719e50221dbfdf8315bcfa3513129e579f9395b75f2f105b0afd74b7f190c7da962b450ac8fbb5249e27501868904a2c6c5af644ba23e3647e016e3e623f98bcb90d180b4f7ab965df829d5243a5717363ac014e232347e8cd7e10066f76a1773f524fdb9b9b8694bd6a9f06f6543460cd0394390cab445e4d50a71af0ae782229657826dae058254bde6697e1ad87082868f3e62eff9b4b642c74048925ab914844fa375d23befc5063f44c8668cd8865c9c0529b956da1debb5578a784027dc6e8fc6970d37ca1f89b590722cabec0cde7cce1ca45b770dfa7b0acb658db3f5cdab9781afa413af652b76287b50056841206fbcbacf340bfe0eef149db83611f4ff6d046f163bbd2f060852bbc7f1b43dcd4d70c50c5c9a915b803dd6a7d50f662b4097013619503216b64f3830e9556e8835622ced3dea75ad09f91c3ddd9c0689fab79f74529ade6531360e5b469ca5aebbebf5a5259e6ae4bc2d98aa1e80af176f00bbd921ac044ceb256c70d85cb4c84d6ac460c1f97c04eb94ca4ccb935791f556e04b4c09ee20604ad62bd1aa427c7c423d572731c2d3b8141be257ccd2a8ca3df68e40ec32bfba7b59751d63bb4b96844c6c3adcbb7e00ff0f687f8dec39a327441d33cb7380f194080527aee136c3fe189c2d7ba007edcc9d0ab2753dde08a02acd4fae6a26ce0a3c099f4d48dcb5779bdda4b8b0b8aceb5de3b6cb7952c1abbfaec52aed8506db5fbeb9895d7427f5c95e0b53579c24f94cfd8497038df77e9c33c9d74ac44985995626effd4203089d895a1f9110020e3ce45e88d4c2426dd5c606b554bbc7649c9dd2f2e1a8bf170c6d3c3752cf86026b97350925a2ac09044402485c3d668c7bfaf049517675ef3b017e0db87265499becc17eb868e7d65f502a2035592c1c63663e371abf95968ebe54e190e4f574801d3f0f39742311c4848d1a3f0c8b191f7364635a8d825bbc9f0b60a9729007436adea2ff736131ad8b1e29789b86943182347b80de36e718aa982fec4b3880c55d68b555315ad7f751f25d43ac999e5f4266dff52b09ae96d3d9ce69cf1fc8a17e2dcdac0297ca64e44d07498ec3bf1712983a4d4b14c83d62d4ee561d8fa83ee640ebce25b4d33bbbfca1252400a3a181246145aa81ee5f687a69f37bb93f4fcc339caf92bcc3ce3e41a0901778a96a3e616e45c69da34d9cda0fffa9c7dcaa8a74e81b3e5fd42c2f756ee121feef4ff1d253ba6a27505ea59b0fadaac3b4acd10dbca92e741e6aed6a869785908981fd26bc46b2401fc290e5574d2884cb6ff9fd668bee125baa2ce08642daf5cee8629fabd84b5e0af3e66ddd189ae61a5f67f3e8756ccadd66b1ab9c644d953335ee01061911f118ea4d4f83dedd0117a37dd1b29a91370e306cc138f9b427703353c51ec093f0135ffa254ffd26ea9770220a3a5e54620d146db93ccc47c0d9feb7b0c2618cfba4a22ee8ac7498ac8e4b49c2500331970bb549382ebdeb571db58e6cd1eef3c504ebec219fb449cdb95744cbe724ab3b3520d6c69115e5d962556bf1023fa78d65f8cb0f9328e6f4ea27e5c212db337331d231df3c157e43fb8991a5bedcd91f7295e0cdc44351a28e123761b1a3ce5df45669e2b34fe79c1c2b1f05381f5780cb472f94ffaf79668258f3b576e42a624ed4bdcdebd8efcad687300685e882d3541bbce801f215b8f280dfb8a94b6f5e72898caa89cff1025af9046879476c4e16b25d1ece37c8468b189d4e9514706f5e8a20af459610ac434943657f1b0d55e1c2372d544077f70060a27cf2c4a063928956ed7319c3cc88a0ef909940e5692b05a46e6d6219cba8767237e4f65e1760db668b0e280a6f9fb99c93a48777e5bfe273f048fccd276f294ec5788379ebc2e5b9f40e14bac5d163eb7e643670c38c7a95d6ab6620e5b7ba739d3ce639783dee2cd439e550c0bc6f73e26b60c2bb9b98c9d54d606d2236cb2338df8c519de68edf7ffc4ce198b2171180163aa38ed75a83be8a820d18fafdb8d526688a7b93718841315b7dbf57ffc93811afd68b94279e009e363d23030ab4150e600bc6e1d68cbae1dc36a2cc953bda7807d26f25488f367ff286e2482290e669241db4b80cad2f12ac956e5fb438594e024daaa3b4720ff576e8dfbb3bded8f6e1034e5b7057e199aea30eb31006b05d0d9f85bb995808454f8cf6a0bbb6354aea34c36852c1485e29c70be30e2ef4ced11c43bde3695f256b313233b876ea3a32f3fa86f6a6ae96f64d4181daaf77cb74745705bd4047369c56f3750ddeb179bfefbb8300d3cbb7a15e4919029198ddaa9de22bb3002af57b8771ececee31977d8a13059ac64594c505677adb6171435767a03bfc37b3bc914829b98ebf06cb50b196a23ab0549013106d8f79ffae386c158f405d8a5b5aaa7019ab5fa1f77ccbd1c5e09a0ce5c8843a2a82342c4349ceca4c31ad03ff07ebb4ff2e1d49864d5f0409fa4d49d315b58996bc09df11c08b409cb4cbfb51522d1296ddf294dc80c3c4c143d660bf64352e7b739125f24b9b44ecdb03955dea8609b67479c89e4331d5bfdfd57c55201798ee6f00127b74b23bef63c00417a828b908f498829031e5a700d9896d0ebe482ef954e4e175d6ee7b8c34d618a57cc8efa45aca922cc5a210a9c86eeeb070f58d6f1d6135e95fb80016b5cab0c57d679b5e99928fdffee7220d21c5c42b03649839bb317534be4700d92ab245fbf00c6a5bc188dc96e7cf05c07ba69fa04e56baac49cb44ad66b3fff3bca18fe3878ea26c64795694829fa6cf7e620f2baaf720e192621cf14fc79ef6bd1ecd7b9c92398d5aaec41ef7494af48d1ebcf748f5e48e4d5ad9dde23162c486ec694d3b53e4ed2ad5ea360e84a34e9b3fb57b1d3d3e6a582a9fc2876c7ee500248053e731fad7cc687facc06bc262a255fee05a09213a6f8d33c6f7b5b2adaf630e1c40a8a0c37e9443f027085dfadb9b16f32f8eab647ebb54341db547b5597a7982af6f7e22bc250c11b6c74df040565afb5d4de3d75db4448d84e78bf7042fa9ab9f77f5404f3f2ca4270ff1d3f2893213535a8ad06d38cd22895fca8484d7f8642014a80daedebcda84b74022025b980122e5483ea847e78d969d211332fbb68b4219b37f64415cf8423eb9d6979bd8c257dba7da398dd702f7d0fade8b5fb9a29b44180d25806820a3a993c98f511c4ba8665dbe39a494101a61f64267ee99ef8092a749fe31e19a3a232d8c022a76b7e34ed980a08befbe62fd250f6f37e80b0d4de649758ea72b0086ce1b41c2cfba69dc3c770f9a94de7cc22e4765a871dd73d6b49ccf3bb5423f4dcb6d61f1f8e2ba6eb8ea456f3051225c2c91a81f4e018dd31d5d6cec44800f2e1adeaa938fa0536cfd5dc85c98feac141b47da4b009cc6b7044bc9831b13fff648ec717061fde8d3e0992852a7f04a6000f1f47817e29e402dec90c6148ec048b4b13e4717df434d4fddee77c5e743780371c603625ab8557e4694b39410cfef27af862f7bd1958619c742800aff02030a9767ee0a05ecb00fc0028b44af7a0dac4af9cb532c2f6f0b798b6c11b321187dc48baec975efda88a750f3dd5d38b748d5ef65575aec3e98e2aab42d2f282dbe0f983621c3fbbc409d95dd482887f4c0d14e924c1d63a296a4660882c563f5d425d985a6131d6a7b68c8807ef65cf3514477f53dbd8005f00fb16e00149cb3b7034c307ef8974a2c0e91158265c33ffc28695e883ea26f7c39af0ef862058a58579c8026be3f768c7b576e213570ae888681a42282209bed731510e9de3bd6812e0f0880d552e134c3195524b6814bf503548ff8ba38696bd27e26b9b6dd97cd73b1fbcd784ab1f23a02e500664f902950106b9029039ad5ad444366f85b6af527812573b2b35eb771623d06faf1aeab1d2822728e667aa764e2903dbb813cab15e5c2c0f87c4d9bc7c178e44b92d9ec7a1d698e91a131ff8e3e8da55012ac38e8d2b10a127ba96051a36ae0893b15e48077a03a96c52b298c0a76804ae366b33682c6117c6524923d0e0a47089fdb626fef35111c4460d6f2a38d8e648a19a986bb957893fe6019d63f00f9fb642244a5ea246b4fe10d8125ea855d90c4c909e65315e1a9b9b4aa30cf165f7c8d8df4a3bb0affab84d01488cf8fe4f74bf14b85930347b023f9bfdc9c95ef09b984f4be493416688af44b15260d9675df396d78481634ca71196626fb58da695ee754e7a52f025ff66f567e97394b890f763ae82932d97b1bc5f25baa2ab6d703b99fd2dbbf5c4bb724bcbc6885153d45d086350621aeacdf79bb3c269306e2d193ec11a78ccecd1613deae2570e4091e5e98359ad9f0e7f5ce9d9e9adc4b77d01e5721936094a35dc03248e19c9cf1b219555530d8b30d928653d886ede83913739ce8bfc9d31cdd3119985082be1259fa0f348b396342d751da5e3a5ca0426de9b376c62364675e41788fa506871d9a21841989fbea149af308aaf8bb303495c26b50f67f1ec77a53e7de91c4ed6a62c8f2c3ac3ff13ff4720a419adca1bed8d9f2c923549f9776e8da5e5bb57acc91fbd824bd4655d3ba43a17cb40c197586e48d6dde26fe512f760e47d59953eaf6540513e4cf62c7b668762fbf5892d7155131129676b184d1176e544535ae7350bc63ef03b6ea973ff566f1229f22513ced212a5d7c13fb06af39789a3251b6f99db666f02bd147c3c5686e26f7cad7b8c5d740f7a3263cf97171892ae7d15a2a90f871032ebe932d58788996ef44ef187d85b9035b2f32c94a8c93519f456296d07294dc3c4b2b0f91eb50206b91eb09c3155587a3466982744b6f65d3783dfdfe9283201aaaeb72e5b9fc795605aeef21a58110ca7e94ec132e708b887af2f295daa039d71c53a87212b31169b0eb8a57c195ce5b7da09649f9e364513d8f31bfcec6efa3e57cd1e9a9bb1ceb281b38158f56ac8dfc9e3fd6558168a9c0de5d874c1484a4f042ec6e743b69a6e0fb8e17f1b374c55ba53ec01e3f07b526eaa67ce8674558f630eed10e1d2c7a6c995ffcda50a24d5a3b14606e2eae3f63b0f1e4adba15ce1c060f95c6704049a24e2dafbc80444bccd7beeccb1c4248cc8ca14a0bb65eaf0b3910e0ed7fc9e1627e1e23d6a5a3491c3a7d3e43a616c2a0cd3137c6b8f2bacdbfe5ada483e1f99621df72e4719bce899d98a97cb648218e34d3718b10a7a28077b1b830b1a6a272d2154b790c0ae9a983e7525d752be80f7440d1787c0551a515562ba19aea82ad367b30593607b9beb89543e83890dedbffd390df07977a6e2a6334a799e172fc21647d1da131a7d766b4815036fc79ca3039ee428045d28a3a3f6c5149c4f4cc089f3998ba3cd68f7762442cccb391c9a49bfe4a83141cf98304c7c01c758434a1cf136ee32df338c59942fcf25f4894cbd6658df84956ed01d3de1c1ca6c9e1c10e661c3e8ce7192d88b2435348737c89505ce5cb97d3983646f064d37c15fa9439559667f1c4ee1aaede6f8f84e43fd1fa26b99968d7c06ba505dfc869119dbac2a421821803c70bc73df169ffe44f49618743c456303d003a7d64653db5acdb6819b1cd71cf9c2eea934d82032c356dda6fffe9edb51a8edc26bfa97d43a3bf20391786be0b2b135b636ce84ee4503a58af721cdfe67eff291f979aa60b1d8c08b13922e987ea958242f49ba132796edf439418fa420b273f1e66ca8a74d03c897335bfa707b172861a6918bd10f988d8ae3d81f87f3a406fd9fbfdcffbd42fc44f1ac535cdcaf009e10ddf385ec8e33bedacf96a499c56d6e6d994579407582618f207a39539d232318b5c2250591fa71c70f054c92c1a749a7644c670609b91f917d517938abbe64847186af0360818675420d4c8dd648e946ae0301266fc3f3c9356d94e253f74a9af80a04674a10c4fc4a4c0998d023bda7f28ae7bd4aa1835a68a958ee55076c4ec687fbdcb4ae41aaa9d370d05707d3a9aae71bd37e0aa274e570dd6d868fc83d268cfc0257d6b82a48d10630d9c155b025d24dee52e3fb01b2a85f0b20497d8cf99b4e86662fe2d5fe289c171650dc6cb0a432b8bd6ca98d6269633ba809af4eee0f08e7f15450685336b95e72e2553003ca09897e06e13f2184438bad247052fb67abeeb4a31ac5d2db3c9e9b5e7814b19e3ad3f267ba13eb218a457b16d258af7ccfbe1798a82a4e0a69d83a306abfc69853148356fdc04750518df0d5295a1d6a350aa37579022b4ac3a6df4c2ce72d301c4b4294901fd0675fbf3d286658ce0aba53a9cab9633155c86449ad7e029d1c5219f38fa0dca70bcaea92303e9b884aa179194d64a5610dd0fab756ee787257a9b9001f6efb75a51498df28200a72345753a15761f8a8d2acfa2363854ca1484bfa7e0ce820ef9e1eaf695098a98fadc94852974a07996a2d84420d32740fada172d33bc53db25335cffce978752c8bc18472847bac89a039fb0d6681f9708a8855f3189e0542fef1ec0199c62673a05882b2201a5f80ebd7ef0afc25869c9c6ec5768c2604cc00a188d0dc63d5991bf26fae8d1873bc7131b785bd06ff8f60f298a3fb20878f0528066657bed1416c0c0778eeb12ed05aeed5d420aae4e4f4c9077c7b49a3ef6d8072fcef3f2067e7a6f86273666e823e5393fb37262701c3e380776fd74f568a36486620a29be88c1a266f90df1e7762093981fc031d19a2931a2d44958dc7577d3f554b3a6a38c5b97bbacef8bcdf30c63c4a9b0859bbb936e46a8a9ae3858468e6f865eebc963b7c54369cf20a3027721f564dd0e83a8860063881d7758f77a012ec2851c57fc3317cc33223428f21c2cc17c49d955b8b1961c488507282df975a0ad8b4edae7e5890a9d2bd746bacfa0c27d19bb75ea5e1c737e787c7ed81ffb7e45252ac10a13d1966d724e09c6e1573620fca7d89df652a9a90a9d6c92ecdfb1c11f36e782276dddaf4f5fc3656abd523921d892a4d464354f9c32e97e83b96e39cbf452f23e9db3b277ac6b63cac65d537422c0e006661269b3e9408ae02b3f16bf9fdcf79711d27445027fde826371a2be9a31aa174aec75aafc57da72b38d9c10872bb536be36b127d22f71ad8bab99013bd8f60a32a7d57082975d1dff8f271805e29297506e14022f887e311b5211404fb6651ce4ed03f5fdd468375515591f459db7814c77cf12e370233b4190448c3280dd53a4b71ee676c8840476cfcd589b30bbc93e5cde78186f8e7f89d7af8ba0d2ebd150689b4ecc906fa239a14440d8159f26d49b28006476e57bbc7d6495089a746616ac7beb0abe5ca1671e2f124cbd76d014ea41e89c0e49bd8fa039cb767b0c15905fcf9f24f3b4ba525177ba088aa79b32f56779957699c03800179eea8bcb15ec0d3d71013bd0d7635bede847e5d905d8f973916ece4dbaddb48f75ae9288acc429c88c6367d1b1fcfaf6a892503071164f2c808fcd8371de280e0b125b2b095001fc41fef3825eceb930b82a181a5e0b658e26942ce907c8f5408e2d1a50055c56b1cc32289a9e042a23206db39dd022bf72e30151bbb1c0e65bd0a07d87e8839a8f286555478845a9dc71dc80b6513ca6fc1c139c9a4101b884d48f040e353bd3caef3c28ed895faab4dbd523de4d713994c73112f46df54af4e8032d2559b106302645291da7ca9c4ce3aec4efb37d9fa8170aa2b8ca97032f18246686a9252b43faebf2cbdab1ff896049a773a45f3704d4ab9d59806d2d1904acd2fb5cda5dfa2d3a402089f27a116c9e5fd7f1cfa73ff5a4fc938506281f91c147dbfe751981f3310f818acf651d59804f3e37073e4a37fed2bc7f2f7222d8c78b04b797fea332e5923410b299e420f225014626944b78e122a137a20637dfd14dd5f89a04c6f44b5e928444c13f31bfa9c24f8de8251cada613b26791436423eaaffcba1541d4989408eeaa2326e6edceba1aaaa8a710d10c059f013470c7e55a3b1786d60958d159113a59d14636e209ebee79bd82af3f3b9f863cd02b50f4d13a535ba46d7285d6c42342c7fdc28be10db3dedb41fe6d52e11f77916d07066f28953996086a4e2ec4deca7b7a61be4c1a2c0263a42549f657f9fcaf9061ba2204d979f98db9b9414337c4793842011d3d1ee6b6a700d68aad908107407878fb027268e58057748820b74c041c8a63b90203c2929b45a602c5c5fdd70640fcac0fbdf9367626bd6b5c683b078ebc62a4f110c9fea2cd45f55d8e2b4e266ec11b61e57809ce1705bfe75ff9157be7d238458f81c11e329b01b2d2b4d6aa7c3e53516e7c6455fb9fe500ddcd11ccea0ba262d17d9048a15a5bea0b791cb52bfe2a06a067c17f1f8944e85665e6e612c72aedd8ab47d1c2fcd02193ebf165396a3453d6984a2b81d06b66ea39646c8975e1816f7437831cf13dfccadef01c24cd03cfa630d6a9d023d37f7403b0cb596dbe1183fcb0987dfdb66ce82a961f897245a4f6c9d6e49129bc853f6406b072666fff776969fbaf154618120d950dd02d8c61e5bde6d1483d5c370272af0af8b878d673ba8a85cba3bad905db07ceb8e370693a830a8b3d9a0d1c4bc16844fda9671247b2f91d5603e0bed07108a33862c10b7adc06c555a2741805ef4da7bfbccdd6d4be17d9900953765fe30d5adb8b9ed74513e0aa62c84826c765ed6aa916f083675dbd2cd20b17124162b114efda6540c445764634007c2b8e03907d599f0674e03ac68d162aa028956a5674162dd4a695148fe567a2dbd18bd0a7f849d245caf14dc55f8e85e1838e14c7ee5e3bd9442c6c5a4e8a2fecde281952e0cb1884ae455157b71d8479110692c42fbf45530acdda9cff3e319e76f92559819a68e7e425babff71f80c4c27d4b7421e6837f4a4362a7d66f084b80e69917e85128b669b455a3c5bcb64211faddb48b033d09f6012d22c8a7b6dda1fda330ab19bb4283c7e696c455472d7752474c8efe60454ba3a8c2e2c6c25b933f320efbdbbb912107f193cdfb5e33172ba24621d40049aad23043ed70da25101cf2fda3b1e78005c21bc3936b3c75424f4b61a7c39a3bff1dd6f9ce7080e9e59e8074f6846834e36984cc0a84d2ae703398fa8cf6dba78e58d39dd26a8839195e66c279808d1998c8227af9cb3ead4fa3aeffd63a6905287ec1b14bc99df8a48ad4e3bdad7563e2586bc906d58e5fb292309fbe774ac0e1631bbd97f1f0c2da2019f49174f8dc8b38e8d261ce0bd6d7e5eea0c559432473f48ed0110430876d31308be5466e74c9eae7886d3d398edba03f65d42c6dbe0f16967b3bd3505f696c56465e9cafe28f6d57c3ffd64166b874936fa185b043ba9b411c4f0e7784fe6fdac5d3fe0a7e30cd8678771bca1e8ae77678f3769cdf027d38c3bae583260a3dd20294accda1adce0806848842b26554abf55c839a4098bb9b7298229f2b04f8219c0bb32ebda677077c967cc1f324df7b22b05a21d46696087dedc857911a33b618b3da844814a2e173b806b703f7f13abcbbb864bc5e92c074c36e71e5d7f801399109fecb8abdfe76e65ce6a65967e3137f535584fcba5f8ebfa093b7735643200ffce18ab9f9aceab7e003dda8eb1171cfce49bc847b1214ad11b482d547bb134a06861a6f01fb30cedeae60fd9f33bf3f889129cff35d5111b942c9d29f12b70340069533f9f4bde20a49bc6cd8b4b315852f78aaa13fc278b3c31a69d4dbf7a52222e82b36cf9d96e69910d33daa28e66a7e867ab6363e0d108e952c431a2d6ddea51536e0f9dc575e829c0c8359295d06a08f5baabcc342112566f70f4ff5d916e20e4bf75581fae3fc5bc32f639d105f335616b6fd665971d599fef54377bcede1ae7a11419975fbe9e0d55398a3eae34a7a44bf5e4211d2acdae3cbc5b80566faa9b5dfcdb2c45aff0a8e9936d125229d17770c775cb7446461029850471f671707441fd9909097c8e208e2de70ab721bcaf4ea9adc21877859f4bb5e95a564f2a76a811b268312ed6a44d5d0e674231d979cea3b07e13d98da6bef444d28b3b34be578ec4e682da2b0e404e75737ab0b7455404e46a1e60219151864735b69f1445356fecc8f0e29760ee87e751451fd27f196a30eb0cad8c3baacda1b143f599c8f9bc8b269125581a8912769794db199a5c51c6353deb9129175a39f62e288a7eb4116cdbdb6aa99d66bfb5fc8bb558d9d6753621087d087b022b7141391cf86720ad5c6287ec8db9d01b8710f20d0faf185fffd10c376d50eeef741e2e20d8c1e4891601ce6074890305c32a52975b284cb46adfcaf8a246e03bed2f2ddde3c199b658f1212b887799e6f336a334346863df056b2e300538d629d0d2fd821549d82ff9a7eea1f69198a0ab45f14e42b6cb8e7fdc0a3c3ce6d9a6b0703b94ae749bea8b83b17fda28e476276d698d31ff705e9801f79f185a95cb8fdf3f31132b9702b9b1903ae3312e3c3ae856b1a35817adf761c6167000ae2db5e6af6875e84de9b14a45689d8cccffd2ad9c288c4013221578b20bacabf01335fbff25a54697441ffef739a61d77fc924f7d8f787fb5d31d3d81aee87fbc558a4362a502fc06c0fefc35b29159ae418b473d7f42f8765b4260e6749e890776cd0e30ae69553ec087e465fb37e554210f3990360097a49b73df95c232eb68bf818e723a16a4e38f3f4d055c7d04822a471078bcedf2f47023c8934de1333bdc2494442a761f4ae841321188dddf7f093e0337a5734c074821b4746fe43a4a3cad4a631b421e03ee9e6fd40b1217d40a31046450f34c3a669c2994c91ee62267833f30825412e8797334a31ba68e8235428ea29feb5c4cdf9c3decec23e6bd38ca3e973a822732b8ec73905406e36ed0f4c1cf1cca806a43ac7ca1b985b812d6018deb4aa46d0fc73fc16eda0f61aa475c102129676819ff52180f88fd78459c7926c61c35b3d2cbe8d60e20e17bb60233f386cf43c61ffe3542d6e6d71e8229177c1d4aa22eb03a995d0c9a0753a9a2bc8dc79ff0993b043a158e7450df3124edd91d748f91cf5c11d4c9f55246bef74ba5bf60aca3aa9ac4613eac0673756e1f4af0a46e5fc79b8504badee55293c9cd881f335f3d3e58e979583b69e909f2ceb1c25b11aae9fc8df6466dfdd9274250ce133d0bd6c82faf60f1f7b627edbbd4d27c6754c3f57d1bde6e8e705274f089fe23b98d20650db62f1ae96a5b088e4bc96cdbb91d32945e882aa9333d8865fc7e6e991d112d9f06ebd182da7f43215e2b1e72d46b5c6b1b33c544a05d064ace8fb6c09dc5903dc106fc476f9e4116484f6bbfc06130fb9a6743fba45cdd2d28e496793a1779f79646b9b7d262c452b01b5e95195752b87a52e2747809542fbe4ff9a7ba33e42bf4430488d25e8832cbc6d05d4249b3d4513c0deac07033d828a4cb4bda68327ff505f14abfe03e919883e5fd760f52550473a415548ca975b1b3a692eb4e0031883e823ac80c2786935719c04eaf5e3ad4fdd8c69e51feac6821fe6df9553a0e602f5bd40ae3ef86f06c1746e0264d18157a23f8d54b0cee56a0ca0e3f9e5cabdedbec583b75c0e0afbe4005a08b299fd7da74c3eeea4008ecc5f7fdc375e5d55eb91806f13b166f9ae4fc4a245250ac27a30d7d522ef3c42d22e88e8083ff57be9787b6f0a1eb7997f12b1dacbb548d2ac462e7fba57bf7bd3323b8d899453380c242391c7cac904be078d9709b90df7853e09cf02288791973aa7f09f3280e101d6294c61de6f9ea54b2beeb30d629e25f1114e9f94a3d402e10c4e196197b477bee92096337d928bbb30b82af889b43f6766959d2791709b450c9ac38ddada5b5ba164d30c35da3e34379c95739b29718acee13d9bc342ae02ed329fb13d784c9b4bbd5babee87e2af1d48e5f10f56f72580d7a4d5976fe03a907cace4e8ac97c24ab22287cbbfacf15f5ed10830c63bd08795e61999733e2d63aa214360bd68588a22f3e1f2f97bdee2ab43492ca1ae8f7af7bf3265a8e27d8ee0f3e41e6fc588a8f6beb38d6bbbe4acb1d38bbe7fa2ac24dfa48d9e90617287ccbe0309da327b2a190facebc4d74f9cb089980ff3eb6ea5bbef8e2fc3362d9b5095e7464a562ee3a13287fddb31217e635e34b2730c20faf59c023e7966bb281e4191aa1f3a03acb130e5d5a2f52d3204963ff567c93a8d61a04c0c248d3867ca9de820106fa25c266e8880ccb613abf1ff188984f064701c7a2694cc9a79551f5dd6c0e5490055ac901c7464c5cdee75a3de44163a797241e60c6f6390aca9abbf6548c13a2fb8dfdc2cb6446a590cdf48b62b2e435463ab1998aaea84cc20b2caa113c4db308bc1deaa805f269cf1cd2a737d979cf5fd07f281d0bf14aa280b3b205148d3a22930dd513141bec1dfccbe7034994b79ab70d48480ec6dabf40ff44cba9fce57d14690705c2255ad2b9d6c6fdd2c856df7e9de4f19b82e54d729466a36183835b01d32145ffc0b3fec7f1ca0de2558d6cdbc88e13f85afa9d68e2a2b7220e57bce1c373b33a53f81ef7bbfd4a6ddd82ad6e3e2de283ff94b5753e6926594820b4aecd680cd80ffe568507f56c6f3a7177a7de71349a1dd053b2ac7cd7e67add606a7b7baa8385aad067bfe8924e53d9ec9afd1718b2f7c3a582631cc1ee1f25c44d73dfe78da7e6baea2f8556916a14f764c1d79cc3399599a00da64d6d263881f629cbd7ffb9c58e21e4839722035d88d08d82cfddbe67cc96052a2f8e9768c6c0a413161af54954aff8c5942debb6b12bd652ba3c691b81548743007ec28d78bb6876a172ee1b6ae1c93e177edd1daa4d569278c5fea1a0cbca738db457e5a974b9c5f3f4a6992c52e97c85f01f0dad29c33868c9abe97814a93887260ace26a67e52bd400a42f84b2f59f126bf95d587e3a1f422e29b655ecc6a7138e595d59233a3d45c141f479139f6fbbb4e9fcf95f36c73a77e85e0ba0b7a2a890e5d56f9d01ac9218333ca2f77a633e560a77680faca7bd104b34c0d007c6113b6d143565e0dc20f2ef07bc3938155c76e66e56b6b5916b22d7b056173b577c9090d46ddd9dbb91291588fff156adb5ec6b53973b21af3a53337ce3cc6fb2654c430731d3ba16a4856a7531f24d5d177a9ac43ac257236883c6c7d9cfb8931e2f964ef4b8bb862906add4889d706370bb4a28f3fb51858b9f2e1b3ab63c3e0fac1aa7eeaec0cffc061bd620deb3d58884ed5260e46a6b03dde225d253c1ff77847b886495219d4747f735c207b42c5103a923eae0fdd2ef18553f9343a6b0a23b4b92b325c9dd03025026404dba4fc4d33ba751b2906b0209ea7cc3bad8b1507c2b370824d3e21f22c6a73986c929263f472f411ca57cb4761fb3cddcc9120677d4d3d8242473d249b4350f144b0fd6174c1f1e951415762d54cd7b269144ac7c59defbb944bf081c4f41067483dc69f4a3d1b6f61fef7dce5a1f55e6b3a96cf7cf9cfe56442bc500fea64fd1580678884ebf54978f03fd91ec465deb0f6e7013d9c7c5c2f3c37f417e2278163a889a891214f79a7ee33454ddf571444721ab7ae3c1dcf2ff8130a979d7159aa60c313e0cb071b3d8a28fd3c9529209f4522607056808e485cffa03350ba461f333edde3a19f3c527c69c72c824df8a820a0a602a5e2274b3761d64e5782aaeb9760f05f8149a0b7275fc000b7d45752f4d203225457c8e720deb2a00ba165e47b611301f3d44f3c5f6e112cdee17ff3a46a339e1e3d673e8c5cfb902495fb459934b8ef2c36c5a9d4ac5b963e2b36ac4249c6c59762f7b58b716a362c7b62cc257dded9d27061a23018c2b59afddedbca00413969ee1122ef0688152dc9ef74f2949d04299084fc8f1896f1c5c96cf3bcf5de2ca67a856798d4472e62949a4cb9e90080bae77281b6d18c17b93f2cbd30659b50083bcbf86fb98b5925d72b84006ffc91d936f4e7d4b560b44f531e4ded990e2ce26affdacd1db112c17ac0e8ca778fdde76777cd27bf0597905d230fe0768a50e337c5859df8220e478a1ba3c9f3f145f60b885c5e947389f8bf0e9820e855ea3807728d22aac81548827cdd64b70153a590b785b916f8a74d0cb401346ae53e926d861bb81b182008bd73917b7c0c8590fa1d99f43a456a0f26f4f26dde31d52a54676ae0d0049e3f017d725f39acb9cfcb3d6238915c3184e44e86a05b17db98a168dd6d33026c754faec0ddb025a2d592715e796c9dd4addc46a0d22112a23c089f3898e09fbb0b3f7173fca136bc458fc73a163c01d655836ca084ed4f6fef2475292d8d4525e0603306767404df70919804a5b89e28a3a87d05fc6e3af3cdd6f549415954990171e2f8f8da645b916f1ac7e80f0d7fc7cc653e873b0f792e872695cb2aa87c87b71796a36559028fab7cdefbdd31121cb570ddff93d29d6d8d4111728b61741e687e62e62d747c147eefb65872bf03cf2b89b19c4920d3c02c7a76dc82b6a21cca4c9a1ec419c02e613824991f0e7b0d1e78b054f0ac25e18aad2a7fe6f0b229c8ad40fe0cdfb9b079f0ace609fa55434edb329c9e4a8d29acc1e1458bcc2155a4df8221010333477172c1d079c2f20d47410a4986343380adee9b32d2180287c8e9dca74d3018fb76b416f360dee5db658592f845a909ba5db7b3e3194bdf5668c717856a8c9ec031538a9930ec4fc57ee067c662931f153820cdcc0f4180355db54c928085e13a305d351483f72a2cecd0b69e55f394fda7f9d71877ec86bf3516906d8c0c7525d1834424cef902ec4427db3c50d347ceaff190f2d488ede679cdcfcbebb805b9123dd9480dd2176aa6e00eccfc3f2bedb1b3593ef42d0305727ba27561d814e53cd9489e9a6cd259ec4b725d393fa5a7ea573e91607fec371fdce0ba663a8cc88be19a06ad6d0064c1b7cad1d96903eb110d725db8bf5ff3767ff9351eeb3c262f643c6373c39c35fe3e89c98e4354de2608a139dc6f4801cf4c758cd901d780b5c17827bf77e6a3a70ebf7abdfada3e4afac586ef740074603f5c30c4677b4b011633a458af7ed307429ce4a1d624337d5aa2ac5dda9506c75b684f172f3261c52e361748655bee2b187231195616113e98594742e214c0d5b4183f435b22fdcf278c796068d73c42ae47148a0987f2efee439cd877f821b5a5d4877914062853abff73872389b3b86f3ad1c9d0ba1251b011f94cdc04567d2a6106ec1f5e3cbc14b362865f2bf2857062b026a90be63fd053e72ad018388b514d70f4ec5e2fdfb89ecc83ae4a2d6fc7b07f1d858b8d77191eb5abfe8d7b5bd31699e71aa8daca6e5c5a1d931cb14bd248ceb1f6b3b4ed9760a5d24afe9183f3db2a8a6bd9313519684a50754c3e4bb2f82f72d4b5084f8a213704ed021655e702d2fb40de585763c9f83f72842daf453c29f447ecd101777140b008250c3749829261d4aa22a1e05f3bf58ddabbfc56599f35765c48268679ec7e191f8302cfd785f881a024853c3dcfcc167e1dfe2bc329e2b1d80c4cd86bce604fd9d39fa6b4258f1fbd2ebe3235c4f94fb6b29327c216836b21c68f620a3a831f84d1717917e82efdb986c7e50c5f52716bff90c4543c46f797fa1f4c7cecb9904218bfd29034e24b47cdcd12f8dcfbf992df0dd9047a4207df5e4f4646e5a3b91135eff56c67fab9f1afc971c76e58db4cee5223a4fce868bd78b0a85dea388c98c1c0c59e027c5703bee082abfef93bd50a4df43aebaa0a47950e95c70eb9cc7dabfdc1923dac2ae8e14eeba7184c0efd3e928ae672bad9299462a27313761bf07cb6fd9bb82b4e1e83ddbfe80fd24b87e43704b8b2b12224ebf46e06a283c193204880004780dd517c4828392493e295064522de64bac054018a0575072d4d59896402e1eb7835a04d768698427faaeab8e113bd20b632dd0fcdc0e949ee90f860c65b6e3fbcd80ce01ff902970107b90292398b628ceb00f6a193805e011fd482b13670273fedc4e5ed5c47026f9daf69a7572d47b755492c462c9149d86d1a30d5a9793b04dd08f63af9dc357d2dc1474c52ee9f5171318e4949e65be3f1ef833423cad9bdfbd0fb8b1fb3d284e8d0660f9a9e66d4c8ea6bd4666e8fc43e1d7da753533c5b27ad64309116afea9cabbdcf4f3adf5d48579e558d43ef417009a5352a778aae608b5f207c6650c310e49329024bde76f140aee6105ad54e635aec3999ff77ed47d3a3ff76dabeac96e4c90ad329b8e545ecfec60a0511706b500949b8f47baa1673a94fdfb979da5b2c4a4b3322952aa5711d69661306338e84144cc321b4461e57e295c4cb59f955878f4dc7a76bd31fd42b389bd0caba4c9f67fb3bbd6b20f6e5e254dcb19b9d88cbe5f34df04dd14d541542e8dcf33b1c7974a85813f7336877624c7c296a230a648f5be1f0e1d084d0e327b89ea22215063f56d41845ebbe811b343b5cd9306a449505512e444b484c336626a2eb2a5a175e6c8bcf0e8c5a076729a8ba2e9366635a7649e2ecd54d860158730bc43f4d0ce4e80716adec256a92fce51c26f35968803106051dd39261263695e9118d863ba996dbc8c2902a9dadea22f78a5c4c90eca06db3eec52cce56cd22cd6feaded4e369b772716f19a391b14f21328fa50ca4d32a8f5c4a428f04621c5411f1ef4fd182e7dfdd7ee7dad29adfb0cce179cb6b95066363b83b1dcdef4d039012d973de8bf3350832f549c87017980e73d9094e75fd07a4984be737041d73e3938d54ceb2b21f0ce63f76fa60f67a479373db6334696a495a972330726bb7708a7fa5778034cc3a299aa4186c56da86b56f920b06911b3aedfa0a36ef7e48a546a6a80da3549be621cc2ed110209d0eda1ffb88a35a96c35c5032713967d99770dcf7f9a62af0f91eb50207b91eb043e88e83650b815119b8c61a94046d00ca7637afb37ab290537702a62961e43c3448437893c9d61f27d3bc6c9e20a9549e19460ee2c64d690c53439b1487da31b79f9bb1e10ed4b15b5a33d17b4090b005e7e8a55dea34d104a546489209b6447d00e6885cb6f9cf4493091f31ae3cbe80f61e3030aa47c4e05789a20c76891dfd375e19ef6030b7f01c1906c6bbe72cb8cd82f935c9ad1880384092102c398ae39fb7606c3c338d3718217566ab52388d4e17ebc8e322e4d883c9082d4771d8e785364f7770cc4aa340b3208a0c7d5e9e6ebbfc365051281625623328ef1ea93d350cbc80c593c03b3c00c4d489d8f61681a9b599d52adc033591af01ae05119c772492d9e5930ccf32810bead4603cf6fb1d83b3d5049dd3e7416bddc7d4febf293f1b407155d8a1b6ef98ecc5ed30d43aefe8c7acdf143ebf904abcf6addcd18cc63af00f3da6ad6a221b423e8909d8376e99772a2f009778060fd4605fc1425c3fcd4e0cc368abc60c1f15c36cfce6309cb7c2a7e12df9930237f705f91898b955e8704f528e23141d6c6dda8133d5cac723bb6371b833b5a8dc8e955bad0e829659f1e0cd6313d40c772a81bb22eda77cf3f29ef15cc9a5cfc2703f01bbbf9346914bdfa272f44febf993830363e616646382e79a130c52d5f7f5c34a6aee14a2ac164903f0c2bfb58aecb4dac0ae56e5837ff850cc0060743ebce1e733644b01b02cdda645416bd0a3a0e433700be28d93aa1665214eec1a3eb2bce7ba7f7397b8a43a2383528f1fa9be67ad30bb2e3e363bfba936b5e25a6940ee14a750f431935e4ffed91511ea0f8eda782f5e474eb59e51cad2dc502a421b370d9d8734928ec913ea5d4d394376045022f04782e63118ab36543f741937ead49bbccfbcbcce47d6f467a9fe6ab3b580be8a28887bd9f64721cbf943c561232374deeaef2db5d229489e91f1457868a56b6ec00d7e995f6fb65bb0fa9b8f72533ca78c637cb5a84085754ec8f2bfee79e7599a30bd4511a85a24a014db44776a3738d6d0990effc73ed265641159a231f6c57c582609d96e4ebb4a321ac1f644570eba7bcea7545a9cd94d60e67feaf590ce0d2307f35a2d4a753f8a09fb5d8a1f4d415aff083171809336e87df271ecbef3abce07e66582a0499e623583fc9cfff3d84a97f398047fb112ef7283412e4eb5db5d688a686d942cbfb73da19e5bce73a58e62872e32d3bddf08271d4ce48432ed7d5ed547f7b76a52cee779e8519027bfd7c5f2f33aef8d5c158a4e6d42fac206de7a52a2fc9104eac0d27e563944722e66100216c3f48a890628bb5a9889672128fde1746667a2ed42f82df93fb512d2d527dca2705c2b6d3c97d1351dbd1337f1e8f0cb361820fad7ed6a467ec37a6c2951b64d4ca92160769770cc1f04ebe88fae2ddf952dd5c9abdf50b9ac9a5c38f60b947c59e1d54b57d6f6aee4bddae19bb74d368580d7cf1dbda93ea302e5ca464b90fd1e6ba9d4738fa5767339b9f8cfceb22da30f5bf219e697f4e7c113c202695ef663ff33fed568e992c8bfb3bdd25ff2dad10b299bc84cd9a1621b1e02aba06811b709baae3d60675a8fd201618fbc25779d623362b23d83a4ee0bec3276c465221dc3e8975cef5441e04682a3d291072c9a69892fa4be4a691a7787caef12ff9dbace78c2c905fb760a0bb333a1db7994179e750bf740d6a7eb65a916e8d32f78204bd409e001941fd3adc456932a86a121dbf7cf03e36a9130a0d88a17d055447d530a4a7ec9fae3b8ffdbc8c66e25a44631bd7048ae2dd813f3e5c43b6212570dc3e2f0fabd724e583aab41deeef28a645334e9c877463648b4e4f0fa8d05451a5f68b39afe1bfb3db251da81d19d620374786b8b2c72b3c9b1c2665d62e5f5a493d09f0f92ce34af0b6453f8208c225d99adc00e8c8581d154bed0c3f933431794702f8feb0cb370a6f1e26dfbcd4ae56b6ff24149b952caed0e19cffff8cbb05ac03391e76303ee6f9113e708a1a56cca63ec2226d699b64e082b9dd87d57b53c47956c8e047b41f26478cbdd158c5938c227ef6d4175e3ee1f90c68bfd62747807ee5dcbd4ba9134df82225fdae7095a4c581f5ec247e3bb84fc053b35850a03fd366100f6f67311cf87bae26969a63022f6b758f198d0155d09136cc87574f2d7ac00d83dc460c82b37974599c68e730eda75214bdc77845fad0a44731e3c9873b4aecf0df54601137736175d629988c6582fda9293e27173188e3191c421994d01faa6cfc58747863ed7c480b7b31b1f868cceb19000c112c2d0554a68f09d17d25a1f6d69c894e87acb337fffa020e12db78df78ba01edd43217bc5921105df3152ce27bdde86dddea9fc81abc4d1bbbdfc31f309e11c8f73afa700c52aa3f6f7645fd17a0f3189cc3a0563017b41ed54267a648f4a08415f74cd3cc09dba072a87ab85d3925661eaa1e6f624e8e4b19b73d90b4aa3ba17f0a822f2ae18bcfe403e26a97131bf66164d15e30c24f7ba2c76fc715fd8bbaa639a94b866ab2a9db68688601fa6f07a6b810621473f1d8e98e134111754d9db2e239203466c756a3979bcc5086962d231dbbb71fc2eb57a4435e59d4b8962a8938953e51e62df5f8c8a462bfc2d9126471dba5853f6a4ab8e4d8f1c71b2d6cb6f9b315555196bcf848c4e9bdaf8eb9718229b65d10442eba519d89d04a322b1f3c27e34b5106babe0268a6e8824492e55ab8bf0b90b566924f8a7ea42d9edffba6e515169953911d1a5505c6b277c844d6b534ce1e381615355aa3601d277a2a54c74ea6e87de21ae103aad22e40201a241bd6c5476338bca1ea838b2baee4acd6ac91ad94b727e03e1af544fa55cf749698069db1648ad0b0f6a8fe71595e693a2f038760acc7f2db5c791aaa80ad90da69d002e59d94e3ab8eed386a63c7fc0c2fd0dffa19fd2c19681e35d2ca4f5ac374d96075b3e228ad1cefd73b6c7af0c04d7701ab97aac8dbc5c8b524ada61b639f5e08e4a600b33a502c716390fb6a3a9e91e64fd57ce1c33234cdd05e59968b530a66456fbc202968db5b9fad47eb2b140511f5205b7a44185d9dc9ecfb910e816de3265f4f7a94087e13cea83feb9d5080faacd16830298c37590f83f1ce9c058d23772fc470dc563bacaac37769f877f0620f8bbff470ae36f894ffa9aebe0df7b9169830d9aca9f44a0fbc2b97b71a077003bf2f90eefa1b0ac11e691c191b888be5b42c5c7e5bb8f5eed37c083521b10a186d8771948e910b1c86814ff76dd7a39d2ece14b9ee1136c1384a3a89a176b9b71a5c79fbaa61ceea3e0669379ecf623f69f0acac603d24c855f078ecc947448e9c0078625ad0027807fa5cc0cf1d788d785dddbaf84d4755decbc00ff5ac3de47fd46dd5b440ac534f7a037fe781815d813574f95ad05abad630a862c8ab1e33e04420a7be25150206ffad2de39f2feffbd04834b51c20193fb19affbcf9618a3127724fcca186bdab1496e8e481b4ba398e073380e503c268db45f0d76054b4f8c794766c7fdb6321bd7e0f2fa05f880c2ab8c6f55d7adfb8d137a44894654097418ce6fa65534a09ee4e8295b5ed4dd7049303cc2c5b450ab1dd6b89ca34903a01b76b8b55dbd03b5dc4efa08931c455b59ac543ab9184068b7a4e2cae812171436b01b3701ee85c91417c40b6d107af6b4e5ab1aa12cd73bb46feb83e8e187b57f7e874d9020e086239acc80a74b046aecdc9ab9c8cab903490d18a066f88b17b07c6df7d77cec14a3e3543f4dbda6c9676676cfe1fc977654f95e9b9f98d7d819bd72661ed2356df1ac9488a5e9ea983478ce5f7c867a2d3efbf12511294fa245a3a44ec5ac1b5d92a8398066cd8f45a2fb6aa846dc3be511f3e74acbc5e493c6fd83ac8ed34b3efdfa11880a557da1d27de237e2f5b0317eec5f9f4d459aab0f7575f573bde6937d10c49fd4a9b996a44cdd073ddda7b36efc0cf5892b231c0cf5bf20b3714bc7c37986d070de30f330ee941e822c7f7f1591e0f170f965d8884cb451f98274813700edac77a1042f6dc33a4110e39b466525057a081fed53067f7cf370adfd4962a46395d07e57a0b88037e6ad45d99ef276248d7bdda65e23a63e5cca216ac3cce0c84772068191f3a16544e58a3bceb6f65825e22c3a949e47e569693c0afdf2e4eea457c580637076e9663fd85c793393763e5a0bb23c66df86ec31aa3482d2721e38109810a65cbd27bd7b1357373305257e43eb421f1fb0d81b71d9ecc3bec775288332a478fe62133d264d06b2d56f8de9d44e1c30bcd4a50ba418c16bf6640bb5842c8650437ce566b06ea8124b3d94722e95339d6e558815531287a3f620f9cb64091e3770020955f2984858067eadd735816d59efedcdd58be2a553e3e2f9fc5dbd2d0c68f464753b012c91e9922d61667581b55ee75c3e26071d2e8a6f6b20ccb8784ac4e0abca6d9cd97a5a389f01b83719ee5ece779b6ffcd9c45a23c41849d79f86305ce162a4d86a5a3ac13828c32a41f16b904c2cad3e91bae24b9d09a96b1cd4907d42e9361b2f8641836159401e2281ae778e7256d85ab6bc27ecf21782bbc9f26eda3cd2294e22b90baf1ff57cd71e544eeeeca206c0010d25232b8276847256db9040766cb6cf7c26c87a489b86fc457b5044af4d2c146aeaa329be169f0ca8896aee673b320aed3e96c2d8954312c889b2bb0f9c099f6bb6a0f9f2c3a944d7c16f1982b3cdfeefa2dbdaaef44a5ffc2f0a1bdd59393856f09861859ab1e8af587e210aa72956f15f377a0aafb603018f397272d43b02ff2e0bfbc2136594499341a65ea88a1ffdce41a141dfadd3cefc414afdda796f06d8bf4f5f6df781941b440aab0558e576bbf477b2a37914d2211f7adc0d79135af9cf7d6a83a0a6b983076eb32007c75297d14f5026b438592e7f20188fd98664e18fa19ebf579303e0b0567c9838236739511760eda8bdc51308ebc2c0921796e2b4ee1891dfd58e175da52eff43edab3903bd178ed47fbaeb103f93f90f722d65e5c18566f50bc26dfe341ca2ff6de5a31a65f39ed01c2cdc5b1605f3a9dbfff4cee0fe5bc1147fd3349bbe75d0c05620fe16dbbc37e7055142b77690bc85678054b73861e7f131beaa3a3c07388c599bf7ea0470b74fb87f9d7ff34fe3e4c8a90ef8e5ed18b77c96a5c5eb6794f42f981cc0b4be8cdc5d2e16b080ef5e524b32a21ef65130484400a2265d3bd46622bea201cd58b2299264b5d454f423228a0b7718f6489f4e2b56f81255a70062593c12c8da90de075e9ac84078da0a6adcd927811706b359dc13fd1062cdaa2b3b90a77743f28d4bc858472a1aed8d843926fb33e1bb781126c2e303baffe87c59e4c30380348733d01254f75b4adcdcf48d5bbadc7e8747008f7bcb12692a2a95787e20a1b82e2c39dcd4485ae754136a8d5f9a812e36064d5fdae980ba24e38826b23ba8dae758db27b546378635ab436f634612bdacbcd1324d3fcfdfd16bc06f41bd026ef4d06e9d1a90456af0dd27bbe0a9fe209739496aaaccf59fe8e9134716de0a981e3f0a497753cecc0fd8c56dda5b30fdedda509b53410c5944437cb04ef17616af7282b1f50fdaa74093c77163489ea959eebce419c8cebb8356b7ecbb043f31d502375d8e70d2e16c21131f92706be3e6276c142bac345110d991ec9495a507c0af66e2d11d125dc8947f77ab0df1ebcb30b595ab1755c946bdfc42a19ae68462b931c0541bcd6a95eb6ee7228e835bcaaaee9e79246763e411c039c6a6c7184082be0454f587e020cade46d4082d72c2ad436305ffa4d71bc0fd24a6d4cea8a38d7c2ec373d228d5641d050f0579f8638ccc4b1cfd6673dc7b6ba923b3cbdc19fbfd51f8137ecdd973d7d170985c2c32cb45b72bb5aab1c630b59094abddef6f849b9024f4937408739db8a1bb2d454df272f91c065f6fe56e1883e3e0212c8a1f4757a94e026e146509e46cc8677c9014f3e375f9f9c759d5b69f96e923907c682d4292031e3ce1793afe4cde6aff8d77d667b2a711b19f1148129293ab1718aec1cc1aec40786c1bc71709f5cee1b9470caec02c88aeb1895db4f7dad6c126f9b6aabd22bf53a58264554d16acff4692aaa4bb26ef11650ba2c8d18d0938e87d6c210873a3ca67da2fd42656e0c32479640b1b6fb9a3d8a295a0f9c16b973e0a30f7ab9ffc1bf36032b6a115f01e561ce73f0a85232326882b15b958efe2287fe4c53c7ec33fa81cbd17a44756dcfdd422edc36f0a2f227e1f6f886f95c50a250e41f45d0eefcebb6d1978b573a9a89fb188166d7ba89e230e0fd0039196accbdc65806ea844a11a96bb4446155828989892f3487631df7a44b5f9622ceef228bd90ca38fd23a24e8ae56e73f43ff746402b624786ff800e704b3719fedbc8cce04bede2529b68570fd2ba1cd8c2f2ad8f009197407317f706eb85e0c08d2e57697241da76ffc472a8df50cf18549aebcd2d950bef64c9cbd6d4622c3750b0d5329bc9dea10b6aefc7cb2786a061916827dba20538572e38ea2a536b367f9148c492459598cabf9aebd0b84256d80f4584b6cfc36e1cda4ddd0151d45d1486b7513c56f692d757eb48e135f85bfffb02bee54d38b2aba82546963b7f10a691641ece6790663b63341c25d960147124be01311489e5eea730ba691771dd9eb9258a9d0635d2f18ab886c260f53adc25e5c8ccca24345bdc7d975a9ee657340912058f8183226c6d00927109424d4ffd72e5a9507a68481f9b5c5360c8dbec4601f3a496236f54361246af06778ffeb473550cfbe684367c9bbb45920f7b1bc47d12d51cd95feb7355339ab894c2cb6968f84dc656e532d33cd515ac5dfc62d0bafaff20e37a573e7db805e642c096f75f10dd38935aa746b6b4a4d505900c4be4b71cf9de2de02933333e85d92948222489cb07f7183dac1c7f7ed9a1a8624e2c4862792c4ef9cfe4994bb43d7c4f27ec47d6d8539cfa43c4d2dd2435244f93487718efc3f25b67f78e0e7cd3da2f9ce3ed88e95f32d20a6c1e6a53bf284367279b1e79089fbab15292b487516b426d2a8415928fefb8741cea5cea13a04f517b736b2126de56d55fc600dfe2a1d8eca0c3d73b2ec3dc0049e799d3f142fbce8fa92e950cf84984426055f66cc5b0d446a58951b51aac77a95cebe0165e83f8f65ba8319fba86eb8f199caf1d70fe11a71e2a8c79b33e572c9d6c20e2940ce80ac925a3d3efdecb1358e6db8f8b90c29c447dc50eeda51066ebabe08a35acc36c5edfb47a120b59732a10b4cfd4f66f5440ed871c7d296241246703b71d44707101133176b7eb13a6553f915f6ad3873aa0f2455429ae5ecf6536a329a2ae8b23766d18eabbac7023b2b8304c1561fbe6e9a61765a45e85cafed323a5c15cfa2fe390f1d0879d2967093347aa5242fd57f6b8f2fe3bba9b6caf29f7943372c62566005394016f45c7a9f105a7377f5e01b4a273ccb698c8da8c7fd48323ee734a7a07dc604773eb442120bbc0c5b694d970f32cde0df1d5096b863f3687a8b03d959ff8f34f1db8b398fee36881e190aaba505b1ab3f91496f8cf746e160acb7b05b1230ab46d2a02e63f06a1028c0a6a0958b7e6dcc82be2115a571d49dcf2281a84d6f0117f48d2759bb9e94634eecb5c78ca2e247b3ddfda2520d71fc2b33aff442d3c31d9c101d08697884720329b5d6ffeb9578acad3c0f969f192d45ece3cdb304ea414a484f5fc014727bb7a8a47d8b1cc6d583af802dd64511b7743a9c00a2eaaa5aeccb1af4a79822c127693307cff82a441ca76a836d397c2f0910326a3c832b27dcf057942e08dd4d8103953b0f9ec4f6124fe4adbcf4cb0a0c5237972c00deb1bf003f3825ea61bb0b3c0dfbf69aa09edfb28b3bc5d1314f64766e0bd63e978dd8455b67db35756e0753ed6ebb1b9a8d6e0f55144d39d9a813b6f9b1183e137b0873d0162f06b946d2ae320e8a7ae0e67d41eb1f77f80f94e9fc625a39ea3ab6491241c7a49883b5a529e802e1dbdfe61cd89b012894a87ffb454158ad6d071ebc8830c5ada8733cec136137dc8893211dc181c7378293cb72dad68e4bad7eb638f8473db316f246e853975de868a0ce401e9c2d98943d2645a5b40c8e7c8562c1a599569d270d37400d221566d6951a2c66ff2d32c68d09a22273772df95968d9ff6949437f5d1ed2e2a58fb2f6d42380f7595ea9a398182ac3634e2cb9f2c67f7f6e493fb40577ae555752131cd678b2a94cca9ec6ed5630ef4f9d3c873fb9f111f4cd69805c9a17fa9eb5024b3a8e0aeb1b83ff9484981cf6c7aac2aaa6d94dd7eb7d10f3911e730225be4892cba719c94b9c05a1bb1e600bcb4aacd01c1bcee7a13efe55f0972b0b60abcf7208218b1e97a20b47e88e309a7d68ca27e6544662a79b0081a299e8a66b52af65c4c2ba2a903caaf431c79beae389ff32f38da4ff417af1af5f165a23f32d088427db0b4d818beedf1bb16275cc791fcd3da97107cf4ca0aa7ba2faea43506df7baf128febaba96aedf7e857dc223c3224c32a10a03ede2947edb63eb8ee2f0e9f3924840d4eb7f376f21adab71425d6abe12a0c90cee4f066a507d017cbf562533a85fae4f0f0e622af26b83687932628adefb9265046d24e42f3b3474df5409150e52aa3ea3c7da0e1f6f6419e3b8d5084ffddbff0cbe3bf5703793e4ccf5645364e66b397f958e7b4b80396d6afa90890b6d78b863e7e572c6622b167ab92acaa2108d2cd17d84ff2a2535ba70b056303a3568186fef884a3dde37a6eef0c899c8e7ba41a0de4583b9882c140c7e43d88a083af5b382392b9652e61b3753376fcbcec3e641fabed123281d2bd1b9521cbabf9a28ac7d8937bda68bb5ef214ed35810b69b6ec25c13a625f3ce1f1a28bb034a51e15a62ead4c290b27d1f2246e605893863296563ee66360dc21fe25d39d943911efd22a293661148070a43a0ea2445d546f7389a84bceca34dde763dee36537c887c997c6021d5cb563a87e4f41f74e28ca53a0f9625bfac383ea8f1a3ca743feca36f098b0ce816c2b55b324d05bc4a8503384d89f977c5efdad6d61be463b94eae56060ac095b963d7643cdc082bd96f2967f1458ea459ec426a47a6403f32498f2c1261b02ed77dd734b6b71ef5d1f31537c2f2ca1242ef471202e7701881f5ca685363b7cec32ea6aebbf6ef7c0bd6c668427e7d9f38cd65a178293a7f7ff66ca2d23f0f3ada3c86f77153749d30c504553dc508a22976c369b984f0fd1b915f8d52c1e2bd3a8ed7b80592be36399cce09e96f34a819282b9e896b31ef29b04f3ec07f64b1507f202f34b7ea0a5e578f25e9fb2df9a50890d5ac598603f6130cb7f6fb4cce3b79257a0d6baded6f22bd476f08b56d075cab6315a89c435ee1b6e5cfebc599bcb837be4b6fe06988d7087545bac14a04a491cc65a932abf610d88265325c6af3d6a313cd70a58e3b67a5253950c0e62392469688c98d1131970ca5151dc5815cc0703a4062d7dedd4a760ce3d2b2ae2614f64b0bbad312c648128b27caa0143978e19a8c9c01a6d90864bc7b1162f47d411a7c7b5302e71ff039636bd8e06d45815c136b828d22c0cb25cb92c1d926cd581426cc24ad2dea1d4edba6aa01bbfbd7bfdb7ed727bc33de4f738b21cfe81a6aca1d56d8e368b849b88a3e21aa4800b328b05a4efb6857136f78f6829a1b4eb6f37f211f2a10c1f57e6d79573ae11657c56407f7c29b073f7c606bf370d645647b47378f1673426e3c03fbdd8172a9ef3e79b538856973eafb8b47d9bb619df9c0001a8f096fe1df1b91581b64ac98972ffe9a89ad65dab0befbbb9c16f64c47cb9fe679e4936c165b9753edb901e432804ea05718b2bce15a99709e69e144dbd7d6133a9118b07a5fb29e846617be3a2f724cf61a7b366dd17618f801a796d4f9bc8479e4cf4ad2b6de7da5fcbf08abc3528acf1cbc0b3fc31ca89801633f0c74a6faa2dcbba432b424f062c4a10a6e901ca58b6812595a89f3397733d116cb4980ba17f264b423ebb5391b158cb5a0eb410c325608020ac6ced04b5f9ac17e411e2d7a0454fdf6184aa751b6543f82568467aa0f22dc364f69ccdc316b85d3bb30e2fe7f87db4b99d9163f852d2ad4ea83560cb63934179103d0936eb91198f92011dd627953ab8300fa2df81c6d8602fdb3a6b200f485dde487ae159fba0392bba06e523238091dea629248abfb91170269366c6691a3564f9335f958e79d31dab168ec699e463b84c3b84394cd008dac5f56a25077deb44c408076041cb49568000552428df65ccbfe15df0c8c815d131997d5d8a374a71dc11b971a31e6e738c31034d18705ab31ac7b1f76ce981ebebd971d299245d88f3d8a9ec5c10b03fbb38f9265f170f21024f15e91b53bdbbc591e9e973e6d6d3b44cc463eeae9d42a1c9df31d64f65652508f55358f6a2f35cb9001f91ccf0311d5a198af4f720d66bccac73463f01ac94a401eac1fc57f206e106f83eb18ca096f943a2bab6d31eaffcb83dbca286bc44f37753f599edec287d764803a859c670c9c3084bdc64e4990883dc4329f1e76f7629fac50f1b92df0a122857b07f593c4bb2a27882fc197e29b067707f34b83fb061fe19942b9200b68bed4dd4051bd37e95721ebc984fb70ad10b55391bcccdfc44e97349c5f6e7820d650b42090871ccacdef2aabcc81e97a13ed3e2e28b704202633c438354c49a730e10afb52d2e6c9d98e05445e0129f9b94e7a3f4ff18134e8242038707c9e540460b475f5186e525888bb652080156c710fbf63d9f067196b24fcf244eea814c7a257f3c9f8ba531e155b3782d84b8fa538237c485b1f38da0cd521b7e1602cc77e2c490ce94df755ee6bb95bb88f7a0dc79acd5b8f1a7596a946637b6fc3df7e05fea00808cf2c6238fefdf97eda773433e4a0098327770d430bf0c401b8ea8d503e4c69dbe13353787e04c648c3ac858df574c15893327283719672df0cb96a899f27e439b9800241aa0e29caec8e53793eec99ded734df4ab05e866a5f991924d99e7973bfdf8deeb95f4d7db1b546cbcb4e8f902930108b9028e3995206fa2eb84dd85a7d737f9b49a57cc1da503406f1bee3f26ad23e72a69930afddd2a52ad79146b2c71143ce4f3cf86cef1f34fda2904d9e42a6d444b7b87861b3c14976ae5a1b1c6048c8699d71025764eb8faf492fc2a1a9a11178c92a9f075011584f41d6a9b11eb90aad8db5b4ff09b2db22293166fa993921acbf5ddf7ca9d7e59f6e6fa2cb4e8d002654049a16b2e8493cbdb9832875445ab04bb0508d0a2eb6dca3b4c5ae34e3e089f909b15171892b61bc9aa96859ce6737ac36b990b1efb8f7462386fa6a4aec90c0dbaff3791baf61410c4b7993ee19f75f784cfc6aadef462e0da57f06bd43190844e630a5ab26a9515029355dc910e6f4dd1897a9d3dda03c36d333c3e149e879a7b682d3d7e21e66694fe57d6cde65e26fd184e3d279ed5d4041716c7ba3df82caea851104545a58a5673a34c27fa9951844bbc3135f08bb7a91e77387164b4dd24a14eaa5bfa5a461e118a68486e8582a0fffcf83ee13a49f79ca362ff9962f385cf6fa52f917779aaf18c0aedd0976d2db724ff14e02a7a371a41724d55c4a5aedd24021f167c652ca6e71bf6fed9a42ade2ae273f19b476a268c27bef14561262d835309c1bb2ad4cbc8aadf95b658a2b6311525a1efb3eda7bfaf59fbdf76f10695e3801b9ce6dca3d8130ab2f123a46084386a2bb8a299c2c1e8c87216f8ccf7f8b460d261a0acc6d691f63464b7197ad425d1ba0e83408c225d67d2efb16638b1fe7f9aef58b6a2bb7bfd36f2561fd5311aafb61accbcbb5cde3d86790ed425a5b9b0bce6ba658a13cbf265998232eae9991388c6adcf54ab654dbbbfb02edd3a00f64c30e837425731c015befc157dc51ca820e975a870b7294820cd7c3b5ce1da69ea8dd9748b291555b245f0b36bf098af22d71f4d333b5328c2c0f91eb50208b91eb0b8434b7b7cb1d7720dd8257d2f5f6be4f5a76d1e640fc1068a1c3356fc05e91aaf7fe328b4a9230832dc907bc079ae01f3acb75295efdb49c62c58fda81592f6dd14f7167a36010f22dc19a5d6c095df6a9c376cb2ddf5bd95576ba4807f54a33a14a30ab7534ed8a5edc00780e4dd77f6455ff2304841919175da83473c68aec8889eaf3b46ff7555ffcc458663b80d1d73a647ddf86e6c3d64a793e328e5b869c5cdd0cb3588dd2cdcd30c2a02532ad1865ba0370f2aed77106fa548e5b3bc23d4c54b83e42b6ccb3121dbf62b25cc37abaaa0722597f34bb24eb1157a051ba042421fddf0ea2ada7b2c8fd24be83360e0b94bf5c82bdb19e357695d71986008e2bc4ed49521bc737388dc87afc674ac0f0e518efe7b82e833d57399dabb9bac87878c682937821b307955acecfc8ef6d9e67fe3d6ea15557114985819dc7a2387215dfca48f8824707d1950be2e366541d2b57f46b6f10bed83af9de49be7850e71d35f846fb46ebd917d985416dd0d40499c5c42cc62055c92baf5a4ca871cdc127c888dd8f2c39d028e7c9bddcdeb14d6ae5b8f918dd0954684ddcd48219ed6e520c2fe80bae37aabaf5b13d169d9c931b03701e7c3b4c0be281ca9ed38a43932a94706e2efa77240c4b2e73ed231b27ba4125a51fc957f9cdcca23084085bcfe14335362701e5b74d10e2ec6e0b188ce6afbae367661f629adf671eb2fd2fa25f0bdbd589a493ad300ae9aecdc2a5e87e464837c0034bd7da287a0d98451a6bffd8e3300a635f649d56f9e5178cf988e0958174ee1f29c16038c5aead226501df7efd7beb05f5824297621b312ed9631d3ddd3ba0ec85329b8de129bcf56ee9e9471f0509e13559744daa490be8d377d8abeb11f7a80b42929a9b428826f7d26593733b1f80ee959b96c1ce5cc76537c58064f6b2cdb325e3442ec01285450ec84b48b6acc5410a16d959dc638fd66c8a7a8a2e482854aa8fbb2bb160055cbd5e89639b8f335c701e02a650f9e2825cd6cc6f52b5e8b02a38dee60ef4e8b9925effeace2e72c6e3c791969a6b563689428914bbfc41fcde527f94955dd5999492c1d72f7bed43fda013ef424ae00b46315b855eb6fffc6e30aae7793d86428d26ee2031651ebd46c83bbe5e8b94e4d99373182ce4fa462f4f2024459f9d975ea5536c0a8f36dd99364b219a0816c9895c06143b0de4c6f32da76d806aa43a57808d6f130f6ef209c9195320d6e8048589c7e4560b6c54235accbfd08b3baa9366f8970355a5af5a98d62e71d76c270289823d6ce84551367e09918917bcca6ba51f723d8d8e035bcce5b333854b9195af17081b2d0fe4ae92751cc778e1cd08b14918f582eab03e82fe7d80e72368ea0e431297c7c1959ec89b44f3486da45f73dca500990f2631d0d2112522d16db659b30dfa8aec8903c90f0c4f85097179f5161083da9264bf8e9eb20b94d3e884b394c4bb3f801ba50b13ce18eb7735c767708bfd8f3421e9acf41d74a8a084d5d3883b3974ab29ea49c0a4a11cc24a25d279b4f55f8019ccdb4e51fb201c725b132e2125a9f75f714b29607a2db38d1ec9ca1eb2af30bac8f5a4ee6434918106507510253881ed419a6432eb2f816f137798d82fe458c4d6106e0b657b1533c50f2026a2896aade1b51d02a1f1a48dceb54f3ddd7a4eb6bd87b7a802fdf2bad96d8fcb3fe9beb01db590b56573e102eeaae89c4306625362393f9377d5956f7d8d79f9cc44828c5ca8de06311b9c58ec2cc232d569ffdc3562a2dc93895fdc008df7f04e6a206ef384aeac0bb4e3f8eaaeefaef87245528c8828d09529a6c34cd8ca7d714c8483faed0673695f1a7fc554b505f29f664965f24fbebd24084f13c41f7725f28b0ada7f08a60d7f86bb4073bc153212c7f109e75c66813333ac2cdd1cd4f8b7611a6008ddb575102196cd6ebe31fd866f20992a759523bf2e97663b0013e436b96d0848b1189f07f380e7c1d7f6abe76e319a3479b8bbcce39a4d1f7ed5f0ef5826b53ccce3e1ad200657460020f7c7af0c9e0495b4920e87a2159a307485832423268fb128abd39b245c02f92c5d4b2744ea1d5e5e6463c5e64b4d6b0b1c6ca2b32d728e93f7c4b001b648b040fe994157d37cd44639e90921e8095740991a91b0509acad78f292172c3fd62ed35cf5ed1e41c2d893e638d9dfeddf993a50ced457aaef0c0a0b41c982b74b5a70c49386c4bc678f21da851d062c406c578611b0e2904f846a6badabe66a74ae21dd141b4f06e5ab7952842c1fb045fa2fae24846789177fcf88a95877932b4ae708627245d35d8c1af1f6e6ae5a877225d1e9b848bdb103b76315d7fda4e61bd9452413a69013699677ea83315a6dd96bbfe756de32db3a6f44033e1cdfe48e953d9c71fe7e052f5f771a0be71ebe2106e35094c92a32323dde933165c6e6ceecb7d5a062b49e03aab060f3edb2da7f53a4aa76173ea366d39e01f95c2dc3650fbfe997b90e40e3ea293c8586e85b55c4f78cf37dd12bdcc97cedb1d054900f86ff021095abb76c396cd0e725d745f49bd6ea1714cd89a6fba948fc8f436977cea1869f79e794b8c16fb463ecd19318b6802ffcc39fa1ff6044d6dc4a3ea0c3d0db2b675278ba0cd1d79fa0559286a61e96f1136c54ddd399dd442adaadfeae3ba9af32df98571c06a3c66173368b60e7499bc04c09e126d0259376d95ef028267cd12b37b4643aa976f8787d945058647a5daf7a3c108ae9cb0ceeeb8e7ba05415bc5274bcee384b9f7571bf20f29036c9d6e53f66a572faf441d21f42f759df287ad063366afb1d71b4814d8aed76da248634e24c80c1bad0b1be69eb96b0b250e337097c61efb3f96820a521dd982e2d9fd5f753cd6971ceb9af8690c634fc3fa25a03da8d41c99da86dc312b81820fe160b434d92134c8e9c68e15a67263e982f371177bdf30556f8d53140262bbedbfeda33b400097f031f4ae7f26097ec316dc8bf41aae8313e41c5b473bac9513f90a9fa3ca506d2307946e3447511034e79480e47741d8a96a58cf5fa159fd71f4ec44358c4514452d55f7fc5216f0be5e008c69fffd34c044df5dd7e5aa9bbb68c83f99b415f14738232b1a2a5161338ddcb1cc261e800c28174468a2ea300437130d37d7c139c381096314c4f57517b427e4d4c4a47af18808c5b75c9038d2b1af89dda3f3f94ed4b2206f955ea33baaaf578e83d2628114b81c6ce1c7a6383d09dd17fccab8d63c2c819b25179e6e2cc97f3f495c1bbf7e9346d8d89a887adf3afaeb409d20838a23a82ef01084ef93427a8261046fa0aa6ccb7544534e904713f53eea1adda30fa13f8ebc42227d1a8c8ef86c78447e382d89d7101d547e7c8b92b98d6e821246f009516c51d64d39f97d38186b60b5603959fcfbcd5d2dba469f61a88777fb483f746ba09b9642afb4e1e26ef6069c3c1a7c209d447bea551a3e84d2428b995f2d0b7b8974be7a2a3b8d510fa8a989846b679c29d8f79463abfe8d6fd6e2a891db7fbcc019c9d2bc5c3f9364475cbc541eec4b62675b248ed6e5538f37c8489781fdbd3bbcca385b29265c38ee133574f7b431772fd858671230b40365474ff05896ef32fa416efdba8bfe072d50f1367e6feb456b55d8560f58f4de19d11946a79f807cab58fddf57dc1b8f2e5d73836a8d8d008060ff10ec213339761e93074595590a5a8021f0a3b095aba98b82f4a224ab8ffe4e5c61254e730c32650a45e98eeda58a3cef9a1e530f9b8795cf85850f357640d9221d3e0cedf50a69eb9cd35645100593be9465ea8f19248240fe36832dd3f34a14973107c4cda99be682210b72da0ba8604dae967da7fcb3f002b1c1638a64310ef07236b491a1d74b8d78201425640ad16684e13468835a3c1ed91f654fb636c064ec81dd6509d0be73077b0346eeb237a59ec933b2f903454278efa7ea85e14edefb17db183b00b98a63d3dbea3eee9678eb6d3b27e00beda4d1461e06751b70dd2844fb82108bbef0f62e9f28bfa7a7040c25893491f0dc3c2150d13a348295d0469823c0e07a7970ea571679ae65f28483a7cab3c48007ac5c7625b85374ffd8928c374f49515a75672d9b65e31f31486c8541dd77711a8d8a600b8ff4594add62c574ace52447e1ac2332b1fe44379d0728ae640aea396daa066e1c1f3fcdded31764eff0696fe07fdbe6d7b8d0bf59c043c469980e3eaba8dfad77b529db7607efe60d5befa6bf2e69609a2c61607d4c484354a7a2b0bf912ce7bb1d1202e12dbc3cf61301982fb0dcb582dfbad706ea4fc2d4cbf611072b6fd09216348bc89ca8950dd953cb75364a0c1a0f5f4c81ee98c04dc55d0f68c645e5e4ccb8bb9cb1b241d02ff97cab618ad48c71634ed4f799afc4bcf606b352e8fdc90e33a3fb568123876aa5c1b994383c35bf30f6ab5e9f7dc8b2cd487d0b8912fdca9d4f39d0938c808e9c4e28bb870d6367087683603079451b3e38d33a13afc451a3e71d4444326fe3969c11b0651654cadbbff65c5eec860e0a0729840acdce94067ba738fe38b2d664eb2d0ce150e285d6861b6d784d2baa615f8d1bda54969f4db87c2d51a493b56f68ec2b9824387a165666ab4a8a3d1bceafbdb268bb39e1dbe2611c939464f139507d32f66cb7d362eaaa38ea50c2ad5eb84982f6c48d7e8a476b2ec311c63c0316e36aace3020e19eec70b74a11de29ca40acccfc729e59fe8ad6b14932242ba6d343b4571a7261c9999b73bc6607c56a0934cc7a2b1c28c17875d46b532f75d0220fb0b27983227331aeb4ef80a96d545e2799e93fd27512fe042fc5ee9a9a2989e1f6bd2449dd5e16e294729f7e6a282ef48b1a234767c0c43f3b0be4f2811406b1e061da059a0a74e0df8bea9849e3ae4ebcfb7a72cb0a87cc8f242d2b1c5af21e0b21a1ce6a888492d97436b1ef3869e597197fab801ab0c76d97bddf9a01a91c72d7216a2beac449d8477a2359220f6a87ebe47caa3704acfbd57e733d243bf2507bc47c5312eb1c1ff9311d9ca0189798695abbc7588bffa2537ef70a028a7cf58bef37cfededa3b83f7e9ce1bbe0e76d309aa147300323649ea02b581456b484ed6919e95321b31af0882d83451c809a650180fe4dfa7f1948aef20d8bbd699c96f8a3fc99aac88d767ffe7e8dd651b1f56f804295fa485ac180e0c8a8d962345f48a3440a893e9887157ce763a085df38b9b7c588f182a4bbb20ec78d46025787c1bfa30b12bb3f84d690a15cf7bc7ea19eab56612f41c2f9dd38852c2ac4d3cf29e00cc34521152fe929ef0bd58e6f48cebf16f02a36a4eb3fa30552832f2eb30d44f2baf52a3c9f671c71472cecb6c92a2f450d91362f074989b62439ee8c02c84fbcc2501d3da96343495c0ea83f7a2887e260a35d9881c15202e1817e420ed8ab7ccfb27a770e0d26882239608ddea109928c1d582d2e29d0a35aea2453dba283d945949bbe0a3823b3d65192a40748f5d1221ec755a900d1f57227bd4d88507f90ac88c692140fa35ddb16a4e13cbc75130548722459563dcfdf702d1b8344abdb2082b59a84964968b736ffe411b67e4be830ebb91378cabe636a79fe6e5741b00fa3bd4cb1b35f9a63ee3f2f2aa07850ea9f7b6066b16b47748f8c3d65f3ef18bda6531a1e58956acfe5c0e06c6f24f56d390402963bc8b7f605633e052040db91b112bd0733f2ebaea44803708c4a38762576884eaf208752c408d2735fbf0a0b99f9a0c03f6beb70b043061227e0805a90c2650d33a39e8922ce84587ca340f87a241673323aa63f3c5a909b76c08a3eccddc9cfb21c301d6db91b57599f7f7d02bc20aba9d7abdc7cc48be0897fe180bb46a7e0dd853beb9ae14e2eaa1fc98b2028397c812a658fa0a0c5a7937cf23544635b412f96eb95e6bceab199ec6a0b47b04cda5914d16a68bfa3e9fc49ddf272f0da8e14301d18b78befa08865b955acd7d7df8ceb0572e681b44b849419340208b74d36222c56af84ec8897e2b88a45e53a85ed443ff41a09db636a2fa132bc70ea8f035d36b074d2b845c595b8d42082fc5ffef2dc560157b408e7f1fdc59ec7619d6d128fc4ffdc48f766436b44303d62fa861318b779dc3301304a0f358fb93d4be7c30ca7abc3a590cbff0a8464b98da7b3410a3c0717b6067941d6ab0fee5acd8d7bf9a77353fb9eee0de98204287c7330f616b13775fa0196c4aa8dc7a527a7155f34e3462924fb9fb5354f56228bb3e55677bcc252658ced345fc5f002779d1204314400dcf5f7646284d26d5e0cdd3edac620c6d67062ee11242a555fd00926b14353c42a90d76bf3d80540d027b634d52ce7b6032b709ebda40255801196f43f2071260c7a56f6ebd9b2c6a62992f85d209eebadf0ee4227a58e096717a36b92599c15193dd53b1e160c6123f643b73aaa383c8ff3228f419e40817deb1f80a7a75294faf2b405a94a35b32003723756de5708f4dd97db093a0aa0fdf5093bd039c6b923e489491186a2cd89d3936a4c82be9f06c153146f1218b3a1a7b92275cadf41541ab93d4622b6a0dd3774546529d97e4a0bb36583ba9e306079036a35339917749b9332c178e4bba0061063ef139ca05cee289ab5533c6b9078e91061bb170cd23c22e7ab430c9ff7e6784ca2f967af8d9392be177bc34a0af6dc2ac6765c4fd2d8ebc6f935d852c8647c47ffadcb5ecbfa036d171da946470de69e5df3fea793aac02cbed2670fffd49b1e9a99a24ce1f0b96323ddf87ece6332fa1556fa068797c7eea4fdb69c2ebb799029274214da65e5eecbd1498aa1e54d7524438a18fe6175565290c810b29db87b97db4b943c38c8460a63a4401b59cbdab05e63c961efde2455b37e603fc15b3a0dbc62928223a1cdaa294ecbf9199c88cefe5034c633577ecd7c370a9f216bb797caaed8a1d99f9666f38946b6d0fdc958ca93058202ea65bf91719ee4f7921c6a1718a60d374b94d6feff2cee06d21c2090a4b4aba69806f5de57cf8422ddb9a9ae4e75c30311fb74588155505cc7b4cc1164d1af2abaca99a43fa72a3d4b7971794bcee81a8eff90acd98e9a14927cfe5df9af388dd13c7af6da2070490bed8ea5865c404ebf33a766a9ff48f61411b77944b5c41bf64e4c7763d45fa900edadc8edd87c2a77e98f0c3cb4ba8369137a7fc6e99111424487561f3f537cc7f18989a2257916ca20071f774616aa00fe1feb2bc42ecef11836d4e8ef7aabc09b676d8faa2ab293cd96d1d02e5bbbc36a8273fc2567655d8007220b28d52ab97555bd7911f6c95d5cebdb3cbc1820928bfbdb94f2209a6bc2e72f408eb4f5660184ed43fe5d91d62c0e7a7721c7d817f079f3dbd4f8dac484e52fdcd567aa0ce016e6745ea922ab5c8a11ba92db398da2ad1adbceb6d81964944512e5a4f59e9e749215d16e883e9309b17497a3f37e0ae8e6da18e2d1c22be6aa5dbb36ac9fa8bc96458e45b2ad8a69b2a1c4ebe0c4b75595a91171f02243d4fa4ac2460bc0dffa1384bf546711ad1a89e76df6e001fff81792c5e3b7ad1dbb0a8644ae2a120dac98edd09f45888cf32a5be43d3b068fc4869d5d4186f60172b5f24a8645420bfa8b778b537d9eaab261d70101235149948e497fe6f5fc84e4456e8b969b4ad3e2f19c47c8b5efcd14bed8d12e16fa9b3141eeacfaa686a15baabf55039a7a88b3abf00a189135251a7919bf137a57a937110c764ab1a0f99a9740418f28dec1d90efa5d94993d2344367ee0e95706624ea4d172fd28810616339f89ac9772bccaa0a3fbefa5a4c7233d9b00da75361c1f38eb7c7f6d9775d558fc830e2602df1783ae4004d0dd1a65108fc1d8b9e6d3a5cba3e4bb10c11d970071d18091d62eb28973ed8924652f8ec109ebd06ab455b839be950eff4b9a03578c67be51600b4c7f10216e19a6a42533b8689feb48ce2c6b68bc6101f7e5fadc9a875b0eeb2e446bddc8d453fd40eb2edd6a1f04be6a023974a67f6c90e227edf6ff0318b21513c9e51a5e3278f002b3e8a49bad5d88ec4cf5e0d6a6778cd9effcb7b0df7c3e474d420c1b32e0275d160bbf532c7631380bb906bf4f6df45b605cb83c952eb713274fddd611e43363b281c5dcedba26a49e07879cd484b7eefab3b9846731489bf4f3979af4e13642493254ed3cd76b4d124f9546dc5b7224e24aac431d89f5b42f93d0f89d2bc4bd4ac749679fdf324136fd095e9871f503a0ae9f4321b59fab8be552d000a65d6dbc2dbf40d7f94d0de6b4f69e106fc4dc56eac141af0683401d3be2b0e551f1dad8d61503f8e49b8a6e97acec885ef8694c7b49b0e582788ef8e5225eba7cf52f63ea86c29e0777e755b2dd8348186bffc32681bbb19cdf9b8e0269e2340f8a477c1321d7db74bea92298c5d5bec769a93eeafd9b4a25a7c444ac34670bbeecfafd33a2f192348b51bf7ed162ba5df8a4f882fdbaef3b6b3abc162edcfafa80da96d2753700e4d25817ce85f5f931c5a3210e05965f537ae68e15fd224afcb326e64ed75d85513b2f6f8c884a128af79e4ee8838ccc45bfd61d746e14102896146c88ecec75f0361337d428bdc109fc6fd825cbc9e24cdd7276d45abda0d5a2c15af39aba978308517f5ece552e0142b8bbdc680f3e7bae0b9f6b206a335d99d82aab0b798a22bd9aa64705fc345d47d4d1399bae0a6bddfd39dc378167198b8df7458744a07ee20527a4a8b8a15c8ca024d534b4e1a0fba0ca511866380b654881552a1a2ea4c722bc8b2dc9aa69d0502699b9c1d24a4a8a9ce2b002f7763e961b3dc1275633eb3a7aa1a46b5f6fb194fdcbbdd827a52c11164dbc3b0e38b49e9dda53336a0e8889a90d1a88fe6d9d3043545e3179b4823641d8a2e5ecbd2a81e8b04203428e1e6ea668497d6a934cc9386f2dce1bc9b45e32659034bf99d6e578d77b9e52ea5d5ae20d273b3d440f94853bef922da378e489bb0e984781ac1910d2bf03104edc6631a1d43610962672b7eb8bda7933730c947e5994e9e27aafee536382d9dcfef8a71329c82c58efb7bf27a5c76d2c7a03575872e087b0dad99ce3824d3de1a00198db1f49fed2057f961cf47e9607086ffc437492a152b94576b50c88ea26e9c6b42d9750137a5419df978e095a2d8d6197af014964ace0c5f656da48eead519aca2662ce6b7a5ed29322f80b5a23929375581ef7a5eb5b15b6969c14572098aed3a416b5e2af5a4c32bf8fdb602dae593f85421143f89379249b2797ccc8b7723631128a8a85e486dbe41babb6e7c521128eb422b648ae233b4654904ed1131e9309c3a40e62540b60d9a0fd8b12a46e7d5d38b9241a16e2748332a57cde8e7be87778dca532d8d8c7160092e9d6dbf3433bf9bf277f5f0b5e1b483bb252b246afa94165e9f91bb284910e6488011821c202fe9b790981dc1c47a3fcfc5f8d1670e49b88b63f60a89c4eb034ef910fa5a86fb8b49915ae03011ef92e69b4bc7e7fa2882a7a4bbf4a698a279c564a89d971c6520311672ed706fbfa2caca55c0530068fc4bf0f7702eef457156e0c75bd1a76af848b022112c06aa889091e6275b82fec5d0ba394e7aebde3096786e47e63c54b2770bae04eb622c2225085224336c988280e2bd915d286deb07a04b608724abb264b0435aac9ff0b2f70114a35f853e4ef8130a7050a9d2adbf3f3d83b29d6d0479cdebf9cfe50c53934ba26085a2b0060ca808d5f3553d83c13d0c30cdf16d56439dd8b0614556866c3f2ad0d6c5208fe61153e4bc4f85d1662944b73b0bdcb64dc11cd85633c073662cbcf7d7d71cf299c838f8f5369ef954e87a12f7ae556a5d2ccce7f580807564790706588349b45df1703cdf8caf1fa5433201508b09a9fa98eeb561b78de5071f27376c003ef054d68dee9c1aa4b6a683abca8e94fa9adeb60019c4a1efa723906b6723848336f5b462ec2ddd4468464967f8c858fdada5a6a7b2477fe202b6374d974a96753e06d0a27722318d07d021a0398ee33d7be1a2a581fa572666b9f93f1ec70cc52f256c53825bfe5c2302c088a1f864af5197e37188aa9c0fce760b1f71c23fa6586d208f0435437ce7085b9d055d9e15a4c743a0bb52d19f93a1043cf97d96fd481230fe28e0b22f6a73a514294340f3d525a14b8cd5c17aeec828694c14e58e808297dec95590c748ec09fa8a659d2e79266fe4490e59cd27d61d038ff0965ff8fe6c1e678e3c4530fc08f1d88a582c90ffdf095751b0b0f2bdb78a127f40aa9cf4f60aab47c8759a28009d47564e92d1398c269ec59073b8a25f5226b65a2b71fb96200c92f8bb91b3fba2076ffbf473c41d6b38722dea89f1049e7b297e59903d2ea434290240a080c94c8a2ba2b06df04bb1c2d93bd2a81b046fbcd918acc72639bcbe6db20b6a6cb9ebc3d304cb5dd618241cd2c9ea4a69738bf796ac507392618603f2d9b41c8fa7e82421015083c296f3284caa8009af8ffdaab7b56eb4b5ec412eb4b36f912054358731f92a9048ff17391ec41652f4e5572d8ebd50d7045c778e36c0a48ad47a09aebb7d02bff8a6309667ec448cf30c01934c4f5cac0557f659e5e9aae7329704c6c713179824aa71bebfeb7b7c8882a76acc070c8b9bff6ad205713b8389320cd6fd9c147b2e2932095ffb4d0fc04b41a2d22c9f7d59d576bc47e538d5ffa0484b4fd41ce827b345b07dd7c726f7c3a01de71198e1081fcd6e8a28b3b8d4393a4a9c92bca8caf81164097ebc3ba52a6eb620140f0869e6aae50260a476beebbc651adf1405b43699e617f07018249388deec6001e8fe00feffa63184137003ebd489bcd39811c2c7a309940d9ace25f75f47a83638242d049626e476bd1b0a0c5b5bfc7d87bbc5f23fe856d0cb78200e80d897f1c8f9529c8b30e0cf3d8263976a4b14d38468ba64527be5613626d99e309e6d4cd51a212205efb6f4305135b09ecfe0261e0887b9d426b88251ccb04d02fc5a696fbf1b51d9c0c5f76704cc8a3c19680f24b8e003ccdc02a2a284e1f0cbb9ed56b1aad4e79b1adb81f5e6055d9da7e77129d95010b97bbf6e7ec975b047b6b7a38f32a11037cbf4a5ea620e63b618c7a3287f902910109b9028c3925a794de22816585c34d8d115d3a496249d6b7029f68f228fc01692362d7c3951571bd5d41317dc2b0e63ba56132739898757d0ff8b56be665404e79d029757731128c2c7a5756bb83b6cedb73cfcafeeab3d88a2e58b5253173a6b7e9622fbee528afa879d7d77c9bde5fdd16f559892464ba05c889b5d0650b51515013f9dcd5f95f3a2a3fcd4e873fa5a9d2f477328281bf550c963d8bd52daa6f870c6113bf9c6e4a8ec6913390d1d328f261a9546e3e8df3412aceaa52080afb71490d86eb88c5fce1163a03f929d9a4a5c2370a620ca1ca56669c4b7d952d3e35e748e6dc7308c330b6521bbcb7c5bdc2e44976725b7f875164b8b843b7143c127e950f28b243f0dece3b0a78e56b119efa4214ab32cdec71f43d6336c6af341963bf4e5139f93dca712a21090942d46ba1db3966927d65b810b42af113a3622c0c9af47052d9327cd9f9238cc79dde8fe0122d29b7a96c4e4e2a0651550c934b5051c8bf1eb922d2220a43bf34814e684c6cde0562861704f6d708db332b93a76533190835d63089e7638d2e4d3c9879a32fe968ad1ad80fa94c8379094e81b5f93778d1e4954077d64899dadf56f713a65d03d7c1fa187619a2781f66574d127726bb8e3ede208ea92eb41e56772f18bd0a20786ff9d169e47b1ec69d32504d896aaba9487eee01ae9f390adf22119916cc1156ad6d08e593d9709d307c2b9a2682b7d10eb431d14e5cd111b161a499248f605975b02707059867e07d4e3d060b2724b076f7279d29dc1104cef357b6d7c10b7ca3e5430252578fb6868d29786d8dfedeb44f3cb2a6a23aaab328368ad3819051f24bcc6f59f7bda46962545531bee97068a3162a36ebc0a9cca5057bbd50cf19e98e5706ccced109da10a8d32f77247efbcffccd711af49f0280f91eb50209b91eb0276ebf9b731a82d3fbbc4bd541c0214c3378d3d4c93f9448789566af74040d6fc67086e91531011482e3c45ded9e33acc46f2386949d69e96ab9461a1b7f2099d640368b38dd6ebd1bed255039e6980bfbcd47d6e2ef2a823a1ba63024dbb6649455524e474eee4bda5cc40b66990c4107b5d709dda9b170708f044f7ea1a4bb50b82bfa96b2c4e17c7783ca737120417877460243c85cf4fcfaef91fc215aba3faffc786828965856342d8e76e8de73445d45430a2c289b558e5e468b4b52513994c31b1f8a0192ebe882089ea60865d0f0379e2dabd2bcf40ebc765801b0e3a20349766f863f252dd0a0f4f36d192bab480a8302053a2897dbc5bb04695565734e0042863974fcf7ffec4e071b146094665c2122739a0fd563659fbe4278fe16ca17f09555dee18c2ab12442e345fee7f4080b7008708410df95866e933d3c164a6a0b0e11bd50f2084af227047996f6053fb682a8cf56aff27ae6d88091906c06e3384d4c72dca11eb2f625f30009f83e09bf20cd5c9e8887a0ccdb7ece8c47a47cf2f559ed30b98da2af3c2a77fe7fd3b30582283f47751963b0d2fcc8c793a2ad9985326ea32979171501605bd6fe13c28467f54ec8af2e4401d1c8389abbaea609625b87004f3d9ac72ae4d0f1badf2cfa3a595d7c2056539f630ebfcc22318c8acd6d7e205702960f5de2e519cd367c324bea9783794c680814b852bf0b95bc6686a0ab7489008a7e387792e25c60ea68dbf8b1ee33c8d00364137de1d5aa6914572ac859b6db0add67ae6ceaa6758163c7e4cd4265811746c4b4d85a77c908a5f6586884c35ab7e984e9ef74e9c3ac9bfaef11abd34b55ff8fc726bb585790b8efce3e6bfdfa6b2fa0ecfdb7c7e5d6f2c995da3bdd62661c355c8a1d6cfe16599357f9ab35d392fafd4074f20aa3cf750666877f97cc153d85fc0293499660a71b15bc7a9e506da0f2bb274bc1e0575b776f8772dcbafad64b8396c62b3ebc4617e356b91f5cc9678b2e3c9f69e007a6384f4842405f820b8a0f6a317a48b409102c874007b7ad3a795ebd85e60664b71bfb74e4604bea4edcb6f4922f01e56e0fc905236297f404ef195b29975582a9773c0a46fb91b64cc844f0b85bfcd86efc3ce7440bf2db8219bdd20a7c327d94c26c70916959f89a9171655f8a7b15da6c11d5d1211298826f10bb6adbcb294e2425d1b6be20ab3af9335133fbe01583ab14a3550a657c7e330588d7d94cf366b1935b8032d6a287ee8a67f37cd67ce173bf381d565c9b4c88656db2379b196132534455cadf2d06b4d5989a6c23877119b15940ed58fc3af20aef168c95b2e10b801acdb5b1386ddfec4c598ac49285864cd568b5796b1bf7c345e3b95c88354f2297477967d6a04e846c3345f62016c16ea539762df7e01d140a642647eee5d1c4949f90ce47d2b7de7d30c51d2a5067d19b869b9257f3ba0bb0dc2b72e7416cacb71a05d2b834a4fbc5b294efe483fdfe3aec7f014674f6dccf23876bbf3d2deac4874293ea246f96033527341ddc0019d9ed90e2c8c87ba1d9451e470eda85550e95bb1f27b5073dcc6768a0128845246f99624d310a72a481bcac47734b87ea9fd47c353b4ba9e63916054a34cb34f6c5ecb727c152d9c78620643b6521c581849f72eaeaffbae3c800802b009e8a79630caf92b8bfdc64643e68b1170d1c6972ef462e48b6e800cb156a76d135bbc25b3696dccb0a79719de29b803aaebfaa915779061b663a6ba6f7211a0b99e8b7e6536cdc0e03fcade17404ad4f46f713d57dfb0debba0a0cbdd918f7da5f3f8d48c5b71c8ccb4fbc600d25bc6425f8666a40c9d73290e99dd5ea27113df6be232c9f5c88b3d66095995c8a8c3c6e6c842896503a90b1cb116af0ab9b8a0d5540daaeb3a70f7ed7e4507081955b22bd114ffcd4108013702a01d72003e5e069291c64d693df32ec418f29a724c13dc23280afae3b87dad0a8a56307da9db61502f6561e039be66ad86aaf9452f056cc8053f8f38b32435f51bc83f007959e768cd150d8dd325e61c53946059f3a33ae1f0f54554ae073d2e14a49c7b54014f2350edc2815083c114980f4e7af4da9dfc8f302e20d09cfbbb0c688d425ab420c0d315e14501a82502d83ee7803dfc3ffaada35d2645e7a93331ba64beee17c68c496f447b71033a78082a5697df3883cbd9f4de562b99c874f0bf11654e867066fae87d598ac240b349a8545ebdb57f3abfa42e4badda6321778ceefd74c063f66542aff5cd9f21ea0971d923a878b6dda788768307e3b024a3266e3ec7cc875d8d81e3d7206c5dffcd81389ec6f98d37804d394da940a8a6b66da9973513e2aad4c6cb6e392e71ad43f8d55145f15c6d004d295a3829e07584927b313f5f0e08e589fa8d273da366c6ca1b7e696ba5a7d7fda76bf0fed6aef2aa1bdc459464806ea292fcbefe6211df7273d90fe9407c1a54dad96c0b1abfd278ceddfe977a52200fe028625c9fd1d4ef90f33ea041e46906f3520ec7de3b3bd3a83c33d7ecfc9f99cbf6811d30e2330423837960008603a695163804a9b4763450b8131cd70172540fcca0020cea0e5c88e4b6b0b5275490786b0f0208e87b90be10a573b6a4302bba531a50de02afad41619e24d43e301b5050685b1991923b8b86199497cd5f6d9245c5651a333d7fdca8bc984e41306e1fca58b31991d0dc15deace7397a1df5630215da40798a3ca48397f200485f9a95135985f8ccf16d7682a0eb7f32837f65c2c5e482f8d7814edca21a879929a8b117afff62c31d74b5b59c1befd528ca5fbf3a7466aa4e9f4c730065f66576e4b6b3c1a46fef9be221e80930be9db0f7c0a74d106e038c7fde117f04f54db55f0e28a9d8586807427554a699162f63ac50da5c4de3a2845804b2580ab3f44821936912e34129c140000e96dda6fb721c6f207cc428e53b64ac6255abe1e2d34610ac616fdaa9e1f21b76cecc2da312042a5fcd6464f4cbf82549d933eb1bdd722b79332e25c664198e9e4f326d8022120b38819a74d80e671821b7bae1511f093a51206e62fc83378bea942baa802a7b8eebf8313ce204eed48bae08a516ffb5fa799f2848ac464ecb1bb4e088339b32288aafc1192059a0adbde4007ba47070c5dbe22a8211d48404e7e7c67a7ce5ea23c92898184a8cd612d2f8cc4068e6c77359c2ede84e6da6a71054df710ee163abf5cc9a3da3a15f155bc1732a4e059f09f49f9f99a1ae7971427f7d7739c9f596f6643604246f715a632f3a3f3ac4765abf251ac5e50f39f895f4c34388124497269275e5b1707395bfda3c7cbe567e3debe7b699e25846ca293d97fe8156d3b2a2082d8c12002635514e7915fbb768ddc2f447a6fb41a062632be1b15a5a311e4bb9728b314d03088a7fcd9004d6d009cd7fa56d8d25b44d5e8b0b635ab81062e0e51780049e6e4e72eca8bdcd686ccdde47fad6ef2faf8885c7fc3febbd5b453b9200a4bf4eece908421b74ef47b15878070f59866e56687a53d8b707d37db70872bf8b868ff4ae21cec3f7ac0358f0327e47ac6953e37a87c8bcf29d36ee156a5882c076664e2960ebef4dc388cb85187743f0255a56219c9a4cd70ee643a6b6823440b9f39887c69b228fa8d5afa1f6d3bd084a544e90a48a9d46cd755f5842398c1c070173b0d9ed3db5f54b8c4b0836aa3e5de5e229195975f35eaefb4e69217558a5a5b6653202187e716077e20c0d3f1365309488a1a25f96d683dfdf60651635ad6902e78c610f3d8566d4677d4d7831ec987ad4f933d1dceeb2b9307c5b1a67496262bbd59ee7f910931c09ed0b8dda069157ef324810b36c3d1e25751f645165232b001325332a59b7971a991572f728951eeb5a9970cd144d85ded449084fe147911efec5d9bf2f1e0c3739aa2690785af018f55e8b86f06f125dab48d1ea04f29d07a112683812bb0920cec91c892b9f1fa1f9b5089a65793f0d2da8620c2aae010bda024eca9c201b4d8e50cd319a3e66bec996d6ed5d62e4305db54d24ae3353d3d1bb6ddf21ae79a4571f172f5f1310ed8fc8d9f82ff4ba586c9e4cdc25939996d9c9574daf566f0c0574fc97aea9fc629a6c16d2039dfcb7d401b0e93e28cf980fa5e5cb2626c276ae8a7e602143e285e308f001c22f99862d548985dec61e6354ac19dbe2cd007e49e6f6a07bead22c98a2fd462739c42eaeb2a82d5d4d2e1510e59271507f303581d4487be59873fe08ddada1f0ad3bf66de056b7a5007a7c12c367400532a3d1a4aebebe2b1cebfd2189791a2f730aefd11684b90d1f577cff33e01b9c21e1881ecc15ea92728b1fdbd81e794b31034e8492fce9359e673b751811b44e6bcc1df92115fe558f899bc1ffe6dc932a77bc295942b628b54751ffde1973d1e504e55fd1c2f8aef4c3eb46663eb126ab443dbbf43474975d0bfe7f1d947ce51c052d68bbc7cb98beaabb97c0aa53efc830cd46628b2e6e6caedecd1816e69fd58dff09a862b091d5183a57a33fcaee3ffd7345430ddead63e7ea6c4d8b3903c4e48dbb0feb2d3b3b199007d2b8d8337e23b0de1d8442baa52d13e3a723a228ad3341b9347d1c670cf8076c0ced986ffe2ec64c0d4cd3530fedcd20bfe41c58edb554076ee3748d3df5262e1ddb93fa04e8b2f30d2893c7680cb8924edeef90a7f9b660b074b703792664e4bd06b6417816f4d5058accda1c1f7816dc77b9af437a1da9e51f77077aa3e7d5e1d2d95df6d0191be3f77a21955261b59493f7f071be316d4d89e27664e83ee07b6fa946679fdea905c786e2e972b6150e35b43bc70a7e839014f8b0887896250467385cb90bbfe77903c12c3ce129a952bcafc99033ac4c65d1f29b299f5c0d7ada9afeb0b848df3eac8600fa2ebba0f12b3a00b9e5a6256e226df4579bfde593f6388a0defc4f14c5391e65c0e97dee15bfd1b152d31ad7fdb5f713b0ca2e3dfc82047e9f686ab8d6f5d15c571eff4de6ceae262fb64184b7bdf7e490e65bc5dffa4a315ed557ab63c45fea2f794785356f3b9e40a201f340eabf50ef916caec406fd454aca3be64d6ed9ffc101a25424763a0f488842ab4fda33200ff7059b5ba68157730f43bac09f64bcdcd20b0e58fb501e8f812522ccd2776a547b4503ad43e3bff7d7aa26f033e4f4617231e72bdb72298073de1cfdbe89e1b51fcce2e43d45d8745b0fe2d0167aae879a7a84ab7428b8aa464ce3360e9998f2572f89b9fe5086c12cfeec1df31658e459c7db0742fc89beabcc18e52772b09739016decf67d65d48048e234f8ccbe34b5cfd3b62c0e361dc4632ab84ae041ead3bec7cd9cc76634c87e3869307cbce3833cce510dc05fc1324e705553e904ded60dd433c7f192d67f8c2fdd239c77649ff3da91b3e9af3aea9851fcfd7dba4c0b4ee06d00013b1faac6f3148f48ff251aa56585b8dde5d8298b1cc619dc32df9dcea7220a04404eafe39244856680c7726d3bdb7ee6b2a919a0213fc2feb3d29a624a348b8654b54c58519b7ef47256a095940da9ab35902ec7ee7f26ecaa8df3ea3655638c34d1da95ac8e29cdd63e676b29e13c6ba1b4bb4bae20d3ab46c5e0cb8ef15256c0859a4f5d59d5539c6cabdc40489cdd63c73fd9731cd21b9dfe83e14bd47d2a7b5d80624ef92334ca17b88f6ff65860188f0ba66077a45b770a65da46daf2fa0e657d2eee6b1d4aa1849e7596a47a776b1738a0f0f3ff27dd6313b36a4be3a2b31132b5c088a200e1698ee4017a11123856c514b1790f38e096987c6b908ddc69a7844e8348952f4d17cc7e707d863578c64674a647ebea4ed769ee5d123eed4f3c408b576215f42d3d61418a2a673589f17220e602d4ab54df79ef60dc70c9bf003bf90ae0d3491c50288400ca6ec16baa86e6fcc8d8c42254f4dde005fdadcdd853857c791ce1692d6efb39cdde896e4064aeb2fe11b093fbbb2340322530e2d0eaa9de3a191fab11f9a7aed505a2a48e21c3ecdc8dd1aea1633e032c8fcb756a669b4a09ad5b7c3f6e2352b3097ec40c4d037176fea360ed9cbe5ff7ccafd54b06cca26c817100ea7ef9d38f9b9bc57720f413d2436747110184dab3c5c5e398523873fca4a69c5769c4361c4ba950197683cbdc62f4f0ccdfb9a802fcad6b0c2b91658dc6e27d96dc50372ad7709217901c8b0c45f9de602aa1a600d7998b458e9f111b4e3ec0efab207dbfed26d7a518691fcadea46faffd97bce7892b63280b8d28a8ca72d8330e3c547668ee2ba55cae0bd5a24719aebe47db9bf0e9fdbe872ed1e12b5ea9104cacd4b0be11cb2814096be586b77ada09174e938a4a873772c2a1b0e2772170b62f21cf4c4e30c39a218dd015c1730bb65e8061d36c762e363966a578941b73af756d679284abde84c76485d1f31f37c08ccb3bd6b8d5592a309d64494cb5d76c05135229f8cd808a19d2a74fa88eca9a8d1385b0bf6fc4551cc759ba70f4cc059ce73a4e6934e8ee5b810447893d2d1aa23e8f270eea4869672a9ae6ef7e1de0313fe883c8c639eb46ea767f7821d3e34c68f0cf842d17fe5a5346eb695eabc45da9429efb62e3e957bbbe2830cc800a1e957f2e221dd50228ec092c22f2f03b7801e032b3c2f3324b57176c9497ee84187b0a75c07836b5c3e3677f77005e233513db3fc5adcae6a6a65b84781dd6c04f88990944e16eb80771db1d4827c29e728e546ac3bf679d21e33e86f9d085818022c504b898d44a94c70701648bb9194b3f099657419ced3edc120f4074ecd205f3d52ca413613f1b075ca6cc4dc90f7ef298c17f8c191f17dbb4f55ce6bfc8aedb59cd4ae3c3c94ebab8f47f2b152df368104104cb295f15ee9707d7c4bb2d4197752ae39686c5064d1dad12823ada52ffa36aee4c9fe2f9567a736e83fae50893c130a314ec54e48e34b9db78a663ed6080eb0ec637291dbd4b45ecede51eaac907580e46292142e7a3b4e7106a762f64ca834393695d42d313b8e06a7d84b05512570a9d917d78322f8fe270329f2193e7860f110713ec4a5e85760d80d41257b222f6326a0f44dab6cecd6168b033d5f1a82cd5d338dfff2017f48ee63debf514b6eb9fbf914240092c1dd38ddcfa9ae9c618c7f62d5b50b9b46245e7ea7fe757f65eb3ed9d30b8b1d4c107057c30f0fb680114f242a3807a890e771346282095d61deb9e88098254bdd891fea1c9c33e6aca2a8b0ec324742a8e60ff47c4e468c38c283424b925d164e2dc647666030b0f2ac19dfbb9a8faf8eec1bd90d2856d84d78ddb0c70e50e63ba10e422a8f687caffa784ac8072d3d256881fbf943c228ff4fc23f1bd47b5f8d505680aaba36bcca776d75d3eb0080620ccd0fe7b81c2e3acc76ef240c0f46f0302b8d221867dd1db5f99533d7e8c21af491198a48e2010bd09cdcbcea39ef81a3000fc56f8e1b323a703c606546eeee28c44fa3df8f8d3e271088284fa5ae04b405f9804841866b2e0b89be167ef383f057b033840dbb8a7fb3a803c3a05ad0486879622b50b829850b102ca0ac6c63e93113db501147b5857ca32d2bf7e60ab7b56731e72417ca382a408f3fcabb8a30250a2a0386fec09acd35f793f3179710208b048964858443492fddd542ae73fc5b4c4b668c478f0a81389c6b22b103d79dd804569a7d3702f0c87ebd972979b135926aa71d0c4c453b0b8ac6511f37a8cd41df3d2c783ec7aa654799ddd1eec98bc6f77ff1cfb8b1acd65d5252586740b64af25de99c0fddf257d4f89b01664af55e241cb75b0651260367f624c4427d0fa8a2ea45bd2ac80bc18bb1caffb2106fff02b24fbb019e6d2b7797402afc872b15d7cad27f31ac0a5084f4fb6e8f3b65c34bea1617636d697aa876945125cd46e6ed55d4507ce4e821c5be6a3d4c594d890dc027a2122fa47127dd031c18ac3f5b5d0a1d12da42ba7be5ca45c372e254c4a2de6380ba33d0025fa607c576ee2ebd0322255bff1c05805045ab72a89a331efcb201672e11b1dd088c4664c10271332e9d87b201e93952f48021e5d353cc952dfc41bf8a19b9d12dc6f0a764cc486afff8abd79340950b1934b7d28ac258a0d0e7304f696836a601b2d43aa7bbcc6c86ad8e9749da6d7257f78d921a5d3a9365cd1f1b7e735781d41ee76f07e24826e9a354594df8403bf6025f3da4fa30e2fd6994b90e367ba65c36a82c0ae36466b3b47e438f079f87a03bcb4ab28f9792518a679b47bd20c41cbdf2bf9c2d54de6eee4655855e7a1a69da8edf2814cc1610bf621be2549c757a3ce032fbecbb5020053159e99a0268a878f220b8f990ae4504afd8dbf0fd51c1d02c8fa186755baaf24d25811cad88b01f4675dbaf2cf6199e8fbc6b861a22090e5f8ecad73c73886454ec4dae63a4bc39b8e7788f337271cd67e702bf36163a02d2e1c9e44a4260a4d5184582a2a301a644fd76338a51de0362c69b453c7c184a7a2f97095ab22d40e3db431ed100dd9d96eea33557a9b7c8a1e367d1d8c980177fa444950cdf85faeb692ab819f4137873cfaba6cd442038e09b812f887b4373cabed7598e33f04417ef71b7d63731f65c5f149ea5d9f5ed89ebfc62a73c2ac1237850e2b97a25c49be74659768cb8c32757d3f23921132b4cd4e31270143f12684b09111b522eb477ebe961010cbcf20bfe12af7a6a99bf21b827022d6862f1441a95ac769e1cd4d92ae081015466b9d5a353a73a1771314b27f4ef9eb79b394da88d90e16cf3350e3fce2af4f7ecf606a8c92d1b4d2de901a353123f39a1a00bbe147891d0e1479c3aeace350248fefc0df2e2b5c1042c0de20193bb26573d8715ff7a566ebc93f2cc187bbca267ad90429e09c4acc956b6864c35db43fdeacc1731e7fa2efd7bed8d7b0a65f7ce1d5b5313ce8c2b4b364a2f6b93008cd2fc92bb6308dfaeb511eec0ee087d9de593e31546cbaceb7acbe2509f0cafb6f734bbaaf3294f3084f3e3c7e38f73f846b8b5f24a581fffdca5b8225e571b3bb14de50fba472d016cdca5f9263cd4b21deddb94ce95ee24b4c01ec93817a16c710fbcdcd6cf669192e2efa02ab2ad0fe473c4bbfe1838cdf1a51b8cabd7ba8f215bb6b3f9c8ebec382b09b782f024ed638b4cf8236402df40b483addbfcc87541a232cff86d94360b939de8dc8209262b7ff6f55c8b9e8ba003a8d1bd7d234124677d092ac383c39f0d95b7eba31dae10bf5f87891bf4eb1ef1aa21440d092843fabc062cb21943fbc4b4b4a369435a58fd426e41c782e091a5dd1e18c92bc6496dab8e4af3acce7d1dcd2544b493c7e090316853d313112b690cdb8db2abbda4d06cd10ee29116cb93bc56d453f4f6cde935720796d44b633f0df941703ebc272ba4ff8cab333d69dc8b40b1994585a7174ce5231c8221d87d4c0e2b682c67e84ed188ecaee876e8bc12c4f1a7028a411ce3d16d6d0e8b83a0a74fea853d08e9a0ac234235f9696e6dcddb1f244956256f8fb2d9b3414ddd23f651a0a77711a2762ac5436cad340c58a0826397c01cb19d488d34ccb6bcfec2fe37002189a2c61cf686d0d2bec80011636c0216e94cd9532654841976d77a8db0dbfa85aaf96825aea84209419a20bce879415d3de0f45d81555d45113234bbc611b97ccd4273251f107adb4af657aae37b2b9e70bd4ff68b90d054d0c34503ea895cdad93b9526e9004ef72cc18e487d4c9b872f56885a6940ed43ac7a1ba046e273f9c33f94c6ec9c9c78b7f8c1129d2c27c82ceba95ba8992879628a7c04d4936551e9538e63fadf4ad47ba8c278c67ee6fc94940840cb529a206cc88414ac3f6d3c31297abdc6a38849bfdb31af6a4ee9f402ffe54d511a636f656a379deb78025210aae0aacb0f5bfa5bb8c95b3c50eb8132997de230e64a0cea5d51fa0881a9dee2f1b7db67b13d364ca97f345a200721fe89fbad366eb1cd2b194ff5701e1c86718a47757176f769cf639a151bbb24e82322ed0d46305f3f079ef52a645c4970adbc8be4a15ae8a9ef2ab604d21270c46d1117d65506b4cea7045bf2cc3c56b5b0dd95e5d9c53819d184fc4b9ba86af51c3610ed97e5999044c4b9b45bbd2ac7b2619bd1eb2cc065fd54642bd6bc313c831115e5afdaee0710b5613c4ec132846dc0c81b601ac436221705d58d6b0b5fc8f6217d75995d38d16a59c8e1273163e99c77a5459ef52fe34baa4768f427954ae8128111d984a15604e5abe599c2c2c8c19b66a3db1c04ccf10092ef78bebbbec8d2a69233c738d3e16315fdac022f6f664c0a05bbe83a3dba36302dfa87b69d951f72f5b06d91e9e0348de124f3522a04027761bd48488e252d71c102803bca05bf76054cb92f8794e8c7097d004d1457c8879515a3755114acb9675a49a0c965af3046471137c99adf2f49b9857cbc309c8a221184aff2d36acb066afea845f7b30a0ea6e3be41962b1e601243b8021d950ea01ef2e8ee3e2800ef125f1592fedd997091ab35112609d812eefc0f5f8e3a2d78c5f31f938054c35a1129a316e4c9649c4dd067b0b1af318910979f4d5aa06ff0fe0b1dc466a54edf2138f5ea4515cd8129dfedbbdf1b84b05cbf8138169bc38adcd36b59bb36d759433bbb5be7bba33c40d9528407154f71cedeffd415819b8d29d45931ce457f318359594095c811b3115a566846d7f530dc24fa8a7c0ce546e467d34f36b52b05149c96fa90be1da5b81c29e467fbd04c61545e279b0ba7a12216e6dd4e65df96330763f18e3912f786f6a93f4a7f025a07feb4870ac91f67d218234536540de0c637bb1ce977d2a417ca762a1364bab0f9778e0cd4a85c1cf06ddac01180f71c1d19c6422ea8b3aa41de8df643d059a5151ee92174e6fbaf59636226873387557b82ce5f72e785920e098e7b700d30ad5db447510782f7b8cbf32c473ef2205529181229df7e6177233528c13dbbf940a274acfce6493574501df7304472366f782f7f26cbb5672bbf54ed5bee513e177809d9a3628f755c1108dccc306b3aa4416cde0e183538dff41b457ca4e10ddb87896c109e2ac0357a17802726c11c3fb0a6d0e491e0b5e4ffde2c249443fd002ee3f9989cdeb82f528b0ae8974",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x7314bf478bfe14c6bd19a087a8d7c61a264b1e1bd97ed17252be32c98463d105",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xdf09b32c761620c5be77da398b97a64f03c3980c",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374df0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x06eece57b68723399deaceac1a88af6125fd78922c86b29641e02be756786586",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xbcdde776e0a1dca3e2d58d1045193fd53794b57a18547bae3591bb087255465f",
|
|
+ "timestamp": "0x6ab8f164",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-anchor-20401648-baza",
|
|
+ "sursa": "2800-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa0626573752032362e342e302d616572652e312d643230333230312d7774613037f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b8415763bc70066da143c359c9b46db82ed9f6c6ad97bc52325ce554f69a73cad44e2118f927b8c2e6ee68acd094801362be1c451a841bd16e642418f5ae0765a7d501b841cb49a5f6ce80d1ff0df7f6c1ca06ee9801af3f2ab4fd292f1338f686b59961eb4d5b4bf5cb0426302d5e09584a7a074c04dcad616dc07b7d6b695b6560df7a8001b84169f31ed734eb9c184a8f796cdf7c6519c71dc82191a82649094d0d25c52309b25f18a7ee8207fd4d1fb34ddebe3a7dfb82ef162726975b339335c7ee97d44b6a01b841a256a5f0ee70a9b72d3f4aff1d519bd95a69cb60081ce39996310942c1fa6d3e1a346b74a6bea1c81050051b1a6685d6b95fa5226f124af84340800b219ebc8501b8411c52ea8a2f7a8bed7da258af04ff6d1bf225610ccf4477ec3bcf39d7c63d1e125b305133a5fb8ffb2c1f0257d2d41528e22593783fdb497dc4f7f476bbde1a4e00b841e8d5563e0f814ae37f136df0df7af03e1f15cf15588994479ad11c420889f00d3beae26c3436ab69a4812eb3c228dde28050d3b574c0753be1c46a4c7abec5de00b841ed3b31380449463c473e43b5e5532cd08513030e3dfa49440dd56a2fe1ce277545e4d199eec93a29a2ae0940bddeebc8579d0ed9cace4adce024540ea2dac4fe00",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x42777dfa49a9a2c8ed0f797802540a8425013b1d764ad2468d9a83f49a7dcf4a",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xb5e768cb3117ea25175f51aa956b48691025c2a8",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374e6f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x98d91f304863f6147b9ba0b9fe38a6f342dfe02f2fa80a3b2819fc16a2fe018c",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x436a6a73024894dd2bcd2ce66538d0588661fe81ecebd5ae7a35a9724e6f8ec4",
|
|
+ "timestamp": "0x6ab8f1b0",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa014ffca080297ae182f7314fe075c2cb17eaab776f71ef1030fc97580dda4a056d210cedf8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b841c303800a396e8633a3d675667ad4564e9159952689c31c769f3b02b51a5cf1c95d3ffa15dcbb83a5ccbff6e6cb91d809ab3a3db7e5004ee25b6ce79ac88a18b701b84157abfe729bc85cf49cb632006e4a4c7dabbaebdd5733eaf82dd5278cba9dd8e903ba689d3853cdf9de972832b1d2d6e1b543a9ff922fe717773431d7a41dc39901b841d201723f6705809b3e63c74f3c2fee9d662bee12d8e69ce6e273bc927de472576bb9cc1d8a3448a8db62ba06c1ebd3c7aeca79d810bae7ddcf26e4b64a72604501b8414796ad282387643b07d82f35faad06960c25ea422001b2fc3b658311d44859362250f35da429aae94d0304c2fd6cedacca005b53e808306d5231feecc131f95d00b8418287166c24f9178aa66c9fd5737177f786c2fae5e0fa085b3e2713cebe8bf50b61d02339f73e24649481b71d754bd51ed7ee09b20c8213967b3706400275adb701b8419833b2ef84e70074a0d5bc61e977a20ef7272239da98d7659c5a3c935f246a414726999302f377a9269c8e49309e7d66ccf1aced2300f83de00a3409032f55e901b84178ac3f76969fe15b796a05e65337d8b28e2446a1681f906277494f8279e3e3a56077a1942a4786058421e438fc01d1ad9467a5b166aeaa53b7c2569406e7b6e501fa014d2902fa014d24f902950180b90290391f532a3bd5fc9745527aeb8e8aff2b6d0fc0e5c4a68ab45b1e0dbd5f5f3902fa00cbdc9e40eb7de2bd9e18185e4caa3aee629382c598c83183d76d50ed5d3dcfaf69d51d2a050898d4a08d35f53028ce3981ffef7dc685fa81c55dfe746d24a4baa95ed2693221dac86351044beee61ebca7a6c993104fe759055d8f78b7567f3653afc54fcfeb7046a2af1e8e07c84898e5dac4f2b6f7a947af72be329a0d414c2944eb3ba94f0b457d6599a13bc27d92542a78ea2ad88c39715976b32446a4cd4cd2169b14d217e8b25994a8fcc6597b8855cc320c66c61672ff5bf74aa1578211c454d3de970d4a03ef2c5079bbc094c038df94734d4bc1a247cbb1f5eb4cefc81ef585cde64822fd27851f57d4c7572c3b174b34a4e7975b3ca8d07c4dcbdb179790774ea4e611aa570678c1181d5a4d18ed52f2761d27ada95c78f206b86ca365b69676d1188b2cd0cb60a4ed72e1acde77d3ffaa93729e8679f65d9e3b219b5cba16bcae61a4cb99c282bed72df687ce6fa141a1fab7d397456f745b4a7250411d2615216d8987bcd19fc8b95380438d43b39479523fe1d6b0c389a468a3459ad5e39d0e822b568df706366d540edfe37740de3b1aa1a5f26b6928439d364cddd4772d8bb4bd89cf6319c04251cfe13ec4eb61ac0b55505568cf41b4bce44e1bdb95606ed11fce9d0acaa951fb1429b0cd241a569a1e8268ce0bc11078b4f2a320d05c11a88adf51fa67b75e89b128338b9ea9e3df3364284a567d2ed0effb6619f44470abf3fe1efbc128e00a5fc5979bfa10a91f5d8f2b92c20b39cd902a1724d7e1f812db074b1ae8131d1743afd4f669be4bffd95e4c214ad6ebf8d94aa1116dc37cec6298938257fef9841d77c66d7508ad6b4b9490cd71cdb9dd667e568cd1f86b778aab8e9e35b8d8f91eb50280b91eb06f1505dec528c92347d23c79cd9f0a86b64dad4a06b8a2e4747739d2ced023591b6df1287c3dcce59a6f6cbbeec6f04540207d2bf7f5421e7cb88988721d512dd3193c0fa8322792f460059a2d6e1a06cd052f395f5b7680793905811bb5f955a818bf59338507b51ca9c0cdc4de8b128ae382ff389f73e717452a0ae112008c65d278132191b03215bcb56b625986e4df8320d5c2639336acf4a7c95cb4448d4e48a873b6b916321f9b0fd149bebec7c1e42e59e7622435b2c00bd0a415f6cdf56c3ceea672ca8e3d300b3f5250c05268b19c8fa1548049f9fc32b2c4b2f141f9b7ff1f3d0ac281762aa6a4eda11ae5c8292417116057a66ed5dfa0ad0b96c0e8f67741263c506954cf28228e6ecdc0d3015726ef9791b3d313873b9afbf58bcff0b743aa99783a85c71742d871e05e847d2e65b1406f5335e8e357d6a07a6c56208deb61b002196601fe480dc655624856fb2a05fcf87518abe52ee288bd25f75fc60651ca55962f7333f95c404f9d1ff09341e278fc4222b867bddfc3327ef0a16b73e7137b1fba2ccdfe71474631e0c1d25d229bee333565a5ee6aed8a405539cd7980b07995ec5251117364bd6beb01a535e86c9b8e911f3a91bacc75cc297beb83f00b8a7f3e9ea176fc5e538d4266ff44f2c2c19fd1f61ee5e45dcaf0d3bba57107ab9f82b3c5e730fa658f29f997b57f6a7b4f42a7b0ca3ec9a17e8390cb6f5d1359c8e5c83d4b0fa5f89c76e5cf0f544936c555094817a0ce4ee10edb3fcb0c3b33f93002f5c6a234328f68fd9e58bab76c02baa3c332a47b989bc3950539fcbe6e9481fddec32bf487a7f2caecce4776c8bf4ae0c142450ee2d51b3272eb35341bd8efdc5cd1858fe34908d333f972c9b336b9a03a4b7f2a54c0854a91b4a91e18bacca6617bd267cc2aea53088f23ec4d66a11e50193af497abfc60c3979a6794d0848bdb0dbe23c1a7f9a3a905841e86cc3b27d7a3eb72751b8acdebbec6c4b95f723d6b23d89b94867b8ad15fd5408ea19ed1da09a32547880569df5a9759764e5352f1b4cd2f8c2f775ead7b4d50fc413c183534e6d3fa6b5c41fb5aff18d70e33cb35af4e3fa30f87b33dfc9ab6cbacba7594b1686ff6427985b4a00c8518d254ba24b8b3b833f66b1d5cc2ed548d4c7556d69fc196fa6688511c48be0689d09fd9807a71c2daae40a5d187c50405a334adeff9dcf96ee8750c1d1c8e319aac779251b3d9231dca013495b33f9a8506954ce04ca88dd48b2b82a01b814a0ce70224b5b3c9859f2a529f0902a6642422521742282f1a5e42757214c275cf0000ca341dae0acdf29aed912a56f181d8486ab60bcd45ebdab23ccb579bf54dfa00743a3325c9d455b30b22cd3af3ecdbd063866877ce6d6d30a8d9a9b8252960e419fa511597e8b8f93a72f4595ca66c8967747bb3e911a8d45b604820a710658d827b5edd6f87bc9410bf365d4abf42aac3ef1a7b6da83387fea4a31dd40ece10dd5e1c4a9ea4306f707a66d1177f90802c9404187feadcdaaf3a797005f0451dccb125fa11acf83a0e0d042e22b2becbbd7a0050188d74fa7c6437e87c5ce6cfdc58fe72398e1a04e1d4cb250ad6c3651cf5681018a352c48b4c5d0d68c9accafadd36ffdb9dfeeaeeba8483e4d096e42cf306086bed0ab8c12b2960d12f573637a1658d74bb466a7fa1e297f8fd4b7148e741c858269c54d9e24a57a5cbdb5868a3a5ee37e21cd9ca565b3c3d08147c09beb6f77f301adfec7b9d234a5b80e6183a761091dd9929041efe57944ed73012c6bb3084348fb1d693ecf1f1d5577faea4299ad6ef6669b16c008b567224c9e7538fc35d1828b153512e350c7dffa11e30213721605af8c98f71728448f7f8e6f35e4a20da711a404c52ec52f7d6b19d712829d146f398fb44f26e9412be1b3438208f059f3344b8fdae00b99cb94d9d5676b91fc7e3174156bd8c8ee6db21fc4ed40247057b8b50d56d8755f1ad976024f617c019014dc53c118a4275beaf78e4255f986cc957816442bc80756baade3be8bb4a2e02169d7fd3b62af2f7d72df9da155445ef96c85a38ee19bf6c9750d48d7ab968c5fac551e9f2eb1028c92c4432c71eebcd03d652c597424c2be4a824ce4dfcf650de7ed87b0a91403d99720a389c62b0ce6174239daa2ce50efd74d17b345966fe9188c3d26d529b92c1b82ee2e3760191e8737358dd66c68ccfac87c2a352c219be8bfbdc66921f3f679826b756cb5a75c14e68dcdf7635cb8500cd82fb47a505f82b739da0e39dbb1fb18b61b04bd363ce000ea05657db3638670a9ba48db2c4745ae15697fe3ff757fc773627b000bda525d1c872ffc22440dd7298f18cbe519893e5d5aefc18122255a006f057ab0701b442b0a899b2a0ddb6abd88cd8529a8c1de47a28e92e039d31f60ccd26352283dae5220ac682d6a90e88e7b0a32e368be257139dbdc2fd605d46c9635cff0afd9d67c3c4f7ba443e97478bc42fc1145d336b939bc891b1111005a28f654cd4bf76588b0ad06cb272604f84eaa1859a46568b08f62abebbafd31631bc7505a202d5106e55456edacf85501b9ee05ebb59d3e529af903a7db71f86faa94f070326f704f0816858925363aed82e85a3696a9ec2776498631433f3a1052391c5571d2d1e3246e3bbb6a3d40f9314ffa4181693792aa38360fd7fe5ca17c850b51526405f6a897c7ff7651a47e4e82ff3e0096337114f98dd588896397bc9647d11fdc7d7eb86e3452bb996c94590d4c6cbb8e39d8655a4e2aa91a7521f35d6da20868fd0d0ddb9590833b413e71279dcb23ee6f4733a54f46c1e44f79444bcb162d526ed6320561fb36517d869b37580b3f983a95b26d3aca83c67abaa8cb1232bb2097aeed39259f57e8f3f22b6e62f33cb5ae7041551860f44c58a71e7d6987eabdc656782675aa7247e898826cb43cb52b818988198257ddcddec5e6d0cb6f7d5cdcfda91b494ccf0073693993e5af8036174ed54118760c682efe454178495f61dadfde913d9b71bab67cbc796754f1e0bcf068cae32e738989eb643870ddb8b0ce60ffc25305c1f5279c58e2ddcb4ea8734210c3a64eec6c684061b32fdebb96374633512e81dce4e280740cae826b2d58a8e818e0c1b68ae98d9280ef6e04fdb641eea564fe4c2965ffe28e0716a80a0389ac9e8d0fc1771a1ea99f744ac9f61e7db1957bd4c56841381267c8c858aa99dbb48a8ac1338f00377974554a778b7697d39f7e05473a7b08450fffe6fa12c70a2cf9a9e2811b780d6d7bb3423cfe48934484fa0895e9c8673a9e77ab44b9d3545a8e7ffb4422af39e98665a0bcb8ffdb5078324fb97f0c6852d5abcc52bcb1cb4188236e6e1345f0f5d6e55067c86a9907a6ac4ff2acc4aa4e95711ed8d8554ac8a9455267cbcee31d54299ff3e74e5d2354e5caa06417ba17a81d68e55fd3b0e96ce2805c085c3c4cf23cb41cb47249809d6c0d82ae73bb0ae364cc933320b0dd1f7610d1c6ccd3c247ef2bd520aef5aac6a3e2f12a7e72b5999198b80288377cab56da749025d7f0d3fb3f21d484eda4fc295ff7f6914cef1bb1eae3f92bcdf1b63b5b22f266b532e5aef3d0e68502341b595332ae075230ebd616e8b5631b4604694f44ff1b438e36004065c521b21ad1321f96b8dee3f2af7d83f47c56d3da90a9a122a89ffd3090780bea1c4def947dc37994663555f1a9ae84fde8087258f6538d45ccf2775fe3348b0cf2046f8f4b3d4239bce04d37e10cfff16e3640f746453d875087e0859c872da1a88d160daa5f54f2072ad58cfc97474d2a7e6f9d84e111faf98588fce957b9daaa04a8669198c5966e433579d4b8176533cc164ef0cbd53811638f89fa441ec26aaba04da7fb0f56f4512b3dd24e30dc4c8d3808cfc261cf7e30d1b817240dd019147c307f03e18be0e1d8a47aee63d288a084932b7b13d36eda6585e386f7223566f48cfe0491aff3d78e30e5a3644e4fe869174708482ac02133bda229bbdb55fce3319d658cf66626776aae111c91557b89d6815d1820e438cd13dfe018e88dfe5e1a7988fe25d7685102aa58366cc9d065226410fe9e8da0328657a20e0b51701017895b68dd394bc40fb583b16475f1f852dea9d5d758141d003477b336beb3c7cafea2e5801a8f8d4a729bc6a055379f964995876103f492393eb14048a280433e2d96f0bc46a423667f2d789baf7a557182d572b331c24c8fa245ab6608ea3875de33c9c75be68d549ed542250f97cb7ab3cd6feb5154263dc84b797607e1c03b029b74993e7ec531772b9d72f7c951c40feaa7dda177ec2916709ebb067bd8324ef093a6be17082884cf40ef77870c149edf4fffed7e158d576acc18cb326dbae17de36baf18e65718e46abeff259c901313f07fbe7ebc1d1e733d2c2bedb7354824801010f4b2ca5d3377833d7809cdcfc32c70df88988c9f59da058ecad01557342cd3e09de6ee899784745d84945a19fb2254e507e32092562816576f107612df3a3416995c842a6b052c5685c944c84ba684f034bfbf45907e39816f93f71be4381263c3f8b5bf19717e324acc5aa63531af879c4c1763902f6227d48b35c166a7037ee331c071ae1b73c1feefcbac4eb589518b69bdaba1e98584409abd6d884f6e6df547459d4b187e051ddb0b66272dd2193f5f3d5784683ec60341b0f3254995cc9ff6c884864991f9b3aed679b701cdb9a151fd8486ac00a3f95ac1b7e9e2aa0ded92c9e7371b71ef446d7c12752a7258342e84b5bc5f458571f0bf32cfaeb3a14409da578089c3dbce208c1ba1eb913b72bd25a041dc8ecf251f26e99c57ed3635f71ec8da5537ac080d1fa60e7f80058926ade75a880dee7e17347165a8c782725867972195c64eb09a070b602c2aabd6210867920c7671f4541fa2c044b03db82bce95929e53df73d87d54a6a5dbe8366e867b9d8d54bc3fde841f6b8eebe9019b5bfcf929fab6f81b8acab07d2d51c66ba046f1d96dbbab8c1a9915f2d6e611f8823500098b7ae65d0ccdb2c29246f2f1e7dda9342c603ed3cf5779f29cfd3220fd893ceae17fa7c8cb7c40ad6c59940a24bcd7b018acf08333c4072a1dff4449ed71c96df951c22fbb9f882f48db8ec1962eaabb1ac7c4e763e84d2bbaa56e378e0d2d9e7615ef34d5d0277dd8508471548c021ad79108a675aabd844e6e03606e116c33bdacc7e86c688af9dec5493cde006e60d99194c9ce8c00525f0ef4617cefb687ad9710d71400593f0fd557f8823f75ef5fd1b3d9e70fa06ead4157babcfc1670aec91684059c9b25317c4d3996f0cf5fce0977f94f91fa77d305ce8947f1a5368651cc6a492cc251ab90d0f5c6497132cbc4d78ba8d1bf0f62d1b7cf51bc57342c0238f8d76d3b841a3fc2a080b09c14cc1f715d0a6aef8f1027c83ce917c59e3d1bb20b23d97f0a3ab2fed2686550d9a525608729428da86543a9eb885c1653b3b4502fcb0bb445d946a0f0b73ff6b170be862825bfe73b0894b0d97799360cd0154dc637b3524362ba16fa6ed33af2f00dce2537ad6dd3d33cd3a1aab059ad9d7729a539527a7ab82105de2c6892a6f7813190811b844d23b4e0dee1017ed0f58a3019b0bd678ea6910ebb427dd217cc23eadfac6d9138858994e28ab001660a66bd657af3bb3547bba0ad2222e6399c1ca817673969260c2a79a6148abdfddd3c786fa061dd229947afd12e3f4a0f060bddacb23b9007c8fc3d6fa713f9cd03f122c26251ecc47c6eb1a9c509fb52d3340812f01dd2856ff8fdc77dbdee116b4c96b5613cd29b3ab57e34c89ab58e7f35db9f5fbe8c79e7c482fd88c68b0140b5d1325e1724da62a14fc3135b6ab66e0cfba6561b52e6558292cba575a9fab3fc905a63356b37cb209efe32cb8b7a1816d3aba9783312d33937825c3c9f46d41b59a7065c4aaaeb064de30f9eea268ccc3b0cd2587998e2bcc8a6fdfed46bc3a99ee670305a684ec6078933eedb17ce4cb4d44ea786699fd5e564672360e1110f912d9847935f8cd308fc82e79a308a24220e38a6a4329f36deca6723b575d24501e40320a70d70599c03e740a1d5eb0c536425201dcc00ffb7fe0c5f7efca8468f43d157cacd89a593bd3fe421e9f92e019fe0072ce820aa23459665c81b0527269b45806204e21095ea7f26da628b75a6c48e5ae14a5bc5d6b5ebd0fd98767a3dd99535d25c5c5543f57b62759b00f58b2f643a685e3b559862170b674dbe6f4039aa62c23b0da881f588f510326d0b0f8b777b2324ea50ad844885f1c204b35bd0b6ac0664177c4785902a1ec75681c02582c03cda2ebb19b863c859c916291435f547d9c58d2b5720bb54b5a95713ce5d15ef51f2ac120d58a024c2d5ef65b4a57de71a88c721ef04229ef7dba6edebae41bf2832fdf10ab67928631fa7bd3331b1592fdd7fbb2accac7efb4a02967c908a07e58ee45f099e18c2bf9b0e1c4e7681bc699fd3dd55f536832a4984433628ce3aa371d6bbf71e0ecf6ec4b1b67afcfa36e3974894315acbbb64a6b18d473d26faf0d71da6091f398048db3cc377e4330e59f39d18107dfaada828be85029c6f75191da4d586315e95a2708576ab0d7c7019b32d4062ea919c65e885d36420475873493c1c4235d72f0276653e45210ba5c78cce3512762965f644e6c3c385f27490ad201ef97ecabceca02d294853127a8a9097ff81cfa6127f5d2750fa0ffb6a9e698bba59e3421a4c1c82a694c5430cb5b57b39cdd6d136542e547261d788ed7a0973c6c3ce2eeecae6ed2e542c60f2b3d6f93f4cf42c17a3a42c59e394af86706c07fd2d19bb702870d7450c9867196310a111928663b5b8313564d409a55588ff6768f0ae14a973efe4d78ec681030ae31ae2242c9580444536e365da8fdacdb1d64974e13880e2b77111393267d1cfc9929b9f16d2890c475d3bec00579ce5427202a2090b0e785a479bc9bee71ae99dbf6c8670e3eaa5a376531b73e40afbfe2d2e90979b4cd24e22600ceffe4a5058a5b48ed1a7595cde495875c45fed0e11e6a4da270215315cc5450ee8fe0b61f96d6ea1f16fd55d05e1bd26ed0203861f4bee1da763fc8c85776e348df8bc949f4bb1daf68a4e7f53684bbcd4dea0d1ecc135357cdde2de81912253e22ce5a8dab5ec40a4f6e757c419f31de2f8c0dd5897b68a9aa2ed4368349e67f044a6611c994985bda535fd8661217ae2f1d917705436aa3785094743951abfa9096d96fa6508604a9a9635c2ce6c5e87a851a12b7e0e235d8ba9fb0aa1e9b46d74a849404cddc3a4ceac5e62e0a08282d08afe7f5b139e0cedac78144627a39579891967fe59fe10772635c9005ceffdc4c4efde3106c90a125b0a97ab7221bce2fd3c1e51454fbe7299e698957c2d183fa2aab80f4f17780575bd37b7221efcf7d6a91c5f4362e2c72f6077d7444c4590fe2173f78f59a7207758aa216ed691dac3fa33bc4aa2ff479da9b1905fca12cccfff236b8f8acb5cc55e263d34a4a21a7d12ebf207410eac4bf69d8c32f4595dc442a7b619bb3d6f0def0765530d38188086255194ec1a056ceaaa1c5ddb600a668347162288486414800f748eb0e50926990b69e773162205954dc5a1f58c83cb40bf9aafd4898eb26541d06afedc0f3f39edd8829aa2da360830e9525bcc5df7827a555ec771197621a1c580422a795a0de0fd08910ef8f280c0fc3d568799876851a86c47be2b5fbf06ade55d78c02105a1bbf49a2fa69d7729b04ae33f3d9cf0efd7f924302352c18edd18d979d94c85da0508d2acede98928c602b3215d8c42ac8296f48cabfb56c5a5d81c4c123386b746324a222861dbe422521ad1e78db8ccb1faff8ecbd6eea2d6df182884665d123985eeeb0cf2b9c90296ec58defcbfcbeb3d901bb096b70b5853026111cd5d54ba9a93741c21dedf3729071e0b3f0336b7c549b4b18781af11f1abb1a22e28ea4024f66246c86c8e1915cdda7ad00a83bf3a8798d296d7eee2aee87beddcc5fe10292475d7b807b0fd56a3255eb07ad319ed77ae522f949e508bd6bd5601632accc6e1eb314578da7546af5547cf99eb8723fe691636902d9219d2b6feba7066756dccbee348db92c281b12482b0ad7d1f1ef2a05aad72122649be385ad3aa022f1a71e18a69dc5bbdd4c5f25976929a0a3d9170205483586c7baedfc1dec6d0e20de92b540db1a927005d92e20ea8b393fdeaf6768f34c75080f8c9fd067ff416f1aae96bbf71d383099daa094870e4d0e3e55b84201f75a2476d65833870172c73fb47661f8cd1e02930b0632d1302c1c06a713408cbe7d9908b46f4f759f933bf25ee5740bad9133bbaefe02f5f6392134ef51797b4c31f77035b5a8dee1707f534d907af113b591139573650abba4f14187588f4162923462cd84331e6fd69b2facf790c1759fd7a4eb4c30262d490e978f5d57843e333d752978c21b2ee947d22f28fe4f8740ea5873d5a20900a4189b29734665bf7343dde0736af75ded766753c817f86d0b00d071df71b3c30fa08b0ffbd113b8b94a0b0285aaa11ea28d3950e2b612f854d7c403e71a035722d37661a3bef67c01dfcb303ac9dfa7c000d361bf25e8a382c25dd4deeb9331287608f650bee89b465752db046f51c449de99844129fa017592ef28b3949b7e33f2047f080f08c16431ca301fd45b3c1f1585d6810ae2226a68c0966c2940c10e991b042f76ff645358cadf8dd1a53016340c9449bb21653c50a2ee09b59e3e3a298ce51e6b728c6f10f65a3a2100b938bf31da30957ffe3cb49e2e92fdfb76e6371a7ccdf2c038ffadb99778abb9d9203524451067b28a0c0522841cf042b26c3bc2eee538b82a5b2aceb2ec491e078c1ff3b48f8823bbd453b831f8cadfa097004844eb8c11237c7deeb16fd30d27c9c3f1738dba0c76188f135c3b56d770db40d1256ef189835171e8275171840491811331b0d0728d880819fb6a6a30c7a54ff965c3410f01f57aa4e979c694184d8167d8c2513421b427ccbddd06f09da4eb6adfba26aa90409208501619fa836beffcc02aba5a8ee12108ef5a2ce572d9bd64d7533de66c3e965723d1a14358d8dfc2342ce5cce79b37ba03637cbf8597e4ea601c8d86669c09a8bc6474a85bd20083b7560eabe0e56e459d087bcdb6491c94e3a8a21af7e021165a93561afa07cbc0415c5ab9bbb934d718bc5f6f7c59b3089d76339ce2ad046dc4b5deb95474999daa4ea4c73dfe94ce80ecc4ea067e51b8c9a62e30d22ead8031503310391f25443ad49bc7c095399b1538e8bcf472863912398c08e941b7db97428ef8c53fc9308b1d16da7d497bbcc827110f2666939110553ab1fca4e5afd14068ee18f53b29a2d2c15e5fd98c553ed3736387aef3a57aec8934cff44fca42f48a921e3fc2b664f8dcb1d59c57e08076b5992508f6325527e84ab8d44011f5f40223aca4519e74f5c20e2f49c25cde7c5e338440d8b6b1600b5da42439549299923abc381f7ea080d2435527ba6a707ff2b17f10d4e7f87605f733043699df76c289cff8fd83afc02e362430aa56d51cfb956a9c0061c18d161f10c538125052dda80812d32bdf042747bdbcd18d2d1ae1b4d3b535e072fedf0772fd79cede878df155cc85a900c111e59225d0490866cd54fb0241b5ab3f7fc7730cda2e9db5ac92b400bac61db60ce64ec6736120350298eea5898f80cd38ac843b286fad948d32eb27de35c1ea2535444722ca58ad01fe543e155dc0e27d807e925e69bb0041cdbafb540eb9e1bdbb7302ef337b0431ba12d0f22a9e99f32e0bf35b9f5fa580c690452bf84a455623f3e7d42bac9d8ecb9f5d820bed537d24e7bed45c3a8595bf2874d5635c4f44cae7e6476083d93b6daf627f8de10a28c4d771f980fe66e8086711c368e758ce38f4931b8f8aae69a4018304cf533e6ac501fe829331068538eb3149ab4d242496948a5739992e21c3d3e5177d2a8ff62d63dbce77f1e7bdf6eef3246a9f9116a60f450658b7703a307519e1e252e763500a51648f0f868836f2bd030e34004d6084cef37af7b33364491385fbfbe6e46418389bb54c45299fa08fb82fd36243161a0c74f7a89e439805a0b8b83416a079ea9387a7e1f4d53795557114d86bd0637d98a7303d75b551778d92d35fc29398cb93dbb94f9db0be2af31945ededc0a53329c9b3c110f0e56b481c200fddb703a7dcaeaa3e2af850c5b358d0164e0fbc979380b24766484c7865acb61fca7b7c09028ccc15245790c93a217baf588d294ab1bdc605505f4d3483c38370b1e9dc9e9bcfaa1aa043e7d512f8c4bff6059c19ebdbde1da003e5caa1b8fb32cd43bda53345323d3ed17cbe4669572c3186044c7782d54719d2c00f1f634c56c3f5c5aaef2eb827544ab9b0d156a91dff85344ba19869e7b32926c4aa39bebfa0e3c0fb9b53035897708851e33b50c4829c0547bd6396971c513c9d5d156ba02f96317516798b5c6771f5de29c29999ca176196e56d2d43386223b9b0d1b319c593c8e3a8dbc5c838745ce830be23386620719bdb3f3433e59a95c4884eb428800b6a74c66fd0637650ba42a1445d2d4c5bd88d948c0ddd2abcc1162a404aecbf4cdbe3586b0272c495a3e5e7f3aef0768a51f6bdfdd389c8711d864ef82199571944ddb9b443c1a87a993f3550b6356a9ca2893f1c3dc9fa8146fa9087fde61750d75d290fd6c080c383763a51f3abe7a4d828b28b29d49916d8b4b97f923a38218fbceb526d562727a279bbe37adb871b279655eb09d6dd53c0942421c82d15510197248b46f1670f63161dd14e8cf154f5962ba5abb852e51b4efb473c9a6ae55c63c3cb033ef6d859147155957079da39789fa73e3d4df80c0d12d52845f88782df85107443736c80b1caf3d1aac2d097dbc31eeee0db793153d805cd1532f414737c43531f900148c65dd360a4f85c772c5351e33424ea675e31050969898a19f9876f6fa528ba7e41818887af5a6e7378a3d61497fa8c232b0425ec023bf67cdc27a2188a89d567216d534ce34e919b4e1e2263974bb299836f18107dfd4dac4809d14df902930101b9028e39e2f3b6dd23ff1d1a7824858ce00cb56bcccdd168de74711ff0e8701799d8d97f08fc750a49d183993ac9b36cd7035d5bd4e3d33e0ec62d828b32e2879f8f96e86b9bca1c3166718e0a7bc9cdd70e8c492e4024b709b4f9e520fd985ede397edadf33cdf2324bfd8f5df2514255e817294fe7f1ddf6d09b4b14359f64312884efe33eceea7392d27f9ada566317c8ee6345ddbcabac3b8d26f4badd5732273e53b534ca6a1a93316817525d29f3c53bff1a159924a6a4364da72e4a4a44537b9dc525794435e57b6504817dcc31ad5084a550150e2d79538ac7718b408e83d76efaba86c8e243389576e16882b77aecc4bea6f124fbb9c9e06876278a08f1d2b5afbd559933f9522678a4946cbca634d4af6d4135dee64aa75d26441cc46594f53d922e8663fad9c893f5aa3fa6a8d7660b26ee710041eed5b6d09933711f93f896c37e946b62bf9c7ded6832cf1dda2854cc0ba8810a7761ce2033c8863b37c14c6f8b04234ba37733874181566148b2ef3bd72a72175a0d7464fa9999b8e6356ef40e2cebe2a4dc045aab586431f5ec46ef8bc8a2c2919a468760c12da411878fde166e23cf50f7e73c3ed400920cb12d64572a5328cbe2ca35cbde559c46890aa67926df948b60c77083add2e24a5f0a39942de2c04bf6de045f213ca3b23d76f244592917c4dd87b05d3aff9691a3690df654793fd1c644966198f52671a96b93b44aa6f2d39b75d71e9ed63d725624d5d5aafe7ab7b782e76438ec66ae91434db4f6dc916c906949a115643b680cf3d10262514e76c76b9f65a28887e92f22910698c29029c0aac4c4a1932796a4f3e9e6c1c0e468ac3233316937f1a9bf65061787098a61eb3171275518c59294c2c555931ea6c931ea6b2f244928711c7915f66d8571029c713bbd7e84f91eb50201b91eb001794c6b87ebdfa5d4fcea7766d68b03dcf1a587e680757e24d42b57b5495194d24e3a9e0fa5112949b60fea7fbee699bb49fa314469210e45490a0bb67fa277b31ff85134314a8b73840652bc623ac52d3f0e41e800a4e425a594feaaa564af65b7c8938a35506cb187304dfd3b97fa55622d75008987662aa3ed7ce2e4a2410ad9b6f6480aee5be3d1bba3c7d3e4e72117a6ebafc5e492afa062a98efa3ef51c2609739d5629f2bf955956cd8fffba0494eecb8ac2a23157cba3cfc44696d1a694af24747d22665de891ad7dba2bd56eb4d689572e0ab26544aae43a0be4038c4fd747a9aad13df1b9af5b7ded29c6c4f205e14b0d6d45f45392bc6fc923ec3abfbc29a0602be50e2ec145edbe813b6e63a4729765c5cb59690ccf6303b80a56609567df49416cd071cae0567a231963cb50d212e9a1c9fc188183ffe482f37e5d79e58cc3cf21a29a4b8462c148f77475d1b406dffa56c42791b857c58cbc5a2a3ef8c66da1c9eb200d42c8e72cee95666da0f49771813648cef6bd3e128ec36dc05ab715f5b35234ea7db2ee3d90f27daacd12442777f923eafef9cbf1fc034e01479bd787b082485ef6b5542746d367f4cfee1de670ca6f3298e35370e213b54bd2d6519b4a85db943a6520d4f4c3b60031fee374e93d2e29558d11ee5e0ce243afee80d36c31ba9b2e92f59fd378e7b477c39eeb78a772bcf50077d665eaff9f3266c6e293e95b15f7f96824736c740f0cdfaff80331a8fe6a146d2984a679ebba4ee10e423b2cd682667850853955923d2366cb340352aa7d3d5764868fb9d29f6460cc51302c31c89c0b02684e49f029453574372b4093d31f6a3593da00128c75bdf7c6ef61a6b29c4326e5225dd8da4aa99c214ab9fbb5acd4729d841aae3c1beab27726c0c1be9822e5d313a03d5875fae84724775591e089f804fcced9355aec3b8bfea730c1472672213cb6c83db2d3c074553219b66660e86d19fdbb3b52c02c4b577771b0f77cf576cc7477e98df2faf02b04a72b6dc63b635d098e5bf5d2c242dab0ea5f9cdea89f5bfbdd7e200270fda99a9e82a44e51228d1e6ca0e9db1ea886b7ae0b9f9d48029b67ffc0bc9f957e0bdd84324861aa38ea30610cd909590610804acaade0f65cc2123144b6972bcca36553fbb4cb647622ac5b3832ae4752c05edbed4b4e2575caabd3629f83474a3dd2855542077110296529eeb6cb1d78fbe29955a8199a1dc4c181fe0a042e1f25701216b28fc019e673073d78cf459830a47e30ef8b91e92c60472deb24132cdc32c19f10526055c35524cd78cfe42f4bb9c82799e0e00dd2c0fd9957827779eafbe1bb34f8b7cafaf464f6852f5d75a3d886fba66532e66422367fd0f6350bb62ae85926197e77ae8489cbb0ad93b7dacc7647e8296a4c26407d541b45dfbaae4051cf140d379d739f5ef56a13fa8373f2e4c937fa8d2ef2f463385dff787e29a9319fe4fa000d1bbcbc2f440cec5285221c51b0edbaca262c493a847fdad87c5c595ac15851b092d5ad11a35126e07d19d038530b01ba9e4d2d6404b404472fdd355f49b1fd069d9f704c612e35e579375f0b562648fc4964af6f2064010fabebbbe4e6490d5f1ac39138ca97aefaba9f46783975b189a3e8d0d64f3b2acfea5062e8af328e1e2dc98cba22b560c27262666fd1dc3a68759bd3c302d74d458772501b05a80fd6329a7ad2dd9b7dca0d0dac37c61d0c496fc09ccad7f74cd59f01b24acd940abc3e8089c32d24e9b537b21d86340d181de07304017db332f36477dc3ee059d569f6bcda1c417f76eebe4e18dc3702845e25d0496d0d362eb37cb1e701cad8771382df2de67c5946ca308f9e41597cff236135766ce1f9905cae015f8815ff85c7717dc9af86bb33a5d3982196cf8e50d98c0da1e624efd827b855f84f4d98f66413de6f26c94e9c36f230b03631dada8b735020402ad803d57f1e4d64717e8d04e2338f49cb88ad53b4146023c060b8508a6343ca0df3fcd922942194c1fe48950023587767441c8b223c1e319d5d566e49c1e00938df61eba2d9e8b64fac2fecad02f3873e2be4c8ead2ba6ca905e2c298ec303a8ddfc5d0c521d566935cd578865919c16be6bf6528aff1079c80307ee45944f91b97ed7ed1f00a1dec0fc5432d1ba7c97778b38401575106fe6e1a3b100b6d47b4d7f7fe5f5ca623c5ffe7a86939ac4f5edaca2ff061497bc1d35d1065b5965c41e3bec519ff095f72cf9a9dae12a195ac9062eef429043f2224b914df061d31ac5971afdd73ee9cba9dd0c63948cd8821a03369013546efa36ac2ab2b09417507a1b7c167c39b0d6594e732585af42a647211daa3b8ed6399a34c5e9aec418adea84d6bbb98f25a8f7a30f7ff507d1183b7b394803b333f28af5fa491cca4201e0d063364853f28f7f0dd965165874cd8056112e8b7654a12055a3df03dfa0964d738fd0af0103f371d8e0b371d65e9fb719839cbcaabf1e86c0eb5e033f847f27b2fc087320857811bdf51eb92c68a7c3b2574d82ecb6053a1f0bb339677b1f8be0c6702fff3027d77539da8a837a6af386f64ac9fcfba49375762db0ae87f2f48a685ea7e99cecd250b8de942c157d8ba6091dc584a21b4f1bc126d7ff8fd709a8b59b719416ce9552ed6376610d6ae2ce37128950825ecd37234a7e8edbe50c4e2f1b5efb91cc83cbd58149a5620e1643b4e4378b78ca8d1ca2dd5138229a0b312642320a1b9d0cba0390ac48b1b7692d4e1bf11e6d61ecddb00254f3e5f786f9f92bb430403f314de7d28306f8f04a4034633d710232560a8e5321996c6a47269d509145025fefc6fe7f290b955d653c16501954d11cc7ec616bf41e6daf7bc15ae845522600f2ce923ad51417be4efe4cc22b31f3bba848b8d9d00e4fb09882055d73fb7ed6976911f0a893995b727c8c624fed85c2b7e267a69cbd73666171cb6b54543c5cf173e7e35feb70594e4625cf86159574997788ddab779b195399d49153becf0f76452cd051822e15e69dd7e2acfd6aabc6bc9ebc52e699fb4bd5f38616857434482eab64f4f46a11746ecc3f8f2276ab34e6638400bd337865913152d19a96b82e289bed3718e2c34e81f205675e69974a536ee88737d37c6529df532fdd2358ca31cae92b60159bfe8abd5d93294c2acbcb58679574bc32e5d32751b79e735cd4872a17ae127f129a3e34657402dd01d20bcb9041efd6654118ba0375007bd9ea624af6138112bfb2fb8fa6189b49881dff78116f222d1f3dd9527bcd4dd183a58414b5d3cd423d5e29294a3ef9915b157e5ce1eed5c07fc18de18b952d44a2ab3f8b26408df5dc5fb08cf76d528842197cb021ffdcd603bedadf1f672f75a993bd7e17ca20e53dd4116a23d4025c28a41b830ce23f23a75599521d0d4d14f03316ab71e27b11449ec0edf342973baeba174c3105a86eb8c2d0b30bd88f0f3f4f84748990d1d736b2114bf152d3b8edbff8c8fe2f9b339f05f096f90acbf6a4dcbc388e6c773360b13eb0e25661ab44674377cd1ba62f74bc95ca4256e93e3810a1262a72086910774d388d81318f01056331f9448e025f2dfb556d513a892bb9f75a23b9d9da06b96f9a255a086e5706152e7be9534e5310a84eee236108d84302a96efdc81eae81e12c00d5d30e06012bab2a8e42d9d6b78b075bb2c6d1658f5643a59098da22b858432c0ed235012a6dad71c832a53c5769726a99e635629db3ad551aa91165e2e1f9b1de9c2993a7c2c1814ccb6b41a9a7e40cffd3bbe9cd0e741f7366ade89271860a1fb1460e3ccadd805e60ac3339daa3c0a3a42f1a57ff5f245238b5b88915beacfebbd3915ed09c3eb0026cb08395e0076b3e6e8c24a77a44b07371b5bae11de0cf213177d4cca310fd394c5f345a587ac1ef91642192f3643ba0d943e3a12c57f8a7eeebb6492c824f892e21b2b5308b16bd6110fa3cdff0bdcdb626a9b21a2d85403830d2ece2a348bfa16cd432b6d99708db4867e3fdc601e96e462408073b23a0d9de6f8156b5e1c87d18170b4a5c62def5afc6877f38d73f41ae9ef64c4511f9a7fafc49f59affa0b335a6197e65ddad17add90ab07d032a34c577fdfd87a00814a2c0902ec8162565c365a46da49874b3ffac13d6f6f00a2c6e0ca49c28521430f36138f62e59fbe33f097e8c30f55133aa9232e16e1ab3aea5504872706ae5f5395fcfe76dcb7a3a61ffa32769c56c62649259390c7eddbd4ec91ee353b827ad35776ffbb7cd9a0220b86cf825ade31c20c73db76fb59a1c422966b049e333a824c5ef033e998e146509b60792e12b026485bf637ed856c7bfbc8f51d021b3dc5bb4c964beedbfa9ebdc6e5493ade3d0142103e669e2551ce51508844b34d291da4bc26019ee53912b79f6a5965607af2c4d562e9ffeef200ac6bcf16ba9608083e1149401578dee0c006442e67b4914b3ffaa58ff18603aa21d97e7bb95dabd689aa6918ce9efcab69b108383c035d6b062e98505f178f80a2008d0a032b477b6f9173bac28dcdbf211a249cfad24d104d8e086568fa64146f3d31a3ec4bc006edd2073a26df99d5a92003e628a925d508905efc15635b8e3f47e31d47a2de9a97f0eac9e20b93f8bbab7362fe1da470ceddb2e9677a62ddc4520912d5fdcdd5434136628b8675b7a18a89a542c5c484eba66e0353c32b2355b343c2664415838016a06230c2cabccb5f3d5beec9982ac34db61f82a7a89932545457922b768e986f862482b4873085b685eea6f98aed465319dcdf9666ecf7136b1e4d9a4f9031eda77d0e4f2b7856fa5de7fa06a21385d587fc81c4f2d34faf37adc162a63f1080a0896330ea13fd4dea39e8f8d818355ceeb68d57e516393707843b4d8f227466938b151a0ee2ad50274a7e0d2dc74a7655a08c2fedd0a7b4dae25367372aada1792c62a5ea434e7e19406d52b3677d5ad7c5c7a0042409a4bb8c64631caf94d5a72b5a306992c4be1a04147d4c458e47563d5288a9ff195e67e4a2174ac0bcfa6a8df2c8e8f381fc51e99f1449a3e1969e788cf4a5babc810ae632022dd8b4711563b0d653b092bca81de5fed4c414d807ceb4ae209a398b4e51454048f2f0ccd765923b5bc58561377e3b2a7ce61351cbafda5a55fe4db3c7d535565b1f0eddef0b8c7592e17b84ef870a9cc3f89dbb4873408b5542ad6b15393bb28f86c49072aaadd05dbc4fc84fd338b369801e1671f7d72ef24a3988a1c35e86ac07c64071913cef97511a289f59d5b797287e30741470b891362fcd676ecfead9d8918ae038e1015db8e8e7573559c6968eda49aa7fd631d464310c47a1993736b5eb1301748665e6e98727fed70a4b6407b702968aa70698ae0f56ea7ae0e5a80fabce4337c6193a1e33d285f24ce586353334458bfa08bebb4dd5ef5076e8e0ab10c99abd983d64250cba260c34444ee1357b8611c4938b9e90a82cd2e4513743d791d5964fd31c5a3cdb6cc9c0d3b2dd899ba4a878f13d5e8570182678641c0a73c3a0a7f40522f5fee606df3420ac9fb43dde73bb79232d98a2a87d1da3cdb95837d8833526ff734ba26ff7d3ee33d26c42f93a5e547f6142f33a26e6d81a520398af440a945774233eb3a1d6b6b8c4d7e17a0bc9b998b6418f80797b30828518ee38d7d6662f7059b393310cd094ea7b4c24b386c115f8e0b9473ee6187996151ad3717b751d82f4475eaa4d786677c18d031e2e22ae7bab063ce19a13424000a2f19b1b092f52e95415b5ecdc863685dae5d1dff0d9cdd265fea054b59c4d50b32dc709f4ee7be727a7ffa0ec478677501a1bab63460c2945e70c96e3e78ab0e696620294dd95bd11e6ba5f81a3c71520f28fa38351306c40251918130bb6c6c219df3428753d86b9322ac51b2d421ec30a6633b1dc58e57673172a50d45d14e52db7ca132a105b28a978d229d31c8b3078156ea9499ff018860915cd6575367b82e5ae61162d9b7b9dd8f77a1f935a10f506dfa12c882554504841ce0b5602e95dbd51230e97f4a60037c16cd6d5e60db7fa4dde746346e877ad3048533f2d58aa6224487a8653d4b793344d1b91b2dd1b5690012e4dc0e3aa0bcd4834564ea4a786fb7fea623c2b7ae4a6b77bee25a94546dd732a97bc0fc4db93a2c8aca28a8c56d5406747658b533e57baa3da592c63031340a946657bbb3cb1479af07ebe8477ea055276406f579cf0010532cb5380d2c34d55b2bb9139b4284c09f855dc0831dd1434818c365689c141ae6c3ba2e05f4050e440c5715bfd758bf320f55785321af89fbb6376acc09b68d52ebbd266f991119b244c1e1b3393aeb80e57e20218af0a6620c175cce212c7964ed1fae6e31d3b946ff93b0249799bbe5ad8de07398f1313a1c2adf76e0867a0966c44d9fc4ba9c6b9b0786f0557d82d837c010d569edde6a2fb96f0ef2fc8e6b79dea069408ad3fcca20d54f1f39faa88d06a3cfc3b6b9cc68401b24520dde8e52081d59375b40496d9cf5bdcc2bfcd899910293b5338bb974ead84559142b70a324c6e1843e702751c53ca48c063ec881b26f2d59bc7ce8c222f8004068ca789420929786ed631fcce8e014140e50e9bc9f9a8768047e8583d6d1e5a91e23f2171e6e35397a1edb70f176cc449b82e0fadf824a55b0fb2f580fcb8ae57e7807caa06bda81590a7abb52814b417d93ea2c4b17db6012bce82938299026c0cf6bfbe2c7948e46647f6058e724c7dd3fa6a34cc34957d1f9ee5e22bfa97a8954dfe5354643888554fb67fbd1d53266da904e46024706ed41d3295326b15833b33473b22da64516376c0a7400db309d361db206e125b2b04c23bd26e71342c130500e3bb9caf0a4f0411376268f77f93b9153abd0d656b784d3043913a71296cab80ce3e55023c9f3ac8e9bafe3e0504099482c6180bd7f1c438240388b1b86d5e0bdf975d32c11756664defcd4e5469ea3bbef400132c63ac3161d349c7611041f1dce16b224db40256455d0fdab437dcce210ce6778c11378a6f9c70ea7f49c1f6f35cdf37dd166b6f8d162baea25629f0fb2c4fd07946dcb046f8c1c53f125174d4cf5ca9ee5886937745d2691552dbdf5800f9381c31d90f4b342373811e9c9b27ac327e8701a1ca4d272aa500108bc25aeda45b0d878b691fd04ae599fc77ad8a395eb6eb2ca5d4ff8c3f1fe1a3bc80cdef8bac6edcac793a59b8b71d0bb5a19a65aa9ec3454cd1e20fe04120f54c20fb09a8a207bbb90e21a5b51ca8dae48f9cb5c69a478813f615f9b3f72962eaa01cc049c0b166978ee324123c388a29d52469b3be501d126d332accba27712b44e8697aaea2a7e21cf703445f2d2889e46f10a11f1e50791c8fec3fb34ef4038f418652df7dde183e23c9f7c5dfad0f6e18ec33d5eecec41624e6dbbde4d001b50bb5254fd62b621f8182df910b13418507415ff0e63ab97ad87d2967a79ee5b585ef5eed0633df744195d7a25130dcd755b44810789bc5b8076c94568a6485fe3b8b2ac22ee00aa18b5860498b24cdc5a0a0886ba702ef74e2cb762c80d4159ac61a23efad1d247cd8b75a258943ab9ed381bd1c465a79c120bf1179445e24ab860120ef431d4a91d0e3b9c352088b1ed538463199309afbc20db84b090bde3b9f9086607c5c415131b3e1f84156e7cbe66fe473e9a1fcff46c11e5443933f1d6f5b250a7e4967b47f7f42a7621fd502be2bd069748bd266a221e954e8c260d3e0b891002ffff5ed048ec9191dcb10a599305e0b77ee8f52198020245c53dc95bc67883362bdd01ba3ecceaa40cd897c6bc9dd325381866047f4f330872b561bd1b9d5f6737e4be324c10d910466f83083112e967f2c882f78af82f9e48ebb9358933353c569c43ffa6af4ce668c9af94a984d56f86e15bfd38e342a122663ac88f6b2ebb45307db83933f473a21f3a571b8ddfd02733cad4fe65615d6ecfcb97d9a60953607e85ea66068025a8604ad099264760a511fcc0dd62409dcb6921fc18b2c76f9df54a1adfc3bb91f0683651cc75b7a73bb42c9e80b14165df4d550309a79e3c7e04090500dd49632523dece17969cf6796a597e4bcd64ac502ed3360a04a4235ebd7b8210a4a2ef4f0076fbcbebce24706cb65afeb5ddba0e82b1a7048a2290034232efbbcfc5bc384e39119904c250f48c3370c26c96267bdd4247ea42d4a30d7695fef18e05893f6b3333e4f25421835e7b1fe32a08ef3ef4ef1b8480a2eed0587b02b67e99355be2cdb6111696edef3866c8830ef3943c9da856e244ec154a620d3284dd9fb8afcf7b767b0c9b8faaa2d3ffae37c54e2626e56705d2ba319736ac8f4579f6788857a41be0b1451aee07411dbe19fe0dbb73d51f7e73540d41f68af296cf60f3593c800a805208cb2da2c90eed91063e5f659234a5f1a0c393497b9ebe3b4b5a1300745a2a8def99082f0ae86a010aebc76a74fd011206dacee58b952ab0fdc4534a925d4e755aef940c7a41faa28b335a4be20883430455e0897700efd983823d53dea84db29ea90626ef2c20fb3a93d172998c39354d6d81f7575bfd4747ef01102ea988fb79e4bf79a64207d8d6c660221bc1251a50f0a3248e8b72965123729dec1c19c160d841ceef621e4f79e2eda3913c72a45044f715e9e14cc2e806184baa11cf45ab6c0116c75aea0fff540190e97195924e1741b4c0bbba322257b9304cc990de6a1f8b122df44c87a13f6b4c7d710bdf747dbe5e688f9ebed9fe6265729122ef933e91a99f254b1e50c07b7a4c43f5730c75551e67def39cdafeffe8dfb513399a57c544493219174da6804862d40183ff1e2f12e206a4092506323d74d4f2a7d8fcc975718ec08a855667b641f56acf08d3cef6b9b88242a61493cfc5e2f2613b024baa4f9a4698f22ff404c63685cf890e1ac335c5455f0bc671aaeeb76b73a5823e91b3d47f307159cd4bf3e5ff88ef8535bdc75b70e0e1c5fbe6e0962691da43316bab60171ab865638fe882139c85efaf12aa900358be4b56fc4c68f265c5a360c6cbb380ca58afa6875af01e061fdaa5872f73217a50a47426ddd079f0299b823f0bf0c770666576fa8f827a76ca03b10106bc2df3a3a3f6dad4156725bff1ee688d074ca14465b1d960c1c5acc038ee4bbf8dd027f25c71f93e2f59109057bbd615e12a46cd604090afa6f4b83f62a1e5bb767548a631d1e7acc46618322013497af76a20afc3ad15f95ac293deabbc5adb8ea6f1e2858aff7333c3d6faf229ffb1e95618b25429e62bc699cf0861e6a3504c80b74888a42d47d1ada5dd3931bf4326b213577f1e50f3812d218aaef72820262c391f4e7d357a88fdb3510a73ea57bca5f03c408ab947a3eff204807df31ec3bd5bf70615cae9eb60021c84f84a6386edccc501ab95fe9f12efd3c4fadff5a095f4b2f3c91dc3dc7647a64ab1ea9f5af51f16ea674d7dc9ed9bbc69cd851712b9d6abd1803a8cf337e9913bf12a4104519c4d44e84012d9b548217f452fda83da3aeeca53c1e8d48631ff7423527da339c668d2b9d9c111ccb41c6d08dd9f723343a1c89018d46eec97dd0140335799f97ac36986c44c96a05c7eb49c0e984b180fb36f9f79d927c697a9368effd5c79af3b96372aa09e31178f023e000bf19664042c33077ae7a8f09a7e1d55481aba68cd54ee1f33b78448a50ed6501b019d0398e11de2a9add9e706caf2d87f75a1962ee11fee80c1c3bf80c46ef2bda538ef5b1e5ea2edf7ee08535ec6f71b4ac534c743a2c891b9ed98c5a8430cb2617bcd260799c96853618c9360a9901aaabf6b322ca73904e1a625b8f6453093db653b4a0e2d909703e707a73469d54c87349e37fba383d7f85aefd40a6bac9299a8b6ee8ddefc6763499e381bc41f155d906e10055caa69fc148978ec51785feb76bcaf45a7506d8f2c3d93a56287ab217a44308b38d6056c3a93548a978516dd7df57a876544d236225667b9e96734efae1e5bc1a3e88205570799e636c6c28be7b37303529d0061cb1833bb37a1eb453458c61066fe9bfe965fd2141b2abd580aad36b21545ca5d14ea790c8e7833941364bf277990caaab3e48d2ba8e61ea68c75365bdbd953f850d4b3b945899fa76a53fd870159b3d7f4370499f38e1e75ce95a866e5e28da6d9ff087c68ba3ee16112e149e3cedccb9abfd4bf0af4b1b1305a5576f8f6e7f9d6447a0a46c8e51b43afe523efeb6b698d5359f47e378cdf115876e1f599a0640eadc6761fd9a3d698152a5b29b307f762f238ac4884f950f2b95ae2666efdaefa3a9993385109412f413c416eebe5d1148aeda0923f2f3c13d918b11b02a639facd1b3d29d94364acd8dc940719122ff6530790d4dac5c8f4ba381c5e8a4fa284e26298d0160401794d8d0f98db320911910f0859c6944035761bfc11372229cc4dbe324767f6b7186f9cd37c5feaf344693a54f59c11647695764e4eb3781f8972d9b8561f0f9213fa76a649a5084c7e8a2881f6bfa77874188939a9eb77073620a21222ba6badab6fc9b62d7f8808cc512e742bcc3669c3fdea4d07a4994a5f372eff6cf401e44c3b3f647e5634be75f4031da206ab0a40de186cfc1e18ffad233ef580ee17309c0ce344a5b7e870e6c280c36360e0655d79c6495097e2e16141292677ad6f17720bf325ae522b368f7fcb2121c008b11f6bec1c268e41390e3707b7eca9217c6c0a742dce69a9f58db424bf82b7a830a41a90ec29e12419685941bb931f3db1ee37a54a0ebeeecea0680819ab034dcc19da13de361f3cfcd57648da975aab0309890c7eb6df07137a2c3577e5bc75770cc0b81206323bc908732817b9843ab73bbf9b727efe84da5812a03139d836a9a41904118754023feb677d9c4f916b121420472081f8314c4706f3f2f316de65cb8fb3d9a7d912259bf7b61ce0415b570b94369898f7ad77266b2d7b31bc98c316ddb37c4a2bb0fd234b40038ab7d62fe8f383ddcdc0454cbca8fc6cbb3995d1e2ba4d59fe84538ff24d1484b43d421e3e760841402c63271c6534a4de8462f33a4150c01afb12b596d266d7d4968af93baaee277e7e60ed1e9ea95af902950102b9029039776cf53d3b3218005f00ca98f595fde5edeb345102c69ffee0915aa0ae7e3c0283918bbfd922705dc24792c73f935b316dcf92ab8424977495b7474ebb15a57ae2b0d7028f77ee4bf6d3ccd70186caa038ef3e80f14b9248915c833c128f597deda415cc96cda26ae4ab3d2d38e321562ea41cce0d0bb884246d14d9acd74b7c09c7479cbc9016924c8493868e9c454e8f8ea6725cf378bae5e5844939d95bdeab34591a3067a73dbc470ab5d65890374f5614a3a264d91b95c4bad6ccc9fd7a0c35faa8df5b768a2bf3a742dd3c290569393d41de7a2bac4b1639ae92d3083e78e2cf20272dae97f1a342ccc43d147bb8320906ede1854260fc84e328ff194cdc4e85517896c781d98afae9e221a85359fcd32bfd5fd97b5f1306d6ed33444b8f74c7c45a635670239fec0a3999c8458b8c6bc6aef128f0899c821881290f0515cbcca610588c1271e2455509eed6ec97b6880edcd0144e5d514c341092226f0df334804a127408a8ce5079647a96c43ded9a29d57ed69a772601246f24a68ca1f553a418c9a613ff3476f5b358a7bb5edc5ed5df865ca72e550369086c5a54ab87a1d615d57fbac46213c8acf18e6ec761d2b2f433f5d947d244c2955cd5190b723f4c0f9cdf7249551b8d8a5eda2bb6c5bbda4818c38646f1b2170ba7395ede41c1579d4f1aa3b7c03964cad3a4ff532aeab4bf53282ac8d21cb1659c1df674925facdc2f73ff959254e6ca8a25bb7b2d3e36ce416720c6fb990291e5c9bcd88e98f91fcf2772ca1c5bebc1ba81e37389fa2d823509d7aded95f165046cc137a615e4a55a90d9914469ab9fbdec7394c84012c5395ec6572f54b4da2557736a9627c52e6ba1d5864b3de2af524e7645e15721aeaa03016efb925306ff88c37b176e5eeba7232b1b8778b03a6db9f91eb50202b91eb093724ea3c06a3e881e28c1495253517c1aacac316e110f3adc5f8c2dfb814b5a12d8b30c6aaecb472296e882d2998fa766333350dc6d0d79e0e616555f6fee3b56cdd2c59f82a50af8e908e16c37aee7370adce9e951d060f4a462130f198531ee693dc61af8735d5c34b5c9923d4824f3024685f1883707eadcc6c37c6fc1d528205b9bda385b738cb04c8e902fc2482be8bcae47449ec9f1627f19b3850ffa978c8d89a4b4975cca875cbe251a65a52073affb54a525c9cb287f7cc2c66b732c140ca7e8362e0095088643852f9614b7cb7934ba371cad29f087a40e5be9a13f1f14809b6f5d8b21d640fd99535a81368da991c530fae8202fd89be96d0c23ca7983ee40247e85b8ef58254fe5db83555cc4cbd71027b4ad87c04d2c561d4de15bf07516476a9da39d9653f514fe362092229be05fb06909629a92cb9e5b0ec544b4702f11f5419b2174e244afa808884b98c764de1b2e40dc72b9b7b59cac903e20c1d9b7120b55342240c420b145de181784885c7643b9984dfa1f23edd7fcd8601327dbcbf41d8f28bec4223ae82db38a3ecc28672d73007a1ecd166a6e414bd11d371ef3674bf80df62d76e4db40f50780b29668067221d0c54dec108138ee002445c988d35af7926c8dd2ceb0562b01fa4543628bfbf2a316c11b9c6f7a734d4aafcfe76f877b181d1ded4f4764a0a9ecf6556561aa418a6ff70977c70121d8cbd02601f06646bb14aa7e6eaf7e6194d49f0c9ed6d060dba134033e247fc5e9cdaee4d96d1be5c6cc48be32c3a71bda55b14ae63ea7d9d997b135b31d364b4794aa6fc0b02b90408838306cf4db4d2db7c375d5828c1a4c4f6295ab9e18864480e308a9b0e74b316aeefd12a64e2e82171d4c688cfd91fff83389d70e69633936a78182c63d492c41bf1ed8bcea98d01b06e53d3dc0bbadb1b2b7f063c605bcc9ddd71bb78374a8e145b327249c2ffeb63e0427cb20922011dfbb33ac972f9c8a293fe740f4e5dbb69e4cef6fc1ad1825e4707eaad3d7c981466ff477de614827c3e58cd9f4a011d0550dc7724cd432c3c62b24e72f670867994b81c41d24742f33fab6d9d67eb73046202d16f99f98f2179ab9f14ba32b6674b2bc01d1eaf263a7d712ba7055fb0b1ec3412a87143d2dec6d9a9876202c01e73bb706edebcec4862cc4926530ab48a923a863fd611923098d86fd3cbd2dffff69e8dc30f8bc061c534cbfed2613cde0515dce3c31f9ac8c50460dce52097f767f1cd2e2c06eaf2877b7c88aa3b8df6d5a442282431d1b463add7c34e9aa751fa3c7b71f79468f2037c85a82b72fe12323d60da9eed286da4df6994b2989ebbfd9fee2a68e757e010c9d7f5494c9e865c71aa08f99cf9c730d49cb32ed5949e869abe19d47cc0a885fc4ffa7139c2a055f13b94fac678dc37fa674c5c7d6c54be3a0a7af311d5d4581b3c26c8ae8cef55d10e18cff78c2638e6ddeee273545917647d5ea320b9279b03a8c2856d134ac1b5a7b300cf6affd245f9f43bcb8e5ec4ac0b677f029aa4a3ce0ab582085b4bdc890d57d0ead0f2675114dea07a567e7264bb782ec636c283e03738576d7e82aa0133c53ab49149c4cf14907ee6844ec93ed877c011bfe93e4e186aeb618466a6c297d544d4910134f1d6717b639c310a5e4a934d3bdbcc0e8d4c84879033f4bd7f73711ec1a73d23fb92799bad70de715c29da0fb433b6f7bae5543cc93a2c1d06cfb620438b354c1137b47b001d0b366439e009055f689682ca43fcfa34b51091ca5d7f8d03b0e083fca3fa8507b84793d17a254cf2d9f009c97438f04d5583b2400976df6b2426bfd00e9a1647417d267955941d20793ba10247fc458cc02856f1868ba6df63a15b819db822ed590fe06139ffda9eec05dba86f2e533e2cf0b8f1f2314642d345ada4cedb90be0bddd10e88ab1ac0a4e64b7149204e791268939cde914e9123d12444af51d4fb064001f369403a90e885fcd10b882e56e36d637aaffa88f7c41b77e97c765ca7af60ce131b9796c8c7486d34d1b911e7359199b9b95ffddfb87afa44e3820e364c7307c878d62800c2b6b4788279e949b0ea6780ab838448cb617c5608d5d1f3ece66cccb4bc2cc33e506abbd480fb7b7a06ad60b663298c03814eb38a799ad4f630b67e08f4e310a4604d9c4384a724fee80097486c80bd01788374ced0ab8423f1a2389626413729e4e07ccf82f363b347657939752faf4e3f0778d721c86f2825f741410c30a4ee09cf7da3eae8b645586470a171e3a8f641b2caea2304640312818bf50e04df73951b6dba3de92aaf5c005032b972a50d31b9862723f7e58841f651a1236a463a8ff2dcd80072cecbdd63b5473de5b6f45139091389545327834b1a667d87caa9a7064d3e4fdbe280b7438d734d96654b178376271aa83ca1b1502885d89984a8d09095df672d385cdbee84cfe5a68c54617ac3b54397f70d6ac06378d71f5014685022c508cb34b567c01358a22a0539fc5dbefda2445609aef6d9bfeefce085dfebb43c44d70daca15caa3b44431c7eaf8a99354d9081bad5e5544e3528fb81ee8a304195f2932d6d81585c2eebb9dae03b2a2819d9e0d8a2065110836364a987a358421e99dc02f22a4ec6503fbacc58778d45c2964bf456f7ec5c1c876343b3cf15e5e3bc2889928c788a914ef447ecb336fce5589f2548df6d5f3ba55b90370752a05664075f923bbeeb516f09ea8a24de19f0b80d9f98ab096e9890d6a16a846696d40157cc34bc99b526b045d38404219ed2cbfc30391867131f4551b1c7901fa7e15b7263c259809fd700634b71e500d904a86584693e9e7b34222ba2a735cf37045f752fdb5a5e7b23cf71ea1e75fd575ecae1baaf283752a6825bbb599d89a2368f3119808f04f271220a6afd79fbb3bd03cbf466a49c87e991e2790e31b9be5beb67b84e1e102e339073d9842febdbaf16fa5cbd3f9c311e6b751e22832fddec52b066652646627389a2f54c24e550e336194b80551356f63e6c8a8cd8de8c39f2258d8cd0008efff5a17c6ccecab85bfe3f390732e675377c65c383a41f27eccfed69fd950157662db5178f03f3f5dcf637b4c16e2cba1469d8568959f463fc8c7745c4c15638897d3cc30dba1a9d02caed786b305b28392d57fe6044819b0ccf28ed262b9178b770bd16a78787402ee6f69898d76b4a70b5008423259c2b3a56d3155c211d03874be4f4c6c9fe09c449e8fa23082d16d92e929c6e2f98cdc4f74c289068a7bb9056d75bc486c5855b2b89044d8916b6d045bcf093a1f2082d9dea03576f8747ab6cadb9ce0b457d49dd75096b8a4789b02650980e87a84abbd302ac0423befdf41b71336348d6dac67edbc64995638492bb135eb4f77670519406e2d3e4cb05e1f285f99add7938b0179d59f80f4c43679b6abe2af058432236397fb129318f7ef5661b6e2c41c692d82a9c2caeeafd7d7c3fc6f8dc22582135ebd155ac442d22e974c30a61050c0c0caaebb8189f88a4946c77034d5410e02adaa44f855de07399e8ba2f07044e14e2b5b21f5a42a2e198fdf26d2bfa9b6c8347c1ed7404e9645a0ee65bd790e321a8c15aa06c5bb6074133a2c8c544465b82b73869ec1ee08b694469457da9d1eb4c3dfb2f8d5bd0a772ceb1d77180a5ee445a2143e0d80406097bb8c775bb890386c482ca825d6e2d625c33d182d5eb0352189137996e8d4c87a6778659de7a1938203983fb875149b590fb65cb3d6a66ad2818c7f1113d8e38336d57417c3a60a2aec2f00763aa9111a1cb3d7a02f6d86c32f37eb3faa325162946912ffe613eff0833bc9432f488454cae8adcd46b063423f5292e552373e88c3d377d853631b799453b589e806d2b18b151c2a0bdce265cb18432243fae77c2b39032c37711c9b8e05b27e8b310db6922b0ca396843b240d9c012c5b24593980335d50eb389210f2116c7ac9eba8e75427cd5511ec237ae35af6daa150184eeafbc671bfa0bd2ccc4628b72b7e12254a4e112268f8bc710fa806cac8ecc6e115dbc070b3a562baa709f64ec8c9040e9b56dc955f23e876dbedaccf6d8f0c3e8983316f0ba1ccc71dcc2e9077f4324db9020565af85cefab73b1fff43e785cf66a66b6b3d71c69800653fc24df866f5a886ab9190a513fbf57b3ed5b10ce1b66957beb11d374d9ebee8255f14a2db593c0431700a552dbb1bfaafbcefba7749bc3c15166296145ddda5c8c35c513db0f8ab8cfc766663d48ea5e9b51177521d0680889b5147e9988e45f7d62c7c06cc3dc4cf3fde1fb687af9c9d96d4abb02076cfe6709bfd97cfe9e7da22c73e84ed8ccf41bad4dd18e0f388a4221fe8d4081ad168fbbdc9e50a1b5afe68dec4dd5a799983a0b7282a4d99c2574e027fd783b8622e1bae89098567e30aaf1697975fc329234db0c400d82b32e725deadaa2776fbb22a125eeb09bc43f92f59338e9dac791a71c6488beeba12f56e7284fdd27f7261a02f32315c51fea66ed3e029bd47aa650b3e0e4f06cac5a93a7253f41f68c3014c7b58e4b37bbd3188f5b5fe798d0f9e9b33b339367c686f83c1c7d1cf028dec1df3c6e869413bdc107f728d92457fcc04bc10afc7a65e5a7bd15303db4187c3fe1e56f219726027581d4b4064fffec78bd9701b068f87d75d864103473ecb600bb47f8d0a32de31df62150b8cbdd04520e19bdaa03f321175b766c67cd90e9f3d3e68d227d16a89e9081f7a0f63e565a2c5fe7cbc748344552e6388567d9c2d15577532c2d9dbe281638e7447f58ef4306356214b81d1b79b03d40862e59393a34754e9ab8095721777c44e9bcdb356aafde85e51b787fb29eb0cecac0b555bdabae6597f3f52507076eafe4331734900d7b924aea648dcae5232ea803135c90b28a7e2f3db2d0221c28196f4d59c6b537d8fc968a6639d0401bf0838281998f7a7412a1ba26530ea13a771db58cdb9a4b6e0994156cca44c21b51985f6d7727b6315338e71803bbff7330352150efc89c79b5c724201e09accf028c495c9937b49c63561c42c4dc82f24270d72834d4c2bba40a4d80097b268892bbb503c33c255ec68a3d850cc2f090fa22c456cf75a2f6b5130e89a079340e1b3e72030bf45fd9d29f42cedb3c7b5fd231d11d2521544454e1cbc5c9d3d70358fe61840e1a78bb502cb944234cafcdfca4ceb1ad29cb5eaf86ff4733206806ac5d76d445d435176aa71a4a4f8c130762492906a739303ba48226ad91511b2519b9b1c17ca9011c21f309d49aee17c431212f29986d51452610da5d79987177cdd2676e46fedb35084657ab982cc34e8870a35730ea4aba15efbd5d3303472205a1c5e628fd5f2b09da2466849cb9c0891a5e44f9464d4db9f7e4ff1b3e53a0f05584a2489a6b567f4077fae8f2bb58e1c689bd7c9eb4d7a3262b6425a1818ffdc59e839539c08564ec57d3025e9839f14a22b6a569b53c56f7e544064543d156f9302e679a9844f9bc43e78b5013b73add5abd325a51a8e61d0318a52bc828471b05c6dacf3e5e827beef2491af405d89c9493068e9fda8bc4d5ea1a7dcfe93134f0949f019aa209478c16317eee19557ae7b3965ad1f5c94e9206f85095f0c898bfe3dc048cbb7d13845b97de2e6ee02e8204ee7488b3616bf75db5a33e9fd6011b51488597278f6ea9d0890bb02ddb36340007b2a2efe9d4656ff27db95c6756166efffb5f3fd9eb1fdc20ecfb9643a7c4f484a5bca6ca390f9914091bb81235dcaee64709326e36529c4c4a5505a0826fa10829d0857ebbc159fd3fbff1ce1ca02ac4b1e033a24129e0911f7a1da61ab03b283cd858dca8616a98784882292e17f1eef78a5524b4787318ceada38d45b0ba7818e5b8e847f88a7eb3174853979e617e7b19bf660206416f1fa39e9f5bd7a8b54e9566efc2dd46da2ad8e84cdbefa8436d32b042c13c6ee06c87bd8b08f5ff4869ac0223c2561e5d678af43ba4536816c67f258ed22e38c41dea18ee94f9f438450b053c3e1718eebe616e5cdf9b2d26222f68cde597264c7cc718350108bde13d43bca4423c46423ec21c23bc61ea8f3f8cae4919221d05efd931d385adf01809cf7740e719281b2e1f6c3dc9574052e70aa082d08274bca0e1453760804f4c2840d49e6ea18606f4817d85cddfa32b02f9685425fd0d6ed2f55ab7cbbedee5cef1841639d7485bfcac98b330cbf5da63b7046cbca2ce1313673d8657754c126d92abf0670cf21f6d7817baa2c09edd51eb1f0c6b74cb63ecc01b8caa492ef428ae8444f1080ea5fb7e6c12d10a664984f825c56e4de8e3b55682bd6ce2ac4a4bc635e569de5a02f011682b194673aff05f2976cc3df2d0b9127234c7cd4e95f6371efdaf0aa80daab7537de45725b21a3f26af84ea43f92cb717d47889f1b80631a91e9aa0fd5440e19a043f198bf321ed2b772610ad04d2affd33c453b62ac1d3d8ec59b2ec4d0cb7ec47283addaf5c2b7b1cf520b38eca9275b10c358ec294c984c106c7cb5ac895d7d951b49c10ba83cb3566782998ccc7f023d60adc7acb8c0aa74a881461db0b9d5e6e9921603713a607649c8c16eeba504a397a674914d207dd0b698bdb5a850ef1566819f9ae486a22feee07896e246f75b5595d9df84551d306eb9fdf99d1b818efbb786983fb1f158d99d030a4bb1aa78cb2f458b9698f7149c6036c987ec9a52405dded301ad4d47a15dd5e10dc7397f4fbcd634fa4aa47d4114e98d62241a303abf2b32401c54eec3be6811354fd56e76062591037377e52111fe7cf616e0286b2874ff1cebbb2e4545029d5864ae88045b00c1da596180ac22e985181e7c96605e00e32e5ef2d235e071f9bad2ac5e4dbbc6770960927e3b9bbae5fc8e4ee8736c13efe13d778d72b42234a0dead32e738cba70162eaec51d2d991322384a767d5ac3173e6585d555cd632c8c936a665a3585a0607790ce8940d4b6c680d7d25f144ed0461cd4ca92425b176a80c6efc25753b1b7d08169f9d887e7b2437339a9017490ac14903848932bee81ddee340f7d052a7426cdc421b0cc787a396e3bc11e81dd4aee447c1de09031e3526861568879bf25dad202288dc3608827aa2846e6248f4429ddd07223f4e6d5b5c9920ddd56834f6cbad24ec80e9f2514a46df392a2fc9c4e0139b9dd0a9c3ce5370427c7ec15eca3b4206f25e93d0cf85052cfc6961a3d1d8ac12dfb2bd6e876094f1a567074e6b8b62e9e39769a4a16b5b73bb0a386981f3cb2e9562c5a1287f7f1651e4ef4f8d3669e17ff5d73f835bfd91d01c14a533feaabb241a011a91d16c040c9c4acb734e44e24ff952e13e1d99791c46559b6639ebcac50485054609a682da3600edeb9e05743e31bfa037affe93173ad7c287518c25b5cc4cd2378ea42009b9cce6fbe8a4546fa1d1edf90145657f63f28391775710d366151cc6f900d92ddfacc7bd60f9839365c0372e5624bc370912b4d04cd696e00c627783de80a70e6baab3803cbb3002d715ba68086f8301daf3a312c0881e203be8fcbd2f71abc1468db0cb1af63517ce423a06ed65258b630102b1ab65af2c72aae6b4934dc3000c5cbd140f0089659edd4e0bfaa8a0d61abde293b55b88122844221e256a5115ff816e7e1b9c0ba3da6d1bfbbbb0053ef5e39158a711afb89f9561e73a480db3ac6bf59a7be2971fe468bd1f8aa9f631dd6443b67e3d105d013eb055f95fcca06e6f445218ae12b32e4a3e557a97a1aa2d27f03a5af3152d0ace886c62dcbb59c1bd13750e81c75b2ad5a2187902a07bab37170a1b7ff9ae09c87f414c386df74f020f2d6139fbef21efdfc268be2fdcb0fc06dab018a511f391da7d2e311b1e770d2ff49d5ecc25e065c4a25cfcd9f633b02760c7533be5290f1cc0d0432758a8d3f8fdbb161865b02e31346971d637cdca34f00377d43bada3065785ca053df39b0e143c3822f8e0acbd56045e6e26a7006dcf4704e64e50ca2794fd45c17a806b03bfde1282100df0941fb7b30e3e9590499ced543b588234831948fa7af7caaa61d9357535394f731b5692f1477256c7df6496215a765e99494f3f37db7d6259c9c6840e5381dd3c37401d5da23b17763e62d7e4012afe22d9b969b9c1c95e158a3d086cd0e15fbada8946a6301c3693c1584df6364ed75276546ed060a0fa557d1e10d821864e30c4fd8d2836b6ee0ca1a33db569dca0a0ce8dd8999bb4c8410cf073e2acc32ca79c712b25651f64963fe5aafcfbe4b8dd7294eb25a0dd3d8674239788f8d10c28bae7a2776a2f45cf8956d337173e1ea29bb93294189a8f2d85c4972c2a452961fd0a8287e2b784445a025fb2c5ef8043e83f07c05798d50f4d54f09a33a7c9b14f464a3b994941779d00c1a873c5d534a5b0f85620af123c24cedfcf035c86e0b6853884b6af81bd15c00a0c10be22ff23c7df9acda8c34fbbc7180b7457a8acf68442199132a02114311e254fa0bb99103f3bea0e767556138890d8a75d88d06329fa2ed244f1f16ad47f522f3d7a3113937123c592d8d986c9d10981344d80d6c1ed820b1676a1ee88dd418febd551446cc38930cc824af2e5784b35f23b928fd0bcf67bd2aac9ab40e345e38c03c4d96f84b2ede9f8af69e8ac499c5a91e06d803207627814d7a9a04fa04525e5782928c280f1953cf143662f6f56b3851aaee69fc989c63ac02d34565a6cc92eb90a7e4f09ffbb9a615651ef6fbcfd427a7aa45f90f6db252b4f232003cbd416191e2074845b3f65fdce8ecf26256f94f8c6805711b89faae204854083f8107256418d97238af775c9af188a2f005f3d3ea556c813af9cb66836a75ec97cd2f8275c2cbe84b84032250370c287588c1c9ccf5af30359e787faff8f874ab9043fecd6ab8679c21faea4e41c916cfc73d32f2a8d9e968bf32a2a7049051f54c0b9293d5395cb0e40affb9e9d8f3db9972d25262899a58153497424b10759194b287c8a652b1cb0a9ff2b9ce65472d86c4f68af21dc126d8cbf891c96df0b7c70d37c626ed0463cdceb804206e93e6212caa3983972f5cc96aa31ea861ffee2a0acd8b91499d296aef0af50c1fe22205117241297cac1d0e3cb993364616d1196607ba50955f7da95322f83e32f3319281ac5b4005fc0cbe909a37c99e9aba77bee2626d3e97cc892b41d3cd0dc35350790cb776a7fd5b9b51ed1a066482afdd737e79258117a328f25d37e3d5eaf523d0cf5fed38de1294a41e51c831216210dd118d2c81feebb6b828b6622bb4a612b20070129ddf65bf26c4c884b1be7572072e04f7a31f30e3c804bb50ea2ad04740bd5fe0050a1ac2d5d37a0ba6dafa9d575769c91aac98f5be77568e203c9c299898abdd94e484a0e83b48c000ddc2426325bd71bfbb7bd7f98fad61d381bb30bd13f24d95f0b099d39a785690afda195b5118ad2d0cc206ea19b746fcf5060cd4a83e66bdf18db1429f3ce9e929b8ba9ddf0cd27fd52a61b31763cac74c990643b469f2007050771df7317e647e4b72cb753c5512ab45e439e9ece72b150ee36c0c560d02818303440b56aaaad04c49382e22fb8d6484505b678aa5bc582c8bac868c4c0391d5d47b1e9d80c0c3f9123a660e2044e24ecab6834dae65d53e9c516deec92ec15cf0187013e86290525d303d5eac79aab7a088b6a077ca95900c2a19a9fd1794cc82f55f4bf2076b769a62221de0901e8927a136d4950a534bed03f292a257f0a09cbc1d5cfbe59279c90655bea536d0f5f0bbfc67aa0a00f49c0ac3d8d83594684c7c870891a44c9998684450fef8913563a3b5b2ab53a0bf57e9f1b0c6b7e12a30f9b783230e2cf2886e5ae1ab85db0ba769f027a3985c9c6d2b9accb57783f3d31a19c9dd9d65b5721306ccab7b909204b045a90e366d80560cdd02635a4a27342585b7d9a2ad0ce192a327985b143567b9ab5ad1b1037131e12953a4b05d628b0cfa733315d6e2ea5deb342baf463ad93b954ac1b685f16fd2d91203a86651354c6b5d0bf85b127c89fb3acdadefa2db93eb2715d6d97d5128d7267fd242242e1f82c20c9485ce2c09b48c4917360162926ea7e3f77a07996a7e07fa4904d283df600b1b5afdeeaa0971f4bfcb56230d4a3fe56f090c6c0847e2b821eb1b4a852c3f759b4487e1aaa08719183f23c3aa5075e926552115155c5ba101d81270b57a7b6d3b5f4a4c0590da5a02a44303866061bb4eda0ef6a8e73d32d34e2734517eb6e1d57d09c9a9c2b7d8f240a9567817a96bc1a4946322ba26cc659f45f883ff5b736db99d85336117c636ebb55aea7b7f8db7b39ced7ca0b5616b62ea32d1479e1920487d094a25990ced55f89b749971781df09bc7165df7e48b7faa1f06b53869809b7bb6912e188d3f253ea15c552fcb3b853e583c8912a36bea918f668796344d839e61550ecad071964256984ffb956e5c7adc4cea2100df75e00307b006e7303c63da2a49e0e150d1673632a332330ae3662bfaf85ddc94199f6954278ff5788180fb84d053efe20515d9828f5d0cccece1a6e492eef7cf30a735c0600d8bd309e6e49da3bf238fd7cdf503bc0e9a01cedbfd414e77b68a4cb355c58965df269f746bac012f9e8b9ff3184212739ba749aa3c2dc566987a87db248f397974dd2151de2bfe805d967c21b7520c696751a8a9afdc0048f5a545c1bbec2109fd71e89812e47384a796ad40bb9276d56136b91bb373f53f818707327bc11550e134e799c6911a438bfa056e2941b7c98c8f3252de80a509a9c9184ec59a759155f59f3a434068a7b1cf67883f19e4bad266bb8c00ea894d2508472d3916ce59015e940e91986f0ffa803ed6e7e8eea72df17de6a06f27e5003a848f5005dc7e7cc4a4b5c22fd0869959702a279a50701331670e063b575c21097533ad94ab21da032fde31e48d5490746892d9fbbefac0372f462608dc06aab43050eb3196290433e74e849510777491a3604d46d79b83094b1f03f14869a058dd4a6ded31fa834c6e53d13802be275ebadb1934c1e184bcc4789a57b40aa5567b0b743e2a4fb1ed1bebf9008ac34ff843ed2b018ca24c8b61c7eb8f1a58ab8f5f902960103b90291392b481f148d8be26d16ba404b217d1879461d856a795afea7bd5b05c26d942017eea10dcb4bc3c3b55bd05c9db989d69d764c13b1defee99b04a7b2eba9f312e5f2fa7ae7153d2affcfe8cb4ceaaa6c5304c1c5640ad597723f53c54b6cb1d8e09fda06a270a1f933d0cec9b1ac2c78a2a94c959134158b62985e65afed3795abd24e84ca5921da9af824a4c6e28ae30bf1b9a4df558081c2664dcad4d4ce238a1e08c3e2129892cefe37555676876febf815b310c9c84a7622e3a83c848566c3fdd5edff9733f097988654a22079a26968a117e46959412ce656a294a0794cf422008e6731776a0eb1043756532be03dad6d7c691aaac08ddf374e3a3b419e96ec1d17c5716b78fd4d83cdd58994271c8ff46726c732fa68c855297981ffb1bdcf9ef58a9921e9cce52face4632cbe158f33498282cf5fe6d23d76f5dabfe937ca2199eeabd8181659fbe548db0eab1894382f0376cbbc79317e51e4779464da377838a3f13475f7efa5dbe99239953facc3cce3f8b1f1fc81b043938852548e6884cd6620aac62290c61cca336cc1f4dfec0bee83a79a21b6eae712874f13a5519095a273b60859dcd8d8cab90a38738665c8c94e6bfb09e7429e6b60e48d39f5c88e1f0d0da1b84f9e84f3d0b6d734330308e3a4fb74613797903f175ca5e598d95278e7b9a6213497baf18871336fb00b8e514127ac519aa0c9dc8c34bfb159982c48c11fc249aa0c0de132757a8dacc325e1dd5e1d8fddc7c90669ddad0b48a8ce0ca489b34f9e91c055a5f1e5221aa3befe4a11728e4edfd8ea3cc2f2e5df2f32fb94cb7470e80a530c4a530a158d53228d79a0d8615a82baf94b0c68e3ae9178fc01816beda63fc5066ef13b39ce6681ecf698acd96d5bb617cf25b28776da66059ad791dd427268a1c16a5a74f91eb50203b91eb0ade668d1b981d15ba574587a3fd2dc1897f492113054e987f24f4fdec30308e88f611ed255efb2aeaf7140029e6984950d236c3160268f69870e979395647dd4763819c7990042a2a02a69578c2c8b555575331c6f40dfb9a2725c3156adc35c2debe4c4adc78b96adaabf87e317ddc48e730c60f005e2d4959bdfe84cbe96c9067bfee5ccce3128ccf262a95dede83fb77ccccaded9180a1dc55a6a5b8e11d383c786cbbbecd64fd60b9262da355a1c2e4d132e3a25fbdf48f91da50732933f84b3a7e064d16ec4225f740acd910160574f384d684bdefef29207fe415e986936523c965842e0b9ef90979422ac47de3595fbae37bbf1885015586517c3a821acdd5c1f798a9afced36e0118f54e073b65a14a88041e7c06133bfd2bab7cad51625115e4525865a4b73ba03706915d34ebe93c05aed6272f71bde8efc108b16158df147428019ef44b38fb573d6ae3cdb12ecbca955c3e68a4dad2bba624cf64332eb669bff6c6787a0c87327b96295e7d046dc869dd128b915a1fa4f9b235e59a0aea7149b299627cb9068b337566497329d52c5002916dd15c285fa5d5d20afe766101cce27c8fbe1c348fe1df41c2a8730577619a4476a8bec6b3a73695e13905f8e3e651707397846b9bff688f03c23bb86c84f0b98b33d5bea2157f7dd1c1aa4ae2d7284a04c49f844ecbc6fc12a19a1ed201bf73b4c9476b5a1fb4648bd57bb6bdc4bdd779ac55233b798f432447165dac914b4ec08f2887973cc33d0589b23e65b4dd67453ee0fdb88ce220630bb76f1ecc9c8a29988932784f0a74091a4aba0a5a9197f27e95af162912d50814c7608ac15f9d2c423fba3dcda5914b4bbe50295a3e0bcddcdef1f91607b7b535da36473b1b776b3f9f9e819cc2d4e22a4743ded0495d78f387e4e3ca02f49127484e8e2093f674b835807dc6b79538e051652dc3dd9a710954a6103d7fdd4281333faa3b8ad792702608f842470e46acab74b4ad4b8d900fa921904167472fd66d669f463f800c34de54fb81232ea061970c9bad9d9ca45e0d6d664c6ff00d2b3a4b4fbbca9fce2e938a42a96784523fe98bf733e3f34d24e32ead6af762c4796a28e3a317d2bc6e1a82f55770e1192f9a98be46b03f0acb6cbebca33511a4e27336352ab436f5d7f8e743ebb7c4a138bbad6233a62c8a61bd56f989930e4de4f143d46283b1e5a3e9822989d8a4c91f50085c5a32ed2e437329a0916c43e0da2689fbaebcdc24c80f6f4f7baf241c3d148cd1e0857b4a828ef1a1ae95c60f0764e7d90c84958e9f5112af8c1694a8e6e4534ff40aa22fdd37c2741e55731868c4d8270231f8e709dba621aa8eed6ac7f648177cf057e0dc79eb10a0eaf7f6b23885c18249d74054f61d3340b79f5b2576249799e11b90e9dd1acfee98078341a23fb1440ea40bf6086279308a49498789924ce6f8fe4e5edde86f37512ddd2585f77fac495cee4c7e5b6f19eb6588e83c0e51321473220e989a2c14f7acdc51574fb7f84212258232ff3429cb6532706f459305d098599cc381df30486295b9f20e1dc0bb1f4a5355329674bc45fc4db3753c1228f8a6e9c2b369ac435b4cc421b7870e9c4a87dfe673cbf6f43ccebe4624b65b9acaada608b07f997150e3bc77ec1f1fa18e088ded3d419d69317a2a26bd49534b8729d942182a79468da7815b41ebace05523cbf3be02d7c2b0084deed7aa179c7aa05cf7613a4425bf7a09e5a1752734e78d7f2d293f076aa93343a85ba6be6e42c02de92d1488222f3d9b9479a5be804c41af1c39e0835eabaf01b826598cd777b1f5469b3957d3c8eb88eba20c3929d4dec445a3cdaa3c1248d1a012834a90d127418a185ddefbd23029ee7dfc481820d71c0a90a29c7ff7a3b60c9f71360a5c6db6bbc9ae3cbcfa7f7815b9833cae94d85c9b9d5fd892b639a083e920cd76c5421c3ef1d16f9eb4f48284f18218809ea0ceded2b774b5cb1aa0ce7237e8f2fbf85662dd9b9d7732ab96ab24933e2f16b0d599c48fa685d72fcb6ef42d9aed4e35fcdac35d7fe3c30e407e8a75eebb1a77820f8d67b7c7e922d85c1fccbe105d1d1a65dd826a7935f627dc31f2ac1e1f92a1e6286460ec2685ca86d8fac29c7f893bddc69511eac3781ca9b675f2a37902f99d1c5062bb12aefa45fead2ecc804079fc524072b689f5bcb2fb24b30619c186d11fd27bfd06a448259b1620eae66e19529aa46da0855c571eaec893b0cc8004312e1423c24d7aaf3e37590a17f7a5126985a8e6dfcc6002fe77f53184faeeda7553820fc43a39e7e4101565f4da7f926d991fe00b9c585ccf77b13fbccd353cf07415f63667736c9063b5d350763680ee34b95e20f9643123497427310ec1b8cf28528d0fa7baf649898255e0652c8aaeb2ba4c141f5a178943d0c3d0e7809601f04218f0de9c0ab5a05cef0aa9cb3f3e9f8469fb04d51e08572cefc428c07feda34e6a2a7f0648da8ea4aa7099e746334ab24461c305951b4283b0a22daf312a2d123cf74bcdc5036dc28bd4dec2a0eb7617524df992fc0b2007bac494569720eec48ddb59f5f568652dfa968881821f8385d681a7502a1c71df01124dbc91dae60d44343186262f3f36c04f9840711e7bc71a0545b5f84a3c1543ba7d51a4a82cbb478346fee6e449e05d2e5ea9247040a29856cfd1e1a22ad2d88fa906b7812155be4ae425694232a806c8d7486f42cac0a28b5bd52328e68d4a30e9a96f53beb76471cacaedfb711948aeb6bc16f1ec94a008bf6f6e9e0fac788c5a3c1733535aaf30b8950ae369a6505bc713af25290930286b270f79d53114e25749085a47be466aec12ca1eed1a4df1611114ad2f37cab8e87835a89810100b4c3a994445470b95effd52a91d3cbf782696c74f6f5621bd82aed87a860b045d242398fc8b31b4713632994908e8cb568f55b6ab85003f18524a4dc9cbde9048009f88ab891619bacd50dd463a762f6eb69a345dab83806a2247b562db2805494cfbfb8105618e84ff983c7a521118d1c71231abc20b7135d078e3aa67b622e6e60b542d5fce90790bdbcc997e7b2eb902efa1ca3a3dbb681e7316e99afaf9583320b2ad7cdb0027ddd299d806a65805094cba0b281d9c9fcd951c5dae550c4cb03ec6c5b1a3dcbd3ac64962cf4d0d631457447272e9b4509be8e4f5582f61d53ab74fe0d5192f18f913c2ccabebd6d2fbf2816aae01c19168271b13ca69b2728bd0e25f1b47d00df4dc33a9cf9f9296a59f88ac0876f2ef54249473533d03ab5f12a3541cbf92c75e2db0c8ca3c600e2ba9cc28ec711b000de0edd32fe9f9884d79950da3f4b61cba4b862b3ae82b527c654a0a8477f7bae3573826105fb51687e67efe0f0b770a5edb715e8dc23113a7f1ea57969cfc44ea7b18bfb44d8da520b7f3e75ff0496733a04a54452c557fbb7d7c8e19e473c1183b4efeda0a5241e7ec95e084b4c1e1e9e46913415b25fa9dc1a174e2b8ea2a85decc3622d8c44630d217cb760f1e0faeeea283296b8f6bcfb68b79a676cebd57df0063d61ce5c1e990efe63950dbfd247e6b149ddb16428d9be48aaf12d727d00405bdb4d0c1b23d7e4ead65ea76f9dbd85572159881fc563d27acf087e46440a31f5d7f2b8050178efbd6faea1e37cfed8cf27abe6a42ea6b6ab0399c3a88df374fe1fed3f91841762fe20dc82d43eec6ee414eea5a9a66aae78c4e827ef0416720dde59a5613524214899563a24034063a487a72789980477335e135ff2df81e9a95763d43f53f9e6dda19fb77a410aaae2ebc03c39618690ae8801c75ab26683d08b12694a84e803c1ce0701e364cc9fcda10205bf91efe6527abc4675da54f89b89312b8eb58803dc52b9c4cdc73ba5293ea131edba4cd9e9800b66bab906561b6f5d15d9c0ffb0ddccf749e9b59dafdeae942cf0009579e410f2548dc05e5201bd860d072511eb5e94744c91c9f530cee402f09a65878aec37ca9acb26db656038c14b897728098d472841a6fe6c16f7a5d36cc3b6218d2bec84266b7140a2d9fc0fa202ee1c3d27cc73dd6fc9f3390c946f3bda49e875be3545846f229d3d3d7c252904e8e9ebde14aea3d37c3c062215cd8212827f80f6ccf314b65f5a8df634227bd27268cfb5acf4399902220f560657496e0576c9c21fa148c1715cf62a5a524256dba98c204aa2c4dae2cd1aa0585ca575dd3301b49b5d57947c542131b80ccebf6f7e428dffb7b128fa708e7b29f2041396ae1f2d157ada524964015706e3bc50e9cf0d3a40f73fc322804a7f233b0cd9a671445a2bdf35d2876f7a7ceeac9bb66dc3e3d98fb72560e4bd03cb4b46e85f0bb89c4727a137a8a93bdd0e085808bf2d0b69d93e3b2af28ca987ba87f6af14c53c40e72e6430a9936896f89783d5c2103c532ae22072dbc389663f91745c04cc7300e8b8004c1e83e63e7f31fcdbc253e2bce9f19349c404e1832fe25ba5dc3f1d470492d9aa6d384f963a4fd8a5d1d0061948d96f1cdcbcd39858ca71e142edbea3990c2f396d237b73b3fe434ef85490d52c4779208245976f1aab0770d3589124926bf68b6a69ecc7ef3bdde13181287d9a7f63b0bf5ea7460de337dcb967b777293d4b5d621934f793cfce637239c3f96cdbc03e40f249efd8e6b96278840369d4dce15a2933714a30e3cb1295c8d656661278e4c9a948714c6db50b32f0cdd1b58ca6fd797a2e994131d2cb85d1117e5b44e44f2100df70d552df6886e2199d5971c753ead3d7a3466b01da1120b0ee8f658f6a03d9199a1e8194103bf3aae5ebed1bff93ae262d8e47d79212ebd3663d6ab451a77ea2d836d374fce014be777085be6ba21c442b85b81ab90a06a8ac132e82fa1fc1ade0c2b474bd8383e5eafcd386749b26a11b854d0a799e0aca24d5f305eda8919c54c3297c269530d28cbd768f6e9a42fc18b9374c5f9b0705854b7db39b2620f585ee86f08c778ba478471f0c6e956be300f38d141a76a35bdd4590c297496ca6e19812b1c429fb07b8c96f5b982d1d7e53ce66efbdc0d8374e84446efbee171624ffec553e4dfa80cfa46bd0adafefe5bce0945d79fdd636afe683f3d8e2c94ba69cea7b1ca9f79cf34ae4e3a853aaa1ec5fd828e4d077dc8c603b6f49b411367682dd947d732dde456e16cfd6cc91d0f3a588ee1a2990b93e3647dd0b28a6be31a1f8f3de24c53a24c0bf8a5a217c611c01431a587c4c6af1d2ee8a81617eb3c529f52d902f47de28ebedfff31edee22a4d3305a562efef5ddccfcb376ba1dfc7aab9d6d9ee980119f6725ce1464d1a5c79517a6f9360d089e3215fe179490e0aae974b68d98e2481f0d631b2310f0142bc9a257a894c19b65f52dff668ef2d13fc4d2a343df3e87bd13d07630f8d52a533cdfcac56988e4c041fc621927499159065097cf65ce166efeb338d013449aea907d40cb5b67e59de7cc34d90998bc5a927dc613dc92e1f89d487e3324f879282d78d395972098ef7cf9b4059f7fbc83ed1462f12bc91c53b9c2eda6497e323131ef22fb129c2410f4cdbe88deea4175a8d2ffa43295657b2e3aa9f73207776649112fbc58c0d9f8a7b7901ef8e94f1370560020cd164e3feaa5510d914f43174ee36ad6ccea42a7b6e0cf2446e48e8165443617688c35ed617ede0073ccabd678652af7c825cd9a6a874a7b3c925aa7065b57d65e32589e9cb3755461895cf8928db30f8eced6b7ae885fe724bb36cb9f6593605b3332a30738acd51e3d543c641786c16d1a1750cc4567b7c216790f65c72035049b36e971979c9e23f43593ddc1faa0a43daf375b05d9494c96f6bdab528529ace78653dd590e0687178f57cb5dcfa3a922c2f049f0530752051975c565f4778fefd2a0c9d8daafda4f998e402d7011dee4da6d98010a1455db25a8e0f057b7373670af1baaa31dc3f591616d70d75ef512cfe88bddf8c813f1f28fc700559d1669ad1e421bbee90972640085c90ef24a30652225c8530b2054f0d1672867836cc285ff99e32110e74f47de5d39ca0299fda57665948c5452c9558b334de9c7e61d3769c39ef16ba9be1f65972f38c992318ed794498b0a1f7e1a53384a09d66a0c175ff45e676db479d0348e5cc21071041d61379431089daa6d7a331499cd43db0cd5ddeb1a85cfc37f467b406f9bfc64585387f48d9d757f6a338b820e5bc1830416be0ea95626f9ac7ee9e613c3de1ef3c243f0ae650a7c5a77995d698f143bb6a0b2bf8da97bb1702aebf3c716e595e524af0fcceea9ba69c448a227ac380f4bb140fd4759a8d6e3cc812f4a3ad24aed042d5de3c732c1b2ed0936edead71be7ef5a7a3afc329ba509ba9733354904746038e6a57627789f6b14ceb186d9fd676ac8e4aaa6e7dc46e5c62bf7e18ff0b53a7076752db55002767e4be6641b42d4187f63611c560ec47cf80aaf223b6a643f3964f17c79fec9cddf970e9b547ddf454aaf5d0a37de66736d9cc518a4988b064da53db78f7462e63521f981c9233905f6cf28e3f8debcbb76564ff35edccbf16b30396b6a6e3ed5187aa762f32f6385880938cc4ac01cd0b149d4225417f1cbbe5fe850196dfdc06e6f0a140375f7decdbf90f4459955f24172c8fd33ca6b9442be0af8adf1e85d11728f80883ce2f1489f883999a9318ae87766d2b17b7b8eaca8120e65fc4a6cce93a7d72ae1e5483932a16167437c1844e4166fdb36f2e150c94dee144adf78baf03021384f19ea0c58835e5c4ea58d0878cebf18f4af4b4286d0bb4a934d466bc23c849e24f6e5f9e7c98b4342a76470843056df4e534e9902c1620900d9493cd9d8d32cc7b7371e7030822bc7131ece5a23fd81e61e905c1b83060f471e84e57201e6001373f3084bf6a75edb921e9df0efb684cc166dd8f33d83db3d128f15d0e97fc0fcfc3f8e01cdd2cfcb0dde2d76fb7300c40c84e4b2c621b62b3241a68222bade96f9d46bbca8a9a41c057b3075ba24bffd475c77bf9a05b63ff009632b3208f6edfa302f85d592ee5b8f9dfde3ffd097c9aa6cfe7c6b3b344dd644b364fe586145b2a5d83bcd5c50f8d1ab1c8209d2d9a00b793b2b99719858a2832e3facf68dd2054562c360d49f3e089a19c40a9556c357dfd7cab01b2b87fc6c5a2c3fb5f4c5dfa9eadffe998a376e957787a6bfe66a347a60fccdf6823e89ee544a4853098c4e21766eb7a0c2d6a1a1e7e170a5bede2ceb351681577391ad5c07c756e311f3051453859de5681588fa546e297cebf159e325d07e10cd5c62eec2f71e55d5dc91728391e72aecd6b042d76349ff976817fcde71a3bcec7cbfc49145490bbb0808f5ae3432bf3e8476d86710d96a37c3a03f058d1833c1b21f4e1612ec6623c9217adeaf153868805ad88c31cc0216666de636ba2ea2cda88c9e9faff3830cfd499b29ab160e07f12e8b8afa381ee908a6d071a086c435fc57d70b356e69b5f3e0f756cdfceae80026d249e24b39d260f7bfb91e14840f86e37a83b62e5081c31471d382b879aa1caf451a5dafcf5a953ce3fcf37ab15faa896620260ee7c4a3c2b137a79ee71470f0de5b582fdb4ed2882d3cab0bec339dd5817a9da341f5a3de8c6a6787cf293f7c885934817838395543227341efd55f5cd8d5f07819d45430059a7ff1cd44a6f5a0c24e2f6a27f4381e1a594a11b51a583f345a2d84c0f9551d904c57aea3370bc6e7323585caad4960bee353c7382702df7f300dc8e5f48d0a6e103b8d642c88b1b727fd941a2efea2f2dc57dde706cfc49a1f29b4b71177bbfe1fb214d321cef291107e53ec864b7f193fdda86f995cfafd310fe3bdd1787a320df60e6aea1c59c8971b1cf4bc4a8d52c774fd2f7d305109f517195b593de75635fbf94f87a8b7b044c44e752d70e79579961e49ed5209bab10ceed4b0656881b4b96590bbb864b23898c33b745fcd261b729b0eac2703cad1001ae7b20bca4311f6dd8469746672fdb89327cf9cb0351629a93ed030aa5c8bcc3cacb5fa35891583802db738074dc4f6ffee5223db3ed491d3b68f677abc9e4651c0cf8933793a3d6457ec63e18c15c073c17bade6340034e2197a1ec4102fa49b1c58e5d67db11b3f2274c6100925575b81d4a191705014ed0c8cdb6e9595bd4918e2686ea9111305f93e8ba6f7181f1405c8cbe728403885dc56ecb6af4b198d40f87a9b6cf213d2a38c0c94aed9b54b9a4963a3b376d09860d291d3bcd252d7878562276cd99287f123ed14ad50d6d7d516394c7d4332932a1c7649157ccb0a33fec0e8a670cb33f989e43a9b7791a37efd884e9a5e90ef27c2b9629be7fe64e5ef2bd0c49373a95f75f19c18de8f5f6e35af5e153253099a8cc95964001a61d3246e0d571f0ba1abccad1fed0a311c7b0925e704c329c87c5127a0224af622dc756e792f8a13c5c6a7ba60e8af54d01707e1275a4e2f23769d40e453bb705429826459a4d0156dd5a5efa201fe1103f8389ed42cb71bf2ba24342ad4cbd2e03c0f280553267c5f918a5b0a0b1e44e1b476b1ba4547f88da685a7ede963a067a4a125e3a201c59d6e49f2216d2ef74fe8b433b1d0dce13dcafdb0fd30a8fbd09255871bb6b20c4fa3f48bc4b2a42bf7755193a544c22e8a7c810d92c02a478f3e7c090eb8c6eaa2f9e4190edae3bbe92a905647a434e36097fba54db7d6bbd47d002156baaef4fa57a5a298c10c8976a6ddd1a0c0c6cda0f5ccef9011b3f51d2815bd159627b7dce99488d1f68e76193b03ccf96f0791bf23a006974d65bd1779a7128766efe1abfe871a85c86e412322c1725a6f14b5b7b5643340d84deef90caaaf6f3f64bb9f7ed2b0508618bcb3131115f7777ab99aa8c4c66ccf61366255d8c285acad8bc871415aab1e0caee26384c6f0d5e9ff878a78afdabe158cba8b4a3487e33ed185e969d8c6e622a6d092c6ccda5205d6f9214027358b955b89ece416741bbbdb3bce16cd68d3af17a64d7cd26d0b42ad33b2df408a4adf3796941840cce25502bd40c3f221d201076789151f9a0121376c6ef8df50b57749f49607417f9a2e8324e11cb6afd66b48ce22e3b1a5d8b2e27cb1ebdfde9617dfaf8b0f1d7b1cb285a725e85f1856dba31c59f82a107e79a3eab109963f32155b9050ea7bf43c37e17e912fc9aff90d0e382a82eba61f2f6d84bffd5712a0dc8b079dc133b4dbed859991b957e064968344cc24e28e3a5a19012be55efc01afb4999d445c56844a9889d9d713e9d69dd997b665fadf5f60b3f002067e6fe4064b3b38279e3eeeaea9afb28be38b4ac3a51a28d52c308ea6813151428effeb2e92083e3e0e21ecd474d615780519a68824cdcc4353d98de8deefe004c959d5140721b1ac2cb994a334992477022ab601c09ab35019681a1afe62fec07ba81ced25825a625d3026b393eb9bef4b54e4415c478ebf9cd3ea13b70db7d0c9e5dadc46798a2b2d1741e384a09300b6c4f532ebf00c3a89b1d22134fe42b82e4c8e1a3ff99989887ac544cb0d71c24d9884f55672bcf654244356cbcfce63f75769af4ea5cb1eaea82623c124e65c910a81c2ad3f740e3b71a2fb62073816c9dae77611d7ea0cda33196f72b1a8f131192718be10800ed4f9f4fdeacaf0a85a3f1ca68631a2388f0e11413ae60859f1ebbf251cfdb18d44e57d45dc76d63a3c1cbd70f0ff87f85ce655edf7d876c2e9c6bcffe4274c55f7e29975a4780afdc188b0df54f25f98d133013c146e956dfa798611444bff9f51648eb07a02af095b72ebdfffcfe0d0fdec977f6c57378fd8a2dd86bd2363b553cf4a82fe5281829c5e15eac2f40660f3a7de231b27419fb129eb139040b58e9d6f9114a3825e18e367da610b31b97a97e1073e782fa7eea5bd015cad44c67ba2728ddc7d660f6b594733753881292d9a72c771a454c1b2c5bcf90e3ac9aa91f24ae8cf5c9fdc106228050850da028ed0fc5dcba61c56c93f41feb549d4126312a4e775f3cc9885832ab6247c946b5163f09f43c2553f9d7347b70c8f8e5d7f8b0afd0eb4aad4c92da4b2a9a81f794966c5915a202085943fc4a466442f920e40bc2975f41fb7a8b6a4192592a4ee85c9e75cc28f93b747885dd592bd93737d04c9c53ed5567ebc240cde2c8a9de242f6f7e8484e1696449d7dc753e976be81893ee1daed85b1aabc305f33aa2bd9074ae89b9c3700bc41e568d65be8f34ad28e729c5c2ada990c4dfaa5f3c091d887301b40a01e2122745f719c445d0de4b412da66d9160262a75124e2a1edbce2d6af8ec5b949ef22caaa7ad44bc3edf36237222100604024f09b2f1b12857f261a7e583fa4ff56220d48423016976485ec04cc5f3e62d18239a15daa70f30e313f2c52bc5b62896ac14f7f4c951af1a19ac33acc3454f9b1bfdd9621807f811393ba06e274d5eac953580737eda502fcb615c6ff7311e7e487eae2d1564d3ea6fd51d52fab0f79cd4c804aa33cb218aace767460323f1fc18264822d634948bf3997f3abbe8a144032e7d66ef74f473523c7da1c9cb74a64a4d891bf4b8ab220786319e54fb02a7f8562752c01790fe96413dcecb715bba683773a432b50440132ce2a69cbd845d606a8f07a7ffa0c7e957354ae7017876318e571eb0164fde2a800c1fbebd4bc5f1731a9b084d3c35a1a1c594ffd630e08dfcd230d6e09eae230cb83932a463ea50fc816727b45e1990f8e8a25c805e8b72238d445dc6fc73d2086bdfc5359e03488dafd12f8e9a0be2042b391e23b9ce55254fff7c64a04934d739d9f62a7a4bf3f26c0256a6730b200e1b8caa7bc93758b77863d681f34208141a3493200b816fb13c833779756d9427b67a3c7f55016533cd1bc6abe9b0529c48838e932529a94ab7a4401f0983269d9a91e0f90edb7c5549c4c36a4650ce19097918fcb16ff2f21a4d24107de7421f9f51786d42fb47da9a6cf5432e52a795095a9bb38daffa113b5dfd126e4682bfcc9aaeb2050304dd747a0545aa2257ae4820442b1ec89dd0c59e9ae8ebdc9d42113181e42c495372cfe6168155bc2ff786396b1a0ef0f663be97138f1d27b12d02f2dffca369e647450e57cef09bfcaacefad667c98623fdf902930104b9028e3981e90a0a941e96204b660ccb442050fb43eaf8545c46f6399c48f5775804df1d42d5fa1bee4d6117f64f09841d14775049a51ad0a556bd644cc3f398f6911293b388e7ea9dbb2989230dcae6a7dcd703449dbac8851740b05cecacd32664124592c50c778cf4bc8ab766462b05c21d4a77c8dff9daac0fff82ceedafb79eff208c459dae51e6145be4ee5f899a1846692ccae3a1672902e2b53c77158ec4c2a13ddad6fff12c3e1256e9da3e10846a39aad6382c4ad286c851980bd753e6a40b7c12a749fe11f40bf2f0d9ac9e2a3409a0eb3b2a661f83d4ff3a56a7253cc721e48b3fabbbf635f28ff3549fbca967c23f63fb35d7ea3eb39930a1563e3afbc930bf3b793825ef9862a153145342e6d85a4619a88e21fe88329452484c887692eaf6cbab9416fde529fd98a65a1232f39b24deb33786a8fab95654c3b63109b23d08696176b42e0360acf8a61cdbe704bbd8266d6a26c16aac26e79397d56284c2c107d8f197c650f5c6b1e5290371f5f7382a81df9999fa8990564caa13f8de79fcdaf8a299f4f6f8b068fd9d4d8d7f184dd33b7e9b47892faf9eb843bf6c1ebf7d1074317bd69cbca8ef6fba7f8166528ac3b90e3bb5a743606da8f2626a55a0dadc2db654a5f31004196b9ffaa545dd4e7d90b7552e80d3ea9d274a023306a54ed1e3a5292af6eeadd98452f4a7da12e415ce81889454dea8db2782068a51b4bac505432c2f6936d590bc00fc403e8ee12c65102b4529312a5f9f7dd92f4a6c99a903230dc44a72b93fc7b9274479d8771a6f0b61147dc50b77022f496f4f40683dd64d7ecad384f9ad0a5313fe95c5cbc4e8fb7e51d62919dc9a466bb8dc59501dbe98d313a66d06c3eb73a4b13e93c0b450681ff9a74d8c1cd54795389529445f74590e294cd4a58cedbdf91eb50204b91eb0d490b8a3f15f33f8632ba1a05f35d115262f94e29fabb11eec76ff888ce29b1bb21fac7e933d3aa62e5304656704f21a0dfa2aab975a2d004468e224895c5968751b67440712cb4fa8bdd661325d0578c6d8eecdd82ef01bffab038117b1c0a6ed1ab74f04f90d0b610970ef9c2655081d44a9c7ed5562d394c6e1a71d34f46f080d3448d75c9136ea6e8649beb66305ec96aff0ab01364de3ae4e3262109f914351e7304c33e714efc3e000fca2b0ec87a531866fbe7e2d20ecf968a579c73872628ee8446fed9e03427cabc58880e2f4328de25b91608bac22fc9f7be0022a5bf499861f36d7f9ddc017daab10e0a0f753b47de66ac9876a46a8b8ac80a11f2e7c238c58ea236802576e2128fcee47cf657791909a85c27b5360800b7da5672a7865b9ae6dfe3c56ec64b660857d6437afc9fd23f48779fe10a08d07156e5ca4e5997f83904e30c91389ada6aca3aed0996f2f884e5cb9eec6b015a6dcb586bf1b352e8ff8a5aaa679c09bd62aa2f0c60c367bbdaafc3c0133b7673bf546befe798f95e4e570476931e6718ce6fb0c50aacefcc3c5de31bf315df1adf15ad2be1eb3c3b5cbeddead7ae7e0aad31985b246f6c8b33381ade8bf7d5f82484c1a14974d82466675c0414ce33060a8a8e37c95df46d257c0fca68c8380eee46e783ab85f186433ff10bd1f9a18f584dad4c6b4246726eb1fd74ac8dcfd859eafc9ba455a5e3511de351f971d641bb27e6d3a75834ec464004d72857175e331f5a92cb6a4f874543eb0bf890ffa6699858ea7e3c5d72e2de30ea6007a7a88fa0094c610b87533ab2c31afcee5bdaa6541f5f11975d2b83e15c241c58c2cfeff1fbb84d6a528da24bc7499baf96d02062fa2dcbbe855b0aaf5adbd298ef6f79cf1162270941c4bf37a4cbb1781e2fb43165a1dc78d2df6a8d07783c892759781fffa7098af3ecb4e3a27ed45915f3e991ae11baf4a626cdc80fa579e13b68d7912110d20260382b2ac07b28d2e58545fe2b2691c7915dd5a2daecc2101ff691ed0a4af04d6bbd35fc3e8af671eca0f092c92455ac6e49c408dde49b0227c4d0ecb31145f6f77d858351d6ddbcc09bb1ba7d50a0af0db31042ed864c70ca43a73a79140f7576fa9333d3497baa1c2d6323dc89496b7b7190e0da6fbdfccf1e8dd9e25f930a8e55cac5f367e0f2d9ae1a425be91857500bf5efb418d76141b9024a6835d4de55c8a45261530dfd8339f288a37399fe1cee511830bb3305c84b361aedf1d96173cda27e6c6515e86e96cae5b282c6da521b64e8875124e082ee771834dcf8124272f355612d9cfe08e2f57762f852788026e6085e4340c659dd3152cca9f911995ad1889790639a9a41c0c783c9ef2ad1f233b3152bb4ff10c180fecc05d6d1daf890df87f19267128b1992be0e002aa662b8fef6423377054ff20173076edb7ca98dfdad4428619e3ac2a9c4762b32af30268b4ceff1b131d2012502ce09fea83f6b0bc110dcf85d03b15347f2189da35a5c51dc139c0febeecc8807036a7b6256d7575072dd0654a6cf7886fae2c576c969e8d564332a5eb41cce827785c97451585e064d6dd843690a1be3704abd7b5582df6cbc7314f6964989a2c1bc541bb346674289c6735886ce4daf9840628ac8e1fd4971d2bc6060cb63fa395e4801dcc9dcd92e8df91cb2c4e35ebbcd2a02b8846f6569463e09c1cff1ca3ebc43bfc098c60cae6e8a16bd00e9fb8967cf987679730e47fe3e13f6c41f34c1840e8b65e0b1f3d62c7e28cb4bd673c415d5dced7e6551066ded952856b2e6c0c8d022bc8eb8b1b88246d2be4f9d430a6f0e0fe29db28bf82790027cdcac17bee477b5226392df81106d18ae8b93cc54deadadceac5188ea23b026a099e9270d279140b4a1de16d079c36ef7a9dddbbc4cc3a450bf26f78813565f95ba52dccc2acf4396da513f9f6e7b04ba1a55163247024c8dcb7ae2b9598576621292f5bf1e44f1d7600b75d72117b110396832690c5534867598744aa21efd8a01c0699e4635daab053539664bb2763d2d2a85bdb7a56ab7199385beb4a5101b3bd7f006048fe0ba28e5214da9c48ce4ce71d5645a6b7ad7ed09b6174594024b9a13af2bfec7411f44448064014a02cb844882cd05c821dcfafa9de1fefe21802991c41c77b0cc21bc504b2b2f9cab01b60132d777f1c983dbff0205132a3158587f1e3f48c4348e076dd4c33c74c748c2311632ba02d1310d9b155d600b7e9070d5320fcc8f7e3219794a7abbd3840f6e1d9ff31f509839ecf620f796b62afb8a2a2949a26b09d5c74192534dbabfd879294a092d4b0a6361e73317024704b7f7745653068721775ddd82b79b9d7ed4ef19f26ae3612f361da884aaa7ef191e95a189cdd9e1ec1078bd93ddcf19ec429becc3f425fbff390fa2fd90c94afae16cbb00cc03421a03037d1d93665d2da2cb192bea8a78b34d10c7b852146f405362fe43aec470a478bdf1a1764e4215c89407608d3bb5e4156fa26f62a3098abe827cccdcee34cedd2c0698cc58d3e28d0447493d747510fb12abc999f178a4705bafb0ef16eb80a809dca67c0dc4ec5c6f565fac75ddfaca299acac22b7c63553fc182719e4f6c2cf3f268a8e1a823f960999907a74ddbd39dc9d0fc2427623aa5ffe0c25d86ceeb1721dd7272fd53a8b872b8a405c62c696e58779e9137d986cb23d1e351337b496a91391c782bed82a26e6ea5c9e009353c78710e47d99861cb35017d0a4c4b28855d467033ff5a4389a457a68d5c5ca8340d143e1aadf300f89969d98f1e2cff1ef0867b7e4e5f32b1b1ce9e47cd1090c569673f2fbfa90ae833deb3418bdc9517097a477f8c390fe96c198c97a05aad740b65ae5b8fc41e317b1fdc1e42a064a9ce0bf00b4c2a927af5f5215d190bcad5fe4221e0079da4b8f3b31c9a6ae58dba3391dc37e70cad1b6dda3b99511c4fe26c82aa74ae5e7b2be2f945384b2d25a229189e6c421948a244329610d448934c115227af732ae62e2fe2fd6ea39f79959d36d91d5736d7cf61f0638b935d129d27e229807f2eaaad327a2e1504490de49860de0aea5687ef23c6c0654a20a99d41109012585e5ec33af73e5606a0f45bacc890e110e38db41906acec5f74c6ad32b6b94b5ec4506531b955d983b5442fe029002b8971dd1f1e4de3f1f8504e9e80a5c783a9e58027602bd0ea2eb7012a9dbdd20a5128e8298736dabbb139260e3d97ee44c32f39db522d01fb9560d9e1a9b538bf2f2ecb6b8b74e111363ca312d64a02669053dc593876c4306350a208b17db39588589731648c34a4320841307486a8bd938b37972e02d8218bc4ea641c7e5de0b18902ad98cdded3af62e3284fde6c9557eb218049fb24483fa2f5ef7621a3a81cf6acee0d901b6179b2553e7e921d00ef7b4f92593b2adfa8ebf556a5a3f4293107d6c1bfefd0cc2b7d35526e3b947657025356d19d368353243d5c4c98edd65b59021b7d6cc7f691e7b1431dd45c9d9648882aa7e715ed1d6ed2600620111dc04ca3a74382689ec739d7d854afa941c484f2df65593c3f190c47681dc4f53f697e36d1d78086019199f63b4d458c0bbed1f5dafe11a8bd290111e66139b5d2c53348180503ab9fedadc3d6d7c75706eb21fb91ec2e31e05797070365f0e100593b8a330221db590d04fdb267c1ff897978f53eef1abee8440b83331511873bacebb921c337a4e2549c2af6d3139b8450950eb77f5ed6cca6eb2bee6d42dcf3c048f3998ec46a68bbba072fe135ccaeb937e95e6de70a0ac4cfdbb16be7c711977ddeec5a97167ecb9819f085ee1d06df402f1d8f583cd7c3133a99049cb2e234a278834015b715cc6b1d1d6260ebcea193036c0058080131b1eef55f34cb76934c7f6c756fd54ebea3b5a6e76113ac12c47e107c7e5f5550edffd59e9eeabb9ce0bc0a5b9ce10a7b1086d9abb50d7a8be02d8bd1e6654680a58dc8bd37f0495c6cd9fca159281ef3111255c03157a298d982d7f1dd192adbbec92bdd1e4219166f8c98d481734ae36d1341a49dbde91b9c70a2011752b99b1a103cae6f1c911b1768e094aa29b928d5225226143a9275d99bb5f0d9a0df4eb8ce34220065f90146c510c405c43e2608dbd9956b56d8bcecb73740c4d74752642a70463c20cd7981f47a881848e4bd7ecca7cee47866cbcf339ef6a086df01b899b4be9b14b9e7d2cb33cd1fb8080d031c09abee6c4d776d589045b300dfb58750609343c7ec1f50134cf98738a6f4c649dbd82f389ebe0de93ad7bd0beae4cd5c25f4c1f00f9a7ec9c514ebc410a31f72819d055dc9e7ef7b6b237dd88e0c5d65ecae71de690a52dc1fe98e24b163149d6f7ed16cd94b2e451afe0df553b252d834da5bc882dc6b5832f653508022a69eb1853a443e329a445c41b89fdb6b76cebf7c9cdd2d7b39b711f81b0f46fe9af78f75cccf3f3edef0bcbc7987336718fec1270d31dd7696e77081594c5d5afb94554e5ee58c2472ce4e5a3ebb07fd8175e2b965f928a1c10981d7f5c3a0d46d4a3cfcf44640b2389b873bf85bae100183f7d7c5072300abd951267b541fa4c2c0f67d3340a2311131b8f915b309dad55d6ce979282e1f5ca756ec93d6d0b7502ff7df066265482324971623ef97f9e50456700044c782ed20c56cd70a2fbafe1b635f8625db8e2091101ecfae87bc910e69f336b046db78fc94cacaf9dfeef4b3db3f8b15249de886c8d85d94c42b2f18f86947516ce44acbbb8a8a049cfe6247bdb276a18ff2943ac389109fb773ebab55a3935e0dad28fb11c6f11ee2a256d5331c97d7159d7f4b89c4dcaf431a06dda4923564df3b267a3c917803e9a99f8dd4fb27850de2e3c95791721e750414d98c4417a81c0503bea0d48039d03c2b5f56f33104ebb3d6f4ded535ddccfd58823eeac56cf377700a14515d62210b42ec58319a613092c2ecf13309e6865ead2ad3fe97a36b4a366bfc837dd3354b14da72e8e8ea9f2a0adb3a4ed43f163bf06a2fdaa8882f5b4cdca72f88b32778d9bd2873df33bae46cdb84d47b216c83fe667c6a83fff8adb7d6f3a304b2eef9a8f4c7a23e43812df443403da1b7f4fa4f84efe7e7728d553bd821ec5ed8926f8025c410e4f9410b9a992fb4346ac376402adbacc683c70a58ed4fa31d090d8ac22c04111b7031a29d412f13c46ec2e9bf3809313fe6568e245a8ad9766fbc4ed160ed1c043416be557ba0b963f7dd12b90bada05a2aafc91212b2c5d52955ab480cb5ae6d2b3520842182820dd19d05710b31914adebb9728222dcddd686aecd16ce03b9df868089c54d2f2a6f7123efb797d6abef3a778b12a05671977daa0436829f4fa914274eadc5732bf9d35b04c5aeac0d4a368aaf11afebbeca16a002cd2d904d930414e1b04925bf6a7b127d8c95c1503f5596a84ee266c7e5974baa1c945deee7acc44241b9b9b754c30142bf78f964e9e8b2a1d6a63d10cf365bdd504e85bcf004da8fb48e9b1ebf3e37461db2b78f13d2fd4a059c91193f98a68deeda5b48cf03fb8f270bbfa546ff65568ec8d849f56c1fe9eaa7d50c8ff7cb686d993c5a94f67ed8a113cc17463317a8e33c110121180da712663d45d48dcdf60d71494a46f5dd2d63bae69feb7d7fc90dd98af95a9d0369138677e00555e5b263f6c440fd2a6d675dd81b9d911d55ee958e63667059c4bd1afc251d5a66f33d88a7c42a222aa776f6eaa869e8d4dcbae1595798a690b7e69495721b9db88da10aa892a4a51c861295577c5cc02affe5b0d494f196972213520aa63426f892bc8d9d6c7c654cba950dfb437d4024f97dd97336efbf35b1eb6fb5bbf36aa10dcf10a57e60a5f32d6a3b77ca81fd24466d30cc2142f614e13b2919e958491c125c69f04643bf9df9baa75c4cac0f44acadd8ce64611fd00dceae5b38e1cb004730b26bf2660d3dbc2a98c603e04e4d78f6dc049cbbaa8a858335a06f116fe6767771291637bd45a623a1adb49c11beac1cb024f5dfc33b45f706e6e2bbdd8504396c11b48afa1121585c6dffafe01fb965d49ddbc7c60563e3eb13800aaf9b717b4bf9951f2237bfaa58b728782999764a0581cfd7578e525ebbc7ce261ad690ee0b1f167386d7e6c8873d2eed650d87cdf1eb0643a21d6197fb103022c94da2adc9c5363aac28855948355d10a5e874d0d2c12681edf3c1bfe669c63c5c3ab715362d9f2115339515a6db6b501853bc66964b3c74c56c30ef3da94e1eb1ac47aec2ba9b88350815e09d5054ce775b610f8652fcd8c7f7f9006b8b8f58b25eb82754746dc5c993bad850dc148fddcd53f800366df6eaaa65b3f4dd2908f65eb421454cb09beb8cba16fedec7798e6664926e8cc75f64d8990b5aed05627cf704a63ec3bf51df5703b9c9856f6e588819aa0e8f7579f5d366dc228b02d5b0d4eb1e40d7a6fd628d4bf943240a96cf0f4dd4d8895e4b96542eb6c12ee0d945ef4354a9fe6cd9de82b30d07c19e2bc25db07839d3b9292db8c89b700bd23e4b03d9857906390341f36e80decb988d2a0cd01e67addcd7cddd975d024a401b05171f9d908c4795e937552d5d741b7f50408b38dd94968701a2261f729f2e98b2fb2e86fcfc8876e36c21bdcc6e960a128ba4b4b9d3fe3d2e062aed3ca5224b160d5ca93702f03c16a7a49a4732bf25af3b4ec8a1824452d069764e67bf9ffd1de2711a03cd995a4514d245c616739e7df1eccfdec5ad1dd94675362ff77502322d120642e023cb6b98c20193044cffff660b7c0e9a798d9232955a1e95d355368e35fbf6aa26b061aa676013231817738a68798359f66a6764fa727d92a1ae31be12ca95989893cf6c5b06ef48693a5400248058d7a02c30f41e214e57523f864a4762dabff2d9d6dd1fd0b4b861455a1373f99594c038e286f6a622b1272ef5ec18e9c554a663be677e8345c232371f1a771ffdf6b0ff2a4094afb83bdf9c1970ce0990293a30929a026eb1912e8b54e71d298e38a019eb5e7e8c26855b6b28f17353eefbc958c504a100921e5121f86d421d11130b240c6dd4cd000a24d8b468cd5b7727dfb2239c185875b5f64a32466f9b5cfc737a42d82d2baf25afa7708347714ecdb2fe13a4b37fc3e1e3f05962ff29c732eff018302a3fe4e820aeb76a1b5088db402f91aa27e2b7497a10e4a28771768eb511da1047d2c1d8a75d7299480a7d1f774a6f58b86c521b8fbe73dfa8b8c39c04fd7063038dc2aeae7a31557920e5faed324d94221737d3bbc6ebbab71aab57e2231aa54c9f1d78f05e64d3a4730e7202c26b3023f88a43b97f1275e59f1e3051bcd02bf8750d934e049b0f75837dd881d71ce0db5ba1588dca20492b5883f281fd05b3ced3628885b0e2737a1f50847929b3d10ae71a4918418ba59451afdff95801e939b0604112cd445c85021ee8f0f2bab91a10805def536e396862b32edaf5c3674e3ccf8192217bbaae1ecd9604815b65222e253f638d63bb1ca59430569f6b30fb7291636565c59d264868fd889593d8736fa4a6e08c2e1d51515284d0c6dbb507296bd05724716b86da1d5d0838f6b6b44378cb7a18849a3d44af1ac5f30c11f6e6c666ad805ec22fc12abb038fef641b6a902f855fe20ed6a557870edd2eed9ada15b5209777936384b1a7c268d3e9ccdd4fe551682b8e10abac16c22599ad2baf9389532b50380dfdbd0983c7336b721f5ca4348a21a4a81b4f397b68c0b31f1fd959bfbdeb20ef40b66b73aac34ef7f19b0c97a13e32d96b6faae1abe5531986283e64f72d6d2def9cad1c39f2313a4c28045744134e815544fb8e0a20471f2f6e875324ffc426c831bd88bb8427c17aee0947d70394991f2ab59ae38b74c22e2d77d0a2d32d147398d90871396120ae3df10b8eda63012922d8351c2e124b9c418c60967e91030eee33513ef69281504d5de6ddc59217dad1f16996abfb24ab2db06b1bd85eaf83eeb7ab9a2568d696fb607658fe9476fd2ad0f3a70d9fdbdf03dce3b3d86c479e7c827d4f64cc1e8f8b3a149222407890c3f187df8f08a42bc3895d84aadafcc83990fc3380816d9c9059ce138d7350a5029a78847f773ad6aded4be535351703af8fd26535d6794164a5faeb7a5760202e6086623cf2942b292c0d1aa1317bdcdcc654b2e31704be8d684ec63180ab84ee7a9bdcedc4cd98ae100764307d550a3170171b14a02b68dd55eb42128dacc0a63ef5a5b567158c0afa746f517d6ca9ab5f122ee36a68f8773e601a7e7f0abcd6922b6487d56d21054a7e718b6f9a248655c16bc6adcf13a991650a7ddb55151cbd24fcaf5b5c88a552f36234502a75f95df9cd206f68ceb0e4fa4e734814529a2cfc8cb4a69c2d05a187e050a63b233aa18f57cb6877932f4bef3dc310301b914e4bad54a60e7ec48c4dc60694d06c5b63b5c6bd986dc9c3e45cc20ab0827ff6d59312129a077f8c17ffc97b4d780e2e201b6cb684d76da51d0d5e6f9552a436389296628124f3f85c6a301ed043a89f13551dfb64da64ce22bc36e7f93414d784ee718eb2e2927f1050125fdc62b9f6b2ef2870ac176f0c2f008f1aa470c036649415cf46dc0a643e9b684f9752640319966149c816a004bf59e0144f960abdc02a05bc5ccdde0001db673ce450482cc38b6b4561620954cd0aed6ede4812c4165e4cedfc5900a27bb14aa25ba8b7e6d1948628fd7d90c12631609c4dfecc7de2932721bdb7f5d05f6cf501d4cd00cf899a22a35bf530c56f51c3e46b4d89c4f90e36ab647c07abbf9e7a282960a82a4def212fa9c43a74d0584b57da1346253141be685151613915c443f2d804794e17bc48dfcd07abc29c2712d626c8e7f252d770429c02ecb3b1cd9bed59446bf4c3422d07c12e694cbcd1e20f392152c017c4d3da18c8fb7d5cedb42eecf2586f918dbd7320ce4c32368a7ab69a62a5f5243c5ea9c417872399e9b102d94935c67cb488032233b003947e28e2a7d8fdeaded6d00bf9af4302b41fccd6effbe78527be5b43806c05366e71856f4eb96f17b0c77e9bffb7cd1da7f976ddd5437cbe5d14457339b9cc3d84c4e46bd599f5339eba861afd7ac61c343bbafc11df2ba0d2465b77400fa4e67fd76cb957f3872b3f0d9d4117185c7914b727447763b7926bcf31f0c3467f8e1e2986b521e2c17960299fc9daa7dc36cd1c30b7ddebcf9cc7a23acac9b0455ef72d0c060ef1ec8a06a73bd06d5adb83d9abe9532da10c0af12dc3231d53217bee0630d01f3b8fac6ae0a732a53c2257c80afd2157d6ed1805d9c17ed3cd2dff9874d7e66df6dad2815a9e27cb517d73fd42d617dce8c626c864bb97d926bd70510d286ae8849450e8afa56152684bf51784ddf684b7b08347194bdc9fa3ddc9d76534853347109f9eac2b74a3e6a17370d9dbc0dcf2450d507effc8be98d88ab0d6bed439523d15b9919b6c8c1e2b056eebb0803014c185e4594c87f6a2593c521495a25c06f66aae936835cb59506bc657478343b955898f325d2290ccd997d7b5ad0410391f698baec74e7f7ede994a3c6f831ed0087bd88e1d5b15e871818f32677348178a258439480dd53165b788eb441c81e76d0572a9da8f118450669a7581591e9d2a0eabda4b3c81e4e28c8e10b1d52aa160149097b5e4be257c53fe1728ff061bda643d35d6e5615854602e2833f053cef96a029d69da07befbec29e5c06f34f751739c52830665d8e7669287b99f28a41bd7fea6e15c3e921dd6c6341293052fc53ab8f6717bad372f3674ce51b32b25ab10551bedcbd6d07f4b30456166615a50f0145e70c8155239f826e0ec33b86a740daee38d1844735bc6c3ea7637a8f53b8a4d24a0e08363e11d10f366b8bea17f351871a394b3750804f6be306cc3bc4ac5d80558d7840c309254ff7f2555f556d24e0ae0ab1fb618a111bbbba70dbda03d75475b197888bdf77ed3a653c73217507256627f6124e9f490e090416dca63a48ae05eb1310d5fa1fe5afdf56af8482c5faaeaab6ab0eb2414876067386146db92b2bb2506f07ebcc91475b68e5af725eed8c88f77938e1c804f35584b52806d1c5be7532316918d7ad85476a12a88953ce1298e947dafd5e75999770d9c971617b9792f9ad6828ff6d753996988ae83b84ce8cc4ca13d60224285681c8c4a21abcd9f7e7f4f4393fa71f7a6918b1524752b2f651ea0f6b76ad571c23f50cb699c53e936a27c7dcfd0af6d4404703d6e8288019b0a1ab8560f1a7d807e608d9418161594aa650a279fd89f01ab1b9c55d11368d69085ffdbe5a6c288f0215aa1be0d92a0841b4119efadb2b98845fd8329faa7f4a5e92fd4d50e497b1cc66855f46b7695d149ca6a6ed4a3ab794221b8cd273b0c2c6ee7d2fef4312692a0f72a0dc79ba7a80c12b1645b146615913ee8f2250234df71fdcaf4e7a7e4d8c85574fe79ffe2918028e13275d242319da576f5249d6066cfb45044043a7a886f47315b8aa6f27ba95c540eb86f66ab653cc73dfb83a2c2f17d0b5127180e50bec15a72b3b2c2366148f1aa4e2149eded10c6e6898fd24a33bb8692872fd7fc9f22c44ac9d859c71c492cc8b754367ea37943c875c0a3031130a2a7c7c73753e3217627f7f712dc1f489bf0549071863793e4551c63f1f4272cfde2a1e6a0d346d5a0f6bb8c9b3e4f6d9e45e49ddca48b7e0d4043b8cf60d301e4822257f509d0f2af19d57575d7e2ce7d3b0de03adf031141178ea4ea2fd9561117cd1e18b563c86473682dc1806a3fdc9965528add51c23002ab1ce3bcd3a96343bc91e1515fd856472e3d4aafe67c6d1b653c38eb7eaaa3d5dd950179f22f283ff67dd9553c72fc5b5292856524c35d2925634bd0d72d6fb3fd8637f2a8d19d30decc1c5060cf4c955176f5bbde005e70b860ae4071cb45be5f8017dd415d18e77a4af15f0c6b6f0098c6b85cd7b233dd994ee157959b481d59fa68f9feb0936157d57c681d74be3c262e71486a031756f7bd8b75c45821d1dfd6492c5fd3eee9c0fb91ec41c0729454286aefd1c8341b2be55940fecc7bc698550bda16e3e92a82cbbd0f2349d2e1c3081879ef3602ac8995f7f902990105b902943958eeab6a84ba1f2ffee09fb118d47c42bd001f26aa9ea440a8fe9638583fda92bf0df1d6d6cf816bc2c5d299d67586f75849c6bd8e91326cb657bb8c3871c52a91caad4b947baa97429c9ef72db5863679ee2d9bdbf14127d0545c42c9fa38545da5af58bb423bb24cac18f0b99fd6cf5be77e294631addaa3652f4089c0795d863c9c11337d4b2e19467df6a1efd81e5cc6bac8c6af39e5f9488ce15368745299a67bc81b88cbc453ca5d2f6d3ee3641a5a11e1198c4f53bbcec851639bc6db664aa318f6e5e0ce568e5b2c9aeb3a88531b008622852d4d626ad17eb763411ac8cda1f84764f3fce4c7eae317a5d327cf568334ec381e3f8400cdc36e4f2c6b10bb7dbd4d02e44f9d46e46d0e125d76289097c6b0553726d4e69953f7d0495a2dbe3a824f4a8a7f91e9b4acf98c3b75c717d99062ac98665e0c8bbd78383ee35a888a5c5b1ca6bee996ca3095c1d54c2edecb0a6e9ad527924d26ad5af6eb464e4a8d874c129778834c7e84a23b00d4cb3344ad886915c77358919cbbd709af30a4d4b32219c800a9df5b461e1c1b55eb2ef0ede6399c4e01097999a3e55df1a62a2e7432bb752e276ced6d75ecb44d6cdae8d2a683db99aabeaf9b4d92cd138a2709a48c1ae860c0bad6dc9f2cdaaf8789be4915c20e4d8c56cb08b97456d8f637f7a73bd8e247e8e5f16f3dc752bef45dfe548c9a0d04f2326c63fef1b0acefae3bb4d8fbb1b817a39da3a6e09183b639d63d7b63077410e294270d77c94e346de20b59113c718246927ce16e75a74dbc1b065c35a30a9cf7b072043ac586138d1ceefd378ef47fdbd55abba927671ddbdec56ab6112d3948ab173a389ec322bb4dacd58b22ba51f06e4e42907326b83b1d3a3d75e349127f13a35de6b2a83316e6b153169cc7e2380849122c8a7bee8e40f91eb50205b91eb09684331114f08cbbd0dcf732947afbafcce9bf7e65159a8f206885272509ad2c3ad202151f93b2734ad15ec5e74dbba8c23ba3ca68d6276a0a23a6091f3041937d623daec0150f8af0f00cdaa2d788b19e7ccb3ef81320e77a6becd0cf62e3ccc517efc001c826e06037e9f7d28f641d76887ca07fa9c013b8e0d200b2d562da7ddf944fdd62eb29c9cfb57798069a720d9c2963bdaf95177e2ebf25ace04f9a43d088d127982bbfde21a8cf643f25893df41ab4eac2d729f6e9de7d1b35072a54768ff2ad0df63f0df657d0a0b43d81e2646e8cf93718e6f430924145e278b10dce02ed338bddaf7575bfe63cad0573395afdc31001fb27430b80c771f58e6913d4deb42aac759bce4fca4f6937d62f69787cdde04ed3cb722284b577ff7ce5154cf3e591ff133fce2661254385ae1bd38d2577db3f840f5a84bb41c3221c7a0665c688c9d173a87e16b09e09b0b41d1b2e014a7c1b8733b4499c5ba73db5b1baa73932bbf5a09f84daf3c2abd37216a268606a95dd566a4b5c41d99df0da6ac80d1db90ded9f754f3d366d4d3e3846f39ce7291d0cdb833c94b01431608e9c75e0ded8835f820dc0ad34667b2c3ed877771ed9d88fbcde9f03db48ecf00d32daefbbc8386ca42887cb70e035b947e54742dd87c8330d0343f051ca6cf18a505846a014d40c47c081946835804cc6a69404fcfca52dc5caf63c91dd8fd978e6348c680a320d060355e6a4a7e6cdfc3f76762c0725f3e75d7050df2a2fdb2ce4176cf0a06aa57b0da93c509c61fd04c19de3cf500a99051f26fe762b63d6e01e77ff083ea6552198f6b3eada42f8d0ebf80db107c96d8fc7ae13cab01cb898a7cf94e6244a75f5e36543d9e15766f8b8f47ae347ba5d9665a02f1d9a31ef548c297fc1cef66656d13c87ef8ea2ab54198cabe61ff5d0f74b1a131f7fa659016e49ef4a6893aab08bb04ada74e1aaaa6ffa21a95b98099bcaa710a27a46fa7ecea6a754905bf5b02e809bb6e72ff0b560eb01664e6c4c3a51e0e4fca39d42f2555cba9276ec34904fa941888655a7ab14295d060e0deab046b6830372be0e6b446acaf96e747c393f8c7b958c0d8e54585b8a9db38f9fc7c1c8dd9a6fff7c9ef7d014ff6a381f34adf8c9d08803c349567d4fded756abe695ceb01f440d450020474676bc84bdbb4f87756aece300a91e256e0c75eb97b95b525618816f3147555d3791b2aa6a181d257f4eaae65110f2388bb35c08d4f5f987b712b9c5647383e2b74c4cfac4ddb44d83de65d3b578d0ef92d6d353a14c3783ec68a891e668003cfbe30989dd7a36d52462f1887e9e194aaf43fca9327b408d7b89ef5ce2a2a51576dfa59c84506dcaf8437bd2c71c02f7ae9657556cec28567b257fd6d82e9f267212453f6e41bbe277fd316ccc58393edf892522b43e19d1217f484ba37e13b6af3b314b040e023fe4713544d973c1b2246810683bf53bc16c10ee44eddcdc7f65c08b8990e166ed9e1966c33d325e66eadd7e448dc2f0e497be26971bfef71e8692a8f9ac93fb501921ab2c0415f9f15347b35c1ce2f7025a8aeabcc4c5f6442d3e08d9d09f374d9139da5e1cafff8f84f649bad577ccec0e80196623f2666cb052391b530264f4bf8917dd4592b6c23ef11442503fd6be38523ee95b346d0ccca4df10ada847312b252615b6869158527a31a1ea73bacd85d9f19e772a47f21fb3ec0447fa0baa1390b15e3675b0c792c0fd1d517bc192b3cb87fdef5415f7c05f099e3c067fa83e4357fa3beef35d22f31d97a22be8eb200fdade83e85e2a25c83e787f9c026ed173dfd4945e5b7f05b24f20a4b4c3fd2cb511f4db46bbc47bb7461c5bfbdce7cc784cbb9a23872558adcce4b93df1ac52cf31f93649125a0bd9d1b5247337ffbad53b241f96b16f28f75415086893aca1dccffe3f33298321b11f849216fb4ac2aef587b28c298155d11c755e309bb281c4f057a79e970be6890a094926f8b0ee794536db27e9da50cd2a62fdf89f6b09d9a6ee89963ef58ad89c15578820e3f388084af1b0c3a2c87ae8c2d79cec5da29787ff50e5eea84dd23cac3366b10b0e3269159dbbdffa4fdf5759954d5754737f991cff267ea6c90607cb8be9dd044b9b7ea2f34fdd1fc1108d2757d9ca8a6e27ff957ea362931826ad552eaa97b60a8ae3b7a5360a88c18167e01b070c77f5b7f6d9ebaeef9a1fb888f9764e8d664643fdb1a7d2839c182d9f8cbb8b4ff177b62b6826239777275f0b08d1d315fbf8f86f435bf9833a6b4f1d73825217ebb035f5c556dc3a7465f63566827ea559a4a3eb90add9bbd53395ecb024eaa55150ab059e798a5bbd12edaa591b025cf410155eb79d3b3bfc239d5e58e2c070383631ba32b9dcaded826e712bebdc18f9dd836b774aca93f70fed8a89770dc3bdb15339e405568c98f396919a6472e79a65adea8b48edb28da2e0b23fded34477cd05d9640ac6e307f1f171237f2730d041222a0b08065f6ea80052ef70fb238d9ae602ec146bca1652fe1eea9e613d55f652a9ee8bd6bd0f01736d1faf2a4c8c3dd503e20851e98281979ceb439b5141494f96979581344680ff959316bcb38393b5b5db519a03d0f1664ed34259e177ba4d605043fce46b3c21ad21e6e98b303edd74ca529641d0540782eb7dd669b2c8c2b6f27d23ddd75362ff0c554d50b281171bd412ae2d2d3d1e4eafd8d4593135035ec61af928db52db8c8737321d60d4d81599df0e04276300a79c80abc069af024a3c0579abbd143a9e0f1029f17f37d4c66c5696e1b853ffa4b45d67c9b786b0deaed9b1520d43c64a8c4c34c84ffa8185fd68f71136cfdd3315cff7516dcf7d095979c77e0e66041e934971c10f184851943d513c6226bada758f91052708f06e1e9dd2d465a6e520fea1e4a1912393443204d71d0d26c30b8a85bd407420b780e2cedcffff97ea3a75a99e2f624a1162101f38dd1e52887fe9e1034c346e9242bc380c86251149724001693f3c757b621581901e53fe2302f608f1833ce968c7b77fccb6ced3447ef99220f13103513378024c7a9e609632c3b499120c4cf85ce9f978cf4113cac7665960db5cf8f7d8f2c758e3a916597e6f57b1bfb481948a88bf32e52d7f89fdd07c1cce78a5ac99effb69882ba0aa0b6d69151669407245cabd9c2394c3e7876e1ea9dc3a6734464b6710f5c1cda98da3ba4b90f90c84dea57a56a62a30e6381bc75a183918021f929f1529fe45dc707f244829212cc6bd52fd88fbd0a8f22acfbaca89c416ce7cccbdabb2d8e0e4c5a79fa785712f99331309aedcc229f73157311fd3a2afd778da0bba1de50cecb8158b88f9839ee0ce8d8b4e60959c63cc88d94953fae19fbbbdb7720a99a8b7c622e93c785fa345e3f2f409d5f794f0b9f6cb40e26ee5711bc59ce837f193ee06804b86850c00ec198516cbeb4606d736cc49bc00e8db451c325b3a1063e2c9b93193db71ac1cd04df1ce4d54f998ef93d6f203c39363eac7fce56fc389d11f1896e33ff2889bd21f94a42dd421beeeedd4ec6aee1da8efe209a654d3ccb446ecb4898d82a418bc859552d5003d62702fcac8850759922e507d581bcfedaa28fc7ed06d9b5a00e47a2fb72c2e4d211d88a35117d65c75287da6ac68844dd50cd7fa062505c9a1dc1d677cf81b851b5dd26b49d4a96cb9b34d355af1fda6a33c48b680e4918247155412619eede082525be0cc001fb36d189068472ac6d1fb98ebbd66b2b348902107c56ecfd2c7589e578976e3bb1777948031cd98235cf082cc73025ad6b3098d48382514436a310d046587a4d67a23d13fd3e062928105fdf01f8a20f239d17471922eda6c4a75856f2e34a3b6f3116ff13a4efef2741b1e28d6d2b304a34f067f9558957aade40914d020e94f65c71eebcc3d2eca0d7a294d143e614ebce7e688c00403c6597603ea84aaf499fa9e552a10bf2e3fea4a5eab055f0ab7763a70fd2aba9455987660ca7a8fc04f2f17798e3666928cda03930a14f3e0cc2b1bc67ddb85383dadd69260ebaed7c3064e9e98ce22763979a071fb444b4a4ed7a93ba1dc6948b44db20df0397b69753a88709de6fb061303c83c26db7566dcc79d80ced2c33166dc126bc0fe8766a9cecd6b3d933e702b57646e0b448d5a8a3aa40faf8d0d436a6bfaa6dc87da4ad5d7fe28170e61d0e4c09cdf43acd6b71341ba422d52a24f172aab29be2bf60a09969f0ac800ae25b592a540851027244b402c9e31fd8ee7f49d84aeddbfa9a3f64d87b6fec160a8dfd74c5b960f785d2004aa668be7f93a2129c80559becd0d385fc1149b9f2fc60dd80cf1609d746c4fa1e815f78421acc23bc4fbb976c402c19db534681c37e942e15b344d4b0834a70e406f72bbb9430736e00971ad44e7bacb86deef81f1ad93ac9176540ea52b90a48da6d7047fdc14a67ec002043271d84936906c0df4a7f13ec67a9eb149e0ac71e169eb0ad254d2629c24d8f56bf3b0e7d0f005f5e89d3d7ba3a3372c785ede271b49c4f6bf903b4658b9ff108392960e5349fed923bc7091acc2ee63c894db1c1752874d04e22953a4d7f058ef670cd2021533c845dc90b709696d027eb138908d76256484e593b9164af1a3776ef029636262b53369a9bb36e1ad6653235940b9a34b02d76764e0f55aedd538c0327d6785041eb8ba48117edb07105316b6103c65112a4eb63cbfe763f0d5433e47ff8fdc39fe5f28ddd40288b8c09b1ea272c32efdcc2821b8366df93730b8e340e8c1f0f0fdd16da9bd78fc758d12d5e4f40d40fc56539344d22be4cc730ec154094f5d9bd01e85e2b2a9b69b87d5790258f285f7ecb5e77896cba7fd9a4f83b4584dddf4a3bd53fb3ce2f1cddc35dbe9505fcd071a825228c957376c716ef32501801586e1cbb2b3de669405937878001c6e8a6b9c2025a1e66f1a179ec7aad0f740240fd98534709c7bcead43c15b5d4d0779c14906392f3ae35d9a42d58d7d7966ddd51ebd5ba233919e171a867542a690607b643f491bf19c713061dfcbdb5586a8fe2f857ac4df1f55e7a7422926ef8a6aef425557e7c4be65550889ef395ffa9b5f32198d0eeefd67f584a030385a8bfadee502df6fa609118d983a42528fee8fe75db6750f61eb5d5988363286acb90f19a6915e100b410ce373fa155ea93a30d4c46bb720f39d82f74e31358a399319175dd5040d5a67cc4839a8849d13a4fa24c1c8d2247106ee4751e76c590981981b7541235be86c82e49685e05e699f4a5d6902e56d870a30988a02c4079621c65af406819eaa64ddcc84436cf8e8c5be952a73d3daf7b83d0e897b039fb7e78fe91d6b3a297104177a00a51438a2c2e68b515438326b476964665822c3de8e90ccc8edf96bdeda214c43da9e2a596ab37132370a469a649e8fd99687364b92f6731a1ed053663fa329980bb7fb31245e32aef4278124cbbe6b1e8a04612f143360821b847803609a7b635e4fed57e031117cb28f8552c6aa499f58dbcbb617d1faa85737ed1470034d7772f27f4e4102b7f4b384958969866abc62e0e073a74b713eca296cec5dc226abab09c1533eb50833556260f4b67f7fa46f6176b373aeaab5e27db799d734911c77d058e41e9dd64b2f578e00afa57249eaf4f648038c2ae0d0d772d05e36d58478e458c4fa338538a5c5cc276d186bc9a8d5bc2d50987e3b0ad86e821c010c78a39cf41a7fa85a51d568bba1775b7b1d6cbbb2a1a93e082ce9d4fff5daf2b958e2b775c4a990dca952284c20dece90cddee8c75d2460a4bfd9d3e76f9e0de9e2746c7b9731ff70c7b43f7c8ce8b23c53dc0a3df525a04ce63bc78c7c65940ed4ede743a1d45a1a8cd249514f7e3f748611358310f58699bfcd2928c4e3dd1f6d73bdc58592fc726e64953fdb865fb8eb2f08e1bae1e6355f38a34294eb0aac2dea93d6edfd1dc1d132b39227909b3d46e185d5618be9de9d85112f1a5bdb9a2785aae1a8c5aa5cc730878856d24a024c4dad69d5a7aed820c90bf2a2347b42a8c03a0479457bf385aafe98437561e485b7a420af357dd39283b637f6749a8b98303e59ab147424236fa45d6d9939af25adca9c99c3f4f46c50357152aa9f8e576e1625def2df4eb6354d5cddcd6f673950327a5c27fa35f96c3464c07de0cdd824995f1391e4603b8985f793c88e9fa5d80b180c6c872f952e6c1a95015e3b5abab882ecf65f5af82127072573099dbfae55b48acb9de471a0c5fafe2796796c05a94705b6c5d415c67ad25c17e714efb7baba6deb2f74ec1b3d40c93761d340bd20e3a719fee3f83cb606ede845fa772d9aa8b7e4d3fbd237e32b5f5e3f43f0fd490eab3567afee1002e1222fc7374cd2899421f1d5109618b417cb6bd0f7db0169a6631a5c0a9eb3ce3767e9788b14d4ad24dcb6c05536964be4f7359f5572500dd6363f02968566557e3fef537ec7d52421762024efc36035aeb80794330597510b94eb801be5f32a0120d1df0975887e6021e5e0c0958790cd6536801e5a75a9f9efd983d27bd920925d1490a821a7965a1357831bf4e94613c8519bc7f2cbff87ef8f0ccc7349a642353ab5448880562f1f12dfa5b5686d6f5799afe50f05b5f5b52591a136d8b5b51dcf715ffd3e5af0987dbd9b38ea80c679dfd2880613deee52481e541d4ecb91e43729aa4f22e5d5309708dc3042022eb834dd6f465c7d145dded0d227d6b20e612db76fbbb579425e995015fce01c0dc3b97c09fd57bfb02cf68c31a514e6ec9a20d70a3754a3b7987ae0c2b76af639a0102bc172f597f3919ac944c4de8cae1de58b5717d9ad4d49185799a57bc5d0dbf90825918cc3d3a8961d3d361ac57c52b17dfd668fcc4a9c6fb653632e1242a6c7bfb71aaf7c1ad1a2051a07f3d8addd520143e56ed07c1a562b5b132462891573788f778fc11131bd4ea26024769f7669f219fc0ffcb8da3645ff4aa085aab301794a0e4e9f2fbc96da424ecd4a28fb5cecce4b3f28df87c80c281d1faf5260733f5455f06218612db40b4d4511fca5132668563f911de85d8bb4658891b2859c4e69547d2838cf2d4f7b10909c7236720fd3be7cd9038ff220bd36801b9f8d06b0c60fa7dae6dd00a3ee4092a98d4459d0b43889360db7c48f179d50dab2b9cf42dea8bc8a2999d0220644dee990a36ba1bf0af6d4ec23dc6d0c5daae5a9d8857d6441e6e70f65e4b7d76b5288c2ab9082d5beb17d4ac7348d997105de5e553dfcd8a08023e78508787a48aef29d0a80b1fac557bbb41acf6bc6d2b2f80977899e316ccd5e87a61b307cd47dc4b7c8600148473a8d9d6a2d55ef3b753d4789f29d2c2cac0e68221194123e4eb4203ab5c7cd79ee46426434e267abe83dfe322df86fe7342f0caa8e9b4a61a6ac9b8651bbc99a6393121aa79e4d761231b18980a0244ccc26ff8444bd7afbaa641d063ccea6fe89e6b0e7551e6528e331706ed8ea7745fa72b6d62fd7d09e9db063ef045f985e99f06fd1fdeeaca1fb7104307b6a063a4a0efaae76c23b888e8aed00d3d95b91f4e5f23b32bff946c7b61b04924291bf0491520238edf28ba3656032208a2d16c40adb52c0d65f03402a918f0bb42599f5f3da863001d837538a57513859ed9f0fe29e4ef05ae4e9de650d6c4f045c8e08a4a37375d80cab6146dcc7ef8ce219bf79e4bfefc1cb4170bf10efe4458153a497b91e695879d30a4a5dd3c85520795f4e11c3a9505a4eb52164be68fc285a7cd5fc3f980be9c969f54ddf9ff314ad1bda2f7edba3201eddccd08ea982aa63950b8b67a9148a100085d0c4e14468e513f37069a5f0892683b5b3959061b37a418240fde9bd63319225b134ae5b7f79067b24650a20659ab901164dff1192595a9aecac4df11fb2eead01fb9bc69c9f985e80b63c061a593685c70f66077306f551e3f763a556b439eb01aeac264dcf761bb2f78870a59cac361a3c26332987717a3fb444316fd8c3e4e5ebaf731eff34fae1b8ac46c2b3405bcb35d6c56dd4b3376f18c0b3669247162883e1d29e1a0e619e81d2ab2ef4b33138d9e3063ce84c60292c373d8e62cc8fabe80478658459bfd59c253b48fc2240bc391229da5886c0fc989314fbdbbb3343bdfd48f3174debc561b40163df5ef24344fab8cb03a54cea87d47a2ceb6e50381c7af531094fd85aaf5608d4ee4b8cb6c8df09fe7b6cc8f48910356d51eb677e0807ebab061696c630207684aff2e2310adc261a04ae06b0e5089e1078710ee6c37f2ffab3375d83f7fe1c603258a16f04bab560295aabe47f7a485c6a166f2528207825feb65689708683718387b7a899a5eb62278e5c54db9c644defc2b6fa9bcfdaa435cbf55e9eded0b07b09507341744288704fde6c2604c9aa8b8b2fa1ec8a3d0f49c94a995f24fc0afb304776d006b499f3d71e3df0af54b9038a7be6ec9063d855e2964e42afbb2552e812fe63942eb9f2a7f1d69a162aff6bd7ad2d9d2036bf9940c6544fef09267e1579c210446527f791061d2fc282c61fc86c776484466315d3686a11792c3b27914259e0939d6cfcb0be7f180ff8acc93e8d4d19e0d06b24853433c197af037df7ef92befc4b2224fee996bef690be7c38cbbcbab699a56cc02b5a34a509df573a75c5879f23f30cacfca43fad8d6676b747bbeeef6e837eb68d989a0f32e4872085000ed982b6c5779c6ae05931f74fe8a8c35e3a03827256d55dde05e441f100477086940cbe8c686bf657976fd3209c9785338e43e6c0287013b9843bc6f7955182b236230b8d51037ff89938b291150ed4ed5f27d20d61ee08392a8b435c8d15ac0401bdd3b61716f78cf2a759825ed0afe56bb5d90dbf3980be929eed10fb49421eccb70dbce9959ffeb2d4287c95de887ebeb259f6af886a88866ed9aaea0dae933c4c445b7b69b56c323be76db6408fbbda0fa1fd37ddfc7ae3a696ac12d5519893f507bf6cec3c4826c622d1aabf62e811f4d5d17d6d36f90f3969064a81e6a254645aae068016cc9c42495bfc64d99943f1d41f2f40667316898a6041adae867002ac55797dd217af123c504068a0d2859524777e33632374fd72da131f2802ad87a88e1487f6ffd567f3fad0c5590c8c8a477736ad89542c53fc42f79b31d9fb39d4838b8cd9ece3bbfc4a9ca566c5b9b4a4ba29ff9aef9928f83d3eb2fdce0e1e0bfc91944a087af339d7de8def229b76d4a550088fd68c877521b15b9e0b817b1c8f2ba35b9d2823a0abee2756e5f989fa45a2d3faf916cf66d8ebba73fc94b67e13cfb7b86f899a7467012b982ddce0e33d1fd99f2417fc9f480fc787671056f5693f9e6268ea41ab45726687a4b01fd2f51b2c205ea25f20e86e84f4c845d048257b4b9d63798f4160b3753db20cfc63bf0a8924965bd89b78a3bb5afa80cc24ee120634b76fce64a615ecc7b27aed8fde409b7a236f4fe9b91a1bb99813ec5fac0beaa05e2d9171eaaba28364ac96567259da8d917df15031d947824c722614ece48ef948add35ccad411370433a03b516ea11024105207f9469d33ec48247147b163cd6efdcb596d42f95e728e9781658a0a76dfe76cdb3576738bbcedfe99ed923a3774741c108c308fe21b628bb4b4fff968ab221f0891509158e023b07965887cba8f9fb2186d22cae64d26ebd318b4359c7889ad839f67846ea7c8056cb70634eb08bea9e13b2b767ac28fe9b4d5090cd5ffbb67307470eea39b30e4b891753da697d9974b1a01da4ef0ea6c80b4e534b0923e5c1083b6a8842e710e71568d96fab297b50ee8b208f7a346070a19e34e39cd294e6d9b121d1a8e938a080ac277370ae772970e051ca267a9083b4d19027a3b4d84d663bfb9d527b9345b1d56edad7c19c54b8af3670d5f6542c630d906ab0c1132695c0c0691ca9e242d30ae8c2b3e6a996e078e2cb549e929bbb0e7b8458e8887f0561f074ee6e9e342e9c1da72095e461662136ae1c451ff848bb57e46d5d52bafa3fae14e5b2010de98827168bad76c0137ddf311d978b0e9084317d25965857e93d0ddfb4535a362357946ff80e1865240ba19f4fe9eefb131f6899ac22d559dd5cd529a68ec00cefca861892d09903a8bd139989e99b937f4bb9d7564b2f3ad3dc812c8dc462d8abc09c636458d8c4927e30a54d9334fbe66b7e5e0a57618fe8c1bc6093d307a6c19dffdfbaa106a49f54a637b77f481eff9a09d5543b4fa842905ba27bfa22873abaf43ed7a615ac1e662d3e12b9cea8dd996fc98bd3202ee8fb507edc7c5f3644b5cd2a523ba0700545fcc27e0c522a20da5bdf8d5386492578f182de9d7976580d81a5096a3b68e9802f43a1f048be8f04e9ea11db470b327f4a1aa7f4b1e9c9fadbd322c4aa36e6330aa04af32d9e6f8892a849b1abfb045ae2dc18f6827e70b290bc2e5356102a56b7b1b75d731ad6217404eb952e7eed005404718ac6773979bc0c944b82685f915aa207007802022af7893164a71f9e47bd62027369849ee316e82e845bff8a5ec7bac7d675249d1f2d0a3c643bc2106b2bbe8e7d3b629d783506356abe07068a265eac2d323e657894d9b9102f79268af2262b471e2fb1ac7df9cf9b40e2d16aaa7f117840f87e6f1472382e23ee867e60d03ea10551b5ee2478d5fb4cebfe74af5650bcd38ea88775592b6db3b2f52c364d9ca0ab4fddb75c4009db9fec0d88dd3c26892e0514561a96fd56e22f5ebdc2cde78416c82cbd37629c0965270969628ab13aa44e80542ca3f1dd90ccc9c9faa9697bb7b68f36ec253d4c7b350f97f5cfcbd22cc3c8d4a5d025e7e3013d8f699c7df13b388f81276ab7c61500c027a4000618eef1f99f82ba35518dc220eb1e75cd55d6012d116248e01bc757e1254309448f34582cf57e9bf9390aa65db27f3271491509f65ddf4a28bc3e74ea6248d9f61ba3571ac2a52b3a73ac48aaea02f32a7137e94a45dea25d77368f1591fc7bb124cb02d00382f69349a3ce79fb935f518f3820203fc05f1f2cb04d1e0db8cc51613e6458aeaf7792365b4d4ea5d602090df6a3992f62c4b7a23ff5e40a039acd97cd73b1fbcd784ab1f23a02e500664f902960106b90291399f7eb42c525e53ae6fa1f6d5c23826d82037d5d2cb16de7b43a5ee5424299adf1967093957088ebb4847ea7ea88b17532e74f6dbeb2b8230576e9346d4c090e4a69a7511c886d89a51b2513a25411334c3d2dfe698d26940b864255df4ed3e4b602cedd903503d5ad87af346276406e2d27f2a987e21216d557c213ef54410640bfe31a42303967152cf333bcce3ff2274adbfafd6cbeca2b9ceba63f7bd6b2227267e35adb4a84bb3484e78cd1aa7fe1925a9c77bfec8673185d266762d50802e50e6bb728b69908fdac9e45d06279a665ee214d8b758d3cd9888c39369a226d0e0505707e557501945a9d2292578e2dad8a1cee38fcfd53152186c8ee5235011c979a3690e1f0b66e52ca57dd94b8fc62338a5f192425723814b35181359776a4f4a110cce7aea71040dde5d5bbf24f98551a8265a1efa57f2585705644d1ff82b8de4c6f510d4a2fbddfdbf36867a9d24d8e69b5f535741acd6586826857aaaa498bb45064af5fab50be4148343a16d3709005a1ed8bc0b6f9829343686364333d49461306d0410fa6f97442cf5a3524f6e6503f4d9993217ce3e573c8474cb92cb2faccf64fc56da6a23c669df289919c8ac78ad2a5f5585d3d0a9ac95438c78e8f9ab04f58e3292ba4efbf4edc9b3f7d8fcdd1e87ab56ba82f3a49e36d21d3d86d71c25343f417e9c4f366ed5515c372e0e34d8136b3ff793a061498e1ceff2e0a481c116e5af02644ce3f3314aee8dde3a9084b570d439e080e08ac52137f8f1fbf0760ab1dbf4c463cc0a6d8b40fdf4330ce052893cfae1a84055d972874a26d7d7639baecf133d7a8cf6731afd73efc1683e31e9943073a55238fb0678243197d74d313a4b167b479a37f3beea25a747aae87426041c148e09b031cbec2afd8ca6978f5404ac20ec7e61e440f91eb50206b91eb08970f5d75aa6e99d61babc8193ed412c6d6c2e1867a9012b8782e9b09aab605d9f93dda3be356ee3a1b4c5b6c99fbff9d8088a04cc57e7f59355bcc8162f527db30b1d4cc269efd810a96e931d9ee176d848f9db174ac109be9a4c03b874ca9d85a79f4b14ac10eddbced0b97af06d778b95abe82816682185b054ccc900837816c1e0cbf1335865acc165aed7fe408d25cd8771d75c9dffc77aaa2a420d4bfcdbec6c41ee8b7ac5630ca7a1e2cf34b6acb6fed2d39524205b111645467dd25657dd60db9d61a909654385012090086f46ff0907d0f603c9555590e9797915419f2592cd08a92ee9cfb43cc48f3545594cc6320bda1f6c78bac9194e8799f262f0d9c1c64e280d842a435442de14f06dbaaaccaa40d854cc45eac8498bd6105399ea2a846dd6e17900ebea967058aae3c3937d573024662188e2f21097f1c3919aebd9f2deb12abd2e2647814ea8b9b8a25691c0c5b1839ff3887ca1c9ccec603298336b84c4e5bc38d1180c89ca75e68d73f617ebfa0e697357bc420b9ac31a6716222f987b02ad9c4e5153b7e669839e1ecddb7c0c82777418fa9ad93483bf069a33c2194864549b1d4fc4e264b8c3bb15b34f8fb7bfa40d0ce1975b9ed88a3e511992809a07bd78fc265543016b62540dc346487d426f708fd2b0f028a2186abbe22da726ebb1f271835755aeb493ba60f1d5b63506237edead92a02cf22ce519d023537a47711e1da7cf9a9796712a6b725ce4d8f16df4da9ae015fba2e5ac8579ce0ac3b02121f377dd6af5879a572fb60ec5f907379c7780e2a77428e89cbd942e12dbcd5cecce554b1d168bf2c7183b3434ec10d184a02b71d1d2aea68f6e847977304159473ccb9c52fb88e194fd4c6dbd934b5225e0c2173b1d92d6a7e90c7f5722a518df822e98988fece8c208aee2b54a8f9deaa7c8dcf5990c0841eba1ad691753f7e44c3f0b152075071b2ab0efa35c5dda5028bf8c072bba35ef06fe778a4d919725184aa5247337f9d0ad4d5e6933dbadd4d5b8c43f67714d04aed7f76c7b29bd2e8228a6fa5f10ed27ec8bf0e611869015a604580057d7bd8947a78f071a631e874876faf27b53ed78fbf035d4b578a0abd163395f0eba7433bafd7c56c5b45ac138c2395b34b83eea9b4afbadc7dbf03c646f1efe2865bbc7cf41c6b8a9765bc81f0592e0e2cde4c89b257a0c7b47ca0c6e2fb542771bc579b9555bfc1ce5e8fdae29f10631c086617bd09279507071254937cbc6a8d2dc2b0ab5ea69781265c7aafa458cd4bafca47eff301455508c10dfdf4bc4505cdade70c65da114556e068830820458c8bef613cd2ceee4b45cf96828016cc991a6a51ab42251f039d3880beda76bbeb15f62dfe12b9b2afe4f418fdb73c4ab1ed46bdc39c0b95868d0ef851f52bfb2a25309551f9cd53ecb695716819ff643eed4bdb9773f0421f21d29cbe553a2a9b34dc3a9bd6a7209baca48678a898adf90e47b643a254674bc551bc314fa9d3a3ce6a1394d559b9e2e62f1421ba2cc6e26896647fbf6d5858711ec5f5e91dfae3463ffee53b68a3061d72fd4d3359bcbd56ad7b32c96e894c0d72a90bccb1c27fe534a0549a30b0bc79a00a4a8f1cd45d0f5592d3db71896210b4b6c6065e466a48eaab8646fa7883d8e31612081a1ff7979a3ed9904be99db071d3448c0400e6eac6015ea16281953692c2322bfd7f9614d4cd99a31127d7551c93bca235dd54a926fdade04cb14cd95a2a6fed0550f85ec2fe016572fc2f8043bcfe54648a93cf7baa1b9b640e5ed4eb6f09393de478c0702a2c73bb49bd9476186f9c00c94f73586181f9d4f18159ce6102972b59ac863ebaaab3ecce5da273f6f4c4a342753de879d5ca1fe15880bb3009c3e6dace70270b23ec8a8b3aa8e5d80dceee4da61419f61c84dbb1cb09485964e57a8362c0999feff749ebdc5e18feb339e5059d14112a63d69c507b42bf7ce1b6ae72cbe58ed12e1b8ccf2f22265acef3ad54081f5a5eb8212f7c8a75c78234974fbce3c7101375ce96b102261a91a47e6f3db6e8c7aabf51637f527bb20768d3073067f114a548cadf48a79ed5cb616291424bf226a91f16589d8f51bec9e4aa7651d03fd31efcb02b97afee488447f99780b2610d85c35466942f8dd0a722f4c869e8194948fc6e0b3d91531ad81aeec4fd68cdfa9071033dc51b4b24ad04e07ba0bbd76e0a2c6a6fb57c42bfd60eb598690d5e7057f6c3add56b60fe1e803a59c5c01a2c7028dfd60fd7e4f58f01210acf36ff4aee864e53a5f2c465ac57327e3779d035d183388e9e1b6b9b1807332f13959f8f4104c47805464e79d5fa7ee1adbf6350c3146c6cd310fa0aa866e5882f521a06101f48d1ce14c28897feb16c6ef344f018608ecd1058474f65b9fd3a81141a81a2bfe99ea97212070a948faa2f6e2415e05374065cba28bc1ec447c3a372e0c7b8aa9a59525a1f05ab581ba404037d9dd1b68f66e06abea8b32ec69f6073e1e28eeeadc2c6f6ca6a2d264dd17ad863eee494957d43b8487d76686b3836d00ba3f3ee40bbb2522baf349a5fae503fc5cd9dac29a8af48d71a967e966aaff046abe2e5e212f625cc78259e97c3063453de93e0c2fc8a649bdcf3b82d6666ba223f0427bd8d1b2568e96bf066385c1001676689b31f20e8e1da00ff162249368f12b3b454357b73f4e342fd8eb57dc2735213af3c6481aa520ec38bfd32f9053fea803258d29e1b630e9eba099a8998be826bb6f978a5dbb04af5d40cae1829e3a9a13f6dfc0969bf73f5e31d2a8a208c61854f1e49362c72f9efbe84cecbfad3057b79309bd5788761364faaefc936f99231a17a75d825f19b92a21cadf1eb29f5635bd4550d47cc03161ac21802ac8fc554c1917a3731bc3f0c3175de8e5dea13839687c5f09fb3f1247f7f6eed70ace3a03bdbc3c1b57629ed758ef7788c2822ca0c7901b0949a1ee009e23a856387ee4d83196553e8071dbdf430de652ce3ee3edc4ca30448033197db8ce5ff1dd62fd21b3ce5c51dd7abc58d74003c0efb800acfd005b57bb45663a00581835edaa23a3468cd49455f2f2cece652ea9cd66e48f1ce641d204266d663041f7072bc3a3214ca632a4233c432806a5a346360055d3762a89df57d5fcb71c1bd21e67303fb2690145880ddd2c6d4b36058627fdb3e320a3d23966ac3c68571045b72496f6f77b3b69a1ef3c6bf2c9ee9ed85d7073271c9c75c7347ee8a23038c0e56fd9a5312cafdb2da91807add3a2f4730868a9ae92176bc098fdb9b3694f5abecd306f9cd2a5df3e56d401c2e2a966573652e5fcdd2216554752e63c1c23ab461b5c7b1dc5a140c2e763cb4b244c2ab65fbad17ce93eaadd7b1bf1153ec9c604c09b37baf3d2f887e1bc3aea3ad05d536553c16fcd5bb9cbc0b7138b59e94e974c6b0dfed8c7cd54c351b4e8a332ad52c3dcdf6ed951821a0d7397bc00c0e6335efc3ef029260d77a734fabdae91e55f22aca9d024e8b13556f75f0323b021e9e31b73bfe9383b199cc0109d1b93fac3d57d6fbe4298879716e45a9f61332d578a3228c300d56cfd1efb92dada788ac804288b14ec1cfafd0514b3f197461f23465104ab65112e2f568a118336f82a01f5989502c6cf9ebaf08df50da15d939979de6c7760ef0ef71f81651242bbfdf1447e6417b045fcdad4f7e43c79b72a29f0d485de969d5774480553a366d01a1e1dece17d9c5d91f453f50897b271d370323c6629fded0d37564aac6c702856bc567b3ee8bcf521007d7cc5fc8de41dd34da2b2721bdf3f085ef26d5f6f0e666127db8c3fd766374bd5632e4eb604d552c0e01fa8e1213f4285bb29c24d6c31792d150e5d2fa023b3ef81f7177d5a8a445ad5a573b4a5590800e83c6e1d677695486ec816613244167d02cc3850626e454ff224a0ceb2c27764e7449123972c9537901f99f101e7b083ec5cd9941f4d5bc47ae58fcadd99ae85e5ac377b2f1f41879446009f94f3cbfafd8eb77f1f2694f022feb15be94bc8d5c4dc981ad5d11eac2d1b8e7d2bb15e875775a3e9c0363e2907a8c5df5a84f64654618f1433b74496ccc6046db0ddf6e157b870cf44bab7a8d6ac920b8613e62e8b07f376fd14713ea483dc060f6d1956554c2b22b00dcd4fdf1ede749b13a99c354805979e7ec75d9444e4a3ffdb18780259632d94e06a50f0861b988e541bd9ddb292eeb97aa06a6307f20de2c5fc1dbc196a290f41224b98cc6d7030c0b36ca49b7c62e9b6968604d587a1b939eeb459bcc7251bb6bb158e844a2f90faf5b142a698a36005cf1c1b7feeed5f25cbaa8630ae0f8372bc5167c82c18766af7ba6388838a6e4839eb513b40628cdafd6c8326e355503888762b3bb98d2eeebbbee7523044d00bc8d24c04cfa9cb32fd5ba7baf5d0881d78f6fdb2ae299751fe47282441804e1bf840b6371ce15862e01488f1f30f1cc461bdf3ba27870a0f98f757c56098e79a60cb09246ae759ee7d6079255e6e45ce4e453a17aacd073ee2fa315fc93d2b102441f6c49630dbffcbf9202b9a8d37f73f215757aa6287815e26e5546ba58e15477e0bcdf004a7f56a3d140e326ee1ba891fc326b9781329d5511e5d57fb56f0800343e30480ae79f0cf602620e6a4aaa6f3c920bf1fab19aaeb384a0eb02976cc7717f640c458301b1abd5bb90fb9a4e13f635715f3a223959ed7c36723f466843313e30b28842b1a59df3e347a5837401e32ffe5272460151c8962dce8ab29ae5eb1d64d9e595ef749881cbdc648fa0c1ac2abf93d978f0963e6d445cd951d22260a80b6a3f6b7d18e30a82f7c304df3350ba20ba07c41602ed417991239c199446bbd070f66157e2f159bbccde7eaf95ff6f08fb1923af97ed666f4a61e3885993edcd79c67e3fc2a31d7f6b5c1d938ce1f4b89bee728e366998a84ceb205f4e8aefcdccd9e04f3fe10baca2a786e231ca2bd5fb3978263e2d426c23b5426d5674fe7c6110ed989ca78bc03291bacb730dd8ff672c48de5b9ea76d19d28f1c574b40d00d70f92f0226d56211c53eb27b2421821d6f4f3354d7d3559eb492703ccd39dcef07a891e70f9c43af895e2686cd590d378f557ce9d4c2eb7961632ac9b6c121254780ed8012e85eefcc5d727ae4c154db364082dc79ff5d31f38c9f7bb2101358a7b672a530bf730e592339b6fa816a605594d6159831183dfae06719ed9a90152b9c3999de5217eca223af8dc0fe1a95cba7ce603bff4090a17ceb725cd9294ad93f8d6f312d6fe4e8ee6cd2783e255f6bf615dc8635738b85c5aaa8e10712a6d6f9f3e33a874e0d76d3b377a72a6e67d340842e7c53b19da3de34d37dd6d94c12c2727e97a536d8a81ff232d00d27e61d6ab57fdb598dfeea5d9db508dbb0ae9c1da9d97256dc9bd4dd519073002ba52993d5502f668e1067397616df75d4390dfc4d89b5435d4f0f593fdef331f706266735ad4f2f5491155c71b91ebd62d44b288b01829dbb3f8c6752019cd6ded5084a2cfaf7e7083bd9921e4f21f3588dd7cd8403ace0613ee01430adf9ddc8c1842655ee9822ce70e385f975bcc5ca737369dbbf37dca819df9589cce5d4cc950dc14d45b9734912912748dd00059b70ed023564dfad21b81ce671bc0f0439dd577fade105d5e2a84dc055eab79dd8d26513eb84abd7acf381735fe4da9708fa4cb638f18631cb30eca297c527e2a0715c9bf3448f8b181dbc7b9291c642c62080dc45e1dc71bdb8e776443cad07e894304cad3ea9e97dfc9ba4109efb22a51e01805e4e3dc730a9d6c9ee55480c1ce7ccbe29b0269a1e81f7bef4723346d95ebddc9a117bd8792c04b5dee140a32c5bb9b5755910864a512c2004ff851d9688117879b5f10e97d37081e545c54f3779f1681ae8f9eddb6937c9d13b429b462325c9949baf76e3af84a7b2171da5b7c7efc4f73f81faeae09fd2e5a4d6bc8a4e6b0509b6dff1ab7f218ed013dd9179af5c2f975289de4293a81d3ecd0f731e2816a3605756c19f2462ab820aff8cf0f97c77252d74b25059f22618475bb7ebe9fa499a5b72e47e398980e3688f1c64f0436fdd22594d913d4991d5912f7dd67004e873236c317d21b46e1c46fa206adea78e2cd604780b23c3d21ed68545a1c5ceadfd545da7e756ea3fce59c14ea2fe751a3bea901b161da6e250f238b2720d58d21adf49353a48213d1904602837270b3d7dcb8f075985ee72f85827a44617df6bdcb03eeb880b3e837cbeacd29c53a758574caaad82f00887f5618c8904b005d3125fef7d58e9fda74cfd3eda712eb212cba78656a65aa2045dc63528333d6a9a867e9ebde1cfb410e74697566b31b7728192daa3b3e934e83db91bf3852fdbd00f65ec006e045d66abcac53086516e6be16122754a2953d71cc9b9fd7fabdc204c204fb5531911d10f504d30b17c353500c4327ca325a90d2ba15f841e97f8babd3edf6cbfa0bce0633b5b845e52ebf395d606f9d426ffc634fc6d1a5eb88a79d4d12e6964a0ef1042ea603204658eee30e0be930931ae83425e27ad6f4fb447bb1410b738bcc491d757c434e233d3ced55b7796df43250796516a9f7084dee38ce2a1bdad15a351ea51eeb64faa63020846edc29405c910effadab11e953f7d8855ceef6e5b99a5f148c982887d7f0be004571abca059aad71bdd78cdc315a62f525b0fa35db09d39fda03e02ffbd75a671f8c4c07078341c372dc7ffdfa8c4f965016ce511d6cdf3bba7261629f1c9c7151cd641b52cc796b40c2947d9e7b742b2504d6a5143d35a6818aea4d31300698be600d89f446eb7855f49becc1f82bbe4f9563049bfb7f9c30165c3f22ed20c24a503db8daa1c3e3c54d5551f44c2fa8b1fb6653a9207b437cf597aa2fa6694fcf23df3c6fe6697703922dc1eb6617975d658eb0a08d0c9fd48e544dd3302029ec28240d8fc5e33ea47c2b24dbb2a92b7a8d644acc566a863feea3e4de3981911f21f6167f7c128ebd986ab2336e116c0006a3d7cd3b12259a9b6154856d69c288bb86c6c383dd91a90110fa99dcf8bdc577cfca0d4a04fbb725357c319d0112183367a333d8aa7f779edaf5257b8b7d4dc1709e1ea5e2f8711414bfcf07002bab29756570d310828971b0b6c70e33e56ce641f35e259674967d81195271403829d79fd9fbabbc1420382ab83434290ea2cac545fa055a3fdbc658045e7abbc2cc932a3f60a6be9d10cacc8e01dad10885bf5edf348889dc06aed310e2950a5d33bf1db9d1ee97315e79091d2561621c000b357e0f20683cfd2ae5636252c4f7c76c23034be09cf2f6e0620171b0a3602b4981cff666e91827fef02c6157010d039351b5c795bcb2f76a410610dc87226a1ea80e31ea379040e0a91aaa78547bca465b51a81da77cfcedf761ddbbf8e98687aeb0e6f55f2aece3e09da67715e1fa44ebfe82276d32e2a501e1dfe479c1901200011d605b003b87cacb35614d1945cec8258549ed3655ffb577ddbf0108108341919031202d964200f74145d2717a2f040599c5fcac8bd3835b6a6dc7b04ec30fc8cd64cac2ee7a0ddf472983ac13246f1ea06cf9922709378fc3e1a531852593c855d77ab79848ef4f6929e8ca0a90e1c4bd8757b18dd18414c4cb67ed5319f9575fa3b14aec7da110b5b21fe5e0cf96f2ed72c776520136d92d03e26f37a74fbfe3f9fb14328b7012e4d9dd0327c1534248c8eb6dcc7f081d5adb5739e1844ae1be329dc7501e7078e05585c5213f4a39ab39f1f2e742ddb24ec19b1c9618349c3711a2d8f801b180299a9f5a474af0b8a96118eb8c88596ba3dc1a05d61d1f4f37cc42cabe9205503e83d2870ba6fb6bb7d2b04986154d7bc69261618a34b064f74dfe54236abeda3c8189ca35e2a33da8884bca6760a574b4544efd1dc3020bfa31b50dd3b0de92faf6470651f870cb8018883400024171ae5b4409ee897c9f26ada42a80bc558d12edad94834583a3d801a9d154d2c7331740f5fbeb95511782485f1b75de8d4c3c7f0418c2d825321e3aa268ab4877536524da81698dcf4b2fd82a37c8cfc353d1a62d06c01fe3bc0c1c154b73fe52b06cb0037a5114d14ce48e9b443f67f4d22293d3eea937a8fad31febe40ad3bafff2e46cf5ab448527f916522b05775b91bd96f413aeebac36a9a3e0b1f583b2f7e38d807dbeb7479402e5f5ebdb291d86f04372cb1390cff8bb064bce3ba2aa12c6682b69f654ae552fa4bc322cfed7e4ad74fad5f60807c7a7ce7e1b8e0390949f1126caaca8cdcd5517a3432074e140c46cbb990be1329e82a6407412c8a36adda1982fc80ef60168100a96258b09486fb0d6b466735559cb7e495c65850f6980592faa94cd4950cb7cfd80049f0454109781d74a2cf0a513f935d2d5d5a4730c9f471ef54022ce5b61550fa9eed77f371aa74c422f51f8ed79152d26431295af9f7a4bea673a545f287e11951c19656829708e9e3b7e4ceccf03d85a931de8907f7c01d28caa75152cef4d2fdeadd8a3b7324efe39b2ef57788b3c37a0416e8a74c4be406ec6d6ca805aae650f05a78fbbf1d9669911ccf9fe1c02ea1f7fcb8fac608c4ad0207408f44a2ed908940fe23caa1a4c3dbe47afd3debe4bdd2f54477141910a183df605a4bbc6f61aaf7c4062419b5be4751b422a9be0173de24377dabfeb062a84517d6cf431dd961bfb15500a34486f7818636c13cb32ad00c52b7ff1d00971196093f29eccccf7575345f2fd5e29ff71d67724dbdea3f24bf6de29de3b60526c51dbefd58dfcaea78b71ed41ba68f5aa1f75b4be12cac7f56a33517c74b56853407ca3c23ac639290a396e72eedf2bd581cbd2cd31094001d04f86a76960cf93f95a354bd3ded631acdbea4b9c0b19ef15850b3a220ef27414222648f45404e22e38a2cc842cad248f629765aa29466b6a2adf36051af589e1e0b19d0c245347d4a61b3b500f42e41497b314595aadb9c4582068c7a6dfd3eb398af10c450315fda3fc2b32e4daabc6d49893b1ac447578a3f59e5d70e17835fd068259e7860c254c34f66e0847428f2a0d0989b30d8e676220800c2ee31816ec8e84bf000f952754469bf8ff0988e440c5d6cc1e02d938dd9ca4d6697a7d31c6e770749b17e2bd5f6915202397f343be418741b47228bcb1c659807910b331e22f94d23ed1208cb534ccc6167821a588ba5ae5b344c19653fb7cdffc9e62a6e2c53316322eae7300eb65ee7edaaeff8c197cab3551f9840b0b532f6c38c4549c269527bf0e0364673a2c7161a0c855268b8d70e766e1e75d64aa8d1a88f5dc56142a6ece1a01c1aadb27e810ca2c4a5be28847a9e134206396519b61028397726c181d7e3917fdbf7d56cb1af9dbb6da49d2a3df3d5192594b15f3f1c342ae7da18c1c5487c2cf81897fb5b67ebbac5e39ca08e61bf5cf1264df9356d394b30a94fe8755fa43dd55be9dc1f011be6703d14717d0a97ee61fe2df0db36091e764214dffdc8c3b84b9cf2ecac257ef63370affff53dfcebd810ddf971fa190390b92db3bc2932d1bb6a1316a64a840f476c838c71025c33538a39082b9ccee8302e708b3248730218c85aac89f98ac4e2dbc471a56c9339a1cc76c6baa56923c4ecbaa5c1c5e09c21b89fad1136b75021b8ba4065aa30ff51f99ca55268f447dad60f903cb776fa8ba78df8959912cb82ecf005d31fb8bece03d3a03df5c11d270181dcf0c6ad4cfc67d2d4f66ea67e876cf2c24a6a3e417f0cec112608a395b7edd283b4c8068f881009918ea6cfd019dccfe0692407004b2fbd6cff3afa921d607658da0280bc2e3be1cc5272a22d9ad880b30a3f43030b67727cbf60886a451502d4b78d7b2e2c06cd849d4f0f58d1d75037546ac1ca21f4b5fc0a0f46f7fac3176e78a75b5626ea1f6989588e6269b7d406424bc6174adbd22def0c70bf93ceb105bb74e0605828936d929792d14d5692cb1063c2c248d18196e5da1370830c6401083339e3234d71d3d4bf95a4e18303ab35edf23391cf14ee30168236b21648e1c9e603d50ec3540771f95a726493dbc898c2c48d9c485efe31e8febfbd7638c233db9ffe2a026fa2df2d1f4976bb66f43d2906ad9be184faeb653bca6144d275a1afe8e1f6b8f757732135dd415a53805e6143d82ff83c998a9979bd0b3f38691e873fdc79e7db4a68fcb5bce6c7de2c6551814d0669281a93df15f5a62f99641859680f7dd96d0eda382612df1cc278171cf92ec030091c14656143bfdfdd719bb3ed50e0231625ac7a1722502b6750d34ce29fe9a6227ff7ec4de329da851196e4985fb6e5d723df5c254178237d403b35858bad7da0492cd289e4ddb1054b753cd6f9fc0b806fa388d97964532229d66dfe299a683fda78b77bcf79306c54846d497e59d8accc376e494acb5c6d80a140343e66d238cc9c0fcaad5ea00648bc24ec909dd557d7cb95547a819b8f1aab2439293746027ef149a51bba52ec376bc1b30f999a770e8affe21b26a4fa27238197fd50f06dd8a4a33c46000a99daf4800f8e5ac1537df2709df228a7effa53d9f963b69047c1820384c936b6a61d15ea365bf55da0e76286bf76972f6395bda449b61a6c8a4fa8d4db7debeb967a877a8d451958cb5086b81b512b3f8521695db3ccf612dcd620cda53b285c753681610f3fdb9ebcaf3cf6a126caa7518e4c5c5f340b98e9fce3f695314a4557c5e0ab404a13cdecb6b458d1c11d7b280124e6b22ae9b662bc3d425f7b954b5887a2432cf4680d5b80b8685c7953c1912cc7c939ef16b60294bb21ad34d80e88d753202e4806fc984cc29c8881b19d905f9bd1f20be258e6c6c6244907f6de2f732de06f126fe69ff4658a25cfe112c26cccff0b17869c699ff82c7bf653368f0c7060f6ae8f9dc5e7de60ddbf09120cf9d0f5f417dc48b41bde0c7df71f3cd84285fa025444a2bb179307e6571cbd577f6a8f91fddb568859ff84c157e32d4a70f55a999a51aa57b23db8c5b1003eee26d6fc80763b936acf4661f9a25f200f4c2ef5df8f765f1659c82ca19b2c2d33c6ef5192954969a173fabdf6e742230a64ae124024e49d96533af95f902970107b9029239ff3b5ce722797dfcfaa833dcc426dccaa1ccd8c665b6dfc9bef57f0a276b19e5b48daaa743e341a1d1d66779f0ba3b9af2584d9a0682a7bc15151030e8d3da22bafa3564a049748494f8d7127829875df0b38d65cbcdd6d2534914628f98d55d2a55eb764d1c337afb53d1ba8fa409d7b99943cdb4caff6245797bf6bdfc393ea5df3af953e20afcd6729eb0c8cfca81e7c93cfa2341c2aedef3a6e9e550624d7203104b443fd8a4a41a42f3a9c03c12557784ccd57929bb8cc82c0a25b56e414d8472f13c90a89bb49f54c5fb2ec859a5eb4e58e5f6328c727c2a6ff7f9b91e4d34775e66133463148be8f12903777f8978654501be3cb2ead5e63e98404b45fd3d762d4a2ab9e7f140af3002325b5b77c6cdcbd4c04ebeb0f732dcb415396d1d0d2ff88bf2d002399d4f19a441ecc4327154f9ba291a4f695ed1332e63edd1aecd6124599814496657e8face33461dd1643b389576b5bb86a807bb15f865925e5dbb916fdb397429fa54bb3d489b6824acf32a9e139ff568c021d6a2335c80bf9c1e2fa502d2aade9e55a625ad22909adb453c2966d703b0a3247442a2619dcca321b256b48bada8c50d9eb9b49444aafa28725de025ec3356c713e33eabbd7cb3e9814d3cb2cb3281408e421b7908f1b1440f2abef6f9286df3567c78afff6108c44e7ddbad6917434911b1faffe03d6cea9d0e5514f47a2a716df0c36aee7b6cb847f1d2a11bfcca8d0dc79842de8eec585f8d53737715457b18cfb3cf1f72a32961840e2451097ea98b90a9227773b65a8b8e465cc0242e1e9a9ee4ef9e4cd4df52fc70a9ea5ea49267fb10df157e6f8ee861b49e563a6ca7af5b2dec865b576360100476f2aaf0ebf4c18f55b75725761c822fcf097e55d6d689b158bdbedeb6b92ec942bf3dcd233e1ecdea1080f91eb50207b91eb0eff54175470a39a690cc08fc5d38fcb493e3173eef1e3ced0197b60cfc57c37b0c3c1c9886ff5871cf387bd1623d090a7fb4b17d6c17ba28f4237d5dde602fd9b72197a3f2350689922c68b73a3ecd53c0f327c226379400e2258e6d03a0a9d94da0485ffa9612413a65391f6b1806d654f99a5ee01bb51acf319626600b7a1f9284fc26974bdff55e5bc12ddb6ac72006462ee88be54ba1f51f19ba63772511cfcbe0bd44567ed897eb85884af872fc2b0ca58df4f911a77372b9805783ee45c7e51d1cb88bb79cc73ba11e63431605ab7e20ba3bbaaed04ae90aa59df56536319e50d2a6ca94d978a09c2e266ac7f14c879a44324a0e7f7c65ae6db4801952e50d56dc15a03ed3cca8e772d7b3ef96bde5366ee24430c5c7c170637a3a4ee6a342d48c74046def2f3a915b5976c686e3a6eff7e4537546c8541ff8901ca09c5b2faf838628261b05872842bd419acb48fdf95fce68b38c3712b9f21f48775f69e6545b888e01fa7454a09c0b62290be3e762aba9b386769aea9a342856b91304607d24752b5d7463562a494e64b2febc82043f60947b889c9661a0f51a86b3b55b9cfe3bdcd07ad58aed800cfde80d34c2d4c84316b45c9c6407521cdf97040835264312119a35b0bae2a1e3263b70316e120d36cf0e55aff55b0f45e820e5d38d77673a9df1941866b19d84529d299559496954d5f2682d0db7e38529567b94f539cf9c6b64d982bd4668ffa3ebffc99152a258a760b15bb7fd9572d380beb65598b6103e140f10fd5418daa38b8728ada2a36ab606a3dfbf0a0c853920a13c93668f929ed3b02fe1d70f5acad14d6ec4b86e369d47a0da20f1823e417462cee5d37ec87d32ab229ef498a6642822a9b07c28ab256d157b95310ef0c1002e8e9f8663bd90a068c1d6c5c991547a6f8a7bdcaf4b021854fde195b6c9f93d3c173f2685f46f7d1df9142a5fd1746f2fb2cc75456c3190ad84358b9ebfdaef1c57c69e95c937a693396522c4f8ebb5e738a7667bad00149646b1ef7e4169b57266e388ed491fc1229fb4e9d713c304099cd208917f7c62b9f1f7f850f84f8e09f98decca8df79247e2dfab91882888ac7eb4508d4d020a985156ca01f9522b24f31f0dbc444a2285883f1b260a54c0951199e414125ec65ece933eae5aae91b6a761ce6e2f416ba84700ae05a2d616e7876d7607a5147e7db2ad53b2faeba65752742fe8e7b98557211ae0509f0a271d96155f40d9d3fa0e7427481d1d548cf519246427a3310737d7d63619322bd3612b2d260a62393946804981507cb2c40ff6ae33d01907a692df9abdd149f131926540e6f9f0d6d443b2b0ec7612e51f60ee747cf3bae2d445873623f81e1b013af1565c93889befc1869b0eaab1ac1d5d4e833050ca37364a69beee0dc6937dc5f48a625df85f6f92c5f5689b31f64d5e5f27f78769ed4f5751b12affb933eb4b84fbbdf90f2c1617d88bff7141e99ed49e4a7c7c28d6267309b931d3818f6c7853e0ee3912a7aabbd313a23aee0348feed68d0c3be38f52dfd7feb49cc178d080a7ce25e07313be786ac9913b80163221ed59f6e04d50304012fca4f33cd5e39cc4135df4f18bbef5e8cb056f6a570003435fe31d1a714362ff00f314437a5daec683a09ff53ba66a25948e8878d2336fe76b448655b358651e4e2b86d841e038ff392a2fd098cc24cabc42dcdebf2921f38d617e02ea72636473c7dfd0d9130bd44334beefd89607b37bdb6def3b54f5eb60ed1435de3a7dbe8936b8986b82e2172ad2aa421fcdf127b9b6ab552b3d2410c007d2f6fafccb867848cc29c2302c7c83a8f7475a1060ce55a74d84c3981c230ba0e453294ed664fefcdecccebc8d881a9780af2e9eceba739ee1c4f369806c59424d695bc3bdc91b1deee9420c4a7013df2c5023d57f9381f437e550ad2b46058f171ee51a7abf7cbec700b9c7944464c927a7be64975833fb758b67c336af66dcaa7dce99da8d14b4c1ec77b9d7c517822015a6ab821c653ec1c7e7cc4ad0e88c07f909c1911348db4046220c54ffc0fe73157269313dfd6ee580f3e586e337eb7407c233d93b39225393ea8a078e60c30b895fe1c30639f7be38f2e16855c7013dc9a77f3af5baabd9cda5a3db4ae1b08f2160cdde22d7accd7b5245fb9c3513ee784614bec13d9b9adc3e289aeb617e1a2e8987c5c755c9ec5a0bb7e25791cde4f69e0e4469482dfab60033a0ee328c5123c9c6e143697fc1437a855ebfe4504f63ab1487116c8827a4c526f5ce2295019607b2b6a24c649a5925ff4963ba1fa2f44e11332655ef8780a8385c853a255640d92768374cc3ec0e6b8141ab2a84d82cc0fca00c01f1a8b305febbfb17039f6519e053d686ebd41fec34801084e040db4088233e9d1fe777632b3f3783a1bb591c3af9cbf0752c6b8d581d62fdcd0a8dd2905268d1a2901f8fa47a5e816b75c77efa7b43dfad62136c723d4c2709262a81411c7097b7983646f4f34bb04b4659559799aa7af24d06b25daa44a6831ec2de199822c22694ae3e6f907b3f24914eaf9469592b1e67481b0eecb6fb6b02f8560a2249e80c5448ed925c7d43a61c7c835295837a73d1da6bbbfb4e86ab5dc110db81508c30dc70121701f7e1a7ee574a5587b611a9f95e52232355808d7f7d662e9ffe28e5591d2358f7624d07cc0b92196b71fe9eb8ff0b62d44e30ad6b80ae07d88a9c258b8595a659f64ba451dfbbcce043ea3942247632a0d8cb8f5966ddbcdb3139234be562f5c3b56c5d688c7bc55dc6505a87f55a6e4866ed76cf605b496aa867ce589b848eb3add0aad77f0ea0b860722db986ff2c181b1a0b829a66c8f31772b783cc11e25cedf1abfb1cbc260bd32a3424a80aa6124658cdabba3157cf88a9c8760a2b1d150c92b2494b937688c7e7b2ab8e8d02621dcda8bcc9160b2fcf20a4aec0d5500cfc8b13e7d630a1d3e23f575d144b2617719e0bd24365de8ede6bdd66bcf4d4618616ea8db75d50f2889c20359533d964f327939afc109e252c236d6404bb43d93286ea3034f821ecf9499a4792f624f5b1ae7f2f0b55a50d5fc949b954a34934e3500c3c1741aaa87e389291f45da2f6353803d51d71cd0148b1373c72db99150b2d25e322522b3bc3159885dbfd1fc74ea49c1de39b3f0102fec1f831710ddd8eb953585bed8ccbc1f9662f5a33175c11a874c1e83bc1c76eead54323e364b14d81a77764b0e79b34d1eec4baeb9edf81983db8b7f06664279133d066c12847e217688f7f127d2ae50c206939d0e9e80348f614138d849d2554521b52ced48d5acc6e9e84d3037b6223d0ae7e42e225253cb97e9ea1058614f613e3bd75087720bf0eb86d7b01638597d09501a7b83fcf371b9367d4cb9f80a59d1cd730c978b94f687b70952843e13eceb63c321e5a63fa723d9560aa8197d285208f4ccf9be34c6a495391054d9c93c33271b79e6c7dc6a167cbe036c83d1a1a12a4feb0799290e2e9621008c80db480d9b60cb83ab7fc4abaadef1e22a530a21f6743009254ea4211c23fa584b3dc4fbc14d0d0fed0bc4ea6971b3489794d41a0722f7b8a4d674ad6c44859a4f4c34b167181bea3567ae8235cb598b01ba17794410589e8cd0aa8e78180a86a899f2894bdb71a6a80725f775eb6468b5600773a6534a1aef4b239bad5e926ca8b86c0962f637d835286bf780d96ff53caeaef31d7d723f34bb619d720283ea738f7c0b1e3e2f1419061ccd8af5de0d1c236a59ba82347e3317beeb1763f6745f767c15a5ade19f28444807a7b3ff8fc3050ed568b46f1c281389d2eff118ba05be056bd72f8c618c5afaa3afb11df9678807976937d9911ca67174146ecc1e2e58078b25b190bf79faeb3c87b5f2c8a13fcc502dde325ff995e355cbe14267b5b26158610e2dd3893838c63335685c2e4fe4a885baec27d321016e8573aad2472e91c6d5dbeb9c11afa9f057f99f1b0ac111c2f02ef610e1f5a6f81f7bb845eeb2ccabbb2593b06e2c0d47f30cf7930f6a01fa5aa7ea111cfb5ab3749b576cc691e955a75aee399607c62f380300a00373c2bed33c7964d1e2171f9839ed80e024778c0f5bfae313549f0efd0cb3bfec3c948808f6d798fdf55ad65edce3c5986dc9ce454c071ff4b8e170a75588716381b0ea953bbe26e10e7c39266617392d20aa79c41158338fd870d09c485859fe96a5a40ec4e8cf9053f28019832b3f73230ed437810af9767a5db7fdede71eaf81dc682539d8d27d1bde516d15661e98721fe658052139f76a9d06a3c8d964680de3a6b503a3ab15df1d96ba1e28007b3927ed017d3bab8b113ab1836f72c1bbf1940606a26af259600f9faa09a17629b8dd80953e1fad8a9fdb966c7d7c3a6d23e15687d6767b55a5dd525216a6fe14f241e7797bf6666838f3a5709642eaf46a3d1d8f8d5210edc4774980d248918b892a30b33b20ee48129fbcb08a808a884cf1691b6675981174fe0a54c5e30479389661ce140cd559cedf12c0046adc3fb248bd31a3a71be347c24c1364435ae5c083cbeefa0cb613744dcee376e8227a57fde06601cfaceaf39edb97bbf908f26f6b1797f1d06dc1c4ca8a8a3937ea16cbbb4132da8309c7f2cf21a1697c93d33dd09c125f8438739c369e41e23bc2d4889e727ae383a48b70f83594f2a7d045346a65004e43cdf3afa5c56f0de78b04e36955e47e387d419550423f4acdf244eb112843dc83b7d179e75a6a7f1a8d5681c6e4fa950cb9b3203f24da58216ce1ea1462395b2c3a2be75e25eb984d7e2265f4b00c4a610c334436e3e69f6730aa853fc3028116cb7224fe9689fa913ebe9622d98f267a0449b5c6e90d10ec534a4c6307a567ef0da4ba971bd799ea2dff0fbf88953900b2f81a94f67a1b08b360dae38975a8aa3c3e9d8deaf76f9f35dc15b343611d8bf8faa01c47cc4a19f46a622e7bcc667979c5f15c89a025cb7fb4053db868ac5df303115cc611ab877a5d79deb5031e467d0e05040e75396683b3b957f9100b5b66ffde45a46c693d824b6adde4c10b3ef35ff1c87b5ac67ab6638c8e3f8d3a31225bf22f43da7b8a904ff9518a978c5c4d68bac0dac5bb57f1a43c4ee3c5f7a49174610f8fdc00deb0106be5192f353d8231fca7887ce35fd8298af4581c1c8106df4d4e93ac15d11a3b0462b8d48859b8188fcca22da80fa8ab7fb4f57aa60a98a5560b067e19c2b4eb6826261afef140ab6f507da75974b3b039e304acb66fa23daf0f5141fe15d121cefac12bd93129ff2a97ebe642d4aec71836a30de4f91e429823d132d63cc533fee841c10ce192cfd7d1630eb1f6586a04a993ec073f6be34b5dbd5175b57192230b5b08a696b7efa46c55cdd399f8684609ed5669f1de4ced97689d3820158eba548c50a4d539728531f1d4c41b4a578e866366996a439be947ab98a37022846e1040235010b33a3d7646bdc7baa5bfc0086ebc874968c7b66794a81726cdcc8bd1b788952ab15934b0eac3f04960443c786c726892a1f2df01bafe3d3a3bd11d55154823ca9ded6df035e4f8f4330f794ea951d6cbbab74a629f045b7b6ada783ab2d5678e61aa21c64a13bce32e371409bdd83e78ba2a39892a2da5f7370d0c25caa30e6c5f07f9eda95f55d329588166295d271937dc1f451e7a119499fb328cfacbdca964736c9e4a12e88186982db71b51954c658affd98c66ecdf8c90bd12eb8ddb7f68582fd358dec8054b5edab4af6829c2ddfab7a9b57366d34e28542c498eeffe1d4117c496638781087a05afafd6d1fc493f57024342dc9ec3ecd2b722c4c437e6289a56c04add2ae470211bebdc3c25446dd4fbc0a04430e735dbd6f2ab0c7481d9e206d66cccc2b21b2645aee325e4b110a71903ee3e75dee78b970cd04a846309c91f38576ebb985491d130c97aefaae55a405247953263b2901c256767a9dc24564a4ad7c72d95a57474fc228570b8b38ffff7b608a4a52e1df9458dcc498621dd23d0d2750fe9affa098d64046fd1c91ccffd512b0050d1a52e0b146e81d6591d0b6f965fc031ccc96c8c2984108875ba039ca476eab695533724a2dfef62b9967bd6c0256448d566d9d720cbf4d7254171b483d9e209b515005de414cc6bf4441bf3b52c70cfa9dc6d824294b48fd0d25db440bc74fa6377260d6b22755c499cc403e2f6236d427b72dfb8bf0d2de20eece37bf7d8304a93a76c87db6bac5f30bfbcc2b5b5a52f2a11f7a6353eaaaea962dcbe6d659e35f3d98caf2102c1b6dbd3371dd44a66dd15233db892cf5f764a2244f31fedc8fb62d6591b7831cfa5e0cbd4d5818a8fd8ea860a6b8f39683f95bdbb5e6ce69d93cb563fa4d7f9b3e5fc0f635a57866a32ed9d48efe6ea6519dcd45535a608ca6a06cf992dc0f9baf9421595f147695342a97eade603e7355e40c6c58c87d510655f64f77ae84f7427c173f53170c1bca53a969fdbb6cb440b00a9216fdb644a41d735930c4d1df10bea2afa817b0c5de97983f5e9515e21455dca670d0dbb8b0c08ddfa8c8e54a3a5144647cf2877485bf790477b53108e2e7df4abfa9a5b13a445c3a890abeb838d095f943d85c4a34797050affa7ad14f9659b7e5355bde22bd58d322ea4b0a7b99e9c66a822a152b218899de88b83c83e855ddf37c3f5450a7753cbf44468b400a97719811b2b4fdac7b53f40cc9a9dfb6c4d026fb822766019d44f0448437eecb22196c01bc000d44e8bd818148066ac0198251525adc33c2b3ca89d6f46d09eae4d8e9bd15220623a3d68840c3e19f0b699cab5bad88a9b3d8abf93104df5cfa8d3cd06d57cdc8b943bc1889c836a6b6d65552887b3f15fd5fbf41aee9104c6d43f4b5187348b02fc0f5fe4a9a2e70ad61718f513d741ea0697ea089005fb8e7bafa4451e91732a3c69e1a4d8815667b81501697b23b00a611cdc7f3c27d8b5f64a966d13bbb08c504400f5ee02f61d12b2bf6bc481418d70e345fbfb20a00a89a6f4114668bc7893642b800a9ea18b7ece906e5965fae704ace315c6aca7d2a0fc804e41e2cec2649a483020981a2665444f1a83d89a5977947fad4ae70e2bb042ab0ded66ba2f30a333fa43042c5826b9065c6b1394ef4fdc53e1ef9874213d20863dd3b82937db1dafe91b052b7ad43953b54919cf559930c5de770a26bb273809c55d70599fc3690ce30011b69e0740444829bacc35ecba30c7f4b0dbe898a94bf8afa51c452c855943f03a1b7bab909e53765f3c9c9458df38dbb78919c3a52572006b9cf4ed1eb26625e9ac317167eb080f5e6a5ac73e8ee352694862cc37bb1e85405e07535f972a8d20b0aae30a5aa782b75b509c617de1fec5f59ff8bbf933707829db978822085c41cd4be1674d3fafe33939985f4edaf476481dd516671f12ce6444efa16fbd37eef144b0a46f48c047159015c5b5b34f737057c8be8a3e0b2805c349e21e37afda1c7b31ce939dfaeec380619cacd8fb33e86afd2514d2bb7c28104febc2f9774ffe40c2ffa0652f95a4d3e7a654d6ba8f5ce920ab313103ef250c54133444ac4208f22516dbb368b1513f32e77db1cd2d9337f944b52b02138c2733263e16be35e728b3fedc3422478c4371067bdabb3185b9b00eac7418bb42bd130e0a9caa3c24f29b200c46ec94b7425486360deb8a66d71cecf38a7c069e12fa3ccd79aba0792696314693ce825c049ffa32b60fe3f5ac7d6a80eadca4600ae12ad107e7ecec52373ede6689fb840fa8e8f6f664030b84f94ab5f34db002a8f0dc795aae3105e78fd3f34da29b4f360d5a0d38363eb228b6cb7bc8d28d4891b83572fbf435898c6fecc87ff55d7127d0a9ccac8caf281e05b617f7181716826655e69a7c3adcf80725dbb083c6cc76219835aeddb11e3ab9cc0d2592769f090a1d6a521c628918ef38d710872999606fd41f03c329d4ce2630c764fec906a3c7da4aa0c5291ea1bc610a92be7d399e05d84190f7c6819e9776423b4b0167d9f85c835043b8b3f9b74804140071efc81485a0bbbfd72c8d9e3b0242a968c8f283a6fddcd120af1071da19e21d84593c5d2fb03f3f29a7a90a5661b16007eb0334d5f3742cab4f24b5095969c1e0e9083b8faf24e285c96920b641758974b2833531e055ebaf073bc987421afcceef38935a4f92f343c3acc358ed4ac38ab1b522d2ee631b697c0edc6f5914e7a0d3cab5c50bd57ee5c31d1e8b6f73336ba29c4261db76b7136f5658bd612f29ba256a2121afc32591f40438157a454147da0dbfd0b37aba0c07402d9f3f6f9d55ab034cc5a735d6483af3a2a180c520d7976177ce20cf80e6a833bedcbe6e6143829cac8db6d9fa4d829746a911d9d8274218b7b1f8935a6c8f4c2c117b0a884700c77119f5c3c06dc4ff92af01ea9c2cb5a7939adce6d0e94e3ee8eb25639d50bc21a514f0e21c1acbfdd0143d1c68040b21dee248ff6eb07a018aab091c2501dcd568321b2c0601f5d687abc5b6beb0229d6ba6f7589811cd5a38d42aab792df3d4ab381c8b7e081a903955e319721b4975a3c5ae08e49748535c9939df976631f01c992f0fa1aae72dcfac3ffacbbbb88e1c1e6bca0de02e6916c2576a98f7017b462837529c53562fc3146d67a94d7476f3f8504794ddec8ddc3a1c932c5fb648b751de140ad61f326573ca1b5ce6460c234c153634d7bd8cf145415d737bb81a35fa614a35022e6d31424c13445d04f11fd4cd13a9c74fac2f68ebc63995023ce5b95bc063d695c9419c98ed5dd3cb4a4c24699379ab5be8effb479bf20bd4484e44d158bb69c7d1c7ff7cc5bb5efaf17a4ce52c94741cddaab2f778ea454c33a2dbc8cf6722eb75385ac0464011cbb7e9097ae1c6327e3e1af34dfb78e5aa7d789c83170174f7336ca10521b6d74a935d1ce5588185b625e9250e918d1f2576efecffd0a7158cea990bb08ad484d4289722746cae3abcf2667715e43c5679c2e89bc3a3d5c1025a3cf39658432b40161ec56afcb0f699caaf0a18c1ef6d91f1b74ad88aec6ff60eef56b1378ac96f2e886642cbadfab565d198d70b541f781840f9ef74c0656b05af32f44190ecc171a169e4406ba3739dacfd7959a47690e217b036b11dc6b043c6e4ce2a8f1333f02d7a7d3c6b1948d01fdbb3398ec7fe6212d881afd7311d3dc92a282d41248786784377c5802ddf61261f0d8d781092514491900188dc0328d2af0cdc97dac7a31c64b7ec2a141db8e24c9130ceea8a01a9919a095436dcc3c097038ca3fc2c047af1744c34a4f2bf45e11489d27bf2a323d2a3dc893b874733ac023495df210d3b7b6db0bab4385e39df8e56f803f46b360a52b8be1dbfdd44d924dbdf8c60ffd30e40543bf6b64e8c91fafed2e2fe55ecb786e3a0295bada79a3648b96ed3db844078cc52e0d2e1b9d4cc0f97ceb63a9ab07d5a82a6900985b776558ab710b5699931e9e1eb4af18a8e83284248a3134c725dea6f44686916ad1538c7aa972eb884b0a2e1085880e14f7314de9eedba7ab2802df386f0deed3690724ef7514b3b894680077cd3e163a55330407222e5f0ed67bd5220c04636d519a3166f4c78b18785903255827d583beee4b37177758253d6672a1a7cabed4146f55eb7698bd426613306b2ef97ba97f5d9166543e159ac449eac3499ee701e27ba7fbf30eebd563b1d3712755d59a8e22463812c29d1e88f6fea97b2e51671f420ff41658d5746fe578414498b8cbb37b053cde0638633f4a0cb78ddb200ff5f214c7b07b2984965d34c846f2f87e5602fe187e41696db39c08f5d6f4d16129a810e65ce0ce5f944c3ee1f73e42ddeb6198fe52394bf81b8918abb46cbc0a1f0efeea2a9f827f2ad320ce541c5ad8559d13303d1187f111747b62554c410724f2035e39d2b91397b9a64c01db0b937ce415865cb884381d29ab223e1d9613719bb84b0bb29869da8538af01c67fa95f876c99115c795f489539d4275f4211271b34f0eac30d3d2d238c337e95af0c79d054b3a082f0b59c1489b54e3c28005e31b49d3097b8a405385c50722f07940e06d0e06f8ac62e2ed2f834f93288fff2153d6118a35b3c469ec110d046e5e8ae2c8bcacc41699c9c1624f93c29bcc70bce3025317c5a6c495968400da31a83b6eb5e1d5d6497190e8d26961a5a951c057ccc8a41cbe9fd83bf78f5e13eaf725c56df5a5947cc7d86460a8556f372d58778003c27606c72e2fd97b9c9aec99be8a8cd0368ce37ea1e9e053516f8c7c9124996f1d45cf90f26c9201e7bb653d3ea45be86a3612d5bd1b7448bbb778bcfb67a7d5435b766a0646986ba64401a9b4cc3873edaa129dea479316c0b32120f4d9e6179bfb372d342491e53ad49245c146bea60aec00cf9c937f74dbb019dce2d4edb113e6171efa1c307ae9866a87e6850b6393829b83dc826664f99928f2cb2823c8aa364b5a26c57bc78ce5b95c9b87f4eea0873305cffedd94d5d30c5285e03abf70f709b0e47fd7186191532674c5968defc0bf26724981b0ecd287cbbff44de8c22aa7417f49d644b60f075441bd7cfc6a55ff4190846ce22656470db64f4b8d6b7967f76b277d7ce20a59bfc86d8f1018c7e996aa72b344eef665524644b01bf9c953ade09705cbf0af02874172242c62420205da5255f086155b6ca2ea621ce50ee109814c9c28b0629034ba886b20b04dd1201f0ccf4d0787ca95fc0f85d765450a145dfeb8eb72829f5f15db72f193736ffcdd964fd5e631ec1b338ec0052381376d37a6f3b77f6fc2b710c3b5a566e7a2146e6b1add6afa96cfe262086263020ad721922f7078cb91f8ecc59dbda1c56c79dd0e1e6fc31aad87c640273ce67ba762e370b777124f7b023221b16bbcf1edf3ebc0617957ef78fa2166887918aac71ba7bdf0585005f0d737f8128393edbd0c4b68a0fe0ec577e56696f9c7d056b5adef8214029c322eaeaaa52d494fc909a10441c9db225b8e0b8828714de00979cee046a91cc2cf68a32ebd8b4442c1a53d65acca56f450439b9800241aa0e29caec8e53793eec99ded734df4ab05e866a5f991924d99e7973bfdf8deeb95f4d7db1b546cbcb4e8f902940108b9028f39ab7eae02d02aa86d63382ac19ef837a4655f679bdfee6933cd7545522ad51e5185527af73f603c51c5f8283d191d21bafce6c6475bdc550cc08c18920c418c62eb01c7c3f44a2612bcca3af81d14636f22d622d87451f1a1b2b078430fa634bca67b71886aecd91352fb3dded969d114469f6c4e324f92bf2ecf350cd30da9553b96a934f9894f7ed92833f70a7e36aa76db48c53124642aec5b49a64b61f1564f8c57360e0e2560c5b0cb3a8cc1cd261fa4e334c5b65496caa38dc7d333435fb7c8b04f7f8926c969c74b3f40dbb30f94862e2bda0ffea309c28c90a65100c530d3b593cd253cbd4ea7bd1a6ca0a2eb4948d5ccea42985372983aff6eb260d34e3745a391891c351c82a449a9ef68b43f65de68e5d0120412376b8aab58527ca7290d89b740306c88f6a58d7fad9c6ffc28d698ba6f3eb1b33a785064899f7c509c33791181548f0c0d67add1a18b922baa30939483cc952450e27114d4c173b99df2dedd50b4515674fac1eca53d97825d913bdfd63db3a2323ae58b028ff27dbbb8a4aed3b51f9719c05ff121766c93897743cf448dc50f0a5fcdacd824e5fb5d0b39db56bf5643c87465bcd156f5d56d1219a278d96a8edd64a52b2e74e9d8681b3427f52444aee67625f96b4cf9f7fbdb368ca7f5819f589cc49fb6b4a80cb527efb462f456defd376f0842dc9cfaa7a7946cbcdaf820c0dca1fd2cfa318badcb8fdcafe4526789438687219fe8734074f915ee3bb913b8d7998c6c3f3ba837b46ca1148cc87fd285932f7f4750c28f23cedb284c539287c2d767aa7b01b4746f785b2f6b3a71922ce635c63dd7c8b41f209b15b45e6106a1d15774c11b585be73568ae2b9c3eddabe96db15ef750ce5ed9587ee50a1f7c874da136a828ab60a62d2b73507451d79aafe880f91eb50208b91eb072f30cddba2b4922caa76fb23f66aad26e1750c29ff56bcf836737f9b3b160b90f026ac38637e43c05d3d531e0dab4db11e44fd20175c4cd22c59a3d0f316c65ed845a8d7ed7b0861676b20aeca0eda588a62a965358c729b95bec3562a3b8736e60dc573c556722df19cec337c4d9df636574e37f767610008eb92f264dc707451e9d4ed46c4b3e15cd7ef1fed2dacd304ed816f47c85c36a1eed8055784c1075b9b0d26ad9f19f6adf44506c6900071f59457cdb0a94677b064196ad0c76a93c5d9b46a0b8a0fb08de6920a71a467c4ee88f7b4ecf665bc6d550eca488306f135bf5f6360ebe34c384b6412aec1d56cc243142bbbff09485ec905d1b92dd0974d896c80acbd3d53c57136b1cf1fca5f37d5a2540fb319f9764bc5ed78e6c0d996da109434857d8b1ef12080ff09b5fba7f1c2e495e0e75cb8aed7b221b3f02a3d64894d3c3ddeb33ca327aae8afa950dcaaa818e60743b4749055012fead7b1f971728463f810e6649e3af189cea7748b427232830aedbfc574680d6b9a7b3066fc46900a44961e450f4c53f637db3b5abc87d24bc67dc9d1613bd12d8706ffb1c5cbf11ce6089499d65085a5f59690036ec2a3cd05e6c31c64302dfa3351e8aeb5491df52fd31b586f5afc9b4805abecfcc7fcd6ca5cbb8ea035bb334908044d0b1448bb78ed6922f57e6d2b6b5c4487c29986e031e2f90ca203ab05b50ea812fc033e05be8173c88c4249d718976b239fef2142bd46a60d8eeabdfa3685be32d08ed3d346b9edd1aae0a413149e24f055664c423d30e9e667615ab08d6f0a4a95fca6d21ce379b556c65cc4142e90bd31bf989d46b7ba48fb20dea571097aef1c5009ed4df26a9e36971904c90cc28b5781af7899be63e1a1a555099189d6cd46ecbc1d7294ca528c188a563fe9894aae81185e686f3a7e499712ca4dc9adf4c562fd6cbcead9ea764d515ed90843887265933df3bda2c5d4763380207450c4f5973352299a018c5741a7a590e43f9938be4fd4d957c90233abed53ae7bcd167dcb55ee45818765751f76e69201236c87f7ddc99a53c374a0e907f6cb865d50bf46db2c24d5adef502057baf307a3b5311a167396a28b2220dbe268a43ca4c8f5976931059c5bc5849306c932f7178df8e776b317806aefed46a9204792c422efd2985a86855b90dbade9c951407a76bf786c83fb819a4e63c5e9598e18382f3fb6527775dd25646b22162b925aa5bc24004e22209d9591d0f24d9de792ced043e43ebc7a1cc7c0732963b41634f3508ad325941c8c66a59c077d523e25f3f02b853c097aa29e48a3cdfae0ea77b1139ad7a2d162341d28fe379ac8d165da34c7750f669f5edebb12daab6bdfceedca426a8b4413941028c584c90a2b573418843823d74e48349504381c3c1b3c6a57e9f98bad91f8a3b99debee512bc3f12b6f9c03243a458981d7d83227146324a470564ed259f13587cd0a590e376b948e2e986045aa40c2a5a19d479a3132f47a41585ef86c9d4382105fe4f1c3a071acd1e43b753fee578da2fd65265a0aa0985b0a177eee44a5b7ef747c6825db3795b2b17cf05997ff8387e89dcd8196f38f113b9b66080eb624c0788a5c979c1eaa4a85d29d05c3fd1eaee4dcc7dfa72a2492f0f7d64b4f1ae207b1a37a3d2c0c6dc9d840233af275a6f8742fc4073569f3cb80eb7e8ea11e99e6d7f0d8930122a41a38f2302c5a8f8984d0bcc54cd50b4c7c6facbcc104f6ae48e6a138aaa9f2bd078490d34f2bcc6ea526e815956090683d2f3de97360ef6394c683d82bf71b2e634536a41372928c99379520f8750e383790eb29fe790b9ddb115d1650ffed58e02911b9f18f7736742ed8174d2ff879148665d15afc761acde60e0cf7867f36b50561b74ed8b4f7721d01d98bdd57c26ffdcd1d6c11ddd74342b50925c6de8f29effba4eab216a28db707e1256486490822d066880a9770f517df61c74a1dd32cbf20237cbb3c2ef8dc2a82a113ce80fb73d8a0ef1c14345ec2ace4beaae579b82974bf4f5a302ab76dcdf02adf2fba43488227baac4b8b012038ae15ec25e65ce8ac0be8e6bfd087ce625485065e2e29eb43deae50f6fb616a16107850f5c7b17da975d5b251a021a9c539539e9acf8edc4b468b0fb9b91d62427813f04caf2f50572806be52234b490cdb21d42fa5235207916916090e51de19213fa689a2a7f9408b313448dbbc9f148bf183dacd56c565b0582aa82ab21b92e392051961cf3133ecde4c7c7646efcba36ef94e288abfa0aaf93cd4d988c0cc274cdf62fcd70d4b758e30adda8f1894777b11a2a17a233e6c12453ef565e7a29719df4c113d3bd74e3f1bc411dd068c91c9ae9026d5d7fb622fa6d764c4f2faa09cf7375b3476f0acf8eeb1b97a1ac73f77c9568e40425b324c4dd2c97e30cf5c33bd67a514c7d97b61fa36efb684e820fc8a89861d43539ed27352390821ec248e09a9998912e0c5f0779c5cdc646ad0ceeeb6cc514ae057eacfdb94f89273ded90c26c03619feaf9d5432152ddbe6def47f1dc626750e481dd1582c13576772321dd243a9d73557a1806c76c3630212e8e2f0842d0d34a81bb03d25e91f716b99dee25215ac4bc0139868c87a01c5d7dafb4948d65d22f26bc7e4a8f3f317863f96a38f74fdfd1c5e5a6a8a854e53936f34512390180ae4dbb4f3c1dd4d8c4c78660d5692d45647bf9b53e63ec822879289e7002b673e66f1e23641574d5129da1501334058315abe8a5df6600c284382e0f48cb85071e2094f9de2fea829499007c97a6e9de54e19a961a744abbd7dfd6270809a74c0ffc935b703dfdde7f2def0e3951285121e6dd027ab2e8cdd9c5e5dd28235732a4cae82c3dfad5d1657c74551a0ae520d1bd8940c920a52d429520557ea38adac9bbc44ed16e15bb54d5fce9b491e97b2b22b1b5d1fc191cb7a2856c490130411825bf9eea4f2af47f7d04f9239fd3c7c2654d5b561207a979a718d72d88d5ce1a6f461bc864217aac536f181ef0c78549c41a9dc2a84f5c98342ac3101428bf34cb435247f1f92a7f5c7bec8cf0f5331f1cb492cffa06133dfe199bb5f5bbd63745f5822700c3b43fe05d231b0f7b0bb8e80c8d576c1f4770a37185c72c6be6b56a0a4bb083c53ad7ed4a6cb9cdbf0eec5f13014e8c6f9121c9239f01e75c22ac33eca65faf875b9ea42f14ebba98d45306e529254bce1c2869427c2dd0e073b45163dc38b89e033358bb26c1aa3b039999e808e2871a1301e4f9af8c0a0237ba3f0a12c8a649cc66d23e7cec4a1a9db8be97405bc40d54520d0436cfb1c1015ae99f21f5ea90b0cdd0dacb37c18fa77cabf77c6df9fe0d47c77619bf146e701310f34066a995347ae5868e0ab8b5ead172aae30b9a808b0bd451e17d766039eec2c4d875278e841eddd433cd661a67c64155a2688284b611ecc198f894d2dd7d526534e8e6c675f550ef4ab94bf2ed9a4c252dc4efe36e6558ec203673aa6b0e2efec57b2a826fa4bff78aa849fb6b2706d68d684a0346467d65f246f3d2d6bddc729820e5b25eac84fc3fed0f98c257d646c1c75e6360551af4f13fc04301e7864d20476605e2ef480c7ce2ad48f9e54a3e679f06ceb37e92e27722da72f6ad6cbb7a1303706c3dd8d3b08d8c3c4e267dff60aef66d9553a73ba459882eb4bbeced199316dbfaa0c612f799b6cf565949167953794a66dce5e84832747ff32b03ceec0dd93ee29929c6cbb082d3ce43238dd76e736681b96841115ed5f5d4c2597c51c4ba0f80f09cfc7fb33f768ab56821e1059a435f88c393e0b93b14931251cdd4b010589f9de7b23e437c07944791ca44b48e94a4b853776f5f49e3c5637b49e717205104c22f2186ff08af3568f8effbc1bb93750df61e49df44dad00c4727d9396a4abf61690da0ed42422e5ce7a2c8098d8d9eb4b7563964a5dbf6e499c6586d80f15dbe37296a9c72af5b004b4b1d40cadc39c2ccaf8fa22c056d0e10632c489ce6ca93ed0c497600ce80f0bfbf03cc5a3ba38be508361322690affd8c464c211df3355709e961083c020726f2a1ffed43fbb83d560da4f69a72e020d9171e55e6e1d264fcad5ba6f6140c663fc0067a9adee5e2222babd43f22fede03d3c17c8f9a3af62ae92c37b61724cbffa8dd1640b617b3df8bdd6ff287c4e06c4589485abd03545de2a3d27544d402bd061468f906ed4df7862d957a1893ccd3a6e6c37ef21aa8ec20eeb90d273592dc83634fa8289f0cb5626892350d9a77fb01ea1529aa18dffcc49d70567307719b818ea4dafefd43b9f90633c79edbfca333b35c2c4a413e437f3005d12b693e711832ab3cb522c5832bc078f61b202283502ac5f4b11c7d97b0298eaa7ad59ed4f7810c9d90fc476c74483b9015945c561ac7e87f68c2b27aa2982ed46268ca501a927c31027acb0191e0e0485c578e17166b926eab159b08eec3af6ba8971490857847411329ddebf5f64ca27766730671f59b09fe0a22cbd4cb24d8a2a751d06807032c9eee9bc9a10ff5d0d925893068b5e4a9e68508684f0130efc89f57aa1aad1eab24c59e501c1787fbe76d4ff4ef6e34e5f12aaa80e6fdb1cdec5e241f2bd6904b35a6b37461469c61ff4c33f6a5fa37a73d1e41c2059bad54b1b78c19ae1d0d98b2b637eb6db2117c3ceb66f8fdfadeea34d386316dcbee63851ad9d82c733f4af1dfed1a2419bebee6b334d59e214652b361b4b5efdb616d5feaff276a77bdc5a9906998b576b16770e47239cc94df862cef234a8a83dde24187adad2cbe081c3ab2f9961d4cb43d1e402ccf863476ad0ab9d8cb8560fbea4d656af7169b012c887ba2649b12243468734300eb514fdabaddbebecedf67ff8ec536ec449cf360b0be0526fb03b556c43a12a7db23a27150085447e5efb76330fd66f26ace44ae2058788828903940361dc3c8d4931893eef8f8bc552062dda824d5b303c6b4f656786bc8ddbc8988bb8ee76f821f21f9d5d6670152f289332b854fe9bc6b4d129a40035c5589d22ba8bdbf029822ef32d852b77ee163319ae7fc038d66a8c8162e9cd56016e978e7efc2df75fbba18ac2813f0b657a4a464322edb99f6d8c7dc4966b837d372bf99809ebcc5125d1f63cd881be46b758189dd1a206bf8d7a1a9d36fe2751222b4abb7d35bb1da8cbfde46c1a55c16ff21b82406fb7dba97310004c643a8d3e088535215c870a7ca75f15bd1aafe4b5d70fc08e396dc6c045f0ce1624fd3ee53350e69ae962af7ab9767c40aea3f835d306bb92e850e250aedb42426062e4857ada69acdb4588cbae88b12abb249982f0a49d62573382588d708cceec9e170162f1184eef6cf0603f235a25e91bbdc39ac9e17e06be7b1b03e2986680c03df9354e5cf2627fbf399583cce627d0123efe5f18344648a430b3948ff5246019e98a0c2585a1a396d37968feafa8c331e0b5cbf2f98b04fd8e79a4442f56c7d46f6b772421f473965da7ff5e9ab8dc294ea292f8b8e10cf74b27757f9f986e0fcab01ed23fc0755194146898cb8f41e6af4e5c301a53178e9cbd642f0664706642303fac0b086f9258c31980be532ccc830a0337a380b928eb6a417b698413fa46d336c879f11c0a562472aa0488864fc895c44ea5840eead8fa8fc44fab62cefd38ec948e336efc03048630b6387b041a232530f1c6af6b95fce31b08de14fcbc4e156ae510121aefa3d0d5a6cfbdab141f608075232330173848d57128e5cabb4027eec70d83c48f80e9f3e424c91be8e0a0012f332c954afdb9c52dc6cc482f99010ad92d48623fdf1f1e0ec0d40a37cc5b446350e8006f89961112da3a0e0a7c4379abaf66e189164bed9876672ece3e08a15b596a80a3851dd7f58dbd83f19a0a7465c0b68fe4a49e8fe74f462dc6e3be552f648034b767a8c3db37cf28c701d4ebcf74546e295e396ebac079762948feb6f642f3d0e1b39562cfd9133ea89c17a37e4acafcd06dc6204221ddc73383e7ea19516aceff94e14d1cf6fc525ed6299f7fc38a2c0ccee0e88e13cbf39863174222c6fc82ceeddfd4d5641715c2d08d40804835a90719470a71224441a5e70cabbb3d543a230fda42d0ef82b168860046717d3d0c851c7bd57659ce5d914f39a75cfa0748236ff7a86a50e71505d4edd6b6d428b3b5b507b7ed2738e62a0fc7a9ee1eaafa785ad14ea230aa03cd965d4915328a4f1b03d57c618bc68f2f5452a87729b3067a8392fb008c77b3d3e9ec35adf80b2393999da24ba7d9d9cfca13f9ef1fea905dd49f58c8ea946232f7cdff1e49813231d83bb1abb43632fd98c34e1948404e3c353dfdf385c8aacbe0a4f382e0fcf60a791ecdfe32d79dbdf41ed490484ce50ec659541847a1912239f75587ffc4d18660e0d0b9939198b42e3b8bd93842f047d6c75ca9b298b2ba542906e4a544209b7a4a3777b04ad059ee2dbdddd8375770001cfc26772c00b72ff9c317b811827a9449f4c262b70ca8b1cda5cf1131d9ec99ad573b516d3824695cf9be914bb39dd4af14df52a4b130ccf2d9688a6d79ae9d31b2df40d89634d1abc3480ea00c84c09be54a29b60cb1437120f8269ab9b9bb785d0518562d8428b5e1edb4bbd5084bbaa270c9d5f72aa065995a55d1b424db02369686d2a4b7ac02e3346682b33eabed2b5e688b2cff8291cedcac480217bac50c97496f3213e970dd6bd8bc21ca30c289801024538a8e2edf671e00bb98a724d5e79b8ec73078cc8249b77bb5ba8f508139598e15a3d55429bba79ce625b51550ba35715832dfba7e8bdf4d2e667f304024b77f929915f26073ba986714a213f5743312b53c6f77a2daa5a75004d0351ab8e1c0d0b73307b556cae262e64bb6b0f07b32faa43a5d9931717e5ed902580d46cf39a8e04cf3ee6d435c23ae4920943501257190dc660e68b550c303f77224e3ec374a66a31db640cb559189afeabe3affbcdafdbe42b5e8c170cb769a4bd07cbe41e0acf0ccf9368e0869de07545b3b1e6c85576abb82d8958d2c9f5eebb63891e40c26b5277add1d858b21cc3de71b39738efa66fe199ee6f623b06e986cc3d757037e8b13847ad31a6448e6441cd403ebc58fad94e03f98fd1fc1f3b4bc960ff24b8c5f8323f49de04f4ec4404064c6f6f0ccb210b7a7fa17c0141709b74bfe30a6840752552d43a8acf178c900097337575f6db3037b2bf8947a4c8ad64fb06c75a069e3b52fd1a2fe85b44aea4c8f2ce622e2ce2bfec877664c1bf76e7180ca0e0172dbe8ca4f65701db96c8bd4f7a68db24d805ff9217258e221b5907b794c505df8f6780553ec787bcaa01af3071b9793ee8f724170aa4cb436ee11b057275cdfcd8dcd0ca54a09a2213b4a76d2bc746ffc89865e9ca56ec45f70e563d5f18ad627a57dc235bce06487dcfb0aa240be19e9e22e116e2c3d9a87abde5553450ff311d74e6fa1b323909d27c05b5053a5a63356052f5b97abb8bb660a954e55bda68d7cae4889b1cad5aaf421d58165b08aa7dfc1095fffd8117bb148dba043f361c9c42bbb04006f9bc82971cf8a3f332f582dde0ec45f4f41a9165c6f696b7af15fea2a6a3bc9cfac9bcd6482f6fa73d1ec753e10c6941571abffb1ef7a674824d37b625fbe12d59a5216ed7e23c903b7c3121c2fc37ad9af683bbe1e4c32f65841d028bc3994fa6cb31ae7b17b170abfc08edef911be854a993309cc7cb186372263eff9b3bfd263fbdced814bba992dfa90647e3070e4ebaed50b5f7d46ebdd89e346d39818e02c69e54ca781ac2c1e20489993c21655c1da0bfb5708c7caa5ab1744417e6dd4d1bd049b497480765f51a5cafbb73c42597a3f15f50cef11a7c6b948a8d513f36a3a2729705144f8d6b4bb53bf3ee3ac467ae14ed1b66e9c0207ab9141f742439918512f98ef1366d010a3136e29df8b0b2cb195129dfae397564c4447eaf04288ea978ce6d6930ebbce4b4df9bee7ad1f1e2c047cf994459b9634c0a51030d70fcb51af5812f496c45d25d0ef9d274e84759b296ce6df5a9329030db5020f236e940e59bbcb73223e716bfb6071a5a0767c1a49c20f3f65e66b04743dd460dd729efce183fd632c927407207ddd69615dd98dcfff37d2a7d974646d8c78e1a4fe0bc067fe458baacc91f7a833ee5ad1d9a00fca6041a9e41ebb25c29a3c2e29b4770b9bcdb33fd3283226ba4d53d5cae4909eedea79c1dcb9b64b302cafe9ff8b0cb147b0c25c5725d82460fff2e5d3f86eccd3f37f2a646b666849eabc797c596ce7e8a0f33fd740572c474ddcf749c31a8937d33513f1e41775bfe0b611cfd94f04ffb3e5167a88df0110ad31259d200d18d712fb9cd7835dee0b3c6382976eef173198d01d5646e4ed3f8eed6c1376df0446e9a119ad5ec5089e1cd5353ac23c94151c3c34dedff7b493cf510e2fb252cf8075345417f71bd0fe894a53ec1dc76bbe7270f1284094af3b3fdf1728fc1b1450cebff9e7d2eeafc35e9b5b94363a8fa2345e6b813b9603e6483950b182a855bc9b45ba83ec009a807295328cd2a20abd0904356e1ec9879f29a53e2529edfad314eedf8ee541ce89bbe0dd0f38e4895f62b4273630d087d8b59c911ea36bf7e101021ededaf534b3570d23a53c711f73d20b0384bf41564c4c1d2d2fe7485aa4162eb92408f7234cb6651909252aab861c6a05dd6c57c44272335f3c0afde8c416b756da1c58ba03ce07fed67dcff9ec42235069855f5eb334106cf6c87414e6f23d7527f7da893d7e7c5785fb5d40e9f85033d2f5ec4c335f83f7feb360650c6c1a3ae42a9ef3370c0febaac7deaf85e22da9228c7f2f6de3310ca1b789f45a7c665c3cc49b744f9b671ed10debdc3967fac40f2340b864404bad4ae88328a26915ef1d57e89e89cbd6e533a83711fefed1583bb7f8da09498c64005852fc74068c92bc5911250f8e45ecc946ce213a744287748035f3eb05a49e28ead4576685ec4c5ef66b395fab366d2f407285349c4fee5e6e0db1757a142aedde649cf17b0b5bc7fac1fb7009b25f60b5a5fbb4f84de28be148dc9a6de24f822b16de7be270feabd832adc0917a2140b1f8b5142c1ea89ecb1324b3d50d42cf66dfbb1311f6b23c793980f5f95d53182012087bb5156e198fc758f0f54a873eb1c617b1568ae5040f4d29af3831d9be766b8064f8853c68581d6478198ed92346026279994220dbe9bc8c8c372bae0b1c9b339b71f945bd04b583fcb0eed39ff572c35b8a8fc2a144f30cfcbbbcc2c099b508ef64d00596957e8e2f267ec58bb38445cca9797ab44213ac2527e9393a7fba5105fde5ddf43826ce1c4867a429335e00db4a8238e633042de89016da8cf1e60ee70980e4938fd130225895286cf6e08027e010df04395f8e8cd2477cc25901e34107057b6df43a93c47ed7508549c3cbf1eb90a83d2ca2245c478a245a5c53858501d3207e732de938f377cd9f9443aa8cb23b4f122883984d43f2ec61c43bdc06035a234c740ec781a79bea2636458c935ce305ec61e58699557bebb80d98c3e096516e64f0226134781d3db0c5c69bb87d214cdff39b51314b30feee517a9466415073a20053b856bb73de46ab4470015649d6ff5bd563b5920c63691a3e118de7e4b27376f0c30fdb16fd4e6ba3248a7cc1d7aab9fa7d4e0e142cb528f2b043380563bb1d2c9689d785825f488512b213266df95dfe05475d5bfc7f1ddfcd670833ac62bcb7bb818ac7b35e4de09c6710160dfd7d53550ce3d1d7de938a79c927b748da4a24b0101d753bbe0c4d087393be4a7e886bda77cce9f0805c9c95d2a63a1ace43e73411f22d7a22add5de7a0cbec7ace078c5e4b434ea2a6b1e58cb4109cc437615d4a5113a4a6ffb5696c59bcf6e25acc884644b2d1a843d2fe3fe714035aefe46f3c885eb94efda5af5dddd23d23f8cef6f766aa9da20e5b211d63ab3916aba4ecad95f55923878efec6ed63bcb4aebb52a0b54d4000bb6fba8cc02a6a2d9ee9487387d66a7c7d373282d17f4d21768a1ba659af1a80e1e05bb8ca71e67c60979a819c7230ca0e113cbd8f1c98ee58ec99d432835afdf5ded95a2f23552d3e5d6ec95fca1c1e4acf8368a7d0f236fa98abda933c1a472efcd0c7660a7900459c1dfa812c9c3ec2120139e63ebc3b9c2bce861778464c0ad95e70c849213be22c084d1ee0bcc586be166c58f7c2125cc0418a8f5176ce56af3ccb283af9331d0da1ec2a58ce9991c1f04acecae78f720fad254062b54f2151683a786df0158ee99fe57000b6d4ede757d88d1ce5dc6bf04a5220ff8e6065687866cc56ebde6e053caedcd83e9f340234a15e5b249b7c202f95b4ef1d9c1d8f663721e5d397407b90d1af47473e098f53d265b0e809139c58dbaf3c57e96b7467db949dd206e14af21a706fed9905e282d917f151c986b17b5719c6d23c290bbf50ea194811f20160d5953806b5a6e4f86108c274524cba0b16e044127dbd795a90a4b709ac543ff481a45f74677aaf4612948959010e58d61087e287b26f97c83d5963d9a929cb0e4dda0a39ac91117742f4f0e597f3fd6ed597915985631c0dcd793d0278783a838b394f10a2558304e1b8db68a0d5ef27d7913f4fece45d02c62d5eed46462ebf566f4ce3d2d007e98535c84108801e35da8954ec920925ac491d5527600f4cfe4ca92737becdf08494fa7742523194a1ef3f7a2334e68941510b9074dd61dd27f66b411a57a96bbc9ce7398ce0024415d71a8d413586b4b731cc5b5d6b9fab2eda85c2e87f07148b0048b42a53c8c71188d8ec1e18a19ac56c96fa4bc359e655dda0221dcb6792e6907268a7b9e1fd7b6da03ff059850f826e60108e91d335bca25ca782e0d931188a9ad4a3ed02848f2400c573507953e0c748a4cc1e5cef29a6137c7075d67956f89103095e66ff16e968b1eccaf59e2a26813b48df531e0ab60c38902dfd1d0a5c0b808b706e74df3477b62d63d59892e4dd3baba0610d87ab73041b1e160c53d75e0085fae50d1f69e8f9a351c713f8c56fa7c1a04389839b266b70c9b1d1091aff177423b0d53e8d8d90b7dfb98c388fee5fc205b5ff902960109b9029139f89299c490e6222c57796dc8981f88328dee53a1d7e252205bb3931f2a5ad180704e759063108a4f91921f266ebec79d7666f1f8d3be78f74265af6877faaad54fa595f07511b6d1ec5a227bc26d2579648ddf773b8b19fdba08f7bb54ff1740aab53abc12ce98f14824e23304c3142d3ef55660d837410f87685c7e998e0924e1f9bd4f76bdd87a44ef9bae493867799aeccdd118d2c077517c251dfcb8f4581cea975255fdac54fdedde56de43251922b08841088d5262b57438dff8f20ac983362af4fd64eda2c49d6f8224925a13324bd077a1798a750c5b0bbad2423142ab83725b7f16212f34e7c65d7c4fbd918505292a5bee1d92b34c230df94c44d23f2676aaeef24a5236487bdd8ebfdb229bc03ec401ca33b968b691beb73dbae2892a759e2cca77a2344b31e154575611c75eab4deb7bb1ce7aa72d4e0c97ca145eb6ea85e063d6d4d7a198befcea52e74733477075bbeb05b6b03a6ed22a9a91be768ab2f24e6aef848398dba2b636ad6d7a5984c56230244e307460935f7cab0b1019328956795af79330c7f861f18e59688632d4f2832d853abff64f552554d987acf663b308340a811cd1501fb89757711911c525d9b9b0da8f6f2282442f0cee3a7703219b53ffd3822dbffbe679d67acb12d34787e9492316a228eade3a9c6168b4ded1cc9646f65ca5a49625493773b7fee441b84c5b91c85d18b33911a37ff95dcc11464be559ca34f2e890b690ca0e715955b5ee26de211e6b92fcf712e320fb6a99254ff6c7889c1f53718090d835f181b63622850abdead2943548751b717e69d853aad53971444585832850d384bd52aef40cbca139812c0ac1a8a29669e108f252a1cedd57a73d3ee6324d2f8009164a1141dcab06755bc6ef52ae49b958b6ec2c92cc9061d098e26680f91eb50209b91eb0fa7b5692b03a4a9b8910114c19dfdd9247115d553d2afd910f6c16301b13e2406997421fd32262a987a436e3e31d12d7572dc8c40e875bfe9a310c142530371d8baae03d25c9fc6155bb7d44148b9754f20fbcd8a3287b7a612f598bdd82d212a77b2ab756e4dc84d1d3bc42dd759998bd40d8de754486baf2bcf992dfb8234cb7e34ec5fc4ea3d4a1f06d23dacb05bff71a833fc4a7462c79138bd2635b570aadfd97162bdf2e8e85d194702ed519fdd9935112093909a09cd2ff7b902f7322d299983bd4b41f3d1102a8bbe62f94224bb2966ff39c515fb4690788b2451d38a8b427b1ac217caf6f7130d0345dcfb2fd77e9687c2d7369458d4d659e44e2fe83bed638fa2ac2e57bd02fff09fa2607defad6bdb119eaccc14a9e9a4498aefa163e5f36b773b234a9bbdcfa8609f049cdbe5c9182702368d8db5fbcd4dafb01caee253a832f8c9e95e2bbee18268463d1cb83ae70e2b059f77f96961c20d35a309dfc432debad47e45dd73b0675e7ec4fc592596030244c923eae5db662a32a685feea89bdfb65b42c9fb4476e5e877af7edd73e29aaa3f470bfca857ee58fe476bfc88ea39a3f080e4dcbc0d07adec81cd559cc8442d51d83def9f94d9d2a800be79d930d7b14455827738ffcc02ead669027b8a6e4b91b839452bc4e8ffd61f0f7837e8e1eda65a969681be787c9ed56f6ab9dd7e3457edf3044c9aee3d826b1528f974d60636b6139062567148ebcaa5f4a7a1aeabb9f1ae9dcecb708dfaefd0d55a82b1c197990358412de1f994b56905a8a515e5462508117863e7687f24e5f89a67dd5d2d66688c0d1a9d109fe420d87a68e203ac099d4cfff6ef97823c1aec3b4abed2cadd265122eca92b8426ba38403bdff651fdf8f4ae23a6522e43335a293fd4ec25160f7deb24a5c3431dfd1d969e3e57190caafdfe1cc34fe0da68fda46578f22e9b1effd677d6abedf400ff964dc1d6e3fb0ef989669182ab2126de80ee1d61dbab42896020d9da1088e09f3a1fdcbcee7ac29f7fa8409f5b80bd4832e84ee08d16106395f854dd9aa55e5d15241517860c93cf596aee6f6496677dccd79f692f96dd91fd07d4c9999bd3405737508b2e6735bfb09c2f08e5e365a18f17938ba051e4a79ce68392a2a544e95ecfebf289b82290347de629a86393acc17a24bc251910ee8f9b40983f8516a64242ac6c94f65d58d634c7081a5e9595e8e1b0771d8d0a32b1e8a317d8019d61ee272715941591a4328f76d7c33ac6e76a72b17e7db507e8c485348be0b0ae6a92e12631fa353a55cd93959c8bb43a7b8ee032ddea67b3576eee3e7adfd3c07c751a0dbaec82cf0bbbaea5f9a8335851cc6b8ec6915101ca38f2db87fcb21e45b00e0026082d1325163cc0bf5e69526c7ecb4810bef6e307f5a3a44a5afd4e1c90b150584d6006190c0a87c43d68708af1ddf6acc14fede2c80e2c4008b66d7527840ffaca8266ad9051ff3eea2f5eb2bd1fa1578b44c0d797e197b066f620164f6a0a929007e4e997388d8695abb4b63ebd4427d889d85cf40ca308fcd300662ee539d92b9b3288bd0208f2882029a1b0c011e4549a18b3e81dd69f22e0a42a0bd4ebf20f1ce76f101e8c58d37924756e66a3cb2ea4c8729a96188a811d1331d176b8fb07f7467642e1e12de358d3931f8177b03b263c7c896b2a09204fac587a17c9556eb9b1f75de489ec3ff13937cb105221b53904ee009a9cbfa44c6ae45df18f28b2e454dcae1759966c3eb639d48098c7382618de65def7cf2501ac7acc9fa1748282cf9ebaeee10e4edf4703b265c8599879abc8896713ebcedf0723fc9e4d51f5e2ad8e4c1345692f6145b543e52d82486ad168c2c4bcafbc3ecc4cdc6bf6d2346903ac5f9c267a5e5021af6a4f71b2270d6b3ac20abdd6a66f147a382427b39a70df244b3d3f24cac092a6864753e038bfd2a2284a05275889e4389813d7bd988754f2f0b8e837dc8b4fd371f7ec37c52755f8c730abc1ad03c42eb85cffc43dff43ba711a793f1bc430936d27d7400d8d46e3ce2f7fdb4156082c0db19ca1af31cfd2da816e332c98710664cf351c39e1899e905b49b170441611b398ae4e96c3b10ddc8371c4579806de6ebc63a51f799a378535ff787a72b1bf4783fa9481c387a338af5edbafdd82d9c8d9c013177712e4c8e3c636c76946042a8b99461597a34cda80de95b01ef363114f55a8d86f925f0f70fd7fc62b9fca41cbb71ca6341ccfd25f1a3dc0600e9af67d826073e710c1834488983e43ff2b60585f83db2306306a0af2eb3d8be5dba5ff1a8e39989689790018845988426877b868028d1dad413f6291a1f93d8baded4088ac28d324ad92f3adf65a480dcc9cf90bae1bc51ad704418536ce42aa06373904b810cc7c7b73f4154f23e761086b3170c12544d864793f5f4e5c466995aefea0f01aef11dca5d7feda1b726fea83f253d57549bd1fe00e1f983f00b0f73c9ff4caddb57325ad76aa51e7b33cc0d7990b68a962c58184d18f2889d954d8fc4a584ab3b6113819b406a2c9bf3333436be066a22a25d4394155ed4f4406809f542d55cc342187c46e9c86c9ff02ff5bbe8523e482448cde73e9ffad3b6782d832707fd86775cf6ed35bb8c9e822b301034b98a9b112b32c362caaa1f19895e323b1ca6d203f7e2f046f9d60cbcfedadb3f3fb4a8047d2690362b3a88161e585dde100b515a7d844b2b73d406398b5686d41ee560175e00550bfd24a822ca336852d09668c5042463eb078c3541b414b67d886aab4779d04ffe49581a00ee2b56ac8a7058ff33705881a7a41bfcb0619801165fe88886762748372be37c0ec1e23f421e957ca3c214e5ba6bdf447b6cbe6d4a73c3375078e9e5a05e99d68bb3676cc8829acb167c453703f3b1ca418f67d164f3e1106f3ebcbb3810ae52e8fb1973455dbf089f4210611d29398fe7b7c0aac47d597581906d72c25b22d12535aa8d63f75b34404ec85be4cb5afd693c86e87e60a5b0729d4a72cee75f07e566d89783ad86e6d5f4dc2ddd450876869979f962d91e97e2ac543bc00ad5bf251018ff0d3850004c29cd664e3c5675bcab06dea1c0fb9d3d4725af7e12401596f228c847b945a244148c637c572b364e5ac47bb1a6c592261f44bc440654e7d414beae80e763a7532c109300701a7feb505f828e6ba698e96db977dc9bf71e90eae11384cb3dd86c5ff7fd1c01f34917c6258fe39f59ea44aec355f4424c07f44be397011990ed1a31e48b0ec70ef830d5d8ad65ae6121a71e535b245e71c7c085d7edf5fdfc69fec27e81246e8a65b843673fcebf37515daef4e0ca28ebb5b8dfd91ced11724c9b679890b9f07b727ba885f6b08cc7896627f7941d021634caad1a9c8c618fed61287231b5270c348ca8226cdfd00e00ed1a9b9f5b8d473c9bcc4d4dff5126499fbabff90bad51244dcc44c3c09ea25d75a4f3ecc6c96a8955203e79ae44a315d82a64c4f3da9a899c5140daa648bb02af8be34cac4c416d03ff117b4a0a8001253fa88634487179b8662f4815c9a61d2112767d7b1bafb1ecfc1deba3e7a04a09d375953aa304cc04845bbb4b761c073493aaadcaa0d8325e40b548baf335829a7177e0e79fcac2b21c1ba3aa205db786a04dae2c873a634b4746e4d8fda481e1be5e237f83022035c9371af5b56b34e273391bd862db48ffc3a655dffb02efe465565900fd01ef86bccb51c771135ca4787afc4ae1f0d96a74cb6facbf142d940ab884bb5aa4bceda8d0b0fe1d37949bc9d939af5a984a17b3bf65bbffbeda177efc043a2062563dcaacda49aa4bfcc2a316c8b8053829151d36a79e5dbac433077768045b5ea0af17033366faf79f31dcff81f77b41e69d84fab4ad37686485e04222261d69d5afe73ef5beed92378695b6c51ebd7838f537033efd8e3441a873b7e4be181ad7acc77b4c18227f6b597f3acef76ff8b45eed4b84d88cf751b2d6863deb96daaaa9b81bf6b1ba0cb83dda3cdc4e389d190d48ca311d28835e3e5e0226a14a1d71af5bb2f0436222ffa09bc526072659e9da3ef7eb8a7023762452400813187ab749d3f1b0fafc7abf15b7b0499d65248136b7647e0d9a271793198e02d9b6988e2d3602a1a68e8ee8a3cf0b02a1932424fc7ccb39a9e31be028890a33a4f42c3ff0c4b90c5551ad3198c30a10a424c93e62d966782dd4068c5edc360d2d0a6082b8df19eb919bfeb4bb75b9a5b8488b2bbc7e7bf6c21fa6e86d71f655809ed9307826510bd28770422e863179a86026ac5e4981a94c87f2ee3a6ba4a106a8318844a2f7c783568c31aec9ca782ad9040970262bfc64a5b58f49ed3e5ff653a1ef8a1a372d9680fd38cac2493255212d45b0e9be62c5e7868c9f5199ed5359400c929587ed7c812a374adf1f7213d70306870db7fa01416c429986ac6eab58f802a458ffab694c84b1b92bb5f62041d0a780133253b68a0453c80745ab9fc6028cb31d6a5452cd9dab2dc07e8817d3abafcb66b0a4caac54fd48cb29d3bff767329e75355c270ab4f2bf881ad5eab456572cbec5a8bb2ae6f31683e6e457748e081bd198d3f582bf749e3b104384d6279e678151edf384fc58aa41975e75a30ac6b54694e02575cbf888358c2a0a20070d66fae06537a169e7c37ead15cd63246e8466254a6e14067108a06b97b98ce478eb55d5d7e7e36373dec5132eac0fa6d7d9200a79cbaa3c039702a8a75d3993df2a69710237d7e08830f061b7a95d117ed33b8ab3ac6626e850661f05d45d0f87386bfd22a1b324e5b397735ef4945c6fa68b039a21c1eaf3f0563abe608f5e3dbe4ce25c8e3e31e5311826cf44c64c88490c314f3478311dc2ec2be70aa33360296da7a5effadde8f3ac6fa78d7a8d3850a85ef0ae104c45ffb1a77eb0a11d4123db6929bbd760b0e4a97324a3836e93ba0d459dfe2aa23823a9d6b48d935043528fc4fc12fd97a4d8b99cf9ff6928f2021ab86172217347f1fc12a99d5fe221eb1dfaf942ee90f2f5a516f685142b7ceba4eef0ea50c195d6de02ace47f806ff3ce32bf054891f3eb04e35ec1c14db0321606a4c7eb17817a849c31299cebc03d274bebf20471448af500fd47e1f2be0c4b87966399b2ad450050dc415ec2b1eb51e8706a7fad9c4d95d4f88210a46e25b379e355d1fcf54f5103ea7a08689c97f4b14419365636bd70fd95aa9d60fb7bd82862e1a3488743831944f57417d93a9153e561e07d81665912fa169d174e4eca4b7c8dd4f88b56912627e0a6a3991e659c87727c80c04cd567253317b47a48ad97b8493aafa8c037b68d65ce6df9a9c281726d68ee09b0d86baaef5d948d2876e8d60ebb80411cc3de07ed042dcb64957f082f2040abfa698d9f170a6a4240098bba558e089b43645b3ef792ce1ffb4af7688dd5e265017329f3a2d58814b305236ae8dbea99a360884888675d266242a8c11f85c4535a344e28e05806fd73838ed6b1f5249c57ac6be93940a3991d8a140f5d79b7a5ef71c03a9e9989f51e25bf652910ba6c4dfb2f3d9cacb5a70fbe3c9d8aaff09b990cc31b729e5a9745947b0d5d8a52b1dccb2029f05f5862ca0e30a78bdc7c2e03cafd831c11818bc08164bde4a9469d8c79cd975e4ca5b8a57b95e46546c56d8210592ea0ddcf3ac3c8d32d2fe715ae8dd1e56887ed25380dec9445230810db86a5cc943452b7ae28c8b6c897542480ba4f8d9fb1e73b6c3d93826020908b0c4bd4aeaf9e5611e98eab6214189eb1a9638a16c301447bff7f4c312b75d7e29d1dcf1a771aed40fe59c54e8cf3f908bbed2e28aa04ff9ad33b7c38c08025c46aa7bd17e0f8e14e53b9ef24111b0c6b4c713bc5256e9c5a699738d73f5dc97c8392f695347dafd12e2dab52fa4ce3260fbfe653b68fc8d6cea7b50035fdc0cc670df118c3e109596d95a8aadf5e1d3e4bf97c1988c963884b3c6c13d88bce8fd9773e9894caaee6abb12570b48808fb5bece15253b8b404ca02f3946694ddff0c1c29da0b9a32d3f2254d263c4f7ffce21bbd9a948e0628713cfb799499bae0466ef937b726df09f36e288b7032a0489f3f00d8609321dbe560d7527a9929eb380763455e39babc9b4716002b2a0a62062e89bd6ab11c7ce96127b2e9d0a4901369b13b38a9131927e44948985ec492aa26a904ec6725201f2d7e582d752d7abc9b0825df682dbccdbf38cb26d6d072afb699e4189ab36858df237352f80c723439af64f955b23a2ebffd6c3e1e57d59f170e6531c518b4c2690dab35d6edc8924973cf487b7342cdf803340d5e51ce4eea4485ca0f207fb5275bf523c18ef876267e15d9325eaf7c26337ccad59eca95f56718f4a5f19f4a74d9f4845f775b19548f1fb3943ea47abd541c3c643bd96b6f69ff7bc23907dbd216c2d7ed90ce83888a9b3db6825147c6136adbc8281bbf28871c0e1fd8405d032e0d1e877f765bcec262b14451baa20b198b1ed679a6612bcc8f42f2ed1a9fff3b0d998da9f7fcd666f4b091eb885c42d2a97804c95f3c7a3367208cc26fab7bbcc19856a1c1dc03c5bd0e527e5f73b87c06afc4b870d941f5dc33b0305760222ad8c3942531260588b26aa1afeb14b42174f41bf6c2dab199649060f5e3102f561f136403f020dfef3e3a7083a45bf4d9b7f8f3f5a8af70a063476c53e38b277d502362e6eca653d2a1eea8f51ce069c8af0855d90161f82a3bda13899ad6c688f080c7f8866dc4fb07ab0193c7fc19c4340f4ce48bad30fdb00e498a23e22759f6b43e520c36debc1bfbd0eae882b637611990734b3613048dd20f9d7254be84b3b16a8e4fd23e31ef72654863038093196894540ea05df084956d3317dcf331c58a46abe1a1881af5bda2ffa650c841ce02bad6b524a685ef475028e38781e118e194b04ca23fbcb7dd45f6b4e47e17267a9433b17327838ef0c551705dd3172f6541322e14b810a81302db5bf9c87af41064ef7bc86cd362557907f0a147add183064f67497e13382139f0a5f49970944daa90bd138e7e1997f800d76a9a3caa99f5730caf7fcdff3fcc7f96f3042f9ee9fe11e5d73216545c5ce8f3a646174c0a2955bef451a6b287e61ed98cab877fcf76b33c9eb9f13d760677cea1eb83b3d8a959e36a66d7d553b727d9a71f5f3f40cfbf982d027d0a88c44952ba8e994f5cb23a66060736a69c9fd8a0b701333e9470215bc5a7aa6c563c2c78e81a5dae07eddc8295724a7f152a9805ea10e3297523767afc67a9cffc5610735b9571cfad3673d39bdda1b2a9106f806bdaa4d543ef6d92bb397ecc5f79527e0f8f3a0d2e2a15b5ef5f96ea287731233b342b31e56c0aa0e0f6e4c89f9e65e3734a4e0f4730d74680c4ee8ff77a2c4aa4e039bc389f537dbc8baea03e710ff8d09dfe6287417fc00da4e3d4e253997b6eb97a4fe4aa2bf0587303201054d102fa9578776b73fd785d5434fd37738ca83ef8edd760e899feab09e1499d03f968e2a907f36882f68f542dc464893649734783d5fdea785c5bcbe78806a44ebf58647aa33e33ebb6b52143ca683249ad475c2fba27f46d3a448b8773fa57db21c234f7b3f85ad9f0c6a971c93d0970654d3c6fe3b65fc612529425f1f37bdc90143d4f2eed093e4fe0a5de19fd0fe168646deb712a7115c54098333f87aa45605826d1e4b30a78167db5d5fe85987d44daf12df60e0e589e6ebd4655ab4d76614b0f5a408051eb3312d4cbcb5cb14fdc8b182fc028aa8cfa364270bdbdd00821b4fe682480ff8abbff6516f9e8392dde0af68dba48220816e13c835e9b7d6f5fbf354ec1453574b280d443f05ef3b3b02f4a344fa01e02b81288ee643ed9818910806ec1dfde6843030cffb2eed9405e86e964a9d21598fc6c76ec141ad8b7be91bafc03c2d0ed6b1bdb432fedfece6e7fcecf1bb36c529b67bb9a4fcc2806f232d013b8c786b4e2f56abe2551d0ef856cb23bc471b5843a8dcb056c29d60557522912507ba4b6b3603e66805e4b9844af227d0a7be93062ee09effe152df392ccfb0fc0f1a99ed994d589692f1bd445aba6ecde05c93109aa0c03f998395fe84cd1ab8cdabc9932b5b48b902602c36341ba300108b84dae107091d485f5f4ae7fcb19b7a3bb522f106124bd8d0b13e79738776f2bf616599770c0a2c4977d6e01b98fde149e7858e13aa0bd81a605ba54087d0cc1c94666563b716df86d46db9d662e54879f1ff17e04902c0ccd55bdc9e8bd4481fb4298522c60066840d9870460b9ed02e7fc146cf03aa02939b25a66b467b234278c18b4a0c4a7e522f3298028488ac4c92cf80656122e38ff73448b8549e05d4c66082c0152e390026f00a1e82d28d883277358abdf97a428403b211dfb1e84894ac7ce91ce6d59cd348487dda66aea717d7e3f597e30a210c2edb6a7d3bfb53a503835a6905b4f5c7444076c94bd723f82f6f92e4178f8401c207dde9227a467b03a3ab117ce89a87d0d3fab44edb597038d2140ed03f3c7f70ab34e2c4db46821015812b799bff762520d2b68e40367bd45cb9366e5626f8f919c143c2d27523f3ab5f9350d5566ff024062f27ec32341fc97bb14ae0972c0b08f8622c37a58480f7a8576dca46e78af8cc14c3fd6ecf5cc0ba9100d361638bf64a2305796fe6bb0604894149395d325899f1f760ae9c55226a10de29e1b4d6d998b55960a6bc27b28400461a678ffe17b4c2c5009a85fba2a511c6745b1651b32a2a87f51b11ee95991e2b13157634a716356a1518e908a68e3e498e586489efe4d1ce541b40dd377ec57d692cab1a691cef0be2bf7e2859ec1d30a239325f0acf0840ea442eb5b3a1258324890c83f02c20f68dafcbafe5919a08363424bc3f0ec134bac88d5b47bedf63d8b0222d03cc817be3605d24ed40066ba5df0a724cd04863ff6e0c6e459e599fe7ffd3d0df72a40bac7d25de72a5908c92af99e6aab2695934352ed89cc74322c7fbbf894419648424fa84f7dbafe86d4c4213aa11b1c055a1e0c37df238c9ca40ec5e285c1a7c7fb218a6cfb00f8e7bb3f409276f8b46c71962fca1a907f94ba1d127f9baa5a659ba78c3837856a63c3c30549af17c774f4573d9a7a6f8cddc608170b6c36868af9a94734d3fefb71b89e5db22f3fd19285af7daa63bfa2311c3816fe25bf1e1be0d6ae3dc6f0598abd64414a830dcfa400b7b8114b135de33b3cd9aa670f0579850d7714ba4ec113c6dafbaff1c4e85e119fa8b2cf5d12988b16fb128e78bd586ed518bfd6c2d4d8f5e548f9cba0db208ae86c05ab6394feee18fee61987b38ae289801429ea69639bb457f6ba8ae8b1f2a684c4a424848c68b6a3aaf243a7f38452e805b31f1e7e30711fae50230a6170f9cec5f0929799ea65fac7fcacebc06eaeaa2c43ec0565c1412bd80f4e9d519a7d67038ad8de51bb2935da61db65a7ab707bd083825fb877c840355d81cf28e2efdeb590e713e2e2e8a2f5b54e20889196650c885f38edc6e192554db12b5430b99a7e7b94bb8198b7111592bae22d490b1bb6f2a52c89c0baca613b033996b4da9010a82b076e410d1fde70de584550f66c007dc1f16e2b8fa40616cf011620db238c0f184ebe2e556877e61377a377a5d9d3de6a7c1aeec4009db7c2d9a1a857a4db933083e0583c91608ce241fc10966ba4958b7aa336ed685fb6886597b7a4e1fc7240b34f3e2d30f40632b9f10697c8cc6d2fe84f2e587012e64f56cebba201764a69f238282d27e507376b1857679519f17e664fce609fb745c45fe9973c30e6dc5d034fb5333835b1f2dba345499bfe5935f22dd005786f30ef52fe380d47ba4acb9ad7224ac55187d4b4d208eba0164f221ee23c7dd5952a63d4fa89cc30f7791561b131aba08f5609dfe33ae0faf61f0eeb8be410082cc96b9c55ac1c08650e2a89d13c76b4c5c959b6b6c6787dfd802b3995512ba259b1a36288ca981f155f8d52be969dc08a2d73865abec231b33c1ec65ea9f5ad8450817f9ecf91a883275f5f14de3929fec607f05e9fd10813a932e21a79f96f2d0e4b2aae9b9dd661fe4990b921df044c3cd6a61c5b3e3a0ed80fa835e34034892acbc41bfd172bd299cb8926a012b11c90af2961795f28a75e723bbb3f70b3f848805c3574cc497979eb1239d917c1ca8a8a5659cec487b4bc6819cc80e6ee9c041c2c60f5973d68075bba0cb428b392ca0362c8eb2f91b98537a8ba44f045c30a064f2275408fdaac923ebd0ea16552f5fdc0d0266d690a6c6a4bfdce7ac49b1d8ae47564bd4fd3cb3867ec9bd8ed0bc48055c33a1fd8a8ec58972cc8c99a64684d68c3e8ba004cfde9c5b698b992ee59bac517d83822f4814034aeb51f25d319ed9eec6228db04d135b9aa55743c38c267ddc32b2d7d934e65ce9f08c20b8753071b7d3c04cf02d4171d8a41000851d16335e942ff29b2e93d916770b39a451b15cc766c621f9567db8e20dd40038c74f30dfecd071ea4ee34ff364c2d360c989dbae6afc62eb9cea48c36ce3549f5c0e79d83de2bbd5ec60c4a73934cc70233a20f101703bc8fb5c21ad9b28279484f0ccec0aa8a22713a9fa7d3e31843c28e6552ce8a553c00cf5431c64cc77831d31451838c2d0e4be3eb65dbb3b5ef8d4dcf12ff0f55aa634062d002b1a41747e0660a4fa26395dd059917267f2d085eb1bcab2a7236fd20097e710fd4f4ae61537f07d57f263b43521bb9210e800504f5b5b09ca7af7ed3362c68d93367e06264a48593d5f12e512ec8a190aebec6000b917419f009a91953eeec18c117cee553f994e12440577bd6e3246548c4f7aceb54551db265ed74e5727091e80e8abb00562078ec5532213019382713d48a24be5b3f48ab8f8723ee65d8b53627bfa79e617340299abd4eeed623b9e7a5d1c052327e45605a2cec00ebb6bd8bc6fd2d433dcd9436b85995768425f4221720d03d27dc6adc3a9b575a38d47456aa648e245198a62e957dc4a4f5c9eecfb0d775419f275384f798f12c5cf23a15a0b9db277b692fa5849a438002d35a5cb1ff3687eacf26ce4b417e422d5d6644f3dfde437ff79eda13a2d0df69bfa87385ba506fa",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xfd60496c14d5543f2dce66aeddd0405e70d276444b70b28f9d20a445422ac1db",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xc3314fd768bb68b986e80c0a14175f6f72630d7a",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374e70",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x42777dfa49a9a2c8ed0f797802540a8425013b1d764ad2468d9a83f49a7dcf4a",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xf1b0a60c5d8d79f690177dc3afa9709210041b4bac10097ebcd335130250490c",
|
|
+ "timestamp": "0x6ab8f1b1",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-anchor-20401776-baza",
|
|
+ "sursa": "2800-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa0626573752032362e342e302d616572652e312d643230333230312d7774613037f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b8411e11b71c0c144659c001d63324a7884832f2108a0400b7e7561806f4433c847a0c5f7a7f5817f523a981d60374f84412c4b83d09c1bd81f3123362831f12644001b8415a4c789249c9b5b23e99568a6e0f09f05677481060448e83467e7ac9c806f2a92106087ff4e966c6771069bf1901a771b4f93581cac9742ac895149000bf9f8c01b8418a4085f0a617dafd70158fd365a836f8f82bafd8cc2861a06ea91166449e17c805a09d5deac53b74e776f59d562b936142247b0accac0a19a794c09ee0dee86a01b8417da38f1d12b715d9489dc6db49d8472193314d2633631e9f6b49b42db8c6be43354af63fff564e5b61cccf27d42ddcd9cc59cdf1dc62c267a9bde7694753751f01b84189a2d1e2c507df658c641c5ca9cf0fff9c7c80eb0d464bba3172682e1f00d9c648bd12d8594a08d8166849ec424494deeaa1e48b950793b107b756a75338ac8200b841a8c35a61d59de1bb7af16d847f6fc887b8d140ae676c88a9ffa67fb2730960927b348180be5e4ddd0c112186b26084a50d19dda43c1b79c3dfe777d10e22a2e901b841cc5a4488c8b9fdffcea1aff9877db32c1e17eceff0b5a24a74302ff82ef4b4d268add7d838cd6e11ff40174b331dc02248bc5e462d86796a896acc08f04ffd9700",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xe6a57b773f7c8cd905cc42e95d75dde90f8e5d41a41f879f83f16d49081fec06",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x5f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb0",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374eef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x430ff461a8a5d0a358ee679c13a559645f3c22e268dd07de95054e4fb469a0fd",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x26cd4f1a96ce389fb9cd6e962ee620aa57e647649804feac6a60a234e703c67f",
|
|
+ "timestamp": "0x6ab8f1fc",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa014ff6a08f8ed1eb5184aef26bcee23859a70edaf7d5c1d52d42019c45bb8da5d468c4fff8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b8413313339f90fbee32be78ba0506b03bc76ea4c69a447388d629583f7c3df44cb247b93b438d9a8eef3d3381d3727175c2bbbd0293b7d304a434a13c05d909ae5901b841e403b1c924395d56c1d587c50edb0d64638c8737e7da022ae545594b47c79acf22c892a7daa93dcdcd3ec5c9c5aaa00b4a077ccb56517a1539f39c3bc4a826a901b841d42f9ca5b26d80fb2f1404ae463a25a140b31f22947acf89048ae1276c84223807edfadd768b6499d5c5c6e4d70b5756a129e7511ca38ca04ea434f530e7cdcd01b8417d4a9d3e8f3a82636530613905ee68e03f7982f92332be72489455ce9d86980904aea998130ae889a99cd0d179e01dc9c172a700c8983cbbdfbd08e2f400fcb600b84145ddf2dadd3f83061e1610a0de762369a0504fb0c5b12abfd30aef1e963478b8028d5ae415eb78bda620f3abd2aeffb2a63b9e837ea0050154ef42fde4dc8d4e01b8419f861de8097dac33214f6bf3ecef11ec8582dbd7a3d0a58b4fd86d73d39c72ac21b5434cabaeb0d1bc4e4e1a65c0aa122159e3cac3a740b61cdf1759015984f200b8410565c2205982c9057eed981fc77f8eb607be056924a482bed59465b3fef8a6207b705ffe15a4ee33381d364e03258b03f8e46fdf6c2360fe48428cb83975d95f00fa014d2302fa014d1ef9029a0180b9029539c3659f3602c6f3a67faf02d36029947bb633869ec749fad5ab8d8c2ffe225547f253a9ff7359e5b54afeeb10038b2236cc0c3f5bac4f16c52dcdce986c5259956c12da5232fdbdeecc2f410568f749042d1d3af6f26ede7d661f963fd111aa9e45439d8846773981153fe448b899016ac6b7f25380843d149a550d0429aab45bd3ea665095974871bed3b48774c5a0ef56049a64d706a927fef18440985ddd044e66a2b2a7cffbdb8e9db3283190096b0fa6d8558b040772369e5a0c15867c3c8d51ceeca029873d506d50e9bd4538439ccded1729cbe56de15847b9a8a6c4dfab5e3f53cbe75713ad4e406718b690d94618b2629798fc3e944699239fe9ccbc901543b70f14a937b5915f68ef6aa521609cebd14b8daf7c4295b2c922b1a37d9217a92a974a3f901f7e1a1541b32641475831f1ea1b4915ec12b65ba98dcb73e9d3bd86de2952c5d6f475aa14ab04cc23477b1fdf16a659086792470704d971fdedec4d98c2cd891c0106df5bbe8dab26e6cfb65f8ec2e5b86bdada3d5bdfbe3d68c3bab9a43922bfd14bfdd53f4ce3aaf2f965a43693e46418a633c0ebb7cbce56f7206e73cb22768f373b513c655b43d1b743d69f2efa68c4a1a6de6d397b933567596845d07343d7239e563b0acc3ff4797b7525425825c558e6b3cd056524490f7e9740e85a840a4d852e589b046b02d21306176c56537c1f8e7adb35a47f7b12c2f3f4fbdec9b2863029ede8f965490230fa2f7b0d35ff4d2bafef78162ab4084d63c47ed050aa6f7185654a59b7b2749704da5df5d2db2bb91422a9f69b1e9b218778e624d7b8d12267fbb1d742eac59d685ec96718f3b6533a9722630f9a37cc9d54f3cf54fd92848547c4e88b26b8e2068f940bf2ac6af2e94209db4f592c42eaa41387015ccd2da9978a28cb355b28f91eb50280b91eb0a20d87fa168f75eed5cf9f588bd16e06ba8b3b91374bfcbccbef20ea7baf546c4ed80bde1a7f36e9bcde86952734aad51311efbf4ca3b1aee9847c9302438aca3079805db45cfc21ea7edc966d71b7c4c7b3a28d5bfa43782dc3f6ca065e3f4866c68376135d3eefe5a3020bae7ba57e4e1f1689a895a5dd58f4681c37f8c99ea7c03f0fd1ade52956e9788bfad0002eed0ec26a26a41c78f179a276339c5408e76c17e03e8d349f77f44058a931b38e6b4d861318d9d88382271292f73484b7569427757c5b95827c80dbe7afbd546735a43d267dbc45176d95b53e0cacbfd76edd7713395bebb25929ed6913323d82e47f98f11f4186e283f746c69b7f7c9cbf52429f852d5e943787856214a5e5c7c1e493c94f3e44377da50da388e453a57cc3c3ded7e13d4e50fee360d1a22aa1de32705d67e93824123a52e5de008f7016861bdc5fbc97525e714c26cbbfbf0b03b04fefc07feed5b1aae6f3720ee95245012223c692e23b094fd9b5eb71463ec0452577e63101d7ad5afa633db78355ebd235ba791350aefad6582af7263ae21079e9648eaa0cad3859ff331e981fb7a7903347d1d051774a30072f117f246dab0b705f9deff92408a28b53dfe16f924fdce2ff91903085adc607c58b268385fe10cec91b1ee82a504980a523f80557a71e56eaf1b6351473be794826b0e0c4d82870a58f4ee4689790322ba2ec28f0f2d101ef5917424d2148a9378d7e372a6182f0a1baa7e3d08a42af8958d9ff772527e4519f84de393007a835bdd7a2ef405eab537af8ce79b635c90e99eb89b8a26c76171654692172bc8bff8ce44ba535cc9f1cb92ca0722293d90a6e025e485ef9f75b70276a5ea4495ce7caa592b90c5fc21b5e83de95eb39d80a99a8e9c99f71d6648808403671ca3560932750004b455596134f7fca20e382e7917a66fd6b231d79295b237e9fcb9db111cb50cfa2513f1f53fd8766d9a7593b7f20b3a29b8a9f9dc0272fa37594679bffa699e045ac0689980656bdd8b9b0046c1e07a78c88bb79c203548a8c4e338b5eb8de785599fb682b70e9d1eb0eb0a9c94e17f683f5946c8df0754231a1e465703ec807e74d2e9d965ba5af672bb456a7990dfce2a7f5f977a7a90bab4236bc59f8e3a06de6eb9540e5d00c650ec38363ac0cfb2e5b54d0214a7b72b8a2a7e88ebe3a9cc1cdded80a732e716ec4c2ee012fb35c8559208fba60f3d5641db20f8968f38c66f43a06d154e4470ef8707ed3ac37d1e9e9dc4e21ab6c6f01813fb90a710b73c7655191d9399a2d38f00ca5094dac338a678bf3baccbcaaa974616491ec2246d1f5d73ed921f4b0da4e8d0b5d439256d8d52b1a44310a41e622fce4064e65c8d78b7a2a3d8afb9fa14fb50f7001c938bc5c93ce08c9ebcb79782de2de1488563d77411eb04b7a167bad13f2330fba357dab65df1126672e3f6ae081553c6bf6ba5f5660cf1d23d930dc6501fd9bc460a9a28ff794acc6504b1ab672dcd58b78df6dab63635e356cc694579b5030695751b8c48a7ab8f133742bd51230afcf6ecdf5dc2cc63c3e0bd562b810e399e38d450ff46096ea9307b61e85f1f722ffb7f219519829f0b6f216cbbf79f4f6a28d63ff72e4aa98387951f69f6e4ba2f98a3bbfc1ce4f1d71f88ab71758aacc4b621c8543e81a12375fb99a74cfeb66bb46b980eef50ca81ad0b7b74dddbb6e1cbaca1c22c680a1c770832e97e362c2db0b504fbb690fa198c22a4ed2bde5e40196fb36730c5dc03cf42b500b77f398a21f40afa747b8eba0cb5072d56bca9662e348eb7bbb8b2e9fc5881423e2cb15b2eb6d1c8b22898d906168d71b7ed57bb27dbd0afffc97d1db7f3d7621c7c0dfbf9a1627ef751deaa7bd99acc76550424b1186f4df647299cdff86e7a7959d12b68ecff9615d7ece8f309c50565c0d2b8d0a8f2c7f1e9430cd833b4714d4bd7a0a0b5ace5e11b1f47f10a0b444402284136299c2643620d94d356aac93f2fd1383bec86b6ac36b1823366be742764eb598ea23f47bcc081074459030d068a45968d2b0509108f5811b2d077dd25eb5f5503061e9138a8b0108563bb0742dc493d883ad1f3c34ba11637b4e895691de076cb0a787bce446dc2740a87151892e6532d8bfa6ae9c13180a1f3e889b15e49da93761c9bc70af076f7155b94e13bbd37a4d57fc547146f3e60e297fdcfbab3d219c2236c1b01e48bd51898a3ec3d42ae0453ea5fc1c4081f950835f9a429ea243346b6cda660f8d62556461b7061d6476749c4d520c2e992f629b4494a6f1b36d32a569dd2394f47d3c0f61b66502204c7d637c7944ea011b30f890879086c8005c055ad3281cd4716481a1c0d8022a316462fa6482b10903e1131bd58468328782531a892203af82d55dcd6cb15da486a5d5050939bf68272b14148dd4227874153310ea07d164a95931ba1c6fd1f504e8eaf31bbfc0f36acff54369c92782b47fdaa8a33e7cfab8f1334b4468da33658e1291afa7062eecf6c098facaaba8df7484864eed2fc1c4ee15a1307def9bf0e414f6ed661448148f7c00cea9db5baff1ca0a89ce2223f70c201a11687a859a632520047434099cd0d9c361d28491661e1a23ee34f6c68035286d6336b38c008542def986cd3fbd07398d5de582a56a5f1722326eba239c3f513a01d623cf8058299a411fb26f4b235419f9b6355f0bb6c0e491a83260db6e5159ba3762f8bcedc1100d7960ea60cd6053ae9e89beebfe940c0e9e129c82031b88a1b6103063d8e39d1bbe89a5023c65b2d28ad3c741f59a9f0139f6348d806c5632639df9d5ae8d1fea38af5433b97398187e7dbaa50aa6f4cc7f15238fdf4fa18f47ca52d309c39a8ed11be0fdab4b2a163241514618024eba8a8f2f5a260e4a273232cf1a1cb973db4467fcbd4b112706f358097f129649d1ea9d587b90ed210cd0dfe9c7352c1880bf3a29cb141ffbd07f57443a3c4fb73a5f939c14b6e03b46832af1fae56b205c2a217f9d63bc65d0632a668232c81ec49fd3815995c25858b2ac6904c1f815faf6eb6c1aad82c7b648633ff06a4c1dc460e081cc5b4bc8dfca7664ac6b7a45cf56086e65bfac260cd6f3d66301c976386b0c2eb40328124707207d8be60335a13108085f91f1d50c9d56cdb105fd179babe26c20732244d4c9569a3eb112be32984570693f8bcaec1ae1465bfa335ff225eaa87aaa8fd663d2dc5d6597482e3ca54e03629b6e98b43c2829341781fe7654fb5dcac65077e532ef5d957cefd4b83df0db0f06f4d6bbfbf6683068d87abd0c80129d0dfc43cfb8e8d12f1b1c44cd0e477aca573f2c51e96014f3110f21d834177458ce23da57c5e764d3c168c8a4df1dfcfc8d97bbee907ad9307e5b09de2474312b25afc9f6653704ac7eeab72267fbdbd9c4d97d9609cc40731fbfc2ec6779e63a08f4c2581b1d1a91a6573f0e79487f960df20bd7ead044507a7f669d9937d591757d526c03eab81286c443c8e0ba1a26a01ae20d9a90819cf36705db3b8eef63150c74d8b00e9f8735e733b4ad1ea9935424064308238d83d86abff4515d1e569750e19fa8041460d9b69a8c9868018f2562fc18a33af97ffaabbf927d0fa7ce4bc4c700401b8c249291fa444a9efda3cd27fe592cc5f1bdb6cf28d91c47a5402e02739f3ca1a2182485b0fdf4cacc83408d44a7e602127c5dce5d0aed8828e576d72fde355c3ef4b7c39575157bfde337051e74c5a3ba0e41c529c7c71db5cc806b848894b075da38d1bec342a6b313e05c088157de60c5ff5e839b920785043351c2220ffa71d18dd2395fed75a27e2c5bf2c3610b5a2ce109948995dfb57df458ee4c6ec0a5402facf5ab0247cdbab5b6cd4e65ff868b085b40d79d2b8019c23db97b0bd6350e178503c85f70c96193b2e9d27ba32c3f7e0c4be208cbde97f9479559bce986545593a888e11b1dc94c67bc4b0e70779da400738c067369f00d47ff6ca13bf79d596df27862b4a287599bafe0bd2af79716a34651fc5022ef4706b848ef7e5f589c81db45797bf407d1b5f04808a10fd4043642274154dc8df191c62aa20c6e29a428ff5c4f7123cf754447d5c180577ae2beae68ba68fd13a69fff44139ac24ea794ca8c23fb00b76af234fb09e3e6bf877f97116870e97ea030e5e3b4bdac8cb1f8abab5f0c60ce1476c4132e410cd346439f6883eead0667bc1ef58c2dac18dff571156182634fff66cb40721648bf02324e48d657a2774854dc6cc7257f01ae4e743ad9c9f4a807cb6a24d724efb7980f3d35b13002c87f3365bf773f9252efa9c89554dfa2aef0db3d26a4478d4b6ec6e3cc22de1d3cc2d3dea56dd265324ecda8c6c148170cbf39d4375a1e12602791022a2323d830dc12b8287de52857f08bc76664a926f2a90498b002b3a7f835fe9670be598e8f6ac0f933b571850bacb165a3731e509db0ef85eecdd9adb3bea85a3c101161eb773df270c6d7942ea10da14f625f2f7f52a448a264210f26b81ed398752ac52b225c3c35b6bc9d062dc5fbe253ad2d84574e889e4694eb9b60971173c789e5e403136af52e84646871ec17136c54b5f32c44094bacdb921b2fba85be1d21305d0ede45b17ae43803b0a064611ac9ed87108a4cda715230af5ff1fd755d0914cf62100368b0141c10ef2237b4453390c8b46738db415d3a679fe3adb682da401f1a05f1fc5ea13c3a30da62aa347d66bd7f69d2233f516ed3f840878cb59e70983a814a2206e24a1aba2b92d89f3b0d59906ab9ac77fb051f37f51b7f054c6386737ba4b11045eba0d5dec9c1a308f76c3d0be929d3efa5f206146d91eb4eaee2779194e5ab472856e0a7b75c377dda92bc82bfd4a30f523d60f790365e70559193daf38b37d390b82c4a18b80c43b7df984e41d920c85ef7736004ef3ab5e2cc945e8ac0953cd6021bbcdb64462ee3176746a06c04d88e8f4a64c7d2d299136971347e58770754b00ec556f1f7550f821738f67e65b4ee69a891d50985c6840bbdfa9997638242df4e65f3031b4dafb84a2ad8621d70c5ee7205d9d625e9b6a3eb1bcc53d525f7a6532c6614a7deca48c2bf406c51e27446471cfba80f6c7bc15859a9a0d2bd57c538155bd8b9bf00c91a26743c1f754fe325325efc41e2f46bba2a496abda61de01cf4f09f94b3b7fa041fe720ac3f60b5246488ee1db5682087d74d72e8891e987b1eac849b842d68ea8e6c570729d23d651c0108851f344012ad65c1841c7b5e9977b8516489fc10704d6c093e5aa4df9000d09bab04a71868572493ec3a7a67019cd358d65daf388b930bb18d6f134d95a9295da0cfd259d83302528f7d7c3e98e71445784e726850a16a408d30e51b8af6de037a03418b787d99a72a0e79fa531440e550473efb6ff1eb8b56d58587635e4a6cecb1ba7b4567f2613c05a1567c3cd6192c6a73fb22667151069cf3166e85fc48b3df2350976ae05a1bc43a0cddcde01d049f33789809fb6e5f791486d0db9ae92447f174784a60f9846bbc274562b0a59eb7e73d07158052ae8e26a61442293495f8f57f0630ba0c84d3571f6034412464decb60542d9abc9d145fa7319e631798e6cf08472aea03c0ddaae436e75d7c0b2ebdda599f6907c4060980c937d66a77c55a52fdf4d6cb6918381df5752e15f02aecb320f84fcbf0496ddc4d23ee30ac69186e128e31fad1308109ca8b3c9b2a60cd3c504d427f98feddf1af8c3dc134b6dc816ccc3f6c9c5a465f019894475b81a5205aec446a2e3e75c3451ae2bba783fc1e99641f523d26ffb58e134e4c849b39b5fd77554feb02f6cda916bdc80efa6464f64d1d562fb6c76d5b33212d19da89eff81e11bbaa3ef624f6ee2b6a2befcf50a1d70a45681ac4fdd6e4fe116f84c0da9295d26e0af926681e10ec92d93f3f78d601f87df08b366bf3e7c46072c1e4e7c423fe2d25e605fe3e3f297df88b5110c81c7eaffc80916919618d710dbde70fe4d93754eb5d46b3373f8d99d3e78266532bea8f1d31e47fdff809a5fe991adb95986d6887a00aeac3bd560d83f2d235b4a617d05f54a28c2cb6e4e9d302ecb7048e74f96c195bf6cf4c70264d4d1200778e8c1e5895495c050bbceffa6e09e00243ad6fd6c572d1a9dc57fa8f63a13047c8aaa93157351e6a7ba5aabd8ac5b8394755729dfc7b23beb2a1642e16c0495daed4ec2307dfe3a083885dfe6e146ea5f553d6c33cbae5f79fdee54958416e83c92031e0c35de9aa1b1877eae11dfcdac192561339fc318e35f79ca6db38a55b2c9b8e8fd5920fcf771f0ac94df74ebd22bc8a846e8d75550a59b9d5da60edb5355c68f8100b685da6766c48eb2b2c385c523bf8c2a4e4fe9a592b5fd872335cb096c5cad283e16fbaf96d7151aa50004b9777f499af836bc6304652fd8e360500a3c91970479c44112db1fdd324c224f565822d97401f227e4efaa928274f4f8b3eec745ce8924a7320e8e8ec1560313dbd39f337c311d2aed773487fcebff2f562a71c09c2f477744bae77411cf9205239af07ca11d1cdb809dc2dd3923e7e7903ef5d1bfa22d95b0b00be953dd69b7883cce5777d6f336c4a6b9598e9af415ee088e96610bd8f716ec2af9e440dcebd51f998dcfbef384df65a55801854ff4ebb274539dd72f6f1cba3395fe1173ee2f02f42385e14b855d756bd418fbf84e085a8a113030b4dcb1a795f1f96700fa2013b264840ff690038a8a55f694bf7e60d98e2abd2ad4152cd51781249e501764766e8701c6d6367458061caf5d1a3666fdc1432bae1d9063d6551b3bbf0d6fb595bf16e96d77782fc3c45257dd178d23866057716f36a0990a6e28185c5711dd297f90aa8369bc2270abaa72766751cb294251fe56564dd78f6ff4da4331ab46e5dccce20e0ce92094fbcd6e2c94c78975d2eca2dfb35d50f17e24ff5c6a30c9a440d38b00b1a751e796a4f05267e780837045d26222d65ba21fe09ecbc2deeb5dae0558687162813b9e237ff0b3647387cf6f5aef7f919156e5efb5e6fe3d446c51a08000b1a3c934f71a04adae5b38e0deaa878cf85c21fe5a7b7ae025686b330525f06387c26c255cfcf5d283d211a99979cb448623a61775588890b3710ae6c0ca03bae67a229410b4a70ed6bf5e0b4e0145754deb6f86e9ec24c2b47c18bddbd1efc0fa17f8dcae82c181d249620a86e58fa28522d65c9186a35119bb0400184de57e3e12bca21510be2410b73bbe323d47626f09a8b0e22608f54f429a98af666788ec41b40fa59cf3bafca02f4000408226892a8c91ac54628dbec474f326275524aa784ddf55b3b033625ae71dcdf1093c883adc260bdc11bc8f1d48cdbe6ad5cd9bf4c434e99bca421da58610efddc7b98576975f9dcbc68691e7d0e3cb0d7ca10bfe2aeccc55dbdc3873a83d75913a16a707628095ea3cedc88874339a9084620e549fa65f584e60cae570f304a96f1634f9261ffed9d60339703945d8aa0296493a24ba104ede1284af0cef086e4a3ef2766b950c1d3d3792968201fc0585d5107c765162895cc7bf49f870904c48ee8e4fd43e4e1159172213f64d90457b64f6612c56183419128adf79effc95f2be0713dd18eb52521003de0323b45014a170f073065424b99cc67df6576b5dfb6d4c6186912a85d20d02979ec785240238ecf7fc0792d6988fe280ff106387d2d93cb9bf817752f7dcfc1e4c60fa22b08d7f02e0312063550cab0046a182688438aef5aaeec861fba205e40e601fa8c0b0aaa036f467e44d71218bd991357008d58adfc2d83008a7f460177c374c7f7c46cf6f9afa7a8db24672f7838adf5552e0b9b4f923ba48fcef46c646856a0035a1f14d92c3e993681a11bdddd8453ca3f8232dc2b149cea6c0651e559a39dca65acc5a810665c55dcb2ddbf10c3ca5d331540b9b510ca4d24266804b46465efd8ce33ef268042efcb3605db9c05b5fb4410dfface9e15b4f2d000b9b9c93b92d2ff1fa8d664dc966d6c9b9124346a0317f8184d0af2893e66d19168840b423fc322b3cc1f3f784c3a82b4b662d1f7023f1586c533efa078b950a0350e80fce906adff463dc20d25ae45cb6706e4ed5d2dc8d07410eae6cd081ef731b0cb1777affc12e6739763b021f774dbcc79f9a58eeff91ff5545b024c8b7788d8a56bc7f304b7f784624cc6b97086132cb57b6039ab570fde92ca82bc00f65e07afdd2e96b661c90a6473ca39312f2a7f57254954b221bc4f0238fac6ac9132f2666de51b3ec75142bc6d8dddb96b61f6e1f346d1baecf4a79c738c6417ba8891e865de963b3da190d1b55a8b9eee12fd7ad423b2be9244f7c7b5009ce1a3e3122d6e2a863888511d6156778bfa522a1b10bcad5c484a98b2b25a0e2083dd4ed10dc6c19ae05f75edc36f178c542e2c059d58ca657bac45dde5d999cfb3ba0ab78f2fe41b75df20a8263dcdf730b122470d9eacf2a6445a0162286e2d9a56dd0fbbf3484502a071de7ac0677a421f9ae376c357bb1fc94c9f29f57355370aa0f94b5fe7aee08bdb8ddec5eda63bcb1edb5bc2c42e76fcc1b4b5a25b7490c5708f027af2f640d9a468f8287f03ec1f895ed6de881060e6b7f75c35f72ef7d78441106d1ce2d15541e96a9d75f1c124cd71ecb2d57dff808411c95f26be7e885030bcaed9120d1cbee70a1c3ec9656f75f645f87c5064fcf7bd0a8a49d714a603406cc74a2f6e8c5b015d9d6308902a61d4c4642e34ae4130307935d6d63c71f364e9161c0b25b5c4c1f8057934c83ab100ff9556cbbf0f82a41194ec7d4dc09f296389d619da8cbd52e131e6d0a9eacc401999e1986876b251fc1be5d2a90b20b35c61898decf7883c83097675bc37e9a23c8e0789b912170c139a415d62b721ef4689435059a0fd36feb3eea80f568eec793e5da68d3c2babd8ef62910695f4150ba1dff5fb3b0b39553c41d6687ec384697c30cfbcab08249ce845cdd6fd4991258b9389f6705192c948b0ba0332fc80cc656b39b14d3282c63b4e7da4142e73806282d77f3849bada70505eb083b9ce2d85178a1a6f930cfb906ad6609c806c682dbdab9dcbe4502e08167c2489a97a28fcaee05281bbd40efcebadf5d9fef170d13ae87e75c9008ba2d34c64be381302edc1b4e355ee43c2d5fda4403bb2df723bf53d885e89c68198a20c93a06caba16af8478032efa81f9198aac9b742879def8ee7bbf86389e147c850d43ecb302560ce4db1b26b8ef440e79d12a30f737695586e83382ad8eb52803d730d6bb6e086c124da8a188fb4e872cb2455139056ad7d8b8b6d1c149cb431697c23c89959fae04417816fb47d888cabc49539c79b3c298668450432951bac652bbe01d6f9475926a1fb8e1e4139fcfca90aadc69cd35e557c21f205cd1dd53d0a545f9280dabbe26de900193d45a95e86517797c0745020d24f264c42fa850395f08df647fd72840560d3690becd291ecbd06de08043389c5a464cc2b96fd163e35c7318c4bfb50a0c1943b3750b2c05f3bbe9722e1e78a30c0c0c6742780b7b8e9a2996a61f107651b06f0a65a9520fc22eef20f66dfbcde168c4613063a7251e7398248cd965404102985c0e66a620c3c4d22e9bafaec310aa5f9b05499d06f4f7d5f952fdb685a85cc863ecdd5554fe7d52aa02f9b0c7391d478fb1cabd736393fb48f28f53c3950bbcd598970a9c0155fb830dd6f9b5c76f4757efdb7e54ca02afd1b01b8a815e36b363cd52b58ca36f8d152084d116280b6c8d20c6946cc8ebde88d4277aa758b7795a855dfe07b9b34a2868b05380bb1fb319baae4a7633f9de713d80234e311a138028996f1888a3968f82691abe3fcc092e633ee5f1809c54ab1ef1b0a4b82d179c7ff6fa85cc20068ba75003f28101d3d900096b222aec220dcf89243c32a7bc62a083f3111c1f346d172721c3026d747cbe2abfc79d48e5a6c28b77c54403ab081a3399071a2031c7bb72495acac8e49efa4447fbf39d95d8dc18f016480fb53a5f6f761d2fa0b1b11332848d1435b101f1f7898d95a78189de0b01662c0e789271902552967009d56acf447eda2743276bc8c183f6472faf22c304772251fc06b8cd2ef022ea86a2bc3775fb97c8fc12bb741c7a1e9630b321f9966ceaff914cf90a12ddde076cb0efc89eb81ef85a134ee5265de2f26d39fa0f082a9997969285729890f1cdb128edfbde4355d6f1047c20706698c07f432def4bda904271d1cba7d18e713433001f9df22c083097fee639ef1431869a87bdefc0f6cd1ccb189820e977e8361a7f49ddf17545d103e568a0664a8622cdeb02874c2524bc6f47565397ce723346049f6fff5d7227d13ef7ea9489494f7a049e72fb18520268046bd39c2858188e3e939e3fc3bacb25d76c53151705d55fe9d0bb0158da89fb4179f7cc28c4d71c04ac778c63b534f0dffa39d70c3da0ce9fed3b690173527cb3b72c32bff21b3243f5ac6f2955e5007d3281a79093235e4f7557fc44e30f193bfe2aaa417bbc5ae365914dfc44acb144c00d0fc937dabc9d847b1661136ea34150358091bebb87d2458d0380d4e4eb1bf7e8fe89df91d3ebf16690c9e84e9a4561843b106bcc631c08590ac9fb8fde72c9ec45dcb024dd95971b7a370b0ba97d54dad3790a0b6daee5a36e57d24c7ae7b8690dad26a9a3f64a7c8d98e4f4f8ce6d4528fc73cfe7939f07e3dcef33c9e0c991250ec2f2651739ddf8c80d4585723617de943e7c61c8daaad00b44697a7853b73a568b155182496d84d823d9038007612300713e7a240792102b99a286a027a48fed16802145beeacafd085e9df434cbcc6a3d13b3526f4c2d209c35101ef69ebb43e65b0b8770f72e7b1800767718d2697897bd1c8345ff7752f89e8860b109f6c6121372227a0f165a4996e0834b807a7f5c3d91ec76a676896c9e062f685394520ff09b17876011d66c9d99daa58bde890094ad4a5ebb9f9b6dfbfc2b0d7c2ea4b94fce886e025d0ab5ae4691bae172d1c68705f6883d02536b292707f8c3bd3ed05af4a3f7db0fe09bc35b08d8b52518b4074b8e81956542d3a974bb299836f18107dfd4dac4809d14df902930101b9028e3962a41acd2e3e4e8dc00c74e6b2bb2fc4f59e04bdf534e0b46a3ba2521df937efc57cb7bbb50b6d3bf9c3b31854c14caa7d6cb431a2f5e64bbd276e578405febb6243b9b4280be51c94339ad460b530b2d30b53afcdec6931b2c978327a841fd145f7cbe064f5cee04e1aef46f7bf1a459ea77fb1d9751f9ef42660f04a9c7c7b9cf4c1e114af84f083df3d7cefbc9e12877cec59c0e028701cce325f25731d38df812879a0dbf2d1e6cbb0fd68b4594f83c4f696eee745e23862d7989d4d64168485e7c87f5e3baf3e4fa6463a394dcf154a8d569f2e237713c720130c55070a83946fb5a69b664c9dc7e7166394d21420cc59ad40f24743ab464e23cc3da63cc563a8aa530a5f5c8cca958ea73e57bffc42f2bec1ee3a74aa5f0ed14a97659bd245573fd709ef926420bd96a2999873a0e2a4556e956a241753b385b80d0069d7b6a7c94756cfb319c3d922749ac19951e543aae5cbdb0486afc29a50d7de4f126f465bd9cd9ddf546725de79cd4a6a941d7592773f95c0fc14d629b688dce3b5980f4b6c517292b2d92aaf25ac5d839f2395e319b85280ad33f985525f0351d4d95aa7b94194ea25f2f94ae3e8d1ed68a471f4170d9cd505babc34662f477195264ff679fbcaf87c24e9d542187f7f29d2905fddb5eeb937449454b6aed6acda3cf9a548d862063e2edde633518e9623d157b17059a7e95962e172c8c4b33483b232365539c8b0bd248ce8c1c9fee5fa506a7d5bc964410ffc2cad15e280a1eeba97a4cd0dbbe3874afd6b5258b732891ca7934df230c8eaac19843104826e8dc4dae51a82903d14a882a370f9d9a5340d1680db9abbbef71065955ea5cf2bbf98e8115d6d53dcfcb210e4323f406b74c6b53093bee436fe6651060d14454465dd96c90b47f631ecd49ec69af91eb50201b91eb058855e51c505878b067d7b82d2405df07037b9df1991f71f63b1587006542742db11d05e6e5ff64d1d9ff65b8bc3fd1b7ddd3b40f0d7653117eff74be3320f175457a1032ebef5e9b298c5ee27eecaf10e598b2d521a3cd6ee6dc5b641f626559da8dec63d860eed309a757d4183a174cc698341d4c775b6eff33d4296aae631da01eada5475b41f26ce7833295b2b4a15c71468f75914b389e2feace5a72e9b70b3ceff2531c8d1f8fb05ffd705a2e811c72ee69e51b771c9e0421dabac5328dfb228e7d23839646e65de9de258b0df02226d19083c6cedb0ce2fdfe79428edf954056dce66bdefac112350a86ac39724776d551161ea9f8d39e48fd4ae58a3c82158bc570a398348425b035e97513908dc0c06726abaeaa709d59691c2363730b2c9ddd6160c530b9175ae9afed4a54dcd67fdd3c84415c6cf46546b62815539b4cfb283164a79012d77626ef0b5218e499ecd2e7bffc0835f0783d75ac9936dfb7baa9f5c293b30ba58cb4b572686b1f4514c2c61952204cc6bfaed790e929bd167ed21aa79ef2fcbe0198808c8e8170818949ee8d3927aea5e015ee7508262165f1dc6f0f918c81fc6b1c889c11605ea04e2f1b70786167fcaf790a4d0ad79bcc977872b13c5fb3e756fd9a5166305240c8ed207cd5d314903a174384d7052d5fe6deeb33bf833f7089932bcc20cccd4c5f4c3352b839c19bd85cdfaf7a57da4f184070ba019851dc4c58682d6d65ae755d9bb4d7b0bd2b54a7c8946989462685582cdac6ad1a535c95452b05d441daa62052213bcb1da41ad40388e91e043057a2ae44f78ba909dc82705e0fca9eb7b83e7027db46ebb4a30663dab9912fe63f0dcfb52d2512aea35cd1f7d5b1dd6a5b65dcafc36bb86a8432edf2d2ea5d7eb7cc0beb1e62e7abab4c3f3fb30c2e42253ab088507ca33b87f4ad07c6730726ad8273760f7c9e853ccef31f26649adb5c31704cefa71b91d5476f48cc63871138ee28515f22c0ec2feb7cdbf914b68dc6fa65a9a9b72c8b201c9a2de2c93bbbb4c33ee7c2df5cb3d8dff5912e1029003c4f82479658afe05b54f7ac5838d7e1bece8c2aa81d9c3304c01a9ba20d25fc6dcd512e8dcfaaaff4e93425f0a740dae4c2be7f2552a169dcffed92e6a3f8b1bb1dcb5d456afbfe074028df8c11d0ac38fe463fbad67822154e630f5329e4cab015efbd42d1d909aa529a4e11011bcedba5e217a637b3745ba5fc338525458aa8aaf74039c9c1afca79ecd1247b536bdb0cb82aae544b77cce639043c4efa1377589f32c55d4a5db2644dd1669cba0a8b43cdfb4638bae333db87cc9237a6c675789a4023742f2af14f885412f58d4c9709515bc025605e23a1a96b987bd444f237f9c9b6489894f95ceb201a30fb575e34d827892b242261dfec34a1c4158f1cfc8b3ab1f894d33b25d026192f15c62f2b607d4ac76085c05c2e441b9f2f5bfc8f52026e751bd26dbb35546d8bc4391f88bf8355259e1d0b7387c0b337a3d6ed5221be8738587dbd99b509c9f925d645b4b7d5ad14e6d4ee303f32b35892d7f4b1419cc389c27c24a70b6269f11348195b8aaefbcd2afa5b48858bbbc8d494286ff4e64c87818c179f2173286940f934e4f466dc9c96a25b559a0f707b3f0a296cd9b75bf857f53aa8d7e9b5e448ac979e74799ac34e6a1c2670c8369ed0e216e68148b86939f1bef044a23bfc67899c83a795c6f7b214ecbca197fc8b6be90b15f09219890bdf89ee6954c070cfcd3a1569662a4851253346c621f076e649bde374ed71620571505319e2c8a0497fcb31b7c5c6a99f3ab6a08ef6bfedb6fba7d1ae6199b8c1fa98ac88561fdd61db56ef83f974e0ce8df4e28b4adbeb4304a1591a347c0d66a1d9209188a1b9b74ff899fa5266e1964eb61896a1909bbe9f4c3ab36f117eecd9cbcdea5e8b8c4af5ef7e854df5d25b18a3ab5fb6893c36353a48bc997b4013b61955a95b87683a4106c1f11a3bbc5613d374611186ee989bfafbaaff4b84009eb946eb3ee281e1356fb6cb23e24ff75fd1f1a1ba073d7d58bc757e38d4bfec94a828326560a3606505ee8982997914c5b6f7916b685fe033c29afdc75347346302cea9ea302c1ef3386d931fab37e44e0718fb850d57183521f3d654f1fd9bdc9d76688b9f78b6b01c9ab916c5d2f50b99d5b0fc66e0c3f813bf1918b3a691c6ea683fe2f6e264a0d2deb90105d913706cc0668b050fe663943a73d8a2a0078e684d83708bc85ba5cd919a4ebf1ab679fba371d258d2ee5d8fb60ebe48ceaa8a77d3ecfd51b50793769aeac9b5fc1fb1a1e7dd9ad8a72f4728a4cb957b941f9d5d5143f6ad3a23409c22d1752540db0072473be1cf068d092af02767ba679d5ab23226bb7431f3c44f74fa125d21fee5ab8e3fe553da89a70e4744b50c8db7c0d9628157678becc84b32a61c14da149e460a7002605545b4b1dc3635188cd81ad5232f56d8bd7da9d9c07cdb4fc9d179fb5dd66d85696e6a7fb5fed6f13aa3d011771ef88e566d41eb5c3e8edc8e6da8b9bb1f22951440e4e71c93422756d603264934c2cef27fd8dd76b264c2e4f02fd055cdbe7c2d5e63b64f84fc26833acc5afdab29a9ff3fb31798392cd29d490a62d922c52fe8b1b58b301e982022d025679941861c794939d9fd18d942ddf1b1464c47adf5ce5375e2b6d722e683c26f1ff94013d3460482dd3440e7b746390d1a3a0843ccdd72d27a18a9038b3b85a8c6501633171e76f9ec0f2856c07af456ebe3e78bfe4dd7b13c33c2ce66cc87970423550d5e9d1de18849d6d87d1f1c0ee30bc848ff719732dc030540f0f88479ae314d922409ecc53ed56ae058920bf63fc8d9b038e43b110b56a1b6a4819246c505c710d96a9669ea82444022748156f76024e4dd04a35afaecc4a4d7e4d3156e27007a76b91bc1f9530d8723273a09b8f3588a03af737ece4143cb7f14ed9a7e449046d7d24b821d1da61b1c1bcf368ffcce8bf3031bce3fa0ddc820047c332800467c498874a3b98224662e824162a724a74ca6b8fe5043a8658b0b1138275ab67199e9438e40400e382fce7773f181ecb508c8fdfa87628d3d1f3b29b719359c0a5d8d6515810410a4ac11eeb448560dab6cd393b78eadbf0e0461dd6c8bbe77cd7936d5b834fa57c0d8dcf2a3207fa02ebc289885218da207a45a781dbd3dee32580cac6e048e5b5c4ac2a7e2d8f283eefa7a6e2e3cd1ee93402177639f9f04b14be7706a179bb11f1e09562be277fa72a1703a3ec503e321557026454241451545b5ed14b46e824b29f9ed32606d46fc30ffade876115e73321edbac0ee067a07de9230df85001c9514d95720c7a3bf86806a5d5f6eaae4ef001e024224d2405080e20cfc6bf0ecd8e5d144665876925f6f9fdb1094a8e7ab1c579a89e8e54bc5630075927db477eea85c52f6592b0ae9e2be7077f651bd1a10d85d5dc846ffb7c9b353d8a8a2440296433a5660744b290592ca52bfc7614a4912fb190a1d672b16bfa493873035c13c72874b01cfb8b1f75da0384cc4ccd5f062a062827539b4978f44a9f895c51cd9101841f2231fbaba283f0ac3f8ffbcd6116d20d1bcd4ea8e772755aa17785cb182f231f344410f033619a2c96c8135adc3a48da78496cb52f665d61256c3bfaa3fa336263424e5692cc0948f0712bfc6c561f4693f27207ccc5b5dc2dcb59f4ce7e42f1836b65d50021371efc473f4350077d22b9b770fa41e14ac7c34b3544110e24d7cb4564e354201aa1688a375312da4c2ed3dcd058c2536a1ecf04a202927dab71ec818215f185ac3fccd6240ea5a77891a6c7f1eace0e68fcb20cc9646daf697b0f665db3f6208559f0a0a4c6e03e0db69e2dcb01ab287756ffe9ac0af1f19454cfca2090edc4b7fcd8d7d246cc5e47b79c6f282dffbf01ca7f1e6dd00e2ecf8c61f8ebb8faacda4d271729d3d18ed90f600a93e4af9b40388f0903336b01878ec0719d9bb605d64a1f7fda80dc4a31e28e8b3d792f4457545f2099af972d900015d9c169e770881ff718f6f7718216b33ae420efb083aa4179375bed0a0bad22aac64ad2fe663005bcbf67c94d185d52cdb95afebba30668f28b6b7522a4deca75e85ff8bdb8d65b8dc89b7e9337914b9892d0420885f58dff1ce894f614cc18eea4daa38fa2829f71d0f784a068b261101b66cdbe9a4c5e1749e298b8c91fd380bc1da6e68870f53bdf9c63efaf82922f2d555f43f6420ec1024071b01748319101e4852e171ede00b6d9f25e867dcac7b8f043c23f64ff45baf3534be21d27fdba339ccdfcde872eb203da1acb11f972b41c739b3a35e7f46fbb151c020765da0c1f721da86db3c296a18dcd57906cb8182b147c5b98bbd4197a0114db21f34f58b43d6aa56dce4abdb27f3148e5227ac0177a14e459639eef3d677cb3d3ab0848233715a0631d049446bf80b92fdeb6d059a563a1a706bb0abb2a5fff54c1f63cacce4a1e9bbc71c2830ee3a93dda3f5cf0bf953d77413b9eeb58405f0aab7d9fd6c761f45098d549460450e810cf2596555d872a7d0190d00ccbc1bdd70fec82d14cc46a8d7aa429e2483286556cf58d6d1922684903368468134b5662acd605ee7f3c0a724cbe93e5fedc7e3610e18e0e467103233867e18af7ebae0d9c903285b10768756465e7b2615c7e1011bef1b3ad960265a92d946c9621afba6f77149c9a5b73a7d3ca8980068a0426613688082e83e4f28a3795323cede10f402bf096401453a9c1abddebd7e02510aa55561b0db7d6b13998900ecf948c1cdbc9b9524ec72d86b67f0d46fcaec1bbcaf2426e2af007344ca38448f0635f8971d642d4d2d2771b53b684c4499ae6678c2a24f89e3d34ab80823f53aef9bede7c6f09c20fb2b73e944c490bdd44a227b520f8d9ad289b4137ee89a99a81c95b25628f66680162bfdb7d05c68b80ab10128db6ed95ec526fcd479a403f18d8772fac51c90ac59b3e107e0717afc388f4ca38a1cf91bc5327eab8663f952edee49b1bddcb9e2031bace94016f563f8575db2d376e2bba797704b5dd077918a27ac31a97fe2778cbd29436b5ff95458fa2c349c67a14353395fda2364178b0d5b7b1b64e8b060f6ef8fa3bd5cf92d011b35648de76ad60ef76c94a758dcd1a3fb978ad2473434d01fa69350889308e0f7e2149642e22e18b565c905b32c972ea7dc00996ee5b986519120bdecf9cafc8ef24952868aa2bc59bec4a55d1117045de50cb61664f0cd7eff74e9d1691038737a15bf555754e07f5370a6ee22cd883cd77b2db099a52061ee28cbb5ee04c57e5714f1e61b3e383787fe4ee09d388160049b8b9713ecec3a2aa53e0c9b02758a8ca303728227f3e6bb4a0429aa78ae075a727b13552b3c2610b55f1cddf7b8239d20f8d6501a2dbec1ae44cf48a1536cf10a73a62bf36906a6349fe9984919161dfeea5d9c0f24bdeb15ec453c88294fe2b722e437bc7a4a8e3e1b6dfde87a9c60d087cff4244b23ca86393625e78871e2a0b1227c3f2108ae5329eba2fdfe534a68751eb1efa800db6c8a7659a491053f012c97ebe472f413c76731731bb80b001c3d9e4298fd7725606161a7284e08211b935dd52452315be655e4bf625853ad64f8ccc2c5ec847ad260a303db037d954eed8c23d3a3ee88e3c997dd5e8a61b11617f21a8d9a26b3128f4cc8284a7475e3d3e5e7449b216f7f37853ca808a623fe3ad9200331465c46266ea8b184d771ce2053663e9d2de6a07260e1a41fa4d1bd5e28225baf01c979f4770deec3e04f5786c7179d94a3fc1d37a5021dc9510e29cbf51b19b9e47db8e18ab8b59c674e40c7f6d2dd2380918a6979f5fae20d78128cfbf68bdd75e5cb33616b26ca68c5f8e369419655bcd18eb9074bbf4a12e8f4c091efc8e013ab1b3cb707439b079c5dbc6675c7a3939301f247e0cd30e16037c581cac2b8c94341c6aee825ed8693092988a0f6e11a468c92782d104fe7325a69d78eb3430cd7bf7a08f47a9dab7f722763be4789f85562d5011088551a28162535f529fedcd983eb59e0c99bf8f2280249f7e9ee02562fc031370eaa4839a71ee700d1076453648c005021c3115c2603fc8e6fe595db8b20e12f6c763387dbd531a99c3ce4b5c382a311a09acc3e3e2fd83a4503472dd9e9fff5373a101bcc3f75bf4b6d6e6f03933e67454d2c18b7ce9943afe372c2ba70b7ea779d3b7f290340c035e47561f81fb4feab030892109661105ff9cb9c6af5707d3d490ea8efdbe72955ffd465cf9266cdf54c15407798b486b15e72beb9de2879e49ff8f7383bc96f3147a8595987631afff0eb5e2f78bdcd43431e90b91104302fecf155fd0df2beca62e016231a30ec0ffabd4b04f3ff0f2e970ddcc88db666f7e3c50f39e71af4f7d1ec20351f043bcf3b51ba0bdbfe7ef10b7d760d4010adde2da4dab1ca46d65f7a6f4b50c879b3810d290cf056c39a66b3fd28e34ce7e397e39c9ac164765dee21eabde3da69026ba256edec66b8511315fd664b8d505575664b5f063aa5f2361c8b67787d9773bb322eba8479f3aff10e6f3a170885226dbfbc12f97d5c5ef58cb188e1e94a858157123de1b75161b49932989206e4b5a2330f6fe27092dc322c5ab1605802b8e0872d5b7d3ff5427a3103ce2bd443530fbda50814be4fa6c26cc4cc1d45cda48f8c8565eb2a6a035fbf68f00274b83350ad1fc6b215868a9d945ceb04c09f5ba20990730932a3e01c76dbf631f960b6d39a64f4f162290596297e8256ef4289c5b409c89bdafbab53b8269ad3d3502187e4f15d7843c1c3d133ff284eabad468f4a0cbf0df7f357e9160ff336c896e8b7c051778599ca1867cf917d950c04720d97f5661790e833676d4b7a34ac338073e320a0bfddc66ecd7feda4f7dc395a718eb1fff449dbd9823c3c6b6fd4cfcca125e4bfa72bb4df1e4c9fe32a5bc7ba87d0d9c555f439bcd14ad97beab8b2579643cfffa70f935ffe9824026eb80a67774d7bce629e516ecabcba70e8aff49852396abbe11187091bf367560aec20fcfc50fdb09c6a8cedee40a017fbbb04cac08a68b3333028ca46c17bf985468b2c36701a787fa59623252490730e7c3a90255c953650ca4919c8770962352f226d63da9faaa78ea861ebce149a0bc74a060fcc5a6049aeb29472518d99a612f05f93bc620265203ff74e1335f64d5019e3aeeb4c15de5d457c9c97a35c505e71cc6f387d620a0d6ef1d46706e4fb20e5b4e636b62262ae7e71a8d0a5b39571a6c1fba9f56da6935e700ef39e45ed4c395d9f7a13673a26bdd8e7ed695073d7b8a92ba05b30fbae892760ba35a9a4d60e3f4b5d98eccf9a9fc71cfcdfcfe55aed80b629369d9c2ce13590d052a53db5b091e7adcabed4e8572a9b3a7f03483645a9837f19db3e554bddfbd973f57a3dbee5fb21f373c775a6957de14fee18374e245e0949b3d94fd1b0a0ba7eec32b8a7f55f643b4bc99e7100a738d8b322d8443154c67cf867f7b1f859949e9efbbf938f17b6fdbf78a2b82d43eef50b9f3b3d79115b6be5500df686c9e7dbde7385dc7f2ec3d7d515467f38fa6f21925bd7d6600974b66a2d8a81056b131bff2175eb0019bd4e43bd05ecbadb1dbbc8367d3a65c762e59e6b11ae5dbee75babe0b7e5f1754beecd1e1bc8a5076174aa0e50530cc85a7b1f9eb6d077fcb704369e7dbb0b0cf75f7b67bf422a4d0a448893efcd10523a7f8c5b54f064dcf3abce387293403afa017adadc3c12e8dce10e2e7d48679088b29caca557a1aa3617dc55f44828ae0de832ff0debd09ee7f7f26b4cac0110a5f6e39eb5ed3c4f4f863a2dc8e0d02b3745f79ce08fdcd49696f2b7bdd42724b917ac7e85b07f7dd92d46425dce016d311b03d2dbde80f0fa059639e8ba05dc5ec9d9422a73840287b3aacd37e1754d4c85e65d6c3c667ef6f089a3c6b264e790bcc5bbfaf2a399434d535d395164446d8d794afb600a4aa6de28fcc407615e944f1f76f45c8c81fd3cc0101343bfc4189334636145694ab68ffa7e1afff530d209e7a5a74da6c6863902781a6b0f71fb6d5db981716c222d96ad4ba770dd9d2c33e0f532e38e121277a85f42f4e3c79d25f3d163a9dc07a7f72ffe93ce70b2b0aeb762d0b6747aa82504fd4ee58f50481455d88bc8e290ea6801558dfc9575272cdde0c5b83af75528219dd747f7b564ccbc12a8f6e590f29bd26032cf2e2fdf07142a6f5066bb9338da571259990ef7c1830d1b487e88d3d84177d1ef60404944cda95c194afb519b47415a285ff74d9c482d628a8d7373347f655fb5c6dca471a747c01b4ff6dbb71a4de4ac05214d51e56664ad0491134cd9979bd26a08294f91e9373e509aa34f5a91480e71094da4dd743c4e45bd1b36ff9d0534d08273b76155efcd1f73d0a5143dc9cd3500e74163f8fb264fbe63d47f888ec2a25f064b975c46ac2dab2e4538e93259707ba5edf92ec7514f01831fb68c66bc41bfc5d96efd2e4ec530196cb73be4195a3af69639402ef4603719c0af0a82225b752e08083a2c2008218f4f4fd2cfe583d44b01f8a287d9417ae9f2e98023a6604bbe9345e6b0327bd53706bda926352551935cb3c286e567920db973016ec66bc44acd8392f8c044a90de403445f6b9da56bcd927118342a3d9a71b662c9d519d2e0f994945ec108e02034b9cf37e39f6a69f77c686740237c6e9fd1c95b7a9558d11aff304486287d81eb77c3942222e779b3705e9d511d67a3706914dc29159255ad36c5401450d85a7a6853fd87e5ada928715608608ea73d1ab24052218b3209c37ae1bc26fe69db5f3ebfcc8320ba6a0a7b667e505a7969efdd77a32d9c85e304c3393ecaf5739fc0b5b253e7c0f013257736cad69a7464ac66d562b1b6f15a8b4f76fad785dea6ba5bad1169543327dd460edc7457a5a528bba830e4e9b26edce04a0a168f4d1cf7cf1f0cc4f28298c63ad96fdbf60d3b545631cfc967a5163eeeb501b2b98ee76ee29403c3c1282591b8a1cfa91f5acea67eb32f9226e9d763269be12ea3f46ab3463d5243906ec9206a4147e1355c014aa98e89d40b323ae1ea6ab0e7ffc15abbf907dd9d772a4d276abeb518ca44d912914c49d3ff13fb7e976a5bd862e75c4d50905c4d22999a477847c80b3af8d56d1175bc1cb430eafdcb49685e71b2ade2fdd6d18f5ae17dfbb346f43a9eeffb219737d69f45e5d47abf785df9a32e7d0a41af0dbbafe3e7ba51e9d2df56eeb62bb64679c38d2d0bdead96f57fa9be78c451ea3776b2a195c8ff3cd34b33c07ebb2920edcd9de3371d13cf6ebba3063928b2f47e15c3894bb242a50f8b18fa8d29dd70575f107d8b22c777d7f7f80e97766b505982ba042a3460c3670b229273051850728faaabe5578915ec6e4304ac9d5b3d6d9a46348268edc5c2b7f51b7f7ba20d0785925e7f8ce4342bb1b023cbb873d844e6b993d63760e712d969da7dc79e9f1eec80e8f78d0dc0f328553cfb29e94a51b13ec5ee56eb315efc979c8328bcafaa73054d2c01d5804db264ebbee05f2b98ecaf2351ee10be39232b999216de684a76bebdaa713f694243d7bb6c22289560a29133cd562151bf47cb44cadee24e533628b37f7c6e60e950e9cd090a081de708e4aa949ddfc641fd0d37742c9059289fba76976ad5fb4386210c89374d43cbce35cd93a23a3ae19cb8c3379e8fa0cd0841285871077d6d38883fc4da616d98255a4b1e1283c9405dd86ee2b8b635236af9f60c987616ead8fd3cf3c644b4da030c59b4afa0c1e4ae19c457905defa9b4b4302111338335c09dcd72dc6cb8158a490ab8be10175a02b3ae3877f7e520d8452bb4c80ef2838a694f7840652039d2271c21f663b65954f404c07718e8e9f4849a02ca00b1a886b9914a270f90223532b1a75437f137809a2656f44cdcb861cbc1e3de8fad31e99e3557e27891126c81bd55bae6e118a865dc899d4b297e808f90ca9aefbcc67a6b11b4ca67e27b815f97e7e5e561d21a7a62c5b5d3367e144a77d3d0ad69be26afc8e8c1a57c0f08dd125c16fce890fab107c63cef15750205c527a97bbbb342a8278862bafefa3a04b7040bd10687e9400062f8ff0d370a004b6270f3abe8d4b2889791c9099c0279a7c1cbdb2cbe0c756b6719af8691a493b4da0f782c36f73bf5c5319e7d6c7a6d9d1a5cdc9f9c3704183f92d92d48a693e34f69f949ccd05b0bafd9fb1a676c23885ae9131a968bf53ee6d81df39ab4cd0427085cf77fbbebcba6785eb53ea63eadb4c555bacd9d02c0deabd3e4929b6a3eca91f613982d4411df5863312139e1a8374b3a68e79c68a906b90c5545ff92f8aeddfbe62f72ee40e6d5d396434fb3b3d12c759357445fb1d4e3cb80da7838edbb6b207ff836bb96a97f09c5e6dc407fc13eeb9efde0ffd88184d74fde519ed69c4c265bd3ab43c00ecf418a226b9016950e6a4bb114df69390e28f7bec7589b1f77312d670b38cb238a394904050af98827679edb61dd51f9654d67fed2d515c2124341af310231af0f3bac5a66bb56906e5a6bc2a453347454e6e1c9aad386bdc0fc75e5b1394bbcfe2cf1ccdd6847ca2a5a0f74e1d4850684f8a0905ecd1990d84e9edb140608e2d0d0b7519cdcd93362abfa367fbec55c8147021f4abf40073a0674c0f34b3ab1c4631a3e9ea9f99e627fbd8a5b687f241a553da6162ebe5e1518beb65f137f28fb38f92e2931c0346387b54bfef0f6dbf9f522070331649e1062ca1c65cb9267f6a201d7da76ef490984863cf9752caf44c911cfcc24ad6f7669277cba43a19c86ed09668c024649167c4404a03db766fbf8f5759e06736499740158d57b06fe68e79f212c014da9e8cccfbdbd1ba38eaa96cf89568804f04ccbe60768904e521cd205d2a0a8483a7d162b90a529764d65bdc6e5c4c3f20e5eda30b633b11b00d6831dfdc79f184131502d6f80357c301784b9764acccb91e793bd278f28349c5f7ae83cb6024cdbcbe69d4e3a05483e6ce93c41f2bd0749d5512179d548cf04d83a660a144a6edf684587714d1952f69dd4968af93baaee277e7e60ed1e9ea95af902940102b9028f396b4ff875389426e872c3dff8cc2655697871d70844d702ce3aca14a0fe68650e02f558d1ebe1a53b1233a9a5f100653b6c63d79e22719de6fd2a1056262182992b04266d1c415271bf95aaebfcc254aa70654b660ec9c8d8d9a7b4df5fa286e32c868f05cbc389dca882d1f119347bd260891e9646da9c257362be91c6f9aea224bd42ccdceab75a4d0541639ccf938ce4458fa4eaa0bb9edad92c902925f342f8ba8c9fa3bcc9f9ec54fe65429783edc7b136dff76b74451e3cb452ee9266a4885b4779fda649cad504285db343d4e368cc46ef2c59b1438ca8432bea70fef7f64d27ee29c350a1f969745368b7312d3974c58d8a0e623fcabb23b05864b493e9d3d59d56b88fae7bacb75bf05656a87a2755770ef323d9ade9d17c08e73fd45556ad4377ed4c6515bab6cc8d3625b8a7ecf6cd5a1f46a3aa0b52a55aff527eb9ee234ce7b00b154e2c6f9ce4014c974f24d634e99f2835a9e9f7e3c123d164a594d25cd4a2b51d941ea8ecc6af0250c72f2761885deb831ea7216717fc7edbf653d3d7e84e057918ddb77f5b2d1f0ff841caba0d4fe65b50cf70b5d5e378e613c9dcd3bf1ecdec3393cf8aa6f25ade0f3e88291319634862b3e8d68cef4393ada2b9cb47a2df5d4ba50f7829320578b64fd0ae42a32a8f95efe234db16f612353d9428d944661b4efba1b8964a7578ab776694ce82b7a843da2582f3a8ecdcc4a8f15dd80272d23b76966e1f243aba29ea571fc9295ba81fe6ed394b65335c64255dcb25f4017a22dcf83464cc228f128c8e1eac3a70fb3d72620e5720331f7d79aa7516b542298c6f7bf9657728dbd0b314c202a7764c7343a54fbf19bda38ebd56ec6cd93a8d4a6f195e869997ce3eba94532d18f2a10be6cec0bccca119d86c3d557f5a44889bcd50228e80f91eb50202b91eb05a24ad16b1233faccbf905c0d2ee7090acf032a5ebc686c01a81cd2da8143ecc7a5dfef8b4f94b551216354b5a3d63c6c726beef071a9002cf86b1150c13fe6aa56666c69f1450d802005dbe88c3f38df59fcc65d42e54bf4868e05683ea06f987542fb0511664492076fdd7897594082806952d319bbb815949170338a28ec4735a4138ab38cb8e1d9c39f5c706bf32c39ff310896f8abbd3663b63d5ada57bfeb83cd77e6b6607b3c6520f814d77a89f9ecc7bb39437d42700adf31f29dd4de2584fc6cf5b203fd7e6b1c649a03d3d4459a06c7f688a468b5d98f4201bb988899c0752dcd7a74945b9d7b57fc155b1dbcbc64982e20466c7933149579bb045787c3ef3c0913bf76a4e38f886c7d04284206a3e6184020024377e866dfcdd0790199bb86a2b146a129518770187284f5a5634ef0d7c728ff4b6f381fd43f173638f476a315266ac518e75fabaed63c097b4e129f0ab4a3a08ed49522a4be1b58259204a29d0658b4df851228d94c38c61fd831cbe47238c00be3e7ddfd26abb66cb85b5334d8084edb0b47b0a173b545b5a2783ac2f9a197009b3291ac395eeaab07858f0ad17b3364a452110e23f41c77a123a923615e658bb9f880f6ab85ff952b5188db1b58407a8ffc7de8e5c2dddc24a9fcc28c00e1f6a552905b1a578aa9d4b70dbc4404db167dc27fab4874c041030b9dcc823613bd5bfc100446a0a56e2002a4a901a5824f9b7d78ca0de7c8228c13041a15be53ec34e7ab5448d63cd453ed388617e59105c351129dca198532026989e1b005ece72eb19bce276e6e0462c7b4b82e58ea76037e3765d9b16c07daf5bd4e466132c2ef87de3a55005d1defff445b8868f8eb09b33daaa244955e2588d650353d87763ade7069c70d4b9a874d1bba19b27ec5df0acd6a06738723179e3f7e4a6409cf256aa96c074b228e01c8ff09a01f40bda1ef356f6a25e65487db9eafffa76261949d6ea614e7cae65dbada81b5b5c74ef9d1ea7da9ac682b7c229c3318e9745e386d1b9b1ff3f80cc3c5dc49e912b3c0687c91f5cf243a97e28051dedb23102f2b063fbebbd0a32b738250824d5ce8d1d7e628ce00a7e3f3039ebf3fba622a313f3eecce6d42b4d6d0c78b1f33382759f1648445a42493a3e143c4df58b586ad296c7fb67bf7733991cd204e0881930e17486aa2745aa18c9b0f96429e4f61c695f94cfa8dc1b46b800e2b817e005b32ef6b6daf4d9697dac2ebeb37270ebd735f4f204c93d8784308b507006bc16a002d9af740d06750c058180ec26618bed4e5e191565cac4b3fded96ef322ff90ecd1ccaf322823035c86481d7ff3982e8ce6fcc0f4b85a310100a662523701a762d2fad46819e63323205bd15a380d339e81d10ad9f24216ffac162c98a47035b5419377168ea3d39de73d37f2a5d6f9c5ff74d8b9677d3073d690a4a672e5f7c505fb45b2f48f3476a2b010dff222a5e59edf959cafe342c47c919a183fd989f8589cff3f16895c645b8825cc6a7b3c00e268e71a9042d5261d2e7162f29acb9661a945267cdf49dbffd8888664c6d8608238fdc45489569ed473657a6c09ff9f3c5cfd3907053c3aa9906978034fa070462b68c2d02de1a5564c3e95e1f5227c7d3efc16338d9a9be8784ff944baa2499b0f212a3e3e100009a3c7476c661adeaf66fe871ecde69dce9a5ff8af2b817a2948991e279e3399b25059c59c3f8033aeb613aa9d35a54d0783464e2d010e6bceb612cdab391d8c607c1bb5eb8bfdc5120d0552d3ab88e0b3c4be70cd058d566e99a88f82d4502ce9f9b475eccd682b622bbb62c55c96f7f736a46b6e705a1008171a2d5407b46b56b16e02101988b923ef2c311a8a65ed5f990828539745704cc5277a156b32eaef37e5c1f26eb832705937573f0054ff15d0a351365984485f15d1566bfbdc23c11e4f176dd90ee11e2bf0afe068fb65349e959570e2de97037634732d2f043cb695c3465a12cc4e25dcb9014dcf6657c8c114a8e63216638eeae1153ef5df5161debc469d14cc70338c1a9fe781332b13db6683d82bc7777268921c6b2cc020ff9427ccc64c8552845835127c112ff3bf2a985fa0592a50f8c2a5074970122dd591e7c0d96a48c2a814916f01b68ad89efae5b380ee77220ee22cdb2a3f34b5f3aaecf7bd074a9e7fcb6d67c8e632943cce0fb3da1e9730c46f8dfe955159dd168180a82bfe6275bb996390ea2169c7bb9e8bf755780781b307235ad7bcf855ce952ff7b2fdff91aeb5cf98c7cff4f998f61f9115f285e9b7e5d6b9e78d2e85743325f44436feda16cb443c970353cca464cac8900e9095d56abe7c183d95160dccbc316e82a59f06f59f358386b2e4a1e33e789f33d41c561dd6a9b939275ab3cf673e4656b627595e9a98506eff028163e71b5e4e3af2abf5ecc7c129798b0c49b937ae2ccd08a61d6b9454d923fac8b32b233447a30fe785d1bfdebac8a2db7227d308696002925b6d5aec9089da27724cfb049d13ec3fcea2d16a16b624f9a38b2c53be057bf8c0989f6eb715f2fcc4db59d0a07f384eee71bbaf2a413a6fc9063972daa866ae725846fa0e0b58e908d5673b27618a251832926ffc371625fc039125b6a33c00fa3eb163f1bcafcfe44312d03441ca3b3fc3791ec704d2e90ec080b80b40df858a56726111190fe705f353a25870ef5bb0878bf6d84e6619c259055d71404c6cf333909fd5615c2faa7edd77154cd62805631c2d8b080d8ff2e2f6b9d2b0ebd7c235bde22820cbdb142f425653ee181a77bdd28a38adc30217c3f2088ef3ba3fadc89959905bf08e672da743124c25b1baaa4f674482450d02f97c6dd0a40bf0d862ab0d046f0c73cd49b8e2b0f0dd017b1acc68c08fbc49931743dcbc1db23acbf55fe2c76eb9d917e1ce38802a0e03e638cd72901ff06489cd16707e4d94fd7356188c5eb8eff02c87f8ad27e6a7de66794cddca0a2fa3c6394a21a2e6d5f7a5f4e745a8daacc7181806087c30534d1eed3ee3d38861e7514ee60d685c67d2493afe1a3994d47379de00ebbb64ecf38a315a6ad94cdfc3854c3fff27a1ff9c2b6cdbed732cd9010205851cd6c264b59fb3f33f2e72fee62da7d216959f02a46ff2efe0a4e724eb1d54b3996632014027a8f00ae018a0126e697fdae7486933a75e1613d60dcc72bdbb73b779eb967271126e8da377fd370ab3a44cd89a6cff934d2efc97c3306964b4053d339b80365271209e869aba56e76ff698429371b1e6257797b3386e801e014bb5231970bcba940c158dc444812b6df448e0bd14a44d81fc2013f6fe8e9488b3bc0d2774a6421276555ea6c3906ae06d2c5d76578dff7f917aa0f0016eab7fad6d8088aad41f207bb14ea4caaa75fb0d0e4d8b05494ef984fde460cf16bf9a85c108532451240b8c8abc48de2e981d45ebc9ae33f1eb79cad64470d02a37995c6818e828e93b272f4435db77ae23bbe4c705501e00d76d6f318621ee720e244de49b25589761b176413a0788f4b42824e43b6f4dcf9e95cb583692bd6457545b999ffe3ab80562c006513202f9a0d8757117f8d84d136708d118d5110861b45f9cc19da16830836ea374ffb1bff7024818afb1aba3804334d29108f53348ba2b6e3c7ab72584e1d4aa897289619887c728a8cf72ad7d42d02c8d6559e88597807b8f572337bcaba72fc245bc328a9abf969dae285758110d44f3d1b9870f3b699f4469ef4054370e8b3ded7c1352d3452a4f2b178945aa2f6a86ee19112a01ab5f26d83d0243177ea76350f7d53046285e54610b6a774bd788ee19a7a1443c6e7c34373dcb002f2be657a0acd099638312ee46fe55eeee3f80cfc2f51a1e3f1c429cdf115612691c70f396bfbf6d9a60a8a2c20a07eba8b6f51c36cb8b76a66af6fafc0b2bd36fe4f24ce03fc8c829671f9258eb4ea46abd32086f2db3c62cbc78c3ee8ad83d67a87786caf7a23e02a8e2093d91860e88fccc47747e1a40f2e7bac91cd8d83f786598c2c16f41d3bc23fcc2347d2c59f67063e83222e9ccb070f4c81699e2aa29c800a340cf60962fe75813cc4457601238c93bce4a9644b14c85b4cf96d00b8155254b5ae53f4a11c0b7d37f1bd03e6aa9f8d603f6ebddc1f8d3cd04b46710424bb20023062f36b65d5ddba350d02f5cd9dd039aba84358e5c140ee481490259f7db529fb1e896358a9bd879d5cb3b7477e9b814cf07c116b65ca6989223e173b6057627d58d82dad8690df9c30181d61a90757c1cdbf7e95e3fa9c413d66f3b34c0d2277cbf81377fb8c0fd560063fcdb55545fe12156ce96776e4a1fa12035d0115efab64b4ccfcb3e57faae5e4e89d3a57b0628221781ba2dd21b62c40d2c7a1a0502bbfb97eeb21e8bcc6b24467f1a4374d7eef268f36295426341971d3525d5147eabc7c1f175e135a8176e409c59680d7ff43671c6a3419e8937d50b8c1e185f084a09891b2ae8c41e9372115f26334ae6bc09eaabc515ec215e51b30ba37aed8ac94c8c93b3e13bbe4c11ef37c37a322851c7818fe6b8d44d4b4e68514d8ee909de580f3dee7458630eb76f9d5539f4e1b8a61575a2fb729b1802154373e2e8b48ac8dff31b23846399b796d88f24f240af19e20a28e8a7f5d67efc091b15a578bc22e6fc7437ab343a72534e97de2a7be606f99047bbdfea9d4974e1d476a5077ffd4be99e09060a2e53db5a4185994edb24f8e1e10d88596e31a10dcc6385b2adc25f3e19960b6e9afe3482e1a8da773acb7b9ee9d7029e7e6af3f463bcfcd93cd52c178db8d478ca77064311943728f753f55bc340c34ff15e9c81b0d35120e9bddcdf10ecbabcf32601012c1ee1b9324181c0d0f326160104fbe97772386bb3cdf0a0a6954079d8f914ee5ce53a2492a672c640ffd1a57fd71eb33d485daf8b359ca4171c2167da817fbdbd017fcb43b72b1d45535bc662de8e5124b84f7c9237bff2ae5c3ffea6b93e76ef607a2972d60a925e5d05a51f43c9c7a866b58e50033f08e7d3e4944cf3acc8109e236043156e5c5a974b5357afe653e0af965ab7abb6ec918f30bbadc6b5e444b6ad72a8ba2038186b5e975814ecedb214778ca69994ed77075c22a48623cab7940cc0e635b40abcf02a4100a823f44f510c8facd979d49c9af862db87ada1f09d952e26061f56fc77cdef925ea688a4b251d064bbb01898487b636fceda30d685317b680ce2c41c1b28154afa80a5353a0deac94d8484855e65ee812aa11c7953ab98caef4f91688c8dc90415234bb056e80adada75a44365922ed129f2c2aba6da9ecbb2d1393e85840ce6fadcacb268193ed94018287278391f5b02a3ccbe373335e17052f0bac1b54bbdc0907612f36a007ce9ab413db7bc2e3943baa23533e0a862557d9ce1ac57fe499c2980fd06cd22431a895d3224f8ee1f5c9774eaf9013c59708abbf0500b94ec787618ede3bab33540204f14d2a7b4615aa3597d395fb59abe8fb6517dab886acd0f38e91f56c77627aa9bfc2a21ebc445a0fceb5eb53683d0d8b69b4e8e5ba219e6ff15830b0120abf4028c59cc781ad16fd82643b146a9fb5ab99b99a3f52110777e09034e746d42e5e7e31ed17497691d53ffaf3da12d7ad7ea8294377b700303c0aa5b7000bebe715a69fe52a1addd7e335439320b253dd661955c15f76e07723b6dd8eec3231a2a623cbcec227a721d033b6121d7019788a302fcc10b26bf1362499efcd1fc86a8f4ae145a0faa637a962b314d1e25bf2e529365f6d5fcf698a41c572a8c509d518982a77f9eba52ec91217f43ffc717ae6bd540d98c24d58eefc29c96d21995c5d7adb15abccc72c0734ca39caedefccc96d93aa266f43f8feef2dff7b8612271998785d81bbf992ce9dc7cdfb83272308f28d0cd65e82c145b055b5aa323bcafa279c349c6b9e3d46607d282419998ab989607d3a64dde738d42af2f49e260aa0be8df38593658beb74aca0fc3a09448af30965e76008eaa944830e8d4123f176c45899e33f72ccbd022450d82610be2521a829afa23a77246ffd196e085d86767713b3cd41ed0bccc87983d1c8a0a261760262da0e093a24f2b913a9684dbd2f8c78d871ea34a184c30815b1093b70052c9331927735bad66feead79b5d72e4570920db6f998a32ce5be8fe7261b47358930779428541e97702e6c3c47c8d367f75cc2cdf4398679a011c757cda5659d0f074c5fb5a44ad757a70adec3b2d8da6b30fc9a4633f568c8bd4079e9dd2f0ed40d8b7c3077f06784592dff57596ea9224b3defa734fc4ae14e296f2d674efab6a9daa6422c1546b2833db73f104f3700ce1deaf14d1efffcd7bf7365fc3310a53ef98fe886822991b69f74235cdb0475944bc0a05ef7193736afb0ef7d217903c963f4112fa06ea8db0bbeedbbf39f893242d56b60f4bce438ec5af7fd5afb7003fddeceb7a04ac26dcb8644b8df62c0260eb4b6df415610d14c2f058feff0410dcee65b54369c30001cf733323af6c018b682ddf284f34a53e16df2bf696db09ea6e4ad950764d8473316a212c1742dcf6d54aec4c7c346d5989c5ff64ed3a11b7d4abc5d0ba598265431245db4932054e8393e6b9df9de5f6e330c8eced694ec709d94c4bb520e15f40586521eef6fd6ca2907e9efe41dd4d529e560fa0c33ae5567db614dbebd1da63175db525302a9f0a08cf5a5dad5548d36351358d7b88d6900386d2edaadefd4789f8c87579368f302050737b4c3d3abb8bdf1771115b4e8e924009e5502530a7f98fa695b0923c856970fc1be293f60f053fea2904b8c758afb303c9d90417a94022f47f8191960ed0f650ec417b2b0ead517ea6e236fc71daab26c4fcf0000a08f1a706efd11f7acc57ada8fae7c45f16861ef8f050d1e2de3e9eb455f6706e4635a83812e6a27579d7014c1943aa6a0b5da217d0655c3bfb7212e6f1906690b92c3c475d71353e865abb379798b2ee3b78cd884dd2c304b29ee0c72e3abb2f0fe8f68f768a464a22c3a64e1666d49b00dceb260e3e598724da23b23d7c227dd591cd41b301e1bc9be5efbf25ee770564f3795f4edb6ba90f7b4d858baee1f2e8cd3bb7bd717081aa839ae531433edf45ac5bcd835b1f2cef1a80a5bf47a2a70ac5a44181ccbcbf87fc8b4b3e5c367d380e32f37c288bed2b0b518b2c06a27a4e15c50e55b07f165e4da78d12b3b1d11248862c732f57300e6e408d4d281ef6f9fcf05ff54798fa51841c6e9a4dc270d7abe69d1c704202728c718587c131d27b47f1da82d66541afa2ad982b9effe6fe744e0158e0c5f483d76f3754c47be248bb2e337e363954e50860259ad8ea3483e40846738dbbd6be653219a2c0c1afb564e3bfc83ec2e4b2074da10695908a69fe6ff98a2f3ab7fe5c2a0b147eb17473b273688e655096320557518e9c564ecaf2135b917b3d232ed2001fb7769ddc913e4fcad95645e8d9df153242a34be4b5ea684c2a55cc1967a41f8c68f5bd4f8b99451b1f92975d281bd5a50cf9a9e41ec5edb7cda24254da91a46b767efcceb2057ca9d4d9e20a8cfe857a66540434271ae03c9fdf2c00472f15d0402e8c84d80d8b9966d1f68c8b7c78d727e2010eeb939727861ce45c52a39097abc11c7495285950d22e8c082dad7ebefc531b85493fbc51cb165da460fef535e0c32a921b697dee42b6842b114421a107a654e4cfee09b0fd54c7653cca65a49b6e3a1d8fd847f01431ff743bfad6aecae32d976645013537308f681a6da04a2cc955cecfdd63118d5bd513ef519299cb0382086f6d5a71b5d6315850472a916f4ffca1bb3437f0c5c723fb0c1545769539ae7a770b489efa0ee3497a74d13b915b70706f5ae437e6efa9e5c9f32aeec144da19d604bd6794fe4fd71e1c002d1de89ba5deab23a5fa2ffb21796f1156a640029905eb1db84660e44539e37a0d438a27d1272add425ea99b09f27c0b01ed8ba4b43c25ace8486ea468a0813f2dabf3e0d0e5ebe3ad7d1a25f699d2759731491c5f7cdc7aea91f454349628d66da32badd9c4d3ab0d6b9f27a6f08c9d5cca4b7a49cafd7877d95a3bb380fe01ef77e6366d7e6befe6eaf4e2da7ff4c93feac7f1daa1de309dab3d756ff58cacdeea4d35e44838a2222186b7b776721772b7041db9d2713d95e93290aa03489b39e1e896f88c3d807315cfa43f3b83dbe4870990f656692cf4f914d71b158bf2f1c915e73145946ec103eaeffbc5359df0b1696160d51500e1eb3d4bf1996e20a6a821ab7597027910d189c307dff7a2c6ecdf744aaeeb68a3bdeac3ba281998e2133509cda6f9656a2bcbc054c562a4740530cdc4710b2a1f834ae6b8bf18bf28f62f03f960be92e49fd93d8d0c84a4999cbd12b1650cb79d7d57a3aba1e8c1bbfb8eae02af3c51462d61acad0f6faa33bac07bd543cbc364d15161eec9d0deebe0acfa4110ded5d1a03dbe557498a2ed07244604c441ddef48abfebfdab152f87ef3facd56857bebc4c2f4fd75947f2e8ca86796419317277b3c9ebcb636dd27fed52413f6b91830fd26bc73178e9e9e967c1b784372db0b6faf5f7b085906400602e70d1d607cca6752b39e577be0786598e2ff9689e9ea08152fa18a4c4d0e6116f1db173d0ed56467ba4990a9b06bbac2e40ef32ab944189660a6e6e9d2a363d2b2f21470d45db5c381fa317086eea13689352fee62bfd03c82dfe77dff1b5572999ce63aabeabfef7f7d46421fc24ad12451e6afbd51b21fc7f9f5ecceabc1b51f13a4f28f635b406d105433ffe2c98fb72ac4d7302531bd6be53a5c956df472a1f2443ad043e91f95972ebdf26b443f072dfd751633be28a037a715bdc90633d1dfe7b7f511e7ebbfdcbef1ef779499714d7f909383ead27400b9af471491aedfddb58dfeee1a454b4214af60b7b3c9c399b8d92f2fe4759c1f6bb5a654913df4648a1cbbf3e85016c02859dbd1f64d05e1cc2edab68622f8d3b17564b7bf7be7e0a0bbfbee6c1442bd2327577f6910d0c6c36c1cdbb4ecdd4fdcaa00aa240106345d621eca5f4a7c0fc939b33ac06724abf6725d6c7b4f4a4a11c62315ce81d44caa2065ed99e180da3de175358af5dab2726fe66b9ccdac438ac2a3821107e33f1511205bd77eff218aaef0a7f08bc4093e81f7ebf5e2246a04411ee0f122ebefe3aff65c2e743fa42b9afa058dfdea055d0258029faf225cb7a9f3776e75d7d87e6b78e9ac1b2d95ec897c214b373a4d7e6d4e5f484aaa7f52f3bfbcbe912ebcc353661d733976d4117cc4179e1b202af26cff198ca9dd7f8ef41ec88fdf6e169696ab14f2811943249a6f0a17d507f90522a422099b796d1b1d7b89f1d6fadd91b7c9d19ba1abb3163ea71f1f99e28b50ffb7adbaf2066739ad8c05696239f645f5bdd5d5098b71120c76b04041e0d03ee9d19821cf9ee1da418cfe448a24bdaceacb88fa41b09076049f0c8d3430b5c5a72ab0c75501764e9e3d5caf829d95c89d16785c7cca563007a39f384398877385247c3f8d2b9c32e5fd65cb2aa7cc3665dbc4fe30e8fa08fe5951fa2debed53d9492f98f4ac2e8cfed7c1d34631ae85bd2a086178afc81c7c2a6133cc8472c83fb03f39fd573ce1e7d3351d53c7c270d42caebb40cde818b58afd7ff4b008387a23f6223e9f913c87d519e534c36e68475b482bcba5e4b1cddf36fbd47a6f6ff822dab51835ac7170ff52bcc76ca94f1be51ade8a9156760daefbcce52fbb398d3f9013d781013bef2af450b6139f4bc3ca94185711fad7d51506a391f8a0e64f988607c24b00a4a7d1d799b97ed43a000891fc5ee1e1b0f1b15559197727fdbb2f58ec660baa7b6142cfca45cdacb68f1053ae824b5148c9577181d72966a9ce2bee618a0e750d32aff1df51ffa6a40c0ca870a9d04fe57dae45e0dc61f49f57a3201ab41932bc8a04b891f2fbcffc58251104d840e1b7b18af21cfa5b0ad80bb7b6c43c89288f36d41f884aa00cdd4dfcd3142d841f2604113628b265d3682deca98fc8220721d65d29eaf50dcc85d982f2d929a2e39d5e5b4fd9156c33ecdaed6bdd8d5f5466a70b7f3f06134514483713b0654b78ba53b3e31cd84aa282bb602768bb857ff6cecca0a88cf7bcfedf63cecb39d23d4baa062189663b416b52a7bee48acdb5335572199654f566f4b9d8057741865b7d5212539dd6112611d9417ab08fb8107dadcd5547822eb404a59ba0a2d91718bbd17a6644d2d8db243e5adb50f88263f4d472645c684289b28cacb9f68429361df981c59d326b70dcf33ce8386d71fdd847bb947d8c6be5c4bee56accc132101a22318fcf2c7e85d483130d091306c4e7651a9062758b0ce59e442695985bc52fc90e08c78dd232796218ab2ac5a7776d5d5f12a045526bb0ebbb1706537092d0011f2047b49678703d143eb7830368ce6fd45288215c9f995879da16be9e8b44e797c731d80b570e233ef322952cd0ade87650530c1ad57e95068da56988a0eee0146d4b35c8f5abb5a57e0758c7c3788bc4ca4bc3931dcc7e6f189ae37b46ade506b7559588538a93fb52c0c55cdeae40bc4e6023c5bb19eead6cf318d70b5e12b99c51cc6d01232cf66e5cfb7d7750ed55b568878846cc03e91a0d85e35268c360822f38e2f04f54c6bf656e834f2c19038f46f0c8a724e7c922579f500f4a6a6907f275ec49383635e34fb2aeb2856446708a51cd3537bac603d62472c98790919023598937e1563e46a43f3c8d39e315dc0891441549e219114a401e012cb450d72f4260f86546c03ea7e2f9dc14cb2d509047481b8ecc81653d587036935dd8bb78e568ead7281253bd639507dc8ee1e9ae345190aacb2149e76badb716c082626def47152542a8b02e761a4e31044bf5778922701e0c52be1f13f4f0d5c03890c4a90a62f8114e7efdb5129338b1743aa5e4d7534e5d33ef9e59f75120d289f563151e38b772ae1b7fa26900190831e7fab8fc1c23604d46d79b83094b1f03f14869a058dd4a6ded31fa834c6e53d13802be275ebadb1934c1e184bcc4789a57b40aa5567b0b743e2a4fb1ed1bebf9008ac34ff843ed2b018ca24c8b61c7eb8f1a58ab8f5f902940103b9028f39703015851ece5b2afaeb4db5786d00e3f3844394cdb29ae06cfc7c1edf3f389ced35b58aad8e8381c97f991944e6f0781bd378c9b7739e0cc0457c375dbc61639319ffb2e2cbe9d2df7c6cdff1a1d692b08c0ec41f152668d4298573b9c99f4399bb36b32695631665014dc946ad73bcab9ad36251f6c496a5469096a347ce589849501d8def9e430961155eb1d23847493b8f1e9f7c0243e09be00afafedaf8a84b4c3d04611d48d9573c94c5fbb4e3aa07d6f11c240aa5d2b2d3145f23e32093e236a6372cff6a3dc92a876fc26b6c96ea7c12107b6e1ea50569665e4d6e2212c99105caa9a95ded4a96fce972b1ed9f7f491f6f19193e8527d115345359c3c651e5cd26aef321f62609baae92db7cdccc852f0b6658ae78a4f50fbfc9101c1dbbdd1c8837c4f700bd7669e953110e4ac7fbf6cd409e7a7d88be131a0c2a98f254d8271f2458cd175045dbfc80c4a978596d33290a9c52653de4fb5940b24999f882f5dc612626620069bfac49168d8e5c47819450344b94ed76c8ca58846ffbea775774a546c6338d4d550d269174bb0ada904569ab256906dfc61b489a1d3fc3726be9b6174edf4377b66cdb7d8d4b66631faa8db4b497cd83937b055c78d586fa99444c33ff96c9209ea730c2ffea679c5934e2af2a36cadd7f918d73e0d848494ad890a2691f6260ab46a7edbf8bee10ac175e4cd23edef85a7886a2e962999b9f64acec5f7f8086b29b6a0d03f983396adbaaa62885bf14d364b7ba1ac410a3eba7f85350335236aa37d1ac4d7968ba8f2ab3e589cf2a0ce2f0310ca7169f3f9630c341e4c03cb5541e431296181a1a38495195294bb1f7a6595745becd2d36661121513def8ac72398605f8f642b46dad2e01399fa3b9ced1b28664f1728097a770f56d6e82fa8cfff20f91eb50203b91eb0b872a5292752f9c8c25c511f71252745173e2f81fc0e01cf4808b93d5dfd3f2e12de3afe912a350f839c53d30e88cdef72409802e7a85b56445a451c0a3b7dc4b984f7e918d5dd6a93bd5c5bb983fa88bd76caad9a16c3670731a2ae3fdba099b7c8c23a2d665cbca1a54834ffe1e2f6fe56e233e7049361aebc1179bbd42dec845a782f57d9b1ddf1f5f4031e56ab15d425861e05aacf9152ecb09402b313880ea1cfd477f5d6fb56f2c4e1b5a58b89c4f181ebdded7eb34164b5de0baf0c5d9b72fcdb54e403ee743b368cae0292ca79d710824f6a0ceaba84d68809912155814d35f86f719dbd2f246a0db69da4e333b3cdbc37b8caea176ecee4ff5c460cbe9f768fad7ab92977bfa8d849d6ead7187f8cc5b62051a48750c08975abed4673c181cba4e8e03a277c293648b2517451ec70578f1b012b74773efcd0f41ec31b25ec96cd4eab9d7b18453e9f50c8a888a5df658b14c59944ee7fa51847317e3b1c0380954125d6e5d0986149b1d3a63ac6b298a19e691c0a526f7c5a9f9baf6cc8283a8aae311dc91bd8d868b042b464e340fe3a2e16073c391cadc877af9d5ae90dadf106aecff76369cf4bbfadf902e44e71796ebfb159ed4c9df904519115c4226e3521c3b5070abe04e3d4ca85bfdf6381e5c21b09910205e7dba41f78cdb9f42b454ac20a347b71a000906097863913b69fc4920e4028f0112abf5e32037ec561e4ce410e182f0daf90d64a73b286f0f18e7608846d2287a6d5adace6f6ca508dcc9514e88d1f840fee174fc21c83d24056c9038f0e07b4e07138f37b1389a5ae79e973096a73343424c15970f0e854cdf6f5b15a2aba8f8816a180e7961b76ac097b873d8371edc9f17ef519a8a789bde0ccb14a6f2665d1d0ffdd984da545616aae181d8a33a07f54fca00474739b707031581d3bcde65c2170337ce5b14203d48e4d30122d30b7cf061c82bf87c9a1e8e28e963f0fd18f2b977018d9e10011e142ee8af311e861bfa3bb393d8736b1ffd93ab8730b34520622a28efaa49bbacfde6c9948aa487b7bbed07896eb073805eb7083dd121d8cba8ee9308dc6b99e823aae58f14dcc8db207216349b356f672e59c41c9f42404f636d26539c7bc0d75938026e5a6a6ac0e23a4a48f45c293216005ea8a16ab69b238d89b6ef41c603a37a15834d51f8aa3b08e586018cacc305ba97626720b59f208aa43691bdbf97948603fef0f5996d14130d91a1f3ca1e2b121ab9aac70e4d099eb6a8c8466a2ceb4a21920c764641100bbc9c85cbbe43ffab1fcbd329dda11f7035ade239f561d33033a2ff2959cb5a31132e3d00aa574a728c14345017cffd0ab7eda9bb9462dbe80c6a19fc54ceeeb1e624e09dbc19d3ad1d2678e2ee39520688b7ce9cec939ef854960011c3d82bcfa3291ce781fb9e4e13f02fffba2cd32fd50f09b3b3d0e5bd817006721cf7980e1a17b741437d4012f45ef460d868cfda05e96b7dd32b5ecd115b730ec9df4566ee4c63f895e0f52b5718e35e706d1dc24673dc9ea4a910bd9840314c0265603becdb3309051b25fc217ab00108cc23b8285f8fe5051825677327ac21639d146d35f2568534b3bf569d6f6037940c6d808fd67814928906e0645d80606c7f69f3c60b165de81dc9bbe295150cb0f7f1f44a1ee26ee11ba68537434b7dee5f288fc48c39b0092defaab719f45edfd618b54078b20dceeb8b11a1b844236227bff6d63cc40279c03e3938e2e243a19d03164c3ce26979164d55367d8604efe9ff336ebf360e803ea56aab4f786fd6bbc52a0aacc5265de52af3186c3f3de4889becfcd34079189ef19d7bbdac89728a5ab918a04f0361b2112992a0701c169fa3fa1e4978baa610464d003e097210915022e387175c65ad3539de0fea7ea588691035e2fbbe7893773c1502aebffc625bd77e0faf6abf3720d7f483d4d589c9f9bbf4a6132cd529da81e2be259b952511654d54f7d265778d7ba7161de7fb19516d3050f6e389c286db4e720b7a00c1e5dad0d88c2b66c540979a9f8e5cad4fcc93ae843f0e1b1b7b1fb5c6ea83a276fc0743b6a9ef84de46a13a97c224bc5fa248667047ea6461458c4d76ef6a8da106e465587293516d9ac10c659397feca0deebc1c9f6b5ec18ec37b0f98ff73338f7df3dfacf60a5120c9bdd2ff28112c1cba2fad35418a3c229fcf4e63cb79a6faf835e2eab6d37a7a1341ed2f7ff741a9617d2ddc057fe311be569d10033518c7a14ca6439fd034b15d76bef6d431846a910c39f046e443897c6bf4910dd5771e76980ce16f08137019992ab33bbe50cdef9c69dce509dcb22a93f26afe6dd644b3fa6a796894b294001994ab61d517756b1118ebecb2b985b92b817c4449b92c633d14948914f7130aeaefca1f8f4c295841348008db1040e3f1cbce9408bfd0a8fd3f8026db359aef1d5d41c2f362344c4e5cbf0cbded6ed3335df77daa8f561423afa747a4a5f2f14439d51c874c860be37f1c5a5d0bea286a21b7b3f2d9ff6abd09d5f89fbb24f68312bcdf1146a1a6672968a6a667907bcd8528d04690ae7486be7c92849f49f0468ef78b59d63b6df151d1bed87fc63011a90563e26c9c32c3e10ca61594435b2cce17bc1166e957922763f331783b690a1e01cb91a7f9ffa35703003c424d95a3d0f10c212706a2b71469c172e79bba19d20ab7841243c8ccf4695a7e815f049e7c0dbc262b602172c3cd8102d8b3c29c988dbabe9ca62ee718e5009e5e34a248eebe86ccf14beb059fbf0d1398a8d2c9e5f91c7cf2e1d0cb53c2cf96078847190dcde5f0523931ef77c1532c110e843d96d85f0ede443f34df3be80bdbc9217dbd9befb4923434c1b4ef19c9d04ab4b96f5708a1b608857e86ecc41f469f786c3ebac5cfc54066ddb27d8b9e6460971a09d109851c2fcab3e67e4d71aef9e35365b9ee08c4bcb9a54fb0087142f8f70ef173d56e97fabca37bdc2541a9a21a61368a153cb3ec115f9aace521248e4f1c7a7fef3d2397ff52b78b1ad754ddb507f39e3106d0a9450a4055c57506e68861dfdc268f17ad7dff5757c7273dfa0f9b6f7b54e2c84ed328eaf89519109e3283ee65b87a012ec9279cd178246015ea6c6409de3b431eed55313ac69f88378ce6dca112ded1c60e74cda0eb9dcf3d51c7f148bdddb5915b1957840bebbbeab671778c3354f8ac77b4e0624df6cb8eb5baeab88dce6af3bb5a4c20adba7e31d62cf917695d84f9aeb4a9e47276561e48f80df6441fb1c7b74680a98cef8265329b5c6ebe5ed9bf42c65108bf4274a895c2791ccd55ea3f0b797a40e02d1320f542c97a239feabbf7bdf6998a4c1aa61e9f4f80a1c6b0b7179f8041118d5939c7203acf052f5c13bdf0fab358a6bf3c5a7890b8e92dc10fa92ceffdfbe9782776bdb35fe8c1e8784b4a2e6864de68468fcc40253f03c80338c92762ef21d74cbae2748caf7755d44f11a2a327e25011995bc1cc6cf0a6cff5d88f10b08a088bd046ac8738edf4a3ab79055dd3d4db6e384f62c7076c38780d033341687a766362b2cc11099e2c3c7f2f6f11d21af818ba480a77f621e05a64852e2a9cf7f66f180e4892c3d9f9c0332e367ecff13b331e52a336bc5473020f25d9ca983e0a5ea938ccb3f725086a496c341fd7006ab580619c3db52f93e29e868fc62987ae03b36dbe94bd6caf8f162dac6b440a380ea14d0c9f550973e5cd5d35c6efdab8727a43941c10d3e3ac56b2c850e7343ab25be6a62afbfb8f6bb0aac99ee13b40b8a3b7faa00038e150e900b67a47b66a7ae2a3e4940b4c49224ccb6b92108f6a299be6d8820f6d417036360be94ed8ae5bf89756a283d10737cec581424c144a948fc45927ecbac039dfb2fc0c2558ae00b525105eb6ccf07c6f884b344630aa79dcf146e1531b65c3c7389133b7478ae4bb14d4c85bad05cab363ce26565f769fd0e440eeed29e6f0b0c4e00b646c1b07f33e10299d375f55dcdd48b89cb1b0e23dd897778641be7ff0d56f6e43853257321833fc92ac43a03729d5a2fe1c50d0092a0bbb67ca4bd75e7c380860f64b4e4ecc308b32b9b11c132fa103043fdbd40fef4986df51665be7555d27cc694ab2644e760d92aee0e3596329ab010d0d1820aa3231a9ff3dc94c89fe06acab30954ff0b55a32e1837cabad67c7fe77e2b3bf24b204cb6bb5d89a33a2d1b9207919ec70537228de8f5dec508ffc95444f6debdcd1ce2065893f48f68ef6b65120fa20054b4921a91fc830768454c7d7651f41e5327dae064f70088a0dbee81ff72694072ecd27efe263e4be3b5df711596de88c59b7feb92195ad17947b1f4a913d00b00618539f26e28dadb70aeac317aa052f9fe8a6e47322f977aed152d2efc2807468363366c178606d38d8cf8edd540d85e62202cb01fdff76564d1f22a4188bdf60d2665eefc1e86d6d8752989f533823f8babede07f9c2dccdbdce4d74a77cfa43ccfa71bb76c4778c0f5eac22fe57e1c267784dfaecd65d9aba757329580684d89d0e8aa1a9db9c03b081afcca99bc9467c2af1fb4cf8f0b7e945e8da870e02e693b41a146968e7c2ea8a326b66acefb4f1400738ccb0482e181b4721d96e40e04cfe797b9a2ae38541cfaad621a00640288bec1f885b463a44c522d31482db0b32ecbe2e56e3da8d894874fa29299fa44b31b0d77edc6e9fddf3429c345bf68c8d5ab6eb42882a25205205463eeda15bdbcdd4eadd0c80af46f7ee29829947af6df2f97635eb8161cb4bf84c00501ad0baf0d91116d1b2157c4f55f275e5c0c6655a48146d67128693eebd939c29d81382cee99fff8dae66c190ab0f801eac1b5ea43698022ea014b30bf475cfbef92e00bb80374ea6f9e8c4723230275b6c18c7b2e3b4786db66d88509819386240d5962456c6930e5b45952d0c632f1a9cb6751914da2561fb6ebedf50575b166d932d3dddccf1ab611ea2ddfab1e838fc4e46cc06882f3e3feb04c08ac6c7e6236cdef749864af3f28f6b91e17e3da7542fbecc83fed9d5ddaef9deaf259c2513b3a81ce4ac3f80385075f45a2c75c892afebb7a2b6e1f3b3b3a7ce761da7b098eae0596ac36401d6f8eefc04bb7be3a740b932a9f88a05767bd58ac11e303d63fc868f6f0acfa50b4238d3c36e57235439268974d181252037d30b2652796438ec416417e36381d28ff8dc4a499b27725e942877db316a130f208ed31228508c92fec6fdaa27cb45695cffa9ba40263f8557faec162c80b3f28e88ca84b82006c3be6813e9c5c7d059099e856ee6c96b5d056e7d07cca23526c9f20b57cf9f9a69d9de606fbf132bcf2e7456160b5ed0f929994682846846d4bc3fe34cac76fcce01a20ec6d540e576784932f78a669b7b81ed449929d4d577463a91f62a567eafe047fb6089d2f932f957ff77b649d71096928cab8541aed254a52105860cb80df025f121677841a0b646dd7eef7eabad78e373ac7ed1a5f7739761ff7cf07bd77dcfa20560f23aa997b77677b20c13c4debd52c80d539c725e741fd2c0b7a05ceb6bc0e020b89ee8f1c8f0b6ad6d183097af86e49d7a0bf746da1360e2af218bb97174f6e69438d6a8021b4f90849488b8398f6715fcd94aac3c4d16eea58673e0d5119799b8b7ffad76801b74a7e9ed665355dae8fe99ed876609c8fe543c1228adf016360569149ebc71543b0584360472ac7f6194823c87adac5bddf881352fde8ae8ff085896d0cc029d104ae581b6acf823c189487706a7ad66168b8843d8910eb6c61794f0134328f49438097b2c7651bdf6252e82c5799e9476f94d8e133797d6af0c4daa5457556862a475757378b0c438e5308ca9bdb56735604b0fd4f9999507d52326a342c7e591edfb8fe20e1972009b4636fa7f4df97622401cdcfbee2a9bc1d9a2c60f1727e3253b921a3e4b78c412006f4ad8b7f6082f12409579772c24acfd6fd25dfe89dc2920369934525fe07b633c99ea6771be712ab2998b8e399a953c44490a5686e65139c2d901912850f19bfea298941e50b79f67bb086e062987054e7c17916938423f6c9e5193c2fc0d3457ca40cfb2976364644981a8d7f418c6ebabccbe59a33b89bbd68efa0de7914115890e6205229dd6964f4bb8166e71fe3b0701fb355b510461ef925ebc5cda19f22f1c93a109d0565193ccf82a95cff02316e62ce7b97178f29b04f4b45ece54aa2b1ffcc32f1441aff9f3f77488be0b9e8bcdde0ae648f23e4b4dbfb30ecb4c2585b83262666115f910cc0a686fcea0ec79aef606e5be3eb3bcb0b8ac3f8d7a5b2e865fb9a0eb53456269b8dd2b9169a9fcbb2a868c8ef5767412095b338ac1be18c686f424b747dc4ea9f2134f03d695a370817d57be674ea135250ef57dd01a9b5bc8f7cdb768011dcfa9036aca37abb22cbd12777b29634035cb1c287ffb22243f35f670a50e32f93d1a96a234e00d116c019cef52dd86bb73d65c8bb89975d9d2794a4268c98537bb213b321115753746a48f3fdfbf9ecea38a116427cd2ddcb0537c6e3d4020d9180417c32277f97466e95620401ddc3da75666ff93b3a4f04d3bee96e8d7c5ef7dbcfbca2e150edc4a228ecede51f6256781eddd2dd94b4b67eecf6209a23c66f2f00a69fc8cbdec7466e66c1218cd3608e062bbf58bb37b6cb363b936c67f3005750172f6d477ca39a62985f1e77c8da060c44bb2e9724698fef08c7fe67a5842e4451ceceae6059f062db46e504edc30c6d828ae89e0e16363bdd970ee3a23125607705882ecade27039ca17d47a331d30a06458448e2ad66ea79b71a4b5faab93a837b5b27a9a07c6a03cfa98d44a34fafd00784bc329788d449cdfaf86f0a3e86cf20134bff4252a2de0e279235001100ae67fa24400d70df892ffacfa23b076c8a7e2ee7433a83003408a2dee17c988f01ffa06cf0a9a0e03f9fa01d91ccfec4b8f606a041355efabeb8096106031315d212c9b1671fd84140b4282f6b302a850134d6871b692b7dd4acd953bad1fce54f350838594122454c085d2e67c8b30d7d2205e2491148a6f9f92897ba5bd1c019b944a5cdf345ad7cbd04bf997d7e8f67a904f555b4be43a8e62fd48a9e1ce498ad2aef000e41b65463a16bba18487ecbacc71466d64e242b3b96d564ce051fc938e7c82f8b9f61134b27649dfdbd1a42dcc77999ca4f7c02bdbd9b9bc4252089ac9a1398dc9f517e70d62dcbf6a63b7b1fc838c3ff885bdd4ea0dd9664def3ae0c699b96bea2a91ddf70cafa834db253ab0eb5d9b64e0286a23902b086e4a4dbe556953934ad2f0ff36cdee5f78ae1cfb133a8281873063df7cb75ee311d5c41678265f18248f273395a4dbae3ff72e221225ea1e748c2902391115606d375ef45b7d1f768aba2051520967e24b7eb945d78f10c8b21241dd64b1aa880ceb8371c2c91d4151f978e132d5dee30dd024a8b78f9adbf225f9f6e068ec7c6b93e294254f721ee639c6372c0e1964c6369bc1b5a201ec02ccd8808cba0b9ad740909543dbfe79cf9191cb74f42cd59271edb6f42c41fd2124958cc1d3a0b800d089b74d8db83e9dc336626951c9bdcadb41f0604fa1f48f8b0d74aa60d57ada438f6f74069d03a41b80ac0dd360d79e475b526cf998465e04f2fff10bfcdeba3f520b6428f60afd36c2b9478b5ae91c08c407270893edfb2bcc7cab1180ba8d302f7a5d45c21dbd4318b95d76aeb95bb23203d29ef867667177d30439005dac711a6d526a465bc9028e27ffaaecc7d0850e1b4df944676720e3a28484cb7670856f8623c858ce47d18b1a31eb96bd31054b44149994a19858a5b10cc33db13de3c9cd0d7c7a376d71b20d8ab759add243e1cdaaf73d118e6c260f411dc8ddca848749ffa296c3d6e5aff0f200c571b10b0e6b851ddee6a02951cdc7a16e48c1532dcd147e9687e67f8f8797b325ca1748d9d5fe48908cd7e887a39a1a2b675dbe9b4d274c8e29c8723b54b6a168682e8a54920c36a8caaae2cda9c64c023e9a9f312101d9272f1d73c066c1643be4ede1fa4c0c4ad3e90645874999c6cc3e6180c3259ec367947b814c8e11b5440313a15236c79117e16e055a23f62485dccec709062fcf53a04cd6695fc74c50498636e3324f177671fca5b9f4dcfed1f7512c4434b9f4a7cd9a98f7a001e9ed390c9f7f26e007351ebf886be7e2a226715d8ad0c229de476b4d4ac4ffa8032bebd0820c717310063766bca0fa075f313d5a37f0c25f1f635efd6a8d39fadbab69560078df3ad1fd9aa9ca1852999897e31eaccd8400faeba62db0e0357e1c9acb4b4c7f067d2012e0b1d6f8acae0a6f8bf3c7d3b1fff402c733f81a4be422f6304cb2623cbfa888bf92ff907b3d020b16932c75d918b39d1f2d42616f2b2ff62f407532593f2bb999cc0103d5a407b04bd7a069a7125c21c1f720b0a8d0dccfd6431919f37255daeb7cdc4aa9a67ba456727857141d04c4ba9b65592012da636c07774b3ac4b40226ac022eac220ac0fad0fadb7e60738c987239435385315f537c137bb3c041c10c503c9b55a4d68fc0fde8dcbfac41c91d81910274108bbcf6861b4747560a5dca653e29da2738207017664136d74ff85fefe78a9c5ddc51e8051c9406a3769fc93b0bac7763ce906286fd97466927e1c52e1b22d518336a84e0ed2e31225a1362cf9e99a95b035400da8f064a84a3ed5f32797820991db2828e02c168a3177ff1d678ac13d95d25979f3420e369c09966d28e192a2e77b20d567d2ad2b09014291cb8945f4ee1c565839d549cda4ec7d10357e1e44d5001a178434faf2ee2c8aa7d350c22e07d82fb7ec8fd6fd9edfc383a1a7f4ed38760d2868a57b64c8314baa48950acbab1a950d141bc33d11042a505211d4284e4d508e839eb6a6d64695c51fd8f0fca35f92f018e985d01cc56d1e357c88da1b1210669b0aebc7778d575088587af11bdf4b636aceba5f81755ee388cd1e581ce019beb38791f69843e530e24cf978c525d05e59f01b0bf123a70fbf04b1714151293b5206674913733e676748184db6bc6e81efd2e3c66b890dface83cd0efb224365ad67d5053b78bb4ecb686626719b09724384091bd192d8155484bfb53d9d879b7fd5c081311f010404074a4e863f24aa7c8aa7f3a621f6b820cf48a6d3fdf9d3062016b4e43a55b972c032982559546d103f7445add072dd66e6d25242d01d7182851e8180be14dcf5f5f4eb72d3af11eb71123e16d9138270391d68a93ea0277f9cda4078fb06dd058a13a05b55f36da815eab7053c6580695ea2d2e09290c76a9c19ccc1155f05a0b3a7afb625037ec1f7f6c709ab7c96e7f9b8ee97854360bb2f0778c6d4d9ad723e90e498bfdb1ff302fc8da21367ee106206d07492b69f762d330b31731bee5e8ce86030118e613c10b7ea670045486e78bcd50a1cd32a61329c1e95aedf5bc88bd63e791bcc5d3e3348c4aa128c12c1c374877f63217855dd20e4fe25b0af1e1a0c1fab78bd25cb4120a120ce87e60eabb621ee9b3dd25120412cb40041a695de0468c104bde97e4d47277d6dd4a276ef817fe56701aff29fee8e1908fd5d851b34b3f3739636964030552ccd7e0391a0aecf31e5001bdf066649be3f4e09d25f3c0697acbdd1988e9928f2720f5371df168ca843555458bc350c2fd86b6d39372a30eb67426d6e70c4d6d558ca4c43cd8a2ffbf225daa609b2e53dd12b858b5ebc7063ebc86f17ae0b81b3f48afd9b6e888ca7f1d493e35f35ecef2c8d2ccede1f56fa9fc585b044e0b1db918d2de356bb2a249998b455a138f1c22ff6ae2b6de0cbe151103ec2c607e6e06e52b8a5b52eb9368dea576ffc72aaf306eb18099868c3a39e1b28561a9cb6a882f2ea3715a916bdda646c91c889e8147081b688baa1a93b5a5affdb09b60d22845879e506fe4d103b77130ae2b7550ac4859db9d549a2a33b8555b9648fcd22a8bded3fb911876350c09fdf2285581f159cd3ed62c7a43a550070aec42abb21ae961aec3f7b983cb6a026b8ed62e878e898aa4b8cc2fd373e621fcf7ba42fe6a10dd36b706dabcb8d84bea800a7afdf3756652610ddc67784e13572e22aa1c8f851695bfa6888b17c05cdfa4c3698df342091952964815bf973c339d8432b11ad20a1dffe313dec5c3d79a82ff7698a8f8564db344fd33381bc6b157407a7b838c7995a4cc6cc142e4f564f5c9334387f151696ba39b3f429fb6a0bd80243336080440e8e8c03636ca013af2a69dfd1616f0ee320d030f34d4a3c8a48bbe3a512a91e62ffe60f970d2292d3aee927fdbbdd1c0049cf669de27e78fd97300978589eb37124dd73898539329e3ae76af7efab438701893a86b5ff54d0ce986a8ce688d47229e6cbf10b4f290fc39926d66ee80d6d6514601367422036a4129bb43afaa2eab4ae80b41bdf3a99d9e1fb67942b7dcc1d5b3dec15339c891574369d9ea379163813cbd54588b53c4fe629c47432d5e2d4e97d67403295568fbfe01c640f3a0969ffd955a6698028e29ea8781aa4f17c72517675caafe71bbefdd14f5c16908b7786ce1ce8765c36e673bbd33abb3b6736e7c893528d5acb30b4aff12581fa378eaf85e57957f02f4a1aeda053a5fa5273242b0fe49f061e744b987c8f1f381e04fa52762271a76b535f8411b24f93f9d26e351bf620c36bc846a2ced55e28b70556cd400a9335c766951fc3f0c8c07dee0b4e4ce7e443bc80198f817f2fa087f3faea363aceeed87a9aea18ed0144e73dc56add8ded0afa151c00f955fe4e2b4f5a92328e7c383ebcf5af6320e35f6901bdd3566a65f98225dd0a4b40fea62d3dde6ccf2ebcf0c9c58cdb1564d7ac8f002423e8ffa35004399dd4bcf1da1951405212597dad90bdc9e9823ff9e987f5761cc0418c631495304a0a5f5d24d7571e405d8cafd948b1436babbe1e37fae24a04c06c31197b71d0cec1b3744ea14f4d9b7e7b6a6102aea38db9e6ce27c3e358f7cad5e2528e4b9016b6be5eea0702ffb1541b0c2034bba60d6d31b2d8531c1f75051e9c16075be4c031ec3fbe97138f1d27b12d02f2dffca369e647450e57cef09bfcaacefad667c98623fdf902930104b9028e39635951219e99cc3d9120225178cb3a5ec9cbac0336d32ba40640bb817a22641f62fd0160b4d7e9a4235059fd1293b384b0970d643a0cfe57bf95b5d30624a69b2de7395132b94d72f5e852271c21a89bdbf7e05b6692369b743badd33514abfa612992f190317adfbc08c09b29aa15758ec772bd1d32d5f766b31ceb0c399cc952b7ae835fb019278a66a393f7b2904a7970054b0be9c1214d01c9a967ffdee5ca6751af6da0ad0e0ca56a9ad88c378884fd300c312adb22b10d026ecc30e9831f06f5bdedf5e1a615de1657035cea9f2541254a77269bf9f089c6f8cdbca91c44e2e89954ef956247e38aa3b3393fbadccc48d29641bd57d929030655ad954fc68a6172322a6636ec789a4cca84946b1976199783c658a20db15d20450326c840acb83cf1a5dcf0e19ec4f6ddbacbea79787479d8a540f3ebfeef06af24f0c841fdfd927412d565959da727177c274c4ccea307f5c1fd4c727288a46d726c7a39c38885a7ed7d6d6462584463e96011fde6c6025459a7aeff74c2eac9b77ca690a6710bc9e275a6a127f24632dc8cb1a86362f3b8968584d7b6282b3e9d4cd054c77685286663f0e65268db5905312ee7d9d78af6c95f296b130bb87491ad531a5d127f7c6e86e72dd4d50947d3549806a6e765e369f367ad3bd52aed2e4d47bb22ecfcf6e63a4cbe3fe0751319b7fd19df3b89f128cf60716881a7ca14e986761b14b8320bec6250e443fc3828e631d08d615293367892d6edc55358c3edf8e37cb1aa159915cff06ba4ff31bc92c9b68a4ca94e8e4c688c9c21e4ec25b0f63c8e4608a57ed966941b27b4e8596cd66fe46e9e63a6b94743578b4af26812bec9c2dfbd5273025520d5dd022991ed6adf5e660932a0d26793ca13e3251ade7b67892b730a5225846ddf5c83b7f91eb50204b91eb01b798e27946f9a4bfeb63460989c6b025c8387ffadabb944acfb14e6e589f825a4e262f8abef742cefcc976d0a7556a3251b41406fa4f5c1c4fc87f93496625cf6a207cedfb4cce4119cb4cb0783737d95ff0475f712f86dc539e7c642b0dce682d65eaa100912a7def847464145e3d003d67459765d325f7ec08220b3579362f553d668953e3b96db5ca9563f9007197bf978db2779a71d1bb09bef60558131144ec38c77ce0c526424b8a7d953d33fad9e3dfa9a28ecc87696ac70c1f91b52e2a8ab5f014808559faa6b5995ed21ec1ed3ff3d033cd2aec6cd337e05cce8d52bb3e4d82eaf5f8d7f30831c63320a87e711afb15eba61e4640d1cd1718d93aeb3bf6a604e706f83a7da74b97dfd66cb68977adfaee6299c8e7eb3e45b34d8b0069b3a1d2d260ef0632d28f20e5d51e435c5f8a0e15698db869b549de749e9cfad31560170ab897c327a0ff932b84867e4ce54fdfb2fa7b0c0e68d66c0344a86f10ab90f808413dcd3409fa6a257e32f9b0af6a9ca16bfa10fffe8e2cb298c4673dd1aa9e37aa50e258b7b83077ea1062f53b2f4a28bb1a252e4598bd65420993bc50aaea159b8a2395a2690eb9df2caf1ab2bd228ee6f11deb362023bcdc41ac61315d5101ab7385d38f976014ec60388ae31be80e7ba065694d45665ebc0c769169fee80f3a51a9de3cd063e61e5d52770a3ca5e4c101f8022f589b60a6f9a5458393f7a20d7c81b3c4184369cfee828e2e17ea911f43cd4a8cc83e98081a8e67c9aec1fa11a18188f9fdbda5e4975d142218c3d7ed13169c0be5ecc100cd980ed2d11226dcb63e6ac9ed61be1035fcd1549edc91d0854ea64a2b5d8c6685170315f5ab6dfd14f540ecf17fa35842a29e96e1c028724e22a4e0fb680dfb5facc6a9c96636e38bc89a31be098c47861118fcee57408ae2a011410c5103a2d800797d1d2ffff244318874c70b15983c9000be4604df34e57336d893571386b50081b175958e342ae63fb2613d897529fc05c3832844e84a368e0de122247f5e563e339559684714585d9d481177f9dc5d515dcbf2b71afff3790c0e41f1e36571e5928e19dac32c1aba02dc0abff6606837cbed00431de96ae16542da576e48f32690692f82745fe75f3de58e3d4c7533fa62d3e838c4b7e5e8bf39eba877d275486c4e0661f602889d9ed75fa9d05a89f8aa12236344aba60efe65e556a02d5f243f66261d9ee10515e5e34c4901f8c314adac7117ada25c9bbe692cbbc1b0d40baa380dcd34170790706f3181bd1b3d030118f65ef1b9ac6309807cbd1425e6cad1ee00d96190c3c5d7c88b0ed99bc634284bb2d70df90f24d35dab7e09bdbe7755976fb7f67f18d88020712b468eee8c3afc9813f9767ed726291e53e25d00a2cb7474a5aec30db5d1feec2c232b7240e447a7e6cb5ad0e745e65cb5f8c901a9a814e291fdfbc1f943db697fcf891e8f23a4065bd15fac4d3b9a90bb7272db4a2965ade28ca847ac5368fd9c3c9e5804e0d989111ac7339d97a6c818dc47386188b0e0b626022611730657c1a84453e134480be7270fbb250dcdac70c6e8d4c708c5ac801807540d56438f4e5154f1e527fd32a1c7f495f7d0b410fa4f87fec76ae06ae961be1d5babd4fe9ba76f70fd898bb5ffc7ad4ed52619d1603166d4e0ae3cb0c5f28818fe4adbb66b2f69f59b649160b863dfd7276d94eebc373e2d850357280eb868d68445d73d35b0b344e6f726dd90cae5e21a284e128731dfe587f51b12115868c9e4a5cc3ac215aadc92c91bd42bfed47bc93a56a705b905169c990fad22348a62dd58af4a753a9592328e75ab3a3a33db28326daf6987d0c6b9384e34f06bdc3441c08fc387572b8b4fa3cc9f144629dae4bef94e6db6030bec687dc17dd0e07b938cf57d32d0f36431d66036097f702e0461265d384450c54b5bd8e06862f1a92596e010ff1b1908534b226155215ae9eb4877f5edb2497ce2a6482d6bf5ff2907447370123ea30ec773373b855b3a9f9be0e02dd3c371dc9bc0900a01606016e30ebdf63e04453d867b5f61007003caf5cc642bec21312a57da505916087cf4597ea3c23bb666c208bd53fa70261aae5b06bfdd6a7d268a27c878700e233965518b3b70c8ed9cbf9856bbda25fdd58828b4870600b2335031c1301cadc6755e08109486253b731310bc80e7d35d0f9e55857849b51270d4b0e846f7c6187576de68e0d3478def8530a80bf90cbf7350762bce264e143b5fd1a479244b870d5f01bd9a621170e992997f0e7c00519ae04e2468b5cb5108c4288fe1d71ce21af5fc83cdced56b855043b2ffc8535c865f0a86b2761d491f702ccd3aa41fc2d9cc5a6191bd86e2a80042ee0adf79987654078f38ede3acd507584383c02f99386b42bfba10ed14339cc50e1007bac9f9a523c9519d2a958755a8239a4b16c25bd31ad453f1bcfff61bb42af2ca84afaefcbb79873a0aed977eda4f442f82d0c04de4643973afb0eb8de34802dbd8eddf1e67df254a93cab4b41a459796b3df3829e60077ae42becd5b4d7f61f162d8e758d034e215f2a08181afd7bcf30bacad24bdb53d20691797a5f32ff8618e16866e426e511093c6810b3e8bcccf6b0c128b9e23dc7f99cbcd090b0e9aaa85a08e876dc3152e9583c86c90cea0c4529bf2f3e7b1e295a17d365e8b6ca17af8376b9210f7098280c787a68533a2f1db9532894afe09fee697bd4de1cebc04042b3b133e9f6bb394292d1b5fbb397e1da13b48008eb0116f70f04d139e10c98e3359a054a4bdffe34f1b7999ca8274779a5a5a2f01cc60fa700e27ec26cfcf34758b0a1b71072043bf49f9e28293859a2128b30f35e26bc370bae95cd428cd40efcd86e3abfac0199240736dbf8c2d00eaf0e9b979e0233914e0225db470911c2612ca9f955daf56f7486a202c01de5f67e9a0f54a30079f3c5f05610a94227ce89dc1905514bc84b2a6dc2ca488c5a7d9c2bc36b6a704b57158e3d43f1ea55da49eb3cdb0c0567cf0802c865895bf7f4fcf3b10e32fae53fdbe64db435daa68e8bb8645170f5d7850304ab9fed1a2e36170a536b9e44941ac102045d350bc69d80285788c3d807bb6aedf0547d427b9a29457b4634911f3a89ca9ea2186bf29b32ddc04d5d1cc2a20fe4bfe591551aae6d0e4779b3c186ead95b6d012d63e269e840b42b04ff9e2ce8921da9021efd855b6a6fb67c2db5e437721b1cd9e555c6d01569effd82c72a025ad4cf88da147e333008a8f6a1cd12ef98137afdd8ed3b1bd6e1a5a0e1afe113769a76d9c7669449b07e565ccc627287466252048f2683981557cd1fd7a6353049b88e10259d141a38b8a3c2998f3fec37da6893b29f974dcd48ad866df5cef3d4192ee2d13f280c448c12c2c4f538d68079537abecd578ef7c034bb3e5fa92b89416cc75e655d90c4ca3a0ab7acbb930962f1b3dc11b52751b42cd2e09f1dd25fe8662cb7130cf1be4888c78c3f5c6573a5abf4381381507ff014abe4f75000a5523f24f8cf14a41d593f8f2ea3c56759534ed9631bb1fa8d815e78d374a5650489542ff6565f0d04dcc0f4f6640dcc38e1f9274cb6a2c87d023cb6a68560f212e33180249b1db3838388924aeb5b475d2d463705a7b936fd0bfae38f5f39203286699bb2f923db4c88b2f8021552a2fb6cf1fe0e6c7db76f4610ac576c96bea583c5de2d75e1b5512c0d6fb4098ff72f4d84b4ad9c689ef14d5e43d02fd8537e3b102ac65377471d078e30f0ac8e8d6684854f2e3413b7883bfe5be74618db4f34d708cd737077b8df3551d6ae40fba1bcea47f333d08e2e8fd2fefe8e5af51bbc8c9683d4361061af2339688768ba981ea261f21736558a3e3d906bcea98a85c12c518de2e4454de6507c5b48bd8660e750d7b2ddd3c64605b40e91f8537d8debbc05873f007835680453f8b04d9bbc2f1f2d037e96f4a92ece006619c504faca2fca284e964e8560e714574508f7d62fb5fa315b1bec74efdaff6a092ecaf43f35eb17c1259835932afdfaf4716f39d528a100c36730da26707a181967edbc9e0f40b2ee5d082482c09890462e0ee0a67308a8c479e16d9d7347dd763d80ccac538738e070cb3dafe84e5e7681c1e6a0dc16393150b8ec560936dd611b96958db924759ade496c1e87089b0191e141569ad1bd2e1f80075459d04fddbf508d9be09b56a995598cc775466287b94e765f7caf4a4f124ee192d6ccf47f8446bd56f2731f7aafbbf2b15ed3aea85b8b16361a38f0c1608e556740d4d5d4343b77586d77e64d773dc04be7a3cf507a6550b7de9656333ed8537189c7117928e195d1f87b72236032256ec205e3f08baca5ff4bec2126f0b95d30532189d2220f7b0b68a329f9161d2d8c923e66982ca319ab9430aa2bb086cfe586053713f800f5833e34d4fcf21f13c09ef03f3bba566f6c41d5790cb0cc74d1417ab6a4ebed2144f5a58ea07f211ca2a758d1351f8bce42449a05aa7d0d30ef6b0b4604703bce56fea3487cabb43841d7c325b9a8638f8ddcb2fcf86e5b6542e2440a1c40332720285af22dc913a7300ef81d1d1749bac8c4bdcdbaf4fb4785eb84ade7e77cfd5b8cc511845c56bfb695bbd88cec77508a63444cf6a2eea39a6a432525fc63b71be7a720e659cad03a14f19c8c5e2358a7373248f3f2fae29c0c6f52d22c72b03e092666723b9675a11e8d8c0a7efef111ab573f76a40bb37775e17fcd20f9b4a6659c14021f2da64e9f16c17fd4bc01fc02db516f2b479682f4e0df1f5a1cdb5526441a8f21d147105a881a06331b905efa71eca0991cd4606331578c5cf9c18f7195297800cef10ea39230544c289528f1c8ed7488eea33927dac0ce9c69bf410ec8bf3bfe56d1bf59e5b9fbd18176112cc0fc6aef0f831eca400941dfafab09411929cbfe41eb2820145bf2e92ac5d06c536809299a90ccedb27b72a0cf5236b3407e455a8be0faedad7912f6cd76f8606395d8e4c3e546a9989e000b5258278edeea8dc5fba0200192cddc5bad6527ebab33cfdbca4e1ac90dbd31ed9dbcdc122e33085090d5b03b1eec212fff5309235fde700acfdb6f2c03f061d758d3d39f898d477697648db1b72cf9b0835d90283545237adefa48354713f64bde8c900ad872f61256409c3ca7d299569fc10f7e1d3bca043d7fe86cfb8413e849f6c8a928bd321d7d32cec1534c6b760d8dd6cea358b290a0d504a5eecd4fb656bb1b051be6960ec1856f696bb37d9f9da858b7da481cdf49296219bc77c34e0762b79b23040d0ac46be24bfe0aa4b9e3090c2bc46a5f5cd164c3e8c03a7aca57b0c365a11ab22ace79f834719fa77f4656006d8cc5ea782105fed3c062a9eae390691883b310cb696a2d918316fc584c56e809ea99b6953beb2dd24be155770f42d3539a6f5c781b2ff17fe051f8a626baf17fc184b1f354fd521ebe10836220c08a8c0502f3e6007cc707aaede7effda0e89571f5c272645c947334919289782157f5e34b128717a4dde1de26faa20a4566c1811df8b5674d23500b61c8a64e74d9153c7de836dd57074a834dd36670ca208876839518c9b264f445b223ed993299035f9772146168a6aa30265e16caecb33ce945e4fdedde21c99df3b82a345de7dc4bef00bc79e03fe3c95ce99b6a2dee3ca6307e3c81b27eca2842ad25a89b6c6c2e6f51504945d38787d6f5b1f6c0afcd5aad6ee27e3a23ad414afe7b8ebb9196ecafb7ece68c4e93457b95d16f5892bd2f0c7ec9e46e8e0552938e249f769e828cdb5110450075c4ac78c57c50bac5936ae2c4c22d850d39d6a22cd0e681fe448d20444f659c72cbe059a037f80e585384147227b16c0bdfa9540aa67201e62e0e800f9ad95369bfbc325d383be7b47edba59b7c9ff9f2a1219fcd50e92e006835883a1eab42da45e2e434727026710c0c4c932736868c9381de7b55132b3e6caa7046c9ff57d60c502b98debd9001f4b782a42b1491d9634eac47a966cdf1ba0cdc5bbe342459b218ff4e18ab821190681906e20f1b73a00d85bd10864ff0adae55eaee60c9f530ecff2d4f2728c70836c161a3b66de0ee4e649231275315de5c4913c4d2a4417144e58a57d6178e8a9cfc76ac1aac9d7a9c04219ede172e119a3d8a730d95b8c338dbf7dac5809a097bfc8ee6fc5b90995a4ac7fbcb6e47aa2421a732476e49d4f922ae9aed6243432a1ccdfa22e6f0c491a5ad346a426a821e52675515027f318c5b12c7f02285748969a8eb05fb493e81c37338f04b67f1824ca4ce84dc8b45785b71af69c48b69584b231052d257b91406d005e7ae5715d8d89bfb43cc3ebf275ded8fce0e07056b84100b9fef82761ebbf5eac5ad7c38e4696365e81f85dd0e48439432d42465e6ceb34fc00ff2db1ef5afe2d48c38f33410e6222715f271a35167da3574e5358454db368dbe893600347db8c6b820a41daad9c17dd2925f1be7be066171dcca7c525300b2d8019c4eed36e4b5ed178877478c8472971dfd728ca821694a670f56619b87d1e1107cf3f1fc83f7c05b2f4f9c88add54326db88ed8a3c507cc0ea6b32b684991c1863641b2b3fdca22d40deb4b58ffcd94b45bc032c425fff431fc138692350846651b1176dfd6a6eafbed0763167359fea0ee00eb923d9f0bf7dccade80419a694005217102b50e325268303ff5410fe0c6b5bdb7a2434069fda3d3f25a10c4098234ec81a0eb05f1c66f2a35377fbc299e733b38871190369a5b9e6103e545873d8f3e4aa84e8d15c86f62cb4ea7405485776f1d20459d5ff6991d5e064ae56353d5940966caeb17caf80447840c0b14f04cafbcb9a85e583d10c16c4e35e507a55342a9d7c2ae0f5e265e4c45830ff03c0da32082b703ee282936d428845b7cfeedb2b04c6557e40610b85c4ec8bdfc74f18aaed96e9cb3b13c441874565786725e68b6fff2ed56ef989faaa4727d4d906e00c032680c98660cf9c1603b3e5a9aa62345a965d1de46c73b8eb6af13ea6c4b125e4a8f370f3f36cf72a5f6e998b7b36e531d8f39d75df529c14489a9068c720a3215e3d3d822c2b478b53ed6386a9440f146b575142add24d253031770f02869a6ed2c66ac208543b86eef977a87a5fb905baf4cd38b981718fe0b20b8b98c6371c8d7596e9889ee1ca93f0182915bf96727979b791bffd1540c7711dbafc5db0ca5a4ad4f2812082c2c14ce55c8687e883c83a2de4e7be9de0d2a555b5bbe728fa5e009a7aa94eb1600fc044006d99406eaa8dd5f8e212d6c7cc0ffba820eeec0757374840138e8189fdd1f7d7bd5d8fba5cd5fad727ad282d437295d96fcd0d626425fa55ebcf28e197fccc04a841e0f5d1a6c8c5f1c6022adf1818089a20b054b7c2f1cf46b6cb562c87c75ebfd37c57795a503642454f3d4d7847b8de7880c940bc3e17286342f98f24ed6eaeb72b2643dc8fd427d12284cb844d623ec64f8368ac3f031833a0d210059f9e230a564c8b65d82d8ddd6dd4b555cc202f3b950dc13eea639c2d8c08df3f4086e2a34f763795fab07b552d06bb229e0aecefb1444c37f99054d5f6f021d718a933ee984d8cac981174c7644d27226b955929330dc3dc9b10705e92bc3421dcdc404b841824c23b8c6501917e52996ae9fd5461e0a76d30a1e9d7b57102172211c1fb93084c732c37ea15f1f7015ad1ebb829bb43686466b8dbb9bde601dec95cc0ed918b8539d3b46ea6c8b106c437779499f4001b09fc0b2b7eb5cd2d3f06e8a7f830a1960d0199149ebc8849391233da272093d4ce4ef3ab8f6561d6ac3943ea07eec4a5ffa03a7f7f3bb034ffac5f19b8af674ac9b93740b10a7854de5c2611f4ed10ee5246b8011e13b4af232a0af0dfeda2283872b6d8e4e2f881f784ef660c2def1463a87ae7a44324564679c78b692e45b51d247dd55ddb7fb24754f9d37558d956a3b6616872b96741ba7cf67278a71b6c84b825ebd755f61c214861d5082f5c4d1a2e2cc685efdb75be8856b811f570ea3c27579bad3162b6d0ba796b6ce0fd6c12c96d81f23a9a460c196a6a96954b605d7311eb3c5a8f6fda47870d30cb139dabf5a174b372f4e48ad5cbe127fcf854c17901dac621dbc088eb113dde7df9de6b8ed604e5a996a4fd2f1ad5f93a9559ca912eeeeae1d146be64bee3980043fd0b41f809ff45c9f9f7e13c063cb31782024bc7ea545a13de45a52530d1cf1665c8073352614f915c14a7e51049013b93409a93a8ba343f9cb6f6b93727d8df19e9d920c6a94edba94f1119a5718b698d107709fb6981ffa6d2567e94eedaa45f0a3a7cb636e306ad48a9eb9c470da7914408ea4dfa4f680e88ea10d6f35d875a305087054a307212553174edcb434fcbfc7a3f8dadc84c7088ec535355d9590b4ad32fcca6456487e0a73d6525f3586147b7ab31d86b45bdb78598a9e72536eb5a51cd734e5b5d186a23cd12778a9e4a2f9a5e89b3864ef47962cc2d5de4982bb3ac1a46d13507ae16c138ae680b711ef1ba5cf3eadc8fb7c47c75c207a073c941a7160e7ea8822d90d1abc96ecdc330fdd681fdd8fd151064d9b3fdd46027ffced07b70d32bc753e0f6cf369e4479abced79f3d329e9da0583350abc0eb0f57ebe9b59ad254156944f4a4b4b459f924de601a9a5040d8d31cfdc20e522ec557f0d7fb4f0c123ef841eb51bd10576cf63996c1cb3f88affcf054191dfd7f3ed176b8bbeb96d923a194633272f576e6610a831d277f39ea0fe0aca555b5d76f5c6d9e1beac1fdf064200225d16794ab3fb1b5b51067a179b7037ebf6137efb1301cbc6563bee24a2f2b8abff0ec29bfb631989a30068e148af8b1124f1ae261887aca94615ceb0ae2d228259cbfffadb38918e2c17618b8590426075ce6325212a7452fbae2cf1d797486d87828ca418b42781e56458507e53250b7a6666134c6c05f499b502187043cec4eb0ada0bebd1cdb80536362332d0222252ac5ee1acc2eb870ca1aecaaa6ab8b25e0b67dee437e5118520c8466cd247d369d517ed9b8463e4bc9bfc7ea9338fc4e6129c428a1454ee3cddd4b88e2de82a547187273efee81e655f24b36331d480b99c6ecdf9031407f01c5dfd738849441766ac0034125116189bec65bd9b2b727ab7f77c9a6c785ba3a4c48dfd8b2680d63dc529cefb1e3b1e5abfa799ef31327d48c1203f4977022947b5c6303cb91092cdcdd6b41d769d0d8088b6044f57e45759b33a0cbd90207f48dddbeb718952cf31603f6b3a9624806f47fc046386864541dc7da540aba45b84fb4eb5c10cb4ce3b19aaf0f378042e8fa08131860be7e7d0d71d4e13d913cd6ca95420fb17a597fb49250227ec792deb59c5fde4efc1252b35a40035b3cb9e423846cfb9aa2b82d47e43259d3e921198d9eeae9986cab2a429c22b288c21dff6e0d978412826878fed4cf137510eebd73e744f9b67cbbe98144c8416d003591b465d4e9a1abeddbb0fbfb4965fd6cfd7d99b5050774911e8d139cdd5482acad6b4dbc879088cfde14883630296aeb456abddf10a2ecb3ce4b9069f67792fa53ed59e9212d38c799592a7cd05705dbec76e3c628ed7ecdab1022d5a98e7f14c28c86e51f82ed973038974802fd35fdfa8f47f4970ceb0475c1cbb4fdb3cfe6d6fec62d459d862f4387db4f9f7cbdc6ade4fedd1a819c432111dd9e724c3864a979a4a98fbc5af6ec4c3f393025f0fa3c8416b752865d663334fc5950daa0fd89fc2cd894efdde69da1393b105991fb164981f9f596a44200b2ff47f1d8522df444ce90988f1ced165634feadf9330dcca647179238ae19dd36ff858cac00761b9b36390b4f15ca91e1f28321b5f6050fb87c1a23d059699e7af964d85dfa017ebcbf1a6585e0f4ff0783e75c318efc0bda10184d12e9416f7a08c43786fe310e6ab0b61db40c7b27faa8e31aa11d8c536220cf4625d1dcc5685dc5bec5f906932cf57c2fba49cb18ab5448eddfd7ff9f2309058be538f1e2d7fab31bf4e9b9d800b0b77beb6a3911f87d5ac92418ec9942d66b49f3943656bbecf566177e9885d5b68f6550d451a4393336ac399b592945fcd3a7d6987608d9acfb85fd780e2e76f9f74ba9c54cd099108cfc497397adc4094211ab5b32b01980b66f1b50ac1af2786af58695c641b8a5eb2ae299c9c988257e32e98b186b2435d3dbee47d11801d2fbb99041e027a096f5e93c5b43d75c8f1dc55359675f7f8c8b9f98105ffdfeb1ea521d0c49d6e1a65e9ed6905849c98d0263c028a4373195dcda6e5b3f3c810055e0e44dbb4edfbfcfbe9537ca366bf2c210a81e443f83127d42a6fb44c013ca446768135b28d540c33ae5d2884c9023431c5d6885153a8dfa4e3853faa983f33c8b5f27f8330037915b445d1a1f4a21da8fce27774c2e0756aae1e75cddfeba124270838cf8773589f3706759fe7978a0389e298e85099776827309b32a2567e1e0841b0a42bec2691ef4d6afba4e3e2e792a938011f62fc05e295eb098b733da86d2f060b55c0689baaec22cefe3e1decec9fdd20d0ea0a4067e366faea11173e093587c326daf43523b8b2993191c4c07eb76bfd8987e73490730777b46f73857d6e969f6eae76f552e0684eb840c4f29345fa8d8a8c2a26f9d444b2491a15e2ef279f1130b9a5f5d10a51303478331d0eba92fdc9c5faa1a06dbc88878b9fe42986e88217ba457619218748b6fefca666b85433d11c814256a0741add139ad56c82ea77c4663d6ad833dd614df1ed234ec9b0bd28d723c8288b6e952d329e8ef2ea90747ce345b5ed6690e73d7447608d853a4ca5891678118521f2268e0a4c42db402ec3e1638324370770261e680cba2313f4ebb30611434baa2859ba9453a92cb9f0dd6793a13efd974d9a116f5332b2116709dea211b81cfa6f102cfcfcd4e49079d801aaee44536caabb14bd2bc7ceb9e5c0b18a533e88c96398158687d7ae936edadb55811bc369bb4f43f280a378317d8a1449394642a3389d03ac503e3b4a9b55acc9e2e4fe267a29ad27280edfeb32b6be43af43e9f7416c1e68231768120f207ee9c20c6c7bc20304a0161b9ccbf919b73dbaf036ef902980105b9029339a7fe1fc2b323a86d7041426e06823f1f46b23477d2671bccaeff25b8b6f0b1f7c4cda4219442ba9b9d8ffaf0d0729632d571672ded4fedfb975830ef737d1c9b454a9433716be77ceef0f4fc5159ac03ee51f6499d960877901611e88030dd6bcf8fd91daa9199230ca1c7fb8c356986e851e75ea58b694d26acbeaa55576bdb24b482a618d1c85f4b2c5fd111a57c4e67d060114a718044e250648d2372fab29dd93285fbe64dc75fc1a8be2028544f3f9b8d11261c81ea39ee7a789ee34c522efce714da43c0e5dafb837edc23178c16129cd1b2f814f63f8f67308b537b88720c9be034fa56cebe45123cbaf38d3dfbd6df4c4e6544fe9def5361aaca5ddb60b9af40e75ed7588990d5749873dd9c208b95d3617d2db517f1d344b129fbbbd95723898fc6196196af715a235af0c8f8eaa7cbf0ef93da190b783709da76b3c294b3938b3bb6798bed175670ac22231c1212573c75744ad0ad225d98aec77739fdfa25ba863f19a4b424b023a888f611c186424489e018f9d6eeb3e488308d6e296b542235e475939d3528dc2ea4e9c4374c535723e63211ca7e36d88a3f248e2ecfb1760c4d429d65fed1d877976f296920f2e357d1fc539eede15bad7e636c7c1600a597d983b69d2e0d0b2967899ed45b6ceb9126909449d51aef8ebdf521541a33f1af3849bbaaeeb74722047798e436b333a01cb7f1ffc2ddaf078ea114f7effebb3e35774af8373c76310c533ee576d49fece0b92d895b4a846dca29ac6cd20ef1e1761a88ea2438bb462f21b4859c8c9cbde7261577bc786152af8bf3072f7b75df056f6855b601f6e9fa691c19ce9585f29d82dd2dd1160934b4d1de693553b69f70b70e1252ffe5450f990d234ec4338b6aa44ed3fedb93115cb7f537d748a19ed4a27dc757685b2ffddf2c80f91eb50205b91eb08f65c8c4116e632bcb9f798d393707e6c966da9349b1a85a438a11370f2bec72c566800de53e9bb5beb4f86d8df60a1b366c7effc6abfcd6217847138abb6a31c2e73032cb84c05e64825c1897c3c0b2bf0f3c84a24f1173d2d3b73c6bcb36a4591da9d1f32ad7032b15572c63b2a267c71cdd72d0f6c3c4e86e16399166c47583cf69c8df73f1d562ed3c038b81a936cad374b7ff068f37f6404a1f2964fe54aeaede2dabdfd713144c7ac039b4fff12be3b08e9748d48ea36b1796e5d7b5c126b51cf55c2c6dc6acbcfa67c4d7fa5b08afac99230aba929f5bcbe1e498b182a6bf8f91e192dff2400b0d48c2bbe37103b7e8e8cf4f960c60f8033fa8bd6f5e6a1175c24470925408c639992cb674968ff80e0dbd8d0ae5d236aad6f2f5abdab8d2d5a7ebdf26162347655bde70d3bc0f9c3c14812f5cb8bff9e62f60aa5a6f936feb9109a383028f3facf0fc3834201e93c921f5c70e45ae095fd8abe4762ad7da87723a8742f78d8ddaeb2ca41b6e655b48c1ac91ef6c396bb5d1088e57afdfb0a7e87a296b47eadcde9acaf6030c352eb1614433fd99de367e51bcf699af8631089d6cb64f86aafdfa8b0bf1ed98942d40b627e04ec938e5921fb6daba80fd00153ed99d46ca3a6c672f31950f29fa30a81fb152b9c8875fa2986cb9a3cd8ddb1b6cc568f9508088d707789ff314911748bc7ab694cfb773d999aa7049263b12478f54eb7b2a061d18d4a2d7ee7beb67c69e6befe5234c911435097f5ea601ceb8ad27e77084f175ef86450c3f654b3d3e13ee7da3c45c8d67b92d41eb664d711eb9e2b02cc355dd27526b0caa2ef6ca7288a543075bfda265e12cb1a12f42c671c641ecdb47d0cf7c0095bff0df3cd01684550f93dc7cbb74323f26490ca80d510d9298723b97e5a34d98f853ab79d99e15932976c6c61b079af682befed7edddc909f9318d2a278d3355e1f5c25f0776b17308e86d5c21c7f6995386358455dcec235ef1076de519a36a9a5f25b18403648b2d794b7834b2be75b590d9fe50be5f5343d01d60bf4ecbe691b073f0929a6d7f9734faac1383f045ad1a6b0121d0966bf94fe8cf98f5a22dce2db0d87ddb41e1114bcc2ea3d261f02d76b4314ae5f10c877eb7d5f8d09bdc6e8a881eca868727edb92d60c34cba8dd9cd6e640855193bd323658b4ea6af54e8a6c7a482704aada1a598bf208ee02e69e4122212d1a93300c2757df1fffc1f589186a302bf0475a961ee4515d69e5877a2c989d68915d1fd1ea8e12bda2d68521ad6a6991f13b8773827ba08bcea146fed2b92d7c900f0543c50e6c9944d7197ceaea91335041d012b527ea7a756d36d7f28e07a416d4eff410034f9c37753ff9b459261c4898fce8a29db983f829f3be6792e1fa04480b39534e1a32369c107d85df1d055ddbc75eebc92df61123ac03d7f9c161c230a29ef7a453202d7940915988a9cba0251247c64ec343e08641e0f26995e21df91ada960c5822b62df46996568768186eea2e05bf86c8c533ebe6bb1b92922307f1201aab0a0fe5e8aaa7b2594d029f447095f9e988778107eba600e5cf41bc1c39d8c2967e1a8fbe6167b9cb9568aaa82726b3edb2b0f409e251701d897e76cf4f26b5e4fce5586a53cece801719f178665e614e95ffd75d66688f8fff7de0909c33a1f8870902d0766fb0ebd2084f06e4446e596fca8a8e9f59f9fda34244a016455589eb14e4b1b8036c586b4fcc5ec312dd44c768a00427dba5a5409505bad71046454f352fba01c59d66a80884c13c0601ab8ab7641348bacc962f207df3cc242a5d1f682c5a9664ba02134e93f59ec7bd928cdf32f96dd5e2efa3d7265bda764db3ede3fae9b4e5123c20ec4297b6dfdeafe166688935f0dacce40e61219a352c2b3f156a292b57b150e0df46c75be88372006c1aa093642ae7b9380729f1d1255a55bd6cc10a4eb7826ddc3c9173ae9794e314c34831ac2fe9987b34999a6eba3fcb4e759a07fedd2d1769a8dd389b156ccc6dc117c829901a9f9d5afed173173ca90c931fd862e3b37cfa94065757090becdb0e3abb624d633628469e463719057347552997e50010fe9912aa5909d81cb31c119bc906fd946ad20485e1a38fff8d3d599fe4cd9d95386a1462a5e02ad1f8d882d5737e420bba22b84d0c650807dbb351a4151fa9d5e522680e8b3668acd496b0c55aebae7a58cc65d7e1fb23a7ebe60402e6307003f143ff519c2ecc1cacc603d397a802993d3ebdde325bc96591f5da446c4601d7fc4a7082ce49cb2142e412fff1a4552b731f505b550bce8cf9f6d7f30f626af1f657082863b126f81235af6eeea6a01b41e55f9a3f572a1ab80fd31cbd8a76bdb893c2a35356bdb38d09327d22c1de4075f3314293cd578ce007149328057c9d12a2eea5e2d27794eff408043b538009421d54cc2a1b869ae5273b816559cd16f642c9286dc970ed05091e368dc46a62981bcbcb2a5565df31cb723837eb61b0a484ded1672eb26b70f31d22bf36d1ca5f514fd9e6a481f80d7b5886e7689b07ca40bb503b99b3d61a503b0897027043c26a73c489e981262b3a800626b38a2d0be209e5eb609d3f916a9b0456182b1513145ab1fe12a308b4acf123cf1e747006a3fd0afc5c29804d44096d53640ce4973a9a88580d2a706db3c9ddaad851ad22aadcd14f5dfa45c2df02f7567bc131b4b9abf2ef024a2a3f1370c9245c4e06d8c6fe48ce6e341f2373ad532f6fd5924ec73f05d0f09c871ad347c6eb270f4bc9cc00fd63216b3f13a63f051152c680496c3c10750f65e2f7f5f80f6623b6d19b7982a356639e591812644983e4b9f41a8cda2dd13c159a9babed711a3b0b83219af6920bdd28fcf256aee83c5d78e32c8d978398cd11a161c7644189f2ad4bfe00fd7cfb0006eeeba78af2ed89c764c9af46c9e624a091f9f95a1354ad9b86195a5d8d7f14d238563dd221c473becee0a49e569fb9556a2342e6348cc9555fdbc02c9ff8d28e6df2b32e6ab2d0a8b02205913a6267a707b252e22781d83cbfe9702725128f68a1b10c8966b9989d8e6c8be409ba4828335cb4eedabae58dfc07f23997e08f4a35fb50fe876eacd800ef40ca0b395ddd6c7cc0f38ff7ffbef2ce15fd78ea8a9446e1423610093e8bef0c6c2a0bdc0ccdb9bf80f163b4040983adc776331377d401ca10e4a4140d702194fdb199cdb477c5e58c160c14808ac35ed1457d78a7ad874394775d7cd2c90a04dfc23abe57d896327730fbd55d348e9135a7a8f90a9b146df936a926ac26615cec9859f9b1bc58a9fe0cec4b6a5dcb538345c8cadfe65fe0284287f0ce2b1b664f14fc72410b9f6547fc39fc1e1f052bcad689901cf16d9a0ddfa06a4a3534b08e3c654091c19bf4aaa9d8649d8a50052f2ef4d54233b36ec1a52f61766b7cf47f674cfcb64f80da39ea03ed616804b20ba446aed29f2daca8f8f3ac61a1d1b32641f944f7f02416d831d123bc01ad6169a8357d1ba90868c98abba6d503d28a58920b2ba0b8da8ecdb5c37c44155bef1483f221801c27be0f2793aa7b26c5cf879cca1059e46a580554819ee22aa272ed01e98bd7d28fb7d5779749d53c60aee7036a47655cc9ea3b238aea7ba0a454feb6c2aea103b793dfa7796234ce102522d366c307d38df59c5ce2bb3da5ac7abaa3f9785ded7c4cb5f2c667b1865eac114399217b2a41e8b8b73a56778b27b5e10350498723ba11f343cf53e583f96bd71c11345ccbb1d02c07374ed6ef5f06b8b2dc059c2c3d0e7a61c544153402332a11352feffb5d0bf10f8b906c08b11d7f3a12cffbf9100da4c77e26b99fdbe5bd89db5bca904763e7d45dae95aee7db1e087bb120c2e4cc90bac5f61a3709d5a7691a7a90dd4ead6b27faebc2818df9b723c60e1e5855bf9277603b54d40f6b4bfd125814a6c85c29cac6717bc135adc431aef4763269689299dea49359be0ed48048a883468c1683a8774527e0e124b37622092f17cface3568619f0bf606a7c00c1937659ce326f728f846b9edf36f6aadf0f20def2b0da330d97185792dfc686e735327d060c047352594c91a82bd9d779c6a3eeaeb7b2b48d723573077800d44cd512fc72c77f543e7e9f48378ba145c4d041bed5a17b8893659d6316599cb7554f1ce6eb5cf691f42b1b08cbcd8b2a02dcf3f94e868fd502dff16305adae71c24753f9a345f847b72fcc5d60a2f9b84ea9b20b05f6f68fc5991c8628054fbd09c4ef4c8a9ef4db6aa886ce5f08cb3c137eb9c3dd07dc990aa00029a4a357cfde515ef8715f4939e67bb6ece25dfc876335aae930f3fdadca8bec17aed2acf27190477bc9886f75caa95c058c185b371f7fe4af2b8e8f77bd45fbf942d76969452f406c06e1ac591e799beca0a46603973365532da7550da46d50e66897de586a8318411448092447c724c0bf8eedefa149ce68747a34a0ae9b4d90a4882a03a33fa31b8735d2ea2bc659f8bcdc706bcd5e98ae1648554f632a353d7e19bdc8cd3edcb9e44d0d0632259951eefc8673421715415152347555fc7ef41585ddcfa989a68d43a6ed9a97c18def8c30ea10e4c109002e5e04a04b1d6e7c809b09f3d9a3b73dd45ee1cd01c90236f8a6e53b148d29138cd92345512f5b17d73b398be12c1b7e52ce8ee7a90c27aed2f654ef01fedd580738a4f01aea3661c66f64c9cf5b1c4418f62d11fb00b741b65a27778fa5fc04791a0cc8df9346b572fa3030dd26a302bda0c2c18aca9013f75577a827784fce1724618ffdbe69bf7a16068ea7444457fb96a47ed226653cd9785d62be2cef5bb39facbffcdd4fe72a8de6d0918265faa46f82059f8d417b921393da13032796021b285c03835dff27eed7355d7d9c53fab04a2de5e49502d49f83826421b99dca97600d6d82bb333253195bdcc2dce7228a55dea8bba258e363b0f86cc2653a66a3ef803aab0adf06be1a9bf96853f8a5356c42687b898af30efe9333037e963f48ffa5a3bf612718a46dc810e7ab794b6c725f04c3994542a3c4b4830466b224e1f5e589bd96fd8b40aa1800b64488ffc92cd030d03fb50ddc172557fc9af8fb21e0c792b70b7d11d39426eda8415ba6c4b8ac9bc860983c156e28eac1f015471b94aa25cef6d5843d189bcbc3611bc7fe3c6078c95cc74c10b803fd9686786b953c6c5e43dae287820115dbcc7e70e48f56ed457e0b60569daa049908b64d9a8fb0a0ac6b84bc4116d8e02e06f1394c384c9f58914a01a3605713b3eefec478f5dc036968278b0fb2d4decead31ecb5dc1701d44e978075245da59a831fbadce7a62ec039c6a017ec30e0c9f9f8d9169f8f647cd312ed020e93961cb83fcb122db98e23a6a26001d2d00c40b78a35d8facecc52c3621d9475b783ac07455015241f7cbde1fff601f9d73235d0a66d19ca9fc005988f4a4678a2fc9b23d348f57cc83e383ac7a6326e57a25bd4385ed9357ef3c4ef084f76e33e1231579155dd1eb19663912ac594e7c3d224e8d5e596810cd98fa06e80c1653a22b588bd4e8286864182c999898e8e1ab0307f6b9878537e39835134a442e56036d22c226b3368cb034ffb04f9fead440f70db5d24269cc7065d388b7306335f51b97b5a2acd9c5bd74cc2659521a9e06e31d6cc4455f8f53a77cf574aa2b90da47922f23ca7a84212a529805adc5182ca5307a4ccd5806f99dd9b10eccdd72bc9e636c837977717b5ff3fd7a3508d0812254fd2fac89c36daa92330fcdb4a388f57ce3798db6addaaf8f6c8fbf445aa7a5d23265131e6fede7f29d4669d8a29d73f1c9ab00f918d93489acc89e586f9b0b693417f393987953cb5eac94b3baffc52183c715be04fcd282a952b4cac72b1aa4cab65cb32cd2ab979c54655d4f3d9b5fc5b296dbcfc367ac69e92ad8ffc1f0604fbda4743b69c1b12e4006f8494bfab52305a419ea3e7d2cbe407468918346cb27c580539fcae946fe0e145ee14feb429d455b9a82d8611a59512919395ec68783f9979ad5d24151a976da157729f45968d7e7851956e82b8abd16749d805dc3ff9f93e5388cccb3d2e4e6671377b94c14ca6cae5c04caff7ab5406c9e695572f09885e8dbb8503ce3972f5077e11d5e396726434b9c90bb6523b1db29abb25d3fd89d88e9dcfc592417d4440b36a19dd8590e09ec943b439394e6e666c62cae0013a9cac2b5d71f78ba3b7fbffeeb572c8f1d1a4744e28a2bfad9c82dd554390bc262919ade5bb4e9bd61ee54c3fb88be8669d24d65a99cfc91fde793b17ee934079a2d2ae823847c2cfc9b56b030f68bae6d877454bcd7960b70d871d971ed91eec1714518609ff3382e50a5f612e31439ec36c11aacedaf486f473e85b77b9c22a5eb6b12b99df28a5b531423a17459e94dceef7a1fd54c87635996d8ee23ee56e3260e5a63ac4d65355c70f85d2c5b4685d505751a6bc200451365c07dac551225cc570e7f73082a641d96411f3044ff1b386f639705f0e35d082e16fa68af67a5ddf66eb4f388fd9a15024331bedead726c9e6083c81ce4a93523f67cd6e32d2a0c3724c6ff2bdbadaec7a736979fcc051cf06ca8c7887b73ca0e393c5af4fe60072cc48c6c51eac0a51ba86c6e2b4bac6dd014cee46e5941c31c39c54e19fc633b8934f404d816fd4e0f7d53b722599ab2983a423032ca9705380b596307aaef08e0d8bec3f206311105c0c0611cd19f9c21478536af33e70b751dfc8cca3764df87be7201be8f4a12ebd2efa69953e525912e0082c5242389f58867d4fffc0e0e536abae4ef88ef2f24f284fbb271583c00b1ab16a9a69442cbd8ddf0c0a98cad84d8992771e8adf6b049cd556418e68a9765f29487aecc23556b11b70f598f6742f0605a190fda83956767df8829402cb8271357169613465618828d3458794c0a31d94cc373f89fd4f34c87039286f8390807199c5aedd88ff8bf03135bd1b1083250805313fd42ad5a701af35365c4356a64d8181bff229333e4e55497b3ac24c7b8ec7a181d8de7c77caacd860a0a0543b1cf739b10c18ccaefc3e189f3526596d48a50aa9e696f9ce4d21dbe989b61ce798d951cdb5e5ba50d9bb28283b9ae69191f36dbe64f079038970c697056a0a694601d98ec4d4bbba31299d34f713eec1c1e7b54002f46c468459c421ef2a3b09206cbfbf2f603e5c1b5f7ac9391ee695ddd6b1ce4f6c34c0b46761f46cfe59c576eb00aed483da09954c20380e6de884fcd5faa42ef128884cf4f2fa7237cb54296907f0fe06485956fb5e4925646bd6e6fef29c8864034c7950817b982d48138b9dc4b5c9cee398f66d17810e782fcdb70b7a4228b40ea60df5d0d77d719661607c8948939168b5430c7457753f15dcfe2d46447c76a8da2f1ddcd07960d6d8b6896bde4a74576f5d479a4321fcdd021486125455b264259ab0f8e9c1ca20a7d5bd4d9a385a72268c26d947af2a67762834505e2fd96601b8b5205ba7ad790b0e3a07ca5d524caea1b212d09faf15e4cf2a98a93a32e60aa00c1eee6661c7ebcc4bb048b2bfed39cca09c7c43adce16e41a5150cf4182ffa42324bfcdc49bdbbbbcff604edea8fb41524c0ced47f485f2375fa4a922bc32a931d8e88276945d67135953198b4167b06a23656078d4a4ee3d8979b8dab483d4cadb54b747cd1ec72a32c0f61d218805c75533553a1e9443d7b5ef49a411dacdbab2d68c23fcdacea780a89799c56d14a4ccedeab8e24cf3eb0d3697c74eabf5273221e9b07b78e0f35b9f3911ceba07b707067e1cf8dc8715154cafd13a639a2e870e8f25136d8af20400186762890b36606203ac3a9ca0380078244d968cd1ffafb9cb14522e98be3b376d4f02dbde1223ac25f48cde027ca270d954aafee267238e9e2b5f3aebdc6ee9bc9502ce7d0d8eb1280c6d8c5cb6126578db66e97a70b26012e9af8550c7303a2635598656e8c6139de924053605a7db74da4ac25a8933db48aef492761aebff35bc5f8ee4b430a2a7e8a874664a91c0371ef804c26fa4b87f2f1477190a6935e154198c250af34ee9ccef77fe9d86b9f7325743331555063c9df6ea03e439a65030c6f07a0675bb5d165e0471e8e7e3dcee91f98807eb90cf00989eb5e3dfe42eb4578c470c272be8ad4599276df197a4137f136fea52df1fd74f719e75aa7c24b21cc41ca56955335b5497bcb22d5fda04625c8012a202bdb7b5600a75391b710e0e8c76ddef485098b48837b25d21eaa21f7ba40d6e4f4c5427cf3270a6bfda66b177dcccbe5bb32a165f10012609d40123b1b112cf414b71e5f676ac6b1ad54cff954bdd2d829c2d889c9d174b4ba4edf5524df6f32171dbc60a5d63ed2096c7da016a6148bcca556a4b5e3892c92f1592c3482e408470788b52e4db31376a09cdeb6e02ec1139d69aaa7c76d88b58f89a541f6c46e6b6891a639d832b4b414e5223067ed8cace15f5582520cba7c654d82f520801d1ccfff339149ab03addace06a127c16c9392466138d545b1086640ae37621adcf26637a9e2950866426cc22ef9b09240aa3f46eef90a7c7f0767a543663a513ac46bb328faad6182e92d31297570593d6b28c63e667a6a772e86fc897205bca57a77f92b23f574524ef946a889e82cf2f983f3764277f8bc0915ea442635e1ab39c5948abf4f45410148b17960958b7261f0eda7a35e6f07aaa5603415eccaee5dd58534e063d187dd0423d4dfe0279ace93a48e3f9f0001a4940ab81201b4f72cb7fe1a18433c468070e8cd75ff535d40feb342c368ea651a80d0eb037ada1bcd0321d9529a120cfc8a73433f845fc1a710409ae7430b81456657be5999478cc27ff9e893f8d9ab867a9de02d2d6db85def93bd7e2fdca718abda866a5311449334146dcaf736cc8f3b65ed0d92c9c52e02d3ec4c036b0b305cee257941c71a72ff637fcd08c56deb2b7a40ddfccc9ca5712d7e9a7733b627cb907a400a030550f38dc00be2d145bb62205feae8371e90458adfc1d8e4ade1231b27c5a5812001b59d11f6e0986bbcf69c2ddfdf241bbda3f3fdfc61d4a9dbdf106330e44a9abe6bbd907cce018e863d5511706ce5c188b3f4ffcf0db3847bb47e01912abd0f4ea737bd206124730e4dcd051ec1885970c95dfc7bc932d90293bb54840f027f9a0f1669bd4e862dcf9e33177508321f6ced1604442814ce2dbc22f3f9cac167f2b4b3996b94adb227eb8de7930648b10a0c5873415fdf8cf82861e65bd3d3d565c63b7a556f864c2cd2fd7dbcc654c20720e76fea4ebffd028676e45fdea14285bcbc06ad79c9db5560faf79e972fa64e6a115c517d5e276700d85a5bfff0262be872fd29d7bc81faaf5ac9197e2ff9480a9b939a66195daa1777ea897a7fd2131ac50cc68fd41c801ee18a8fe5b60ccc7ecc34841872984f756e8187e7402354b71d908a83431dcc714c971dfc885a883ff7acb2f632f25ec85a9106480102c107f7d6b25284ca7f93309ae3cb7ff7f8e98e90f336ac6963b959b0eec7cb97f42b414d3b7ab77bbb1184e9166c50ef3e77ebd2ba322a32ff5a5f0f3485247a6812899ff7242d412f76e21e8365dd78d28f07e540764255044773059db4d5f7523a5d7eeb3259cbe7f4a46fe36aadc500c7c66a7d81bb8ce0beb98385482e4ed61d70da0cfbe765ead21524727dff11aae562bb3891c0d24a16d81bc008be9cfca73b226b0568c1e0bac3f934dad680717307a19feddf38cf06c98df371cab1a411ae7ee45ec4dcee20e0c9b8565e8ad898a60fe89d5880024daffa8ab4d162084a9990c1c02bc0c86a81ffd0b5e3a75f05c35d4bae2c7b19b1f1f67f1c9bd4a58f4213f31227ee959f799fa6172b527278b09e056eb54134a34c7b313f636a6989dc099b1f658aeef7bc86c8f76f11a8a873126cc10c40b775a421156e6c6c9ef31b8b115e99d407c65932fe6e42fe094114a21dffbb7d45b15c6ca1d3b05300cd819c1d5542d79a924252d2198a4300c55df265aec2b7175c3d6bab59fdf4916871b3c4886c274a23d0ee99b3f87c80591718f873422e840e4ef1c2bd36e08b9bbe49f8ca4a3ae82fac0d04a6afc4cd363f8103037a361906567f4b63ad595cbae9950be3e5e06bf5a353743d9cccad6a9bdd132b206b6f13dbf45cb7818c4ed45e0624e25b925bcbd5e58d30a054e85aba3ef2e2625343c0ce0601f68c3f628719306b4f4f78651e7cd72fc00ef60fff877f3bc53d85a1700a90ea78b76f288ade18730adf840f53fd30991c1eee0fc9fd9073f4308cc1eabe814bdb8ee12721aae7e73ccbae3e3e66ef4961ef547833b4da06c066ecaca6640bdac455b2d99809bbef7a47a4bd89bf4f7afa994c3625e734beca4effb71bafc790f9cdb24916fd03319affe5f8ebc2f0ee271c0eca2cc0237181517718258f75846e4a6485623036fe2e1f5e8a48f75113f4affbce333cefbb26deefde16fd5643c947fbc2a5fbded47f859a3670442130aca7dd322b8ebbffd9a493b6b9aa3b8d31a8f92b957735daa87fb640028e01f95a51bec1d69cc8cecb175c42ab728a29c7c6791d39ca8a3f8563aa4889f03ae8cea58250c806ca71a7f1f8a71ecf07ddbbd6cf2474cfbf1745f9852a7848a41d7bb3d9e8b5c2abf8ef53707c21c5aea9db0320ff8521935c1d78217e0d413e403bf742ba160cbc51332cfcfb9d5c5119edaaa8ef3d588cc8221cd04df67a4614ab173a1b5918b0026056a9ba6a6693966c5c21251eb2ededf69d33dd70b5702a52d4bdb2adcd6c909d0c45bab9256e8fc7a2a54eebe3397ad6ecddcf793f430b619c5ef8623120d90a0d584bff0b98a00b6b99149b06c17bc2ae6815ef1e5fdcc10bb31450a59ef4a7d20a30af94a1c91e73d4fb5394045344bec77f70191b1135417c20c4379c182f815ae49780fd6ab8c48c90233f072f8aee4f66a47134be346c15ef66f954d3bd58c123d46d54944ebf84afab08e6699efb83bc21926f5db13e740bb5db828004dd1304613c46c5055d53d6136fe1447f6823f41613e6458aeaf7792365b4d4ea5d602090df6a3992f62c4b7a23ff5e40a039acd97cd73b1fbcd784ab1f23a02e500664f902980106b9029339c7c4004544255e5e367c11b0477367a20badfd9b3e50aca344fea8995e73e4ea66ef7f5e41894420a0cf41cad4d35325a268f749892943ad2f4c1146cb522524625b6240bb720923a0c7dc21efdf2db88f3f1428fef0c9c1ec90a238828ae15fcaecf37094b1473298b532c958314671d9cb6efd913620d6fa7282cae8e5e46ce395b3c737b99245c8c01afc1eff9d1cfa38b0d55b30dfc5484ec91dd549a2bfd58328257016731445af1658aab760b3314b92249c21ee0a410df1221a5a5e653332daa4c986d41a152f6d2815177a667f66dd48627f2ed9bbe5c69dba96ade638fdaabcaadc66d283b2137687816e7a23acb356fe346c77e52735ed5e37494cb0c514a15ec62809f965a4ca4c6feea776eb21af0b6437c46ee5178dafef1481715e5bca4a30994b1a8581b31f468560d7fa1df4a86a526f9db5b9d8e7319d343d53d7414a5a45e8b4ea5ab8f217747c55633159cff95869b69b1ecfc410a78786e424babb7446c91e2c64af3b9e9cc510357d5f4405da93329d350317ced9b9a7cd9cc5a4e8355a738e092840d9af8157c30e21378494e54742bc6e1149590d7c1ba611dac0b61f8d02b4cdd45db423bfbbd6eec952f15e91defcac2570c2f912235ee9b9726c2f0e607612a2c30529643fd882ebb2e33d62fea55895de7db1899057e712cc9157c3c958575846551ace616c56861a548f9f2675156c0328eb3b3c2765c9bfeaecf1fc6b2ac3168ad3af1389eceb501a079a1640522eec87d560f9cb77924980b3db53d7e63ec970d9cc341b0f33a2183e5fb51aab5aa98b03c52779fa73ee7e47c903c924b9b879f217da2bdda0c83df615571702a04de3ac1110ff625aad498c6862ac91d0c7b4e3ab955433890a68ce69d33c75d71d0422cb77ab559b32db5db3632c6fda77820e2a50f91eb50206b91eb04d9c3ba195049666b48534640ae7665a6b932681cd8cca79ad4ff9e57513a581c6c12700c99be039d2c2de0598caa15733e68d4a46f107483655183c851bee2e8724d3b7faa059b53ce50e58505bc6b5455adf46a5623efffc96193252815592d678ce38b6e2f9d3c92e20326c3c3454802f5c7d05130ce8e05c456150dd43f92fcc705575a77658de904368109907271e118e83fd85f91baeaa8a9a79883c6aade0fd1c2cbbcfc30791d1d50a1c50b513927cfeea8e6a4a6db74387ef9a0c9d4c13ed7cb358b57ff8714e43bbaa3394e92f2bdb17c1f7970ba254b637f7cb26fa43f1b8255bc0ab04b5703219b52da9fe6e880a7b7524dadb94c810b58f0d8b6b1f8be72c413918b68eafdd146bc4b525996f5813c96d49284a5ddc022bb58d0095fb108029020ffc73f1b883f1848881e66ca62462a56968af2076e9d5713efa4a8b9ce4f12944250f8b26beae3e6636479e8459edd900c9acfaaab2f45ede8c9b5842d831aaf64a4764ac9f30f959e8b2fadd8e8b17f1f7f533bec57946b0faccbfb88f72512b00f17f4e09d53000656714303b45c0cf52a86b9389154db4aa1e8e01e721b8309b4a14a20812fa31af538ae129bd2b53535fa44e7729e09c4d51ee44221369105366558a53c8fbaedc7c2275a459eb98dd78696c4742aa4c001995b20d1565fca8fa4bdd2d1990d7156b25ccba7008d4fc045afcee013965f0c65e8e5ee8445139ec9f1e8593a0725345aec740c697cfb0e00dd67ebaa8d1231015fd98d0e6a12ea53e20ae8519ee40ad940037b5a40e70bb7d7df8ab902fbe52bba71f67d08072f90eb1cc8f3473483323ebb2d72d17d50e31763d851522e6b6ffdcbf9d16e55defb66c6b8a947acac156fba9ff0f3c427a42aa5eeed1a1263bc3a6cfb63f195607691d95cbdd666c661c71838881c3b14a71657c5cd00e8f1383eef5648b5d7177c800b1acf60c6f54f0d53f34736141f689d4130fe69580666ae7080f59126fa6e0bee6828628e06338acc5f889e5018b1be0297e4d23d3d5de858bdfcb9c8cff81044c8a1ef492b68b20ac6fbab9b40fadb7b6af5dbf2c2db3d66fdbcc9f33d9c5d478d14ebc5bb8641309a53c8b048e0f30701d3d30b40f21ff6cb332dc3dc5e2fcd398519bc1b278657fcab82e0d169a59a8c381c573767185e2dc22b88e87287ea171737266a1a654045d104867f15701c85d64140b1438798ea2df2ff6fc8edc20d02d37be030a32c39cf06ab9c460694a1ee08d1d8a78ab897949c66f2ce669a3d2272e690c67d28096a0a6f5239fc004f1799f43f162161f36b4c8ef9e0423311b380e72e951a04c5a6912e2ae4d4ed253a39078c55fd4cf2f3518a70f706ee1f97f4f23626acab3965950e166ea73d7bd5d30a2658b6e347483555f8fd3d72d630751a80805f1f8daeb631f7a836cd3a9427bcbd6943502b51873bcccae48544dcb4df056b5642cb69de168f3e5206672b0cea9df9c9cdc110ac47a580b7863dc83d45646e317ab806a98c89ec40525950b5bd37d89e784554e2c9b6763ff56f2a09c9f1c46f09d3136810be30d243ee16aabb9633328d6f2bb0259570aad63656459a4b28c6ec3aba9ea33a7f48b5150150c6e572c115fa6fb4efc6f1cb9ccbacebe49cc067889b84eba07883e268302c682f8e8c7afefb2fcea74f105a3599d393844b88ed1c05817c0b762d90fd47894d189507f923c8d0434a3caf5f2d4d0465c1354c177e82196bdee5dcf0e726877948ebc5ad22b3cf691bcfc6bf34ac87d7e9abc5799cbbda22a02effd17ed2776b5559c5242f4df2923e0ac5df16e6ea2b2b53b500def31712520641e3e149fd7785cf437f0265fcddd1fbf5415cc3771d67fa7aeca4d3a2a7ef695e9c51edd5fb06f35a26c1dabe9e467d5499dec773bbcad1c55c1b51c43eeb847ee122bfebe95b5cf43c768afe87f4016dd6220c42b2107121dcf0065c9a3da32f483b981ef631ba61636659947d3ddcc795ec7ea3820dfce10189c3bc3b7d5e9a95bff25cc9cb6130cbacd31330996a742f1f6ff23f82cea0af9d2e273f65aa90666dfe1002d80caa3bfb050782bff54361a04dd44ec29eec93ff509a9004c50190d9552457c5b7f2be981f70767e70eac58f9c03b218a5ddbfed3cd73c65c940acdf3abe2ad0570079139ec3eb65d0f733460ba5ff0b9efb43ca4589695a6e505321d736f49b53823e97bd1c02ce8a6e10dca2f03977a6cc44bc98396eba4ba03c28a0d9eb8b9ba56b4729271bb30625250d8e062fd823eb5b20e261b9886a95a2c45120a46782a0c44b273bcb8050ec8cb2f75334ae38e0f4de3b9f82d36054a43c376ac61bb0dabe599eb9dc14517587c5a472a1b92f615746359521dd6204d85a2c9300e857d7246f6c3d7f06abd017165f56ae648fce0091591c14179bb7ada8e61c5fee7ca7a1e99c7be17577adc8bd22c0f1a004bcf2cee6865b5b5386aca1d6050ff0b7c9678cb78ea39a2478fa3821b31374f416c0ee6ee929244b2f1aaa0e83ced10235875579ffd1d9da889706e60e7a862f8a125afa96516057cca09ad19c9fc642338cd3f762052eea16faccffc662c4903f9c4856dfaaa5632f99d63252375736e9d34ffc6706655bf4986dfc4cfc515f4c630cc0355aeef32459802f7fdb3db60fb97855df328784ef11c2cca5ea8cc01c66b0a1e490ab4cc763b306963113f4c3d691f473981e813979a992e8d67d1987adbbd5af0107c9e36e1056114d514588fa5cb86afea46d560af01297d1aad04d507aa3e05a5c612e4edbcad077691eaa54b78a9a4d17044ba09b52b9610837b177e20b32fac6c9ef14eb8bba44fd5cbbaf40c49d04d125918a3f44393b97407bb4628728a070bfbbe2872fa86cc24c1ffd262f66c42a01576f70d2aec59772d07202e85635cedf9ac506a85e7e77646601fca13f6455153d5f7b27ba3f1f8a2e6f9ade343f7455f5c93e13b8c80e7793960b2e70f3ae59eea87484aefc276fe91151f9f0f96c8058ea2890bbdf12ca83b0d3282fc1ccdfa6c2a5777a50f85a8225ecb9f3055b8f1427eac60d8a3346789b9b9a08626f5a90c1ba4551ae25002ff7c92900e091f491be1f6a164ba9a251277b05d476a67679ba48386081a73ace10b29264df8d9f9ba1e1a7ca8759b3f981a34f49e9e3835c0b44f1e5bbb5abf67de421f4d8f27c9e8064e0b938dbf90cc4608e287a8cd2865eead281f008b2e122a94d48b58b003967deff1ce5d0cfbe82d8d3449a8c2c185160554dfc9bd3bfd78ed610f89a452ce23696f0ff4f8246ceabf7e9ad9718a29fea23c6aca9d2e2b22760a29161e893bc405eec6b71c8930650cb8376508b47452a9368878a8a3ed8130487539f9ec9333bfc86b5ee336d51f3869bbad5c77371d4846c0f5bd1b87edf4435e8309230b374de626a86e29f3faaf2dd7ce90c3f506a5ba27a251dde291b7d76a417d7de32b230b0cd3ae31a986631d18183d0519bde132933a654e391cbbb2c6f3994e82ba25ed66f5ae786de6b12f00bb2d8113b3550ef83d39746190243b9b4ec852410471289abe151ec5fbb0a9130ec0a044dd5b3a9915b7848fcf12f31314431f5084de2c349ae42a2e5e1b2861f29b70cbfd833d251cde895f0bbedf65f7e6b53459fac9589ae8eeb96c7b85723db5d8a27b47c58e8bc5bfad16d104fec308b16d1842d917ca0d737b237a4e5aa69a8d2d6a9d944fe9707cf6a5201e12f56330a779dda4ac5a0cf784f8e8150c14011f2a1184456a695dd628a8c7ce18e025f42a0b980bede4a41f144c752903c27b307e395c3cc4d3106dbe933c196a6ea150b185b6c00ceef691ae1f14a88cbb4566ee388e41cce2f9f14b23d9db9da51a400862f87c0574e22843a9c36727bc2f73a49c8986f2726ad78eabcf1cd47693719217c3439c0a7e42767bdf52df63c443962e8f93207d881ef8b0d401a0094e840695e3a2f1bd64a46e4fa74ebe9a131e4124ba46503bb7d9e6f6f479c8a8e981651b924f4e67c0f5bba495319b6c8c49c23479ddefec12e0108e70eab393c1440dd36a5a9e74b6b5bf69a66f2995706f223e847e8976f1b5b4eafee21d63b1c310c260c6040e63ba99bbc5a7fae156d413c30fb4996d1e31eb77c47023fa811826d09afe59c457b666f9dc3b0e43463be40272da1d94b067b80fe651ff18aa77c9cda3d2943f956e46980d2942630fa922aee397460f5134f3a9295b399d07b222a54b41aa251da32750ad2cec0bc065db3923bbf96463dbce534b21d2abd9c955e63af366a504ce725d7efe56d25999ceb5f88b48dbd4a748cfea6856a8643a79485fff08a27328ff85078c47d28864db1b6129b38a129e9b8accec02901db070682fbebd64981677508abd819b2bc1f28ce60a28e88ba281af9b2dc8d19138b7a12e67adc5b91b3873f4badfe81ec844d18f488ee6789ce6c1d38f43e2ef32b3093592b097e90dadc6035316d9d51cc295376532fbbe542b809e11ab47390839e5e64e0bf292579bd039e8e5ec0552e88e203123ccfc3779e6f58309b516d9faec37b02d460bc5c009f553ea07d5a2ba1ff9bab62fc442fa032acc0655e6e1b40d4f5e3b0dcdf520932e1cd207ce5f23e11b9e3a9aae651491b5fc669b75ea87ed04dc3565bde236dac8083020afd288eee9ba87d403595e24496d88620a8361253452706909b2bf816ebb8be49ac08b6c0807213dee5e0d7326bd6cb81fdfbe9aab3f511463f66c1bcb2bfcfb9a5378a9f84d7194d3b66b8c30e1c8a954f70f6260f778ba8240bc3f219ad292750726f78094050eb24435b96967133d278e2ee5b2cdafe7276c2cb311f8dc427ad2066d5de65f94a6497762b59a1e830852bf2dc40fe0314d3650f958a2133328688eb2ff2008015beb77b4b32ee8b628ccb6ae7ab38056409c22b9ce33ffa2b24191fdfaf78408ef6ead1f09aeefb719953267ca0c577f1342eba34c4238601a1d55947c9174cb7d8d57e7549cf5fb7941d058a71f9b6c7120a1e71e5b6bac4d78b74aac560962d2555ff75af0e2eafd907577df789268853bab02bb4376d4dc8c4d21b436b5f855063d39cb79fecb1b64a03db80798a71cb6b2e683eaf456512c355a2f4b76aab85f8080a78be0320c767f40162dc296ca77a283855d22538689bba2e1531401b1a49cc835f3cb89c2265895d3fe19566fd75d1137bb463d8bc0a4ee01e4d4a56cd601f12b793e16db9dcdf67677d1094e2fd103db66c3a313a8befc0d881e0e200306794271a1e6108688e92fa9b338921fbef6d805d629251b070cdfc301a6cc09af71e6e58f410249e8e8b71b9e29cf2a1a8e79d416d37df7452dfc4e2c0e93450bec27f43c833fab72ba5cf9a0fe35e87bfd7fcbe4f61660d559b0fbb5430ff86c48fee73f398b2912d09ac082d3bacf9a7abbb3d445d950f5032a08bfacb3114e1d4f851d14c2a06305fb2bf09c7e470224204188c6f008bc2189e99b2e09d351ee35a924ae2804f5eb5e312f1c376dc9e580d006b749fa43796b7c92a24e090409af71f6788d706521e6286b29842c8496658d3d9a5da16532dc2bdfae007503398e3054f005da980734c06757312fb07cd61adbdbf8851105782e98cd2234337e17278945b16df031163d9eee4e1067efe855e9c01dfd71e59bb7fc62de37c7f2acb46ed263d67ecdeac284009d577d0b6a04f46e3f801e98799750e1a7c0f6991076dea55458edf37cfa2f6d4690edeff6fa9ad18e007f48a1f63829b5e36d994d6e50863802be625f8184bac5eff0fa66aab07984501301b463b3cb5ef893cbeb012c1e4bca05b1842a1ae416fcec9c947eb45143b31face8b1a3925c539d1ba567833184abf5767033bc44dbb36b7cfcb571acef8f98a25a48ed967e594ce78a92d4f620c8a0ec7d0da013fd215058932da92b56cff20fb7142567a6c738a73b940a8a70609aafefe1e0d23d8c5193b66f1c3dfb13efb6b7cea3f0fc5dd67e36dc19cdf607ceb8649aac6a8a72cb285630c3cf39c64ad45cca405f0d540218288490e93ec22bae958db2211874c6a625a28360b601fceba0cb65cf388fd7a029b87e746177c7d370929686722c61ae49f84c494cb3fa32a9d7f05687c977d219f848332679966b66737bf81080540a0848b93ad523196a22b0b9fc2ba867c626efd74af8b2dc89b510de57eca2c7f6a448be3e04837f5b5a26dae0177a60341a31c3f0ea2686a998047c7c397ebc8fc2ebab74352b93a2245c942520251c33c376114199c8355669f5b7166bc8090c4981893b8e33b516a2dade67edf279cb97b2b63c3a3dd95cea0d67a72b1cd2cc8ca05c935f58a9e896b5354ab038f25455e490723c92495a5eecc92ff1cb46e11084d6c0374706f2c57aa6f17e5ad1fad6d60ca0bf558c4b9c642e6361f9750f999591afa855bd800d018f8efbb75918df7e311ccbe3d328502876246e7e64f537f8f6fe218ab759c97168b21cd3041702ec01157bd4888c0e4ebe806636ff3254558faffd13a5d33fdee89d0c962b17e49cb8d5af21a796385c881ef69f4340f28e04b4e4b2cd958ba166dfa89169a4b693ecc7475cc38e4202a0b0ec5b1ff394cefa1d70982b9e701f20b6941e23f1c5a52cfb857c46e5a285053b48d7c6a72bae6b8bd4914a923a441fe8709e9fa36bb44366efed4c3178556baa19b432621aa50fa5e53c3ff71b7f4eb32859f600611aed0beaec0bba80e95ce5948802d0126cc8d909c4f53ce422ead99b9e1e424fd8b1eb2faa57b66b70901120a7f2e06d3e6f4346aa755e98c3c3b7d5819af033f9b891d1946371f0fd2b10340355c29d8c9380e319bc06b1a69511956790ce1b8f42ec746feed1146f968a7bf085d8334de7f94e3559cbd4b2cc2f7391ef593bab0d32b398b1f70217f195b74dead000d8e91ed895fe3b775bb11419f3ed39c1d5b0698b7b354312de66209ff7cd6a6625fe61de24142984ffd2395d61cd1b683148064ec677ef2fe10aaa563b3a125fe85131e540a4cf6a79ab6508a0565d4d720abbdf0bd70c1114e73611f8e438d503143632c8cf2f2b9f46d2d962842f23173dfad7e3441ca428bba1f7a423642b430ba79cb37308d25fc4d45c62140fe7c15e7d049c5efd3f013fa451ea8e8d5e83c69258979d6b303a8e53e9d3492396e2cd325461df508a80b190e36a091a8b864368ceda4db1aa6f7859118182e5d673361fada3a29032d4110907edee94bf27f20f197020609b9789177127b4f76140ae9aca9ec75825744ef080920cbf51298fc2deee399e89b030ce77d6471016609a42b459e1e22ea577065752a9a3a2b06dfdc06c57021b912abc492eeaf3e40ecb5e96cd99f8d9703b27798be1568bfe4698eec0605793cca536f5155b19f244b57ee8277f9bb90a2383df0dba827cb48dcfac9b05721c2e26c93b7ec8d8cd9864a19b4cb5e22c56ae50bb49d5ee2c1b67c73c41bfb68145e53827caeda9ecb1f44c3d181d58cb242624ffc6370abcee7bf37d61839745d31313b0a5ca0724f453f01ee0fd986f7daa512f9a2a687b28425d5f5484252106b689ae4e7e82b2472c90655dea7564bb7ac79360bbc8408ef16750e9c5e0a231d5fe0f3ce81f204053a006dcbf716b9e11ef6dc9ce7a2d1046915d1f6adc0abd1a2cef39bfba58cfecf05b71df132f39865eec31f32fc06eb33815bb0ad9ac73d379325bb499f24fe836aba0dff060f49c01fdd5c6dc0b110510680969b82185c888d0ca2f922c3711501668a29b4704b42be4b15e0d6d3aec3eb9282e056724fa6e206ca0bdaa5673003d32d63df25fffff20f8375e34a3426a3833ea283ead0d69d9d6e8d24500b81b2dbf12e5cb5d99c79db0bf7eb2c3b13ac06f84848ebf8e465937a942859f149f2a30658565163eada56042378b9a6399f64549cd2fbf59bd4d98b5b7e67655382eb88f12efa2c5c8b65aa9102037ddff965972f3542507ddf79ea0e1f338f2feb8ba560f33fa994ff13634de6965aaa0570802b62db719ddb3a173f7d4225f1bc8975a1973513c0a9b3f363161cc5bac109ce3f432126c939469829da140ead3dda375fe2d58a9b65f1de346359802ed886e018d73e6fbd3c6a5f532ce37ee2666ea2f8282d6c80708fd2014c2e5902b9fabfa9ff84f8e74ff31560b4b2b6cf5e94ac6605ef5236e25f3d84ed422529a471fc115a8705c45ca6efb4adc75faec53b0abb93e1f4a6df3b97a10da0c8e0452de7f3d8423e169493b3d730ede9cc1e6c6fd47e17ed10220284af7de7957ef9ca5a8ac893f47f4a8dbe256e9495843a0e53f3f5427c90a4a024125cb5018e08087b156859a07d792c52b66c0f40dd59ce1d6ecb09fb844679a8dcd55bf5615e4f14d3bc608f9ed713d64c74c45f914654691cd869865b1e719bd6ae43f418bb4b40ef3ccaea983dba37c7d61af3cc3bafc323f81de17190afcde5bbedca24c37bdeb4d8b04dd88446d9a9b68a5c3319911962854856231abb06014d975d8b6ea126cb3a95f1a0a8a9f98d67d404259c6bbd930e18c73437ebcc896239642bf2693e562fea9d755024ca07687f4e8029ff9c2fe89707b0863e1207045c9d10ac95b465bd27dbbe0002b170cbcc29ad352ec14ab3a672a4670f418150c03da95e4f584b465cc5c16991ebda81ac1e6c995d75ad2933a4ca4fbfc11b015e85322e1d3b7bb71a08c4807076c06fadd1dbdf54362e43beb1a5235f9f4887beba0bd6b70adc369ba2013aacdae36f3f9a1c2964c90974d2dbff7e7f8f6e159307b9e8c64534fc36e5a310a2be43be20e8cdd48d381b22a7d2d892eeb938a85e5082488d5e18d8506b0da986cd9bf3a4299e1cce6f82f7b6f36cbbfd1e0c68bab51dda73f8057b4658b685f21fcbce81b9e57207a59bfab34543725d184bf4c1f213302d6aa841a86b287dc43712ba85fdf1c331a9a87dc9c863b8d2cae8a305ed7bbc0d109a4e0cc72c1a5315e2be671d7adefd0e98850f369b7291d0c85c771ab14f8a7b38a811d7ee17c8c2df9a80e475cd139e25635a2e5d31b14c81ddfcde607071283ea8072a53b605b3a4c0709ed063d09f881d349dc6fdb3375a75132b16efe5cedc96cea37fd119748f73cf49c89541682e873b0d5cd46c3f6c20e8a79f6cb5d5d23b5e739b81ada32ea5dcce407abe50fab5836a9c65716472dcdd70efa75324d87df2564b891483bbd715a5d86184c5ed5d5feb383e771c15e9eda0d747c1d93482cb9ac48969ef075a642e859d480e67ff4066756070eb82b5231b1cd4911feb25f4e8d65deaa146ff19b531bdf82c9408901e3e25b7b83352d5611a0dd7d9d3612450c02d87e2a5c36b7574177e543219891b1094f8d0d7259ec76c3a495b3c00b70d213965323e8beb8423d48ce9a7bf48d88d77d76b0d72b0a4b47b9e1ff9cffa0dbdc9e3569ec7f86237ac5b4dfef2c9cdea74c3cd196962a6cd5c7fddac4f9d2019bd933295081fb3c9120adc5fa109db0c1c11c24bb6756734fe788d7c9faea9f39e641407381091baf396871aa0c3bd917e76edb03d8665aca21e232e82196de6bd8099f86e6789bfbe00050e526d05014cba3e160b67b1ab7ff4b8790be7a84c691ddf9f55bc3e1d535b8c0b642615716bcb13a562a8fedec5d2ed46e1cd40552d26725a9628e83b2179f76cf7f3cc9297a488733e03c0a89683038d59f01e6d7a5833dfe659b73d84b2b61377c1ae814a1f28a150457c91ac3d75e1152bade8343e9c3bc76bf58294d1da87b68a4bb994d5190c47b7d73b5caf143ff5bf0737d98efe9b347e5fc2a6329d222b50b873b7d0eaad0efdaac076ad68a0ec24fa4f032a9196c5ea15cecf18bc80b8d1ea97179200d90c705e8817b2a905995c2e3c664c1ca1b35da3fe229f8f2ba7d807ce586601078ef165f7dd4f847db1ecb6f43ee8b14e6cad1b1afa7d76a751f8bd54b16d0c656b94f8654ae539a8979d82145b6c1e1e6f0fb298b0a028dd5edef8a85d6e6cf069e5a7b790e9b0d49b07874a8deaea53cc423498830d9eccdedf12f1296783cc1d798569b52dee008caf9482c1c346f2ffb487d5b707e34db4284c09671a60fa7ebf9b63c8541fb6c39fed09d4025c75e670e3e21c9349e9fa2366cea289ebc1cd3a5c22050d21b34d641ad9065e1c9de796c7ecb4d7e30fb9073851bca0c0d8cbd2a8781bd370f7f1f8a4f94467f6e6916262515fc2c675cd67b23cee79ac5ce6b250a5751b846fd4e5a02940c65022c3ad563439d54b760edcd669d8c94f7a8a5cc36270417a536df514867fb7df5703d8cae07541efd75f7519c1eadc9c3a6f1fb52aa30511c2f4b100721761e6f5c5f1ada5005dbaa298ecd52cd14fe8bb9c59d4184b0e502d06c21ae38b9e681849fabb4e9fc46407fa6500a587dc65e5518a6a58d9f72d9ebc640760a1102c89b90fc1c8350119df07dd0038d40e7d52c2be09a6ee9401e1f278f6a05ef382b1d4a78ef8e0080eb7a7e7a762288461fb4ca5a5183dfa0d5d041424962db7caf4442106c6464792d01935fd7e5f61faf48b4bfc757ffb958d0118f923c379edd54dbcd3a7373ea1bf4dcf16fc77e0d894e23ddd16986f88ead420027bbcdb042fd5fdb3cdea704a48511689c6614c316ccf26231d32902367df87c27cf952c8224eccc542bc3cc1e897222bb72d545d3cb439f15976ad308a2d8b2d62a2a879eb8fccd1d6470e54ea704be77b52b677cd7ba16ea5818b73b3cfa262456d75be9fb5d59e8c8408378fcee195812ee57e88bd8bd88ce6b9c1e0416efb1da0b6a0622ca7e764d0f60df0a2e8f6e679c4777d3bf8257839240ec3810fb8543f5b22c82f8b7ba0de2e333f2c2d2e20c421677be76dc7d39000cfb6b09dda0614695076297ed69cbc8dc9c01fb52fe9a4eb8b15e839a4d223f6faff56d53686506c2da7a252b3381ed99944150fd86886da6e5b408109fb7cf10a52ae4a51081f38fb7264f69e15b46dc8d774a4b567f8ff487372406b22c122632d50d687349832c60378315eb2d6af1d065234517b0d4ad4e90018b351d395b2cfae2deb7cad51dcba29ddb1b9aa4e670bb902b39736e742230a64ae124024e49d96533af95f902950107b9029039bfcc13292e94a667b603702b35e9a491e4205bd819cedae8f28feeca59ff447a0b911386651c2ad190d8974b7c10be6713c91ec184cfc631aabca1a4e7b0cc66f616fdb0eae20271d9159e292b4e730d6b1463b26daab11281e43b7a045730dab22d1618b67e329addf2519362d4470273cf8cbc78762b2dc76c5d3c46713be3a6bc087393b6e7ccdc315d665fcf92a9e35853ca4e00a052dc9ccc72cd0830b8543535e3c4d9c6329cef5091848f67edf248b6ee2f9063a81a2caa1866acdd964909222dfe8cc3b110556ea88370aa5d6ec2611521a82383d04da08d5ce12664333c834068533e4da1926aad06db20947b8d4ab39e0a023b8e5ce688b228f920cddd03a35098c977cfac3cefadb94919d18a715c6be391c496c01117630312b55c333edae4a38e8f13781773e79dc4eaf732fb0a0cad448dae7570c269e52cb7cd65329f0fcd7e0e79786e833ae99038535d8680e590246bfd961436a14289fea24d5f8e4cbdd1b765b99efd481a42ce648a32a07ea62a9ef098c9bc31c209f491efc83154da29509d4f019a8795062d13731823654077b3c515bfaf5db271df096ad2d0c6958edc11661b3714b74a102efc552effaff49624ab56a5b08822875b935dbd11c705376ce2256e42a6a3d06afcbdf8fb38ef740ae5196670e55f4f12a5b32487c5ef8cae0a08d6e65f0ba63e799d44ec7f15cfcafc6c929d4b0c95e84c9b8ec0bc08e121478e8c1faf9c50e89eab1a739846ab2ec55eaf959a6c7efce754d04b284f5252d41cfe7b4a58a28c9dfe889062538c591b673c5f55deecc1c6225d47411760445886b36a857b92f5e4d502ef8edfd0333e99314633123409a2984bfef4fa9fe160f6aa19a50b09d9950eb17d5354c1b39494cfc652d5bbc8a36932771183d2b7f4f462c96480f91eb50207b91eb03be6996a8b50f3b74907ccce08b4376aa7eac4004fff5b641ba0a470c16b158e4eafb40cac4e05fb386b5f17135a3ac8213e0a1b5079e385c2fdd1eacf8e0a7e303b444492ac733c81ba388b0aa867752a48b9551fe098976a2f7fb6a83e1ab146a53b31908d07f5dc46f6f9f0e02e3da2256409267a5a6e5a79e84a6341706a62cd287a8e3f72fc138d2bdae48e7cf299e43fd7080d74c9a70d43d7cde3621b66262b48ffa2fc059edf4cc25efd943286621bd30b2768f9562cd32ba9fe39137c274fb2f5724b424ecc5ebde7b533a093edf2781daf33c4e2a7e9d752b71771d7ad0ec0be5c321540696fb82cdda3911a1988537c0e0e20f671a6b21c57df3008d6c554c4151689f61dfcb0dfbaa61526882b4bd67ea9703367f986b41a10ab538212154bb29e67b9a56c0dd8a9d4a5e8557149ee95eb0866028b59bb098dbb14e3c3785a0bab0d64c9f03cf4cd7649b4a0bde963ed6ae1dd610978d01baf5369a29d75731631317ee727f3d0a92832473e3f64f5f7b231907c88c7c90912d61b0f7e159d8c8aa8f1f629238979d32d554ac27aa6a1ee60df0170fc4410ca80f0435e8ddeb238a8e6642d93b42f575d3659717a0ee3139dcc3f8e1b0de1fe24de60b56f5d306e2a295d7948b4709beac74d3a21614251281585c5230cf3096fb55514a448369867dac1264c797f571c9368e902c52d4c6f31efea04eab34b525ffdde8151c7fe60ffeccacd2f18a724dbf43a529bf6294387bd9072ba7252f05f35f8ec58d12a5e16b75e78fc33a3a3f160a552676f1e651e2de2fcfc591b0c89e4a9a8661d46e260df027eb5d7aa13e121781a9637f12019d65edda42def61db031b6a4e0d3ac880a55eff3f597a15e46976a363223b559c76401efcae3f3b0402383ea64c83a79a1f5e486ba2bcbfc5fbc48ffe8a1c0b3d91e1ffcc4cd334e174be27ce097cfb13e50bd5566a039e0f34149d111136e121507d2537aca8c6e20b3f8125ae718755d8f732812bf8fd6f387ce24a78e6537c624271a85e4c7206911819b5aa3395321bb256e9ced4312a615ef2d15a0aa4f950f4ca0cde23b90c203a7a813f63038c3dc62f626cd37936ad677c931c64161c6b077c8b07e98f7ef8b347c95c070209487a7209e23ed983dde742c95d103733d3df735d2c40b71e29e3e20973a0d02373fbad253bbbc064f68046140a04a57f4a7f22693f9fad84da8bb52d6e32f7fdd7f57ec34e7adaaf059056ba0eaa5ab8c4d171ae8d56becaee5b05e034edc5695079895e81847906ce108e61f6df0be1985b3aff56ea23dfa29490c2bc3a6343cc7f5beae4a772a04c4bc8e2a87fad899d5826bfdd4f0c184404a94836656b520d142f7ab7adb7d96dd156fb6e69224c92c47a2de52d0e0dddb435dd43b422749e4489f5e4390ebe34df7226a14ae0eb51d6872e63c0bcb602c8fcc54ee1ba5ae46f254175e999b961b12d16024ce1f765e321052740fa0c5c667825ba456de2ba23a75df0f136bb01ce1ed62e266cbd746571163e7f08fe809593ae4b374d5ed7c1c7a1cc9c6c50c84538f502ad830e059319345a0b389205e34331e41c22d09dba3d56c99dcc5bd7bd906730342da3f789d9c3d4c397f59e1dd997daebd94ccd7417f4f088d91bb8b29ed9387806c93e6825a2afe7027d324a8a132efe015db398df4fea640aa952f24bbcc56e430bd7ef7d9dfd53c80f0d3700b5813634f7cd5343fc328a9438f2a325e71060f18e02d7a17322cf32539a2f2b8dbd68569b20a1e7bc07b96d7c6167fcf7132904663f95e585bae4d2e105f3925cb70ba8b90a25d00b3fcca296035164b8febbe2e5e4fbedfa9c357ceda19687d1fb15151e1a45de1d0be61f6a6fa66e499f535ba7c08acd24f89100a1677937eecf3ed6f4fb62fe72fe954f52c86faffe28a2c1a652555bd803170005a0772bf3aeb5f616b1242185d039ca52da9a8dc63d9ce5fdf00758b1cc1583f29f5a0be27cb817b83227e3ae6615ea510423c9e54175733d919628ee50552b3836b3a8bfbd6fb27e2d51ed137223bbb52b5a9531a32d79dc0c3a425c9983ea44a56fa81f6feaf5dceb3a1f5ea79a2bec54de125e7c1785e27804e19c7581b574e3be8fb5dd0dc9b6e842849b80a8b5281904a32d6703037c549ff41f6df480585cc1e7093d34cad8d5bbe81a6c76fc31ee01ed16e213405d7e60e15c7dec545824776e850a8e6eaf88f4892b87728f42aee54af1f1b87d66470344d447ced33ce126726d4edc5148b269835f7f00e4646211f927c06ff19f74d4ce3713dbd568fb39942d63642735ef62e19bafd8645a58af7dbd0c99da17d375d4984e24f91dc4702b44fbaff2d98063d6f095dd88b805665b427746cd6c247a127498d8d5b7593d1963a39df4b25a1cc3826603085400685e305f17311a99ac41eead0a098f86730e544c1f8ede8bef64b030fd24fb58dd5267bad51df13536b059f6a9575d690b10e88ec615b3486efc41e9af0d4ae3e2decba22bbe9b55065025fc85ba4fa2f76bad96689fdaa6d70d7b8f21eb1416d2c258427a548ded4173ab0b020041bb1dc4f047758b482396fe686965fc1f2978873cb68e1903b938701359f7b2d853b59117ba0b7736cf86ace30739c1b8c7b759c47c5bddee0230934e689b1515ddb559bde7a7d17cc80af50f61695edd74d19630e77bcca9568f43f87ccd1756233b0760a2562b850a8d4fa627d37579ddfb982539f3b19dc8eabb822f639349894069ba6b56c53d95b446e47d691b8b112ce3880cdf2215aca52971c25a7fc1feb700c562eefd993d401574864e890364c0d193319967605122223bf28d235638449ca8e525d40db449dd4f014295e6376f47f2be820dac69b69824fbca4de3709f61f86206cdce6ea025dee298a6ee07c2b89285ce418b513e87d9de1a6a6cde12a6700b7c49b8d2160252aa4e656bcd78952a5d09d200be94c78f548e69d25e1c1f1c88b9806281809a6959c8799d2abf22144cb38209423b99a98e02e6ae447be495c4c3d9b293399a4796ae76a7f5b8123d91886bb516bbfff98259185f3b72d4e413a5e4972196316d55e72fb0ed5f34f89485951a25266627715b11a7f783227fe60ada8c30c1d59fbde87c3c9e9b21cf39191ac19fac370f2068fd2e3903f8e674862fb44909f3301a7df2ea1526198e3450d6ec1d8b4c260afbeadf9186cfb5a5f126b4a61263a27a6ed10380854217480da2e06970a6219e51e4fdba5f510d43d2d7c15bb52573a10f6854ee8b4ab03ae062bb7d04ee1f1bfbf0774e343b2bca41f2b399f1b67a8d2cbb2647609ef858bc4945025b925f33ecad7409f37e6cd4b6e0ff41e329b6dc49f4bbbc1e9e564dd0a6567756083756301377faa871c1573de864a364f632a7acffcd38fa144914619faeae1c89fe82cb866593eaa53b437a2a631eaa952943e68ddc320070d77e33f2a9e47ced3416179a28f04876b377dc021fb2e61ec3774011d026f2e1af393dc3aeb267b4f44949a2d156b215abb0ea3a61bdf57cb40aedaa33248ea5064d8762b094ae7e29411b7f422efd579d19b769b5dab78c492b29eecb52b9091a922562fb3df1193548849529e91b395cf07ab467a3076f00f0d7819623541e67798b61c59b84cb963be2e4a3bef1db5d0d1cbd34480aa670310600be242599962a623989b2ed5363fc12438e25980aa9570ce51ce938e97324c88014bee15f4f33721e5d114711a19d7606be77e5d7e1eb4b06b032c4bbdd2a9b7d1fe71b39075880ecfb7b2b7aacc8051f099b72068208fe5291b66c3f81fee16ecdcd6d69fb021a7c68299e64f857b192273358caaad22089b997de8d14b0f18587bf2d4cd70ddb3723d2341c344f20f3083f4fa57718ff6b721cc157a6da8092ff65ec2407293921671f37f45d9eb3858d1014699b49d0074f53bd562bdd54058331f25884bc7f2c446f52ac828eaf9e3352c54a6c2649ca7b4ac6bba4574d13fe8b079c6ca4cc2153d545acbc0acb7b36795b48bec91e5317bb87cc81c124f3ccb876d2a74e4144b1d6aceca6a665451459c4afdf4c3898339fcec79513063947d8adfd69608971bf99eb96916a70980b11c3c54f466ba0cf825fee591b9b5e9a4ea1d9867d65c217827d937ffe11ae2043c61a70e916a9e8f7c1e5ddcbf77cee0f04b980b07dd406a5855df37b820efc5c523e6c3e90aad20d25ea364dd9130ffd5424033c605f075b4dbd943d99b74b880a0a5ad927ec785b535190b2500616ce03955d4db75745f2c7e9a69f2d2e86d8a6f5885fb096ecab494993dbc6c4b7c78e7e4ee82f8b1868d39b0877505a28c6a034b65f77997682859663a735c9f0673bf937db8d023d3b563ee78dc41a69c17edfa4c648cbec133ecf1cd95069a2142b47afb4fc9e1992f84bdc4fb0812ac43d6d77b58ac4f4c1c22fd5247422ae11b2e0c05a07cd01b21d39db8d6fc6751f6968b140b33facfd12f2d7e5b70fa674d5b9ffae9d1be9a7d51c68502447dcd3b9d7445c2f3d09c2e3ee84ce35b67b30da7c55a65f81b3d743d025683f52bb97af59922d1ccabeb2091559dc6c1ebaaa9a6f9168e8ae7e73b81ea83c307e92e48cf03bb855972de98d124bbc1a5e2b9278490853b7b85b5100d37251c8ef14ffde66970a72c340e0f0c03ca7977141c07b747e7e1a5ec3d2443645a714b86acc745454aa55827d0be586beb41188fe1045adbe1285f1d1f0cfb6dacad5f12a52d63fa4ca974dad51de1580941b521e2870fcf9b567151115e3613584bc7376fe4cda1f0b86c39fb83ad63066a54f4350aa1f88878c9aef6807f65be38572dca3a0a25d40e29e3bb77d107b12b2482c0d7bba96f4a3916fb9b44948c0e5a628fb85cffcfd20833c42a4adbb0df22e91aa5f22c69b6d7f8e35a3514a7d5efaaa848aa978d529e6f99cdbd485e265afa07a9f28ce2dcd71160a3fa5d7e9976f6740663390150ada3b35f32d4a855711db537ad7c9f4c5ef592630c377e4ba57d6f7e8d1bcb35241207963df34db3efd255dc0e7ed31bf6a62911ea7870b1ea0d168bd9fc53cd2e85327355c8122ef142a193fba8dae3f2b69a35a163e342e44e9541d118137d42c3934a51d769d22ef060b005afa54da3979e7959ed5d21862813432cd4a76007d0c6a4f0122134748991f80bcf89d10cd5fc61f8e61500ae5a1854b979e676c6d3ac23ee19d72faeb3f9c8101ea4988bd6d6f9e78ab551f621196ed25ffc7c034ab41ab11d5d3289d1a100c0990e56523d893f38d35a612084c7af7ba42d1baa7657a407e509963a8e8189c0f93e7950281c35161c8c464d0d59adc07d4c0fc517a0567dcec3582a62c96aea29b21becb1eaf4dc4c909a922b289c243410a02a5663aa6619e5089c6742c741e4292945aafe72d4c0103238a6fb9a8ed441fec6550dff12303ece0a67522fffce5cebb7f868bc097be278cc831aa4586507f2ffea21e0d0a3d15ab087504ff202f73ad8a67e2d47d2fbbc357cae4342502365928a531e70ee3a62cea2d05d3448c08979782c9376e1c1c39ed676c872b272b115344ff0c65a6ffd8230911e739f1cb70bdde38545bb8c4e31f222e30f9b67e744220ea855666c171ba1d96cc7aaa1957027271585965bfa4ac1711c18e67cf3af4eff1759295daa4b55821a4e081dfad131fef9f35f859c99a2c3ee68e93b25a56d70cea78571436d188c5742a9d9761859e0a3d7d97058c2aeeccdca602db88ff0aa5d116ceccc056cca237cfc9d2c500c42f267e6bc82d2f139a7b3c7686f1f75016a356b38a5dd2507c302aaf99f0e79f95f3f3d877ac99ad2a93c809771c363c63f1c4bb9432f725dffa8ddba761b666e77913b46c501ceaea658f828dcd6d79aa9d3b8989747c97471efaa5ddcdf0554051461eb8e632992914e2d758c56a64a06305c86090439b3c08132d0206541fef2392c487d50874494e9dcd98bbc7af4ed74a0aac9b4283e015495f4bad15f977c2a905ed593f186c7be1f1953edfed37176444cd952b8718da18c78866d6d5bfbcffa3f627edadbbf1e7759e170ce1320cffa941338dbab01e84749aca055e8978d059d7e337a396232d48dd8f9714a0142ad6ea0c834f7b6266e6d0d90f08199b0b5758c9c4bbf797153160e3bce18df4ea66afb8963fd71a7278a20f907583b204c7c049cfea6a95fe84b5dcf4df09ae6572b55dce3d1d1cbb72200348d114ab02739a732480d5fa813c4a464e552554d5ff2eb057993a776408c7e82c79f69ac62da0d9703e68c48021ab42a1ee9e6e3dc0d72c0b6b6aec3da71826cc82b6b8d947f6ba366026cb2c260eeaeb39335c221d2b09a93ef26c29695b313803656809d37a152d3d57b1e0481bf20af16f49675a145b721bb77550a5a7bfadaf8a9cbbbf234a6535031e147bb7db5e9cac16a6c0a09c170a4e2f99e4d3a322d8b8cc3b56106cb0a42e7a3a9283c25374abfb435dfa3f97e47d41473308858efc8ceba737c7b650d758796af61033460e3940e6e428c1b99a0264b5db646d69da3b6ae8e0e3055533f8f15911632282f29b052861a12b15e3df6c8101cb4e895dea82794c24b3577842a160e56bd7ecd402a75d77b3e7f6d3a53daf76e4e4bf0c35e27b9d9defc2a066c8c3fe5f200a6931f6f6204a66cdf050feab4f4e2acfa71acd7e2abcbe40d8da7d012bde041e6f6cd2f8bacc391365cc2a6eba9aee9425ffa98a19f79bf7284e94eaeefeaf7d502d671dad94341c97eb364054e7b0aa1f1c6acbc3a556e7b1622b92de245a0dcc6eadf921379d3db37b0186477a9097622942f61d2951859c161e7c3ab99379259c41e947415b29ed96e446c46a846058c2b44ba5891b716d4d8d316e9e8b849d5498f91be4e84bcec878b10e4a64bd3b5d1ea6120edcabd30f42a1b4dae1b4c48b699bdda60548fc8dc4060c9547e94d8d36289e5232628a2261e31bf56da1df7b4089452d2d14819485ac14d19ada22f9b2bdecf9ae4366611289a8623ed7e9667618fc6d8ab34cef2b89e032c9f4c166c8c572f221ec583b4e108bfa7508e580d1c42f4bc8e2039ef2ed629fbb1af5ce63c76d79b942e613c1fc6c3c5ada16eafe24be9b20f968e23638f04babd8255c1679c914db3f9223fce956f52c3ddb4f65d0aa053372ee5f53dc200370f8bf7960e8eb612f23cf57f6d62812f9ca26cc686f19918b5a5031e7cdf769ec3de53322af1aae2aa49ea75da052823ebf5eaecc349806796aaba448298ec5cc2e95239b17d62cd41ff34e8ac28061bd93e159b3b5fa3bbf73f99a25c835138d7c71473cab27bbbfeec12dd60df1e8ecf831b58eb57f1a95dffce41c2201bdfaff5a97a74fde511c952b4d5efbc8b4f2de7b952e5cb500700ac3cf7d3c51e4f69a6483d2afc55414a3392f95b48d2a4fffed0b181a5ae9c3102a0e98228445567a362199728360419d3efba6a35e3fec597a8ddb3b5272fc1b07e80e73f155903244a1485571a9e439655a36e4a0f65338d1a564a8a06551bed8e0aca7c05efe7977f78af7a7fa0f3bc98bf2b87afadcceef446288e95e6b519b7efe1c1ea764edf63940d099e7fad81175d1fd335f7f85038aeefc3f7872e9c3ec0d292de78121473898266576374bba74e8c2aefa0dfa257955d383c528e478326547f02caedaa365258e000ae6c14719c5e293ce785b024bac883aec5420f7b6895d96b5f51cecc10e0181a72dec25e646cc00ff3355f1575aab75cac68c6a15359d120147d31859c5e2b981b0d3dd0adf84baed75272b2d7c8fcb907aa4299d9d27808522f843cc7f7b9cd454832cf020467b6377d64bdf0bbcdf14bbf81e590c94e0988ce0772dd10fd0a8f8f30a2f3296da15d6d7dc30f6cf6f0ff82b09ec025157ded123cd2dc3ec878833a68b5cd4038e1c384197d8b99bbdffa226e93942216edd9956d8c521f4847be4bcf4ff5edb4da8b89acb20b9db3e789ce7051a2991e784ccc92497f7b7ba453930b0fd659ec638faa350f84b797c644805fa5d70a4e217501faea056063650b2439dd53df96239ecf281d35ae5aebe92204fd2a7649a57d53c2ea55c4194cc70b884d4939881c14469d172a03f6bc683bccce33d41ebfc5cf6b4d6427afb0d9be7780ed7ad575b75d9ec6e60d685bfab2ea6252debf3bc4a6978fd38f697100159ddf4c37d30361d5ed61622c7028f1615703a13d8ea5f7d32b4626ae8ca9c5676d9ca1f94e9558aa8e64c349dd99d6b2cf543c7427f475a8375e41efe8c8cff70195e92e4a228538dfa75e9c704d89d3e0746b9258eded8cc60db17862e5d083006dc6200e4359c703be450718515c149ed6ed7eb52511fc5d1f0f5450e3e0b8ecbd3257988ca0c9dd21627c7b7aefeecf61985911e7aa90b4343b32e96c60f899a7df388d64fb0414c9a56a949e04bb67f746664ceb22788dc0e8e4b7e2ed76271dbbfd299881e6ef1039579551cab6078f2130985d38381b539eedd76bbb28d5c1bf0e028e9acec063a174eabe9a00d6ad4e3ef310cf3c429cabffbedd5ff317b02949a4cad2f0b6af76841517ba5658d8c97e7ee2aa1031e73848c138892d6aff76cf2ddce2db1efd384124be669c64d3f19d3f5c5bc5717f2b5d95a34d74c96265324708a88ef091b26bab587889406f89ccfd1e0bec1aadc350d926f4de02d19e194a4aa85eaecdc30716731e49bea11ec831ff60565046e0f5f532aac64edb95f610b7632577e13aaaa51c988da97be1e22655cfd679611708fb4218428f88063838b5d7ac5b257f73da0fd3c31a3587d857aa0518da161e03182e3ca6c9a6f036734a8202b897254956d965ab9820226925850b83006996f642c34c6c391ce8e9adb77f2912e961efba52b7c6be3bde64b2faca34088bebb5e7a0d8c6ba94f9c25c0aa8bd5bf44ad9066ef97f36e42af513d30bc1a97f2f70678d6b5c983183e0240e456c99b34fef4d62d917ba6a589be2ebfa4994eb386e1974334f685c2ac4a65f9dce18c6f11fcadd8d77eb5baa828c0d1c963f7f93f56b3df96bd881f3b86a8fce501d0be8df7a42564375742a526e4680cfa9f1d6c45646184d28a0559b8b44867d2bdcee7149bd854a551b76c93849c3a8725add5f2e7074eee335425ba328e287df16b948093a1c14183e30c22afd5ee68627681bbdd477413364bf30c27f8b0cad4e1c41cbbc137d1e58ee6be4dfbc3343c00a813b32ed8e66ec989b18754dda56f406c6841785f641f51795bcea47573b5a020f40e604dd5eaea1a6bb5cf9d33782c239bf87752ac3cbad63de9da68727302846a72337889567d4c4f93c1b7ba636ac84dbeaf3b79f22477f09b4a27fdb939518a0e004eb19eb0525a501fd639b39baed0d159d8d97d70eec9e9d1737381953e7b30559f9d1a8310ebd9c9de8186d9ccccabca5eb8054567adad223c6f7ec26440790d702ffc2e1ed487a0b628b6f52be3e89b66d31984883c540f4126996701dace0a0cbabf81d49043b03c2c3b503d487d5dac6ca53b0b4cced40c1554c209d1f20580d79dc1d112fdebd24c04538c733b9a41fe073045ff44ff64696f0bbc4958abf258e9f9b25dc5a2d3173e3fdfb737cb015b911ce9d0af3ca1b0e15f6d9c997446b749b94e314747895de4afede9ddc9e01296aaedb53bba5c46eb60c9e11168e9840318aebf16c662549812aad1cc1f50b50233d1300d4c8604da8d993895c9d716dfe1edc3c57f632ccdcff0e484fb456f3dcc1c2a9e042ff937a8ef9c7bb2b12e488c8533660925b8e714aeed508fd0d2cb0b328c6e1d2b9e0747055380c5030de130363313b587af20bab5e375814d6067da2adb87dd7e85d00a7ea5abc719624609836c71306ce58794929464e11282209948e92a87ce6d3d517445f0a1beccc8a4446f87422ab280f7b0fa044551a40fda069b78b3668e19b452d5462f2b0484279bc2e19d2ee874cc451514ffc9ab16c2b3f1b575e103675428cb8bed77a9eddddecffcb707a36cd7a7169e8b04b627fcf42edbf37ac58a1a590bbd56439f27579f919ece6ac1d6f94804e826c268c5782f6a30a9666a0c3b6888f1d2dfb698b44ce5db79b3840624be38eedd7773ab24d7e0ac4a21282df3a3e918fc170a95003f6581c3f362326b604359b25bb65306772a49a24666727a7ea2e214a7011efe6a64d4c20aa89a099f96a31b7745cc3699027e51911a907696526d0a0329d737ac464521071ae7f5355f089dc3ec30c91bfda1956e42befdbd18c0033d2f02d5b471fb78c7e4225cfee286538db8d9d1a8bba1e1d546f235b67a8634059b2a0502192a30ebeaad7a96df7b5af2efde31f03ffb6f98a81b1072bbc67c48ae0a9dd2aaad882497a2f4757ac171d58ec6d17d065be4d332216e7e28c7c5c2f304c3bb6adac9e4a13d83c471c27160216f42845acbf5e735c88c10773eb35992a0e99a74b5f9cf95890869220c9eb41515f2ad555c3240f1547afa8626727eafc86269ca07f265d3a7b1a6c5d9a3318280ccaf438d9933319f11732eaeb5385f5bfd78dea163127d1f9cab470636fb8f0b4c45bd917dfe6b18f717b1de303e254e81cbfceae0921ed3a4ea13ffa8cdddd47d98a0ef79a80d744dc79c5251601e3971a96596bedc2c76554b761c49bede06efe4addc7c714af90ee2f538510c3da4056822b1cc9b6f05c81923ec6be3faec8e0af9db3c60b864e70a0fd8ea34f947e621b095acfcc14d86d46b62daee0f291a4b536ba1b24a64ae30f09ccb69595e583b499e7021765cbf647441717f1fb3b3a593ad9b4294104aa597af15b087d6cd92862b3145e67ddc1a7968f34a3044cc592703b01c21b059c36582668b2a39fb222ebd92591f524039216747539acf5a9c7ef00b21d4a2b54d4bcc7b07f76131f5d9c399336b3fae9fc2843c0cfbb373ac2b958f2ece4fa67de7d5194320468acffaad11444dad8957628b0121107d4093b6f36b8d3352f6799722bd30fe661b53cbaf3dcac1e8d41382071eabeab2ef4ec956eb8745cb762d1a80fa976a437305244f2a00d37aa426b026f915579ded734df4ab05e866a5f991924d99e7973bfdf8deeb95f4d7db1b546cbcb4e8f902920108b9028d3956eec6a4927aaf0803a82519c0cb39e58d80234010d2eef73bbe4aaf8067d905057a30eda694f6bfb1699c66d0a5a28a4d31494017d6ecc3bab00753e1a9c4d49973133b4e7aec4961957ff78cd2814158e8e88439a7c3e457ed5fb937c67221a77f11958bc711df3586b98238fa2f3a02a465d324309dcca3bc6ccfd3eb516d77986d8dcaf720aeb6a5367d8437cc32468a5fd534428f7e5dec10ad2f7a10b3dfda835abf22b30c94668333a6d113365220ee397b2cab40bc61a71cfd238b2ec9150eabedb4a2c1343cfeb58f81b1203f89e9002e2eac3dca867914c3fbcbd0a60467fdccfde662b367c7d9f7c873d516cf69d59a2f5a66c5019cf8a93a881e4d73527eea5a21f3dd31d0e314861e7425014c55441e08e6aa9987d1237c531e060537e938aa2c810a2f6dc5321eaebb5f13e1b6639fed0cf9afb5be9cca09d74aa1ceda4edffed72ceee0f17939684b34bdae5ff7fba9fd868cfea4f4285159ab5341298bc73b309fd427adfb5e450a0696272083a897cfc7538725dbc0670f9df98b594a81a4d0e9d7ed5db6fbb7572e1b06af68983fbb0c9936b5e32e702b241b85a59779163b0fb6a2c94a110321209435dc1bf5bee3081b356f96430e2e955bcec0f1f27baf512559d1d19c8f3496aeea1b90f4ebd125977d794dcaaead99be4d7dd899fe9f8f6db62398d10bd030bb2438f1c099d12549d84d5306a125f3ba84608e113fb641f08a1647ee3f7e69379ce3505e32bc049c93133df3ca97b916af9e2b29867cb6e44d6b95e14cd6c334ac42de056e234ec5b2f06e4a3a646f2c0eac884bec226357ed9fc42bafaeaa4e94642d2df8608d6288b9ced56c87b7d1d7ca5b9f0a42d06c20ab56dd9356fc5139266de288994ec4dcf7e8acf93a26891c3833eb1eb1ea98a028f91eb50208b91eb02c6a688337d3d704d032d159e9c30a88419fdd9fde5e6686062c7c864a940b32e176b64849c083760dc14b595d383e0ef66018b277a143e1a7869cfe5319e6fa2bf8e9d3f4852bbf2df728930792541bb82723281894be8db31c543b77663525d5ef5daa731ec24367a189abdd6ce340661468282653096b7de798a1c7302dcb02eba869c92be61786c98ae7ddfe933bbeb985999fa7388d1b7090d221f559e8f1fe75d890b4d32eeda02981a3826509ed7efb884d7f37731f5fb5a5e1cacbac6b5edc7b76733c8fea99a6c1e4b331d5283c02c5265c517203567b75a942f49bc16279f66032cc797e2b4acd3fdd224e515d68354ddaa90d1bb1bf5e80c360ce6a6738433a75d5ffdcbbc4dba915b41a19c64ec0206343c3de87c35dd05be7fc8a6746fa79afacc55a69c5bc77413c5a22a33c213256241c33ea6cf4143db031884096cf6c0dac84048fa752d1613a836adea3d2dbb154696dc773c838412f0ade098fbabd595332fd5c69b279c2ff87768d7c5c0efd18a5bd8821660dbc75a2c826854c1655211793b76b9c71435157924370a28dc1a3ed7bad228b81f1aa50c620b064ae0e9a63622e1b6b1ce78b753569128b138a4df961061278e64d61ed5ce215fa17f1173653b878900a135ed2559916d888067b94e49d88b55927d44f29da8c1eecfca95867acefb0b66eee8fa094a866fcbdd6e6aecd4265f02aa233e0930d366d2fa64da0ec77b0513c141092e9df03a6fe134a3318bdca01f00421a02b21208584d0b3f2792521ae1e693aa3342f67d788890001e71517851d1003b2764ee08ad0ab28afd601ed2d098f32e4a74aa36750a0e9dc2e9520987f1b2b2acc47d55012687dab23964364ba7af377d22fa873932127752de88b180b70ffff5ebf9fdd660009000b03b736e409f8c24068243c5f97520ab294846135c02a0ebcdd9eb2df2280d278a32d26739885efa9dd4e4d59fba2e4af724c7e15e30343285d3dc1b568ac30b51e3c3363835db3b469bc410e81905a052ba4d524fad0bdd4745f3c608aa94cacdd4a058b0341e4c428e7c253b6e5c6b6da631972d54e77fb40ecd0e6fd796a0f560e2b668ff7f4bc66296da8943396f9a5e7ec0e98c3da144d27fa993338cb8a1b2aa7e182391ac60f72ceff09b0a2d6f24ac527cbc8627df9a35e0d84ab036ad16329e009b20b6f79b706beb2e9ad46165dac00e816170ad4a96fa64e075c274d540913a879233a2ac85c350793f188a8566d37a34fd64f3a650418c35ee8be71b86cdebc1e766704040bf3a2d4e1ff4ec54cea33697a6b136fe29df80293e858670ce1c39740597d437312772811e49ae20e66fcf128bc6d6be690079385f82153d60a9de66fd6735204aa20181982ab8e88f170e0964cb46f5eab7a70369885795b153294b4ec715af1b85d509df1da54bda1d58f962d7ee19ef2adb82c3e29c0e9c4b88075599abc42f9080fba43e267805970c010b4c6fb95382d37e5fb3850cf0eddbb2cfa7675f1c45fbfaf7e16f41c508be73a82a017e214da23e67b1826457ae32a1802ff9fc4b29b157e50a8c449f58b111580ed834e467ab389af09b61090ae6da8a47cf60481c5d1e08b476a10ac9a211124e89dc6a9126aaaa5ade7157b30a232f048320c26a240695919916e13d7ae70974e08f85cc2474624426f7d3da8563222dc8cd058a54de41d313469f8e01ee031ae6fb6b90bcfbba1e44122707b4a963f780c50da14a32b04986aba0b5a61adc4468e2645f8b935bd7fff3d713f002162d1de907afcebf6137884e0b15070e2d5a9bb9210821d332a89258f25e7e028610008bdf21b58a1b4e9b60e5adc09f7de2f06191f0af4a0583380c1c08bc37d5e27b936895e6d2410b118eabd6cd85d639d818ff557ec4eab3dfef350ce069db56c3fc4873eef3263cbe5a0325fad17d862a5f739ae44ffe9e715d6e0b0fca79f5b05e3a7b6519472a6515599549ee1020fa96240815c6cff515c499b9b64f8002552733a8ebaa4c7b4d9e473939c2dbd636da9fadccb32eff81e493846279aa6534cac3544568895b68f4db6c561833dd58d6c80aff50693623666e047e2b7bbc80fa39c0cab7317fbf32bfd708e0bc35ec2f18c33bb57ab40ac04cf38a965b5b4003f3d621f8a8f9ec0eadf9f676bb6377dcb4d37d452be258ea7da2af5a9d1d1a2deb82aa8d11d30e4b5e74e605f96bf353f090059f25c57c29e5302e6a5b353e0f5bec33540036753163216c4c0ef39bee9ac19f7fce2c9eed19e69cc16057ce27ef846a654d8fdb2f48b9b80b35a993f0a93cd6bdfa5ec89095a38b16744a33f9ab66d2b97d8fd096cf7e5b4a2023c18312ae590226a3e4177bb8f400f48b935560522fa1c61e212e2da0f399b761d9e594d47d1607d6525a9213eb3eaf58e5da59a7b9d2bd7ca085349908777fcbf9067a4a38b8d66ee70d323790c759f6b1ce7f210c370bd8ca97ab9f7ad71a849d23de47a898f28e66e6fb7e41a3859107210d106efd5c7d14c82a39e927a30e4abed8617cb940b8ad7d6b2b186610206e37ec78de87c00941dccf2a804b148260252dd4f6a70c872fe587dc86fb6c42fec94bc231e82cf5d6a9c1bfd287cecc9f2d477d4444fa7b219bd6a290bb02f55d55e81815bbd328301978cfaa4d31d2c8cb3f5847268b613869b357371a7faa6d8047824d72dde2283d097955e9649b6bbf184584abe0b6ca4541d6de24154ac74b34fa0290cdd74c9e4b88e54136cce9d79bf57efd92a2892a2429b0d6fe4f286c2b135325d851a91214894c75a5312f8778c2114854b8335f052828317e69ae0c4d672322c1039879313c426fee5c96b167d1adc0b6978b5192b680592c860098b0af29bef9b7ff401c5e0c2970682991148f20ddbaf5e405ffcd6b56930d161aba1973ab18f55428f591a7721d66d81c771de8f7191036b85106239e6680d8524eef9f1a659a22374da04c59328d865a30f88d482f47b973b4a83cd91db33dc516a2a0dc327206c06d8d1a0184b67e714be0ea6c1542b0aee3cd5d36d72072549cbacb50dd67efb67f42e0f48bda5c66ba88b3299dc089247576cd53b54e489761586a8ca8e6221753324da7f27162b49fb360c58c6b8539ddb4c6441d9a01621dcd81184c8976540c1ef939e850c76d2ac824f254e051fb1f3920c7ace44707c8846dc38bbb6d09d7cc36f57ee82c689902d633b3a1af6505b5f397ca1daaf6a5b37938616900772a9f37b028fdf34a95b8a78f3c73a5a2bc4477a7e4df59dee205a7aae1b8f24c94f1f22d18d00be638d27ace239bc0f57e106bcee5ad38a6e286a788f493fc9dbd0a596d3fa59be3021671f54692452b9be03d98c8c65dba91eeb0bcfa1fabed4e19090f76516680dc47e43cd3bd58afbc6e7b0dbe030e69cfd4945b80bfdfb97f44c6d0ca79562ddc50dbb39ace724f6d5aaa5c2a177a2f5f27256bea21d1338bbe1a6ae9c99da6610615c49a2b3fd1a88f2b662785acbe349047bd299567d8e48b8f64c4df47290edbe22b6001e7628647cf6fc93fbb6b6191e18ce3cf428d1ec858f5ab9ffff80bf16ef194c07cb2aa15522cf3c9a27a4dadaed7fa777dbf3dc7d804373c03f22c9e9125503d35d7c18bdf278c90e6b7a6728860ca6ef74825282194182021c65d10eb641f958678662f6dd5ce3483d7955ba87a1b5c9e63afd41253d7ff2c6515ecc4d7aca08b9b89c40e81b75e577f1242fd4d9d0fe39ccd392d2fd7fa5e08fd4000b32f9e4b5e9bc1a62ea7ad7ed236574411d38ac06b6a5f26ee93cf86994ee1a8ddff17cbd9c5c49caa074ec3f782678077edac476d0f330f206f6d5eb0b7f31b8b9d4c7e37551d333e8890d2c5f4db8261369d08e04c614921839e664a44e1e18538fd8cd22edb96442793bebe724e9436026856ca1b6bb0a920f2bb3e199e73223dc6909a5f2eed8edc3db70f45f779ef94347bb0bf7b10a12b94dc29ac2f7061709f8008ae12ffb098156c6338cd574d11ca116855d54eb5ca6cce48829736405ba34802faaa4f1dcd2756e6ce2fe9550f5b8f328e23870d2464e089b20c0e187859c4544f72619867834c08cdad4f22ad0bdca8be9bfd1c0c85cb56e5acdb0894158a124edcf85d129ff3c1147304b34e51d5e6aade843f18207e3b6bea82125ee088513424d076e5367e0f17b3cc841935461dc3c5c7c547e64f0f4d0a2fea0c4ce3fb3ba39d03e2d4d35519c35764a1f601ba93e7f2467f389fff675b9ecd1a33fc5d00902d79a89fca09278b9a5006b0ca6a3c74c46b4d058b6464793cbe3971785a078bc9914d3a788b03f73a159f1753fa5a876adf28e9b155c831e76ceb05e8c34852b8216f23f11f8e04f9e400de9c144d10e70ca78f5d3317135a2c0807cc579c1d38a5642537ba0f6f2b09def84757e48ad8134bd8981f39a511000593cd1c11db1bbd1e8a141f5eb8b39c2913d1f1277df92a3f748dda87f8293ab0e94d45594ab91f4e781cb46c1086f1627d3420f5a9187479bf1bc3308e7b0088cd56868ba33148c4adbed6c3fa4ed10015aee04c45f4cd0ea2231b07c2fbe464a68c81ab3b5104e6207d31c3f184af08ce3905de588ed582414415f0e78e57cfbc680f52b96dbae94dcdfaa2bbe439760d90f8b017814034771c609e5c23d314f0a42775e69edf5fb29969bc2753f9e549ebb60cdf5fbf8f25b79cc4b8936c57246cc9c9a790b90c670f13a0c9f5ed9ccfaf6483e48155562b0ae059e508342828a36c0749d2ecbff172b3756f8fc6d716b984587ca4d6e1dd84ed43c71fe7d1e237e1ed48d4fdf8c52064dc429303d885652880aab490dec7b8ffddf166a1f028045ae55f4bea5fcf1d8767534735ca52ae9cb7ad3aa76033d29329afe02187d272faaf3402bed99c89136572a1698d4afdc47fe15e4e5fa7cfa5030907d2b571a45f6feec8d968440b77b2de17ef03b7ddf620906f2290b3f958162e3af4a7f1fa98b60efc570c3166bd129830587e0b1ce9b0112e5178083f84a597577125e6a93bfd6606c0fe8d11d02129e7dd265e06313bf07abb015cb2899834b82e2827bfeb17a506dc96c78c06820f2ababd61e74f3dfe3510f69cde270e9b9016809b768c64f088d6716a0c56abfee69e6d34ebfe31962c698201ef1c7e56fbecf2e34d178afde8accc77bd03a598b20218d472339e15500bc2190151727d2aa72a410edc3319af8a5e5020fb64469f3946f7d89050cc8cc9bb68c2dab997d4584379df506bb36710a90471df0d5366f645a61638f06d79f74b8317e126c1a7014deb02cefc595092f49e42a7e447182d03d15950fd9bfd3b2b479b3e5c765bd5b13b28c4611830cabb0d9788294b61312c6b99f9ae5b00eeb3918ac70a78a9cb8e0815752b6c0e8fd1f3c73b8540635ec64bf2d87b43e6e62e029ea2823abc237953fec79ff3e7bd5fa1dcaa09cc80ed4c1e9ce2c722a81bb58140a431f82cc212aa2bb92546ac6ce4bfb6f190a7b6acebd5f7def3a370ab7d2a1bf7e0e95e04c1b713213209a4a3b26c41f70913e4911327ff4d6ee0d972c319e08de46976dd785a989d8b3a9da265014cf01bd3e7ff2160c02307609facad3a6348b02561525b7ebeabce43037a7b61f398591a4cbdacf6ad180667c1d7e07dbbfad522106da63b77a3a16a22e70dc64d7edb400349f2a172bd7528090155319225b980886bbbc1631bcaacd1a59c778b21ccf2650991c55b183566ce5a84b73f71ccb6a20722bcdade23ffa1221ec4726f949e303e9fc8b763785d8f36c7b890db4b36e56e1cc4be974a39f262fd5dd02feee8a55b236f491900bfdc9e1d1ec83127a2a8395669c43cd8126d74be8d20a674add56728e0ca6236c2c4c320a7a7ddc2c604076473febbcded55f8c2a8a0401c227ad4e237471c8a81aa09b3d12321e5fc4d6ef325c088e0456cea27d15f792e1035d4d4430d5a78627db4c88f74008c0b73dc1caa71e84f676b6c2f8edffb14a1c9ce97bd35315b4204b18fe910dc86c56e34446b8fbdf0ae6ff9dc24c9ee010be8356eef9339eb1713be0943555b5ee9eb5d385df966856e265ee649159ccf777a39a6702d165797e506aa89ae80411804cbaf38f76fa5c24007186ba0fe43e0638af88b1be0f12b4954fd7a077f2c1021d1e507c34d5c4f3ff49164a2550ef0c55170431f059467589196f50fd0827e020d779b5b3be02484b6c2a91760eed6d9a78c0f050d6c2752836d443ff47aee2bfef37902e917a8463c155a5f2d2a44a75b1b91d14193937776c397e8b3c43a9d1666f679ab9ee10a41956a3d7e5900d45ea70c382e99369ba1ba96480c731b56b75caef8659618e9e81755d6a843feb9e83fa12e561e35946001346af2ddc12b72f71bb94f53d9dc2788f632e0542a01e779230e2a14df92b109f4f390d11b2e407b3db9e4c241456568f6a019aa3830daa578e17130fd9bf3a2bce0d40dd6daa3a6329a9bec5a3b12e2768d05c485dbc07cd47c439bdc35ff3ee9a0ac36e70b9c483ac379823e97e4d653a6b60b22febd842d11945600ee5c67c3d61e21afe49db1be89d841fc265f950d81478855ef83b4e647209ce9bb4f226b00d43e72c8eba84a0f3a11c8024870ff73ab68c3dcdaa295eddad042b921e468ffce3999707bd34b9ba5316659117c5964185e49f8b0f3c548fd7d0d859850829e587336fb65dcd1c8d8ebd7b698db9cbbc983897dbc94656456e92544258ca3288cf9b9935099f5c75d0e6695b7c8fc94077f42685287a52b65fc62df692a1f2829617e8bf3e02e39492400682b31e0ec4498ca5d84e411882902458d1d14bcc853d5899d9e57d25fa4ba27ee8289d7332c7e30cb4e8c05ed7d17362be3d1b7bd0ea7bdfac689c8cdad9d871d7ee0908c74d8888f429e41ee1d2af67fe234f9590ca7a72c4ff666163c9c23bf1cf34e1af833c8b214e4fc676e40404a005ef956f6682abf6b1a56645c34127e8d6bcb6d26bb947ad3a5a0f59e8a9416be5f305612b68674d325f7b4f1bd4b9e9055da0051d3c25c2e436d3b8e68edc86163f49c19f0e081e7713aebb815d92205e78eef166898128c79a70db73f359f515e1cf294015edf8965bf37dab32c20d6e193bbfaec068b568e0ba2f5a02f10ffe186265b5dd49f4a310a99fd5f3d3729fd709306a46917cf2e8781e024fe319add94895f14c7018e04e16266919880945b6b46191e38529f364692d9579a9beba0546bb05b62303486461748a3cc61113a5d2c8fc9737fe70b146e03d1cfe83d58aad3eaad35e20d1bbafce15c7159566a29d899f184b01f296e2657a5751c42973a4998260f2ddcb80fa9990101f9922573de9b2cd6fb3a2946ae4dbf49c0971ac093510190d60183fd837095af2654f80802d6e6afd1dd1843e7f0356d93b857e152450c342aaf0adfa2df6b16e9ce97b280359149e75edb12ebd0262a6caf0815702c4da8c551b1ff083f6b20341bb172dbec4264fe156ab6b8432aadd791bf3c6ca28aefc7f3d1b6834fd6adaab715e70c35046833abeab9e6bf81f30f8a3439a657250d4ff127306de42e64f655cbd2d23f82bb876ab04d64247d9b29baeafa26098a5836633abffc6ea422692a4759b73686c4c7a8c24ca95b2138eb5d62fc45c238a783fcaaa6ccd1b5f1168c2cc28fe18220f27a3075be30a5cb786e9acf9fd96d9fcee2af3bb10979f5680f339681d6033766cc543e30beb2e5fa5220df43ca3b1266a793ea4eeda2c3dd02e4eb45af3d1e62e885bb26e9d030f0bbb38e568ee76c7f60ba7d26e22ee38ee952161aa16c0b8f7671189b818aa6beb0f0e38a40eca538d10b77af6ca98730618dd03033a2740606b32615578d92cb26e08165b251b89b1904ab219e8db8f0e0674b441b71aaa11473aa5465b0e2bf2e34c925b0345d6847fd03aba2867948d1a0875574c6c6f244749a955922d39ce9f38b3f2537e291f1dfe12a3b62742c69f2c4a29244dbde7ef59803f35d76ce31cbf8a82cdf79cf24eedae2f69cd30c12b9e9e7a69160c7604cccee9f3a0fa5f9ef61b33f1f130b77993d2b803d8a4dcfcb8481d8dfa9994187a8f14ce321892d9a71f6733a909990b450dd6e300f188dd61060a40df2d7d6979b1ab8ab95a143e2463614b84727dde08fac8140009a605d81638099903212d2b9081baba33a093b1497d9f48744a73d36335027176f953eeda6e76b3c594518dabd97e33ce779aa4ebe479bb57ac4969468cd81975fafe2ad8fd83dc741c1faefb01739f79efb9c54a5911ddb88d64f1825f2ba74fc659ad5440f1d6b454d35586b420883cda5ecc3a55c7f8583669e9d084f966bf4bd8e103aa009c5912685fe7c68d3d33ed98d48e11ec6b49a389642c160b25bb09340c63a405c90eebbb2b2a9070b0f6ff7b9500542c064875e1b12046be665feddd741e15784b8acb8a39058460297d3c0b5d675993fdfe08f7f400cf6325452661979f1b8537384443afb5ff77439141f3305d58ac624dac5e0739d1b66f88ab2dace10bbdeec119791388d1fbe0e68d2268a8e5deee5d44d7373a73b8801c5d38374785ba6bad2ae40a6681a0f778b857609dfb4a04ec14f0624c0d27e53f5491d7f5034070c35744cb691d44d892ecf2c3c7e414d4cefa0de87882b05508bf31a66dfd5b62bf79d9979ec01b47cae5af384252c193b42a25a34e2390b0a8c404d5a3ecd380b13f4b8972070787fb109587a63d720cae86d28c8d0d164040934a00c32467d8a6d77895a488e5a7aa90114f06df7d02c859c2bf8067110cbbfe0d04f08fdd638628af7713b9eb6dee0b4a6ba230979ffbc08c026592c13103863243a23c39140c8f5c4464cf87c39f405bf0ad1c0e7a3c2462e60028c974451391e9ad3666443b1d58b4a85885c6b89e18a709d9133579015a3bdeb79e383b7dfc9d2327213ca86e4a150c9c03a2e944334c71e09e39a1ea5deefcae966993cfe8ac16d2dee09e4528c90bf69f4feeb252ede40ede9277d7e8116d66df20ecfa0c90142969ba3ea486872871a540fe4718e0bb296832db22ee6828f259731b1bde0483016dad6318adb1a0115b8f4fb877173fba5a950d2d7f7bef09d9352df675e6bacf5ac95fa37ea85acc48306d46c6b93f5404c7ac71508575c5b169454b5b8c4a3487d9f3de1ea1bd3b8a1e619061161fc57ef1e65f4eb813a280c6e5f866115f3b1b54361c39ba70ea2e0ff9823cb95c12c5c399900a9daf91f1090071fe97393f4e576687186bd40c99f3636bba429adbfd51e8bc6748071b20385e592283a5b2bed32677fbf9de374e475ab0b78fd9b9454a0e8eb05f6d8f32fb91b38ad125c276151c4046b3246615cd1538cc430c65fefab39e19d169fbcd2672e5b4e4500927654573efe2ab85a520cf3c9d56286000a16b06e3bbaeaf612a980f1aa1b8b35d382a35fa66819eade14d5315c38fdff1516d634e7e7a44145f66b39e0d893df48ac6f8c2d7c816f00032d49a8de260444b6ae409e21b44ed56ba8a87cbfb958adc144a11585f98261c25f6222213784d2ad0c7a8261947bb8727c96a1b2947b272d3a8f9b61258708003f2324ab9a753ba17bb362b7ad13694471a9d0afe1aec9d7a5dae69a570ae4b886d80d20f23d75ac547edf38226d302704ba19a7ee7e65e3ac73477ac683871ba8b7c426c07a6e7a907b17fe20356ca4d9d2163d380aa73512ddec28291536632e48b9ac6f7eb45021d880d6a261c85024aa6cc99279b4e1e09743eef374bfcfe73dbe1105fadf130009a21fc03bc1c9d51ef3ebb1549f0bd5e622e993b4b52f0d24806d0fbd4f131c1c11994000bfb0bc17159b36969fa1175c089d91bf0eda4cca0dabce98db38b9baeeb02709de7a9d1a9d8dd08a360bb633f1656f96209e9f76d8f5f9555002dfd6b9235bb576aee42821fc3114a384e8d3aeee906ce0f985b40c01242c2893395850753b60aef866bf88f9c6d848abf9f3d69c660a84af4c5f12c04baecb94dbf4776aa75f0c73013b5b5b016ac56ef8ab2edd2024d0941bb0f81f6ab45706b986c3dd2dedde0fafc3168bd83c48d432b2153f0063660246e3ce9b5078d66f769236c4fd24cf1cecaf61529d1f1d90dc7da94f29b2e4aa2608c0cf0855a95585704de29a37f0cde89ac89f303f053656d1b0a18f514b4ee3d0116a1d7cbdd8da21153f9e289ec9659f542637a7d7798df688082e40f9c911c55a797dd004169b46786eed1e4d7d879b8687486c37a3c3e07f1e303bcbea087e26ba5715931ab4576ccb8a306cab85936e0895c567ed299f2e156689659c2fcacc888faca0249364cf966a99ac6e92ff8d2aba6b9afc88710891c9ac4d585151c200e7d8498d4fa57c94f5a4d1402023fd8b39417e3d18812e9a9f930c6364db2a9f0a3b14dfcafb8783b0a25a2e2db3499d3df55835974a8230cd96f3f9c5cc84f6087ca0a720d569a549735661a62a059cc2291944bbd9bac7bd379d58ec38664a8973d3c154bdd6fdde16aaad1c2b59643cf3897f638c53efd7092aaace1129839ea6f451f31d40b01f04c13169baedd6b3f487fd229bb9295ed874c390abce10e1c5628d21a3375fab2154bb84771b17a566ed9442beeb7fd8c216b447547018dc33af7e112d14c27e2a102934d90772acc878809c4e915e2f683706b65898eebcdd2af6e9f6c3e16f0ad05ea389d231a4c913241a837bcc9d82fce6b99ee0e5cf36f8ab998700c5c94e895dec43ae92262392846305105140298a65543e23cc9bcf510b3b3011683e5f97e1cf304ce746602d80658c4cfa5bc1fc4a45f28da3289eea241189dcad1e3a9b36dd6a381942ff328dd5a1ddbf65a55a2a53dee32914c707f7b1d4b5614f7be1b7d9adbabf2265ad298cf7ad3c6ea223205e894f92cb90561d5b8498d2698245803ccb18660987d8435691cfd1bc7d1b19076f1dce14ddf78b59e91ce0ed79ff960289d5b1c3aee45b0ee792dd0c9127d871b2f234f060323e4c227fb746a0245c98ad87ab73041b1e160c53d75e0085fae50d1f69e8f9a351c713f8c56fa7c1a04389839b266b70c9b1d1091aff177423b0d53e8d8d90b7dfb98c388fee5fc205b5ff902910109b9028c39cd2a02030648101dcf36e95529f3a21e54a46c38cb3ceafede164f9afa3ff9d8b0ef3ddef990c55511981c920f94f7dc96366cc2c35055e29970a7a4d9520e96df228e498c64f6acc6fe90a1bceba477bf22fa2ec913c2797f6c4a3cd1472448a19562f066d1a2a7c68db1b8d8e16ba9431d328e37f8a44b5cd26e5c6a0b995df92413eb6c03b043b6b2d53990e1aadb52e3e591ea7dd5ca4d91598a132631be62cdef9ec94c8bc39c75a7fb016bb2cb6ac32c6394fa679917e55939f1b395c94cc8a79a8acf9aab475355868cf4d31efc25449eecb9ecc1b6feed3df13c1ce363a486f08d2a149c33150c2e7f2f0982a7d41e34f9a6f65e7f376795d0747124b7b26e3ab8460d4fa4dc584e7398a67521d5c63bf590df9012ce93af4b4aaf9d9b7d2ecfc6734caf48e6875e7128343f461361a136b959042a19a485bc9c5b21267e9bd67d43927ee6b006770dcb5258a58340c958e99f330ee21edad2a91e58d84cc55ff65dbe1215fcbcdb478deaa03739429306875b63b51e8cdb88cf49ee7bef54f5875e208e91078316f762efafcd927746dcff3f1c109cf09849ea0db37672d854a4d9e47d99d41d3fcb170449bed64d64fac96691da9cb9f9a77228a06cac101f4641d721d3e259be40a0b227f2d977bf78a8e802afc7d5848d82b2289b8c2100779bc609e3eb12b2464c76ad3b9d70e9282c57ca546cfe0f1ccecbadf2cb2958c5f94d78312c1fc94f809a74d73eb219d68f19ec8d77439cdccd2a7306655468760fb67f5bdbf27671ec624985cefb9006434351f5378cd309d5d052d3ba748fbd8cd5c73b0e1a133281da49c7b223e6cf779299c7696e72fa09fa54e0caf0d2762a19e6a23b72d4661ed2c172eef26cc9c650390ca298c2f6b74cc5f956b45d4d5ef7550a5560f91eb50209b91eb0e4b202210e28fbdf7bf39b7f34f9f9b14e8a32aedfd1aec0cc58fdf069d5cacc6f5890973ff3aa006a58299ad997ea373a8a55fc81c9619b9aa9057fbb4ef8ce1f73360c9dadb3875bc8a6f09dc08691f10070e7dcc9cb55d5e5360de5930425e376b7865a1706f8957464da7225ecb8c12e12f092022c3447cd811644eb18d15046473fba68a631fd1b1c19603c3b9fde27cd4af859d08825055e420b4b08afc2e15e54c64466dff2b1b9177f785d9658bc7a5b35cbead6e836fa1b4651f2865d4ebd2a1a9edb9ef8f78b80badab5b7e56a06fc7ef478f42efc428a4212cf927e9ecf9b856afa2a34df03eb229607a03efe3c43079bee7353be8ca53555b5a358b594c7728e9b8eb1d6dbf0b4f763d6216141d30296fef352fcbebf97af9d21e033784a6ab2eab3fceec2b16f7aba7bf20cf3ce4cefca1969b0aa001c4e62ffd4e296764a1ac4e37899171c2cf3de42a26d02033f4bd8148c4d8658dcfcc187261b4aff7e5e565b24cdac04bbebc92b03b0c46a77bffe433431df6c708400340ded522825ab461d8fae589b98dbc79651267977583390221842511c589055bf582d83e084c178755c80e03f1d46c2aa8a25c39e2b532416fe628dcd628c22a22fd6600b15c2bf1ca609bc5d0ed5d6b970104207d2196866cf4ff92c3ebe97f455ed0139baf172a09146680db7c477859c5cf99088cdb56c4600c1b2db4745389850aea95ed33eaa638589627f42d79fd54612210307842ca845b89c492b5cd6e211cfe53a0547a68209c6663be466f8d5f8872beed5aa044694d236ea32ef5dd8b8df681fa33f6888b831e10b8263181f6fa7f830c3c3696dc23c3a97a2ec7727aae808dbcce37fdbf7e97981b8d5eaf930bb0956f7ba5de53b7804d771bd2d39fb4a704b0aacba836280f77e6a151cea803cf12954b32d250a6ecac152ed59fd55afb0e3e0fb0d79fe339fb10839a11476d681d1d5960e9e894b7626fde452a112e6104db8955f09bf3cfaa79ab78b45f9f87fd1109f2bc7f1e3428575948c0fdf5ab22b2d757f00344dd074d71db8d95d945bdc0cbe84587f1e715adc4cef3f6d7484a30ada2412287670addcfa415e108933ee70d6fad40a8097604d50a523fd5665e0d046e9776d72f4b75427786fb897bf4518a2d66afbb8670d747bbd3d93ffeb0513c74493f4b00d4cfe557b72c7e95c62af20ed41375b127e612db3293914ab5086a8c08fe39b15c39c52715606cbaf653a54b65787d5923e85cec6c40db895729033b8aaf92e2304b42864bfb3e3db4ecb63b336c4f66cbc4f6dca7250ac7bad08b5e23f6f110a58743f042e2b6ddec68b1f7e42cdb53c0a82989c8eb3ede49853cea557ecf6f4cfec75c40594f19c8ad5e74104c2ca6177480e95f857af964ab942960d8787cdf23343dc7e816920815f48cede26f320920fe942f35a36b79ef8441e3b41822efe015f97eb83e84ad4636cebda648ae2fe4e11132bfae4d99c5adc57414d37e67a2567f9579463d5b6a5c5560c58f2b3e8e0f60d0316a2725a455fc4f66b121485cc925b870c056a8c3b89b8bee34108b3226e33b377fd071a56f4f44ecdc42bdd4141b4f980a221759feb55fe17b841098157de1ab9453335bc716092e8442736a75afcc88e375ff5c8e6dd23c68910b5a79049ba6ea28c41c29533355edc3de14dcfd53ea3f3520274f8a47c94b303484c00a6c2d50c0dc8efb510e6ffe708eeb770c5959055e0153ce8faba3fc30801acc841ef01d110665228a8b50ddb93dca3cd430543990aba65bc7c68a7430f22c27e3f181988d0b8ec548ddcae57d838be944aaa5ab15e73216de690b3c79d59baec583b214b1f44bac9ee50f02741c7c08a4673b879b6e4949d60b5271da2973ffb469d08276d0457efba6c5e9f6585b1981228666a6d0909847570a0c1f85ba1f39169a9857a23cb44ecb105197bb50360f2c27d9c447df892f8965005d8ac3bcdad717f80d41308856480cd659cabfe119d14ed577755dd5a1e595158e445f48e5d4acf1a1c56da8ace8d99d12ed2ac738d68c9d9acb16f99a7f5a9a7ff931f0434d4663a271a50e1456487384e336a46a7730579a39d140deb68851ba25d487d7dd51b0a6d9d511479a4dfd5fcb605140eedf6e08ec6cd4a0787feb784d8d805e85b1616bae0bfa45f6574a37dccafab6d8b8140daa500817df20535fdc652c525613c9270c108994212cfdb9131f00d5f56d07244527ff1699aa8f9c7774f1719850ecace20b9c4b0f767477216cb233cc454e4f512faee2b137365bd08151e28b19c2f46492c38ed3a50269f7b698cbb3f275380e173dddee15c27998cfbbc67dc7a17b93bbed128e1c013c959bf47bc869247577ada5ed55686b964ed0008f8661c8fab2f6eb54425697ca4d0594ae03099abaaa753e6fda9b7c75ae7140977769538edeeecbc29dc7e0c67a55f460334f19db0b1ac1dc2b08228dda5b10fbd78b201bc2a7c40130284386c7387c613aeea8c5536c7646d052d29bb55017878523f5dfdfea65b993a7773407e2d15c05e7fceefa8dfb3916463894825894845ed0bfdaf9e073678a52dea9e604f2c106860fc4fe56ab1eff9ccf4072518cc5cc6e47cb92adb595173c5fd27aa002d11b8290581fa073df80f881bfd4f4e1a8920d05bbcf772acb6f8a96b4691315f3bf6959d635339af25836e97f781b370c0cd9f26c2a50992e11a6e5c39fff070033d750a4b2d0785b0f03e824a0105973ee54370f25f2ac3697206b8204045e0c1c2cd32aacf81b7bee7a407976ba3b820347f1cafa454ffb4876fbb35d10daf41294e84eeaa6eb28b4c27b137e6218a6ce53948a0554652eef778aaa1c36211970833bea46849e80f04a684ed7dc9017b40d22f293f93c0b503c90e411f61652d6fb757191ba14cc544c0dbf29a4794533ad2f798998198776ea320c519ee3ea84c8b2c88bd06ba87f43001142ddb431f50c50a42d7a7f940c4694c277819bff1ad62e70c33a7fd6c501276f78e5a098681da5d597c6c6546ced3aa4bc92a4de67ac3108bb90c8988cac445b5e0bf924eb1eda9d05885166c4979c4e4356648dbe1c017cdb379f3b44cb5e086b1e4a2d875f0f22ed3d3657cffc2862d03781ebaa0def02589193683596e6945b801090c3a64485fbbaf1db2343fc11b39baf49c49e60e956064847718545efeb9f94f0504dcf7b82491980996d70afa019e8dfb2aa36e1c71948a075cbe9a20efa68ac3cb2e54189719cc081e35df6be545f1f21484a0799a847e3473248dc82e99544130fee317eafde20bf6f06a05e77ff62778521615388ee3c1b967456b6b0b3160f6c279b09d36466585cc225483568b26888aec7ce583ab1ac7f35ba907d92181461b42d951f96d820832e9e53a53544ef26f4cb2188c563da1c08fa021641fb366caaeb322fea63dc88960b4ed18548fd15c3a99e38f6b1e014193f650d605080ac4b1505b8f2b631e967d97e556ddb184d7e7d0d308b942af30dfb257c1a9721cbee2eabdbd204271b07c5ce05381776ea2521d99194a64ea03d2fcfdc6415f268ce857987fe145b38b0fea498384ff3e269052738b125522195bb8900784600b4c872419c65f72bf8dbc2abaf2273f9754d77c6d78cab073689df382b2a4903bf9f57ae7dd3978192bf65aa706bd77953dd0ece9e261b3dbb8b4420323629a53575c85adbfa02664796596a78ee94449f5aa889e0ecf8034cb627f0b13218a9eb47b75178298acdd5b7a931bd1f0c9bbed148724b1d51312d2ba430833046cf2108dd56fd907d1ffb8aa340908b1ded7f02d741ec30f360dd4d852e9318a84b0f2c708163e11daaa13d016436523e212b157a729b2ceda2b2d20b7a01865bbfdd25483c2e699301591179d8fa406303f9535ccb09a654ce191bda4908ef4e7d098ea237a031284a51d0ab47022eeb002ac2f4ec2cfef54682fe050d4523c890fd774df0729c2d3b604729a8dce350eeaab47228e3d51b0d4a14703c8ea143b3e2f4c2d12a31b56977e59fa60099eea0bb785eca2b3dcd897ca544853e1d14a3c23f46a53cda0dbfcb839b5ab7f21b922c1cd3f206738b59b6361b544a656cc2b99a65ebf5b5c892969641bfbfc02fc64e9e53ed43e49a3c2d1f519e8bf6855ee0ea1c33d3db374e9561040a218aa162b9edd2c55cff4431048df15dc56de3ab877ea0c69c55baafbb148cb75651716c0e9055f2f626a0643b05d913cdf0175290fd69ad44f0f7c2402ed23fd277c4b40043365df0074fe472a809bce3b83fb3c7eacfa62cd920e728d9531f8d5d25849da39f06a0ccf57029b351b19ee8c4e2e851eea50fc315a26aa88d3c800036eb23201b70bcafda9cd8fa2974579d4f5cfd1bc0440196af2e8a2035883cc219a0458a9d974fbea147c843a1fb27c87267e52b1051795fd960bc3ad87401794b383844fb9bed70d9b2c786464eab99777885854a7f7cd1bfb83586eea5a1abc1f044be9816e0ecec9f0a121bb24c64fe2de62027f8e6c50f7bf397c42acb38ef78320cd661c2e422ac10e2672d018b56f2df4cc582ee1e2c4c9995b8486cc2f6cb22358f2243d4f20f47c245543b6170b89eb805665e8323971a6b9ea80efde7e87db39eeb5a8130164d1d4049e17d36590c3d09b29f4c8b47ad187a1e5748afdf11f73f2c8976bd7c4428463ed650e83f2761b1bab5f4919f385c6eb5c59111b818bd2e9a9ccbd771078390f11805321297754fdb7327607fcfd362cfa24016339b9502b4571a5f444892d19246ef86b8937527b13271c2f7c108e418e77eb8c7c5773406c4cf4649056af5248f14ca3b72ebed71be5cac4adb58b2d79b6068ce9ce0bbefd35d9748c13273576e2382cb29808f096c3f1a8fd3ae7c44ae2044ccceb1e4dbbf73965e79e56bcb0ee7509043220c640df56fd90cc6ef3e81468f7a014198d085c678607268f984dbcb1e2cfe2c4158f879c5cdf8b4983f595f24cc4ca096af9f064578cf044bb719e8152449e1daaf885aa869263b98e31c816cde7e987654517a2f139281c897d26d0e264791431fe4e6f9ec3ca4f7c78f4aade1b259a1f8adf2ce6696b2c12e42ace4207eedd3d8f32c68ef633cdb82c4999492d17b2c5d0c57fcf4f4e3778e5bbda4d77ab034abeccea7ba177e77fde8cc2ae33ec83964f4bc490c6d3caab26da1e39cb107f1851b4a02f11e07334897d8a1efed3a9ac0b75df7d94b95c694b83479387f908288421f0598c6a0883338e8ed9537aaf21192b69e46f64febb461499e7cfd57c49e32593de8ad625c4ab5ac1fbc7c9f5cfdabb51cd16c53f0e6f325bc41bb0f478a33b978a20d44cdd917237630899180a6bb2ccf67242ddae372346924fa6bb7ac0f2652b53650f13b376a92dba2774c9ff3f3cd5840581828282698b59e56306565c0c1ec3035ee1a350621ccfbc773940abe5ad30c429c2eb2eea297e0bb2fa51809368fe356becfb42a2f965b3db884355475bf9f27b0641f19dcbef573bab920d8dad600e52806335f86cae0bf0962e199c82f1883cd92d66ba176cbbbcc4c7519f02d25b4c824fdbb7acd7a884cf34c091ceb97a800cca8f78cf043dfc64fb3acc43278361dffd2475050bc38ae746edb417c0dbc1dc81ab2f212456bdedd9ce4643218deaab9751ecc3bab90fe1deb0e04c48ffb45f92a74e00c9ed5a5dd181165f2b0e271c2989ba9ff0d33be906e8d69ad90ef2478e5cc6466bc2cf9bbd485eb6f200042d5dd2f1161685ed7dd5f9b806394926d053657e5b267886502577ba94b737388b7c4d0cf08fbccd6f9cca4fce1fa5f8c84c41e46a1d729bbe8efaac8394df3ef026f4165683519f69926ad8da5c9b746818990f4c66c9f351cb0b962584bb4d58d10507c0af9be53ecc9cada86dcd9d4f5cc1d65bc6f6e5c218e5ca5f6ce687bdaf0f2c14fb5e6f9c17a75b143276f6fe54ef795eca593d94bfeabfa4db0df709dbc8c07482f123504d9cd1d9dd44868119dbed5868c5a9b918dda22eaeda06708966dc8a979ceff8f66fa76fd85e2bc6cd9dec6a3db616dd245e23465b843c40bfd669eca642391dadb32b08ead0e06a0acdc03a2f9eea10de5555a2e88a311d31b09fe3b725d4e275e2dc30a54313eeae0d3692698fe00193f42f06f57b68f5562f11ddd1403f2df2f050ea43fa71c8dc7f3d9996da146a711c8b5557597bcf5dbf4f2e6e092aa1fb7651d6b105aec54d33f3bd32c8fa56b25aa66c8e8cf0a1362c2d2f72a7cb5a51d323cdc762995e5a2f03edac13d1847bb5dc57564fd317c8d3716650661c315939c7af0a8a9bdf20f8323ca7b29022b12efd27bd3b142ea2dfac021d88a480063a1929a2c1af4d485bb3116e964722a283829ad74e6148de8935f0225a75b697648c6127c666274b7c2262cf1005f1ff7cda684d7e9c5f855e3fd884fd49186fbafc718d4c32eac2aa05b206f52b1f79556f7f747bded84370b8e62125d39e5f61ba133a9053cf49b9312bcade9fd519690521eaed8488cc88826f62097d76f0a7efdff6b62e70e2c42ade82a9d56a029d5d03d2e31db0068af4effe6b7915c090a9cdf5910bb91f1dea59259825ce05320f23d8f2d1fcea0209954f23a390a683dcfcd4079312488acb847311be4db5dafba6fbdba271efff7db6e0a5d408fd9a49985e277faf37d452f48a73720e76bed787234c5c53260ba41337596a4b12a6fbf6b55f9afb58517c25f9f5d2ab5c8b06d660a520cedc78755579630914f088e7959f010f1e0ebd294ac7cbcf6425e0a2bc9764eef55bfae93ca1b912698e021225f640a31ab35d63276ab3f04fbf9299f0c1464445f2e516856cb78f287bcf5eda274f0a9c7ca9aec6d6bf596ebe42a44a9faeade640ac0d03622674ad6d449128aba07c25b20171668009a1b012ed711f0362e37c6bbb2917ed7b4dfe74b25dccb8fdb726e90d7fcc0f34128e33d900dbdd5dac9b38cd016ab7df07a749f82302d8fdef4aa155e17ce91a941c88c788d97bd0696ea18a64b12397c7aed0b21d78f52ed8f89e12d430c5d12a13c6fa2b5f9b8d4b7ca2ad864868056b2cf3e8153879c9e81abfe2199ed6332f3b4c5ae631907cd7e33f48ffa2b076c77069122e1539b73a246c40856f538c1f50cfbde2b0fb9c7b9be1fd844e350c9df85c963525449f15688b785e7073719c0f2c79cb9fdc25a8c1785a33baa4d931bada42bbead0344e6e83a5964f9908f9a3f6de52af6551a7c2b74cf42b535d2b7c7c972917c7ddb1722c1b8f2fcb3450580764e48ae27735878c5fd2b2bd23589364613ee40dbbd2caf1d19539742bc03365b45b8cea8406996159e7507ace1a1f6ee2b30682bb59e8f266ad7e342ccb28c694877940bc1be5238c02e93e755cee1cb04bb705ca7723e3f8df1dfc9632e947e2c7691f32dec059951630a23e426019b4a2aaee356e813a1810aec1ce098bab32cd4beb778bb287abc045d88a951401590f3c186b6fdd581a55617ead9493b5d202655513b2ce58dd71c768fdbb31f2b6dc0ded03b3bfd2cb940ed05ad287419b85e9f3e65f58d60509da4abde18029220c8474f00c996217fc393190ecddf386898b568a27ba5417d73b0d0d34eeb56c23d3499de20afc0dba0fa33257863d912a1e1637ffe3a5c599086c1fdd6edfb64fd8dc4baed13882006ef39cda9873ab5ddadc5c561adbe9c50796ab854d1be1b046e10811efa43b9412fc4fa588d2d687ef8c8afa503a5aa7cc1fcee6b9077415b1c218f0e8217fa556c29313fad80586526da25209bc7bf3afff557e76126a3c0430752fc0b2ddd0bbb952f11c24f2c9ec8dd3df1b677fa86fd7db1293f6475b3f1b866d921de5cde64b400351025c8c2bd69c3de86bc3dbc01d5b9e0040d51327a809177c4d9c4901ad84714da9c5d1c8dce4c2f1796aa39acb85d8319a919194e6305fab8d3a406eae7a719f13140f371b4edcb4317cb174c3d59613a633ccdececf727dc91cb2ef08736876ecda6526962dee67d5d48a5ff994dcc08c3335bf88dcb6eb4ecafa9a2a09490a9c6b057d60ddc0b82b76b788820835ea429e24ee7a9c42994c263aa85b934a12348c313bb7ef52961cda8f63cfa9275f1bab575512db60f797c06742150d086d52afb54b2516d4909ead9e53002c4eca6e11beababa94582e38a1686b1c5578b1f3b06d793943af14919f3235e72541ea7fe114691b6548f6de4abc463910a5b18d16b589597d7281a8c196165585000e421055d56cc44d63f7e2a54758bd52e20d972a10fa47ab45843c203c5ab2dfa5d73d79f222dcb19095801ef8bbb6f4b778515fd1fec3e3e8c8515d244d3ceb6889576e2509f2de00b4752d00415df8deeb1b0603b0949545ee85ce2f27787d81b5911733500059ba8c8abee7dcf22f904c765d3dbda0c0cdd7c9c4f1fc310bbc4ae3bd054d4a54f23b29ca31ed25902823cdd94c7244a7d6a3399db542637b376ae0efc61ab6d45493bcc2cf7cdc0a938c1264162953e0f745bdac4eb41fb13e38cebac1c4b2d4071f5359dd46383c8234354fd2851d841fdd9dd6b4745f2d0d2161802fada6ad4b23259d1840b646a243cc68ce96df0b2e96a3ef6464f64f0fb4cee9d39f8f8aa42cca2ee26eb7de20101dc21677e4a2f5b8fdfbd9191529ac58b38cb838a10512bc0228b5a88ea44445782bef66a0bfa994863af598c69e57515a1d7297427b7ad6c836b874546997cb5a4034960b9922068abe5f67f7b3efedc354d01977c129deb05404ab11d9c76a8605c68d826b740a093a15b8bf78e5a4e99af99d6fcd198dbad77c74fffffc0ff02d98d5f4dc41009b9d27a98fd8d016e04f66e2a0f55653caf4c5f796261192cf46cdaea4ef29921f1f756f361fcee81421fe1c89fb90e5a31fa3b2ab4fd361649aef30874a314f800543517da2f3b6f83b1b12d3ea01371bef65e547b24bfaef1fd467eec27640c917030d3b98a23a82460321fe6f8a4ecbd535a072ef918b1e5b54f7089af2bbdcebdb45aec4c97303297e1a2923e2aae020540c6c056248c7cc12327dd862e427f12835d0bec604ed63c1923c819000bdaa99854224bb6e32c1a3c13fa17e23c94b7098110ed0a4e2b05e90ce71f60e534c1c072d3a59fa1626d56efe0a5d4f1cfeaaf4ddff815cb7606a20d23a9bba5697407e531991a2dda38c045170d84f5392f96f334d6b051e559b7ccd4144e33ccd5c9b93b9888f00e71277ecb9e7131ca0673b43d5324e2efef03ea09ecf521276ad4ef8a4457a0382711e9625d9f4e974a7a9fcbfd755dfb43194ba4364507fe5c1bee27b15fe1e1fae6211ce98e9bfffcb7d36340cfa9f94f5e0c1c84c4178a59ea23f548a33e3a85de4e1571e59c66f2e73e8c81fad369bbc10385eea93af0cda505d25f4c7897a7620ae60b77d45da71765e65aa71cf3b71f7e0a70833926b19f136907635a884f90d986877ca8258981666190e109fa3b0aa8f5bc73420d747aebd93a00d68c3c88a330d3452e0e0c995544df6236d7fab0ed7a7df78fc3e547f9069917dbbd77ef9f85f93cf18affa4f96e7fd94f4e8a4159e4ef67ff4993ee988cfba30f736943f29836af851d475c32744949acaa891dbb9d437c21e9aae81b0af75cea65fbfdb6fa6de21c741ef48a6c119ac9500f31e5ed12e2f67f61336ffab2428b5267baafe9e340df14b4501312cfbc351613465437a07acae7c6cbd64fe24b69795a03f9811bb647946a1e4577958c0da58d7990dd6c741bb860cb7bf2f39337168e038372c4a677c127dfa0ad13766cd41af1eed85664400bb204183b3faf7b408abed2a992f2f759244e5baf16d41c7e7a7cf890ad527aa0d593c5d4af40ec4ac02f39e5d60e5db1327076bf5f69f49c3fb81b2241d961ab9741c8d335fcb8ad615de7e8558be7fdce9374b374f4daad27b888aa2b11aeef5bb143b7dd69918e5192222d8000a96ea709e9bd99519855ff60ca1d459904cfb27a8a6e74fc30afede967d1147f79dc69303a88ebf36a7eafeb33f23f4253d67b6c4923d9c81bd5e852ff6d6de989ecf1fec96e8695dd61044c94de6e3a36deb1a19024bf14258c6adc6c9c21355271df85704c7082f55d388d8463eaa476d3e7c0399cb313ea1b58beb13fd7d675e01928da185388564cb3e6f79dbd3cc5979b115792e094609b720339616a2fbb4cc1d97609eec1db2f496e9a69527182858a0e4ecd1333d903f1f6b0e7b5c6ee98eb3b58801ebe8a0eb891b615352bf5adee9afbed49c9060fe709d48b8f27b7e756e35c373114e69e880c7a1d8fc3e8534c0b4450362659e84e38603b047e2ce5a199544c6ed5e40ff4a26bfd1c2045dd81d908ed1bf1ab3b4e20b57a98675e742a071b832b593797b8fe93a327dc8949367732deb8c98ff4b6b85d1726c68385977e2704c8ff97a23e6435ea45f62d0f87dd55c9d5ac6c76415c590d5801084d1fd39c3f7d2ffe3292cc9f0c22a9b2463eeac0b6b94e01aa1b29f65a474c8b13814d638aa131510421ce301f597d92c0d4bcda0960363018b865c91160c9309b62185c2742921246a5685190d44a6e975f7eadef28d2201a8effe0e3934f1114f3dbb5ab0721d23338e2d55fde402da53196aad07e28f648d371dc35ffee7d68ee875c69f595030af1ae5c28821c3e70972eebaeb9cb6bb89f696ed7e1a1f768beeea7602217f56853f6b8b96c9d1856529a055404054a2600f11125ea7283bd86a1918dd2b3fc5f724e843eb49d5d60bc94540548a435de7bdf4ff3c6b354d9c24f3c4b35a8cbb69c8bd586342fa7b2ee49a0552008cb8f51ee160b60d28da530c40c9b8450d8372c69c97656473ed1a0b080280949b52bdd68e0371c3fe3023d1091aab2e33416e6d30d387c049a6f7ddb7cc04b15fd2686a91918fa05eade372063e9542f81abf18adae017a19ef55668ca3adaa99091a36f027bbf1a1865b1f6109a197ba137d0cba3aaa0d3bfdf5b614e6b0c2b3196fad0740da7ec46d7ab870719cae9197b24ec8f6ef2e73ab7a712e7d01d0d15b79b02d7cdce7d780300189681c8944c66579cf1b9145ef3b6b03fd002ee3f9989cdeb82f528b0ae8974",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x5c36c0ca25b2edac4ab1f88409efba70b5e1af8db028b94e08e9ec7130d6e31a",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x97473985d04723299559f49b856effb47d7abfad",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374ef0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xe6a57b773f7c8cd905cc42e95d75dde90f8e5d41a41f879f83f16d49081fec06",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xab2def4befac4fdfc81f09b8e9b174bf8af26f0ee939cb568d749af6fdc80f36",
|
|
+ "timestamp": "0x6ab8f1fd",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-anchor-20401904-baza",
|
|
+ "sursa": "2800-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa0626573752032362e342e302d616572652e312d643230333230312d7774613037f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b841dc33ea158950ff0fb06cc9e98b172e9e4dc9b6b4f954fed60829b6bf2ba83cf941617ef934e6e95b4520342cc07ef03c7d383e27bea11963d188554f4ca86a5200b841a424b5fe11fa04506eaed16e76ab32868cb5296d3bc7f0678dc3efe7234986e15e67c2f5d189af8b92d5696bbea08c20ca1839f8fb24a2db130be2142d67b1b201b841dc84a8adba948246ad7b23ee07eb88c75de583d92b63f38e951e12269e5ecc82159f9fb5e5bbf50356b849a6d5ca0668f186566f75de6be219df3b0f7b82af3300b8418b8e8a2696686866842e76172575e40e7ff7b22c45c8cb1bd9a71ef79205cda6387066c31197c6de564491dfab1ec4f298deef6706b4482c3f148c7913f31bc400b8416e25311f733235dbbb399fd0b33d4661ceb2a25f622c12edb3bba930ca22fa077d85e9fb422c2aa8bfbb3c3038f4dd54a3de1a69870b2be16c44420379ba452a00b84197d2bb1abc4d5d1951019c04a051390f846eef1dcd41006184787f327f3b21291db89b4de2790cd3af2c6b7bf37ff7ccd4f86fdd641ff7888deb3ec8251629bb01b841f6da67acc840f1e57d5544bd1e19455e59f66ab6d4f6c002b56053863e5843d301044ee10e7c2ba748477fcf8616bc01a1a602069e77ae60f8153ecf7a11c3e000",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x3f97707f744262d570f3573a54060d182847ce538a7cb4c71a393b7bd36b1f0c",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x1bd5514286f5602a6762b0075266379d29af1c9d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374f6f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x053ca6c85b4b601948de637b1e3c97365ec9db82f5c6bcb3296cb2a807928f4a",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x1d029476f9258c14edc76b9b291dcac3cfc37840eb93c87d7e0359aab3ac3f90",
|
|
+ "timestamp": "0x6ab8f247",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa012e9da0fb471aff3a477b1d9acdb1942c03b35f3fed3f4f4bfb39a57743428646cbc4d3f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b8411460e5f0e9731048698e6449f6c2aa79e3c0a61be788925cc99e58f2f23b435933b866d5a46bdc9aca61130225425c5680bd5f82ec38542f00de2e1db62ca5c401b841416000d484311c96f97d1dbd0e0b39fe20258185ae8bc0cc9bb522537f0095a12a5ded59e0320ef9c17ac1c2459583637e59d81a2df75188d7b6a99b9d024ce500b841f300911fe9fe5100e0ba1ed751e2c82c65d85936b5be7987a30c7e3bbfaa60ba2f5a941844fac9b770eca3dc65f987f4cdabcd26b17a84658fbd3be0e3e29b1f00b841ee849fc0133f7db281e1524f82b1325e6c3aa27644970f0abc3d3ef3c9c66f6a7fe81e7bf86c1caab12f7448ef04a77737e18ced957268501fed0bfcafb394b400b841ebb06be4f5a68a08d41824507d887338095adfbfcf284aef272fd26d9721a3ca4fb6936f7f6fc8c307fcbe1c70085b206d51f7436a8c31ebd0b0e8ef46a0275c01b841d7288f62738255d41550c252d4c2d7af69f969393a7d3a9042605d47a25a4d303fd51827c7bc0be4ebad40159b32ce08a98f80b0047e6fc92a489a52f478983b01b84132df7f84a9be9e725e8ff0452fa22220c05995f6bf92293bdf8923656e9356470016cc1e5b51f395e9c56bca20123723fc206732bf1a0eef3a393d170fca65a900fa012bca02fa012bc5f902940180b9028f39847378913c921adbc52a2f0c0bc577a6e34208a52ecc58b5ef846554ccb54f20cc6639c8f78347939f9de1ab9c82ada9f64523a5ba16a1a8ae24cfcef4e5a77e7c140346b1bd7e420e873544c1098fb104212a32912fea6ef42a3c2c231f863cb40e2d5517f356aff0d5f6474e7ae764aab2cb12ecf302cf43bc783b3e958458147aa60b50c3a76c579d5ce3c3f53cb9ce926e9251249a7b0c5650d02c317b875890d5a3d1d27c48a59b4e39035bb892b64c71d84c7722e0d4ccbb9c428c8010eeebbfb87d79fb2961ea6a1795332da1cfab1b1e6c2adf4c4f5782c7733b7b442e0d1a96521fca2368b3244b74a5a6cd487e547d3cea5e6b23bb977b86837899e6fda66e7a4d29ddda8a4ef2042e9b82a8ec5458e2f36feac3e5c5c3d9c5e02cb9990cc9c599280c233c38f1bc19675a1b9d2c9f21c441af5a89d53abde6ddd8c5ee3191d04917cc3ad31a95e398aa9f9cb85114c3c7a1a02217083baf4ea1b397b2c1ec8ee19e3e2cfe72c924c527894d42893ce21f555cbff118117f91695822e8f7400f12506b1e3cb404855dfdd865597cd41ad22c4b5d4450e2378c350721884c73ed73cf3182676a096314a752e4ea323dc5dc4dcd731ae9d736f4b72215a28496e755eaf1b9b5a26a8b609246454886d1d0b8663ca5e8206dd9a2df4008a1d488480c472240270b9153ce258f356cced9058bddecb66a12af73a6e4a7165f4b0899c3682b865a34af1aba5ea5b7834771890b2fcaf2a33d4c731ee97e737dbf2d57453694cd243be25624f9982f494e42beb53d357b78fa6e2bb16c9cc05c55bc431f63829b3c86b17d8d2c102972627671accbdb098169ba4d237495edd806dd9fefa34a0b60dca7312d1e47812fd60cabc9a09a15dd028639c883a2b8cd8fbcf1c3c9bff506fbca5d60f91eb50280b91eb0a32ae858088995a716a97df6a5e7c5709e511fdb2b4f853be29121baf892386fe6f34196f92d86549ecda9e1701ee518bb45cb0c6e3ecbc0e57a119814f28075b214966b9b6877abecc89435ca24a50e60065b1c0436f3ae5132e1e2693b5a1fad39a090437d569b74efd8cfd0f445e3c14ba89e35c635713ecbdc3e0c923900eec514ef4b2e2a03ec44a8afb107006d0d8f0be02b2357e7bae5164cd0372b984f0b703f4ef4c4e58dfc4ea0914ea91fdb6d00dca95658cbe5922463f39f29562fe6ed30280065e3f6c0f2cbaebe57ba9ed3b0a86a571a40e2941602365b83181f9c6f92ad048827f8eb1bcb9d2fe662752ff220dcc6cdf498d70416b6a85d8f69670c9b8d9fde203af80f82e9b9d1c3ae538aa8ee0f596e7899efdd346a9ef51dfe3472f619762ebf13156442f4a6650e95507936d47aa657021e0e3a69c2301c7b75992ff75d270083e6ee77bb3de46b08ee6520c83c863887ce05bab6a0d23206bbc6e8e8eb02804ae1e56907083e19a7e85b34cfc83bca26cc33736f08c83a039ca14225016dbe56d5af08ac587f7cfa528f9d6d214428a2c54242ea7e1d982de096c956e99135af535ff7f72bdda2910bbf489ac6b174711d922f38af78fb9985438d67860293344ca0d66c61008d73e0f4dc195e5b6841ab46e6b466b503bfaaa42adc2071611ba24c77522dd79520a8c0745e07c67e7e8ece9f1381eb746789aeb953bf2666512115cfce26ce559cc3f7fc888246aa98e475dc23923a1ca2defa1a837899b2475440d0420832b1796bbaa453f128c3995f409d297d7bddd49132ebb9782fa6a3bf7ca168101893eef31f2e7682327e0fa0626c15f1c6981c494dcec125bc11e575422f3f45baf4f810bb9e729a2575ed966c8ea76bae32dde4b9e67c1e1eb487773a44fc083de492aaec5605a776a82f9a394594645bab3482422edf73e6dd59fb89e6cf7258459f632259bb9a631287e3d303061bde80ec876c74605504f3a21b9f7893b4d51a20fdf2742faca53347f8108ee2d4464f798661d89a1aebd745534834844ccec78e0c44bbdb57ce424181ab23f3de5a755ef29f701359706eb764eee5626003e68393958412ea1c1bebe02fd8a6cfdeec9e7273baa5466a128140719269a5334a43e15fba79d2728dbea6d256eee3d3cbfe702d1b0c8a6e724c9c7fe36336dc3965325076f2a11e2c1e0f7cfb76a89d20dff2b252ec9e0cb621037f84cb4e31da047d92c6c85409d16548834d90d49a24bf82cf7e60a51edc326c57ec26aa24bd64f91e82f80a24d36631b9fcca760d737fd4b763d8c88169cd3f9275518afd98452df7ec2df0625f708e6a4ff8a5da92d212df615409388d71c268fdd8d67e5b33bf2757db93cf1f7b2c7194a682e6f333511f597ff4e1951333760da07054a4b3913668ce9e3b8698043b08de8e2b6ed0b3fc6973950b2944a1fbc115d196faf56041128cfda053703168ba039880282702dcddbe1ac4398b08cba35bbf578e32c64748867b7053dff500688f98843df6e153b0f64503b9e91f6e856b22c45b3202bc636fa004f656f4048bb8db596292fef25f631bbfe3d64104e31c1bb0f9119eec8e82fa6ec7b0ccf45542e91cd0abab3f00e7a95d29567d581890870b9ff9e2047f91f80266cf9d574ba158a5dcd4a9c55f53a0eed61c5d30cef15b4d5dbf43b1bee9ed377e3c807375e38bba57fe4a60a5a80e6eba219ebd096696d5857b5208cd3bf3339d5cf0219f7643f8851def3b4d19ba9fb281071f332f8aa4239346248db5395d53f1ab7bf960c9d26a68a839ce0da48a2637b35de0e8fd6b45c236553e202dcd3252cc292d3d835098472f15dbf3998ffb0de471ce467e0aae5cf812e9b523e9b398377df944c5c8d8dc59adeb5b100f33f2499fc3c4d208cc2d44f1f0494cdecb4306a488e8f31374191107631d7ac77b24d6c58154f296644ea38154998e6c42fea7aace2a7a98b5d39473465e5da2a413734fe3ba2cb5dfb0126298ba13e190315c6cf7fe38dbab4b35e3f456c3933bfe7a403136e82eac0db803519913a7adb3456582db84c70c92281a7cce259b07a7ebb4e103f8797abd370328c658fa03bcb75536c53827e8acf31001eb6fe8bc1dcdede0fc2bfa2487d35af78f980e2727d08cdf24be3856d8797b53902504596ceaec4fe5b4d0411a49c27f5ed325e6578300fa7d6cf36dc7384cefa5d740fe35341c55633ad70eb4c0ae5d168c2d4d9fb7c612c4b139512cc13f5d8d604903e356f5b38ea8b8d759f0654460781a7df4ae48256ff42c5bd622e63102a4f260720be0b8812e78f562f8085234c9b2d4b12326ac55af4d474f77dafe596919a37bdb1f547a1176fc3a26cb625db6e6d6a3cb62211cc7b9cecb71e1679526f5ae18e475a91e7b323df1b9fd1379d1998da81dd98d2d5fde9819560e2ce7d630624936b3b1529a514703226a5795210f5627358506b4e18fb8a5914e9bd328d65dc0243beae1e301ea5a706bb6eacd85d3d3556616f39a5028c94e02b3e32ba69d17e6ee4451454281a702cb279c7a099c911ca8d184d06f084a1d1c605d9e27e7da1294a8ec90c03ce84ab893be88f430ad620f6500c8bcb2f6781c6a81cd88c7ed148926555ad96350021a7d46bf9b99ea5d39c1cec3f4f151168672f68ae7807021c4f3fc73ab876855634d53e87f49dcd67b488a163f64f37d0ef6231bb9752f2e6f3cd7388c80b4a27260f1a2fce1fd7a856c0a9f4edb913cafbdd49161d0be3d7446c46f2aeb2727d7060106e81dc3998a53c9d54bf61c3700e982eea868d02264535e996ee66888feaf567abf98caa9bb0a528d1e873eb0a4fd6f4b0fa5c3f28c400bea6d57fe8a3c883e3c21fb18db6dd8cca78505891e3c51384670006f93c87756f7c3b050bb251f277e5af9d785be65300b3992e61d7d0efcdb265b92ab2db13706d15d9ce81ec872ec07e2964c8e1922add856c218a75949830c1523fd9f60a212f72986edd4a7ba0ea297f052f570aaa7f21834e9d8cb0234fcbccbac0991e9c27e57f57320ed8bbaeda821bfd892bbbf0fbd81823c0b736642b297cd1f11cfb9ecf595f483f5247a0fcf8198264fe0b71c3948751f7fb1c642f9f0a5391515761df2127aea9ee37c42cbf4c606ea1a47581ae4d18e5944f8b9a42ff77365f29724bd3dd0bbf8e11f374869249a06677ebad506ffc4b4a82301e8ed9c10d2cb133972c634baf66b369197738db44d3d21c51c3d99e2c7832b4f480ddee8ce59c45413b4e1e802161a16fdc91626467c1cd203928c206a367ad4adf3d838a42fde6a6e56e12ea1429673b5f0afdc3ea1ce665d16091883a98309bb12ec64cb6158c5d4313329a92bd0f9006c0787a97b900c5032e08f94c5b04fdd85455e05432bfdf806676fee7f46af48f9966cbdfb783fb9a6bd292bcfbf2582461fa8447541b694a5b2de7d7e64c867a9589f45aef672245414faa41883f5824429f6464f4f84da959dea4230887edc83f187fff543039c66643214e5825d2445ac3b1d7e0e15bd7b16d5bce0bc46303bd21a59a0a1baeb49d5dbb862db700562c25f7b678b80d0457c5702fad1337fe85a3eed0cab1ada00c423e2202dd7852ea3de5a874f58df8da43ee9b9d61595b0663ec03d0fc7ac43b254b9dc918e97ce01e5e406f5dd250232b280d3f8272a1bf0f95289d8ecf179aaf8220eca1c45d08983521213826eb6609e74527ab9636aba2f3248dfdfb9930782be0b0f9877866347f8e7473a5aa1d44e7d0ae41da9f2af9b66594bae295604eac515abbe8610186f343812a89623f43bb99bdf36537fd3747421bda605c169008ca2581cde6bb811c954cdf645da646ba565df39c4928bea578cdb036913707439afe9608e30a3a7c8dbe4e11b4f51abb93968322ad74cfeb96738f3338d47ef7e1184e9fa866ece26409b920437d9864f4b38c33ae91129ab9c15ad05d3b6f3f95eaa220131c719eae21b5e4e19bebc03c5f7b4872d1fd2382bcb9d2950cc8fb76b7f9705267386d11e3c5aa85af5560efa924ab53265b5a8787233d7cf04515fad8f3ec90f9cbc31dbeff88533ad94a0da9a9d3546cce67d4e0da89b57ea89822b194150c9f6d884adf24c26a43439fd8a2151f3148295dc15dbccc66849b57f3a7575acb53e77ac42f462edcf5f6ac5b2e31c5230ae32a24b6d1f3a69dbe430d78258edd380e31a771193bba35c732a7bd378d84ae3eae6abf2d7b81df870e58796e17c504aa0f0a7f12902a90bf15b6041a5742f4222cb3d002e5ceb660e5bb85ed858804dcbb665b3b6ded34d417e14de37035942aab0f2b32a023cb9581d7f3531d99ef765d034f0aaa41d0b8e2327a2f2929fbf417641afa34d44bff3213a7258fed368da6f4f95d261519c90bb42ef5910a9d9cc935027fc090d1252c7daa7fd3fea54e88224de174e941cf2adccbfb750b79dfb76759d4518db4ad235e474df332e31a52db9d73f0f1d0b7fcc3b353ba165766584d34fbc1c343d14a496c39de1ce686051dced1b7b389f26aa2c9a54928e42a5ebcd8652146150f2bfc9741f0513b2558e1f343fd855a400be4b764331c95258d9febdd45fa99b9a7f34e1e1a28bd91b8c0a35fdba164c70672e5cc8d5b734e67644876977c3c1eab3e028065846aa37f47234aaa7fc4ca89c707ef3c510a75eda4044480b2942602a9c005d336338bf9a05898a51ba62d123ceec1c2673d98d5e1c1d80a647ae2b6fa2fdf504d7860767e4144d04520fce409879584dc413ba7decc7e2532bd55360bdcb3ff1c54af367c69a05442ef6b4a7bdce1c6844b55c29cc73916404aa6a94694e5863f2e282996284971331c06388eca3dfffd402110fb7d5a4f7a3e4e6c9474124d5b076aee8f07b37fae022e0b4cf9baf69df32a9d4601b42f70d1eb5a330e94d9e9c8e41d2842622bad5a52e2c3c61d0642174c72ac7f8c1b563eef6d0ac5c4410ff231d6a4ce1f5eb70a43308a9d05fee8449b46ab5d0eb7fcffe69e6bd5a3e32cee9e63901625cc77baffa371b74e6cf6c801610c792f3f477ff313b670e1e2a160ce18d696f12f741a79647b45dd31fb51a8f351c538b6da8530da24c0060a740f9f78aa44d6961fb733c53820924281af82e18f887d272a41221f4392cf580a087438b2e1a6ced42e01f420228322c1ce61ae3bb956b73ddf4c5a2fff0cb3b20cf40946ca3b1fb5884f420587068ef039f9598a3645d58d7226ea167a9ecf31a29d456aabf60284052ae3484ec7d9c165be6d6de1858b7f1aa6253f13a713a822c2b32c634084f4f780cc101737654c2f18672de3bd0b63d8ef09e2fbdd9866a78cdfe16582313c544343144dfa6a9b59b9acb6ad8920d8c468b3e0828b52b5c36f05784f8bba7f742f1b59e4eebaa6a122d8596b31672432bd6ff8f6825b0c15a5c9967a7f3ef41603bf7ce878e1564f8fae88442cc05e5f010e82cab404f4110778f8f822420c026a071d84cfd43469698817d474ae0507b953843fb38d242375f025b7640ce61848089b3762df8c307e0b3b273d9b7ff79dc82a594158c1e4af5571a1628c2721b127de8091d462de6711e308b1f99c8f24dd0f1686a1bcf05b67b1b7a2c807b97ba91ba3885a88073abcdedf5d9d95845a5795a42ba9c8c1665c075295ea887b41c4804ec86f83095283bf7191873f7e4282b07d49834db14593962a31b843608d01cfcc0dd1600c60ec9777b93a2df563625ea7905554d32312e6d34b9737d7e88ade77f94ba61f2f786f7feb972e81920a7541cfef446459f6fafc44dd3e9e9f5fa93f6441e67afb7ef090cce089af5e21ae61b9ab750e6513b6fd9ad7f61861fe3298ccb64a5b3175baf48cb16c921962ac66d28050c70e198f1ffe807bad01405adb1d2004ef4c3c5346da39fb943b3699d9bf60aa69ba891cf0ed9575d87a46b6317345c48ab866a56736b7c8718775215529c3d75b0a99a1e4d7bd957b12a72c18ddde976e8b91b666fd3f8ea24795f268c89d2b9a3c67510d1adf24a3ce77654d3d269a1266929b107540e3956633e69dc583ab7ecc7ed5d32c8357a030d2fa4baac7546188d61eb55c29510cfc6f5fb8b9656a62b044e152ac342fdf068949b9114b1a3cc887d6e045a6688280984896b4057f61af86c03cf2ea9173c9c7f8bd5485a447f24ad3893389a034cafa674b9854dbac1999b6c811abe649b02593cfe26d26c465287c40ec3c4d26ff913fc6badfa93cb89c61c07f1c97ef8e058ecc4b97da49e595a4704bddc149813043f2353e3097c7379babc80c56d8ff399adb12e23f9513faec13cff6f5f88dcd7a401cc9d01bfb0aac4a2ca01dfa1d15859cc247dd0b78d21098da4a4b07fe06f11e5367f9cb17e41ed1443c8c388d175b6c2a579a9df4d614f9cc988ab226ebd2f53b27ca64d97cba767dceae990c872c1b25f21d6a2741fe05307299e0828946ab2a1283f28cbfe18c496421d61c7f268470f0e5e35d6f405ae7857b350603dfc9ef66f0e3f5d7ac008e03bfee185a0b120b0bd37b5a3385bbd79bf3b521814d0e040c3c8dd7cc581e9189a551a48a400d698626ef9752a3852ae3e6607472878430dc28d4410396163481df5c57130e4a05e2bf175c927ca338edeb55ea5a5ba05918945af04593f3e7d68226cf3b5ff09980690f8f3202e68bf5b076ea0b6b380f6d4ad816806893bed11e19e5b6e105d183ba93c3168c6e2bec590c5ec2b3930537068b7ef4f7ea29435cfc992805bcc6312a670b2db7a98b91a889b29a7c409b5b97090ea7a9f978c52ede1eeb8e96eb28a4b2019c4043591e7a5b0bf82e536e3de8fe6b4fcc20c7dd0e76e3caecaf0a32e10be4954ddffda9138ceb28a0393a6fa9c43ee8916b382034a7a9b0f79a4d26ec2cccce7966c46cdcb00f6e89878ce45bb48d3f31f37b8dd7eca7de1743c77792e26b8130a113272952bb1fecb7f1cc052d09f7be5d5955cdba59474339893f223be56a9d3e40661d0e4cd2799e0064c4c59609a64ea8e83a1b2eb2b42ea265720614497816cd52bf93e0141472b8a109461ec879c8d588ac0ff461339042e153ac1d6b010461f971543aa15f129e40b5a914a18fc0966825768bd3119e9087dcd530517f13dd0bc871997f3a7742c335ea41531ee79b3a9f830e76f657b4c2923c8bee1d3db885ede4771ca02f3aac11fbb5705ea20f8cfd03fe39650c0186025972adb73ea95255182987cbcd4d526c4cb7f472ccb526ce2631a4d7e087678355fcc9fda0ea533b43840f3624798a4d94533fac28fa5e936d6ddc29f4b4388e2159472be9f4216a213c9ccd1f16852181c118166798c3084b5e179cc9fc6081424393f7bd63bf14962ce998a620bc707dfaea486b569b8dfe70195d8069058b778afbcb7ff28f725609c3757b2861e3590f923368d6270d336e021baa885078b4d6be6413b81ed77423c6e3331927d74f6e07e722a44f37d037cccade6d150451e84c72d55d3819fe3dd44fcd3ce1a0727fe91a8cb9a32ac871fdf70359c62be328ad567d3770c3ff59a439ca36c8b346a79593f1a04a535b5b8030306cdfd530819cb98a32ca456db601bac90688e8084d4213e3678206656988c9f76b9150725e1924f8f55b41cf5175f2eabfc556c8e4f423e553577e4e10bd93b86b894d8a10cd19dd210a262a9c30f85c854b46f556700497848d5bcbbef52a151795865662f9443d26a2c3eba468d08ed7267a72eb769983c373c3794291127708b8d11b78183222b5cd610ce3c5923918c80305593aa3d128625d83f4ef62ca08d145e12a72a30640d3ebd82c621085d5b2aca025ed2c49879bb11c49885b28df5d5329ab77ee255a0bee8d7f1fc0772961bc671b238b2a2cb340c65193b04dae432d7425f9b537673be519eb97a5b3851ee162d8be1b13a5b655f0d6447df88904f2b020403000ed2fb5aea4d055efd18a9c251f91bcedf51216eac8b776775fee33c0d7364be0fbbe700e63622a91c6a21123250ab0028d6ee1832b420933f524e3346fa2d5b2a37f0e550021cffab30c03c55004d55829f60a3b32a9bf0d058cffae02573035f3f7d5dde675cbb4591b484319333496fd2383ef239b00b414cfedd62865067454a0d642b69693b43d657a851c260d3015f7354d061e23bac42f0f9477607e13cc8c5a650023c57a70ae3ca190863e0e0db556829a533c26123d599141da1bf7d43eae0ee85e7edf1f7b85941f7bb2c1a76eff3c5392408692d04eb87b526b775e1199b4d00323e7404df16f9e89e9cbd30faf0aecbdc7236833366d2d473336d368aca0689e62743b08e256b64c0915a94e8b8633e02fd14900a28231a9ac3e0b3c66d25a298151d8276c71d96320a38d8c07ae210fe70a646623a0a533a834a8b7125076ac0ed73286f563096bd6e17359cc1bfab51ba7c1eb7d5ed60cdc7ad31aeae45c8be66582edc4962b8784e0e550cccc1da838e2c35b6adec942ab375cb3bf68d0c279622a40a8dfd8d83a58c1c4c35c72488dfc4054a49e8b0aa6d52f9b98a8802f92aa3bba83a05d26e47a0b3780c9a8e0a20b39b77970cb97400e23f6df7cc5702f4732070c954e4e346db9184ca506addf3cd2b0e0738add5dadd335804bf47e7d403f923e29f921153fb458b5c4ace9e0cfbb4bf75fa5c1a74ef7b9a82de10de4a4517622e38482ec4ad3cede353824d3db4417b41b65035cfdbaeb8a5a281090f313b4a754b55374d9550e6dc6f8f6fca94795bb8a977a0a708545b54a1b03ce050f2b08616e1249bb8d666611a52afd7459cc8d219290d8aace003c565e4274a44c2eaf29e2eeb2f007e826a730ee64e7e9ace08cfc5efe89bbce75a9ee54cdbac22b3f9337216a7d59b8bbc9a3cc7c50711b472c237494c1086774139452a99ff9b231c71e3b29e3ed7718157072a7974b61fa2d579f2ea146066a01fc3f1c9e9261ac7bd3b9be7ba8969dd277e713c83a9e9c2085b86a2b3bb3b8e1d08f0290b5044e6bf23710a0a01abd95fcf5c3155ebb1b38f0986fabfa9c81cf035e99a3f2a67e494cb8f10250b3fcfdae66712159766128bb8355f44f1878472ddd046e35cb15a8c423f415f02bc2ec55b9cfc3e3d03b5688229cb0e76818cfe9ddf73ae7b4dc73d3e3449153a016db0029842e8705df647ce738ff0340ea336faee928a4861ccad9c2564de5ce65bd64424f75889d5f3db62f11d9e512041618cb308e7de39cf81eda1d7b783d9a407df1b5ee9700df994cb57545bcd4d6748df213810cea6d6fe3971e0f942af1cb5a13aa7be9b698ceddaf41bbbda626dd2776720a420aa6a0196009311017dde996ac6bf2ab3d3e0389698614a4920663d13d94b9d5d9ae48d2e9ccbcf88b17dff035faff06e603fab075724e2d7ee6bde71223a36b3d9ec7e9346ac6273482826baab3b7bd08b04959094953459ba5c76013e793c278621d3574ae074e441b6d439c15e77132d72896eb5a1462f219100d502a0581c694ddf9ef87388303a63f63d729c926d8849506b3781da8df91a0f61b9660dfe09a3a2e420ef0796492e9b261869ea04ecbb6ca2d088af183b271fba978980c120c5495fc450ff4afd9e98f1b2d219d169e386863f29288300c009b194402e2e5912039581aadcf3fabd9968772cce57a68a31c77ee7d73119305c5db50af96f9995aeea126a5812c4ce0c4220aa5d4dbd1c3b3d9bf2e9061776ccff0a925b3f05cc0e1ceb8ca576dbfea071820377b98fb040e89c254b62960602c20659bfc005e277dc902e1a87f499105ab861ec3e1be75a97bd2ff3df7031d859db91698372674bcda2a087fcda4743cecaad450f890bafe6ef8de248294ebdc43cfef215df2a15ec313565823718db1d23c95ac99326ced36cf0bc5ecd58c4ee3718b6ab18f4bc1593681ddb617843a8db9b8caa98f971095de4a51f22bdae998d2f99342836a6ef252b554b9943050420135b9cf04fccfa658d247ec1f9a76d9ba1195204556cbcecb9fab8984e1231296dfd6db1d8eaf4dfc17e4be54298fbc270da1e2eada76fe18f4aa2dc7c26912104d7f61df28c9b8bc66d0891c3901690ace737b500745d052cff74ee635a7287377a94d0ae4c63faf36083490d78c6704f3585f4477e0d9862ceb40aea9d6c92d753f90c6167356a13760160ddc71526859abb6f11d5f51ae65c9882d36a985a6760b9857995159306899c0d947142dd37d8ec2c7aded9d62172578fea522d287e5f15bdd264ca5f60a375d9ccf6edcee6cab9f7b1324389a16cd23c816dee9676488563585c11668283cd7123c8d4128365f8c098dcf38713897dd98e7e0942cadd711260d46758bdc82331068cf076a0501003f9d97e472bcc28dafd6b9083ce0e7d5e8e3ee2f3cf0f7b4677a8a36c6cdec6a5809d47af72f89b7e5db7deb6c4f899f47ae0abd02ac70a12338c6b3ad4f22a298bdbf2aeb1f4bbf291d56dbff703bdd12641486ad37100df0f07d4fceb7bddbe1d2b75674cfa04e3dccc35edd5b17e3702107d3dd43a7f2e006817d58ab0774507721353d9da1fe83bcf8229776f3c3209c540f5fac5c0b9028d705b951a07c684b3f9ed53fd361e2437e08572205afb26b80da45e85c61d24317d2de239dea970fab450e217bd5d32dd79cc0b05c4c34589efe6eb6b8e9a1691c3e8cfca6987d4e66579894efa8c633819687bc2fc6a521472004f13e7f4b6963e52ab264069dc78fb2c6e46d37f16675a556ba59ffd80fb4c01064408f8925baacc8baa11c41be63d6ad6fc53a74044147c68ac77bba57e2aedecb05b72d8797a0d86d0975a9fc6e3a411550872c7d088d356058ee3a341292b72751893debd496fc161d67a0815311f858731bd7821f12cfac9e18e0e985d03f2593e72cc13c55ac5850cfc1a717d40d5b861bae1fd2b81230a3bed0a18cde4786be546734dfbed5f975bb16414ac855e5e74c86d8eaf68df890d984b99403d27029242e6972fd079df92efc23ab44f89298abe0cd967b54b0d294a2d034a47365dc885d85604b66f310283d9c4a9372fea7b8a89d567216d534ce34e919b4e1e2263974bb299836f18107dfd4dac4809d14df902960101b9029139420deb95f8f8d1aa9a7dfc095741cf9af974858e5c8eefe1ba4e8bab9b3350dac8a93529c1de37e5094249ea40df3889891094e78eca6594f6a154fefa09e85398a32d1c5bab443fc14d50df74120c67b88ebf8bbd5141d87b2dd680e2f3c851b2b59a033af7ca6113fca04f92d91b42c6c0e587308944bf1dcaf54748b3ebea5159ec70b66b6428e713cf1823ddf412a89bd71a0469ba7ee65bed37277d8e6ad5e5830955651b990a085a1fcefee852a3cdc6ce8d46768d69f1c1b418d3c5877a2a55b47e472ef86b53ccaf4f12abd0e95cfaa1eadf0abdc9142c99f9d569756f73e251344043f3ed875afe068dedd67b616d164b23688bb354f5ef664421e8f6b24e80eb4c32f3296af7b91abefa13d16d5a46fd987164f59219b789b53976d63a21d153476225f707bb4336dceb641192db50f6a90d1697154b4546421d8afdc0b24e1c3a9071b3b8e801b1afbe4bf11fe2699b983b106849034049bbe4e9ae4bf872028affcd4c8ce1057b8e020d943ab9c4123fb2448bcfeecc8067cd44b99f60543bc2538e6b39f818ea5554d114831a85a3426397389f28365e00dae160a59983c8ead45916a0c59e39fdb93c683b5006a18d887339da1f132d05c7b70c3eb5bb243008bec9c7d8b2f9e405ba62f1bc6776c9d3db10b5263931bc8d4d2b41738ce36b70f62e3e2499055b40e5a2a3b348be6949d2cc77de6ce96a6591797e9b275c82c2de05e9b6e195c934820b28c5f273a74259329879edbc35a4d8f7528e9e6bb1efd79094b62d05c77e33d988d541265cfab1882ce9399c284ce5715348dc8eac2cab101d6121ced64cce559f4261aac451205a54924d8627ef6982a543a475df36f3c9514498cfb6e98da89cab03f13762dd34f6f9806c24ba786a10d4da705edbbe35266599a73a0880f91eb50201b91eb0050a593c562131c42519f968043a0acd57b81ba4cef80d6bf35e34acdaadba400154a64a83729c9f0f649b6af56fc43c1613a1f94befcfa18c2102bbfc86cfee2d24b168c688ffbf9dc7b2b22cf4e3c534f472506db22aa50811e5fb9a6be68f8cc796a6b47ad542758009b751bab534aa033ad390201cb766c7561324aec707ca5deb5b1c94426d1a964460faaa0aae2be906f6ebbbf539f23635f61a47c7c76f77744640a68f47a473263a13b6f3c850fcf85162fbb16db503f9168754541d5e701dd9eea549dae5ad8bd1b77916fe57c5c1e21846ff0b754b256cabc1648d82c6b4254f46af0986c40652b119679bda3c77ea77ef83b3db29b263fa23db603fdc7cf2c187300d82830034b480bb15ab2574b2865280cecfba250ab6ab47bb93992059dd348ed66c10d8b7fa22f11f639c2f752a56642b281bf1e0b67e93fff138dad057d948262c87b8128f4f61878fd72a2e38dfc0167809ee160dc081a54a334c6a658ec1d6ced21e85f7671ce2246433aeb105a5cb40a6ace25db553bcf808f48212ad15db2babac372160e54727eb820eaf54cfc010c3d51e05590ff9ec347ce54241fdba8eaaf56c63d9dceb21eb6aabcf7e552cb05cd5a8fb6d189b31f3bf871877e064d6a69ce8b3dc7549901eb55e0553b5398a1e17ecdf1f9792aa3bfedea9233ace580501dfbc98da1a56588faff33b10c862bd6b85877cbfbecadb5c1590e95acb269627b1fc066bb982d90c22cfdf12fa23ff6e48a33e5ee5f0d1bae4a4519b81249b53c196f08545e79bcc36b4dbde0677666852f0440ccf8b5a62356d6b2b191d3ddbda2418dde0aa5aa7f85ffe88718a994196dc2494bd4336c884f9b0ec87f7beeb9ae97832ed798ef15861076eaa6d4f3e058b11e325ac1314abf924a4ee1d55ea73cc5c8bd9d0d6d685c78da838744d5012cb9be63b437a8b18cf03d186a372074162d283f03fde7bdfb2211aa0185e9b09f81d83ac3d5ff2d1dbc825a34261d405cdd8e8ef9e6c654a9d5106abd967408dc96e6d44b4406f9a32bc380c857f63caaba2a9ed9adcb73e8e27c76c6138163e203d534d776836833ac524657e6d71f051d30ee58ffe5380feebfbb5b621ff472049bf7b89fb87a058c7a78c8baba83656903a6b59278ce800fd43ef47e64f03d5e4fd4adc9bf1a8060c1c30302bfc8873517da403cef4a06684a3c9a1a276cd58fa82e0eafa53b94f78a30d2308890d32e5ae5695f9b4422d59e04026852deeda062875d755efebbe5efd43bc415da1ceb1de053e0ea53fc7b642782c2eb339d2a5093d59a011bc344d18253a3799808d3cf37c96706c414c26be04706e661f89467a342aa227a27763dcfb2b1d24b76896f72cfdc1a5410eff8147d41b2937f4c3c1cf3c44b5faef7048c2e1cdc26481f547a56ac73982a6a0f9a6cbf1a223f983e7899a5dcce51bea17e9e50be8d9b4e7b00a4fe1b919c232234e7f98a34f3181c7245be53e892d5162e3d5f2ef972225c87976de430d955b4137ed8bccee048d4e167670eee1dd7152d0398adcc44c46544cccd362022030d808f5b6fff8bd77b81701859c8e5ae551b06d7eaee8bffd5b7949ca7a74288868efaaec0af49b86e5f44af0e2ad5d3d7ee45739f8ca2a72c9753d5189cd3170c60b987d1bddb2ac603fd7ce7be47b20080a771f60e72b4c164a1ce052d7f6437844cd674d823a23c4cf2ffcfe13bd6456a7355cf4195037ce2b7c860e2e01ff2ebdbc44a9fbdbb480892360edaab84dda128be41cc4927cf4e413a04d62d04c5ad65690d6c4e9d2981a7bb85516e57a70ee6af4cbaa7e427d593d7eba43bae45529fdbaf5dad9579ce8b731cc37695eb0cb0b2715dd0e170bff75058337f77ae9e55b3c142507a5988ba1590330a5e7ad2e915359feb01d8739cbed1b18e4bc4c5bc0444b79b10b17218afebbcd4951dfc78c5fac0b55ece8019afd79eed09c0b26e5be6de0ae8ed3afa558563f0eec6a6613727b572876cfa70922271fe98fcfe221b68639b3f7c596fbf9cbd7c7818001264774f0051a1ea4c39e3d9c529939d2c2de21a637e2ea1040f8aec38aab2cb1c28c2b78110b5f8312a1cea1e005c7d0ff0a481ac2c3b684580b9dec5614897ba8768dd0fb0f6a8d49043503596414656079d776ee8aa0bd40f338076db2ab19dc8268c4e1bc4ba9c8d96cd33bcd7023b649e7c43c9500d38f79efceb09ac14dbe587e9e6d64dec06453074e7999266bb4f54a0943233bc7298c63f3a5568d90af5c6f930d525f54de486170e79e63f8063fcefc52449df2dd79fdd82b80789d3e5aad708f42b60bc9130f47fb4b770c1134bbc9b291969a83af2671ef8828d69f20166a79414c5d0f5c5523759e56e793eae4cf6cc39bb4b06026d0df2c8f3752327f02ef2f8f99d7689c385200fb40de5922309e803a7dc4ea767839ac615dbfb3634832a2c23e960976a7f6a0e8ae9d4758b74a94cddb27d768dac5223ed2b821e1d28e4d6526129dcbe225e536f0b49ebda36c6a717fc3d4c9b20205018f4b06a2262077e6c95795773d0da1c44364b67eb8a9ab67d68fe1ade773e811bfed2cb9c161095f2b336dd02a4363ac5afe9f1b2b3c83e694ec6cb47775b77578afb2ed71973dfb7d7276d6b5ca9e76c27829360af66fcfb9bf5ad71465dbabc71eaf8b0d1e81bd071bd64661386239050df6f18cb7aaeb8b9e78e96a5cfc5b8bb3bd17c870cb411ae62ba94beb440757f3747ceec125a39366f5ea2c902b0271cb472374c000f5c09489f7c953b0bf7fb2382e5aaa1a0830f7598c0e5cb26bb3dfc4b1ed04e83182e67e8303ac6e16c9f2322a8274fec18b148ffc24f55c4aa61a62cb1b062d4b6e76738bdd8e219f1c35c472d9bc18868cfd8922e81ce70c42feafc7c831c7493e106d1aca06f83a779c1cce1fb273d49ec86817350e0688c1c04a47c44faf30bf7880a70b9591d690b2c5e9ce1bae8e427e9d2ae73179b62ed00609d7e66aec8d017f978265273a0cf9545a491e6b38670121f9aef796123ad2338193756fea7308f9915c1e23822c6d57577b388503f02fa9337a9fc34db08d6164bafdbe747a7b508ee2309fe5cfb32e909ca136e9a6f953d16ccf66c22c9a6cd4b69ecf55c8ccff5d5473aa9d5cb2aaf103dde16429fb3e295eb43c91790582bb7396dd169852009713bede34441390713266599eaec41afb7a11c9022ee4e5ab23ac62712e9a64c54cfcd1b775d11a7fdaa47fc1c7278663e88feea55f4fe359a8d8a403213c740c6194804238218d986661fe614498f99d7d8c6e828b9f2702913b2035daa7e39bd493a76f433e2332c250274e315e7f6532f1fd793aab067778192c8038f1aebc36b65bc674ff4a7e1447c8b56ce455ea5d216e77f3b51846dbfe0d2c1bd925ec9899eea3b3572f1f57afe87f21675d41273bcc6f533c2acd5a5db77ac65ada9a7c1334c3db237238136bc18989867ae4e9800d71c127e81e412cd418ebcc2683816267b2b259c10f86a9f25480a4af47db0c4d4d30c88bd6c1eeac11c771a2bf188365c7ee22c43ee8d1814d274c631a9c547307b8074aed5bfb6e08c89c64de6815b4c1e78a9f6360b6040d3c0ff6cfea5664968004de8427138cc3f9c5e2f589a715bbb4e5925e86428ddacd765a0f22c280f1c057a9ec37be252ffc3e5dd26e3d48c5efd4f09878d7fdf2e54a579bf089e284bbe8ecd00e4280ab31efdb1fd7745c9a1c73a4be1eb2a20b1dc22612999962b897d804dd126c0b429cc97e603095e9f276fb5dead071f9901e6aa56c760dd05fafef417a9402eff29ca1c8ce1383f751e2181faef91670ce696437761327510297508b352c99f74f393b8f7823b8c5d6a688f8e931e494a9ba03764f4b455c098c27be4e16c2af8659ff12a38d15e6f7253daeaa34dafea32ad29f689ef3bec06901d234431ccd2d700c34b694811199ab018d9e24f42abca48ba75e151f93eab5ef13947bf10f4b13ebcf5181ebfc6ba251507248c1bde1356ccc189790a4994cb50d0407f070813285c530393e18f11f373c4c58eb529be3257339979a4e6d068372c21ad12dab706799c10f2ece056fc8fcef20233d217646860dbc5af04c5d550126c688ebac3d0a75bf934de0634efb5248b3b8f205418127e735d038878052d9e324a7b52174f05f224945db74b050777f114039a202dd7449491123930991c87cb1c4bcf809a2235fe1466f15a1eafec0f999b3fb40814c518ce6c9b45920ed31dc55d012e95628a6bcbfa891b313dc6611e90565a6f1342b125b0893b9fbdbbb2c8a58a12ce3c149bb4d9db4d65313a335fe34293d9bd163f995be8decb55653110ce47db6f3b11dd923b8a65d462b6daeffc68df734dd502e7d0663d7de4032f9d730ed47e4efe1c1bc242185cea33a6b655b872a9ecb2e0278022c8a6083600ae823d6045bb574e7188176ba602f5da6555c962f072461cc8415a4f081ca097396f382be90a3e2874b5d1da24df3075dfb5e369867c80f220d7b5fe26fb7450445492547544dc21fc1039d7ae62ac4d6de4eac954df04a0802581e26a7b755151d0985e3080c98f2a57bc4ef8c1e062753ad0aed013d51c1df3e5877cc1a1441fb2741f424161d8fa03909afc768c0dc3ccb3f4ac584b4dd1c3f71e5458776d32546a5fbeee78b10bd9d1057c958c7e6ec8372f9e16c8b3aab3dcf5c58a47817596042b2911868af3d10d4f7f35b3f9cb8f82a5049691fd1de866fbb94a222f7fb4743547bc7b5209ee5594cbf3232c8d5795e8899c30f154ae4f2c04a2e4e5097f888a9821787341f86f3be466da75a0fa7b9d36d5649f42345790f969c5a7f85ca6f0b2a26a996e2c28a817f121613553c1a72563c000f0ae84d0f978b1e6fe431a93fbde361d37fe98c8a3fbe9c3975410f224f67e712479658b4b7035c9b4117fc6305f12d70683d54e1a3a625fa2109d661b2684033ba2874d908d21961a087b3dece9e8500b4e71a9893a45519dc5ac377ac9a8f0226123cb5b7eb8913b5662619bef9ade40afe19e8816d278e65e63962b9d1d91723ca92350a44a55f76792fd057605c6e8a868ad076b04a779f769a211dd9b5be4ff1cfc436d2f225af449cb63463d31659a8a77a8c652e89189f1243031891a07f5b0fbb1ca491a927d9f1dfa014fe65568bd48cceeb9b71e4e8ab2bae079b674d5da44ff3ae57d73621286415c990ede55e7ef89a2a44e6f11af71fa6fc2588df4466fcac14ebffbda27759fbac29e2e319436a29319825d8bbe59a8a441ae31329cde6d65c7cdd929428c03577441cbfc45bd8ea1ad4c2fa05655780c9e1a17d9e825375bd99ad01dba86f0810c73a3b931677ff900cbd3aa29b2e79191a6bbff51a655d48bbf98a5dd477f873d05afa96ee28c513d8d8da73f8bb878f007f7157f62531049c366ae734d5aea34f294eaedf47cee591b6405e91dd8993970fdeedd57c83fa347a512a7d9234c28cbc3af9258470886419e0694bd5b2559f671fc5648c4ed4c3f23e701a84231005f38848552eb651320a8f92a664ed65cb99b0b48fff0eb64c92341d6da20a9cef1c348f80435c2f078e3532a6321eedf12f834b1f877eee67b10777053bb02bf7a0042570b02a3dd375a1b302e63b453e3dee6628bf69f7d97d6eab78fb84368169a0992f519fc3d68691b7e7542745783ddcabcdd4aecb2009da0b27a1d26cdf66393e900fe32e6a51c428cdb99156e6fd8bb44e39ce9fd0118054bab4e41455a48b2c6f8e71f161c4374088075ddcad4d1d1a7af33ee5f729da69a03dbf9452e72aecc2477f5cc7ce2f2025c8b1bd3056145ec4d59a1ee31bc3b3c013f8c190b07682302b33edf1dfd8c7793e41e7c87b19e9909e51752e5360c93cd3b661377f65cab08c1e6d32d377932997969b0fab41e3221b07464709c393c8a19165b909b8f88bbe310381b55ef8f60e1d606668c089e4d89601ec24b7860f5beccee40e52e45eb8d80194f76931e8cdf156c3f01fdcfe1e28f46a698c619ceebb5ed7f0f6f04e2bd58e066280a88db9f570cba3c02ee990f433c85b3ae1c1e666e852008247b3607c6bb40c0b3af34d4e4e97c8dcc507f2e433bd6d4d81d92faf47de7d8fe4a1ca3c483c3675ef11eac7e56029fee06051d053653cddc7858c06579908a1bce9fb9cf3d3b3ef4a7fd61600dddad7e13ca3bbb0455979eb15424761e2a183162e65cc4e33ce76aef5ec691c9ba4359a345bf2da9d113c6ca734d55007cb35f66b0532e3c9fc74350f88134c8a1bad6d8b098fc990c5f21f61ff77bfc89ad5cf5e9f5504902229ab7b8aaff8652022df0ed158c1fb7ae0be1c4e2e6cb82185f1163f624304f415d063705edf78d7832ae36c22fb95f3cc91b6e693c87557ff02c0fa03ee3ebda020c8a96433685343b8907c36ee345455be133b460c276868e6e40b01840273e5efb1b5873831d3380948fa637bfc80c9f65c5d6a6801e3a08923cd837c3ec5d13f1a6ee8bc5f0b19b024c6f2eaff36e6770364212351741a29d374e564391c3403018b0b65a46ec6c222fceebfc0ce29381452815842d7705f21d91cb7837ba5717265b9d48c8c30dd34d9ab00bbdd6ebeae253b534c7c3a61788ed9fc5259af6331586b8fda4767a80f7d07a307b9a1b4632ed23bba587f1c323965427e57ac9ac87f6310b42bedb27b4641220ce9c4545add6a86d82bedca1ea067856bd87dcb5300e5b9c8f8fe0b13b07eb8d3d729693bd55c9514a19298735622b3b3366ac215b8dc9215cb6a0f3247e9a3d3f570c9e16b71887a3b1a2a65cd6cdc51054dc8d1db20cc986a32a204dd05a5e2cb577706d9d4c0a35fe8a684a186f1aa6274bf8f610ae7401b752547a6e0316c5784d2eaf7e9bfbf151f2f20cd924a94832af053302177cfb506eff7482f63fdc6accb8857cb6d50bf69088f5c9652e4e0b8e6fd5c6a141b9d3b825cbb06ca94e198c5b422c838950c0333e9244cda2ae59dece15c2542bb1e9d9a39605a1d069e72dd775efc9d21519803e2a8d0f0b566978c6e09a27d28575e79fd926d4828f97984c09cbf967e0cfea98073f19deeb17ffac8f2060030fd1c2e7416dfb25297486ec0a3d4e5c2ca10758f2a8c6a9933a80cdf27b8285c2cc18f54e0f9ea144dad205faa0129428c419180f2ce1beb1f65e2b558de8eac1045e4b39600091a6ad72dd146c515c4278c87cc8f34b702706cc2a47d79fae47f21d0f1900d422e97993ddb676c686dcdb1beceb82fa73e26309099e76b4c9aa1e4e94dca3ca0fc38f0ba05717162ebaaf61fc458250041d827246c5f30f0fefa87d948bb97a66be3b43b11628af6a97a1c1361b395fa31195e04ffff8947c8436113776715ab50e2114f62c9cc9d125f581a21c3f0a8540793e498156614860ba2b368e7ec7a7ff73908e8131a21a05eb15e16888b4280319e5af7ad8cae8674496b6c96f98869064edbbc74fe600e5f781f7c37b4662428b01dd50eb94e7cd38da2ee71efff01f37bfa7108d03b0f57792d3a8deab0aeec5fe49652120635aeb6ad468fa4377fadc6ac62cb67597e1aa2bdac815546b6329a57f5dc3ea9115ae4116b5e7816107562f5b86d4a7918824c5f62f6eb66dfc5d59e39702b5907e1750db1fac22febb4904529ba52a6b2eaa4e4158b47c3f78c74034ab48b0685a5fb69321b5431c513caa605a9bfeca5201ab573197761d0bd395170ecff0887420c4b7b1a11ddb9157b49c03ce2eada49a1b07891ec531e033a31173bc4a5390c294e53f0c8807f97ea5fc1421cffc77c8fdf8836aef58ccd119107722e9a812c44a00964d406f886c960696b6261f72c09c64a70991d426d135755f94481868b7918f7d1ec874c2e3458cedb7aaa65f7a64d140a8a7a25196b9c79fc96a5018910cf22fd1d7b267dde6f4963120ef19bf682c6f03b2cf2d21f1546587cfdf5ccef2068a8264d5c9c586b0fae899d726e08cb5059605f4674c6b17fd879101c748743a75d4f8861e5da9d4f389bf79e68d8232f9a3e6a55dd860b46b9e998ad754a653e2e28fc0b9c4db2b3f0ea424d1e1a8959b043dbd467e38e9109d68351df55613ecfbe41d211987a8a06d1e057fa68d91586569a3b490e7c5a120861953343612b337451b9cb8f90f11a485b545fe051815e888935325dbf1c1053f8ff1ae6029bf22007b4d07376c1fc2c085b9891aef5b92e0c7d5219cb72e1fa6229eb3df06cf8268f6f0d1e22e5475c9d0480c73d2022d57d42eb0b7bb397d5a82b788554d38c4d8b14cc516741588c1eab3708a790a0154450e94a9d836e7509fe0e8c58bace6946ca208aae283821aebb2d68ed7d5ddb120931f8688141477024085fbb6052285db9aa2dd9b4ae70fa5fd719ef99a3d657f15939b32d5d10583b93cec2b5870db8f2d4a419691e7225dad96f4d7c935811dd121d8537baa2a9c2a3c6225e79f217ca38613e15f2ef5e8ae8e9c02bceafd636bf6292cf4d944fddc025027ad27a1747a9a2593072bdc8505fabd49c5733d4e56b055adfffbc7bcc84ce3e40969c9d3940124f267eac1cd0c022b7335f5498b0920f4201630fe031fc8d3e9ba371dfb01cdb4224454abd63fcbaa117842895174adfc4341244c8e057d7c16aec60326e6536175f6f13522f02aedd9c112d5a5a5ae12b027f7b74b257b1322c591b4ca8a353f595878fd87f4c4fca39a73d29280813df6691c179c80b464d2dc33a4865db7937718f29ec35cfcd6e8fa4da5c91ce5ea912257ce162cb156f2bf2c8bae5a7d725ef1e5287039cb314dc713dbdd1f3f94b3a620231ff46bc5452e7fcf50599cb65561e6ba23097f1026714b4d4446522304f4b9503a5f7805ea3ec30b332f0d8e43b6c14d3718a656782c5218a02081fb7354f8e5f6af4af307663f285c2bd2b358067155eee24859603b88948ded4bd4fa005d50830386d5302c96e9bc3e7e6ece3dd01a4e4b9430f020d72327794c63a1b6fbadcfbffdbc9b4f5928498dd61da34ebc866790ae2f1f7bdf2f5c83975a1a5cd54edfcee990eb29c0bc623861f2587ecfbb302d895dd73b90cc2729c4b52cf5dea81bb2a606b939aebc3df0b9d541f861adeccf4d073ab2f739c021a9f0c379da3ae3872449eb9e01aaeafe359394d7ad2d76de405d497a40e9df4b19ce4beb1ab26053a86adec5f2ba85bd465a4b388dde1824412843db8e9fae70e05aed9e8af4a76740f6248e9c1c495d99d1f7c6f7cd40f74a2449820a6ed1c1f7f1abf5464ed18600d9cd6c96d1ab9d44a58e0242dbdd2b6af5bc34bfa00d04c6566115b5f0c373afb0523a28dab590e9975186abb06bc1463429cc3b984a3b5f6b4066246a5ebf133c07f53862f9ed3781440506bf112635b1f7419380225ce682e61ca37978551f22f1c9af2aa68f2b879d9c1d2df69c86a1ee231c89897f54a4ebdf0a41928368c331c19b10085e03361c8931fb46e4cbd96ed2206e97c5d15530b7eaa0ff9d683b2cfeabadf04cb9936fa2753c048014c1910310b7d8d13fc09b458ee75342726e80f349a28426edbfedec617da4f220d0ab193f39228dbb2b085caba1858e685e5eeaddcd9a9ce7033b30d30a8bf39fbfa017664ef60f9ee5df0d8756c2e9998c2696aa2eb659eafa9999562825b224335ad1b1a1806db8a94c46fa95e58f8be43f4f1546351d7ff854c65eed002ccec44a75debaaa23aefed7af245e1068e168fca5b0b06b4b34dcac962b934ed0313f0c14189e72dea88816da9c7dcd4ab40e3b90934b4af49c7121002e75e39b35135f671e9edda186e5edc502ef3e88a81985be4ddea15e5b687007e0a8601fd80aa51a30a6b354a3f60eb9ac27f2dcc74f074ac22bae1785620abb9077d067a7aa5c81be12af73c64024668bdec2cbf50946362e50495e2f462884358aae56616bcfcb89cdf679ea516b944b8253fec6c90204d07cb47f5e30d6948c21660043efe92814ae8bbbf346b6d9e908273273e7f72752f853eed22bde483432b65477bd1a3bbfebd3ebc298e90046e233937b0425b7af6e890f069c667100bf2e22bb70e86ab1cfbe87b1c78ae14177a3fd061565931ebb74d8c1aa260f439b79d44c4a142c9640ab28ca26f41fe963c6a0dd0bc2eafb6df042cac13ba6dfb3f3aa009538cd808fe9686cdf739345b8736ab1400bcb3ae676581b180c23dcd9cafcf4ce611dc706874fd58fbf9bfecd82e2d13d4b077e1c565f6715812ea53290e19b9f14227648af529a95fe3ef215a06e4f0edda060260567f8e8a3e2239423e107206b35272e89e4f7ba8d9787308e9b8ea062ec0c62d5a44d6718d1e9d970927200482f7be7c5740d14883ce07e33b3e04e3b1ce49f3581d0feb1573efeeca9f021ea08d6f79c335c9ae589a9d562936d2feed7cd21ab1b99210abe940ca676f8a4568ba1f8f27f6d960730a87d88731cb0d2049fb72e581d4f681209c89d6c29e3d7660eedcff51ab765552091e90c52f1efc6e8ebea3abe588d96ee3a032401701c8faf6ac5eca8660586dcba7ba57c782568ea84124bcb737d1a7c77a3310f769278fe6af82f7ab26b3373efa21f20689cf00bf80043495f1c79191f06f74ba30dd03410d96d9d255085afa31b1efe831dfa0960bc5630217dd4989bf9ca1a27ddc83a547e29de72859c45469ef74cca0be7bd5bc4e4d9500b04c00b686962edeaf766295fe5dc543b27f18e5a10ba9085407700017f3d6d247369717fcad6c42706eff23fec67eaf7a685c0b037a5db7d66c23023ce645d345eaf85a15ebfad3a4db4f18e234918f682321ec608fed3492ec15694788fb48b432613af41ecf0be3b4204d0718a6e13dee66df63062bc0187d03b3cdb02bfc85c9b280ca50eededa46dcf1a227ec964fff4f825477b8e8bfde203a01b84441c1cf7628e7ce6512a9aca94cfd891e263523c20a13deed70ae4c97d84c207f8abbe30e117cfac61ac2f798114583d6795b8a98f819f04efa3a4b269b91853c854476b44f455a1a9d70bf784155cf6eff4b01292c50b217741eab373dfe9985a608503a660a144a6edf684587714d1952f69dd4968af93baaee277e7e60ed1e9ea95af902900102b9028b39f72c429575c026f584f13c71c365d0e73f90ab6cf12fe0b068b059ed3813afe08f9809b3cc882736f6d34794cd91dc6ca4ab2dcf9443e1f70abc18a860f8ff238d7cf59735fb1cd6a02ad4b778b91617b1adcee1b688f54643144eb99caddacdd5824922b31d4a19ff7ee6bf6cc99262214753e2f6581b1a5bf4eb514b1d1f3c6f896dab8891766db73ed5bf2ce6d2534b7be18a8cb6f124a619d18dd3ca7fbe19006115aa46248facd48922eade242a5a74c34abf7bbc756f7c38d48e3429dd89555d27322e46f774ebb6968975f1cf32290949720c5e3b6dd881495d9c679a247a64fe1829222ad061bcd129499f1b5d0d47b5fe7b2eddc98cb5d061b5b3a2738b454361a43ab21eeaab2529bb8bcf0535ed06d34ee23a8db222b652b1eaf63c23795c621eba9a8e43fcd67b380457a56ed56f67d6a945568e4fab5e3ffa613fd1bb8e1c425d55225b35b4cab555ff7ac84bce0397349ea20ea34101ea999d29635ffb06aa3b55d4315d3b2586d53c66ce823c82e09f1d4eae32d59a6bc635073ed253c6bdb82d333a4d7a69963f0a675d7a5d452f57b104de5193a56c3a87b7d156c4fcb23325ee16c67c28f20a6f3f5bc8d3b4d3caae5334d43917febdd4fcc4559ee7874555b9c1258ec555d0b473a6b3542090fb29d3ad0be64cd99aba63cfbec39a64074c94c290839ceaae3a1eb7a2269b7b53382e76471666b4fbf3dc931204d7613364761d6c2eb9362cf56ed601a28c57747fe5693142f8bba5cafef1e2956209cfc4a5b919cda1dfcda7ba1449943b4b55dfc2dc6f3d1ff84772f0e941d6a852edcb82ce25a8db594942a971c44894178f5e9f3ee9c5186b55114f59f539f8ae7f8b8f841b15946291276625c56e2209b9d2e075338ecc65a55615975f53996432981395f91eb50202b91eb00f75bf5a0db588762886f607eb0835f2d676584122d4e89a900f25a13ad08ca95463ccfa4f46ef4ca551062e31f1f624fd0244fc0f114e8f5228fd9f394334eea790193d27bef1f393ff494f5f4d8048dedba3442375ada094810d1a4937825900a0b5f1517cd32fbf0f350b425646402f445a97ef800000cae62932248ee1bf4c6a3b807366fedb20c89bfa61850d4c6d3420d64ec730dcaa1212fb92f4cdecd30f678714a783b3beb913370ce5f697d0f60bdb767453fa881bbc40199f2fa480e0b8fa13f5fb57a138b98d9010259b6166bb56d896041dd5dc9ca9498b3c2c26cb61b01915b978e9e22395fd6f526147b37b257c6fd31eee0d8f850aee790e270df64ea653eddfd77b3b0a98cbb2d62a879b18fda31fbdcd8f625ddf0e1139c27ca71c76f482bb6b4dfdc3254be659308f3ff9fec7a664feb22e8e52231512ca299898e04caef655b95cf096ee6d833eea85d629e547bf17baf1d83c11be2d60d02a3f96c47de4c8ba8f3a3d6d9f136a84042df5f49d5fec56d448747e47ae47a2d60d9607af3f989f4465a447db6eb8f568943efd5b5dafd3310dd054399ef5c348c863dcced9ec36f775db8a2a7ecf0468d780189d3c9795813c717d67bdae2b7a80d0b412fc5226c832a96231599e56a862dea094efe243be5b931c5368485cbc49edbb767762a0b13289ea0cb190cde494f52a0b6dfabc897fd54eb70daccffcd123452802e74d08b7cff93d50b72703795d8148030ef702452bf2dc8d5e127cec8d254282ad433f587497016e8e199171d3cfc59f6c8b34dc837670c428a74586474d6049ffc60f5c3e4cee054d0c5f1c27cf156a4a8a2bd119415e6a3166c1cf2e464d95d09719912420338f309d95f265e6a57cee9f9dccc380f1cab4a33e33ebdacad4e0737668c6c69e2394b70becb0181186d2783ca8d196f8c568346ade2e7010a1998e984c9a9430ce899dc0e370359567d0f79d22ec75d1415841ee3463accd3053af6aac2bdb95e7b7a913186609809ef5f03b81fdd088a1581a58f0ce892ab3524a276a3ec1342e94a0f0143745bfd7c72d172d0ee6954a1a6d48ee98c3534dc7629c14c1056c26a74ec4da0c4747ee9b12c3f337c9a8009ecf53a2a3e8eab2cd8cfe5ee8b303ab9dda8b5f2f53d7355475fd0d9e2e631bced5fae3df7587aca96244e19c550aee5421d2c7564fa52c8da8dd4871eceb0d3590c87daa31ffc033fa563b98081eac746db8034306e207ebd0990807e3ebc07b29f2f84d09b43019ae4840b1670c2e6bc38de739d7e327f934cee38cb6a84e2f0e74f6723d7a65b926cb36ee7761cbfc63d9981429709c69b6927562cf7434c429abee0ccd2ca336d73ee9e93b011c244e7c000e747edfdc46d85146efee7f8587421135338e96c15fc2b65492bd4b08ecdae901267523578fb2ca1b37f6090008502881441c14c888646c4fcb0c80d3680fb8f1c011ca8e3be932aae70c5ca4769919740c669f029857fbe59ff7d899d9564eb922bc63d0bf05310b7c98d71f6a3e8864ce6f17f23ff5f6ea604af3f2c8829663e384ada89889d4a2858d40594c6f2d16c76f19bf7fc67a10325aac9e38aca88339d1f8902be1203d262450b5dcf3d848380113cf07ba06669a2e7073e73fb51596e0165943cf30a608f2830dc9ef34b393b3e7d25f22e8cfb7fb1de58dc7520d48b6275c7fda94d12d5bcc1d03da4ec67d5906609087857357d311d0132017f31b4c55dc7fa9892d38298ffc56e4d296954220ab9d7f9a7035c7079f60da806e51a3deccc89e0ea2c9266123aaf7361284a7ffd26f49d4282a227589702ee7487127ebcb08d086f13cccac293cacc94984e7a03c4a858c35176415b8378958d72d2055c9aa7914bf9a9958ed0e8fc0e44704031ca35aee8b14d9ed7d66c89d4e781116d3c37a0a225e70a34e57f57cd5f135983bfc5579f527146aae98fb6e055f043957e9c2187bce795bf80154390d8c6805f05fa78918cd843bc29c86750f3671f2b04bc24d7e7e3786bb9a2fc537d4fffdb64572f6087a7146f0856c78d5f42a4c87d76bf5c3401389c085bdb2e79b07ebdee04d6a92587b26b6346d8428f60c8c655555bda0bbb5c44c0ac30cda7a49a71343797167d4a8a1737d4bcce20885ecd7472d82bbc9c958cd0dd907357260a67c4e37f106c0792e087de55793f223804b5671e40a442871355ed19dc2760249e1b60e60043d638816b6686ca4c65e2397d48977057c8a3c1ec367da81d5efff79df040be3067f47e5430fc82662657ef69f7b7929c6d91f97662e44482865edf3e5c88eabed54e6d3de878a7f5b3aece5a7f0f97566d28eb299860dbaadb3993b9a31a43b1c179a9e4937d1dca64219a6fb99b1612460627a368712984326bc8768da257d6cedf81fe28957ff3718c00a1b3c41c34e2388b83fb5fa47f90359a6d2e699105c1bf4f9ac1c2525d3532e3b7fe9597ce5dd57cb06b4bafd2f1cf3c6ba1d21ca81ae0b12ef58ada18e1b49ac242900ae484daa1b2c80d665d65ad2c5bf2710f60df6f9fff6f7c32cc0af651f8dc9b0005e2a3c1f5a9e670c82fe1c8b296d023e04c2f3d743a33a555b98c54e6762843803e59e5b1e7549ef0684f6e2e9dbb2e892b0772029f3bb89b19a16b20177ac284337c7a252c73e1ab893d7b160da0e69bb81f81f9891ea930842df11c52c33f41eea2ab4c1ef84151f88bf071d507b47ae3d7c9f7d6cc5c57a25b236349e1dd82b37d42c36ce800960c297eb13a779bd08d33b8e18ad9eab2eb13daed1e8a279588fa7953ea9f99c65c4dc1998ee7f13ed6eb594574b5bb95ed1c17477a9c54764ca3abf67c227b2fb646ea487d33b8b84210e0b110d6dcd1233321b8caa5f09bca5e3bb23f6e7b0cd378fd5ed56f78dc997b7df6fe69c7a9faea38bf7016380cd71af4b638e279c87b29a9dddc3ba6b3e5212b6cd8e07300ee5c894636269bd689552b4635421fc944b06b5622d8d38b72d54914df96b01a4d144f5db13d9a2b15570da139c283a7609d4e32ff17eda223b418c6e1124996ce95c5a5af01ef40561f5dd54216682c647182c74e7dcdc4e4fc532959ead549758d05bf92754b18d49bd53ca86584c1cff4becc1851796450a68209a433d3989a8873d00493c324a7415d709cd9e5732704579b48b2875d9ed4d949ca497918a1ef7992152665f72b5a26c6071f63deb1e77254413020f81c2bb59316973b5c1ca8308461b897692bcd817ffe12f0f1aa412e43476cab9557d5b7a12605c4a2bd5fc7677ccd76d9adc9ec05be90925a54ac488e7fa8bf160945068e76e0599db8e90b14f8855aeaeac3296de58ce98f5557599fb3fb2bb195729ddc1aace732ebbf300d524f85bb4bcd0a805b8553c86d399824d9c63897c54cb4ecfd1d1fb299b567f1a29c36bf35d301911a2b1728e33e3be481971c2544a2ed9eea52fcd78d0537e165f8da12d8aee0a9fdddf7d1d7fd2b06b0de6f4f93ae4ccb778d356ef188e923f6011152202a26f291db3cb3c4a46af0b7a9573016a0db76726a86a349a850a6b645597560d52475b6890a105e3ea8c980bd1d9a6f09edbb2c244f5d21b9e46cdabe8e86df2e6cea3302b393536b14036cd75762a669a52b93819462f393ab86a1335fa1bf6d91e0333bb9a4175a917a91539eb4fe05083920e7e5808ac3b70f7d688e7e1ffeebbbb23b1903aa554dba2401dd8cbd74e161017a6b79c0f902576714277f8b2fbeb176cb9fe1256edf10cc1735c7acaaf35d049f7d324174d19147bda94a52c464a02abc7f048c177d1aa2263315dfe220687abb7688f3109260b16da858c2dc22c8a79f69b8cab22bbb48fc9dccf2d49217b4473dea0bbdf0ee54b8d74398023648d07675c430808ef48c05fb6f46f01ce53c69729ff2d8439c745b25f6e47623f3759fffe2b71d598a7e424491f1c9374a81ed9ff956a49f7afde6b3695f45bbe5c9416c48e56af2d509bdda768220601287a2e5a849de26def25808e07b9b3a629a2f72698cb910132bce1c29e5728aaebaeaa6672e8a690247dce58cec2ff3e2b34ce59310f138a51731b3e496cf9a9eedba7feaeb3e8f6132c9577f25680099fba83b8b2e5cfcf77f7a494b99b10ba987d24839d469a65c5236e5194bd69ef1d78abf9d95d2fb52ebec0cb786450965d3b4948fcf0c265ede6b7d71e53a8b7c791a783e8fae48f5d0ef203e9137ccefe87005fc7bcdf29f8d25bb8de08b3faae1ef58328a1104b86a77b738a636fda24354a8580b8d81a6c305572d035a604f1ec40c20acbb1801bbfd28d5086f81dc6caf184354f2308816c980c1979f64cf38f5a9f43e928a6b6bb622d49a63f3e6873eee01fe136bb181586de54f23af6a671b66182bbe09f32b8f5e073be37cfbcfa0ce1ac79ec02f1e30bde62547b9f9cf861bdb678f8692ae604dea1b2989c9399fe7bcf8d9b4d95783cd0616ba3dd73f604e39b2e746b18add65fd2006371299b2e48e36c7ce979392cec9f9466e7b1c4e9e9e03ade3558bfe5d278ff97673a7f8be27d7735307a75d91406773d59f070ea48fe442d01ba4f2518cc6ec437423e4255bfd94f806cdfd5a583c4d8ac681b94adfc212828aab74563e0ec2c880e1930119f33244c6bdc613cdf6634daadb5119904a0461b8f3af7094f59e388d0df1538cf63803df19b13c67f6896af69916c73b7735e809a98f1690189d080d6800d7a564a5c4c83d1de2250505857fdf5f9e668205a15621904d4499a9870fc74676d5dc689bb167c02befe0dd5b78015db0bf1672d9e05f6b291aab87f3dc0e0db31b784b88a468338da2df19ec013329012e00f2bad4626aab32d3c90ebfa1d9f5faaa98333f1e423db5834bb801897f4290c4f6a175af6a2db554be6a5f9c13e1371853da2794381477a480f044f515cae195a5a63237cd268dabb61585f8bf4e488eb7f45e7309722c757c858b4a231c07c18b93776156e6da4929ea7d33adb4cd4c5da9e8a0b089acfd8175c4ea9df959b8378b5826a058ab3cf1add0f2b65a4b08afdfd2d2729fa0b1cc2d4a0102455e2c67728d1139f93973e715f80f198ac17d2317740da48fe4c284ecc385dd87cfe66f18e1ddcbb34cd6be217be573c9cd6640e776e98693f4ae6885c3bff78993aa30e07a1283d59402924ef2f8ed210d553780d9653293c914ac767399cc20d8d7672d37ecbea5d775e52b68e2f95817e17b0bfb5e7ca866d26535c066bc0c2d5c4c1f6ee30907438d6a74c0c9570f4a36f199badc8af7d2471430db8a7232a7c53172cd4d40bacd62c4b8771c550c909df79a25336dd3077f642c38beda716af6e7b2987ca146a92db7a26b2825f1d9def0b4da74f6f7a021ddc3e3d263803345cf36b6f0b4990209b321a62105ea6467e7c1f4cd2cab5abf92d7f143e479975b04df82ce3efcd28957c6f0e5efc09e774a7e9fffde26687e28e692060cd1cf815624115aa509300bbda70de87ace9eba9f4a9a7b559ce7b12d6bfab62cb179978a65a3f27a505ff85474863c19366aa90c24d70f34ea479a8f56b07ef089bb444162bd8be7cef6fb2a9afebbb74ac6cefe168c543d5f7641fb9bb06a751a7c4a47941fcc7500a626964f468794b6fdfba25188e991893efb0153e445d750899256c7bc3de52142f7ce9ece262cfcdd8f37304f265a5b05e5f3b324269bbba9f6fa221d875cf92739f391cf4ab78332527ba8c17779722ebe23e537c8c055139f15449c500854c0073865299ce2bab57ca6948e066dceae53370cea80a35e2689006089354e8749131c275e5a637b6140e3295715f32801926d37eb86b20e7176d1455a2f9c697d69725f84291c283f816e8bcd36ecbd7fd88c2e184f9415c27fb054a5bffaeaf7289b80c519b03a4c395b42c998a937888a2e0c8254d02842eafbdc9257b178f2543e55e14c681199215a6af1ac5a08de4e7045309299e8ab67b6a09e13a10350956ad74554fd148e73bc45bf2c4b756f16ca75659a99eb9e893774740c63fd02aa5c99f5ccf0d15ba2ecce1a7356f44682734163bb97c299f5f0a6e3d4146c08de2c941df8ffda2c769adfb111d6e2fbd332869850bdbe770499a2032277e541a872b1ba1fb8af0f8082ef6544920d7670a0b07a1064973596159243177771f7ee84c3b3bccf38dd6590e8eef4e645b656a7c111a47cfa0d6932b9604138448b1b6bd735c416299302beef217a8ef21cf49993b7f7b664e201961a35401bfd5d41c0a3bf18453bee75bdac89a1e54ad2f7e1039714e09ac34853b78ecb9ee3a1fcc62ab1b88e02edfcd0b5de139384407a472f51007bdac829d261ad88cc9d0b2ac57620e227b365f872acda85e978f35ea49be6cd6d441c8db6e2ab8b077875a9e0670dad113a83d4f610a5644ccb2da04c9347c898950ec978f1aafc00063cd4df0e98e8583ee94d16d1dcf3790771766f38759f795935a9eb9040ad27f825b2102689df5e7d21095a92b9bec0a8c46b003583069ef02f2e26a4a049a0e7b819d10f8c9f3d62b6fe0a0ff8281eedfad25d02d17c0264a494364e992cf0f294f4bc9931105088e8d114cd7cd2f620ed397314d460a4277fbced08b18bef32513ad26f05b431e903e822da20f12d16f681afa515c5044275f107ce1cb564d3764803fc5bbdcca751627d9c27b30bbdd30cef2cdc942386085d8e55e203703af1900f1a21c96cae9ef970bf02561e09cb7b7183969977c0db3dd1e8478e59290d9dadfc047eb7f101d769583e9aaeef5a45d6dcc815bd04bed2c4386458e72d40737573dc03bdcb71abcdc848092382dbbfc8665cfd2d352999ab4e84be2d8a3647aece347d418e50495f7043d66122022e7c86377f8df5d24fa3c8569a38c05d562b111c6d6a4f03c323d8e787f1d59095c6550f336d310992b997962b1ee4cab2e040b3a65c1b6b510c0db4cca39695494fca883d7e1bee2ba8222c59c206d6592302cc4b2629c9fbdfb849abcf09581a0bf96b10ea3856820ace0068abaf94752e9796d19071f6ac6b6554151010180a11de3b988231af268bfe35d5706e3e8b3cb21d366d9322670efb90907af530633a1c91333c41c02a12a28cdce7c0c5c9c5e860e5db5483331a796643e40b869409c97f8f6386e0d4af289d02704d071233972291aced1bf0764675257134ea2fec9c9f65e9b7773174024a2b200dd27428ee5e27516bb629b1c698c00c6a30ad70e69f300ae11391bc8d594cd35d1022d77b3b0e312be2579bed4c391d60b713b22133b4ba915319111ce95ee540dc9e7d06986fe7fc1795755c467562f84ee0c6dfab163a6c0d40ea95bce475192672b6ac739b647c741cfa94b79942034efd53e86c7a7037266eea60ee2a30dfd132c2ea17dc87374269df5ac05eed0a376f553cf72249e4bd33f7a2815b10e3809c579efcc907c45213773cc4f13b634fba7d665826a15084334c32189311cef4fed4cc908f4da1807e3282dc0bf985f1e4ac6eea3d7d8a1a66c1d6590f95d717c13f49a4f6e53c839efa64f205741b4c8080f7be7cf35fd3f55a06e4f3827d61fe8fe8bbb2035355c580d9cb195a62a72051936d8b0343adf211fddaf7e3f5a5fcd86af483679e431b5810355fa07776705df014705eb53d77853c4748c46818cb6ec2e16f741e6a2c3086ecfd314c53a3b138b33ec050ff14ec5dec143781830acc493f249527f6a8672763b6acac6accc32833ce3162d9b6646fad21c38cbcefe83df0fa60c2398c45c7a214903b12e029ef8d86fe9a73e5f38911ec649267c857b42b1a38b2c58de7016fa5da2b7037f2e3eeeb83dde452ea0032a727f865ac80a06c62021e418b50e29105c66338329d69e03205a635cb649017b6090ea169ab4d3ec6362d8834974d2f44390fa8bd92cbec2c5e2d42db16809a0f5ad91bf98481d816d079290db42ee8b90fee805f6511a2f578037bf7d689a3f98df65751e7c1a3570e22d090aada7661d8892413e66d9b8158ae94f040f405be79e72a01960d5008a1f29dee2ea2dce4326be6462ee0aacb8870fe295ba47e2f1d36248ea29ed4330a23b25c984062a1b58f820042e3f25ab59ed141282469c494c35a243e436dbb2e96210963a0c1e6e909dcc0e65136697b216238fb81c642a6f5ce210aa0b343f01ba9b5171ff8a09d00b711b25668c3b0cc8fef120db2bd0ce776a25def094fd750b613e9b44874cfaa40501786df8698dbc761d4412b5923225ede00ed1aae66889d3ebe71b0dbab9e9dd5bcdcf2f4512d0ebf71f692c3b3beddf6937b0e8bc2331158c9dcfab157888f4b3e046df9caaf22412d05f5b2ce6039e8b8aa74494b42d631ae80cdca4ef0165cf361b1d7d3916ff0597887bb5cab2ef168e0423d5be6c2ee9f9ff81bb4cc92f159476db7fe9c4c8e5dc379c2dcc37db5e2bbf61f856daaddda4834ef99f651c686c04c60e18b883c37c54425874ea5b9508a3c825272366a7b520b324b2721b66dd3ae05e10c7e390ffc62a506fb28fd7c66a783efdbad6e5aa6a30cb4889b45a5b2a9d35d2766b94ba440f573294afb7d71622789ccbf737d407f3dbec272d4850f1d46c35652c11da6ae8da04c9ebc35c41d9a5f18755e234f1a12968ba3a49233d5a2526459795250f2b5ae7e6ece649feae1f094d367e22db279db9798f076fbe2a7b635f525e8a4ae231b1a9dffbe3dab377ab420f93d811cc5003f7ca03bfa9ee47839d3b0836c8ce4d62d41a01838fb8516cd7d5acabd979d6d534ed015770687af4ad75a84edddb7ff62aadba4f5046b06f803c3b67e0f9cdcd3bdf3d419365bce19772deabf0cf50a75a66de87bc2788ed87c4d0c32fadea116f96076fdaff2dc2d5fa227c6171f6560a92539e1584951ea5703f383f5218029d0a7787ad516e196fb7fb5de7ec4fdffae0e8b0993501e7fbc23fce6d8cb96cfbe85cb4176e47ef7906cdcf97a3cfe3e7c1b07a712dea2863f366d2e58b0a39cd315fc1bf839a292826731cfda3b9c3d7e807eda2e1ccbda31ae55f08084258ec1d3eb5c7e92031ba8c0a19dcca65a53448c2d9cd0f60f9b07e1e5077c8a465ae30788ff297112bee4e63dc8ae0bfdd20337a73de7647299cceceea01287a81eef2cab8d45f2a2a1e89440ef97d6ab6169bee5c03347e78bcf6dfd823bd78bf0989d2898496351d3ffb1645579a5b818532dfe32deb2edabd60673fc5ca71d9140c5364d8cceb2bc507956d4a9d46281ae35006d08b3045401be88f76090d698a0e55c578f44d62d932a89dde77699a4dc4b361291f06743601b475404556889c3bf746e9917364707369fc86210187e443ca7e793431ce9501d508af9efe018c32577be7491a4cebd1baaa3db0627445d1a8083dbddf16bfab0160203ccfdcdf10104c98191fe8942696c70f74d2aaa7e60aaa9f15ee50396e3261c5bd3a6f61febb12767e96f40b3d75214423140ac0a53ff2f65f3cb08e4a58e19dabef4510e3cb93ef6aa17252f959df013761d6efd19081db1c6b84bc0abff5993034830a3c7cd242b6f2073aa72779aadd774b5e9a178e052c872f558eb41aea364cbf2233e29c357b41e89ef1e60832029d2c80fe7ae10d3dbd86997f64bf26986717b78dd5dacc8efdc53f2328ff6d0feb70cba60f1323c932af00a1a5ef8315d3d4e5b5df5841519ead6cd13618c8f4fe33a2ed47448d391c45d6c5fca29964f8142f6a1d169164df6969ee4153f6a2d9b0f01d78cd50aefd2d65b31406c7c90cb6d60988165ba17137837cb053a7bccd1e4db04bbe375219c4039fa08e52377c7134f13bcb0d4734616c7fc37b8213352991e40d5c3bbbc97b790ed4e8f1c2910378e496485eb89759748a604650cdec857f798315dbe2278dedf6f125848ad9f7dcecf2459c87abf654c3ff4425675ca05e190c30be34d0d252ca43c0133e8a6857dc76d4eb61a12d360ad8f6b63dfb6216c8d18e3a473ae0ca9e6d82481c3a31e93319e5183f34db0e687451e6ef4d871c745b76545c64bcac74dc042ce5f9ef2450e6c2509d1020b4d6241a262d2d7c27c19b83f3a91d8b755553ccae40fb43d0e8501bfb18645a7e336ee2c7ebe1093ba91e130062ad0f631106fb1ccc04713b47bdf0e3a75c62af0ef73bcb96908c428413e2b550e82499a2e6fcd0758e4f47117ba6ab4119afbd1c3be8d4da5b85b3172d4de60b2cbbd150a4ee4cd6e284d63eb15926f934070f29baff691105e690e99a940c49f6e160afbd4bfe5ae6a1df8b273002e0d85385254f5aadc6b55a2e323f7f9ebf0094fb5f94536135bdbccc332f1b4ac3ab8844a1219f40f2ed8cb29aaddd870507544b38c0958f766415280cf3d7acb9ad91a9336a23ee0456eaafab4d84c13422705053ed0ce2665b21e2ee718cacb3399719512e98097a97eb290ba67b6ce820e5e1891451637bbb69bb8f4ac54db925870bdc5f24185680e0e70cd25c1512f3e408c901f5b87b72441c06483365b09bcba6ee6fefee42644a7be0b687eaf653a61d5880a8e9d90f19542a6542473e92d03a6a89aec383e2fb092589e6c3de03d2f0b821fb86316557adf8d2e0b52b6e883f91dda1a9f5066e55ee82f45aef312fcfde11df1fb6cf0d761103bfb552c516456040f2d6cc588a0c33a9d9f85a28cd580dbdc35a19f3414a504c761a7514538f7b704a459572195c1f1b632ddda5a9a730c5d067b16d646d3abe2cc7e8e51311b3221171357f92996f99621cba5c4d416ac006fb68dda4ac5b76c4300949a5704d680621b734f9499d0a14feb34ecbf491c74e31d2a3f29f32d1b7bd4ee1ee4977f1941b81db55a43b3774d76a700485e700734ed91eebbcf06feebec74f1ba708c956347fee1dc4c436e0536f9776d3c43b1ac68dc5c4a571f1b9ff42b384e1488fe456fcc37b761c89e30dd3a227b9a39a74f28a6d684a3628b814c156d9d6db7b124abb8ba6c3ad6313ccd4beafe81e7439aac300d6e872354cae3b945d2d89b25139988d7396d0292b42c4e01b223e801628b87a4c6759f24c61e85aed7cf0fa7bf9ac4fbb78bc5f7e655398dccc6143019bb4d3155ecfaf2dcf7fb1e4b7af4e21eab56358c00721dff902960103b9029139a41b2fceb87ea8010a4c1b87a85f4765c0838885715ae52e0151c28687d0ebeacaf8b8be6b640cc817b2baa658f4337b9a9e0a33df80d7f5dc2de526cbebc4cf91b8aed7e94d5fef6cc98260f1f5260d122e8eb7c397f8754ab266b5474c69334d0b0692c294d0f1d9741d943b362ab648a262b5299a2fbbaa9db4b0770ebd0304bbbeee4c0e9bd2882252649992d5c34b62c54535d5fb811f915d95bf864567cd983e068165c3401be5e20a76d7997e914c6627d6ebc4d5289190a661c6beb11da413fbd8b06b8936265728b165545c346166a5eadbb80166ab4969a973732ea376e1c55683b274166eefb5c151261f0556b99d50b0520b45ce4f144f99d7dbffb8cdbde8ab7f3b63345c5776d101d28b4ea66b139834ad12e376b71031589c218d7f2bb7e3cf9134dfb99667db4e2479cc3e30a3d931604e652a4d3aced5264cccdc80345ac55fc0f6b70a531b5a5e18dc7d0d6081de33bc64418b43dfc2d8953531a7b3b285c7484943a5ea8beed553d0e0e53324d19a613a3811d7daaa8a4cc88b5ae3cd51f483a425b311deb22f4b03befcb24fa74e3063f659864a089d1e280203583aa619338e360ea12358441f18f8a3ed499f1d0d6640d86452123be9d3b7d9f4ba73819ae15378c78ffd156ede7ca9dac663e73a352492a3bc2c56299dcf90c80244803834b9636f897e23be885a0a2c318fbc33acfb5fb4fa8cbbe0ddfd577de4da30b3cecd3f8e4ec2d1e264b057f7c8bb2e9dc160a31681c8f6dc9709f2659835d925332b8fbf82d8bbd1946e2e741cf80b5d2132be3812b4d125a5193167109e1f73abe7ef5cef6b943767b982a1719f6cbd14ab18622e889c38c515b3c966b2b68789038c2d2fe5c6934a349b9e6c028476bee69e876377f78ea13369302a8126362c1c34be4d0b5af91eb50203b91eb0956978632d8ed32ec00bd65bb40f6dbcc2b2815ae90f83b64bee8925f6b86c07e753081a8c8c7eb3b07f9335059ead59f8d3963b05159ecd2aa0743d5ade9fdc4b57e19647d1df657d974a3812a6295682c7ab3a524fbfc80744a9431b8e1d8fe5f421465099fc7201148c6ed804a49b21c81b3198338072cdd6ccbbf09359b210035d8c629456031145b56bb5a9c2fa48b5fe4a3bf35a73f7659b4e35c85f933dd805b6c59792c3f01dac41398bcd9562a194bef79e600db0dae347b836a293a496b2a6024f587937f6b10f1cb9725471003687e3b07fc1fda939ade274912eb62f375f77944f0d30422673ff2390096fdd2601fb9430dd27fe0a698c1557fe8f0fc725a564d4da45571cdabf71a15fcf5f49df3d09103a1800ab70b00271b23be8daa446835c1000a3dead6e6fda68943d78dbfb42fb003a7372a39fac6e82b7ca6bfc863a88eecefbdef5ddaa4dbd8983211ac922a2500612f4fadb3f3168c81fca47ac244741051c86dfb0e4b355fc39aefa92b74d95ec0d0942192fcdfe4e75190fd4d5117d3068d51f4c09587e407c902ffe6be51a0e905336216a8d9964056e5e942f8544345b64b08a263bfc10814d75a41abe4d47c7beed5ed0809656fa1180d86beac9fd51f9a4fe60bc736c4360808f9f49fbca376c5bb993cb5dbda52ea962766582927d1e8033582881488ac048daed322fb3794d0427a13d9d774d4aa5d10edc437d7617eeee35dd61f1dc220cfe3c3314e69e05eb89bd2b513c5a7f8850600e2191e9878c6d8bc17811fef187a8e53a1f46848910e563ec2345e38745219164ff29af9c942c5d15498fa319088028594db72be3affc6670846db65dfe85f235d2e5e139d985eaab8b3a94ec7b810139a395d0d46912f08d5b56fd868f2413ccb0a47f5fd2fae3063ed2f4096e32ad2541070e0a98cfd909779e2e683fbf4780e4ff830e74d28bed8f258b6672389ae010aecec00ef7ef1edb89eb51dae188a5e0314ae2f25a6266fa7989a79d7f8803db28088712bdec2149435117f8193265bf980ebaf3cf1690e625cc1c5165cd40d66d9b8ea00a5e17cf77039db8a470aaf224cc2fec25b930f5c90eac94f8c094d6a4b786dac0897e08453f44f8ff03d5931d6cb61afd9107786e5840452253e9f822b4c833a6d2c395c8e8a23af2c4bab81327120ee047052ef6d99602040761eb61417836780392a519af2dc2316e37309021ed210d30e487f01035a2d8f31381e72af9b2121fe97b188da224c6f4e978b6a434b4b5bb6e85edae29c7fd92be930dc6184cadd8a88377c5469c9bbc62edf75ce45e3eadccd169735dd1d337703ec1de1b9d8a83fc84f26f5cee5e972a6611ab2c9dc037b11e3173c3231612c0c1baf7b50b2c140b36e2837453132df9e288362e6e12d1f488e8bd886c2232424acd6d932b99d97ac5f47f05fe8a4c7721df0d70584bb2c3d9a9a162d773371aa2f5687f950161460e24a1c4790d33a194cff42f9703f03ddecffb0406170aeaa6d033023f80363621f78a6ffd9e4331b2396fcfaa46a29a4ecd387d8b75f0dd4191d97b6c19a3f7392bc1834477805e3f177d45ae87d44f0c9d4b23ffdb34597eb740f3e53fed905b9edf7b3b8fcb5cc279c9dd9d7615d63dfa583fd58f6feab281f20b19ab9e9a2761234be8d8a00258565feda456c99835861dc15c53cdb0afdbd4a878d00b6d33b0440c6280db89b091095be70a20ec5df90e90b749f6c87a870b2b7134345ca84e1b230c9beb3218a69d142d4b63471b69452359408dfd58742249f3fb53a846eaf96859da142752b6369bfc54c1fb9ac7b76007b7c269ac43d40e469ee885697032a79c58c3f821569dc4a6a7562cdd4768cb83570742981f098f3c446f13ca6d58c481e6c5f4cbaff39d16070d48796cb06a2b003e183a73752208833f304e29fdcb26105c229c79a468491e671e0eb0fa6dc20b5889a104f2b45b035585298afd91ef26be00cce0f30bf73ac11670ea4a14f81015311b3470e0389743ef2d6b9933e298074e363c7babc64b524a05ec1de3fe0540974ea6307de6e30bce5b95abdefc39da59538a9ef37abc073dc15aa2042311d834d2839da762bd12696ad93a1425b7c62750930293f29db8ba966b6badeed4c3771ef886506f06aa634d9feeb9d55656ebb8cc8e6b1f401b2bb40fc14b35434d4bf21ce4f545a9a9b13a18fb4c9648d56f0cef5e362046ae1aaed5d8473aa68a535b93129feb552079b1ac1d022f76d0f6cb0cf6f10ba499baa445a7346545778748694df6d2f9b6d9b3075106d726016765a9ec00894087da886b518ecc1f402c676c7d82f0c01f0fb4d432bfa53c6c4874d69d0792035f3f20125cd749547df506f1897717f5764cccea572c660f38363aebf2c53078af087aef97cdc7ff9f38ec1a64ab73615ba0e18284977e0f167d5a29e18286b61baa8e93f54a8c6db2f8c780196d3ee312a22b5e827233e44188d24e9bdeb0dfd9b66fa0818bd0540f8e068c6eab618223a1b17afa1ed892887eb21bfe7f83a99f35ba68598c713834c73ac6d77510a760616bbf6e319247461705773a6602f26cfc4806e7ddf266e10394baa6ffbdb2fd409420a2c8943b522ab7374a4b3a215d94e409930ff22eb9447af0c1f0666f48d104d09e890b51461fedbb5361189c5e95725937e5855edc3e9b72535de4e3115defe6518406cbeebc2d0ea82a8d1508a8815ff610929a847791292fc18497ad0e00284c0b69036cc5d2c4db3fdd284cfec88355c6c4447db3b1f829ee6dc848dca2a4ee617e6f0b9e0c776c4eb1c413adb42b6ed23497584f6a401ee7a7220d555906a584f98974fd58cce9662714554d51950e76eaa3841d96a85156bb51401ce1e9b1c08e4db5c0e93857960dce6dbd14b27d9906132c704799d8dbd8fa88d24d05d9a08ebfc216e79c223e21ae4632910a9cf48aba50198596a47ea93c8409621abe7454408e93d81173689b319c0c28691c74d95a631f77b9db9940aa71f70a6fbd0b653ac8fb45182d93b38b7ad04d7a40c2ab23fece47a48c5a49baca15b4d0da9133a77f2429d0002a616be14b361b96986b45b4d6e1815a5fadad941e97db521e67dd3a0e4ca81914d5c3251f8d18edee66afbacf8479360574b72099d9abeae2d6fd8798760b3f92ffafae4fde0b1670281c9124e3fc78ee206e14a57408aa84dcdd1fef2996288a9cad9b9292db8fad61cd4dbe4bb85029518d5ac26b145bf7e65d4d71ce541bd2ca82b0064bbc2d87820c139dfda17a96172becaab33ac4eb87c46d5f141524039b6d541169088b0123a5e61d737fff319b898697a5b75fc09d4de34468baa00571addb7071417802600024ce94875eb2f21eea9291944047097d15a4236ecce8375f8fbe61fc33f011ef52d26f385d071f718fecffada3cc08bfa46c31f28e08bb018bbcb9d47cea455d3bb9508d8049b7554571a948e2ce7786329c27fee50953e68a73a00c38e12dbfef473c86d9c0daa430080d7f5a4c9cea3ca47e250858176ee95b6a6061b447d5508f7da4e6d2d2dbd664b3a189f1a2961157cc89ca9db47c813b887016e15ae521c773724d32416e4cc94b11789b502180819e3387510caa3c20566b544a741310b63f8943b4329fa783ab00da30c61dcdacf8f9bdad7ff73cc1f0dd38df2de4a6320c6c6650932500761471f3baa3c875e135132bc4bccee4bfa4d48612389e97e6b1c1adfb5d81ad464d43f6a81e8c73ae1b1dd5c85c900019f04de15cf4ba625d51d545be6336a11311e43c5b0de7c16fba26202efaa27a19507e02ede6fb9a93332ad3d08f01579aa733f267d8b5a7cf4d85e890e9ab8f96095bb0fde9be1b9944921329449f5d2401fa3267186582e2e80355a0d9f3beec753d179c1614563e9d01ef9c1bb98e094b67d02c2d51e8b51835d4edba7d2374f557f75ac2336c924ea1cd4fd4c7feba1a35c08ef816a6db8500fc675f76a882834e1d89f7df275ae83cdb2dfad689bfbcd21d5ba05d33a38f0a6ec062cc3c4ff9550f05c067cf472ac276960da1bbc210ff20afb51d301a4d99da79ce6c850755852e6fba2d64ee31c746716b584212ce5f4026d479eca94d038d188037d7637da74fd797c0483267c6c6c6e4fb1c25e7f8e654dca3e297ea4ceb0f17167ea9ac35438a89d85bbb21e3548bb5e7a23f935b455f8e63f70201c2ed04531cb42d677bbdc16d2afc321a8a3ec43f6f45b8814b02f6a37f66dc9c7ce2e2483ce531c1d1c3012cfd8d4a7dbc05e7ed308710c4dfd87f4ca2a9d4d952ba1ea49c0a0e42b1ae9e50d8c138d6ec1ff0f8b384644d5a30bb32d9bac33ceeb33f9a8c3f531c93a84230271bf073523abc6a96ac5fc74a5becf07e58387df5aacedf9d15b027df22fb628597a84face6d7508c132a3f8a10e1c4df5ae1d63c2b8cb9b05cf85f67714dae204b2d639bbc54f4e64a834e56a5e3f875316d4eac3411b6631793ce3c93e1562c3908f5904ff66730e76f7e37b73a21b89eb0aad2867d2383d4d2d1cd7fb7b89bfb5285239684f1ac144a726e01862d4bfef601c8687b67b959821b4d5457e7ec3cb98077bc503bc00980852a92a50568f63e81e674870effaa8a7a5055b94b216998790ccd3f6ece225e2db10712279fde9fcafaecb4f062fb67a8864ea0375bf36393902b5750ed5c289077fa15c007f0e3e722422eb3af48c39f02da167a0612265b2bd4b07ab21ba98d8bd569b68ed925b0208d3405ce3d61325e88586aae8a67f793b0ea44fa9b9a3f28e980339cca5602d33428e4345052c39a8794dc70994cb5db9c29a0d18107fd208267201d44da90ee0b6d6c34b97d5e4d9f0e6d3bb681e52737de1ccf0a041994821a1a81b0a803a695ca4d4e843d3842fa063975686a0545e928a9bc5232472af7bfd07b9a4db3da32a570f359ba82c0d44e9e039e6f0eb980ae17a0da1f9d63dc7eaf89acbc8f9941d9411ebf52cfc55de5c7fca5822ccd30f1ca204cdbe6c9b3982fbb58b00221efb73d7629b81f973c60aba1223af7bfb85844dc4ce05fd674b8f0bb0db8cd1f6a8d31a907c287de3ab9e7db8b98348567d413c343989a2355f7b4aac5ddf77eae8da38c535d98c7253e5ca8d82d2886f319cb612d2fe61d51c3825ab7e00a9ed50ab8b19617ad25565a1f905b5143fefc35a7123447ce394ae762e0537e5e995377d007e4d84269f1521029c5598fbab3d5a41c6e7215a8a93c6953ef2329f064f3bb83ecfb02eba00ba66a1ad27d99842183e4fae37123804386d5524a628bb3a3caf1d635621cbe696af788c53c07b9d8bcb10c3e4702612564b79a6ddb2fd0c23a0e6df5362a5355dc2cbc39cc8e1b0285048231f5cc5facbf8b649ccb96478f61816b30f117cad4d732f650c06a5d4572fdf349fa378e156846a0c1f28847274bcd0d92d2e48a263d44ae6cd881ef832d6e707e527c9c130fee631c79b606d433acee3a4b8311dce6faabbf6171fa749e31f1f0dcebb82eadfbccfc9e2a3224fcc4ca52641d78d95ce061c6c3de51c403dbd843bd1271783f62e9d23b5b6c3bff7f81c5be6d4292a695c56ffd7660c6bd409b15621646204fe6a737aaed31c7606bee3a7e1cbe0cce964f1a564182d8abd6de17b139340f5eb92a1712f17000a9a2f04bd4c390cdc6a1ca6241d7d0db270a887d23f2d591b3e798853fc8b77767bda2a515b4985241c0f9278938fe41708571fe1208030e10468ef2b3be37727bfb0277f57893e4d9841881155c1ec019414f2da271565e6376a22f77d693214d5073796c9dc06a7edafff9cb572bc4008a74549826621c1800749a4bde2bdb5f850d8361b796f701d17b825e5f08dbc85bb76617d4e6920676a8cf203978e92ee000666558e8c99a2195be705fd9d249ef5efd10dc2e8015af6def975742305742460112c1ccea7d069c36cefc553556354d6d1ac2cd4e1bc6e7f139247e6ca6df4d4d8d0256860b4f497b260a8511d10fa1d2315ef04d15eac9b926ea6c86fcbed278be17fb263bad0c31c89e6620e25c69e9ac4ad9c0cf912fc3e010b068800fe5d339dc800adfaeddfd48d7f0ccf54d79eb520876be5b650c547465817e24c7cb6d4da81efffbb6b10b521e8e6d238bd109e3882ba8ba00677b87edd169a7c30422f1d6dfcfcba1ddc48f4740348e186240c56002064fa528da813fb2802a8d7cc151c48660967ba229d58576967225b22ef8a4d537d1e82c8f14bf56a639e3c3545a7276eefae1d00c88b18d10154681b24a4428fb21a63ed7f68e51b13ac288c2a08dac0c4d7d27a541f8967693d299b528f2004ba9840f266d7ce5216dd4595ae3a6ef0ebae3fa4fecbc58d2121dfd67ca019eea152455c4f48cbf4921802a9ec3484bd01acd2bba2137e3f1a14046b4e40bc8014ec2c7ffc489a1b3819103dadac37f47dd30afe79c7f3d334a92b24c79867c3b70c64d5d429f2422c1420cff1812745f7ca956d5088cb9d1dc6f5475168f649c61c507ee6d87ec6762d3ab78421982bc5eea171eb876848a9567b0f3a2de1535fba1dd5f0bd1b2c42434c695d8023f25ac227cd124ce6ce460ddf1564914e9f0fc07c072504bb25c6a940cbc021d6f30e9fee2e17865d8e9ce5cb92c62030a407c698798c771376084d0a4fd431e324afca86ff33ffc817fbf677162ef6c102961e9066dbd5eac1dad9ea89a9f9f2848f4f8c3e4b743ee44774b7d98220132aab6cf82792acaf9c1a725661096511ac9e5c54789750b68799af7fccdc154efeef160fc393be73c1c1fba45d3df64a12faba6b56e41622701224d5a5ea6dc2016305479fc481fe10848958ff23370320685fdb859e069dba2bb918ef938afd04088c336d79be24e90ff3960b9ff4ff996a06d96a1636b30d59ab8abd6a1735b4d6fb033d780d79139cf3071a5fabb393cdfdc8a5b835575beafc5eb7b638b0d9112d802201546173ad0579a09f8bb4074ad8a9858715d79c9e19b59e0bb82981ceee6b71225a573e374e9901fce7fe71a311359bb7e381bdd7f7ee5a3635d3fe02f95fefafefd3ed2cef38445c0ca1110d78870ac1d01b26676f61ac6120bf849b50c0e9f4ece36bf73f9fbbdaa63d012c36f4308fb6590f5019bec4132e2c84a6b3f0af68de9c1384be888238341de71234c689ce4a499bb334dbe9ba0148f41622a60d42473f4b5e1e3ea112a3787b8748342c1f3b32cb95e588c1fbf46fa71c6b47f0c411480f3dcf065edc6f5ccd0969b1e1084c6ed196cc19dda4cd123b244a2072a2ef62713b72b3102e47793379cfcefbf85830289794099694a4b7673865f4588032381d2d271559e66112c446dffd9b5054c977530e9164c8bfc68dca1af5e0fc1b2d47019322c3ee1d712aa04047ab9575d0f559624694995b70246454f11bd3b3a0346907ca96a40099ba5a2ebdcef9a9bbc5d821cf5552665e4eb4cb1f7ae9a0d8d8ba5bdb190bfab1ed268761eb9735d823db3ae165cd4c9c460a99a46045aecefa8f4d1e9ee7e3d0611fdd49b0a7a43f60eb416322a1441ff9bf3efeddfac3bb14dfad8fc4e535a015e00b9b40018c87dac3dc931b559e181091382e95898fd32279aeae9e061d6076a006beb75f4df18a63358253b643b1c9277824744b0b67506fdd0a58f87e6af6f801940c8d74eb181e88867555458f78ea7830f938d05befe2416970d38320b853c084cf9b41807c7434eebd159597a83a1ca5f0991e9b36407fb3aa145bbb01e2bafcb68eb1ca0695c81584c37e252304f1accf02d80a3b1da292518043943a76d079266f2e5096f233dc91061e14c381537e59261e0b408d4dd9b313b9ca31022c8682eaf0836b1ed6cf6fee0555320ed506720d154afd68cf98f32d75ec457cf507d6fb4adc074a5d1878c051620cdc37e006a42de70ae51940dce9264d5b1fc00773398f2e34c651a043abfb6a1aa93f8949ae3462c97cbac078c84ab7bf18a6ae0a5ac46defeea8f8b0bcf38bc486020ee00a156d652041a177bbfe98709115b2a806b495ba103bada4bea323b3ce8ca595cf64142bace972743f606430d78180fcff0b94958e147d781e99d3a2e4d5184bf965fbc63ce32430081eeef856e64dc991d28825b4ff27b8689b9ff9df5267fb983c6e95f73270d2ee38a5299d28b255c27accf21136cf7f48048235e17df0fd466ebb9b43185a433860df2c2e035a7298168d0dd25dea04d8397aee921ae8e0f28e4748dc77e2c46c4dbbc8661319db9434329a99e3da720dd9bbd9e6e20cb2314660b3b6f3a71f67f6a907a971facfbb393a302be7bbd304bb3a54f1094b4fff38b2fdb70ef986c1e370611aa22a529a50f70b0216e6309deaa2763c813623da316f149ab6b59f5a0d35b428eb8c11e4692b63f5ed2863c834c004932efeabff3a9744e9942cbff36b6e885379a871a69c3f0db945f89a3cc73e6d85a6a8faf9179018a8dcc0cc3ae4d021124e52084cb9accb806c25570c3a9d209bd2dca3ef59924af72f9d43f2c76023dd4cf990b48d75add103986598e9522cab292193d05af080a7bbd9137e9570aaa94c30b3c2e3033ad31eaf0897c6e4ec4ae5ab01b11143f658fdef46fe4b4b80e34617ee15b784b5a0f33bccbf2f783553c35774020011e0a5ce00d974853d0bd1887242c8366bd912d4f49cb21906cd7ac4a293b338531bdaf990399da64f945267b92a9262d7b73bdcb46529068e3885bbd30c738e88228860caa210f48b1040af822fddf8d3890178e3a5ba903f71caafac5798dde8ea4ec99a1b99ee589a4ef03255b9cc28ca7cd2fa11385eb01f5c40fdaf8f6e90bfcbc7d048f6190640287384af5caf5d3bdb92fa8ef607c4009a350d8920c6145f771d02feb325e3d729a790f761b23ab69b4156157455bdc90aa0770027ae4801ae25ff747accb1fdb718b43b154a65c6a7e2b2ed32e5a0782cce4384bbc41bcc6084fcebf0b1e453100897e80e7be34ebde0dd871b443503cf6f5d766d44d069ca3815da65669cf4e90511037396b3df1b0ea8da173ab64d5db55f53a595716ddb7abf5778ba640d322180d5f30d86aead07a991397e79c1b7a986085855ae8fdaa8e0ba8f13c3807dc0d75cdca1b54dfc846d32feac169402164054d57227b59261f11838abcd44ce87b98d725ef924e2bf00c3bd8adc9689ec2ddfdd83f8d75fbee9ecdf88790ab5a2fdf5dae519ca392898a5a66b2f5c437c96b3a94a7942104283903eac55001fe392aeae03b007f18356a41b5ec13e89642e36d69c0eb3658d47226301221c94bc020a824d1599e85f0589288ceb5b8d8f79f2bb21247595d93fae1e7003459e72c1b5c98a0f97b35b112ca849a5aeae075087451ba42471e014f97d9b80482969bd621451dcd173ff6960b6213827f9c77e9f7a94ec7f3a679ad2321d0e2de5287886a49b47acec4f3d44edb9309ce4fb3b59d3cc3d0f2d6a6b7c5c47bf98f352d800b76da6a11d228275de4ea2070e6e3a03433c3b277db42cde2c88862d7294263f1603f2352689df885ee7fda92cdbb94cbbddfab92cd05d1a91b7b4ad35d0c9824d04550dd9d54b3caad3f1e40d6059e6da245c2c6aa4c2fe32cd8e6fffc3dce0ec5c19ed7c9517f3d5d0b5d59d1fd7d1285e491fe300b46cbfaa40cc37916383280da1b27699dd35b4c8a0666e9a0dc6d32ce0f10e70fb3871e0c0afde4ef6b03b731a27b1c78c0dc0563b3f529647c5d21c08bad0765764f99d60a62d39351cb1d6182b3fcfd0db2b82c0a1d05760010c5b2270b67bd07eb7b70296ad10a7893b14a4fd1c7953423fdaef1d5d9015dd70fd53f8a0d5674ce22952bf072e5c7eaf1ac8df11c0b3158276df6ff71fed18acfce612f825c340d014627af09810b9b16c3636d2e06fa3bd9b919900c87c79db3efa719338672b73f806c2dd5c92beb1e9f4f4fb1e3528d0af50e35a82b0d598e18e839c897bf0c2a74aae6ffa86c5ab6a41dc258faafa4954d4ceab6c41bd8a28574ea710f7e0d63d5415a7bb1f21722f7e4b41bf8d5cdc487bb534e01e60e38fbd14f9be90a275c9a0f6e127cdd287a88510ce55de50d88e4e206eb3d71bab2e25707125691ebae47710b94231ba3bc58c656111e17999418e30e2f3c7755692dbef2a0ba0164e71e5901f57ecb9283d9bfa41b48c041e9c4d8f878bddfd670c291f024a03ae6cc66730a6ebb11d7f61df6104e3158b01c4c6bfa309fe60d703ee3b909127f619d23086bc0ac7f2d421fe89521b74cf1c0ef7c25baa09480a03a4ef3d75abd5d2ac04319a79aa8a2ab762a063b9892219210ccc9c46491e7618d48af217f6c1e024997807137a4e12f0ff14f6aa6bbee51981f7cb30c4cd0f624ac493654286572a343ed94852af9aaafdab9d34e5194befae64525dbbac89d86eb3ea5d878689a2e1823e8ff009f3da99aace5658c7d8b114ace64f3c97faf170befdc5c3aa2d4ec3cc46d4d9f43a3fbcea1e8e5d2268bea5ed0ae36970edd1a9a1723676f22e99ec7ec0e0d1440abdc168bbf60177d10ca582dfdeff82edfc8b0810e1dc25a43ed6a50df8b8e3c5812df9903c7969c75352ff852f8aa2db4e964b40ad9bf4c03111dc6a34dd651e2679be7b0586f352b8a4422bd8656bcf09665502b6814e1ca3ba0eed12125004a9df235891ac2b61b63af37c490c76d663c1534128976315c21939f60a954697766a14dfb74020912772481ca52405516253c1d930b26757171e9ca4e6c7f52cb887f50a468ec4235fb5ba62e96bb6cde080bce7dd500d55b70ae8d425bbfb3702ce70979fe4c43391b8d419ee3fb3a6d185af871363741fe403db0980d0f8e143a5fc3a254d9500bf2a19e201a84e9c569454008d2457ed4e9f4b301be6a84b1afa94bf2385b9b49452b8305c45ec313011e0f871ea5a814ba61f8bcd9bd3b09d7f5e6e2feec15b4c951335dcc14e415a5e7fa5ddd5f15f10348d7bdf5b6c193d5b54fbc48164ca5818e59129a43ba6a04fda3d986a0bd1fd1b5a1bffa005a2656f5a8c31deef1b9d116ae5601f6312d56f5ddba89252c9447826cf3511bf10f9780631e02eebe2be93ccee29eafcfaa77b6a913d312cf6af902980105b9029339c6087a564113ce8d4748413884967214276922cf0320aff191509e0eeb5f7acc56b5a67bc0f7a1a00c991ad41a16c9e909034d17b4b2edf93dd8619a7608d8e73dbd118660d07e37d7ef3a8e3291b9e5a57d9d973b22995d89b5864e82832717de1212859ca9a24ca04e9d174d383d8b2a9e2d395fccd7b1147a5f6d1b1c43619e6b8a3d8c22905c9f5d1e7118f4cf932697e654c8391da2462213cd42c1f8d679a565175393659252a7315429f845c98e64b47af26397921ab98a7b98d23478c632e3f0d2e25021dfe6bd93a21a9c699763e3de66eb581c50a93f82268529a5f7fbc7bac5539506b090fae5d5c38d8998a177ae7b4e80e3d519e4e2dcf75c1bf6814de435a585c7c92a584609836e261f6db236e81943a43393cd1ce67be4b5a6bbd233e5b1e3d145dd2e4927a826522e75ca18c84db827194ad1206f029e4b1f0dc7d0c432959d4a3e891c5114ccc1946e45bdcd95156d49ad777408cc3f1516577f589ab36f94b2ac175a5fb200c0a38c93d5e8e449077372c6ae894465c76d3351e33f0e916fca8e5a58e98e04f1999a609a0c247b5fa3fbd36f738927facc7f77ed43273850711fe34ec398f8aa3a75b006149d28523eee624c818555ad46492cb30758da4a63b034c9045df807b13d49f039471d6e106d4f654cb233b3aeca4fa4f562101b5a646c341a67c75b227fab97c41cc9e677d1363379ab839b08ee693c7b332c145051184ac5223ba761a5140c4c1cbcee12251d12d175f25bbcaefd1f8ed55bf8e4ab1ad91e9ebe35b8f36311e44e30333f2bcc915f79e8f0359d016daa12f3f1e1e5650364c8b56ba12b74c961c1821d0831dac4cecf54127f19c9fba90c853f1eb798d236f535ad93f31e4f9d52dbd7b166956b73928f566f38d95d9758d62328c99354670ca125fb20f91eb50205b91eb09f4f0cd056df299152cf863f0d3f1f07fb2d476fcbd177e6de5277793d178a6eb426a43f811f23fc4628427e467c2d2943b1fdaf22c1e7f3d1b9369829f653daf5f889745beb564a66fb5a8f267253262438a3cff2938a246c60eeffb1b5cbe8c4ade0fb8098bf9cdbf5a7bce19ab8bd2b71e5a10f9366da4692f64f4698f506eae8230c9cde273db6c22a49bf315871462d3e1c343cc266789becb2e49bc1f2eba7dbf0173952476c34fda2949d68caafee2cf0b9137af5c02db4823e77adeba250ab05990ef0da8a22444566277d8ed5828e591c5069ec39e4f14bb67b464d626bcd803e11d6e81cde6620c92f7ce23f21cda265a31e05fabd55f168f8574dddc4786216161bf61d42e549206d51fc7252eb62423834f4a2481aef34bf8e223d4238bde99c227816eedbfb681084f818d9d7f9a22517505bbf03bf9572dbba1a7d255663134759ec8f7846731163475ddee5c548b5d2927a6e8815ef9937d77939f450e5dd61e252735ccbdf4887f778055e80aa169f82acfb2193cfc460b2326f85adb404b0cd6dc04f199d7293d842261acb74ad0916f27437275ebfbee6eb244b166798cdbf28b515af2d5a8c5ec15f79b9d8c1e0d9e3e2c6f26c9cf42c32c306605841ceb29dad406e0e88cba75ef15cc2f9edadce34d742d767593372ed89897f8690f438b2019dd24cd4f6f6fb53f600f43018a9af384112af016efb33af790e68ef902fbd9591aa4e76a1543988005112b5dcbf57289b94fe8cfb0c0cf1b34802c3f9a72b9d3b1a20005597bf4422b8ea612f530dc4a5fb8e612a2eb8b78f79192d1532c5fbd743cc0577040577936dab100edca62da09385a47439bc655e9508f3f2815cc2888192ca5cd79f1cce824bafff16e25e437416a777cb3cc2ec5032ed2d0ce515ba4a11c0e5aa3d2357812f069aab8611c6d285c5c800d32f560726a4369de89ce3238997b4066b297e48979ff5b45ce83c4d460e6c8cafca3f143f84d9df9a8c5e823f36456d3545da1f4b6620f313abf6fd7605ec901d9912bf23aeabe4dda9d306c32957e9314cf03b5828f640f8932830903aec9e42fd62b85630366e9f195b79a5a721a57bd7274e166a9154df17b970535dce8ff66f0d134786af589234d7c25b8e95dca30b1eb958aa46c31dab70261914d379686264274e3091ff770d306a11ee1d348df67dda5c1826a47cdbf05be2c59e06ab4250f614fe86ca468f3a587bc6e71d7a2df727ce742678f34ab30ed634104ebf4c151397b4914a95d1ce90d12b0a3a2e7cc69aecf7ed7df7b4481130eaecfdb011d81f0efb61795914480c4ec3a8af028f4efdcf170f2a54fa7578b6a51f7de4f1462f20be16331e77cadeabe097e04627f1d77b376609b2ba1bfd252d8c53105f3f26db46de05592b6f79519d2bb9946f264eb6cddb8bade05561ba58c2ca643b2646cab96e9097fd756533ff866ff05623c1f01234e30478dfa2fec78ab8ce580f1254f4f1f60ce262508f1809be90a84caae0a54416d526c17280b093ad0ae1012d405890f52a219c8392a0e27b57016d5ea762dc53fcbf23b8c5f518e8a185de7debe0e483610af5127b628c12a542535dbbcaa4469c89a5ae43c76ebeab521fd9f4f65af344ccfea4646f5be0fba59593bb80be4726c6f60b71f6390c232fa7934e288a93a84823866af644088e4a3bc1beb29e533da8a1eda5b37af6f8bf93b9ab71a323dfacc72c4d8e39adb2b7cad6e85869ea01a39a76d56a0c5942c5c78f420de3710f120af677d75960c93f155761e3e007dcceac49b6f26814bf7519c53d23042c708a4e0bbd38d53ea3ba348ba3c143be1b018591e6a488d28f1a6e443f3f1bca8f311dbf3bb16407cbb519b0bf4e4b3ff7bf9aa8f3b6ae10e8eadcf990bdcf514bd878478149a73f7db7dbe2b5a64c968f11536f0d0eb3b69565b75f7a0655eb37bb2686755cbc98a01d85f4bede00abe49c40cafb85393c51a5f5fd497c3035e7ee1451e45ccc0a3da759a5bccd59e86985c6066e26b80eeb3dd860e7c4c0413b241a1b0ad2b1cb2dc99c24bf2ccc3003f9e7172c970654e53ee8ed2e80b1ce08c6a3ea30cb4257355419596123bc912f80b3ba1e9c0547aa06c33f16f619b2b8fd8b2411b3e85fc2310a58a4b1dcd726583eeae9a892d44e74d8ab617a5384c53c9091a4bd07dd8eec38927752c083e1eb88b772ab907b38634542415ed423fbdeda3e0f326dd2e00da98d4afa7ee7460f6466190537d328a1f6caf15c5c9de5a3c0b6c944318490c2359686a3d3cacd8d0a1a3b3544f082c1ed28f67bfb6b96cf27172de7e02b0a5ce1710861733e941afd871f135dedacc7cded0a49c0030b45c2e298bf8e0b78371d57c14d570b5bac5479ac5b882fe28d0d6511cb9f611b810e4f030f49826697a49dbb818665d3babb973a0bd1f06d9154d340b5315fffad07bb3a2dfb50a56d92b1802cd4fec5afbd7541997096c723491aa6b9ed221ba399dbecc92e401a0b7f1817a9e95774e5ad6663187f9d6ddca959487d827c937f56507686810e580e97cb88b00aa3a3db909e2948ab24adbb8054a3835035431528c2fdf3db04ed9d72d64e21dbdfed6e4cde45af93054fd6aabd2d6b5a0902a3de31b07aad483c8c81ab183285cd7f8c0e6474a94d23f17f25ae9e4aca6400d7271b6d3d67781048fbfb75988f036786c7fd2ed98ad0e6d1ffe6c09db22f61921967a206fee536a7efa8a47afb569f4d1f600b5b8b808a61f7dedb514c058f9934befe17092feea8b4802f8a30c284434e4563205084082cbb8a571b8722e484b085206f75c7806ff1fe52401fdca8453bf6c49a19239883fa04eb1cfb476da3a06dcc3b8534d76913f5969f07f01d74070b6273978ecc90f40b29ca6dc3b5a9928b897935a37a3f2fbdead69e04d1c628cff60b7fdab256b8d90b53e792d4a9ae7a95678c31c5cf49c371e43b8a712aec0932d8bd2f04c1b5e5cfb7c70420c45f2ceb5f5aa48268283adc80b9305c2a16b4cb46f7395b4893fbf67e0461f56fe9942d518a60c05cb085a65a6a3eb0bd5fa210ce9a597714d18fab9c88aa93258ffc71eae2a44e1141fd661469f3131137e1aa316605117e1b481539ae1dcd02aa3bae7c61bbeb42dabf5861faa45f9c8d3870ed22402b205498198df2534f3523b21674313a9ba0627f315e3058d049878ea5cb0e9c770fb05cb0371e99cfa89ebaba5cedfa699c762a9d149a253cc486e24326fde2f3a1cc97cfa6e3810a19a7765a7d0a9cd968b9b1732113771d7b9dfb8a0da29b669c5f2100622a977f81482355e07b62065e6fb1879b2bcce4a280496261ba7a647190e2f3d6699a1f8147eb18e903dafdcc602b0ad03fb6d00c26e1eadc52925c4912820d39cedd4e95a8fc981922888633b3143b05addff3b6e8880d9f84a516a0992fee218a1a64369f1e7c8a926af0e2ccb3561f531baeb62d3ac6f140d2b4647ca1a567bacb75e0f5cb711e3eb46200c1bdb745fd6e3a7f2a6b6c0feb095698f390566033b68a50983cf14f789d43ec53489db716025cac7f54e825c7a27749b80e55c59a82ccbac4944b48fc4333719cbebe5cfeb622b5dcc29f5bd3dbf02239f8e7765891447c7b3cc756f8bc3effd8e01a3c681302d4d1ecbfce36f3356dd02792f29022369bdeba99db6c9524e4eba4ca422546bfaa893bdafab400f2944f11c800d5937506b569162c3002ac3e56f5486b6342865ec6475ec3e1c4df848c946d8c8c01a0844dd87830cff66680b1204244acc11ec6d0f0962f4ce247b6642c1ff0fee55dfa43a5f5988e7a0cd1d171e8f2e45cc1f316de24818e992fdd9d62865640856e3d1208a374b36fe309f4728eb601abe018394cde3a85541fd4a0adbe54e9dd07bb49768b232157a74d02de014d4b2d2997d4473713fcb7f5e85f3a649133c0641b78b370c14b6412677804550a936d5a99067951eca6995847095c63ee2eaa32e105a587a9b5c6257f7a911eeb4c3e15393c1278d5a8e4887c56f108e2e14396aa8c4b0c55e3acfe718f8375eaf17b8980e4550b294ae17d031da1da4ad01f0b97980bfef517d0b60b977a0711b1037737265224dd5bd7ba2d16564de195712f1aeb89e63c1f5762d8b8e37b91a6f1eee4d2272c312dc5b08d9e3f731ec2349cabbad50b66e843dc85d6e99fd09a4a420e623531d804c3151a5059f6d5c1825e53df15832ebddb88caa1c8880d7965c75d7770c9622dee7984e22430014c223ae99df63c09be62e3457e2d730e48aae9bb18be87ec0c7f9f9e5fd356719358375a88ca3e8df7389830a623d0e89215ace362ecc299cc3bd0dfd4ca4a59ab4495b5ee952351550e80526149fe551e3a7f0f53520b3895197fef9525fe532d55e5b8822ce76392f451f15b0661ab7c4deda170d4a86be2cf84db758ec0e3f07d807faa7153cadae6ecd4747b1d7434f1dbb8214b6c8c37a18967f1768bd75ce61a00f73a6a47f993e54896c79862b6c5866f20787841affafc192d0d061ad8b2ddc463d79eb02aceb912f30bf0ddff609fba138fedee0c7a0ba507db2b3a5a670502c61d5e23e375a6ad1b6aeef8e910dce5941994dfa8ecda7e0b36f4ecdf6f7861f2e69c25110a6c5a50ae7af71ee5fb3a1715d1497259d2055b45289b786a6c15103151625e0fe1360ae766534e030797d4be2cfccdb1b06e12a3dfd5b89cd7db445df8dd1f5c6803c92e016208a8cd8dc55dec49af8578090a78d60dc5cfe0160d7322b4e163373d0b2bc0f28a935406cb5624135800f3bde9ede5481a374d78e363f97fc5ab34fe555d3ad54c27b0fd9866fa9604de176b14f1a4e736e5c599af5bef1e8d8cd168dbe06b0a3ab5132be573940c40bea75abc0dcb7ff8fac062039c8f471bc5d6838d45df5b9339923abf87e371c296885ac4de036f349e1e4e1f6b2fa6d0ba669555aa705afe07baa6bc9754f4bee06f1d13b3ab8b195512d3464296950a7e7412ba4b369cb844a809cec559eb12bb22e997db487ae6902a37fc9fe953493f6d6887c36aacba682fe5626f2d5dc375afd50d865a275474a35282e938446a1446219c594146906e83f836baf73abfe1904c9a7aca340056170f3fd51970de27744dec41df4fb26113b7dc6d1cfa96f546298c0a2de377226af05d4f9fd2abb17f176c2a233c455269ec2d668b4a35cff401ec98cc8469bd13c17b8a41e63b90a78beb13ba0ef608fb3abb8b8892ba4168ff83fb3ae97433cb637a9b110a24877828d9374a44c1f4c96471dfac5883ba69daf269d032239f4e479a48484c9c0aa8ad75532fd1d62095116f6bb4418267ac7bb8af24fe4068d6312a7db335d306d1cd15d515b7a9abed8080fbdc3624be4f65dd233f16b0701f5efd8b4a7ca01692bd07de08562fc77d117a2db5b53394e6fdcade489afc3e5bb5fc96d21dcde85ddbe4a034184e18c6b766327ed310bb4ea0f18423388faa70758c521b77eb24e94c3391445c41152616048e80794f28e4f75354ceddc95343a6642f191dd51ca645818ed8bdbcc0d8987539230b75ae140cdadee7a0f8df3233ff752871098707cf3de873bb1a47d38cf9d75bc8ae2f08ba8cea5334876c8603dffa89faecdec6efe5ad69ee9a62a8c391a28a329111b39133be6990fb8b84b1d51a9db6004be0ef84936ed26a1e11332a7d59482df118ae633854fdbea3fdb0eafdee0bd5489ac8533836e3b11a1a3c2748946198883b8d7665a3e1ef27f409cf983a9e52b9e6a7f4850e41b4c88df97c71fd2da2887c64b6035c852092eb60b500e9a23368033842b41bc2b51bed39a75dd0b39cc91d90237406b539a9e357f1e79bcfe3ad21c5002584d569dd988d2774a73d405cdc71e5769a9578fee0e1e0ea79c5f1060a5d41845e217827971c6a3a3c5cabb4b6404fb059cd6ef391ffbdb2cf1b06a3ceae17ae2f8baa1db21f5eec737df7d78190534c166c5512d55eaffc99a198f8644004ddaaa82c3cb333eee9f7ebc5c3a2656ebcf4cbf6846b0538d508b1f426a51d1ae8b3a592a73ab4f27326648d58ca9aa40eeb1274f6612eb1a6e02f3475340cc05e821319b077e885c53589a89f89dee20157fcc4e7b4b56601bed470d7a3ae1582684e8f8a69b0364fafc7c061c7f8e99e89751d7cebde905cba92a0639804d281e44629fd9c69af6a1c8a2befd8673782de5eeac1b592b23cb578aee27545dc6f6579a5dceae975fd805d38add068c9651a46178e25ed93ad8343dea1391d4b8706fdc652096bf30062dd871fd074aa05c9eb26edf7a6aa33a0fdeeb5b85138f3dbb38d43a6e09caf9d5d286808ae1a7997b0bd1872421c72b3660de61e131241e2ba2f79cab7c55d82370cc42ecca128b0b7c542d080d7a8f9cb8851bd66a07349d7cd788bbff10432eb722e81bfc1079341a8af7fd399e7c7bcfdf171670522ddeebb596195cb5cf70c323dc7f8c72f0f1243b2ed16c1700fc4fc77d6e876f9491a8be37fbebbb29da5f1fcfd150ad7e36f1c7f2a28aed297e9a1d9180232e69cad0f13704b5fa8d57fa3361b1a95aebe55ca55d6211f4c935dc10374b1e5c18cb68f40983ff0f1b8d00e660d6289ea1f2dc6302b85bf955f7f0e68f549fdeb22fa94be74a37a02b847b73accf8604c582df5fb8fc73a70533a85c68bfac7ccd4bc925f898eeb9fa42f28a82fb05cc3816f661b65ad2f4a663cedc79ab39ccf53ff90275368f5f0d0422cd54f2b44dde586e46ab2b1ae25f664db0a661598a91d642cad26d2d9320d7e1609a9c46f95d48b9d2ea538854eeccc509b67760a4d0688cbab4c509f0878d7f08cf3954d63413aff185a64f67a3c7add409620a14fabaf4d9cb285c03db7542b3b2e4efdf03d0aefecd1b4b2bb06c3dd8e0ac80ee7a51c8636bd5ff76917e0c7a97cb0ac729199dda92fc8e294ddcdb11a58d28ff70a3bdb484931d0fe08432a7ab8001e66b3f3b34ad73ed7ad95689503dfc33d59f6a6b5d26d9a27562200bd4948921944f66a9385e63b1fa156fb8c88ad50948f78480843236c759b7722a5a75a82ffe6078d38950ef15a06286fe7489f98895b7606ee324834df945000ba8bdb6778cbe85ecc19b11f6a9162ee06e20825974005dbaf4ad5ee07044fe01e8259c98f94715df3d710be2b6ab931716c0d6ca59750b0f211778235056c54b63b4563eba9704430a2a7a10b4fa9a5f740e4933eafe874a31f9e8d3af3af18154b1d9c61405e2a33be673070ed8f0e0372dfee9887c62a8c2816a6cfc5b2a611539ba41db93f5b899fcfa90cfb7c879308b50a512238b84bda76b792c35a1548dd79022b24dbb4ae4749d4c07de9165eb96e9ef8306869bcbf16212e2c87d625234deecbe2421bda72a05d5c7eab89e54b54b1ba075fe594c41acba2bf48ab546b30f30a4ddb54162b3a1f81fbfb6c4cdcc6a911229f4933e622c5baed8af491b16c5c2171dc274c07e71d9b72257b6b709b98022a29fb64fc13c213343ddf8f704d29114c951de501be09018d76103b6031590df2e1113007c5ecea7087cb31cef6195e65032348bb6f64e8930b09551d839be0208abf2a350a48f4fcf7ae08817a2161b63f96ce47d148c6977a47f15193194a59edfffcdb125b5bd192871cdc0ec937db2f3d4dd121ceb203e5d6d260c0569f48d37c7ee5dad058f9bea813f44ee938ffe14fba41a18645bcff33d34f138ee065ac0bdc0d1adfaf4a54a0234305ef75028c4e5ce8c18faae78b110d210461ceafc91515ad8a0e47bf89c145283a58be9e668422a08ffee6305ba524367583c1e87ac8d8a94af519ad62b94df111ee47c5bcf130e1f22fef06f4c3a36646540571be8473e7ca1a27efd251a36115338e445a117ab2394facf8ccd71bb3c4d137fcca84aa4f40ff1cdc5450346d348b67697e7be6bdf34b8189730dd5618ce3edc23e6517d54ad6deeaf68e23b1e5aab79f5838ad934b3ea113d732ae4f75b74d55980a30e17bb6ad56e80158f6503b73ecfe55d3625efd5b8a25b5cf9b8856f9c8224f673e7fe925606fa2d984246ea71b7630de68bf322a6992012ef057d2b2db4bf06976913f89a8355b72c9204a656f73fad7c1e64780afc3ab06e574f8d4a4b6605acd333b5477b60c4847ed44ed863a3e2aeb6b1025034fd5a50cd92f49c38136e73511d815b8e717696c4e87eb3d25ea77fbfa34801752c22e90fc322e1e560cc505e3042b9b4cffb412fb5ca1c0d0e16bb8459efcfbd3d55c65f6801815452a043ea895a0330825e32ac7d74115223571b2e24f2a0e83e2c93bc941717179b7e041a6db8963659a67c65467066ce4f01d0192b40612d77babbcee142c331063bc87c7c240e97944272e4a22c023c01917f08de50f43c0c30b48ae1e04e18a87b174c8f79df479a368b8c6295b7157c7e053884ec5b0fcf5098d0fadcf46657fb36823494d21eb83aafa05d5bf4582944958e40cac6ca20d5f519601ae14fd372dae949823a915d37bb2c00c1509d8c8dadb3c48fcd6df73d8b9778e79d3011d0448f8876970eab0fc90f516b9b41b2205270eb4d5484d11bd7c9053e0aa2c31747efaed424c2855bab716683a71b6c5e39db610ed98c77a552406c8bf0240f2f3039724765e75bc5ec6bc407da02c53144a50f2db4b6844bca39a4ae933e9c321f3ff94b6359ca9544d79c80c1edf6de56f284af587c98169a9c91a9fc816371285a74be9d450f3efd6c1d0c6ec073c61099afe798a545bfea0f098bbb5f117d4045bbe3f852c6f5aaf428a96fcdc2b830723b9b7831a542c87a1932789a4ec02d9c3f31b461b57b8f491d3a2610bd62a4c9aeeb9164259cf70f2d207c7b1dc65856295a2496a424922ede1219274d65e9fd551d245947bfa07855b7278bcc54d4acda04f33293301f47801c06706b58695dbe96d65bf345c1bccadae5a48ea4edd1e24dd09ecc910dc9b6a68f361142be21adb2faf26977ca1fcef6ad824565562c553a7083747c139dcfce88d793be9bfdef2104b6b3eaf664ef09c4824d529313c26b8a729cd040ee94c1695cbf1d9686ef1db7d9be56661622b2050851fc7a2636afcb98134208b48e25d5483b5f3deb455ab88dcf1d5600f72ebf787bd7c013cc2b9924dcf53f520dd90cbb67f9b8e36752d79fd12fa02c876c19f6d7dced6edf99aa305f242beb8c8a7eb415a1cad321935ea6ffd73f94dab1a3a7bccf0130f7a6476a39f248190a2685efabbcf03a6a7a20810364282a8e0f5f5eefb36ea4aacd30eb3230bd46f12d616b9bfe053becfb526a6b80b982e7c6b2effae3fbb3c536810de1f493636a640e3983c19325b65d213107bb462aaf6545aca6505ce7e8877e8fa03bb6ce49d635cd1383326c8686aa08a7f6c1628c80c62cb98e074b9545e51fc24871ead77fdeb3938daf555a35cfce6338fc8cf24106006b9d6b69ac058dd0e995a71b702690090e1193de3af876af085cd9a77c0d6c4f5f93720c10a57adc62df56704d155d9ee647b58345d3353350075603ad8c5441a649b0b9bb4810637e0821cdaba5195e6ba295f70a399896fdd6d9a96a4462255e6a7e124a20c0aa7371f64f3f0044389c5ab72dea8a3f9794d678de791a1d915ea6f31e3ef3b03ac2e59f62bf03dc0e66da43e2c824db543dccea6357f9f2e1bec75be5189cdfb64c97115d80775313022caed2366001fba13ac6c20a9eb2569eec44e233c22e3816d85d3936ee3a2b17b6811f532d0d6a2d28d818ce0dcd20d6bd64818650327c44fd36980f5b676cd04095d42ac6248a429e3fd3ed7d1d25becdbe9072eda8d9beb27ef7fab20712bdf0339e3064017ab7b9ffb293f59cc20e9e0c8678963a3abb4a58bb8524023d1eacee27d88993403df223700edf6b550ebea2bbd7f3308b2d772d8024ac659b6de7d229714ef5d01608f08e2c30614f62779625ba8f7551e27c339f1b46561b25e9f8885dd03b3696c3638a9d84d45255469d5984092d77c96bec286820570b0308f823cdc6679dd5e82047f14ec54c3079bf16fd3deacc74b640dc6f412f56f6cf7cad552773948b2ec7a68eb0177c73bfe70c7776194574175f0001d6ba37b707edf2f0a8ab01de283107226f05e5a7e693b4ee1e3578be6676cd8447dbb247c0ba0130420de95fd79e3f4e326a3467341d0f3556ea71eb62e6932c79c7a3b036cf2e0703518ddb5b6757ee20eee0096f8be79d1f3e442d66a5cad74ae377116e2f311ea8f261b93fb946b5f92e4b957a7d02623bf7f496a3ed1e3e0a30c607df5a50ada5e6779b6611fe1f0d6d1a1f6f9e714a02f2c40570491b7842fadcc6afca18b9e70f606faf68684da83a8deaf72d9584c4fc07a98dedb4668b1a7d0c6e1e6126a0654e9f0e71706780b5832c0bea77ce95dcf9c4de496060a56a5ab7305dccab66cd664a2b392639a93ea16651e9e1c7315af025293f6d91b0b18efe354d911a32f1e83122fbd9338fa47aa176543f93c4cbae20d64764fe17f59b4373242a894a2c57b40288b5627ed402fd646516c08e365274616136bc1b16fef5ce59b001122f21bba555af5853cebb2020b3edfd2a4dd90dfb0d185b63ad5b9620a447219d79269485ad9534651fb4c5787fc3297359375e4602fa661ddd68ea5eb9794adba144abaadf2639b14c9f9ca88058474f4dafa011525dc9fac3555b8e614821fe7c73ec6f355a33adee8d1022795b9fce4fcda7c2e974bb7af096c36e93bb2119bac70b957d4e96a789e600cbfa8baad53a18e64004b52dbb91aa967d37b0d575c4f928f68b755ffd79b57bbece1dc2cb792a9c7482b1bbbc05b1c0a545a933cdfd68283341b09ea9fff4c41758e9405a0ddc93717389d9955c1ed0ea5683de1864df79ea6fddcc1be6f6a385d2f631b63e4d48f84c619cc5aa7267bd05660af6cf645ddac98f032ef1950c272b044c2a148e0e8ea2327453d99d19b67bf7fe3002fc4d25c0e6b125b53d7f28f596d6e8c8efb98d0647ed9b1babbe693a169e097a392f2d8550ae888681a42282209bed731510e9de3bd6812e0f0880d552e134c3195524b6814bf503548ff8ba38696bd27e26b9b6dd97cd73b1fbcd784ab1f23a02e500664f902920106b9028d39a7e99a24fda54d5d14f56a73c809c7f225fb627ddbb7017a1bb73838d739c900c098047854e74fd2148b36b81e3e773940c74f6bf11aece7e9dccc2d8feca681aaca6f9de9de3ddd4b0f230c9662b1daac7f2d1ed14b79ab76bf9f06ffb0e91ae198353c07b2f8cf37cc7290f5e8e230c84e25f1e2e18982d48f2368cd56471f481d96106875f508240a679a92551866199773f0685f023f148de01116124ab02493452a68ab387a34d362700b766f139f8c9c6c3e3198cda32a3e32b9c4cc21fa08e0cfc5527ced03127230612fc58a7dd754a52c5846bd5a93d3183ee62d6d6430f05ae4cd25667418f8679ab5d8897cfe4f5665ef9bc1926eddb19e4a3c1744959454655be3bdd2c1b6d339bb7a6f145ad686b9b0c0afb09d0ec74093ffbecccaa93dc6ad08a672de75d48b9ed8850e0e11df94f2a6642a0d699796ec6314b9f5a28e85ee02ce7d6d11c0d8482bf1fd12528168a1e6f194e2da774d2bf70b12846b0644d9f5464d854a9307a561c2b9f1d2b1966968971ed98a6b6f900a5e62d52a314c02577e9fe4689f9ebb3ce63869721baae749c57d2d661b93aea1eb32b8fed76fcb3e731882aa82b1b5b3d8fb488ff2a30b42517b8c2524742d51537506d02483e938805468583fae3a4930408dc39ba4799cfc219925f76fb6871506f2c153c82561861a3f6a0488cb6747d26cc32e621828fa934ccd4b3b28270214c2a1abd522b102d0b5eebe3f7a6a1149054ab7ba96c71a8b918d6e7278938e27f768ee70bd6568cdeb56e5679666a394c933f9ed4c3ae0f3b312f52d139d63991ab60f269ac53670a2cf28ce32680ecf5cbbcbdbaf057b0c774d35916e936d615b9b036d08eece946ac701df564ae7df6dd3d3f5480b3f3332d1b47510b94f1e1f7d25956c8ce9466c78f0f91eb50206b91eb02b3861c7c564bedc4ba866ea5112322a3afaea9b846f76d8bd9c8014f50eb52e3176217e70bee97ee1d38f8a43de2237c296bbb0678c7282de61b4bfb80f6f0460208fdc6f222520f4ae7540507dfc4b77be45bd9b11b06ac8c086cc250df4f0b12bdeb4423a841f676923e54e183fb42f26dc9837faf303db6efae11df7881a2d7b2aacccabaea1cfacf23b1b76a1f14d11e598c1b43be835adbb58e9914fc7eb4a35c4158624098d9a69a77ff52f7a615e8de964eba5e52c5552ba6ebde404e8f2afb37da0574de8a22b92b9e6911a387114734288a5152092636aa2ab8a6819aa5ab117d13991736ce871564b902d33724d87c7af8eda1b4abd742fdb82e1f6a8c02d7c84280139f600c140233d99f32aec1a1b18b26a2a5882b750eec44a2cf98a53f41446a89fed452b347022b8e92c5a3c1b14556ea40ab92e8d9988c4b456bccafde2be3520a9cc670b2b0c2b9ccd1483ef191972f3d3fec1842fec5544021b216f7794a32db1ba034f82799af15398bf4a3d664714b3514e8d3fee042e9db51f6f53ef3fecbd58e10c98b3bec058273868430ac7aed70ca69df1d3fb08e4f979d789bad81c426d9ed5288779b20e4c03298c8154fe53a7d8148a2098402bad280c220144d795aead44b660a51ff07a28230e782b9f30020998c27ef34a7946d4d980ad37786ddc17470cbd2829ec30263970a857ae46d0689a1656d0c99303af6c3c0448c71e71490b5d52a5c5987539c28f4aa37692ebdfd13a614daddf6639b99df356aa1392eb7276e858e39e281a0bd7ae126a2472545a9b283bf44434c2cbc085f0951795e888f816e4a58b7d8eefcdd422faab5e51cbadcf2202809e06566a4dae51ee3b20ac887c55f7c86cbd8fe39149746d194a6bbe8783cc5391f871522f40762dd283cd0ac912d1fdae67c6d026413deeaf9766cdb2b893ef59ae32c5ec382d5a6e08e59d5746ac468fb53d4f0f87de2e937770b5602bc6167a9d82d0826d8352413bfd997eb17c9e9c9ad99c0130e93f2f1c778736de02bf12311de65a143a69037b6e90a37bffee402c856fc3165ca97be697372e9ed6f044c11b529cbf261e62f966bf440450cca00189c57556e00aaed44cd44bf2b25ecafb42aef60d961fbc513c03a1bd0426c52f22c8493427618b55a21c8bb1fd7a30811cfd759057c38c9e3ee251e3857fd0fe6b5ef83221697fd07f95b424863aa77d6fcb929d8eae2b0d180529c58947a37c408ca0f2e5eb4fe738e3b5a7dbde8e7d5f939eea48016a4de9a85628bbac1aee0670ca75420c9fdfbf7af5eeeb2ef7e2be0821c447a8b95ac7b675086215939c814b8912834124e2801bbefb3753b5f07ca9220920208e9f69789ca7a2008a0296716c40cc36b6d81157b0dd86b15b2dc4e6574a7e268e677944677e37fdd83e79623df7784fe0cd97fa195bc8435430230a22e68a80a28cd73d5edcd71ad26710ae77b37d1cfb952a64acbb9e32068358b55b54e65d3d871b0a0e8a5b1b0a717f024108510925a35e823433b5b20ab7beba313f638ce75e7b49cd4b0bd56093a85daca6f93c4a01b46160a2de09e780f6214767d0b8f32a46057e716bcb371a2cbb4baa8740fb8bfa45d24a4a4015354b944720d90ab49369c5daafa275c05a342a3521818cc8d2ded54efb51e316ecd34c22c27274d151495c881ad2ed819ade7e706d778c5e2f711da2eddda887d07ce7b08b245a09fd72fdf4c016a38e38857ee22ee6fadef05bc573510d8b61f9ef6a6de9fceda0921a67bc4057c3788ba3975d41db0977d1abd8e0a23c1e7a389e988f2d90f8de1281e2cf9d934915efc35dfa45f72df096554e4522e166e93ddd51675a7a67c99067e93758e1a9c58b1888430dcfe12e3ea6f03829d52246fac00addb7485052023ff7ebe65ae38448db1f481745352c473b4acb62642c14fe7cec083a7ea6246e778a6bb7e39525ba9549d252952ea6d260accc112e9ac4c8de602575ce174fbea5f5a844e30c6be8247f72ea424e43a74c4b282d00ae4c7db5fa41d2d7ef273fd9ba7b319c06e3d07f0add228645405bd19619ef0e7d43073b86734efc2e80a427cf8bbeded2c1ce5a67b7c78dc64579a4b4f723fd05248e7a4fafbd7685da8639599a0e4ea98ef095f0e399a5887acda4469688b2be1886f8ab8314f3e9b66233a4307600c7b6d537b7dca9e69d1ded6c4aac3a478ef9d25a4e36035cfadd53402cbf4cc888a6966114c792cd4e6b7eb9d047a0dfb4a78d1e03797fbeda4c5e62fc438b159adba40479af7b0a04f6f722c5465ef682d98c3612a8ada847859b29f4246797baf4d9d04157ddfa1e2933d72eccac7a2001665b3be5e02b81850137f5320ef0e56ce6ec818f5a384bd35347963ee0f8047b3f0110375ea32bb7b939a5a307bbc8280bb6a6f06c448ee2b767cb343f0e32ea8cf7c886a055cbf46c920bf3c280cd1c3f7211960235df93a8c7283e9a93680781f650442e0e9ea6cd69537efad082a200553f5fc4ddeb785a2d20b9f2ec85c912430b026ebc41cb3985c4c4b74ad53c9c131076c27485753d71f26c3e8cbbe9e5c52ce0005b1fca10e939acf47b6ce5b2e0838faa9a310d2bc54ff01844064df4fa7b70fb57f8c49d9bfb4024d10d8cad8b45b0f3060676518aaaec7e5d34f2b4b2005155e65b6ceb76b15a97ece207ac8bd51b772651b466446a7724c7573b644116a53c4b64df3d42803ca918028e9eb55162d9424a83981fbd7523126097f56a1e48db9555e2a2df60d911e401d53cefdcb07a2e41515f68f331fe61b357a753a5fe112d27b6e3df185e36d6a0cce7e77b40900f014efa57f07be27ce0b16a168e93236ce7f6123199b91fc370ab0736791c2e72d6898cf43b7662c0ea85f72c9284cd66b788b0a76deb198127833bccfad764532e004bb1a2aa180af43cd323fa5c1b167614a5550748b5b7d67e24cb1e5e79bd41c0af8c307497382a305366147eb562b2aa918c9f5112ee58acacc218188068a91f4dba6d2ecd08eb0550c5c7655c4e97e85d0411e9292820dd7a4c993a9092b7d1e5541fab2d7c3f98ba2b30cc6e3e6a45eb5f512addaaa7776fd3f41c90bdc2b8073710575e425defd02096d09103ea1a528e0f8f8ebc0633aeaf91c70ad0dd76913960f800e4fc02489abc0a067ce1cbc5bc51d538410dda7c2f3ab16d3e99b455f29189a810a7af21a454504ff0a6a8ba340967e956be4ff27fbb995144c2d3d280800b8e0f05f87b309b9306ad4ae7470a40501357ec8ec154b73bf3750d3b67fd12b5f0e1ae4193eaecf24c87850dd5ec66ad08dff177288b19cb92bcac24aaa77a3df71f7dabdd85c2644bc907a1de7cf5670c8f30416603919b679712f0bf747bd3d2dcbffd7ccf2be0baf9049fdb04d6b84c4edc653ec43ec98dbb095aebb980ce12161ba0d66ec263aa74360a38e6eb0f05f27ff91483eab7c06603c8572b363d2b4163e7db62cfc6ce405bfff147b25ca6fd6a29d5d0ea8f2ddc19b2ca72a6b8977c0eb779c25175ed32dc7b4ac0565e1208c8aba90c8efd72c7400912ea80d56e2875f24ad9a23bb64828c0bc937c25309bf99d5c683829ea28ac0fd86e4c7e9b23e2edc8a5e8d6dd100bfaf7cd9e8e756ad0aa1f4936401c034b4e3e50ca481c195290d64cfb624ca6923a0168c296d31e7e523ab0f4a76301b013f9cd5be24bb5a478f5efcf333c1e0c0d85812a58b51bb8403a86f1896b86800381a0229cf500b06104409b9691c7d9a3230111012153e7156b66a4bf2f45391fa01d14f5e8ea823fb6c9936dcfe79a20c6402f5167c75594b7776c697b15775feb65def12029b017a8f02031c2749b5144ecaff0f29ae01cb1f8c2f37e0309bfb5944e8726d886244ed99adbe73c58271aaa8fe074e325b82dbacd0743754e292ddd97919738da85397c9578d1f3c1a1f51290b075bc7743eec3cb7475c8bd26c6ed8b79cf4757b503e4f66b6d7f929f1c50fb7e9905da2d115ca8a740c588022ded6e178fc5f5df97a7495b62aedefc1769c5be7459dddaca36542ef2c3127f9fd3dd30769b08984cc76e3f59633b1d58dac9e014b1dc7bdcc58480f097c9af86515a8e1161af5417bf1ee5af479629ef08031fa3bb56ae29e9c13c6b5653c80bc69923947ac1afce7e7e68ad7acb3df9841079079731c8995324058efa4da73a2d8d4bc8c9ab84f4e009997a627e94faeb24d33c1a86fb8e36091630db50cf7e47a81d3c930b6fef15f26968b0446b0f6f021e032ec166825e19209f65cb07fe2f5e02797200689c2e793fc9b47787c77fde0be71bc0528a96e7f6e9635d4574559178a324cda5440d2b955f648505a4ebb708a924737e1b210cc2c53d516e27bbd693264bb40d8544ec1e6cd8dfa4d0f8c70061788fc6fba89c1445557fc49724dcb989bb01a2c9ccc1b6d8d0441d4f2e984cc56d83d4e3cc6ea7bcc476239932ee670c610eb6de9d71e93432409c4c215559ea6b35568b0d0e215836bd5a9e5a23805e3bed251bb06c7dc109179c32c4dfbc2b9433109835c936c57db4bf536283f4df67e841be233515320ffdf065c34f47efd0df4b2171a047ed43dbe0405ca5de1b8062039aec38111328721fcaf28823ea51a151e9bc1de91402dcba57acedd71c0b11107de6631a72f171be3f285ca880c50b838c34503fb96bd5790fb9aa27c606468ea2845a7ef294f2180ccce94c7d2c08f7db0ee3a678f2d981fb0b3f038f23038403286fb20eaa2c3fff29ceeba98d5eece00d423c79c6af633a07ad60e1de74e3606ddcd3095ea83a46577a777886fd0217ca281768b01886f691f42019cf1c592b9be0b65c46c005d0bc3f12bd9b0d886d9ec3ca8d0042890ed88ac6acba4d492f19576a2e10b1546402a1fdf97dbe93dc889127045eaddd8a6e7cf3853ab133a7155725e928c6a641bcb7ff8b0aa2edc11e00ab115faf1f0c2fdc16a83a2d1138e4829cfa6153f9dc74bb5551734bb25ab901cc2174d1425d8f50080a8c8dec21f5f29997b65fcc2e4109ae2caaaee40d22dd02fbe82243266e192c10f8a8a9ecf14eff052c81b77b1f061d0277a1884059391b7559a2be0afc6fb285e40d47aa1e90b613198a8f0758cee6a13e9c7882204557a6799cb79a572c422741b15b7c07486be69a54924df763c7faeeae1fd36f2dd336943c719fce9dea54aa6ad25d55d4abdf53f5e10454f36bf715141990d1a3d670f0eb1086b8c0d3903af1721bc3947c2b2530cca16e4f63a88f0158a2818531bfd28fe1377dae1b98b82ca27d4b7fd546d83b6d26db63b3949d7d2e81af24a798a15342e9e15b04a0477449334fa3b4b7c7d6d585b7ecd22c1b445772e5463483d061c127adfd7c8647dfe373b5da1b13966da7da46321f6c1ecff1f75ff15aa26f86b36fdd905d40aabd30b8a28c7a13c78960eb9a5c080d34fa98a23545254c0cfb845e663e6e582781e0a6c476b23fe249da18d4e33ed50644ee637e0788f654ca914f7f5a1d4c35698463b57df7ea8a189150dfcb14c4914b8c026455040ebeebc68bb197b49cd22f202996642f6c5160fd783d0e7602a7af3dc6c0dcf2b5fa39e75e0a59770072e275ba7384372c6bd9c534ed45630b7aae265309e49d5b676c91ff6df509b4725b98627afbed475d2e6651df814710bdd72fb4381da1afc9e60fc55a195d30ac9d7f161bfc2fed7dde616e05af6df5222f46670512b07f22ce20a0c154f7271fd57dd452854f75fbe64f00916cd67d62fac2863ae2585b60f0d2e098ea3883edc325ce60207966f016d6a14373782dd8f7116cad5985415e3784b1088a81248663f569f91f81350e6aae36408091b24c3e57b194d62335cda32e97226ad8a631f457cef151f084ff6adb849c4fd89a557717a03256416da85fcd503868b188627393fa9f8a1c8e56e66b51d5fd22f524c25439bccb626a107a27e8fb38243bc2e107b62dc8d8dc89268642ce863a4c58b6a91ff9222e5a401e2c52f66dfcba60730b92a1fe89e30736daace4c6c0a1916274a835a4db6048459ba742d69e2483cf53f95add2aa3de727fce6c43ea7f9a2791e3f7cc691757b9c95f49f06ca254eae617f225b8288fc47828a41bc85854f4cb176f20cfdeb895787ae0e882bf0798cd907e375820a0cd74650cba16e725bb269f851be28a849f708579425b67c120ff3efd14b9c691aec514da8fdd1f39865d7cfeef86b8a31cdc0927c573499119c3a4aa2a32d1d21578d2e4a765e06e78ed6e179bf3142f66e1a203f909f7c40cf24081e85e1362cb65146bf74ac4eb1c4c0408cb16e36a685f22ff2f0190ce10a8ea636cc2b7f75495abebdf357bf8485c090822d0aafb078c6cc95d050bacc4da0fa85b71b6eb925cbb93eebdb0e104ed5fe346c7768571cc76fa6a8760349fa73e05e74b9fb0b29542af0f34ac3320b6d5f388ba8042e33ca223b9f174a31f003e4802dffd5efa894884e0470ca2366719e6c649d6ea9201b76c36862a9015330d52331032bf7b60c77dc935647ea86a714486fda85884caca43e41d531ffabfb6fddc2e48d8944a11bfad16b604c7941aaa849c50eebd29c614ee10729052a6ed9ce440117c02975704b0991d0084e517542a02c9684e60ac6e14c2dd2bc2d13a0ba6a8a904ba2841357332eccbecf178190178ca98a4bbae378009e87bd55dbd543f9ef19c05bf4eb9994cd1312ca24d2c47fd041c0c8cc31ab4b32797d443c481cd1b510936b9894ff4d77a907d98df73140b9b4e33d54a974cb37312fa3b86cf94cb56d53672b5a2748114558a6d10be6f8d1fd268a947e7f67e9263c0a54960e23499e476ecfb8c4b8c214028efcfb8557d499a0c9e9e69efd1b4a74dcd3d720289b4d5721e194abad1a1fd36e45f3d80322b4900b17011c8aa785401b6e8577d5661e342330abe4a7f0a031f589e0ce967f18832bcde0cf2327c9beb1be444ed93dea6da43aff6c8503ff1df8df2348a17515cb80fe65657c4585d679b6669ad042f80e151906154073c382793957762a201b2465f4ef98df77c68afebb93467aeeb69f71405ae5e179aad71debc26c6deeaf3339c4965a5de7ea5d4f21f3b3bfd608763bf810762e61b02a4b06fece2af5451ece94c1a0a351920390adff6c53df18e078275a77f9acdbdcbc0078e1e3197dcb75926fe00c45e385d427cbd4bbdbdee1be7b37a6d58d0f31a2e06217176c5daefd5c2a96103d62e542c2a6944fa5ab5f993f74ce8b26bce27012b4f46d483183064bc143c3a86281ca07f54b114af018500757bbb52a420c094996564d902c4c78bab931e4f196cc8051cce5bcff197911ef7f92e7c3b6e5914d0308d5e784cc8427cfa9a6c9b76960d15d894a104f8ed88af2e06e1e3eeb0f95af1f6cae1b43e970edd6a61fa5c1661de4da95ecf2ed3e84f634171986779ffc11b79fd646debc4d2c0d791e8af3d831c08bc298ff34c8b9201b3ffbc4fb77d9257b9e75860d654ea1680292fa025ae283aa5863ef74e76df9f35acaf72b810bd8abadb5ca45633c14805a451de486871002d03b400f3fbd2c8fa5e2c3030d2603cdc255429c796116ce7a2a1f1559d2a864f36ac03758fde5bfe79fc4fa291e4b9bee3af3af37463a8d11478f481b68eaf26b7e810cf4084374ec3b726431b6d746fbfdf695352f438e49fa076e449ee82f1d33a99745d0e7f296331959dbe1e5b807bc5b986c14ea1bccf3484c2c878bd157de63c6e5d876408f8feb06cc409fc06e91521937954172da489f1f1822b5d2a0113e23af6a171eaab9891179d4b7aa9f4f97d3d37e766f43d3ab69ad13aaba277b86c7b6b51330b929bbd796d708817cf0c0410ea4dea2d49b94078857e1d4cf60c2670abeb629a8603c3434e2baf7d6624a7439c63e0b24333c7cac54a1f08a024c38d888c5912c5672a0fca7ceaa23480118bdcae6b2b25f9c493e6be167b0b074006fd504e1eb6d6e6879da81119d989a7ee5ce1fabc71374f4a7560165f443f5edac3f816133d1c87a417d710b75799d7d3065b77064cae6522b0a78747ce7c77e9dcdba8d2ef4e6748773d9f3bb4db59baf8f7a041a20323de9e4bf6b58c8e8e83b226e79d3c02fdc161f5c82e626afeb180e3cd98387d694c81cc8168927117e37be8a73b464d3dee0721b4bd77122c4874fe109f222294f79a538615a2d408723e304082e3f3b0713a384a61763811af31839bd5813b8cc6dd31146df102836c5692252ebbe139988042c3b9c984a515d6a20a0a762613a5b7bb42e8e7be780aaddb96cdeab2a5c4e37ab7d4e04a3786db23bc2d25594fa8bdb2c40e71bf9d239c8c70b96cecbc9066d8611aeae96b4b4f7e7b35ecd486ef5d0d9b5a06af0cf23abc5713b662ccb52994e838d8667bdc39b76e0c47806e418f0aaebf99e2594f32e832b07377c337b3fa45cdef8610fb7e1d5c282d8a33b0808f3ca73aacd11a3d68ea1b998dd3e9d2cd75c57e63af734d87f4d719f48b09f9014356aa6270caa98128c4b2e7429a0a57c1a38d7bfe4bbeb3c13fca049f996e57bac69fcc6fc334081433eb81fab5a2fb2eb8a394358bfa5d5391fcc409530bd624663fe878462bdaef97d41ce75bdbe431ac381af0f390f95295541b1e96aa513a92317f1cf8658bda386e0621740164e0fad0795fe93088b7745117fd1bbf1ebeee6759dd6582f75eb60afdb7271a6f63da502e51ed777859ed9737b1bb935c69dddb1a2ae7fbed481779a91cbd0dd5fc08b475f4efb22e07aef105fe50826f67ff8f4b40a94c998d2627916bb2700628e310186f39ac0d9e0f9ef6edf82b410203152274d73888da7a980c1e248bb1671376897dbeadf0cc9ba608ceaa4e1b2b611ea3b146baa6cd7c74c05cfeb293082a5d2c0c49fe298e5952e9fe0cbf51e926dc09289ee351e3acea45229bbb1aebbf4d114a74913e01ff7936c41ace44e9bf9908df9a8ff5c52557f129dd4a512901220ff4195cef83d731a84162c084e5f270a56e065cc227d3c14fdafafa826e5101986c7360f039de11233c07487f9d0a28b40cb60a4245776b30742cc995f41b93b58c8b062ebc0b063954be394c1c430b67cc02e6eaa40b176e89df8b50f0e467d5cc9a6d71014c8cf435bd10afda69db5c80b6bb8619a01ac1664186302024937afd6b5b2a8fd4e8a66c092883c877fe64ad0d2bb1b913b4d494b1171a73fc400149e0a9ddd394f0ddd0f9785a6fc47338a05587c234fe73b1b2d2ec11c86a39ec29f28d8fbda17a55cfdbdcb878c4ffd461a698214c3e3eb07f97f6e5dc11b4687cc4d6df7bee7921d9daa7b6e710a47bab4cd7ca125c475247035377970912fa8260af07273769d0ff0d4b9bb4cd6967860992cc32b64832f757dd9fc144ffa73815d30c2a5d04cc5f068bb5647b8abfaec280c713d891fefd11195e0ea30a554eb8ce162743633cb86095d82d18d790b805e46d6b18e46f59ee822b67189dceff284ab08ee609161bdccb844bc64a49a27ae79308a738ad2f26d0eff7068d4b0151f4549036fbfcbde4b43d7d2b4a1d2493bfbd2ea7f18c882ae50c3b0e18fd019c0871e9ff606d977577895c3c302b5841eca4d7611159e7cd4500cbf526617034567450fca82f17273c1c30580a585c4ff1b888d872b0fc90bae8cff8318efb09c5dcd1c5b6a00d3fae566ab2cf387274ab6ad76d2c197808c589052ea627293e1d4fa1720f6c9e01cf79bf3443a9cf68f3b02e0e2ea5c40b9b1dcbf64b58da647d5e5633382a4023645c9778998964b26f6209fe010f78ec81eb03b5f3ad88962fe29c2865c61853bfcd90b173e62dea25b497d4e9f21ce31c635583a72fd6b4e300fd5760bf29f53862604ea250b60bc8396361bddb02a51b9fd8353336b3b30a126fdd16ce5731c4f00814e8d13c68d950d0323eb3bcd31c3dddc7a5283fa2db90399931d8f50cc211256dcea15fa280f657f0971163ac480137b83900ecd87ce0a57573d3d52bb0a2250c046bd5005980b5ceaaa61b315504cfd8e69dd4fa0fa92fc232776da708c063094fd069a66522f177cf4296ae001ce167a7f0b3408fed70083f910db29b4b1ee8e2745c115049eb853fc1a8f7ff7be1d4f015c6aff557a4e212c7034cbfb2a996b1773c1354979e85aeb4951d38fda200ea5294bef1e0effd23b1090b0306c98e730685513614b98361afab39496db7ad092bac98cee4316adfc370a34c16a9ea40d546720d0372248f680971c8a2b049a927a3040ebaaec32568b68f3625db3896051d3e7a3752bf276d4329040952c2fd80166544d76c15138faa5c1ea083d774d05b7bc5fada36a6907df5d3856924a4953a476f5ddf75885aa9889e459549093488689d6da3a2e78d521e6225e8745927d61bad3e2a20cf302f8c02bdd656338e77f3be9d63d6668b42ffd043dedd2d04b8a9b544d2cfb84ac77df4f80b5e302435854330163b633fe269f69627de164a6a301ed7fa8917c53583aa83dca177a88ac765eb170129d58315b8e25c4d2fce22c66ae7553900f82479041212ece2fe1a555f872550b60c8cb3510531b5f506848a9088deb77d00a69b11cd976ba78fc86bbd65fc128dd54090c766875ddd13ddc11b2fd89231b28c990d76e0dc8fe34d1d647dad51177378502b7699542093e707e5386a52709aeeecbd832143ff327083c2a5f55efc2b22c6c8a6f3dd2bbed05e11eff8437c18cb002b45394f1ed2495cae15ce470cc7936d47736001e65290c7025194460cad81877be55bd9cba255e7e98308265848587a2d1932a0b182bee3931c09b3f1dbe9af522ab2dced7b64821409677014f391ad01305648864623dc58528cdc416a74bc00ad0bf4eff577d047ec20a2543d15b90d52369a8fa22ea73c9b897cea27e74ea43bff0856c83c5c9b2314a0f51413b4c826ea91739b37b961e95fbff0d8c172cab6698bcf8dc4e9811dd52512fddeaa57932ccb0f1556ed3b536d147da45a94b6e8ec6ae848792a3a65b0a9ff8a4ac37e98617115f48c9319872d45ea50d4ad4e90018b351d395b2cfae2deb7cad51dcba29ddb1b9aa4e670bb902b39736e742230a64ae124024e49d96533af95f902950107b9029039967123aea5e1172b2f17df2fee0d8f91af203cabc485d4db0f250c040a8f36fc8c9c701d1ea675e6ae6598b8ec88f2e96cf209941e097891bd3095c39500cba4b5763598c519ab3956ee082af79efa5095e6e548524d0cafbf876a9a888cedb6a269fada8e450369d9af9dddb123cc60db1975ba3697e009271d7466dd974b92c453aff28ce665034d7c4de443e584672a33210ae1453eec6a3b06c47f24690146e361b49496bc8191e2c8aa365a6fe3c18546ce4c5e30e5449ae40cd06a096adb3463316822b1df51df1c6f1b16759649e9bc9bb2fe4ffdbb4917b268a429e5337a329c89c64e84e7ae7e7afb1c8d34b4ec914bceac31f48e5ba2b2ec60acc982bc1499764e730092c7def78497f9a372c23ced61cfcc5209646f9bc526c9a2966712790eb61399274445337b3c08b7fbf0a9fc103f9cafbda966f1ea3ee5bc9391cf0eed5f61bcba6527150062935809ad5c4ff7db1be97a1286d6c449954d4bcc8bbdb05b7efd60c521f47b6aef91495e68a8ace75d4a2b6adfc1d759ea56cfa19deec3670da3665f15d446f3c94b7599313068becf61c54078e944a19399587a99e764f168135a4d19aa65598dfb3c7011f05b4fda22d23bd025ba6f1c74ee0a3be593c343d1a7466320b7b908ab6d97d9a139b6c7bc943ff3d4193f6e15c9e295a2fcc21a08da864428ffe84a76f0a6be85c1a69c7be0eb5680a6b9e5d3bb82222912b478259b2774409bb345c7ade5cff886b2ca0a4ed4f35d0ad25599a4b2beba25290bafc18f51ade2580c5291335250396e462b27c8aa9f17d3b9876b94f6e5017e699b6a2924462733f513589246d0e80abac1d6329a1c7a39d03a8dfda4fdb2acde8987dec6fb72f78e2b3ac33268415ab09115398d593b9a349cef7e229a234291bd39cf8a629d76e0f91eb50207b91eb0a723b260957f86692e20e11eb7cd9db1beec4125a98af493f22bc1c030c7a2ef18c3ce4bb88973a0e418ced983be7d130258ac1f3eb547b4998d9277f461337a47cd7f884ac880a0228e4672d1131cd6af8d9e829ebe3318b6aef9a4705dd063f4ab8379245e96b9fc8f534677561b78b6a086f7ac98621394d1f5322fd3b80d0e2d84ee11ddf2bde35f37d06cc5a349d5c97d02c18e6f565353bceb59992ea9e4c8f1483d4d05d9c2f1aed140e74c4be69ed7ab299dfb7249fa51a435d5ec8b3bc98e87e15c38b2d0243dc5b4141e89255932e67783d36d0cb0087e0fb25f35904ea5e0cc834c272036530e08aa4b6598fc9447536be6cb5332cf7480affdd8de6c52cd08f84aab80b860a90b8d72910120d51418b1bb1656c02a2b8faa5c10e044d6371d9a550a8fa0c42eb41820ac891b7e78896c5af70041a8339f68ec22eb08fd60b0b751931ab744575440d42541cfddd6af0a69bad55df09842f09e7974ba9ba96a9e1979b6a441a5f50fa0c0d095f8a9306ed0fd43feff300ae675380633b78dd0634f6209ad53f39331f9ad570a6eba02782e0fd3a992ff8123b1482053879d32a1bc5b2580509d98adfcf21456aef8ba578170090555433fcd4089779f9f3ca71cc954641c6130fb1929151d6b35226a0b729116021b10c2ba7b86f4709afc51e6438e08a9f3a8ffcfa276e12b2049d895b6394d77ddd2466c339c9be06a608898ecff8be6205b6ee54693da259063caa39debc3a107aaa9d03eda9203faed67d10bb7b2e1d16b6b778afeb60fc3072d263ccf6c38c1b85de72f0d455f43f599a594004817c15b76a268a99a4f46519f97698d454a5a6a3618479a5d5b301382ecef1b7b860575d6bf869a854a789414528b2f1fc6c8147db498c48d546d9abe7b56210ac54dd7e39f32371509c4b012cbed0799902dd8ad44d5645559ab1519fd7960c3d8fa8b3146b0b41feec651d05e23859e70ec9ac37b5b962ccb032c2083b6be6adabdaca2500eeb800c61094285b46ab05a77b1517b5388fedbf08ad357d3497751b7236551f4e9022ac79008145b9abda0e0ea1d6c52a24b31eb699def8067934a57d0f06083c24eb92b453922ae827115666465fe08549c05b55d276c23f3ad8067083cdd67425936f62d8e0253e829f782bb5a3f0df0448e614597e4791e3f68d3f7be2f5c80a3e378b007f92611bf8e8f33f347e210a7113eee8d7b919e6d6c1059038619e448081850cc84efb5790a14d86def75937f1fd060a6373bd1728292ec2f686c2b702221e5172292ee70c1e91326522fd36c3bff88effbfddf6a84b0bbaef0b2c438e0035ce26481293eefd5ef3cfe42c85887cd43230c500d663c231bf85320db9bfdab07de8cba6cb6728f5fb864c365ccff288dddb074b2db36ee62d89c7442c34b79d652db02a2f4a9bfc3bcbe31fe7dc05bd57baf1e2b7a48b163e2f62ea56e76491e9fab6f6da2f68d076b9dfa355940900b5e0ee8accc9bf03fcb4a91f4b1f488497eb68f3dcece95505f08d4de22b0d42105946c817500aa571ac5d1a4ad6588ee7c986d8a18cfabc967321bdc96c10178a6ef4ed264d17cbf0e7ebfe6adb43ed70116fff8579cbd5019c874af985c0ed241a6386a0c8d8dce4c5bc29a7ede07fa3a38b6309b8000a3f0ed8b66c4610bb7ec5dba3713c739b6f181f9c1ff8010e82265eb90450194c6e24a7a6b11a74cff8943004df21619c89527a64fec6a5872bd19d239d0a18f9dae94afe3fddd622ff6b15268106fac0c743acc57880de8bbf5d8ba1cf7a7b8d6801ffc09018ad954febed038523ca5a63f2fe66147d16e572cc64af2fc6b1ac549ab694b45cb98b9fe0f7dbc6390b000410d474f6bed40f24adef3ae85fc53b3ca4c9249a28df6545e854092944e901ba4c8b883488bd0271be41d4fd5355eab65282be0c090de5bdcd78fa441635cbca41be9a6807e31a24566898b0af19e8efaf1bac794cfc2bcf23d2db0e4b104bb1e29058b58e8e8330a7464b5e411e5265a79389ebd12bb5bdeda1cb047c64d06b941aea8bb699036b5156cca76d4f7e41e51378e96a23ecdafc99d8f09c314133178c30ad7dc3e6fa97795b4353c3c860de3a17763f7f35ff8eabeb8b3b3af6fb7d08ece134737f5614c62bf5315fff8e652e21333a23031d6aaec4add4dbbd2f798a161ce1bf432abee5cae96bd976b2bf4789ad2295518ca847dea8df74a168dd4e64362dfdf8982af50b2fa8ced0f95d74fa4e67793ef7ec6552d37e6e0b721607e16aadf0c81c2a734a070ee3daa18472389571cda61e5932a9abe7440a7da17ff90c78456470094523d53b1da9651a797bbcafd0ada16506e9c1daa606a49931fca8aaa8e37fe79dee28630ac0d9c6e1fd236eb88ae87c2263c56969b51b66bed7c1ebf1d4ec9874e24d593c37573a40d8f5799a69c036fe3edf3bab43a13822a958d5d3d9649c55c3e99c29f4b1126c635554f9d8da87653b6712ad0dd2115ded39cfac84ea722782a61fb0b637731dc330aa98ea7212b0c96d0de677b462f8bb6ce5e60d2f6249b2b66db816d28cc44bbd55eb7d1a76efcb7b0ba7ed7187493b4d9e0cba6123a50c84eb22bc35ff965c896bf32a516cfa50a174d1ec955cc477ef8e7de2e5c13aca0a5dd242a1c36cf7230b3bae891d8c91e5de28e645d5b84b59928bb62c5c37b3d0bc83ea495b6f0bb3600f26159b71c4f1c1d665c5d27ed22bce9a1a1f504a514b1e03aa5b702d0dc645fd40de7aacf82914828ce90d5051367cf9560ea54cd129bd4819ccc6c775d466a078e4647a3c0322a958ab60ad0be3614d7009f4dc7032de600440a2a3f8812a469c8d7227f10fca761545793710060d1f388c9ef3c02a58140d2a385a5eee32b7b379732a12ae2db8d7520e6115590a1b3c9e0d12fcc7319fd09a18123e94f407f5eab91371fcea0563efc6cdae3d4eb5e3a45e56fe09a098f1348332e863180c96a627000d7023079ee95e96ba9f29024a890e4ef57764f486bf0db297c521f1fee393f84e6623875046480557f027e84838cee6883e0736a2cc0c898aecd35e9d8c9ed623b492dd6c47e2355cf3b9cfeb0f57c12d083e47c132135bce98065877f161df4d2375c4b3925b72eb984a28a7daed88e48d30d39e9253487600823abd0a0bc7283975cfd48e1f45b2b5d111e4123c90e837635b2614ac46d8336be5759c6e0878b201188746f4d3e1c90431e367f58be45d639da7834d4aaa92b4dd4dc1f912b49f9c9371ca89c3c804b5d4b1b79f6253194550030ee6c51321ba36eaff437dfac86d8312f12eba60dc32ce7463dfb1df92c77eaf72973d6a1de5ec59f0cdc2ff067ab53dca4d7fcfda6fc4a7700f2bf9b8b4c8aa943ed5d15ec36650f6b3dddc4bb29b73f743d81d729208dc2c3511381ecd6af70789df94d9d00f6be21e698f2fcf44e81ea69c67087ee846e36b8b43badfbd11b2c6d072907b57f9155bd4b8d30fb2c239eebce3f63f12395354f6712d26699aeb8cc363de0a23950622363aa4946a17bcf8edf33b669379348800caf188e2b41c08476276850751151c44f6dfd0510ff4c27ad18141c0b0f42bd3284120e23f0599af2cc5007ac81ae726b8d7a5b34df55bb436c3539bd07d50911d3c1cf6b09ccf3b663e90c04272e33dabe647fe5e73e6e7387064ff968681d081f090faf1551221e9af840060d23a3278a39561c4ec6a8eda1eda8860eba3e5f93c294b60d3a93e7b249c7194e6cd08304a460f258b6edff811052b1ef74408db377097c0ab124ae58ef5923a9b2a6144562ff9e9de77628ba6507f516b3af495e402dfb8055e293d72c41b81bde4130cf35cc6ab8b00d93254dcb36cd7f4f67a6217a36f9631b8d565063492048b2aa6f02be1fb2c3ac2d65a52f6c89f6ee8f5e495abdc80d4e555ae05e386439311186b3495e741453464f5c1b67f202bd6bfc0fb1772723f1103aa081f2e7690dc27b68578c82fdb149af2d21da88d80c7b9e7dece016c4aaa3fadf57d76305767721b72096586d2faead0ee56fd8e2a615ba93513d2a6cfb90c26d6817fbeb4a4545667f7d51fa54ab66f8ffc4d4975c696fc2ddf951a8435ab21a4da5b355bc34a5c2d6f4420242838ad1e2b5e577327937d9068a1820e719be7cf8e9a11a724825a3328b721f40ef5264614bcda4800ff2433ebb95a8420853b553d3ea0c909f93a35d9181d75f23209d00a007f7979b1b273589318ecf12cbba97a79db49a03a89e249a53f21920e91c92b887cff980a58158be27e8a130f0e16a1532295a11c0cbabccfbca77d25d3632fa2dbfc1fe9ea9d8131baa46927e1a1fe78c8cf7502063886e1e3ca696c921ba842d59afc591be1fe0ab5e978a4fb192e41c472e39f4bcc6a97e1e62778e9124b9da22f4beabb2b8c6bd427b28ea303e3d37bfb68733585fb3c31e8151e7e60e335c346ea6c16c53e48d944b21c3a64a45d1c77c4e4c921affddb591bdad3001f6d7e33b3c65111ab8eb24e3d7d4f3606ea5f53a8d35aabcbbb66b9003479872ebfd0f103006deb92a703142e7640080a29774c24972f1a1b79156140bd8daa610f36af82684256577662b820989d9e955ce9be9fedfd5135ac397dd8dd7f1e77245f25dcf7540c38d4f64764588ef9bfab8ee229be31be6fe88b877088225adad452bf5ac3a9ac60f8acad60ee5d4fcc2869495a7810aade373abcfa302a5a48ecc4e10785dfa8e8c21a5aceff2bba15595a4f372c0b4cee67d6543b735fe00d22930604ca2299cb8044c59d52a57a0bc4a00a9bcd6d8151af2146ca304bbf8147cd6ab782eed64742fec7b6f37385711197700cac825396630dd92ec6396e2727af2c5c9d459fbb9d4f945a90be1286cab45d3f839ddae1ddf410ad0208f04822ddea99a9567cc18230986b122748763ff9680b64cdeb79a7c5e3ec773444e014317d36350988c1f33187da227c5debdc5d368582928a3f801b80ed30b05ffac1d6646646539e99607ba196c1c71ac645d8ef74e3012bb3cd09a3bde11ee3fc65158bb59cb869846c223bc5013fdeca2ebddd89f94665a701f0d4424794a1a99670b598f5ee543bb6e6c2e4a488996cfc98b777f86fa77bc57263d4650a6c6bb8d04db6049f48afa58e1ee1e49c43bcb2c980a52f56387439aad975aa81e259357952878a6a65d6e168c9cdceebd62a0080ef7e89e3e964d9eca62fe3697a7e0bc680df45633ff3dcd1a1d0bcf40bca54aacf1a528eab5109fc6b30ccfe8b62656a48413a68b3b299aa4875e4c73755e95123984f96cc95273b36a9e1bf0691dd616d8841c99c213c383aac922ac909502bdda9eee334979a138872f06ecce2e364cee716ff6837639d13f89446bc7104819dbf325c4b5eaa74112ca5e4f78d2b558cdc6a091a8c663d5c4d88ac54a409a26252855781b11004dc5e92b40066af6d9db81e103eaefcb56cdb56a34bc4f2f8c30e66848b632407f19a3e1d29b4d0e84d764417524baca7f436c475a88b4620b128c3312bb1fbca684b653b739d2604e25d113d18f98d2184a04918975faa071eb025ca7eb638faf43e9e22b3451befc16870cbee5b4cc656702618372f6b92915af8cccde1712027839386f7e6f29cb02d2b181a76c3e9d4acbb920d59fbd6f52436ec345d66b715ad3a9c19df652480cb5eb615d29fb5cacca00f2c40f31d357844d8eb0b24f8ec8e969424726a05daa03ca188f13f4fe924335dcd175b833fc18cad6228bdd9979281cc3cf1d53390fc68443a668b2eb91624af00a91f878704d4bb36678722f5ac708d4410ffc4c36380d9c467f8eb764022965e9825d5c67ef02a2a3572a79b61713a00de797f2d8aed7d749b30079c50774041413b64008efa59d235b8a0a8c69c5c72f5490add204e1dafe7a28623bfe6c502cb352b108857dda3239b1a07160182c4d9123682d381e57b4c5b08d08b04ca800a7a8d39b9e2178a6e1753855fb17fe45e736b09d34043b3e02d85844dca4ad8bdd23cdf67468e69162ccf9b708b0109f6305ab6ce7b4844c0eba0ea65991677bf5d03425466d8d2e0d910359e899ab59bdbf4885c2ef0effabfce0e376e8577500e14cf9eee0d50b3419dff09538b71da76314877368fcdd00e2ebb47d0168f16119f578015eb3335ace5817817e882bb0c88c9b4fd38ddf14f94c9b2cccea90a1e8e075e5efe6357719e3e1d99acbd65ef6cf0712fd34c5504bf4c244bbcc67e31d36f1c61d8e9fa8d5cd81ae340be008971ff113c3658cee983181c4ec16c4cf24f6bcb9f1cf71ee3ae729eeb9afa55cc6fbab12ce334afd7843cc0de924c3c789dd9bb981d3450acd74098495324b96af0a2fd63fd315c67101d06fefac3308f2d8169ca9a97b2bd58968cc9a3ab983912cd988b836c1244e9e7f4b0ed9f50227e5f0cedb0ec19ef0279baeb99ec6a7afabe15919421b98ff7cfe09d7e0d2406aa58e0d19ea12e0aa7165a2ee858b002d62dcff77606ce77be9fa9126391d4832d844c05627eb78caebf0db5d13ab793a07960d9bd8e0f5945073fe650b1f46051307626aac51f9ab24d187ffdba358f1c06516d0f3fdbd7cf7c48a38435325c0d442260e56e28b5df134871d5b10e18016e88083ccee72f3c383bbce3abd19dd3fe5e83101c7dbaf610855f3fc5b20f2089a65b48bf37fd445ee0ad852ea9ea63740855b2b98d5bc121e526748bd7443f5e753d276cacfdb75bf0718f463de53382815470087806e9359c2c9b81f02ca0af62b8f5ac16954284a612eae8bcc459ae096e2e712e87db1b88b9d93fa65fe6b1787baeb5763205980ef0581a987ca89a128326fe09fba99ccd887fd50d9072a4a40a40b8bce090f2fef4959cc07b70579746c2a18b9bb435549d008021c63f69842c39a470d07c9d38dfed7d6d15d59fcbddab5c2b35dc528003cfa73154f6bfff1716f115ce5c0aa2ed44e6e054f6a4c6f6ef41b43c2696799137c59d9c64fc80e65c145bc9b5f3d8a4c39ffdf5b139c986825a5d499956b1f4c9e2239cf6472d579057e2d33686ac44c97249424ae145e7d787e2057826c7ccbb9e565a69d5a373daba70b7f7a4b0de9e907ba2f86dc4ab649a24650a983f45d4e1ab18d76d4e5b14194f859e9951ae78e4a5d240a8c57d3aefd8ad1b3f6cc7e3d9a923adbed327508fc9d87ed0407f92100c21b74c36f60c2f23018e832e80f717002a40750f086fcaa74227c8d8fc0d5685ca2ebe1c2c7311da4d3e5c7d433953b2a53c3217b0d2c096c9f5c745184cc359fb0865496ed710a1d7c65c0e8dabce4ba13f5c12f1de580d92da6fd86cdcbd057fc9f5dbf4b129edcb4c05ecfc40f0747aa66e03eddeb6e8b7cf42e1c0055308a555577c6c1516f4a712eb1fe3ce15fac47799dcf12ccd2f3187337eee7d5a38675e4da576ffbe9efb9681226d791cb8353dfb69db95575a7ebf6ae1185110c28473da02a0509f594ade3488ee0140893a48d2129b0144cda822c7deb4eebd13f9200db76fa76d140b5883c77f98021e2081554a9a5bacf9d2b024fa811b5888315d9e015e68e46c65d387140c08d87e61a9249f3264da0ee4fa227f90ed1981e4e750f4d5299b90292821289bb3b2f2c5914fea48d6cbb078968b9ba4594bed3d4ca269920e6d08c6af8ec4fff6defe93dd9ad12803408c82f0b1e77ff2d33aab8905736938f5d8ac03870ee791c349d54652d54d50c861977ed5ac03a19884f0efe368876ae3605c73f1aa2f65a8195c4139fe75415540e9f3dd0557b2fb22619ca90b9a1eee1cab6431ab395531c4093e6af1e8ce911307e8d16302cba1b5277977a5bf019a5afefff8cfb4dffbdc74048a7c64b6281287f17085a449cca5a3fd17cbf0e6e58ff8eb7849bc8f6952f6d469930f5ca3dc6527d4c36fbb918875dfd7f4704e76293a9bca6f87001cf52a1f0d2473e684ca4ced29d51e31f0afda954baa5249e3912ecc118be3f3f3aab168ab48612b9f9347c94d88b61feaabb5780e0d2005cd001c4ad09717e5f37a306ce7706c1e726857fdd78e2de4fc311c3a229e63c54e288781cf1f75974ba3dbdaec238d2e81fc663ab6b83b85b129106b653f6c7a29e243087a0bded43c98f4acef513e2687e37b19cd25b9d85d32adaec0007d22842066a9c0c7c6aa145a00a059207498d9e780a3cfe8d6b1b84f3de8ee16ba3a61554b299a5c45dd18f4548cd366e3c7915b304987238c907b5fb7466efae2668cafb715ec2ec29babffbb4bf6485ce5950c0420c0c36c1f1e588773f947864fdbe987bbf5c9d3f1e8b752a27460304d5cdfc314806c04e8c74d7faf1b4042691b76cbabc62940dffd2a5e60131e72a9a082f39468d2217dd877c1304dae1341799f788a95be389d00552336ec560016b874ade8a4c5259d2201ec8306614f56218cffe18f4f7c3d72c635e672b694013fa3ee6370eaeef58fd84d33fe191d671b843e73168cc71b64685c7b4bacc065e89fc2fa616a0e32fafee4eca1c286498c3d121cfc1c4f7c3b46184c24ef18fd4600bfaa4cab348b7d24a3b66c83db31d7dbdc247b83abb47d51494b6386b1b17db1f7b251ffeee3a18e9fe76d2b0bd63e0a779ead4d26267b1f3a2dea463e2b576018c3e1203bafe38160c04ec7d8f853530da24dd1f43bcaf1be20e6d028ec606767845ee1547c141bd73dcf3810a8b3690dd388e416cb5eeeb729eed53addce4c7f1fadd3a728e9caf9a0f384c05c57d2c966c97ac329f476b84325f5e17d9517aad92eceba8bad846900689b9e91b24d75f144e0246747a4913e4f503e0c9448a5918063fedc0e1fae2e365e64527f4dacadb4b067a789843857d160e96ca018ef01347fd2c96866aa7472eb9638fcf3b677e2bd32335e043199b8fe2d247db25e3b070343c621a687f79125d923477d235c9ecbde3ad80b9d6490b570c6dd55ef7ec90af0533fcfbf90955be614848468dff2cd07816fd3ccef048966a19e328c6ffaf0ca00c3e6a68ee765c8d8f6a601336b5cd8acd1c36a88e065056753d96c43a90349e254c30eb92ac02d6350d47065c46f95569a515ab1b6185b29b852743b4692bbda6d8b83fb51ce94460d1f7a8dc6ab599c32021e08c3341f8324178fce95a6a8f502ee6e46613481fa3c93b1784fd599fc6bf2c7cdf27fe34117edc9ae437913fc96863515b3a723dee00c126f633466dd1f07f7c17661f425ea78e7be6bb995c0693d3bfce9217d052ba13a778cef007dc8690f3076808d7391ee556fbfd8eecb1f5dfa217ca739249077135ae97eab94e79719af02a334779ca48832e33efc8a8b930b22f1e7e5609a76f2ef16a83ea1990687f8b6af2f4f4a5dd510f7ce75b7743d8a80c0ba745f30cbd0af465afab34d3a2e533623238ad98d6a34a76ed33f582222020c0eb8b8f7d5f5eeb08656a9ec47a95e406f5b6def001a6a14fca4ea517a71e9232954efaf631445f3093a7684f86401dbbbdbc47a1e385ebe9d4296a0f3ec76c2536c550fa41b5d35a1ec16682411db06ca6356e06d900a9642d8998228bd8b9e7721d0774a33f8d6245f91676e5329a6cf044f557ca61c070740ab6dfc111dab5c70e8d4dead3652f3a9d7aa8c5e9b01ca0a5338a218d0b6aac8f1480fca5e408e8a9069fedf19a93e3c8141419b0a14441445a216b62c3c07b39b42536879ff4fb7603d5107c1624370d6be70e6bb521f95e5e7a6fd3087df5f104571570b391f71d3c06b369f27c792d9921bdf66766d44710ef5eab2a9dae1bebe27b63c6c57a84422f137c9818eee49625d089d497e36e3767ad7276d8495f600aaff61172b3ab29b400d613fc1b0a0c632209cf3194a29ec4bc06e29ca50077b2c67b4ddfbcd70e296571ada76f93977b83fc25ac8ccf1c4028289c747f13d2432aa0dc2727ca3d93e6557c36fdc794d6166ef7e604e4c8e6e5950d91fc136c288aacd761c519781894ab17bf36d6f1edba0bd61e6ad6fec559470e83d24864657d6a0b39bf715919fcaf4cd660913b760b2461453c59afa90ddfdeb2e0caca02d68ffbde1a81fc77a3bca808534350d79ce5369b0fd2e54841e862f1cff3786f9a420bb46d49413bf8644e3bbbe0572b98bfba3f7b556d14725458660807f3ce5a1844de75818adf3e15c65b19a8c4a9e648676866bdaa1615e2060469d084886cac860ec84050126eb06f4dc1ab0070fe7604b9bbf12969cbe15debcb3950fff183d6f68d1e0303253f967654435ca5f4f0aa12f9f6685c3b7f6107d1741fef71c14e0a8756381ee9930073e70f99da76c171d3e7a71b670b33f93a05497c265e84230c06bf1641ca250bc2dd27b06021e6b7850b640c31a9bf381957e4a62fcb3dbba5c024809088c2d94938edb5a538c00ada4c99d69df239d08a277344eae662645361aeccc7e8e9525e7c288a7a3da88497e5ec19b27906566e361053ff908bfb6a7e194128b68576d18b320d343451c23a589eb743125eaa659247d149e68c8fbb379a28e14c4d8d70262fab73539223a5ae79902042180f36a44b93c44174a92335d0950acd0dff6a2f1950509ee25393ac99da8a86e3dfe15c8ee99ada1c571d6a2543a40699eef993c5ac6c2fda20785372d49087043d88f456a1e4b415ba2dd58eb6a785be24d6ad4521c970653225b938c8808d1ece6e2cce20257759db31222b5eef97eeb9a034a1a37f44ace3596022507c4d593df57f9b449d98aa1911b3b815f6d01dfe8767ed2ae693f4d823ed9755dadb96bc9c690b612581fcde4baa265e4fd98afe67e530bf1c3473d6f14e3c6493dd8ee7b8947dbae97f2179f30eb4fbeba9664ba8dd2cfd1f132692ef99df190f5977f120d5bff1658914563dbfc8c1c893a58f0b6d8084509f2a5b8860b7adca34936c984bd2043e3a9e4a5d3d43f83d17239d4b7ed247c270d1ca1ac398dbce323c5adc22ff2b14c2fd3764a4ca8e96ad7850bad85d32e011475bef7433f3da20476acef018d57c9f0a5aa980a7581fdb53b84a4ed20a634a5ab37764e8b6b08da330b6bc54fc89087ced5a47436fc1a3caab7ba4df57f5269e95c41153a6b06ce754cc5321973bfdf8deeb95f4d7db1b546cbcb4e8f902910108b9028c39cd307c89409a3f5570e6eabc54644fd067fbac219dfbe1035cee450971e4505f90d6492a3df87c569d22cd5cdd2bd6b41d16fb39a8dbf0e198f77e1ef1484ae1b2d111f1b69d237ed5de14b6d1a6d0d50d7c9218473204c55be08f6d0328861a6861842e3e0bb6a6b0c5c730532219b49d10755362c01607eb148f6bc86dd386bc73a655ed2c1374cea133bff6174ebe4dde263471d41aa163a32ac21ee772b3ec572f443daf6da3c7656e7111367f350af35a92d80e8b454ff0411cc586814c8ea38a4f04b3f97f50ff24059157219e5cfe28df6e4e4517fb91691d353b319a4863cd122cf357d2e8bdbe670ade46fc917aea569d3b1ec465de7ca811b62fd8a671fe4f6772bca57feeb6969f8197afd80e26d712ac1bdd323fda6dd327b1978bb89cd428cd93938fce88c378d27320acee22168c0a649cbfafd9768227083a35fff63a685b04edeceb3a2823dbcb4cad287f2f1c5e38f59a534451901852e99ef266f108b2350acc30779cef12c72f611b3f07def599c940884d2a831e1f5c6b00717d1cab77c5b4e4f422cdb2e08b36bdaa819ca0581459132fc8437705a13e4037ae4bc7e7b86ee9264d92cd419a0e33a8b4e1e54bbf8383144e69eb1c5e42c4323a5b2d59f882f460b11c6f6ac364bb53ee39d8dfe510299c5759fd6b4d52ed61d4eeb9bd2accb64542d6a8f53d98ae726db6b8e46d2ee491048b9085c5badfb4819540b8065bbb06eda439ea2cf303ccfa72def8ac92d58fec2dc9d24b5ac9f794fc3b2b4c735e7542329c7712890218e030d18454b2b80240eaf1cb2c77255a419b090d5e88daad55bdbd0a9f20c9629ad68a9b6e943571f527905f33ffab6de9a5212cbf0d437413af0d0d3079d09e3a2a220f36c9ba6ed31a361d9635d8eaab2840c9d3570c10f91eb50208b91eb07a203ebd0133a6ab2186d57da9da6a92b2e083ee3a1263254a62856eced46bb53dc02cdb82c920f962301f77d509cfd9bf2b6afa9004d00297e0f2f38ac2e974f0de86be43432b630d23e089d69bba06fbfc4574cf7087c5105c62023358574b7d1bde3cad79c8c42ddc23b0702c5cfa1f50731c51925f841a0dccb136c690ecbddb3ebb297ada1c7d328d1826c4723ad043ff508ea6ee0859bdf3b7aded8b998a423c2dde1877889074f7a906f049e927ddf070f0297e2eca5288b7449e0266a321fea176faa3009cf1d3364e20840f806325ebde9f4bc1f49e9ff6877d8a85dd7a5086a66ff0744e18cdd5df1e6c6d3a96238f3f6eea5ce250b625848df9d8b6e8d38f28ee1cfdc1db9d18c0d200ef451e16e86f78e6d7caa5d103d261126044405d2a2fc71e25d335c0f04bd51cc619bc9bd41431a1be056909c1f8215fe9dbadb35b9fad6cf0bd6d4847672916b730e181671c736fdfa53d7431130a4973a7d860736c335174e792620e759686163e85e92867c051f789cde1cedea52d07e0ca1213c9b4e69421bfec95ee14f0a19222942b95ddfd1738eae8a0bc0ba1cf1d69d3fc3868af952fa179ef3747c0f6cfada1bb11e723ee040d6c4cf25b304767e46040572f553d64a64a74d6abb4da27da6c59fb57e48980dc1da83c9a8caf57af764fd1227d34e834eb9077cf5ecc7a2f04345a8dd54272365b26f5a35be9d93c3c886a0a80f1e525cb5121adc6eb0a842dd41db4734cb036d0b030e4dc8424d47adeb8fc7ce582298ac8683a1f154a80c52dec5b50fa8017c5e9cfb8bce1f2f3f368a199a3fe253da156155dd3cbfe802d8cfd1673474cfac77a96ae7b71a2addd0b359ce5a1717b99f5c0a3bbda685995e5dd66d7d97c263d20f04d7e28faa01d4a47075082fdf94a57c55b210ac250606e0b88f95138a838a3e8ff8d6c751fe38746e68ddb12b7cea6af9a97835fceda837d9e1c38f7167cb464bf78a9414234f4af8935ea3c3531d9957a0d827dac56f7b39a3cc598bdb8aa9895d25a7a87bfa60f97053ceb3cb39572d339bf25b81d07b08990e5a5d251cb7e67cca80cd8b16b10ad9ad7b25ff911ff6e88002dbae57d76b10d4ed3b5cb3bcbfe0b0a6917610f1d1ae593f4bec47d9ba799dd0b4bef708ddb3d2ad4091efca1f0f1649f88244fe504ec0b3d33671a300e33f63b375ea6c965b9973e39dc0c368613137e2516b96e22550cda2b969d9042c4b964160cd7bf223b71bf982730bd95db0a1d7621a144af2faa9fc271e62f368d7b9c4d112da0766473ccbf9abcf9b6f3dbc4a115a6936ab7125dcebcdae6d534fd8b8e4f03a51e8b5634863180250a339ce4cc3ff2ae7da376f43d3ea69081d9ca3e529da9f55aa58ea2828804af0a1c837067320d58f86ee929d45a13b99a33b4cc3738f97649e0b6b81172d8a267b617b5df7bdd3d1554c25c8f29eb978aec72a6d0417d71d200c864e852e2dc922e5d1b968492a385f6d8a99015515700fb0f260457041e3ecd1582bf4e1589a5770747ad3e8c296ae43cdc79010405b4ab8fb001ed5ca1e6e35bff1e4fe011427cd60bc02c2e5a74102960683ec4e96f8f7402ed4ab788b7b6ddbee916d2f05350bc5bf4c569bc8dd52a260083a1b070515b0d22ee321b018d9181ac8e1747774679ba2eaf6663dfd0491ca2a66e04333e3fe58c443cd6c12eb0803726d3830f53957d2ae38ea09f63c082bd8d860c05bd3b79eb18b5965903e66eb151da3c9acb1f8f06e71d9e8ef0f036994b931be437cd7801ccf45988caf7e4836b641ab68343722f623f9507ca8ea2d22d8f0e0b5a9e9d3dcce3bb95b6d214303fc04e6c39da0d44725dc7ba6182bfb6a35fff8fca8b8799c3521cd4f86489d0ddf5d119ea03ef329a167230bedf9a34dcb4d789c06bb3185169655c3f2c0490f4d055e519ddbb3809cee08b0f9aa630c7846e3d03e2d1fda7b68cbc557807495929f49ba1d7baf2f342952d3771884f4281103bc0987f77ba1f2f6cfb3bf39fb8f7eb39744f9049b66e573958025dc1879d64d181e4e77f9521c87122b4f661d346ec3eba205c695c6e281ef58f91c7d06fdbae4aec62e0b93ae7f705e35fd1d2ccbae55e4b5a74ae30c6ba16b97c04b938f5a5ab6fbcea3c3afa9c8e9ad32126ae5132bb6ecf4f3bd322c722c31bab49f6fcfcdb7574c8f0a5ff2359f9f41879aabfc3be53fcb7509b79a99ff2b4c18427c21f45113dcdcea128d99b5b00f55874daa81a034214d6955dcb47f1b65a1951e2f36b16ca973f42b516195c9f1953ce6bb2d23eaabab45331d481f8a5f929be0896f7e26901092d86b59e3361fc6ffe58347a438ab2af0581ead4c59a4e5698507bf584eccff0dcf6487cbf41353354ece25480e4c8b28377dcf8540a09fca581bbe230bcbe7ca1839166b86e7c585ee33f8767fbc287ecdeddc70ce890e4a1d372f00636c08bacf3878ffbc348f76747e0274b2270430370d1ce68371217d6393b7086168e8cae602a349c0882acbaa77ff3cd7469f2efba249165349e258584b6f96aa7b47bad4d314cd908b27290ce3cd04565a55b4d8e47e9b15ab4b2d8c6edc8068370b265220db5b7c0c8dea8783da18d2cf83e14d4971ed21e2df98bce03eab456b85a23f79d9484e0902866842aadbbad36eb3a407283270eed5a67810f133cecab7fc34487dfb6cbbb86356272c9029e5080a9221406413e238b7ff69fb2f99f882c2a6e656a54ec35ae9b640a1497954a3ae03a380cb2ad1a471c35e7045337e2ef2fa3deaecb46d81e00168ff7db89570146346cc3ff7f736d669e03b40701e7f18eced4ecc2ea1b93b7d714905aba3bbbe8b97297e6ec397365c46a72eb60f97c2acca4691e153636083557a36734c73ae793a96265174a5922f8d3ac3d1789ecd85425b625c5fdb25fe0113afc590f5982467387cdbf517ec60a88fd4538ad4c3ee088071668055c628bbc00672baa6ad4b5f41c9c60ff900aede801d1e00e05087f17135722afceef86dd67fc7252cfdd1bc146c7a75d727d2f22b7a24924d49558dd127cd56da076927ad9cd73787477560649d1fc0a752cea732916308706616912e513a5f6631b4ff34599113964186aacbff4aa8ae63aa265b225525d2712cf287cc00142cd611059525caa7ace286bce2ab5ed4df7231f6dc8efa2b5202e4ac69362436cfd741ec8e3d9f0494ac9819a9e4427a7161986c3ea87ffc1a54bf9ea1c8305b3e3676c3aaa0dd598cdbcf2560a37f0b5aa4c402ca3b375e1acda5a8d29b4e7730f15a3264af00fa10bd286d9eed19d9d821e4cf374c3bcda6bd64192870b5bea8c56df9332d09f9ca3a3eae669072689603b5d428bb1467679f956dbbd268854fa4be25837a1aa5fdfb7e61cdd4ff791a3a4e4103b8046cd05e9d5cd50ab88c33f9ffafdd0d70dae59be97d891c6b6eb7146db46497dc040b1f4582568f2edef13e84a054276da9f3531e537d684fd51049a72092ae47cff814ac8e50618ce20908a278d15753fd71f3effeb615ff4ec55d6a5574d5d698c11a98e88232438bebffb05bb51d69aa6bff1081244c8b3b0d3c113901267fdcc22c0ddfb51cede23337e5a467e7964f600013aa91ca5e879ff000334a2d852121edb874c43deb0ff596891e05bcb3a811bd017db21b658807db90afbc3f31d15c3fec1e65e7e2cf3cd7f5a4d2c718965fe86352e36af9a09a9f516fe6ebbba42ae927546137c4469c5bfa0a018b8c9df579ee0afe1948cd859b927ff18f4d9bad104e6a13a8236bf5371948cf7f37b3a878a22604cb49e7fc974e929e2032b108392c5ba0a578d80474b7a64879017e97752a89efa51a23195fdff043cdec69085794429ee0919df259eb7f18872637105a25556e2d448622723589bc9e468f9fc1aed6c2240739c2eb4b5466185cac3f7d159a1a8cb6320a4e2e3a24216e10a6123e73f99f52322c0b16573978dd1f02700374472b4ed5cbe20482aa1b5bb0a9bbdaee76b7e2c3b85c050cebc8f9b348708d111df698e5218c56ef788215b39f0dc26c255d7c6ce2d946cc8a60fda59fbc14aa3c76f614ea2fc573a251f5e528394ac74d01adbddecfdd5fa38d479a735f270cd2777fd95c936784b112709bf73edded886ebd446d3affa26cb16d090da185d3870e05a3d78d001b9e8375248d25e64dd3c145a8992a6f6ff96d06acabd5c4802fc5b8c15d373b91354269eb85252439aea0b6900737f80a35a6207d48b43a7226addbd6dbd3f7280519bd71f8c190485f68ddbc29b28972cfbd09b7ba765a32e68d43bb1907113f7e4883c648f321fb93be8e5bad191f30b4861e908a073066739438f44e3fec3388ed8bace5863619dcd82232a52891170d651869aa108949550610c533a977b3d328a4a8ab31942c1a41ad94cecc68a19fb258bf8902a47f76d8ac8e6dd896a9980ce614f114ef57974a26a5dfb4a88ce390c8b66feb876dd0e509488abc9139ec66948db9b8eeb492be44ad54329a0ac8e7f379a0bf67b33a73d1dcf1e433a0e28fff1448767044092aca3a8600ae4eaab34e0992bdf91ce61bfed1dc433519f83b70993c713fb945fa0f4ec9f7e0c5999a3433e4d1f6cbda5da5dc78adeb1ff1e5fbbf179fac4a11b84c674f31d768a8d63e65059066347974984a1928f375d4500013a2ba9b3afbe3ddac4cbc3b53829d92f67a67ade6ab8e0c1d857b65c4fa5be4f956403e8130fd30c837d23b731b1a33446b288d4458446de70e38802d7c288ee4c4fcf358f7779b1f37196198651fe9578ae45c07c8650cc92fdd0fdc7d4f6a741c537e5140e0704d71d1eab9be2ec40f9e20b0be8be08e107ae39b2dbec7311a13f8baec0426293d51b5066345773ed9287d7bf713a903c74a1668d3e05f3fe82ec7cff0d3407243a714ca846640fe86b9659b2ee73ec2635a613e65bf8581e159d15652adf3b80c9457dd1d6e5c301e211f2195b54fd412ad4db99f94063887b020b6e019ce0cde1d45685305830c9a13144ef176221773c48397ac71c76aca7f9a7227168d17ed049d7e8a777310e38f9efd321f1332cb7698621d769dcd4e92cd0f23750eaa9a53f355c69ca4c42ce02552c02d099976cf5976f36faed91f4ebcb28c357e04958f0a333ee120d3b432bd109a5f5538b6092a823f1df449ed54fa5c8639b0c519a269656d444db534b210e49a4e51fd0919b34e25ac854a4f8abba5a7c1db94dd04a6337710da1fc5a2c7ec4e3f9738bf83fa87933f07db2b95c6b5f1f659d094d1db5009689f92ff739e9b50e4f19b65f5ffa6e8bcadbd7020a6f049bee6401b0ebeaf575ccac30acb2395fc1774241c28d443b54714d6f33cd93e30e4db0d4011a3f53f6a057ddb3bf74ae5729b6a6985aa9042ebdc514d864b257029a3ce0dc6ef657527604389bc916c0208735e65b6abf0d3469dcfc3b211587f8ef707deb994050ba0058ebb03aaf56ee42e2227047767041c4d36dd11a2546e4a4f1f86bad213d35d43aa47f336a5837e97aaf44d442294ebf8adb8bed1565755306795b516681d3271f24a2b140ebab1237b163dcc7dd4f7bb978b4a3741c6c11f01ea7a48bc1a2a3d929b77e179a212c3bbaedefbd6b63f688be2274d86ef6ee454202f85c5593b73290f97984c41225b6fa4455122d8e73a2b365dfa849777c58635f19b9f2d9641d43b8dbaeb4f1996206d5f2325c10f18ae5e468cb4390adde10cd870c753162717b83cc2f932e15f44a546f3cf39b16ce4ee947a010f51d367ee139b48954c929692cd24bf8a88298fa3af8534190d670e1cc7c6d4caeee05229a9dd5af83173e7eee8bbc45697e02be1158be450e910890bcdf7dc65e02111cc09e206179e0a9b41979b937c16cc927b77c921745efd76c731e76f79dbc922aa72394663f29c05180c5cd77384c415443d58ebfb756b681209a6570ffe336233b7c86eb4e099f1898d0fe564ab4d9d50c2700d74ebf96e628d1a99a85aea381c92eeb372b499137e5b996e15b3fdfdf607dbcc1e5ae899a09907d5afd017000d53e7e878ca4403d763c8c6fda7c76adfa42e590f7c273051d0ff15dec194630b75593bfe63b618e2c8d080a7b8e928cc672b5d3c9ca5f8c9d76e7ce5d516f1738ee18ae73dfecd6bb2a4e23554e55265e5c6a6871e14d1dbb5a4294b4489a05cfba642e22eb6a373d4a55ff651bc65c39d2639053a00cddda186f2bec785cabd7faf0befbde1b3bbcb3f66c64cb206f86df1c85d30819d990985bb66ba8c2363696374dda399f42039726e52fd7e4411ca1f302398cbbdf48decae978e27f4529617f703bab01074620cead6fa356b650397b617b533ffc11a44f05c5a12a3ec5880053c05e9c9a4be5914e9a81c960f36dfd398cb6b8b6518417aae1b9ca74ed27ecafacc258d50ad56d70a2c2d8b5c4f21b78cd3a0de9a196e0bbddc3a73a4433bf5e43cad64d3a7423c6e0e9958a6ec091d19e7e95480a1b577de505ba0f9e1cad7dd01a58e6227f3963127d6d4f3b42712ca6328b549044edb1989baaa8014c7c8f8086eecc66e6eac9efab5ff077eeb0f1bb78c88a1add23d7105a781e872115f0f13be3a37f48cef6b81b9809a07b3535ebfa48f1d3b9d9e5f7b41f6ac10ecba9818533bd6e1d7ee7a510ff0969ca4adca690985f5adc82217da9f2dc60e85b85cf586213b8adf6658b53eb0526097310fe6061cc5f94a7cf7aafb73eb38c36362b2684181e625e1016c07b38909d76c627bd364ce01508cf63493afa826d893d25c3a5c2c11b785120f52f2894e207e415a94cdc64370e061ea3021285320c166be10e96ffafc41362828b20995cc00b6c1af6d0b766424e7c8e42058383d8b6c9f6ef6aea15dc1bc261024186f69b61edecb712279492291b0d6604d0d2c427f3985c714bc13eaa56071330f45b4e2ff76d644a16f54bc6f7b833d913ab0490ee2b50ad93b2507151d43f0d8af8cfa4b5a4b27643bbee7860c2d4f6dc0b92b8c7cbede2e7bdf7fccd1083c0aee8d043474fba2fe94058923c37789daea83fe86115d205445f1d26c190488bc940cabe3cd029d057c13bd122d4b96d48b5f2ef9f41537fc1eb05929c110e065fd12887295f356011fb30aa34d355a57bb7ad6e35aab9077dd76cd698ce13ccded13684997555ac7eeedec0cae077151046fd2c1b3ae327141773c78a986ba10f1d73236b08647074c5c577cf205aed9ac0c66862f9c3054731559e890ae6bf2d1907042f3acfbd513965eadabb6092d11aff188cb8dc95b03abccbc1006457d4fc6f1c96092b5b80b9fa9340ec34d954068eae74c820b73f7dbf70d2fb1c2409b83e3ab6e384aca6372f3677d0061f937f108d97db2a64481e2181aa2838548121d1cb3055dca309134e6ccc23e144cb1aa2705f7a6fa1de141d51745482ab6a7adb81e4a1e753ddd1ca5baa47e4da1660ca0dc04c4d169da5abbe3b3931957101b0ff8383d05f70bd083d201647c343e1c7183d6c1a8f8dae9df29ee44d492e1a13c30fb2c89f1b2e479f07b66e57c41a390a36247beefc08ac055db83121f50bd96200a6e9f998152a90f92e9ab6c0c6042aef39977e79f7c4abfa14827aaf4693f64b78e358d636b60147f6f74b6603901d07362efa059e1d0ca102bbd1a425b25c94f93421e3d1ac4e93c6fb2072cbe0fb7ea994bbc3b634705b954e99439a95831974dba17a9fb518f623103f9c0ad9ffc5cac77a11646ebc8a97f9d1a41eda8a3854d0bec6629f44216f635c9fe49c2c4529de954a91122a3e5f5881bb0f35c35636b6978d13399b7e85ef094641234d6c2b77ea253aadca0314198d76fcfff8c6ecca9d13a2e332ca94058c08bc69c43a9ea0b652640fc5821279c051c55cad6213b6fcbcda337b4d465825eb76df193b4ee0a8dc28c9c4f24583623b9668eff82f8694abb18450a84c779fc49d35c7a986037f0614c9fdc674876c5827aba52808146edd18fe7fcde44fd33fc5c98b43abb1bfc38419b0199cad7e86b38627b72c765e9f161ed3f2d1dabcd8bda45e0d726a46442d639ad5448c2625c6ae6dd3c0988bb4bad2c04a9c6906b7d9709fdb4b239de1a046a85598a1112eb2b793eedce05ed6a3cd00d204f3aed92929f6dda104dd0f0f9d9bf46a0ecd0de33b5ba02ed02dd185d9ae952418f454ba69057eb5095bb25552f93534474fd056803bead97f1927188f537478eef34902c86557edf6182f7c6b631bcef64f39d76ba36137e7b8012f651de01786f5a5f4147af0d0e9946f974654d8c703b62d19e17e86851d767777a74b8570f40fe34de2aded044a76d77e23a263d66dca06c2dd968349975a5660be965d4a8e4661e48a6c0537406644ba91babc1ecb65bd5b93ab39850e3ba347b94702640487340afef526e650a9b248b371c41b89622e402315e58217bea2e6e4cd35475b3b8de079172bc2344c2dd7cb0e6587b481e49a6e8553065c042920076959340e9bb69dafc454bc8f1e5e4a36be6daa1a0ffe3aa903b75787ca8018c967458fa1937d798aba2514a1df58a27ada109dbc51e1c6e7c980ed4044c270d4a8bfe5cfc8cb66238847af651796b396642f32fc25bcade8c3db43e270721c647665a30b05a713a94adc76d6293f3e2f3dd7f9be6275fcfd55817de29472c31144d94c354b774acc95de6abd29bf468c7ef8ed2770483d4137ca7b108f364344ff324e4910012f415350a5c33616d739aa8831f8b3723f353834f132e9f337466ae2cf9fb00f92ca3ac3957e51610a35f3a86ae7e2baa13890a6fc2ad03bc9a9fab5f64d5aa9b2a725035c43e2c8c4a5db529fc2f1ba722ec9fd26b2b700a9f2a1eb88fa6de94e018073ed6d6b22ab0cd3454b6f877a4c08e9ca9f726e283b3a68a7d3a85495046f7e49868db4a7abe55298e25b1b15f57539ba09ca3fe83186f0361bbfc23c1e36fa862636c9fd379382074c46020044a2c237d1b049017d095b70b0e8a90c603e24114a9cc02acc9527fd9bf42394767a84126e025a5cc2d2e07926d00df00ac3dfe8b3492d6598b7c2614017223d8ad922ddccc6cc8c3eedbd2f3620216628e02b38f66e926ce6162af24953f41ef74476114f5bc3ad3efa18db0595177a7f6f9c0d12b97c5c12f63836dad79b81304287ae47e716f66e99a1618228c22a9b9d46925b749f679f16a517bc2875d729fe7ce724336029a98027eb6b38a38b5d84c67e478ec35dbdf022f1b98103c1fe90ad1a8c8ad6150e32af6b1a6679c2b3a70e1b3bfa983e9032782723d6f99d90d188c5d88014ce436746376ef691f753e66eff5804153717d05a22a685a70939d5420fdabc6fd2dadc1024d630d35d49a6d43e70881697be35fe9b29cbab54552bf9741ac7348bf7672ab469d74375bba8384417ffda237359ee0b09e1ee1a765859f37f6bce3b8efb4e5288c36cb9d9ee1455d19ac136a9c966b0d4fd7c04a7b232addb568301f1fec3ed579997a8beaec706667f1e14fd9d3306570c386d93b01c8498e020aad0a6afa80a3fdb7378eec0672900a8a197f77a4b2e82d935f7051a4919768fae8c919f620e73e913cb897584aa0862540a8f345473b76bef674ff9787a5eb85a1e4d275dfcf15d5a7c57a5c603fc14992e00f9b0f0b3801bcec7f15f3564184403e1d1171b3875ed3be3ab7cb225ea9a2f7ec57855df8aefb8a629b5cdac6859e0f79fd32746c752e3a4faef377cbcf3bf476be76d8a40eaa11fa0cf5101da453669a2c4ba28ec145819e046233cd1b4c20a324e41d7bb31e427d3b65c4d70b494bd9dd2487e4ba3735c95824103a3549336cfa7539ac284f7fe1254aa6e28e46959d64d5ac963508f1a2eea4a7ef3eab45834ba68096c6361b66ccafce601b2eb3e7196a1dc67249bbc193d77df75fa0cbe9eb3f5844d0ab3647f74e51c19b6fa8a7a788e88c69f2b577cf51e105ef96ac537960fe85a3139d00c901db3c186a2c4344bcd0b8cc8b338346499e23147adeab30a9a0310c05725cd6663917c02b32cc867a8768deea43b2525ac717d4c68901f24a3a4064b41116bff85e23962ff796dced12f30427fc1e89f9554b2877d1b0d86659e460be93b60a8ac6c51ac4651a22853e2bf1ddf55d94fbc470db638781716c50f38ed461e4a97c53a3914564d5aada4a6c3b26f01663854f15a4ebba67fd35977e9ee948944e3a1a2f026ea94e698c373a8a32f28505667afe6617765d240061bebe113fc41b834ca565fec1fe414bfcaa45a00c9fd2284797a73f12b7ba4a624032ad31bff5fabe12505725a4a0776eaac3a4674e913b193d074a024782a28439fca25aed00217f15a4cc435e44edd10b9c48bd25137acf6285fcf89b1ee39f2eef695ae718ec3cf0a9c15cd55fd0d24aed8e8097a3acedf6b752f38343f632a0115ca7ba8facaf70dbd4c7bb5e2b5ed132ddf0a140979230f0a8a819728880db688cb7fcb9e0286d4d437d53baf8872998492d66f5f294743e7fd40896455fe0cb04be0f2d21a7a2747e82fbf35acc01c939a4adbc425f99d7aab372adf24526d9b5e38ba3ad400c53af078b8c7209a11df9d894a703421dd04b69c593841531848d4fd83f15c4621eb38de6fcfaf349d5dab50e818bfb2ab38835cbf42fcd9a136a0652b1b18af03520146991e4c35f13b931a748fead2c28d87c84981ddebe721579c1eaa7505951b66485530bdd83d8221fe51cc201da5b6a146fcff64c27f66ae3d4472a4c5d0d674b1d5d84ad7683ec899e7f82b9e48f9e5900d411e1b291dbc8484bf962987f767c854b6a5992a747d95ab93f3d60adedd2890952f847c4776f32723046bdcc83acf8c39265173250a6cdc9491d325d598672ea4b918145cc790cb6422a6692af704d242e564204f06ba95042c9ffe7d57bb4f9bd422ddaf5ee55f58ff6b90238f510c761b6786d0df97b64375639c9cde8b1d2f2c8dc5cb1e4e3d3998bd6f6687dd150a01733cd16d80589d54c7301bce1bf97388ea14a630f213d476d0b78bed19e8155dc128e1d8143fd8775c83de875855b6df16493ded317cc418271ed0b7bfaef13272dca1c624df8bc1302a11037cbf4a5ea620e63b618c7a3287f902920109b9028d399792765dac4486866ce859cc4103a82ff23ce4f0eb45f8f4205df1d777a10cc7d4c36906d10f0466964be84d0b391762d882c1e66b2b3a747da0e8293548762918adf8e5cd8ada50901719897ed82952ce7978acb1aa5bb8f5bdfe98ead0e1a812447153e72d72e7e55c44234b1c3bb459bd78dbf032f098fc8a2b42237a318d5f903efee54e2a8593492f4ed74cc739c4f5a2085f6ecd024353d9d9b4c83356423b999cceab8b9793634380b32ec66dba3069534d97313bcaf4071d827e36f029e2c3842efe19bb51baea614cb3206ed01443c8c735386529215f77ed097eb26cd1dfd77ce646626a8088eeeadda8e4b3d935b5d9d4ab32238492c668fa4becbfbff7f875f3516ae25da73ea564c64fa4841513bcabeb4535559c7df9362e0d2a499e2848cad1a87614bd5c9a17e3ee5b9ca9c337f31d3de4211dfe981526c2f9bf1165a17cdc3c2919394321b8df64167974240a6de8c8436b523fb7cae5eab6c17d2822a46618baf37263fdf4ad9ac70c80afcceaefbf2086998a59912a2f83caf0642f393f37b4f86a5da4194e48ae74a39312539f7c245dca6abbdccd94508e5e7150ac57c75b5ca6c07dae77698ecd21a88f431b27610257405ab712edbedaff0c8ce72191fb2df5c94622ee8f3202f94e663aadfcf3389c336a905867f66d4c8ec056279dfef274863ac86d80a151a34fd3968af3353ef95cfb64801253126c5e0f7bd4a7885b4c8529b92aaa10f2223cf7964bf5b024f2b5b7a09eb470b75e56b1275cbeee8f14f4ebf7893642cb6561e419662e3c6bf33ccfef363f049bd6d59677351f8363cc25e10991a85ef719cdc6a2f59c8bdb754bba714a7fd6dce4a13b9694eb618d0b25e32327c1344cd878ad62044058aa65ce71095f0f52030a9a1734c4eb7fe5287cf91eb50209b91eb0886eec3379fbb538b5f28ff37bc6186d1d1245cba02765bd8fc299faa46e26b8c5c6082b90e818f9c4c4e69c99dad5f5930ae2435bb32ca20007ce07b16ea1d5342ef910fb0969be8bd98144febfb288c30ea0a7e0c2bfc61eabf39e98e76339addce8fe2438a774cbf3234f17a58937487ca9edbb3c3351ada2d02e7383b3ba550776cdd9140e7347bd973f9ff8b29a4cb7c797d86cd77e47d1a4d21baf8820b1464fd4e644a95781e99f121adedfae4f3084277176807d7586645d2101bfc0ce7c1feb3ab01719848ff81c3798bc1d6abb8fe4998df91ce0257fabda1a78b1600a6dba9f7932325fc9a233c0b6344c2fef5dc84e53d4bbdfae7d8d5048d8884a5b5f0f1d8953b729ddff123e3e8fb9fad7bf5dc4272785745d6db7a1cd3298a876af11d4940debb6bba408e081984412e5dd263a91b1bcc364679ad0a06e1baa813a178f918b5b31ff9113f1dd0a4a36434cb1b38bc6cabf6a89af6d4b551be0df8b6637d3a30a02149ec9c10c0f6c447fea28b9a821b5b53b585943837a028c2a6a7826bb6da35a5f28658765526c6ba5972a5e10225835b514b500f2ef8017b8c66c5b7f2cc1f1212b69ed9e9b92d253d1833554528cee989fecc11be9bdd451db7bf57e354fee6a19ea776163f948d4521fc09a9eae003a321a7a9abaf1aa881ff05f8de53a43aa1e49a07da7afe6d71ce610018a9aa0d2f4d58401463a746fcbeaf0e23e1cc69c1c487f6cc30220ca18a7bf2d12ca6f9916cf276232c64643774589b7d7970677933079db4a9206772e05a1bc1066517571101520a24e536a1b5c1798cd9ffea5c383bc05d7e85ba51898ff3e5646763f7255b9ad8a5717ecf20782eba7352de838cfa9288f071f89c2b37e043f635d0369f2b3becb8e9b95dc181e50f93c4a2fccec0ee46d4f2ba8980bfff4bce340294f0f39f4f6816770598ca33d62b64733edae2d773c4b831e2bf1a1ac0d6a615a4bbbbe04f2b09099ccb08f9ea8c3794fa00492000a90797d442a085b2f56cfec991836cb9a15e60005cdbccc9394e6f94d3928b979a1aad27bd49fd69c5f41c37a34db95e92a74a9e46cae6e935f90bd1902f78af892410768a4e42fadec11aaf253347119e609851aa9efdb99fc4523bf9705e79f5d0ee701dbc07c7ce954d3bec6477cd6cab910f106cca410733021b6248ace50758c0bee231c161f1515fc2e1b14c449984ef03f251e6391d7ae2e202308a85148b789b63043d60b79f37555288f8c12209c681dfd07b349dcae8340aeb639ef065502e643c12143c57ad8c90ddfc23b660fd492b2cc1e69e535261ae07bb36a361a73f6f3da1e94df9d8919ed1c0d208eea699c9549dd8e0f35fc939aab707262bce4377fc8a15bd033ca6e5fd145eb8134d9567adb77d97b364cedb66b0e64b2f205c2ca2c80a4e8fbf98812f59b247d94cd31b9c24001bad7fe6d8ba6b2cdd196bdf1445398a351cba6f6065a1b3f664264b68f16c1a7ada33969a7bc0d0835149669e8bb1371a9f37f9bf140a9be4d70ec957d9c9dd3a43f38e5d30c3349a561ebfe3d1861227cd665cd35dd11f657725435c21c16aa08b3499898a3fa3b16156a11ee28acf3fd8d9bb791a400a3ca2c9bbcdc9943a7e84ea8a4be728050a5a83c234ab1f0e5589fc2237417eb821a888c3530cbd43adcc5c9356a0195d0ba277e07bc961d75c83e878953b93c86e396f674868fa55f112b7a9956cef8740655c267395aefc83f88684231a7bed696d93cd81fe02f2d407543a5bae6598f9b881fc40e4a390587780c640047b9823d78b6589d7ed5c1105d58c0bd689a5b4f6784177665a7973325a11848c7f8e9d3216d131ab3fb8981f223ca6c91a7d761534a3044b59c7192652b5ccb17c4196ce705cf649bc9872f63594768ce592e990f4b7ce02a540918349bbd78062e564b97630d387452a26b6b5e33fa258df5b1d110cab4c5ea70072810a522c266b757e2aefa4f9256855f7dee04329d6ca877d2adeaf8b91acae676a61579fab3fea311b3d4b42c8907540c1d1b91cfc530b425270017a669c24a1624f0d095c4b6d6e7e150599d0ae0984f60131a8de5c7bddae00b67c8602e87419a6b09dcc3a07b10deeb84818e23b8999f55030f89503a08b2a433dc2e7a5e54fe506fac5cebe5ea3a6dc2357afefe26a24de18cf59f11648d67990b2494ddda3a05add023f80c31a8007017e1c2a53752e7df9f553cc67f502bc9bb609dbb5b8649d0e622eee147a60b6fb2eb99008566709ef6ab28899f7580c9cc1afd51aac487ff143778a298fda442bff8877644c4b31de5809631bd16f6ad6b3cbf1aba75812b3007a8346c0ee7a40e7fbb115aee1122cbf08a8e3f5138709a96fdd14d6aa8a0d0707d1aead549f1eb6bbf0b35a7908b28ab0cb49b4cc37c6ea66326de5f130c5e6dfff21e03977aa454609781595c948d0d1f33bbbe3358d365418c6330eceadc0c6fb04a61ada4c717c5d6c4a7b5a1d43dfa18244801091f865be2728e630d903ff06cfbf5e3cf0c9dc6be7493acf50467e12bd330d1700c13e7017cf8b6ab495ce77cfa8ae23f5aec9b5c459dd1a23657d7a461d548f4f200b71a87e29c918634175753cd5c44f5aad3b811bd8243a9974037e49ee8bc5ff7dfe2c1ed05a92b04c74036ce2f5275220d2071c3b66a2e41d141c5632a444f0e4e347630b6060d13fd5db2eeeb2ed5bc22c6a0295aac4ef25a1146a8496c5837d65e5ad60c6a8de831e695e967fdc03f806b15c5af318ceec3703e426c91f662e02d02f045de4732671ec41890de4dd062d2e6f96245bde6471afd1b12640a41d4a8e0361a4a88cb03d8f0c338aa8895685808b0b599b7ee186b2ca0a3e841a5df9557cbd99946317418a6eb25a036f51ecba8a34f347ced12409e85513cde40aa234874c15e17f05b805779c5364e440c9ddf87fd6f082cd4d9a85b2a50ed417f13d0766b9911b9c74b1e2f8c8998cf6367735c28019085dd72e67b8fb7b9bea13a7547b5109e7b81567f83e6b4752bedc7ff4df024b24fa3a3ed4458c5ef14f0f37824dab2f910f004155dca5dae5af4fd6bf4c7a1dc2b36aa2334659854833d0a6ad6827c94518b7fcbc8518f88414b091ccdeef51e6f2dabdad9ac13f0500c73c5d1683ea841ad7e6233d2f33e4560286609212dbe2f492247168a0a1914a385044e23b7271389546433866d72eba6d5047b1152e2ae9b6935a090c6a02c42bd029511c0740704100e28102179c6a69990e472104e6e6c7fc5422a15e703d1143d9012991d5da292b59b30a9726b80b78e36b7fa5d8354495194947c40ee66521ebbe19f96e5c1e0280df72ff9c78a88ed6e8dc8d4cd9cb65faab163a3d18efa396b9d276c3d3a36873cf5ef1b3a6e10bfc609fcf20527b38a949a6907a1e603e0778a1b205876b937d52f60f7c64cd0a209a5077b2d211555e2bbd04066087864727f2e04dc7b4893512b5367193d48765b8059a5d30a0ef70752d0497c0048a00e15486fb8b2d0d7568c7099a47dca594b5dcb242ef7a5be6a73bbda4301b34fb05a540c184b4d0c74a475669ad7c4620952b1ceda24021a5cb6b3f43c054deb24dbd57b59dfb35c8a1c10aaa9f9b76d4852f4ab04812d1b30094baac6d20757ec745d39bebc26d3b5eefac9d7ec64431d7464d962dfb2f19e78917ea4d2b680b98dffc971b100059bed42ef2ff1701ac87346523145d5932fde413da36b23b6bb2c726503babe3e31ea8e4ac46015aa171b29a243f654798ad9ca3363a5e4f31275d77d2f76d0c04577ab8ff2cb557c2252e7f22d842a3a8a4fa8110c5cd78d706bb1b69225bea3ad1874513b3984d8a1a32a1c35c51af5e4b4cbca6e5ee0f5ff3a0ad9c5f4927656a3f24ec0e85c8527c8736e8ddd46e8180018d4e15b52ea1b6b96c6481cdcacd81e6f3675ede98ca6dc9d940679b0ee71bf90cbfec5c59abdb1147c8e05b95f4a1c1b115954842df7e4ac24786a670ac94b18e87b4b055b4e7f8a5885c3bddaced6670b5053373dba7bc44dcef1564b50a249a26605dbacbedb8654bfe0b34fed8c1b534bfa950572f9e839115c3536f917273099b03082cf81e50b461a3a92c89aff5074dc79aed2fdccb21f7bbe317b6c1d44e66252b945f31e19ef40a09e24e6382487d805645b0a582b08ff232712feba10814f749ec02465d0eda8f46eb9baf3b65afd977866c44c7a5006de523a0c0caee7f6990e1e007ee2273f178fdff11851294aac7565d63e11473ab9450184143a0a3c56b5bf1d12d9c31f08faa41e83c4b4853ad32c7fb6a2fbcc9f889682c15b5f7e19d861fc6ecff828abcf8ae1d35caf16ff05edb1919da83893967d632031095ac0177068ef5c4f5f51641ad231379d52e3ed8c13a83a2fde3e657c4f11b92c7ea8c1c0e24d0baf440aa2eeae05b0c0c2e06adce6455dd478897fa4c24ef54be935690b047bb47bff316e4849afe3e4e950ef5eb4e6b48070c3898445b890bf39767b7f799fd1bf4679e758fa9160fb9d526bb04fbf21542b776c6d0c1dec2bda5b5b715923cd8aac46c7b5d34cff27c45da2d6e935064617f1bd1b6ae2f1c61a40cfd41439d0ee671661f32a616abfae017d1f1a664f4f3f3d429256d9e04c6b652f1ee0a8f13884b39ef40fa9ceb195e0286ad9655e6c47b151c897a4cfaf4f2ab1b487ab27a045224944bc236d4aeadd452cb1baadc252eba14d1c42aa87d73dc9873ab40d7c4b2283a6621305cc6ab274ade119cf9e41b96f68e4512599729f2e8d83a177ddf282fef90d0bfa9c6fb70aded615063aa4e3d4d8c7267da235475cee1be2efc5f65d5eb715aa8bacdd874e669b07d3b1a7caf434bfa7ad5bf3cd44c68831c040fb0fdf26b042bc33c0a71a2658ca09ab213bc7720998e8bc9420cb6c81eb287e470544959d74d41c3f871728efe7e54bf0812eb6470d3d94e0d2e4da1d40f29ce73ab0bc5da55e6c59f60ad1d74139e959e74e1b268ddb42e7dd1f5602aeae19267da84fbea5ab956660d6335cbc78d8757d063e6c003d18ab7686a7eafa254575eb5e613357184b6faa0365c2cddc849b762b7ae1aa8669caf80dd061f442708e73c6281d7593dc71059c669493b266b26465b031bfd2ff508fb4bc2b3bfb364a1894e065d71bed9bfd91146dd10d288ebf30b27f19f89ae54aa82ea123d866caebf56206265a462b570c18746632cf2216da91f9fb1f2789e7e0858e9c808ef0282a56aa301d86643d639d67be5afde87bae01b2699ba82314ce126834d416540446983c47f4516a31c0eb70279eb9476fc7a6e3d8e6a97b02ea1119163173ad63e913271b0a6551e82e3de2f31f5ba17c043cc4cd3d6a6db9a3a16a8f0675663357642332b1617316d395cfaf10595580097f5ecf315b08149b51c1f99a215f1b8e2d2755a316face9f2e42927f1775268bbd77128bd0867bbb3e0eec7f03339ec0ae716dcb0f403f83d5d124c9ab3edc7436f08ff7e5472f88484a53df4ffc7952f9f38cf7ce250095adda6039c69284cd4331406982cff58e3b62ec61656bd83c17659212092334831bf3cf27632515dd9e5e8dd056f9732068cf86d387fd8d1eb41fab65c6688ac1b607f04e6026d654b44225285733f2c69f94ee0133165fde7b82eab26eff0e1c60fad3549d31b844635e1f35dc5fd2c522ed3851382a0bac618a8d87dac330cd8b096dc8c5b204692f5c72bf26cabc628935684255482523b8afa24a089c37dc7f0b2152ceeb87bdbab26ab3ccb3127892037cd30bef062bd6adfdd13e0d4a87dcf240a17735d5f24c93eb841917fa14eef05fd8d9b3d3be76a601496728c95d2a97b22db80355bc82635ba448671309740db7dbecfe990fcbc8cc18730cad2d812db375246c2ce74b85ca9c3c6a8713bc46efa7cfd8cb2681ede71ca296293dfb506b530ae876d4967b39338d80e6b8283b1bb93bd9c3694ae04a9c546e2357e80b39ccc0a161098936364ff27af968f78802527560cf7665a36e07230f1893110cc3e210816e88ecc988e449a356d6bdc8a856a10fe599e4dd02c7f67f0d3c9a8ac23e2c417335f816fa70d659330e22bb95e9382e9cf4a9cfb3f1da165b1031b45e49d13934f490b46439bf2fa7ab523a469923ef7b940f238abc4ad796ec2323f83979aa4ad2e80ee7b18d160bea714b257e7dcd04ba17c014a008ce1bf4dde2a572188f188ecd68b2ac5293d39905f5a2a883f9a2663c1821d53a3fc28df4fe7df198da72f5a67f6b2fe192250b4d74f291533dbea47c568542646e0d964ac8988c872c56544a0d8d924a3a18efb4db689f01e868941e819adf8d41e004c56b3d77770a957b011edcca377496ba8c6eaed37a68cf87d11c35cb42c14289480f28a2609979d3745755e90a855bdf20d6b259acb903ba127f1e4f37d65aa3df451ccb3dafb34382a915ad4fa976a742b11b052cc840d79cf4ca9dab84c1cfc0635e6482fa6ef0dea67f655433408e8c89290a83ca338f2dcd693a4e195cfb8f388b40bf0debf78352a04e1c6488a1b6bbd76ec74eb40011a3322450984b74bd4f65798240fa6e6912c0f3013a61f627d1914e068b824aaaa18b53080b36d45fc811b21d2c49369da1a6f8a47f37e258e2aa5ef41e223ccc4fc9d95a07a0edf9c2cd2facb86502c5067dbbd403b18ac1fc28d92d9162fa26f73689600a4c7d9beae90d91707e18c61c2e1863ae3a9de8f0fa0fab91b75c28bd9dcd2fbf932e8b41e9db3856229f167cb12af44bc7a49f55a357bb53e04589e1b64492a8a3dc12ae1522d5d1173f9a48ac3148bf1c6285fa5f3a2cb3ebd85f46cc3ecff0ae15826ae6fa8f839685b85bed5acb64bae304a5c206fcd9ae62a2eb8944b927110d2433e5582b2258f749da02d044c1ef0bd6953f54f73481f26dfa75a699670a07209ff5d8f8642ccac569817c6e1a4f7c16caf80111c5c0827369891074495649db6acb016e875381c9c6716c25212bbc08b1a91cb44f9cbfe502822e2f690f4bb762ad6869468027cd41ff01ef3d0cc160ff5e1148cb681c54f0d009f222d57de5532fe62d0aa8e3ffb54cd38a3a2a541f81388cf4c1d82bafb78c23c547c7ee5000544d147c4279ebd9dc1adfe15e41a6136bab37434ece711adc52b5975bed84731170cb839728ca5d799f8bf83740d0f5d00ef4cbd05ae7d013100575b22bf31cfb118550dac6cc14b496297b49645103a5fa8333eafab12b07f22115fc31a854fb05cf08a40879711b1d2d80a2f55802d2c865032d383240c07b3cabac611fb7a8864047f0538ee7991fc4a6a68a354bb0f4948727ec4a84ff348e135972be73e5b85940f08c83b3305b8754cfd901ffd5834cd8e868e3a3f9e97bb0e42fdb8d5cb51ce2061efbfc4c9f5dd154d1e4331cf8150edfc833f8f930c1774d72a552e53bf86176d479dfe54127a4642897bd6f241e3e6a83d5b810a312bbc3bf408ce2e4be5610a7949be5ca74243296da51c2ae91491cc8e1ed0e140fe4d6e27cccfdc9c887633bf148b7114ee967a78fc49746ce2e79346f2c427867bbf078840f10904a1b12369af28e0e04d8c43d99ea4f8fc8dd68d062b74bf8c06b5e420667b0e52147586b3f2e6df01aa3d96aff6a8ec0cad263feb179174c0a65a1fd0d1911eaa28469bac594e6b71736d3790b84b4d70933877bf364426cabc1aa262344302a07a21daa678b9009286143bc657f07afecc701aceb406ffbb0e67e606340880e69bec0f7ebeb0da57b2f665f257247b762100aca6eb397725e3325ef65bc7315e260d9217349696210279aaa6e134817024888670330422d6e87c0375294f4535f8c478363a79e33df7ddbcf05ec3ca4c8ae07b953e250b7e16230abcaa38095e88a634637a4830603b8823408812d8f2a6ee61e54a3c8edc32507fe3666513c12e55493487c2e5c660b568cad1dbd9cc1d0d9aed41362449e977d6d95a9aef72fab9af5fc3a29df6570eba52153463e3fd8f1a069d638bd3a6b4b17c3616d2d3892718eb99a8a0afc5c3fad0103d6d108733766de117c5467a0c141a4a825961242479c07135b1c04b7e1aa327241f9c90d70cae9a5f463e7fe07fda63d98f583098d6c1e5cbeb4b63e4024d4fa39862b6adfd2568d35a0ee06c0eda48b1880a64a08db006491ffbabfe505c063fcc439cafde1c777a296a5c869a11b2d7cbfdd1a15fca181f5d9639a2f12ac0847b93fc4f9adee37feeb97b4138c0f3b9fcf948ad62cbb08a8ce087087644ae000d4a281c4a2bc2b970c9686871639e87420f1623ab747144f30d065da3ed500556c8a07ad749f5fbbe914a52707af7677d3c70f7d6fa6ebcb341ee38f0cf4fa59c6d130fd8f44240391246f348cdab7caa2f4e4b9a59aea87b7c8877c5578c28baa07c950d348d876067ebd7948de39a9e291d0ae0d04b315caff7dbdbbe700249e8a4c5cb7a787ec8df99356ceae91f883a5138fb90cdb568b0117d901b48e01515e408111979b47acc39291ca081871c1df28d7e561a572dd54e0eb214ec1bfdfe42e5d200a4ac5d1f5471c181dab3280e3b8e26fa9b540c766570e3c2ce16f1dd23fd49c700a53954d1ecc63567960048c74ff64a224c8de4330ed339f84f84a8b62ba0d14ceed279eb88ed4dae9750fd47be79832ed2045f12446cff8b022a8738eec4f31724cb1453878b13286b0f89f60405df32b4c95b291ed9f96e4f0b26091683a56b2327ded2302d14ebf9e7459c5d614da3e1dc84238bc90e96e0a7073c404fab0946c5ecc261facd64d607ac865cbfd65a2946f11d0286556f7790955be4f3e5084adcaa7db9d45f0cd8975268efae1f291034d9ac468488b14966b7dcb8bec2c74607b2e2144d3af65f7f8368957269b755dec3b72af0d2c6ab31adef022191c110c4470c4ba208dd69d6d9877a74c3134c12f17c82723078e36fa23431bf2879e529719a785669cc167019f6f991edf08a502b95c71920a2054ae7f166c23d8f16f7236b1dd658df36e7dd411d7e7d0cf990ea4388d31591a80bef218f2249abebaa7eb57b4d3c245855ddd9cd2a18767486701afb6121ecd13ae92bcd9f27259647d37f6b55efff87724ad519eafdd58190bdce7cb7839649060cb11c0f570a501ace7799420bd69373932be10b47f6de75fa11293f0620624170158c966cd0c9427f93137e892d08b64015ace278d64263a4301cfacf8fec94b6e5bdb60c4731bb8e54d8fcc85e6880fc8d711a3fa95d0687c6f07d0bba79984e837e2f507fb3efb0928e5145c335de72c91263f18f0580564f956ea97a33ade612be730890b77a6d43017b0385770507c477fc29fc4a67c58a304360868e99094b8e13880e2b4128ceabc62fcba4ebbd2766ba86e17f860e11637a853cc67af760106ccb54e8108e8389e39b905b3247257814138e17af587f938bf73d7109374a3255e83d7a173c92b1a68dd79a5cdd2a535703c073a4f8b8844007140d499ebc0f037e2221ee0ef51226d8465f4268f7d10797cd1896010163ce4ffe2dc40b9a3d2c7ae386f30639420bce387b2544bae609917fc93670f5cec041bc0f6b2b9a38918871564afc64ccdd2d35b582993e50928f3abfb4d4321f791feceeb45d6bb87e25baf2827ec6479a668a0764bd6f611f5f42d1b291e9671fdc377be9e9bcf3e43c8e54272b4453c3e9968a9aab6ee20bbfd182f7c3c79f42b1e1ba55e452563cb19664e332fc9bb156642ba02ef47d169e492fceb23ff5d518c79b316352243a3ce492e8bfa0b0db78656e59d4832e5408cff2846f753c986a8550a8cf299d7a683455fa9d456d9584c96b9665582d9d7f549f9241f1cf5c127ddedd09486f0cc5f77d28f5212f8fd946247e6b901aa07e2e6c32180a522daabaf9bf21baed53a8c67811db23e042b0e6b816dc9c9547d339d26e2d03c87c169ffa3aa4e252610744eb26edaf6bec781334b26fb659bd9279babdf3c8d6fbf9741b1269933b30583d6fa760e0072c09d6457546d1b526ae6baac3e1cd3e2fff54f981ef308bf04d23abd086539bfee656d3b32ac692af30ce952b668c40a61c176230f8b081092b7b9ccd5f23fefe221e91098a38f88b5d073b58d09d7dbbedcc0d3394d3b311659d07b0f75282fb5e7aca51364a1143edd73351fa1a58c83e6cdb255f7e8b100fa28cf5d7728ce5717f041223e4b91bd8c397e8b175ad8ba7f123e2aa006f64f9588f931fcbc00556a1bf65f37f5e6df7d1a6b1051ee73ebd58e2f6e2d74270da224e98cd249b9a5976282323a8c559af28b6a2ed6ccf8099b937516a90988db20d5536e71a75d93193a1979abc58cd208aaa9cda9ccda103171fa2d7a6c99144492d2a9bf98aff53d1340ffb1beb0459bdf3f3dace3b5cc4842c26186fa8aba0ee87afce9c20b94ecce27a8c81c80095e81dd2d6ac715d448f9ce5498103b107b8ce172f1f77834265cb4721b2d0261971b1fb8520744132630b4319b0c1aadd3c7c84d21f0c238f290cd347c7d393ef37d18987d92c5bf3379a5467b8a2fe39f56b9c9db98db4338b2df7ad492ca98bf4fb360dd6dc5fce34d8bc4e52c263b5211e7ff70c36c4494046420452098e33997c80d3af8c71f6da5512ecb71142d6782d6bb069680b8944f5c95320e781e63ff01c829a9796baf94a006cbad6fd78ba67ab6d72dba2caf649f8190ae6fc0ee70aaf271021098c0dc8d3919b7a08574dd10613ce588d0ae558a43af9b5f1c7154d4c082b18e57db10c694fc4a4a4033e00b4b1714cff86656ee32d8826eb3d803df6a7205a11c36fc1d370ecedef91f51e284b03dbdaf9d11576f9bacc037fc507d2af6b0910c16577e850eb9c3882dba69891675cbce3f5a99516d50b097b59cae76f470237c04b0ff4c55efb22bb2354e863c16267197fd9f1fab2932cb4ec9f88ad9e0834538f47d0bdb507e3fe9a55792ead9a8b66ca483fdd04b96ffd3c429f2a3d0ece89700bb16c88e4550f080cc32b8c7c4377cbcd0f2fb8b40bc5afdc96ad4fc1442657bf93e676bb916e11fdf70eff348f2fc3527ed01f9c6acf26ce4b417e422d5d6644f3dfde437ff79eda13a2d0df69bfa87385ba506fa",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x08a612927e5ee92d00d7f53aefcefd6a0ed2a0a98599f0f565093a1c19d20664",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x4bf6f91d84b37454544279cba152581ed6820044",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374f70",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x3f97707f744262d570f3573a54060d182847ce538a7cb4c71a393b7bd36b1f0c",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xab5cb432cb20279223e98ddc33d45b2f1418b4c768c9ce212b4818ff65740692",
|
|
+ "timestamp": "0x6ab8f249",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-anchor-20402032-baza",
|
|
+ "sursa": "2800-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa0626573752032362e342e302d616572652e312d643230333230312d7774613037f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b841d24cef8fb7391042174600a6f051c715ecf3b07bd565d134c43e04e3069f57e340af8b4916177a2bbd2d8251613d7250de9581099162014a55448bc612e178da01b841d0096071019f8b626f4d5a45cf56e6482aadfd518b8b2244480a04cd4913187d62a7a8e8ab2e114f610ba1e2d060d667895308904e5195e3c1f9f5a9002949ff00b841c82ab01f09789732e210aab870d331bf16f80bf8e3804bde137f5fb3dccbac09543237ce6fbca354b63a5900cd2d27e56bbbc498e577b34d51bbeaea5ed2ea6b00b8418a28e166068660b2f49a824aa0d70f7d2e29f5ed6309eee9fddfa3cbd84f0fb06f2e8d05c1c6d6faf7ea41005822f409da9572f3a2bad846bccea9abbe300e2600b841cf11d0ba98ea795b72f427df46138bc938611fe5c20de9cd872b020015f64f282fa22d8d89b5e0664b847a6df23dd3fb00e89f18f531561969d7591622f74fc100b8419a22b8a234929915ae2f4324e5d6408f28bbf9ce2d398e9e8b1eb63c46b29e570edc23c4069dd195135522cb4b467e11b94dc2c4417b738303aca1773e79db6a00b841afb9a4523e31af79faaed9a3d25e17e17969e34c1ba402db1917fd0491985b234ab48c34d7813cf31c196a03fe786d9abf3df673eeb5b5b80aacbe73f9feda0300",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x57ca",
|
|
+ "hash": "0x8da07f49bf3349a500a69f379aad574967490266e314ac8a5c49e2155aa69270",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000002000000000000008000000000000400000000000000000000000000000000000000000000000000000002000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000",
|
|
+ "miner": "0xe13aa491abbc1252dd714e7ca0e55717a2143eaf",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374fef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xd04dd232eb1f1d969f0191fde6f420a1fb3b9d52ac8e2b32d2783db1ed7bedec",
|
|
+ "receiptsRoot": "0xce0fa3eb969ed8f3897c347d3c2e025343a5853ffca49d7214cfe0287451fcba",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x32dd24cf9b39d30ab8d0863238a6f959aaf3244a3abe0b5b6ef2287592f10493",
|
|
+ "timestamp": "0x6ab8f293",
|
|
+ "transactionsRoot": "0x5f313fe612886d01b89305f4d584b4c8a04ed82f124192a58a55dbe0c59df433",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa010d4ba044446172e6ae3e2f394523e5c060065ba171a281351e5361f661c0670617a773f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b84143fd6cc790bc799e0566769fdf938e2d04c7a29b16ad3b0f176062dfb4a7d2fa001c20498cdff5c01a24629f80550af8a0e518e321d3e4aeb65a8e84e6de500601b8418869e90075ed04728feacf7c3ecfc5b09c5a67b103d49411c4e8e292a14a913320ea923372ba34eced19951f2b876f86c3ed8b39d068812c4a3a81a233d0378100b8411030c1dbc952760a731adcf1ae47bcff90dc64bbfba19fef2910dfb4f76e3a7f0dad6b70704d5874c42428504259ebf78cda298df469317558a5ba533847714201b841982ff3d28c6be1c6d7365dea0e0d722e166b9187232d685a53505af6d96ad5df41156341007908855df1eefba92287397a56bd4b1ca82a44a3a982868c989aa600b841e7d84df82e29062f9b5f5983bad326eed5ad6a59be67c76bbdef22d512ae96595e0296723739c87dc45af068387b9b4447f9d0b5511375032314c31db80b4d7e00b841c24a38633f55a7321f02515eefe0bdc62052f0fa9b6bb1558bf0719124c06a9d66511ca491711cf3c1fb14d1b1bd50f63ea0054ee1e08748af1dbeaeedf193bd01b84162b10822a281374113e46b04946b0d818967b5aea5e110c950d5fe8037bab54b6f5513e0841c2512aa7452601367f1dfa39577902aa64c19145d1242db397fd900fa010a7802fa010a73f902930101b9028e39e7312753082fac9daa82782563e9232f75ab7170b9aed2ac98645dc0f837a9e855db79cf1d8890be9dcae3a039a6792646d4cd7db647da40b09dda9ec495364f9a7937ab24ca1b74c6defd920d8c62f927de27ca9f83858c4e336c9f364f00ee67eb0bff0a391b7d59f7a502e0cccf7e059ab795aa178b0674ef0a8a23945cf431846a84ad296ea2526833cde2b3a058198a6b1c79ba0625d8522bce250fab916686ffcbfd38fafa7bcd20c41aadb4b6bfdb6a131b1ee5486a6c9ff9038e53f0e2098371d02348d69d5d1a7728720ec58accf3d1926cee179896a76986df81cecdb487af1ba1cf531e445f47eac77620b1c5c95ad1669f4c0b42adec5016be047e5b3f0e59ad66db1f7e39e58d944fe4fe1269096b61c69299f64aaad738cff7ac5bec935973215d9defd5e58add10845b220bd71a350736f60e77f644c49d1e8177d59f735a78e7e933da71c8191191ab7b754e093ad29416df36aa302a3346b3ac73f8c5ac99a33da7131326e6c4ca84aa9999a46720967d9c72d851e4749e134e49ac5a75a9824950d61e1d7acf53b5c6d253d42b9acbdc00973215270b8262967d29e287f3e674e276469d48cb7718b3c2773a38a2a7cc556e2610f04edc2953c5e6c6d0f794f419c195f17007a34d5e290bec9962b1aab4b399abe14ffbe92118c31f3f3434f5645855c6a1bfa3a4f2c6a5aebbe55764a6514a99c03491922e84200d521f8668b0512c64f1606e0f8ede98c29c082f1cdd22882317babbff3a0ec70a2cf2bf97b3a0a35ed997e11ee0f75d421498f8da48d2ea8c323899c7b0bc87e7aeb077c84bc969cac1f46cd7b59979282b76563fa77ef5894cf6bbe7ca261daf433dccea7b6e6f741a102eb40c3dfa0eb67559688c11c042a1874378924eb9bd4814ce5c47935632f91eb50201b91eb0e483c200396bd2599fb7097e3673c0c1e1cda0581849aa240493eab0cfa38df68e9b1937013a0ff92e67d5a7425ac973f72008ea3c9555527e62213d4b3514333ea29b23f1f5d2921ef97fd878fbf2a8de01f521d7ac9ef45c77372907cf275228850ba7d5b03a95f3ce0fb28bb9f16098c323c623c2905eff56e7e09b8c0f92ff70fa6a7bf47d639e9d1e46fd04534d07a6bedd3c612fecc9d70fdcdefb0c31ca78e46f0709509e5006cdba5bf59b92361b8b6ba7a74c1bb4a81959d28e104044417d0f90446a436340cc653e0ad5123ca5fb9c49ee4225ca6b076e98f5fc254bf7928467ed5a32f7ea8ab737a27daeb20edd7bcc7c79f72a658e73b37b6db22c6ac5d6484dbb4008f5d4c598f5fd359976cf556ddf23860d41c100c0c0a8e0a77f0f6b8925688658204e3867175ad98cf91630a589c793cb1e260f648bda46846ccc05ad1f98f4f5668d9915ea4198a4398eeb0f91c614c3a606a3462e87bae460773973e6f230c24cf2c5c77eace722d555782b0ae66a589ffa85785a42b58f6827792cca5a4804a7d9d433e58659dfd79f627f007358eeafa514e92eeae67f64e297c23e4209746e8a63bdd9604ace5adcc5df2daa5e60b9a2f095dbf5970cc06da384f32e367cc7cba18ec5a4b33c0958c59488a81a6fd0bbaef7194d7f5194579c09d83837dbd8a6334e41821ac021fcbf3f42c2c46d6df814499f1df63f684999b8f11fdc3475c5822699addb4138b0383a7369ea540cf265ef48dcf8288c70f38bf15e9b38c3aed49fedef5446c76be7db4a66b0a96936798a7b106c8b1a4df1ed1270da70259ca075ed280c07faac227d58fd8f9c2c663209ef3fc42a020bc471ac8ef96279786ef1eb373920df638de9cdf331f7a70180ec64b247655e1daef6b7ecdaaf441da3ee54a0033af8197550546ae27b6d03d26e6c00efe9ce5fdda0a9d87530deab07c66166eae481616d4d150e960265be9d3d2264f0eb83e84e54413de2a03f91b05511882bb177b9940d0924f4fc043310f7a4403d78d398f7278ef9c26ac10b77ed505a64ed4f49fdc1d6f4e7c1cb449c8ae03c6f0be409c3b2ba08d6c0ade0c42000ed41f3b1b88fe401fb2b4e7180bb576c0cc98ccfb537e2da35e762b07c39f1b1d775ffaf02e10f79fd20c76660adfd1debd54fabf7510db270abae109228fe348dca74879329f2ea13ab45416ab8f2211202c8982ae7f9d52dd89fcf38a4129923ce5867652df0ec39e6fbafde770dbc2fe200a8886b1858da7da7333d9f5aac7253620bd69a3996d6cf68ad655bc77160d8e706c1cdb8e7c56ceebb9d62a3426c0a97ac1f611106864b73aae8f39b8defd844d928889170b66ddb468c52f5e18b4b81e35ab2a9c932918a8fc811004683372c622c41eefb4e412ca18ded2c190051250c9d6d7fae473f5e334148828c704784e20ad933a83f2b30ebf2e03766dea07a3ca302a409a38a63b0c8e726b63bf3c2f3dd2a12caae2bb4172ab04627460165b9146f030c39bc2bb05aa8d040b01a3c4d3b9de45ffab62afaa6c461a130979317b64e02d9ba5d4eecfb36979e947090370af94fc8796c60aa8412eb8d849ddc83aefcaf96d0e2f1d879093ddda604aab0eee41014de8c17c9b7cf80505b6cce8a46bdf650c1c3d4c8d53ebf14d4d48bbd6a5fddf588f158b10b0f2c7a4f5f81fc9d19ee1bb4ef64ed945cb06585cbcf6e391cc5854d7c93cc6f3268626313f4534b8db42e35f789b1cea03a4478c0eb95913c9db9a75a6d9a0c1071a31398c15d07d61adf3b744169b2031f1fc519853bf1622d31648d9bcee959114b0937c6437e997eb11c30aff98eacaedffc2eb8f07fad1354da4fed54b7abf9f64baf9d03e4d8266a09488ba52fd4db3dac51c2d53389dcff1b73e8f404d5bc3c4dcb6e28a76ffcb5e6f239df226bed45dc6fae89026d8edd5ce91bbed69d1c2095c7cdfd7a0102737a6b7a3180dd03f0f02a6905e7bb895a2e29f4b9f1dad3627b8d06574a1d778bd6d11c2091c27e9620036ccbf42de82dfcc78c6cbc70f7bdd3a229f716a7fe444b5a0479a2bedb58457e89d68b148159bdeeeda3a0a92bac92ecec18034bde591b4197f03e2e48bb046d7c8a0b843c6671f3cc312881c20d126583e4c100193597e3cf657a7b2154298a62eeeb41a236380ccbb8586a55e152f80040c7dc9303cc725ee2499f960cc2bc47964ce722628010b762d569d5bc520b4cf2a62a098ea197c12fd2c52f99e994ed38683b0f09777315eb53e50214dd289eda18f9f2490178c22e38094d9e4f1b41d0ef29b81cb655dd7c8d159a5cf79286daf80550c6d668bd9bf383481d1b8bacf763a57694aa41ed7c954810b330608cba6dc33656186ce6e844f8d763b97c764adbfd2f5a014117e3cb08c96c8e0a96b93691dcfc8cbed8f06eb39cf6771e6cff373ed60a0c8c585c773363baaa649af7d26bda742c2f879e9bd036d83376d7b63dfaa13d12f59a75ff53b25267d223db6fa434caa0dffe7deed8aa08da5e70f134fc36318ec840202f609d010dc1632ad0a6b1df2fceac5f59acc8363d3c6b8de3a20ed0c6ce696b7a2154fc997faf35e09654423c544d7a52e27fafbd6e3575b52d0fceb7c7ac8a6a1e0dca4e732848846821e7c733b66a87cafc871d3b4de278f13037c0e0b44b55e3b5e87bff517695426b66566da4967dc14837662f0eb2aad2709b240ed2a1e2cca124a1132a0f2bd116936c82ec90a401394224526e45a2ef99b323d788835d402ad8f6d0d556bd288c1a06c66e3a75f93888f415d1c3b44eb1f8b09abaab97cb0109f087c5af2c4d3106eb6f1bcc7ca11442e4e30c2071e4d67b5d5f4ecd41444c6a89c37ec6804e6135e473aea85642e17b1c07cd79e35aaafa4254e1c12035b36186c7dffa8dacb8ce1754a1cbf50277c066c823e3a3279d1ed2edc96a45099bf63ee9681f124790b66f60239499552decbed7e59325b30781a6a82d6a030287aa5a5f528746c7bc5002ed4d79eec72d05d5c544d18af5330cdc3f6581def28c79ef5b48ad9704037baeffcd27ffea73178b011df204f331b26324b343a2a38a5197ac37bb2c37bd68636a3bfa135dbaaf812e7d15ea4e377833cdb0fc853c29101f496f1d10c9872c25db6837c64fd130afab8d7235944548e174405d53b97b6afd88cc1905cc955d2f17b7bb81e5106a5637197d52e0d64ef68b1c4c9493f8e1213297cc41567298e496272761938647883345f6d57dc8afacdc8030748f0236ca9a360b800192f540a22dff821f6519f404ea220cfee166d6d0ee9af2d6908ca30268ffb410f05d9229604884349a17acf36868b7c22db945fceae411f7c4844eec9624c86d4e83f301eac6e4318f9f026365d2f85238fb9fd0e76685c697397473f51a5eae29cacac3e0d126809dd404c8206384be395297c4ebc3528d3873295784e029e9ba0aa95a55492b5cf596e680443aebd4169143e5e4cf77b1582128d29492317ef18c2299171560b38eb02623b50a9838b95c049aac26a60d48a985dc09e726f994b9a4dffc5934ad075628bb65127d9c62656114e6d050802a68164fd114f7200130e2a3b6bb5de52a253ce8b036862d41e78795ede00fa32961b2214095965488da36072e46f4e17fcee2684cedc3da79106e83d4e85ad3d3de2f215bdbaaedd971f2e7aa453c610ae7f91529e51c6346d2c9e93e029d528e404afa093938c08ffa653f2268165f85ce16fcd6352ac43a28d11170d4c210d70cdcbd3b4bc53abc84040c9b0e1337a3a322327e5acf735efe8e498fb1dd7be9a9ce26c2663ef3eff74b9ecfab13684040414fa70a18b010d3b456195bb1b46b98de711f1fa5c4fe61a72b4f49843f0de944c82060274a3cc709cfea61f5ceb39d7a86e58c76113e02d54d6c079aeb659d0f0604e395b0b7da796d3211ffae8727951b883928c4c723374dc90e3120ccdc19e1a8546617ce9562a62da46a3b4273ec7eb511676cc5c2cafd0bc36130dd9de483fc9cfac2f698696f6d4f7cf03f02159ea6bbc68e60d5ede6584f12cfd2f3c97eb3288f59e9153c8ba66a1e44df8e41dbcf7bf5776b21c6b386acc04866b4daa06b0d84968375a6d913554dcaf98372cc878de0154aaf459b8555ba730654892f128d55b865547df0d3462667be9c335b12c372d282b3a1753a287e7bfc71c8c95d3ed5f48720e36b0a46f0bf51d8deaa8fe46a129636a92d0cc5e003bd290defac321686876bec99ec1a67fa2bb30765029d41e75909cbf5fe68fce8e73cec6bc853924ce507d4285bfa72c9d7daddb8fb9f225953fecb9fcc82325ec4a1ef5bf67b8387e01fdc065418054606f3f0fa45f3f8aa56019e0d733b4440bfdbac7e2f75ed89e68712d1bbc88dccb092357476bf30a353c123383a4d9def1378f303f18ea6e05e6fffeab5e558754b700863f2017bff9bb3cc995ebcf88442f21bd4e030205ae6025c48a47703a73bc3d70567d988e39895fc7c8fc55f2b69f28a136d77df0d2c2264f5c517513c3b45719d08e1edaef9901b6fe1bbab722aabdee60a0f008a27a9db16c5371c91218808c0546d9cc77adbc33368d75e1eafd0719a4b2147374ddee62ef5a682304d197e7c9173089ca389738ef554c032c65a99662cc707febb038a0728262656a09b60f3e07d8b6231866c4b735433379511c0bf0446c4863fdc453cd537871cfee416888b8027d7dbbf8e8f5972aea61e3d41bd4a2f6f7fae7271308b1bcb1a761a44d6ac782ed1d9a805b044fda914dc7430adc99b740bcaa6ac9a7da0f4cf577ec67836db875ab0c7e82abf956aa4ebc42f149c7c2485213c9efbae8b4def9ccbd4d06b4b30798a48c58860ed27fab3d05467f53aae33e50d361083296fec5be4f266a96969b80647e171140a2d9ead46ed05c8b3ef322fe8f5aaf187150a1d8f0cf367e1e83dfef6af73636b0b2a144ce37a070b2c74badd725062ae3be251a3aa08f1bfd56ca822aaf1e508d9cbbf5543cf0e9d234012a2612f36d445f855270d6f37bd7241669fd7c192dbbdc9f99b852e0c51f930be96f02222ee42b853f9eeec129eb67bb474cde364c53c8baf987f9a2d99a73f3f158e637a2f44f9a608967483ef0bc48d85a9a141a9802d5636ca60ae7acc1fee125f331edb92573b02450056466ae50a711ace0fbf4fabc3bc3adf5bf6b19c8d1779a048a0216b272d01af232325342f3d289b47f2b0de69066ca7552db2bc61aae9bd134758eea17fa79dfb9cbcab892dc8091f60f3448982e87563b0c56845a125ca90e892cf0a55e02d87688deb60302b1115f5b4c9b5c10043654c97b98758bee5208c5f8b6d2557f6e78d0f0f07f0d4c72bcc7762e7cf3fcb2b4b35611151dae080f94f9da535f80d4e2f6bb09e95772e2a1ee8b2da31222948cd923241d0e6e2818ea69965abb02b99c2ef4cd151864715f49665166df17797e90c3417ab5fac1675a18c61e1bb8611a54d167daf6b285b047234a75353a127f42145037bde82801f74600ce7b5b0f18fc8e5ae30550a9a7736b55a0c1eddccb51d85645214078d6789fe50998aef80eae0287988ee782553a4ab4e1f579210df05e82aa26415f3ee02222daaadf579ccd00b0fc6ab56650bc265d6258d927930d32e0ea447f5fbc87489357ac7d1eb32e0bf9684dfeed5c6ea5d9a89b95ad76146dc35922fe2137f521d0ad89f5c2626dd6c097ff32ed3e4865c3ba80d7738e10dea873846c02f4f86a9794264d61aeccf7d7f507cd614caf904c3f714a550a4e43aedc8c81a826747de19e7d43dad023fd8e1c4366504ce99920031d44e5a018c0da55458c114281b29409daef30c327c391c6c8420eb2e227c525beac1e342469bb54451acfa3e13736adf60ef8a12ad9e2d9836ba3e2d6bddbe6b5317d77ec7053762b0da39289f89c506c9d0813d34d43d8b203d04bd029ce78cdaab360b1423e7c2b3036280121d7d5067da025bd15f8c93f83d148d51b842fa802951fdefb105374858e068a949b0f6090397b40f9c0314f8eb512a377dec8c4a84f8cba1423a8015066cc646283d57d26e09dbd1318da40edc1e0f91efde4665d747d60910b73d238d449e7f47e0a525ade42c5b88791ab63060927398fa9ab4272620f9d64d695c387f5401e14c6894537d17873dbb44a66ed30436a49f053e24c331f1c2674d953e15ab0fbb47b33ae472336e77b05c33b86de3a141b677f5f2be4cfdb618d61b9706bbfc5d3ddf1b5c95ef4520147540582fbca8d586a8f990dffb3b4e76be82813be362290f3447274adb1068a585299645c895c43a45eb0c32c34da62ea1fa38b66a78f0158bdcf3fa5031170bf922bd2c1de96961d73fb4076ded584ceae191503f38616d546db92a46b9971b2f783454a4bfbf7f48dc8356f8fa99dbfeb68e0db426307a920d4dd64d3662fb5ceb1596fdbef9fecf5254eb3149775f9f7e2b63f1e318225b7ede70571a17f23a8ba7a2c8b08dc062fc0a759aee54fbb74181ed1b39d7a4d947aaa2987723c6a2423c8cd5fc6cf23bfea0b67a4ff64b41b874ed4d1193a0e2f54236e87f90f05cf0cb9696ce0ec1e5e8c20d37aff266df7a2f013829b4bbe36a3967bebf3c5f8ce61dd10bf9d3ed04b8a211e9d783d28582fccd982d896a8da099a425d42030519d2dfd7cb0c140f7cc1b092f510d7dffdcc264bc4e0b4663cb7d58fdf2a87c1e530d77f6021ded1c4757c87ff5000527c942ef278d525f3924ed2c34d7c90a3a9469b8ed3a683f146079e7af127990db37eaac32c81a1b104a7ba0ae8d9983ca1315fabf3a7d4a05f3e5200f80eaf6b1e6c7ad072712a638bf9063aa1cff5e4a59f28fc5a95be4b8fef650a961882c1c310ea7043a971f652665ef99af45f84a2edbdd90e90d1325ebacf89cc3fdcc8c3307e6874c2e1213bd35fa85c643469695523051e175b702d7424cc2fd892f8ade60c97c03974b6e1d75bf1a93e1ab99667066b02b4f941cae0520f24cfbfe911b50fb83b8a005cb0ceb3b03f820a36a90e34553ac1f936c7d4da7e118844e1b06876a8df0815fe8372ec5de0a60d8985f680207ec1066e80b0428650c37e347f695529fc15a0d1e47286e1d7bf88352aa91ee463b9914e2bf59a85a8b280c374607088f88421752461b78ef3123f5c209f10ad002b8717da8d241e6a5bb7c03c836c360ae4708297dcb68c5c76262f1e6db5473b19e2db4bafe179079ab5252b4c64122d96c3b32bc30d368a41ff318712e11cc4e9a314f12b3f69fc2a0bb16deb3357f0cc10da310397dfe4284bbf987b3262bc7a5a0eeb29600e9a8fe113ae6144e7212de5322fa7fbae875cdda674106a55d8506e79932df0b2f8e50372fcd5f01b0cd228b454a231042ebe09e9150e49640de54a84b2f18d973bbc0ef10dbc355f0a2e0a192a2878c9c2333c1f3bb20a3ce4e07331d04de18053f5b23189420fd27d0ccd32d88dd74dbf244e2e59c6b360ec330d5508befcd3fb902058fc35bee7b940614d2905f5f076f6e453fd2e889dc4c817e070a355882ff216c7c41e4f9dada6565e0f2dd1802ac2cb219d288d43de8946d43735d5eadf2163086d62376e96f9c9d1399ddbb5c12f7fb9413100855f622683d65572e2329abac3e92921d2ccf568ca6647bdc05ba514375d8f4df44a5f1599631409cb599478e373700a79f771f723cf02b2325af98628a6f25831cababe8af2739fd3852248a7da5f5ed98bcf6c40c26d316d43968d6c9c9b7d9c7644b78fb60d658bb8119561cd447dff8c0612f62c26f597481806c9ad3a3d84aec73ea32add51f52297a16071039985daa4d539a9ab48d062721872a9b7b2ab5f5acf3b4e3705f662f694de2e685876709e6cfeb8f06d0a43c15779b851f293bbf00d35bf976197f6ae1a68a7f93f69d660e9f20fbea40d63d8de66854ec56cf72e1d1e1ba3dd5885bcd9acda8a89293a1605e5cd416fff95c77e22a427502a9fcbfdb94a94b3e2f5223a4fb739f4d849d69e4b8e70dc23dbd4bea7238d0e78116d6adfc53b9c6b7025c70d312e0f54ec581dc8b162cd30676da5ccbba9d6dcbe36bef575818fd2c27b3a088e52da85dbe4646412f63f99bea4c261f6eb6c1dd3a864ec335cd490854912f481b8375f2397d2d64ba2f1e5d6569bdef512f0243e98ced872595927208c47c74daa65f5ee0cd6b66658591f8c446789c86b872ecd34f66e78cee155ce7313e09bff9566999f3abaf3f1a47beed6bc8394d036ecabf2808af7305ed6b565d14a28e4500adcf2b2417aa2427b11eb8412e800df310f1062e0a68899abb2fccff604baefee77c5123efbfd65e24dd8b8e6e2706040b70ba44d3e09140ca3c5549d7be53e6fe76ab5d985bb84804e2cd393109dc3244388b885c463fc22caba109b713548e376001248c4299e28393b578c9cacabe5b143b231af2be14ea68157c17a175ed5b28846bb4c2a20a067d44db6694d50a82c0583778e93fc7cfca2f3aa72a591f4870034c67de2b4d2bd45c1da6f94158f39a70cd80cfb8e7d453d74cff35868a661243322ebee9c643fca93db03cde40e4023d7fd61c517c6190eba671c07cb948c3532f8baef9eb0eaaf960b443a69b32519c583fe12ac352af8b4adb313652b7ab4db7a1f6334961e6b7105b9c335800feec61c61278139fe08d028f6dd6259b7d026deaf1434a0591a43a4d218c432342a6b6557c369005af3a4ead0646be506febb8a7d0a58ed6a90f9d9b98e37250c16966613885cfc6a71ecd2072d5e9249ce09c8461f18cc3626ba1aecce33c45da2e45df7ec0e7fda765c82c85a6f1326d3e18b0444a752506f1846957750823e3944a7a5e5b2eda94c77a7182371ababb5be5036fb27db2e8de0284f25350c97cc3d43c1944f80f60599bd4064550c943690b6210fc211b8a678b019b752f196f0a76bc4ab1fea2041063c71a8910a1998de5170a9ff0bfbd5d42a4f9fe962d44b9d01ed7e4e8980b2c41fe0d9971ed12e2a2b4258649acffcb26fb65f9f5102b36fa8eca328dc20ff1363ce4f40589dee89206ea1ad27bd11c7672ee810495cf81a0660cffce87f473ccf6050868ee6f8729fdb25a779e0a5151dfab2009fe33760e31c5b72d612a3eeddf7c69ee9b413ca97ee78884f9632b3ec93dcf291a6f63c2d65b0a771a3bb9073db15e3b231365494b67b14821912ae2b699d89daaf17a95ed4d3a4dc159a52ea56e0beb691a0300367b5f504ba1d3d1db57ad10f87ce96b96313fd398084bb5aa33593291b1e11ab5625adb723bd0b2523057a2f630d7c5fd085af756fea107d1a2349bec412ad6958d2cb58f5994b7b51ef7cfaf2da82dde01ba42343694c6f3c58b278294b49721d8695faf76e136d6590ee803ba9e02091dd833e7549b5eb036f4d87078bb8d9d34575b6255843928fc7d4143fbac310d677b3970109d8fb3a520cc91e80fb14368b3a4be8cafebd1179c3c64a79736b0ac97a0bf4e79f019287675f11577cd335aba37e4414b5ad44ad1b1097592de220eb12f267a788407113f4ff767b0a145db1fdc04ee410db5f867e023810a422f7f3fd5784823a02e3ecda4d38d363e094263d22f3d03b84012b9016743b992acb79c170a2baec94fe83df77046a11ac404d93dafe9d6266c1523ff02b8e9c01859886ff01f1c23c8081998be012da5d1b04653d9d1ee863cfc246c8050ffdd7f594792e6e70b59a1fa1384428d67baeecd08065fadb90779aeedf1b7bb4c04f16831f7083e0a64cbd9f24892114bf759f3f76c31f97c448a87e84ac7c7d24ebc9ec96081c95d0dd361c59bec38b871180f2feb62bb01454be18d4beaca0f36096294244d39fe376da7d89033952590c406a59adf3f8d1b6037f5445f83bd7c5290da1bc74c2124cb63d3a9674387ee3282e0acde4553127a99af46011664ce59b393df5602394b6eb5613bf3bb52305007be62529fdb5f879470beb6055b3485428807bbdfbb38fc2cef70ba9b4dcbbac0bdb3d07c39541a2ef91fad9dcdd65bf1d8a069936c52b9ee58e31bbebc255a71fde970ac50019e6b48df84b95a3cba4cb4156e64ad2c12b746711beab2568f055578f5a4b246ec5a7d05915d2d1222e7d0fefb31be2907828cf6dc83f33a5a5ce2d497d9a8aa685303b780e5bb791193d437f795d1500a9b8226dc109267233ebd72b8289238b2f378f695c27955388ee25af796fc5531370640a0165468537f693cd28f5165b236b2cfc31184a49cc54d77f5fa67307c4e8bde98011b6be63a21a18bd88ea9426665457714b5f6e26c5bed1e9a2808cc03976ffb47538651323642e184d03a668629157f38ebd4318d0973ca92d61d4334e2f6d595f60a0c330f84ab4b9edfc3cc47d84f8d9f982f1a9020910f3d4cbf3fc89ab80772cb5f355b7ca05c1f24a7c6829d48703b79474b760357ab4b8148a9bd956f90593e61fba5d23788e59df3cd6a38ff1621511a34d936645c782fea914d8b19eca83315f50f8a9c36d3ee5537d6fa416e505c5a1b792dfa3296c63dce7971fed5c8674858400685c1776b128c155cd2325461be5ddcd5b21e9d8d5a573940117bc2140798d41b259242783475285846337a1dcd58275f657b191510db85112223afd3193bf5c52e88a66125f99cc9b952d5a0e0bf3a938497c23591829b5ccbc44cb0a54c3b2896593ae995b4e46b0cec0dccc7f926e1d4524ebd261bcff4ae73ac6290210353b338eea006fb4d158340215de78d8bc21d570e0d6b90191e0ed80115bfa3b1e71128bde9a5ff36aa5624cbd60e15636556eea1828cfe1e00dd54cfc3d9e74b8780567936bd217ff8bc6faa8a263c77fb28e2698f261fd4547f13f332d888072ca9cea04535386a7a1562ef3549e7298330cd1dfa8cb98a002c415da54bdb4d3bb1a7d614a5f032da0e1bd64490c34b3a5d341c46d01d395c6b64ef7a3f5ad20e117cfac61ac2f798114583d6795b8a98f819f04efa3a4b269b91853c854476b44f455a1a9d70bf784155cf6eff4b01292c50b217741eab373dfe9985a608503a660a144a6edf684587714d1952f69dd4968af93baaee277e7e60ed1e9ea95af902910102b9028c39a75af6b85e940a8cc67ef7635d99124900afd0090b332323a05613bbb66c010a08354d94eb14db04603cb7cb8c6334b99916f536a7e45a087ac1e1362e31599ebf9805350ed2c937b062aaafccb62d59bb57128e947ea1a16748b22dc49ca504ba8a2991af0f3e62d831a2468ec1cbcb02debd5b5c9c7a89e9a93413c80d2361fe61825d9650d3f6bb77192308db037be0f30dc613e734e35a44639ef1517aacb672ecb44465e914854bb8c5d7aa83f7ac8a186c9f72088a263e22470d63f566d74cf6c96554bcfc192b362aad3f2bda9ca0a783ab9f76e479030a3bfd520051ca2c9281d5de45a0e479194ac995f29b2d253bcb85064092b62cf4650de970d74f4cc26063920f44b0d621efbeb7d955dce7dc4f755b092c796c4ff71a256b6aaef18688958cae019938591f5b8f2a6467def955bc9149ecd34ae2674d9478f5f9b782199d752dacfb4598801da7372114cacd133921b186aed879d34162eebd44867092e5704a8d6b49bee0e1906a0db6d9bdb5e50dec3d3be899287446699646b55ace0af48954f02371fbefb64f227162b0a85ad85af09275610fc4814ad56febf267809ceba1d09df4c7094350196c7683733829d93279187ee914ab8e791952df7c24f3cfbc9a38d66fa391a2577a14888636cb1098efca3368c2c18852b4ad4d603134da1842ac71e8943922fa9fba4a0f883bf2a8c3a790c9b3d967d6e352e3a7359cb4ed0548a0657fa684d36fea5e51b194e2498a2adcb850decc499dbb60bdc8a135c9a3c82f972108885fbe53eb423a256f04fef2b41856ccf8679e8bbd23290a82e8cfc404656366769bbff4529a2728f6f0ab9172cb9498b3ad827f94d5b80c1fcfbbf0f04296ccee493322ab68d31189bc91c17152dedaebe6a91e98f6c795e5d1ba9242f91eb50202b91eb024fa12fe37cc2bec359edae30b1b380380615ab001325665f90bf4f6106ed6eb120a13d667dd1a74733050f1ffaf858227282dc32e4e7cdf27c9ca6104d26c8bb74ce96daa7ecad8594e592191370c75065cdae34e09a288e8675537ca348cb187ea0ff5c56d1268c30d33d6eae084765f88ac36d61fd62fbcc81330763ec0e36f89eb061b3aa7f56a7edc02b2349dc4027dbcfc44ed8a21d214b7cbb8f35b44c458a84587039bc54b13f167e179de557d97ec18fee8ee7a84759cb163e8d97ed385e35c1ee98c7b692abd08a5f1a8e57fab2dd2fe618aac0ef8c052f91bdc28fb7db41038badc4f02f0284c58c93262e7338d40c40a7e8db667a5a7f44ac4e830ada21e9d5b4f7986e2bb773e7e53a749940568d3d6300ae5cf1e71cafe74e6c97a6be60397e8cef24a9acb9b4c3b10187ae352f0ffd55e83b7724081d364ee4961ab62c4191da88d171618f43c7173d9c3a9de648f922817cb0dfa0606ee6de6f672fd066e07dd2b3ffe0c54840ab7536529ad50ef8754c8a097b8a2a79cea7d2bb42258a10a78a574821ee83612fb3753fef9f4ec4ea6fa00880e75feb9f1b773bc06d9e0597e0b485f505763ba5a037bfdaa6a1e7b778dee68f50426cc46c6f6ee31422883c3713663f8b26fe1403e469c01b8f11acc1fa407ada957c7631edc31703f677ac4f26bea045243f274f6381eda47d7c92c8968685d7a73ac7f893337f5b46f73f480d84ecd2e4d26d1b22e622ae598094d6de0c8afcc9f42e95fb350c7e9b7356312d2d389828042675c2304882eaed1f90b53d690ebc6ffa8ab6051fa6ec1372dff5cbf1f9f9e4f34ad75d92c57f413faeb7c87daacf9c4e9a71aa2219fc7c44e861029c113dfcaac10e7300b41e3c7af5b15e5e2e03b321edbe0e3db31dd24b99cbb1a93428272ff8fb590e9fc48138702be693004c2b78226b8e9a3c3088457051e2ecf81cbf8a70e4a5ee723ff70417aadea726e83267043ad7b489e5a068e0ac0b20c833e253699ea246ce3a9015eb7be2ff7f8cb72022684db348c4b6fe7c51c3fb52b46ecdb924101e4315db2fb7918020ff64008a9b7c91d79a1facf51a8436fffe4a043df8b4b03e6475bb712302a71122c7e3649f5cd55733313d0ac6aee7d05ddf2410025af5161435b13d8f42350130e86a7cbb751b44f3487d42027477bd526b6e27f4659fe776059e730c0fc9ed8468cf69fc0cba3be5e3131102d51294fbe0831bd87f9c96d866d0ccc9843a174cd5ce50d262b0a484f8934dc7461c23987b5b726155e8eca5a65a7785fead385c32759a8b3ce58fe88a2fe066efeda54efa526ff1030b221fb62e58556c798f89d07aca77708733f474df22aaece9855b3ef9263041245a106077eb4c896bde893c49ad299b84a3913ee4c364a07915279ca41a17bc479098d720780789f660b694f81e545e5156c8718cfab64f354ebd2ea75c8bef1eba487350d1903beb760c39c961c68e33919d4d93938b269bf8188cdaf54f8458aa2021a525e9b6b4ca3cba7793b92df46f22bff3a4fce38259d70ed32939855ddbeeaf41437d041d93a0e6c68acffa9912e7e4a2064be8f1f0950cc2b8ac7930e5c7e1b2e47b5de90e160d4201a845d318c9b02ed1624e5633c55750e8a1b100ae77070b6fe5de0477602170de4a39eb7f9ff3bb6c198a6cbd2d2421654d5d302857af1bf2f3f0709ff0829ffb0050ba1d588f0b1c3ee0ebef4ca2ba3a54aaad1453a16f482dcaa0987a0dbc193724d524c39e1a71e5f89239f68c0703d77ec16ea98b00fd67b2129d8206059c9c2b042e4101c6683e31a89998b13011d033e48242fa0bb5ac2eff62c8f2acd61b0c27a96ef4d447a9f308c893c69274195d9c6b25a7629218beb70310a8ce5b32ff32207d76d9b8477a09b5de695850363ac4bdbbbc484842a7ded31b77b83c6bc0945e4724054ad75b3539fb2826ded50095f4964f81394e2e024ef43e5eb00902e4391a9fa9964310dcead75345acbe566a946ff541c43892460e0705e7a024aed4a1edbf7dbe9a4a305b4f6e26e3a72b10a876d9d4531c11c8ba4b2b79f85bfe1e382fdaab6b6ca26ca0e612f7f18d8fe1937dd696a1ae2367b59b953c4c6d21301cad08ebed4af5370ed56a7d0fe20730836c70159d3dab6614fb05a2bb61ee4b7668839ab93a2529385923d27c1aaf85e3950e3668630a12923730c3185049b9a93392839c82d4ffcb16dd18989f43c18d9e0734522fe988cdacdd8b54dac929cbb6fd18419e2784c56a892a52ba8817d462fa51dc26b12f4fb68e6fd1ebcf442c5e40869a1614a191fefe647b8b6999d92b918534c7f4978e1447a6c176c9f8a0f84a0bce636c6c8bfdfac2db993ccdb98c6ac5fd38a15f1070f5c534171ee08f06ce79f4c6a1a235a6c8991fadefc938954e9d2ce2b2968190ecc40fc055daa66194915d8ede93406057df5666812ca9f06340e7068851fc5834ffa8ead0813f29fe8f9805328d76a1f9190517968dc294394f4a245e7a1ac59561d0f67e1d729252cc44e42e2ea73ea7b00fd781bfc8fe97e33438c3746aebd038a50de598ce6e75e960b66e0c8acfb211c33e9fff50411ea927d6be243e2a7321c5a1c98f87082b3ac3bd72f7805c31a66c6976e53f4d9488f11d8c0f19b116c76b78b562e499a7078b37b7c8eade1a6f57494cac58aec88d40c7888e45a2971d6894d4ef65b8026ab64fb9fa6865e695bd784c6d0a5058da6c11d6fdcfd8e7232c44ea0bf336c3531cbd794cb09ea2e82f0bbcff180cbbe36ac3e5da069a150f800dfca30fcd65ea8664b73e7ef2f4c0c9e63593d97a9ba4b794a888086814fdf4d9748ebf450e371ebffc678cbf53d4f8b7f2cc2ff31d33ca0a5d26072d0c784008c5d5482c5a64c6f972d062d0529d97901e22c457a67ee71181adf5955cabdcc1a2c32dc6659f98aabf60aea10e667ee5d59810d1aab4493c0c436ac0330f1fbbf51e7e4e4f4323cb70ea52d0780446615ff77b7240249ab892dd5f7925998cd6a6590620223a2e4678480503b855a22f251fb91367e09c6f69be772db0537d524959a22aa16294baac31ea715034c960663c0282172b283244255c98810b117cc1000a36c38edc5873219c173c35e965fe144bb1c5b4cf82a63e71aa3ced5872cffb0f700e5746f13501acce17a50b273e9190a163a090711388fa46ae2e91b4a3c461e541afbe7f8ef2d41a913cf8656c73bb26d659fce4dc25d3478f3994d369cdb73cfcde0d3f1a32c1e543dcf6cd7310fed2f7d40642e7d553a7cd440bc838c4000f5690646eabe976f7203116ada37214d34544fb82d96917ae7f7f2cff59ca6dc3053432f7857e7ec9181106fc9f5f5f5eac38107261883bf79250dd757cc74d9dea36030c781f3cc565cdf101d4bea6ea15ad266e18543417994d234ca10db221dc598a0f5393e9dd64f5071d4c419c8a2c8f3fd939ca3655e2c640832adfbed77b1b0f67a49668a77b5de992b71851aeeb500e7875811d458a4f67cff0ffb3176aaba777ddb04373b4fe2180c249b5d50159f4f1710c051cf44931a9cdd7a41ae7f598c42f0a09c66d2d2e22e6bf8ab44e22c7312dab1c51a27c3f3ec6839daaaceaf23a51063bcec5fa9c42962bb7d1b59e3f6db8d5dc8381c45b68c90c0e6fb80898e851e13767d226a7138be5c853e0d2bf9918724f8e7309871f024bc91f3ffedaccbd5aa86efe1974fd07be6076441fe369310958cba57de1c03bd932d7f6c789157e9a97daffb38aa4db9166a29ef6e060c12c4479e5501b0c7a8ec635f23794cc5618517f9f2c1a362bdab021d2c56a565749a2e34f5f6f8703a71eda7784c868eae6c06b95792ed91cbe037a1b665a05fa5b20c258c4d120b884a84cc899cf8ddb51f0674abbd79d4efa867b791955d12a64e0d945a4dfcf5bbbd24ecdb1aeb6c95bded8979fd4e27cf15dae856aa25fe7a507c56b11cd009ebf92642f7ce0c99d9ea7d74ef0f1387ba6f103b4187f939448387cda03e7a07003dce069be76da1b9db226435c9d6d9488ca6f2b6ced54fe2fbb4919dbf8737a8381b2de76dd901521bd7f587f672e6ea6dd37ec3f88a3d6776665a11c532384c6a93b1068fe232f40603a7879c76cfe7c244e15e365542bced665a740821a08888ec0fe1a9e550d3bd1a9c0c3528d8d94aa4356f150b31df913f9e8972cac3b21c12f2d714cf37a38cdbe6ecbf4ea6a2014f7582b6d9f926ebd95152bc7f68e799b07075c1774824e3da9d8c1b0437fe201f93e75c5a47abc5c0740822a416b157f0208281568c573dc0dec94d8b109886c17bd37b0fc76a5b039074f1b931892b1aab8f34681f2b639e539bb01d477dbe3f320c963c350174c75d2e31482d401d0239f358b56e4c025809f6c97a5ce7e7fa4e37e3102ad8b0ff2e2d8ec4be54f3e93651861058316bb1db292115f62483e5c5b17479d8bf04c05dbe05162079f9b95fdc096bd8893c22847a2f4d3dbb8b979c6976a4dc45bba26272b8baa726da8f73a6c252f2d1991739ba76d0751836daa3edec4239151095b4da759df0f563c897c5697438ca2949fede71954c0838b8f804218320b89fa208e71c436cbbf28319caecc252efc6b09916e3700dcce2ae26fd718f17f8060b9c097c9960ab291175040d79f99806058e44ee75b8bb4c1055218a94ef7a5d23a50579c9f12586058b67c808fa740ad475ccc88290f28aca7c831724286b6b3f2d22e2a7620981e2d5b230a8923a5e20ede95f5a9cb1b1e4f72b9b7e4dcf778ce484960aec6c9249d385e0dbdca446ab542e131f333c1a6426560c6d6c9f55994bf779dc9f88970d7d3bcb072f6afcfc57c46e6ec3f9ca3ac6042265bdb3cf437f6381aa232c2437f2793beb78e84096b57cf869d9c4e708e2df1221179ea7429673400f96434aa8bcf06713a921c62122ab230ab89e5e860e4198f76daa4918e1d0d2d4a3989d515b3b455c8992ab4e96ad3c287a5cc1f87b207175f341fd38bbfa35a22e99423f78a25c93bf650bba686fa87c615f0f7562905c4cbb335431b83823c9c6b776b8e66dd20d273f27dceb93d769ddc02b0000dc1b04b1c6966443c44c3bffaec2d879bdba190c1dfb1d3eec3b9289a2384042d8a5732df69a5e4f43d74977287a60006e8355615355f4df9c70f0e2c187e4ec83264abc38b879e492d6062205a752f1ed349f782503caff681704e95384208ac8fb1d6dcfc46fd929882c3dbed8ec65333b412ffb2ea680b9ade47a0ffba220ff91d7182a6c2683233a20d704c8666b4e5393543b3781153c16acda7d011e322837f02fa948251287c818c84b572674df8838d12b6bd84f59d6933d1e40b707b2b351dbc31a171877cf4c26a4eb503696ecf778851456ad69ca86342b112d48b89d4a87dc2d1fd1af132261a9e42ba5eaea660c0fad4e20a569a7d6784a2cf836d6611d3cc55273d856ff1d6e80dcdc5a71537c8d77453b8554e4d8758f0abcb8ba8a9880a94406e91a0ba86a3f7eecd4768e40628d21bf81df98813da973c17d3eaae8dfd42720fbfe639a989e46d03bc36018fea801dcbc132a85ca41646dec648e09e4ba7082f029f27f8e6a3739935b63290fa889d853117ea4242d562f30d88d98218659326a4dab3328396ac9947829b93760c1bab22a4dc34fbef89bd6d5857dbfb5047f8bb2ca03b815e147af2f851b078ef52609457bb3be51ae4ca4375053b269f65a96e1fdd8f85cf4b67a43d750fbab9b32e610a692fcb0eded5f96af7df90c1c8ef04c535ab9621a0377dc36916d2d878fb8cae88f3445eca2f2ad39e816bfdebbb51166955cca502ef8d68048f9adede6d1783fc1972bb9c5e327ab436c5f9a93a8e286812616f4b4830ee1ff31177cd4e0dde2250cad9a4c60cb5a9b4602fcac8cd96ef786f743ff66cb7be0755deb82e4d502e684f9384e080e53f6529225ed698162762c5e99b5b3b4a4e88a777d5426a099ccb18fc4b0acbfef01456d1b8c73701fd92aeed96c1256a61ae12300982687aef515c468a6aeb43942fa4acd4a20bd443fe7fa11b0434522c79755e06fdb475874e17573de813b5b7ad01a1b7e79504daf955e35bbd4a7942bcf4c0a08c9ec98a81962bcb6548c5c72ad8ce4d8c78faf98bae20f6214dfdb36f8a490688948c502919a812db9288043a1b3ee228b5bdc494478689334df12ad64e2966b15ebe1e23d85e8859fcc64503431f10a3bc89547b143058c7fa72cbb9d78f98aeb90ad8830a03a6f8275377b8738f547707101166d06b559f91df0a43634e82d1c8795d94cf74c29d139614f37b6b480c410dd82c1fc3401b8e1b53d0ca580abd5f63c0c938292d14cf6c3054a55b78b92a00d1b210f74aa95c7bc54e127e26b1c32632d966f4f7b2e7720db788fb37868125f7b5352db002f3f7b37017b08fdba300d0a108192b77757a3ea7db5bbc4e71a4a4c4db166b951edd4574767955693d2434313dd85395e6bd7c0ff764942bf590022a338d0246502a14913d41ca5cafa344aa7a8d1056e20d76c16b7ba658595587c3be16b1b4d6418d781679de8deb22814870ef14d2ee6fe17cff4712a334cdea77c4d95c554d1af59440b26a4bfc70ef7fdda9707938973da926e88e51ea15c5ad26363823f16f870d758fd0010a40d6bfcfba856c8c7603e1b352eedf6cae67530940822f1c2dae455877d2677119a42e85daa5bb6e0bdbc171dd3bcd896e4687ec41c6245e4d452bafa145b3eef2c8513134a61afb800b8dcf1093d665591e12f942bee590f72942302f1bf2579f8bbd37133859df429a95be21541ab5df11f98ac5023420087fda601424104158d64055e85857fae67806117256090f8a425e752333b33ffb525a4e2e7ec8ea3303deeed8d0e502ad41c9061d8a798ecd55e88b6d2cea8efc17a5bfef70bbe2cb19df78c7f587984fc2caa1abd6d51d5a0b47956fda0167b4b5322d2e1a1d37f16aabbffda537419cd330877f4d7c84dffc1b2de54a683946a3e125ac92310a18f9cb9cb87ae4370447308af4aa6ae1e2c7b515262e5eb267b29d8a9392db0d0d02a31588c3a0e918d12c4481eb3055844d4c7ee655473fa4fb4218d3a49eb754f6e446054520ad0374c6343c6514f7e8edb37e7240da5b935bee2764c39cb117eaecbda379d6ccab00b820fcaa70d304014d112e371d6af43718300c63a6246bfbd3cf7b75051d9bc20edfc67d71d49d7a3fdcd552dd2357cef65d750b0e5d1083d36f29856a3549a993e0e5f4e0e40c5f090e1b873afa8e38047e35c2d2976a104da9caaabda19636d08f211eb61dae2a845c0726719cc665d114f41c6a14ac091d80d976c2285455e901010ec32582ab58a5c94b9a8655ff9345538c02cc96cd9c9a9e23b5e65fb78a054c4970592cd958d84ebaca6940d4a9eb2e4853d36176238e2ac1774b33f537983bda4b70f9ffb7167c3ad21fc19742b01030ebf4617988a5aedd748e658893be3cecefbcb4c7147114f62f9d203f2801552f2488d0957a6268032c6f4fd2eee8aa9dabf793b647c41575a42f1ed5886d5b42fa178555512f307c6a2a7fc06d2c39b6cd9e6c8eb94c8782a1ae6d7acce667a3697b4cd0bcaef1fdcae6cbb83bceb49412ff518a399f6309fb49ab437979d50be9f0ece4f6f6f76846eb700fae5782880370a418ef81fa20208421a4873ddfc7da77503ba1be05983f44df83b328a01a7e75ef456862a61cf4031de19dc4371022ee814734276555cd1ab6408cae1ecaff55498e58d8087b72b5b2c880b5c0d07c1a2b1bdb3b059cc279fb6b2e686fc9c4be909e929b5ca6483ed77ea091966dba1cdb90bb03ede82213b4e6934c7d089880a617d38a1ff804915599ad62da2e68661edfcfddc90256b8667ccd1192ca9fb23a7b4f9fa683c86abc4b090e58ce9960735ba4fbbd9810fe3458d7bbb37ad6dbcb6d3aea3fd5cbeadc3772133f1708d65fdeaf597ac9ca8ecc6cb6f3db6567f7092f8d04a8f4afe53847da2219a8e8955702b00d50b4cb83c5c518a7bf78b36b904b318a7c4f25e4c351581e20e216a535e4ccd75433d5af24aeb2a67113d2469dffe12759da90f0b9eb89c7cd0c2be7d02b5822ff6f2ddd1e8737e18013fbaa19553844dccea51e0c5efe99f34b2cbc27e0c1c6144cba631e12b89ef83cfc79495b824b30343b1b779b474834de62b266ec896a930bea6091c2cd5768da3680e48dd28f5b25d5ca13dfcb484bba83771d40dff031541cb3f870df6775fba093e11df7b866b3a808dadc4158a8c3c561564ae7b96e2c90ab8be9f28920bff224d1c13971e3f14ea039d5cf6fb8e367a0f7805b580c14e20bc9050559cc4dafa4fb08c379d7b1823fdd5b19652606a7ba213a6dddab959d03e08be77562f79797ed1b7b3b08cdd13c0fdee565cac17644614812287f1eaaef3e6083173aa64999277d1950ddc0519ae0a5a44ed73149ae1305a319d8bd478e56bc9fa943af54e2640079873085b3793956af3fb23b5bbc732dc377e61c0dfc98cad4945d9afcadef989a42e253d350f2937c90660c501836c3139965e7c1b32aabb4d84b7c4f112751999c2e695ff4d93b769bdc098ed200c7c40f2c285ce726015152d9c5aefd0f37b9d4d233030f75b90804167e2e00717d774ec6e2332ea6c8a5eee03780184a494b9c875f0b1cc0b65e3885ca19bd1a99bce4c981ac84c4b924d7e58524fe772330a4d5e4be917f36d3a550d438033ea00bf2cde390aafd288a84c92782bc2df20f374c47e79fbd88aac885710bb1d0a9979f0fb1ee53ca170690f87e18299af8047397d5e216760aa5908b7dd171efe5be2f370d4f11a299b13cb24666b52a47353affe69b63fbed259e6a88169a5a76f13bf0df8171c5d9f206a8b6911a08a23f8dbe6bf6b58382928d91756b58f52f74a047fbdf748bd3a8da480b1a47dc1399e8bf408b4efe78ea8e5636344789bb78ff7e9705fb85fe5b59345ff9e10c9997a7273d6288f604ba92a66ab67444545d336ded725c96e44610381a3a740e8dcf97968e0a0dec6e2bd46d06030a22e8c415d8e2aa006067eae719a95ccc744fcaac91ad8d0fd467cbc5cafffd4c23fb2e48743348dd4095caabb2a4cfeab07fa4bbdae2444c5b64338e84c1ce592bdc88d536bb21f567fab27e88fc89753e41d20cd0a60b33f1390f24573e83db35fcd9e3f11a128182d62b393a51abfcc22f9496b7a8491bb8c1c35c32fb3b405a7760432ee27adc37aec1ddec59894990fb042fd0384a8df5bf5f57eb661d4368629730777f7c8844017ae5118b608e926bb0be44a4283e75695354eef2be572cb60eeb288532d39bd4c5f70aa33f580a26f8df20b4d4c174fa0f9bfbe75a12c27e29dcc9287679806b51b9410609c6e952f76c8332ff02469b893347b0631d692d8df9058885264436b895fa9a3dabfc564db2968a4e2953269ebbc2f88988733ac9261f4509e04dddf41da0e3e9d64bd26331d09efd2e03d01dfec292289256f125b38df98f8bb6d59bbe54510e60c5eed5b90f581f1577b18a8cb8ad4b61cae2242df311468303cf630e9bedb6df200cbe5bedad1cb79624e2e53f1348435f6e8d4127c16754930697212f73347e25e7ec5a74d883b0207a49c932fc5772cdd47f9906bc042d5ce74b61616df1322f36eb0d80a302feabfde70a713b2d51c79907cb00e38c04074f1885c37638a6b94d1f19c1f2686bbef20f891039a7cb1e37eaa45aedc8dc343244577984939831018f27fd0fadd51dda270f2a49b5307ff7c556337d8029494b0ac3ae1c1647914f8b30fb4ef7a9b374a4b63815303846a57422244aa869d945edb9485f97f2ba840601e89e27009d560300e80af70d1fbfe22bbe9ee876856d840259aa6c4072fb887b6ff9e14a0f122679ad79ab7f86d812dea52e407a4dbbe8de864a83b029e86becf13fe691971ff1ad42f29f76a8cf0b5f7546a17a0ad1d157d7fee87ccd321abb9ea629ab802ef5d8a167c222474c074bef866c94fe823a3f9299466cbe9a2227ffeffd7bcd7e009aea562a5a5c829817180e4b9571fe137a1d917fd6b6782c66c51452afeec59a033021af9c687e310e6803fec67814a9c49a0632c85551a1e2a16f177da15132e7dcf600886b1b8dfa0dddde009760daaef9c1ba36463daac69c0ee1774d3e06af7682f8df5d3bddf2e673f839366fb5d8d78ea6420f38f751ae668adf136fb3e144032e71689c4ddb1d102a18d3ce7b6daad83e1ee8103476297b805b6e5550f182e43f7ac239775cacad0e9bb6808620b709ed8eac5ba126d5c54a35a9d70ec9b3c355dc3fcf7a13b97532113f40b2d9163ad9c7fccf0c757166e239a442deca229ac8807cbdecec16c58c3522d59eddfd83dbdc0d45470d0dddf3f9e8b26c8381fc02d535dc34309e2674836a4fa7f4492382d2c7f667a144e4be93d4db5816e6a96da8e9597860bd9f8ff0da5b6c38d42795660a9adc10cb7c7a04c06109c226961161b36a6510b2f2ddec13498017fce82e3708b0f519be8291af12adda4c52c3d190a0fbeea9f34c9fe31c13c0ebcaa4439b764b585b79dcb4cd49bb30dc8adb50fa94a1871da4666ba607c2f6342a479e06ea7a471e66ae6c48c9cb74359336bf6f1573c4b5097878b329e5025dcc3a8de0ad6a82ad2f507987e5c5ad9bbb125ba1d569918b611eadf28eb00743faa189836c943a951b3c874f90fe02b9ab4a778b6beda40f17ec91182b81bb784240cf450d8dff694795a2f0d9e13b383fd004c31c6445a1e72b9bd74f2d00f058fff64fff22116fd8a525869ec2d8a16fb42e70f21a64c00a06a6cb0595e34073541d042f482d0fa4cc263c7815708f8d5dcd5b1c259f3ea66ac7825ee90bb572a93c34e6626ac1f02af6d5699e2404d721229c0b3b66175fc1ccea91f5268b2fb4d9935c592471a1ac7f338024f94bf24543a4ca4e805a073cbecb31491763680fbe6642c7b0224ca15a2700fe6dad090ab37e6923bd1f0a75f50091e86573034b702c0d47435335a0d50494f1b1c59b518b92cdcb0b743e2a4fb1ed1bebf9008ac34ff843ed2b018ca24c8b61c7eb8f1a58ab8f5f902950103b90290396258baf9220bb85deb7e02fe343c23052f658cc45442c634b566f66f11aa6508efd9ac1a7fdb1731dfe16be2e7df0526ecf1b9cd2e076c9398b50919d1ba59d46f2b639abe9aa4b95e340db282a7c62db8e61a395479ba543afb738340a724120174b648a383a8e075dc631b3f79b14605bbe691ea4dad3d865071a632ec98f75cd59b5edeb4662cdac2b47c78a1f76226bc2ebc76eefad6a0c83fc66135d16f98c4f2dee648a5460c337ac522e366dfd810ccfe9d92e941b5b374166a728cc19394560b8ef317488d8f0b02cec8b0f89f469820299c9e366cf449c12f130bb6d9456fe41950f2f0ff4634cc1899e9ffd4e09dac3bfce3fef25e4962c691baf388913b5d54c31fa4850b434ad86a8c72c6812629ed538570ed66bfae7d4fb89ca72e6ea9b720a45caff395ade6809a22f45cb10847b3b8bb6cd62571e3283d7f87a2c75f7cf1f033bb0b2631f573f59041ebc5a132d55b170ea4d3ae9ba1d0950bc11890f214dff71ad96bafabf1055fc6f7b0accb79cbf4213c3564c6372f2676156229a9b59a3cb87163e8f082a2cf63ba826412180edcd9a7c8e4a3929021bb98d601e05f63fea62567d0b55dee240e7b0aad2618d207f891a46b5c59a8c3daf6bfcb7b04986904f8845fe3cb6a048b9dfa6b92c00f6561dee9b7e25f14deb451535fe04facb98f6a3ccc14341a49e88f2e7bd77f550e39ec94fab9189176f86cd48dbc63f23259e98ac1cba2b7de1d63295a6de594e62f204971889ce2cf8060d8ccd2b8f3cb9266ad278642a596d970f7d770f96cd35f5b86cd7d9fa0a81175df4053f7f2a6410dcb24d04eba238e33297a28f7fdb3f66b696f497da9e74e34cb4079dd51fa94283f5c0f534aa823b05efe5a1ef429d995899b9e696e1e7582cc7aa758064cb09428eb12ac90f91eb50203b91eb08d9dab203f0085102b75ea3c42ed25f1c708cc35c11a396334701260cae93bebde4048ebc085502144fa40f661459455273cdda9e594fc412e725662a6160f93e63715df9e399302773ca57a1ed1f0c12d200e51b0759d7a8d5d86d05d8c48e5a6993a6b52bb80790259a31b1f781c5265c32f39a00d2bae6efbd55cc745d01415d5055264901debe9d2aef994a6fd7ecf1523e52c74eaa90821ce337d4a07bfcdf9fdf697df14a585227bfea2bba64ba38712f72b7df5a45697aa7671db4c42b25632a2f6a5eff237d9fc2e1719f39a622fe6a30fc05d3c8f96e8fc7c9a86f32d9c0152463b63f3ac7b5d2f5aafd05ec4880f33799926c986e43fddc172c1fc45c21c5ab442ba5cfe1c91aa880daf35bc386f9db0c5e81ae3014e364d4081386077f3d6788b271d426e3425350c181226f029463200a0641863d4d77a52649f083bf36da639efed4a3c8e2f4de47025fe0f04816d19fb06d1984aea1bcce99a6ea4424239ec11880b6943aff2fecf39e70abf552a37c7607889159b2d9edc4b31a63576f5c6de7d4884242c199d1ee750c655735148107331b465e48ab44e4f33a9837f332fa05eee38d252f1f7565929682f5485c799956293ef84def8dd446b72843e3dcc3532917302cf303142da68c3cc26787869f9134888345aac20069085f6f019eb86ee68fb28aeb11c61b8f61a6112f0d324bd732c5723dc5b52ced4e49edacb2a8b01d4065bbf0c0327af26da9c514df5ea00d797339e3aab5f9d976860442f2cf677e40aee215617cf68330347db295a7e541dac742ddd9fbbe62ed75af0284ea2c0e7a256c0e21bcc5a4a6c92d4ebbba212a9c7c93ae1cabe6ce590a1b28419cdf3fdcc7ba64dfb64a8f184b93dc3a017feca2b9e57919ea13cf6c9feb946aca5a3689e0c2466705a14316457f0d5b3ede3745b15230a8031ee786eeaadbbe44157340938eca991a3e8460a995344cb96f9534af58d82ce8ce1ea021c1f91e7310474da42d89b7e26dc1516a7e42ac94a0c1346733eec129a19aa4f721df711e319932f73251a00b35d66541993ffd5126071ba2d7fd36c900701fd27a52e2433963ab3f3883c5a697e6ea4a19673ea684cceaea9b51eccac94f606c80869f2bf26e200b2ea9363786d5da9d8b34c131614475ed0246b2f3eb6f94cd3ba997c3af0589f83260f67d54ebced1acdc05ed0832a51d2ce33fb7f8c74b85144864852bae26b6aa8eaef8720e5c6927893e2f3a195392fb8259a1a5e081c6642181cb1451974ab956e33599468beb35b288a523ed3bb5ca3368d2a852867831b7a8abb3da5387bd5e7cf5c97457824827b991a79a682de3979d3a65862f7ae1cee8513b0cd4b7e35911e0ced5703f8354834d95df5d780f68e6dbf19b3a912fbad55255581233cfa9350977fd59f944f7d6529a4568d396e227d59174765605f815717b642a90a09b8bebe1c1f8e2f58eac66e665b8efb8374cb4b48e8cab871c3e35d5d551c404355d899249698a313e593c6a85c080871329f7f603326d1f7013d6e89f23582f9d5fb7a544b95dc37f454d2d1e4328fd1f4f066e56ab0fba1a4108178625764803e625197a291f6bb16dbc840ffafcfa16d6050f284b556571bfb135f615ac320a2a68ee129fed683fd26961f8d57b4edb8ffdecce626f89df6085125153ea21901038344a8cbcde8a786dc061c0a4d69e3cf01fc55519c584a36998d553d68652fcae1ff07597fe1c7695f39e89d6b53b444ed9b4ff909f6b93ce8b7eebf548f2d08abb9f7536c98b9192a8e69b0811ea7534413ef048913b03550b547df10a2cc0361300a9a7937689f4f4399862c1c7ac332149cabf085fe5fa15add46b94495d23712fede7d14511a6d2bce4ea8879554fae3f159ff8b5c1e6185b4218b46c62737dbf6291f1139b0da8fe55bbbb0c5f24234d5c941ae95f741642cd5f2c6423a4818ce3adacfa0ad4d024bd92497d2cb687a1d0ce59317cc5fd412bc3a59f32a5c9a031e74a23aefb6faa8e381c769ff7b88fdf2326e33d04f6d30f148df6b88806dc0ac11dc061f616396e546813503c6467656cb77025d3808a83d90c83989cbc109d5cdc6520c8ed7488e52d51282bb75e07da1f2cb3ab73f260d12f745b67e41e1e3addcc7b6b42fd9ae57e91ef7d71d7e3176f6086bd4d7e52abefbc4333c1b6adcd7aee250d0ac7d080d58b673cae32b9f5bc1f81c2c72beed7c5129d6f540568a53ac93c2eee608b3f05034a16a9353c32efe350fb7aa3f99762c517123d9856d26664a5c8b366dd7b51238e6418ad5382e6c71ec9ff13c0615fe7ddd14cdb8ddef77ec075e8fbf8fcb17bdea815b767815c3b0bd3a14a82f4655eff3ed443870d4e495d5dfa3b36e8372daafdd4dbbc74619a9ea4afc4d8d7e76b5385652e0706da9bc210702c31541795a77b6c4eb1b729548a79e76c86f3ddfafa629e52bad5d88e19ce76a5718d4bc8e4e95063babc515137ea910ef9d4bb87e9944ad6abeb8a725d31d66f767367fd34912b3cb358053895d3d17474376d406c2fa2cc132d07fdeb5fa6ce32fb3c2287157db3265e6943ad8662dfde5e01b35b273a7477b4db23732cdbe8ee8bb5c7ff5de9031bb3aad042019ee389a3aa1b8a02db214e7ac75a45281b054e7708ce30ba19391772ec2c287eb6cfe3a42e0e5111a3bddec8673f2653eebb8c3a235ff6a2420f3a5ffab5c67bd4ee295028714642258696f0bf230277ad30d2c4e0ed0a9bc7978f55d4f166c29d0599e3ad6bb502227c70900863031d6437c73167833267df4fb33e5a7fda959a4783086f2facba1b506731be39f5c86fc4f45f6168915bb6a82be895b47167a7a3a73c71b08cf4ba5bfa90007abeadcc7ed14072ec7b59b258d06de5304dbf7bc6524c083c9bd5d4926b2a1f3e41d4ec6d0c6a0dd9062269a1ac1ae58ee6c4b02e043a79fde058527b2b3abe72fe4d357957848cff269701b9c19ff154e64c59cc82d7ae19b416d554c8443d55fdc2744afb9ac3c268eec809c56c7f97aeef6f7c3b324c7c2e373a73f13aaf870bd4d81a93dcd7ada1d9704b6bb9d899f15cfde8a7838a4487215fa816d76a279ad98dccc3cebc8315bae40d8347603a784db679706a982745833512386474a876e713505d5aa9b5cb36b2856cf7007bd9cdebd95b492d7593fc6946bcc09d12ce28b4309edd254071051d2fe25033c1fcd638d0bd38a8ab3d1e558fa37c31fd0de3e577127eeae340c66dd64d42997ed42edb0e0b1b857161b41ae0391e7fe7fbcef34083ce843e8792eacdeb9148aa67cf1606fdcdbca50717e3dd0e8d144b63665ed61c460e8f6b86f08b94e73cba1293aca4435429e6b65523dc0aff74aa3daad9fff5cf6176844580eab1907f1e3cd1a2e37a94ab70a0788432d786dd73b2d617fee96ec866061249a2f6f57ece333bb91b0320b98ffe79f643fd94022e9edde69aafc5dcb0742256835b1978cb7b8456251f3a0a40553edb85fcd601839f8cf7fd64dcbfef335dbaf393a0ae59c14b5ac6cd36481bc97144204718024553041a6aead203caeaaeecb00b3cdb9741fe10b946958b606319ae944ba26ad583a2c9ff24ff3a12d6a378a9f96de2be99d85e4b03a4a1b947c8eafcb6a5a8dd25a2ad18d646f1fd949efb5626472a0099606d1c7d3a2a2fdde4be5c8d8fdf53c90a9c239f8fd6113e2125db7428e00c07ec9a7c22480314eee6c49ea65160090c8d89fd9a677fd4c01471caae4e1d875a126190c7ed8c7dfd4cb327c66d5004eec2f113db5231b473f4386d8ca4ccdf67e2b96b0b8370915ade033658e3960a504a2d271ce1e92ffec053f6e05055cf00c12a15440803db7f9fbc4da823739ab1f74dceccbec203bb36c64e127a92b895b72913f5d4d897b174b8163c9daaf62c4d0b30f78840036666c67d8188e98c7f94a0e4f4c23bcf42ab09abdcbf3a5e0cdd80b78500644237159fb5cd42ac37a535bf7951b21b3496a8783f7760400d11193caf83891ea1dda1f1660907776ef85aa4f572fbe16fd8227e97c2e59d78e152d5860e25a75b748de29f7391f720f08bd2c81f95364463dae881ad75b764945c2895f509718fcab0eb8c683ffc1d3d282242288140bbcdc9b5cafd2b4edad1335bd4fa045457dcd9368b787f4c9cbc6e7df71b235b28c3beb505f8ad13836a034bcaabd48a900aa0f12e00660154af7e2df18b658eed81d961d128ee3d66e02954fcf2f4920a1072c8c739a4ce355b6dd294f2e31fb318bf0f0561a205509fc87fafa3dfcaf8309def747928b037fa29472bfa907217a7070ebe7e0abadc7d20e8920f1f06030ac024a1c77e9a77b7cc4ceada61514c850dd2e3a1ed763ebd4e8e134641f635be2c3bb141dace7ccdcbe393502c050c4e93ff8a3aef19a7150e5acd0e9f65e736f5c8568318b3a8e529adb1488dd6d56a409dc07ffd293af1fc7ec19aa66250b0b67d7a41f399d9355ba9f5959d2d9367edd80a2cbe01afb6405b034bfd76d09445c639cefedcded0686f97d40b568dc837df44105010bd30a57cd71449eabb3990f6f7294bc0276ef5e7ebd3ad4b6d6a0929238afcdfe55f271937c64ccd8aea35066a4b7b7361d8086e62390961bd9f86d17fe844c90e71bb7a2e71f90ab2b9aa64bf5c057595b6e19ed0aa128377da3efb1e199110e1236d023dcd2bf9f18602d217c65b6e74360276c5fce7e8d42a5b960f11b8c8b9d0f81b3831fdc114cb838acfac080d77618b6673ff1682d4145c7af35f954b95b5401b1a5bfa1da89a5da8f94552e819bf9f7a7e86d3c355087ad219ed9d3b9334d360d4df9fb22cf74360452f479050328c9f09c53e10846288a1ad511ddbe4ed28b3e4c55bc1c9c3a7c308e28b69acd6e692361895d69b295b1f0ca267b8b75bf38342cf240d2b4add77dfd11f21880352387d2901bb98d327679350032caea6c90e7b2835b898de451e7aa8d87e4b2e9c5b81e68c81d85bb57a0fd6b28a290da9101e58480a94b709097059dc9671db2ec61ee2aaf17006bafef87f054a85577f4a483d07ee99b9e0bf0a09a8a5154556f669220a2d24dc35e0bfcbac3e1af3ce2bb5072fd98eee922badc0db398786a53cb9b28b37a82c9a994882f6313873c59e00766ecf8d655c5d3051a81f8de497afca8a231a1e04e38281c860c4002b68caaeac320109bb32c5eea9159939fdeb3be77e64787690e09a139b8db6ddfc8edc44671b1ae30d6ac1b36c794d20a5e541e915b4ff1d147c50fc1919c78b16de2ef2a4576dfa82e1e6eb11c81b168e0e8ef77101a317b86bf47ff44f32aefcef8c7af3f1a8bf064d09bac721ee2ea3ee7fb1fd5b91244f2d27a6a17aa57174cbbec9c4561d9a6cb8b9a1e7843641d2c6d5c6669a9ec56ec7e4b233aa80fa199cc3d54f5c1d307f7610e3419c391abe537c48274d453a0609be32056550b85d1252111a5cc6f595b8f8aaf3b99b0602e14d45a43a455d705d3a182419f93026f2607aaeff5d6a2263e5279899b1a046fcf02fb0ed30d316cdefc3dcb393c21473659d302b5f7c66f4a0eceff128369e40125f1bbac48f8ffe8c78084d50f5f8a80304f2a7ec8e97d6b9fc9f12fbea904fc7e5677e426f65f9001cede5e5799177e84ff53483a959585ff674389e0a737a918d9efcd8fcbf2a66baae008813097b1c07506816dfd395cfbc46d26e1c4e50ea1ebac5caedcb48cf7fee59f4d3cde3e99cefb567e9c28b0c0c6847f40062c7f3066fdc9c29f53bf79c830aa85cbad9f9f251761558ba4bf503207f88dfb1f8814f5487823d94ac5380c0a24b5d35f51d93ab46144f7ea92b7621a14aa61efde094292f24221418e9a2a340359e9f39f0e30757ceafb64d5429aafae422ed5ad9d0e7bcf8e14a9f0e99f054269502a21b8065f77d6f215a8cc95fde3f36041b120622e747ee71dcc0e3c3639b81a855cd9e45d61c03fa3b1a62edfdb92d44cb82bb2abe9bfa50c0b95dca332fb396b1aa88f277cd96ec7de8ec371d96386142b9516e65ef65b1f08ed503e200389bd36ba335dd370574641013491735c0838b4824c2fd116b43030023847fd68aaa63a0ef14439046efa01d1b99482b84363b83102cb27095a94a7d548cdb0204d141c9521afd81bbb7fbebdcf08d0687f8b1646b54a8e981f756ec86fa29fd9ccd589c4aee76360ad3531b1bb04a26b00247fcc5a12a505b4e60251b9e1c07a3d81403d5883bdce3d48b42071bfdbff2520a6f981e156c69fb95fb0dbe23bbc00e7bca624334b67d1d6277866146cbfa28c562f54b55aa853eb9b2c78f5dd889f1e3a630266914a7b77038ca6715d543f593a95fe4f62d853a6ca96748bb372cdc61230c9c959830a64949b75e22209cd4d28d4f61b03bf29908c8bffd97ce7c23bec39570076eac61f451b307c6885f648684a6778f83743db84e38101e1d1cc676a4d0bc966a80fc61a54d48e9e6d4032fded3e1e6070e668410095faaf327cb3b1160b53b7399617d8b76f8364332d0ef8160a2e943d0d397627d4021e7cdfd03e21dd39ba46a630fe842228dd13216a1a4df64e154752a727665ddbd5f5bf95d21bbef83195e6939daacd62e5069d8076c0b7201ac5c3dfad47e76ec0b7f67087cd2a67886681729cf4dc6ed9a5d58ff9fe62171bf56819eb6ed92337cb60b620b2bcb3f970df6e6f6047bc9bc2ac4699e4c048f2b0106ae972b0b165f8e77c7d29719ecc3298cc6c4d3aa57d09f4a95a71658d70bec0114fcf20e71dc223e4900a317be6bca8fa7bc3b892835dda7a9ae430519b02ce82da216de11401d5eb04f1ea7c129d1add44502137a84d93d0804959d5f55162081cacf67e915aa8795e255103bdfb9ca42f16ba479f7d9ca8b561785c0b0b026372c121ec2c946f916c16e71a486a8ee24a01e02e743ed5d99202ba4d11a8fe8a62e135cffdd7933663e5beffc9d69adbd09bbbfea6414d48e0d325ded2197d54f50f61ed15f45d8e945e3367433fb384d80a2b0949ad55f84709aec37523c4651a0d368cc00adc8719e6378506917c0d9fc7047bbe85c1d0858c9a7103f0ebed245fd4a3959868b544d01e1e18b825a597259a3c855e94ad7cf25911e76ca7ec309a395472df9d542280f13c4db444a33e1c9ccc08b1cdb05c21a26f9929b36fe000688157af002dbb3026b156b04d6fe4f763bdea03f3cf662e348a709f1184ef77f474c52911f8ec7c81a9991849327eb2ee7280289a9762628ab7f4c345482d3d644307bdf6c8ed4617058e0807034d8ac41131f97a1f66f2d94c94c8f751ce554e9a0ba8aa15f2414bde1e91e54a1f646e6df95640771640525a58c1ceb73727f40aabc4db6bf236d2b374c748b92960313fbe1ed89c0fbcc4e61075482c1169d35c425019c6adad2036735cc5bae6a7d9d58eafd5852313d760c9c535ec15019b2656c253afcba08e31c0389b42479a485db8b58b314c81f4ed8528a6a68a8ed8c20ffb6e0bb501734108c9ad499bb2b99ec5a5aa80376765f684ee33c82e6171702033378d4152a26cdbc394a5a1931d3371fbb7d35e54b8c31e928446690631722b90b59d84b4e7f15d2478ab824355d3e2ad822a43a1888d38dbc2aad5f7125cc99fc97af2af77912f07d6f89e2f3a8c8d462cb1c1ea6b854ad75b19a239e2a9b03b8d448a3f39fec4c4cb8971f84dc506940f38a432f6e4d7816320b6894fb8f77932c557e33f6a3beda1c5ef62a8f35be3af963c0dd592cc9ffc16483928fcb6f92fd3031211c07694f69cdad029b96221bce80db09cceeb6a0cf97ceadace38a22a6af7a746376dca04872f8691e5fa37dd9c0a0ca886f3d5f92525336b664972e8ea7d57b3dae5c78063e1a0a645e3a7d586c53a996b561b226ce51bcbb76bc948c86043b29ad4120a855f1fd4f989d8022c10cbe1733894f109686cc086fde349fde9095e057236180f60003e6a0ed8b4593f1b110f49adc30f534adaf08c3952538c328fcb3e498f64039af17308ebc32f16d1b32e20d0ae160bba296f71bde9618fc18d3f74ac4a2bff1d00a8497bc6cfe0b53731e48109ad73cffebc7e053b8433fd6017f642c1744e216b881059a40b394d72d469b54386c9adcef93e72dccaadf789dbe42b75361658e0ff85a1a58ece2540692dd874054dbfe09a50bb1e046786867311fad214f30ebce0273ac6c861ad7b742fdb49a0aa9154d937b028227593e7c37a67cae0b28fd5c4b658d31ea0800a4fd65ea53edf60d77a3e55474026b4568f2918a8132bb3068cb57757d15e1f695a3cae12e6536c91b9f78c119337c3def81bfb0efbcfc5b92526aafd5d13bd43ef173100525164c9e67d9fea6799beb00849df625c369df513a664b57639cd6bcd1108bb5da9af69fcb97348d1fb5779fd99280bf56b2a9b439db2f016608b3487cf8713efd10cdfac8ea91802d7660a0509e983ced83c1fa6b78e3c6b1dbe802b53d0aafbdd2bcdc70213b2ec73e723cac3e9ecb0440d7f077cd7a90fdbc0f00e26be2b0b2e1889838b5ff32b2c6b1ecbb0d9eb863a21199ea995d7f5794f189e6754345f59142335be94f06c542d05c629da9cbf76de753f7b6be0d297fa1e6861ad2d033ce6afde596de120c9988b1a96ef67f56c3f9e9aff0665129a1299a7ee3a40155ab71b9a27b08d7dfc272682c3c3610cc0d4c442cb5a51eddcf845df307562cf3f14da87b3b4edcb73ba0180c950567a6ed0203a3a31b76acf676ca572c998662e91f5f3b3c210114f5c773a71589616f9c683bdbee5a0cdb80a127bf67528735982a338efcda2757f46bb3a0c58e2a9b104a6870f1d1c1d3c79912fcc2001cd1d5c63188bd1390ba9be95feec51b6de981c332d8603274acc1fab8027f712eafa91290333fef6d197e9322877024668312fe126907f6b441eb86d470a01d5c8736b18510b0e2247ca9aa99fdaa9f8934401ce7962f69eb70498c831f73785566848dfe304ef25dbe47535ba1b1223d64229f49d7ebbab8dc8c650965d8fb6877283c00cd1bc66ddfeb63f88073ab6086ff81910493ac258e3bd292827fc4a18f5ed3d460e986227d942e843e33ebad47a22be1f476517963d9e5db69cf0f6e2fbe37fda518102aa36c4d3c2acce682cca6844a961d2c5b07f6f8466a73a94191e7cf75f2d31f775ea55d0adaab64c707503d9680288b83ae8de1db30ddeaec18b579bd6246850ab27b3062a634a5bde12f7ec6859ce7e434d0349262c59439835cae713729ce6a2d5a429691f91bd9af0dcc6a1459c7d3afb707829efefa39c2109195b6c4eae9b63a8b54f85188333fd60fb7ce8c54283e3ba1c5042225d70286a0ee2fd05c04ad7347a09c5a6bf8ff9f95b981486126ef0162d8b18dd69ebabdf4555926dd377bcec75dae7f1f9082f2933a37f302b86e116b845dd307ef73c464bd5e66be0d77ac54c5c2bfdc3c5460b4b8da983cab0a0db191a7c884a67f0af697701ebe0b98e4034ba8536c94e813a5a2f5bf407c57b5c66abfaafb0fb98fe55c15391c0dec7b92e4dddde0d30545f5284504f049b272be7a2912db0713d993e53e8ab9f5d824582c0c01b0c2c542e91670433464c1368c76085356ad3c063586ac8c1bf92fc6519f6b1dadcec7292aa0e8d3f8a25ab2f71c5f1f4e4d0bf8cb81c389b2c74170a496a0b9c84a256efa39bf3467dd72d6c3fbbb598f0066ee88720ec3bcdda5351bb9cd3b2a23fe0f7e0143ff2fb1b614c385f609f57d23d56e6a5deca445573a363dea2f06fcbc881dde2d4b8add55fe412e6442bc3d87840d4536d145b6debef96f5bb5062c9bcd71bc0cc8623ca5aeb45ee592884b7108dfa203d417725cbced736248e937b200d04e7fd733ac083ce9240e89886cb26285699a3b88fb843508419a0def670d5aeb85f2be9b43a6b4341b490dc832c0e8294503ceba86fd90370cbe82142ccf4191fb7447dfda18d0869bdc18d001471798803a7eb475b51fa239d587db7bd25715af6c682bdefeef0fa17c40730a26e0d643c91f2a50ff29a4ebe7a55b2526404d5c4f9c94ae7a89e31b6535b3a54d6651c893260c3f8eae765eea807feb3a03ab4f2935fcea1c6f5cc2f712db647bff4846e59b10ca28f7a5348189f920882b92f0d4f2b7522b68a0a1132e7095e5e180294482ddcc1d8b16cba1ba49d435ba9c0c60fb2ee50ee4d6c3ed749aa82ae753fb91beccd9b66c87bc3c0752fac1b2aaf590a23fccf1a2f44c81faf8f878e4fcb12f312c214cfdc9c9d20644c91dd9e6b4a17b5699af1994086bfb87838ac57091523b0f7f034a60ec4c5b473f44ef852095edd0d758c122cca458f3344da500d13ef5c586e280830033d3e248d34728f5fcfdf07534892afd630a976a819c8573dee18973fa240f7f9ea4ef06c4b2cbcddd78f650b79d98b73d04df366560714c31e36cb980d9c9cc66bc8a1ad44c9eab119677d2f12b0694dcfc43c32103367a6a1990ab9f0e67feba9f85e6442c95adf84896b2d1225ddb20f800259e02bb340d8ef84aa8b2dca1c6dd53a7a70c4cde8e5e0ec697fa4b5d11d9431d471966d09e97c43727525199f92bc44d5d33c7bd4bc07c4755e1eb19985f076a0ee37a6f1c6fb82db68d5b560a81da57804119464e1e056e26f1429a1c7d4c8e09c06a287d7a67362c5de854aa1b0f509863a03b4fca86077bf529e56adc4ac5c3af0c8d91705e4561fea192179a66f16089cd9f53bb0354b494fcdfc3812202f39d60d4e9b3437d440c7fb75fc412829f7d02b13cc46ba02c563ca758bc52a073b5dca5b3d090b12354bdda255acadf24fe5ba2b78f7d2fd2acca55b2507ab27b0a08b767e3c0135737dc45752ca7c22f0e0be8040164d3686922b4190a5ff5febb60dd8c7f4136702552d7cd3c2b7bcd6ede63f7b58be837e86d060a51f9d44c850a83f935f166a0959deff7a68b08deee3c71e8634c2183ad1bf2885e80d905d9ba75100e0be5cf5195262b5b7fed9080594cd5aef3e7d6d7cd924c094cde64a47a9f7c5de9475a9a497fbaf02355a7a39d8531c1f75051e9c16075be4c031ec3fbe97138f1d27b12d02f2dffca369e647450e57cef09bfcaacefad667c98623fdf902950105b9029039b44ee133c3592ed9c055facc3d4f42b9e20ce563671b60c7c1cc2710ac452911e7f6734d10884eb2fe4a5e3c099f8f62750ede07bf74a4f1bd343a7e661e68656856e4405593932f39de146590bd742458e6ad613bab2474d0c1a93dfbf549899593e60732ec2d93af0fd90e577b6b638bca27fcaeed394b43134e2e2e6b99eafda9315631cfaaf7fc32bdf3e1a9d1d75b7656de8f673bfcb856b5e44a250ea153e8a91fe439b062c94a29d276d0d83b3b52cbf53b5d999dc26c9ff4a12fa41563f953d20479c5a967d4570968c4f1912b4e9db9bc79919c563faf32278832b385790c12a4b860b1a8aa9b13ee2be44a60df3fc4909526fc7595c1d7148c31e6506a1a871635c9ddc51a6245d1c94118d33fae92c7d4a419cb156ffa7346d39f899fdef0c4e6e8c418894e95e5d2ddfa4bef08da5e49edee3a9d60a14930aeacf8de4a533aa91483534ff537ef1921dc350983711d043d2b5ce4382dbe0ad90c76d0e6f2f3dc164a0b399db6747604de668f68b8bbd2aec83e4f4e59314b284ce3d086b32a6ce235a86858decd81e12abb4cc975d4ce04f9dcb69f3f1e41b77d387cacf2792c384540b974e11524625fd9e48c73ab014e9bc3647d45edfb6f3f2d16293ef3dd16b4392f50915d9efb03bb35527f234a461a77fa56f7593f942ca756452ff9057fc5ac366b564b71d77653b8f1334f50185982e032d804d555d0d1a236e80a9ff2c7fab64a4202da8abbb38f12fd56d9c973743f07f74fb4c77158b54d5ce1f29bf9ca724ba631f7558bebb44c4e42a7644e2e8787f589e1b1bc9d4e6ba506cc37f9293a798519427245cdfc6ad734ad331a6dc688eb7c4a452199856d5e6d3e23e1908bb3bcf4291b5e70a891e8b4d1e38d16991fbb75e2a787586558043e21ff9c3cddd532f18740f91eb50205b91eb06ba6d7154f66c80625fa5c02877fc1175d91dc403194e990428b511e907d9691cf760eede7c6675d95c4af472ee2201aa89338b84d33b0194ae8e5a97a2fe9117dd847bc1963dc3e03e8e2a55dea8b0847d167cbb08125200cb064440fc422623e0ee88efdcb2d19bb46188ace2e220b442360d2d16233a840492d91602c5658e6b3f23057057aa66f78cee497331af28d026b16e67d719e8d6d6981ddff5a997e18592ab5a97cc6bd1a1389fc28f35218a28c1989c410d01345d61bd8608fc90cfcd23ed779b1f0228fe33ed2f094aee1caa448b6022764b48f411c6ce3ffc7cffaadbf6a2d6e30b1d4631b119cc9a5af52535de3abbb11a710a90f3f0ede03622dd8618ac1d71eb17b5667501b997e1c9f8597371143ae960e561340ff295acf2ddd38b28190ac3623e87331509b8b17dafde7d9f862f2612d6c5ef2413a356bacc92c291661429b0f8a8250b659088cae015287c4f9d66038dae0cc9330c43089b4f3cc948a2507ec994f61401ffaa49d552d473ac4c136f9bce69a4c2a21ec860dca94b0e8000dee0f9d7da0139e18749c3c0a3a753861fdaa9ff3641c9b41399665dcb94bb298e3987ac5a766596f805cdfe6f3a2d66d61678ce5a1043b2424c922c4a032f623df46cb37888c064ce72301729f59b414d12d22ca2f9d2ae04e6613695aafdda5deadb52cebc84c709bacba0d30f56a1ee4b4ba55cc160077a9157b33802608d85e46f08c591101d850fab5ab542fefc46ee256f6756cafa3aff80fcd25ba1cea6595c66307af6a8aae617fdbffe6c0806c1dd3c962699b38ee4e4ebced098caa12b96bdb23702990ea3220bfc17b51d9466f5c29624c1f9933637fa2e28819fca2addc3733eca79f553df475ab68e0fe5ca4383ad9064913b30ed2156ddea036655b690850312aaf89fad5b75570c1dfb9e1527b65e3075f72bca941380983f680bbd7d4a7d7930fabee9bd8277b51bc0d0d8707ce3f7cdc11ea842d029c833f3f5c98bee69287a0213b15f0a15e271f1f43b1ffbf05d287b8c62164d4e8cac7976b31844b2f47ad1bfb5a253d2b01bb7188c619fa21aa30e3429b5a476c1c447da12a7e390aff01f36358457527106bec1d1cdb17b59e48a1420ba66675e4de02e3e60e9df4bf5e655ef6406a70dbda9d0be158aaed52800d84160e3022e7a00aa319bb408333ef6e0ec07cda5e3b6ab60e66108b4e739b2dd80541f75e8a857b81fef88c106a258d7fbb78e277f12a5b91b7c7ea234f11417c48c1a851ac15af228f4c21763f0713a109769df3754c62da30cf9f8a171d72dee3234005ed7d27cbd3a4a5ba633ed6a4684ff2d6ec05fe66ebdcf8bbe5845410bf8350d6ae5fa6b8592e3e778efc5dc817ab2d138ee44edd9116edd80b64632cb864275c7316e32d973e2c4f13983bf1648859c58d824ec23861b3580382cb20cc9d7b3ce4cdb1b70f19fa51d961c07d96bca29e879e6eaa64c99fda51d8084cd2260df48ef9fd31bdbbce0ac0c6128dbe14e1a7df9481e0d35965e522640a47eb934db0f0b9680e8cedefc9369ddc7f8bedda0aa7f63dbeafe20bc7eec6e2a96d33afcd334340b8c102fa0861eec7532254f17d676e397aec4a6a95425c5f1e3a7b3e91dd4b8a610799c092ac24a599e928223b48fe06d44a407a809f3ffb5d4682bcd6691f807c5c0887a32ba3cce02f82163aa0903dcbe1e2516c5f58edda2613fb2de788a57c20c83d2c40c2211e58dde91381b45ba27170085cbdff858eaacaaaf86613a544564259d9468da3c3de9e88a482a256efe063673f1b0a8432b524e6e01cb73a6c2a068bb32cd9fe2fdf3dc59f3c6406e600b05ca0a289152c2bb1449c87aabd8d3bbeeba0fd542aeb9caaaad077441999be6b7f1cb6619b2083ba80785fa7824ec838ec092704b8a0fa87262ae78b023a7edea48fdf763d448aa47289dd8b72caadf8c413a3b55b98531dd2489e56a9ab573a3e50524f78406fbcd6d317b6613ef97041b8e2357363e4d66701f331cbf6809d74f3a94ec5e14cf15a819dc0bee2b1a9cc12e86732644066650dbe3275a9f30fb62a88aa4725b56b57a9ac717faa61f58e4859ef0dbacd62e3f007b21a418b499512c9589c13adabcc82a03b6796e9be767383622d659845cdb02a9b28d624cfe7c68d76a28cee35e3b77b23426eef37d25c0f21d28195926eec70f736628bf86a9a907adeb400d01ebb7ee4f89978c88882f761c0c02264ba3d2831894d6c458ffd3c5e21f1a736cf9c405a97e55a913547affd4525aa5b0ea0becee338662413cd77366b5f2169c857559eea8c3a182392d0bf8364bc5452b4cfe324a3739b4fbf7e9af943f643642a0b06e2d0687b33bde9c5a4a29d7794fa50b8a6fd9e1f929a2d422ecaee46c599d33dfd43092744e88db30b3c1adf0e956046c3987dd49c985bdd3a1e54053e8e998c69ae9c8e36fbc83161bf8df3a96e08f8721ebe149df69aad59e774510539ab0a634e86a7f2ee51cf4c4f002f94a8480b540d8e53c67f57ff9888779d483d615529bbd67fce27b5354d2db4e231e1961af91e47a3a423ae6d3fd879f022597870837917dff6eda8558e6a7204f93bda3b2a6be76751913d40dee9ba7145c31366c5f337781708eb99e83e6731a2a9af8171821075776691c8004c8c0a67b12c36d38beb53815721856afa8135696eab6739f279215e3444debeeccb1d7c0fd639bf277096266fabd35cac2fda70e1a8753fd8c707678e33511de6ea0d0555e6801817ee22339b4d470768cbcbc2252a0387a152291e0ecaa15385a3c9574b99c805ead86349cfae904ef6446a5e2026fbdb1b99cffa27a00dec7d72da45192b3e5036f8f969dde3467122b09c3f06a6a8ddace2bcefe515f8570033c6fe24fbeb4a6df75eec20582ba6767a439e7bcff582f782f7365a4824a62ff2b022cc6e86a1b422c0c5bf88870411c01ab7732e884854c700a209ad5ec96f830d034ebec58007a4477e19f6468b7e03594b606e08bd44778ffbcae376354c7378bb01895ef558558853e6ff91adc3c2ccd8ba8f218968761e4702cc99175d8c20971a9798c4066d43f73e7e590cabaaa979c625f47d0fe1472a0a9d6324e367b7d13bfc9212a6e3d37ca00f3c01ce458c2dfb19b74868cf231629fdb09bc139e61db3d0e064c83be0e308b28f57fc910b6e5ee94efb68ce24ffdf6bcdc6ee02eaf8d7725f91ea5a2902cc0ef9b0fc433cb39ffe19686ef8d9249fc708bc77e13bc28301b4d29868f034c9925627bd400b55fafe26c071dcb01a5efc9b50e5220034af800cbe8884ca9a4f7a4dd20fef1d59d8974c08f8dd62040573c3079a404963f9740f4ce531483136f0c24b4aa53259707dc45ee51314763185f68c080cfb7528766bbbaf67415b38eb01d6da34411d0e5120bce623ebb0329a913b8f63f243154ea3cfa89f11da3db5becc28804a8e90bdc5dbfd8433abb9373bda99fa9c118305018499c42c4b9d1f1d2615ed1e5a0c0eb587668ca63ec3a3d76c3d69c7007596cf1b249c36df46842b8309bef1013f148e5731065bab399e18d0f4b5230f0e2f0390939f2853a8fe996a1dc023cbcb57f35f0a3f3b64b4c30e5ecd21800c43c044f9e9dc85d9c3e4c8991fc2ec03a85bd01abfab3d7b58bfa1a14e5e90006bf284dd01c4fa78607be117a0890fae35900de248ed3a4257f9a4af2c5d891f9d0b283e44630040ac4c4d8d6985c1e1480e40b226a53bc34bf7865e41852f56545d69241a174dcb7b703310ac148f3c218b77ec075debcc35e87ca709e0638a710ed6c47eb254678c9cb26888aa658b5d4168d4660613c3d2c5748e4be67ab6c661cee7b6c4cff9ddfeb2fad0fadc10dc142d0f814b58180f28fc8f22c62bccf6f6fda119cbfb03c3f5a519daf6b11b54d2dcc7563fcc6006c0e59a3b9d96504a55ab10d09aa1b1a8d366b94da139564ebbf8642c533d9223ca5990bab386f8326e1599c41e16c37b996977a5febe45ffaa015f7ab0f3508d93f7ad358339ebb428722f36fabf316c54e8f863830abcc7d5b08649234bc5fc599341858efd4107daeddb6c7358aceb3a55f1b642456bc69643e1c336ffa8b9c0f79f8b2c460906687a5a8cd702f83181a2d751f95b0fd53d42b62fdbd2d7759cf35ef564f62b1c3a62d60a0ba715311ea4f3ddf6f86cc3829727acdf1df263fe721b20428260aaedf18eb25ee36300fcfd4c2fe28985981159275fde60cc0619da615ae63dc89a019c14c3c86845c5e2c4f704fb6bde055fe431a2ae0162d3c958879e6f4244d1131ea46c8809d65ab9929f29176bee74e2dc78f4fa00734a7d69180cd40280293c423f859bf0779ebea489a7ba378923bae9f131052dcf259dc372328677a0d2e2112d0cfbcaccf34e6f2be075d700152d808c95778d35d1bce6defc2ba2ce6216f17e9d1955ee403e1738aee985b890f770c290acc9e287eb28be4a6c9f0e13acb162dea1804717d79910de058d516f1285d979d1213461ffbb8d960edd18e01afc84eaf0344ef44ffa00124fc05c4dd5c1f3fa305ee7afe2b6e9e7bdf11f1b87cc80053e88172419f199e311c5ac6211d584678931d63a4a1acb45314f146485664624b95c9feb52d13d58e5367fcb464a840cf8361c0fd15f4f52d63436a5a7b79305e6ff786cea77f12dcb27e116d0d4ce151b01f2da416a4469016c9d7a740f8bef3037eae65b0a4abc6b8cf7f2b1bb4b8e5f444136db06bd6ba22dceb47e67315f3ca97e6afb65ef7e42be03b036a899fd592db0792e53b78cbaed27eb507c3de36689c045279919f37fad4d1e12b74e58642eb8ca25d76062e5531670eabc306cde7c21838418396a3408f4c86577bf159e1139b7f673b26374443947a647654a2179c04727ece5e0dc34b5e88eabd7ae32ac5db203391ba7363945d23d6d2cf2d6615b46c70973ea4e966746f76d52268de9816a3947ff1d4ce758b11bdfb6ffc418258cf19fb998cf816d561d61ca85f53a01c763554377dd1079e145d45a7c35940c6cc65a53d842f303bed326bc668a0f5f901233a390e1dce62599bc0227918ae151a96ee3b30c31c79c9a2ca7ac818603a83e7f2f66e60df27f53347bf5df0c4a7de00d41f0a852f1ed18d3e837fc3f95a6aded50f6fe9f9e5ddb4a64911c4d51d31b6d18ca5b24f0fc4778f7c7fbc71d1de9ac8bdc89a4f9a2151ddbf7111ab85f11f1a25996b359c7797c9113dffeb5654fcf67913fa0b8df2efaf0cd614554aaff8cb59497e15ac0725b1a05da94f3cd622a1db1726dce496f56728aabe9f8d52a89d41239835cc4f6ec9e43c4ea0646b292d6fc46146a94ebafa8524748b0da55b9c78bbbf0d9efd296071d5126775acb3afba7f4933ff155437e8ec941111c8b07e1f2ca34470e337151b6fa5c8d9254b865878dbf380d485a3b6fa3d51bb24f1137cbefa30c079b75e7b19387c08f68ea9aa12bc8d9065c63e74213ceccea83afb95e223988120616717246161589933aca5c9fda6cb6ad6a3a9fc103553846c5c7116619081b4079f8e5da5ae9291906f8703ccbebb3de52f9b09936498e48ecbf05cd5fcaf088869858619ba6f19ab80402f756f770754fdbc74f98c5623702cfcd9adb099e989a4eda6c1408982098d8f6063b315ebba5ebfb5fc3fc864959a214a371956161ad269e8aa1bf92b0e69f3ecd7ffa3c98d704011002a48ace22ee194b5148353d83edf600d16b1c86b6d205010bfba45822b7cb468fe74295349ed7c8099ebe1673741909d6cae3d75fa9671501066648ac0ac42f00041ea877772c0b36dfb19283c56836d19c8a59cc58764f4c8dc72e779be3db22e7cc8fc0fe24d85ca751e1ae0767a0e8cafd7894020f4eadf3a50d5c78c16421a50a26e8bada795067944d75b8cf7d9596e841e350250c35ff063ade0ca51854167b44c69ebd9824391e2e7574cb670b3124aa62f9f73b1c13205f2d57cf204cdd2cad13d22df172d42f6938e581edc51f3b2ef62af115eb0e14582d7fda4ed79669e862f02402c291f6ae04316d05f4956c01bcaf9305023929fdcd8d0417ab0cf68c151c60bd6c1f5da04142bb080244e60cbf9f8053b7e892534657f36dd98558d5a512fe723da3771980eca009e85fa76800d0730a9e14620bc339d227deec210376747880ea32d3fbb3fbd15b40e79a51478517c9e84c3d6cba8b0989cc29c29d2111b82e5a2dbfb35f31501466ded0c6552f7be56d9bd949ab777b6502f84306c23643d51b877e8539fec5c27126eb4980d96b2b702965af4ea455752129791ae881af59862af9591025618cca4337d582345837cd4f1ba50eea9c7e8073501470389bcdec0d53725795814b6683a44d0f4c570f973633780bd300c189f742d1213694508136a7b99f31417146e7ffb183f1b49f38643bc4a2c5e51759118bed1803633f1a34ce6b1d85297f2d38f2aaacfe07d7239f1aba6fa4ac38a608f3f72a49209886022cf4e45b922fd6905407f43a0133efbf6da4dfa691d5d8db599208ab2841b1b071670a106b7de0cda7a48f21dc9d787ac5be3c0ea0e9f4aff1467f708be4a49928275d073474a491db097d5c5b06e2ffbacc4c29a80bf8591bb01d4eac8c6de6161a1c9afd23f5bf88f12554273366ca8c0e8674bcad34ba6307d956c470ef30ec9da25f10b95aa3c7aab74adafb971bee90d11d6d30b207e4d24533984ab936603d17bcd75cb1de70ab47ff700920f6cc4981fb1324555f3e49b3fb9da2cfe56791e0d59719cc707111e37d4704ba7a2cc656b2356e111331bc361afc26301e6802c7e19c7b5681040be0d6992e1e38565e42aa3fe352d79ec9c01acc793595221c453e642eacc09a01e4aaf7a58673f0f2f7d29c5e01a24a396ab197632a8e0cea50cbf4fe0db8a5b26274e3d72bbe43fb6d79cede8079beb10a354deec3b67d65cd492ab190de1eb00c551e0eb2e66179ee2d378f4d3c56bf3cb5184752e56a7a6f12c67c2d14d67a8eb03d6952461e04a9e79abf03338df793b6cb02b628bb2d32b490cf8ce1ab9290861971aa462f304c5b4571942f306c53b160ad22c50a900837efd13db85186dac93de8686b57fbca7ec631412214bdf727def41ab7ab5d8e8d9fa8583d388d1e71c7a61bd5414534d849f14aa0cd03e498130bc6b3334b5848ad669bcd4b2ad20c74382bb100c4d37ac663365f0feaea3ebfa15900781ab62291d6bd646cff2773e6f287422dcc7820f537b9e459e0cf91a7b51564c6a3ddcbcec34e88ea58bf2db850aa91edc36a0fd88d40cba7acdb4716c01d7e6e5eb3e114827f4f54db245abfc3f02250f960c3f573c37234509017fef7541adec3a4d1429b9631e058bc81be5696fa7d074e363cf80a6cc78fdddf925340f82ccfff1b3c72fbfe8b45e69978554af279391bfe7b0e34fdb84363e326b0053efbe0840b7a3663afff6b6ae24f781ac58c558d21ac601f1c1d71ecf852be531a5a7fd92f4d13ed4ca72f40eb37a4983af9dd12a2e38c0d19ed28a05ae3c19e130127c92c2ff79494bb9efd251eb008c0ad5c30bbc82e98215df801a20aa81df4968fa39d8ea578d5e4018b191f3013a79927d08509dc4cf1e386290c41be222a37785671899d62fb2c51809deed8ae3648c677570ae689aea81956a5d511d7f835fb43750efa6921c0b9c7cccf2d5bb2db1e9d3234a64b18e9212d1b5bdd6925af4f6f1acdc4b615f2d7ef94c20cce2153d4af73670a53251ad1807309a0df36ce35f2ec21fb9504456dd031b66f6450df105ada6f0defeca17cfea0a0fd4d1b4f04d32940eb87e61bc86d12f235f0f5af1cc5544028249757cc166e095d8fa0fc567c3fa00ec3d3989f6ecd96b07c2a6ea2f93274355eb19122eaaabe874cb84cad8cec6890379ded9ffa24f1e7b868690e8f858674955794c5db9c56e5cd6eeae8e82f3fdc7d94957ecf9b5142d41f10442a3266b8f6ba073d33562cc513212f6ed40404c3afccf2edfac72baa82bdfaa7dbd8c91c990626f6d28f5d4015b108241e336ec32d07eb78f695452c830ef93f5f1a17cc2eeb9ccd7e555a23c1008a071215177509ec64ac1aed36f3b78b1595ea22a4afd5d231c88a0935e87bd18b6afc4366928981b535fb8b3c31f23574e92425255eeabcb2667f08b3e112e8a1bdc5617ff0ae15a1a7abd29b2bbbea2001376e5798775c58d24b46c7e4eebafb2fc1100e4d0ea15f7908518d3f20abb2fd6da822dd6fa7d187225558d487b2b448f2952ab055f092c713cc3310a50f85cdd8010df0ff3c7aec13fb907ca20f1819f40eb36f2ba97472ca792ccbadc14da22d65ae77add9ff941276cf496f817c5af421809ad6c0700099e820b089413901d0cb69513ea671cb1661ff36ed9aa1c4b0926f657908acd3c2b768ca93bfaf208e47ac8d855e4a122b45e484b870374f8851f320631fb2fd013e4ec94db14e17841d0bd193e8b2a47b0cc4265bbc73a7ea037184f2dbbc8248b660335623c4e967d8ce92047ad7481350ef98f267ad726c5f9d094700f3fa01a3a5c2f83cd07312c7a32ed765d59a741bb92ff8e2fbc89884601ee588fdb4b7dc48e880d7c8cee6e61e18e100ae886a2d6f6ae536998e149c9405efb21c8628dce237e117908b9c50bd529f2588361eb25dd7e7aecb15c1bb585c9f27b47356d7bab77e4b30b36fec05919503eeab5abcfce843cedcb406a9aa5aaa7ef57e7ebe3737a959fb1792efa1fdf839de484037a211ff92d3f220255f098d419f2e2113ca67f8378496952aeef0f8f1399170b7de9c3d904209b105b159c513a68cd10c835730a0efdafc6e37827062179f74c416fcf8076ce02c224de2977e2e77894f5b1cce2a84977568b42acf12ec1f9747ee3039e85ccb5a6af230618fbd57a9681b61947b5c7d91cbdeda0e1306a2471b9c6b731dc1fd376aec514a5c210c2e609f88a85ba921d7a21e8bb27c10491d360367f57ea5e708d0bb592176e60868e5b547c860569deca6bd0d339ad6110f4400e8942bb65248f4b9f150edf870936e0429856bfedab9ed12630725833fd5feca0fee6542a4320459d8bcbb04ada0241def49fd741c85c589bcd6b0af37a6627382886a93397f27f8fa5e791080337a2cd48534366451daea9756ef387c6b399ecb280bf2f986231b5b4672f1edc2e6f6d95a98f8f6c409d32639359428d9c0a0106a9f1592066bbce54663b02eda0a5d912d3ac6e0105ffb4593570f48d215aa06fd1330140d73ea241ee21efd2e8edc3f9798aae4d800b7c0e0716b2414532d076576af79f3570d000e911722ebb6f0d5063a6797adfb39897e3365b1ee9766dc0c2e8c60472228121d718c435a890da5937f1e1e7b358e3860b62caf59509f73b31e6d55ebab1669d2339573f4949c483e1db3491296d7426b46843e33c7442591f3abc6517006ca9cccdd2b0f4c9ff20d16afb99d488ecf0e33bd4f0dba2f28bf9de6cc079df35e03f6f55b66b9fbe1c760b1203005fe449c3e8f06027a0ff67c819d415fb33fba19fc60198885ea9db5acb58804650692bbc1300cbe3c621a71b450f65cf7a321b9f0ae2d3d2fde7d28b0126ade1d46d6f9ea5b06492b2c7a4f595bbbe8367eb36dda9b3233f55f38e22888b4c9d4d1d46fe349ef55f02e3e44f426dd9a2545b2b2a3b0b2a7527f9fc70cdcdf1ad3d78d216fad0913095c7139dc2845d5712b829cd5ea4d8ef0499823e7414984de52fdeebec35cedca39d5167e3f2c2c0aaaae3cf802810796565d4800654af46f21056f9d8b41ac6c29dc06a48b3f0672af49a5894bc641ea5633ab5a67e65e7e777a5d8635ca899e4f5522202fc5222f972ee2a1684f93b5459063338daca98a1387deede9232cc52f029d89e36a1098b37066ffcb5fc4421cdd900b273a2b32e0bb5801c5a10c040920db1454872dee552ee29fb394dd7fd3e5f936983cb14d15fda14d2bfb6fe72688b512e15b92ac81c5793be3dd14304e854462a6874740cd302d6ca57d9e883b7146df5db45fa359f57efe5335168745ac3bc99deb944c3b9da14404d92ee6cf2c7ba2fbf3c6b4966c1608e3811e97ba0be45c5b15b4bf0fe7bbe73d8285919a0098e4a4191db6c76a166fe4e3c8f6b19321a78ccba578b8d362a99f633f0d31f488739be1ab4296400d3e74f15b8c6a7d05933685d7967afb90fbd80b4bf62a6734dd6fb7283047310edf7d103f22fbfe9f6f5fd0a869db9ba00c49d65065983e1de1f54d0a15fd4c0bf6fc81e1d400f8090fe472b17702ad25326c51dd64aa4f353b2db9997797f5fa0b47c8c5b279d05890add48216b5c111d09e0ccd52fa7065657ef4583fe24a56fe8e5b3f35b32d3f63788212ce2773fa8e0654d689de80e1636f0cbd565d0ec2cee466df54f65744329a8a3a4ebf3d2d21cc2cd38af12566b4072788f2dfecaa2c5a981c593350a1267dc982529c9a419d448f127b2722b7058858feba82c13bcaebbad61e88ba8f341e52fdbf6d0e34a70765995aa4d64672c880432e586b1524bae737f43ab3df3dd8226a3b8b0d017fd9ae561a92f20608d8ae939d633fa201e77dc17ae5f7ed038e887709daabf7df1122e689b676790f3266ebe365b59437ee49c7911199da24f3ba2b11ccf61ab78ae304c6cb0997c500df3d56ae5f40ec3b532824eee1b7017e794ff65f42ed2491b671e6c8ff452cecb05e09aac1a64403a4633ed37e804768b3bf49abbadb5638b24740d4a633dd2de1d490ece60564b2875614035feab5edf50a1c6674981afc469c2a25a99d63278f4ca43e6fb5c00b118a5c8d190a3ce9245ccf6e1dd1b8197e1965a722018437ad7229804ac8208ee6be548f972b74ba8a30cf6bfe3248f1d58a34c951bf430295ac9f44ca338a2e913340347f27804521704faf914f6e3a02ba213ab7001b24ce4777358ed8cc674c837190ca9ad5d0b048fa5ecda532a4ce6f6019876c481f90f4eeb031f430c598e5e8fc613bb6c2126240bf5105344421e98dfb3eb2435335d889814654b5fa6316dbc8fcf0c2bb53f0e7f793385447f4cb1b9ce4c5a948596e56a1dfeacc986ac80ffe6cadcedc9fb975d58e86e1ca29f902930106b9028e39d9050f7cbc5895277ab3e85027915c7aa1ffd7563190fb5b55eccd9d0bc0c5cfc4e0df751f530de70b57325be927110172328841fcb94864c506f68e9ec5837517d45165721b9beac0b58e1b88c5d33a36c73cdb9a957cb1ac5b7aa5056792e51433dfaae66a72b10f23487c735726721f61e34be7c727ac8369a309296fd5ca1c8a2f3f36b42962bb69648de502293592f32d7973f382806a5d18d2837a245ed957e62b592cf951525a2f79119be6492cae0f0de6433b99234719c967d8c825688873cc01a9533b0becbff2b4f8e3ab9ad7e8de379834da76502309b09c31315aed1a190827d87e71bc9941cc5edf58525368b13463586e170d0771e218f35b9535bdbf355e0641e66729e9d92a91b94d1d88cc23499bbc894727282e2e41929a40c85daed5736e1f6c03298423881a016672e15d0a7c914b60edbfaeff5d9e28082bc54380e71883b3d755593c3d5639e3825be2359d5fa972f26956492fe9d529e853fedf7e04622ccbca48617085dc7c2c51018220bd1b931dbae5a2285e96a9a28c1f72596299701bfd010e3349123d3f456a04f49c8d779ad50032b9f2fb4787298afbcfa4307dc57211fd8894e54a3b9b6273534bcb36e1e39d0aa5f7b7de77563324f7976edbd7703559f895af3951a5659315db8849925efd0bc48c1d79fd2d03fc269a610751f9ccc21e4f75f9e57ae717f66a9d3c8665301a8676b3593be8179d78580eb522d109876fd84afc72a1be1a378e971a9360f235296bd6cd5b1b93cb7cfceea7348de424d8328aec232cce36388f05ae25fa33ed3719f08525918515328171e0d769b4cad0e0304eb21382622f0986aa8b004df234ac49b1556c4c2e6e8db1a9c2f45befbe490b6c928a018677e54d0e6f95218c175d0d6e5106a67aa945c5cfc8bc70f91eb50206b91eb07e5306029c5c182df454f6107f82725d8fb3b19ebda6f6a7f6488d1f724bd274ef4802b9979b5b65d30b4b5dd54e89965b9c145ba61f24e7b10e0f0dfc3b809696d7e4fcfde44e028815108ccc35719024f32ca4638794c20ac3427452edcb052ac98deae931560bda79d720cbd2edd47449c5529283103ab40818a6f2e92c60db25a344fc0aede9ad7a2fb315b72221f1c14547f79f2990db8871377e259a99905ec63c07e9d8f3fb123045173d8fd13e70daa760128e0fab82c5e81c139c36d13130a4d89d803e218347d51fcd6d20a7ad32350f139bb6e9982566d593a4c3533792b32ce406aa62dc4a2f4157c01491e465bdd8f5176a0ad7c0b1a225738238d5f2f44eca6e3a7269d6555578c69b6fac8435c7628e1da62b2cf8809528360f4b02d23114460e428b195ead995465057368aba0bfb97ac4ae50090d5daf05dbe609b6e3332ef3fcdc8b000f1241450c644a357abfff6585d1d066288bdf3c0fdaef1da425bff5f251403bc47cc7c426b0a92b43c48db84c6dbbd329347086a15afacda1502f799a8d94cbb232840bd32e7a77931c1b9638f4057aa5f6535c1f34b01894a2e1b22695fd81d5e3bdb7ab991043db784487e09918e6fc57baa2425968609476a9eba7a21d8b0892a889571cb438fad60794a2d3ef671e99703b948e61247829ad371dddebd7b89aea30316eebb979105e0531f4d3141870524b75bb310fcff388e5a828f7a5e5493febf37a18daafabe52ba2da590884043d1b01ab6fdd9721d2f33b52cbfd9f991b65d62bbe89636794e0825537fafef425628b0fc43f03a6448613191c09855def355321be8dc9375ec4dff6026750191ab924d5f8e4a1cc7881c1efcbc59b816aaa5700e4d7d3373c20e0db16815f79d64e3e2efb696bce61bac77762aee21ac2a0bdcd342f16c1b6361acfe7f2fe7acc58a6c0f5e10f2faa4935fb3190928c765e554c145173d0a498489ec0825859caae631b146e5af981a74eb3811debb1ebdb1f255806fd5f79596ce3fa3b86e1db20090867ec0d19729af49a4698dedf14d92dd035cd0ddb9835ea163f66a5bec587660d098ea6bcc8f5c3057a160233852ddedc3a46ec59b15ecdc26b5ec02205c2303683680e7374f836eac7d159f83722b936f5e204bdbbb52fa958e3c6e649fd4dab1994c6732d795d73024aa80eea4dd71633f6d5aa6169795c6a4447ebcff8321515487f2fb05a8fdaedfdbc2900ff518286e880c152f2e5deedc0f4ffdbe10868f5b0ee7e3ba1b70482873426d2e4b0176d4d52d1309ec1950ed1a96d960f1dee24e2da5231337516cc39c112167161d04dd0e85843556ad1a1cc3730e4d29f6729ffaec419eff347542988a755b05e41d32c4ec6669d2b136757ccf9397210ad2664f9ccf038f8544751266e59b8f6b93c253f69a1473019b10d6815116b38a2f2eff0f6335af8b763578b4f29d06f78b709aa3d5aa8aa5037bf524be19c11efcd17032f04f805512aa74547118f28a6dcc08dc1b271d876853cc35419280c6ce683eaf7b423a48f702d9d3c026e376c7e3d3ea7c40cc6694493dc9bbd3d793d1a78911be517731435c86c1276f323d275c542e4b09d5d8255b69d3d47a83fa4c48769663371a143aa6d8b904604a7f11cbd94fa7f4e2d59845dae2676e2cc10191df043fc9a889d52edbff0c7762086f064966c1a186f7f3da51cfb9f38c7eddf947dc13f203c7cc8a50a1d84980c6f59f57a14413ee50fb1756bb4a09a5e02bb149a7d9d25a2535efbe4778ee3bf8d8e9b52e700f6e185102a14335cade7fa9cb2d7de582d84ca0c6b6e1e79d7644d574f767935f98e177894995f2f7c454dc3763eb6984ed60579449e3b411b1d9b2f395b74893e1b95072919265fff9f8e88ad288caa054e68a68044958e94b2e9402a7519af8367b030ba04788ef3e3e38c174502dfcbf6b4d5cdb25373c3d52a23aed621073d84612acabfa11dcbdd993bc65f4a7f172b498fd6b47874bc5b900b029b1600f10b521a135e622bd262cebbbe364a4707108d23b4c9e2fe0f0ccb9a0bcddd26103bb2b639619a1623c50a6b2cf90bab7b9a6fdfd61cb6ab08acb880738afd5749774f22380033de0f578fbb00867b0fa129f4752afb0f45828c2e0ac0265583e1e886bbc497ea5abd198d4c7a72fc148e25c77da3114a8d0b0344679ba9bdcc856b8d7cb5078a49b3ac2d4ba030bc0afed1b14de20063130cde266fcd7b9fce6246f7236a8df21a2631795ff996f0818a6b4ae2251ab67a2ac400bbb856060f650400e589e3f6ef444e022254acd5ae8cbbefc485b3fad1d40da5d907f91fe774cd8b5e9b6a5a008f3f1cea80d78b88a19abbf21d8b95efed4eb0796d613a0e6183c815a868d7798865fe810d81765f806f2c8a855a9da90c7af56b04095e14aba2096abeac2c390bd34ffe28fad3944b8e38afb7563c2f5605b68397acea6b244e3ecb369e3bc5af7b5f1aa3515deabf1d1d98c335b1470f7d3587b3d384cc981d15d0c20560e5143717d0823c1f099575d1886fe5d3c3f0ae60779ebbf9409c1a0f346bc786d2df69f36fd1995ed2bff5354a6cba5c471faf8a30ba4d32e2e82459fdf2a7b93084ff06a9e3e305d904424113a9dd1d6b47beba41c27007b977118501820f2e8a536ad9fc270c8ef0c296bb1bb340ff8a7a77d4cb2d2ae4f138ef3ba91b2f669e4308b4db53a30336ed38b2e191a3e015311cce40859eb743bcc13339059065d7732157dede0136c6b65b3cb6dee091ebc840179d36f3fe216d8a6ff9aaaf56b387003d93d5fc195114c1ff99df5d9d9ce06d04ca2d284dbce6ec39cc29c73eb385dfe5c739f9aaed7514ce87a03bec9cba31592e3e89427315a7e3b042420e303a5a7713b75a5d9d7709c6898406dd89165d97a7de9af8b525dd59daf504471e7ccca401ceb955e2a98a1c960667907dfd13841a08b6677e377d659023ddd5fe7da26588877fd4705a5a81b17b89da843d271e5de90dbf7ed1a498a3052e984d1f412cd25d4c00e2628efc5e0441e5e9cd21edea3b9ec0912b0ee08e1e34637c3bf2c30fdb895a6630e3ea01622c444e0b6580e3cd97de73166b487b68bde702957f879a09ceeb93ea7feccbf32f8a93f8fc46f95365e977c5c085d2f955213ad0bc426922c05b555955efdd4468f7a954c7efb59b863a95a2c73406a96707cfb1acdb1317fe4d1486679e219d039db77eac18a5413137c4bb49a6d3e1c769ffff08ca3429d5e3842ad9157e279a7b69a187cf8340a1f5a152c5b56821490917af630d0dc00e9e46a1afb5fdc8f58375d97223dcda0e58079d94abd4919f46601173985a2af990a51be3c3118071b0543e0dd377edd6f32e264ea4c348eb07c4adb27259016956464c878c35be4c400e15859a050b00945ff4d051c48019df34612603653586012cdf27ceb34f797ce3e7f93f56c50bce5e228a6397ca5bf866e4215e0964c4d44d664fd4c384d61a5e85c14d676418d5cc03a2b60d8c142dc8d918318f78cbcdcac57d05b346d0f5860e3eea9e8e712e033e57869d64202e0f38028c353211733d97d2185ff6859c593b6f833a7e233215c76748b1a77dd5a9ae1a9323e426089f6ddcd57de2e86fa52bd0f5869ac88e92322e607e70862e5158b783b223aeaa14f384e82d5460005b4b88e4237a96e658ee55635f760610f8fc2a08b4c918afa0d466bdd657165a14043b8b6c7dd9d9d071f2df87c711011e5008d0b438155d77a2d746113dc29d06fa19fa1e1d1bf4a7b8c11b72d292f13c200acc25cab61f543780351c4a1ea92a093ec0e8e7df5c3a4309b8655e614cc06a28595ffa323a75da07e923a9fb74c7685863b9f433134a942131c0106e697348435c7b1d65fc8d1cb988608513eaf0cf91dd120faa28469cc158bf4d365ef29484ea944bd55f2fafd5d9a7065766cf9b6778508a955562ae6c0732fffa476202a0032622a2eba870247b1a01aa1885ad278e1c20264323eb0e05bbb30a3bd4c2fe6677c8273aeefba18be8845cd30cfa4eabea93f52f504b025ea254f2fb4310a68ad3ea7a428f07c4e9db25cbe597a27012b811482f0b1ea053eb2f058dec4a00dbc468081ed5ec0d69bd6a42106bd2ee65c99b4816932bcaddd32b5ef0d0de194d810a72c959666248cff15140fa09ea1f4725b7850a005ffff1f689fe5f6299473c58f2aa24f77afeea058df4fa5afb8c6abdc5410294effd5568aea3a57d259be83050329b49b42d1b562f5c4c247d1c50b12fdd513f25e245e5fcc7f9d20d074a124c8ca2482b4ff4329123515b87fb12998079a4717aab8e9568899af34a498e32c7951a601a850020c73fe37741e2ba7055547ddde9ce4bbf31890c40e2395bd36baf8dd88e99031f537b2e4787ad8c1a69c3099a84da479837447cc279711036e0678c5f1f1f44c2600347c386adb6e91288352a74ae19247d0b6f43d56119dcd6b073c6189bd3827ca13a718de040cf414a86f667bd59c8e13c86920f64ea288b2cef1efcc6ddf0be8dacb877c8537543661d1380824be0e448e6181a53f268429da3e1e37e5ff60275d6346e241e3d6a14ebeced70e97826aaa542d6702eaf560d1ca8cc9e65fca6425fbad0e516f57190b4d9354d50359f829602c97d74bf13181803e18089cbe9c9db3aae1baeeac60071e1c6be2116f4149e1dce5181274d50d36b4aa5492a68def687d22e3e8fb7ea205272ab92ce4a36cbe5031f978c59eb59ca7434f40716e176798da38447ebcb568877ec968422eeae4954a8c196813bcb1b6307ca33a1dcce7dd0c152c2647d45d74519753e4d141affa7c14536be7f2a30fe14ad86f30cdffa8217c1794b5f7a106db630b2a0dbb08b6f3602f546ee4617830a6654586e324ddd364de281a4a0589be6d88dd92b77729c4a54ee1f89462823a0bb5a17784855713828341820e96961ce2bca533b3cb6ea013d048360cf150333e7ee650484d4025d22b83e2281790390d9b73ecd93b86508cd0cbe6806421ff244e7a1c8543786a6ce564227f1ce1e37aa119c9173be84b441f6c76c0707eaa9cd2d745219981e66cc746b63b222fc7bd598be8935466a3165bd4c3b9c98ee4497cc2ed72409e5f263bb1e93c80453c92d243211e20e02a588a6f08bb329401553c56cbb7d2b51c1e5172fc64d0da2aa6b604bdf99bc4708e11609ed7717821f629a102a7471f8c158620c9c601ed4093b5f1291153590f118c649b1f2ab715186859336157f96ec33b25e9e27074d1e665f5632ef6eb70e61e02db0d5bacb1bd214c8cc9a0037f8bb3998ff7f177939eb4a3a00a4b90f442488086f4b8c1fb4736f78d55b07828cfd9beda19d464d0a8ee5795c92be90308aebf0628a80423662ff22f605af441f8599d4e109bbbe8f92dfcf79bce8443296e73ec560d7dd86cac9e4bd33aa61ff3339a309859537f534b60c948f1c90f09f4a250fc17ca261e1aec1db3b517169ad13df20e5a61aee60cff2dec4607fa2493f62b7c49e3d48d4eb0149c4a87c572ea5ba1b89358b817fd7748a94ee7e054841340de6a9e1d57aa4fb081b41f81c3802c4dc5f0e2e11c7d391a12a97307b617329b4b43e6f831e91f7bb4520d1c74f7acfcc13f146975618b6b68b2d46734841de00347f72261cf5b3c419611bb157700d8006ac6256ae3cc3c61201e807344d7065757fa15adda11e82167bece8700d6a8e49a050ada577c60a46fd613ffcd69e26a3afedbb456b095603ecaf94b8200fd84bcf8f2024627d26e538b6a6e9140633dd75389bd19f4758345a159bdcee1ab038193bb0e6b2f5674f23427d08a9eb3a89f8f892d7b8595fe384aa8ad5d2730e2deb7d8594d206f71cff469d7e35740c9b195c40d3b17778df7dd3269b143bf02d039b6ce582347e7b5ec920102b90d50c14086b4d08690d871a7fb2c83449e2e881ee31814f57970f6adcd2c066b9ca339eb88ff89a1cd7c25af15590add360ff1a97df07378e2f6d396432605b4066ef967385dced8af41081e01d1eb0e375a7b0f4dff717e2ac75d8f6929f2848d7d752eff63dff009fc490c6e6ad6038f6baf631847486bcced9f4be380ffdd5abba2333658ae195666f408218d6cec1bce899b04f756f3094c843aec03c9d51326970284012dc607f9e4d4083171a79b3ae486f54c3a7f3f22a56fef4dbb2f80d700ed9413c65f90dcb5480e9d824b9b7b409dfe7937fd01a7727c54ef2b430812706e1d43445bb48a4c00f50295e9c8eed19c791d21fe9b8379cc2ad6d3eda0aeea46ac6f5805fc70160414abf5a96e1bb33bb865b9d565acae81cb8e6032ef215cab01e8e3fdc624bc529509b307a1b04008428185e858e66a545913c8403e02ca2bd64dfe44921ba3814a0d254329221e11dde8244a865547bfd4ad7f3e8ae228a693462c5c26b4cb6ff8ce42cde7c33690f3c710b3d7d39fff039fc6bb15d371c091e16e984d163cbcf92a4a94f89e70d384dac8941d0745c5642d28c757c4dbf2a3cc0ee02a01143fbe910037b045715867b7fd5159690795d7030db3afb367db466d328f0f5e21f017d1786476579e2621e0e61db90414f29cf6c1b40145fcfc9f34eab7f403b1a0e3c27201cf7b97c551f350b281a1e0692b6e090c5afdce05a9872d84bbc123d7d015b105e8e7e60c3065881e21a606824bd2db30231171269d40b865a35f1e1f1567c37949cb2d65cec480dc8c36415bcca688345a1677ce160afcbc36a34221e3f85fd34f0f34443e450f17ba1d49a523e9eb7e8445cd77ec10b783897009e2723f7ddec0fe9594c3e958e7ad7a5630b8b5326895c72a524d88d284a9fea8d39a51176c395ff34317443ac09b97afaeb8bd5d92e2c68cf0ae1781160a4b0a25db2a142f407643b7b8d1489e1684384f466d090ba9fd0fdade900e9b96bb134e82ec384b5bc4342dda7646a33e17d3ad0525b655f5eee21320f417d6589fc4cf7093b6b0b19fecce0abbd3e6bc4fad39385c136bdeb5b3487771cac02e79f579a3701ef7bfc482a74ab28b9afa26820b13bf92d2642a1cd40b0d156b6d276be2188d62e5d9684fd38b4ac64714722e3abab5e6497c95ba5789e5c162c53aa73aea58d769a349139f4d20c17ae5ef7f53aef1a9b5c76a0c705184c2696aba7d0825a73fe4d8cfcb914324bc30dfeeba022d4cfe0dde4c3ad4a56784a02001624de0ca171df6b531e95a9e99b51a95f5a1c5352a045b5ae7e6eff39504afc1ed66ccda1d3d141ebb20f8a3dff0f33b0143c440f608ebd3139233fb0ca85b0f1384b963b507e0dc240e00ff8ec0752137c35229f708d6f183f6d0bd2837f124a82ee454e2066710d69bbbe7e54789eebbb86e4adcdef71ecb4cc8a1b706d2e26591a4c9890400bc14a3ee85deca14268be0d01620f553bed8f53badd3efd0db8d40b87f1cb79139ed9e2d493028f64034854c1c6eefc9b344595c44e38425907d93bc13f4fcd8fa4b2430c08553c65a1e4eeba71f0660ff5abb6bc51ab709db16689262c258798b7b6dc05a41224852e8ae24e351e967b6b0c908410e53d5e7563ea6961822fecbd4f358232132ccedd044e0493aa0bb507b6dfcdaf31b2866c4b46f65cec441e0a1f9e1458e8a4acf8b61ef17342d8047af35a8093ea822d2659e0c6ca365e569a48ca2e07edf5e02774e4eab92f1aadb1e9847686e88a0fcd71f170b47a952bad122a497f5ef7c4538c018d6968b60a36e77a7d367e7bb29072a0769265e0c595cdca8ba982502a25eb09adb9dccb52b7e42c33a17e4a9c2e0d6635c94704b38ea39bc66886a8657fc2bc56f819b18db822069d0324e6787016a5a766446b0313af4ced0e92ad659bbabf69cc2b95bbd1ce47b6d97769cc0ccac84169f9ffc43c257cd0f0e5521f6669d30ddfafe2e4838843d3a43aa4f854ee6bf5a12a3ad38e55e86d9170dc13c296b441a9611f0fe70e09efe01d449b4c96bf7656c20d061c42a1ed3c2405b844a68603e0a8c3ad4a893751fad65f0c11cd780f40e8ce4f81a1f011171938852442369556c1bf7ac37d7125ad466af9750f663da58bde033f65c92a980be3aa8bfed4452d8cfa9d32068fbe7eae7a04e82af10a3c7d20b01685d2598614bb88958f6831625120e215b956aae8d284262bde44983ae9dd95590ae05f7b2d0e7dce07ce8c76c39e73d0ebed6c19fa92cdb378bd05c5d29b2aa4ad799b717f7d00f46be5321fe1cbd6becff4216268469dd0b434586e2f3222dab1cf00121d64b63bf5186ee7a2fad8ac5f395d73255d70a78dd13640062b59e1c4b252b9b34cfd4c0f6a4f93f456ba6a25ec0cd3280ff6d6b2d170b5effbf404382557dc0d214aa6923f38cf68fd0560cdf7769e0c3e7a45696afae440e706421357207c469a3d7cd15a906290e55e849effad960469c67310ea8fe236d75a911d4ebeedfc08e3d558ca4e9b0ed3e96357e834b93161e4fd73cc6787d813547e8973dae93d9f9310de367f23d02281eca12eec6ba29e384df4c3475b43bbb6b7b69dffaea695e0cadfa1bd0d95ff83f23a49cec867823d983c445b292ec3733ac8cf29ee903d20b3e5d1e266a718048759d47748eb5c3b01de7a66b905554ddbdbbce8c1f158e4b25ffbb729c79dc1bd20287a889075f29615740cab22222086e186558621504aee828eccc7f318452a41d439d0da18d57b291b9924bfce4d29416952bb55919ee768047bd9b02fbd091bc59520c535472484b0f1f7dd3225e7b4ba18a6f3f36180aaf6caea3ba1ee7222f46b8bf8beb67d7343f72c73d42354c311e948998ac2334580bccfc03b37b029f75fcf89ee3bed0c0a80efaff9305dcd04910cc38910f85ccbf2acc243d4ba4c49b2be440d0d76adaf9c8bd89ffb9dac7f99c58c271e104fed645c8a18fef9e4a88223d2ace08fd6885c05d7341722f6fd552a7f83de23419db2fdc86d858160680304bc61427ab07b62fbe4e28686cc8a714a747012ec9d7d1770fc722f0aec01e6ca0f1ce8b18f93d06d26b250b0ace3ce503b6b3501bcf2a82019604ff58474c6618e1c5ac214be8971c90096f6cefcf8e5d24b6e6a9c80c537df555a112150c31e0160229e133d63109cce9140ad5736e83bff10245c723c229862eed9e791063f665c10e23d8b9e88f927e6d35cbccbab25f9631179a2f777a387cdf90bdff336105a8acf3e5be1d79e7142067d0af0e9495d442506eb3434033b3e2a6ab22291f5dafafefcf1401a270fcfee2a1e5531ebfb55e04f07e44423e9144d237a58f400f7ace018674d6ddb37105e81f08e2d9dcb641a668cf5b25414e4fdd710fe4146fcbf390f22fe13811646c683da53c188a02c181b566323d61f3a7469732b77e54455235ab4ebf25ba802e8495c7cbb754217e0f32a4b78fde8d6d0c1771c1ac217cba4b036d9add3f1d15e7524f5ae2abc61e8aa7a595d192f70c4073a9135f8351a9994c6f5c87e12e49e4ecceb20d209ac83700aa0ff7aa65cf3aab3c8f6204a4df99c713b7a01c3165056aa3c31d6dc4acdac7de389b6258c697ef827bab055199ad1861fe436710df10c5201472ab1db84b7dd284fd26878ce9b9f6b83803960ee3f4ac0f0c58cba1e9f00e12a74c0b51dbfbd1503b367172b71f0baa083a7b0cf09228825fe539a18faa7d0be03c96d16c3ac55b487588fbb12086b37e1bd62a1ff61fe3872877367b155d4073951943ce45ee0619b517d459363a0dd85932392da5200171ebd55f3367fd28d358f407cdfb496bf25f0904374d038f5da626c19b51ad05502234a555d8cbb4cd7257173ad9eb61925d2b5e2c2e11fb2d34752ba93f4397b463bac85fd5e851f2b5a6417efb9b3ff4a60214d0d190e08e27c2c0a63d48247aaba76f7781374bbbb165cbe05dd56988b79ceb1982394cb3287f254302dab054f929b8e7776835cb0940de7b5291352fa78f5063c00c23695e21c61c592a97876e394e0360d19dce952973a254cda1a33e79a92075d74a4700d05ffd009d0490e35da5ef2d86a451930d6fd2ba2f6685baa951870849cbf4dd750a6ddeb7c3aae6f4bc99f066a340ce201cf579960a128f2183787017760950a83efa1582d99f70ec5b820188f909f35b795d74217b271b2690654b915da9bc1398a4a349a72280200f52b9ba8c4be40ad05f28b41e9f18be7f120d1ecdeb916aa81c178a276ca3a547d46f14fdd715fa4f430f8a9cc09c08119ba11bbcd7efdfd1ff89228cb1ce26bc4b2eb7f40bef845d9ef4ea3544d6c2226f67a62997125317d26526c82237ff76f134ad02a44187dd4b9db26dcc36f6a8ab033d268648fcc4c0dc08ef4060bb57c73983242fca729e190740fde19489451987e4bdb53e346ce90fef76f04f2a5cc9f38c68cb50723dc160e032f9975eccb371c3d817342e10903c2562faa444e1124c48a17080eaa7348651c1e20037c309c4c9af56ebaf88b40641e078e84c1716cbdead7ef1a9e8550811c049feeba2ffc71b4f3cef9df4c883b1a8c5034f53ffee0cc644445c9d73ed5d63533ae6e9cba32dc9eb4d6a90f315b0a7d3e9bfa283193f72077c3064660da73924874a1c0975a446a1ca300b4661c0e5b2d91358956dab6b340aa8f2656b17a5150e95d367079b99607ef8e91986051f826e1024b9b8f16cf884940a0576250594e03c12265c238ed6851cf68bf9fb9dbba4c000fea62b2db0a5a90a3e5e1baf76ed7180992f5a7c27875c51b269819918b810cc4f143f26c8a22f7210ba365fa2c2f0d37cb0c81cc4174a636043b9f585463d31d75867a44f2856efd8d6cfe076cbc8266e679dea8f696bb591847c69f2b322ed4ae5ca72937f8dea9c77d627231a2760847f8d5f6a8dd4c70c46a951708a26cb1585c5eb367085e41491cff2700f61d424467e1a2fac72e014979e4ccbf38afe2c26c75499281bda4fcb3dfc1eb3b712d2efd9d86e94fefc1a3d47b56a3184c023050ff866f9c7698318ff487372406b22c122632d50d687349832c60378315eb2d6af1d065234517b0d4ad4e90018b351d395b2cfae2deb7cad51dcba29ddb1b9aa4e670bb902b39736e742230a64ae124024e49d96533af95f902940107b9028f39a9ef9a62590763c9cccf3fa965d93a086f8200ef7141b1c84d0c5e80e9bf2b2293c02abcdc561c5283f560a059f8ff69e1bc4a32f05c8ddad69a27754b0f5b5a70f6b0537b95fa9bafdaafa6fc2b52d9067a70dec98e0df086dba6f4db3b54ff33ba22f5bfeb735d8f6331dc3f7676ee272ac7d0928a8c79d08b433076748323f2680e3e89959e347447b1a03e715806d2a440ddbdf4bb931fd9084991e8a95c4377883175b147d3e23b4dfebb45fcf99e1af2107a52dbd3709ab0c8325f13567a55dd45ca0f8f77521403a3379d52622216a27f6874e33754cf22fc3d77b98fba1536de05ad15886ee78c80773b9fd552ff079baf39cc6e0e5f4cd1e3eff4ce322a7f78fe867979de509fce555b2f8f3b7357e6cfe74773f19298868e2a66e641970dea6c9a48e047a1eaeb691dda2d0ac0c376ad31663a8eee1b9d999276632c143ccf57189dcc61826f9248878614cf473aa42b0edf2ce6fd8e21f118819efd43d89b34e63f85737eb154dad7aa44dd74a954707ac7af64dad26d925f9660bda95089b70150e746192e3b5f07fa782e335bb4553bb0dd55fa1a2f1b194694d71b4dd124688802ab5d258b2c3540b8c82a11f683bd472d7b4fcb6abceda13a930887b27c47e16ea0615c4625b7936c4cf43756685568d688945949112bb4488cfb7e23d3fa3dda759947ceb2e7599a72e43585dfc91fde92d4351c7b6734490a86c01305e8460c1d3a08c6763f4dfb1257f88c3dec7aa13cd20ceaf09a1647d9147795b80c0f74cd471d14c8a0ed22d7a4f5cbcf209d40d3299324a587a455d05839c769373b17e6711942c8cc4327ccc4cd23f6d8918a236e421ce56dbb9a69c22fb3daf719dc42cd06efb6bd2ee659492324e5917fb668aa36806c02b8eebe73ecca6ae3a279a54b17b3e590f91eb50207b91eb078ab039928a18911bf9ede20b172c285926ade88746c373b334f6b88b752b00b2aaa572444d29aac8c0d9f3fc2b02701248598271a993418f768aa606a12beab8ae9cc5bbae624a3ef1ac3c0059b313f09a16d356211f7a137e9bc3ca6feefcc33d10669df6eddca91da748d1e00792b965bb106444433679ebb5485cc3809c10bd5509fbfb1c3d6a29288ba957d52377df48f12ae53eeb1171a9d15ba969ba037d04a2f45ab1d914e6d37cafddde8940151243c245c619bc75a68721d27b98456422036ba3f257c7bd9a42b4df0f40e6ebfe9dc055c1dd01f56f60b3cfbd4cc891c08852fdc87a9665e9e48361c5591cde4b68972770c902a6d69d6402a2c518a83d1947a6492a0abab06b0d30fd5df59a6536dbda324084d74498986c27c42f3f4fec6e446d4a27f3316c04f8f927fff67a26db0e5925080c327bfe2e3ee7ee89005d447ddb2418cc7a9cf9cb47ba197561b7df4c61f443af4e67e2ce7a69157ab244d0ea82437e57472a0256eba42d8a68e5042032ab074615188bd2ea137a292802dfedec166f6dd39a2f078d0fcbdd7fc0135b24d522258e972a5680d0044db4e3fbe21c08c64553895de631c00782c13a93a5539b261149e331200bd200ff11a8c0e5f022628edac1d03999ca34f6b05dafa801ff590e929792bb0fc41b1c0f02559d6eae76e9c91c8645285bc3d6b5adecb84d82ca55c1416065250d0cdbd4b43c0b65abdef077410dad416cf933d4b433dafc95ee4e0624377c836eb7902fcbb8f793abdd6638423756714f19eed77b02bc42cc6f858b39a4dc106b5aa6595141fec9751b66f0c29c8da5b50a13aa39e50d039bdd423476deb0ee8e82efadc41b5d6fd135f8dcc08e7e890c8af8ef3586776abdfe5b32a7fb47e4e5c93d7a30d3d8eeed6aac1edaf879f5d9413da24f638819f2c76ad0e6a8e5787a4acce517103c66c6ab1f29eb4dfdabc0dfd4080b533f3bccbef0ad4c90d7838752b4b1a7f06ca2611896a570061439c29497b75f59d9b6e5db329061178aff08c052ee496c67ea63babbf28ce7efc6ed34cfe6b3e1796e6e41a538bb173c5bed0e631426c6e19d58e4038df5e401556cbbfa8db757152369d68750cb47d2efd674eece84be824f9a43d666449d23d67294b00966cc59a8aa1e6dbf16ca310939d845fde1609cff1393ae46b51be77fa8b42ad9af873d557229543141c8ca7e0319e4b96c14448a3411f8e84e85d9e12446c50614efad2e50497aa0d68bce676e83b1c059050eb57b390545bf85081740e06a09bbb97b1727534a94912976bb9b2739f1adc15f599a5af1f8c48e5e9a6a33313290e5f210dff7a18153a1ab82aa3942b072704d2dbe33cd85760ce6a7060c9766066ba81a9274e7bc4f578255a85dc91d63cf84bd0802ccc7d77d3467d4da5742c9c0ba938b51bd226ff351bf0eaf52ccbd35e2991aaf1acf7437e99b677e88ed6ee860885b797e8ebe05daa4f3e9a3a1dd88d8b602638fa14225ab71c84e28aa225bf7b25e1be9a521c88f8085380a061d591c7378224c488a95ae67078ad7aa8e4d141bd1ca06facdff4cb2463f1ac915b14a1e79a4502af457d97afaed0dc48ba3f9d9b0d19251bcaa535542e6e4639c339933e182b07423d573f09d0ef5898ac7ff295192821991d46d4712bd86c6feaec421c85a9200730f8c4b5a1456493df8d38fd16d7ec2eb425bd7b307dcbfba45e1ebc17d4de428967deddb806ba86825082cea74733819f70a78d86e7452b57bcdd21121d6604e57bdca694c7546ba29162e678b47361320e52c6b4824ae511e454a37930ca74ef2b0aa2b22921963a501dc191b8a33005bfb215803fe6b0b87e811758315cb127883d2995fd093a992e9e1cfb3daaf85c2f541e44089860b7812e6d581d20461e167ae8a648971d9d3822508b3fecd7c36a9b7a44eacb78091d2c95a519630287d8d69d5a0712fee173bcbc95817d038a2e05c0ef879ae050f9371267885ba7560ced5807a6849a6526b85edb189745912fde2fbfc23e24b893a3312dcc4f9d350ba9e3d8b402917958f9b0c6d9d9cce8a29716a448c96695b359fc35c65dc8be349e46f86dd9be73fe5eff443276f5e7f767fa0122c6e6c32145e2baf16f935474b522dc773dcc55b42f8bc30ada183fb3450a94ae867ce579616dd2fc23d2b4f01df3f312f2a38d5f8909090673f2152159a452cdd6e0c3cfe4b2d0c4cdf01c2452e5406cb4a86704e8981df600f57f4637ef92beb22163f4cb50763f8a5c5befd41fed520d219c874f577f6af0798f15d4c90b43356ede317039432ef4f1ceaede7653b7f37dbcdd29a6543681c0ceb79e030d60c67bb6acda55aec11ccb854dc2c1f64534d2ad3156be6d636bca22125cb98385242012c64abe25c9b3a8e93434c88ccd6270756cc23d85a754a0100b8a482250130de3cc73ce441720b3e00df7ba3ea1fda021b18def223ef6849094861770229e995356452dac0d8dbb1bb0a2eb4dff881a60b4faaccd73e5277bd4f0f0f32b7d228ecdc563f5b42ecd590449a70d0b0d09d9118586e5784109a45bc3278b70b29112421918b5ea43cbb0a0d7c8cb014152b22419fb36f529a2f5f65891a713ed4d70aede5818eb17a3cc4b5f2c3df75d1917ba2e5685f0b52dc9ef67ade411d5aa8d335b6a4369c0312ebc8956756bc81ceda0b30138c3713b4b5514f4f7ea4d4ec6c96249b1f6fe5bb98ae92a1c2f78895cfeab65da8fa93fd165523394bc1e18304ba141499cc868d58145140af44a54ab97127531e4996198557b1b56454181febae69ff056737bae80c313281a87601ffa5013859dd26d030b12ffb136f3b5e9857769b280d55f9e7652130a886df741a439fc371f019e1bdc2547b768beaf9fb9a31907a9bc79cd14e4eea142e4527666f36878c7353e276ee2f5e8d019ba240ff6e0c8dc1cb130b2923eaebcd8c2c36283a7cfe2bf3ba2699e8a0b36cd0b7caa252524652443153a5a9d2bc9fef9801ccdb6f0ff2d44d4ddf1bb45ce147b568e81c59f83f0180e02499190cd141b14429cd88f389b5673a132ac568f22a5ebcd0f8888b74b9411cfabada132f6e2ac3eaa34d5a2223ff2bd9b98aa6975e95567fb6798afa72e6980c7b5aea26abda4400a13af5a327c6f8dcf1ffdaa5d9187c803d7acc54119424de0d487e0ef9420770f037376d94f6bd0361df2bad8321e2cc4e9197b3cfb1ae371a640849bf33aa18a5636a8ea931d43d5177f5a27ddd81cad350718c2aabe91e4d28d1be891746ae5fd550fee78bef0c0dd6695545600d65b7062fa9312099520c9f29e482663d4872b9ab3359034d6e7eba29473bb47451e311ce9c5810979ed70114a033ce7de7faf7b7a7048674053cb2728442b4bf5506fe670738ed32575869c1ea03af430a991b29c86ba68311dfaf95a03744b510ce254197afde81a1bf57daafb128425625304a77f7a903860d4cf62e17393c744ef09bc2eb242ea1b19615277ab1850ad164f74fbd799089b923d9b535720ddd5b788be5dc6ec5d800618a671b2eec21457dcf7340434cd5b5e6d467aa1a35edf66f6e69fbb2eefebc03b096abd44a7b84afa1a318a93033506f9c533c96c4be47cc170de1c9b754f24f68b9ab7c122ca6f2aa078893cf184c82e9dc404e746ebac449997bbe565ba102b08f5330128e6fcb88374def84813423fb98eb1623b41f71ba00dced6b4d87b10623dda2227920405ab6edac4d2762a8db90c6ff4647985c5ba9b971785ff9e2306af5c15b9771c9f0a2e0e19c254eb5834126f9befe7c2eba7ba20d2c7bb682f9a3e1c12e5e9e0e5598dce3522739eb8e44bc02e9610a183578a0d632c1eaae8031725841233ca25e8f3ed6eae820b7c7c1a9e4f38f6950ad93282e0a714d3835b99e1fe2b4477266d2220db592c25c06b90871a3a2b467ea770c1c5cf4163f2d23ea6423f04db634a70fa61d9185f09e2f2ff743279fcd334f54eb5862c780e6f7b8a425f10c8e4de28c31a56aca59ffaa54ecce1d3a5ab9a57afc36ac2a18a06e39ea9301b74edd6512fd76e4985b1439596fe3a080cd0013b53af1fc1fbdb74736103493b3c6776833e6e749bc9235704d29ea6293db588d53e9a13705c3850832ea9b5136dae298eb16a3cd5e3ea7e2307a1bc9933b30f237ca4233dba93b5c9b052c40b968ad21f305b26da3a8eac0636c55cfd0504476fbc09f344d2f06f0a4d0d0b11e37e72d93fd9d16f99d4d4663d8740b7439b171fb46cdd440f92626ce6a52f4cba6708c30173eed11b7edb9fe8f6443b4eccc64a8099d0b781eb7ceedc6bb7e3decd00cb60ede02b5e6206e36db6619def4fa856c87115e9c5ea76c5754f6f42c71deba740f6ec407ff1715e6d2fffcba4bba0d140264b1a0303f9e4819242120409933a7b873691f0b7aad9cb969664c14959e15d28ec8f79a73dc2a70f5608ab2022f199ee85d78d63be435b35e8a9863e6c98e4eb95e6c4985c72e04d9dd31a43cc9753a0ceaccddf76cc651c59f3abf8852d8cc51f9fd288e066814b0cd324b4c3bf1840de04255386db34460fcc3314e148ac7abde70c84ff183e0a6690584ca5ea5eee1ba0cb0978a1395f36f123866f4111cc9993770f8bbac7df8a5a7a7880371c7afcab427bad6b5f38d7368e5f9cddb953222e110ed527438126bb50a1af82f17f51a8e950d5569a71b38cc4396b13a21bdea1353a2fdf5dd0c393b589e9a54a175b9c3bc96591d9cb9fd28cb01c112b2e9e5a76744412e32300a56e2a792f369ec2399057c7b641e9872647013687a5d4be300604f4a58e8f9febbc7c309c45c28f6d3548495665fe232a8e3a4a7c8a434f8e3cfb0faea032f4be9de03fafcd762cf3064e526d3153651a15f0eaf94506ce1785ba7b90b47885c5b6935f6ddaabce1d00d7ef8c2c2298f9a50584669b74aa2d3d1f424673decc36804cecbe80a507e2a6b594d85bd863cc0545d7f3613addbdfd935e0aad91d493466d01f6781afe6de0e34309832f11009b26dd8354cabb747482f96a8d60a1a1a8bf319a93d2b48ac908a43dec81e0503eccdad351738fc93ab846987dc5714b13365bdfb4c1f984ebb74066cfb755adb5b8da27efe13e7d836fadf398cc7e5d4966171f494071ce3240c0d960b4da936bf04b8ba11cb857a1b7018238065147bed7707bbc737ca9afce00f5e8c95ca53d95fc8319402c2cb990a5355132ecc1ddd4d9a479eb2a4a91103834a2bb6abbb054eabda1e8415407591367e3b58449946df02706c444dcda0ca8efaa6d7d5eed7d4122cb59a07c81e437de8caa18f971eab4f5d562da6665547c73b51b6cc5ea4b30f8ebc845aa4ce39e6146570dca9f7364ac1e6823a9d3bc250c6f02bf536581f122094dd22407f1f9f625a93df3d132e3fd28fe4011feef54b1b0141de943fd6dfdf15667446e9caa0f6e58d85955c49831ea38ab49f7404395a7f2c97309d0247eb401e36c2048512ef4a2b2f2c0908e854e6affc0c13b20d0999fb223423031a1de03d3981304ca64c5a216781c9ef905918273de7ff9cba2450ea6762514c3963985d778ed0efdac1a510ce0129c8aadc0fdff4e734ad7d6e48e00eeca14c005a64e8d99d0e86385c681fc1816fa3d8b5c4616e7194e30e7e6e5fb1ec840cdc3541626eec130c8b4d251d55b479b6a16df400cf9f3b76b6dd8ba85faaaf2ce92179ecdac71af15500dac6be85fd1fd761382b50b9495f40ec49ab381f1cd90f4503aae5f702e441380caa99ec196626b3d18f3541211968adc867680bb2b76d02333e87b5f92bf83fb4504e07a4613036a454fcf54f295e4e04d9e9e588a2960d65503ab0c17bed6229100f984c507ae81c43d25017b81d29c4624798e29652952e9925214456b7dd2ba1b9b12e385a007bcfc92b8cb33dd41a48ebbf0fe16f1f101373d236265b5509a015902a28c4a2b14143e33cbd3f18f92901add4e60b74d756ad4ae753625137e8f08f4e8847d703b6c8d3fa24f5de0a8801626e8ef108d5142edbaa836274d1ac84bf0a095addf3fec6a8e125e536a336c39d4f042b5b0037ceaafa9a082c0c2b4378718bfc47d33be56ce6221daadc921f423d6615f5083af3011e95819c6d6d45028e637276acdc15556122d2f8a08f41bc64ef41036d569f4bad9b64a84065863ee5ebcf32a97111a685530e486036c6d571cdf90e1864519ecc9cc8617f14845d6004b5f325b06edd10e3de845cc0444037e1a34724860426328162fc0eb661cda85d3d9dc0eace8eb593d5c80276d12556a3bab58f596b959fec50d58e9c505b67014c6413414c29540265e55db2b3809b94bd37b4af52f4ede3cb286c57f2e47ec9763ddee744013fcda555b6bf505e29943088550a465d9de64319e08298296e46f355d9fb0c90ba210fc648578bd8281549ea109a9a6e2aa1547b4b1ee889a32d7559aed990fe364c2dccce47b06a71517679a992f872363ee2bbbe7d037769ba99d0d82d64a4609619c4c3e91d1005a683376ce56d972acd151228b76c742957d933ec724416ee3b5847a0e5ac81e9034e2d90d83d53b5933378a1231527e125a30a63b291f9d04781e33b25cf4bec333a040544318b10731f7274b3a56c13ce2d3076ba42dbe68f8081f755aa68a223b5142d926c2936b454c78011d5eb19c22d2564b610de4e1d5b5caa42ce0f71992a9271bb136efea3840364b9ee930aeded1ec236205122350a978bb2224f5fa2098382125f4e66c1f35236fb8222cdd3e5e2dac423e960abdd51e42a03789c9fd242917fee738f39091e3005931ee99b0a89f4c8b8bf5605f30c586dd9f90e42099ca415310afa36fd83461a3e8b10e330cdd324071585903772cd3278744c58274e6b84a83e8a737a7254cf79484aacbb1f27a583fde14d3a1213996316726454b5e2d93685a712368d2829d52778caadb1372c9fa6ff5518b8e06188f4e126b9971a252165fbd629ed5af79d756837e33a845478f2d360a0a7e9af50d13382d5d2f80626791ad2725e4af088f970b8cde17eb1bc44fd8acd46a9afbc02e553a68665788b271f20867c4311609bbfce9dc5ad843cc94639b4a04e81cdfff7be6164bc1d28cf305278eb02f25a6f0046151b4c6c39b2f395bcec656e4616a4c6c50e24c07e5cad403a69a56caf68113d21cd4305cda15c612a5f34a9b85c70e7bf3b1fbac58b984d69021fd79121deae0d0f388c2c4f0926ec2b317c91f6095dce1c777ca67af022392333da904eb265e6b252eb5f47f2f8c0ef2ce22a1065eca8b3ca8ff5171db685702e81009909afea852aa155745fec4ff3328c0c075459c17dc39bb970f583847bf0fee3b8c42592d79a1fcaff0a9fb46543b77aeaf53bd5837ccfd03129a76ec9a55c6fbc11949f619e8d474ff34002eda73a555bb45566b5a531df8f889944da6d9df4a0ec647e3904b1152e12fb773f80f662ed8db5c61eca0990e68b2be82f5b2d5c73216ab667487ca511dbfb00a5977a66c34d60e3a7a34d2a9662059f9bdc38ed73503cb6813efc78bad88557b0697ca0ccab4e574f45ea58040b5aba6a78cb4318cc5792c86b70be5d8ebd1c32f13a0f0be00db82f1a23744b141cc94e1b01340fea8b88f1e268c81f8103c0d32e164785891122aa31fb4af3d90e05bb13774cef3e7ad49f70bba24ba4018c797338cff5edf43324db76afac4699acfdaa2864efb461f52d44c1c161d2875d66d48e25941223e734a093a1789f26c684fa2bf83b08ce8cdbd6bf65170e43bb3406061e0769fd250aa21e085f314fe0ca7ae62ee265ed17b06e4bf19ab4d96d52adff04de1203c36d3f60c64396158abb7072a41bb1948d77e9c08ade61ecc145af5ff6df7cee34c5cb64a226a49a622621482143e55adc96ee60a27ece12474bd95daeacda8787cb951c6cf45c94f67999870dc2de3b053242134b3a47c3558b10174ef50eafa6d3fdc22bb3bac3e8ab693693d4f6014fb63e090752dbd7e36d80406d9fb9ce9e52b6c09ea088054b2a04a2947ea3c17090877cffc072169e2e9817e36a7fa2b5eda7115807f8a5ca0065b12c85b54b6bd2b000b7b8c9feded76b9c53f021fa0336b3930be75624ed6a5ada3d45e8f68605a5f817add608ae4adcf16cd8f360dc9ea532ffe0bd0f0bd5279bbca829d7c165c750d0b9dc273f1e5097cd3c90fbfb4ce710cbe9071e23fc91297dafadfb1d3bbb52b5634c52d2c0efdf221ec481474489c840eb986473ee307d1457a96b8e9b71cfe908ab0fcb654cf7f20e27b7b9ce615262ed89e6d4113a6ed099dea4af6a2d0fc570819cdaeb78be8e7cab57df30935c308dec13f337b3009466985c436f7e9f209068b8c3dda0b1a1bba29db2b79fa1a33a7daa410f1d2ff9e86d4dad9a1609f78b8019998377b3eb92777aa93f1e80bc101c5c6b7fa7fb183937c5e88644f5ab55cf65744ebb3625c250e5afafd5cd58d2a6522a02b0ea364bd748dc48f99e3c858d82181352aeb1fceb8aa3d7740d320b852abb80f0fdd4e1232d9d5e230a99861e80f1333b6d2b2d1d376e11607c577484b20e1eeb0bee47245c2d2f1f2ae7942c754b6f5e1646cd7579e674f959c34fbe99c8097aea883dc3e16a4d7659195d821c04ed40a586cfc5ae7b7a762f0f4ebe4707b35de12fa4c21e61f29d0767599e04c1fbaefb6c81c0a9e497372c311263981277154003c523900a11bc7e2b4ccb4748d980d1efade945f41c86acbf2a36e02cbb93ecdb1b3910e381b2ea7f670a8c76adce4b71a47e179dc5d5aeb5ce8128950d18302025a2928515948351040837558359098e0036d4ee387f21e03b88074cacd0e0001f89bf38f1f28bff4189c955d3434292215343d19828ff354acd78e421b792fb4fd88ef779e609d71a6f545536eb35463f93a2b05bbce10e00038b9d32475f012a08359efa8a39d44087b13ad784acae0dd0b675f8e07611b41c8f68b9cdc26dfed5aaf59dc94f3e6ad68c4bf9a88ddf92fffe930fa5559f477a275d8b47932293db60acde9b2535c55f08920dad912e93bcdad449ed48675e680252f11783f44e199b5ca4705732baefe10b07fbd0d7419f4d4abf652ca24795471dd6a2b5d014beb8409f14f74e0cb57f04a08a62d95e362d5b623f371f466e0277adaf9b56328e71ac35aa1a5f3526a2529abd3dd810d48df24c30846090e806cf269c0d220f9cd5e41db052f7596017f3135b898d646ba5b98efdfe9abd0533912218c47140f079acfa5fc8818537fcd25d7f1200cbd34bcde5ed202119ab13d3176a39c9d4e724491ea255f7fd952a8f3d760ef8c8ec2ae28836f437bc7bb1ab3476c64ad37b2450fe592a50415f15497439bffceb450b5e51be52e17c6301121ea890029fee99486c190608d240d98638a7a09fe24afe1f4ee2c643d5ae4886b9267217c8b4bef226adcb943e861034ad9fe0f1d4269922ac62eb740de0155be1afd84c9f293282f2bb8b68c38398809ba5727e93782ef5318103f43d19b56a992d7c7f1a27971bd5678c9884a8d97fd22e21cadee52949c75768e34478e8e6e485586eac4dd3ecee0b5f1bf701be39e4b966d9f36d9fb3ebb311b8d86891684c173fe4b77f500f0223aba627853bee3e50d38f85c093e17d35c3c4c4f281820ad4eaec469bedbfa4c941550c9d0214ae2fbec62951291d462328fd4acf9bdb18f440227f196e4cf3fa2ab2b7deef6cd8b3c7a7bf1d8612e7fa891f214e0b1fce8ee6029695bcb58754989c65758d496caa3f2aaf3ce2da1529b7eabd54ef60e90f08c8a87bfa425ad84e941fe4bd66b87d30e55736b40ce9a9575424a4ccedf68001fe8cbc9d68b0790ccee344257a985c3c61a3918b30f299574da1eaa1e0f52f14d9854d1c5913735ffe6ddfb9def1ffea38b02a0efaf07b7f7b5b28ed613aa96b04d700d08d44b27ef3118cb85959f4c27b315662477e10038391a3247c6b487e1e83951b3b008811a0e5b503ed139e00b64d7f79a077ac9ef58365b331d85eed9ffffb2baa2032864a95cb18ea7933ab857a210ee707665c534e034c56ff53bbbf21d5ba50be718fcf11b60ccdc657ce785bf2ca135f0bad4c27ed9c6d2ac5875759ff51d24468aa7e4062ff912a912ce9701697ce42575609bd8c38bef657c8599e6d5aa3e7175f6d868459dc0c1eeab6840dbbb813aa762bedc48cf3e541fac01dbbbdc2d16dbeaa34100b9f68587d3f3a162c91b0adbe445faeb918b2c2d7d7642b4b8e41e38862ee5d0364bcd925fea2e6fa9ea1fd732c314dcd418a66ccec68071b97bc5533b36f43f7e83e73c466f793da59e2b8e54e80db3987a1d694b434f0da5454ce4bc8d49a8f6e6e5e4eae5e019ec5e7cc5834c1685660c1158b06f1c24df744d6957a6a34a52f6b1995d13cec26be2c0ef5a7acbde8ff928587b99b3a844567c7fee811a2b39ea96126db6434125cce11e8becaa354bddf9ef9b9a935730a0127a8fc9f50ff05d1f70b414a2fdae930f16f227ff0afb1215cf414e20fdc1d479934305131216db16e31746f03a8100af9138f1582c491ca60065e1c4dcb3019eaed83aa38e3eb2573faffa9b4bd190cd07198d7e393a2807c95a9b47259a88a411b514dc742c065f215bdb34ec7ebaebe4dcefaf5bd98028b1e0e148ddac656a789acb1c0e5ddeee510e52016ffd4679c0f458e1f7433a33c37e188071928a7a084a36d2cb17ee420ee25b0b79451763a9cab3ba9bab05b6e24365c484e4d580e2717bc72b11771b6235055e203c6fbe9ef2332157a341bf7a159b749f4ac6ec4576dec206f4a1890a78ad0362ed140b1ad9ac1cb64207c02e77eaf497a6c2eaa1f95db85006282494ddffb1988a3135a7dfedd60213bde2b4485e999a4df17a695fd8a5018d60dcae02e3c0f24b700347c6f3c3880615c52c8b2b83aaee4540a2a8b2d94690741bea1eea449b68adf6f698fe4821b5fdbc6f19ebf633df97273789dd4a72c89b31ba6425cd22e81bbeb169bd8fd9896066bda3835a52b86b96e40c599e099304f47c24515fda6914c7f63612741d4e368d9fdf22fe7eb584c388d4ce6edf0ac4ede97fe78c8f446a4af9d5789078f902910108b9028c39c680a79bb313c35eb7f26f2f6b7e5dd03b5ae813d7b2b979e33fd809b426dd235ab6e228424e4aab414fe25c8e31ed238dfcdad0fadc49914ef27aa4675f253ba3ee2314c85890df8a177bb344c1d6154cfb71831aea639b215e5ac6ae76a4a75649c6a517e6cea21e58dc4308f2c8222aea2abc655574a28b8eda1e4a55c9d5f423caba6259b0903977a350e5b2d49627e0e1c1b788a1de9b23f92acfdb5b2471d019fa764538084afacc6592f76e41a484fe378a1d2c84b3b049db09104b2d4d3df36ef6737bdd527d687653e8d23047160c33f7b384e0b43f854c88d4d2fd7d6e96c4e38b33151ba3e25b1b94a2e7ab4397a3cf0b3e09bbe0ab45f812864c801e94a2ab1efb509252c4e0cfa0d403bed137be1c7e6dc1a97e591be93b74a04305cdbbe6e3b68a146b5cdef57196b483110450edef9ba755f25c89889456ec3938f71586dd66a5f247816c9869bf487f99e454f6ebf5ad9229daf325a52096b95cd5f0db11ad2d67a127bdbc9bb4558a86f373b8391344d3d97553b58139f3dc6d66f571dd4ad88c7e5cfdf215f4cb8135de305c16779d504d11e651a9afb23aadf49227c887b1682617bf41f54f5c3f3f9924945813a6dba0a056913862d2b8efa57fa703504359530e6a6316e5e3f737d7e3f82f3ad6d1b64f6d872da25b151dd512d99162248f5c134a8b21a932ed29daa0d35ca3c4a1274eb374d392a6377e5cfcaaa789876261ec451f03c7acd88f3d0966dc328b136d709d2a4dafa2093497a4d8f25546b89e661a085eaa0dc7c66ecfe9e9c8f667c8e7e42913a842dc848839b3ce90bb2b3692d5937d0d5e7e93904fa6d0ae39f8aeb6233ee8977d6188483039fa93910c243c5991b8d7a63a3dd7c97db24be87437ff12d8b7308419a27937593895a62a6348f91eb50208b91eb020c323199fa1adeab4fc2f69711976b5a79fd14edb33ff6ed6b8ac22e3d8246e27b2dd74b7be97a0b34609f5c539fad205caf2abf088bbc09b901288c5d783ba884b4845fb85b30a54994acf087b668f1470070616cdc3923b83e151900bfdc937d3e845a25c4bfea6568927bb6b284db61b1aeb23a34b6c061b23b7c2cbc51a68f6b4d55a7f0e5b8744f6bfe8d33dc9db5b8d2a01651e2de32d46f05d2685d324c36c4fb9016f96a92a37d9b794d14395d0bbd5269e54d5de37a0e623439dd37c1a01cf4ea79b550b1ed79865d7d7e5208115de3531d0b55f49ec181c47feb4b934321504a7a444f8fcf4d14f79a146c38c3649321f341286ed4d1ee2e148288aa2deaeb57b89ce229887f7bdc93c52524ad6177e5d9021f47ebf148edc21622fe5b7d35c45998766837cbd2ca21f2b95b30e547816336ef61f87cd537553c333a94be36ce9c957f74aa80c8454d314fd0edb92bc4bb5316004164ab36e477189abb743dccd7a7bed40f90fff4eb3904c0db3c1aa3dd5574308c15cf5af45432494f75fd53d5ac95b05ea454d7d2d91c8daf425dc223bd89827933d1b6e9c170687420b7fcd5bbce5a5173e5b2a7610f6b90b9dae7b743633c2bb5ce51a14183409f8493e2679cfc5dc848fad3a84b7f05585d46d92eabef13046d8e33cf61ebee035a645538d950ed8e4c450442ea092569eb1dc7a3494fc226fb9594c640f405d91f91429b39ad352499d0bcc7cffbac165efceeb3ac4a853a899f91cfe5146dd64ab8031037e6103a8fd7f2bd3c65946343e0fcd60ba6f15a9b4fb7b1dcc2bc3fa0df94697f933fab99b167346b3d0625e67ec918e9d3b77e43b8ff88f264365580f2a45cf7d55234e5b179a9c59cc16e6f6658daa7e555a23cfd986b30aa17fe658203f4ba916a94009d2b58a8cd84a283c958ca124c160ececb41a10126c765180c50fb92259b812692b4d0d39b5171cffe54d65e4fa094ffd6da0320cb106400d4ac69f7c59fefab49da329dbe64c74ac4b4d7c87e2010d3da5f839dae12c41a3ac5f6e93dc6e647150519652fdd08c42c3bd49e32ef677c5cfe3ac486030726c8f50bfdf3dcde4d9c54b8abd3593957d6c561e5f8d01b4af30dc3f7ebc05bc88cddfc9fa0ac77049229c395850a93add5a0c9d5d4a38288b284c7476a064b8a86547aa6ae3a84e67b80540df634db204d3e46071b31303cd1b9d1d3f73aeeb80c0b733adcba4bc07e988abdcbaea65a3fc7a90ac5a2b651fd82491e5bcb57243ed0ae028486555fceec1b06425281f7230d221d840565206f23d835ae7426c05e3df28dd3d5fc6f5d09cce07ab962081266b176fc6c20f807c8add40a94e5f1492e31e17112a6bdfc20ae2bef3f3528ac3ceba886a8ed520aa42b19450a5dc6ea0f4e42be8ded81683b68e1bdd1fb7371854bb591b637266ef1ecc8f37ed623c3672a8497890686746ca1be8fcf5244348ff2cd8970c7a89a98d079ffba4b59ac6926f69dcd3d6391b5fb00265c50d47acd8e0cfbdcb958791f54d970cfcbff9ef661c4eb4c5d1bc6a227360bf12837b47fc0cf130d5156cc17205e82169164de7dfcce64a12f8d1389bc08587aa8fcba018e9df861fd496b46e58ba87164420dbc3b50155ee1c38bcacf37fa67947d5fcc7f6d8ea4199add0cd090b5271b0f092fc539488c40f40e97a4db4964460d60eb6918e61b8ae51d2d8402e9ddc79d576f08534bbfb5801f661c429344f3bb9bffdc010553b19c04c24538137791f5d8dc8a5caba1bf3dc5e1927e7aa3a06d4bb57a5cc8613a0972c330e63668c579437567581008f513f822010d42a947bb54f5e4e540f9eec28cf7062b3d49e6d946086885a45c7dfc376ce33ac2ecb7e1338f57205e87910a1668bc822452856bbc38c71ef61a238169219d0f96001f2eee81729f757cd53a37517e011e3934342f2bb0344a540ef851bdf406d81f2f514c04064a7d6520f653d48aa13366561c1f6542614ca54d3fd8d65e2ff4a21fa2d14cb25f05d38bb66c2de14fa35e48e6f026f3285f6d0648c63df7465faa7b07af5e0ba774b3b6290716cb5e88b3d999931d4c72f9ce1e6ee430b77f9a05625615356f92565ec30d5fc81c3b04df821585ed78f3b1792d86b4395f0542bf1eb7d86de054ee350727f463499668e3d6e72ad64276cc282a97bca8b71bb2a15a872c4b86a6a1d17bd0c7a2273ca58672680268f81fa59f8d5929e280e116a3207f46cda195c89762dd4890de6f884cc0ada34441406d82297a3c2daa2f21afa3aa7d30b38fbdb2980f9b389b895568c55df50c3a52fec5fb783b97d6693d88520e5b7da7bcadceb1eb09b8cc4d7dcd647b1fa72e03ad63e70959f2c04aa28f70be4e73122dd1232b3f6db97363935d5ddb872588dfa652e96ca8150268a1049d92ca7bd3bf57f8b249e2dcbb89fc04e06acd406a9b8d157330bfa70a43745c3fd2f64670cd3103122eecf4a78881603bbb85e834fcad0bb6bf69792ffb32acfd68fe806e1a03d022c545d89ee4e49ffb11c9347f4e9fdbf95d62007ba363f53f5f64ac0bf4cc6797602022b53e3a0024fcdbd00094d315600082468be70177aa717032ca2d9f5731bfe961675bf0b87342dd1526fbf8c737c6ed4cccee97840aa8916447e10ab7f7e69e0f3a88f0a5357ce7af91bf62b42bdefc94ea2b48c9baf367b8e47b77bc41291228ce233f9eb7b0760ef8a5cd58ebd1a876b8f6c5c0fc04af2edba4ebf264cb4016928e68f0cf3d19936eee6cd9925858c08b268917005ab62a0d5359d78dfc83cd0151691702d5f0f068830fe6c82cbeade5607bc2f12f1a347a0d46464f728f7c9f327ffd718c1aad54a2e70ffe9343948723a04490e2dcb728a6fdcd95bbc0e6cdfbf9572a150b80524c31f4b731eebacdf723113a80ec85439c576e4e623bdc92f3506a7bb72924643144f322960cb1b77f537f0806e56fe5b107c2c3a53c2493a1d931450a48a3edf14e1ff2b0dd9e4172f554f1e41b77f4378974d8fd8bbeea446d35f02b234a3f581d3646e57547b1c8bec402e91f27f696e0be1b2c109a01de7375df8406dd4f02418dc72f4b636aa106c7e992e19481a8109006de55d839c78ed6741b75426390a8e3fc11b6c739a68bf9301ce7502eebe99f346cd70558151d35743eb3f4b0fc194f8d1c966009a7ab5ec9ed17769cedef373468ef5740b2daae3ae9d97c9065de96953306343d1a4b11c09c2c9ed1e8d74928f449acaa4565ac5f16bfa152e2385d899dbc49d078f69c888a6918031b6931898bc0b7ed252a0681e124ba3053fe11b0c37517c2005a61398f51d1b9eb72cda0bfa8160e92bbfca768657a967aea2fbf3980e164940dc6a9bab9aa7c9ada2d1d7fc0e35558c8032f794af2facebf35ac7f413c1b8a2e2162280c4e4496c4a905623aa7459bfadd24486cd282c300078b9cf98b36be294ed771853c36165f33330e5047852e5c7d96d9a683e9a1cef732530e4d5bb804a351d346842fd84cd05a35f9973b8bbc170a58d9ebd481d99f3d34f42234e7ade499b402b7183c29fee2378373deae7d55ecddf90825905999e5c85fe17a377a0bcc8570784f1086cbba403d59c0002dc84a9d7ed61b62997977d1f8be3b481041bf92404b3a62754fa08753cbb841064393a970c6b3328dee30072a5b1feffaa89ec6961daf2b794c1f780f874ae3c6ead76b2b0e59861d61649dfcf454c853d670dfa9a9237081feb71a4cb4ed8c1f8ca5ab99de054dfc79ffb355ba91d66029a9830896936c2830860d5b9af6d047d6c671fa8bcec4b0d2c237c854c66442fde56b5305453602d360ca0f4e0746039dc55c18c00c8638873acea36ea025dd641ac1e47e2b715f83fb68e564f931071243a48f4be0c1fe46a5ecea07dfe67dc58cdd75ecd7f40e5ee0d4972958991a26d7eb08cfc56a54cb17fd36c38dbbe871048eb14afee00f8c8d3e0a01a6d7691ee175b89db32ee3897a4893b8fb5cc41a8a3b76f8d758b2e4e9e6b1ce7a46632b4c43be634fd8cc5d46f86ef9e995dc4ee4d03927d74224516ea75d0f140ad60163d8b99d533d602014e7e2c15e21668fd730a698e6e7bbd8a56af936d6295114ec2662fe5dc352056b526bc34b142c81ab7d87589ed3d3e58bcbae1053bf47b15e9f57dc6d60cb48183b163ca12328704068e064dbf8862af079430e3f18296d9936dbccc57cb1fbec07c0f68d03ee6e6055ac40c3c698d6a1fa351a868e5d8ac1b0666172a43891ae5c078e43908f0cfceb87dba49489ed45d46bbd260e3e31d9156ac3e86f9a12353bf2903bc95272d4b6a871c0d1e03fb6e5830efaa4a8efe0d617185e32671e68d5d4cad5422edde48aacb39afe8f78a0c0edfc53080598504156d5fa698c3868dd730aa48ba3f3288797e0ac33ba4850d0f9bdb943df8e700adce4753aef2ce02e4149e6b204aa1413cbb8d0c1a0552c6e7995f563624d9d946a1d3e702e711edd36c773f0360d18af70a8d16234cb071d18d2acfcaee1ab27542382cd77488080ae4f1a613cbd62603283de52169c4cbb782e355b7ad1a254c0d26f718b4e86f018ea996cf61088743fe78df821761deba276fd24c25a3d8f55d39d561fcfe4b1fc2a9ecc138b97733ece046e709f2b1f839a515f6e8c5a3d9b43f34c9b9f018a5b1c9cf26626d1a452bf12389ecb4f8cc33cb3d5aced4dcc32ba0fc402737cf46295ef75264a81070956a2b5d8f341e250eaa0706a0bc971bb4c10bde0f21ef6b02f168dad2de006c92745be633fb9e8cb8d1b2c0549fed6b1ad9701b8bd97529b820df902406cbc30fc4b3a9a03068dcb4fa01950ff5bcfcb38c22a478d94894a786f4e5911eb9be14910e98ad26f0066c1d4d6d6d9eeb2a9cb18aa386f77e128271d926b677d6fb93d30eb26e37e745fc34bc031658504f76b7c6e42bd3d4541c82f3a99b7e21f0dad5aa05a112d85cba7f8923add92d63ef893cd75ae7b7d43af72fdf9b74263bb50f83cbc94b3fd46a376a1214ed8c288a127658fe529a3f36c9f4bbc63f6f62fd717c9958f4f8d4cfb0f78f2529526e2cda9c87ff435abc0b5af47c9b4b9bdb2510e61ae7b9185d48dc11a827c3a8f5e62d8e9cf6faa1d9d440df9b84a3534a80b535b0c3a9847e24f1397fe1f7715ae36a7e07760e45bed0dac8037e78a1e4c2c7521387232ef2c13085044cc28ec9bfb061c58a01795b038364eb79775520d6e8b43cb36735abc705a4449f7dc439bdfe960aa4b37ec66c7f43a09b7269de561a21cdc1cedc70bb992513c73d52ed8387b5d07792251d2dae03791bc661d22bf85db111eedd585f2bdbb01783fedabf644870b1d1d1b9eb0bb68b0cc66a20906878502dc5c2712f13d778c6ddf52441f5b58aeb830af6c3655db5809ed7830228b4f538f3e2ad2d8ac365d55cdb1b05a5c8b64c2b27d81a3aa564ccb111a1d163310fe090677b10a7a5c159047aa7c9025f51f9bb40eede4e9f2febb2eef6269f6fbb84a67240ad850ab07e79a654287a9189b3cfd0a8ae97bda16f69fef6375f08d0e5a5cd45429ee7308ff1f9fb3a1ad4e5dc51bb93c94d85c5dc4dd183f942ddb0a1ea6694fe7ad05f77311e15d43e52e0e3300a19d45dbbd632fde4785e0b21e023a618a38953e96e7efbc486c0d40dff1081c36f2211d71f66714319e62a9e9d79baf9b0d7fa08ed233a6522a76fff883da03b0718dc60b4b7c33225f2bc635336d02fd581616f5f9fd2b0341ac4d0e2e035bc0a3975b9d3ba23c6bb6f317395c495d7cf86ebcb30bddfb706e38cd0d2687005db412b08ce62efc7d893d223d7971ed8868e79784e7defeb87d634d87ded2d7550d403434f497087752bcc64e5973127395cd728eacb6f5a2ef0d0de472c92c216ed991c666717e2d685156e5c176806e82826d9b57a0f7d27ee98d1e1fe448151974a5209c6b0aa9bb04799b2dddd08e3d1b92f280330f25ae40e15dad7a430c5f02dce39d4f9098a250d60a445498e2161ce8604f005787efb4094e3df7a8d70a4914e488bf21a3cd3330610d8d68d60167609148f56c76d8ab8342df50186b34b7b25b0c0d1b54bc9f4f13fa5826e0f4ae4e5c518c420978c3a8734da5168c5ce206e3a9aace1f26646ae1135973988801b82b800cbde1a9b724871b7e40871c422d49ec4ea411a5a69a3402ddfb07556d35441a59d832a79e3f0a8013c2b90e893c281d57b9c5d40607da9774cc2fbc7451ed31627498dcc85f65b0ee8dc375a66f78c0fddb3add6225088d0751e9e7bbd86d11f8aaf13cde0f09e2d8930c855ebd4f7ab2dc788d4034408fc90d2f8ce795dd6ff6969421bf84aebf71ae46db605fb4d2f54d59e9679dee2ff29d6f94134d76decec0b5ef30b1b56da9ffeaaa5d35cefba88e78ec1fcf2ce7c8373f5cb8daf4af53ee059453e8988cff12d8bd7921ecfc6c54cae2961d8c25917284d5377bf3aee4b343ecf0b5bd641bc7c57ca6cbfb632794bd07214e16c15b17f28ca1386925653e80105d44d6a9171b25096b9b4c144f5d13af36e674613a19156402c26d24e51e624084f28432d10644688ad516601f7a2f03dc384787d91c469c935130bc7cd78a20a4e115f61d92a88ceaa4f8bf0cb191ff9c0fb1419d1bb04d3ce3645195c3702ba0770f98dccf78899f1e696050c7e992c939961009ff1bef1fa82897de9a22e4bba10cb08bd25321a205088ab43725d597a31ebf161d882d588229346accd48d6cf239d045ebf17a78465788d0646f6a05f5cdd5018567d6f82754a766e9eba91f9d5dee38061dde73b7b3c7f5aef09bfc570747d2728e50a9e90770c6fab6345b5c48623d17abf983a0674673c0af0b47172d638ea4d99b73ebadb519e042454035e0dd027f71da98ef1d93a8e12026b53ca6b6fa930ba42c7d8adb107b18553fb4cf24921c76dd3e8ecf3c877587d27e2eb7873ca9fa18db120ef3cbf87d3e451a7d020687d54205178e7ed74a6fe74f092d380ed867b4f9a9920d402a678cd9638df7af971ce7d624d15f83f8d7b74de35cb6738f0fb760c2dcbb2c851ee11b1435ce8b4fa0770004c00f8365454771bc4fd259585c33f677640d39d435f8a59c300395f818ef8dc5b12ab6f6c4486e1fda0a2f283257c97baad025aa2ad509ed0e3032578d781244244e31ddcde311dff808eb74f72454bb6ef5b66cc10c174fe562c49f4f35b494d5806443c3b25db45666170c9b2668fcee68cb1fd230caf311fdeec5ac1bd8feea75ee844eadd318ebcfc7b4fea4a12ac40eb40cb7ee3affe4762cd0abbef163da106238243f440a5b57fb6ed58cf9f7dcde617d4fa3e369ad175a3a96a84694980ae20acd56f46224e7ea938c13a1f961b54f111ae551fb95dcff120f9d29e14a94d8a15a2fd2a480091cb9b010506ac603c85f67d6f8fb32ce079d072eac2c673153a589344f55d747f0c5c1e31931acd5fd3e03c5a9252a1d38ae113572c7a7c8bd1f6b5d6f0aa0bd35292f20930707992cf901425b07834e19757c313e3edcde5d509f7a490af1be1eb275ca811da471b227abd293d0c8bfdf8570a07cf2321a6413a25a1808fbb80e951caa3ecff12a016825fce3252d7f92293c30ce7cebd3a0ed80d4e1fc5ee34cf414a36d489d4fb4c1c7b0d19f812e6a670c77a9bbb6a2d1a3f6ceb5276bf09ee8ee4a627a6b9c12d81fddcd21e6ef0e00144247b47206b11970a89d2906fae0bc5fff5c233f66842172230941e8b633edee9c79e6d861a1f5bfda9bd5114a0d0e7b02d61e42773afd44af40000720cfd07083e2f9ce9969e5e786841e0610da7959ebae66cf1723537de3dd1cbfaeaa1b4121ed6ded9ea941532983299265b5d26b18b2f338e6ca3d0ce431ea2e2ab1e4cc8f1df4461b0819c7bffd36f3a95879d0f025830175161be1c2a3fd0febb326c566186da03605466132789c01b84ac8b9707e2b7836e6c69482a6524e35159c07d5be4be8645e17ea7dc2c244b161d46264d6613a885a1a55b249ad078e4988e8869fe4f7e859d585e2ae53d61b96e3bd8fd5e19ee9ad3830281e7f8c10307b00677d0d7aed8f6e5bb182e4286f39b0d9c112064cc4208e8652ce8472a6216af4193a1fb28844d2be51b641dc8d95667f69e49354b0e738c94aa5f332bf6ed31002af060bde9a298c5d183a77691cdfc0e03edac668f392d65da8ab41cfeaa8f4b930a1fa75cc04c06457187d94c89f7c99a552d2e0da71c1ae93b2efe3536c512308b88fcbdfeee0859d32e5a548c5236a5f2322069a19bb349098caabc58255359817dfc09223bf620b38df98e4b376ba434126fe9d61273444b5bb98c6159fb98fd5470c33e2a865c1456e7e4773f77b49d5d4eeb993efa7d11e96a95f0cc93541ebc928f34ccd381ef1313e987cab56da4612294fbf04bcbc81ab5541b157da009efc6a3641103383b1d5d3fdf9bdf4630a5f343af9093d950292e2b907c16c59dbf0d166598e056ee874dc22ec3b2d79540dffb93a1d000747ee82f6eb0078e78de372b2dabb8a073f2405d3e9d91d7022c2056ef6e2747177680a852a91239b3871918d2d49e0e272b99f3516b10387c95568c434fa8ca8716ecfc75584c29337e02298b195479ab7fb393bc1a651a04e3a9ef8b396a0178d48e8e5b5dd937265460215ce50906d723f433151b9c7d96c850bbe8575c2b4e1c7a814ccf52c5e8f2e064197c39dabb04add3f10e2c4235c68c5ce40ed9d9cca09b16433da9aae930a62b715b6a8ec1e21e04139753dc1d74b504d64682409741501ff036509e51dcc6244336496b2df6053370289ed751876af5ced4136975ee4c0159750343b199d7888beab584621556a5d0181dc888a8ca8831cb44a483f7ecaf363c52a21c69af01e4e2bf677f2c16c888e4889235a654a5d26b79f7c36eb878ac73b1cad5009131644875b23371c6cf9a0a46c3228d45cd3b2e1d5350485156a5e9c9cbf9ae286ae02d4211375bf652bec5a8ec4a77946cd087d36f24cd619529fef560d5bba0cddb856c01279a0ac2b0a6bd1096ff6313e36b6bf179a2be8146801fac2cdc84f030147454c4b28eb798e24326b25f25c4973047b2ec8aa06454dceba5d7d85fdfc39302f9d7c9127a15cb9cfedf0955aff89dd11da3589ee5a90fe3ef08526dd7bd59b5a6401f610e080f72beaffd84cdb5782ebee809231f616cd5f42427cbd31b18193e7e9b26ddb44da7a1fe91ff913f2217f7ded224ac499f287ffdb618e990ca44f59f26f466ea5af195539e074d0940f399cc67576b96958b98987ef77f9886d8f22c37cb1bb2563915783db6a766f15affa4e5f149aeed4bce9156386a8cecc40c672c55928a6d4da198166ccc23c38043c8a76552de74b33c43565fd83d44a8c392636ada987faf2610c1057f56697515d684c98113168d1c9a37f52ccba4f810bcd5ec1874f873bcf580f9d1210b99b7aa5310d49a05cbfef4eb5b86ae6fd28c1673167f369999f2d199df3485c65f0d82a74b2aa136c7b697a8a99b6b5227dcc1be01bb277b637ac92c09fa64bbd9da4049e0ef961bc56cb932133e7dda6cc126a885e304db9eb9ffa9dde097522469fbb40e448edd6810add860b0589e83369ad9248077d3b85a692ea4d4211435a5913bfdf4275b63a26c30b74ace7940a3bb97b2001897ad5c843757a57cab1516abdd5c002d5390f800e6eb154583785967c871723c76215f63172ae2e0399fed3645f9d80abc457716ba35b196f8dcebfea3f3c696ac70eabcd9f123b8a017c9a6a49232bfc058cd5306b2a4497fc5136b74552cd93e93bfb6a28796efb004db3689f55bd01773a9996a0df6bfdf678deb7676496d6e59f0e750e36f1567de46e273b4e6d9963ad30fee9c268fa218e88114fb17513689893cbacd473f3eaa9294cd999558c666981d5ac01ac1759310d85b5954cd22439f45acd7087b33028c44a041b56c704ebb4c32df05a553200a6b699c9216b07926a13843a01228a311f2a9a95fb417f357ec71eb950fdfe16183aa8393701ff2c0d8856e99f3375ffb36e5b484e4b8dd24bfccf6851020c9246017cfe985fe936ac957d32b0c346062904313f62bfb9ff1e8d2543ecc6831418a169c5986df5d91c6c77b3ec8500088483c2d0662a203f1411c6e543cc569711588789460e8d463c5412044ce9b807b6aefd156d502e59538b743809501179a3bc7c83550d64069967eb60d2e29a8ac672086e7f4741a7fa66562b6aa65a04f185d9b214572c48bf9525de4c2f5cd80476ba8c8b637f0497ac7f2c9e2d7dd32d11748cc03f687baace967b415690c4b39bcc2c35ed2e4c02bd3d3632b32c347a1786272266dc4087cead646b5be69dcdb8042d6631f463e7b39d0befaeaea24e8704f13a07b14367a584bfd8acbcefb373b44c9f9eaad09af96c3e6bbeb4c9c11988ff0ea631b89adaf959f28e83eebe220f38ae26a92db76847de372f63ea399b891e1cc9cff2eee1a576bebb4eec85f0a829a0f106452377d17ec985bbda2a910e354c20a54e30d58429d29090e8f3695a07732c3690f52d68d6f51935adb8e55b924d0727d02217178cbcfd73cfaa1470abe1ef47f1bf95bbfd1637317501d8956b52f318c544ac02368e586186a3c9a449089f0d0e864246f3f27680bba2831a64a415d3659f25e9161eadd848ff05b1fc4ff382a0b56ebea57725cbc345633720628d128bc1971ba80d68877bb324e030b6d68271e31f4ef43a0e5f0bb0cb1220ae55d0cece71707dd8991fe056eb0b9b2d9beeb81e4a00bc6a298396f6a3fa9293e7803c6d246cae7c1159bf4106077277fa6457a3d108bf4df7ad0538b28ce85d2be4ec19bba57d7e6f69813994636fdbe0a91aedc50aeb353451b036f3cf938cb374a452131ae17d6d0317cb68d2357a2444821a05ab9555714667612362aedabc3603b0a351ecb3e76c990b48e52a4ec149a64f904319d5b1c3aee45b0ee792dd0c9127d871b2f234f060323e4c227fb746a0245c98ad87ab73041b1e160c53d75e0085fae50d1f69e8f9a351c713f8c56fa7c1a04389839b266b70c9b1d1091aff177423b0d53e8d8d90b7dfb98c388fee5fc205b5ff902950109b9029039b78e8a5c3e5f13d60f52d0f1b307494d2e166ad138eee1f3a8ae73b0258863ff0acffa4861eccde9b9a8b3ebae04ab48567b33ffb4d5a63a7bb6436ba4a3a14e232cbe6d36d3e9c281b9843056141a0dc0de1d5cdd8cd0a7dcf459da57dd191acabf176ced7bc981414869c333485b53cdf5eba9b24ea5ed3df4aa0a1c77bcb9ed19d69272a6ae9e0cbce593a5a1702d1f2133350de455a035e4f6387e318f85a27301719a270b50b4c552a29872dc55718273d4d49490c0262f5cb6bb76feb09b623187f1c29b4d0787a0e05fd9dfeb03be679967592e281f2a21b4599af6cd8b16bfaa77b048106214a2681b4c2bead3c21206c6fe8b3ef0660c91f8d4671d48efb7b62a8761a542eb26f30d0b4a97d3d559c374a328318b785c1b5e5ebff88b1ed29698232d63c347e0c06f10a58b10aacbb4e7dc3f4886756488b9d2ce46150b66490cad81e407d6392d7f36ec131b657ff333f5160286bdea3c77452593d0ec93083d47229bd976ac82a051ba66e3e9c9c2c14a91ee471fcb3c3d43634a3e52a6ed7d37b4c8089e7ebfd6fe6535ac7f2e6b2ef2af3ff37557d461a15768d038f50f22737eb168a44bf5e96187bb911477663bbc93c29bfda3ecec032cec27fd1f4413697fba6bb31dae6a39582ef04791e22fbb2b36bb44c0a3473bc9cfba2ac80e33e3527d94c36e886b0c64f61793cb256d313bbc68ee102423eb8c57c8b8c0f3e792ee8b3481658deb12aed027ec7bbf91c9273bdfa293b88844f3a56b659c4359b812e2fac35fb86241b8e644322c3324ea51ccfe8199a3e97216983e4bac9bcc7ab3a51d9c692189d108ce9123b63ab1a444c9b8aed41a6c61c8891e811ad8b6c204eb284b2aecd7b74d0b62bb9c38c49a6575b644d6b69bb1e66e2d06795dd1b2acdc552dd851187df2f91eb50209b91eb0e3fe500cb3f7fcb95aa6556d586cb55a3129d5877579f7b777a26bff543cf2d1357cfebffb5840f05e6d65d8cc9992e53fb69862b58fdb3f6841d60a7a649408d4c69c9bcef940aa33fd249ca8591fa962ad1def4f2da09b108b541ccd49e22b94a42561c400ef8b49456d4f4f03c67f9b67d1db5cc65eaa4a85cd2755add937c74694a4588a504eb63177d82d16319b65bc400867c7c9064759ba25b3bb25aa1a6ad68c1d109d12d472cc7e056f2bd59d45ffae567e808ca933a6ec7124b01c29870c32166867ee993a20c152f7c03a309af2908b209ba4498d0bf7e4d566a45a678f7af2c375405e0e39059ee582b5b663523123d85f5fad18a1fd6c58a3ed378d4b0cfdd864701a969714c142ae898f06d1a25b53baf376cd17c42e35c29777425c46e6937f6feaa6a01705fb22b7553794991912532dbcfe19af39d11b47e58c55e75b6bbbda3c5867cc760b235cda0b9fdef8de04ed949178c02080f9644cf9053dc7a6e510261c6173f71eead9eb173ddd724d5e92c21eacc157d3d9a92f4b5a786bc7c1b94280a1aa6898118fe4469b9545a20b425c9c90065a17bcf986d92d985cfb316691b9a2cdaf3411915022e31e1b64277a4dc9f5490bfa5220d98f2b05f26767b25588a8fb2322f4990628749097a67857d5d0388e916c99fe6c506f8eedaeba6547bd68305280c35b3f4254fccbefd899ab64788c424762ffe3c0762aabb567585ef2a50d3edd806fa22cfc30b6ba1a1eb8754e63234cf3468368a5790df4eaafd0f20ff748961eee84453580070457340d3b329b2a5550344ab0893031edd2b1026214153bdec09bf4b14c50ee8929580b46c6243ae73ac6beaf872a53247427ab90c5898aeed8fc9513e1d2a6a646a6d738c738e3013b159b53952eb8a1e3416b603303139bb6301d52e5037a04b0d14677b2482559d1d0221f4708c43ae5f85d9f82ef01f3c6cf817734ab7d1e6f7c8725c1bbb61ce8e9db6505100654821f074d497b875dfe4fae6d186f31ad6c2a0f464c5cee22f07359a995a93fa2eb65fa69e104cdca2b1cf07928fa9039918bc2a4542b2682d9fd3ca967fb3cf9609182a5c649cac9e45ab9b92cab5a729bed61fd0bf93f4bc916f58a633e04f189019757292b739003b451a3c0aa0e47a276e42343d91a9111b8093b6b5f6ff60ed233ad52f0b7de82720088e599c882da37d2f39a05e0952fbef82e145bbb781c7618292f9530f3ee652e38333295f2d0bb7351f539e308f4abca6bab38b6ea4685c4a68696e0b3b26b1df4fe1cb3ca53fe3c1074719c35eb4787c6e01dedb08072fd5e33f3c5d1d2c80014c6dc5080003e82af6d4830dc3360d219909e0905761572270b008877ee4db3c87bec1a4d8fe66967d9c8253f7a3fa9adef4a7aca25c7ee5d6b5b4ded349bbedede20787ea9f5df2268c9a319a6454b48726967f226c224c223554e8b3861ac1614c8141749179ab8b4c265b7db7d375cb5c9e7a7af87ada70fc6a7600c14d5f439abfc6e303450d428cac17365cd61870a971406a82410c6c083c36cb1fcfd48f923c9a6c9d5f35e2891347e0f1b1d9508e880a639edc081a3aa56af40bb9da031d5414e069c18b6961949356c30dc8bda3f060a8a996d268b2d057760fdfa0369bf610db209eaa74488e7d98294e8199f9916683a2aa58de7710418170c802f1ea84fa8a18aa7dacde5e6ebea53e86a61df78d17a17e9e8dbcb170298aeb72da2bbb6ee7c8cf400707704cd5943d972f4f0ed0b889e2609b0e3dc85cbb371b4e58182c86d014c4ab42baf72babb6d0d78bd7dd7aaa261d3db6eefd180a0883a649d980a53ad8054bc550ca453caeb1499bf57b2f7d2237bda327bebed40f538deb395aa65bf81bd27ddec9d0502aa7949b4e6190c865367cd3a9d0d15020899581957bf1569d6bc33af8810a0c44307d84ac01af1664c6bb7be3c2cba79942e3a3561f9387b2ed2a5fbd1bc713cbe0eb8c1247a37dbdc76973728aa0e2ed49af2679e3577d8fb621a1893f95c73a193c60357ab6b388cce3accdf4be662a2049dcaaa95ebf003899a6e854c1fe173f4cb8fc9019d3cb8cd3acd9696962bbb2995499510bfa6415ba62e35e59171779d5c55a3060df08486cb5afe971392246cf9ce64ad5d2ca57ff3f2147299d5b34b935d3975209cb2b26d6fe43b8129d4ccf80caa86e3eef5a77e99de2cc9290e991d5a720d3a36290ccb7941575e9b9e14adf1cf508a40b0980b701eb3291ca3a237fc50e964a146dc19abe6bca629ef9053473131c2f5e2cba6a204433accc725a354c06069e3ab0a5566130228ce15826a9529cae5dcf91f7560c6d45347bda512a94344f2c3acb5efe9bb372ccf8f98969c3fd23418654da43bb5f103e306b9c7e086c2c351d5f7e61fd9c0fbb08f01d7a274cf0f3f0db936fae4929b3107b623e9f3a102aeed8f66c47c8e522b93c54965ca766a98ff950bac680c8920adcb4fe7d6fa0386c3f15a1031783389e898dfdc0195356d14c7964d7ac1c966289346f76ad696768d8c35c96a21616f3b5bbb25b17d30def2cf09e6d1ff12290a89ab448ee144d675243aa155849982ba981233860dc8a8cf75d850c65869c5a81f64fd786912070f18a19b7f9d29b33186d4f4559c4c354b8b00616a9f002655e51d228e8920aa497c62b01d5955a1985fc9a78e2d1ee1bbaae1f4ea8f973c52be84455fd25287f1965d51fc58bf8bf4dc87e0fd0b03353b8b9187bf672dd8df6cdf5d226bbf67a794db5828fa53bc26dc2f1b7af503f1d1ba0802602e80423d4a979fbe713db229ec0d1a9aac5573a64fde162edccd6c5a5f2023caff39b32e406b13c8374417df7d3c227d7c2daa690d148aeeb902ce887de353dd95603ae571d9725a5aa3cd94eb477e0a862ee23fc91388a9d7e868a6bad06e9ed6b282a88ceac24e02ca9b139122bdcc711ec3d643de8836c68e74cd050215fb5993b9b25b8eca9f511332222acd7426d23593ae6c3f41cae561b179063e1ee8506184d4c4c5b5d767b3fc085f37f745554b0011fb54ee2caa3270fc52e61d8c80be4fbef797a7f0901f52e3f3fd800e385d8894fb7913e0fc4098d65ce133da97b67e464ea144776735f9454631e394a5fbed7a9f8b45481a5e82c02f5aafa740ebc60a1456164b31b14ac98a8850a2a2f0cadcce8189dce4510665f9a2f12a32a2d3cd737da8c163baaf2eb4be70603acd7886c9463009f1aabbdf403dfe7836952b24008832806fd7e7bf57bdf644f49519359aa8b3185b2758d633223939392075b49a862dec6c6f6c4a8338513ad8d3f29c6a398c1927aa7f5fbd1c7442dad8e30e8ea81484f5278b840ddbd87856b93efe85eac82500f8474f24f023b5185d9b66491eac6c4bf89a5558dd95ec36d6bf63f331a770deb78a796efc3465b354a85c3833110d59182b457c13a23d404c3cf3f06790aa43a201fbb07524453260e97984490b8c47da78b88d790235f2fb10e133d43c8f78a61a720b70a5e642440bfd6c59734b1bc8c49ad49c423d4740acf4a9aa080b0e1624f63517451e08d565478fce199b0b49654c1cf1af5d5ca6031fc381f480af7c79a2d324bcc66d6262b1887a1ebf010f516608e2220ea060cd2003e0d1e63ccbb65111c1c5ebab7b3ac3788b8f6e4eca66b0de17969ea6b07e38fbd9d2bdb25d08b8a73b4cae70f6c2f5f69df3fa0bb50b0254d8e64939044ca90d9b44a9843e397922fee5aedc846f828b92f11fa93ebbfe2962ab5bf0b8d656172e8f3d474afefe1af476bc956ca3879095f9ce2ba9531fac340e316d542a50f773ff8f3bbf65a6e1299af5c21501e58de4f7d32ea16032c3eae31a422065ef5a7460709455886d6039c4f1da3e47d926770906a0c6b412a83fa53485c0e7a091b1b97f7d771fdf6a2c69d00875bf7d7ece92825d79fe814a3e90edbc839561afa3d8f636990d29c437622d72e01ab446187463c7dbf9de4dffd6c6097cee0c72d4dff5b24cbcc503ab4e4765f3b103d83880439b9e31c5be855aa37f95a78528f1e16e8f26bc2bb430e0369a5e1ac07b044bacde6b70e2cf58fea33c7d199de02255223494a60e1239bc8c681702d4057da6ea1cf2c861259a4067f2242e55fc96ef7776c3883b3c15f532b35be420d7e1bb9d013ebe603e3a12f9879d4ec8896ee3e8126abb69a5df866ae90cdc9ad6dc10258a9d2198462516984af67db2ea3a0cea517f5c3f460a6d793deaaeac16da40a94f1b14108572cfc33962ead0bbb35d6b3d68536df3c1908eaa15894375871f667dc594aaebd1f251e45498dfc15946db9bf625817de058984bf2b69522642dfe90dd3d8d5c4f47af233bf2f8fc5d2134c91e72a674e33b605766087d7883604c41693c1eacd941f4ff8a2a74b1687da8da917d990a58807548584ce53d2504a301c1f566169055999bf6686cb0d2842cd1405b7005da1678d9d132934eb987ede405854b72d241940aab571c4b08c80b04ad9edce97584df13a9aa271a96b7c7b3b5100b516c7a3e2e3deef7d5d472f3188e6533d445feedbc790fc303c46a74104cac514735eae7ccf4864ee1e8917f096ee632ce9766667480372580ae2bbac3b0203637c0c3b272bb181c3c87908b88d18d69ef5e6c5ce198c78f3e7bad2b63e4ba107250719b9b7143cf2c73a6dfcbbba6064812666934634ee28d58b711601c254746589ac2e630c8d60e794aa66deba6b38730ad96cca0e6aa083d6a9019da7eb532652e2349dac543daa743fc597e45ccd91871bb2ca98e28cce308b24c32928d83a9e8cd87548555c1a6d700503bb1186f43387ed13c7b779beb312c0c501dbeb3707b266e5a1b889b35baba83344f8620af10643a5db385981cf923879482e2f45c4607fa3dd353734a7427d464ac91df52c0967c121b30c623578e739696583b2e963dbe8789e54f20f4215fc9119d155a03c73bb067e7d6d0e02c89c00f9deac813e2eb6fc45a4fc38713a9cf5c3ba8e30b93d3f6f6233310d2f3d830aeda71adc69c76a8bf9cc657ad0ba20b0f0ad8f0d251b87cf0c88eb464386afb57ea858ab9833c99a1d46a066c749fbac990c2bc96403298cf738faed39ca20781d36e5489eeac2cea6ffbba222b2d32d8197b4e31a1f9737d6e1f1ca256d2611c84c0d0c40dc1efa1f25764b9372b623838000314b8fa11934de5018e82408a690a5e5615c343fa29328ad48ca91a40b5f6e7b971503785e6c2fe805d39b9ce7d7e8a740d349f57f6159a5951e79c20d04028b5cdcf0f7e69bf241abd178f4f7be9dc5bcead15d0ebb8b1e4f8ad15cdf39ee5c5f84a585ea82b9ed5de904503d2f2f919e6a4a1601ecfd4a5471dbdaafbc700e7b3b8ca07231baa0440bb513c8fc1f9c3019a17b4250b9c32ed9f0062475da93ac571e4e099f9ff8c3150e2d372c42dd459464afa90662db35784b3367c48dc2305fd3ed57e2aa5ce07da5b047b9ee799837f3838c2dda31cfedfec33f1e299ad3b3775e037eaef507bcd12c65605e1d50ffa61c1fb581d0430b98364dcd413785540ea09359ff180422d627f49b79633c07002346eee43299b42c648605db86f1f119986a28b68674edd0e34e3d819d70d7d08de45ff55f639d4939b8b54621b761da8ec6f9f7de52835aa4fcedc2df4fba1cdd4f58e69a224e11f2a57ce7a65564d7a7fa432e9eb8c20ae2e1dd23b1bb556ec402ad16f9f65aa5cd9f40887b4d820ccccf50492285df8d26093bb8eb86e1fe144b696099c892922d645daa0b876fd805fc89fd66880b082d44636a084c2d6377f5f761e3d2cee6a25f883368f56b9608c98cec05aa97aaaf6f04a4c58c8478f3b1af233453fdd2a842c42c7cd3384dc7c52eae0079934f75d4de0d914972d9ab17c26cf5d345b5ea6b065b3f27ccd6517df39d84064ed508dbb281bb42e66b9a49ff5e8d8567695f3aa6f4b5693de72e93ffb49e6fe8957837b3b75243667dcf8b11353c693703a8a65ba93a682844fd1c6c78515d15737d562aaaefb3128d1c027911d39949b1bb90af0e032b843b6dfbdd7fa05eee2f38e6ccc3fdedf81903c004badc8ecb429faa3929c7eb7369f1bb20163c584d2206ae33d1cabc238cee31d745f78e009f7b04bc15bc42ae70f40a597ff668ac0e52a40b632502a4f9082940dd1a002718b260e07ab237a53a8e26bd72329c796edc1df8fe41a401bf0672554571a422d2b5b9d3dd25d9871f81198b898e7e57d6cfb34677f179c48efd2fc1333ba9fbef0efdf161595a22f0ad5d6544f9fd823c80c12e8443016a98c57a2095544e1526b61277819cb65ceb40b7f8ac25f28ba46deade921ebbd9fbee47817c318287ee4b4e1e8f218a8dca19ad19bfb57b02738b32a36157f54a5dc7ac0ff217579771a06b44a2962f05c42f0bb7fd19dc4a199a93725299a44314c899a5015e66909df072b9c9de9b2f91148d4cf21f58a50f98bf1ff3dd5d7995f51b435757fc8acb5db34f864189bed838efcaca8b4c0be5334fa93bfbafc38823879218b22a163aeda1176032d8f18e70f74a4aa3a54fecffb9dbb6d8f91be63991a97d17c7e9addf6811bae3e0cf302b66b59efbae926e5aca34d9fb7bbe835899f8d1072fe95be279e02f21fe439dc75530c977245c755c484f9665e33f80c3f1880a024c615f1f5ddf1c44f560bfd9e643733f6d7c0356f2c4445a0f6c9a49f174391cb1099e7448953b268cec73722e32959acd8a7c509a0cd41be3a50805b06107bfb274bd591b554799d438fb28559ee3806e01613577802d75305f15cb486ce42ad2da76895091bf37e1df685e2bdad18e1a74d1342a72fefe306307cf8b057b8fb7b173ca2c8db5ec9893a273854a415dafabda4d46e632334c2f5ebb0c80fac0ba5b2e8ebb0c058521eec4cc6a3829d4f1fded3eab03b909460fe92f6aefb1eab39a2713953f1f92879a5cf5837f7630f4115bb49b7cc8fef7148c095c0359570c44bcc0aa13f94d4213cdf0731b5b63d75737af5151addb0f542a9b86062be463090177978cdffdccce10d0e569bd0944bdd2509674a78266758fe1ed098f520c1a38d48d7641a46af7de1559a7b7c678ca507679d4614d5f599bc803baef93975d49256745eb1039ba9de8fb1b45048af68fb308275dfd34f906110d5ee421c19e4ce9a9bcd892c9a635552a938571ef5e5d906a5cc2fc50e36a793be3b666590c2bbf3289c0e7a870312d822604f1d962ee7d7b5ca27c131f5c7a8caf638916653fc0ab3deda6bde1b9b171b484a2f734091d2fee788d00fd1dceec0cc40bdbdbc3618559e114e5b77e1b8a5411c31a05c1fee4ae1f159234fe2206315a0536ae7eb73db3843c69905b329d40f62d1bb91d5a96dff967b7c589e7e5ddd27cb0da613dbb905a9ca0ac17e0317f31e32fff197aee8298c0f13c1ace340c20e126a326cea9bfc69af388046627a8b15b21bfa02602f33449b84483266fc62ded6fc5ee4354c73ff4e481023c0c875b5a8524ef89f3af6c1601e1145be44f57973b9933eb2569ccf63f7d0198333dd3f89c5d55d35c7859efdfb1dd9cf5d10bf4d52e20fcb20920cd3d3557441799bede17a47710b8f45303c693e49f88576c2d4f4d32859d1ee928cbb566e69ccbb6e4ba90174495248bca508522008b903f00f66f60e656abd18e618a8ac99e1f1778fad7bcc11d52685a75ed1c2653e789a330eec935f903a76df7edec58cc875338fcb010c518cbc148222be65cd411a012961ee0a563ddba05b544298dbdb59ee65872d7d3bd05649e07c23521984e677a8a03a2e2300aeaacdf87fe4657bc6abd9b1031e36e37314eb3c596b43ac22187b9dbca88d272d58da03a558cd7f45d4b76e4e1c432ce2867d2bfd902521dc7ad753b56cd43c4af3d2c29256d895e49bf2b47af2a7e15a69b1637f79df0cb7a72a5e3368634fcf4448b3266da99da36230340533343fa252acaecdc1151d44b74ef9aea906ec0000d40ca9b2d32e0eb2065a524d70363f4ace83979160f7a412d6b51b8b329caf8d4feafe4f75d196a3b8ef7f14e8ada6e256d973fad7d4cc0efdea25244bca74a848f4bfbb8f013f204c94c737f018b8ff6c22c3fb455b9d5f2e81ec74a7ec54358b652997790bae44e21079f0f632a5be8e96d8f7f2c6eedfe6e5c0b7bd93cc9ef4ab8d3e2c042208088ff5e54f84b291d03427bfd6ff8b511c6117013fc26367792a573d668cbaed0b7141776ecea26f9662c05387067d3cc5fc65454ed3f0f68ed786083c40ded7e3f9ebfba257e3b552e75de5eab7767574dc149b897ca94082c51c751dd73dbc06e0374a188fafeb409710a8b06c246222ee87887d6d370988a2ebfb553ecbf08d44b5b6436edd21d9b45fc0dd5738f6e2bfce6dda89b6592dc47c4a84072b53fb32ee98fd79210b900949ed2e698302aa3ba85cb6e95e6904c7917ba0c7a41b7fa17bab39179c6275372b3f6076987909ff6b4ce91f667de5031b404e29f341fa1145cd601895acd345c3bc1a5107333c3a67d7786c617aa7cc848f9cdd1732bae298197903c9a0811aa95053b92c0930815943be69b78b415708d6c96fd85631f95e7b8b09e940ae6299178d3296f7a6db80300f8754acf154c8a91848bef14e34e99909ed99018a1df9f4b8565e93f2bacba43bdae300491ed8c70392f226aede27ef5f11cf9c9fe119984d0e5dd6c6fb1355e4e837c7189914edd54880982a383b8505425fd56e91323f883a574b8573ce21c50d778c5370b8536877f42d49d759a8ad427b7128de486b3d8dd3c926fcf6d6646f815863ab752b05276f126095c2b3cb491638755ebd8135e3b73a00fd9664a6a54bab34c55af2cc812c267c852702b5fefe7e401ff609226d076262fecd0a59b81637176e394af62809a19e94ee1e702b437319d9661d0805a51667dea4c95ab84f532b31c8ea5432a507257d65b937402e5dd0f8c2ff32e8da5d02378cd04eee5a48afc02c10564b0694f9df505a832d49eaec0ea4f09c0c8acca18f37369e0f91458bb3ee4b370cac68e458b4c8cb1d235631a18e5e3f8106533481f2be5f100c732b57bd421f827894c1c2e3c47d6eb2d9217f9cdb2e1fe5fde604bcc1d8870772562f71a76f9af1e476dbaf1060e3410467f7befb1c951686b208f00dac87e16ff3317707dfaf190a01ff84fef4ade5f11593b19910bb20b16be8a198342c0f2c0ad444d00eb761b7e6a75f1b0833a6b41a204e5a270e2ffae033cf6172a5823e1ba8c6f7de4c6cad2cb5f23d29e424c1a6add77017fabfa7b40cd0d8bf92cd0ff4dcc3a21e8fe43be46e76aaa1aa5122a0c1c8f419a4e11dba08026cb99629e8ae9b80106b40993b4848873e076649d265469d73fc43efb577f02c91d5e52c7d7989a58a3e383a3d9b808aa8b84c50513d5854e15999c0db55423ec2924cd2517bf718ee623b1d6868fcf93934c53e0d09f2cfc127c701e588a7e0314e33f9e220d8f9fe319cb1153e75e39a830aa7c73bc5de5015b8edf7784149f76b2e7ddbaae54763412a7e338923595e5c07a603648e2d71353531975d01123cc4642eb657cdd1a1670eec8e5ec7c3e14d16ec464d9bb11e12ec4c3d5e294520f848ff376a3b4ed731a4e6209bb528c2b7283188e68d8777cc1a1517c727fa5fd75f40fa2a35c84e77fbb13992a4835526586e5541f134d95e9ed1a1656c998bb4ce3941f556e0a5f94728ed8d88eef3fb3a8c3ddd6fc488f5a7da2552ff0c92ffa5378769c323ea10067152bc8c2825ca38bac72595a846f4ede21b911cf2a2c95f46b18af17a6c875181a718ba6b65450dbc2e042f14db45c86b4fcfcccf829a4cb37a534f63b8d7cfef04eb71c343b4896eac2e14ec79b366b0042de1248a17415e0a4c3fd6983ae60626dd9ff380eed53ecc3b14b33ef10e906107f9674a222c116720e433988084d3f1fa81c03b11a5d9adcf0887f6e4ced95af111036a67f6a9e0f2acf4f95a0df45ea837ad8a0315c13c2e02d1a4cf203249c4e8600a6a946dc15cc817193fdc545b83b5a82bcc96ee84eb7fad62de662177a9e4ce2ab7c2ff55467f054dc8aa68e967cf856d36894125896658ae48b8ff59c030ff186934ebb7602d0274d87f4521a575fc99f112f2ffd3848fdf4eb8f93314f1726c9347a4ac7c11b4149dbf270774aeac8cc9c043143f99172fc692aafd3c18b449cefbd917be0e3c65fa1c92361009014016e4f884d11e72a88710cfbf48081f114ded3abb3283771f41a88f43793b77309e9ecde033a6d02f93ac4262afa1c6bd2c72efcb9942fa616203d091bf36ae49f7156fbd098a0ce7ac417e52b124bd61e2aadd70820884233d77c45dc4df7f98b014efd08b3acfd7721c871108ad746ccb50f1a4f2565332d80d66aa374a049af77b256a3a4a2ce1bc62732254e4e3891a1c154b9c0c771abce30a5f3c2c01e3d05be68bcff02d065914cf7f31b7162556c1e57fae975e93c251888b95a3b9462d3e6c391294fa0703abc1069df2a8e723082b511db0f8a655dee77e7c3377ca3cfc26a7831ada8919db3c028bd2fef5d28c0864e493dac5c9ba36efd157c3051d0872186a128d5d8ff00f7fa9af584e38b3a2e60c561e7a561fcd86c0e69f4655f2865be246573b05f8223bcea73f6e4a7b0a17824e83ed3c74f7f48d4edd5340c6fa83ab44a9f792c7ecc70c63f162900c5dfdbd859e5ce28152db8399dda00048d535bd5b721e84e421130e54d86776a9abc02a7c1c781974049c57a5399b000ada1e7a9fec723d2d72e505d7a7a86b6c92d4c8bd8b8d0c176ae7a5bc1fa0aca4e100585cdabd289808877a31dd42e37267dd44a405b626f24a89a038ffc35ba8b988c5d4e02240279242e89dc574589b9d8065464a33aa80c12a977a3ce582c210c7ee8a8ad281dc86b366662471cfca5581b795fbd9aaafb22ff70f472c0a1f80baca6ee958fb3ae42f849c676464bcfde5760c00f106abf3c4d66bdfa33eb3e083209b439b76fd531447d5dfd4fd3ed46e5bda24db34a810ddb87896c109e2ac0357a17802726c11c3fb0a6d0e491e0b5e4ffde2c249443fd002ee3f9989cdeb82f528b0ae8974",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xc83d50978de752609a71ae9fe08dff970da2c76f71ed251f518b742fbbfe9837",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xf73bbbd26a82dbc769066550d8d4585eab2fc00d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1374ff0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x8da07f49bf3349a500a69f379aad574967490266e314ac8a5c49e2155aa69270",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x4af4ede0e4fe92136082df7b677ddf56319a3824b31d052b871817b4b69ede62",
|
|
+ "timestamp": "0x6ab8f294",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-anchor-20402160-baza",
|
|
+ "sursa": "2800-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa00000000000000000000000000000000000000000000000000000000000000000f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b841852e24d5999e67583edee0eb7e8f58303e70b415a22f0eb0a7174a83849521250ccafceec8cef2f75870ca8cf4e915a0e29ac31bd098686b50007e57dca4368701b84144876d857bb2a6356d3f9c4134d86e12d69d119bb3b064b7c2f1991ea89332140807c24f6d9fecdbc1f840b2442ab7aefe53a5d3c86effad90448a2f8168b8cd00b841f45dd07a19ad0f73a624ac7e0082787b1feb9ca75e59c3a340b805e78ec5ae3a2d88d73e265e8f35f829d6fb649117607612e46e6145873414f49e789505b02301b841cae3b3d020c0faaac3a20f384f5dc4ec891cd8cddc337b6ab48e237478c4c7ac70f47ca9faea887b947a30589e0d897079935216abeb6838d1691a7753a446ce01b841291f680270210ac0499383ec05b7f2ef2b9099c50a5c4fcd1922759be2f28435041ac3989d26e31b7318cbb97d64bee580d437767a02834cdac9401adf574cfa00b84134a3961bb0d60095b94ac198057443756537726e714a84f3b80b3146eda982d67d6c0f16bc388052a2aad447a9eca79448cff3bf31d5a9d2ff0f5e70d5affae301b8415ab39f612d4bf55572c7a5288021f7911835aa0f02fad58079e323b9d935ccb3703f46d59393b2810930b6172d6e89412f01638be0e0746eafdd1de7f86e7e9b01",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xfad8dd0817852b69b9a47dd573ff96d9c6db8f4f84075a7c33b16d0c95840722",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xd38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa2",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x137506f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xa04e7eda56a13f67df1f4e6814b25fc18179de0b6ffd40fbd00b10da32d202b6",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0xb2e62a545dd5cefb0c1318866ff7cb41b7f2097c337fb75a0f319688309655cc",
|
|
+ "timestamp": "0x6ab8f2df",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa010d4fa0ed27f3e40956c6b0d8e9c58aeac18b085fce9d3861b0ed4617c243a6d4046e4bf8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b8411f46c3cb94126731824375c9f0aecfec387aa463217afcb32255d2ccac54e67d136320600ddec992f4034a67061e52a325d7fa8d494721e3a63e04b923a9033b01b8415d77762e6b2425e37098100c096a39fcfa7c0bd57df5197114d3710e9771724d742c61770fa2828efd4d839beed1069a2f2c39159c29b317d5118f613c48f8c601b8411e91cbe27d678381b1024165d5396bab21558abf70d4f685b6e7a9be1b7f7cc10cf37aacec37324e68627978a9ae98ec51b5fde81c70579e9379a0bb356886e301b841c80e865b698688fe8c48205f6d5f1f23c93151322ccf63ef972b1eec936d136808c32cdd2b0ff4e89080f90d94f17e42fed7d47b13d8f2cc879f9fdfb16d985c00b841303759328c174e6248ae274698f12f4b1c495f83a06b1ff501dfab3baa71bd0c333082fac8deab9cc7c3220f00d076d4517c12ddb013da80b2c1c0749914e67400b841dd3c4bf4e2f4ca30de31d24ad9c27b274134868e550d1a6be32263cbca5ec44f51ef5c67418ed05d22247aceecc9c8123fc491411e881e061349386434279ea801b841fe2aebb5a66cb900a86a6b413ff28be4c2632d2b411b42531516e4c3538e7c344ca81e197bba021b6b7ef6ac9a1e989d903cb8234116474dc995356520d91dac01fa010a7c02fa010a77f902910101b9028c395f555fa9e764df3ba79d84bf725e737079ced616234a02b29e7878478a2cf7038bebdffa1507dd5b7a4f20c747bf8c545b3d3a3bc4452465fa512bc63d3259726227783ecb67f399d53094c3545f9a364d8ec3c419b429357eb34aec5b8729d97cb43d05e723abf35a70e9313c85a2a3192cf228ef7c3395b98e2537045cd05a9cd81d4232be5cbbf7ae514ab67513de9bf07ef12fdf963ae7efa7d2b3dca8c2d9146d72c199cd8325fac527267aa33586fdd3d40d31afc5d8d160f7e061bc439a8b753eac919d2c325c24631b99ced157289b67a74ad4c598f7111f0b5da9969726da8264595d041ec292c33af30836fbf75aad7dc8c97294e35c6e0eaadbe0689a6e8c7211bdd0f5385b26a72f0164ac05bfe6ad67795cdf7125ba7cfdacc13847f6d8bfe39117435feb4c52817e6f33368c020092091889f1daaf1d6e7da25a9837b60788ed6b3e759d0e72aaf9d5441171d834e57e406f223b94a5375738d464c621cd32b4969d2949b33ee7e14dd31d1cc62d8d9f275fe7966e94c69b7e3fad07782eba5a8c905a5183349492ab1a3d46fce936a8b20ce2d92c6e5e8e3781664c72cb18fd98bb9929a59c76d338d739baa68f89b4c22e1882bad82591a34560c22b150aa45db7792e1787a3989947f47089cbc193b42babfd118f9edfdeb4212560ee2f5a83f3b1e0f993c8877097c930ef41dc6bd8ae0fe4d366a3d27c76918f3b480e3172b6620be714f4c3b2118e2b33c2c419b82ec9385b78de3a3495c96ee297c7f1b9af344c01f9f0380d4cea0f252b12dea51619bce9c89d865f5ee02d6f4b5ce3cfd75e35bc71ff9ad716c2596f587828d82339b4d99837ad12d1656e111e077fcf0633d1abf5cebfaf681c0f9e59a095e0175a46966d3c8db7947737b0b06e67d93fbc66f91eb50201b91eb09c35df478f5e84a27451d2141f476b2b8ac51ba713e164d231f6c336fcb0e5e832796eb88267126c3dd03d96360354e918223b566e5ee5dae2560eb3dc96eb28f70d8c7448f34a4302c79fa904fa73b62b3e13fc750d5207eab5fdc7f40d24beec7d8c411eb0ef22c43c8377e2c8b6c2a5dec60b729f190f30fc521897495f71b6916453cbdb3233301d8c555e19ad1346a318b455d0c25c5305089ed1afba2a87a437f00d866bb6fac483d7e93f1346c483d1d663de9a85a3926098c3f65b80ff01558d691c04347f9114df72eb8e43167d1a6b398bdfb65a30685e1f987cfcdb98d6ce24cb463e887bdfed985329016b445e719a5cb8f1fbe642aadb2d1e48f4745876b63e598af6c8b17ff6a3cc18d1efbbea0785306558a3a4d3cc48d0dd9542f3fdd701a69e3e3625e4be0795c201f38fd1ed8193e85e74b772419aaad85dec3f891c80f82f042d7fda53f7eadcd4cfd4b05605f3b926628056a6dfb61534fcfa73acb550aa0c22a3d1e1ab0de327284b3d742abf37477e23fca014ae2b2de1460150909400bdc3c9c58b8d14e1c0c3f20c80c0ebacfb0e400e388ad7ae876e65d22435aadb1b692d485819125fa244a46e94a67bdccd31922b17f19d1cba692136798c0f444785be90da3d4295021b429b60c756b0ca6a9cf6bf0ea90f4c07044c9351276ac17abf3690a5ee502190fc70731f8bfe28fd7609d8eb65ccf9966bc331e4ddf90c46d6314db910bff4738f060fc62cb8775baf64b72214b572485f678543299ce0dcbbc673eac90074fb24c2dc5bda054e56741f49e164f2a1118aa9ad82a56ac32e118d61e3ada1b523a992000334d50f011460f44bb83c4db7609bb97d8420356388677ad72a30607217559f82394df550ca45daafbd67f0d74d3c0ea60c49a33e4340cf9506654140af9f13825e49dc690e4a296d8e5cfa85b1dc1b59cec107f46336404d1eb3927b6186dbca839f2f26eb6371a2e9c496f4e28163314b9b49e8290e3f424b5e5055c3e32167c93c7fb4bb3bf8a5912ba0d629aa3b53921574728372af5b81a61549e961db2a87431152c8e316d1ca33dbc2d970315c76c10003a7d0251c276a52031772e7a367ffa41a2b85292c971b1e6c526f3f1e135bfc51ae6cbd2352d40438d5454891981f68c1e44ab41e15d64b373842d686795b33ddb6aa6da4861a93cd1b1777cc3cba817fe3b644962f889faa8c21abd9412f0e301b00654e6ca88da38267010eb925220692de625f1a9e08f78f8bad1956e4504e2b5e645db0f6583239c273cde138a0bc9d0a3df538ba8668e41f36e508ada6f829fd5deab97000a95a85c98a93218fd6f641b3f58dd8088bb30bd4f8f8789e35a901c8032f7f7d65b62891b6569511b8bc8660288923dae592ac7b5f403bcc79c0d65bb92981470f7f83d5d4ebbae807e2cac6dfb2e9dedc6c328cd4024043f9673fa96bbaecc27d00caba1f63decd05870ed196ed591b0428dd1f6f08927b261e57edd4d4d658b2ac4ef69e5fc40f894522a496374ab1a075464e1d6cc2756bbcb30809eed36e7e109c998962a213fa44ea99face681131362059fb660cdac2b5354065721060f794096d321898e231b5ed2543fb8f96d532c4fb05735cc27b7df22a07fb85ce4a991decfe87fcc939fae5ab093ea4484c949264edf56c670b3bf65f0efef078e2c88bfb649f50786235953a247d9978691a6c777f75acd08d4171488d1b1d13dc9cb843426e620cd61b062b4faaa1bc3af560f77735659417aa629f212d229ce96e81c2eccd42e0fe208a7ddf7a24ab0a68356e66525c7c55a18c4e4506c7ceff7e9a2a4a4e01b78f817ac19e73caaff25152dd0ea559f1ee73d111e8ccd6fbe804d8426536fda15b4eab355c59649d84157b71d302c48fd7db0b744b421469e999be2523710c7731320c559c660999d6003ae22eec869ef4e74a397b6c27dbaa9a900d117fe3306cb45df7bf386d6495efe0769223eed9bb46009449bb46b8d8225224aa2da4454ed36f34234559b50d96f099b06ed1013242daeac422c635a5891065a83e5d2912c349a6cacefcbe218b74aedf83da79bd586550ff760ec52c21fba2473a6543ecb6f2a061677cbf3089cd8816676641254a3af4ec8730191051258dda4ad8f37398f06f971e6144e6193b495eef2a8f4079d629f0a886f6752e3c732d871dba445b952ed1a0a76c94cc95a8c624a3c6cc49e7f465c22b0e5a0c6c2199b17611eaecbd666312d490f4eecd146e8f0220ae21a5547ebae01767258d7b1ee71b45311fd1f4e2e4526d36479b99b8b244714617f7ab81f288fd766a49030d77b9539ddad525964a215b8ab168e231c89285b640b146bbe1ff3b20954d75c6fb9a7f228601f974eb7b82e8866d8a829dba346cdd26ba76e9902822afeed414a570d60566488febd94e90462e0f01ce86f626a12ba3426c8d3a3da010bb512143e7489bc53c4908cc40bd9b5940d07eaa9cf78467b051ed6db1d06d2f0ad0ed20a6a40cffdc99cf762a6cb89d9f576ca701455629d33329ffa6ae83550bd52b19f1c19c30f1e06c24eae86f3aa2680e1177b1bbcc513394a5dee47809f75da17eef0c3a00f02bb882b46bee3d87cbd4e0fea106a7a75fc032aace5a94b0222426ec6bba3789a9c6f161bb0dbaab0604baa8a0f8a284b6c5ac082cdef5b2a85cc79711ceb4c2f402246c50596de5af1764a72dc11ee622189ebb035c27c66fa58ed998e143b2ac64c60e12d2e3735ce99bf639632094b0a64eab0a52d31233c2be47f35dbea3e3d6c15df72f1c7067fd0bf0df42b2e9afb3e221281661ece9b4be4fd5d1f4534f01c3904f07f67d4d42f21d4cfa825ff3f2937b71198f34892f64e35ae7d19bb4a6d83d576fdcdbc580ee08ca89f09c8ef1394e0c3ab3927a579228a7f76ebc5303bc7ef0f1b195d4d0fe7d5d7dbd887ef5e49fb02e5329675b00da8e8a925c117c3d24b621b2542c13124650474feb7dd2d90923b64e3f94183f66dc7c91fafc00592ae217029dc250ccced295009569700b321a27b490cbd1a009672fe6520286b88106ecc58a00313d7d1363f9d666dff40b8d5f89bbf806a30f6ad0d37c24d1d867e9d33cece85c999a5a1cdddb28f2caa45bb2f7efda35e254e836427438e836187e30ae58e3444f56269ee4f34b3a0eea4b9ae1ed29f03a049d22cfd2fff9b5fccf9a0fd88fe7863983ccb52e0ff50127a554e9aafde2faf5e458c4acdf397920dbd0dc841165d0a38113c3ce9471f7c8f48f8020b1e55b5aea5f4e97ff782443cd3cd23fda4c47ab90506381f1e2240af9871c733abb232e3b8a972a6a2c9e67442303ca45ec425f666176786aa352fcbedf766bbffc790811fd8396239a20610f1607e1c8e9d33a7879a78c0606c35ba02d21f633675f6d7756db97c8229244e6d93d03450a1b55c4b26bffe646722c610b837301a1eaa3a223bb8e684186a5d9625a49521808767d0752e3c853bdab0a9aecd34e245c20c0786ad656babf3fbe70ead38cbef0deebdaa1894c352b1a9d204c02d14f86746b70bea3a16179b320898ffd7d02b0e32806784bc81276bc2c2bf47668813b04c6c27a47029f4b8105bd1ab028dd124b92c8bf55a3c1e741d5cea4892f75847115bf7292b1ae7b0a327a7eef3b09709f41ce830efa1450b78e350013a801062747c0766cecbf296ac504c74164d39b5db829aaffdd24991e1d54cccf1cff24cae91e60f4f1e3f3964e3bec9aa40d8e302204969e928765115bbd3804355838f19a40109f74e8b54dc1d0cca8cffb0569dd1881bcae9ac83b9899499e18b1dfa06a8f1806972b009c2b5cf72706a1645d3fa718502a2dd598dd3acb790e910c46c8c03347a1accad43c5774c2051b5e41bd691eda39d06ff529c0c28363dc22acab5cd5ea57353a7ddb48f194375e5f4326bc796514fe09265adc96a75aae60647fb74aebdfefaccf816a0f433ec93ecb786a9ac907be0e97b81154b06ae111c7575d6330c7cf77de1619ce577b5e0513a56a41d892e3fe3c889fd2e2dc05000ac7723f193a31586b056441c277f7893ba13fc6502dbdabf8d74b6cac91ae5efbf7e055e6b4fcf6f88f11e9ea30abc433dbf09505b5271515dfbf2f80c7b95b44854b828548fcf1bdb3911acc87d738ebabfda7a75899e57561d69c99ba910939b1462af2350ea4ab130f22695c69355f6a52650f75003bbfb1da4a23122af437d6cd0ab5e71459e5e319a3c5178c8409b2ac5915e1a3f67609e3602d5da99b40325353187424bd1ef027b9dd34612cbba0540b8f9a7d5ff2fdf685c89bf58f8647b2f8aa8055153857a9b1a2fb626045ab4b814cf246c0e6e3e70702079cae1f88b44994cb3306a2917004dfbc7441882b3e4f847e621bccb465af601256e5969e1eb8854c8b1489c8fabbcc982ccefbc434be8cdd28450b3391e2ce8c25b1a1bd5018326480cd0ac8e24510890307898b885f037258d966e0992f9b0e07049d602e941e63feace87ce924135e9d096abab825aee1abd2d766d3adca37423e697b3c27c41374d5714c0fd2bb7705d90068505632a563781bbb281e85efdea75747132718eea81d581a04bc0ad0489f29859f16aa3b9e7a714c673b54d2a0a7f7922c101ea40893e4862c8c6039c50243fa32b4939b51038d1afa39bd02634c6c6c35a1a8e4807d21e402103af76f1569bfaa692eb729071ac7451f03adb642cf688284afdf181a8a1d3b3a51fe81dfdbb972bfa38a4fc916a721b93b7692449333a6c455f31c524a696efcf8bc0b90b6ecc414a7ae687781561f5b97dbc01ddb6a1eba9a63e0240bf85426248a0bf471a6d03e58f2b28f18e54dbb1de461b21180521cc9acd80f3319ed85815f37d2a7574007ea0a747e782cfa5806666d6d4bb1ef7524422b6035f0f8968f0aa1231bf761d8ccbc8747b4a7f77ca2af64478b13e89f6504cb3aa93945831d664ca1ddd630f7bc5a7ef21f586590bd1bf17466e2314b59a93e8b03c655ec08c30a5b98b21654826e43ae0ee24d82fc0fd3e86cbb31bf9af7db139ab5983e0c708191e35472893f644e52f5282996f00d71b8b45b00270ec50beda0bfa138350aa18a4b430a2b4d9bda3f3918b879d1acedbf8bb92de4bc7cbaaff888e4b3b08962b5d087a3b18686dcdaee679d43c640d3dc9c2b3316553ee0c461fb61fb2685060ff02fed58d61239d6cd43f2788c4d7b6a5bd246cddc5a435e3a3277ee99a509f8cedffe8581d6025e92a3fdaf4e870f9359f71748ecd4d3a42cd0eb718dd9863b5c16a061803a1573433c31be4ed7c6a3c6a9c4b8026cdd64e30a3c6b254a48d25a6a464a404ac1c9780e3bd569353c2b1dad4579e3024e1dfac7a39b089c6a2e27223c326e9446e251ddd69d50dd7af330b73e3419051a4207ca635287a3870738bf43e6951130885afcba56b252f511accae781bc0afb468de0c9311d4471536409e3ffc87ed3ea785abece0071fdc34d574ba04d2345511d14c77452e24229d32ecd8b50ec0b8ed194307f94d343de8ca35fe07f8eef63a5431fb01156df983e843da7cc0aa9141d978da2d26cd1be413b95ba31a8755fc10dee35aa57d11ab482639478fae0b8b96306b1a508a1ec31f1d0b4211381266c73b8f0c0eb15a04b1196dbd31b300c806fd4254f4b2f862fb00b2f9adec92b8e77fe566759da6e638051ace09b922725abdeab30946e7060ae657a9a4533851f0b9b31cc3e737747d10f9093737483d95091356608392cf049f5eb975610d409b0b9615e5635e7eebda422c7a7e0e4eaffc33d4f0d0e00c06d1e168dad99899e7f344262d357050947f69933377af6380008a5666256dcea65846549c28b467a95c9bdfe68f2b2cf390ebd809cdb8f60a91545fd4606a34c94ac786d7e683db95f0b2b5358cbd8b111827849de606d7a8974d54db968064cf086c5115689c2bb69828ac0b77df26dc902502aef0a14c5e6f05d6a64d26102353419bc36709e1d087eb6acd6cb6f20f7158bfcb21d45ae24be77480a8ba553819eb6f5185dd7222156a4940f9a5fff0d9ca222401f272c4e4bb31a334e663ed1da6ada7ebbd21202ab534f56236ee4f07f375c2cbbf58a71ac933cbc13789e3d9a91a7468ea3a2a1f03d2c13544d64caa702b88b9e595e55505c22f8c3cf5ad362ce903fa4b7773ae336cb6afcf76b613dbc823585359238f41ff739e9e7d806762c53b843bb98b68acb431dbbb6f097c86c4f2c45ffa33139a6d372e436645bc30ced2affb165db57f21f246b0d630ba4a783f53f26d74747d4c1824817d6784044cf11b3fdb4223b0d7d2a38033ead8239893526bea04d44ccd5a138ce81655f6efe613468b6c2846e59535078796f04d411c9a0bd9710204bf57b0be66444bd9e387119861861fffbd0de65997b312cb02491c32797fddc0ecca427449182b26cc5f230593a1f2e9c53c7d16ec2ba363df942adf9111a2dc87cf840c9307cc09d67c74599917ba2b363dc3abbf7982337317494a7a64cc3e4891a567435ee59344c4989a7bc26dead0eaf5b7f03b57cb446f4645d1d1a0ba6046600bd6afc01c884d2f499e51f0291c7cbae9d6b3b19290a3469b0d12e2b721580edeb5f29aafb18ec0997bc873485564c06b1186972eba55890dcf3576a072b74c5a29f3edceb4084565d855023e6eab982e4e53f6ebf835959926f20d6fb26c9966bbef4c99a664b64405d814a92cd64dd2ce415479f0fa18daabf1eed4a989de1e11d51033180a21d4dd47e6e2d90ac3e2844adaa235c3bfa6c418becf62011a3de4bddff8dd15394d292272f41daf283d4e910b7ff92d777a470d6f1710db0229a50e84a5e301f9d1a046aa980808c199a48962d6c4782f8126fcf4e1c7cb3b290e0880030b23b4f7ccbdf4d293ede9aadd746e1173edd4d211272ffea270084d928fa4e75d47647a0c920503288aae0e234bbf7c38f29acb246fb45515d07ef67ce250ff4dc8985453924b2b7837f6996b820a630b203b697bce4865da4d21403a8b4cb4ae71a067bb939a28ba6752d4faff209be9a81e6dd4cfb00da4b337c3da8c755fff575c6ddabb58a485c1310f4586a8defca6988690cd555e7922530bee9f1556526e3859b6fcf301d1bb644d0ab403166cad87c0e35f6a70b6d7617b8a55c0d3edcc93f06d01f375d1e8a31a4fdc6a9f052ab4c761c87c97d9f02668528a3bbdf8adc5254b311e87dac3447554598f0e417d99bfa4c2ba09a3c117c555129f3ce6decf41258c10a23a1c2c3b92286ad7029d5d4d381075667e51fa87a6665f5f75fa1d0e4fa3613af57b264ac737989803c91db62f63d2a3f2083bca1b96c2fc8ff8a8725e608fa587376ed1082b436c588e6debbaaf4e874132caed9ed6b9b50dfde241dcd9bef7b167fe2537b29178513efe82df33aff8ca7d92e72c94598166677ba635232bf5c97d9a06bfca77b4b4cc1da5fdd1bc2677cbb249e474b585b7d7ecae524b9c96ea680da6327cf483d5fa6679e61da74f5847f0cde9ed59e7f0773b0bd75f27e4d8952f164cd736812706c4845bb91fb3377c5046d2f1f6fff887123bf6a09b39a966a64bd45afae38c8740155a39831bf2c9dc532b4fc56774c561a593339286dd3a4c7dc6dbde6f4c7a71381b1a85d23662263ffed11d8f1845595d4eb35f66b6579be7439df6c9629ae08ebe2d2f2585cc9e322cf4e245bd34a6cff969fb2003667a5ddbe18742e3d1dc82c44d18d0ee5d67a00d12d57268b115b5be9dcb555a11a2a989aa2af01454736b6d4a72939a8e5a6046f679895e9352ac1603dafd12d132a2322c8493f26e2bbe851f19b6ba54c681b0e8e3ce0b5b0a2c8abc68c0a6b3078eaae0f0cc82e8e88ffe0977c2715eaf93228c09609fcdf31f32544735e448e216318d239f667f57a062b0133d9d92684f962a4b333e40aa3b01f5fa6e36b3406d12fa0150a606bc013ff5ac30db8957a21abc5acff199dcb90bff4c2d4951459cd7d0d5ed988e912a68f9db4526d50590e06d38ca7c91431555b26f4c5e61b509633fd07ffa1c85c07c8979c36b54e78d4dae9bd2305dc87d6e9a9238be9203fc557d03141cf4f27f0f25021cdacef95695cbe114a15c548a0db05c89515d774f968cd6d84311ad466bc1a2fcd9467996a08f9c56e2587427a626bd1da4e90c3f1995fc7dfdf37b138def5c131d0a89d22cdc38d8fb51c8f54b12d7a92fe75e296ed82ec837442c56ef5124a41a978ed1a8b5f1c3cf2d644e63dc222bffdc96fef5447c83d6d466e5672f2fb49f1e13ec49d077156779c351e9e20f4ffabf265914a57e012d186677b7da98c8cceae69118a0fee1bbea319a22ae416282ca133c8d01c50133b653993142c8afb086a746026b4ecc3b158cc71cc831b435fbb035578dfce99cfa789329e0b9f03a4223df5c892591f489ecfc2f17d71f9f9e40048035acc145b5efa5675465e171042934500a0a0bc9371f3f994a5c5561dc4acf9cfe6b3a91527cca3b11786987e7c6b50f3d6cb67e3fe0347ea4217787523d3e04e6f02656c75fcd0107a7e26b8632737b018c1545ed59e7f2a5dff420b3d5b4c3ee887894507433dc5ed9aa1708ef334d6cbfdcb2709756034402e57a24cf953590c20b709d0d8fd38f0d88cd9eaa0edf20339153bfc182a6087a36f3b0d7d1077d4bac72b5fba711b4150957ec929f32493d47e182167ae58809625c7287bfa4ba72f8cf905eb4629c7db7dba5e4792403da9bf24f20ce1a5e3ed57ec6a26524ab33ab40b5370d48130a32f4beb09b3b6586912caf4aaf49a48b13e348ca97360460453b479077e701410ea78333ca7a985cf2e6339fdd96fd700db89fb34e94ce28296be41a4e88f4020931648bd92947cc0ea4c767f222fb900f746b74466f9142e8c819cbbf58565815a47c4473ee1db080571aa05b695ad1096698098f0bb7eea2cab94917f8b96b3b4c32628e928758d475ec0b1f1db1e9b1ca05f193da860816e342649d11a40ab40e44390340e7c8bc11591fec1baac9bf7a5d35b194a25681dde01cc84d0c722274d1e21eb2ad58026988b593e5537f568cfa944603d3d3086506da640555010764fbad23e95afcc7b49fbf5eae12d96698a2e691d12a5cd63ef101bb55355b23171c5771eb11a4625e4ed0c778a682a4df816395e7e4bab58efc4cead5750823abb5429b10e3f2bf2a128ebcf7493f3446b47eef892e8c38630d4f71aac9456695894e839baa2ca86255d7111d960bb9b6ec2a713e5ba2994605b7b9d2a6807e82259aad2b8e11f49574597f488a50d3f315bd065da92be9e7fe19812351d283e96cbe537f977c6c1df8d606aaf9f60822870bd0b1d463ae1a9e28cc9f0316d9b035683518c771af376a3b6db86627c7122d332174278bcda8a997a1ca782e76f84c4e5c9eaa63245a3e5dc2c1bb4fa8b52ea2e980a6b71fc786fdba5f1e1fd86b0621f7356cb0e69f692632c20fe804a973398d10740497fc5a3d8c47285f39a927ea5f94c8888a791a664c8adc2fb2318e90d77a3614e27dd0e98cbd7f0e500ec24d0a9f862cb9a97c5e17849f9cf2931c3331ea6ab13d402526f4764625b11ee68f744e4e13d46390d138e0f1ac1e6e473feea3b21a491015dced803faabc41f26c82d6836a13a4fec8f82ccaf066de7db53725bb7d177e572613e29489cb3fa74f04d7326fa8cf95b750eacf3cf218beb7d20f8bb853864bafe141addffa040711dbeb81f70155852732e74807a72e0625a0bbe995050da5c9b047136c527ba93cb57f1b19a7f29b4c6b61162a2c48e9fed7b2af2b5e90cc207925c5b6fc3edc93cbbe660a70b4452342063477adbffaf03b4d2dd884a44d122c449e46d9c28a588fa9eaa836717042e26da15479e21d316d9b389b460a8b2c32051a35f8817bc836d66a932a32d399bee57e98f2b15ce420f09ffc38bb4b9be8f8a06f27d93decc5256ac076c989095fd5287cda11e1cbc0c7bcd9d9e06867a045272d01792e4b08ae3ead0d96f9eea67049958ee0227ac8965422cad76997415ed5367e48811b400e83b2aa8d3336e6457ccd8a9c501320d6a50098644ff85d438625a8dd19dca30799884fb3cb9f380b0b3bc6cbc358a68e9bbf0b055ce6f9cce818025a0b65a7646912ae1065f37e2dc67c0495123b7a585bc52b5c28e8a618e3a3feeed8a4e70a673547aba3ede0be83e6e22ef94997a7e24dac93292e2099ce69a0a8541b1594125b02c847529687b66f7c68aa773a41ec94a9724714e73ae4c2561faef62b5dc77c61cf718ce8e402e75331b017df7cff1d8e7a0aebc0b055b406a595a294955549734c43a3db479f97c152b9e8066683a5ba13f34ceb0c0f5b69d9b8fbd9b1ce58a27186d87ffa38e8028358826b62dcba66f72683109bcceec45b33c1ccfa83a37c959dc978eb177cacd5ee1af0d315669f5ec3540f6105236d4a0a7807cb722a3de7cb6ce861b94bf421700954be58aa127d4134ce33023d3650c529e8aee33af472e190a9408e5c764921bd897af83634d0e2e2fdf03e15108edb120b30706ac756e3320674c34a12076adba7782eb30df1fe45f0740a50035342ca7e8a62e9d8349ef44c5929cae765d9132e89d76217cdbf108331de521684a1ed4fb82dc4e4f372123a0a1114553a33748be9d4b4f1c4d7d4ecd916b77eb534d471da845eb2842e20236fc6b70a0eaec3774a6068ae2435ee7b9fcf86b4b9dfd0d18c8ac9e790c5646529f47dfd91a68a88a48878d8382895dd079e0057b849d747c031a521114826abd8881c842b184c0e05b72d3de7f0fd837dc9502adb0801e437f878e12f9b2a5d20a1bc5f2b8a4493380b832b7d4e792da7c0df219c35a3ed118dfc818383d97eafe6d9c9c9b25095d2bb4f0ea27ea078b63f530b37a9ce6a98908e9a11bce4295f40d527bf78cd67caf5a12b7d543a674ff96429e67b2e06652aaf94e0794259776d153239b88b3f6fb667558b118730fa1370116d5d1d8af8eac33c043162412e8b43d421e3e760841402c63271c6534a4de8462f33a4150c01afb12b596d266d7d4968af93baaee277e7e60ed1e9ea95af902950102b90290398fd742deaaa39f569a25741cd07a426bbf5e89a9699b6e879f98e8d0b053eb46bb7d84d9263fa9a004315e3621af9519edde2e4179d7ceb957485312fe64eb680e92c8d6449086e78e5dad0cc703529feed00fb24245f6440900d0c9eda719a92a323d868f0a898c03075ea063c59903b7cd491d250d3975b31d428399e46e4bb59697cc25bd10282664f0df64dc58b380a1ee9c76aa3d85ac1d06ff3f68442555484ae90bb814b76d40efaf7d96af0d665874d39512e1124d884e318a2ce8fbcb5f3e1f8d27a29b128fe334a4d72acaef2513bd1a8fa3228e8d9399ab61e26e3e479051f56c75f3ad3bca911865acaa28ddebb6b0c72e7e3c2d9199de7350b19a4df0df6ab1089cce1977530cd04bfe3f5ce746b2455e1bc5af936759bd1dfefc3d62796c0be37befd06b524ec46a074fa533dc7340a933e7cef78a34ce496dd5e9daed198d6454513eb129aed659be6afc723e53779c587a5af46bdf454fa2de2435982203ffa37f3509210eb0d139db6392e958b74c7cf2ef42354bec6a2a430e1608a65a7f5622a5023f4d643dca1c5d0c68cf21680d2643cc719dc2b10cd4606f24718e5f5b6c12cc5c8b6a7bedc976757c4cd67ea174c2575f96ad05d71344a30a9e615118ee99359066708c1b92a72aa9a2e323818dd6b612a52da8a74e00bcfbd00de273145f97eca26d6a763f3a5f0c3c9576a735857b0ed7d29a9b769b68bb311218b46d1bd930a7359287b449666caaa9706586553943209a7302d1a6b59916090e7c074fec934fe0d408f5e2ad0095ebff6e57d631db5a187d3206ec47d7fd66f167d99a28a60a8aa56121e87981240afc9ddb52140381a282e5066d45316f8e53701ce627f14ddac6d7efac296c425c5465ec46c87e0acee4591163d94dbae636d8ac0c0de9457568f91eb50202b91eb063a8a2efbaa76c121c6ffcd4cca49c3892653806bcd3e31aef087929c7972b23d2e5e63f1a3d987e00145e0c4a8b4f9156570f22028ea322fc4e6bd9a5323c03bec1a14a6b4735a8ae085cdad305e79cd5941e11a6036d5fd727816542d271c7b8465ccfd005022b75b542d0e7f1e0df36fe52dd9dc1d7115c0ca26649a031fd0ffd6315fd99d23f0a1930534211b55452ffca23fffa7ae0a735851789c04497ac96fd622ea3a379c2d19044dc70b82ce4c7d017936e8c06f86b0b34b0f3dc87659d46b360d86f0e94eadf9d7c64d612ce26925dfbeab89ef6e1831825a4f99144f46574fcce3ba253c323af92acae37143eae9015b375b28efb7c9dd40c5069ffaaf32441058f910c5013bb35b63db141aa066b257917048288ba35106e9d67fe35ec356ce1f2b18293d7dc183b99614e173be715736baf7eb3c71c4382d0458232c08cb1a4189be998faf8e946bd01cf4447d579650a58b90026321cdc900399503396e0c81d2cff2e9bd2d7d8c1325e42d299f475828f0ca3cffec006d19573fdc9766ccc7123d1251750b8529cfe5c164551794688e4ece05a4797b7ab56a1dd4ed5324b6d42a18453340492952a52a8be860f8661783daf8edf7b0445f63d1612a37ab4f44369bfb40a0d12e6c3294b7fc6fa80da5d88864802bd56b5f530895688afa2d8c0dbaa3e8c7471ded1f7f7b1a1948004fb9498de8fceb5a8aa7ab20aefba915ce0718ec5c59ef44d7479f4dcd63dac28c59803155d57ebcd1718d371ae86819360f2985deadc58882bc84c1b6a877137a68c76acb3ae7b100b2e2e90b4de31205101a40c6de8f586887b64f71e8dcde64a6cf2f567a277c47320e4180bffd5c273660f6b1126a14816e962b3670b02e0eeed7fa2d6e28ed43e8b3574b5d01ee63e7e00abc8c2ff6aaa5033d96e3128ef68e4ec38049e8ebff930870276212103a46db062bee32341884ce40accc411d8383c7272269b293dc91ceda7afe3e387649e890aeec802ccd8e6089b476d2523c07981b5a5add9f55991c418669864cf1c84821ffdec3bd19c9446075c4051a1540ba80f1f04e4fe7ac96942883889898625312ad86e5780a8cdd4094a3e6cc2118808b3e261e8bf33f44502b70b5b5413f0feb445c65f06d6739f2ff9f67f97dad5c9b98359493b08af95bf46c3ad4c214abe6279501589759c0906310c95824b093ef39fedf7e9b5acfb762b8830933132b767cf5ea083ec2f9577d4928dd1edcfcf1ae701a6de531b795e753b30401c44b1b5125324bf4f8848af1d71ba4c5c676e01781337c634bc118fe5030d21f3d0a67bbd31959f888542a43c8d64563c5b659b647de5f1d8d40de8fe5094e48bf5238005297bed094949dc45a6bcd9d879aae922b15b3d20228aaddf28fed366e2efd41bd9b677bebed0ea500a5ddf5c5ffeec2e84833320e02c3a6dbe71ff501ea89e0516fb18bb7d4734e08a8286fe7ab756af179dae748935a83d16dcf2804e76f61747dfc82795fddf9af36757530080e32cf847e00d8b60c03511ed4f3f9da5311dc9cfb2f8fcc74c6c1ad70e38d87c4c6b2251797d1afc31aa50f2a385004b5ccf4b6c89f4d0e6ad01ae276bcf5d5583a793b45989599bf6e6de09a46dab1a27bedad4b705c0f7680acff06a672ffb11007be3d94daacdb6cc1ffa2a7b450ad00bdfb638bd9166852c4f34888b263a8b542fe2ff802004407c38029640ce3ed631f4b7339fae488c9700f1597586bae89872b7d295ad4824a51f9fa961d4281778fa1173de455cda4d62cfe82d87891a69ac0e608ae17180a4c27ac3b4ee95eab4c3bdcf08867a15f99474cf4a913c957ba1b561ac9b7073536b268992373e968492a80d2c2d58417036fd786c82a7b3820985e8941f0f7d9201cd6370a539661cde596c4eb42f9e345ef740119ccd6bef3d7f96f2468e7db633bf4ba1d0d7cee037754a9880a5da1bde063061ed39d7e1a13c2d976a1ea62733de161d1765e3a756e75595edff82036443c5d25ee16ccf4c1530f7ad5d193b9180f10d6b420b4d672da77dc8458f4806b7c4db4493140da10feec0d22ee4d76527cf845da6cd23fd621afd731e1463955d17c8fdb8ed55c0dd7daa25db648be67a4abe4884083151a891f31c4a675b5dc6f59dd0ac262e779325160451efd3215da97ebf5d599ec4aef6bde9e6a1581d2effe0555931ab2479e9f067df0595d7124bdcb945598b2cabdc8e8f0ba3c3de51fbbf605e2c3e7ba4015bcef4046969d5936573d4ed2ff815efb52e1ccc52ec96d66a95868d4c9c36af631f2b99b2c5da4f9194bddf371efbbcc3dc5abe8487c47f0260d44036ed3e8f1f16128a6819352541eae74c14d79cd5826b137c420f428f1315c9b3a9bf96876f1079d9bf6bfc9fe0ee6d73f5a57aaf971d3c574d32504c1e012400d7aecdde6230f9905faed7d900df1ed5646fd007a2cd724da61496a891b7d06e58b695460fa99f85efb02d4981a0466555542a6573bf08eb5933b230d1c84a31a56b7a04769fbf0212a0fe462250b571f672f5766f38931c6c620bfe7a020db8ed1931ccb959ff964250cf640f044990b4bf6837fba36ecbce64b3d8ea186c47910c89e8cb2f45ba00facf8d6993662f1dfdaf90786f3d768944e8fa002068354a70c16f8199d33404472018f08ede9b8835a2dabeaca23e2e96691aa24fb736b7d320761f8dfc2606f7956cfbaf7361c5a4381ca758710ffc2ab0aa03f59b2eb583c09c90d3bd54faaa5cbd92fd771ce01db62a7e895bdc0568952d0778bfc1c287fe13d86f751d2835dbab4eaaf5fab1c2377080d84c60dba463c6d8e1f2e54b0a38f54fb72ef1dcd83563c479a368ee7cee2b0b705c352c6a70675bad82bfc0f38a9662ca5a6acf03b9da2bc7f2681d2ba0ab52aeb60e384967cab27b774f9bc2fd47909d7a4fa7e49df388d0d8490878a463495864895c66cb69d26e25d83d6f4b59afc76c56e6d668c630e9195a4a754ac59ce4dcea6821994a97710e56f8aa359c3440dbe6b25bc09da2d5989ba915a389238649850024b526aec17a3cde713097e26d08e551fb104595fc213824c142549976a5f1566426fc9bd80f73bf055b13fd270f93e1e86f2aa2f90207e01fc12a9a5e5ef96810d51761bc256e5b3c5dea1a33b93be94eb15f9610a9a74d8a87d93f17f553fcd92c2b46eab140d7c91610ade5d5f699010d62cd1faf955c2bee3ca6d9c6c0121f899e29270636a65fefd0c15c708e13fc4fbaf5563bbd5018ae091004402cd71fd774e93c2e2176ea729b4ee96d71f6b0242884a0b944081e59fe4afc2e8b8219f8a3024037c4290cb35d22dac62f14f367e2a5f124f400ead23ab2da4b5250c3fed45066689fe555d73656e93c5d7da713a4b2a8e66390f833d4449c8880a01ad902895251c801ab57fad83513c33eda35c3f346e0eb2b711b2fcafed843372022852cce571685bb1fefdf4d4b0d3ad91a5f911c828bf888aee690e411d2360b864ca579bff76c59b4f473a50efbd1411d71d67e4a046269871d70a1a8da6bba412ad77c4ec38c9ddfeea204800d72a421fbb9b3362bdaa0ee3cd646e13f1dfafa0564350b42fab33711219afd5d87d0b600f762f96ed1407f192914fd92c9a8b0f1498faa8a54769a8890e56942c9b45a7e70ed2f9801cbaa7eb5070e630e5609323f09b636106c1e640fa829d5a4b85032ca0de0a22294525f534f8406f5fd917b78b3d4e8346887b1bcdfe6293ee88d3e81254aa3b7b19196723bccd7ccb16da11f51302f7a2fed21286d0f83cb00870d5d65809b6800213b10c8eb79add21dc939901d24f359f74c0c02725c6113ed22c8665cec67cd24c999e24d7e7cd6c0b2dd5f32465792a3d940edc10d02756d229ceede7830c4a366b440a06747f32ba1fd1b99018aba71422a46cef518514600c416733752ab20fa8f03a998a9cae86d2e2f76afc4e9548d9149f1e318c1375d2ef87ae347feaebeab906697de53273d411c9849e98e4fddbccd2e0e48aa6af3abff2224a63963e600598380717d0fee49f60f31febc85f7b5c24ce100b4fe669197880220354984232032c6299de832c77b54d546db21317ae73ba087a4a5b25b14b0157fa511da1f9322cc71d4dc316425eb1e0bd3f30e358cb4b225b243a463583de06e39dcd0e30a75910017953b4ba54d2d64b15c3ba561d493db7dcc5125eaf6abef2517bf43a22db814ad0c80ac0ffd160027fad1bae2dc49ea3033e348ca3d6cca134c8aeba29ce404d283a70c5989c4def5379967fcae3412bd7f10f003c1e17efe870e4149d0af7b315584f13a20ad514ca2e5a48168c362b73a96ce510968805aaf454908e9419192a274ca9b8dfb006d51b9095bba03e419dfd488837961cb842a2f03df16381c019a56098a54e370fd1d2a986bdf863169eb2e0f1bca11026ff93696fcd703b36e420acbd78b6ab4396e49fff13419f62743e4ca60fea0c8061207a12a096ba963b56d4a46e384ea594f32c031a7f4e3a993093cfdbab1a0e450205d6b205001c1e6adaa5f68679aa7b4fc46a9dce35dae87ad3d23660eafd916c293cacdde63cd8051f5260d68e3010daa3998a44aa156238db367655039cc4b9b1014eaede1d83170e7f831272ef12449bf65644fe02da911ab49645d09f3b5df5705a3edefe43ca927aa9a9f3b6892b9cc06580262f366d95684b6400fa12847db02a246ada421bd5fee990e7c3d1d7544a89cad4ee098f90ed9ea8c26c7620d6c48c9c7af1e95f533dc48e2ad693392be5edf70c374d40c40a59b05ba1e21bdc2b1f748de4f698fb2131c3e1cfd1a4d635c1c661f86848cddfb7f08356c6b783f57056da94603878aa94846967ee4216177c64e564d3285bb875d6355c069d316d1cd58910782adc6240e65557981fba67fbbf3c3ce08323034c4da2810402888dfb941b1cc5cc5896cba5d60aac79b6c6ff0dee5c26a87d35a1e38584228495373c751835b770a918b6798ee74dc89bebc4f7e98112d4cbe551b51bc157daaf1401fd84e9b2acaa534515f5a925716d24bd69eaa064bcadee4f30209f668fd4996ccdff0ff8dbf364682ed461dfccc22d095e562066c52ce35909edd7416303ea12788d98ca888581bf82422083b69d9560c4047dea5568cb5ea78172b56705e63fe4058a07ab9658b38186c7f4ab77f652f25a3c97f7831db9699308b7f930e1c1d123cc362a09618926c5679e71859f0da3552698409a2a94cbac5c89092e28e4ab6e2615e6e7dcc4360ec2d267f6f9c91a59dd9e8044326f9d272a717b6929ac5fa14c913554dc641e3b7dfcf0816c68bf1e0aef302fbb7ea4ae5ec99ffa788b624e7b6309b2c6468e71c7f3351935c651dcb33de962cda439c21dc93ecd7aa03836ad100b109aeb9aabd6f7488f6cf9f20ddbf7e86f644c96a33c2b5a87a7e5d1aa48756daa68a14ed609f17fa2280587759f63c54b5d30c2ee3d0b100e774645df312c64a45adc49a994a80b486ab4f58164c708b61b4f4415c7066ec32c5792724cf8b9efe04a518d53668c17eae9066c323710626875b234a591be6d6399f333823a62d79007bff120e99053cc852d366413249c012faca6bf59d5f2afa7639cdfea8e76e9e2499f63b561ca91e2531b51280714498da3d15b77fdabba5865d7ab2611614df3b07a83988a96a94852ccbdbfe2e5691ab56e014f2037b1bde673f0d37ac296180ff4ef5c6a59b0a46483c880fabf7db1cde169bb049ad005aa0494d134879a71e6ac8b0a856366f235c076f5c107716a37ca686ea44dfdddb9d7f7dbe28e97fcec4f964fa98fa746475acc130153572367987f41c714171d02c8664ae8aa6c8b36537ec73d17f05a5ab9defdbba39f21fe822274a40e361d0dc06c6e517b0bbc6cfabbb00a65b6e89f59134196585e0eeaa77264293eb6828d75b4e009d8abbd3ddf2b0e0da9abfcf5579676ea88e05566f12d80d1323244a292d97862a994cd7f31bd59242d663e0758362e4d5caade9e3f8e664ca97de91784eb01829a2a291d062d86cc3d38488ff56af418456d0b040c087e7e3c5898ba29b411c1668ce02da05eb71e779d892106f65040cc3f34459ff3d79df6617122969d6b20e766427c3681e602c9050e5b6869d903b0c3f0573d9a2efcbbdf29b134a27bbf5205adc9b428e489e95e08af624c622dc197e672093dcbbb04393c132c11849c397844fb71e027e21164e8773eac22d87f78344464afc8037b32b68d02a96d495b93c2f625604c3fd634e29ef4e62f34f59f41538a2b5511c4c77ca1d8bcc358b900d276d19adc4e2622a997b7e69aea055e08d7273ee49db676fe4df01bbec7ed253c72c735a00c7d67cc6b9bb29c24fa85c5ced8dae0fc1468958a3816debe0bce48a58fefb68dd6e17445510dcd34ae147258b8ecbe01a11d030653e88c30d7bf0b136e98c4499e71eeed328623e265ba0c78b73bbcf9f2de5cbe68c052cf91cc204ec3b7d0bfdbcfa13d83a89ca01675ef6eec314fe1cefec5322f08a30d190165bd5512513fba90e357c1e7f5629f697bfd470a37c9a9de3ed1f5520d16f2d84e8d5ebdda3464c66b2ee4c5fd5c7ef8d4b2bbfafc722bb136f0184a5533617bf714a59afe4d1d7f938fcd2e970ce199dc649848b03499e93b24cf1e0e1eb5e6e47a21b952dd2558206e7c487c97740a6bb2ad4b01d0e58d1ab95353783899f59c706226a93b0d6543994de4b874e14f2571af6b67fb6d6e1ab1ef3b46e0796b3464f70afa0f5b033721acbdb2ece22d6aa297bff22b551485eece1e2f2b699e8f1d476e718c1f5a28937f09cc889f44c72ced448edc1c9272a61a64969e5c12c2bbc10ae565070bf5744da8bfdaad76e2918946ab052c9d49329f8448735df109473e975708ee72df640d5bfb08be73e68423460de75adfe336af00fada7ab6eb831d4c6aaa38dcda26a5148435c94e0498855d386e43d04bcd35e1b6d6581462329d7b2759a77b7c7516342ed77bee8876ee6aaadd9904143103e15b1f4e40a9840e2cc4763bee9755166ebd89a048df69c6346bb124a5efd42da66af0e1a01553f70d3cbdebcc65841a14684a65e859477e38fa1cc0d6621d25088301cbb35d68892cb76c1c6456ce60870493722425cb0d3c4ec82d731676971546cab9675995574733ac8fe2e5a9f9f8f7aae4649b38ae10213e67efd86ecc95d7bfac6437c730c6fe4aba5409d988de82f8e61be482bc3f404846824a4103cebf3f0c1213b07a794fc5704f448c59dd3a111f903a1f2a0e276e6145611135567d63fec132b715fd02a44ef486af7e449fbc33f89f5aff425c4aafb38a7e09e7605c886ec77546e66dbc7ef37648c67161310726399b2d370d8210ee4a2c33e55b257d8f3f2e0f3151640e3738ebcae5956ceed8bcac617977fa776eadeea8364abb8442707111f9a86cbe589ba569f4756ef931fa10b1c11408c59a633d99b358e2c5539c1bad02e5ef3a303a7e965d320068e937ef33f0a6e7a0c6cc60b5a0d7062bdc5c0b8c848ecc69a62c6233a8dcfa134875a11809b1682cd0812da9e68d4785538721ae0e397fd3572fb37427ed8687210c78843e0d352b3edd3e3add99da00a79a5dbf1c12460610e2920eb6e9b69a25c407aac860727b406b9bb58362bfbb6c97426b40ab6df188c2dbaa61740a6aff1394e1b84621ebc6539064a12d73ea8011a1b54bd04081360297e77addb48851f576af036137a23f6497be99ced495355f026a9320a1ef39b5294130ba4c5f640f08ba8faa4af13804717dcaf86b0ae6b7643f1e3887e98c8403c110355fa364ead74275c5710b269aee93bc9572cba2a45ea750270d684b8edb1a0ea8e8395a8c967923152f0f79929ddae212921c7d0ac49458ccd20bd3fb67ee16e65035467e54689ead27d4b0f6b97f654179b267016e1124492bbbfade543007e1472ace4761b5ae2ab2cc2b8dedaffe1b5fcd075e2191794bf10620a333ca4d5b3a3bb92680ee4d198421ab60b162e29c3dd26669795940408809b7e41cb124d3ffa47d1efe7cfc8e9dd5520da261a6dc3105c412e6bfc7483074f7455448c1d479f43084bc26a219f4beef6e3995969b86cc0781a88cf4d6d31830a7350ada934e0f5edb49ec9694dfcab72660d23a5d8789b8c407205d29f25b89935cbe69174aaa0fdfa096b9ea8fb803762da36df4e9b3993a57d393f501fdaef78f853c79490c74eceb095549eabc1a3f293505afa8010a291507aff4479098f91d61cb8ab420d07797f8c084afd054962ece98002ee351908ecf248751118cd429328c7a29f35860b831a12a873d569edf7ce6520c49af9cc665f6747abf879dc5d8660e0fc67841fd71e4957112fa3e83c5e2ce76e30e11010e91dda350f15ac166c1f59158a627bd112d2073449ae54630b6b1fdff0bc299e6e5fd5353e93e941fb6aeec2c7c9c90444ab3ce0137b69a4e888eabce135316aef5c578d15e22fe7a58d93658b5a38698c77396386fe7ced8cbf1746b0449c6c94ace4aec34aae39c199ee13bfbceb4940c98ae6c0083c82b528abecd768b68a7093ad811f3eb5e60c4d24ac2990f4f310006e1b4c7301b673292909fa38357a162752fb5e2ca5b04d5754b42ba2d8229ae1a0861136cdfa7061bc32ec0d1bdef4ce784b98b5b085744a230d2e49e30a53bf26dd44083c6a90419831f008eb6d072adb211480f65a861ce194488439c7b2d4a60049dcb02e0d25872761770d9622d8773f06ab19186edfb8f837049cb93b215bae3c162382e5ac70972f23e9210de9a0beb45ed6d3d74ec758271bf155e7538a8b892f79f2e49274ec853b2808430e5e783eaa62a2c618a91f143e629aea0591be5376e6931f336b886912d04d8b94cda1db2272d50d1aa4a16ba76d1d364d58cdeb3ec32f1665efad3108205d5d5a98be5a794b474c096fd89c7cfcc79e481591fd5b3d290d3af3b26ba64cfee9edfa999cc2a85240e05dc9df49606440f1fe26504be2e53c709a529746ead30a308c4deba489ec6db5eb3b89ece0758db96e2ab661bed383771ddbaea3b563014a4dbf44c440d9b1856c39686a5be8d1c8749647556f1e451b7aeb89de6c68c69cc5b4e05fbac3bb79520744873b02c291ea10ba740b1f98fa0e33b9d3f94afd0c9a3a0006a70314fcfa5781380ebb78a0a0835f6437ca903add52148994fa41f2fac48c6aa9729ff275a37888e9e1fcab03d6b641f2576b52cbf33bb89a911f526dfd38cfda90b22b28769b3e18aa0eca181cff74af12a75b91b77b092606bd33173dd3742af9597b6a067473cb761732569955e3c90def1bfb283a47816c5a3c787ecc393740d5560559a7713fef114bd4d44afb0774f41ae9240c6a1aaea586ed4bd250d14e361a950d315515938c4b847fa61c8263663b9a036a6bc0b3caf64caf521feee4590b36bf5779bc015efc0103c68fcb9941a2347d0f432ff07384ac3b1a9d8c615b551dafe5e382b96d9b649f745b535f03e50b8976b44f4bd46a04c3fd9ad4039d7b30c41faf22633b49baa7638e3d2f9957673a5521c7272713647b8840d86458837debf55ed502e5ba55ae6469973d6f40152c21a8c4078dfe6bc02a7e771f1c0d81926255d19b0b7ba1e05f639a61204341d2c4185d2f84c9f4a1166258f21a5a825f3e8e7d469c080cc6ef16b7b465a7f96b7f70b0c67d3684d3b537a63bf440245276c621ca8fee60c24c1a4e9f56c0e81960a441ed0d6f59dcd3d117f0941b7abac6a27238017918afe858ab0b0676c95a6cd17585a70d1c66e3f21a1e5c3be76aec72ed448d817ca227fce6d4dc8be720ca3b4fca869915f74155316a16f066bf95c68449a736b14e92fba0c7d61a31f350ccbb3ea37d4e1373d71e1a2d52d85f737036fbeff61e6b94fcbdf043094ec4119bc32eeaccaf00ddba62e267d8b84c266a084e75656411aacdadafcc3ce62a3b57c777efe54e18846ab754ddda1bc675f0d10ae385c00217f449b2ba0841e4723a6658b30cc9b172b799f4ad99ccdf06d959e8fa3976299b33ad5d7584b774727914caf6c61373a69118e011df4ef074590d2d7559d7ba90568793c9154a41676a22f32213a8a6b7b9d38def08a856200a7303912573cb69b4f9d42fe4638bb183213ab0a4bdb83a17be6d584047a746775f5b8d1ef9b2435fd98db6ce3678150a32d8f7ef89ac5f081d3ab4435f08326493c859b0e5399e608f48b86c782f87fd3d9211647c14b9bde423511ad13e9192501a04dd8b09fc4a783a44edf26b456d0d6eea56b048aa24fc19391ab9d436d02e0f7156b9cd80f69da39ed39df378c1787ca8db3a9ea6804247bd341c8ba95001987ca0044e271a2f1ade4e79e1620a216f7456687b8bd40427e20f7eff17c4e54d91708109e04d89ee1a57e02a96ec5c2ee11cfb5184275c2c726c2440a8e7022f5dfd9da6e71e75e5f41b14223200b67ea8305eb4f202a21404a616f917edda949288354792800e50c46738bfbf09d04f22acc6d99a510ccee9ef1f0e661f08448a2943ea3f245be1f46a09bff78bdbc14475a2956b7df6c7df151594d89241e1e9ca4e5f12570e3cfe84f3514b09bf228bb49dc75e47f98fffed12b2244690883f5c88f0fd6c45943b69a390e14c602cad4e7d8697b07cb5fe7f5083d55c04784c1a15893ccad106463b85ec2b61a5bb6b2c4635faccd77b978d31541688a2897d1dfbb25ad3b2ac9559c8c67858667473fd7d8f770f519fae91296fa684e46e80054185cb8bf262280152473b3eecb3496b361f394e06467c2788948201d0c9f3e5c42cc76e99cd7253d92c7b788887b498b4279b17afdb07dd43a857d96f84686129cf523e3a180f823a3d33f9f44648f5d3cfea777bce078aca32aa9232f85d2b20144d62a4c755ba09e4e85e12390c01cbaa2b6cf40be27f10d98cd6e5edf7f206fadaa011c9430b220c95346426392780793cdacdd254140f86f3cece67470b5a7527d4a6ded31fa834c6e53d13802be275ebadb1934c1e184bcc4789a57b40aa5567b0b743e2a4fb1ed1bebf9008ac34ff843ed2b018ca24c8b61c7eb8f1a58ab8f5f902930103b9028e39205d8b8f73e21db42572a0661820ae520a7f5e732e39df63810cad73de19a6b48b38e69b2a0416800231083c3eb64cb5acb34e9dd34e46121ade1258022e64ee91d821b21272ad2b4c169d7e0d18f71217017867b28edc19ee52355e167f310de42b5a0c49ca94efe74ce222fc3138b8e57e418c46500455a8f0daab0b7b6db725b2296a0508b2aef1d97ba35ca4cfaa2fe8fac85407ce0099eaf0f15e3b478615ad09a056c9054f8a82e176917bf4bfdf17701a7415afa5e6691d7dc64b659b6354e64f7451a636ec6a69b61d64d7aad2c7f8b083e95c671a5e2231a63b9ce80c7f6361f750905899944b6bd1221afce89994ef956b6aee977b6bc66231d1346e3db4ec67380b5e65c18e55f63c6a6e412db040d11a9f296590ee92f585a6dd7389de5717509b2bd4ca3be2b76156aee6074bce7cb3e9614fd0bf3a1a5ebbe884bca88eb9e2cf6ae7593dd7a620751d3d9ad356d0295f4b0f7d39cbe520d8b6ce9351d4a5c40505238f9d3aa0e2d20c90891a88b65bec97c3f4f2795910afca2f883cbda4fca244d3626253d4e736f86895759226628a6307c723104d823bb4b40de151dc98367d2212849161e4fc5085cd24fd5ef2a8b598f16852f956a09837a40590be7844f7d350be3edab81489ca4df7883361e7d09c5e6a2687730b1f97437e946375138f66ae55a6c2e9fdd77f4ef9daff32f0643c9b4dddb50505223626d3c49b1bfa66a4cb396a75bd8560f1fc69b2d0529a955b2e7728a423e08fe93babbc2526e021316631a68aeab77d15d672bb66d33f958e1fdc5fe78a260fa192503f85110a10e5ddd4c178b329ae8a8f1ea6789abe8a6b8a59fe2db4f2a4cc62a0f216b1c2f6a27db31b4d43f2da77cd18e449ff29abf6324e0dea58ce2898034ade9916e60fc4612bf752f91eb50203b91eb01d03fcf8a2953b0d293ca61177b0c576ed992262a9b5a406d0b29fb97fefa0c1e34b21cad88c9839887fcbc801bbcd74539075674fad43142188c06314a822b459c98b5b2e9ffcebe6a851a2fc77afd060dfbcd66444c84f1524bec78dbb8a5bfac7bdcc2d69ab80635334ba5af243a47e6972ffe3787c6c440b8d79ff86796fb09c45f6a7fb828520ee8cc3c6433e08de4c44d28ec2997625d401e82d3b0c869293f1e2bb18383038c88c88a17f9ac9c99031060bb4a051ecc5f03b214e36f135e46a9e9d6bb25f0338e63ad7200bb7144caf9af085734d6637e77866794e37b3a58e322ccdebad9aa2b4ef50b08ea19ff1018282cc1b8519e2c868edb40f256b07b2ae1f3f649c90b335c1e5bcaf6e457c4c5f5bd648bb9342d4bd388df3014e7143f7d30c7f05a6fd05f732af9341682a52547a50e5399271767ad2a0ee5474cd55ddb6fb106b18be59c49022aa01476f655f098cecb2cd2e45857974b47f8279ca2b3799daa1c5f4f41ded1eb91cf6304fe20a1e440af85f1dd74771e98dc84f5c0b3dbaa11584649c1d68256610c0bbddb080467a5e20a414d737de67289ec5c359d7124bf0e944a8cd733e57b1d435d2a9fc6ac737495a56b71fea7b3f493603f499e5b59ec1747fb066688037c5476836bbe13c9a4983459429f3f732fe20a3f6ddfbf4ad14c61c2ecbaa586599abcd712c450b00755518686ceb41a11048a5d7b7d227be5b37d29108d7b940d1eae8d7858a78251de544d2d18f1734722123f7e7fbe5983618efc0760abcbe3fc5afe8b3362b7cafa36b5c17d84c22455dda45b547056836f5b61158ecd9c2ac57d30fa48e9a23deb558f0cfa3024e14c3c14d57253f4ae810f31ed496f033e785b6cea48fb29a7ca452bdd76480c8fc6f2ea55ea283185546cc6ab1f0aa437c80ecc6c8e457d13ae0b57305a6e31afaee21d990386e37eb13d71b4dd159b7e3a954a0552a451539383eee21f6e83217a966489b42e06f5459b11715b7cdc7a45a1a275d6389aa80b3afed240f9c858129904c1b665f68f5773c456fd8c50035af2ff6ed4dafcbd3956cbab891c5014792b46cd9646b55e3c7dd6165aabdb328e1528d2af4beca2d8a0bd9304d5eb419e3821e3f7f2f1be61c730780d03a43f4bb2678152d7c3c7765257c93bf1d1187dee7a86666bb5e25cc9cdfd1e528c6c37fc20bca70d059e8c8287617fdc68a65de52bf9d46f981c1d7a937b0c3aced74b0d67dad0792a545e789b427dc217b7c9a4ed6eda9949c095493d38f4be1f05ffc4b26d93d63adc9e7e52af692fb4da4b9d08cd97eff86d8e28741a67e2c69f0d3d16c201c6c358d06b7cf3cd10d03d1de66f9856c546f65160c74c69ee8014ffc43d763b45da6f278c8a739064b6975de3b31b8de60a8bbc21163ba3c6b71847627ce8d0035f8059861c808b6c6fb3fd83707e5d24b10157ce61f7efc6fff95dbf1dff4ad0ec5c9c261b39c8c92c32444077570ec88c070ceb9e5a1cedd17b4e90ea3799d3a6b5bc00f0a1eefbdb1040e47f2221788fe482e75213556bc5b48c66711cd9523e95f7e093b1abf3ce0ec2635f2df6e4aa92ae8c2096c697c6f5f22f64fb67500c579ce8715d4d49c0fa797d533efccf4cd58c3d3f45e1267c373c4f9e04301b8863fe03261e91644fa7ef001691882ca02aa032c9f14737555f5e05267f0a653487dbdc03212dd2aa98d548c99d208e2db399f7c38323188cafa7ba1e3f0e7ec48e88a790b4be005c64ad9c53ed9a6c052e35d33b73babe7b24fdfd137d76299d53aee2a61c0caa131ca94ea82cb881cc4bbc3d30b809a980683a54d064ed7220660ed70acaf5427470a009ef24ed379192572380e5ac9d7020b5521c2617dff352d49808d48b390d77ce7fda8f7903f748a3a29c63018c23c4f56d760ccf2cca27150bd15df9869215996bea18579f473430c8f7456efc5088103f5df8a32671ba297a504bd3670bafdad5c3ad351b86cec1f477e152a57fde85212dfa23db22cd2c98b72265ccc2ab1dc95019281f099b0c661d760a4147749f832c12078632553d704d4c0f0059bcff60802b3b67de14ef3b6001c6ea0c0894e40e0e8f9d8ac46be2f06a40e2ab756c1f2c14bb16452948fd2d1eb27a8ee76e79393ac787bbe8907fd2545dc611252572bd0417e90c1fc18fd7d62bd92b1cff7bdccfe7d2f371e71799c18b8a8af47c32528e0e3296a16ae9c9421675fa2fb0964b9baf8b0ca94b4fce273b65fe3b64e09466f4593d27cd395d83272b5ae84a39178c8e3329b9594ba8b682fcc62bed6ea0540fa5ef83aa63a02b189e46867bf0b99d0e2a5e199ea5e2681cba28e247296d1608c43c98f97b61335f6658780fe142d78a1987ee650beb9eb5ad0a2634eb86cfc6b6087b72da66710e0d57082de2cef4b8a5065aaa72cc43a365ca4749bb70880c2ad9fe07a4e1cffe255e98ef796a770d0cf7553d7b6d63c79cd38cfc813b5ca7596b82e004656fdf55ec9c26ee2a00af1024fcd302f0cac136323090f913f5e41de7dcd574a0bb24f54e4e2405aec9857969a720a81baefc6f2d52a6b9851885e83e4e7ebb9224c31e8cf4451b2013a36b0cd40c072d3966eaec3e97e88f3a2b988a93126463bcc8b5f20ad368fc83064bf8dcd794911420cf160fbf3b7e7fc81493158862389b1b6b435c49bb170cdfb9700e77a776e187920375ec3dd8dcaa6877a71f1f88259df6ade1067da1d1c5cd2306fe7f2b45b9739dd27576b6ab60170a4274a64f9b60d636938beb49d046344d696875fc3762148b5173f919d48b193dd171bc1237c75856b9101af685c91d07fb0fe29ca1903971d4399611b45243c69dd8340332d69eaa4911655349b8013d115407f8ed5c9d382e38d183d3b7f4756af9aba5106de9bc116fbddb248bf6ea592ca4e543560ef599a7da8220215e8c3f97194c70b157a45d8da74ecd477e9a0131aa702131a2e3d0078d43015852a774bf88b8f6ec7c4553cab3250e89317f6e302b6a61672fdfe4131909481b653843a49298da60a542dfde638c9bf5a5c251e80565e113e0ccae0554f5eabc6addeff7a0cb0c0f4d38f48748aeae7d2f5a1fa6c053cecae409eba4cff12da588c54fa3d5bb033ef0ef43a2047d7b01176e640cc479e0cb63bf6ebe711ef1b07e847dd98f0320c8ede388a39b609bbcad7d73a772fd6e113cf6be2e41efdc087f0aca0cd59cd2d380fc823d9bde89abb8d54f9bc5e01b019ed5d94f944c9c952718f7f946e6e1d66512a1bfe372c176de843e94c84444028dc364568f2d56b8bf7ab8e1f940f7bc888e3c4f75c236102376583e57b6f15b5e1ab6b731094ded3ed07a6f117be4f51c8273a6637e7638dc888f9c7918eb2750ab103a7d44b9432919c71d5d9074ce766a51772eae8c5b96c6b70b9ee3bbe0848000bdb62de1f16d320e5c2436b8178d87e92e75160c37f0cf3e2d104413a4d3e1f165e388a61477bb96fe8044b7615f7772e240459e9b2b7e62fce00be1ed7af8a63ef608b65566f48fcf0f5fd7b7dad72e28561cc8d4dd0ed5d09f1aec114fc2e3b322e191d48f54d6939ae122f19429f5042251b6c8797a0031866ae56ffa3521045ad3ee626f509f9cf439677fcb1fb224f3405c49af0ee838487ba69e1b935cf2c8ad37fea03fd889a96ece90d64fe9b4fce33f744bc1e899f3a8f54df1f64212a290789301036b9768ca9c34716a572c0c6033c81a9f7bb83c0257947a402f28ff1141adc3abb95e5078a803dab4e33a93d840ef43d9f388b6375ccf3dbba03def87e504f20d7599ad214385fea468ff3278640b0480131255f511c5a303ab656781ca871534a0c087ef8d5b816c3d4ed52b821d2ebeb1d44fd012cce2b1e3ce63423e38abddd0e61840fe93cf78f37b5221d49040296df6123099d46f5d3fab2ab20e6d8100af394f2472ec688a15423635eb9ae4d78cfb244ac07f0c1330d5a97517b9606e69d9eed3d7bd1ebe598c1b01a524c004c5f322b803b9aefecf5028be4af4da6f54189095a819df940a914e52edb6c05b4abcc16e713f9f4054e0308a872fafd001a0d28d2f09e09609d0c6692ff1c3d6d3f4e811f8ebe09ddeb329609db3192cc3319fcbd7324930e1be787fc15799df10ad336e4d858794b10ccd420cd0e0824f48c2a279c4b11e7dd01f9946909e68f609ce47a142eb24bfc83e78e69c526604d8495c8b8af1c9f70de85959d206ef637c5ba86504394402a08636194b7dc7289c66996efd656b87dff6cfcda17c3fdf76523c204843ee5365dcda331960bc4cc165bb0d3b86bb2fb3f566994a2c916b761f7815ee0f6604b41f134094e7a05614d6394d42bfe5988b228a0fb3cadcee189cf8594a4c4820a5fc5652f0187591d4a4a73de8038d5e47d68d27842c43d6115fd32b27f54081ab65f0e9f6ab1ab6bdedf1e7456869ab3e08d35101d413bb1035ebb1ce6ffbda8c6ed31b792fe65ea5d2f4f4a63c1c40d01be83af823332bc53ebc93cd206e6da4758eb66ec039cc8d66516004590ddef25c6e7d60e4a5439da876f86d41d186d3d59bdd912cd0509727bd3ae856aa6aa637619bfcbdf20bc3495860ce4ad76ac3e999c3a06169ee37e8c97b1f11be81b0c1ed241b34c00058d065f3b613f8297cb0ce3a042b99fb34be45360411eb4ed7c4c7fdb392cb81d42da41e63bba3fb95976c55f684413eaf5bd115fd896719261d29b471d746fab010852286c98e5bec284436235eb20bc1e95108ec5ebd0732303f1c46446dc7a69c4da619c93ca49e95aacf2d656c2abe93edadfdb610d5af4d50c08a44542c77b00a5a4d473a3017d90a87ff491340f99c23625108f2ed1fc4602e3a5aaf6c140461734b47d01adefca332410628aed1d7f21bbefd3b594847ba4ff0ebe9e0a955a237fab3a0bbc45504bb680c0fae48cbdf62b2460b608446ede3513e421e783540fea49c0dc82ec5797227a94d1f2bbd5c52127a2ed14858d7ed91e73f017d22450555bf54afca6e6b4c72d120dfe4a5c4e2f82141787733a22d3643e8a0d5c7648dd0eb21e67f263812cf052b6bcb0f3153ae6a07a4ca4953807f0016e25a433c8d6212f2a8646811eddc1d6c761ced6eecf1555d3c4b06ef93490d8b5659ead365c5e909234d52343405c4ed6da2178876f0674bfe6bcdb098a8e61d1425ee0cda4c4110e89c40c3343dc8c5d25769c8ea931b85bab65c1618c6618574660736164d41ce945fe0b9704dc77d8fa81ccc00cc9e01f20045eda47ce7df640070c98392106e2ad96708b722d6535d51be6a83fd919abf043b97f18dc004f836b23f68659c18cc0551594499d4dcc3fd8125e9bec743179be0d5af76cad815e20e11e3cbb6354b1aa3b262e04c1cb9c916c72d5f98068d08d255a2dfc85ec61c3a52db2d3533acc45d93c0b8e3d42e6ac8b1bf2de09cc65d286a0264d1d793d6af745f179f528f2c5a4fe923e69b075dc01f4e162cc86459297465a9c923885d12ca36a3c3842d430f8faba981e8dcd8c271ddecf0f3b109d4274880fbafad6cb768bae0153d4a7ecd1b451f133adb2acb1e0af5a9e04753e6c353811044bb954583d6e4ffd372430882c18bea66b3d382be5cf9fd4ad3631d9cb3fb21894979cc15f7287e1e447565e690175685fc8750f7c74294cbad7c8f67efda0e174cbfdcc7ef035e151983bb500526c7cc14c7101a2323edb402a8edad170b5980d001b4737617478b49efc7fa729d406f37d8142447cb3f400ece91362a6cf03639a3616dde55ebbba446fe31cb263fcd4b5b3a393d7ec4ced8578d70888237219f5f9b59463bc0f4cf94e33c535f7efd58707f28f0da5d3ccfc010e179755c6979b2149a9130abf0c6ecd63e65bff08df172360d473ee3aa97c2f64594cbbb2cfd7cdbef18fd17cce080e1c678eaaa9c4e087d4a8a0cd46073cd61ccae90df0ae1f2f66629a5fb27d6bb21ba03622a54f6198255e1de97f4ae13addd21050ff3cb592ec69f9aeb3195749d638046b481b2f3d6bfa6726710326ca33ae16d9ffcff6e7f61b5d32d5e5c5e91f63adf493fc76c7aed4c3f5997603bbcb2a3ad1b5393349dadbce313be84920234e38b16e323d3c7c27bf2f2a62a67b40ed61c7e9350b4923de1844d6a244cf34b376a9c68fecd4e2b11dafd6f8415fde97b06119f641f959ca0e7e96b67a035ebeff72c00fe84105258df5dee7a686357746abbbc317d8a7a886ef4edc1dfb76e112dd6917f37a78a3efe447d973d830454db0191a1dbca4a55dd1e2cca5759d7f8e83d9da40dc2c0673b6d9ef8fdf51f1c88c18ac1ca546191f20ae415c2954dc48960f9403c2b9253f0bdf96895fc4ac28dfd51e2ac68d4042aef93a284a633d9b5b4a0580e088024681b72aa0b0c049476b8daf12498e33db3809e0fe0ceb8f7fa76af9db28ee88803f44b48d9ce8fa9fca8ea7d0cc99437d7e59312fcb11655eecc6877055eb01540262f22073dccca860c4e92b5c76589d058ed62015c205982f48f02ba0ad38bd69f4d868f562fcbf589ad1915c9347d5ee51d980425206703a4bd04f259f342d4f140111be800df25e836af9de44966495ed9a2905645e5d4a535a7f9d1962cc3eced93a686414f33c2799b1b262796f58c077b5aefe962ce6cb355082523a28f823e42cf27958863dce9912f6eef6528caf07abf4fbe86ff6f5ba9ce1dd00dab92a65b44a361fc32adc8227a80df560f356269c04a465b6d606be6ba09645bb17a742e7e7a0af63b7ec768f9dc5caf066f7b0cd7044131264ac5b7fef06026409c45281b0d52610ac688b311f3b4531437e856b2f0ea1c6e1a2175aafca0445f5d9e6a24839650426888863724ee5866acba46b2553d1520c31af442781918034d02b492adb9bddf455123713674b0b2e43f91f8595b2f084879e8e800ba0c588da8ed71e9155b0e8a4425ce11c9160de1451ffd3eab8e96e42d2af58720b0cbf67982dae76a3cb1e161326253b4c4c747fb60ea0b764a65cc6fffa65c92d4fcbae12f8c6794a827108e1e502951b34b765f588bf8e4127df9c3a2b525acd39da4af6b9840c5fab377c382dbe33e490a7578f5b2b70665a7f78ff514b319b3d7ddc163a750fc7cd20f3209cb9bde57daa40447ebee46f087eb6682090a99395f8c8995df2c8f2446bbdc596466c62e40a10dc598496de0844b03a269b32962c48bacc5fe709b3057ee278aea47b691fe64e822045c3ccb8dbd614b72e8e21dde16e58671aa51adae46d1e7b612f69934c4512a2f81c01020e5d82019483221017e582cec59e4e5e7f5f27414a5f5e8e806eaf63e5c43954189a1339b4d552b9d4e5e284d607d952594f64ffc251a5caddf3a46935b57852d87be74df18aa1bfb2d4f54495ab7a55e1ad870ae85b08938680c764ad1ef5d76aee26509de19ebd8eddbe250aa4e49d68f55b42aa1518c6d1bac4e7a6399b7bca3610721bea61aee975ab013008bbb871940dd6410d3f482c9d9e0c1dcc6e17c22c9ea94cdd95a21ebacb891527ea615ff1846fbc501174744b79d9b603fc87ac02ce14513540d5825ec461e28e817078b9349ab1344c685715c35ba8afd95c95a26599fafb2a1abc050cac1b10bee5066b0cf864aad665306bacf4c8b00908aeb239be0db7a46097ab4085050a36855585813ac0f23b5ebe0f9b0aa6096ac5b2bb6722c784723cff24380f94dde4c74cc106e714773043a6e947edcde0720cf7b1006b4dd49e8473b60423a80a3c6b091bdfa053e6285bea73885da9eae9a76d1562cb0c2762e9484edbd6ed4bd5bd14d8371945b423d71fc59e34f6208230cd25d069a981b762ca56dbabdc7946b5c0cb6ddd5d75bc8d853079c771264bb7104919319bd1518320741741493df2ca3f6718702b70d018303278c3957ef266c4fa76d6b034e5541ebfd9fcde14e284a807e9f36594bcbe8f6aa9b0a836e41cf508174039735cdcb5b4387b9ea31423d27d3cc3b5de768b37d2cb393e4b15e733b6ef6c74a371f6ce8076548b6ae1bf4bfb79c6fdd73033b04701130566c707b24fbd0be4390b5375bbac2fdf5904abf6ac6c79a45ceb241f4f9284a0d2ae6506d94c63d6e299cd1c91e21a7b624283b5fc279ce6113295d4754a8b3cdf4b419d91f20558d95998737349b77972e57d1cab24692a1c634a1d09ddccf81889f3e312c9653e9d4ada353163507282a3fcf11e34085d06bbe8720728227ad624daabdb155cc4c8025d6c97c8a3d238eeea560f482c420c0de64611bee301a4994eb0d32b2b43bf59990031f02c5e0ff9cede88e27ca1f8571d297d0871e00b5c609f90abd7e091ff956c2b8a858ea6ccaff2787803c1636d2deb861792926a2313a3f350aaa49e21a970c2a4c0ab9c3a1fb07e9968e3dc4eadc1620f58a4e6b7d2e2b0106fd371493553ba7b669a5cc4c0bf9b42ed81cb911e2055225349cb6482968315d332bf2fb8ce673ce985826b18b2fc40840814caa72b98f79a946c4bb98861540a1b23b97d9f4b3fc6d81598d8ec5f9333806e834bf626eeb4e7cb546df1929f1c6bc49ec46ac8fba4390b4ac89832d143e0b9ab958bcaf82af9dd07357fa51e856bd94176bb415b905d475809f3fc4463a6e6cb33ce5f24931448ceb85221b19fbe9ba8117d42740927bee337dc6ac9fa4538d209eeee1b9b257b28793e244b4d9f11f461e09a7bfa4b98563fa637ff44d8aeb3ce4a8e71f3f3017acc2a2a658ed345ff35599533e38acfb5659a881f60e3b00bbcd40da0ae8233b3d66bdf522ecc590481f23f64cf02aa550b5827581bd0870a9843982f94567c5d493fdd34a7f9a2dff68abbe1f908c10db153998adc8ec4d916880d8ac48268dc827b7d2a853752262727503a3404dbeb6edb46d20bd236ad3986b71921bd94e1ad4f30603c3163b1709ea94aaeec456a0fb7cd7a4877c46893860103297fed6eee821745d5b286f4a07ea173944ce1ec445a7f284806d9915d5366c369e1783ad6157bb12f80fdea27a79ecb95a4329f1e6ddd711b30e48b0521745ffeb89e8e2bfbb8a361f11628c9963665e89b4fe4766534d2075d0e13178fa5097a3fd36aa3ecdde7a55a46b1d0965cd639979db0b275e0ab90d184b23ca93c5a3f67fe90bd09cef2fcf16e65b1883fd442e8240cfabe2acc39d253bd9b6f264089252503be753560f129f7a452c9c6eecdbbfd9cc62bee3067e72279f391bf7c648bc3b8c14c94c832b905e08b308d288941d2fd8619e11004be33cdfb26b3876ec6df43470aa5ac8e0cdb5df1541069c49f9eed9f6f58b7a3eac849672a5ac9a8a1db7eba7fe14f287ac450d456f9220f8a5234b727d10e0f15754202cdafc1b632f6f5948df72068b0df3af5dba59149b94a38f0c6586126f3fa1d5ad5f0757096d3b9e56750bdeed5c0d3cf36b2d801a2975e229e180efcc8138d7621c4150cce24d5572ec2d646f0e42975ff72158f5b94d7c0b6123b1d1fb41764cdb2df4f52e7f9adb989f91f2a51a782b1bf1b1125aab870eb82db295abdea94511874444ecc531530dee94c23d1f014542317a267f089b760d235de1800b7fd1150a21ffd33a95ca6cf8d7bc3a205dc65a64999878c379831362dbf9c0d43ec19dbdd8c218c20e0445d6fcd80ed8df50acf4ed8e825a6d3b78c2481340cd0ad0108b9995264a6bab4bb7e8298fd42e222c8ef64e9678cd9f316dc18a63e35367fe0e6c14c5c8755fe975e9d8c56ae17d1317aeb1fcc22dc100a159f321a1a3b587c45d8842a3bcc8f02e44d918e10e0212eab367f07325aeeab752448da4033ad9351363ae1b462dd35b9e12afbe80654598af372110bf6bb5c3d7652d167ca66e16ae1cdc8ebe4cd30bc497d31b385c7326914e785cade2ee36436920ddfb2397df972275282eb4eb5ed8f9f3754668c41717d31c1c9869a71e395b87830a9019cc63e2748d2f8cd2262e75ffe667ea3fb5dc860117fd1bf35fbb461af5351a0ac86794316e4b8757a2a5db5cc30bc577b03ffcbb301a5f74d2101c74b0b46588135b00d4db455b05813f85094e6979f5fa665baa12e1852ed93e352981a57d9f7f6d6dbdff47efbf2ed76ae8487768b040203a49008056be55ed13c999d9793b86f8d5d26c27457152ce2b859b512c1e6e412fdf00dd07da61815671c707c1b3544caff67efa08b85dafb4e2adcb06ed1cc4daf4d219220134c099ff3b0256379a86e67d32d7742d8a9c6302fee2e098a0968b01acaa644306db47f23c14b8d01d003ad1a8e115d77d6ab4f02c3209f826cdeaac25f18188d94a5a523625084daad988552ee6e190e3fac0cbc1a19a2ba898fe54cf8696b8e98e074f4a41aa0aca5da233f3218a369fc7f03332f973bc82010a3a3b4afd564148b97a18aec710d6524274fc931550325387f181a9d8a647e04b0276572bbe8a02e0a68581a9bc76403bd4879cd718295bda6971361d94ffd74c622e32fc038195ad9c3543111c3382de0c5409ce450a464218d84ba31787c7543598989a8cdf8a144c8926bc6bbfd13e752ee0034515c230400ff885073d5373f32057334a58e5ae9a8119ae1a3a39c668e256ef735865adf4ef118b17becfe0500ff885ccee25475199544171261f78833f5221eec0cc69e7ed982478489468898c03103870afe366b038dc9c5645ab158b5bca4ca64545a144a5fb038052342d0ff19a32852e6bc3c4b79ceab0495002866af98fa0a7495c891d8bf7a70cbb645c5892df81dc13130322498cd83bf53cea3246605431a1a4dbd5f715e5100b805587799baf1d5b15c4c9aa25af0512a8777d3c80cfa4653d1cf2118e84caa8876dbba06c0a2f6d81e5fb5a88c54811700957f0def107e4c7aa54ae03bf4effb5591b3509ac8d3dc7e1eac564823ce5011b999212bb196f5d675172939efb445b6858e33a781da545a1e7cd3ec69cc679d655760064954131154237742a83bb8ab333d2bb0cd513b2c47f05dd5d921e558888bd14429bfcb96d975bb754ca997691858aab71f9c1458b11901c8842299d0e13d40be763ef9eb38bc4c3762f582c0f1f6991b4c5468d1fc60174233450e57cef09bfcaacefad667c98623fdf902960105b9029139af1d741a90cad73e4bdfe90e444d0687072b9be16ff28279d21049bb54d7bee4132b4d1d77627f10625b87318162567dc25572281877230fcceccb393ca2bd8eb55c2bd308158602ce41f16ecfe7d2ca24e460f7218e1eb17c8bf610d5dfa91d5e249bdac7d2414dd42bafd73f89d06fd5d2c04549f56b74c1db6ba95c7c800b2ea21b92567cbe0fa59e15395679bafea48c49210a4b95dd489c9409ddb9391f15c2be72e4b0dccc0f0ecb9dedff9c4d3e8f87b52f382f7c96f10f56cc0f1a79bfac54a5b59b6352ea2548274c8fb084fdd96d3bc69dfcc81e99859d2cc0bc345533ac5b0a8e9706ccd73ce613438f40a978f2ba8235ff8716fbdf9edfb3171cda517c5a50444e508be477c8fb0ae8a6db76dba51cd5314509fa6b36347fab652d4569c93e0f23594f14cc5d1ebf7e615b2d47ee45721767ca506df31cd735cd25447ec2b72b53899311f8591b4e6bf326a618ef2d4308eaa68c9b40e5a51b7d292a2759cc94022fe0122431ad39501b24e4e0196d65698872f09906b32a1c0b3e0b6090b2b8c6bd8891dae61be775e52c1b19c65acbd79ad56fd8656a01020ce4e20b9a91b87396c9c2a2a11a81868654799c19fcde66d4b291847d72510da94bce905c9a43c6c2b08954e442e55c691579fea14b5074e087a50f97e78509bdc69c6d679bcf0d57da52f232913ec41dbbd244c43d9a8d25f9effd3b6bb95255f615aef4f06ea3cf1cecd8e1fd2cc880307cea197d63f294976980307ab0f5fc1b0331095e31d334205b20f95853ccf7c8dd89367a3716eb1c120b2654b9c79ceda385171ef9512c02773e78e538809e7b6fc81ce217972a30adb4fe249c460ee518e7c351dd7fef7287bb99427a47d51a80b0e09eb821e6dbb427a117d6cf9b88ea59087f343fd4dfbf9cb574b1b458f91eb50205b91eb0e53ff3d7506dac6e4f9c44929d3fd7970b17a250d94a39fc351af033758fde4023df27b1199577a085607f236805cfb91c5ffdc6a1ef59dbd2b287acdf88280f0d808d55cfbbca5b05ad9c872d67b692d06edeba7ea9f325d0ea062b5e5d30b43f191d11de44a790c87f387e00d9f3b737951dd3254cf4050f8341ab1e8f7c45472ff9471d6118444038043c2f716530e25ae0a720b8b9069c452e8f5774cd2ac845288508b0194054cf29b37b059e6e2da7cc4631d4d9022a69e36f4c9eb4e75632339a773d50b6071913978233897f35a369d64c6b615c00acc1751dfcaf608fc08c33aa0e1b21b2f3d826985a3f94e6daaf603a6f8efbc86fb5785563999c654efcc35d2c5c0fb27bccc747d0cd68ef4ec9185c76503a75b44244243ef6ed1e6c210c7fb2300ce7eea3a002604391d85e2b429879c27d37bc658786278795ed7c77f313c485f8768141e80c82c13c6e6c4d16010efc4a4138ed5631e494c5e385bbb90cc8ab4535e62680d9fcacdd1d91fd52211cac110cd199122acd7828cd2fc834fd44620104ba27976b0cf2b4e0cbaa8284255b13a09de99243e3e6d3d9a7dc7ebfa76b92ac0de5e741156be6ad2f5a043e3028b7bc237f02d92a700e468bab706395490aaf5f9e63fa15e552ded1529b6a75feafac03b14cd16d317812e4691abe7bf2f804a7f45058cd4e896c1e85e7198499b9179c9ae7e86f50b57f10f4cafab808d118123bc8118e185ab77e9b59442b4a3963ab2beac096249296915ef0513344f644edb10956218b760b15b25af1bd11a2c487ae48b4d3623365bacc6baec5e8a44aa24143e98f65bb45969293967ee3c994d8a531db6a7462d8ec694946848d02dece1a6691239dee3e8d88eda85c386e79a4e68c2ed79b8b78ae8f4419586d883b9cfbfe64ef829e818259e6e21338bb87b8fc5bec59cea0c2969623a37a3f4076e062265c5f5bd47f79a6d713801d4991182e9cb21850656c58b07ea9128bd75d3cf0bdf66541f20be6d8a33e95b481cb812f8d42be405594268a73a910109b42f5fccbf6b2c58d69dfd2762a075719e70c259437a6ce2ff7866ca0c737d998ed2da0a0e886fda077001e3d630fed0ded9e2aee556123e8d17dadb97fb0a5a596ef4bbecd18f1bf1153ab738633b448ac9d0d94991a7457212848decece91daac4a7e6b283bcbe162bd89ab81b1967dbf65ee5501855516a7c8d9856552ede71e3fa36f8dc512f4f7205436fbec1f2acc944ad96448922714a99adda4e8952b96a2d8172e599e865a2d837f7bd06beeffdc4d10db78ecc6f4c88ef4fb2ca129eebf932f91582552c105f913d9f3cbdb1b12f729d665f9c139c66ea5ad8b528cfe71f3945416854e4105e1327238421454015226b0cc4dc38e2de409ae9f394ba2673a245ef798974c2ed0add2cde93d8d1c98af020927b4c4998ff98ab12d28bebca2ddc19aeeace4c7d044c40f2928070c24b66b61e341a729495ffb93e93ccdb580bf4d4004f7f1d4c0b71e8fc7d491013423adc8268ff6ba8f86bd068c7eb56ff329c711729406404b1069dfe4b54846e763cd0df8533d1dc509b1e5f7ff6cae6f0edf8d3f2ad4424c86d37d90ed9fa3448319b4a4e29a83af7eb52fc8f8af45a13f5ffc081854da53bb9b0ce7d99e5df545c6a6ce8e35805c28becaa1783fda22417a773e8586f0b84a01bf86afa002bb4d09318e3844214a0104bfe05916eb1a8efb6de2fceb90f51dd42e5f8fe04ffb0651454f43c636b4cc964020a97102545a63350985b5b030c240a901b29ce69925097dc2519b185dbe4f054019bb975595a168e8c4a4e2ff0c934b3e3c5733e40aa49000f874b8a5ebb69998df6570758469eae79806a71b99cc5d9d8a461e9519ef1f59629224eb91ac0570461b2a7be18a500b16e1d5c6211e644e5f8b360c34ef483d701fd70cf02adc23c34e0cfc0d23e8766ca7cf7577e9a686d5ba7be8f373f04f49303ad4494b90d904547d574bd17330518a8ad9154a3d9c62f9488a731da7176b92b6fadc187a447cec4e624f74a4086c02c81ed6eb2ae43e543d14533640c88010b79c457b1ac8e17617815a4201707365f77130060908da0ca35b2121b7f60488433c2543ae019443964198869e6e428c3403bc873d9012f6eb6600b4a3d087dac193987524c717565bdac054265b0d941d56aaad177309d8dbc60f3c6e26950145d6e761437a5366cbed46c83ceb166790599f22d56a4b9511ac3072b6fbe7c6766e4d6238d2562fb46db264ee2dca2be7d685ff4c20c2fcd7bccb372c7422ef81cc1d1edb41e51f6041ce2be129e8c8b3d464b90104d070246f85a96edb268578e32e104434862b03f504814fb068a917fd5676ccd8308b26338e4c8edee3817c8ecb6da478db6775ebb7fd299c1bcc3806c001d9f17273466d07efba3650bd85a368f16cb257b7223cad2b8debf7d76b059311f83a8b2891feaeea91cff4b7a7d2513e6e4baeebbf691beb20acb80a66ea6513e1bed70570029da74e7dd14e9f40f904f66922d43227427d17271c1767753d5d1a2a39343cc58dd2281cbcba722e1aaa629cb0347857906a48759648225ae977b72ed5b2e019852fcff30fbd9b2139a61d764004da898c393d8c903eb241d828834d0e1341a909370b0a2a7a0f60648a3e06d7a083cd584268abb70b0e563992a843752ed1c6e07bcc588c524cb78a6835c16530a3dc2a683a67cfd2f2dae5a0e855bf4e208803d07dd23c7e936750a942547c2ec4249d77af2f4c9365696c1594d194a365c6842fed7bed58ef7e8dd83e96d0da8dc3dc1abdae6ba2f858b38fa0c588eb5748052a2558c2896b8f2db1629dc174127df233453952252b24986e6a81365d8359c86cb90963d831ffb12ae34d115c32574c2c1431eb5209ff70b9a0c42d0962323cea49c505b5ad8d415245482dc912336196e2380db0aa7f974655e667ee2b0b910e65e6cc59c6c48455c4c8483e9d9034b51679aef6455eb9735c8133a83b6b8390694617d0f11723540c302d3baf6a4fe9f34b15ffd5c453e3ffca202f8cbac96c8a5641d3a83fdae98e440235b0fae757818652be69788a6d199645220921aac3cf67ae15fa34c4002902ad9af3e6b10b690526d0704da56664408d8b17794bbf09e3bb4e25e88b90aaf943cf8bb3ad591863c367a55025c60e25372109bfc1c8c4412432bbced796774a2e89a556375bf4bc5d7d23064f47857ed39d67fe333315410cf6c7f3937a84f8b02f10c89391a19172fa2f0a6e6e4c3f72045f6a7b4abddd84407bac2fbbe49796910f500eda4be0408a710b372d2b6127250f80cb3d7a8265519b87b3c7b1d897ef91e3d03fac650883ef9688b99f73348067ee3aecc6d97e0e595168a9e626f41c0cd14c08861893f31cca5d509b14c743b0306a8e99735a5f407fc4cefd557fb0a9a2774d8302dd4976e93f6cea52a54876a311aad5faacc8859afed4bd7c57e5a402ffced25a02908a13501afa50646786813e7716a96ddf4b5af1d111962f2fa618cc4584eddfc85ef5c3c7e926cbfa4c8212e55dcfc4ed5dd459b66e86fc20cd7ae89583ba3e4db8b075c8d604755d25b5d1355e41193d18d571f272a2a45defc92808746712d0a7b81bf27937bc7cea781a0f7e0bf5a7b9a36239a3dc68b9e9ebc274a4cd6a7392ab12081408c2f55b71b1b095556323415999023e6a2dfcd5a3b0b7dd0b3b8629ba23df821c54de17ef51d7395a947439848bee85cf115aa07ef2f8ab15f9a6f0f42033194474810056fa6af0ae2917f0326010397f1e7a7ca516e89dead3fea6eae9175874a86f19f6177d40e486d37f20e58627ed807369224dac42f96b5234f82c27576da3bd71b4768ba7fe58d4a198ee98ffa635c1668c824876d0a03f1975dbd659e8a37de136d1fbfeb0aabf9a08eba8094ea0b597148641d8093f604d626e0ced0cf58c409d7aa472fdb3842f305a432ef3f256e393281d1ca3f9a2cf80711cfba8df3b99f8bd5f6ddd4945a808b14dbac98d331aff99485ffb2ba0faf6333e7aab3a34414232ffdd6c8e138828063af9cb8a4cdf1f2587fcd05d7cf71ac22b4ba315d636b407a00936d1ce283f47551ffa8f6cfaf8a7c3ac0c433cb1d6c740ba0ab5e51e76fbfacaf15a71824f4c9798d697f711dfc4713229ac22375134c565ada5d59ed8356d1ea3abeaeef287b9054a8f0be86237821ea2fc888d822d6fc10f953e6831167862b29ffe13cc2385f7758779f9e001110358d60b11217c9a027ff96a2552c084fb7f1d9aece068b39147c8f280166416eb56eddc1018dd38dffe886d5cf006963143c2fd586001dd30400033c3b5b84626ccdf38098f4a711da5ba5ae8d3aad9cba1cf74869874d2af8a47143bb1d9db744b92616780a91c4c56429dac4054b81c8dc8792250306c1b56583dfe444ada8a0ceb628cdf4c0c122993a3ad068538d5fee85205d2a07355e8aea8268b1aa5916fedca64a0ee4ddcefbe04b10d69c97d6b88e03ad29ebc62dfa310998229b7b9ff7791335b47c22c1a6c08a8f87afdeaac09c362a406444796732ccf7ae744d6e8659269c81a7731de8e8dffb4673007285998cb188aaa5ba8ce8ef7d0a97ccd532d68b79f014124a79ce4bd39aec352c1631033f04e44b5a04c5ad3f6b6871a8047b114f613858f3df5cad6299a9c04bf677f2954af1683fc03ccfb378df64c3e5a5b46f62c397a1105a0a7ae911b59793cb6ba9f55ed0edaa45b211a0a75ea66d33abb4b9ce962666af99a4ebbe336f27391dda66248e06f680ed58da555dca116df9dd5939f4bc7264d65631234db9acaf94ef643c833c0d324f5e5d116ebf3d5d1c9019ed11c522b31040869d38ae54f9048060237a79b08df8aed6497c505adbfe1861ef170d1d7e5299ab28e31bb4a4e4ae593241cdbc91bc289380a481d8c38c7aa8a0e83f909dbd9a0489ef57118800b7804b4d2baf5321c1fdd175bdf0c894175fbbc050befe320eab1f290834536d4845953af64563c3606c01dc39bbec2d0f871475e5188d19055e533f8a379d470d9789f0c6f4e8517f38c67a6ea03764e27efd18b054d13988abfd2a0c4073d0a515b99f405254a87644a2f1ea5e4319c536cf113aad24a649ed3b1f38be9679459930a32ce78b904e858a1567eb0fb166f0b67210b4532ec00cd3695a9d90988d12cc226e87480704816ac8e21e6260fc469aac46fd032e36630d60d592cf7fb9eae18586f3f7a934cebe1f8d4673d60ed99d7236d21acaf5feb9d22d99b16619b321cf844b4914a70d4354ece02c70e2650f1110e2049786116d7023ce1889d2ac94b537f127b79f2da5dceae2e1539123ab4266a514fc660e0a91889d01fc782b525c37c6a8318c3f3b2d8ae9b7115410476fabcc671fc47fd493b8074f4c5dbf5dae17e8d45046d8be4228d81860aa5349c2ab56f74085de7bcb707e465119da5b67b0b6ea0bbb11ce37ac27629b90df765f9107cfb2731ae23a184b4f051930f082f537c0d4e87bf18677b426a81a42b23cd0de680a2fe398d8ce9c2089460c62d43899ef0dd25892e135995da2e6fe64d0d1472499f7afb553cfd20f5ab05b51201567c7f58cc65e6f308b307c816da024600d71eb057d2987186fe2c8dc8df41c42ffedb8333198335e787314749690bf00d51ada080e011b8b18f4caef69a43df1627661eabddb4905eedd2f1a706384ff94466947aefaff75fcb19e61ea0350482dc9955a832a4eac278cf6645a3be689eacc262057cf81cb544a98a85d8dc4b26ba0aab90da586db4c375108f02204330505c41a7f0568aa970cee9559b2402f8aa5c96dd49e350336d632545940965de009eea83eec17c0b8a33b0a75cca8f555c0c9d5bf0b0334209e58174bd0d2d22e866bd4a2afb28f579e5f92d0e936944a1821f518e8f98cc80f0f83f74485d1ff1570cd83807e29a9502dfde878b6153b1c6e4126e20390d8b92d4c1863bb2b8cdb88f863a349c93dc0da927ea7ca0a7fc39e9cc1ace2e16ac1280b73c9cb9e1fe62d4db7acc5d60cc9c22d1ce9ac0006bb31beec8fb959afbb1fd3e65ed504c7c3073ff40b4b1eaa3e2dfec8df9f213dcac7ccc1dc357b810e953aa8514068f91cab89d4574abc06489d8dec37362e73e411097d92993f0aee3b7d187552370fed666a851035be155887ec045425af4960388d377e1dc976ed06f0388c617c868f600862c5f9bbaf79c4385c802fdf800a1b97889c13ba649e04bb75cc85e6ed995355ad90fb5ecebe44993d742a4033429ee8947d47c305ef816a520271a0ee691a8a5fbb00a0b3279965990a217051eaa904d380c32b37f274e38942eacc6f121caa95a46bb343ec07f72d0d6f71e4569e301932997b0d929b9c13e19d97bf820e639e87dbdceb7c3c04aa355cee32eb8dd21fbc4eba320de2d00dfbd0633da157b5a6e40ff66007154bd78aad48c8e936d3ba98490d7f45f8da3afde62456943f4d13ca073df4d7d4c23de98ffbff63bae2df782f97cc89886d2c22615a7c49d7bbb1d353ca60b803b5cc2f722bdc7608bc4f1b4dbab4d3f632022d7f206f7e1549a209afdde084e4cb40d84f008957d3e6068de9bfc36fa3c0f4fd1783e820356f4272256669158f203d50a7ba58298f13d7988870a7ec59e0fd54d04e48d36e63719a3ea502749f6051aba9bbb914819c91480fcdc1fb91569c1ed04f1b40af695c3f1054317f77e9824d453972f04db1f099113af6bb5879d0477032b3f0f1ee381e377868fd3311f307454621f0157741187939247f2d3dd28f6082468231aa0a7411595fe6a345bb814dd37a74849ceda94582b21a1d81725ccbe4d548ff6c63d659a93b678fa04eea9bc98182effc312a40a05e38aff3bbcc486cf8dc095bb00f2633c5f0acdef4f53d427e759d76d378ac5a056ecf9764412b87ceb51ad8ee6edbc2f03c3922991d429c89423d69036002c7cff9efb430e637de93f55b9a8411bfb711b0ac5dff0a54e1a0c6c02ba0f6f88c709393d0f2866a2e3f0e0b7d3160755eecbb8884ff001c1398a6afd7415e898ca82a23755cfd09397204518a4529faef841cea90a493e6595a2fadedc4e23383cbed6de32eed20f474ed41cd344c7e55bcd016bc3307c96546841c086f9bec0db16829f37faf7a518a97a3727380f87ca71b8a8d0147b8f4f3f7024889544613b9b0e2905f963a3d073f7447fe7a2687ddd2f69937df9fe488b87e1e6b890daae4727728b621fcbdff8553f17f73d1a677ae6dd8a843b7a208e9f977630a141a5922407c5d6fa85a8e3a7c6cf206e3f8d77423c35215d0d78241c03a1d01891e9e4a17d9b1648ee436dcb87bc77347f73d456500da2d35868f9a2515a75666d0ffc363880fe10252e89f753ad460bc2ba5ed92b483c5acae9066c0afd086f8ff3a43ca92e22a6bf527b8bf221f4b0603f040eb90b5d120d8c7753e521b940a93339af74492606117d455a52e0a65ec90b45f46cbb9008c45916bbb93d5f679cde4c6eb0500c2c76416fd17f05aa1cf2cf5e8509d310006eaec3b04cf9a314573b1f5efdcb3ec922cf43ffd0c4b681b1e3dd4874a315efac912b20f6484313e0523d98fecd477dc336c2c0d0eabc312e6667c1823658d2de73d495b324f623f80e5d82b63b49781fd8bc8fa5a1905d6e362786834a96d76253e670d86f4cda4a1ec93a261d59f02ee2f0ae81c41e4379adb0c7217668cbaa1486a00349a2ea689ec7c1d36af1d1103e2019eb6ee7980cd0692d4f7ca9f20fee4abbfe8d681a8514e6463284bcdb518cac5f114c80475d3e6a7de2a200c8c45ae849634acc37dba35dbe943d5555c02def58d4d1641692611e110cdde2280fa42cabee8d24f581dc79f066d9b32a2f3c492b03f19f7f3665538973c5f86b97cc5e5ec57f413c8e8f340774cf659c07bc9bd25ff110a18e57c2a24aeb6e931b78945ef42b8d12416097428b0c31b2d228f70fd074943ea371af979dee779ea57d27e47b8171da5d39c3f62f932c6f49828223b233d0a99ad417eac668f60a671901503520b2e1e95aaef8f89ec3756b5c8c136ee19bdd282884f38cdd6801e5e07f16829a2125cac8f25660d2dd6bc77e8a6752a7c85b0a20e3f3dc6a00e2289924dee3bba5de5fa8191714236df604ecf6cf3dde7136c0baf14ab0de6f37f2ba06651ce25b4c78e0e004a3f9725806e7799cbb37967a9cd36d13d1b5a33b2fde2fb886ee4bbacb99f53ccb4a8578866c01210ffd40fe84392c8ac0201c0ca4b5c0f189ba56b24b9d942a7da752334cb8ea26df01abcfd0f60d3c6e7827551c43d34c4da9661d95054d5b617352e2b527b2349c1b18f95779c3656e5d24814bab32707ab7ff5b743a888caa01db5cde4ec0c988a6a6db9fbce88c7a21e10789968ffdc2af6a6b50910384878485ee687f59eaa125b106c0fa19c5cb25664ffc95d86f9264698714bbaf9ce2d79075f3f02fe454bcacf3d2520a8ff137ef8a275e9e7a1bd1fc7c656b51b64042ad8e5aa2bf39fdcee1958c92716d0f997c9fb3004fe53bb3ab41c4e3cd31e2000b20977a4f194109cd9f125f8c3da10b86b63623bf86509c72c1074380ee94e14407018931890d341653c2242246fbac8f5fe1a73167cbd96b80d9019ccd3c0e28c25e8f55f55a7cfc4faf30df9ce37cfda9e6a242a76b2fe81f5776ddeb0bf24c02aec58e0c955eb16757468dbd2df41bb6ee589e49eb69df1c9cb63a2fc50ce812146271d50a02882e9e6192571c96b9ec5d97390f75e173823d16942d2d791c6c18f72c4029b82ab0296eca4b26fca59973c7c0b206584351d7e65083a4293a66a8bdfdf927a2be865e979e9861cce003bcaec88a6a30a1b840f13908510e4250d2182e7ae0c09b5fa304055a76a3bb243bc74b614f7b8fd15c986af22ee5d5fac2e23ec3ffcc311101c2981445192830fe98f0abbc70855c2c222b7868064025453d2dbe43d92181d6f0fa63a7862fac3a15ec0dce0340037352d077179070fef7840002cbfe955b90b342555dca27988e530caf5be2c255f050c2eacb8c656ac2e176f955569c4231da009b09c646b1ae448ab4b2f075d9e11babd26c2416e0fd30849bcb6fff664227d0b9dac25e5fdfb48c59cadf91d4257d0eecb29ed45d992c26fc9da6a9dd9dc1a9cc1382092d1cba612762be556d53a5fcf262d6501d2f90cf77cb9b8b6a711fd59f2b58fb2af4b5c508015c4bf6dc8ffe1f5f5337e3e4391934461bc4d79051fab6bf7ea0df64ea0988b1de931aabc14f149653a567542864ac71d267b76bf27f258f69c9ad1f2252f51fdb29675e0f755a0e0dcea8704975710d374f15794eec203ca18c56336f05319ef5c83a0d9d8d27dfd71c171aae3db552e102eaf360b7cda805107ce25d786ddc8f367bfc78144439458a04b978be97bd3c26269b403d937da97d170fb242d833a56cad95b7a6a665a168ece7dd16b42ccb3cf63f323d6701ef3bb21e48607c959665813b753d7a7a5b763d7376636532776b6e250408c983894a51ec56475bc1723cb80fae3df9e9c794bf29e05abb59ec912d82d34d739b14a9f5ac53ec4c179d2bc668991eba1edddd7089b90f48a275756b97da275cd2c5a11066f65d9e2742e5f6ba176c40e1ec5d6f2813c3e6ebe52a6e49e9a3e42ea6ff4c094bd93874c30cef26999f2a2d420d77f3a084c32e58f0be351f2385ce1bf02c4f73575fc5aaf01527457a7500290e081700c76a46d4274dc97eeefa180ab86c7feaaf5025b9e72d569a7cc057a1b1dee44217197d8fde68d37a8a5f79f9721de2700f84b70ab382789861ee11dbf7fdd6f96053efa94ee08656351b162f36244be16dd18be05e7cc6534a1ae0fb600a3a0cda74d09c9d26767481dd8af42df0a92650975eb2a8b5ca58e040529b637bcb980ec02235f8ef2f351153bc56faf60cb5108d5a05924a9b1df2273e18c532a366042174fb3b961303e513ccc8d0c0bbd6ccc9708553ea48cbc9485cd25054aa3ccd6a9a40e10045c9b50e5b05f1bc6bfd308444191cef6847d0602e6c7430ac1fd437508cc1e6c8da98ff860c5226d79af009f6979507ef3ed61abd2bbc5da0abb73b82266c706e17e053c82f0d174a8d36ff9abd58f614b5e0b446612b550663844ecb6b85cf852cf9858d60388b394c3bce8a995498196911e63016fae4e66034f0198e7072f4b7a7f4dc1c484b9d402c7d054d9434d3d35b5740cfd3e4573af49761dbe947199e8ec7f5cde38742b29041f3e71d0f0e890b82708af44bc98d0e7f493b85496890cfc0b238818e0886abebfefcf57a53f466c2243a248f2c210da1aa5b3d898aecb0f5b96306ec8961806d5df768b4bae3e50851e2d2f88de241dab63cf677c0eeba9b748910757c4a5508d44c8d53d811e29a9d07b554325475066fd32adb0fc13e82d97ea393297f7923dd25c9715db3cfeb76064219a2f57db0cf6e57f24a976f1bac74d516b1fc9e807ad2ca8f8da08a89efd378860dce072d484fa4648d81b548c9f0960e53126216551a482509b972e988d6f2667d462f8d6d7b45c6607c713df0cc013e66391e689a8a16905b8e73e578f5f6c54ac778ace9555924abcd4af9c3751394ad2ec16a5104e8bfeba15cb918c61d40b92ccd6f4c3e1824d12d829d3f6f63d4aaf36184525b97ec0a6c307ffac6084779eec8a2e7a3d36116f37332aa7baedc2c99a256d97cc2836113153bac525460ae0d6052efca949da3ab1b438915a1c07207dc1f46b64d4cc2282b786fb6c347a466ff13343cfdc4cfdfdb300242dee8dac2a294d6119a4d16b0baa0b109a63f08628957b63d30db347937db17150ef074d654bf777b18d8e98bfa4e690cc1e552c505b4d6a3f1f6660318c7baadad26fc6ac3453d3d696c41cf89871d6bc4f14e07fb26160eab7ff90d3add18cf4ddc71479b05ea6de77f9bc1e4ae198bd80f188c1d56faf02a3c11b22927ad04eb041f02ac931a1a13d14fdad0e6071b61040dd9794f61ac0d7f14cb39e23d671e1db51967166de7e7fc0d1e8fcb1b9ce4c5a948596e56a1dfeacc986ac80ffe6cadcedc9fb975d58e86e1ca29f902940106b9028f39ddc19e96612d006bdafb29c4d28658b43c51bee4b91c8400c1a583ed9852b9dd520619424e9174b48d5295fd021cf44fb875162ea48223bc0cb61f988910d95a4b90da4e75f89ad9804e2eaef74e671e3d683a3496e9655be6d296d5f135929de16593ab2d721b6dc29b38098feb4e4dd60e2e85d01e755df3f1d608ebaf1ce363d7a5852089a0bc872f26556270a9c68a68f597f99b79ec72369bfc21aec089ed96afad737469de05574a45b98e7ad9cbf69a693b44d924837d3449e27ba7c175add22ed981ad6b60859f1b9328758f8b5b4fda53f0446b0398aab8ba252d1db8c4cc8409f1d722d93384683e8c5d9d719ac779531c7a3a482d75a84a3a47581c1fff0f4ffc3bacde38ba479b92af9fa27f8621ac7b383156d1a6e514886be96b4b6179a812bbe94bef71ef42489f3e175b1b5518c623cb8c6e16b4e27cb07bfe8d9fcaa61c45e698977cb2a5bf54e068a55263b3c5efb5b1ec0fd296e94fd5073b59d8e8ed7e6feb62dd51e04aa276664a6b211cc2a2331c263dc92d59437947873d1687818f2052340af528225b9d7e19cfcb919e514930d75fbe7e287ccc1342c8e4b41707620568d81699da58a425f2741d0a206fc304e361967f6d819c4a3fd75665f26556ed86ee52e79a03f129523a0c3df38af2df6630620690110e1782aafe433f7c062a5df8c45dbed1220954dfb3d41a31498d37cbf6fdb245dfaefcef9d8b6ee3ec62d8cf1bf612d0757ddaf4df53ad4050851d2020171a04b25efd7bc4f6c9a72797246cb3f0d62d54960deb95def7592631757136085a1aa8b4788ed44f958b2b54ff6ec9d4e043952e625d4aeff4f5b895a7466c0c5b7ea6bf48621926ef9f9e530b1c5e13ea82c0d99e6c81f89d0b7d9395df215f8e096499e496abced60c902f91c4458c20f91eb50206b91eb0606e576acbad83eaa9ae34e616d90c0f77f99731248fe3030ed29bb639275cc93eae39ddbbff8b53d2838d9618c13693931aecc92aeaa56a63d87f30eed0cc08f18cd84c23759ddac820b76b0158dce02f086f72c8db0e0dddb06593ed09fd2ec48255db0ba614c2427c5dccc0a289202db1eb8ab93daabf646209a44bb1ff086bb8e8069f8168869eee6caaff1e4772f6639fd749c0080af5d97bf492429341550cffd2e781d657a1d1cd28f8ea879d772437abd25da030c4ae3b446c1dd5c1e8aa228b71d49f6f2d79dd4bc5f181b8d24eb70f66e27f556fea62d2e2fe5c7bd4f7031a3ecdbfcbc0a35f09c98c2aefb9fd1f625c5a001b2a89e12ec408e40e3b88ea0cfdd65701b08abbb925531aab17de2fd857698fb2ae210807ff013a153237af040c1a36bd1a97391d0fbdbc76e99b2f2c52503a53a027ed470a92fa72aa7cf70f32668fb1c237d9c8f188f3f4bbf1e82eb2c0f9c35be73c258c1ebe93743d6dda54e281696f8e653a5ce405535fe4c84bfa7825ae4ef4ff2287455ab7a21a19a83e5c384affbc06844cfd4faf0cdb8ba69dad5fdb7c2565f72fe4cc4a56292373b714d4630364fc85f486762d3f96875feea2c8094cbe1f7175aedf2a5e3a93c8d2177f8357d5142220486bc71ecd890c179bf2c15360a3687dbae7380869b6a6061c7eb188581cbc3d63084a7eaac556ef1991a47ec67018f765349992ba94ffd81946f4a3792c9a73bded502825e17b49046df7b741de50aa16157bb52c855b70f2458bb3260d818691c3679ffd89902e0fe2cd82a1fcae49895fb7b14e96c5be5c3a496a18246c60e69b1456d6392bf0154bbe6ac98218b04426f3d33193728763cd20b3b63e746e5fdc06409aacd594f08021e9778705c3a4a5e5709a58b1e880aaa0a9e68fdfce7e462ce678128396d24e5ab210c19f44473ebc0bb01b8866da1fc8c6ae4de1ca4695f38b53f0929001f3efbc4a4f309121d39d9aa7a4877622caa480b76bfb08a7d782934175ec18f343d2e5a63c3a051e720da033b01fd7fe363cee80fbc3bcb9f381aaf575a149e3bb655e203c63d3440959a27407925de5f8f09f0daa3114435320352cd2aaf8c4fbdff52fc0345f877b42c884bd53338134f29f87d77d6bc9ee9e49987a33af5ca83533c9e9097bcab3b21563d539d4b8cfa8eec022588cbcb8eab0911614ffb3ff241cb4e11f1b25fed5fe4c269dd3570e58eaaa732c02aa25d860d09395c745bc6e1ad3ffc028e0b23159ab0c0682c22f2bdc5dd9ad46bf7c75ae2bb58db55ed35ca3f4607bf15857eadf3c0bc95c214153aa426930eb523f9daf0955cf27159a3e00b150bed1d5e384cd358d73755338de9a1e6863fb029ac0f33613b085f273522110fce160a8b2f82ac9ae866c67b6cc5f5f346420a61a053a49fad178644ee206b2e4d4b8d73d0cd1bae006574068f549131c50004aa927fea74791492310774aa80722eb0e026cc03523c994c062319adb8e41183a61770d12a8581cd6102444195a5f8643fa9ffff0463c7bae7ba037fbf538ac8a982b2f8245204c907a884194c8857573daa37e54482d1acc612662a57dc9bc326f4f168d16c857068e491c6e985bd66878977c24b2acf7c35e568512e4b6c883f4164b938406ec22c802c593320ad23e2be601ee120dcfe44b6431e28d0cbfb0f8b67c8bff8c8148ab7c748cfa800c1910c50c3d171b096c755b54054290a6f94c8debf4ffba583b00ae8e0f9e51917a290427425ab5aa3b00155713fed8bbf080e84c29ba2de61f7d0f4c8063f61918413c43fabe4ee8241ca7fbfd83f885fd6d46cca325dc38695bf257232fffc8678da7bd7ae35d2ba1d743b6a1477383c456273b5f26b39941271695721f11cbdd9e6162cc2fe0bd6a9e2355c4473cb4f10a74e451a800c901199756fb51c74ebb7f8e184997b0ee279f573f5f4971a72db4d474bee9412e4cd2e5adbea280e87dea65183262f5e23e6b1f8bc0a05499b249af645168700193e6732838d2050ecca615a08d2297c5c15064615dce28db89255fdc157441a37d18c19f90036d79ff5be40d48fc8f5345e27afb24a09ff4ce5095c6194e26b115bb67cae0eda1fc818b05199965bba60c16d809b2dffb7eba2e0095001a0ef3cc5a7da2ffa9c473dd2ead35ed495abc8f3b1b7a30b2222ce23d33bc5ab640df3257d79fbb392b814f0a8080f48ae5d0d5cbbf3365b682f782911561ce0b7cd30929613cd3b78eac14e4da143527aad4823b5daf9c46b195adcd6aa1f0abdc81e5a42b318937a384ae0b4c4f991396809d9749edcb58c61669c404f02797f746360d778c995409d69c0e789ca225bcc647ca2b586d6c3afa082b6a9df1f4c4ea906d162cccd8a48139081061cea52bb2ace4e8527d94ac31ae36962d42ec889e9073c90fc20b18cc44a0fdb560de27325fc0536a86cc235d2b69f68eb192357f9e388d1c3fd1a763ab6d2c0b889f6b9365ee2de420792522a8bb622f2a14b516820fecee11c70d6f42a9eeac8a41fb6c3c900c3292d4c4d5d3ae9e3956f3edd4e03b37ac2794f712ba247e2b12df071d90ac679c761821d4e19954d0ca7219ddcc2599fd7107d241ddc89794f81d1a1ade91fbad2183fd5f6fef50f7e035c85c56d6f1d3b3515f6d5198707bffd4a0b06eaf4693be0a32c5dd07d578b098a2f2792d191e6b403cc39a1cd19c41634325b341d1f33856ef31c2ab5b31d39033b44c557fc5516864ab95d5f0e02b60f2413c40324c202568bc8b9b750c7179dc5cc4444c2113abf2bf3d13c1c647b8ea53a773190d29594c37594ed1c535c772a3631504ae5341d0c01843baafe562637b795e0d96ab03ca9233cc6289bb824d99ae5d1516d978153ba95f3318863f287a9d6dbc6fae6e0fa44d1f1a84946126bc5302fe19a68ab46482a7404b8b054cceb274e689e3e07585f01b1bce41589e193d31c8f1986a371973ffc8f45eab7ef754d184f79714f4dbf68286f8b8f3f1449d3e0d7a9d2e9a29056706982472eb74cb8e2f067a095928d33089fd73074b7a59bb9e978114b38c3617d363cec4420c247f14aa8322be788379091e40939564c600077821cd9b1e1517f5031b7e860f03f8c5422bf162126b819c44acb3fd0869ddb984e5e051c6a290fcca6ecda27394eff7fb7438d01e853c20b21b2794c77eb9e5fc35ef603bd7b903c137b157ed29181e99918ecb1b4bab8fb6ec99840380a4595c58ecc981338b9f642ba9fa24dbcd23ef9c060f6c340bb358a57b09cac36110c1348c58299eaa8387d828d593f50930333d79d3cbddce40082d0c4efbec7b1842cb98fba992f209e4d36986feae6431f771025fb72d6b656dfba046954fb2e521b686ea8643599ac40dd07bd799d6985e5b21277e75906bdb53404f36b04651e6d2d13fd374c5e3a73a0c0153a85c80dd15e86872651f11f9ad6535031a10e3e6c0110fae30c395a143150bbc7cef51c24ac60e55ada2728c5021c24b22cb49e210a1abc33cd16931154af773a48d60d79e11d2cce5a54a50a43930eb915317307e5ad3f7abd5c688e828b951c928b05bf8a9d2830db8d07045b7d9c47f4c19f895b7ee462331ce67bb91ad01bf26509e3a845b6e3b727366566c1e527dbfba3f3a1fd0b3510b25fcc7e286e0acc36315c12de2743af5709489067645f3448df362c3f8a1a86dba10672212f681580b1da83a527adf29b838090ab85f51abef2d19857d530e8e826697f1a31625735cf0bd73df73fc67280f4136ba711278fb83c6042c667b58080710881e047b441769afc23d86b5af870a01156616175f48e69477a806386e71e7bfaa66f5b9780efba72f2aa0525385088c51b42dec10b7b91e9f4ab8e4d81a84dbcb48a6d7ae83ac06deaa94dbeeb141299bdecf98769e0f5b093672273f198e7ff1a9ec2358f689f267fb141804be46e6a768721b6f6fb679833683f0a8fabdbaf458a4b680216f0e4f88a88e91fb45495378b3cfc82ac468681a5186c405565220143a0274763621f3150d5747158117f5b7ce0c8b41367a24052c44222d7d8612a0d9e45524535c5c05d968233ef50a3819d3edc9cbc0ba1f1b38b2335bc32dd4f689133ff83cf1e7a8676990631edd7abc43ea613f57731d45701bd826da149aa627f34bb3de7f36e1e3666e1e33c8be82872a78b6587bc65e5fcec1344ee9e4937903ede9f3c3f3c68874cc62458ca9b6dbef8524f807e51ff7f0314b93526958b49dbdd2c8da065b0ad364581869bbce29f65a4172b84239471549425b0d4656a42930d28ef10af2067d468ee447a686ae2682657608f3d01b62bc8281883108763a14dbcafe1ffd9e8998a7f1e0bc89a49c74d69b3981ab86a1a37138e0ad6499b8f796124255abfc80b22a2625cf40a59a0627a4429aac587cd02d5819c0a12341993cd6a7e027af675f33e225b2f35b1ab99816a0db86be2fca8cc79e21412a317a6c04d8a43da318da4e0a596a1cc456f0b67ccad22a0913c71bca33d20c674017e76f3152fe66b7d7b79f30aeb1eaad018cf41fa9ae0b308820055ddfedb044d2245a01a63d2d91eb20fac6657bcc6f48c262689418059a7ae610e01518075ddae8eb6cd9f3ec03e47772a0762bd4aff9f9a26f33f6b9358760244c1ac401601e86e83e506d90b81daa861a938550e0551c68474d5857ebde716f6771cb20fac5d465e8dac7a5345cddbaebff20cb33b94f4f7611df43720518c21e666a728ebf92cc95c9bea07cdaf491cea77ace6523f8ddce709468edd6ccd482b0ae47c581b220bd716e0f2a646c37548629133631b2e53461252c9b2504137b21239bd009dd0cb0153202a1a8762872c5989fad2a1c281135eb2e0667ad2a6374d19ab1b2ec7801d1cacb03810bda5bea489bd383956ea08ecdb288688fced731fa0c777d7626b071f1c20c8f7ded35328c921368e533b56f0aff857cfac42a9d3edc7e9ca2e4bbd0d3ea4de2e53024441fc8410351bee36f4694e69a48bcfdbbe3dd3fffd8c27e1fd9b73e1607addee5d0d5af5d3bd2d8761cb1caa6a8b6ce14311a81a97c9b2c6f6830481cc95b0ad5818df0a20c69bd89485445a6c14b69fcade0de74220e1481d5d3a2c055744ebe67793c312cd7ac88322ee008f040d3bb39360d7608e97350c629538ed4f92277e7538c12ab69a2ab986806ab2ba2cba983fffca9e29c10d953c763fb96c06268f388327e762853020dd7e1090de04af1981c6141f3d60bf1ea82573234b46417ada94e13e08b36ae5419138442b86edb0e45b32575fa40961f2faf85973c2a9b18083501082216275c78fad56ac72a79396143c420e19e848bc5f3abbfe3455a17968980c2f7530db8591bdb8d480ec4999be4e9d4481bd8564693dcc735b747845f641c809703334cdc4c978678bdc030536f7c85c08715de3b5ef108138c53a822729a35ca1e782f9575a74405e6f340d79850b159dc5a6702e6dc3fed39f90b900427cd3dc17247078914fc354c7346adb46c7cb6190d733801a42f6eb49aa60d78e2cb56bd6d8b8a1e1a6505ee0533ee83b2077007e0e0a7c2cefd88c925389619a2eba8e8b61d664b8a0428ef34408f4a79cf31af3a1f44226e73bbeacb916d03f60da42da25bd3ce2925253301c53869218d659ab29fc6c7a724a24b38546a2dbfab564cf76c3c3648d4ed114bffb1a688f1939482869194f408c0715c8840214087f1c07afa2c5c930e716bda38764e8ed7fac91195d64443bf35156c85cc598eba63d14065ccc272328ededf6bda879bcd89c47f54cac698e607ffea7d2cad6c21de783631885897a45d13ff30ea35ef34c07cb0519f2653c5a89936b656a780318ce8bbf819f316219c4bc4a3ac5fc83ab44bbe147c3701a1c0307e4897faa7204d7be4ebe4d8ad42e067cefd77b8a967a5cc90ff67760b567f792d732519e1c4fc285eb92a8b0bb047b24372e58a5bc128331e2c51833d52537300e1882e773c3e7831246f46c92298080b3b5e05fad0e4f7e0db5a0fd15ec9846719c71d6042668b61f827f76d604625230783a65909c986cc48008ab28bd942a35413d03674b746f0ed701b4d6ee9ac2c89d45e23221200332ca87f2c27d0ea0f395fba6b37c361bb3515b027a94560be9fa7551e7438b73c6c4f53eabbefaea6ca6416a4f56bf55883ccb9c97a085c60fb8368762e99b34d56da87ba900c153c0609e9d8d4ee7449832547cf1fb9704014f7f9088b9993e4c33c4bfeb69f8cc304e083c6eeeaa1f1e3ed5f07d2e502c3a92e89b3176f727dc5b0b2aec90534af0f1e8da6b2954b440d9a0a2ea71b0047f7597f55f507b71a3f8dde31f9dd776f111de3e62cdaee0007cf0b97c4d6c9a05b6891a876da4345508a8bda6206465748cd037a715b9afb730379d19278a81a7d073188f94cdb95d998871f1bd409252e792d22d2eb2158b80fce355dd485c11bb4373246784116daa0daa9b35ff949732c073793a9fdd460efe45793097fb22982478c5a15a92f0f33ef993fe99f4fbb15fe432c7c4016f1390cebf55c48478af5a859ca3a0ff14fc55b7484a556750a39ae8cff5b07fbac2dd915977f5d31e9cacf2c8edc626e8d80ad9b5b9eb69524b187ec359d2d553488189aef22559296e9585fbe167f46c370305b867c94261c0b911edb2cade57683037de0838d28e21e966ff859638af599dd22fda440cd9fb0c78458d08a8d4d775598952de45c0f7105832a13673cd5413b900b65f9c072f29c9dd6d4ce8309cc369a15aedcb225721425d9cc6b758d0e079fb5830bd6b58f37346586ca22a6e0026cffc601a1ffc20069e12bf73517b936247c440013bbda7f74fbd50a0b54d9f33b2c48316b909e536a57afa1ea5c5d2b4a391208490506c0b5956f562e69dc080f9ad9e5545d6f74b236b50b268c64e6624aa4c20c9f1179db537363f0c2d233c6c14fc5b2bdfc4ad6d6b23079b0e793a69bb04fd581163e604efdd7e500298fa4941abf1a3d1d7bfe8fec87288469138d4e459be0376e5ef5328de05c38d8ff5c26b4c184573ea96de0f27c456ff9f1833946caeb60c9385076ecfa2cf37719e012ca492d76c98c0c36a45e90a96a983eb8ce6b9f4c8067fdd829b0630eb7b8c13a9cd0c9038fd2cb41d5e82c94264cc8f05ba3c03fd9923dced299fb31c2a68d5b82aac75033a9705ba4528f508fa788d860d146336233741e9ddb5a9567a2580bb360b9463f4331b810b85fe9a392ebbdf3ceb971404b203c040e6bba26492dc43e63e673ad288436368c6628be7eff79bc35c6959510fa90c0418d4cf6d337ae0bc2245ccadfad4d541a95f7c3d77e826c09d4280a03f1c9273267105565bee93e1d1732aaebf67895b5ee59ab406f605e15b1718dbdf4aa536c183d9eb4ef288405cf57aea197d1b9d569e7884dc81e3f9480909a048faf7d58f8e2309b30c1d29bdc51be81cdef4566cc452c677b97d791968a5466bfe1a0a801aade4317585989e067e93345d0313788b2dc21fe2dfeb1b3df87e01fbf8b29df9b0472ce3589300e862da227ae8323871487468434c7e51b10ef6757324c6171e35a58fec5ea94704a1e96dd5485978c6225dff639203af088fb3bdfcc45a915d56ac98ff31f44e93b951b31a13235e23739f6ebb13f138b0701f36b5b51b14181b23a2c92eec1df80560a6520847e0ed7dab3b2856b04c865d2117749e9eb32ef3173893eec7f4ceaf2e9644e281b4991ee3fefaf9e4a9efcdd6996ba5c942f10cbcc79707d5982aa8893367a6ed7c3403bdb7aef9bb1dd3287b1de94b8a962e0b52b112f4c358bc9376e1d0d5cceb50e5bcfc88f1a342f5375e5eeda35e067f1527b74d04a533aeae4e2bfebc9c7e67043cb1386cc233257502c16b951158ed08820625ebda89cf7769be97f1eb418f7ff45d52232a1a82072d7d19f08c00364be9245448fc3e3d6b0ccf5198444db13a82c64121519688e26b015f452002f380053e36be3931ce005fdea06730c9196dc08f3b7c428a4e9c74d84853976ae14e02c74744a4f824c23b51256dd0db796e28877f5ff731421b1d28410b9abbbc0d6b01dcef216d2c77a7c0be7d7055d0dfc51701d3156195632ffa31e6ae61d3f842d2741968009c06e393224f3ee99dae7a4fd2494e6fde8346415b905027ff027e3f7ab3f3b4e95575d27a6252125f682fc1919984517defa3012d43a4b9cdc551866a46549c41f038a785a6e229f63f319877b30e45ab495b3a5901ddd61e27298a196bfde2cb0917d11ae8e8e52852321ad56915315894314ddbe76ce665ff51c4efee2d690e97b7692f5b78a3ccebb3200bc28a2bf83c919e3a6f1ced9acba43a73d97cef4ceb9da7492873dbb53aba38787a74c3168c22b8556a054cc54634d5576fdcdd4ad97467446c17807501e7962397653f2fbfcaa7c391717d734dc42fc44c05d9903e174057d571e097353fa99bee89d8a50b8e47b61087e467185843123ff47f06694ab26965f5066be331c7ee9856b34dd8a986ddd96f6187670e0b33cefd25f708d83ebc7f578e92a4fdee53957ca202cec383f9379319f0b732ab8591c00f13fa96e79cd982694944b11eb238bcf88b53603f24b0ae6037b641d307a1b715fc5046a7984a2ab76f5cc6aff9131becd059a90904cac50b72a2b7d09ba96b21a993a56410ccedeb214414d67a922b2322cd15f53a7f39efbce5d858f93606d29fb4352adce64e3a026c09988820f60a074cc5bb6f00c83a026354fd59e35bb099cf90ed5df6fdf23f440c21b1ef92833e2805f1bf0d82a974d7310c90a7419f9d73c89d2845ea86a002256a59ec85585352ec71355534940f14e1a9dec9a683795a38de9350aebceed92a82b6c9d3b82d8fa5434e3905d671f0d8d4ec17930708f3396bec6f52675ebfcb6c46187a26a6af866a45537db8d2dda132adb1a9df5f0a31f8ddf6002144897b7e9beda8592a01d1aabc04a5fca2697aa44dff4578d0ff7e8b1bc95c45d3a1e321f5ce36d6a673320a2a14e98bc73cadf7992d0a75aa0c7116781e4ed377364b67893f47b32b4c918a6775938b9aa3bc20f13797d899d0756061d17cd91b42cf01fab7d8093e1b140a011e0cf93b37f42a0fa59a52f8f92dc062d8abcc2ce1a484f130cf345563f9e4c62b93583d1d4f5193a77bfc5301dd1e4eba6c40a848875dc964bae62dfe1f98f28a6b06a53f979b9815f803af19cb902740ae75e87294cd77f9248c35d455b3ea967609eeade5309f6ceb624ae4e791f1499f63ff525a3ad78607a34cfcef95c8fabce581691cdd66fcd666154c4d594368f70498dda3580ad8873ca1f8191b1f7a09cc04ecfba92db829a68991ec645b612b69cabd022c5f25eebdbb83adf8a5e086cd9e8fff28355b68111d90b28758a4cd01e826dace8029263af991195684e4ca1a4c4d7c991a146d4e319c31ccd7077618cc6ca4160c7a3220fcd38c4a71ac4d44350f7b77145ff8811f5dd5b972fd85d317d5135bc97e23efc7dc3cbceaf2f539127f57e86e373f8a7da5133d76a455cbd5c5c11e537fccbeac84734f99818ec1f282e46b820242e0202b5159280e4e784825ced89265b2df32f0996213b3ab5b0cf11d41b6eeaa67ad0253cdd461084ede56a8f0d281772c2bfc50307952bc8b585d0c628f14d7a1a32a89f8ee32f42157646f01708ac6101b673a365bf348a2fbb8a78f1164321ed73df6222ec5c9894eee2ec40f73227547a729fe76b0e61c7be37fc07d9e4c36fb06f0c2531014bb70fcbbba1eef927f1a6ab792d5c4758b0f2a75d9aa0aa8ee5e622432f8262b54fb6d9a1dcaa5911c6d691cb05da6a2a903bbfbc334cf5317d829d30c3001cab2638e60cf809ad7d6b5f11663719fbccd51d9233eadc418412bc35e8072de2d79132baba6ccac167096e07495c773d90dbb81898422559be216872c57430b5f68a2ebe78a96bb72cf0dc021414f4ed692156a0df418de7fda45729f0e40340c306d8d17cb22a0ed0bbdb05941c152f9379e5d1840930f1c4d435b9f7a600125f5583338d8242556d32d108d109163b953e3eae4c6f844d841bd78080b2ad3b3e51105fa749d35bdbc0729daad1bea6bf003cdc3d4d3a4b5cd57bf4eab397c075c482295911dde5e4ab9b8e58e3f92e888840a448f221f7b78d3bb966ecc95a9a2109463ec4b15fa7fd886bb1e26143ae6522935b0b128c25047976c44d34bf70570b30edad53fc6f8c17a66ce2187f98b236ba4854021ab37e0a30c57b9c5a0902804b620c5f0c70f35c29453e1e8497bfb10f79c001263d495458c60cc1385367e6a7f703855a60e4ca58011f20a57d597fef3e4c4d9850d27118d55467af8a7b872c1fb8ce5e7989e8fa125f42b0595405dc28ff93e82aea3f83b3b0556de31acafc11d5b9718495c27d7a76201705759b9992f2edb71514da0945c66ec2c5335f61b739de487fdb34ea05fde7cbd08dc64fca3ba234c6d78e62fb8f852459e71fb93ec4ea85ab24bc92ba77388906f451403cdbb3ef678107d984223779bca177d164b6a25eaeab5a52bc25ae2ee2fbc9b134826ad42e86a0186801b036953d215da786bf42bbc36e64b5356285e2854bd277d47fffc04e211a372d7dd0591bc985449c95cee0d709035f662df14d668f62be6835afc1deb012c5f7d7f9bd287a2c5beba673c65c5487ba952a7a7b06b77c2ce4ccd463e9aa00e73de12af4d9cd64f9bb67cd7c2f46941985df3e4bd42e37f2f3b1adb1065f26bbdcffe61686ce60fc50577177f82b3e83496e8e937d5a0a9e421b016c3d4da18443ba54f1d9abb95bf72fe67a7e14d192a4f102f1c133d8d0083b7a3b883b8800dd5ca573a830e2890e751db02a0948accc8175853d407cdc988e813485bb696af1f91f94e33d49f52f4e820119483670e86fa17a71ce2b555e475e07d72427df44a8b752a6f3a213c12200b2bf0d3c46b028c411e0ea2496d6fcb7fbd80025d8a1972c75ba9a0d135ef6da11d800997afd528bc0c1a42588e7a40575072d4d59896402e1eb7835a04d768698427faaeab8e113bd20b632dd0fcdc0e949ee90f860c65b6e3fbcd80ce01ff902920107b9028d39be1d796eef52eaae963f451c7e4b7387bd0fd297b8e0fe69d841ab72718fbd8e65272b5e1614a1f1b9946c3beab5e5eefbee3d2af700fe209153c5604919e9b292cf39497e3e58a53425a3c9d945909308f9ea21ad99045d200c6bad8ece6095f443d3366c8479cff2c18e4ef54b4c36996e966967d9d0260d5706e3cca0a00c63d965afb8fb95920cc5a4f9513cf335394c720ac98e6df3b532db70461a78f4ba91dd99d0c36e74fbb3b98c4552ea8c00c549075797d6ceb204324fbdd83193a82b77f6939e080ded12284442058c4cc7cb7faa36ed654210ecd032baedfa7993c23ca9bc879b7fc5a13d79b1582ac4c50ba7f0e4beab8e19e291a451293f1544533f31ac655a6e98d0b8ae42279cbe3404bb41dee220af461698f1eb9337d95d4914fc290131ba080d99b3809a07da4dd6d5d8f1b39cbcf3ab0870eb68ceaa7d07dd2209533181d8be59f2487790d3ed70af6e2709fc49c2d5519db65098a404cefafb47217837d7ba5a7bb006fa199fe3e967bacb6abb0b7c5927df4499108ead7522ecc06e99637cdac5668e72dd91add69243babc285208678fef0f9b40664d9772064cd01615f36bfbc708525dae989012011e90ab8b89ebd7bd53eb698354e3fd39f2e712202c0a0db4587250888e8982def29f6c927298a8126deccf0a8239fd89d23dc97adedc993137e5c719865cffecf41b7dc5e0f32cd177c09f630418fa4ff0ff5772978bad47a9ba594bc3f094280e97c7af3e701c698d576a99e6ec58a6cfdf9b84782393c4c325c0a3ed2a4b330703261b6439bb4a38966705828122a943cdb151675a32a38023b92e257584adbabce6874f9d5d72db04ce6fb35f6fb29abc6645bcf3d3d3de85fdc49caa51776906aa519caa121dcda64a4eceed45c1523c782349d880f91eb50207b91eb07b259c8963028611c2e4efaf04e40674cdb312bfb899eaefe8b9af3902133e203ff6dc7f05ad2da3dc085b5dcb1397845b6367f323cc332aa23c2444f0d8a9e276c62b3c48ba6b8dc3401848d6248aea9e7102e2bf0efcd3d6c41dc4d78648157d79653d0afc8e378f6fee264ba2fe1ee05536cc11cb887cf4dd8336ece4ff4795d54ff9c1c355b7390cba207ed6414bb98364b0b3ef6e7fab9dfb4f2bbb7c332fe7e4dbf2a2fcc3dc58460633d00322489d31c8b80920267023042cef4461310bb227b54b7a81c607f66ba8c75a8b6d52fd65aad6f312faf3407faa6cf5486701d0c689e65949d6b8debc97470d9da3fb2c1f097cac772ccd87f9648b43a703c0432e88d5109e4d490f0f50a97e00b81d7e5ae7ac5c6453c969289c50414e09d261406e726da5f93b8eb56e851872225d21dc1aeff9e051017119f8a540de06a6c88123a71015e5ad70e12a80a890304fd7297b35bccfdd8cdd59a0b088d58586a31aedee598f6cf69765197c4a7a1a5df93ce5e187f1ca5a9e5b5101593ae91c43391cfc9747d2075728b4949000b49e661cf7f26d5b04b3e760a017bf18f6d5bae4fe84c58987b285ddb2c0666e483e66cdd7f49de50ec7b4be4d13b6669214f01668b8a8b6011c998ea0e65e20f9296c0711e7cd641b6be467134013220832a98a327c714e2a132ad0d39b016f0c357ceba7291b7032eee19793f03c87ed9f9024bad79f6fdebb441b2879a8a7f863a4b938f7c59c80287cf0c74ec348d6064fb994593b247315679804353d1a5bf1d4afa72ccaa014239f710aa3a690ea016517022b599b73168bcd18892b341a04a71b9d041c44b192cc95cf1f38699e7c34d7f0b52f45b7289687683016e3b114fcd6c63fa99392583fadf0d159a02ecf14a88fe5282883b7aa56d151db9caa88440d630e479b8afe2271be4d62107457fd4d41f08a827ac3508bf319563d2069553865438cbaed94920660d9ed9fdfe911a7d45ba17b14ddc6011d2a6fa31c0e5de657e0d86c8255fd405ecb68f84cdcc9984e00d62478b0393212628f6122d90c7e8c7a81c7d9745afda4336c56ea84234f73f69d428ddb31a0bcd4a81e802417c704ab9c86e68aee06ffa28f25df56860625377f6e1863cd7f1325879ec10a6c3dc4f876decc56d04c55ecb36c374f705af568a2197898383d8ab5a8faf67de614eb675a8d0e33790ac50aa66d3e805b997797009d2a3e3b6c804df3bdf636e887ac9fbf8fc739519be1ea50bdcc764e867a0ea0727d7fc6711427465a2a01d76c7bbe7ffb23a6c84e176c2fa5236959e3847cb6723c592a13c1210dae7d4c9fdfa29f73856f52ab40f34ef1a36497d4990528fb646d77b3bac72f75ee34804a98d83ac3c9d0351b1a2eaeebca7f2eb1301eea8d5c4cdc19c2bfbce273136d31504272dea77019d30ac402cd5b9b74d8ce73376d1238326909022e988dec73d8e8ac1e9ef9030e1dbbd364020738db1ba72b26da333eb52c5ca6834779405c6ddb09c9530e6c380595721fab156f73d8464d25ab16bebc4945ac62a7886982c40c0869061f6c8faa92db7aebd9921b0090800e48bae4a97053d65a0d8fdcdc0ca4bc39c8ed2e1f2a66406eddc0d89168d5f40873c2f1ccce626422668f747449acf1b02f05c0737d89c2124748d726c14e2f0b29c6cc82a7c91ad5824992bd339c286278b946906de5532b10fe3e8fdf857e520dcb5479eeb5c48ffb97dd8bec8353a4d074de5528227741c09cec82059371ec4ef4cf49f08ec269b4cc8ef3ddd42ea5039e68751e0ed19689bf5e809ef1e4fdb9210af0aef72f5433c353a93516d4604ab0d93bb459bfb14a1c7ad2fcbbc61cb6f728b668cc61f30bb55beec5292caffe616a3143a2229369a084ff4c959f2b948019424e5a0bed9acaf1b5a74384c7edd2d28d1b77ecbdf53595bf370bbeff81511d8141b0d488747bd987bf6562754a1583132180b1cfaa6e26d61f1d0ba3b66ea8abf4d0ce2df27627c6282bbabbd18a62bb75f7db3e42d7ac103b66b1301a7e34ffedd4c2f868550dca55d455c0cd99304939a99c79d0f50a5ef867e69963edcb343d76a20f9e5896daa7e71c51b8c0745e69af2ec6e8e6aa8193a1839963d917d31940da18233f6dd84ff949d57af7416da21cb26311a57d2a5b4bdc11460adbe412fce4703ae643cfb5cef6f641f18a9678a40e0335d63aca6371b7fbe25ecf96a6281632dba4d02a5d4cfb8703f54f70e536ddf4ccbc5803f24a29a55fa4d6f9a2b741f9ea446a72d1b244b932954690667e78e08335513e585c72eef8da7d5034a49c85babb5c071eefccd661b7e050db8dbd1bc98e8506f84253cb75af83dd19e816a4516b99be2a5ebd6da5b72a45d1b26c58c5f81ebba14c1c5ce074fdd2a75384766a2bf43b45fb79ebdba7a2bcb14dc5fc7565178a074bac9c50e7ac12dc4de328a7fe858d2a823350040a58674722ea69231529da891e94c927ee75ed60e3c627f6ffb98813c47847a9eb517800e453f0d1f7fd9138e4b18d32ca8bf63ac76f9a39526bbdad0017d3d95c795dab3560658f9206a77fdb3e8d81b803eb785943035baf86db7d975d7759d60f3550d465c0bc9d833f35b16cbb1b589f303f3412f0798e2a02be2921e04032fd45695c1f43a4c427af57ab43b628b15f985965f9ad89c0673f31eeb82dad1f2451cf89ec976c39f985699279b106f1085b6bd0b78f648588a275d10b7039213e60c3b56ec57f26d33e61f64bb36b8f8ad8cae247f414991bc7b9d41728d3d83b17be7c773eb541348a4538e72148010f00dd8d4fe94a820264269bec48276a614754bb2a35e2e32a810227e0240da42366560c23278c400226215c3f8e2ccb795710563037220d1011b611b206e62d46e8205b404d589db6162c1cda823200f4cd45fd57b5022c6fc4d3b353bfdf840e50cfb71a53e43e2035ca5739bc71461cb03e7155b0e269378a5732e702ca06fbe1ff04423f3a7edca2fa78ef39785e714e5f8b51afc6cbb968ca9835ed995fd773f9219fccad9e5290c62bfdbca4b85d85e751776eef97ad0e745870ea5229e0bb567b99f4fcaef275eb2dd67eda59d90fc9bca0ff198315d5b3518b718e861ff967c702b5ba3026aa01df17b0cca4ebd45e3943d810ffef1f34b4d391e24277bd74d7e6be3dbc9f6c766d39ac34919e1e4a89a5b0ff943d42f2787dc8c78d4e4e93822d65ebaf6632f84e4ea93feaa4cfc7793e7d627be7fe89670d43d99f76e1ae6edffe2ad24e5d011edd148bef307d77b3d4e63516b014603b00d8954ec790adcd138ac7cea1c70fcdfb7a672dbf6999e620a959507a5cd3d23c8b2d87ecbebc97109e900b7bedc171d32e66c531d1469d05e2d3a9983dbe42cc0f6901766bb36545c68d34efb55ab8ad566a239c8250e57579d4d3e0dda60d9a33e26246cb0c567db0c06da1785c48e11690f27b60df1cc862eced0da1da049249e309004db333cbaa32d6c7a8aa7c05332845e1ff18d45047dc05c30e93978b752610d2e03870393aa53afe6744af1dd93e62143f8bed8ab0b1e87b01eba1550e787f4bf6f222bdc5eb4ecbdb78c213f99b7c3009197cf60f554a36cb5ad5adb9ee6cb6321c6e3ae317f0718dce9c04442bb71b807825777cca2babe8951f5a610a844fd44a7263c5b375fb896fbe33c1821216a1038bd51ef1ad40946e8247cec07d6a82e1ae54d6237ac478b2f7eb492b35736e31674dab8018ef96fa275a188e985d3da0c5b79367786fd2d43cc5400142ef836ed8fdb3cc83eafef973087c5f8bfec2ea675cc01e9f7f3b0662c50ab643cd6f1111f608bea6f6ce628c8fcacba047628e7a7306afb6dd30d2d33f4061a70df5a443a53314d63400b624fa0f2899bbc26fe566d08fb5c2a8169bf4fca6f544e3b6a9c214370996d1d4ca7be972d0319744026a40b62a6e3deb546d6d32fe3a95f37e94aebe2fc33d735d1071ad00531ca6b96cccdb1eddd8484d944907e5380f58c89a2e414a2d2d3a38900ac85640eec2fa6d090e54e403dbcc356e23880da4df166158400375a6e841f21a141ff0d09abbf893290ada09ac4952dfd9afe37694ddb9c191c3a7dcb0e9e09b31cf53281b08375f44d2c25baa82f3d8c022b4c5dcfe585fff7b9861b1627d19fb127fa3099baa96ceba44b565e901f0d18cc9293847267d22064fb63583921bd176c5ff9d0ab8ec30de7e6937b16b0e8b860655c074f9ad5e0dae2d9ad6f11c2fef8b74b6d12e2a7f4dd4577853d167bd9259000b61b3742b4a690e29dbbdf980ad3deb24930bea5b6d8e274d85a5b83a15d9ea125fdd85a4d43463b5371b0688c85e1a607d44cc0513822b21dd2f93d4079d33455aac851df6b585f091d957d08d14132fa3eb5a0de0781bddafc3e792613a5f21e684cebb2bbe54d27ddba33816be8ccec7b2bd16f1346837182b8a20118d44ae0046ff0c64b3f780d1d768c6111531dc89773b520a5361b69bc69be8aa56ddb88ce9a23c94ab8fc5e652b84db4c9a387be82b3387d78abaf9f92e082588b6e3b93360bfb2de8e88b88d20a454b4550f1bfb084cd30300e8123dd4ef6f60ebea94d71ba61fe60789b264fd344cf88874b101452eecdb7c82a61d6ec68a06c1eae482adc41fd93cbb978b3f3c55fb3f1f2899f4b844d9ee5c6f116009a46b7a68ca0ff065965cd857993322f6692ecdef2c16689f708bae9a1915f0466714dbec9eebd7cf6bcf4928d793686b957ac896529b02874f49ceb938c94cc91da0982b19c92bdc8978e329263c5adad3c506d7389b09dce837a6c6b72d98104cc1f3989ac015228412c657e6b05d3d7d974feb999eeddc4236905f8973c8103221f1936e3e53c741bbe89e55c12e1db892191a36311f545d5856600efe3fb42fb16b43feac0ddc25ca8a1d40caae996873e92d6ca006fe31b6233adb1bb34306ba392064625bde1f9a19ca8ff698ae8495d53e99bf40772c51572c15a7c617aa932fc568e912f3c22c68a121b81f13c4ed07f210b4b7d209867affa94496858d2e04d80ce86f256b410cb2c04773ce54e39481874321574ac6fad5c9ad77ff9ee947d005b87e2aaa43e695328baf01034f7453542698c4b292b482d93fea6773963b5bf14723f7124ef0a9b0ee8d149935c503d6d6ae08dcccec83c0b05a154aae25f8299d45330923c582b931674baba3ea0fc4c851ff7a464aca4a63fbf26c58b8cbfbad13f960090a8ce244e3e95ccf4a0c253ff0ee4237a7b404941c42fa53c2b16921a1db953029e9815fec95d443f4510cde43c2b2d8c08c5b27bc9ec1068283363c642372cfe5b18928e573da67ae61c8bb7b69539b039299df933ddbd2e189e72da83c5eeaad879c541fea3101d8e9fd86c6720fb45a6ea3dfde0dce04fb0e5ef8ade4ff3c58359e8066b3d9599c09391909cb507b230eb9e3428f3bfbbaa269d2757c6dd6a8873dc93d8d72441124897bfa94635541306cf69b739934768f3acc5832bab264d921f2daef32762646219951c4cbf2ec5aa84b3d7b8d4a48475e4d30a9b6e6aefafa8d541515cc0427c44055eac032e32795891efb7abc92e20c65a1cdb3ff5ed0671059a4038b92365be82e07cbe2bdb6b5e8ba77850310192b80f9b8251769aab71230606395f2ecad0179b0e43e4ec8f342d1c6521f8d800e041f29ed4f7f20668c254d5d7dd686b679ff055de5b21be43c6925ffdf263ebe9405ac9ea88339ce76843061716a91a12e8c40ed273f69f17eb20e840f79f2f0c8abba3ca3535dbbed8bbded0300d41b4cd7d252eb763b609275b234ab4ac92aadd3a33af3a6acf20311ead60730ee517241bf07cc4a5184efd9ca8090a3c863ce4341fd2854439e5404ec4316dc4a832b0cbcfd8ea450b83913f1de34a3b3b0da1e8eda6a78063a5f521bbb5de3d55242e859322bac67666f0cea33be66cccce7043fe34834121a833a14fcd65879c3a6106085053fdbec931dadd245f4900cbd2f3644a52b403e799a6e4474b9651149c971d4bc0c309809754e8094c0a7362b0a2bbdf194db97a1509838a50066b9c23918465cc6bbb0b5515ae6d93fda77410c0c272d95ef050b6abab0d4e0efa0ca0284b249dadda8138490afe17fcbe1094f8ace18d2915b8f803792d93a9abd2592a5556e8fd49dbe04adc6114b4e4707cb1ca1513276b0e423da0c87e4e41c3fe615f474a4117175dfd8c385067f7872972cf4baff36a206c0a42bb3198268f1ea6f168142f8d09d1e69631dc261ae7d9fa61b48cafefd16c4b8df11f5502f5bf0f6301188d6c472fc5fd319870099f77837263e3d729222458c21567d2f64d77f1cb0f7edd79566ffe18a2eab18b952051eb3b2ebaa83946ee0274edea65f3c0026a602470bd025d63a7b2229ec30fe403a985b628b30ac13eb8c058511ad1842add67f6d77c762de2a5309a504e14da366c4529a14d93627411f92bc8d29c07310b3ebfdd2dc925c1cf7a3ba19bb07914849eaa1fe996ec9e357d81fbc79ec10aab42cd0a0464fbcd3d4c8a31c518a50b10dbb58446688bbf572ad20ad6aca40d21c0dd64bd5970ec154bf6f7bc018ee9815b18ab559d28ff27fc19a839b34230041ae2f5092c5d2af0cbd65d111eff213242e28f056e0ef85d361099e8d2a2be49edc1b0ab17228b4bc26cbf4db0907bd0a80a56c8315b0eb3fdd4e50138ace989772115c69e964760781f9129dae19e766ab34e10a068345b211d70c0947b5d50e9e7d6574c4abfdd5d1b54125b16f6d7e3d75cafa69549958eb1d8b843691ecd90c266bc03c04e2b905f2bbedd5ec5bc06ec125347c0d150cb95394e4ecd274ce50eefec45954eee9f2e376f570d81b16e3ba4b18d55b5db98390d1a0a32884048e8d70114d18b8e2db07ce723d2ddc7bbb408f8385f1090967f955c4267845c8a87144c7a71db2bfccaaed77377f6ed7da8fdcdd785350e7d5c6fc3101ad88b2cb2c0bc112be7cc13e0fafb7e20dbec3b99d41f7862be129b26c4e3d3e0bc0d8d65335fb34198c99060671384576954142806a8402c5cd9c35d44fc899e8ea1a372dbcf8838480542a30cb3c152df6742f53b5e751d51ba210f6f726f15a77007d813850fa32235c5b05732b63c0ce43a741e7a39190914b4c475f583036b0c5837153e16c0bccfdfbec6519700d8471b3efbfd0ba1e62921e5d15430367bbe557bbdb48ba2125e9fa60e98bafc7130d3399edfdd69e4192e6a3ac4ffe45728d2ad1ed353843a3cd7f1ea846aaf6dcf30cf9df8e61a7cf5058ce3141946c5091a7b6c1f229a5f8bf5b54111209064abd02dc7842fa616f809478eac88d50727deb82ee9213d2aec99cae8175f115e7e1f798c1b2f6dceaae165925a8e7ee802b125f513d31fcde1cb84d8c4496c5efd1e5b23d48fd245a91c93c57478e4a10c8630da65dd23e6f38721b2210960d0e6994e3566d12f4b15aad047acbf91ee61efa7d5f14607872997cb2ef14f68b982df20aa64fb93ec49e0ef43827b27e251d1a454b62801a288f6b34d11525f38bea7832a4fb216c8b66af1558ea6e80a9cb7fabaf478eca36e88055688441baeb3e4e1284a92f7c02714dc4312aeddc73c6cb4576e2473b827a3f9dad155f081d920054eedb9f4df22af1d4de57287e14b8840873fb3917422f74c12a0ff0b5d60a63a7ba660eb45923c5474f5d30093c680a0610a72fc81b2d55db919283186a6b509ac97f62f19e3591e52a706fe1bb027e2815093997cc5d8abe33d53ecb94cd9d1b243c2f70f73e59fd18674bba9e629e357e49e6dab1ee57f02c373725acc28530eeaa611bdafbd98c073258a3c692d10b7d16cdbca0921fee8c583f2f1ef7cdf5073541a79f5314f567825f23bf9e646e184ca93286e5237f3940790063ea15491d0ccbf7ee0550f5d17cf03f8ab125d5c5ba6d63756b55441f677fabbaf35393f4a21209be4e8335210ef2f9fbda8cab6aed4f7047137c467c74c3859cbd169e28f66b3068a0f017b46edfb633500cbd10049a81e42667c1445b4f004302468cb49d0710c92210225574d0c6ebd28090b5e1701862a7d11cfad4cab77b291314db8a7a3f6f96fdc959d3e6500ce7aac8c11420a3aa14def3721f4d8d85863c52b8267d7e059d8df17a60f3467a52eab17fa4b0d45c124ec226ff502dd725f0cfb87c4ecade51a2a8faa4e525cfa4b3f3d27b6bfdd712ff886950b625174fb27d9e53179ba2bde5616e0c35dab59dc48be3204fc183755da03763c9d21c1bc9746c20e5ec7acd3a39e73f05328f6a273dd30c0fc243fa4ad85fa39562c3163b32197fac34a9f641a9f7db8d8ca4deca2624e4c5e890e5737b5457afe63ed347722e185da7e5eb0cf89e15dcc15088c9d9f4e64c07de34769b00a8b4535fc84c4746aad662ed16a4d8310dfa094817024e22f1af1f5ce47a1d4eef14542a7c250510d61fec9b778cdcb15e89e1b749c21391dc7e2c5a93409e455515047dc660814593f1ab109a3cee758354baf830605e8a4fc3a8538a73388e445665ec7675530fe1167c2f1c6a9731901a69c30dff54bd502377858fdc6ce868cc25ff528bde779109229330d5685af9c7955885d9813344826fbfa19e0a175d848b5b397cfef5b0331cffe0bb1627fabdfbf718961fea21a616858fcb24e66e8674e9b10c3f4c90a878fbff939886155734a157ed4fb59e1244099cfaa54cb14d4f3ca833f69e74ac0d27f7f03c09c39b8d7b696d570c2a0220e586bf6a777b0ac12d95b7779ceef4cd8303d9d1ff03d19af538d7f89f5d5f089532d9f238527874b77c369463aa496bd6e8ada67f7ebf69e70fb05ed866107505d05ac09818c899f3f054e98db70fb3fe50e4aabfbeca8051be55300b34f809fcf95de5cf3b542033bad1c0f5d430e9a01192d3006a46d2a4d50a535eb276234c7b58b7aa160f54260b8c426b8433996c27a57dc9430ff7ce7f1e81472a6f470f9e45eed8af50be92a3fa14f5dfb342a991b1d812af5055d4ad605e6ed070c801051ea33a4165f5729e23b649e505b1a62bb8c0194e3d4ad72a3bced3549ca47345dce4b245e43661c08b94dc836939f688938b12843256f047fc210841f6b47488bcaad4f2769aa013824d69bdb835776352b1134c7f05073a1cf540f53f79fd789c714495ce510cf9a100fe8e21b8e95a7548e902f726023130f314e2d9fff149e21301f0fb63492c18a7b410138380f6fe8836494b828a3473a4163b0c5a15b67d314c4c6a41d93a3a955fbb78d669e7c24340dcce1e7f6bab2efa5193a4be9b56ff8d952652f66f2ca11872736b7e132b7aa75f31f62b446f74ec62df8fde8d184dde18e3ca19344c5edaefb4c05ddc4ebb076f7a1d254f0e3a72571afd1c026f2fb0546bf75f95fb731ce925c1f59b55ae022f8816270ee2f02114b44bbadea68745845f07700b6068200510f2050f9693113c3827ae2bcb0c69c8fb1d1596e6ab204cbd10e2c372ad8bbfb2e5407c3fb509f1f524eaf7aad131ea0c41221ad6cfbc36d95468b0feb5214880cda6a34c4639202eee30444399b9106354525eecc9b206d3a7fd1c8aa142c1f7356e54951e401b27eccacaa1d92c3da4d7908e3c9b70702bc0fe35dba7760fb1010d74260a9b8f8ecf2fa16cb341dd08aab1df189260403acaf19d9e9e7ac21a3abfb8c47747e1bb68d4210aeb9909cd182be19ba98f1614a2eae7760d0498346ff014df6c1c573e4a6f9e7723c541c7331a1ea5417631726058a92506e35510d25b61a6038ac18faff712f646e3c2f30def6c89d3f3fce9518dbe19133b8fdf3ccc4766b56f5972eb64a224eff66201ad3229e5eb36781119931a02f5f0f865c6ca4ff4842c522270175edd42c6ff837e4ed3b003d056b1c7389972aa692ba476005dcd8ac24baa6d2682f3d54a1f5e7f133f7aeff11630eac22fa04b59a49cebf3f69ae10844fb57d96703ca3990531e3dda8d203de8beca4844c309a80b467ab066b5b2ba33a19ea87159a43cd9f5291414964464e1c80890843973c20e73c7380f3687aabdf01363f5d476f94234eea7c5bd63ee97e243363989facc8f4afd5e907712380af68f7fa36ea318c90b921d38bfd99c695ca1d981640f3504e8d690ddd15b212a30bb04bfc6e3af5127113b5fc0e87f90ebdfa55e29330819af08d6ef04394b04af503959dfd6f52527f19fea1d18c9dee7ee98a46b155a55828dbb949561d1ff876826ed63288c6fae7136c0c940e5c09558980d398ac251ac0314dc97dbfe2bc0534d4340770c0a9b8b20981258962ec36fa5a49ef32156314a1627fccfa0285cc30ebc5a77a74770de5b400002ba744df6f06b6ce372ce3b277e2acf7438bb44c6284ced70ffd6d141a5cba08fc56aa48e5baaa56f15d51be3acf8014f1f1f2f62143ec9593f3a5f8117ceb766699c071b4897cff6d833a58e54f77379bbaad13db57fdf0c46ece199c8c8f51f76c13b219cd56c42bbed2caac4ef075ccf56edaa6679d8f030274abca94c5d279eca17ded5e4a8253970f3a5c1b55a52904422ffc319a24ee5679a4dc53b5cc7ee98818ab03f85a5cf0941cbaf401f147867287460397e53ade67930a77a9845b92fedce03f018ad543f9cd56c2f9b5bf26243ccf36719666aeb3a066232724d4365e8a05f312052218c022ac193ed7d4a2990420f5e5654b5d387a956b54cf664eca32476baa3ebad36693fc352c8de8449da7cd36fa28afa7c2945e00c6ca78ad79326a2dbda1a7b0189fd5416a1c9f8acbdf65f662296cba73cc2ffd517d66a748dd38e1705ef85b22b4e448a269a40236a4b95c05d72da757c167cc16c577e436c4e701924353a5f9c1981a8d25697dd8d7c8714a3a81d831188da70ef4b97a35508254c699b603e70362c23eb999e59c24e421d10a102459e9d872bee81a676bbf9d3f9876bb253afa589c5e1522e0366cadfda4bcbb78d9ddb2462fb9a9030e2ed10bc70f7c6764e1982856ffb2dcada6e8279d3d706368526fbed50c8b6143241a8704c9b065b282bcfb6d8860aee55774f9e937a35462ee5e1968a6bcde0b3cefbc560e0ac4ede97fe78c8f446a4af9d5789078f902930108b9028e397cb2fe8ee1b76044ff69cf82df9b6bd5dfa210bb510cf122560b8e8fc1d78a3c056374c3d863fdb995c4b1a67adba4cf20872c7c7031cebdaf051a52dbcc6e8e5cbc9bda4994d047d944088b9a38c74eed61cbe71e2616b6c68d9d6e99469998d556f90afaec1e0b6ff2ced332b5f8021478f9dbf565f98ebec451fe7b3bef1cce29a1700eae4fbd009237f238a26ead8c6998157d9ab0e44b786d01872e0ccf64f43b90a9431ab944d68f0681af75985224fea449cad295733aa762d6e1fbd3e77e9f007021c50cfc499ae8710663b0087d9b1ea9bb960872a746a5daf37389b398bcc693c9df0a3adbdbb3d2160d7c459a643da5dcef917d92cae0e51747e315c9b2355c272f1569cb473619c84d3b5d2658f2f244e5b3477b51079a9895dfaaf6b2e77f4f3788ab1bbe8c919bbde22a62bb0d41b4571efa4b9733ad45f59687f7c2bdf259d719f4639d6de7cfac77696dee1d05c1271c4816c6831f61f55c7f42109a616077cc6e070b2e70393e7f7503879546e3942cf476bb4d4f4a7cd687a43fb8c3d260774d57c64ee6fea79597ef657f497389db3f04736595460f79283dd838a9993a35694553efccd773e654b430ca41fa30c6a492978c6cf90ce95e2e92f66b858020e2694e38ab163d0a3133c79f93c37d08351dc2420bc3b946c9a219a6153b92f468a8642236d11b36646532262bd2a2fa262ad71207a64e3aeb7b8f0f5094de11dfcaeae1284216f9e7a252bb159a7c8f61713dc68233873d33c893e48b1b5491f89e1036b79f0a61d4795a84d0b7e96245aa4ae2eb2437b26c9f9bf4a5217b2a0f727962b24b61e8619625d869774dad4659674f75535ea3251687fb5a16bac7abc4591ebd170bfd908e240c946c92c5094e2f45105f29ae150a4a401295851ed2cf20b3b8f91eb50208b91eb0d7c36c40bac143445758a89612fd3c001a8b899f27809db05de7f8e88bc6bccc439c372d2cf3abbff8ede0f76ff93855a21697d880d520679ff4a08793a4a9cbb273a2994910c444be20d85d4ed93999c07b560cc6283abde13c6da9709f0c06187aad1159be486067cfbb4a68f74089c400020abc8af46ee6caefcf3077b0328440731d952b80b23fa5580f19b179dd7c987908f54d863d4068eaf2d6a9074745c09cc845e80eab24ec6daea6204f82dcca96ce9c63ee22b52462fe5cbf115bcdbb519867a382e2e1113eed6f46ad133872946e0334b17af2bd5b1ceadcfc7780835ef53f4fe65db374c72b1c81c7e2536e70afe80b50468c63e5d13ab41decf02ccbfc45a58968ffb582e09ae28f77f6e78af9fad62e430abdb73f5a8ed4bc2123150d76d695c7ec36442eead4369f9802a45690b7c95dfdf791c57ab76d22deccac5f087325c3419f197305467b03cd6a251bc458c929aedeaabd1ae53679c0f18682d829b48ca2551969858b0976195d2baf1109e0208c0cec98436dad21aa9c0a7c8d6720d7a00179acd9ee53e6ff670dc54e3f1efe7dee505f14f23c3dcd72bf9e4de7a1a5893202523d3092a00bc3c00c21f162418436809a6505f369f42b82073e1de804a379425f294cea971cc1f0f48903f1aae84aa01830b14b9ebf384b417ccf967e308997b863b02b6ea842e92337e36d54493a820d949e2f211e1d164a2cec600c3866657a8ca141ef75d477ffbb3f561a6aaf967f7df46040723134affb5a229db6a1c2f6711eaae21450925b8d980d017ac2a056aafdba5df89de44f382db011c37ed78425c3ddbcc1d5637de98fc8a76054404b038190031ab849a81732957c13dbe37c5a6584262a1bd7108ab849525bf7a36f5c4ddcfe2b7d22bc9cb113b5b204f7cc7e144d4a59c82a0149dd37eed7702688f2662e3c3169844f54a942212991eb179682f8ab8e1bf178cfe36637e0508b8380a425f8baaf5730e326f4ae758fb8898533d41364567f110536c5b0f944165b63058efb3acb1ea65c0bfa4443485624989a21f3d5f085bf3e8771d68d084ea29ce63288cd4f16467175c5898aca57c8cf1dd0eb9a4351b5a225f39bc074491ab4ec21cdb0b2938f62bd81e3e62bc126cbb5a41157b0cfcf06da21bbe0193392a86c92e013959884ece9cd3c0aee24b72c08d8465488ab04acc916ae6c4e5d44ded22309e4b3b4c79526ac274aa47016503d948f13a42e35ea39416b39d873c6f7543d4ec2228b25eac8172aa401c20c198739402e9a7143119123b704182a75b964d1ce2cb7e7202011008e2a44865842b236047239a89733757c5de8332632b986c566eeddcc764be0ebe00e17f7201b2a43df9b854b50cff695c8c65e32597953b8cac206572260c07f661ae10afa63ad539c028bd8b211f605ad35ff4a7e1184817d2382535df90712e7f7141ced1ead470078bbee82fe09e5095a05fe5b177c509c92aa861a0e84594985b332815b5eaaf9f14c06f20f9dd10c3e1b894521d49845bec9fe59288c53d4577b37dd0dab793255baf31934497333db1c733c4ea8fd96639b3b27fa6f6ef68933b152dce6dcb8d045cc7dcce5c1dcf6fc5de31813d294fa3b721bc716a2891afe2f4f7fbb054c7a6bfb2e68b475e2cde871ab0da6ebc3707335c98649c6eaa39236c27334a613d4c497097e38f757203e52be49a3eb284b80037d68ece2a709d69c7516c5d70c78b3a9a9598544072572bdbb7a08e3dbdd8b52c808ded7590cb8c809f0262664ad6f570441b0e05e71663bc191639da737ec1686d577217b13cad0a798fe89ac69bbecb92220994d339ef3315686f70dc02d1c343ed304cd5d83ab142a758d898d0a72f48f38edfb9b81664de8ef623c4bca81e44baedca4c480ad74c1594a904d6973f73052bcfdeb75c9a586ec51cc27d4b3b2c41407d026a1af1962e2c6226c0e2f5ac93215064b8b8b7407a12778cfe5fab5e65f7e6abae6e5f89723112dfb82a54281bf91900b0b11331e11da02b4664b4887099dda462de7ef07b00c0e98728eca7cc2438763947f2aee39f8202b6c615b2f22634f3705d7ba7ca2b2781f78cf90aa650b887277ef3363231c78c08bb1502fc6fa70b129123c272460a00a94f1a4b288b0445014811a2f9967c81cc2944e93001098ba9678be005a61a1534e4fc60a8e7c4f881c8965699b72f9e0a933a7efe752097cd54424a2a79ec8ca081856717cdf787b9dab3eb53b5e5cb6f525817c5dc6b2345958a8c3c22d59bec211fee303e3fc7bf7a0f25fc9441f10d47da07cec3f8079a40e7da7273e175e2695d3a76a1c3af04b49551171358ffcbd6f233aa039abb9f123b3075488e48ce6eb02cfcb743fc447390d628a1e30ed6c5c2ab1082d669df37bb1bcaa507c5e556fd58e569bf793e8341ffd8723b82ff36d9799db3e7e73e0caf73d23d5bfc22f57fd785ba72c4ea3f23ea535bb40ac1f50f20683b612efa779db13ffbf42ec1e805fcc569d479dce9b93c99bf2783eaec1e6bd35bd9ec8e1fbaed755769c7336b2f7d11d6995ceb05308d17b3603b811f19a274f07750ee3eefd21d9246fea83f5233ae362babcd8a4d48b71bd95fc7907b2c7e2eac21c66e12773557af53077fbd029f3f7b6581352565b94d767d2abb08704137aabeeafeb1980aa1aeed9f2e7ddfc2bf718cfc63a8f4177a79dc908fd011e932b3b579f73476bbc3e6c25cbc2f83b7c11a66581e18a68d7b65a67d04726b3425965788e54ca7b40ee53365a4341b5dc838fbc74cd5a9790965436ac9faeb307d1f29fc35c861f17d64e6312611c1666e8e48f1a316401d21f80713d4ded6c77f7cb77ac55b500b77f2a98e18707ebc0e2a8dd402e888746212597e96839b1d956a3c68c06f24e7640aeffd966525672db1493658e4993d4527089b04f3f220de4b335c9e5905a235bd8e9f00b073d8cbaf71975335bce055d25afe3ad00d3881deab1e7c4c8817702da50f8179ec3480118354527e0915d045d6ffaf0ae5318c57abdade02b5aeea38eb2ea6bd5c76aee400479db230000bd5e3ba6920a4120d2360466a673483e5ec48573190e19118003654807cf46d5d718caa60f0c5f421971636da99593fa47cdbbb092df6aa9388225fae1888f9f05922a037b4afa7b68947f6471600ae9096aa55e5187f27cced3cc87a495e12cc614b4e3e8ce541f1d2a06286e2f5beafa0dc56394c203f274aa86027c3ff186e28b98e4ffd61c80557fc74c5f2f8e07c86747da2088fdca5d1e41f80e70b37081dbbd2ba9e7aa19ab4a80fee5a25471d8a5f5ebb8c681c00af238c0e18dc34c2185c8aa719136c954126e0c03ab21696b48825a90ffb2634a83c3fa2ee030addfbee7210edf67865297771fbbb7e66eae9e9956b3381683514f86bbb37d9cb910aa825684681c2ceae758c6defe83f1b0fd9c00297c6883006803930e8883f967f0bd75f497ebcc45074ed3a9e2f6cbb6366d89d0c913b3aecefdb13db2ebeca08b23ea17fa991212278c72cd456a046e50f2e7636e8cc9e1ae2bc0be27dabf911279131064815c161755fbdc3932a7c50028e73ffb7de571a02a9fd214fa5e8b7987d2002d6cfa9e45c2728579d7de4111e3c099a169cdd7755f638b1468c1157c12977b02792fbd91f75dbf7490723a361ef55d58c35e85828a7b3145bf16f5d3a9a9a8e3d90b550d2240068a3bd79608049e637dedb192550ba2d34c78a7041b8c577a6fe15536e45f02bc853560bae52563d785b19a79f081f77be6f03c90cd8af30372800786bbe6cccc3c5396f45b271280aec4070c8971394fc078f09d2bdefa4f6f51be187ad18aec70dfe31a4cf51e12fb74d42790134d7fb8e8ca8e09bdbe8ebc7115f84f1f2cfd9ef2fc749f3e8fd49946a90a8575f7362b7505d92dbff23d6a48f28e335893bda4b4b42b9e818a7dd29a4b0215cb0a2fbe315b8e394c1d329cebc030a8d9d2fbe34dd0aeb047174ae43d0062627af618f3220d1e17f71c8ba7c6813a7f98bfbd84d27caa77c8b61fc92ef2ac9eeff3392612b75ccef45e03988903422f0957dfe8891a1ac3f1049a1e6063f18f5228bf93d551c930508bc364d535296f7cf075fe2d586451d8258e540d3cdb8a117e8123011eedbfc0e40fba8eaa0f9e53cbe9f36eb3b40258d4b6ab2bca75f4b00bd9796554e6b7d4ed14f06cc363324ee2a97b1c94aea31532a6bf13b2a5a0b3fecd741b67999fc772e01b815617b6389e27f607f6bba56072d5a8209f54cd9593e09035ad2f6fbfeda5c8f3a29d97855e2bb00284de96862599083be98e2ba34ff6fb83c451cdc7ca12a1205d238efbda8538e1a43aec60d1b3d3ebacad18d67c69911952d6972516a765f314ce2bd5bfabc6f0b849a289444c6b1fe2158febfd74238753303f8a83e2d248f29de164aa80db46d04f2aca2710d18b296109ddf22c5cd194f7366601ba9db0200932c445d3ace04ccda6619401b67752a6672805a5c117be4581476d15eb0d23a3d099543200d72b39c532e9878ce7077009debe06dce7b6ffa773696d18856daf327b800f7d804230eaeb50ba8321a3ffcde7777203e6e5bd4618d173083222c1310ae5ac3dcd665e4ff03e4081fabbaf686ad1aeb1a12d8690b82d13d4ad513b94f0d2fd0a36b0f0081e991a86091ed32eed0e679be1d0d89cf4e56a06a89b13eb0c61331759f38a1ad9bff651c1bc0572da9002a1fc002cef1400c3a1efe0bbd1eeb340e483cbe982f23d94c3f872ef0e89707f72e9276facd4844f8ca1c7158948c3474edc8371ca4146281f6f722681be3fc48568442af6fdc06b6e2c8930d0bb47506129bfc0607267b2b344d04aec88232967828b4562a4e1fd9bbe03eac4aee81440c20d7e876bae6835ac2ea59c5486f5cd2bd3a117aea37cda7737d6cbfc355e3f7e089ca76ec26707f9ebfb003ecaa8fe3bbd8d934f942a2cae1098bccd55279df89fadebe07cfe7e6a697759b8f8319ef23e8ceb4f776c09ad6c8bcd6cfef42a722bc2ca1dc5b6a97525349b0f913f594a8b5d0bebf6e8f2992117f908b6c35c303e49e2a4a9bafaaf5dca0dcbc60d22d65c5221c7b8e8cc771e3ecd70ee6bc3816ea9fd0cdf657087fdc23d24c10613fbe747b81ca1d5e019a658a4a38f5eb58324531bf3aa486277326ae5ee5d997f8f6b220e0a805dc5cbaa4ea8d82aa5b6bcd45821a73490b17e759c8a3cf5e082f0851ee91a785350ef310563d71ea3a0d66707c3b335a3a333ba73e94fafb9074654e8ca0e859ecdb05ce55e07eed5645b1fce0e610268fe74a9d8902a957d2b331652a03830be132a4890a552ff3636ac459024e72ba9b5ca2e304329c6fdf24a24c160454a1f5381a2d0e32e4b4e4635cc1ba7dac09410f973d891436cd280b7ec7adb45d5937319ffe08bd16b44035d48546f7ac9d6e1491daefd0a9d35665ba0ee8d6a46e4ef5c4acce64e817b48f7a62d46defb712bc612741896d93274e9363092e846ea3cd8cd0044822fcea3a1c3033526647f225bb44d71fcb2615deee0b16ee9c14b443b9ca42a01a5d5eb7ebcd81aca7a1822eed2b0a98c7757c6d21ea4c25fce89bfdff87a12309b3e0d4565a7505206dc56c60733ac8d35eddfe55449c57fdbc2538b52bb8f464840ac87331a6b6f31cfca62661b8554c697caa7018c3009cdb08f8dcacd6859035d60ec4efd81c128b3c7a22d407c0b95be28983e74ed816d8aefcfc2950dda9e91f08f4df45d2c10e69d73537d63b2b4aa3ef3a25c271579bfcddaa9d439fd4d07d60555303100f06e83c922e5bf47d2223ffdd32f16705bc2b0f032952de0b5cb07bb647d6c6a18694791b7c274edfa184dfcf5d6ae596fc6d1af351af97bf84d0b8fe7094475f8ea0cd00653f27eb6726c106701e2f52ad5f6b0d9bc0de379941091c0bf4b7ac2c95d6d9cddcf5400cdce3bbdfb22d7174865a6c2f99e35fe6881c7d0e19f40daa1dd5515a25cbf7d0421110a87ffda87483040059de1883a9acc837de2e77176bf216d6871a6e72f834c86b066687a83c6b58172f4f99a2eba98adff6eebe498809d8a1523a690974be9bcbfebb1736f67697b1940439617bd1b9965e24cf41c33d9b570632a3ec6e8cc3bc69d4361abdb0dcf078c4f4aa69272267bc0de36c391022bc5e5011d712f6702ad3aae35ea7ba8b929da18a1f065cc7d519b41a94e019dd931a07ef785fccfc1d7520b312e1492e633ece92db6c34dd13620308537efa003a4ffa92482cd529377bba1b38a53abc26394f800435c731a3766ec411f5918d7523ad3cc161c031c7e5f27beee6290361b9f3d65df52e899f128fcd7e2bc82303043ad22a5d97d4b552c637c74f66c8b72e2409bb7cc3ba323f0f022ade58558fc9ced848e28cfbdcbb0f9ea71221ffb2612d98818bc223e2baa43af5da5afe2a3d8ca5e0466b38b45b57b7a7d8a4cbf11d96b93c53b23b5c1cd9787749e9f7134e0017d934373aef19359152193e5f75dc2919e51c07342e50e96e2e9c9604762c883e34949082778148a467082c63f47530df02607b26954364e12bbe8d9d30f270c38b5ad97d8498b199d5d49f93d5aada0e15dad5b13dda15b72de0f686f8acfbec329b82a5911917d9ae8de1c959caaa4f399850fd1a4c839591730ee89bf9630543591a11f0a1ea5481a625938ad49e00c75a264f226a0f7f03e6d91ea51d4b77d00c8d42218b6ba63cfa6c8cfc65c2b856c00d2ba6076864567baeb8bee032cf14f6d1e19d812d1a9ba782c3a4484f263b04a8fc821f2c0a897335b7876af9f50038be25f520729731029c7bef006619f1a5d9387f5a4fd28ca65bef6a509db849f1103cbd060b3785e5c8c2f00fb8c27653e0ddcb7c9dc6e77ec69c7bfbd1edfc3bea88b34a2db2991e6f1e0a0a03fd2755981a419c9ce3a571d1e74d9566a2991fcf677b9281629fafdf2faeb695c3acf43c47b0c1177fc4059c5d39673b2d4578cd85ed12f7155f2e16e2c8aed859851e9cf5b049f1cba4b806fe866457e1a813f9f95100c17425b10f5fe690f814fcb791c12706e0a059a2872ce73d6a3abf65adeeeead2e818359bb3af884b6ea8d51446b6895829e3126e5e48c5e437b9a51cb2c1aa59690ec5c4eee08f5755cfbd3b102e58c7652a28901705811c155cd2109b987d2af8e8cc31387d4a6f5019b9be3d100b887e43e60ab618703518297c60dfb03ace085589f9e561c99b21a808f132ea550cd91fa54dfadacc88934298f6c5735e3ae35a965cf631d841704f9ffba897480878658f30984b874bf9b304a4437288ae67d9cbb1fda77d16ca08e52fa14900a51b87a85c842188f1632cbbf1b3b5bb558bd0f8ee6291e05689905f377284fe1ec51feabba4b25182726f473b37b2f7d18d2c3b0c9fff2a8aae4a7d443443c3a4c19af18ba1627918eff0674b1b4431f321f47959f4eb1013dfb4bc274b903f08db36a1cee9663ad42b1e74b54aac15f68c9e40c3634e46cbe7892ee20d95863211414ca0f7bb00c340c21a7795d1db595422743ec1d9eb52be9e844987c154dd55d3e7a3c32f602f03969df18ba05e316125389164fdf9ee39405274c9f8f8f3021050dc9d072412385e894850c2afc5d5caeacf128d13d2aefe00d4bb2fc260737141720bda1ad922170f20c7df6d399a48d1a4d7a4ab4cff97b70937c1a3aca7cef18421e6025a66e070a2e161bd104013005fe80d7a5ecf167a54908cfbd3d61a5637245b721961de92cb475f43faed95c9421a17516ae050a7401150a9753c982f9c65dd3eb802f719fe30376d19946495a467c510afd970bffb6f09e53a6ca0cf38e9baecb7f42f7b41da5227447222bf581e410c955845f9389f09179c78e6acdb4bdc760b3b5abc8ad1cbf3ab9c45411d580f057f5faf746e355e9d32674627513d33672ade714f096bd2611fe6316b8df7c724cdbd217709520f51fb21109e81942067480f4d23367fb492fc888343e2325bd97d06482c6f8ae3844fb5e39ac5c978318c91cea61b35f1d32e70d404e88beb56cbf5fae1f53f31115cb3e1486a9db54d59a8636dcc77843a2797b71a1a3b2eb330f481973f6044275fd6c99f2feb6407534a82c82bbb58351242aff9902d579b29aceca775cb09e406bf59ea272bb49580439e8a4e247ae43c89a9cb6e417ca90a1bc75f7f813d52bacc326da60a974de552d6cc8fd82d3a0c929c5708d4e9a09ca944d09ab69e4483b2e7fedcf2ccec14c4071722af84c415b7a856bc939535f11b9eff2f393913e40e15a9e2d0c76db840d60c75ac782659ff49b0be32c56917080be450c4c7a4f81ec22f42c3deeb9ed97045f8c0bffb4588fa49c01f530c9a353f7aab0a3eaa7e6d09316501705d030c8114784d45359d2d218b0fb4a222692b12d249955d372365dee749ab8257b5f6a0b9522a408c556cca64f4626011e546bcdad16e4d089ce9a594aa93f902158c866dccd9617539dc5f640abd126800b3aea7f91d26a601152cf57f854da97a3c9ed703486b6edfff81be5ebb0f1559d35b5828501cee5f07579d87de65ea4ed190e6d4cef9a32927c7e9d79e9c567a7aaa897ca84132a3ab3546ac1038c3639d2e0544f505b3224c1b2b6109e4981f810214947b74b2ca3b912f2824cc668e4dbbb4e2c0c5f7e29cfc678a0aeb8d5c56be5005f0ecb50e05425b54105556bc45ee329c8c916fc372f5ca738cd812fd1089749738dadb9541487c93b1d6b8bd587cd9473aac1d2a00b4fab6f380ac275ed2d7fd6e34c9f4ee4f35434c0326aa0412c4c9de8d94a46f8ab6ccdd34d4825bba400d4fefb5d84abbabcd1d3f15b06fdf773207175c325263ae73de64e145297753d8e87a46753e1ff2b2cd6fea7d823929c7ce8f1432662e0b467914002bf485f861cd92d6566af9c56674f23ec678d9ef354d50cde07f239154b474fc88f7677bead9e2d74d65116850d54442355c7c9c0856d84a4cc7c55242cd45af8612e291636487f182e7dcbb5217832be06aa72b9d8ca9ba0468f45027c5b048ae0cf90a343f7e7158df71b93d35c518b58ea7ec9f0aa6a0964c0ecb9833e7e1025a65881e63065cc6117f8f6f52e00575ea7833ec058e229606842ac239d22800602b0397b3eb7d648ff690e87496d077d3cc8e1a9c9a383125c4b17ea5a8b1c71e546aada26b5d1d854201c0614acf353e5cd8cb46463a07d1e399afe437a163a0b32053fccbeccb4f8b2bf9570ad6ced27a1ec3d13c39013d3a92fb696191a0151b20ab7dd30528ca09791e7cd1b5f6a71d99397ec17eccd8e14527eb5e0b750bb2dce2ac86cdff83bc25a96958b81d50696eb7467e65196e974502273da78aa6ad8a533cfe690f0ce9bb434d78cbebbf1f84637e85553a1501151b99b31441f32c1f797707854b0318a83211b787d3106e5fdd0fe9c6a815317d19cbd762ba080792813b3cad151d1cc40e8763a468eb21f62e29167d96a7d00ddbd890bdaf2541d06cc033778afb70f1347b8c072153a8a04330b73278797df784c6c552fd55b05120e463e8bf86bdc53dd9536ceb38e5b595f0e1852d383ac5aa733ad294649f0c10512bd3ac602fef1225bbfb67c8834630f95721943a9afa8075d0956a4688c30be569e2180a444661098c9eb717cf929d5c7639e570416beea02d8e2b742b16da58136714fbf960616854fc7f1fd3aecee769643467f81d9ecec08d144fdfd61f9eb3644e51f1bb11f0c1dc46af48c962cc14fd5bf76ba173bbb98e1f2bf51eb5a8180999ee4a378c51335fc7f27511a489d7aca151bf6f355efe0c64ff8e5a84589cdfd35bde470a83f3adfbdcf98fe3a0af28e821786484363edc51b10e82a6ff5b0f8474eab47b4a501557c18a1dd8bf6c7cd20349809a23fde7b7c49d6f3ff03b4ca18de642a5931c4752a6343bdc64c6c1d690a54be3d1d9be9b3843692fe14a5a264ed6e7ad254297708d52f4b27096ea7aed899ed7f0dc9cb23a91411e98327ef5d3bf0279c9e08dbc77e6c7217880ef0644e73984dcfd354f587ed4d4296066c1ed5dfab5c33b8a9a64eea14501c748eed19cbbccdc1a24f2893d6b675431796ca151ac4651a22853e2bf1ddf55d94fbc470db638781716c50f38ed461e4a97c53a3914564d5aada4a6c3b26f01663854f15a4ebba67fd35977e9ee948944e3a1a2f026ea94e698c373a8a32f28505667afe6617765d240061bebe113fc41b834ca565fec1fe414bfcaa45a00c9fd2284797a73f12b7ba4a624032ad31bff5fabe12505725a4a0776eaac3a4674e913b193d074a024782a28439fca25aed00217f15a4cc435e44edd10b9c48bd25137acf6285fcf89b1ee39f2eef695ae718ec3cf0a9c15cd55fd0d24aed8e8097a3acedf6b752f38343f632a0115ca7ba8facaf70dbd4c7bb5e2b5ed132ddf0a140979230f0a8a819728880db688cb7fcb9e0286d4d437d53baf8872998492d66f5f294743e7fd40896455fe0cb04be0f2d21a7a2747e82fbf35acc01c939a4adbc425f99d7aab372adf24526d9b5e38ba3ad400c53af078b8c7209a11df9d894a703421dd04b69c593841531848d4fd83f15c4621eb38de6fcfaf349d5dab50e818bfb2ab38835cbf42fcd9a136a0652b1b18af03520146991e4c35f13b931a748fead2c28d87c84981ddebe721579c1eaa7505951b66485530bdd83d8221fe51cc201da5b6a146fcff64c27f66ae3d4472a4c5d0d674b1d5d84ad7683ec899e7f82b9e48f9e5900d411e1b291dbc8484bf962987f767c854b6a5992a747d95ab93f3d60adedd2890952f847c4776f32723046bdcc83acf8c39265173250a6cdc9491d325d598672ea4b918145cc790cb6422a6692af704d242e564204f06ba95042c9ffe7d57bb4f9bd422ddaf5ee55f58ff6b90238f510c761b6786d0df97b64375639c9cde8b1d2f2c8dc5cb1e4e3d3998bd6f6687dd150a01733cd16d80589d54c7301bce1bf97388ea14a630f213d476d0b78bed19e8155dc128e1d8143fd8775c83de875855b6df16493ded317cc418271ed0b7bfaef13272dca1c624df8bc1302a11037cbf4a5ea620e63b618c7a3287f902970109b90292390ae27325995f9a588d3ff22ae4745ee4b5da1080d73fcee3da9defb1bb863437f972caa6c6eec7443fcf11a7b934a562326d5c2ae70cfb4a85ba8116e4b98785dd267a46dac33e3d8e0a609b4aed4fd44e228e2b7f07d69187448dd2428071f7ad3e864b9d304f0af3c4450f4eb0bd43e88e5ecf915a4fd8e4d484d8e47af56b9ada6fa3865e2c223b4dd8d340fbdfa9e69bb8cea3839cefab38f17977fa7e2ea21c79db3c1e3aa39e38c6cebae325e5376a8450a0c45c6a670986b92b5a90d6519941be784aa14546996c9daf3318b2c3930632592dc5b85e133ff9c00b52b4c84bfae529006e222412f91097ab704ed6f13f89354c75870d1a3b0d23170d5425ab4a908ca02df897f699682f6f7bcb89acbe665a2d03a7c9b6ea515e9e1a8953d100a1afd22386e89255a27a6b3d39a29ec42b5891e3bfc395494d4d390c64491dce733689cb2ed9aa6dfb3f90dd90bea50de6857f234d6f65eed0ed4a0b009411666b5b8acf2478fb02e3afb724585ab48b328173eaf74cacc99128cd8cc5ff89983ed90e6b8a5322205a1a7e045a537163f1b0cf56597e8b1dfa2dca672213ee0b78e74f68ba5dc1c2d718ace989feba5286af0adb26be18fc3e7e6ed483f4cab356046731023b2b5688e654bfccde2dd72c3055633338aca559fefe0b14d7a1db7d1f025d9f4fa4af3269aeab4eb02757927b600e6b868ea84cabd7036649024ba8d3f2fdd2478e1e53314c153ecf862cef81a7a6747fd4cb49c5147e2c2647938810e2411ee1594d599267a61f4563ef0a8de874d6aa3a29fd82181bfae13776a0e64c79713fdeee2ad087e9ffc5529f58fc3f3ee8034ffbf92c06d4d3a2a77ad10edaa3ab1c4d10a62348f8d914dcea39c77217fcd35528453531b633f5978364e531acfd1e55c6769bd9de76cff91eb50209b91eb090f7bd4cdea0ec3fc5c4a574fe34de58fc02495b27a55583c8d5079ab9bdc5932346f0004eb94e7f404d10ca26d87f8de4123951c58180f146c7dcab1b50700294129a66be4e21c4fd8954286b1dd6e4cd570eba199acbc245c15555a1b2e86f88b5a5cbcb4ad6eb179dc1e95b07f20b9aae16486d3bb0a757beb6e2d5cb0338bee615082b10b47c07897eaad20592aafe55272984e57d6d40a964fea3b4ff438914e91f2f56fb761ca3801e2de65cfd09d94d754bcca62868bab99f3fad7978eaf3dbc131bf8ca3821be85d0c368252eb3c7c754a69897467d8c8058268c210e89867f04fa673c780e9bbc6199cf8b638dd5fac092ccec611a751d953078a17cdcfb1da93ae347e2cab16a81eb914262f8643d7a626ba6617ba4ae8a070c9bf9d88c916c38359f00b9b6eefbfb42b1b7093119a4268a80a0a6fddbc78e6f63a9a162b4c89759892ded4d0017be05d0601973fc13ee47b732250da3e0141bf1e6a6011b080676ea37537f07eb01fd7c28c7cad60207862b0b4742c45685242bb76b93de97172ef465bc07df94a98187500909a5143440a6e7f720c1be8632878c3c8ea4a0b0572f1cdc23a7363821a51f1b974fd62516686d0bdf7a96f4d3eac684e3f0e30ebe19e3dfc972be7062c0e76eb411f57f27602ed37565daf6b607adb7bdfb83ad1dfa3c4adb6704d3cd848aec3bc41b099ac8618271d29587887067d7c3078974f7a3ad0f998d25323f98352688bac035475dc0f767e6b0fbdd48ae8d3d8d7007c93de234b8873b0c3b411aff188e1d43125bfbd37b38c7ee60c1034057cac0af28f464b096791b96e837b10149d2d65caf4d85d25def5b52921c5f69e6eb6e246e28ecad6702de86f688f6f624234331056bc2a1d57259bbe7a1c38a98096a28c81c12ba38b7e2ef7414a8a521be0b34f9b84f3cfe78ed2b0c534063961906fb3155d6a164a405bf0df7dfb1f076c5d4c1a713a65da9d61903303136b2c639331c22fac8f938d13471c7051304f94063ae8c5d9a643a64e9a6d6d839a24b4d67ee6b8d49c71a1deea5cd4120b9bab92581c5e06ec0aec8570eeefadcb5ef8ac62e579d3e7aca871b33b35bd6639192129bfa1c9d9b33db20dc3d172dc96be596fb10386ba77c3112b72ae5f01646d5717f0457bd1475e7120cf1b2baff8dd72272175fa73898a68ecf3ab78d5c54eba4263711a1cce335081b55ad310a2a078baf0a17c4b9e2537eb130c457a28ca174fb8d7a902afc539846450e4f0bcc69b453c1abceaa1432fad3717e868f05cc49db827ce2fab1bcaf8741378db5bde94a3c240b3fa55e427c855f044fb01c6ef2f0012c74eed79d486fefe349b6d9baca6db2f560e0bb62b692c7ac1671576762a010774a213f8ebcffe6cf6068b2e66678525c04cef987a2758dd39d7858f2f95313c26250855eea392a09dc1e73d761308199f6a8dffe6da970e9d1b3d82ca6c8b36104bb129d50207ff1b04b27b686461f9f9397a8eebd12dd78cff690bad1eb2563399eae0104032e205adaad2597b77c9011ef74c681361d54bdb613c02ad38f919e01dbf41af0d4f46efd803720700c82bf8465e285540cd9d3b0f6c6ba5cd12c07ba9bac8fd448457655aeea912369fd5be8a6f46e6326a94161171a9a8bab191cc67d71debd83ece515b2cb235dc85908671b7e8dcf1596d005a06f7373cd35d61b572383a8e1b419dd3a8558c4613f9efac15b74125250367746630f60bc53aae2de76f68035e33aa5b5eb72fde26fb07814d5f63ea9e14efe5059606161903bba33a7ce72990767cb4916bc795dd649209c154ecba23c7a73007a0e9a6636e09568b27871962b9f17e31b270bec1ded8aa44122bddaf266e748fd2784c3ade64b3c1142b715bc175c8aae955e4858081fc6ed9e3125428ea623d855f9ac59b2922dcbdd66ca81412e9b6f01c6a07a601fd183e3a1f85ba68328627095a408bd34f7ef801f586157f5cd4d47d3f0f09a895ed24917af04b36c4ba5dfc7129641a567e8218e7eedbb2fa32792492fe867c9d1c191a274969bc9e67f1b92df341f06d969dcd1eeb4f53fccfb3e24448009422aafbfc47991cce51a4af91623ad3401251954eba42c0816908c8ea29faf5cf15e0a5363e49cfbb8d93aefcffce2d368d261020415ae8b617c5684ebe8a1c3a612e55ae6c03b3ecb55216a422640b858ed6f022284cfb563608b128d94f365bc89b1fd77f39fb95806349d791b494e2b31a53342e68c316b626e2458e649097476fafddbdc999bb072787224d3646037fb47bc92d55075d912e0ab585a8b91ba19e25f39544fe2f8fbc88530cd17a0c61c37ddf785612e71002cf9e4673a5675c57f9b6b5ed505057a9950966dea730c07edb6af05482e9d036ffdf69bc7720943a555e3b87034c6eead9fe08b1fae2684a0d3d610f3d0ddd229ab72a305ae76b129053138bee3f2f7ff5e83d44474cff85f6b29a68a4fc18a99d9d850eb5ebe360ebfe493a70df28a90f35793b6c477d5750b18f2549f96940c71991174a924f38007f89db223a86b5cbe00ecccdc678a50a569791ad3c8a1fb683999de22fd5fb9f0f8105f1b31fb9f14f7e5fbe6a13555221d85082834947848533e9cca489b27281f7bfb9a7b7c5bc909ff2ca245e7251173d480759ebc8e16e1472a5d435b8bbfb12fa6bd449a29ab60ae13faa08159f067688d47551c8c3d613d1b65ee5c8cde71631e359b2e3b80bb68f6803a97561efe87732741d2f9d45516d85e7263c9197d42c3f98763d6883b05f0bce7108532e144e47751c89a46e01ebab6ad9cdc5a248b6baea67ef6edc81fdeae7a4f906857a94ba29a59d3751baffdf475ce17c002c8cd8cf56cabf045fb3a50974e7d7442a4495b4425cc8df8beab9872eef499524b8e5a6290f86e43cd048b6c65d0bdeb770d80a2c355c28e1f965b1deff50e944ab2ad69f39ad8a9afd408c7965a758112ad3e7bd7aa727409bc49e5f0a247e99cd373de9d9435eea64e24fa2c43c2e1c0fe2377a83b0198d5eca9cf6bcb872a673886144fb383d871968d8277faafa5afd968ba8f764e09ba18340a7ec9cb18436853fd82cdceedd9981cab51b8d5ffd7e54a0bb2bb21c22215dfdd74f8a57f2fab31a3176832f67a146581b6164479c3b40558d52f92f3bee5d014c742fa8b348008ff48d0272ad6dc21a9b63a24c997ff3d15b071b1ee69d1dac28cbd062d4bd0a345160057536d768f9ae224507a97deacdd1c5d28f378e7a4aefb3fe0dbecd71f2847af69c50653d4757501699ffda681e086d4619ed098bf801db0fea560dc3868bb3a8d6e1105fbe1f0e9791c74923f33d201feec4ef4508995e2e172de08e872935816ca01b6a9ef544f531625023ee0cf1d305f761c67eb395ff27d776d138ee817056fd09668f0a138fff2a822aad27f8901902c7d45ae184276053dd01d223f3034f9edb76b2e9b89e7da76bd6e78dcbe414c55c21d272c82afab566910da6c9a742550d3c372dfde3339960dcdc6fe6d9b7b344eb70769dc2d9fa99e5fd5c39e078c13d6327670ead590dbc929785a25c7f8a6d9e40523270623793e44ff76366378e081883b41ba010cb053d27b564464753d72cb9777dadfa2c672346f2368bd58470865dcfb496daf5a8df503ac7c72c3e7b76860ca3ac4d31035e6e0d92f8fd4a886aecd6b726ab978ab70adf756a45eb0d74df31ef45575f16d0cb305b0ef7e42e760034d01b6e6451bdf4323a4c164f2d4e5753a8f0bad0837e7bab1125602f9f13fb0258579fb1cae58280fbb7d80a158dc0bc8c3423742149f5d7f89086575af6b35ccf5c5311d5fe7ececbafef65020b8bc8c62d18957ac6b5241c9bec6a039a8e130916acff539d151379f6eb8c172f313dba93c0cb4f85a90d3430f0c1b1abe1b1cbeda9307e557b8aa4bf9a3a17a0c7861e3663306be88f916ce451ca1bd0b41a83cf9e12ee3a983c9b495bf74858f3f525cef5705d3e7b6ed893d82a00421e42549e7e43ef8016f94daae26df49630aed28bc389579041870bdb33059d6719457ebafffef7c942f413ee9c287d486a0edeffb287dcbcb9a69ed0be646962fa40aa2040283aa70f35e505c7a4b8916a18a9d748f4d3230b6707a04aab8c0e29c47815c5970084261c68b29fe080528b7eb4a284e4075cdc1c7a2bf1b99f95ef4942162c5228e6f6ed79108caab803272689fb8fbd54c31b043bc9bccf501bd0eba2a7691aa31f4e009e06257a48604dd0b117080190b71f9f3ca370f1f7f1253a03448b30f1ce8a84e916c07cf347ecac7e7c19d11063ac24c9bbcf0d63a8ef384875de2f66eb7a8530459d54927b4a8969c6216f83dbc3b9b7a27ed81caa5d470738e50473debe0d46da47f7a301cfe53c153900203ab0e6db774c11e67d106685c5896002a37bc4f5400da202cdbea465ab62ba939e84f14cfa0429a5dd076e5f5a599e19038efe4ac6cc434b01b03f3cbb015002bce46af001200387a515c9bbc13b25a8f5b8f7dbe2291cb9619cf26cc6338b61b71e96b0462a508087f6ffaef06d5bde8985902dd263b847b99d04c48c547236c7028e92637b3c3ce3ffa7c149c04f9b323859ce8a163bedebabe6c508d654075038f854cb1a35733a8816b2c0122c1e251002b4a524c1075b2371223ce1ca3d641f77489030421972517dc4898d6bff6668a349fd02a57d7b0aacf8e9470e0e25a2112c2f1e2e463c691cc36d7a7fdaadc0f3440223dd1bc6bf715aac9d6ab1eb8ffdfc834d070952ef7e38feb30be73bd09b36503fb546182a18ae2795664b1fe8607e92d350bba8b8f796311ac7acef3e7ace05145ee30084ac9795f134383e96af3fa6ed9dea5070317ca6fab82434f08df0488d064f34f62877af6438b1b416b8c5d1207ddb060ec35dc874c784df91d78045a2017b9caac6231128587c316529962a17f7847d690e52a87555a5d1293d65eff94414f8fb38de3605e85cf32d9e6222acc50df5ea599249d6ce862745f820073d85c3707b4bb83f3862aaf58dffaa5b48b4389de313c4736e5cec91490bb62cca58423c9ac3fe4c1244d2826c195dac953d3b9eb534eab0851b5a5aeb344291180e3a2f0a044b4e7947f9efe8590702a7246ef129f49bc111dea66045400519f466615e952a8ae1f1963f44efb20bc223c613f39bbc48983ab3cbf9751423143589926a2daf8c7bfbd2733de6c8f728d8776e47ab7e6a83ec92ded5b6554dfa6fcac6c0c0c3b635ae4b8431e5aa4173fd5524087d59fc5d0511e4ff7c3a145419f4058be43ab49dddb55cb9f3cf302e4064364fe2787d02c9a6cc7fb4f1d8c13dc153eb19ac306f7c820853fea8a07498a50aa1f653ad73360563f8f315c377ab844f07faa65aaebeea5c7ed5c81392aacc744668d0c21ce63d0cf77fc5d3943c2fcebacd8f3bb2c4067384473ce4a638a5a148957d9bf3f01ce88d61e30f210ed841ad3f78788397c7970ff394fdd27c8ef6a34b4a532141dddaeea02caac900aa822d03d17fa886235f2ba14a5e09f74e75bb18765e29d784ef3561b78da0f3f23991b9d5aab432f5edec5fc8e9720fd70c6d446cb8251220787f39cd6bb7ab36559b0d4b9717fdacbcef3ec960d52e1ac365378e3657905e0f4101e038a06f0e523ba887123acb26506deaa86364a7a8eee97c0f1a8dbb2e2e57674dadec202a782b0d0e1e679152a7ef224d180e8eb4ed91ef4bbf90ef9ff778ab9c48a8a61fa9ce8eb27533c80dcc8439e246e8b779d6c667eefd2305e27541f3537197e67d95ab0b2e876ebd240ed8dd775a4b62e108bd2943c181d3a26ecdb84f3662b5c57b9ae33dc4b7e2b17e7f2ceb2c339e623d163f0b758c432a8d209071cae8366689289bba29a4e6a659e36824ef7601ae8d61eb245530bf4f6aa15d67f63dbca86c01a6371e2a29922ec8902880a552b821300fe4d3bd6008c93594283d1e8794667d411502dd6856fab6f2af4518ae268f3a001cfafcee09f7dbc1fdf8f656120f1b94899d4dc5a989ca21f438f1439bab9ccd6c97517769a3baa3c450e8119f5c26e7792807541f472065779be314d3c2eb50424f9afaa117b7a6567ae741849851fc644862efefec441c4038933f6cfd9bc2059fc0d48557d01d6c8922fbd5ea504fc240e0fb855eb396e22155a6beb76273d60bdacbc90cd4f9fbbe195852c148d9d29d13f1ab8d33b3325eb83cec122fb1f366f883d73afb2a9a1763528dc13cbb1506e829adfdb008aa4f525d839c201c41a9d47db93ec16cf2b6ddbb002639bb8a5380d0d32c990eea1c7302c910302fe29a1833ce8bad7aaf42759a0bb768bd08c395089526e7793f2167731fe81f5c51bd5511a2878f98de9d10297cc5bea739cb2f2d8a625abece1b00b6bb4a71045b6d77f3bda31d07b5460a947fbfee4d98e8ca16b0644737f44b0d7b77d3867852889d1c7c8381014bff82c89b31ade466fc3772c793e8a03c6b4c7ee312ee075bb96eae33e99748b50b33a8edb207d87d213df9e8ce3e883728ed741dd2be168e34693be96a950a373632109093855b6bdd80c29d22fbc5e46dc1bad97b206ad48d171565b548fea7fa25ddc677e065235ac97661c59df09ea375f7c6d585e41b2c8a81eb748c8e64aa6de1a989ba4161a5f5336444761f241e83784ddcea66a85e24f10bade3b81d22c57aab571ad2e5d4ae6eb1509847510911182806a4945c0747040b865fed5ba722003cb6516936cc9072e9b78db78fea3b17e2b1c12a0619b5430ea155a814fc654c32794318862361511230918000da75fd841e8a13b7765cf0bd4cd4a9b41da5b514659a3b8406ddf581d628bbf732a48e65f0723a94ad85d0ea92123f0e7734daf76bd0a6fae23d6e79871ce158fc2519f0223d53dd132c1900394a2bc7b6d99ae9940c3e7009fa48f989b57ae1f45ab2ede667d1370cf608ab5a4d6257b58de29bb906fb96e57d908948e61de6de8b19604733b017b9a8677567d05c31a4edbe852cefb1ac74fb0df6d73a77a984ec6fdd8501903d8cc7d708fac35c88cd7ae3519fa020b761a40b66541b2110b5abec7f6b35e4cb7da835fa090c857e32ce12481f46b9f4e01349e707b79e86242d26a0b4fe141b79b6346abb17a87d19138d4a9278558c6fb32f517d7478e033b407e9bab3642906fd9e77b45cf746c6720ff63f82d6be7c512399858b015187401f0bff6538913647d61a15cbe24c4e91f43aeedfbdc1600766ebf825dd6ef8ff31705a0efffe821b767d113ba7b6f3d40f05463af4489466baac01568dd034bf9d83e858b3ec9551000d39422ab2cdeac6283d908cb3d3aa266483ee8e157bc59d56bd185fd6e1969342d3bd00811f53b60e902a9c1cc376bcdc01614bcb7156f0be77e3da00ca9374c5c7ce756032de4cddff74f59521cc9565a044fb05965b54d375c60c6b98e197cbdbc8de506284d961d41843957f1a8f9b3baa7564bbee55df6d27b409717d737af8c0074c3dbc5d48320af30085fa18e27e9232ae3107c77467677ae5760c2ada1feb81756f36cb15054b35c1445f754c3b0674aa3aed53e38f858d3da57b8782d586422026071085f7077331a06a1f0f4a9102327f39162231f2d39193cb4d6039dfdc415d03911c1a6e89f67401f889cb44b98a9e69281b08965fbbd7d792907acea146e46163f7d99bc77b8f90a0bbf0ba813e59f01c0ce0a9fce2258525de3ba2257354f43202a9219643048e06480dc004d884734e7e753db98c0f76835ee077d8f8285ff102c510d30e85a971063a653f3f39230c5abf6b8f38f896b46da5acb8ff5b1a8d279b8a4940dffc0614d2d090beab5b6d4051883ba95d1bd27d6da28e42024c504e0af6dd4554ec21fa1a41e380b47a46d049b3a1c6cc5dcdd61e7aea84c036fb91ff99e81febb9e93e4798f766294871771c168953094c07de7acabca586696df85addf36b2c792af471afbbbc9cfbef4bc88082567effdf9cccf9992bc9b5062e43bb608d241f5819deee336b7e842e857babffbc70d7c99624ee1e822516b7f90099cc0780972d942301177cd9d74acabf8fef37f53ac4306d356124efd014283e873caaf002ae8201fa3138032acfd08d1526aa0feb8680237368fdd25b7f55dca77910da503e997106d265dff3e6e46dd22a95a5f2d64014003aa027dc84320314cf7a75858e184534528cdad1c368a221cc4686e229d55f409dd06bee51ecb395aa41f1ce080b0813305d9724461617fb84e04e68399f732789bcbf46611f352103d29fee4c048817de8cf368dd74a8d9268e20256cf798f1d644e1b23dfa75cda593e0bdcf62e8c8ab409076fb6adefc23f2251ad7330a043a487761cf4c9a7ce539439bff096af7ce23df3c9dccd7cae6898cb10573a7b5a89ef30fbff30329b934c0d760a3c712eca6ea9d05ad4b5952731f897abd1300ecbd229c2ac7e5d8c39f7279ef5ef10f8efb901aebb338a42755b13533aa388f304843fc35f7d91b98cf3b22c921d797241dab5e49585afca889af2956babc6916959c2c506716c1e45bbebe4bc56303d4a009b212fd339eeecd1f2588bddf068b98162c0bd793b350ed83739af258f9b3fc98d6daa3b71e89651716dacb7628fb82470b89b610c84954c9de8058530d54cd3896e34a303c5646701662eb923bc29c1fc26da60130e4063b8d8d7abe89ed156c615f8383ecb177cd798c813cb9be9c0248c858e025339abd0152ae10fbc0c0856224719351d474cdb26d69848001ecb213329f19e45fb01353f68c3d3a06b53db610d06ce32a9bcf8ae9858001428f65d08218f32bd29b1eb568853876e28731c61f4b6b108018f54406dc08f55673e199e0153fe133065cf0ca995fde3e6c973b2ae88c212cd5325bf8c9d276aff26ec9096be2af07ee0efa5e5693532aee5101c46bdb1c9788d44742ae173b6a3d9e1e1d29e879f14c5e9dfad56b92db958accdcf75c1d87aaedae5dc222c9d4cf4eaad91c626b41bee9068c75efad62c24f9c7a8ddca0e06588ddb5519ead20bdbeb02a5f51b52a808493d7115a7bac08c3646f3c2524a392a4e70c475ac19d82050f348ddf05244457f1a9bd373735c8a8c173ed78b9e4017a119cf90e40e4edb1b283ac994906a650ed118fff588caa3579096aa7a52b68a57f06997389a47ebe7d441e98b89444032538079cf842d32dd41cc8e2d3346dcdfc62177159e29243263ce592fd5dd44512b5bd54f292e529f0e3a2641945a76b9ad78f207ae120dab16ee14ccd3f4eb85122de2208b911fe6f789020b1629b6aa6b9ac2f6d59d90a6b2f8ea62d2c497c01692503c505a9cbf456c10506f251758bad07c8d76e79e26e6cc8f5f1a14fd6ed4792aa1153d2dd20b929219bafca3dab2a58b994ad3dfa04addac67d0820bfae29a7902b379ab3ac33cebe24502a19e69ea61b63b4e311ae072f11ba0e6d69626b4f64cb776b7363314031623b27d35cd2d93c6c3ff855f3e0e3d191f1c3a5221007fd0505825ccc33eb60e348868af3ba27116f6a32a9e5501c80c9de16d158498f97b6649a79b75b701dbe07d438e1570b7e03077ada530cda2031eb6b263feba4c6c9632e72878faca763f012e37496348a015da94267e3f005a256ad8d1674e42792ff200519f529def9fc030356999206f8d5e47247f5fe94b4da945b6bd9be2307636ffb8352bfe447a291adc162b2380a52dd448f7bdedcbd7f55c60b9f76ce18b8cb34d9753851f0f858008010736802a2fb2133b73695c8c479ed6c4cc9d61e92ccfd46bbe0e377ca66c30ec86a3a6508b1a9a15bdbb3b83e2068c11bfb8e42aa19ff7fd4749dbf150d64471708c59a8249ed51a007ec0a8f27c3090c96f1628addf0d7008597fb9476740db8e8dd331e54f917748cf846daec207db04c5f08f505b3ccbe7dc28988de24a44a43827e0f2adc7c35f7fe7b9eb4d1cd71b6d6f8d2bba4fdb5112fcba95918b2762c44606ba8a8c1f77eac59f9c550c5000a3ed1b515093dea611c47a53df9332f621097338559709887a3bd4e539b12b28ad1dd1e284a0b6be0ac2aaea34896e360b060b0a417511ed417dc842f465fcc8368c6a478fcc737a96ccdf34647abac52b7a159ef05cd5f8f41b39ea7d2721e33eee2386b37c56479816f1419d65305b59c0ced9ab4c693fd6cf963d35be4182336a82b91977ea85ae2025b01113a512a938bfa74731e80946c42a564c7a4f9aedfe92f9a7fb8b16263064762f3f442dcd94b5fba9cab971478365d737c5464adb51bf68c1470e9ea4d6109cad7be973ea570fbead61bbf020ad68835c4c6a1431627a4cafc8eae9c2ea40c5d26bcd7f261bafc3d705a699a8e02f9d0ee9d94f5f3f8350c5e0b5eec4db100b2b673c84b8d0467a67668fabe1f4fc944b9139faa6337aae62610298ca0ef0a360593d9bc086249452d92bf1e5fce6f5c47ff86da9865264e9ea59dbbfa7b10efdc10b1c2e6a90e3be95707d87e64c4376290c435656edbca37bf0bf71976de51e5e8b9cb1ff9dcec9a3877923403933275fcea30588ea1bc6f33cfa8d8386d82420feaa840912ea5213daf14e757205586163bddc819e390f72f9a43e3a94c467b14f948ba5d5b2d526b8a929bc2a82a4b0d6f5984f11d7de7c43a004afa0e6755b6de57a2e60fa4d5e3c58a33c0f2eff2722bb646f08936f7d1ca5d20ae8bd813f0d157f8d4aad47287853eb7b50e0ab66c9d67921c7b0fb87e58c1a336efd0730727df54cff8296dc2b6c987ef5696e2537a9f7b10fa569a3ba721b3316306dbc8fcd08926d19db41f015d3621451b07181209f356a067f92159c5df4cf656d36dbada613ed5d5cff6c16b214cf02ff16f5f01f9596dd3c9d6622bad8e3dcc8bed4d7d0312573fb1de58e426cb1452aad82d6ca84d506c339c3a1e5f7e8b082e981d52f4d9182c5ca605000098e6b9b7fb030da52aa280cbbf478490d4981a89fc7b7b0c13e177809d9a3628f755c1108dccc306b3aa4416cde0e183538dff41b457ca4e10ddb87896c109e2ac0357a17802726c11c3fb0a6d0e491e0b5e4ffde2c249443fd002ee3f9989cdeb82f528b0ae8974",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x2ae72ae380ee5ecc727b0259435341ade87c9cad5dfd6c8ac8ffba0043ced613",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xdf09b32c761620c5be77da398b97a64f03c3980c",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1375070",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xfad8dd0817852b69b9a47dd573ff96d9c6db8f4f84075a7c33b16d0c95840722",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x196f882fec406e03665e3465cb49da69ed4ac9ee034a6d4b9197397ddc16bacc",
|
|
+ "timestamp": "0x6ab8f2e0",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-anchor-20402288-baza",
|
|
+ "sursa": "2800-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa0626573752032362e342e302d616572652e312d643230333230312d7774613037f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b8410231e067eddd2f9554429fe6972d550aefcd70f937f9b4202e92f46f3ce25415545c058a5ccc92eaf910b5174220eed71f5e52dbe8b6eef425b53c4fc3256ab300b84161ca12e6e2025c0ffe1e82ad6faed10ab3d188a49ddaf19fcfbb2741c3ed38605459c748bbb32901e6c999e34ec234f84cb1216c78bff30aac299336ccdc7d7000b841a6dc78dff4f90b2d682204c98a7d9f8ddf39ba631bd578d22d357152652d68202179c88ad3c33ecf1e2f6c53f4c2a9f9e37ad7a5de41d9809214b745cbf88bbf01b841ebaa23009b5b3be80371df37122572790b3078de5f012748245f5f448b83c81d488cc60c27c2bdf356d47d4c264d618a8d67047947447fa8c86dcd8cd568d9ba01b8413e8b7db966cbe5f9ba900276722608189d486cb9d836d4c29451b716834c4e4043e85982ce167c71ee1f2c310d16a88fb1195e7944786b0ae0e00950de50f6cd01b841eeb7a5562614db3d38f869d12ce377d03fcbe8b515f7ef49c6a154aa9bb909013490e22188ddd8b3e93f8cd5967648b13e87327edbda5cc99ed6d093a041222d00b8419d3489da35e344ab1c3d984c82387a4ba3c9a6c5f47e13829e2f300ffd53740768c96f2b59365dc438730ea9604681c28a9fd814f5508fe367a16c198177b03e00",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xc444d0f8ff8c7a8d3c9e50bcb746b1912f8a683a6431c72a901322c47c677355",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xb5e768cb3117ea25175f51aa956b48691025c2a8",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x13750ef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x47b00d8449017d2f8d8f12cea9ab80c504e7fd00091e83c2d7fc729292d5505c",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x6f766982b977c1df976daf46d2fc5ed427ad9c79da5e7f1b22fc67bc8ad79ecc",
|
|
+ "timestamp": "0x6ab8f32c",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa014ffca0bf3b7602a1a4699f4ac9d1e85acb5c5ab96eeb7f542d0fc8736d0cb6b4cdc8c6f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b841ed9857c48b4646d1a381bb3a216c044bb48f015032cad7f207f5768bb84784277651c1ccbb3c03fd88ddf0745ff14dafdb40d1ea500592849567a8aacac6af5000b8419d90037755c2dabaea43a59e0c240332061a1d6bcc0897c1a8cc0b6a99ca2a37076a2db8d811b10f9634897605a1b72ab27960d698fe634509cc631f8b827d9800b841996f66caf4cdcfe90ab588c93b81930e52b1b6dab559a06e434dc05a037209510f59434dcce06641ce6dc03dc88f188ba468be6df8221cc44c353025277bf3b501b84192a50e7c7faf5cf2c44dc59974f964e6e6883548c2ab76d0a458ee3b20479a317408e75214d891f6f4515f6b26d43949fffe4261bfca59785a976fa29b60be0200b84100a8b823321a12b2d13392ea821ba45deb2ef25cc358616909cf96df660186a343e2ceae26c76f3864e16bf83b76115ea8fd8f9e6cb0738d6d4f63cf49ee605801b841bef7f74ddc63c525b45fb9124672820c0452adfd06c7e979dec14b3305e601be467727768709521f5c1ab4153e7d15b7d8490cb2ccacd724cee411d8abcbdb8801b841862491d57e766e6bafe63b328217008e2cde5ff202f0729533666ea78bfa09a81650cd1610a66c100289f03c2ff36358dc773aaba249bce7fac043a5c58d710b00fa014d2902fa014d24f902910180b9028c39c373bd0eb27e0efa2bbe4a1e00fa42ba7a720483c394e6f052110876fefee7fecd8f21ca15994096306521cfdc4a2214be524b3b91701b2a1ff12669f47d150e5763efecd275165727eac14cc4de3ce84777fbe9b6cb00d8641b3860a9982236e5410cddeb996797cf7c9c66f5da69d7b93c60a2550a4cd361de7b31a34cf3e28be20c7e35c5d48e95d6fd45d4e2591cde010366aa1bc7770adc7135f569b74944475a06f2816dcefeb6a99eee46557f71eb4d32048a22178f549e206d62d33ae6f5744f1fbd5bfb09e8b03cd245fcb02c7579bd9973a437fac8e6910e230ae26cf4fff1e8046bae91a3f6077cdeb20d3b06f7f91d77f74fda881a3e99c7e5e04c6b414fb6498809c9fe198bf56fda586eb2b6fd46d1515ab235415aa43008caa8f1d1c97c79399f48d1c294ee61c78be2d3c7f50aeef50335e5a8d6218ce17be0616c7beab291d7f0e2f5d74fbc358527fe211245f2902c518b6d798aad3baebad2f72421fe846490fb87b0ad66d0efc666c4cf1963d3b7530bd7b17a46f6c6789779da649bb53d5132e59a43e1889c56c59d9a33d8849ae7baaa383a6e0c319f70a2de34c4c654e7dbd894debdba553df07fecb1469919df864d27b257fd70f5257cdd32732d99bb93fb7d6a3320eda0bb341dd780f2a51737eec9a9c3b97d7e9a0a8df53ddd7ce5bf2eb94d8eb48a5355d4a1b0dc5969646b4549008677e70536c1d8dcb89e5a0c1e77bcff5b32078564f3ef1b5d9d0cbea7ae0df910592594541b72925376081a1299d7a47bab8bbabd4d9e4e025aa2ca3dcd7216bfffb195f9a7aa5f748aed5fadcfbf0253748b7ef2b9147babb4e794aa232fad65da7e2d1cb9c3eda850d2130fa87b2892686657c0999621a5d862e418be962a97c55eff3c6b02e71054e2def99cf91eb50280b91eb03270e1ca185eed5f5e2e531018a252696efa4ecd97eeb26fe40cec9bc3ea3a20878c7783601fa3d5a41b7c70f51122bd09e8c84365bb16871703b3d6fd04af003f87da22bd79f5bee8dc0ac12d17b7c8e09f0cb535c111dfbade7f00770bf5245796c6d9f4b6ba77829b477345e88eff61c8039dc2f8552b38298641ffbd10d1ff06f65261c6a03ff8ca7e7aaf7c01c479f0eaf5744cd9f2b3f196bc7adcef8e11c00252e149bdf0927f075e04516cc2d6b99f8b6f7e1a1c99b929bff9e73c2febb49839ffc2d24b77dfff3b6692d3d0ece48d5a1c602a5a901a507a81c4eef49f328b55100edda570b23e0a25b04bc73f5e95f429a50fc95d9cd5c5e144dfa147d5ad5099bf3ab5ecc969b2641a2fb75d063c5f8af6ce8fa2134ddc6281486da472324061cdd74cd261adbdda1aa028ab9c2d5c1959aef1679c063ff10946d7b53c05c66819fc8f8871f9aca0b06517eefebf35c4f27d2c14fada31eef5eb933776cff026521044a57389f8af9b46092a80739594b75aa286022c8c0919770dae8f07800d298066aaa439de2a4edc5ec9eaa875097979a9de901459d609c11e657c11b086626998c832d09ba5ed8cfc7d499c4592a6de4f5028312e4030b2dd87e131a884febf93ae8ca7e8c4062d0bdcbbb917d47d75056d3c950e5be72357e0717c0168cba76fd59d7a7bf18bab596e255522a7af477ae5f1a4c6ba1afb98ff271c869a470a3aac6a1567c67acaf876e340b0e886d831e8001db75268677abb9131db7dd78fb62f51e964e09e1a3ef8e42870d41ad30fee120fe08ac6e483f4c9950c52d5e09280b39681b305a4e4d8dc5f3a16edeeec9ab283c9a91b094070f11fffa9206aae912add4eabbdbb27f182116cf9f63c4a5ae1c9cee0fe9388d8111a9830f712f8a36c1edc38a3d3cdbd9aa0c3921fdf1ff7f7e8dd68994105292377d3528d5bff5ceb65cd703570c8d7b3e9f7b043ededd5ed50fdfa1a0c00fece5442f34dc31cba05b6f52455570fe86b5f20c45ad5edcabf05b7091bf34bf99c23d2c6263757cfba68fa2876ba21dc715ad0f3f8e2aff3e0168fd492fa8c57021245686f992ab1d68b0a0f7856478e8ea4892d5affaf8234edf082dceb91a59a7614a86e79a1326d1cc03e3eccc9479215a325a417b069dc650d172cbe123b4ab28385cbe692168ba3d1f55a07e437658316e0c173266b437e34087930caefe23543050f0bfb73cb6d492c7415a30119650ed289ad31d9645ef645578cdf16bc0772c11f9b936083c722c5d21021f4ca8aa0d064b14a85223c3ffa6e1106e68807ecfec9e5ecb38ffe934304a2c385d8f58579450aae8c2125f5650f180ebe9b50efa990ba67fc78ddcae7a3c7b7ad1055849cbe5e1b3ca845341def08c55d659004e9abd5e2b51b5bc89ed731bb3d893be2ec4b1e592c8084d669504ff06ee7c0b921086532243daa564db53ac5f4daf2a4df3a0b3fa4a9dba843ee1f89d4b5a13027782daa9ca4b008625197d153b1e75046f24b81e2c85d5ec7c47713baae75124e5b61a1ec9572cf92db1aa2509ca7aaacb09f2a1319606cea37b8084643128dfcfdcac218cf743e3e1801318b5ab45fc9c4b7773d1f162bf9980d63232753c5945ff338f0fe8786f4952cd1709b92ebb7239ed41daeb4a8df92b6fedfb0876b46c9e5ee4250dde8d2f753b52042f9d43611c3ad776148b05071d748236b2a8d827ad159aff953accd8ba237c29ad1aa362b0d20455e444e65b4fcd375291020a839e1d2918861735d4a028f56ab03e2c7be3537b1bcf92daf30d01b879a2933e63a90849dfb6d399a23755969301b6577648aa4cf04caac85bd2317a6e4579b3f79ce5e8c8e827f544698f8af496424e47960264fbc8ff02775decfd670634a3f57ffbafaf439e612fbf9fc11583b01627c4a920d32da44ec635c46013f23cb2947d0cedf329b33027993246d32edd841a749e1b20a6a05470505fa0afbaa2c41c4330114910a24d2acdad605a9dd97d5c58b7a663bed1188ba7932dd70f4584ea05b0ff5b94e2f8caac308b743da8f6a6922918e0bf4cbc2a3d77f66fa24c9db912f311e574f7dda35082f1681b4d652ad9e8f6c809c054feed7e46e8abadcf0814e7e1daba45604706a8e196f945e96aa71b441d548debd3fbdc950c25adc30a116bd19fc1f02008c37f2677deb6b2e16c4b60b303873bd533084b7bb8fc40cd30fc9937a4cbbf6ffd4f9ee0630cc9afea90a4bc738dc9a5a0cd14613f0e6ddcb44ac38aef82ece202b5007b87f6f085b4eb01a700ab8f0110568ff0110be7498247d3adb2ac1fe70def612774150b5b5540240d364411466e163ebe519b7b273e9614260c698ac0f02ebb3f8acd5723c87d2faa1fd509a12e74022d2c6862e3ddf3ba39e9f83cb86ed9febfed30e9fc59018bd8f62f02c891997c0c542ead28076d0667213cadae134681514dadba8a39fcb3e4fdf8ec756afd0988a87466e3ef234d3681a19b2071843e1abdb4737fdcd8ca5dcdcc638c7378cc663197a57798cb3c988964507899985bf8ffd0e21a56dea22d3177ba23e2266197adc0cf945fd39112a78cb29b53357a11ed6b289c9b9a7d23e129eadf91ee577b82e525ec77904f233be3289926684fa28d12fc2022e036f80fb7657f09371845e2a52ccc1f7bd339b33f9ec315e026133305927ecb353145a368aaa55f7e6c1d971a13f11617bd62f9dd95a0a004d1971e6c1ce09b56217f8b1ac0f42e94915afea4a512354be10e4b930381a9345d94b33494e5b85b7dd24ea746aa2465c24d418c96fd2f113c433f0a2f703c508c0de7fca40dc85a9e0bc5bd116a5dd729acc07755b2931282363f5f137fc94a868beeb65df50953dcb1d71ff3cd5c96e54d556339dc9ece533241425b27effcdfafbb6235a8f2525af88df44b2c3f28bd8d1eac16e33b2dc678a39215b740d140a0db1d50f507c24670f14e19568254abd76432ce4597b036555f56dc4b9da4b7e25b7bc7274c4bc43bd270132f9ac537420d473d3ffc9233bd68b6a63e2352328176d6e6fc9872c0c0fcddee5daaef2c2c5e691076789ae1031ad05b0efc795a101e5c59248c32256790c2bb249d0213cc8fd5596367da93fd5e71f2846d84fc54cba0bd18c74121d7d8a1b1679fc81e5075988b5f5cf62f784b2e1f4e4fdc4b34b4b5b11a2634934f9ed246d9f2c95c603dca15e9697bd844f95ef8fc2da615ba3b79e48cb58e02f81affb058030a46b418a31a17beef0d4cae0cf6d312b449c9ad892d881278457a41b3325895af832efab88c7480c1c986b8b7094544e16237068feaeb4b0541645277dc88813939bff8318581133ae1f90a5e05d1a88bf57a462de314cf41eb0411ce8ae879ab1fb865026548d4d3dffc79718c97b986796f0ef2368e6e94059522aa04a6c8c13602dc98c6a81e83e35051f2c58579ba8124de7680483bf719707c2efc2bf74024868fe58fa2a32535d95548999c0a33850ba79aef96ff558406a9813e3346207c1b1bc4eff17b4bbdb5f32956911e999217ce3a3af9e65dbfed44e42691f9e64afd139944fdc1b4e4d6bff7831dd19fd8e840798d19bdf0086789047c89be8baff88d6951d742e3d24f3b9261f7341cf79fa6d2fab1342cd5b86eb402e5981d3ec6956be6c56ae2a84e2b46d187afba8a568947d205ac8a7419693d9d82e67c9197e882e58c98f03d4ca4271f32d3da21c6c31fee7ab5f2e0a7ba57816367fb09b616d65a960db07f0f57fa96b70b343afd85faaec22adc9df24d9e6755715fee8cce70107251756dae5e347971e34e2ce0a13a6ab602c6a8b611bf0ea437df4da957d2370d4a437c9503c446c919a849691b66c2205247e29949b12477fc7eb1fc86762775809c1e3f2a741ea481e1884e6425cf683e1ccf6aee1fca9166c560e927d4cdfc6d3583d902cde257051a0259bcf626435ce64a21874439905444079e123dc89a5ab7118c4947ae8e76687ebfbf8db96d81a485d4d1854b9b52a34dad15e5efeca3c9a5fc611db7cc490b706138dc420906b861ed60648f9577e34dbd57adb61e3ca60e081ac1f8dfd826866e42fac61099b9ccda22c56a32590fd51fc19606924556adc94e289c986be79e8612c9a385840ac5ac5a034480377d19f412bc9fe3896a2e7be236f94b2ab5c1f70512d3db07146c3d1b2742ebfa81fc6fc5186f942cdc968caadbb4c3a2d760a91316f0384bbaaab0008d082a695806a5a90ffd47e0000a948d5f391e8e3bb40bd88e08f288e4f0fb042ef0a331b3c91552579be5549cc52c9ba540b798d16966feb006570d2b867531fa71bb77ced15e379298a04cbc705393a8f47f9ae42e29d53e5aa6cb267707ac840b174634bcb656b4e6a635d6e727375a5c26ac83d3145e1396a9608b4fec8d8225e2f4aa361a4ab61ccd890d7234ce016dee5b6b96e8c509434fd8c19c9bdde0bd211dcebcd5cfed86c4910a81f90477c7777e48bb165cbc35132c6d07099fee1f76368f0dfc78c68310ba86566a99acf043bdf9b59685bd112041e0883220d247978410e93c018d4179645c93a3b577ff861511881277fd7dec9fd265ef5d83bd551a3e8832285f7b2dd4fd362e52cda16e0b7f2899f0299bd66a96ce7b4014aaf8e3e7427b8a335187fe3e3e8cc55eb305734a974fb24697c51a730d8a5d07d9c8450a70277987b863c3942fc73c7fcf9778f4d682261022c577a942e46d53e4273c97d5225a9bc60f6a192bc2b1ff85a41803d02550c78b86834394d4a9366e24bbd727c36c5a0b13a9f12ebb1632eabdb4d0978f94f960809e7fb1b51645c045b2f61d8ef82a800eb47231818eda6470377d9b4047d417141624c4c0c9909f3c9a0eb75ed4aa5f59311d1e6b8935c617e9a5df958e1ca2ccc6eebf5a3a8a4d8c673e28cb425978b1899226b91da10278660a799a88d4f165a8f71877065232bdb9f91c5bd827cf0a82532ad75a0eb12801cd5df9d6e6a31c32f341862631edb343050dcae2f873d26e56a1e2f9d1df1641a1c1ce0973359f76143d8e38913ec84e349f081eaaa388cd1a4f2e006d8f1a39035af5eb314211d80c96178177393e88b5998ddb4a8b6f525550d441d7c608a5084c2463baf204b0cd37ae4cd8d0f9930958c81b1c4bc0ddd63ff95b620839cb69989dbd29f9109b56dd85228c7dd04f4d6400951a020a16a2296beeae7694e05d5eb483031c86881190c7948de5739cb846c1c36a68bfb24d4ddbe0808553644817bfda373cd90638c408ce46c88e712eb1561e880213ab00bdcd6036f8bbb766c9b12db77d6d3f4dac8693b41c2450885b47b7a3c4b22318f0476004beb63d84901b1337b0942dbfbdbd544373bdc4d6323e143bf69ec7db6351a4cde78d86a25d034a8ffa6b75b1044fca09590fda4067b07687d57da2d3e7bc2195b29733c7dcf64e701033a051949db9df0f79bc70b8a8861d9214488dcf68a2b25bf7e0ef40c5a03bba3ee7566e130bc2b19eaad519300880c0a0b0685c12c33080c40433d5d8d558ac3567839df9eefea7e2bcf60db5f56d874277ba0c865e2026e75dc4f499d8061c4c0c39509573a0157ebcacc21e12b8d33b37a7184107e87fb4ab2ab9c568ec165531dca7412e15d228c3d866d4b57df5793ac1c73b6216b8b543789ef2ed6fe525399e8444e501cbbbf9a9b3167c27968ff02e4fe8eb091e18da5ce133b353fa88441353d5a6d9d00a2e08f22f804c27550e864266302bc0fda0d8ff58aba2aed592c0e3b425b5319335519f09ecb4f77c7215496963861fb2b998375bc15257cf54083b176b3b1f73811ae066d4dc0489597ff19e3ca9991ca1a3a2801eb3b281e6d1c5d3a5695b02647c8db61eed686c0a7949ec5a3efe6a6ce671e3773e5c5a7d0d83db99b9221673074d0d7d6c5c4c45d3afed620be3e7f241b40d30198ddbfc6374d73ae4b904355964c15f02c3349e40713fe623eaee27312dd1c84f5d9cf6b2dbe9c74459d04c68412f85987ff2539a3300e3b77d9191c92f2ec41cf4934ae334719bc9c3059def02a370a428d664eaf00810e62364b94b636176ab028a700faaee469510f99671abde43ff5688f55dfc83a1a0a34f106ff17371a775f8d551b560549064fc701e7f80c0e68b4f8ec01baf4998c110fa60e0c4fc854a33f1e4c7522e77cbeed0fbeb624a4249cedf168873d2a33c2f413d2e70daff3ff3993d9b1ffffc8ce4b6ce107a4130a5a2cccd50b978f1da1edea546c0bb4a289266557b238c03626e7bbd54991ec983b9c5e5c7d822073400f2e68b693a918e0c08e8b29bba4a1d9240cda9ee11a59b38d88d18711cb7c1b69e0dd26077ce54ebb380f2d9e2de2e4c2308f4ae97f882c6b4a7a90ca80ad0f06a9321a8d7696df079c0407557ec6c279b47ff64161565d8e59f5fbbe48e7edab281de8d340bc6e2d9aa216a66aa6af416e4797cebb2edea9939194297fe6fa15243eac9524d5d2c465c812cf4dba227817b775150d14f5e1037676b64a78f5a88b9345e723ed21344739442e4dd0428cfe923fe7a9746d1b56fd02922ef1ba77d58abf3cd094a0ee53172c297e965e884b13a744f16b75c3189930feeafa6e5427219a9b04602cc2565b682ebf0fc88117f481172dc1e5da93207195f392f27eeff9cb40cd5f300a60bcba9497a8125c2de91a2a2d13787e9376a41945a6ab34a82a696b6e2ae3f9420999444ab03313abb347517efd9eb79e766d404312432620ab589c41889c7eece00e54f504d2c562f79bf45aa440de446da1e3e52e3eb83dfd1303f66c73aa72645e7cf1bfe6f9b0ce83ba655c5ed52ddf9b888bb7637d11bc060c70ec8d8ee954537a552e4a1da7cfdac3231176d2736ff79549a66c33b7195c1a7f5142203a481505154c7b6b45f555c47fc802b7300bdec15d31ca27cacafafb24ff8a530597370c95943eb89a852f9a924ee714fbcc968e50d139213084ebde1651c6d5bca222a537a018599c7f15c5b8bf514a520561339b003831e8d879e3320be233d8e8e77115dc695f279f64654a73b2837987bfb4704165afffe2f21d0dd207532c8b210f1af821e41870acb557ee0af0c64c68e4dfb12f42f8331160c3d7687bf233f245d110e3481f6203355195736d1ba4d9b4ff1c43295947bcc6c51128f584bb9094e98ff8557667cffc4199deb466939597243026420cd3d065793690dff879fb0ad8821d14db70bc765b72df4fe385ee883f9a77b74ae133e07c8675e2c3e19c22169ce270e287b9769474711b1bbbb9ab2723db9306087abfc710b4355283597b8a243eafa8adc722419671a938bb5def5d52a835c2dc38f3cdcc1cdc71fa43a29377839a5175d901e2c51a796a70a430a2f013497382ae59dae0a0d3148f71a5a7509b42f925c69a0c4d08e2624fc730612c22b1486a33899332da2f2a8049d76a6ea64c5f1001babcaed2041d56eda7e117b1bfe33e005d63ac94e8934b39763cac34240235172821898c1f2612b6ba528c254f61646eccecfe73eefe73ff5683b346c13fe0a081c2ddd97347f16a80e600296f3519a89ad5b7ff48462a952b30ed485cb22c89b57c46cf3b33bf5197bbe9a139aa114ef357bdbf32e74446255f8e7511f4e2ca46871630d40d903740d18902a73fb9f411dd39581ced0b8949236f180108f4e6a555bb5e6020c03524525c87a5e56e7a103133e3e5c69346a81d07d0f07fd51d87e88259198729af735bf5b8dfd502f003dcdec0d1ca06d5a993ae0f34a67724e5807e4f9468516cde7e899d5e990aa21b40952758385b3686445f2a14b412d2862e3caf17a1a7be5e5dd8b00860213824107fe9fcdff66fe2ffde77dd4ca0bd9c5c0684b567975daf88016a62a8d692962cc96a0b495b4eaaf214817ce1f7c3d60db7d273ab2aa6398cf5b391f6df9ce532c79a069e982ec48a487b54f9cdb6bc24cfef075f3e9818deb6ddad9811c7f48959be12cd5f9979ef7491c42ccdd374e7a3f40126e7af04c76b1a71a3452f49329e18065cdfc683f1cf495d2684b87297954f9b63793cd71d6637d42558f940bc3a46c3761bc31414977e96030f4c2ba9b971429cb576c56d4d1058dad1ffb0fd80a6554294cebea9cbd97abd967364c94c5cdd895774c7c71c48f74a270bab7b1aa5fa9e282432d3bfb17b3e3c4f99b6c375092f567660469ccac1d7acf0f6417779fd945dcb51aca01a01f5f183d6632bba9f3c1ff1c5b95a1a09f43def59a420ba9486f7c4131d054b0de89ad1247e8528813d5c2ae565225a7c26adde8da9c0905733ef0737a9310292df7b4d938a4b02a48d5c8ca3c3530df6e427c023240748df930d9839f0d14fa6a3e50ffd5cf4cb2f9fea8a2c0f64779a92f2adf52632a82dca00f5cf425ced6b60f5ad8a8eb985be7aac8087efffd1d7ac92050c34fc2690661cdf1d9c2125da59f3cec3f5c527c33feb32e1e5e2e0e9e4e212e91b660ddf8c429295baf181cea38ea6a6f9afb2ece0f071b3f8e162665fa09113c0d70670f2ac73ec4a830962d1706c240cc49933c368b2606e2d46ff52707e5e6814dad56c5578c53a16460a8186d986599561f92e6e74d441660574d359ee19ab8f6e7fdd9cdfaa9e451167b41f61ca4bc70c21f76943b4b65421c6d97bf29a43f939abaf9bbd30357d02c126b877729ea608557948b9173666d135a4447e1802c7cbd708109ad0f799158a2f2341603e64e09a273ff1035a18bc52d33a5d6d1d2311c19e998ca8f2d9b4f8e8e7f195c3e99da5ee38c53a7d8813a0841528eb406afd67d3ca7ca78220ab2ef9c5d0e7338caf8ee1b646fc7ffd69b07d5a631b9a78b04b46594b43e354523e332c32e576fd93cf9f30307992cd6e82894b827228d5a725b6259502491623145c043006023b08469393f1be0d4d67e9c24012038b0210e1716bd2cecba77ff712b813cba5d31b4a49186eea2ef1d7727e388aaf51d3e8405e21234593eb798ce8b852a76fd69a223fe2fcb6e8d2deed8909839c1159e07319095ee8635854ab166226f9a3bd4eca9a57f0c1ca97e19003773eb7211ad2ccdf21b24b042c7f96d9eeb9b21acfb4c01f868805c1887b16ba32a7ffe7f923b594550f7eba9731afcf268e841b8c10f0a15c5393a2802ab1fe6a81fdd6f931d6694b90e0cb6400e9b7c09c0ee679174546f32854189dd553794811604da3749ca4ff897efda61c430a21120dc01f946417f847c4f4c5c98a05ee2d68d925419646c36209d6cab86a9eebf72775713229decefcf04e1f3043ec02cfdb955d0ec4e0c0235549212dd484b36f7f0431f1c378cc0eaa61f8bca5f3722c1dcc4bce9f756c65e8b5e6dacd416af083ef19d9f51e24a6f687897aafa59962e01a81f15a3d396ff0abc3b31ef6af5ed70b5836a273eba17123e7243719c299bfd7c740e75493af5fc730f06077b4f3ab42ad707b4b2d3afb2ce6d349060090b1f70282890f481ebc05a10b0e64702b5adfbed9d4360d4becf84980c7fe439239fa70f429dea9a07aeb07392ed5a28120dc1d7c270a4a20b4162c305420e560f352ba2c414f9fbe3d313fe8d8633f03f0b3194bb08b96195c412cdd8224488cc46b453387fbee03d34dadc44282df9ce401430cd6063e27357e6409bcbcf90d9a165ef5690d228a8b1999e1405115a8db719e10107cfbf0a15d60136f3571e18a81110d0e350c76eb7cd93038b32cabb54c1b06b7354587523be7849916d35ac2a02b5655c6d7c3d38b3c8039362a9db10842359df0ee07aa914b235b52780ff2dba6965f00b55a2f51b1a0b4e44b465273311bd7349f4d001dca2d7fa962485013a55538f1ee9a93ce6c41a93b93a239ade6ef7c7b8971efd86d665c53e9797b48c69d47f16692c968354aad0447bcc2dfe94d0fc9275fcf6f0fb56cca074a32fd24a0953308429198a1ad612a7a1a4625b852cee5c6d8f45f33c87ffa5ce5baaf8f7a6a10cf895838938de854e337f9d10612f50004b5efb36c6abf874ed77bcf890bcccf554e96c983185cc2c4365a7c7229d3f2144af6ab47c9e6c31a4a4a54f2e16602ed028e087d19c513e0f9a7bd4e699183876e7093ca7570b3bde2b150d0a0c68994003924b955ca8ee1673b2ba3fd4b75a7de9607f7b72afcd92e2c9c2f13e67d409c2c74dd84df20cb849063bdf6b60e39702a98b064ec50d1e14da066d7c5d749fb0d21c9f6bf337489d3f22ad6c1042e409f4ad7ad8994ddb4e6e9a269756389a4d33d72cc8e330de278696268bbde892f9b48291e1b78e573066b5a19979e35d62c6562f175c14a7a27c33b0747323ea6972abff213ca9501f1841948b177e737e63e357451fbe81bbee58ce1137493c1eed3112f06d2a96c9f1cca32b879ffb0f78e2e94b6b5b3b1bca3a1a10d81f8e92922ca378a3885c3b229663e3f6a2f80403f71faeec6e9f3d9c0a5e0d4c08e419498543ec38574eaf53843c2e260f1ccc7d833639af7a3d04c0c038b0316875adfc54ecbc88283ef27e818e2b759f76869f968ff3d6d7da627f906912ba76dd156f80098484d792a64770c662b494ea3ac04acd8476ccf775de1ea15f3ba8d0dcbe97dbc14f65c235fa3f0b3767fb91a127403960c296e714b35b7f852404e3caa102750f317b254f03f3b8ff7370a5eaf2caad019786f761fdf5d687102a15ab567c14f957ff1ff0d776a5532cebb06f3203f1fef5bbb07921f1b54aca55daf93c3dfabd6500f2af08761cbe1fbe5dda3ae8b7c13668f5d06afcbe3cc474831ef0b8179fdf5d26a1394d54cd77598f9e064f8cd0d007243397e76b95f6ace5732822a18abdf697ab8254c5015271455f7a554dabb0a40f8835b23fd00427e2c64235316470edff22488ee777cb1255fcb5f491beb1be200102ba76cd2adae893b271af5c006fbcd2f426ad8ea77da45d597082c333f8a058b67b2d43b4dc43b42eac22edf97b147743e836dc4ade3efab2eb2d3d621a947ca05de22c052fffae5254693792e5d13a89eb3d21a0726cc06fe91af4f77f297fa8c232b0425ec023bf67cdc27a2188a89d567216d534ce34e919b4e1e2263974bb299836f18107dfd4dac4809d14df902960101b90291392b4ac315cfa46a6207732b989fa58ef9a201d9c889a15ead5971db6a9fa592f144c5f7329a4110baa86494b41d03f5f191db3f113e51c6120502e4d55508acef7f7cc8ad6c1a3616196940d709b6ab23ccc68e21b1df6f4efe4ccf26fdc1cc561a6e1abfddcce2e3f984a9dc4aed788f5f70e46fa3944427258f9018833ea3363dd81e8510488c1c7ed1e6d112228d345133aeed4cfcd6fa287985d098ff418ce2bda85bb08a98b5e61ac595a6c2bd694b64fa82082d6789eec8768f45fe473ef9488ea2649fdd6f9696f18cd0e77188347f31fa6d08159da91fde74255a761407011534b0cbc78e1d85664d233a9ea14430b7d687f260eb50db44bde792f81bc2768920aeb743b848bcdb2a94cc6512ffb6253948239bce131977e59046629513c3b8362ea74acb70c6639bdc9ba591cfe2ff3932a3062604decba8fb643e924ea7f3a118b0787dc90a070f5ab7d97a2be9438a348c5b8b9260d679b4695d79ca6cd041115271bfa9375f953f891f55d0681471a5692268996572484933dcb8148627b9194b1fc91a96862f11e96749b1f749b27505263124c0e4650681d6d737e8eb9fbab3ea75fe3a9cb9e185b5bb9c0b19894d4c6cfb9c5e793bd42325098bbb32daaaed54d4a55a796907e92418fb6d1c8ae35f8f43abdcb0643438ff8f22eba95f2d38aae6cf7a46d6371a17dece36ba149948c69eb69a3d891a280c048e4464c57761a6b8f0fa75da871d2b7da779e436a5d242b1ef9c3bca824b93aa51279fc34fe95e308ca69e19ad48c4b9e2a015736e68192dcb16479e2c02ae64ddbe4e6a18dcd117c6b8b0c70e455aeed647b0499d3a26bce3a5a9270d7888b7a59f970c5bd1e315369e62ddafa4bf4476dd3cc2809fec241ca7cd5fbb1aa621dc60d03ee59fd5d39d29b215629074e0f91eb50201b91eb0dcb2338898bf1e013d203b1c94d992b00783ee34ba3eb39081ab51ef15c55fc22249a11b10d4b896ebba423da158f8910aa8b6fa9248215366a9d6ebeb4716355727998887837eb223cf0f4f5e8ac02e896b127f8c9c8b5809bcbba528c8b4d7f04deda9d1d8aa5f8fcbc9b277f58a46730862d3645599e0c2a947d145da9c7e6f966b9f481f6ab23714f75642d0f212ca328b3adf4ebe5100c2f06a1130c6c848eb34e5dc0e6bbc930b3c846d7b365e8358cee895785246749d539288f48b828b3e6473542105357caa83226aaacf75142939ff85f73b3ab5d453fa3e9d7dbe65654a47a78c6a0d92bc8d7067ff318b1aa85bd90957203288be3fea990ecfd507f063846e17f06fe77efc0f169ba37e3e6210a7a13c4cc5b0451151567d4bbddd07c0962358dc4d3acfe92437cbf4446482ded43624194d188880182b02f4bdd73c4f0be5ffac88ed4b4487bd0ed5983a3b6506794001cfe00b7ce18d8fd13bbf3be68c80e48948dd7eb69df81d73c0c535e6fc754216511987c0b1bfd488ce6b0f697215bd4e83b037022f8fd5a06009df1965e6a2ef9dbd3e1127b4b0d6c7f493c51a62792c6e614a4ef726c842238a37599d72dab83878d1d78e1a2c02cbaa012a46a17a380d1a652e543d00652c45390eba0ffd0a133c689b20cfbd1e3f2508c67a752673eeb316f9d98db5c8073263cc245a58cd05bce39062ed1a852e6abab30bcdb0db4f12726bc35d567ec8bee988372edf4493c9a92ce4dd8bc43b6cced84d3f99ca8decf87be6c282ed915b7f721843e51d7667273c72cf11eba3e02bf7244b76dce26a2dc710e1107aebc82fd9497155a44edbc96c198356c6b572b52cafc0141b5481d633d635d55ed3344fb3c50c9fdcec92739f23f314efb18d25dabe352e7ed3c48b51b6811900f3028fc77e118723ec70fae7516301e633211132122036dcf2e18f5f1060d344e71189050c48767a26d00853baf90a77f11a9bdc13c8c66c461262b5974a3e449b899a31668fa58914e8be0dfab4db5dc72f61dadf996b303ae82144a570d297b579441b38c27ed6a57a77a9f637f595523e9a7cf68e158e31b44038c9374c744c5faa65366a22beb130d567befbd807885436378ad286208a4ce673fe2379b0242d53cdbba2411185302efb461b39b2aafcde23187c1a687dc276326d9f9d33fd3a339419f065a321c970d69b56c422e66d1668b694cb3127ce794e3a242ded556e5bc47072a5f36af558604719d51708a5e13d1dedc21d59cd6654f24643ff88730ac4d57b2bae4d162fff33be118cd5cdb154524d7cdd87d7f2996ca4454fe95e493d949a57eef73ee07e13bec227f79829a7bf0597811e0d03bab5fe94234b2270a1bd28e60ddeb0c763522f0cf128f92bdc551f18b1dbe5174dc3963b5ec82e12518adc9c56c7b221db9698b45231e9c92ab0feb5fe8e3434630e3087706d3560cda3c41a0b0857365aa354232ff41b0485bed895aa5dc259618c1280181af5b7223faf1eecf047cf9de1cc8ba78e2c4d7743b48ea1fd8fa119ce043057b802381d71c42457b4fa712ae03c46c66ef5ccd2bd2b1dad240a036283e0a510f5a45a3268a167dd5e581186230a15f44c12d9af7ccda51d97800c5c66ac48f0d37238dda90cf77a602e623012b1c176dfb1f7c5349afc5f2201c66dd2d7cc6b738401b135fd40b4ffadabeed8af45f4b9d26998b932063585f2b11d7f323ab9c3fc9162eb9e1797dd2eb0ce1f359dc3a284881d1468186018ab365cb4e0c8616c7970dd17df6960a41992b0faab0e7875c1490cba8a45baa4094d55c5a75536c5fc320742692db77e05d8c8a3409ed9bfe0b23ba9bb4c7df2f2110d7a070ad0a2cb20449946f9286d2f4c9d219d425258f7ebd2a469e1d67efaca90450e3d12cb58a44a095ef3d907b5f55edf42ab13bb46f9f747526b8c48e61d2700f9d85928dbbe49170e8359a488e186f11888817a65f5f87d8e0202b3b4024a338e23a7e20636e484428165fa01e7e6384b0e12b38d863c0d493d232d52f60664cc27c4050d79b0a3f3de6ed305af3d70636404e3b89dc3a05a639eb2683aeffb4ba87225186536f01ce4a25e3961401bf7d0aa70432e1eada05f51df26b20fc5db393173ae43daaeb10818f7f82f4450ccf10f246609ab861661fcb8908abcbbcda271df7bba98ccb269910159072e2ae7d4dea2724071d6261d7173ab19a7bec1ebe3b303497ab96afbd2126ab130472064f82213042986c57d453bb4220dac2a604e0e29eda0f227efc17794591eb09e244a0341b889c2d8de4cf2b3da005b4c55d835742fe1ea5578b0c007d6f8cd56d750e2c96e26ca25372227631aa37f43d8b2dd3316732783fd3d0d1ee667c9a96d190f70700f4c8bd94e18e02df4517e62eefd6feba8307ef98951946e13b870ba2948a9d24e737b3ff9fcfb932f25020b2204c9a2fdca31cc69858141a4074e82d5be72afa4c62a207e47e73ad847012e613a5374e1e138d858606dd14c8eb83c3d63816b2336a4a33210fe37ae7638f0efcd18779a1fe137daab07991f692c391ef725c05cb389f7aadea2f975b159dd5278bacf32bdadc3bfdd8d6b56740948b44f551624aea933f25ede417ac77bde2b6c0322586b57d541e25ece6941970549d781c7222bf8fb1fc54691cb44f82dfd5e6751e0dfef821c152341af7663d8b8c9c4608e16da8e9a2994ed650ce9edbb8a524f09c621ee6461c80019c5eab252cc9621b645a88ef207ac8b7113fd50f94d1f7827a4ccfbaca4db39a1a6f0c95fd1edf44f3bc4d197b03e5153efa5259bb5f8063a5f5f6362bff397ebcb7dc5b288820d20700f5b15f42178a10105e6ad5455a870355e7271c031a1a3fce349a1182354a90a6a69a44a82e0066db410d6c96bdc17f761a1228eea55982049d1407e58dddcd2a0a728a1c40aaac33292534e3f2ae93f310c92385932d9dbc782c74066a45638cfb6ddc225638126c4e41f9348ac3d5964fe14172a8a9b0b9e6d6ed477e4f3fb96d5d7b6de0762d4579098f1d6f69ef072bbc4f5b69f533e1150c3feed93fb593e5b6b4383bcc0fd6d27f38a4fa5d0a1a8faea22e02ce2b2e7ce953b1d5db4e22ada8467be2848fabc2378b05e77903a731c21a03eabfbec10310e9adeb4c637b38b425014c589f9561579de2e217dea377f41adee8e83803c056a4af6059aafb6a768761dc8479be3c4deff4907979c8ba6827b583f1a63e47a82721111bca04d494f9eca3c167a25564824698c283cc5d4218136b2d0034d1f8209799fa42e394af12262d7c2eacedaecf8f1099014dd658b2ac7f67d5d8298b673ac0cf588df714c926a4d734843ecab516d2c83ea7a24c830d0891f2c8857b2a86e338002ebe6aa7333ac9e6d93604bdcba52b7d3d784b4a43b5e13198b148bdbbf2dc4e33f93bc86cd0debb3ca6c8e1ea1394062a3dbd5774e33ab85d986fb552d4e8ee88d621dd76e6d4cd417d521ae22d9447733fa3e5aa2a3667c89b3797ad929be918e3b5dd5b2f7927458edfb796cc6d89295ba2e75f89b55a97e4fd6278fb092da10611e43daf0808723b0f0ca085a7f603c21fcf39bca667ee63d19812f72c8451abee3b3ede1835681c0e360467901c0eec147eeceeb8d60c014d481cdbf6cfd084048d237b577bf7e1255f8ee4734e02c4fa74228706b155ee8e02ba4cdbb8ee5565d3eb420ded705806825196685aa14362d4e514a966f28cc9a29d58dc4cbded5685a308a7a465ee69a24e5279a89d07873963b91c3aa110af45d018bb6b2fa3199c8e152fc0f743eac10e01961821a3e35c86376e174344135d9bb5e39c70aad549507334163bcae89fc124cec39c3b2d339687fdac7a16e2e62bd7953119f68cd9d6fe2d36ad996e15a313b9f2c0958f2086c8cdf6d2001b1af784fd305e8742f5fb71515c873210a32f4b1bef923de11e99ef79f7b952370702f18e9dafc555dd9f7a7a368e1ea8aded3a3fc540ae7742609a02ec6a2e34001b4c493b43c87e11894eca85499ce5e04a927c98b294caa7a9ed8b753ffb85219165c7d37c1044ff964b6a1fa67121108486cf873f6556050b2909f6b0b41acdcf2d6d7cef93765d5c97af8dffd9feed02f3898668bf19c0c5bef21f7e4d82b90419e879eb94b1ca7e099304a63400aa59bde487573a9ae72c868e09d56cf5681d5bd3e6544380ff8dee5fef707f3ff21ed2d2bed7e9ccfcf6179ae9af4b9576e6ac2bd5eed3ec338a3ed0dca4babaed4475cbafd111d73e41bc1a24a15711e0c27e0c2842b7359d308e464606610cf829fa9b438897dedefb24f008b9e3c385a4d2e21b845e7812a8d9d2bb48c062a5eac32f66929bdb9942b8bbecdef81244098f1cf9b17160d9e8083dc6ff6f1e217cf0a39d24339caefd938b1444dad49a60f847c4c69f7777b5f81fd4c842a0196fe5526609dd4ed4f78d3d9196fab52821aa9e45ad0dcac50a4b8473a09980eec4d478cd57ff75b821d49ab3a3aaf3f99436e3c5d6d07a31b41ab911456ad10b9803c41be5af814f5f666093b42624b9c7f0cb0e0619bbd21c26e0cb6ca6685efe45d6326f3658f93d591e220c1bfb5cd91065992371d67262609f4c7411c8c0e3e9c15fae78812844f393050e2aecb156967c668bc22247f8870fb883b354bd54ada195681bca950655e6fac8f205ba39ae863d08fd0ee77f4221a25b8068ce3d7ac528996ce3a5d447de5682a0a6fa1e354fe983d6bb740432ad176274f598a65601765e4279c817b44dcabd063123085e5eeb72fd91d01f765deb9e4b8cd54c21b6ddc593312c1b48929d5e0bf47f856ad30bd133ac0bac6511b342e0eb60c51ae3b51470eac54c7419ca9e3f7d9b6cb38fc8e3374cd595f0d356f73e8ca84b6ff06704ef020331c5f5a682e91a066f40d4e57eb12e3991f0b7261105e29f7fd2f7177a96e25863b814a39e326eaa4fc67bb6ed53e2471b66eb64b6aee52d88a9dd2694134a1f16bc91ffafd8f82e254573cf2e4eaa70a6a54c553d4b9b004c3d09c3ff58b61dfe1b2df4640f222a53fbcfce112589ff6d89daecdff8e07fd9d1aeaa8066f2613b1742da712a1e56f28255e3b73371894443ccd96fce693c26f1131fbfd2104ee0aee5b66eff05ea5e4246cbd49646517ab106bd26929a53b11c124e18f5babaf362d49dc3ef489dcf85abb93d699235f4b4f5ce7c0136e3ee378b0fb953ae093c905c3826db3048ac28f5a6b31cd559474651c081956766f4e1bdfb4cd93f52b4559cfa7a375c9f6b4861f1d859a3be9ee1db52ed3cf47d56aed6e49ff4cb7225279d06906c50609ec3160183d520aa07e5dc6cab597b55037e7aa36330e921290cf6ecf309fdbe6776adacc8b496c7b308b7be7c4d941a16445628016c5f0bbaea3a1acc09669ba7066717c320e0a0973b20104638bfb158c446473395999888abe93da09d2b8407ca1b05acaddc31fe9a973eb206e754b3dd7790ca1eda940a919a101508c2e73bff519a2a75917a94fa99c553354dcb19c00e5e29f366a00ddbdaa4e96c27c956f1e39416163761a78e6b0a41233f8ae99a8a88ab56702bbf1242d7653787f2543cfce411e5aa49b10e2b4ffc2e12ee12783a027c73b3ecd993f3ab080296ef9d025e507a1634de0244f07916ce83ab7cce0a2d76be805732f31d0b28eb42584bcc0b007c5e2145c4235779ee3803d052a8c9f86cae29a3a59c09f46fa2b18eae49cdb60678f8b7dcdab5416db526dad328a46f0fc1556607d3f4012ac42eaf940970e015c8a3d7676c2f42c6cfd49de53e92020d5867b2ed1e48aaf7e9db1d7c9422f0e935fd849244fee7c16b711181de472b76a0b6de7508fc5316ce10d0d95ad83c8f76a2b7785b1aedeab2535eab9bb09251de5811770443194c48de7a2a035b355846a79e1f187d6b37434502c85f434105e7b3129af4a052967941789a174bf0a5ea84afadfcd342e45aa8186b9bf8842f82b9e57ea83a69f97ba4d6630c3d04e67e8fbca2bbcaf263b84ed7749d7b5e597fab841c55e3dc5aa474f9f21125e8e20bb42b9bbbbc152d81074e0e48400399a65bc15caa82f257dfd1acb33c24ea395a09bad9aae8db220e1f1a4a4ed5cc934fafbe48b2bd77b167a733dd432fcae789f4cdb103a063dd9f82b05408e075e1a2e00cc58720d1b8761c98f2d201288f32486be078dab59353af41a98f441fe4d0352134cb8ebd64b064b5a046e410fafdeedf0340986178c3958cdff2b5fc565ba67f587b11afb93fbf37d5ab88661a5e223508d4d5854177fe394b97d0583a3863c94579949d8eb07e0ef5bef567e8b128d08e68ae68a9a6c566ea4c9c44d12cdddd5e4952318465c2e57d41811ab99e74130955af5d61fea1d77034bb2a1d5562729750fc196d138e6ced76ab642e591972224c0c5511525e483dab1f501741494ef147e151b66eac3c290760f173c61a1406746f4253a9d0ef325c27e17da3540f67ad764befaac3ff067e99057b4e3af5120213655c32e2826855b19f2707a01fd631ba96200938cf0e1c2b71879bc1a662ecbc9c90ad49ad5426cb82a7f1affc0657fe4eeccb604feb5b31345f93e71567b6ff23cca0e295f45c9d87877cb880ef508785f97f2d393f77798c16326c2de2e9d990c43d013f4ba2fc43b876f8081ef08b5450ddac6643649c11d988cd24ad3b5a2b56cf86d0e95586177b04bb86c81bd612f51948044119c7651515cd2129c6a31adc3b08aa42e921a826a75eae43c364a60abaaedfa1b18278e628a94be6259089efc79b26f4fc258045a7485812660f67abf23f49a08c5f06358c2a9a0df4842292f25daa372cb8702aacffe264ccf6577a900761806f53c560b622abfb7cbf4be1798aee28c98af0a5987685712a7cfb3087d351f70a8f575e78996489d82f3e9f2b1389dbba3cf40c809f830313b6f6dfa8fa9c10331315e9d17499f46481a539b02e143672faa06a8ae9802fccd9ed503a4077c40620dfbf018470ff53ff0459b3ffbcf6aa5fae995ae7c3d8a99042332722e53e8ac540041c61b871f2edae5630507db4b76776f66f4f3789b2697e1c16a11018390a782b44b2094e661c4ed7f9847e0b5541d6605e3b97e51892d80a803f250757491bd20b887e0b1b778e239de7ac016dedf42d782f8fdccbe5caba5571cf1be15a84771cd62f4fa34b9be82d3808118f095b0f124e564c3bef72787c13f16f6c4d76d8a6de3b2b0563b742ba4f9e14f6f20abb58ebffbb3a2ad86e1a1c7ffa6708e73f8fdefec3fc0beef67787bad3b86f631f3ca3b1fe3c2d901cabc8590062cf06ee57f4fd75e83b765e4120503cac3b7e3a6e7ea98d80e54a18336dca11edf45834fa7f6460050cd8975a67e67854dd07a88fd423b8cdccf4be8bd964eb18dbf99dea7891c6a023c2f19e9be4d49b1aedc9ba185c0dd3cb3762478adf182a1499c1c702b3feb707210dbb813fdc5287e1b915cffb0af9e5465b93f76a0995ca6dea7069f1ade3e6c770b723ea61138c9f00884db3b545ba496a85837ca8666ab0e070d79341b807099c3784a8858ba400acefee811df672165559097eab297aba2a081f033ce0c4c6666c27d75a4c017a9f827f0e813d6404dd3484da740e1a43cc8fab213032c2850312277543dbac5dbcc136bd89fe6a56e3512a840970775dcbc75ea62a8b2a6e7f0bdc2a2f1042fd3a33d1ff3d1cf2e7bd9ec53fadcf2417f4e28e42c29420834e74af3ced01ca38c5a3201ab79a4a6d20087d4087bfca1c7822bdaf649f8b09a2b087a480e7148a738bcc662a694b4f9e45a4c0417926cd826eff00df4cb580b324b141cd5b75374075e3b4da3e282836740b340e92bb4f3fca803d472f61a187884be13f351306b7e3d72b149102ba34310f983bc61d39b1440a03814c190eb8271c5da7e492e7c8f36e22d29fb44f327c64e4a005cec1e5965d15a2f05fb216fa78caedbcc503d507cde39860f275aaea7cdb9fd513253dc8145a8135d7a855775df1ff451defa0438e943917aa38e7d12225710f800ab7acfc2fd56067d028454b05742c9ca7127f329222b7b4c58d0b21b1dbc4d5274ddbc0a7fed985ba07a496052ba7a58d6890b04d5b95e62da56c1795ffae7cff32dfd1077fd1a0677bbccce3fb88a68fbc4e303bb8afe18f387e27e82712434e9744089f9460625d9379a4fee26e8c332b496fb90acf3feb2f2d4d2f53da9c9ee5b91655c3307f1c212413ac012e66d976d8f8bfebd3268eda18d5aceea9944a731004a4766f47e51a814e592084e6558381fc91e786c4950a026bc663037f99b7bc3e25c4e17e5af329b3e473588a79faf6cbd031246b6727942d9a76eb7ebf97dc93f3bd04f1dd7aee066859f690957ed7b7a56ecb03567aa3dac0ca52d525bfc9a73bd7e7efdaaba417ca37f2066c7798935ecb3445f28a5d2b1ff5d5be32263f1c605d9f09bc3b804104803451d9ece7da89887aaaeefb24d4fe207d19b1d6ccb51b483c1d2761d6c8159102e141679f2629b5840fe7096e5e5ff0971862e0476b84cb7ffb007b5abadc181d22b0cffc2422367c2e7fbfef31990d04cb85989d9e52a51ceec0f647cdfa2443ff41742fab0f7edb4917b249dbd95a22a9dc8f09b32feb3852ef73bbf6ff8e1a56ce4f52290360f15313f1d906cb4b927d86da34b0f14542bbbd6d6910cb8501b85f0ed6e7191c379c9ec3e53a5ba19411ff4626d4045ae9e8bd79ad84c36d479f4c08bfe1ff7610def0e1be64c37a14bbfdbbd07788556a8e2ae4b91df3321b7c436a2264e50eb8c33aab061afa926e34fce3e55fbdf536acd674a8838b71c615a81ac45ef056eb3a19e7071416238afedb9d05d7a82996ebcf65a34ca9b075f23a233834c897b566760131ca6c852732f8c91cb48b438e75302fc34442f6cf9640c09c63831dba898a06b8668406b2e61a44fdb0b02963892013a63aa75f229c8220fbbb8eb28b6ed4bc92e45d0780c8d893a6d4249e472e436ea976d07ac0558d5b911e1e8b92941e805d06aacc364506dae48593aa70aa92c4879f4d18352dc3d9d7950f5dd89cecb2e40287ac834778f02262ff1f75b1edfb00faf4ea3657ceb32030fe93151f94c43776cdc0c900af13cbe609160122ab3e03e052c9f1d20a7202b5a2317124465e0ee64e146f642697a418eb3c782fb8ed95a2f0406a434fb90b63f6c185442f58442098bc6718119bebbaf0f25cf0ca0390a038928bb8d7ec677edd86eee97fc51708df7b5b9b37438dba2a4536bdcd2195055446df67e9352bd3e6ca27c1133209ee6c5181d1bb48795380a0a112eb76e1d808c9f842a3c39ca86c825d8fd1650a3b3243b783867cffd0e7600cbabee65ed8f00853b7bddaf7bace1ab3e43372726845c3360b3cffa22a627156f990343cf8dae22a858e89b5ee8f38849c64e694ece072d96d4be7556d81267bb6bf784b21c7ee9e5d0c49a1cb962ad7f421736de126307560af5f4c59e27eb169acda1ed50c0a28a92a52acb10661ba5381a8ad0cfe0ee1b863d90bf5b56410ef4509f78f961a422b7f4c27a54a5f8e9805443598f758e10750f530016a185c1036e083c4704c10689222a8591aea04f5bd0e9a40ecfa1a77b80623e3a52cb2cfcfb8e379c879b0e984c9a5bd669c56db225baf12fa3772ce3a6fb877f5c1bd8abcb2fc2028b00f1986eefe0c285845f1f6f2f7aca6f9928c6411e7871a96f82d0c8615b5b36b53ff3ebdb2f7d48cb01053c5410a0b572aa9cba63240e00184b8c28d88e9134c530920b073206736dc8799e7350fb54b2cb642d9aecb1536569fc3861614ce4a59754a8086f79bb8fab6f4aff53e7af586d859886b972379d2ab0cabc7dea2457bf33d8f80b41befcf2b7c6746f30ed783288b34382ea93bdad7ead4b789c39ae4584e1a3bb4063a3c315d43d5a982300b75ba7a3db1bea774b0e5cad8ded848d32b797644db92b3dd79bae3b8efdd589d20747b32a0fb0c4361def315a2df0612dcbac7090fe8652159f49557564b9066ed79367f7bc939d15a2f32ee9ab66ae89192f512f2552236b59ea5605bae2fffd8d46603405dde357f8274a22b347b5f29e82dcc4a28b1d3cce62639a5d0eb1a35b19ac060ca8835435b5d63016187e8ee9e1a2ac66893db1de01ee988cba67f9327c34cf37b61b9b8e12b2d7ca3ee65a27bc7d2ea07192cb9a3e119fa892addfe3f19dcf4a7449a4e3269604cb19705f2586b8b1ff3cbf6deda4bb5698f445ce5ad4a6ceee077a0332b3efca011819a8535c6c06dd102237f31d9e54b6dc931284ef810edc2fe7d5e4b02bc5e2789dba3af0c677cd0973a575e61ca65347adb645829c03cadbd26133863777be822b7b7fbc577667fee52fb946006234006f3392ab539dcb83dd1d6b88a025b45cb30a6ee05accf87d6c4650747e2d00c72ae701399adaf04699eab36c1c24e40ea93337cf3c0df1cc4d75c09c3e693880093ddb91ed71f857b96e305454ab6e7ad90e4735be9fb9a7d6a52ebf80dfea51074de4c1f69ac02daecf5aa23d56a9171c473f72ed986d8df592fbd4f7cb7f95581f450f81f76932eb184c7df530d294884d657ff061361b6cfc2b79dcbe366c9d9ea8f7680ef394bb40df90f2fff36184077ef7890a372c75d1ed49f5e4d2b3322c96f9fe2b5e29d72484c68e6a44ac5faa3abbb8c8b4253adb54e5b0990e034d44943304545e68baea0390ac6926884e50308110efd58339e6f0ced739be76cacffa9d6bb7ec0c8e018a5adab0680dcf7278e22ab02247f59773e59b140a94b7ae0b5fb1e2ac4c0726cab0c823bb52714e4243b2b0f92c9a5bfdbf451192507f546a636da5b3643f9b60029f846383c40c4fa553b52a8115f045f742ab15750daf7155cb9482227e9044cbb05881723a0052e34a125d2e93feb0258a276a599c5e8aa0c7cb535d7a65c27dbe70b8d5a3b66c497b490af8839b47429be48b3ed153239b88b3f6fb667558b118730fa1370116d5d1d8af8eac33c043162412e8b43d421e3e760841402c63271c6534a4de8462f33a4150c01afb12b596d266d7d4968af93baaee277e7e60ed1e9ea95af902970102b9029239a5f5aad337027262f6021ed08d5aa74b965b73c2fd3e2410fd699550fb430df8ad2ec843054149fc092dd22b5a07ddfbe09f9de699549e91463bfc53acf067dd98d536097318a48de68676328953ad9c6f5c176bae85cc30325126b4425d819491156db46dcaa9e2525c417035c84a9a30b68dc410d532d0b99e74996689bd9f9c939ca157fd3dca86011be6b66ed4c9299a5312ca1aa9dea1ac69db82c1b3eb87eb0cd6b0c86ecb3f7d36c51d54e19d4ea609994789d1c5a6a2acbe49e0fb481efb04fe83239b532889d14ee6159cc291a071fdd1a7cbda8070a5991ed1942ab18c036bd3b8fbb357f404cdc3f1b90cbf826ce132dda919d82c688f3aa917d1b99167753a69517c210f72db8ebcc3958e4057e1fe97ece12d6ec5d1b8dd993c2c08d7be13cbdca5f681bc703866757a9ec65b8ccc87a39ff89060eeef23e8b65d43884c662470f64e04ac9a952c48772f199a756553d95d7673d51358cb76d462208135a60da08fde8c17bacb9b26847a7ec52edf44a970c223527c42a0c027aa9cce38b7e86efffd74f0eebb495f168efb2411fc3577acfe2a6d5eba8ec5d554f964d91dd842fce8c444ca56f44897d9852890f6c695a97036988f0e6fe6bc3a170c037b9b44182e1235b4e517db14222a61bc2413aedb10d0d309a48e9e752ddc5dcb9dc4365a770212c0ea283f3ca121829098a21e2f337ac40f0ee95d33f05c5b97b8a2df2fde98534c42cb8300609e9bab26d11722c96cb65d2f2a2ba8c16c873e8090186d44f63ffd94a0e53ff1af4de4040144df591484e5906099ae572182b8f2e228e45a629597edb41dfdc5e76354ac1acdf7f37d097ea3f79b1582fd354ab7eb52f67e718426233338f8dc3cffb563f061a2d57b9e17fcf3984e760950ab6da1060a4c7bdb9c844fe4b420f91eb50202b91eb01bf2013c2cb73a89cfd0f4e3bb14669e9bb644fd77e4cd3a6e8a472e1eabe7d91d6b5cf268e9614dd6892cae32420bd4f2cc1c541744aec07f17f4d8df9058b47f2f3c744ee7db041922ff119097744edcbe406719c81d00a9e62fb99d62801663ecc921d59299a09088d879113933ecc33fc92b909f0aad7df11382c58a3f6cc756d099b0325e47710ca8f42fd5b2e2597129c319d9dd448013d9e2a9ed3268938383b9fc10219b8715edd0d5327f421a9d1cb432233fd022eb5f6f0cd0c3c76aed709fce96890313cc77d5dae1782c5d195471f90c6a1bbef363b0a4f313363343fa96816ca8719f7d7b1eee78e6043c2f20983e7546ead48d67d2e19bbfb0eb3c47668cb2adcb517d87d547343912357471640140740345322a8a64032cfc71e6e8805e40be157d24f92a2306c6862354727afef7fe5162d70905924d1bf04bdcfab2931f2af90c568ff4a40b826e39938030a02f0986c34e156676b5eeb19f3da3c62f8b6effa9a94d7007a39c3f9436bd8092d226749807f592901e482b1e4091833c26bc1a1f73566fc5b0942e502b42e77f185c54126227adfc50219fc6387703bcfbaea9182b7954c863b072484202a5813ebe84e4e82f608af5c9f2dff8e3808d2c2b942b322bafd210c1dfed3466b27348bc0716164b395a18f1a448e0df423a2173a348f6473de4d5d30e887182bcff3fbab30baf431385af28446cdda97a5df948ec1e9018b594669b5fccc1084aaa6deb0e2d4de40d72e95e186965f88c939df1934eee4747a328740d131f9d621bf978e8bb252205113286fc62cf62e42182385ef975178f6b64ef5c646e7c59026172a210c6318988a1a324ccaca2b29e7fb5822e2ece0286b1312e87b302e90c2dfaa0ce19a6cedbe6ac9dbd63449e4e2ecc9f8857186392692224c5d41ddccf2fa91c71e0954d4c8260aa232e8316d85680310b06495c9f8beebb9158d65dda809280d3e817a20d34ba6e3f1eff09df088d9da0dc53425699d4332285339623d1710457394db45aa283b2aacfe6ab3288802017773867f078095d460b71f3ba5aa1acd47a6247027a29d35949717cf4529b3c1d75100a75f0b3b811f18e53856eb2ef6ee2f985ff2ba94b37f83d3e7cc56783a9c48cce6d990c169f68527d3bb362bc67071fad67eded4f1f9bffdd13964aa51bf005942039e9f0e7732da9174b98e23f88e0827868247c546172e57ba7fee064906d71192506198a286f573dcfaa486bc040a1044f3fa254b3e54d863e23811a422115a72c7139c79a5bd24451d564d97e5fce5960c77b9c48b0e3d8fc7a8ec0c6ce3f5aeeee76ca24635eca2bc69aa94c11ef75ac9daae1e4e0a69b1b577da0771e18c818bc47f5d2886487d4f0a4c3e7bdb4fe77eef6334dd43d2bdb88ebe792f79033538abb0ed254071894b33518dec22ac641b683b5087eb767245ce230b195f24b381dbbe1aced6421d4a9babf1dd58532e1ea51c5c5f38705ed1baa23266f8a335c90fb82761639423adea8cc7a057e407d9229d969573bc5b134dfcc56b58bd4eb71bca167006ca845e4c411a8466a9c474a76ed15a7c5ac9327af9256e60a8b44fec9730ad9876d5877e844a3db9bd2e4e3a3dc3b89b3ce1bb9d9e5c6a06c2863e83f4bffdae8cb84b627de94c24b6c5409138367003a6f73ef764c0e594274917d3434ad7e707af3b3ff5b653fdb5021df4ece024246ee28f8fc0adae12383073f6ee6f4120c71e6ee60fe0ad892147cc4d3e8322d0ee42c22876019cc3eb934899f3fd0dc73cd0eecd10c85512387a85cdfdd91f41c1f471eb03c802aab3ebd871e7d70c24d21300a4c13bbb35d216b56cf3f85b3186e514be1038feea8c72df66fcd0f0c00644698f947f0c939e7ad59a7b5da04c2d21d82a4948e3377d26e4e6d0c8bdead381998d809d5141b7e970cc8d0fc4a9bd0ee882fcb9b1fa2fa247113502808a4daad8919aa8fc89bfd08ca9492e334b1be991fe0688695997cb00ca6c1e1220a501589e2b985a2c42fed1f3618da2dcf5f2a5fdf1669a45b13059ebad6331ae6c03e29e82dcc1913d5d52de4caad60cb02669c7c5fd1fb4ba50f46da8eb0b0556afeb933796f0dc2007112c8217ce83f262799633bf01fef6ece653a7d711945d34c260557372060edfc3fa5d1aa448c7578d8005c507c83f33a94526bf8accdcef813dbb0645bfb48d4559bd64477a4f6e9433171f4ba4c1314408777cdd35196e0c3f98318c5e4a16533b80318920dbfd5046b06bd5f3badbc9a0010f6a0fe3fccf36ed60a9570125b40a02a74b76c1ffa5cd367620a0c972f47fff1408537ac54f78dca8fef657dde6f5aa548bc5d3801933d08c25bbc11828d3ed768b2e654ad5bc871eecc4e06399f5583505c68ccc7d996c546d0c01568031df1f0133cd0c23d3fc769538d0314c0132951011e6675af581ede93f896b4375b4e5e2b8b344e3e4b7fecb5c0ffc7ef37067db0589d04320f2471d2bca3667ddc8b164bc30089c19d8d72560fd302bd30ea8cf13638f9cdfcb6d0572fe7abe67638a38ff39d98af596582f05e73392ffde25e5ffc94539ed09cf46198f4ff9b17862421a73d3ebe843c56ebb8f6839a93391b19d8fbd4966c246dc8d7fa0c9c80df5e012f9f20899b0807590c761e6461728f0854e4f93bd560e1e6e122f38dbe39fd56057df252b3008a1d5bfcaf9ed78ca148b92143e90b5861b333e22ebdc977f88049a8bf7644e67b9cdcc6bc1ea382dad3ad758672c37eb917b0a4c0a21389b64081e0d41439257fc36682d16e6fbe5dc2b0d91af53c728934551df043f5aa7c1570eb89340f31fc833c9ee4a82aa682c0a0aa38b3646bc15f406a13b62d1e85c2362423b821b711ac078a008c21a5a6f4f924a4a49cbddad8b4d32058b1ffbeb3e7075d5ea65decd04aa4d3efcfaeca0443e640ffa58e5d1a24ec45c3b386db85b013a71b615ab3918195ac90b5fd41ee4dd4eb39447fdf8b215aaecac21ed57c7172869f2acec1611f4112cbf0d5f2e5c91509959b8e5afa37ce1a0a41163a98290efd11036cb34afe576b5e7c5a38b957532259cf08e7ec6ce15c39d8183795de0c8ea49b79d5483713570faffb11b4b7151c58104ac0d7d422fb6acbb8c0bbe7662d3b458d467f495e3eb1db8e2d229118a40e5b892b867373818d6b2626bbf898c7cffd6206d6d65a11419c342093df5d210a7cc0de27178b7976a6b96f9fd9efb9f5e6b363d1a4a8189d7bdce755587f0737eca79cfe8d98781fa9fbda5ac2ee52cadc883099eff5303031f162bef611677231b52f8a258e2fc5084c1c7259e72c1fab8461abd300b6a3cfeca072b1b6db3dd0014289a6af5dbeafeec5b29c0c53594432a209acabc8455caa64d29c89960ef0724c640a2d83a6f5911f10b5d038b76787fa721f7531153edc95100e56f632666533f78cbbd909f7699af17be24ed0bdb7d507f0754c21df9e4c1a0e90d395984e7ffdb33adc5899d3294de83921d13057d48a103a5134a852818f52dfe9b558af30efa26e21b023047404b9080d01b5d7f62465c2a865d1bbdda28b4461089a029cdca6dcc1befcdb9d17927fca1569b3fc86c3339837b268f0d5e6aa35e7b93b5650065d7b188ca2933516c00733db14f6efb0f4947be5923dced3134fc2fb65a08d575d801e53fe864b234c45959e26b293813b5f604b5d2b543af984104148c4d2f2b5fce466c5360dae2582ba1875d77a90df8253d1c9e37c7c78b120431786ee765432e0e53ddaba987db8998d7aede9fc78a9fa357363a5cc9bd88d3f8d70516ae1b8fa10af9d44fa3651bcf81138c5cef43a080782377ae3a5da6bfe8b48e1a1c2b0cf72599082f9c98bd44223895f7e842ea0efa6c6d745e6bc36f11cbbeb088255a6f782822a1532663ce9073f93f6f6d6fc5bdfe96511a1b0ef876ea0e19f8b679abafae07e25ad984cda4b9e8c8c06452221b1889a51f72734b97e756c25abbee2aab7cce63969462c47da6da37bc6628cb2a10bcc0524daccde0b96e5eb411168321242941d9a02aba978af63e096b9af2eb02b5058d2ff56ecdb4a1b409a28932de0f0885075fdf3982d35341ba847cacb91b156767d33d930c24ef38d2248c87645b065ce5a4a4934d205b1a243d4fb5715ce9f20ffbd4427740df3b86865b4a5b039ccc057433e8a8284eef7da0ea983ed2c7d6b09d7230d7ccadd8179e5d2286109957a5e1d285c4c128a7c37d6e36169bc922f2e0bc00a9fe3e0f0f6bf5904f829c06a79f26d2e0e8634cce715404046329ed9a1dbb2a5876ba6e6b4e10ccd042b4ed2af6bfddbc6e7f84016da00a265f82e64f056beda855327dcd1b4c88a17f7fae88529af3661e6390bb566cf8f84a6582aee06a49ed1f695eb9682b195c07c4ee4f54a15919913869d6912dcf0f98ccfba29b2de9fce49a485b25c51477faf5e9b114669be74a0905ba91a117f675bc7d35da8b5e054a5eb68aa25e99828eb6439532f0e0950d16b76b4242d9d53ff198fd42952b348ab1fa825ff03b328ed5c53e9999ce1f8f300d26a847ebf6f58fb11fb95646d217e401cf6773e10048503ddd2bd9f25d51249ba5944f6480ae72706002614400c958734c7e78ddecdc138c923e55ba511dcfa1e5b8b85dd94c83aae3a39d847e99c78e63ddac94bf92c642fe7aab61198d5a28ac9ff8547341be412bf0c1de7f85c6b3a73817e32e11459a35cd3014f848af61ae0366135f58c789101621648ddb0151c2c98b91370ab765c04d24df3259cd72bb6e83a17241e7241b89f972f44a4f14b27420b9ae53706bdf12d552d6dd1dfde82446e1be4f66e87ff534f6d5fd3e7b7abbed4e0bb92da96be1a033b63e0459de2a5e2a40a5342e593237f5354db2039d8919906b7b9a86f47fdb2fe2d4e08ced4197d23b72f805fee5c806846663ab31973d8227e4857363b855d245b60c79f8c007c8094493adc6c491ed5ae9228b35b0e54d80fed0ca288d713c6deb93cb96501d05aa307c67f7cb3a7c995e5c3a42f535bb2ff500d6d8e2653fd64dad03534578cc5aa358ea898f30000100a820770ae9f3d8bfbd34f4e2a08bc697d58bb0bb42107edb0e389af7ae9e8ebfcbc84e7b29d88d8c3a86765fdb672244cf41cf7fadce6e93f8822ae50fdeb0da8585c97330d0f23006d537c2417716d24485733c5ade4a83f3830b2d4e48730e2a5d5c2eab6382525a8dc8ac6b22833d908d0954ef6c5cd0c2c9390e2322d4d63d5e32206365fd716ffb24aa8b2bdbc4f055309d9314cdbb6bb8417b8a0512d12bea897411a7c54b4a42d8118fa5d9c14d81b6960d86aaaa12a43d1b2c124d8ab3c6402fb08863eca9693bdc773d4278c6d81ee93b0a74d8ca9e8dae298df97298b7f3187a86616f1681d352a5c86a378210527ed24c0394f701254380021cd6f7f51306d26e8d1c4ff95fff01aee58289b24851d5bba23bbc5620c2cd1f72edb44be248660e114a67f82f775b399fa0c2d2cad9a843fae79c4d8642d1c2b5e7eb1fb1344c540ec8cbd259f8a780b4b7a9a2734d5260773b1d793f8a295e093c2ec571add0af718325d76f2c0be3631fad951314f1fc0dd72756329e3716c348564fb6dfc2219a7b6baa7178aa492218f362e4bda71195292dfae47077430c2f3130b11f7304155af11ef60cc1284cac3661e86bcdfefeb2fa4e4b0e0cf0d3486056740f6ac60f0158f7a34fed5aab9e7ce1d81c20090cf7bd6e48220f2dc058e6c5d1a52d99c1ac85dc2135dd72cd9375bc70dbb36286dac61bd7a32dbb6004fe47f11dad3ea18b9ac4ecd6d6d808f97c8e576da8667bc33d1e5012e339c16e7d2f96858d2b1f39e3abb3c9d9af1f1c94e6cfcffb737c0da850d09c3fc68b6493b1f8a162fa501c7689af3f95fb97ef059527818c910499d16a935af573555c01497b2f44ff28f2e456eadcdb292a87d5e81243265f425c48a72b34119e75c084aeed184cb4effec790981046f60c3698c828a2beb4f5792762eb55eab73e2d675942b283c13b024f67f2e4cd3647cf071b93bf6b281f8555bd1fcafa714a3461a981956ca63d3a5e07144a6fec900084de447670a0462e71c45ea9d2e7abe3af3102e73fd1cf72efc008dc0afcf541b1fa85a3b74cd67b67e7d0aabd2b2b7e8a9b314c9eed0aa827559496eb20d1b92be675fca1cbe341b72d4daef624ae9b9adbe3df278863d3dec79547c5738becef07a477706301422ef06e1da020cb9c5c1e0563ae07028b73654055b3c2b30fb358943d148c02af07c81d711390b32ece1d7ff5d7c849c86b6b4f3f01d3ae27b7275bcb91362cfef160ed86c1812b172435c2e10684497f8f356865eb21dcfbc3fb7d31f424fa1346c93a0ab7e0ee652a169b69af31bc198be728290f4ca257bd6be3d7cf6e0a041b711f859970f968a5b005ab78f32b3aae26803a22370613f2a5cf5d36a79e2965374e378369e3b2a936c338ab322ab53fc55f5640f97031bfa362d5b234a8a230b4e43ecd7976f6fa09d7e37e350671a481c398f6b67df1d5cde1d6636d7a4e2a38d5f178abe38ad165ed022879d77b7c20934a11688a2d59bd2ab5627cba1999b9fc428440eaffed952b293eac54ccc6c0dd5948bf9b983809cba8c1a9125a0906b4e1952311fac105c5eb5d74cc5549747100514146548c10bca4979e3fe2c75f286e1ce3c9b98c5f573722acda0054d9f54d50d25db641fb82bbf54a3eae5830d5bc693eb1ff0b04e9d851ee3303a510fff9676ab29e5b7a38208f65d4420d1a3d3623b820db31850073a0a5f53b32985689d47299d1d60476d7dd024bde59d0b65c6ec3f15ef1d929662e26c805819ea1c474de55e03ce1830d96f24cba8ad480a7af4e011d4fdc1b0042053b1fb1c605c40dbfa568005f01786138d11c22a1e22bf68a171fe84a721075d4ea58c5ef724947ba25e25bcf95b1fc95c5f8de3565173958cba5c15fcc1c52d8ac091314217300c256772b213dd0ece218c5f45f5ca9175454cd34e65f36b3cdcda69dece774d7ae10afb34a63b10ac79f0c4d9b4234e1b007d68cf27d1acf4ab345a8040477d0a69b31a94d0d16b4278fc0d8857ba00c560e6868fb887c57c999fb1f5d90ace4b3981c77adb6ddb94f9156b74b02f0f28b0404b8b94a40e11e69376325b25cafe04c4e3578faa9bc85d03f2f98195a9ff8f6f9f4d73fda4b30e002aac5bf06760efb6835c33443cd8af8a47b08f83441b231289acee4e1262292c2db582d040296a539ab92c2a06309baed5de3c67706ce407099369a0c885a60f8f8af565f6b1e804036c49eaab72fa891268d00750408c15b1306033eb9d11d1812e42fe0e4024ea749ef85a1df37f0b1a8f14afdd2a21f1ca18d2bb75d5b91950ff319540d955f92b155ad485d12f93544c26c20fa64f75fc5e7170bb8a13d107d372113c5330029acde9af750c32da0e4589935083406026c128b3ca258c8677942adaaf43486c0e88d8d7a101e587de26a027010cf9747fcf72e0f35de546ae6ecfce8c9d0d2fc4d92f7fd6821aa2626c004804259f4c3c222120891ed7f9f79d51b40c51cc581bf01ce2b16e26d94f083b98694f8398ce481669f43567b08f0ecb98c5d47017870c2f8f56617ac0ede6fa4d23b1ebd70857abf69a01eeb5d3ed94f4126454e0d880df0203d75db7d0a7842f8e8d6ca1a43db7647d507e0111184153c03ddadb9396ec6a669020b2eba15682727bca58ffa1e789d35d206ab2d515a88be9f6bbfed86aa748c971fd60816311bdd31f54ba6e51eef0965d63d7ad1af56d697e8a48033d71ca6358a946771678d3386de2701fd639efed06c9063184025bb30df6136385d5920807cd60f83b75520b8026acb82af97a4a04794c3e55c64d290d68e5440967a383b1021363aeb715784c42dd196f085d524c0047875cfa3ca059fd7016cdf9ad2c02cfc2e73938397a418c29df50e9e7792b23de589a92083c077d241633e568f485962b9ad4615c64af886a0584712975546e669e832451a8763946c025cd88756b580cf45457bfe868235419f567d5e047d631eb1f29ef4330460141ac50d022fe99ee45b9a93c58106411491ece797b86ff523b908719d0066e9ef3df8330724d1bf374d73f87ac13aef86b213280a0f04860e771d9807ce61ba127119a490da50bccf8b338753dfdcbf3022d4078376827b2a35e5c67932f237825b7a31992276765a3cff900fefc92ec10ddaf110f23c15fd405ed8ccf90a32e60ad580ef59e58298583dafae371f7293350d28317dd5ffb85e20e00224a6e68ea303464e5df028939abfe8d8aa20883203baec01a0512d4e48be31e0c063f0c133b293cb7de7826f4edea79d55822416aca5ea2ec4e285fae7347088edaff5ac74dcb8c70bde592903664a54d898a533fbca202626b97c70b5c21a775ec14cda9bcaf7aef3f88cc9c344fc2f019cc230cb9c0204755f59055eb3cf891106b97d0d2559c0fd1fc193f747c1a430567fbf3efbf20d68e5423069314720ef2c0435d347a43a4d59358031939ce407976a7a9a8bdd2d48a8b9b1b3fb1d68fe2fa1da89b15cf069d5306982782474651c512feb0d21bd52c77e1b3c3ce82275c031edacaf04b357a96b053a8cfd8ab1016336a8404cdb992d3f313a9d4ef8ae710bc593bc6ad3e0f4bdde5f93d41f7e4534b178e0553a8c7a016543422a335b50c3d341a1c77046cd238542731117376c2a6ef9b2e2663fcbaffd458a801917f856426fae43098ebb99d746ab82db417d366ea3ba07024972b9faf48408b0d9daa21c7cf738750ce63fffa3b9cdd4b64c34f7d356596a392047bf249800bec4c649673bd94a374262ed763c4695ce009f2ea0834b19470c95b137a3e3e115400cc2dc6fc315f0bb406f2817639bc98d479444e0a1b0942aea755aba07a9871a4ab4a6061610e1679a89ab72d5d2db4d51badbe7b9aa05525544be90c028ec4a351eba3da40630bacbe2d5f787d72444c3a675f9c48e5991779f44fb50bc9a62ca6a6fa5acbc0c7f6f3a0beb989468b4144fa1421dee004e1a1989bfb36e7b407df98da43c7586092b668f5ed77434804b9699fa1e25c3b5bff2997bf1d626c4630707f995bc71d7d0a95126760bb172a07caac406c504000ce3fcc8edfdcf9eeee05d2d0d61a9240f0007e41ddfb62169ed175f664577660837a4642071e8ef9a787ffa16583e7104943d3095a10d984f2910e3a4fd6d5fe6a9335df4a8e6c75dfbf249a4059bdf40702f5a6c545ca1ed16b272288cfea8968279db2e69f79510594edd5b4501db41884fa80d4afd0431cd56e5d276752ca80921f6b2b89617f1a4be906007663b71e819e8150ff061ffcf114cd287ea1867a6430ed6f71bbb91b3b11f43091b6c0e1203fd5cf42c157ea7c267ed7d7fd9cab21686e6dfbc9f56d5acfbca1b38f218196e7055f32e00a5f21b9c44bed06b458a43a4ff92954a3bd41f5dc91e3a1e92f915ee13216a1604dd0db94743dd4e0f956e7ce3710461e845f7e76b8504949d2557a001b74ff9c824f16bd613a96f7be6b5eb0e21d5ffb094ca26316d372c2a9da64983e3d0fbe51647318e44f37de4fd7863dab4772683904badea619244417526fcc37ee84d155a1885e9336ce9ae110bdd3937ba564c6c7187793ee2498523bcba3549b522f0a8caa3bd30523ddff6c67e282bed941d4d15415ddb8fed5d9a5e17f57e96a185dcd82acd5d4cd088d0327fe4c7a69b238161bfc2c68a5740cf0e886233925d52654ca4d8555ed1ef7e403a62dac79f2f6fc38958cb4acb10ff2fe85b5c535beffcb96f6e091195100848821c8252bfa893b8ce84027ac1bee666ba245adb8a57fadbd8ee0a0648bc486743ba7cc083d1332e302068b92528f2b8c0b53a1a2f6270bfafa8c92123f6fb9b08f52d141ccf169618aac7d657cb54c7bd2feffdb2661c0c4dc6fa7ec2322bf69461b8e6b953629a6b63681db4a78330237f14114f81ef968b14bb9c329b2e64ec8bc37c12a034854a5739802a90c8a6bc5cc9e5ae7a8c106a94d0d427a3ad8bb6b69c389669a64828cab8bd9ed9917ce05bca966c90979634a2ff067216df45a92acbbe112d1434818c48b90ab99bf47c6d0966cac02c758e5359bcc93abc72041e5557be6cca9a29a74513ee94f0332a68ed7fd9cd7dbad603a38b71eaf0ee5b4f1d898289f623fdc29ec7a280ca9a4b07c890b44142a6161cd8c70dd12d918696348b792bdc59cac40e02d3204e0ab14f57de7e3a2dba7bb6582261323f731cbf9b26fce3fd811fe9e010f0aaa3a6577a42922572f62510cf1b7d080b34808cba3de6f71dcaacc14523c9165aa6a858df9c1c042feb477359e88e0b527aa0cf1fb3c59ad2e062c622a9b664276788e0c543b2b3e9fb80920bd421dfa628264b70ab3afbef703385be3c33da87b03634c86388b7ee18004f372c61a7eb9ecff04c6f8efe6855da0c90d37e53bd2c44ea9a53e194e395d0405c1d282c9a608aaa0f3bb7457cb852d57d360d25d7423a0fa5a5294e1bef8dccf1f48e768153137d21914083eb504bed9cf127d5ac5a3a27f213d70c9df6d1c29ad36a9b0b9a9ebaca3f8b7d8c08812c9df38807693e213e161f93e5b49b315140f1d34f993cc9bf5180cd3600933d36b24ceb1d7ade201aba5dec2191d0dc9240a2be5861eaac32b912efea7dee1dd5fe46da211eaeb6c37192d06594fd7c093448341186ae6c729475f97bc7c98f02d54bd52b65deb0a9b284d745ec2e892e0db7dfc9db7dbdb4e6e4202e944b965d279c2b27a3e90f6653a1793c844b3a5b3bd47c19168556864dcabaa79938fd97a308acf36c308ac4eff4915a947dce974cb218f1aa6ac3ae9ad5a2ae2923ca71039554037b84bae4b1df99c9ef49164aa3bbbaf50ade9e4a7ab4039a7b02380c2f69dbf37ab614a13eee4e21f654d94abba268787c3d934b45cd48a97539475d2c06eceb7cada83c282e1bce0a369911f2968ac1c3f18f0689b25218d36d60c514456e49b5d00d23608118fa296aa334bf205e458bc72334b648d57df7e0a71f9409190573ed2b018ca24c8b61c7eb8f1a58ab8f5f902970103b90292399c69892293d755e7e081d644dfc9866911c54f77fea23e4321d13a6afbb4dfdaa709e44b1ad320369970a7abbe2f828d9c4b5d6654a42615bc95c71248350f6a9712763e87dff363ed6c8df5e1409be449c6c246c921ec8a86df40e05a796cf0ef669826218183338471a44d6c6c9129d838da5c265fccad52d03e4a23a84f3d8ceb04d265bbd6bebc35278518631282b4d3d73d25c1a1d13c0384566b5484130517d3c8f3f9f6a1f3b7e9d46c0b4b34e14e70876a5530fa61391b7678d1d7b3719a222c8d72554ae26e8dd3e1863d7b69b90aaca1a681a81297b537c0335169ff0bd36d29fac4e8c957ea4fbc1fdb4145d197d49a994381b54e750a742d0356d73c6e3353c7ef6b1396cebe67860c25c871d8d6371ce2322e4b21516ec4297d9f75abead386759ae9ae17d0cf481454e8a1c0e0878fe6a634ec7455991853e9a797b5fcd2f31d62ceae33d9c8db37c6733e9930ec21af53766ea2831f3512989c3172f1a97e89b62f18cf0e12b1a0ae34caeb4d75515c546cfba20e63efd5adf05e623eb644f611b97e05e8f8d88c1c8d658e7ed82ea461a695e1311e7ea1c3e9a9a3bcdb58a22bcb9a8d524fae71402a9078a6eb706e77b23883cdc868991d1969e6a4c82ea5e3b076e4ce52afe17bdaeda6690331447e34c85b26c65624fc261192e15dd1c95ae54f0acbf91073d28278d1ee8b14885f52de5d13dde7143d425d8998d73632be069556b8de722469a08bb232b599a1573d7ab4be68e448da3cbcdf26d9d1a73d96b4d18a84151c6da8924d9acd6b79bc2535907c615deb3aa92a57f4664098312ad214c4b9d10811326f189be6ba5d7dd73d6d8b26b66cb22d66739f9de356cd1518e650e2350859a9659f078d79711fba0cf669c13a4a55860b8ae116dba41e198e24de0636f5a480f91eb50203b91eb070cad2947bef25b613ca52a983f853f48e80ffbc5b504aea1cb730b941ec9790396f91c69c8aea96349e4d6bcae736c559dea58704348761e5fb018a33b25692bb5ffcb1f8fe9dc8058f553bb84a757e87308445aae11e821967644f4884c66dc76ee464caf4860670afb4fc2e9383b0312829afe6aa06a5f20cfda66184f3f664df6c72d07ed1d05e6b3e770e80dd0689bf98c080885b95deaa3b80d7487ceddd0bd219a79bbaa59ad67de2caafb7f61e9dedc50cda78d7aca52c3e40e7504202f847e9cfdb7394a3e6f9d0394f338639d7ba3bf0366d3651d43b69d09eb0407bdab061722bf8e61a30b198e7128b6c4f552e6c24d8d2e42be2f6a24af9f777c36a5a7de473cfeab4110eecbe2110bd70c724e5c3a719445f03d648c98eb637ad0d2e09bf58be4f418cd7edc0354f0c05d7fc5874d3fcac321c0ce8225a65c3eff84d0e2f744622155662a870b4bbdb723badb917a93a0c6be9a4185adf31818dce01fc015befc29065febe4b46b84964eb9865308d736c33d63f74129208069bc0d89c91458ed58f952331fec0bf21dab778a31d24f9babd409d451160c3635cc64a75667cf720763c8db13836ee043aa7eaa3391bab853484831ecd1861d32d403c6cd85763d8bed4465ef19494e39b59beb8c9c21418726b4f6969864ae23e1b023bba39ac759d4cde1c450729cc3d6c96c8d77ba68e10336c010a895ea5cb4e65c45ea90fcf28952a0e3625c73363819aac91c293b952cc68178715bf3d708febc561fab6d623e8ac5a5ac5015aed79c86e1aa9c362e6acb0d2b7f3a48fd88e99fef94c15fa7a3eab01ea0d3c9a8417d2fd490d7cad0ee60467b1c291ab230433c0bef3bd511d82d6abbc23670ef54ed37f3a5233806944d611c6f5f84ba4785d80090d355915790f2728af3daca68bdec528f36be420ab9ea8174b430b944183189268396bebb2103f67be8f98925191102d6850c59d0dbfe11fdcd86baa2e5acbfb950320196bad53c6110d9e8431307a4891c056c9b0cbe78ca0dc06e2ba5e58b8de0a7c006d331270debceed6437743381345b4c5ece9739630fdb6b9aa1d253d6ff30358b5d4a981202e0fec4664855e3a8eec662f5f07c7e8220290c855e6543d8ea1126a2fc9a8ac65a7c67acbc1797b037d3a5e70faa4c04e16b5f6b659b717c24cec05d2937ef6bcd94265e413ef70e3c7a64ad892420d4b6348391ec25a65d74dbbb57b9a0204b02fc77443e3530de66f2add11c0b21876db870018eb51c2ed327d54de485bc9f58ec056aa0dfc8a0c6e76363d0ff795bf8ee10631d4eb016dc3825ab7b08c2222c95d4da765207365901a7c189ea4489e6e2fe7fc9e6fa6241ee4b61032c19b2132dff2b534caf020d55194b50e0e582e7863650d22edea7f20cdc0a62de9adcf98e218b4a7455924ba8d916536bb3700fd9ffc0f77ca79e1daa607bcf3a474a484861cd403287b6a6546398dcdb574ae0216d3b230efd9709f2d003e1a23e2ba7ce2ffd9d1680d4e4e054a73dc719e3f2e5a65ea4df9926b5ad22c4ac5571fc02d89ec36d7040c027da86869b1cdff0e3b69f47ebc243c0083af70c8b4a6872733be9abcc86e2c976299d538b81b540870a6283f127f3583e8b5388c273cc16f6583a12d3355147359f78c1819b75c5f1ef1cd9b3b7b47becb57666f99637247c6eaa0b7849599fce0b654d64fe4624474dcb77f196c1f84e58593c710992e9c242570ea3854841081ee7d53788ba126a60baa6aaf41fd34b02887cccf2b5770a0f5aa343739caa683f80b64986f5c9107c234ae4fc01cb99e2a71f905be72f6f1a3b8ce03bebebdfc8182958a5cdf511a148925c021a801a9002217f19bbcba9d8b7d4644ef88787fdfc286b3838b29fbc307a66436f4220e3b0fa49f6518d3596b8d24c5d81bd2b4e0854d2a149399686beb60c177f424ccda5c97f4a4e3d541c523e68e5ada2d7e7584ec43eceb0ae40861e1b032d6547a9357bdf50e5267da81bc9c01343f7147f1d2968cff71204de0707cac4dba38d3ecc7960dda5b2c329368f87d980d4a3892b1c3e38b96bf1040224bf3c239e697c31a84a27a673ec210c7ce3af03f7fe20543c6b3f87b31f4fcce540f45a2d04bbacf37161c6464172dc5cba41ab94990739b25b92e0ae792cba99da71b890dc89ac52532676ea267f14729aa0f18e67d823071d341bbf03bb0d40a873e66e2d25b986e6ffc5d2a96b6bfd6e86ed13bec74f1dfbd3b4e1d0a810664fa5dfe87ff532f48b3d438060047e3446e6df705eaf7b1cd0a52cbdc610b9141e9656605421080d08fbd84e436e5bebb1338e539b3a4c58678f12811ba08ae9f6958bdf8663157b20b824e59e5c0cbdbf64a2fb6f2c1f84c0cb2f827a925970a094a4334e9004221b44cd5cd66a316a3e090ed1f1a001cba4fa2796ed692f0bea7f87b9c1969c1b2b4e8b7faa54247d9127cf23d608899da724068f413e108c30a54f15ca88da4021c74baa400f4c54ce2b474ba93e9a7bcd483cbe679fb8f2a88e669a343f7bbafedec110f74d395fcb2face7e099d42924166957bb1ae3d359766d52b2a8958734bc37429b71d3698758bb006c655ec975ab5ad25874e42aa526bf06611874bb47a51dbe6244c0808b09f4387102ff52f3ae9a0e6ae7469636fa4c0f345b25a92ab7d34eba7074de916262007bc676ed5f864b35ff4952dccb4b85a0082d71486ecb9a415a6257c5c0deaf2525f5f237861c1200a60c9514f2dc0e3aee816c330f5ecd177e0272e9f7881cee47da828e8066aa30859f9a7863f6cbdc1c4efcae00782ea1d5785990b14ee81792dacb3a61a96c8b55e09c5446cd45e5390eb2efd9064f8f1d2747132043d68ee9d1fd41ab3710db96707d1b9a7c323105e25887dc970e1fa42676ede4a7cf24018f3d036d6213b2b2ad3cc1d6acf363a0a6edd2abac5f994160e328f651ef27e71f6648112c853381e848a2846f31fd6b4604051129c6d5291cbf0f43341eb9b8e6cc485db8a2e7af5886ecbe38025dc7c6014917bab10b4ad6ea62ed1a33a0c517015e3cbc77130d4460788d67638faf9390777d98215a38ab45c8a43410cc348efd4cd12706290ed26d36d02d38b443109e2d32ec7faa93e5ca5ddf7ac9769f84188ffe994d1826b65e504c9ff66765c0eb7d1f930eefd279ad7f0e4e52f8e87ae8d0ff60b58f327af8ae0faa100edaf53a3297c951e3b68ad97cf936d6200466da4f7a4223e5de3f6dc9c29afcac49476d86c976fe5b23c59c4464c1e6136838cdd30ac0bad38aafff4f7a413a56dc28ae8a0d66fa2c33ad4bddd148460308c525fa1bad0b98d03c706de444822ed9fe4c58502bc8a8d7a04e956ce4b49e610dd2a4bd5158e1bcbe632abdbe8233bad5128b8e671067226463fe9bb0d1583c085fa21227bf7107847b7d1d96b4ded75218e65962e39adf406e54849c72796a92d46091ecb6d370647651e769ee048c1aa60f2496ccee496acdb8f9ef7b97dfc6c36a50c59fdbea7d0367de11ce2871b1a14fae7489d03cd4abddfe1208cf3457bc85cef81cb18d7c0c086d60ca6a3599980df8e2a9334a90345e65bf35c7d3d5dd8fa43777c034ffc61a0df4bf63cc3da1cd168191c668f89d75146175cdcd9b5365e7e15955af352324dcd609ee7a49e0d5bc70660956779a43477cfadee61e5b377ac9c0f1bf47b5e9152e7e3fa6ffbe5ee5105bbb3d2ace38f3d1517981395e072332823d3c8df7fcbc95cddc73d9ac0d6ebf9178c1151a9e5f51bc35550f6a305cb559920d2d8bb55b4d913a3edcb5225916e8b61e25587d3377e60d45d5162322634e58c469d1a741c25f98eee0f50a5cd6b0e205681658f44ba0c64be706555f725bdf564f5a01733c2bc311f64371a11e1f0a3879e87ac071e8c4fae99920cda2d11f7ba07a84a880bc48bee94c9718208c4475935df7289272001122c944e345675c57f9c29219e27abd1073e73b09c49e6439532e6f190ad98d549121f8b9471df87feebd55a2b24c6aa2a8a80761353217a7169f9966b18c6a3c09fd85ee6e2c7f6e5083c78e2e9fd1894d2056a406cfd8f392cfb44aa03be48059c94c9ed9ccd6f7f83f069b2bc1a7bdb92ad4d91eb271fc10c9892d2bd018ec372ef8a4a51ceab70a1998267830acb413fc86d6b0cd965e7874d5732d0d8941dc6ffbd2f13e43fdbcea9626aed27fd77cff218a4d2a93d8a590747e807efdedc99bc07672a36bd1ba1f84b0d044e3da7a1efaa018f7b1375874fc712fded44f29b95184262df2be734273b47d2f3b39fa68dcb24ee225d224aa6785b6288827d41bdf3319bd886a43ca5ecf8a8b529128cb19e4f456f5fb7d40dea511e0a5861aebad28e4d29f20559d9b015267b691c4ecb074c2f10d12f58648cb0413f59be1764fa75bc986532b60a1251c6aa7ca590e5d56e6e00b883aa6d54edfc37e3f398241aa31f3dda8ea3f6e2401b5f7faf8e9e21bd7f6e64e25f666577a352114ccb1182a2c8dd1143c93b696e1f60802ebd9700c097cef44dcfa697022ea5dc0c48052fb33aac14077831ea25959ead815f38dcd05563c0cf01dbd29bce442cd1e279621235c07a9a9d4419cf134657d8ee30c24a210e9bd81933cc50977d8eaa0514748804177101f1baed1ec4760a779b2c67786032ce8311ba2b6ccc9b99c351221f5447bc33ea610c5dd36c178fdb45d1bd194e911e1cc24d52f3da0068235bf618d011c115077338dd0ba27ffbfc99f4f68024234ec96a83e45112ad3054dbd0755ab38b1dcf2d085f7538a1a6fb2dee15431ad7a014963e1b9a3517308d2a476bf8d85a392100b06be50be8ac6e084415c468a64a6efd5b76d9fa52bf60ad9d179fd2565844373e264d505608c1267031fa85a48ee3ff6b6eeb5e2c784c0db0e7e288af7bb50c3d29ea0a508b594a67494394c12bb7ec73b073a2fcd189d89c6ba2063440badcbc26a54373f4d809ca5ab3b612acae4f314e1c3ad60fa898f864f002a527ef9d30be3f8c2f5e077b3cb175bc857bbf31afcf5b8e4d555fda9a2be4267365dbfd313148c3e60afebdca19dfcd7047c027a837f314b8fc18230eb6720f692964b8716d28463ed1e91068df72816bcbe87dbee8a8910181d0bb2b76edd371d4f7040e8583127b244e64cff5a1bae1ce21469fdd1497c599310ee0bcd8ed18fb3f1660d26cf06ae1cee7261a9ec4b99aba36130ba076583ce9cc1f06e5c644f693172b418d02e238fc9761ab87d395669c5a04a548dbc103f2fcde135f46ed61ad924acf79f9bb917b25555886b31d7fe8165c4718b3c80ac2c00d8220f533e6a2281cd287aa37925c663ceb0aa88f37fed0dfaa8158d4fabed4b83342208ce0f7ed8d9839ceec6ab08a5766419e481ddb15f3165bfbc23a3c182394dc15bc055dd39d068790de463021e10a449b3a2d1308d3a9f94675bec9eb796549cda115690b2a4d03935755c0dd2a8f021f4d375fc86877772081fa34545fe6c498d2128c4e1a313c5f1e468957427fb437a06ff1e9f996fbebe749a683b9e81ea83ba61f2f2724e132335421269cb1b13444f14e40f6b595cb16bd3ae355d7ee3e6cdef5c5ad65ccd09f4388cfc91f41b7d8eb50db87e65b31055f34f8e1a1e7e88e77c24ac8a892f767bee4da4daf0e950ffa1514fcc7ef66145a5660486aa125acc2cc5ff6576f61fca8bfd47a2d1dd8c28f5fd6dd6a5000e780bc87f2eaf60b0db6d50f8f16761f5e7a243051efbec0869b03569107506ff6e3569a63c940c6d9d2edf598de7079861392be0a44bdd3860871bdab9ef4cded57db11f5fb59e46ee251f2570de2de7fc9df6f4a9fdc636a562dc68d0548d64215178f0705d5e03b68d1bad14314fccbfeda368bcf7058c891c92ce7707caa88e5bd3cd3ad71eda008cecd92d6cab5f595118a9b479d2af6b83186c29fe14c60460a56c5937a5e2bba7aea0dd0fd413c923616ea2d7405826866fe15558fd3c4736ade7e951fcebd0e478eb75ae703a819bbb7610075907e78832bba9f0f9bf62e3b3b55461cb5b644f55e9556b6fc455198b6489d7214b0a362d43b6a9c89afb0774ad14430904f789b44cec7c20f4dcc44f890393a3b3455138c4d0e791b8958be209210ea7960c5acc0c67c91e45f390165de9f82dd6874fadf85709a09bf57656d9976d4c3e5d39ee8595df5acbe31d92f65bd916c1add94b852d1b4fa7a18829216e6dd668c2970440914b7ec11393e9e8f874a8f4e2847b86e186a15ef84f3b7c93ac21e50cdad7a9ca951813cbdca4037e35919851dca69e67c38fa64ea6c2ac05af1cc0a804d4b6ef764730862cfd1267f0b263a744ef26044724decba339567047703e6b20d4f46a3a473c9c5d8cacf71699edb3a338bef58a4e3f0dc8028a37e7b1180386debbe9f1fefef32f3f3998cf1c538142bfb51325cfac66045a06e2af74f52f2ac94bb9aa8880c5e9e135eff3d08086f1bc752213046eaaaacf38a1ca44cac96c7413c7402ef553b34aebdc657e4b24f100ee78ab46abf05ed8a0c98212d1dda8275fb63175ad65cb3d88a43c86e73b4a2b1db1ab2421c00e535427b9a78ea9effc59b04f4ba55c58bbc4289e3b6b40fd6b078546441098c5e5589cc331a28ebba7a96ae8115bbc15ea5bc694d279ef71091d64ae61dec04948b0e702bbcfc9b71fd6c909b891f6b8ab759d29c26136edf60de9d9aac2166d6f078268c7c0af1055dcc494c4874e6ae8dec790deac2dda1c0abbed2e425febe2a8f652dedaf8cf4767c9b42962c6b140e477f46c9600e20d59ccf4900805225dedb6c9a6c8106ef931e5a253b2ed3d8960a26806fb5faa16873fd24c01c9f6cf318d3a136e7b130cb7bba826b851bb6b42fb2352210ddfc2ca706d859db115ee005331db5f8c8e02cc17f1eb646f7f1637aad70302aeba868875b3c01b3c1a82e91658040aa43c5bc5725b1c28e906f04dbffbdea99f6d1144bcf7241675bd210cf6911916f8126c5b1803ae9271751fef6c596baa708eeb9af7734e1198799ddd68da85a4e1a797e1fa8cb8431b59877a3efd69593b6a9017dd5119b916d8f7f81e39a83d61ae72d1964844e6cabaf4e886ac4acd5a5177b58e039e397a5519bf57f4e094ce9d9bf09da9b85312adce4e92f05d892fb7548450dd1e628bd451175d6201a81676a567b08ea0145d1386572883d695a9cca6120fd2588835b34ceecee4bc6f38805af63215f89edcda2f1160769b15802023ca686ab2cc6b35577f8d210724a527115ebdf11330d64a2f169fc14fc7761e11960a81c43916c096c1b51f85bba90083078a120506b600a0f0c0b21f146ea4beb01b82025f9e5e7ada6f982c0b4d8c02aaf325183a32a0c08b61812ece36e82262c05657d7d96fb2215154d5a9a67fcc655e5cfdea00ce927c0208dac4522359649c8af616d37b306a68dd72b4652efab5600b4d7e151cc29d270a3b046ba501adbd8b0b0a11a79c3e7b58ee746c6220c2be586b2ff09bc55bab05ad88bbfe167ec27938afd08ce04a0ed012dfe9840add8493b7ca3f670cb7e782ccae8509a67469272dd8d44b5dfaf91bb79d46a87953a3a95e04c0d1976d4638369215c8cae0e53aed9694ceb5609c643366ddc931daef6bfc66510f6eed5396ab9edea0b9232355f3027e0291ef3851e958c0ac6a514e201ee9af0bf935c1f7f6bffff0a301c29ef48efb7310fa0507056891141cfa4e5797bbca946c3452da79aaecb289023335be8a5dc7de6bb735dfb04f8e5083c8f76a155574fb44fb8c9eeda61c4e72994077d2e8d05cd35cf2e263a626882a766efe4ff5b37fe47d455b9bed81bedbcd3913b1ede7d98e4112917acdb6e70843fcf694bd058198fdc0d52a3bc937098faf9890f2c24fde4c006c147c029650a7f53180f3f1795638dbb4fd9d411e9321521376376044ee1f7352e467a9a6f926b75a47809830a580d5e3e0408c34694083440e2852653755a4087cb3d3a1d79d19e405602e354aab8fc9ee3e64173eec07a70c38a515f27ea268f2a85e700053e0078d827dec742a88260e58bd5dcaeab6f6e3c060627b66e22c85c36a5db518e184cc2e8d08b81c3f4dc2e410410ed0ccf92ef267db2b12bf9dcdbadb0ddd4b34a09d7ab381f219a9f717dc0551d2f8bf2e7fed07662a5a49b5d905aa8d0e10ed2126f888763ad4b27a0415a76e43a62976da553d01d20e53ca67daa8fc913c9c6dd60b7a69093d06118fc0db70405a215b44eec851ebcabeb97ced8ca83027fa6f90d33e1206988cb15e6fed9049a072847ec6b0be86d1368d8c256d6e38994d135d077f40d7d35ce744b6a727887f0497e7954d138bcd57479b9084e9c476c33ed044fd87a8f72ee433062f5fa11d77fcd4bb3a9cbf3844acf2500c48b30a9e8b7e40b3799313d4120ebfe90f4f900cc67c02b9368bee1d035d8fad015bc7eb12b04f834e3650cd9fa7cf40dd3516486a2741c99d77a3223d009ef4a8233b8efd3245660aeaec79980c395fce34a56adaa578a3257ca78d16734392e476f984245e3415bd7aed918e393231f4dd5b2881cbcace17d3383feb9c29ec3a627b8d2aa3f13da9b4cc22a7a5e43e040043d316c6005527a6214626d6af9a33fce5677b4dd09c930eab6016be8daa69432a0ff29db2f895fa70b8b9990534da9dd80e056c04f217ba40749c57377facb16dbe75d59d2d2255645e51f25440f1518b41e2c01e3e098f90ae2ab26456c8b767745e55033cfde910a14da23b2241f6797c9e80d70c1c9e36ab1d259e534645c43b2bcc467d4b58dcec96c0d7072adb5a234f90bbf6805866b00f403b97a16fde9aa6a22e09d8df1af30acdaf7cf1497e8000ff828fd61e8e122b4a25d55d827acd611bc205da196f90aea81d7f7161a6b81798801ea44177806210ca56451aab2c3d151c3c72f2c8325b4572f593035e8dea37d2b4a3d8f4e8f0676a6110f40beb4e23f90e61853a7ad40d847a31e3cd6e468550754346d0a7bb66ef785fc19bbf1ca90929f1ba637234da8be3af6fae365a7aa4919612d82035c6c571b1f3190dbae2b7fa969c33f8714de2eb0cbaf74f86543e7af1822ad9d509080eb1044a3435560c97ae2bf9a24c3325bc042e2e3f07e9c36cec6191f06e5b1c232dbe3d9963da822ebdda78413a7c539b324a9ac670690b5a12e119e5f9e8ab50653859ab8ce357447e36bcbc8cab4ab57d1bcf607a84baa9a84f06a647ca8c497f5e161ae0ce2e59a483dd31da53d471c9895461bd8820f5cc1ac95f18904303a2c33fff20a70e8cd4212b8559db8c0383ae0170683eb7c880e1a4008147d4c01da37aef6c28af880dd6b88471f6935e5338c87e870d2336711f88deb9cc8c3d8fd067601c43d0daf178b85233adee1f42c237c52de446ed1a169b9ba06825b48481b9c9e02f63c30cbf6ff23e178f6237bf19b74161c1d698d4781ea7f5e9489f080d48baf5f86d8e089c8387646c8a6cfe794607fccbab11ba033980b939f59f1aed259ea3daa9246ba1fdbda90b7c40c2dc51f280304f36f2aed190deddccb52297ecc1ebcae00315d863b2e037218c496fb23771708b07cf8d722d86cb6dbebdcb6de5cce320ff3461f1fd3e696392fa14db04789585c91ce332d5ab36a328f6084d879171affb55ffe0b8673a633809836b09fbce5fc1a37f271a8f95b5066e0b026cc207861f56c6cf1a6ed86008de2ade123cc9ca3a90d154089367dc6c00bad92f8ef0b047fc360ec852bffa3a9a51baf427e2c49ac6cbc8f8b55ec4164c1becbf572bb930b175f2b633208222e3cae96ee63fafe0178c50d5e900e9824e616a5be8c78b015cc7771f6ff7f29393d56ba21beff036f4c295d019671215cd22df0d2c9c1307ab826bf6e06099480cdb63e2c1c5932eb34eb07d24594cb42def980812e8b548998bdeae8d630c74ab2d54c14e38dec310dd2fe9324801082a8e0d431a96cfd23fa32e232d2cd4f8220607c7056c11ba5c6fb936a3e1b5618c9da6b59806601a467be7b6fa772f5d1fb7114cf75f56d284149a1a27724ec60670e9c2d905af2aa12d44594a80cd7323e5d36f9ccdf6ca71817d5fd1a05d544f656c88e22662250448658dfcee4946896433d24ff981c021ce6c549c65abc805c402fee5a3b13c731766d09db74ea0a4a04a3f0535199a0d499cf0c9c7364773ba307478a6947e4643ff0b4f30728f5f1cfa708766ab73fc53ebb62738ab1987bcc1639ee0b390917cd2fe7f2d7c18439ef5c18590b4bcc3175ea9015d612f53645c9f6a924e9328c46c53c40d25945c3c2f6cb0be4f92ab14ffecd9f45815097be269b6c1c15710429d4a954afcbfcf4b139de0376d16452791059f9927dd7854d1fc98b4ad411c14e0f1f4e7023b9a3fd67ffddff45d77032420897e22094fb99c3f1b7d8f497b8f9cfbd3e447183b3f9f5501c038f4d85ec3feb13a48a483476676f1c6ad2ee5f95e8c785df62e4ee8124bd43501704e3f68921db6c2391f203ead72c414935f2fcc0a941294b0bea25fa00ad9c67ce409ab7d3bfb2fd5e9c56b71a36a4138f760e4ff241a9cc05f7b31b9899ddf1b2bd85e4b7ad755addb82be9bb09e6f922ec6eb70c902f981e131693a33acd8f3dd6676a0d951716926f50604b41035658babf648bd64ba2f4147d9c83b045a2d3f4d56108ecae990b027e9c261e69022b6a07f55f84229dc77392c5021101102326452b811aa4e6efa9074f92b846eb962d39fc0454e33f559313ac48bc88db0fdeaa9d5b837fd192d761b8dcc71aa1d5736d9c36d245fd5903d857778b372c5e755a3abf785aaa86777cf985764972a364b73ff6e63ea284d67d98f0d6620741ceb2b1ec08847d9f75570f81a6783512917c9bcd3f9f48d24314718ee87302b8a52a49db877d23dc76252fb1863bded472bf734e83d51cf77acaccf4b70e462ac715a22fbdba99573ed3c0b8bc30446d8a448e34236a0b53f225b1665c4a2e0ac67800a739d347dbfe1781d78529392482ebc3cbc5af5b238d8a184bf765fba90cf8829f0d1ace47826cf3511bf10f9780631e02eebe2be93ccee29eafcfaa77b6a913d312cf6af902930104b9028e39b54e7073cf407bde61aa5b938c007808986e6172594ff68c221489e8d224afa37d9ba5987a43a7a8ca6fccedb36a87cf1056cb24f694a32dca76999b17befece3f6666c2b4cee3b52c44293985cf355f8f7640892769e61d62daa3e8fe898172da75963952c967bce9efad236ed8292a495c8e45da6e3c17fbaca21da7d918a7d6a7c8ebfa864539dddf6b9e4eb4a5d303d54aa3598ffc7f19e7f6deb376fcc2e138ca11299c89cc61d81f0f75d71d7553713a20a84a46e67facf00655e0997bd17310885bfab18eb7f3bb1757314d747ad2ccbbba253a82b820edfe6a8be48734b49ef341c677318d357ab725521e86a9c0c2079f0b349cb16ddcb5e58e7ef08ebede1a7253921b9a4852d30e59f42e8f00e8dbe4e83922c31e1784aeec9a9ba26ce33cf837c6af399ca56afe3683b368d59e5fdbbed0dabb8cbd7339148aaadc678a41ff6a90ce32b8c5d5e79156d91863ca93d1243029138509ffa12746234f75b12cbaca85a318a484eb9092365075d98399dcd389d9386235512d58c0c323c997c93b95f3e3ee1b9be7d84939a1d5ee36bc8c3b81ac3593199e5ef7dacd695ea47f813c64bc34b59bb329b4cc791bcc1112396db2237567face567d3bb2f2b97ad810d24458350304fd63bbf0aea28569faf29c28648df08ab5a6c7d58235c4f9a2d04230544dac3dc89167d8b5c8e464db8c608bc1dbd6462aa46a2633f9e2433a85f81e65a4bf6e2811b195919ef36b2a584b76d511a07f58b87dbf4580777eea922346d517091e17292997946521e0b79a5439438651b78d6a39dfcf1639661e7da683b45d39ab570bbd31acbcc76b0cb331cbba36d76cb2ceaa02a6322a3d32c774aec2442f7c2ab12d723db0cce55c148937ddadb636233f70f1bf339dea614d80c91cc49e776980f91eb50204b91eb03ca18874433c2e96de724bb9f234db035b4c74ca92c6426deba8424f429901ed74c6c81260409a036869d4aa1e42112ee742e77b88911ca824811110ef5195d22ea078f73cba096a917b35eab3bc81d6741bdb1f18515b3be952af755a16c713d0bf918eff28ca7c9538eced7555cda7d3085fabedc6e09869186723095889e6a1509351c0e4750b1f251518ab819341cf47fd3525db08711041d24afeddd54c40575c1a7561dfc30982cf2bb22f1b09a0853c77c6e580ae51bbb6b6f277219766f1ad5954041e80e41b2956b26d79a71d7efb0f199a002fb2b728f48e918f988f3982754a468215a1556fbe710cd46853e9b085e781ca7197243ca272e7d4f8258bb301dc5dde46ca8e459f4414ba11d441e08033671d638be9c5c14c80137df67e2544be4237cc95533c650ddf73e704bb56653b145cb94895ca6f81179c9be3aa1e29814c1ffb2627d0cafde077c5f213296ad6aaed89e1b6fd98f0af35d46a9eb73b882e6293e763c174feb5b1c63f8c63b767dfe38c391e818a27958ccced1e9de0fd2e7461db8e024154f2bdd9de0c77a1af5a4d4a494ff2e5b260f0eb473fe843c4c8811598b92f8978639d725a87fad066e97b3f95a2c157a5fbd98bc3c4852855117a33bcced86dc649fa7f6dbcde2e95d04777dc31171530f2cf6454b2fa02741a597671406a5d56e5d8cb4a0993a585b4228afae6ef50c51cebfb9b12b5815539e59e0a08b406465578730d6dad490bb4648b2b9b212126b164ce40d53b494ef87bd24d88881d8bde80a9c5cb5f4150a06bbc7f82dad69ac33f186e43e2c96db138c4e893f0a8447608f9998b2f1bb7ee50a8d2479301d19209073ddf86dfb30cd021a58c64d3b3402a485bf82e58ddd8cb848e6aba5563f76645db28c99187742a50572461eba4dff12db78f4d4204a103aa679a0d1e9fa986d2ced238f1f3cbba69a7e92951471187952addbfc52f8fb6923f821b6bc7aeae6597f0446921cf36ad95338d2577db2efa777fd9a83f22711dc531890719917f12fa22a6ca4a7cbc6b4169d3a004efeceeabae3eb9d64e099e4331f80b9b5ef97c73af5b8b4235df8471078b5f3e10c20dec72a9e6c69322c79d2aeb0bcc1c5e6dc45c241450cc3341fff800c8b69386a745f2c9147ab5b468aceef414a6361aa946c280695a29e4083b59de59a151e877eefcfeef003d60c353940871f8295074bda8f9b66c98e93f2156df6020bbe11f368b79d21d5e2da923fbb285bfbfb1a4cce72a1330848becd2e9e82603c36967df14800a69bcbfc77511c4853762dfacf8938591a8bceff90016682b23a9ac6fb83e63e2b31772baf88e2a16672cb952c542d05fbd0f06d1f503108ab0112bbe45dbf546b38bdc88d8991821470680ccc1b3d4832702723638a682eac77d42680cd9656a5e40a1323e611e33ea59ccd929e613a308ec6ba11a187578906f760eea00bea6d75a0824fc312cb97b0ba35726aaa13042b251091572932bdeecc26cd220f915119ad1eaa2698f293b9bd57b7910d77a44553defe9e196942244eb1f85414f69495bceaf0adad642ddf4176747bc9417af9fa969136187e469d4aeaf88d0177c34d7702c897d258197169dbad303e12796b5f167f6da570c8db2302f3fc7b058cf0124b10f7ea84694424e511ba05997a34d7857b5adf79eeedb3dd7a1c960133216b35788082f4f1958cee0c6d5c81d24bb8c3c0dd2bb18734d5bf577b848e7f643ed419ba08d20138ca9093998cf1b688531fbd307d14c6b068a694a641fed85f12fe348321323d66df84b4d35e2dec13438c744f1fd3696a93b818964e77beaa9d7b41f694000ac75170bce76cf7ac99479cc0a9f5622c66e645cb9b65a08996e02204df1c3a3efe7fa48ea508b9ccf67138c542ed7939d3b17ab2c84d1c452157aaf961b1e1f84e0a5269bf2792102818286a5898e3d2801fb5366cd0355d15306b640993cce4b0ff98d5f41b7fa4a5abc49a0f6819c6437193e27c00bc934fe277cbcc8eb46cf40585fee94b31ca49691c28565a8f39d794e13482038dac352b145e5013e917c034c897e9ae36976ffe8ab1316491c2bf9496bd3296c77e3efd52dcab29d65fd77214f36189ede583bcefaac078ed8b80b1601fae09c978a737c584c0ade5470430a5df08af189ca68d24017b7cb8852abb2a154ad4e259c6f4226988aa9266b7d0e1f26e68e64a6297115a19e1478fadd22ac0ce3a6e6dc0f599da8a7024c87b7a3c36e99995f08a47b024644dcc9e0cece6d9f483fea1309aea30e7c7c80b24a8cf571fa1b32ec561c1cee77f1fef709449aae3c7b65cd47826ab315b3cfcae6a9cdb03c1d47ebd7d99cb0e8c8cee1aca14fcf02b9d2d3e14b216e1f5aaf35216b9df7dd6708b7aa85d8a36bf5f51a26552f8158dfe8518a2c53f9887ff083d53663a40128423c09373b64b57f9792c380e234e50b806bb8adacbd38422628a6a4391ce83bc8e5d77b9ee00ba66a01209ed219ca1e0abd9c349e98efc10efd31ddbcba0a122cbff14e593a3b1d61826f2aa7190212dfb2dad755d6eecccc8f464d0abc9c2c52ee4ac3926ed33f41220956c1b67ceadcca5be8ef61160d54a978fb33002f399db0532788207f6db5240dd4129e1c125c0ab440e7b3ae062ed1fadd55885c07905707b965a18187acb2ec785bfba0544b48e8f9e82c9425505773e8736514deb1e69b4929fec50831491e4eb5a1595808aa533428b866b6155ff0252161a39a4043592be62cf6f9be8b396f96038cc401f9db70db90781d9003ea7b6d8e1e5a7f6e829ae404a69878218cd42be1d75cc3f3ef0e9c5a3df0bdb104aa9e02b069b1414eae78d882525da6209f530541cebfa37985b5b2215677d02ae559d2d245b0da1d877ba78d1fcc79a9778308c4219f6d86fa2c58f90bd6e0c05cf3fcd90c9194f82c0b930e9ecd822edea10e508c476a792ede949737d1b592dc173255eea15213142c703965f459b508fcdc17fc7d8f90c45b7ad1a76928bbacafaea1a6cc51aade91adf5fedc6d736076d25ab588f0dd1a27ae1f1e8b1b229e10b6ebbc48c75b984a62643f3200242322918e582ba67bf2de50d8e1c23ec60f857b6f417722b8eee9a9183e15f0906700ab84cbca858e860f5d325e805aef5a697d19ed0004cade05ceb4d09267d79a9d006265000bbecc77283daed3bf3c9e1c91ff66e56906d4a290f527e220bc170dd3f5c1fdc4dce12e5f3ab21a68df9a51faa5090a73f748db92a2d88a2c75a49d43f84ebf110c9cb3cbd9c3e319cae00bda9fc9cfa32fd8c5dc11f15880cd2e6321fd346e6fabbc1ee13f9d9e0e7de1538e18de7158caab2f012c922819e16a30ea1e66aca3139e942a19842d90f2b06bd4df4bc7c8e808e9390f5e7cc7b5048e56e9abd0964bc8f6790be98a937c70d3f5b0c48a718997a1913e40388763605391b5d98d752356fafb62b154de7208d71933f5012bfec0c710464f11e17281bb18b4f826443f4f28709d9683485d3834d082b5a4b07df78b1013e154368aed6c2d6e968a8e3292b863d9b8db507bae8e31445bce8404b92f4f95e4372f5748c2cd7d7707c7c717971ec6f10c6f2624268a696626e466306e7c0278b39b2578e8c9ac3fe3c6d2f309493994499795fb26616e71e3018f8512c615df3531bf83dc2a8d4858a63b653d877ecfd9867c921dd011a41a3eba3182ef0a0ad02f8133c18783becc2c08b2f0786886267ef4b3e3df21cb68515429039f46c7771d5020c0f97fc87bd41a7837e38feee3012355f0f187f71466b2a55070ed63f9730e7f3d650a68938078dbf29f22bd03435691a1a34eaace4459579f99cae8e221b1d6237f04afefad8d3b994ed72c11834dd566dfefa9717f60159c1d69d1fa94f82fac266875a696a77a4624bc8d53a6c55f6a61baf0bb8ed2a40ce0554fc691a6df37fcbb499accd771b7a6260b0b4712cbacfd46a875031fae92473f5f73f5fee3423d4062225d1d18e9ab9f56a9bdb0be48c418bbb3a021db25b7e728c82a790962d2022b65efa1a0291efeac840197b653b805705c3de9632cef49446533b5b62de03976935277e35df1840a99a03862bfac2364b86ca921af333de9798464c9ad6bead203009a32cb42ed4288b18c9b2458da942d72b3f5a4ced645271b14039eb32cc5f4b8f43bdc215cdb1ffbacd7ec0e08c739d8c2c5a63b0fedbd7571bdd6d206f3596aa6caa0741b7bb6a1bffccc1385c08a16ea7ce12113fbc5f5e73ba080efa08c4fa4c27101aab1afa8a187b7973c5778b92b46a1f145b256ac71f47bc96ff81d285731000deabb98dfb7851c0fee0d9c3816eb9d391302252db787651b8d0c6d716131dedb8fcd1a891701ff39e251c119200ba2cf746358e6ed2b1cf3877850e54f5eb35aa2b85ee19f725000cb4a0294bdcebdbba68e46978e5b81ebea4d1c312a3cda99fcd8319be0f17654e7c81a25f28e13f78400afe5a9a32399dab311b31c45c615c770f611893dd0e578c0c5b568a1dfaeeb7ca6bf07478b3003e15ec9dff16d89796d60fc1444ded22dd971782937bc420dc4322d592ad16a409ae158201eb5dc56ee2bc282533d14a49c5c4926f3d8ae8d12c7f4fe520adb75d94a8005ac8536dcf6ee9cd1f115f4ade1db7db1f099f0e5726f25a034941e53e2b75a050bf1cb30a5da80cc3c1c8a020d918472110a30eb9ba0ad91e932b5182a8579704d0a29aa64804b5ce0cfd93e30a3806af27dbe9e6e74e55a1a234bf0eef19f8e43845a56b738809c30083e71c4b9f09f223c96c5d65d51e30aadb15d7ac8d32394bfc3e4fbb2d666820df3d1cf711fef1d889151bb6a822d8d49aae12613897a923f9be530456b0a28e03bfa8ea74bdba4e5bed0a636719c2a610eb3efb6a6685ea4cca37a24c0a1c88fa9ceb8652467208307adc6ada7b291f19e0e7343575d972b21761d5a27c49788455b825590871ee76f6239860a61c54be1eef2c2cbbc6e81dbb6e28bed293de24a8a57700fcf21feca1defaf74fe34befca7ad29adb30854ecc8bddabf10ffa00eba0eef2daf879dcf6788d4caf90db405e1afa693663c3bd0a3367116c2277b5a5adff06c75659789129f0171e6c36a0f9436dde1213c9ee45fd6f67bcb478d12836832ef7b02f57136e7c5b2685cbaf2e8ed0b74a7aaa3045fb48c4e7b4fc1a65e21948de1d05ec43a44f2b5e1e25479af110f8ad4d756677f222ae2c5ec057f7483d1ec3d989dec2242654d64f38d0f3fb2cafe8b197452f5f37e2cb13e851652af89d3fa38509b34f857f593c8e61b8c7be49c08d150364380d3a36e873e303be1aae22a631b7337b885d8ebc2195ca4ddd24ce62e358940b48ed07293dca17cab675385c1f65e1cf6d18595e78e78d5d00ff4fd21a410c9ac04dffbb244f6750667e80376bedb52be1eec28ebbac6eca773f583eaff5e4828d71b61e0b900c1d252a5d7b33f4345600c139bce7bff867967a19b827b2f82a7cc8d73d73c432de1def2bde72cf70f49d6d77001b1b8c22cfe73fb6ce9fdfec556468bfcbaecf381eef50d32c01f334c8258c9920c05e5a8fc8ff0479ca042b5fe0d2235852d9a28c9a1c01328e7cddf6464f59d131d3d167e387fa2eda0f08b7726d31c31e20a2b34a32e5f71d3fe00ce343eaff827b0e5f1977e1e22164df69cf792f4fb78ff995e6e0cdd3d34c262b4ab83a12834d7b7ae1b4940d7d026b41a66a0298ec21c5cb82027b7a7b52d21e0780cd6ed84b7badf2e1d58ce7ebbcea3ec1b4c17163e9266a34bdf1b5e12a8018bd9ba8d1ae6662e7fef83e0147a5a90d61d24744e148c80ec24bada09d97be7d39e3aab778700bba6a00c23322a0510ea16cb323196b98c496fbd2b0d570f7b083038c8e385531cd3c4b220e1eb97caa89dc13ce04c4f2949b946b738886b5f1c06eb84507339f66a372829487c1fbd90898441757e88444d3ab9eb24376b59dd477e39f6ad82cafb67200965d0a72bb4f0ac44bd5f60f7d42455f822876ecac03a794fae7a80c64966d4d590b9c6d41ad414b9ca513a2afdc210a9d5143cb3d840299fc86df47e3ca6d0c53788afcfbc1b67cb94941598279e77f98bde1a31b018eedeb35d8b71a40f5dd6623211f82ddf58dd1e4ed3194fccc00c63f78540d4e74103a703432cb0c0fcf5b3a5b79a8b3edfdfd4d6fa84b896e5663dcd00bab2852cf8307b9a3fb1880bcaa195f96a1a48d8ad7b830395545ed07633ef273dc1b2c841cbe0ac6f9df00a68630c7230bf307514179addd718e88c5c68ad72cbf913dda576662849373ec4600f554ee603688adf3e28c573cf984e33aff707d9188acb9e175170bf4787ad06928f15c90a0b5a0e7f2cb6d9050584c7600d63d0fa84d0e5627a7afdf26ff5d87cca17308e96973f02dc386d5b3f405d79ea288b0dfaaca33d63638899f269888a3b51a4e90094f210f2b8fbf91a54d765234571c58a8ff7332ad606bb07b2b81e1c2c541f4ee004978209956301725942f3512ce1df1ce6eac598a1c215e5a3e6e8973944ffe0d386673e31f5d4c6a83d2a23c7f3847481ab3c474c053b1f3a56e93e75e9f305c1dbc3de3dd3840cd605b1a2a741cd070a0d6a27197d0da6f36113b8049dd163a8133774c65e240293e7eef09867c8542dc082920186be3e4b7a0cb6bbe0ce36b37646bee2feb6c2df89d3ea284f69c5ae33376e0b0f73042614f0040438f6718a273f6ed55902046365a15967bc18a8856376a0db8e00fe580c4ae879eaff1b895f41e0df43e4119f8cc0233599872903726c33311fa10f91e8278567b45bcdbf4f39f795e46733cc1228cd45fa3884ac986c8bab49d4ea7f602889ce17886a73b2e33d78eacf55ab0cb669397026029f182d9b229b72ce1c4f422e11713702aa612e2940f45d682c857ce06bd27c6e7e54b7c21230bb49cae47df2f1922ee8f2aa6ba0087a591ee9b68f7dd114564d893ebd25406f1193dd870ab4f653ca40343fd169ce97d967a2fe3e0b277b19e853c51e52e5b7380fcbf267b5004668d7f5fa5cf0e89851cfb1487a697fb89b0732e3b33c19feb625945fd0cd73a62b4436634bb7e65d9f8b7d5f182d81ec67be83979fee7596ae72ace7d580951585d83e77ba32d3b7f202a9e95620ba8637115609d1ae5d5a7c56ac9ea767bb5500f024f3043f9386bd4108dc720f4f3daec9423dbc69fdf8cc263afc4c661d2958680ee3e7d184bf6ae03b7aa6ed9c244f5144249b397beb7b4ecf41e861e3ea03df62c91fa9c8448a853b34badc72f4bc0b6657fe1ae22fd3b9f3c44aaede366fe40f39c2b580f41e63f3d880ccbc115773d454be8f8fed3492cfc53a20be29e5578a0a9e282e5de9074e5b9fd656013d2b8133e8d73a6a36431ff70163a52f3dba30c8576dd2c165c28c8da0e77be5046b07afc9eb58696c04acfc0fbd6e82fdc4406f42948b6c99c5e93d8bdc69200ed00737d511705fdded38a343c9392b8a73ff15767df3f9bd74f18c4c56946f1444e575da7fc0952b67caaf89a25adc4a3f464e33eb188204b7d761d02dbcca77006a10c81bcc905ac8dc1c0ac7faceca68883eaba346fdf981198271345585e570299512605fdbdb4c84ce8cc423b4ad0e9e5365dca947cb703b26dd86ad038549b2ef4c30f827eb87b8539e2690912441d746683ea72fd2ce97de1066a9262c4a8ff5d2aa9d2dde363e93a55a6fec9183dbe11cc12cf8c8f1936535103280cbf5ed5df6d00bc3b04090d2de54f85b404b5f78b474df331c617f69d637ce8195a1caacf6b63509911553898c2cbbc80c9d464f97c9c84909553950a3540e7eaa8768893d2c26b20ca6e5d7d3850996038c3851fb2fb7447e2469122fb3dc450c0a6bb646bf10a778311857b43313fc888741f202e28c4de653df4fc18fd884acc0925709e3d59d766b438b8e8298fbd30b597a0f2f7defe9b20cd0de287c04c68c163c90597739263c5abaffca78805faf459af6db63ab1bed0080b390918f7838e8d3d551191e98b5412e483a8e0e9c6c5a99368837547d5abb925368994c613ed9af6dd00477cef047edeac698fdf600cc1a42cdc3905ee99db0f285a96a3e552a1d28404ae99683d0e549efeb2e9a459cb8153bc9b2911ef0dfcc1920b2ce290d88045c854f73e81d360101d579a44d9918f71c7c688327bd4537c6c82d7abb4c6af3a77d3f0a473d42e5633055f3bf85e3a082a6c707fc446423e773d468bf6debf073bc213179ca8dafe3f6d5a05d2f1860ee7ddc07f1a207d2ebd72f04c967c4f91a74b2a49f58dd5ebefef0c80aed9fa6ad4914fbc5a0386873a77efdf8257dd295414058df17a54d88a438984da1a27b125d9f3b8b51eeeeef29cad2ea65646640895b952040f9eafac0473b0175ed29bdf6960959a84a9fbf308867097fc9fdd2296c5bb3dc11ccd8c798b5b83e7e4066172a66ab8c28495e48e1a4db096dd2360c775dcfc0201a4a94613c880814ac7ffd1fc54dd63c25b8e381861ba6d12cde2eece873310acb469b838d4aa752ca916274be42233667588ee56f72dac6043493e430b84d27180e3d769669898ea41fc9f3cace37d7ada3acc1fa3da62a1f1201e60c34e3d5786442e18ea3b5bc7a13b11d4abb7a8884d7430237c551e3f91fba4917c5354fd7edf89b34c255ca98f45c728954955db00557bf41934594a3d832c63e46ed2988941d8e78c4a2f881149258db553e1a084da72159ed6039a9700ce773d2d7483167e907e4acf397d42cc4bbf4969bfa913da85c89592e85866577f254f4a396e290153d662fb3c69f493a35271e63cd5dcafaacfefed5eff4aa73174026d9798a9e0bbfbc6f5f243a12db5e5a83c3c11cae13e744c5a3169d52a6d6635046264683f3de60b760903abf7e3d9d4dba68e97e3815d9a254bb30a727c479929e6b8ef3b677d99ea0ff93a38486bc215b0ebdc7fe25e1856694575a423d80be0637ed9cffaf77128b810e613bd3b2cd40317cd61167cc4cb6683874324e3e61eb31fbd71b3e6f60f08538b5dcbc27ca561bfd9fa80f7fdc262fc3407c4b43a2b7ebba6d695d9084382c5f408e911abbb616dae2f3376c4d9ed96f5d0cec45e7bd3079853d63cbe141dbd664e3a0a7084d3d0dbbeaa73c62f6ea366c06f5704ec9a0e4babed3b0cadd3d5f42a13c2cdb9660c6b547a89659c7ae93d1be111c8513b31a3a0d5ddad7f0865c074d1c057dd982ee2fbc4fe51166a6c280c7d8074bbe50fc654273ac9c411143d881408a86f8bbb37de309502b4ca35be8c9f35cfeb00840670cccd14b8cd525c61492610ed149a178ccbab745a28f5a9f52afa501df9ddd56cc93c3b1f91f6f178570759efcb034b50542ecbe8808ec28b1fa11a9ba738b275ee515cf28dcd97a54dfd4e018220805e1ea4a74b4141f988e929f4e41d8eaebda0c53e38275ff4292b8f2223332e9261970b2381f01c5b048cb0376e4e1fbca23daebe2b7f1121564c0e19a6b2bf4da5814077d07baff7dbc78e4b41cce6a8d36aa0b3e2aa015c72b51d0f6e617b02166815a84a944c3d8abf1fdae1a4d100092685694073a3ab379befb25b1b1724162f4afca3f1afb60711824ac87550b4dd9ac7769773649fe07398f43436d1d1c23358a49e116c49f5a7cec49f71411cfd8fedf9a361ee23125e248450669d6e9bedfda16fe93e0a515c76e1f7924a32dfd8c0b92ea27aef2c382df76de5f5b4ea8d39add2c506079fd688c20da94f6433767e6ffd70455e9de149eeab8b66c8f5c8bd691c158e049a242f821fad4a4bfb3dbc853ce7b970a8d99657b4842c9d2fc90c22d78287d95ba8b01ef31ca47ea0e4503229a11063b860f5cbc7c4284aef0e4299e77aa3d6de71f2ebefd16d876bd831ce0810c7bf8ad8955831a4f878ceb05ae0979e85dbdee15333ff03ff082ad213d303e5be2b377980a2e325f0117d8b607c1c769a2a0395ef334c20f339f8c381306ef5ce4ccff4d58209ff1567b49fb2717c54aa7b4c556b08cdb11ac12753aa7f48287884a67e7772090386d59542a44b851c3e5b0eaf929d688b2f685dcb31cd17941a4ce1be17c99a7bc25a3a80836de3199ce18c59e441f5bdae6064a0335ea7332a54fd310a96015219237180037be006efd1b3dc6f3a43273dbf3e7b8fef782f25ae2946501f5c192937634f98b4db873647c5a93ec2e333d67ddf24fe84f17aacbbe149f78e6cf9f612278be9d0c5b150c347458b752a125bb8aa73b5ea911b97ef7a0a7fb0045697cc18bc29d1646e1ff9f055277815b932ea4789a2579cdd6137798fceba32e09f1f126cb955308c919a7e26fd8efebcabb15065206e101a4e0bef6163460ebdb8766522998e7c934b06aea92b6c8033b76f544c9958668701333274e07b29cbe5e4773a1f58da5114b7541ad16a641c8dd3a239d2522aa4f41a12c1d0d51f3f6270f544df9e30bf29fb63539d8251ce8b18138b6f4b19da1f345c4576c927dd4f7ea3d151842410ac47331b5d5e9dd7bfaafdd708aba71b2f62d39d142f12170b65bbaf4f4678d9c77bc3d296dde123babae3f338ab9749bc315acf1a7c2a7418ad490815daaca5a24d9d2116d4bf301628b4a51e52e11f685d65eff802da1763d382171acdb8b5d058045b5010f6cc41bb6a8b8168ed77fa10aede5221bab2cf6eb5f58a491ead1ff257f5a77995050bc76a4e09c950e4486ad2337cfe8a2dd19c2dd567ae7cf1efd9df63ee377eac57c1b3f6409371c1194873851ca4a4212a3c4b946cc590f77c904397f1363029daf33038068476d52b0a6eb9b78cb3af0df3cdae3e5f816761ce0f36f9acb4594bb7e3f7174b156c290dfea8002ddcf5c623c9b908b9bccbee0cd78258c08974e93d691a004539bcfffdfdbee4069ea4e71fb56d1fe8842203c1f98131439b635eab5a8ceb54d54697e18b734a434f0cd13d932f05ffb005c14479aa3edc36cb3161d5596b617f72b5d19d7aa6118d4e9a138efc16bd843f117781051f127486ad9998ec44396b372ce49ead27b72feb400f38c2f60debd40fecc7bc698550bda16e3e92a82cbbd0f2349d2e1c3081879ef3602ac8995f7f902970105b9029239850a6a839b8241756de00a16bb7bd2bd93caef4160b3bbde7af67584b0481dff29b513cf96c12ebb3352196985bea793e940895ad7e757dc615e645474fd23d04ba6861883369254fe2c8e1d74d9ad6fdb55c1dd6652ca999c8359a297690d611add7bb2364de9ce2118fb3b03f7c87aff12a72ba0f627ea3cb5082d9da10495aa08fcd4e4b4dd82768ca6670eccfda55326328133d11d363b006a8671c36dd93352aa4a34e88ce26acca54eb7d9d322bd1b8fc9b3e1cfd8e842afe6484ae4735fd55aec5387334096ba36a52f5dfbdebf16a4d33953405a175321dbd310c62650b590af2bb998f3536628a4ae3b33ebcd2e0d52c129ba65c8dfe74c9a5319bd126ec732190abf4d51573c69a0893b682e957740bdf70713e534b61f688fdf59979f312f7b1edb44d91255ead723910a73e236bdceba7186238bc7462ca52d49164e1f358b1f7b84f3cc874b0967e1dda3cb17143ccc544a09d4f9cb2e48da938788caa36804df5571e6ab4531905bf8ed31050cab61573375a639d08aa949a4813fafe57dce02ab1d3178dc3e2aba80a186fdd940baca040a16a232910955124885632a9c23911f2ea8ee835ce94bd717f23cd5195c5633ad573d32c4ee29a7f6e9347a2a57bbd6b9765ced6b9ec9a3089d316e895d95ccfe00d0b02a529ed933ce3eb7cd8035696b5904a6fae68c9dcbc6e82a7b23f9d76f5434a176c746fd48d382c639d9a2468ed31864e5dd8ddeff119e93a890dfa0065551556c110659b767f20963effdc3144e371a77eb9a21ad33284f875a5cc58bd338d2293e18da92ee55f3a6abca6775754f3218835a1266dbaf0d86a6b36250bc4910fdd16db24ebc643d469d2066bbd84f600b8adcc3e86167fb2e9f55546689876cd417363093df149d04608330d754774e677df2caccf91eb50205b91eb03a502b3edb02c02df3c8a87c93cdfc51821707f640a0cc7b514877c7018797eed750dc89ef884838e239455ff63ca0241af88d5a4ff8790a8158ff681fdd1085022a80f79bc55bfff48f1573ea143d9accee4857469a64c7caaef53ae1755053d1262c25f1178db66ea4220e2e645e0954341d565395bff562a35037ffd64978998817055600ce4fb1b3ec9f958b1aa5fa074b87dbec5fc6ba4097acb7e351744a1085ec21a5b0be699f53c9323eedfcb24203ab34575864c884eb713f81f8f2408009899438cc1560d9d326a6e1cdcdb085b859303e7cca709e2f62e3d8aad34458e78c2b79e16f75606828f8e80da33e64a2e8ababd3c5dfe6176ca52db8e87f698eac7a57756e03ec51242d7f9c5b409b30231000e5ed7320aa65f20c7c989a3cd2c0f5e03f9e1313b451860b39440244f79e85ea8fe14312d801b6d45d042dc9543ab80afbc178e35a664d92e1f6870aa02cec21b0ef4e2e8e5035f25a29271f21f02c821bb08ae50e9b6046104be94918a1af515a4171e772a79f4ffe4615ccf0bd04a19103fd84680a968d583c4b651ba6dcee44da30d1f2bed2e96711ec4e6ca8dcb8ab930d01f2c8499b54701495c05bbe7e8a800454785428d92db46f51b059821ae2c803e10bf68d09604ebc54b4728c3a1ab8b7ae986252bfb3437df3b8c32c650b951fb6547956c25ea5e0c1993527e852ac053f5c51f0152115b58e6b2e7fa2865c769cfdf073f863a1c8199a20ea4f72de40734477e3177cc0d7784053c074fc0ee1719801507cd1e6e5eb3f7d9b7689bc1819ed51174ceb505091e12d5ad9bac4fd2333f6eed3ef13fb069397ad981bf6da60c56c0c9308ada4effba3e1d4c75554d979575fb4732f0423833e300705c4c9f0ed745b18a1ac484713bf763c5953460c61f290ad3d94ace0afa512d75127cd46f30f80482bf7aec8d4dc3abce53328667d94eb7f1cf6b69369d9e5e88642d682ade95db1b300ed8636e08b7d9180f1d3ae591b20e0126588fe35fc61c1c4b5e957149ab71ea26bd1406f519a8ff4af04dae90bbf9aa51a6d7b7206b09cd62e63c5acb5ace3b4dfabea5f9a752ef33ff6acea74151b02125cd54295d0a8186a8373262f248c0cf0143aeabde5b3638e4ac1ceedad98d12894492f520f7caa40a6684022a7063ea6bb1d7d561edd284d07245abe889b2f3d0b31c323fe05e66fd9c672c429fe9c0c025eb9d6157ad5cc57d9254038ae8b5ebd0edeb8f3329ca3f0a285b74650a386deedfc0dd7cfb3ab503fc3559cd5943d11dd5280b52e283d4d023c4a014401413fb20b550fc90eb57cdc3ecb1fec6563bc990e3a7643923328037f1ac4aa8b9576d5106a4d0b1cad59f54e71679482ce7d0e1f623874a297b373af7ba475751fbef4c9e007105cdf23bb61a358d7a073217b63ba535de0ecd5b4fbdb48446fa1e34de25c07db9f6ef34fee22c1756c5ef75702fda9dbc108c04f4568684c503d7f4689660352935f4d4453994c720a6b7d5d9b720007c86474a3088c5444d21d95113d286c25ff75ec9adeb8fdb6d32420f0d1d9a5f317e9964125bfeeb6423ff9b5e6721ff37710b180fb1d840a20a9084db35e2e0a99299245807f7d3db66fd59d89b2caeced239b9e30173c302ba7c06eef5a19567e1a2cc31a59c63e89d88de311bb95d8aca0b6fddbc7819ee51c3e29e57789e8f2785a6b3783377916b9b046d3651fd4b1eb6d5c6f8af63fa3dd11e833751e1ecf617cc0aa63e213a731fd8cae26b2f2d9877dc4d39261defa40d2e229577d570555e93f290bf7903be98697e0855c0d89fc5b84c4edf6f6475a29c001419c581744775a0279277a38521770b335d68e4a7e1b668381d050ffac393f9c94af458217f58a6959ec7b2a3d6387ef3728193381b54d35311da791cfbfc646508364230b0319b508098aa4cbd3db6e81b636f26fffb52b0e97a1efdbe3a24d0f23c18572fd3429c4cf49ded289d466ec4e7abe30a08967c9b3e8c3d5ea96d8b6bb1be73d0b5f61ac3fe01293a29c0641bfb85488c31d4510a4f25c8c9ad7229d7d43292f72d2dc6e45974247f45fee8d4e57a741b108ad95f78b29c59675f517bba831112606a6179bae272d218388589e1039c4f9e024f3cded05e6fdca8427d522dddbbdda46d4ca014990f70de3779fcc5c48a813d10da29d6a45365cf302cbba32f58ad9591f303190e88c8142cfc00a2f7c13a76ff6e2813078f53c8bef1d1e2e601917821c7fae39e821df6f2b0a8d1e0fe6d08d9f2b3b97f9aec5f59aeefbc1778306110fb7dc51ffadf7b9605f2abb6a16453204404b5225ab173fe22d77bd35361a5e1f08161be60b1316efa0688fc2e3ddf8c6637a71656f182778e596b71fbbb8b731d1db1f6e0e4232f859895ff38c7ac13a7a418041ba6ace069d32a3760098e940357f7b114430cce3d323c9ba4ba2122a21ba3d5e23c543d9562d60f48fb9be6f6b2594bf220ad630b32f3337442cb9ec2e6c93da2bde5293fe83b8044a21607561a0feb3e775bb821b735c6de1a31678c8383927b28617082f99c3bfe4f6848d2673126fbdb10094c669bcba9464d515d97fb134bdf03ec3f9cca8283684bde8e9fcb17b0240a640f1c5ddb01cb10f586d153a7648a9c6ec57f6ae8e5b87f574fae4a58a83d2f5dca7f0bb0a42b376f4049d799a4f3136f63a6e8929e09c7d84c59ea8e95462d396fb42884c1d1d64f6deb37f13a2a55100a797d48f3c34dcde55e35005cf8530361b4783af2dd2709d5d20b7257f562a726a9e787862f984a9159a1b56f3ee3d45fb0fcdedd9e7e9b62f404b49005d1ddba8989070735655dcfc588a53435533923cc05f6ed63743d19af518deed877e0b6456453448086bb256f5325b68abbb399356320428e6c80ce0258bdbbe6dd1019bf4a11ed3ab12137b33b4a56a83932df0d676689bd1d0536083012084f8a27808e91ef9e3d011333c1d06d26aef48cc3497cbf15a79fc4d210326db493e691d34e57c38719dfb969b00489aa54d7da843984b68508d21fa13426d6ee69dbacd9213a9b07d7bd654ba0d4da9fd16fae4fcd8741df873cf954fd38f3705b335482b9a3808589aae4ad6f8344fc0e4e9a0f3c20ad58bb951d23869f9e9e2cf8cdeddfa160c9c01b9fdad67dd00d46287c94bef95fe0a5390c5fb8ec433ff15b1d73509dfc98dd4e3837e07a57ecdd4b7483a5cd51d3e197f6834b648f6d9f26cc1ff9ff3a3757bb9b523fa66233f8534e1f12ebd65f84fd0355f52f8218243aa696fba7587d666f78313b729477283d38f4c23751c376deee59f7e29d6a521d2e4f53a613d049e20fe188f366a481da4d26d870c9d4d5da3951af83af9b0557f83af7d64adeaafb61b2ce1ba80e16ba41db60b06b73952b17ddca8351558c9f0a1b4d033fe74a68645332d43537e6c6507d8470cf414efdb3fbe129de7c7a0955c60fb581fca6c3a3609eb57e467033df6147661e180f2fcf5f371a8bc6ba8d3b783fd607c47a0b0b1d40cc100fce1716bf2c3b5b388a57ab44e37cecb6e83412365604c96fc9a324651705061fbb33c73630af034b205f27bfad663f85549d906cc8baf46ffee0c9746bd074eeefcae140194abd26e039210765fd4cd5308e93a052b3fb8f9ef6cca4c7357e779b6d4ef73f9640fca8d4d9ce2ae6a8b01d0c8a29e3c05a89419810fc774153df2b2a26493bb3481945729f29278dc15964c0bc20737a8be87b78c59f1ea13f359ad1a5124570e70babaeb3175e3bbfacbc2f26d02ebdd812c53a1a35ea17c7a84f1fc1446b41abf453822f9767a3474b43accdaae9799791d79d371aee4966fc98160c3b5ede60cb7b403af428d191f1bf2ad3f4328840efb5814aaeac0a085c00508a5b58f6c3b631fe67e3f2d43f32c6c25480802cbb213dcb63913bf208091b1e4b3d72b578e661000203f42edcba2e91b93595fb5f501888026ade28d916a118ad689cdb67312ba00251ce6596823cfd8581db0065a2c1e7a0399c7f747023f59ab53ccff5228f393c0dbf2170d01bb14483ec616d25a8f8bf0f2bd617ebdd19400fca850e697191f6becf12ffb5fa21fdc31b36af2cc0bf03e1587897b00a0cb2d3e4ff13d72e61c54f857d48abba44fd32e13ef9f93f3edf201ccc2e1282a31e685dd9e6a673928c5b4fed8f3305347c7f3335199e04ab032cfe0255d64cd3ca8ab3facdf8e8d26457ac28d681df12e66508bd86ded620a4ae21aa7a5588be78b90437a5d90d70d84f6068584048384809ce3a9dbb0672159642c9d9bf14df70e124a41b11b84b0d427657c2cf71506ca1f8bbf35beee27d48c7a6cd75163e3adcdcff249593ec6c4001594f0932d2e221de0d08e5db3fbd5d657d1d66857a766390447cc0e495dd9e5f610bbd639fa9f21d875bf660727d1d130dae9ad248d70a41b3d9d4e31c65ea142ee92147a58d9674d436bc8ef8bfee81d32b0202b37b797452e01ad86972b50b78147c4eb3e819ab4fda7e478b1b1a646f4b1074e77cb71e3d5b505c8c086831a9cdf1a2e8150e395c0b64a4e0ee6df39d137bec2a66e1598578f667bd0785513dc45dc7d229e226f5ca835f0b20518f25c1a9e49a818f62af2d99d5b2d5de292758ce9d6830ba395eedefcc09f214686312dc40161b25ebf5f6920ceb63ae64d7ceb18fd4b779002b1c03bb398e4bf22162ba5671dc4d9c30a4445a59f34d836c072839eebd667b5a1240f4dae2bdfb7ba53d63a6de30cdcdbe426619e9229908687f61480b0087efd41d8f7d448e191b2f63cf1320415cbaeb292be9b4292a49d01df89fa67dadb3e418c09432f36c61f19b85b85366c02aa8cecc314ffc17793729d9e327e561139286c62b64a071b83706b0595aa1813ba732e833eb9bfb2161f58492f727c947a817a9116382ee8ee1b2e66bf612a23ce3194b149bc9f66ca68f4ede818707f86295d771ca3eb12406995bef5f1c6cd791eba5dbbcc56479f2ed3425f0b25541caf0f5d1329fb8b3b14b4f10262bdc5cd4c4e7adef323e16abf88f95a88c3083ddbbc42cedb3c0109a16ec669e81bb8c91007f35744a3fce2be122e7c272d5f33ce1a3b14e6838fd2885eadef5f019b70d1ff547d003c8f1dd1cf4fa5dc9caf13207b9a264c3ea04daf42c706a21178ef23e8484116b644eefa027cf7a31613291083a2158a56f908768d8ac30e8a0835c2a14232d3dca2e8c0720436685dc4615502d2e8d7882aa8e526fe881d43559dd414d7714eaca09d5c7c9b020901710c477844b162688e6c2a5fe7f2feefd3a146fcca3ef025ac232656843e7a4572dd09305d3bd7e2b9255e1345d8dbf656f58dd8bd5fe04e9dbeb715f8c67445d78415ef8dde578bd97e098174d6720b46b2448defd51c1db2e61f64599d12e662719688194d64c2eec51e3bfff3258bd1b9e8905970ead4d76df1ab7565572485e52373fcb9cff799560f83e8391b7085e337e195220eb87d6c4d5c31a85b90b53a85749fd777caa78b9d038023a227d3d832fc8a96a012d98e3dbaef914d6dd2f5c1b3869dae1c7c870eaf1b99608838b17e069990e8c8128e31eaa0efbd4eda2bfcf6b60a4874a11839a149c33c56ed000499996146f6cc3acce8c0bdaa4cf7555edbbf14f41fa2f6065280ceae38e378fdbc918382093b54c043eb318b6a1f2e1aa996accf890d8d3dc96593a12dfcfa8d86311a9c7fc0d74e0906d31065f25606d7103c959ad8cc4002b09fa5e3b4750c5a17b626dc80ea8231cfe8b626a8e7662ba7bccadf97e84fc1f59fbd51aaab1fd2947e92f853d5094665bb27805bd56b91b1488de3940240df510c68dfec5bac2efa91c1b1c907c741ea57cf6adfd0d2c9aeb95628e0e0b94564a5c6ce745f3d2efedb66493a472dc5622732a938ae0881ab461df065cc92282fad30e3f641a96884b9839c6b5a53943f93460f42148750157f3a10adebb1fd47155dfab99a333a261dae4aadcf50c1c257adb0656a70930fb39afb0521be08c2361be1679879bf52e6594c3630a59fcf39ac1046b70b8505875dd5f66b5c17c728a25f05a948b476eae9f4ca7009e2c68d1a8e3faaac41d7ea651b1e1985c5675fe61f7499e835ee0ef9f3edcd692ea0efcc4e51a91b462745bc1c3f8d6f2569e4b4a01508dcd423f988a993750c36d9e81ee6e0b6687c5ffd79b787eb752aa92dfe16c9d44d2bff317c76c48b5e62008da25f2c9c6da6d4ceb25b2122978b45f2d8b85542316bd12cb2036dcea559d61fb878342d204535d2ebd2ac90f1293f789bab63b2b84f9043caf8b8d085de584ff15a89dcb3ec2ba2375c4a0e080a4168501d229b3fdfe215b58cf24aa2a71a295777f8a796dd5e0051d584d6296b3e32ba6bcdff1c064b011ec0462ab78c4461cd4e5964ee8bf192522d55019d6d268fdeb4caaa92f2ad1c36233806678b16c139d6cbbf3f2536f7acf2994895707a9a33faa284965b0ef0ba2e0ad6514816360412e0301c17517613b0ef2dd885b001a143db9138e483bd8bcff92ac675971b52feaec7ba9e58d81b796a06303a1a70d2d2bbed45b3acefbbd98838e5ad4825a2f68af161a609f4ab1936b97c367ce622e1b07d9a122586921e1e7bcdbe05869480839d0fbce79e19de357b79d655109288b00fe2016941bee05764f461f68d730a42f14a1194da4ebc134f4deefc45774896cac4858a19328165acfaea92fbe84a0afeb0e1b1c12a71eff539c9c31bca4d3625d97c7b20362313671ee2550f4b40f8446c7b773383b1e350d802f99780eb450dd69f1a53ae332e1777951164677e60c8112159acff020e9df4c8b2fe702fa11c458b4cdcb0f394e4c444d7966e308ac122163ab216104517d4fa708c05b42f663fdd9b4913ea8e73290dcf3b5dededa1c844e3e319e1f3df22207570dd16daac31042f4c9a04628278138455f238dc407da12b51fc6b5b16697d868d64c1a52baf42871b809b27a28f93b78f952cd975496f3d29abb991285949823371569c177b8c31021ea2bb4cc05622340880eb1a8f586259ca4780081d9ca6629492eb9e6b18daafa19e1b269ad8914e8e11a9df05a17e72e4fc45892cfcef098c2a764385369d943c27735b09425308503e3989b648980a1b437379dd686ea81ddff1c745c3dbe16ddbfa1103099390bdeba510ae84624ab08a64e4e2a9be3ff0f14d2d63c7e6074e57fa998631aeaef9bed66d9b525ed2be19376067fe767fd9d55531b35a17bf62d8b921df6690fe7f652b88f1bb203fc8b8e2e200b606a565d5560105a40c8fca74ee1e6fdbb5eb77dae3831f492c64f44e2a0ae68ce2019339b482486f6eec61f171574550c820c7c09edadcb7b8825075650267523c53b7abfbd7dc5b4d302b65871bb734f5b018518bdaf27da0cb41e07a79994769d37aefa6391f2d3331de833aedc841bb65bd11cc785a6bdbc99a9013a28434f95ed815c88d0d82f41f59077925045d864075e685a366dbe042d2f8a451cfc9e88453407ee9c4d110a71c6e92b76653e3be2ea102db904d57af8e289b2c70aaee9eeb2fcc0e36ea142533f2db03dcd8174e49ab465d7204fda5aee56b99c507b60baff4b3161e04c7e6814e781274cd4a624f2365d99b9cbaa8e96df04126cef681ce3bcfb9334668c27886c27c67f1878304b6274efd8b75a944f26835738a9baf6e5ab83816819329f8b105c1edc8976b0f6cf341cc579d8480efc1a86f334dc191426018c1722b1ba166153568e427d44b512042ecc48496376f61ce0907872e04fe68c708586e3d068543202c6a826c172fd6806c542e3b36140dbe66e1c9f44e8e06e6c3a033bf20006f0349fc49616c14f3980ec3eb0ae864051f946c4bc95af7a5be6577c845d77c0f70f1d589cd04833fa72ecdc2bc096dbf03981ac1ffd5475bf1bb83684cfe684b4ec87841522f0b0e9eeb30b1c75f97eb52dfd3d94c3d014dd480568577c14fb9d8c7841d1c54d6c671ffbf700ab6d414f3acd72a263283c0cdf671f723f447ce2e93ca39df2d1d176528ca71a4e2d7d0646b15839d2cf51eee88b9c7354397c4ba3ffeb6daadb2fdad2891324b17a37109b433efb825d63511786ee7270501d4624276e2901f77d0811f345339f0836b61d8df5eb056d6be8acc584fa147ff3e237aa6f98a207d7ee1caec6b2bae865bb3a7c9248905638ccfbe855e70cd48ef688a56c735108408dc6ac04f5eb4630ca5fd62f83cef119832d1fd14a35c24146e9e3fa2fd6536cd89b247da79ee6fd4b23c1c417ebd40b59adcf30b13aa3238424d4ecd4832d41504f3e8344caca279959377442157f04993b01335d8bccba17dc14047cd7b731d9f2e137023129ade1c64a523002000e6a8f3b4d5a4f48cd79935155c13509de86bbcbea346e6fa9a53abe56c3a53876bbdbb77fb6c0e894c0c24e96ed88ef064bfdb2faf9250619352ecfc8d8c70b5b4b720672bc77d78c63d8461e7c6b65026094ff57a36ee3057aa034e8d578a6c8138ad49af4808757c5d4578c12b4f36f1d8121ffb0c68ac22fea749c3034ca556bb559d4b7f77c176bba46dcd023569eb4496b3edd91c15cb679616fe954df4c44606bbc3ce3486e88cadd7c9be4b36348f405002efbf65a1163144f6f4fb10cad860dca01ff66b1f23596ac7401ce493bbe1608ce24315f19a14bc9a68d4d7a81c025070b09505742ec385509a3eebb6806c263bf6001f3d52f3d3d73968725443d2e98dffa27ecb0537aa05d36c611b32d1aee4777c76526db30dc3757733577ccca11189c21402201131e54c18bca17b68269fa5decd31cee568629dfdeffa33ef25b0453f2b438f2f0054f8bc914a06e857afdc881d4e91659f2db573c367355d67fa75214a2e131b97e8ee99faeca884e2b574b7c2cb29d331866041cef57e36bc1ea7476aa4da2882d884cc541bfd17516e6b7507973735b5a59e0f5cff02b8fbcd9326aa393530a5686a835e581d74a1e97162f5020598a7ac3410929f0966e1df8bfc6211529b1037c64f72bd32a191e44c511c688c04d047aa9105d716c3e05ca683d158c24d66f22775255c37962062345b05c662b8e2a0b00b0162ee1c428c54d042182e8e5473e52845a3d9c760626f8fed4adee8fdffeb957459818eb1f13d9d5ef830e331c593afe32c3c3d159c86c8af7061112d8c23988fc92c316d5750c0af26de50a338b78d7cdc31b229c2669a348a851608531639a5a7fb33e462127193403b7229cb7fbeac68d6e5c49180cea973afa839c8e620e215dae2973f4fb39351a2b1c85ec68237a47513d5f0618fe31b872e986c84455f8cb9cf2a63a63a98d2a8fc28c72429ed4dc512d8b32e2fb675e5d08fb6402b0c1d94ab14a410be5022c7496e0913864a99abfe9165ee065ac0d4f16d9494665aaa73fcecfa4a605240512aed131c7563d06101ac74f0b24e4829b9a993f7eda2a2e64b3ec0ab91f50e47bb9aa6238eb2bf396325116a197fe0d70ddcf777c2985b2eff4cce7c21f634ca61bca0973bd529bd1f9c9de06690c4ecc810e664ebdb7a396dcc0347061d7303efe63a00c0be59761ecceb57f6e928782825fe636e3e8362a62ba6a92645fdf1af242ab1fce4c7a3a7fa12c0f8c5b6e8e01b99a64b1e71dc59b183efdc520ce594427878fdd4c229fa8d08edddfb778a6ac6b6450a8feb0df1c64e7da60ca35a7aa3f31992fbbd20aa6a52b9f34b0ecf208b7a4518a4a2fbfa37eed0b775839b1af6637d8b0b83593a49f6da97e3aa6c6d9cb1dfdfd5acce29bbcca9ac11117bded350316cb18094048a5d5fc2b9dbb843b01c40492fb781416bbf50c0aec6f0dfec4f5e38cfe0cb0acfb8c419ae9d51c85738b8160c99a185fceb5c5e13631070af4043a3526e96a21d9c20acdfac12bb1de81502c930cc0bca87564e8ac0c51133837de7c899ef8705c797256515f6a69f4bc142526f859cbfa94557110301800db39ae0b8348412648f1ca924abd827689905976cdb2b5f42a76e80aad169de8aef1f2ffdef3bf78d50b1e006f1d3dfd30b42a5c7d31c941f51e03c09736a539079b740d9ce6aa5671b9c8f069f3e319d02da84b7ca4399354c904263d05eb71cc2bb1e43a55d0ff54880e838cfafd56e813a16fd2681f6dfa83035a2927e884419b45be3e6dac7b885a05d41bb467fb6fb795dba31e457630c954ff0a7dc5345ca6a47810358072772738d5e8d0ded8e5f994e52f4734a84652daaac6ba4e72f7ea0648acb28e40a62b8a71a7c41f390191b22993500ddad216d942f189a7cd74ae68829b604fbe95586b5727379a0b2f300e653cbfb073b0709e47049a570ee06081dc7551020265fee14770be458078f36d69845fb6f65a853e2ab7288fc82a4efff4312cbef90fe9c7e5fd016453cf66b5d79d0b6c243b20cac2f1ca7762f0e06438e01eb8cc3d841c968e531dbe8b8cb6ac99b31322e491ca14b8e40709661cf0d50e5604971d5923e601dd4684880610a87c976081896f2148783d4086abc06768829c946b36c9ad33fa9c1c2b489a79425948b1dea391e6a9602fcf5770dbf1301eea67478626f76bedb48cf6ddaedf8744f2f6be1febd8be212af7756f2c2b5da31a3eb0e6ffad8a2729e6d20b2ad4352aa9f0e6c284f6b69655ed09e9ab9309f93763f3d6d541c54d8f5bb1fa5bf33623c57e6701bd4c58b45df5ba0a78691ffb57e0844b9523336d3a67897780f28615cba5419c79b49f5253275e266bc36524fc9f2ebfda5287b77dc93bbaa060bb5221ed51a7a9a93381cee62461a4401740a193bbc46b667b6dc75e2781627b4b22dc3be1dd98056154afdefefce4969182d11bca04ff736af197f3b28d7e702ebc18ee1aa790b01b13aa8c2e422ae016babef2d88ee0a2e076fc3059dee3cd0318b6d7f2be21a80b2a15a7cec609b709210877e6fc0d084776c60081cf7187b6db0937e22853b1d2751fe6f6019876c481f90f4eeb031f430c598e5e8fc613bb6c2126240bf5105344421e98dfb3eb2435335d889814654b5fa6316dbc8fcf0c2bb53f0e7f793385447f4cb1b9ce4c5a948596e56a1dfeacc986ac80ffe6cadcedc9fb975d58e86e1ca29f902940106b9028f391c82a9aeed6b996cd5a97a67c7183188b119f7b4000eb10b352dc92e2f1dd95ef6757a26146c0490bdd219f92a7fda52aaaf7f716e8cede8ea11a1ffce85fd458be3c8626b947315f5bb690ffbe9f73c999e6081b21c038d6889beb252a8b3bcea6f9481bdf1efb391d0e351b9fde4ef8683a019bdc5a54ccae688b85298ed848e1f2fe238ed6369e580b339749fba85167e345a89f3178b2b9b6cd9d36958226beb460e0acfb5357bef439af4404b2a678a6163e9123138d7c8339a5486c0e34c148785ae9d4b9edce5baaee5fedb7a60d5a2fbde2f32cb4635100889101cb9fe2c5c9164e6dc9e7a6b74730944b4c4b8a4d1a3d58e87891a71be441fe3c0218b14475f87285c8416ab498dabcc295d9f4073a92c8e1adf26dd991c7e4b258163d61f5f0f9dc9ba4b16289e1924ad4fedba890fe674bcb272fb4a34f45e608bfbe0e6268acccbaf8fa8ae48ba84d3dc3991719d32a864df7eb4f89828e7c12365f05f06627dd6ce24fc572354a23a76d92a166db00f4f449238976d410546cb52f34aaa999e93e5805171ce364f82b3bf1cb75d45515a76ad4a6073381fd6417d696870dce450677a28c6a91214976b7c7aa3544646d317e595dc71038f53910d9373335bb57e4f0b2ac64ae4071960eafcbcba9eadc1e69f71782f2e46632a79b8069ca1317f1fcc3f679dcb566298f5794f7c765afb25cffbab76a6738eceeb4c685bf3a56473a34837a39de1ec28c61a4bfba487589274db224147cef8726f7227a9f735ed9753356c450d7f3d9861f0b62effbac056b55046986ae05ff912971049d657392f9295625ea3ff938d125e8632c118f4247e08d0cd211d145a7ee3a88d7a9abe7a5406b0cdeac99f27eca05156ce06891d2288b30ed7f22a588e4c6f78ce2b1936cf8e8c689d34f91eb50206b91eb03aaeb5c808c5ed4bddecfa31d10cec0b54292161b19f69f92ed50659932e2ad1811e36db32e2ce23c8b0c688cc464a5aa550283c67c9b296a705a3463635783f0af7c5ad66d50a68927fdcbad89fdc8ec8ebc428faf3a9772c024b7ec2ddfdb70e4f847f17a7dca4df40fa59df8d9b8f76153768829f8b756bdc40e4182cd78e3eae1f5a1fa1979e49b48e596f4d411dac3011ebd5da94f2acf0d0378ce1024cd2b78864f26a808c3ab34f27d9a0c3558e16dc691fe1fbd1059fc293390c8351877583f3f2b930448c4db60b4bd6013ddc55357753c35ee7b60e310d26c2a46887286279801368f46958cc36832cf463b83b25a8795c5bfd3a863966d4b094a8efd792dbdf3771a404631c659c180f0541e8fb006f061bcbba5214b2ff9e1ee4c3172204632541bbd1c0d69f5435f797795de560300fba65bb025838622a753ce148ca0d93a43b77094fef104f1c3c2a7802c2857c067997ea12ecc5ceeac6d5112f5714ffe96a8730a7c5971b2891adcde8cf7b3065e03a43107b247834466034ccbae0436b7fe9bd61479b7e38f6a11c5f7e89debffebb4629ca09cde7bbed0ee65fa68e08edeac0e059d23b045fe3219a306259aba1947146e118a231245cc8f86dbcbafcd620fef192313c91012eff77c31fd1514c84387a79632a54b2a6153db1925ee1969ea293c312d17ef5ea9b3aa9a3292222890508015a854ff23a32e734a52297075f24c134db5a738fc7368fa415fbb1f9f9b10c874b68c479352580c79831f0f7e85a2e3e730f71b8723f9f263885991938a84631e17949bb51722d65acbf38dd5b8bd3988037e41937d056fa36f669aadd3a1b21d3c324a7047d62e827a21d2dd1c99bd7d71a6a282ab6add59f83dd4a67600f210ab57b93a84865eece4d1fd1eb0e900cbb44b706d7e6167b662b2b5429780a28c0525c246d196d4e07436b4807cebb19ed030b151cc05ed3e9095aee865ae8b52c10393899cca8d5950a654ca0951d2448f45b9a546c722355f38bb84b18d02c0dfe889cf7686ae5a64d70845223af1c89a4b00c19b9f02b8c46511d8484c26a5e508e46a96db098e51c30749eb0751341320761fa2c123c15c69a26416863e7e8e281cb742ecefa72f32b5e88ff15a42711ebdef583b9ee26a379bb8c55739acf1351eb2eaab3d291d95431c8191a683671efe0115030124cb8a70a2cc5a561b0a90f4c943e481c1c0030cfbb1283165b29c916e0ebeff73c74944c7b4d5798aa2d5b3d6b27fb2ebb87dde81a41bbe346ec8e95e13b6e120a513420ad47a73f43ec96d6093f9606f2b4d8799e90f4f957b1306aff69274404b0fb9a6c3ba00de41d5e0b2fb605a0f1f1c2618536efa19865b5e9b4a61097db2d45534e22510843c1cc75367f6c711a3c80cec781373c4c6aadc23aca90906c7479018650d1e6ef673fe8c15ed3b403fbd0748e6cc3024cb7f322ba1e4c5c139dd7c12987e570d7b0474bdcf2d06a4817804984e05438f017933bdcb80d14fd62a16054031b72c26fd9954dbbf867de2f565fb65906e4ddccb8f9d79fca6ff9121c664a2d4d992064656e054e684db685ff3c89124633edb1b8a075ef7ac55b53806cca6ebaea8f2c33286c1ebcde8626731e84ac7027eeb3ab71225d5406e61bc581f31a11528083f8c3c017281e707fe077d7c7b1c421a7dd2e4c9691cece2b2e9a86d826ef76a7c797f588ecb8d1e2ad97b240ff40a054c710a50a0311cece11d90f8c13cb28276a8f4ba105c561f38093664abe512e1bacd561e60404c7dc2d84488d12f1e67e07c76a342aeff82d3d0d7084eeda5a707833b2d7afa15f04f8e8d02f03621f979bc52b5921001adf4fb679d1bcc93ed60544890cbf6ff13880978a9d9440219b8f85961f721f57f28589f04ba55335997ba0ac90a2dd44e1664aa653539ecdfe4ddfd2b53f4e60892eed2dcd521714d0ae6848a24f0ad058c36afbe47f4f062e39f01149374f1612df8b7d40a0de8dcad2f9a4c703155048c1aa9a6dac7deacdb5eb99d4631c23675d8630742011643d3093a11d70f3a19356e8b2359c9cb678ecfad821e73f64b7e1d47f382b11aad0712ad1a53856474416566de8efe74abe27c31816a0488cef560982f161b8eed49e67562d41d4fc03d021cb8a3b608c1b9390c66db61bf0376a3b40883eeb9adedeb11efc27ae611df07ed1a503f2962ed9a1fdeaf56895ef1b7bfffa81d4e8fae85b4cc1979c9650fdaf2a1d85828507f06c0b74f4d8924dc15afde7d5d14fd64c4834a2017f1e39ea6032dd8b227e1bc8a1b10723e0e46dfca212cdc276d59c98c47e693dd65815a35b75d3316afe41503495a1724655512ee13853e49d1977226f3c5d09ae84e484640f1ef455206610b5f040fb0d6e8e264553abdf39d1c27bb3e24bb83399b8d184572d93a3276cbfe6bbd62e0093b482c64e8d56ce2f3757e140e7e316027559df1a370babcc9bacbeee258f4aeb2e32f54230c07e21a9e502d18d7810059f3dcc2945ffceba1039d563bd8b05d77964aabdc486c0556a2947183821b02b4faa1e25fe9475e7bb769474a2e60a6103025405a0989adda4cf58b572cfc58f96c2f6b17060c96ad62901cf6e510799d38329e6817dc845990975fe24c4e2af78837adc7ec3ac2e80d2057e66e91202bd53212616667874d4c6477c034cc02336e1508b5a0932c91c89c79a2ee50ee15de3753af8c3bda14fd96483d320fcfbdce7daeb858c2e664dbb57f3f73e0a740c8df6b24f7aa9ce5c1c6f1ba9c2cf581bb4e79ed944a9487c181d5ab2cf88ecc3d34803d2bc7a7c7d8d015eefd070fcfa3071f3c64cbe88d1d93c4334f7ecf288120d469d4f408ab796ef8cbdbcbc6685dfb244244a255b4858565ec64bfb650bd4a6b7018cc319ddadbf60e8ec4e3eb6b11f33829aed4b11fcb8bf08a1d03045f7d782b7ea79afc27457ac0ad14fe0ad7b53ef2bedb370d288e0152fe63c8ff05f760fd183eec6b2000abb7b2e6a99ea24d85befc43326e234ea51677f03f8b9644e8fe97db4be7ac4b37a7215fc0db012dbebade8d644ad575c538a77731ed1955fd176b12513500190d63ea7821bad6c9a116fd5136715b1111c10359a7f8a8cc8b9c995ac6399a0b343e78cfd0808a6b91a3861975c5ef872939da4fa73e1c3696e74769ef2fe5cdadbeeaeceaa56d5c1abf85415246bc8140073928d1dfb96e56ccd4e5d7e250a0ca2dee261974d1b4d4b5d43ae2f458ecf666d7f6a30046dc1a6915c6cd3607cb6c0d688371365f9d7bdd804876a9478aab2aab4ed7241190af5c7d38c0c86c6448e0fc38cd9d89c7d4ee6053cc1c1ec4c9cf6b3fcb975fa6fe2e5d300d890a49bad1a423331edfe2c6678fdf5a218f9070d32e8812fa62754fcb37c10e37f12074207de36b91302d14cd6cbeb60959f3a93121a85140fe063ea6bd47d907b217ae78e4f83343a461d34e790cbcd6633254d1d9ad9063b4837dabb4ab8e6bd1d3eddcab434a7faac70e8ed0aaa59d4b2ec34edfb10d0378bab4e8342ddb297889d854a1b251179be36082ae48d92d8136f66b712777df5b0cfacf761446e57328ed3d97cd229c787100a9e195186e88427cd16da787b7d0adac8ee9b7c4a7475090a4cab20ef60a50919ca7716179588a6a0647b354c49043c725f46d6fc3492f3f38c41d86fe2d9682c8a0ce428ee4ba10b640a75a85dee3756dba9153ed931799826a881abc313e08de66aa0584735099e42e247c7d85acd676b37589ed0a6b490771e8f05be1b02b511c74500630843f841d9ec8ecd90c59d0d31217cef5cc588097363afad3e949c51c19ead69850c97df1d89b7849fe2d1b117dca3e9fa707edd83e3aa5010296623c87a3f11de7355b1f54a7fb22ca2162777452f478ac2be76b87f9f7a0c9fdb0b4d5f0f8f00d3dfe56d3d0363b7ebdd5c951d8517ae4fd90bdbf1254d2529c23d2205ff45e5fedb172b231426450714e9ac72126ac35e25ca4c3a5cce4c59d4f9cbd492fe6b2136095a058d620890009d19e0902e0af77745aebf56db5d5ddba3877cf95221c0e7c25b0c54128312cfef50239bc3a8036e73df3731966460724468fe99f838fc77d83153c23af47f5368005026526bb9e3fc9a5ae4fbc024ca2caf2ed9f024b0444692bb2d5316f857344a124700df52e97d6893b30e134fad78472b1de65e0f3b72dcd279aea8b2f6cd66e53dd9a0f017a51b6acbce5a3b436e5f32f4fbfe17c8c764ee403f4aa8b32e0508247811f2dbc65955a9d8e816ccd1c9f9527735e492c2e2ac5a80422712050faeee4b7ab2e21c8cc3610b9b661812b6f06e54c3824d2d14ab17ad0db98b2b7c22be5537d2d6fe7ae41ef68ec67f3888df901407b173667c7f42cdba94b334aaf51943ca275c14630439b9920e28df8e0a64dca05d16095438f6beebd32bd723b978d93a9d3428efe82d5936c089ea72c18774a36b733be40e461029d71b1297d372ccfc85aeaa2dabf742b1a936f79d350da67968474d6ca3661450d0729486fb279faffef751291f6239d95d791234cf2a784b438947c23437f9e974bb5bd5da16f4f5112c249fb122bd0bd9bf9dc1808de1eba44a884f7d140e7af77f30617338a9166f4e3e956e8f26c1207e5370af0be88cb97d1f516eccafb0ea0d33d89b75773cdcb2d334f4823ad9d4abaa26db764acd717dc7622612ff43113527f247439af051a77940183d6f7235515d5f9dbe09ac8f0f4cd584b348bcb759628f08abd43b6c85d07e3b737dab0c385d5b7c165ac996e3f0c1f90f3f80749e0ffd71d3f5ece0368f06c47a64d7590ee0ca01981c3dc5e37ef6f822b353d3c16cb73469d2982b8f868043fe3a9e2800ab8443f3ce971f9cb554f859cd9eb538708f907c2d92b929035c4571fd8a7b44fad1d11e4a74b16e8b29603efb714a5f61519d6f8aecf24bf7d3bada2ddcd71a4fd74757d119f058bc348d606d929c93d50bc42c6abf4da918b22184012d635e3979357c8335140f03e10cbdd3459acf0d1dd09b57336a991fa75f70044e8656c79032d268235ea20464755e7d3a012ebb1c995236065265c2e29f89ca5a495c517056ad9a6383c2e96ef72ce0866a5ffa8a2a623356a3fc167c3afd13770113e4ab0456b9b15ff183e181189082aabad9954a6327a85ea01aa7f607d8ea985969f4b4eb5c6dbf0ea78a5f4fea9ed5640350413fcd5fa9d938d5e4275195295a01a28b2f6db8fd1e5168f87db9f25ae9fe48f379b9b8850f2eb3544e92cf902ce4e0421438b02b39a05e1d95fc9543574eb0583bd2961a217dffd75e5dbee5c2d72c484287ae39bad5fb5b38e7f43b6ff815b7693fbdb219f2d9822c376cf84861a52ba30d81ea95bd39ce93c35e146350f039b7f6b16c873e1ebb960ccd367ffba40140b7c38379ac3e25a34a3d926c7ec1e167681ae04f1368c26783d25c770dbf71a278c09e7f6f9b77694067a642081e03794a5248bb0dcfc32247b77ef585b47d00f1b9ad5cf560ba8af36528fc30cae9eb2e2a98c729f078496eaca04b3651fa1e67babd6bedb9e02850cd5e0ae14a7aca0db8dc2103f9ff59bed0732792fd358c0063acbfb264bc573fc9a77805a2270b1b59ef9a83b69f379a0fe6fa924226121a311558ad9908667b8b3bb380155dab82356b61cf7d287cd1c4001ca66335106ea29a5262a1a3e66c830c0d6cbe4bbfb269a1e37b3da65022a36957aa8e21e1691a48976d59ad7b1e297444b18317999abd2ff6b9f3b91c0a05264d75671806b566e073a87b56d53ffb2433af31590bc7e776a11548b663b21a71b15995c3a8edf7b732d67afdccf64817c9bb0d73d33c4cf14b4a074ca66589b75dbb6adffe1927e483887438002d8f5b30156884c791c84a34300c3c670e0f753f7c724f035277954a884581517205feba91cf18bb94ec1daf31f1ceef6f5c334841829f5d896bbda59c4a3959877933a8265a57a05baa3dc01d73f24bee1da43baea1a8416daf7a69a8ac2f3764009f49646d705d58114bbdc8e1d335ff4e85d343e37b08f1900c37ca704c59e47cf501e4d89af3567d94be985cefbaf7051f1496ef370e1320cc61615bcbed80ee24b249c913685691196012957d6800e9160404b94b15ef918b6a3a458ade3166ed2eafe243dcd296987c3a994da145dd5af73ab99ee13a8e36a68953af375940b080e0938318c9bb00534065cbda7867ebd572a9d7668e566ef2bd9d4f319654445e6a8be473bf08971eb395ed0c179dce78368cc45ebc2a28839b636c3ca1b8d215bd7bb13c0adb5e55e1a0529e6bd95df35b5b972131a3064089a063b53f72128d33cbd13ff27402f6ee860afeaf634894a209bf020eea6883bc321ff4e386123f10acd9c001e13bc49e6de7ce3785421e052cb11fa111452688b81087049d52f05660c77abe0f560cf672caeff7aa5561cd355f2c676c190130ba3069e2f91b927db850e425b207898c638b5110543cc050ac4625dfa8b4aea466cc6565772bc85434f56369bd429732fb4da3f0ec82e21cd2819c10f2290ddbef13836038e00d9453ce3e84603ab0714fecf4c84277e19a17da9ada31abaf8fde8df7272b7276805dbe547b1f57649cf1f9ce7486aa15310ed1174bc33002167b4ddb7d2fc5a4e61114dd20f8cd8a394ac6fe0cd00d1dbde9aa0d9495f4e0a662d9cff8e217263382b9538ebf4776e5c09152ae5c9360d89a5652e6ad5df032cafa97558c5abfacd485a9d6b25e71dee906618d0d4fd6debfff88c9acf117b6b04fa83434030bf1ce297a7147778685c016e9112c7280a089f68cab1acde3c941d29060c7fdc62e891bb6ba7781e0bfcdabcf1230eb41f6ec604cd5095d6ba2683a1747e8e1886caef23179c9f10b63904dd012b244cb8d600d14a39e1003eca465ad92520b6a18da20536e89f97ca59812d0bfa9603f6d896629849d8e3bb544ff34b83b3d1abf7601ef49a031fa5e094a100d21057c9afb6a337360e0e57df974846892d7f5a138246a174b236dfdb55f2c2c3aa45a969ef440acf5cd9eaf853c4317ca4e84e6c0523376c58b40cf802579b721f98c58c46113f8cea73f40913c89b316461ed192935b0479b65d2acd4ff6f70c69eb27651fafe02c58dada0abd210fdf365d51b934f0d585ac976bb711b6b48b32bad744f6bc0569ac26953e80034f3ba12f9964a9f4e71b261febe0b748ee6befec74f9f787166deeaa89793e01088a7cb69890df3b75357268b94e9201408ca755003b4f91f0f8e66d2c461adc82db7e6f3a108e4d7dcf03e880a9ecfb3d23c5578dd8d6851ce103b7f0cfdc14f4c0eb672b469f60125626384e7f56939139b1a8f54905c147b96f3cf5b0938fbbaa8ecf55a31a4355eac563f63603975672f4ff8f2300fdb9fe18012e1d2bb77077acad29bef01211c92a5fcf233bafa279416c607b7a9050a66ebc7b581773c6bc34ae3b9f3e239386a45e1102b61b20225dc11744305ed831548fa7a3ee02fd40993ee9a1c658e95afc94ad454440eff15f9bdc392ef069aaf5e0a9853c043ac70227ce14fbcca31c47eb9260bed511e99dec64f779b5a1b533736b53e708a9210f86e531b3c2609d219c23e9bbc9e85c4af7682452af903631b3407866984a10733b527d9c35c670e344d2d36c979dbb7038afb41ac1ef62e1fe9ae70c3e3e866fbe52cf5a22a6b165c961d891205e26ded039eb21e4c55e1c816bd6131b0bdeee8c404d88ece58a2b9b538cf6cc91472f0b7eb4c75c5fcf799298219658787233acf247e58a02301e54d5f3a25085346dac4f35c81e77cd240b8e0d0baacb16e99b71a27e5f3030259e47d6b2fd5aab5d34591cb8cf8424d4b9eab35b954083298dd8eeb225d69406eefa6dbbda416e4b69aa3d64fd23f77e7bf20f0a354f185158d32afc5fc5f454f05cf3e2fb5869c96431f8932e959077cbe7f51f28c59829aa7772b774822669969d2aa4c8d35e9706ac3fdf998e492d84285c7bf3c4b0b22b3770d70372a281c77ee7bf5681485322cc6f16b1b349ba8e7ed7f23c854fc20996a9accba0867875748a7453218b1ecde405eefb2a356500e703bd7309440dea7b68528e674db80a3db410ad93037e43842b140614ec3a356f42452a2f4f9d3c472e6e4c5424687f2553ff5c931ec53721196b1e5d965b393a0d6f8b810b69b676371183fb9324b197c2ba43329e45d291c009c7ff9270ebd384162047cd942779be6dbcb07130ba62bea7ebaf7c35d2a29d111933e19157af31bb5f61860acf03011f4de4af3bf52d37c6d455cc79e85a6450bcb771b7fe79ae7623287601c5ccb3efe60453bb268483cbcea2f6807a818a0a0a8b9e1e1972209de3fa1288aa05d9f775a7cb36dd2ea602b907de8dded579d94b281a15eaff90122807a25b1c009831dd2fb952319044703727e6b608bb26b2bfae43412baecd28c8a209e7a59fec207d3f756f4ea719f80df0e3a50362a344ba2bbbcc9f2712b637017a39e114a86120009ea3457c3bfd1f02208862bbdbca929b2561141b52e003badac0f1dfcb4a2ebbc261193272d7aa5df1735b5f9511bf307cf8593bf2deef9a53382e005153ad042edad5234f068312f6d890db334fe2d05454346583344789eb80f4f43b401b8bd5fbe6310d4d565d83f61547866082dcc923942940d7f7383cdef4a2619006cb4e480e3fc214b6c5234c52aeb14f25aa2e63b3f5166617560d0d1cd0e82593526aa5df983bca128db3898722e9e536ad5064a7f4cb0210f3a9e07c92dd61f769afd15ec05c23eedcfdb229df0c189085fceca4b55c5ef091f5fa05c8bc5fa3494fda0473578220f1e758686bd8bd768ce73d1fe77de160b11ec76d02cfca0b4b8511c112128713b908897555f6e56b132d9b3cf22d51ba61d987572a6ad0de2166fb224dcb2739f07eea485bdafd60824a7db4c6a0ba0d00eebfa27a60b547532efcfda0ad20428ca64e4aae97cce24037f1da9df70530626ad504041dd515ce701e22fffc10ccc295da5bba1b9af2a2ecf06eec08132baf9384d1227feeb7d8ac2a97519ca14784d12c7c6ca5a6022de742871010787354b897043588f97f9851c2a7548d1bfa125a42f0c7ac743205eb0a349598e19ecd132f56029b93ca7debdc8e444440fffe3acb4d6d6931760894d0358cf549ae7883cb64f74cece267328e482281efd4063364975c6e0aa88219aae0d3eaca6c9ee8b7cdcbff4bda4728166764f44dad504dcfb6d8c5ab88849115aba8e45d9106486d2a85942969e741fdc37f578b37ddb89d6c01b88f73b2127a0c415f5e69ba61d0c5daf867ed239b59f57692d0085680ca7e8be4cd3e9af08ead925d90feb2e3fa471ee2ccfb5ccb132059bd6e499d698060ded721a90b2ffa7581fe8c77b593298689801e4b63a85b9b4e41931e55718293aa93ff1f6d37800fa0dd610f7e40a27a6ef9adc7f47197a0c5c6f90f1b99d9bde422356ad4f1b5589315cab87f5d68ab54938d86d1996e40bfa3771b78c46ee9d34994f8eefe0a888957ef89d63161c3cd647f2e8b2fe0a4ba44c848035e8dcd810162fefd1124a88991f3f4a1f546bb008868f237496e4d50d1e9822bb715a2e917f653b53567764d837552b5c19ec7e55bd1da139d6c233b4c50be8439b523435af23157877ba9c1e72ae790718b587044bec8b954335efaf265a421468771583160fa14c902f1ddca281e96d171f861c90edf25f8e1fc6f4f3c6eba759cc09b315acf9fed06a70aee905a71b386d4eb53a2350e098f4853f03fe216927ff3a174b87acfe51193bf1d6acd1d20e7e1f5614f74191c4cf216f199ccb394766352d89709255b78a967eac08647780b34f1e8e0af79ed263cef8c157deb134663e2697fa7095d61d38af413e4e990dfe9be203b633d83496fad346931a96dc6a0014cdf95c46291b67d09720350dfcb38369daed9b810d3beb28aa7105345056a76698434988868fbfa6616a73a55d93f620380be159c3fc1cf3947988d03ae4bce33af178f10c4aa55338db29c6facf6b4ec7c99e3e4b3261a4b1777d85b184f38c4cad8c82fcff99a694d27b76112a5c3e8d283a7f898988b988deeccd836ca45b6983f6bf0a537f20ce69c86d2349ca324b40180c0d620b655d71ecc0779571603c83c51976095f6bf95bc19c39b5912908738ddf8bb7ebb150c257f87b75febda064d85a5b648e711b4a30e2e03a4e48b5f8cf4e76b940e27ddd2aacea5928b7897e107dd3449b4a0d5f4be888062f18cb05075271e8f7bd64078e09e7987739a501d6d21d0ca3cbdd5e9994bc7f71258a016c83e566234b7e717dac3aa6578525bba3f9cbdd8641a02f42a91c1f64a4c8c1dfe96ec45d040f353b5d5558299183a9cb2ad8d4f6fc16dfb6d595bd4c9243df47485540e6fee18d9e79ae1e71e4589f4195b0d9c095ca778d00d7cd0e0772cac34cacc4625ffd2caad1986acdbfc898e943b156a843b4f1b923d297aec0270d5d95bc20d74d2c037c7e0d1a66228d11c1b3cd68743ea7f48756b62405cf0dbce20c63223181da3586aadb39a01e119f4c5ce818a573875f9904d7161607baf2050d9ad9d72361605dc08616345ce5decd6484c18edc8d68da9546e589f8afac25e76f58db50f89031d06b622006d5af94a00884388a4ae307250bddc33adad7c141aabd3eb841ef3ef56e013522ab0978f7a80e33623314de0f9dc81e68e15191e9c3f543afb709c4ca6fb47c8c1e76e3af3665c3c09c988dd899c101ab3252122471f1fc5c6d0ef643dbd38fafdb9c452a0005ddf8344bd45ea14b200d71f9610714960a85c35c28429080efcc797a594cf025768a82a9f531d17b79c89a5a9c00d3573628a854af28149617eda725f3ef3b5885d6658d036b66808bc54cdbcceb85bc831f26682aabb45cce39d07675c90cbfa5a6a76b339346d0fdbdba9bc2415ccb5897964e1c5f165e78b99be1e81c588fcd2d3e29555c358588bf6e7f381023194fc87420083dad238255933ac5662c6048f61aabdfad9ac003aebd0580fb0764a8698427faaeab8e113bd20b632dd0fcdc0e949ee90f860c65b6e3fbcd80ce01ff902970107b902923952eb5311096680e998f9d6aa038dbfa4ed2d8636035e34a93953630d36c857630ac09af0f3fa1eb116347a84b4ece6a4460ddbd798d55db4361a864c9ba0f251f8ff5ade08ccb97cb6c9e9074b548d622a52c62124e37469e81a44475a433f356e20aed158ea2484a6ede3a639b1da778a4f2cf3a959121f2f6a53ccb52aff72dbf22de828b9cfa84bb52faea4b650d21cf5f01407713c681aace4917da673f7894ad5d2bf5610feebd04bca76e59a4dde8dd27542c36cf1fab5a58c63f8d074f30090328aec84e97ca0e7d735005b7fbafbed934b04498c3b37dc33c809ca49b09d4ed41f8a5d930cbf5621145d6588f91ec637c934b4c972719c78febc96d1f133e64666fdf4bc894b651162f91d54016488baf364285434467f584c963c9b04fcb78cdeb684dcea08e5a97b8c26e3fb58ee4017964ba7f0cbbd22458b330ca11ba4b7dd7f4ca9cd65d348d4851b8f3094b837eafcc6a908309046e866cd46c345d91ced5edc785ed7f35a7ad0b565c4b0211aacf2fb3b5988bb3d01fe4e79e549a8e1a9f98676295e21ece62d4ead9a06eebf77f538243b6b7e715087a386e3509c1e73f324d56ad5f61e3b18aef4bd2bd218f26372e73a155e6298fb9ce94c5327e9ceb49d555b89617d922f7f8b2cb1c3db4835f11d0de4be72a44da52f5a88326bfd8e004a1829cce097619fdb1d6a732bbe557336986aa8cf9be5559df0182c9c09ad1015d1a133ec593567ff093e6d788bcd55483495aa6a1a918320f63d6277ae7ed04595ffc57b9159344f23dc43755e08f9818e329ca465c82ed8e8c7719b20e474a3760f3ddd468a923e91278f63d5cff446ba932b9d7cecc946f0615d54b509a3cefe2dc92b51b14e5d7c860d7cf711b9e63bac9982c37eb436ba4c533c7a10e2d26df35bf59a79a6d290f91eb50207b91eb02f2b6f4c7ea8b973bebeda7b6a7a26c33a7bf549c4210aff27214e3d86a24b38c3aea489e76694c64255747337b4becb6bb24341882e8b952e6a75bfcd1a4c099c1b86112780880c5abe1e0c25b57a52a6c03b8cfed62a8967e87ce70a616dff679dfcb9f4d1c2c39f8485988fd699ee337fe81834da92dad7c1b324f77b997001d7983c07d9f2ffb7cbbeaf3b2493c96196e55a4106759704fd2435bfd155acf94cf4c769d11723311c237887a72922b6c4372f049b097afbd458281664a499603ac5cc02996224e765d64c6c130dcf18f386d49360f406bf84be523b9858c3350c4f45215138e70b1cf5d0d57abe5ec072d926410d60c62b8ce7130f4ab052061e2b151aee589e4fa0dba48052c661d8dcaace6d707f1066cd68aadbcc523d07ae81b01cad8dba21b6c09f52638fac23a4d4a1d6f02e289d558a69ad2721f2beb8729eeb545499f81608fce5ccc1d40bb628ff646b44cad8433bc93c17a6b8593009ddd6b7009dfa813a11876e23add3b7aab838e23f6d514309b8f67a06322bd83ab4e79ee1e537eef28cdb3f75cd9ffbd19d7d43749c10b34b3cc52bfd0bea1f80b429402b4387783ebbec587c8cadcdff124e7ac8739b54321f95e078d6251313dc7092aee4770bd4e1d3ed37bf30acd387dca454422ffadc0ba9e9dbf2738ef2d6b0b9b6af29ed14e0ffae0246cdeb82f99266c0fccc34d370e9c3b7b0eeae6698116e320cb0e262523b72cd531c05d3e997214846323549a487f9009811a321f1d11293850732bc9d6fda17e00503d82d6050185875e02857e992f694aed6985a5b04da8f04700e096d77492f2661ed694ef1be3ad06471b02cc3d107404be5f8d496896395c092b8d846ce2155975b526f0904e58f72dc6a9a5bde58dde2521d45421db0400f9956fef529a9d82be2f0e000b1725c33dd423891005036c0ada23f3310e8d546b75573ae211c47825dedab4885534487f1a292352d971f9137c9e28e745d07655f9c9e1a1f30a289076729c7898a55b9e71b7c495d8b0379f4fbd3979e01342b3fd6f17ea36d249b850b9501ea66876a954045575638ed81b34b6be2501f9942fbdcd396f8d6ef132caf18a706c3bb9c0e1cd44dc210e4faa1c5d94fd1c638509e948cd8aa15ef53f06a4aa86e6d626ba68eeb0243675f198ddbd18baf06ba3317df366fc921cf40f206bd947cb03b90931862398873121ba05bc05844cebdad8adae276dc0cb348d1bacb3b91248687d0a37ee755f4e5324b2ca34a17f323e4325fedc7d0bcac0c4f9cf5ece900c32a69dbb1d46f3ba8969b76cec662a3ddb6f36369f2f35f1692c1695ec971fadbad77e424cd314023dd476f4d3063cb0bc2e61a992dc49d8c92283f8df21a352c9909743e9636e0030b3758fd73fad72af7812282421ebacb0d9c26f92b06a2ea46a8c1f4fa58662decefd20c34d4b0488f3d6bb4c9fde52e5966ebd8c6b78c2e7bf399b70c208aecae989f53d77b1dddaaa48fa21ffaa70d8de2c3f1045a7819e0a4bc313b8b0036f8979ebde3ea05aa476e873d4ccaa613cc205a6bd0bcce7746f985302c66cda550bdb9d54fa8e419b9b526c622acdd5860957ce321a7cc56fdc46605c43d46b145ce79033a2415605460a10f9ead505dcb04aecf6d41b1d570dfbf65c8f2f2cbb2e3f91d0e30ece63b1c3e88fb2d9d38c0b53ecd7dc79ec70361d9178375a75d6066a1ff91c33267803b85eebdef20dd614c7f1e2c0849197d2aff0e2a472b65898b2569c9160ef1e967bcc120875db7a9b50e46dfff5c25d00d8d988e5774d3f26ee7459606d3461c1d9f501334218d006069e7a5b6cae9311ae8189e7eb5f278b9b424d0f4fec27a51d2b632e0f9f1dd82d4716da5a994639f387d8f45ae0c7a5d90941a46e80727b0578731f7811015f23d921f674fe9685c3af3e313962263e2b0bc285c9ed92aaf55d188fb304141b35142bee04176088168928f9fa1eb4ff56831a9f2f8448698b8cddf6c58c4f937699ff2999f6a33bff43c221e82aee4bd998ce24e298993b1c4d0d4c8ad012fae479bd82ebb7260080c2c457a0490fb30d064e84b5582557abe43b09da71dc8d686bae31d11029f557fb10ff2320f87262e0cc5f0a6899ccb81107a5509d178eb6d0b2132c945ca1e66abe02e48ac08f824ed6bd61e84fd39770ebb44faf9fa2a9cb392f82c35747b1a5f43e7a358bc8aef0143e01dd6a4fa3a5c4428886a90e9637453b58ff0dc23eb32df5e1db5c46644ecccaa6a69794479894287c96902b1c84eac240da68bc8773e5e670a5581f30da26e3fd7920d9310586daab00d26e7034f4c5000166912661a1289d834ef203d1c9c7bfb5d0caa9caf4f81d4617213881f7a52e9738b9d89aedba4bf503629944e036922f297304564573073fe2da0e106b6ae848893f6895f0a12f9118de7fc1119443ff1f2f35e71a43bc94234cb9e5c2d90e01dd7e742ca31306448cc0e98d831002867c231858d06bd7cbed16b784c3ca5a019cd9c6b535aceeea90e88ba173d69512c885141a8817d77495544697ff05e84e66dfeb21c18b0f0fd882e2f8ba09b62ca427eaa6ec3497206871a556d4c2503e0c5cd5ddf3459c2a8f6f857813224ed44cb2d6754315fc8013f5588b85c0b33672f84dbdb08b85c5deb29d74c93ffbe418a8074500e1c4183a3f342e5c30f64d9968c3f5d57731ad8af6d1e2797cb9e18884b30e26fbba401671df4147153f73b1ae8c391fca3d9b1b2ce8d130ecdfa084da690bcbd9f1586a78186afcf837f598fc11b5e91b18a1b7858c6b5472649bfcedd8afec216a895de6dff66fba2e00fbeaf260631fda0736c6dc882d2becaa8635062281095e84aec8d4ccbea60c2bf6fdedf8830be28b0031c0ddcee99ae675a34002f10d63c8f6e1fb609a0ddb96dfdcecc631d7227e7b5ca7da3f071d805ae804c0f0b968f9fe5ea30b9f78b69397ed6a7dbacecfd9f0f93afa5d0d85c80c65b2acaa857ad82a94e4a8389e38e0d35e00012b13a4a2d7324724be72a5efc6886685f0d87195c2654a8fc0c56a6baaeadf31a7e99520470aaee1de88944e0eff192e45c6bec09e61b0642268375ddfd6abe877fb8daa4741bf505f172b4f1e2bc9c8a78a74c9e48f0aa6e8e0a93666c0431406ab7046fd5b621225b98cded1a1772a51163c851acb886e22c258814d2627cea88038c30fc49b1281085c80a495fb2391c9b9cbd954deb4af33d047abc114f048253b7e4905723893315cb3aa1e37c7e3657fbebdd71eca22648cd98e71a33aff0934c12c2e6e13ff191197d5c6762c86f7e97fe8a89fd82855af27cb050c0feb6d7b7d41b5ee76e2be20116400abb0eab6a2fa0ada7dfde38b5357840bb7510f22651e6affeddfcb49cb8b331ff1d14777234c7dfea11107debe49ad467c4b5e7fa0794db39f9bf17d53c8dac374da7f7488cfbc76daea6277fcc410e3a03a438ad8ad40aa15ea896c7568bfc617763e1de131ed36679b033d72a7adb9fbf65e2543c3d4f1d59a0bf86243ec12911ce2aa44334de00ffdaf0b4eb0f61aa4238872a138186fbc84cea7b7d7a20dedec2bbce79981e8a1aaa8eee9700001acace26b1fab1c6b78f48848586f2bfea7f44158e3232743203cb4fde21599d18c0274eb8ecc79de3e4537700e4e1d18cf5060215e7215d63f36dc6a0209bf7476accc6abc1ee3535ba94334e9023c6de3178f493d851797b733f2027f55d01831c9b2028aaf2175b6a27f7311227084c78549bd0a7eae848353905e888fca9cbed8ce1a69136b24e97f31e9b629afa63bfa6aa0a7d936700ac9a51039b018cc13db6fa07e49c90f0cb27b41e1e3aea27406ad5cec7d92740cab6b3a199a85299b24f4a3b1512ca3a68b52a9d1f5551be86a593ecf1246757b641d65414fdf4cc52cef00787e0aa524c778ecaeff6f6c2c7e9df40782416295981865e55701144e484af83514c53d3210ea23b87436bb399b082050902a7f6b428bc9dd7c0eb49ddeafff926d208d8bd84dbda53f3c35e526b56ff84e476a6e369f321ecc3b53bba23d380cdc58fe5f768ba2db27c192c474e1db4047d3161da7c0ab6725509f9eb9e177ac124a5dc02c0cb978c2e553e10354c23f7e34b64de8ef244fbd44567bcb183e398c17d781a77cf08774bab0f9f7644eeb7f9760cb41eb4ac67730f1fa1f85b8f654716a1426abee0967b524c9b4b4b4e2de98992f86c9b005d15dd44f8708b47fa96fb2dfcc7067dd895757539abbef3f53827907c1be369a4de712c95ac60d5481b572d842f59d6c4a613bd05cd736429b95d837d16863d49d91b2be8a39d38a870778a6285aca7c7e809bb431a01cc08152cfa06139a15a5422b39f80615339fcf2bc7f5f1e88c74eb52600d94fd9d18322a53c5922e912a6d77145069b289e83787fcc9bb444cde94ffa04a9adee150f6adcbadb095a4b6ba09faab4592f48d4cb2d91f6ef869b1b159afdd1cc565b45cc8b7c742fd69e07cd0d88c3bafd68c99f2b1280472b388f8ba2d65b5c2d0953fae9eb407dc7ba4424220f32806545c85f68b6a37cee85b74e2e446e1a2b29bdefa87ec7cda33645568b0af8c7b6df66aeb1e8de2d5600d35a4507c108038774c2cdbcdbc709d5952e82f791a7a29b403bcd185d13edf5af269e7be15537c63acb81321ad59b18794192adb4ddc9a3e96718b79c5a57d0a2a758d3b4044dcf1fb3fef88b71d5b9ae25135b59a60b57546723a597332b238ebc99105ecd4395a5c0dd25cd8e93917ec7eb9a33cb73993cf13871734998fbda97e9e54e764b574d7e64f7783f9b0fab7a23672a0cd55f17f2f6727f7c64cea67db38721a8dc1b69b4ae3c8d4953366c6496424efd2ccf25a58595b62bf20d75affd2a608b84522e1a3c11abe34eed539bd7751f1f435860f3a14f9f0e40559320b9ba76fd35053ad4bd3041f84e5eff0d3af42edcde3cc25954d7c3566ae912e081bc8ff2811babf6a821c50176a08c7abf1426fa6c57dca88744c196441bf9972c30c1f43a08cb5cdba29141ed687b0a8f57385161e39bed1bb35cb6fc100e0de74d3873af386b4b9dc0bf42b98e27019ac61f86a18b434f030e3d204af94af8177f32174f5b445ca396b09912dc9e0ce28d05b948182b4ccc2a3d66c1f0803eef1eea4c2373a8043905c6a5775833b4c80de42b38e0ed27070f0dbbe281824d981b59c75c85adb7f503ca6e08a6e9bc1fe22a1555c20e3d2ef6811009c0bdfc27bb13b3a641df5dfd79f4537758ce097b0ee4fb0c0b2ad09fff43eb61a02546c89d2e496ce6489af6501e0630f75733f70a84771be3e030244869db130cd7deee735cc02d9b9e6bede07dd7b422f36d55cb14ef5e3d30ab199f8cce6028b91651f18f910cf0c5e808a5a074a8aebe65b7349b4b7d90b7c21d4b2f2645cf7f081a3ce277f0cdc19fa5ef088de605f7bf370b845daccb3df60b4ef8b8f612af9de27907b8c6dc5b1cc94fd93654bc8ff1b28aaa716e9cd41ebb3a68f46c82a140910211b0960cc2abcd9953dab700a98e6d66b27412c8a9a0ac4cb9af645e9050eeaa2ba0a011923eaf3ce9db196969c0c95f111d48d6b214b42ce081d5ffcd015307793565653e90b51231eed6604f6fd9277a491c78d02ea99cc11b81b9723ef0c5ff058e229f72d15983e8df59fdf2e9154df46e594b2e176d86a4fc9f5971ddad1286385c8520b0a5d0ae1bfa19df6e5f6f2c8d73e05c28402b050024001e504f1abd368a76e2b5dc5138f2aacdff363495dd23f509bf342d2305c9bff6b6c302c897137052e58affd75cf39b5efa012b13dd4869c234a9745fc46a0a977ed657495b32be35d727d3f929fcea8faa831579e86c3c10a400d9f4d31d7e138213e1591999291c8f338b99ca0e6c44336f0eedb6e947f52c6c5ccfe6a1a2a625e1bfb74f78ece9bf9a25c6187af6ff51ceb1d8574e82b2e78e4f96c55268879a1e3243666d95a74827c0917a1392dd219aaf0ebc25a609f1de2c1826d2c68b58da3760c4f625860b299bc6333a83b48b4ad6ceafdb574e7b94ba0f5054624b5acd5c8b61a785eb45a775595a39c50718ae2458daf713fdd1df8708c33ad0916c5452de22fb7a51dbb865827a39a75d29bd1a5bf0c22af371f80910eebc4de108dfb9cf9920a6e006205f6ca36d7085e21ee29001faf93f317076e068859bb166638a2105a064b9ab0f952f9bcc79895be9b9cc8f6649541f3863a0eb456d9e24a6149642086a3de4358878af3ca0ed1c5f6e71b55b69b58a1946c0a085cd61040b067b1b08e0882d92ae19371929eb5f0dc3bed32d272e08e7ff5be9da0bef7f772161dace43712c841f52d229f06fd6a236e6bf578d3aa84e1c7658cf16e34137c413a7aaf6d742eace4927093bdff24838f5a263c4f1a442e545d7b97e26b770b2413616aee40a17457cb59c1df230629a6872e526e6da133b1e225a8e5be22a4e8b8e0ec37bed0ca208d86f59a210d0fdd1c7fc31f2741ed3aa539adab5be14218783d38334be7ff311bd7e4359c691123a792fc662f9acb5129dd91f7caf8190cf0b49c2251b0ddf8a662fd51a2069eefa98a3cb52d9f3cdb059628d21ba7758d6f7e17241066bf2b284c224f5f69e1c471f2a3439d3fe708b85df1e7f075a56e2695a2ef97ac0463df2ed2dcfb7811718c9f1721d38d0cbac74f6a79a2bba511f27eb227e30c0fce82a1316cfc5d5e5a8269697cba0814dc553ed43eddd45fbb33fded65fccd8d33721b89d84e27d150f537440287a56e55155bee377a46005b9a7ccbd06b84aa7dc20e88c0d16c5518db8dfbb19d64f5f91b22289ef4a384d506b38c34c620ecb7512f201df6b30ed27213cecfeaa8bdac3f6a78bc7358887a99f7f1b083019429eeac095308e020d2c59856741bc419d08f999e2a4f4a762fe8e3d7696e1efab3cdda006bcdd4b7c437c7c7a9020a0596dffebfdac6e0625c8743c816718506820ebbdb2c04d0c0645563d4645de44e79bec0fe6a450627570f1c6b76e9bacf24896dd6fd226c341c5a055e8e43e91c27b906f04ee75b692bf12f9aad64704dfb1aef705b629bf87fbe9b5ceefb568d34f8880964351e40a9a9d79c26158b33e8e59a2c8faa42c8b98710b6a61e45dd954ee105181d88663fe3f5858d28bfb41ca28e00c46804453443eb12ca817bf095a6848361f66bd92975d671ff028c5a9dd04cb6aa15d21a04db3c8571fe918928b5d72124d4acdb6d99f761e0fffedd55ad7470b70b7ec4a4f32225e9e60b22894002196d6f8a396bded88b0c04d401d025545ef62bc7b96416a845c081b1f4d4a2e95f06b9a8b49ae8aebf2b8932218d1232a7a28023fd428534c601edf733b2f4296f62d305b70ceb61b7ce9838741381c1d91e5c974c03b41e7d973ee7926845f2aa0d8d0862976c72e87648504d6d725548c4b3654d7424c7fa1060397a69cf35ab0ca0aadcff78af4c17d5a9d51ab3704447aa1d0298a368c24d24b914517b4eef8f49fc793d8f8e5f1e7e00705a8d6236e3bb16531091ef32893abf4e8443a27f44b08ad79a6e6a87cb7e7c5b63e1fa155117c6b8ebc154ecea6c8a1bd42c5e9291e2d6256df9afb22e429b3186593b1eed59ff8fdd0f516539052828bd0bff462eaf0030465e03ab07163cfa536c4d5a8be42eb119759022a1b5a9b75b344ab623eb1a61813856b6d41707502931ce7ff78557466c49a6df7847c62a22154a6ae0cb280b12ec3af195fe70c88f40e025fcb8ed9ae690deab3de150fd314cb9e3011242dab51521cd3c4fa203d3e1be0b8c3905a33d07b88935be2406628ba3c3138f321f9d45d673d8aaaae8741548ebe6bed9d9dd7ff2489bf04afa4b9eaafaf604304cf1b270ec94d55ba1ed2d17f47f9865ae68eb0d5bb0a8c070a8fc75fb97b0e4b25ec33dcbfbde6524be521e38a481a3fbd565245ae0df026451f3fe555a355abe18a67c919d307d35dc410aa32aebc2189103fece4d45d75d13b0fd943e204e59fdb55bc905d08518bb6e4bc60a898d03785e24521ae5bcb8a4d9600468c15c87895685bf3ec1cb4adb38e9a1c05e30f3c2952439bff1ab805aa97b56a894012164cecb89ff88693ab35344a245626b43e32df2dfc0d62cf6f0a36b93de411929eaa3550a240fdd63fca0b8449e6b9c6090dd45b7041ee4472f5dae7d4f758943ff991a5f3c178c7dba6f45940445afaeb4bb52fc47f8413504e38570869abf84503bb1be99585c6133dff6bbef63fd7371d412395acc4e5cdc3d93b08aa690996308d8c24dbbf4c11812740454c3ab3e69b6ba053975245d74165e00c52e73ae6982c47c9f8bc910e5bf8eab41158a07fa78e124d1d7cf003f507ff9b5edc7f92c1fb532cc59f8254d5872eb10ccd91e1f35e57792199caabc8a1ff79e884633bdf7a20aa6e7480ddeab77cc17c9c2ffa447c35d9c93c438c4791f3230a4d028b50cf138df6edce0cf095985836089fb381feee9a88e9529601352c7e0fc4ca56ca1713ecf290cc1b7d173e5ca14215ff3e8996734b6fa36c84405aa3378490f2969a7e2a067bbebba389047dba16d089d10bf37b1a6c4d966f62facee582eb6bcf974931fb07b0bcc47ad020614cb1b0b57350d67356ba6083e02ce11e229ef997c8c0c19085bed113f3a1295a4c6ce451581a123f8dbe6841e581cd0fe158f051ab207340e988ae24e56f1d9d18c715a9dcf546502ac79cae42fc1e825fd26df83f0984e8090bd29db3c21d98490a30307b3de0559dfc204348652002d46de0d38d96568003365711a29a4b041a55844532526f28ba9f60ed1d08dffd6dd99bffdae4d1531fe9ade9a6d53128a22e0e5b2f9fd4cdedb83e9a158ecf1938a2874457ebcb7ad598e795972d849e06e7079c8162ce50e291f39c7af528a08d5bcbc57db010c8a61eb98005693c85bc6bf9c641fe786709c9b3f8f593c85252109fa7bbd7440ebe77e06cc7b3c60fc3c1f1ccbfedad48035b88d16ee23bf27ffd16a9cfcc2af8f28d2b9a77823bcb0175fcd22e459fa66efea26811666ea0c8ea72b368a9114ba13565fb492b44754b800c780d7c42a98834f71115ab9b0b2c388f674543faf910b0665346774ce1827a9782c392b3325708375694dbc9431d7777f23a6f85e43dfc9b6e94206c2babc464d54416e4170665409803e2b3326cbaf6f79ccaa841fee70ffc4f86aefc13aa8efd9c42c01288a04a2fda11bfb58971d04c0d3534b3d0be3fffc1125adb1980b7d1cd08141286def2b399cf34e50265cdf4f02a311271e2c95d23a1556526a143f6afde7e1807622f28374ed5593043f069c6a7f7544ae7dc2da4b744c5094f7309bd8515f796f0e0d277218e4f979087b7b20e5e3cad430ba155a46b5686d1c2e332b2caab3009f508a23fc2e4d8083f0c96f41610020c9770bd4fa5acf82206c91c8633bf70da336d1f477704eab1cd88a60eb7bd2c4cd8bcf96c47787dd83fbe046f9711ff91afa8c52c36b0cf412ef12679816402bce4c291fd0900d684adc8591d4c4a5bfb33a9047e2cfd5ff00b39e80f5a848d3b39734fea6f329fed2b7b458df6fcbd20b64f5887034ce07c84ec70db3dd5fad4a194b2f30e2a46ebc896fda63fe96585b57d37964c5527f10b827d8d4f297e4d4f336ec9ae6f776f870731e7c1ff59948e36de8485efcdbca2e45854dff14c275eb05b8ad52dfe92d668d8b6c7f3d7059efc0fd74d712e8a719e21170ac66a95dea80e3bf90bf8902fabd682a7c307650212dee707dff89a7cb61eb7d3335692f5d35494c95d6cefa67079a9583a60aa0eb79e00e52120a138144f323455ad34f386128662f1ba37bcdb2d3876b8fa442fbb9d00ae486506a554717396fbdfd523da9bc64c62bbf93fabfbab527bcf2516798c63aefadc8f81e3fac3422fbcf309a06ea66ab5dabf5b6f3a77b5981f49fd784cca9ebffb8fe3b770eb266bfea28204856133d50a0af32e7a3a8a74ed98a0f9d90fb6c3314fe92ca78a9bea60d6558fef62595a24bee05518dedfa7e57707af04db901eff9db76de3d68b9e3e501cca4af60459429286e8863a4b9092636e0ab6eda6dc1486d5712b5af80232fbc5092b2edd547fec7b9704d299bd7919b728824c04cee5eb5a2cf5394208805fc2a07db497ab6ad2cb7593450306d7557c19a35100bbccadfa105c6c77e431fd78b7d2ae519b4564ae6a0e75aa939919de418b1419e890fb80a17202df26c73919ac7bf011d221337e9bf3c2a573d48fa6b1dbf52d52e79177897a87ca25f822bb496473999c859698b2e9227de8590addf4834dd15f89a7478a298e5db0bb8442410f9b9d60cf4486ba671cefccc6558905503ca855eee253e732b39166b5b913371fd34044b9af0cf43132912263ab4796dec547f5e9345d8bef8d9ceef176238ad2de4c4f4b236a9f2c486dcc071dd8f9ca54443a64f32dcd2cfa75cfbd32fa1b6c687e142a64de30fd4ca7bb5a33d5b1b31c4e856ec57481e789d8fb4b5910073399c5507775729c50f04cd8ec3073bdd927ce2ab404b35fc0fc89b7af982a9b8b6f3c63d95ecf3d39755436cb8c09697913130d9db4a5231e68a58ac1d0728f989ac876942125ccc9d4339fb3b3514ed41ceb61c1ce7dc249c9954fa232b50323d114ffab65aabf790b7a2d48f446f2c42db408f89b21f4015096b4c281be4c2762a49cbc7920ffaca27e0be1dc38968ac1622f999e03b120fdc62e0a9be0379f6cd59b06f51582a9436ab69b43a7b4457ac963deec23b6ee2b8eee90d349da77f235ba2f7cdc4545c2ba379dc485e65d32e4f8d9279c0af43869fc82bea5838e212ccca5897e44971ea69c63075550c12e13cfed208e6218569ede2109369cfcc0af1d2276b8c289bc1a3ead2cfebfd0098d272f7666fff3a9797438a6c0a7e01d7ec859df3a292e84de8fe281fa8d898dde8fb7590e0250fc86333d68ec5c5af53bb3467ab781ab7858fde4cbaf391c014d7412680e67e302919949de017335aa701a30530f0dbd1ebf6b065b282bcfb6d8860aee55774f9e937a35462ee5e1968a6bcde0b3cefbc560e0ac4ede97fe78c8f446a4af9d5789078f902960108b90291396d8bf8ac2246b7ed9fd868607fb97ae322a80b104cfa9977e3f413fa6f7a4960b4491e06c1ad9a33be21bb363da87075bc7631ac84eedc0879022b8a3d03b6c784d91d91688356c360f1f157a71b49c773581413824938cc2f4e5aaa8a7ece19b72fd18756dffca3686371e90f6f5927681d3992fda0690604a4c8d3b5a340481ab5e60c5aa2f1acd159df31a399053cfa655a0f99cdc398240b38de3363b3704cdd263fd3977a688c9b984da456fc7c89a93acea252d6a2511de1778963d21bf11070acf2a7ac3fbc48019cd631ac269e4e8fb75d712e9e332ee224d65e84c26576615ac6e2a59e882dd9aa7af18f2c4dc98e2b3cadba55926dda794a9c8cad8e05c721ba46061889e089031d6468f2d12ae4e22373d1be0c72fde0b358beeb5e0e50a4d629961565fd85dd79116c364aab4080d47dc98ead54325c7b65bf3dfc95b830b42db7932e31edd1f8c1e1b36f82c3adf63bb50966e6930e97a87bc5b9f579a029c2bbdcf65691d498bab370c93322985cfa904842a76ac3abb55a0c10cae5f5b78dfc09e7c87a78cb0f52bebace1c5709d7f03168baffc27ff458f61585c8217f6b83aba336a9b43d23b2e4a0cc0f24903ebc36d2a9b94c50dcf6d95820be4d671b2797d4dee67a1e58a73791066af3a4cbfaea33b3f964c11356666351c31b521a6413eab569b86347fa44ae3ff309f92aa826e64cd4a02266eab294945b7b958cbaa4090a4adb280c5c61117fe957e51224e5ebce26ad42368cc471445972853f483e1b0fd2b4e4d0a7230ec3e46748952dd9f6a1ed1577673d6761094ed2e54e262b1c011920e41bd7b275d21e9b22d19e8bc60d8e51d0cdbc45479cb27f64211654a09ebc2a82bd47b8a68eedce7dfebadb0ed3d1864ba7f41207ec7e1b4e5ec2e7a5c8989dec7d7980f91eb50208b91eb04a4157b76cb4c6aa2f56f5b4c18fa952675623ef441d0e12d1c5532171a2b2cf67423897ff2bf495efd53227618505da5d9f4e81e1d4853bc926f0619df94422ad348efb7f846e2544dd0d8aed7f499f1087cf999f518f0293373eca3828e76eec16af87c8b2c2bfe56672e14155c8f83ddb150c6d2576e2445459c58f7dac23da17ad7881f0a0a48403a327914137b34075c2beac2519d16054048d67e9c1a1924dde549e2531100e4fb64d1fc0b6e85144481e5ac2824564b8e003a766ab039b25ef701dd66e07a96425f0ec6ce916d9dc5eb47ce0d263e5476d8bb6de4f439f5819f34b8d41a84370a68a46a9c8e9d72a0354ceaf0eb0a56fa1f7864382c0a21b1b07db9ec79ed5b47158c8bea8d7781a35cd8be8e5525a161f7684a7283430fb449d560952abd1ecd73962e70c38b24aca007b5eee79c4ade6b66e42efed07cc9cffb591d52ed25aeed971fb73dd7fb2f773814f8097eab1eff02dfca02ec6e0512bc6ae36dfd7257c5fc74097d62f1bde4996f9533fe59100edd412be84cf650c60da6289ac82bb590c1c0ce2fcdab4d74936845af619df33ae95598f1a1e86a8370042c81afe006e5ca41f3d2aa19ca1f6f566ed8e85c31c4a62fe2a30992119ba31e3fee66654325a97bd7e49d619947c66d80ed24321f4b2ad45de4678d552387a8aa1da20940c5115c508c21c6ef34bd2494d59ef523990435e856967ce99cd48d862bb18de3da612cf2442625486497d3b123eef53c0b1adb31dcea6457e79cf4da7c98a7b9e2d0ee7da93a64f20f41f2a83e555412264b1731477137679dbe4433d9de318fdb56f06866bf1951741f30730fd3de6866bb9374f57acf544f61c378ac65fe50fbe06d18bd8e20647d7940124a50ba2971de8531b92737c45d979357e97f5e39e9470fe44dfca49a4e75905af23c28bca73c6ddb7b7e953cd27630e766ead6c0fe1f1eec7be984eabe2fb9dafb43299440e219f0545abe5027e9c5af1000f5a70018959bd349b3ebe37360c717dc5c26cf5290df1df51af16748e3e6af13d3acc8186c3c566a8eb7d8ef63a516e71b7eab3a223cf2e07c4c6d6f4f0cdede5a71613cc804c4ae3efaf8dd3a5fbbe3b423ff364a6516eca9b5aa4fed457a957cbffd4a092d4a7ea683312b30ff4f88f2e78f19c504fd9c967ebd9d9b36043344cc5012aa520cfb392578ba0dfe5778538b79f9457f38fa880e0ba887a3d7f517a6c5efc044d152d8271dccff60c3d534a2aa6edb33dba81e22223a945cab0843ee38ae63aa7958d2044e08770a4018f13e05ce4593d7f15eb6530836212ef815813f4029ff639359d3fef06e555d623673b0eeff46c3e3189730a4e9d27a0f919ef6ca6b74465b336f158020092099d84c7481a29631150d345ba3537931024b7aea16c7cafdb76ba1dd09c16f628d76a0c2690c68ca13c88894c1167793ff6e274b0b2143867adef2781e562b835a70882333baa56e097a5d906617e758b6c23b2cb21e7fe7986ba062733758738e45f27d20987df00cf758eac3a2548f29f675a78db026167e87e1c5ac59cac4c692bbb759f3389bf4a08c75b027d5050c6c2efa816229997673e624b1e867934e5aa5709c34f51ac700adb259c702d04201225b540e661a66a9e4064db66f7d024f4b48a9afcfcc6e53088ed2af46fe855791d77eddd6cc3a947433abfdb0d637f99413a684ae98c44b92b4d12271e7e18d68fc204772c77d57047df05e76bed9d5bd439a0aca1ed6e895b36291ac10256cd7df7cf924e74c0dffbdb3761a39e21dca1ab637ff2192518d28c89af3e90cd1a4575f49c40bfd99f461bb196652e1e1dd1708379317a6000bbf0ddec6fb525fd1c1137a074319b89634e5f28ffe59e017bdb69e01f7522ea6a55a39817ec357d18826e3f9f5a6f7b051b72b6de528f4a3b427b6c88dd60a26e4ccafa2beb01cfd1daea18760e57c20922782c599fc77ba1725c2aab5444f6b7f40f9381f4de37f22c26da480dd5b62bfbc1115b7f1ca4665b25cb3b22782c982d127cdddd79c0933c5bb65f49a22f131218ab2cf9ab687d9ea5237a987f2ec9f2cc05d9bd1a72cca513fb9978e8a69082d5bff7fffc5469db643f441ca552dd69222847e55d29f9d5ce0d5da654cf2dc133ba871dd2cbed82c43e3cdbe5e5f83975be82f76b88932c645c2f6c55bf8991dfff24606625ae2734d2ef4cf7e3a1e873d340e4c4be0b267896f3e630cee0e86a751c1a020b032630d8972106b830b907c76af85eeb28ddd034217584bc4883d05451163f02611754e90c11001245e3f7fe65d5ff8931187cee76ba556f32ae052f70146819bef48924279f48b0545d60704ff52a7a24e49d81e237cdaf738e4faf8b5467420914400fe65b91afa1808ae095a539fd982d0fa3d5837e2348f235cbc10fd358228000882e4ef090f8260656137dd1335287c16c8d0a753b20ef8b5f0f20631c29e34ad8b3dc7d15b6aeec8a7be828cdc6adb3a15350568efd5c9935062663513978ddf79ab84b0a2c6b80f1ce85dfed7a06f6bb8d5a380a68b248483293f7e93fe3231d9eb815a08385827ceb9d0bfe82b57e2696d4b2397603282708c48425d0d024c95eb459917b9f2310eda10c0ba68aa975ce3ad62bb083ea738da2c19378e20df4aaf39ba75d57d8d78eec930e762e592c7f48ec4cce00a5405d0bcc99873da232192222c2b0a09481ebebcbbf45a4f80b30fdf210044a56130276ba1be61e79a6847a159b1ee4975811f8c9374908256bd218375e018aad0ce9e06d2258461065efd5cf8fdd77221e590eb8d13c9952330444626e631fcd90e0e6f8ae729738948cdbabc8a4c89fa4d151dbfcc05e1ccf9660f9ee69764a03b03b67b25b3f2bce8a867a29a6ccfcc41e63150c94799a137ae1f79989beffa906e51a4bba9ce09d715419de9f3a5b61f91c67ea24bb2d62aa91b8cbfff3438ae70b46887e44e8e37e6123cc572091df75805805f7c651bdc404b019da41ea376fdf904a5b0beb9746b867b22a6e5949aa7b98d04733d3a197ef7ecb64ebeb046028fa8002f830c077659e4906bdf112361b9a2799b2794cda9c52c6bf156cd96990d7c619e5ed0636760eaa6fb892d764304c0a158534e6bd210fc17c868073a9213aa204e409f823226a084354a053c2c62b374f3be2c38f1c8cdb0e7d3ba58826c8aaf407fd94bf63acd83d5c1c7c1a3b175c3a2cc363c5597d20881de1a60126a946ab8f1cd49160fe2aaccd16c3154ba811481773d1de0e5e0ca0435c3072b953c3064334caefed40f0a4c726c3187521d41a574b9143b44159de6da79b2cfa8ef7943e57a45b1a4301433f624cf5f332da72759f9c3f2f0787f7bff6a8bd96cf3a17e481d2d59614dd4e494a528063728c642838509431df275cf12f25028e1d0f1ae47458252b3468b32cefa3325eb7a18c54428402256938cfce6738c807caa24f166d8db3902c444a70ac2678c0b660303865b9be284ac343b9fd1c70efd6483a68c3affe0eadb30c6da775ef7c79a8075adff0b54e274227a2c8bfdd72941474859bccf0f9565b6478ac8e53b16b17c53eefdce4ec1e9fbf72fb6a3c74369d80615ec12cc0709cb85b989b942b724366ae93b956ad4842ececfe024f29b67f8bca902495a4246e9c1f8cf3f2fab8449c6ee5bc413a2bf682e83d3608602e6684e69ab0cf93f2239c5e1bf2f4ddafb09b19867fbc3edddc6439eb4305b2cd433424265f3c097c38653c39a288000e1a1341ba3646baaf0d0e7e72ffa34478aa1d7951ea9dc271c1ef4ef5d5a276f23ec59b1ee2980ebdfde4a6fda2efc0eb18e567d974f68547178994713ebd219d69f3ac0b9849ea3e0076b0fac2a18c7296173bd15d0b905523f1d6589dc1222688ef3a71d3523ccafe7e16cb98e745f7ebd6ca0d10741d8dd6b0f044a36c323ca138eac803c5ec392ecab4cad8810412eb4ac1fffb12a402565fd8c9db388da676bb6201e33d0ea0c0f230459a306c7019428b70c4ed46b6a033efd320e5b0e89ddc1cc204e6b4243de7d14e66d597fc1e0f73f339430f0569402031924b573c431ca2b706678557bc04386763d04530b0b81e334c497acadb39ca2751f0f4ecccc6a39cf87b02e3f92e3dd3360fcb13933c7b7962b990ab5f8dd1d23fc5497b7a129650b52eb342071a7e6eb495b800ab3ba61781b2d201931d51ee811818c5fc4f6b0fa0a2104e68fb6b4b46373e09d592b98ec541e69f75339c9d271073f74e0dafb865bea8e631620406739ad4e09bc2371816e66cc42e8e95eba7ffeb5395fc88923ce27e03f219c92b87b9a7f10f26e197f0d3231c13bb8afd1a8415fd7b0ef35b604194a6075f077e2386e33359b4853f5c2fb69ebd707bd07ab168e19fe1ec0afe5627088a4c1d9da64c09fd9b8cd2e02be2fc4e2bfa6f5b297dcbe6a2d1f58421396252f3f14e8e1dfd056a5c7a8d6ac1b15f4c6934ab159208fd85890c68d296804f10cfa11cf03b2d16aa1216bee23105ef38bb32c25431a9f66d873b12c84f0905790884db44b2e743d2f20d1136b8acdc246c45e6049248d8fd1512ae5c4d05b2786581f592e8757f2c2f0eddf5b58b5caafaf8a16571feb9361f59a4802532c69b0bdb666096aaa31666c32dd771015b770820ee5ddd003dd084a90d544e4b07d696f96a7c6f0d5c83fe00d83f3f0dc0fba03ec03f0156da081a23c811888abd92b8bc6ed7282cfd04a1c9e2f3808c122f0a4447d094224b9981d913c2640d84d4b54ae769ad974efc4250c971528ba85243dee67029fdfcbff37d6f3d68f0cc055cf09c0c96b7b467a62b5990359876367e6797907e0d14d8a1c1b76ad4d9278d9e783bc6db262fedfb585727b93c4e942cddc4a134b48cadfbc7b150cf82cafafaf7d23ab4d50f5769e0f0ecb76ee34310d4c3017791114199271b624b538f85a1c48da0d5372a800ba88a0dff44576f2c4997ea3270c040e0117dddc1974497175aa6c596e3fb8b0ed3f86a6f8e0403ef12e8625f210307daf57972a982cce91870cf1ef2387f03ef399bd72a6238d625137685e8cacad62c1ee729a2e0a91946ed9eaf72189e07dfb6177002213b597a7c78b001efc602a8eaac5d5743020d5ba4ab9004deb2f93b9f5cfddb3d2d6c900ae7e4584c0adf5b96261fcc247778132cba7efff816ea2cae81e81f9510c65a4be8bbeb357fe81909b11b314c6baf2f3dfc1c124ddc798c298873f91e73537fa9e52187f0a6d76c450fee0b34f026f5ff0a8da854baa1e32088879c89b8d83d36ff7389feddd6324f3afa603b75d5179718d4245dcbf38a05af84129d80f5508985bde8c85931b48e73c71a89e50c5474480aefc8cbc56e2f8df75accf2b6a13785d7d5eefdf2b9d993bcdcaf1f20a9b7f26354d15278acdddd73506cc253c7746077b879621c57095fd503e1971b58145d84f9c91f0292b314d90dcc1c840d6b0b9d3624ad237ccc70d4d231ba5d03965bd32043a31694faa235ec3113c8c1ea1c4dad1264a042818833b16949821ee9594b8efafa9d4d0c0af03ca61481d687c67b0fce551d5a0a822957d2d5162e58385cbd33b4c322c5ccb7902dd5f8744ab07e5321cfaa3fa28998886ca3ea212b20271c51b3d8c3b31ae96f5c6d6a498b8a888be8532614fdec0665e164582e0b1bfbc1b4276ea8b809f169c1b2ae45b61b69b46401a9c1b5202c482a5482c2dcd49ec6f9e3d6e087e83b7150b05ab20ff984ffa7d394ce365b3c0b967f21a659882ac0854977df790ee84968bcf19de87feb9dfdc08f7ec16cd3c86c0c5d2d28486d81bc741486b62b9a332158d4eb4bd585f51463f362da1c59e037671f8a51f03884c34457e928cc2288c90abb7eba31dd2f0b3b1c788f7c01d71ed4cb2239baab600da821869d833be59b26e26511d5772d261ba9a8af9526d3d9f25e3684d9f46971fb1ad116c48fcaee6d93bac88b558a77bda5b04f909cd3db09197d17a9eafaf60133753ff7618f1596d1264a6ae91233bb69d45d6aaedf0d25a15022ae5e239a0045389777319b8e5946087b91994dc5b9f8f8b1dfe247abcab06910d82b574b792ae1999536651abe454531ec8cd227b4106ceac32270efbc7f97f8568f9bd4721cc7b74a13885017e304627b22e41b0f723659d8dc43829c30e8515ad4baedefeda0b4dfa4c4fe788edef3b45e491c3faeebe0de74c709c4a68e433d47407ccb685e3108a82a70cfc571c78a5b445949b4e3897357c4248e6dec31d06770ae36f9688457a8cc13e7fef33159a8d96b787df7b340028579d1889e58a2ffb1f002dd1e99b3b259245c97486c7ef3ed59ff46acae7ff1b2e22476995fb2cb2dd5f07da76e59a2ae2a6bdf938ea9745ce22e3c050e63485120b4bddbcb4246adc11fcb72783980eabdba9108e74f8c389c8caa4e823bdb4ab3c6812b970da82ab0d7acaab5ad0fa164995c86d6a794b325d40eca9f1d33492b7cdc302255183248f70a2a2a1ab2ee757e45e4cd3a25fcb066168ca258891877f5589a473942cf5d55f5457432f35f49455056bab89582a174a77fc8686356868c699c3e3c396077f204692fe81a2952e3f3cc15fde5598b04c0a45d134a022de523946a8437efbd7427124c16e83aa68dbeaa8cf9f3502770a2db120e5065eae7ff7e2c3048aad2df1c33c6a484c0b151ca950c8220a99b0185819552639284bc95a35b86a0463e202bbaa1cbf6142b6df2286cf345de02d4e9584121386404a2039c7e7c52f1ff6f6634792d82002ff4e0d7102a1d24a87d6cfcb5ebb01b74beda828d385d7156f3be1393c1734dd3052dde6f2cc686b77df2d4ce684e607261540297b9394f7d6e6649907592057fb69ab159655b30a6b4062613dc99e0cd41dc9c8abac5f1669b3c6f36028f7d5751496f27c86d6fa4c8ba350773ebc1c4ddb5f5209e55bb53af68875405df6efc5a838b8de271e6a18a83ac9bfeba456e0f43f27f527f765d622a460ba2f3a1f72e5748e4c3a200bf7352598d357037abd6c20d47bf8d8c2d68a30012eaa1795cce7fc4b7d2f24e8c6c06fbf719c81c2385f57cb221700789d88766d65d2272305e7bda3bc95cbd13532157792b8da6c49a7c13716812662198ff29af95805937f5c107fe674c7c150f3b82360676a7f609b8f2c5b00dff6928c328d42a8632a0d175337c4dd3160e1bc87801251f23ca70cfb5057182684e9e93658abb433917b478845f5f636c1ff4bdbb987011b7d81744f473ac95264a21152d5e0c497eb02f2a070c6af510bcef36cffdef8daa26b27ebfda63a249bd66070236bc5d97790036f61055e07a8c5628821a0046423b775523a03fab86dc8b9e7ad742b71f8416ca8488f6ad4aa8e1c3c327ef31a572d8134a06238fadd52cd6fee38d7aff6a8b6edc84429fb3f904e06332af54fe5287a19db235a1b03e96d67587c77a32b3e7e72983e5f047e0cce5e255ea548d3c5b187c16f5d4a636ab735738eec12645ec36fac0aff6ba83453b803f9e6c7b856e42f84d1b4b22fdd261c866a510bdc1a3019af7e7bef8496329e4b7300a2034c758832047eb1256d261ce931ec6507651fe9eeb252e5af4c6778e07c3aa20d26ddd94ef377c3e2685f98b8ac4cf1b399fd5492e918ce1a8850d764bcc28e678f4ab165c9d295111f79048d8523298b993e901c0253af64f63a125e8d4b0129a2b656455ec61fc300c71216acc432c077947af4fa41c69ea0cc46c35efe1cb2a1b7bc4d559c2aa2f67b773972e2af682e89913513b1c2ec495995a3edfc6559b3002256a74feb3b20d538e6ac515ca3e234e895c558edff68d50b74b3d8504f872f0584b0444877f190f7cc8a3ef04ef2370fc549484b0b2a97b0b7a472b8237de0d1d5d9f6fa690f1a19ab527ab3a3ba343ef291489c84b63f5c81dc8e8cd4c46cd55d396adecc0fb0c5bad617bcef9da5f268bdfe37d33f9ff1cd3de1cd30aea92bd46981454cfad5893ffe68aa322d5898afa9e563f59befd83cbfaa6aab7dac12cd8edd26eef274f1d00ab04d47b7dd489cf228fd3f0f4a4e344a8cf2fc594a4c46e7eb732f58ae732d9913f974cd24f3599c5b208f9d921f8f0d8000520948c2da7f63be4be73b77deec37f7a109d6b38ec9988eafeeeaf423c963372ce68c7a654e0c1fe78e892244503fd5c0d9e758d01936fde74ae3448551ad5adb57cdab84d6af5e3fc2e8c0dfd30f4ea1ef4f81dbb8d08a35dbf8084cd0ad300ea20e10165d1335b7cde2db9f40e7466e89f31369382f3ebea5e2e6de1850ee72288ed751d76530b9bd0727dbbcc78f04b52646691de1faabdafd572bc0642c6db876207c4b46a1e20c0bf8163dece2fd7ba88ed2082ecf2b86afab116913b0110860782808e01701b3719c85823369af0b1682a7f3d331096b009d8b6ff3bd569a51611a136b9f9ae80bc4d1775e0c15a514c33556adeb3a7a970551e8b0840704044833b117b5d54ded3a6f554cf551fd64f47ff037d4869544fedcad218743bae6d5d83f4ec857ed8601135b691d328ab0151da7159a5e74dd56167646139a65b9c782bc333156b2d492c6e9946f3edf6974e2fd1cfe9d4464483d2ac021c40d004c73a9347e7fefac91b9e7b60b369a6b9b162452123ba5f0a851a5627b1ce2a87e92cd7bb6c4ecf64b6b20ef6aba1a601564776fa46cae669a53dcc9c4210d876de6100d2e60b18835fb2be8bfe2b3ee0369c2bf83228a9d2e200690533c371acb02975ef04b4661887ab427266b84b97d260454ccc88ca62629ea09573807faed701790a77529bd08e6eece3b745498bcf8d9eaaa895a6f168b6edd9ed4e61d5eb16fe752e230904f70c419464935fec21c42c23ec23e852ed43831337534f6e21cbd6a9fefcb4cbd43bdcc51bb8e7f322dd56ccfbf11324fffde01a7ac33c9d7c6a3ef70cf2a68f71816312fae5f0f4f0fad6d51e1b1c3b372ca7cf66f3be26d258a9353ec4f3e58cae5a95ada72f0ddd4b3a4429701c0b83776e0acde4d960a15e5ee0ec1ab9af8a95ac17de2bb19cca93bdaf49cf403c0c39461b4d7b4cef3f724742e76a18ae6b454a7150ea1e95852a0d1dfac377520bfd6706bbaefb0886968e7b1394c589e08fa31ec77979fdeb401345b197b0602ed5014c565c265419f17bc3e59039a1617f86b2852cdedb2ec9364efbec29e8582f155c472e5c95c0c6bf6818079d3f02f252ec359f27d1b99378b476189f9be40796a34a767916c882ae38c6df2376de8245e332c660fbac9530c13c3e0e05f2674a4b5d91618239e5e62966afa7ab52364fe59573d31bd3de85f806cbf9c5d65fbd4f01c85b260d485a945d2fd0e78ca397af3e24fa79e05be41d82ab7b884dbe3eed6af308d0de1a6b7b8b822271f8929f551b1ba07ec5947df808afd3067823520518d44b09c8fc05c608a8ab0f26354c24ef52ffd330ef9e4373a7f823d878f63b89c8ce6afa50c83d20d72de079c69b581290aa4f45734e89eb38a24fb9813ce274117d86d0b26353fdc5c01f2084193a0d07345e4b5c752528ceaa0ac74428078554929a9c7e3b14d7d3348f2bf5b578da682c269b6f09c5def081cd6f04a0b1be6d297ec3f28857eb57d7a9d5bec81ed1c7171336cc7cf9a9777997732074b21b57b328629abeafa40b8050aa8c481072140ee6b9b4bf1e83e699630a7dc9394d7c0673592637237a6bd9b603b61f6124771ce31359b702f179732a34c6e1f82ca101f30e8d2fba4ab26b2d045f84967742d2dd8cc97038f3794b5498f9913246c99105e50551e0e69df53dfa131addc01b7e463892df5a7e7cbad927f0877bda2562983e86502ed140eeda383142f1bc933fe9ff9280eaf67998bab08d385fe55c8e7cb434e7c2757266f5a0a33ab6d83c37aa5d2cd576951aa9eb2c1b8822bc07d363db9a76a5713b34516f6192792c8caa05dd7c7507c7bd69ef1f26de978d060e98d9e93488dcd09eb6e38270cfdfcf543b19d6e9e5d5b6efc5877bc54d8fb882b5cdbdc694ea8c3f1c262540e55f541423c6f678aeee05a929496b62e725137adda55bed2a54e7656af313cc8bb7ecac44745375713072e23464cfb97213ffffc20d0749deb426ee6dfdf8627d43bab772d9a5e38942e47f3cc1df67e95e9cf61ea85143fa01a4bbcf35b28d25305f95c35c802f049c247769d27514c02b25e7c3bee02145745b7dc11699009a9f9a6e0b52191e2b55e9e74dfd7440124b90a245c853e182f45c03ada2f9b21ee5106a6cd01699f214f27fef8a32b81f1bcce1b9f4371611d162f887ff76b4210f6aad7870c713476e0e94740464a39b7fde59f538a518ecd4029655d2f65043fde79c1061da916dccccfabcfed35de69ea0dc2e7c3261dce96e765627d2e65e20fb561b8adc2aa9c995bcfcdf368f9799dcc73f6901107ee8aedab37b1e3a8a4b52749e59347d432d252579ea981c97b46c8589832947c8fdaef760b15959d028070213c127637e11e89b022b0a33de029b013996c848a21483010fdee31a613cb18336442480c0c3ceafe0e8c2c2df8f632448b2030f2fdcdce6baa309daa93917e0c79185102d687e4826efe55da257735cc0e5f8832d887930472513e68d13a54b648f6f2692c667233b391b1713d6cb80fbfc012746b77fc6a47f8d193178752cf3318b7eae93e269b7194f5d239ff149ff168aaa0165854ce6f21e1122895337a354b1478a13c80dbb6933f23fdb65a6a4863f72d25ddd2687d7a0329340522962ecfde7bb5364027894d10d5fffee21b2a34930c0ad862ff00a5369d92087cc9c082987970f43aa9f9bf9bb8c312ff83a3f7311ba7face381b901026e38e99b550d41cdc3d962deb40e2f80a91db63981c0053824ad47f7cb33f7962482656054def4d5eba17c9fd2e98c88dd449e10e4507ca015d7996482247af0d73628a9f1d9906aa5a90a0225d422ed09352c595de851d122e9d0719c35dc6a44dcae2a02b0f4f9e0fc8eb9176dff008b1f259bd87db5f6c38d99da5c3c11a058a6eae0792e9c292c073b60f6b9eef9828a9ccd25ee9f8cd735d0821fc3be5d433587f053e8d8d90b7dfb98c388fee5fc205b5ff902960109b9029139077f9a4b3c8f1e446330f3ce516d5a541e6e44702a68e2978273bfd9235c37deb5dbcf73f57ce281cfa1ee1035dd378afd5f23ed3728bd1557f1e6608d1d835933efefa53c76fa6bf417f19d58bcdcdd61b437905cb1b69f254f61664250a7bbcf827dab79e42d0569b7c91ccf41bdecb76e0bfbda273ede120cc829967a045cacb489dac58154373b84b8a7b0ace99ae3fc97bc337ec62d15caa61bc5b893c4dc7a3e089048ea8f274f50f7cd5726bae5f5217a0ade7092a339e15e90a25d13669e9f018ea23690bc99bd984cf996f6f5041749b5d79b034297785a33964977b1555e00612485e564d4c6210de5b4b1afd0e8dd63fa969e5865ef99c517778ebe7058821e5aebacd1baa1a4ace795d6a2e8e75bc418adf55558a62a78906be2b48e4f4ff3b381f2342dfe32477cc66ace836ba83614ec586c99f954860db24953c6af14d6eb58fc93ef6666e48ce4711f975a3b4a4de5c4d925c6d1270f4b8f12e0b4b1c565d5e04c44b7e479df4c77413afd521d4af351856b60ca998ea4a6fdb886be70a1ae59dca6770a4578ba5dad19bb7dea51a97d63e7a0bcacc82621ff8db073083689287d14d969fe3b1308925f56e737f6d5c3b5a7a3a69757ea13ec86cb6fd8df1eb1162439f45a64b1600b2f67bd4ad789bc791a28e714db2efbf8b9a4aa77bcb24dada7f2d1964673c96f22aa9ba256d46c32369ef19bd78a2e53d85c4eb5202078b63190fadad83972aa4cdaf74f68df3590bda6619b68d2bca610c75b5df5d51869480b3bc6cbd45ff9d38b0994421ecce4290be6d8bd3b5a51416ee98c32a37a78209dadc25820a44d068822b8d6deef1ddd951c74170862b91f4b6c7dcaae8c6869f8177405db8690be799851a14cb129d47213d7bdcbd2a1f2dd914b4cae84b5b285ec579c9cedf91eb50209b91eb0221acae84fb802029201929dd6f8852e743d01e2ccdf2a606f76302915c620eefc7178dc413a425a04619a37e7a5560ee2362848d239bee5cabee86fac8ba0688fb9da7679a89a6e386145424b3c72ad433132a70d56c632c12964ea8b4946e7a0fbc931198a0279119666e0bc482b350fac2eca3ae5953eb18ee9cbf63daa9b62e251e617a7e6f030789a283d65759946f7a80d876f96a875f7967bedaa2f3de7344001625d89ac0a4d34d89fe39093d62ef37ec1bca195cde1c48c9d284e70295fb93351bd48ec39fe17cbda3f5ad6dbd6c3f9eb61f7f7848b82443209e644e5121f62ae4d3139335d0859908076d562814699dced548167959de87b05552711179a5457ca596918b09b0d2b7c4b8e85d93b28df0bd192a5185204d91dd1ca89ad10e00ea918abad89294dadad99d204e3357682c238d58177f1bea839ca76dc0104a65ca4d9edef36d668a3dca86b6095bd6db078f9c63ff023651857916b9deaf80ed81c5af813a0c50030c883caf0d67632e85d85eca29a1e080d83ea94f919e621125bf0ab84255642d0c10da85a49ca84ce7ef875123ab1130aae80137607337ddd0e3bc2d689b81cdc63b41459032ee8679a90acffbf0d5a8827c85252c9a5f7c3bea16a010c5499edbd743bd1a3a689940bdeca5f4cf3052f6b8b172f571f423acaf16e19111d8dd58afe9c7f62da25b0fbfc0ecc6716f7d3b66d68b51c521d8f09244da134907429b939d7867e687ec6712d23e287c15c223d5ba9949d2155756f7ddeaa63e01d8511319420a4e83aa739cb1578d6415f873908c694718f54d930a43381db285a997f398ab5696c78aa51290c607810a9dbb53e257ff5133f999fe201633a72668f8c936eaeb4791c0e80dc7fab0ebb92bfe79c01f2b43bf11670408cb4c46928ae62b23323ad9053a7dd254e93254c438631f00b4357a87a879b9e86f6606f96d33f1645996a3107671970b570bfb3c37b0e11929a3875c12d7f14848b51352023168e730608f249722b1b09dbfb260ce562133650265c72f8077431f6ae2c11a0b22693ce82ac82216e931ea716f065d5b8201cfb92e3dd7aa6b9da21e02c69206dc074ffad81d69c33c8808178ebe73134b44b6639bf357c736b622f12b9a19ec6818ff0313056c745467ce475666851a852cf31d98b6467f616e9f65280e02385b460fc86ae20ef72bd305559b9dfb5ef67409f6384615708c4cc43421460c63b7b9aaa2c0e512b32a34143890e7955bbf31139f6aa727b2db06da3a9b0c47321e2865259792465dcdec83459697ccad25e118889c0e56476d1889b92fd1f6cbe4e4b12ce36f3b47a3966609d655a15c7dcc199c6ec8cb19ad68cb7eecbe19a0c4fae990f292c41b6e7d262b533179a4c46f0deb64462d77739c68bdaad9bbb3d0f8ccf333c200cd69baef4aea5054a47912c460114987905a584d5274cae7656cb515bd0bbc7d46a7054625cdef9d2ea2e91e4c97a60b4a76abf3f616c5c4693bcae0e904103dadcf65242ffc92515467014209da155a3ce3ff509be39c08ae94f27903dcebf7e37f6a8aa5d8955ef9b02b5fd6e6d422cd20ec2a93c48f6d216ef116e5af4a8c477d494e5eacc1043cf60abe9c4b070f76013e9a50dc29d22a5eca815cad54f943e0ef27c6d13c7cb6abee3a79ded0217254da71d6790ddef4571cc7867d54298ca89c0e7faab236c334143fa3f2d4c7c142a28ff42d1c6795272ab88c30e383f8e33b8108dba4202c57d2bd206ccae88d3044a154035138073e847f73c755458adda2fe6d3d01a903a33b323d906becb3b24d0089b2c0177893e0eebfcfe4c696437bf1441aaff38e245e0e3eaeeaa10779c3bbdf43c8899c1a61cd99cbd219b4b697dc7934b52e1854260d83a183555d7b98a02d5570ffbde394fbd9c658aee3baa07ef0ecf5d1e6f469043c23b2a21eba935d79edbda5481548fe9cbee078bc7e0aaa7f9836f062871b9cf03b1d67055a81303aa59066db7a77655b93911817143db7bd3477cf0c5f1001e20dd02b079a6143344d1246088f047f1b65a0e4aad09379161dd54ec92e6170786ad13b5b8b4d774964f88c8dd75520772885f572acaf9c1585e3536e44702a3d99932a5c6157173fac1e6feafd9c40988c18a1b39608b8a5c2babd8000739a0508057cac3b4f3993bae68d58446680692a3c294856a9ad2a3beb0d893bb24348dc832098be593b66742c64e0d301c18a91d6908010a3c1eaf5a622c4753bf5ee35808e07fa697b44d3d697f59cc2051ec194afcad146a5a923b89b50ad88abced87c5ed99ae605f193a64ec01fba76273f3b8c04a7e38ec48092f0b2862564e50f3d7fd5540a1111c720232f35db62e064cb91ac6d64bf2bad204bb274d026cc32a8cd36f0fd709b310ce19c3a7d5c26bde2ef974381629d7eb322e2ce8169cb6fe5e144d76cfdbc4ebc797b2b9b93f12def33d6f0c639000b7cbe8bfe2c8ceacceebc9fd093d2f37a4a381f101ff092dd70e7d2981ef73c104d49ff084f755fbfedca247d496b572ce427910755ed611ab7ac3c39de3507581695b80ed53d3e0b98f1b6eb07c39a8e2939e60c00909f7ddbac5a212da4ac1b048e99298a3d7dbe7ef8e89d81309c7ea403c7390db7c825101cdf34bbd794409f023033d8987662751b631c904daefb59acbd7bbafdd6c4d18b028334e9f17348306b1022b29efb67dab10de6a18e151277c29bced0dac3a71e0502dd2a9bc9341f73368d771cb1add36d19df502329b33fb8e78f696ac78072dab732fb7c7b28784c39af022805c1ebe6231225a1c4fa4c13f5944d58cc00a3570be0e02380241df56bc96611e4f8bc9d5dc1714aa212b6658a014ed60976944381cf74473dcf72249d8087ce4f975aa554c94462c44251fa80288413d051d58a507f4afa5af799f82bf9a900599ff01c541c72915063455ad17497842367fbca194203dda1e7af52ffb6cfe3a3c8fb39f8e8fc973eca1ef479bf6b5c13646fe8275a659179f2d45e17fe933751b93b8d988b467707875336f6e72586c2036593f21b5879c5c6cfcc0d6fdee29edc7d073c3f33ef7da8101a5101487b155fc5ca1398f228da87720c479f58b814b950fad4e68e353c44191d77999006eddac24ddb72587d9eee4f8b59a4697c6805122515085d78debfb38188433c4863f95b0d8df8c1a25502b880074c0f89b05c3aef63802baab1d209277bb86fbbdef63baf1f4f63a11619dbc24a24acb036b0869bd7bf90906bdd37541a9309b549ecfdb4e84feddb6181d251fc303a215d8cfaf14ee1392df603f17b9ecd5df465474148ec9d40b340694620c2ee4530aa5d5736b5558dab15fc7f1f9ab59e9233aa203b62a9eaaceca54e7aeaf1937bf67708675957d7fe30d5ab9784be8037673044e8c888f282b6749359b648dcc43e067d0121b3b89229896ce18fc78a299d23256b4a42e1815152594da06a62272de638020b16929d0ac6a18488b2171f0e129a57259ab95055bc2e1ed45ff546644e16ceba53a948d33b5e3dbf9bf292e6b869d59a716d66913ce77005eb8529582cfb6fe5fcbd766e91cda0d1747cb6e66f3337f828719b75c16fd86d0a90264a0dcd93351e0e05578dc4d1eae59e8e4b7643c7fab49cb34fd83b5ed56f8f6044202decf3fa26179c00f946f729039cf3b2632cbf1adea8c83ef0d308dd2f66a01af0d1fa30858e21be57c5fbfb3d16844933c507338122231a204d285b2853323d1024e1fa56b9b6520353457e631d00176a50c411caeb05798db5d84cf1eecde5108c18dcd766108d745bedfd70de495596f1676f027111603717150403f41a144d00b839e23cd69efbfacb09ca8b75cb6c3d5d374d37c056df7f9081a6f2577ea2ff805133b0dceb0ae0b607b226158408623e53ab79d4db64ea9856e215594b5744e245c20fcc2e000d27fe51f0933a85ffa9a79978ef783b0c31e9461b04b6e5f5e6aa2e38de7eb6019895fe7a23821d6f29dbfa5df733a0bc006f13a9ea7d48653e78c5c06c8b6b0d7c6e1567cec3ea7eb92047fb50970de7d634f4cf136270fec14134c5df2823eb18e7b5f17f5880a1bfe70d963f21596dc82d333f6ccf431cc3ccfd21922c8657e7e08a72ef6747452a4e49db91d3cb4182d7411c88ee9db02fc5d3eb284085a83ce2485513eca23dad624220f8e9831d6cc018527406aa1fc988744e132fe5b3963de23afd92d0cdd51fc355a29962b872bf0217e8d3d7919f360dc42e81f5fc64b90d1a938bfef7faeb4abf55e142a2ca01f20f23ac7c2cf5a40187501dc4ab48603d4f2e4de895866eabe90627d71fb6a09106a244a8eb34979e727dd4c6765d5d891de5fb07a96d6a2225f246df6d4737718a1845f9addf7ca1dbfc7c454fb615ffa0559a816d57625571ec692c2371cc52aaa160a9ec7cd4c8595338e38e2b494f912729dc3c7b767bd197aab1f793e31ae31d10f1d2fc31f70afbfcac4aec5221ad47c2aafa88e3b11ff9800ace5b376d4a068a2b1aef704c2ae9740bff89732340f5ec841b934bf10a63d7109273d0d7b4739866924c47b1c02d5d215ece2e988f69db466436707ec3d32feeda311ce0ae8cf28762b7a5a9e4d28ded16670d2ef8b2e75b9bca557347ed2ec7335a754853225780c85fdf06b9c31869166d71d108da35e5bfbf65901ba08a497def2bd4d4266595d8084fbd8360cef3e33649b1271c98da27f330925828b1bef9ff4af1e8e0b0b123470540061752f2dd4d52c2d8519b803c5fa802df8a7ae1a97e4dbc71d6fc7da5013d360eb9d96edd5a8c075fa90d64c9b93982fdef911fb857a4836caf0262f1e5f90ab52029ada6b6d2e675edf9b8743e9edb9a98c82a8a0de9bd5e078583a621d8ce789b8cea896d545ba4284184aad149c0ebe1d448102590311cb2386095204484d75fe7e0259c5b2cb844730390c27c87958b444a625e0124451e17972231770f7fc48778a1847de17c5836666d300e793176b9fc143bfad887a3a14ad099be08c3284443ecab33ee5e752b9f9a100a0c8257398f201069dd5d7736efc0e80fe791551e463bb6ba953fc18bc064ca946f9c53b7901e900f7fcec9fd20caf0f2030fc73e1e83ca46ee508d21ab4a39f066c913e9f04d29c06cbee523380f73e522d2ad6f92d2272e237a6e6a571bb2b799a558a3647b794535348f7f51993bc47a60b5c669826abab6132230e027917afeb537a721186ba3038eaf6361e0ac7342192dfb844843a362770b7777309fb67d2b0b348c65a4322ab88600c212861ed002200b95e26ec40cc75ee7097a71276f7c4f06bb57338e74e4fd756a38b9a18f595291964806642c30d9d0340424543233cd72da162c451d0bde91f86996ba21da94a8d331bd0d269eaae93bfbe946208954d4b541d11784b702b16f48612e93517532803200b30f3f82905e22a6ae5b31bc940cb8fd1b1c6c701fa62bd112353db34393c0c94e4f2918e19cd9b30b6495e0b741b6a4aa43654f5e07bee5d9feb6bea8739ad0e869d2a13228c0d8e2b177404d64489a574b70b58f92ba19d86bb88e237c2123c06cf5091f994017d2234ebfaf36dcf176d2905204cc89ce7354b64d80114394906814a07427de9cbffd6f81f3b0edfb3d1558faace9c4c81f66af89f64cc1bd3cf18bf3341b3c1da60f8b3767b821c69bdb0d989412a5fd6ca321726ee41396050dd55bf58b4c292208c34b3584a4d29302b2de4ab7df4c434c756d322ed794de57c054c9ce777991de513e5e9cf7c58466fb48288efc6d5d2d86a6f4e291ed1ae6d1872562cc24734df2dabeb9cb3571ae33073771ea8e99970e930eb9c7a1564eeb5d7044bae919e155d411ef4aabb20547202380146b95943935710e9e41d580fb9a0dab86f4843cca5228e630e7cf36b57715693d284e342b897b1d8bb73e3956cf2455b3461d5856a17d7322ce3841ce339e6a2c74416299949ada27834bc67f093fcfc0db4e4ab7231239a49c2fcf2d85a664f58a7930215d4aa1b6323bf04f7834ba41105d1b4874bc51a7ab89529ff4ee9554dee06b2ed081fe835a4c5d4ac8bd2f3cb223cb7cc30b73c59d0022f38e9990665f2379bd3cdafc9f40438ab20861385ad7879ba69a0140c1a936a6446e46bb50eafe079780d8304f4b0a2a27dcc0758887d172066233fb79a2bf307effe0fc76f8a7d9326d801490d71f223481155d0173f729167fb0bdefe78f541b365d8bf6e5f4dcef099381c2ae9c473cab86444fc0672b3011cfd94129d3eeb90ff2fb18c3fc6db93dbd19d7869720571b565db97c87ec4ed75214899700316f2f1e369f3d58e96a0f67caebbd92d1db7f3e269013415bbd052c043ea1179cd670ffc4c264885a3b6665e3f0a132d1f43c75fb1befce8af0affd17f414fe19d0e20908e3315b9bbb048979962127fd93aaf3be8be91b1981ff25479daa7d94a68d91eca0e867723b9990dabb2adec4dcb89c9810d7e965b22216396f796864581841c876cd8319725abf488a90b96eea00d1e17c4b03f626630559d8895ff60344f5f12a62fb3946e09326a9a5027bac928928d9d63754dbc403c5c0cf2a2777469b783fae9149eb684256ebbc4bb5c42deb6f27f0fbedaaeaff627082759db9a0de0793b5c2040a93fd8d1eb2be6277d963c93342963a013416cbe4a63c84185e28da4eccd951195cc686ea1a3a1d383cc13574cb0759325dfcd854283dbea5ad685accbd2f4025a763908725b57ee1ae29e29bd2f31ff9c664d4311b3209526cb13e9e36900a2ff8d7a3cfa3517ad849f2b1dc75a6871e29ba4cc7f1a90956c0f9b6cb622a51422d3e88bfb99ce4a884bd2d0566f1c2b2876dabc5eb9265d95ac4de65e6af7a38a9e46e2fca0b8668e7939cb36c5c98723f279488598f84687bbd3625b5eb87a8c8715e6b6b9600eefbe3596485250ba8098bbbebce91a23f1e8ef026a59eadd6a9fec942dc8367cf93605979f301c722844b72bb0ecfed73252618d5b5249503c5a352078c7b7bdaf2a14e9144d59c66b75389df4093104fbc279d85f70ea3fb1cc69cc2d15f89e67a867167e4bc4b4464c79dedd130895c9d7fe08b84e02c41bbd82d0d29d396c7d96f362e7b2e08b568db360771f77f4abd3e0f2e10febce39eade4fa2692b3b253f27bfd58053be9d53baa2864905d9afa7903ca52fb47c5fcd3385a0c35191c7db1de71d96f26562ae9170baaf07d7934437486d2b09f83a1c81f57efd182a9d2c4739d07c4f47727a43af8362670742596da55ed635ee64a98dee3ac4c61f023ff9128f23314d3065f6cd577bbe16ebcc983e4b69ae975289dbc3bed26a66357ba51b4742a46753f38b97f2625dac37a7291d88b90255b1f50f59e83c4abfcf4489fd45ea2e8ea69c4564cc1ccc3627aefaa68b498696dce09357b61a9f57f15b2b50855db9123d024c75db36c58368f06c050497cd280b2b5613ed5dc4700a02f538dc30c63fe985644167d7b7298427f1582b8dd4b9e96cc910c429a2c7814740d4f7ccae0b03d4d3c5ba705c25ac61bb5f1718ca49ceb5d78f5fe9dfcb7735e17c557a8780f5bcc2026b8396e76b478945776bea43c00de549806c8d242f9f63a5fc2626e521559430f87d83c3e93cc4b3c0bf945756b11045825fb85caaff456621bb8f42b087265dcd641b1dbc9d10d7b523b2c6417bae36363afa428c9d5b20e06b95c60ede41e6919e38d8f7fd6efcee387517be0ab47e00bd132c74e4d1973befc080f8a945f265d0f537850951103653fd62806c230f8720acc779bbdeaa2c3b067d02349dc6809a2f2c9ed8d3e10047d935db9c9773a2778c35d89c69a17352144843d6145a523dda4f7bad3b39e6533bc2c3edf022b75860e0572998af804b0da2b007379ed4f9e072475d8ac41281212d2be9d045aa54abf33a30b1cf12571c3b5acfd5eb7d80da82c82ca9c99473880a805d81f2d8c07c395552e4ec6b5375ff32f6b003689f1e27580f64a0afb3e9e0d76d779f36a7900e17941df93b6b89b963eba1dea80d20f9336ff130410a90624ad6d9347fa9d4d0588cafe9db16e740a60e832bb8ff20c8551b6676bdf9dc760310f4b64ba392d77ab9eef59c6ca89724af6c6c1b53d6f5b7a7717514c5186183a99ca88659d8ae81117215ca9be50c795db525524231cb257f9b57a0b537098de5aa2fecc4a99c256f1179e1653b83c3b2758b42d0352c2466649c580674736699754ece8f780067800d2150429776215aa6caa88143e9d1b760318cd05e853562fcc45bd4e1b963bf33311d7e98962252a581c0914305390403fa81269ad34499388b0ed03fbf3d017b61bf62dddaebb0499554e89c892c71908ad5f41dd08f97ce3f1b4b718bff764f0b98d6a6e5e420973e55ee76cf86d0139fb99480c0bf1747d9fb2734c772ab8e3b5609e2f38a81b27882eb473d7212f62fa58db7f01f039a0bfd9031080eef9dfccea650f1c791cc3059612b70580f7d36f92e7abd3b89d02c23af6450364b5ee20153f7ade17a366f572939a88d74107010034783251abf2e8cdad1e4b0bccdb1c7fd3c89088f861728bcc665d4cc775b46e4bc6742a45cb220b117a3acea666b57f51c2733040cb7803fde2c0a7437b058425376d4ee794693ecebd406378cec85be47c4418af0b1ce0a50662222ca45ccf82b17c0cf60ec275c6339daecd18854ae7491d90109ca2f408f0d345652f8e13c0d07d80c1a8be1f1aa67740fab38bc964190efe6710b0d70f71484b023bfaba62736e1006f5ec96081a80a8a3e2918ddf3c6fdc5f552edfadc77a2a531b13e3ea1976116606fc4250568648ed7fbec94054dccdcffee8827f99eae281ac6631d8c8fb010cc09201f060ee58c6e2a06deac1a1511ec7ff6cdc4cbee4cd27736a83aaf02e60953481e55123c79915ce26669b743ca54b14574fffea9331b88ed386e5249412ef6df4e7a489a5a188a42d248b3e3c0bd02ca31643cb23704a911efa9aabeacaaf0c3a98780f8b3b90a7b63c5aca0a3b2e5e6986415b310760f1e4419f7402fb1a4190f4af2d0b7fed3a1d06deb4289ad5dbdf22eee5bd85469259d106c2a873b26fbb1f2c3ad7061a070190a9b189873142525047c4e642d14ae06ffac0b8136ba047d321a5274aa648b03050fdf8f991715b446027501f304a2a6b4dcf570c36415b39380439cbe03cd8e315ba32523ee977ea238fb67d5bd46e1da7f6348d70fb9b9793c218e7a428a8dc3e34608b694012d07665e29d0684a013996733186afd82558fd9c2865ad935e8e47ce0d45be34b18b0a44e32e6a2b59b7488e634d641288196db511055989934660d4cf24204b84d9eb3b81adde7c3479e0c241f3f7fcb959e99d5a69989a2a43cfc59fff4631f6d8a74698a7b6522ad1db943c4da8ae6c1f50a818fc1ffe6e92d2341b49591825baa10ba8fb18d3bf6430356de264646b1cf6ce69b21554fdbf4ea985b22f3db9de2a22378ec772dfc52191e76614c1abbe87541771ef16d780010653bc0db417ea8276847ea5726f129e54410a0a1f29ab485c35c321e580f7fe3934da6fccfa9d55e4280c9ab43dfba13059807fc729fdb7dd1e63a47af0ba14557a7ee83ee79376cbffecb0b4390e5e2af995d265ac6fb6689850f297576388b5fc4008b5945527ce4e5d55b15bea7ce47f518fac02d2e8314b06e179ad14f0a1b3d0eb283753f067ea41bae9f4c6684b243e93f23aa7d9c88cb77fb0d742b2335c3dde537c695b42331c7ab929a7b2c237d5b6e4b5f37f1c01546221f4d20b2c781308f5b9cf43e2eb791e04f08d765f8c48ea952cacab734c4d4d15556b8b72b28dc122ef2438f0d246816b76b9abc2b2c7135644b269d8fe57cbd956160e771c5d2f3196439744dc0d36c998232e509fedec89fd38ae03c301472586505a6839743babcdea259f69d08adf6b63d080fa187d3b91e1f1acfae715af44223ca47c34a0ebe3e175e2f2fc6742134d9ea817eb2bbbf3167c38ef6a1988c0227b357ceb545b3674671abee4b1d0892697ed7d2c642e31c8381f334f65e441e858bde201f89cd47bcf3570372dabf873b8c8593b13707e7f6b05b3c95fcd2a9ad07f2143facae5e037b2f3a7603b71dafe3e9f315da2004967c53a411c8ec2125e99f6dfeb00414c317bde9b47d38bed5182e33e0b1949e9b225f98b14743bc855384f92a3a8bc3124fbf71f9e155b84908902d481c9b96128a67d3a3e66c201a999d8a02fb3fac366214a07467ad73b3f46c535198b3b48303fecf2746d4437f918a383b913d213c0de3c6dd509cf8b9cac6c7fa9a38d7fa6a903c9428663571532c56d6e1b898a4357633e6b068da81f91a921729bd7a0554a5c3b328a5146cb2bc99ade77562fa881d519e2a39b1024e1c0c7f390e3da6474405075cb4bfc493a0cb2315879e9a23b44eb6056362885395e79cf421fb9b295a7b0cba5d2815f0adeabda68061126d0feea32e2389d48765c386e113bdbe767930c65827249b1639708b2e20264e4857ddc4cfe8128816ec24ce7ed805056a6a4de8f54824ddee0371a3cc277883b6ce2e1176cf11fe25cb9dc5abb35bc7b6f0a669ae1bba75e73b07efd93b57f2d76c863f99e8a5dacc1a42f8fe4a9076feca3dd46e2a5421a8aaf058980d9dcf46a9109e6388136ded256a0d2d23bff6c99806a05fd3ec5818acb0426f9d51da2bfe969065ec67ce2adec3281bf291125931654463937c16fe77c304fc25359797d56e41a1ad955fb527e1565a726cdbcba3f8d9ed2b3dab504036deca55cbdeddda5c35467734f2b063863cf9431e07826ab8218db6343f1dc4ad32110409214f84abbfd227b88dc65a8c08f1c4b16382ac4bb6f3210f1dcb6f04bc5110927904de3168bb63e303f611b19ae231cf8ef2dd578602f8604133a25c4a696a91b535dfac944ddb5fa53277c1f9a2ed5fdb82d1d57e67aed217fefb6a33103e82bcdd9642cb64cbe75020dc812cc70924eb5f9542e7f8d0a4b38eca5bbb32578c6f2d223709b22b665713490b92cc32d71189681c8944c66579cf1b9145ef3b6b03fd002ee3f9989cdeb82f528b0ae8974",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xa4232fccb05381cdb8097a53487991858217bac42b0df1d2697cda58480a7ddd",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xc3314fd768bb68b986e80c0a14175f6f72630d7a",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x13750f0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xc444d0f8ff8c7a8d3c9e50bcb746b1912f8a683a6431c72a901322c47c677355",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x6183cb2e7dc76be68e2938c30960055d9d9828211061b3f119bc836c980037cb",
|
|
+ "timestamp": "0x6ab8f32d",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-anchor-20402416-baza",
|
|
+ "sursa": "2800-1"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa0626573752032362e342e302d616572652e312d643230333230312d7774613037f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b84109b5ab545b14b3e5f565f796562a70e82bdcd350a908235c271c83ca81fc034309caebcdc1ea84019ff42cd8c4510350bd8f223bd598e567059c542eb2a9697001b841d6a1266b15c53877205f194bbdf9605cb049cb01924712e335d8d3d8da7662ff33c4411dd775b858bf6e17a766579ac6eb32d86dd158c36f8af4b5849882696601b841bdd9cc7b80a30106721f9833f79a2286564ed023aa3a49591efe76b37a85ea7257c3409244971b3c9d314b608d54ca6c4750c8f09c963382cf08316b81cda32a01b841892146f1d290ecc06168979daabd11d74406a43808565c243be2263bf0f3332e103ddde0fa281f22c16daae42bde9481dd3a5569ea5853d0731a4f139395f41001b841e111c16c9d1523fdc9f844e939cf027c0b64a7d35efdb71c9eb5a55a8c5dcd7e0702c9dc285fbcaa609e7aa8e0862fcf60cd17f70bd4a6f640473b1b770337c501b841b820a7379fcfbbc22609b5707428dd3eef8c1a397a271338961520594ed1453869e472e1f74e54be4dc595d7f7e08fdb20ab89a768af35f37ed0dfbe9210b8fa00b841e00d30479e0120706f974727f9439062ba5abfcbb750cffa8b9a30b14379fc9f377dd9a15539b1ed0d5dfc6ed62610960c1274658413201cdaa9f1b40861d56000",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x59c6a628fbe05515da2598d28cbeca17ea6f3997c6ca34d3e2bdef909b636c4c",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x5f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb0",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x137516f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xc434643c512647b22b658c0329f23d197661253b6134211f2b0187c5e453fde0",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x076885d7c7d6311acfe839756b85ec37da9f342bc6c3d9317a789ef99d8ee8d0",
|
|
+ "timestamp": "0x6ab8f378",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa012ea5a0f7b037c0736e9ba65ddf1f63144fd64dc13728e9ff38e7911f1c15a243e0488ff8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b8419cb831af3dd73fb774d47d240d08fd50d227aa603790f952ea47fa0cbb47bf990edd4a8c1159670846ceb1521cd5748e7e22157f01324a4d48efb80c8cb74ab800b841688980f6c2a6fda513f1842b6e9c8797f160cb5aa154efff731ce5f095ed650a24d0c0a49ae2cd9277d416d8491a62eaabbd7c1cb60ee8f0e7e98ae271517bb600b8411f360b679891c5064759d36945a9b53c569fdf47e776fc24a6376647707ac4815803ccdbec84326e92b83a6c01095ca7a8dd79e07de708863f89d83fcd661bb300b841de4ddf2f6a264d6da9835d3d98a2684a8ff4c4e994284fac4239c075dc37d8fc53bff2e9b399707646914477a9154daa90653b3cb19ee876a21b806b9f1db37000b84180fbe602be6e3dc9869d70093b320f5e4ee86954b018c05b0cda5972371ba57466d44436d17531979a24de6502739846b6b0985445734156ff670b94cfd1a23c00b841b0847dcb70a1f3c210a670c7dc66e5ec960f68eb9e1cdf59bf8c18c73600699b580b446a582531cea5e0cd3a3f7a283e783da137f4fd23d39fd3bd768a30ec6300b841299bf7608c2e4c0419efdcdb8065f4685d5c8bd3d7d03769ec1921d3386748cc2e99a8d9ebb5ff0336e2fdd5175afc3827fb4dd9eb08af7aff7d36a186eeb2a801fa012bd202fa012bcdf902960180b90291399fe60b0f6e43950b3ce5da2efff9e8b50c9b60d1c910b5281d3a1a48c49abb777d9486bb57cfbc00c49fedd1643c4b92843f2b863b1b99b717ef3f4cf973d384657f8f75b2282afa2718c1c5993dca25c03b9b74d323d9f410f707610fb1a01aa984efb29aaf33b3a2876f972b5b7729c83928aba8fa6f63bda8dde7781b68632ad244faa54705ef434d7fc18362200494b6a629326b6c38888745188561380552e5297fea1be8568107a9e26c956a369945660c655fdb4447d6c28124381ff5c1baf3c5459849f219eac67967cc4f51a339a32f8bae47ce447bcb3956d2cd88811ce7ee68392e320d30e2c9a31f4fa3268d444849a244dc32aa6f19dc82ada96111d34890e38d1f24c62b7f245651f683e81be32741561c22c13b853330d7e937c969bf10a2af9bdca56e5288c43abce5bead6d6f1dca42ef6adc63de95e137bcc0695f57537ece32ed3486ca8ecdecf826c125e4e4a2cc6433258198225898a42eeca19dcbf6dae4e420c37d2b55ec2410ce24891695c156f832d49ac389474acad2e4216a426734aff2aded7466ff87d441d45414816655dc29cedb1cb2ef26cbe57d3979a147b3325a8a6242a4c10db64dc9a8cbd9751584ca686b8d322dc4cd220b0ec6551577cfef6458f3a6f65cce2344ddbe435ce232cd761f9f9cfffe35199833f3a4b3da62512ef30ef35829d17ce58a37987a3e4c1b579355fc94b8d511c0da9d2884112c47688d6d0218e4418215386855bc2fb10c6a4c9ff5b6537cf4747a7e81a408f10c90f5bb1746661ae96eb46c5a3fe06a1baecb4fdb8accf74966598dd6f61684845aa2db33a975cdaad1b923ba5f707eb4317b7e50e4fd689644d9c57ad9bc71f4f8e5afc48865f91c41cf2e77d42083e8e28a7ec99a4ffbfe0bad1556a3f3cfdb2b48640629f91eb50280b91eb0b790bfdd9fea601a532bb29241d563d1522f8a06a39083c900455446bc96b2f576e1a096966c6d206f98b76726eb9a3f97a49443e52c9f47f3ca715a2b2657f3499565a54306d2dec4d678e2af5fc9bd127640b19fd00e6f295b8b414f514c760db2ad5b6d3a7c3058c68bba6483b20cbcc8cd9aceeca7e9f4bb0319b8b151fb386382cbde6c4e234750d4e145275fc1b2e114902d684fd7e7f6aa270e64f4de760793b6f719c8bf375520e7ec38843f5df54ba390623400823239bdf76c84eacab05c65c1f4eca78c54d40ba70fd772c19eae7598d493c41d7e4363e5ab19520eedea153bbf38d4042ce6fe1312ab4e347b38c66c7e3a3618ce641acfd4b60f3b33aa8c774c4a2109788f7d0dc2412d3f6c3a607bfb27ee3149d5a4d0ae82158c3c15eb757c1c1380798dafb35fff4d70ebbeb9ceadeded1b55a67befb11c1eb13807c727f773b37a3ee75cb723661d5b92993a09fba147c781c5275110dd7e9b0dd25451be9ba805f87e7d8dc99fa4bd1f7e011f17780b36c59291af85ad243ad2af7864cb59a672395248b3ea84433bc8a9e43a1197e141cb0de3e5952662da369b55c7da12057f585b0bc67c10422ba6df00c34a1362c86d4bf111a12008c995d73218e257a6fd9e847504aa3db8c1792cec5725465ecf47d0f33a20f296f0888045166569a325d4633fe1b4d321482361685e12d2eb5fcdf0058796fb4aab53c24a842b1163498cd7270e300b0d822a9bf06850f4f754f2cbbb1f4f7635f42ca93e505a0b6d78301dbf281789d0fb8e1fb6cfb25329200688035447b4d1f154f0697092caa99292d25363a06ad321f2c820397c1963ec7c62fd597a021043e97ed90f99c15d25ceea39f28cda977a45f3b4f7b934804cf85d4b32873f0184d67d44ed3d5ef62c907742b0eb61587b995b85a537e094f50a6485c0a8df27c638f8c44358628e2f5d0b58ffd9f089b2a2145d14ae122382486ff9828aaf4f0fe3cca551593717e2c20a6b890cff831ba61674f9088dd9a28452123c1898ff36e6aaa926cae5caba6a5f6c9189b440a19fb863ba82470e8652f483eaab8eb90d382a837508c4de531837697913763b9b2622f5713861f55c26ce80246e5be125fdfa353ec11dc32a84a83f8ab5a2d2b44ed49abb4c513be03ad9968e824c0ed4a0ffe45a49692393693106bac78972d5c46ff102ca59879c9b45310414e1b2f3dede3f07f14020a15dba08f09110da1267ddbd16f4274c1e3bfdaa73044d81a8f9c6914e312b3ee3908d1cdf6f9957e5ac7aa449dff4069291936ac96ca289baf65c04a71966f36bc5a4c38abeceb95605d35451a36174ed9c96a7af41df917dd5b2cc35f4e088294f1aa9ef064912f806da33865b125db5d23c5c3efc063a1d9869e76c96ef1e1284c98c1271774f6f97d5135228bebda82893c8d95c23439fd11733216708de7ce7a60447d410d49d90c709a11524d87e1d2b2f83c801bb175ef75cc48afca2276ac2ed7051a72b48ac37b5df855e67d9a667aa0f08abcef15c376795a43483c8c153d77312b09b120fc93fe706dfeba166ed67ba1718a63bb2d03e4731a242023e6153e0bcd0a3db1c2c534cb032c60462422aac19cfcd19bd42ea8639dbb124439fa6581701e8e879ed3d332390254d02ca9fb74f4edc585c30df73549ebb2797c3fc2464be40c9532fbaf543c88a1409a6a7bf61f9611c9b85f60563a43dad0fe771d664ccfa7437011add0a9d07bfb19dc3a89326a255bfc46aa4c3530cc3fe10488117cc6260b2548758c148d8859f3ecb8552922e47ca5dba79874b2c593cae2508b55788b68fc5a14d00477bf8f2dd57622b45e7e54b9d8a2df0ef67a4ed64e073f6c8446f3e9fe7988b3c482b72c09a3fb50f756538231451103fcd3aa401f82408accd9b945472d6d92240f3db8360ad771aa7f74261743092fec7d0eef64ff62af06323f8f078d1cc8a754ebe0b2f6f66f665cd08a6fe86a2c1a159c888609ce249cefaea2bf96e72c1678c37213f737c35b453b9f311951c9b15a9f9fda78fe4e5fc8e73de532610c2ce55a7948d42ce513549931bbeb60d28b7792d6030068d7a72b445d66eeccb2a3518d8490c0350c37620c7b9763866f02691a196a49a70e2f30adde16b486c12714dc77bc5152a9c7594eeb7126a8740c693f756559c1fbd95c900ea09b7685b48a503bc1267d39ab4fda7088c68abc4b4d0d7f5c0c5b3a6ce33ed6fa6567230c8ed7d39c970955843938115ea8e6c86271239896b66c148171997a5d031ce15d94280c4bda24f15815dbe7c58e1dc66128ddb9aaa502295eb7186083b6c2ebf2fb7e90f932000e1e2b03d150cbd612171f146da072275c4ffe4faeda56a7d253d2c2802989e54a423a81e151791f64a36f3c377dd4fad846729aa9f8b77aa9210596e1dd56d6532ebbea02f845d2328993f3e90dfea60fcdd109804833b860e318460b69401dd3c2809484a528b8a87f0e68a1a267f2f7c86735b5935f8326a54272e6cdc318a713d64816121b12e8e6d0ed84c5204f903a4a698c0e0e4867e2cd58af3ce070daf9fdc88338413b741fbb888739a663670ce7a498997790a52fd42577b50cb2c9cfefdf06a1009bfaa31f8e64becc8b615e99203d51957695b4956f86964b5e46e7ca05f830638dfa4abf9bc7e013bd2e7158428c27755cb6fb5b306808b04f86fe4afa9825169305ce083e36526df3200141dcb9a10381ec651396e161a2a8afcad8b1068655d918a8309b0fea43e4611dd76085647f0ad0863b3458a8a79cff43d2e3a1f60b6d49f42759c2bac80cba68d8f57f44db1c3eacfa4ae405b55322154b75e23a8413845a42b473ac1aed1f034faab0e1104c2968c90df8e563c33662fb208a72bafee62596589adfccdd391740ff0756511f81286f853dfd927a6b847379433c31c54064b73870b59df4dcf91ad7574c397ec055d1805c6b260b443129688812c1a25062356ff8c36c88ba3dd5b292769f9927bc206909531e8cedac0f4f3ba5131f3e86a5c85a8537507a8c7b97c0647d38942a08c69a9e907bcd655a746f08b429346d3d108104d839c77ffa504776fdc94d6dc1eb2b40e2db48535748019f290d55a6b73943c2dcaa91c7756cb66683a7a07103b8db40b311e1fb8bfb769d1b77fdc483e715b11320a39123aab14a5bacf39aa82870cd06c9e7dc90743377488f0381889f72e6a3c5a9c1bbd685eaf331792e764e68ee9106a60cee0c8d1dd3ab81e00f9fcc5b24a928d1d4e149d40778f6091f8c7475972b1654d329219d49b4c09a5665cccfaf6fbd7530d4af68f35ced92b5e7e6ebae089b7988ff092365ee823b94fb10d2bb38b8716d5e84074871cc18b29494bd56d1f8a3e599900c4d954734aa6129bc31f0a9798373027a379247e4ab914d4d767fe49ea2d87864b09ef7851169aa2da1e0cec406589fc2cd2e4ff77cc9f2255c3b8e609c6caf25821e228617b76d3051e859d56c3cd13f8327059405e881c655cf716045bd9ec20d7210f1d805a7c6579c56a8a437d5bd92f7ba682a662deba53d2171d1625c4499c4d061a2b9cd8ca3ca400873c3a245f3156deffaf745b439ba2f99dd2dd2f07cccaf767f9bc17307b86bc4da77e35e871837f2ba52f0bf20c2ec333c19f67df29e7477c793048f914ab175107fe93de5fe7e14192bac574df54b9d123ea7f3fab9acfac9114c048e62e9394a3d638ccf91ed49851845a90a065803ee15f7f9aa6263581b6db3ccf8550e2a73ec95da6fd1c95a201c0022e1cb960f919fb80b421319d3a4256d507d4f3a9a0d71f6d6977f044bac8b8f5cb61a8028aeba58aa042018e1d1e657ea530acdc366988dc9289d60e3b5afb207b53b8beed521710476a32c9c32c3ecad510b36caef5ec049f6ff8e3b9184ff26697056b5494880f9c37caa154c27bb6d3146af438ff8da6a8e9a702fa62d9d069af500fbb00c1fc0f6ccc3d67682927da3a456f7f0e6ea086d1a9fca96d2e2f4e4d961cbfc368190773f82b2b868c4011f1df3aa7bc90113aecff370c0ec40732049ec191278daef3bd3a6942cbb91b3cec38f4153469eaed731a7e3f2d7d54892b6dbb85cff1bf716d8b2ab0cfc9976ccee5f27ea1250ab9fd168ba76ff1896fa617db081aba856611fc943b917b39a26648be99ee1a9a56e2038710ed669c3fc5bbcef48b4016cef3e2eaf14a54da74bde346cabe10ff7969ffc2c3093ac2d983431a2d919da8c575ef296f9afcf883c4dd88f8cfa5c0745d2170d2161935f2f3cd67ef3a808da40035db7a2c442d9b780fb96ae18013d6322e26f9ee8d3d49f3ae6952b49790575f2573702a05ca879a56c4095cd0265a86b70f76b84fb609d6bf1605b64716d1a7918286c5eb0c9dcf28d165dcaeabd5c44ee9b63a1fe5bfaa605b300fa7bc9f82ea6da6209eac62898316f6600f1e45081b7820df0f7bb43f44086a8022061f54bd32b6c6eb1b6c01169843996193089b7d73b24bd858bfa3269c1682fc02dc03dd0b37d9be83e3783ee90595aedfa18c78bb9e7f6e878e42424fd8ceba4852dcc496ee1a60087d8f72830bbf3b8c1b481207b653b8dc33c8c4b86cd534e1e4bf0adbda8037bdb85fb46d6662daf3eba61b9b19b8e507e892e637051235f6c81f0e57e56dcf55ccdaedbe786f5a574efb23f7eb066e787efd5694b938bf4666c59f9159102ff93701bcadb7c624fe465214dc462eec78a79ac464f331bd6b3e0eda8d53b466b8c951d2bb2b057f07178719c59561ac6c81d5929e820475bf23dac266aeb2d260e789246cf32ebd7d11b9f96acdf382682d2dc33abf79248a0fe3c6f7806625c1c9a4040c1a5f15d4cb4da512f2a119f2702d991cb7aaa8eb4e2b2f824ea2eca09f2a89070d7176d34a633c46d925612aac55168e4672e24f4733e3cc635e3c81d8033397d7469cfbafec8d698058c612477eccdfde041049b70890802a07dbf07a2a7402d8429d9fb9c445db868bceec8618822898f4ac14c87bfadf7e45a8f6d111960a591810c534da42008d7682664dda29115ed097002f881aa4f64df47b033d48528d8667f1ad2b819bf4f8f1f0f3b2d43c09b0b4f25cb62bc6fb15be4bef418417561c19fab5b8a65f173f70fac0c3f6272758219351050772c62a04a920d19a2e1e6c3b27b73e9ccfbd9a8efe9e7701723bf8d2f9734417526d74187e7ca141c9626b346c9973b740897de62bd5368a5967f1d2c349dc804f2db4704331777771bb392fe1581c79959c0db8b67b78473ce9b224529a039830bed99d9cbd6218555c27d9fb4e0bcbe3a37656558e2f1c00555e285bf871fe503d458c371a6bc28b6bf4f8789c615f38ba8b284658d5b48f6210ee9439c3f6fcb23cc08e0b9ceaaa4218f1917685c5baa8027e4b95e8761170901933851923ee6d76fd365adb1ca60a3d2d69724981411956f4822ef957d17f7e0b08a6e114ca0fe5c103c81ad1cb74fa6369dedccf969cd20dba5beffdbaf3b59efbc6daf28213ff6a69ee8ebdb1ff8e06fdc96610ee065f79260cdd02ffd4dbafcb1acd3a878d9392cf1eed5d0831a7d5a76a4f84c9cf7609dc9300d3c4bf5341a9abbb46428acdaa4a3dffa909563c03df66e42d1ac32eb2ba1c5c35070918b61deb4e934998f50dac460affd9c2c0d396fb1879a1c00f92f741be4a8597f2dbc7e824a0e9134fc2ccd57c2cbdc876ec51fd8991a3378c140706e755b91ff9e9ade84214bf56e8b6e1e2c2b3232e64ae5055aba187549aa8dde8b18564ff1e8fb172a622fa6abfaf485330a155f8a79f936e167f0eadbd2d8217ce089262dd193435274dc8f38dc855af49db92b6dcedbf950752d4f58f1651a29e4d78531ac021e3c1c203935d2eda79f463c98b824056e5ffd1895fc35696f356667c9e3c460770924b593d1ca638af5be83898a538538872faf8e3cac1c341d768b019c075674bda03500df20a997f68115eb3c41853b3a825b6158bb540bb2602f993f6350b5ae6c84311c260047116c668f68b66b842c32a625401b0770c5905da8022e9c17e20d225ebb3ad9d3d4a1efbde9a40f96fbbdab6cfaa25b94a934ee755acd75997277f34033d5e2562112993467983575d53e2a54dc3bde62289cd949dbfc375f51c0ee73b5c48201b0b162792e314c108ebf98ce177d661ef736c893562cf4a747c5b7464da0373f44760a1ce31743f4902f225e022d6a7a1f352d973a6ec81b4f3e8393c0d135e0b14d8ff9b500eb40d5bd377e5f80e418ef62f44492e67fbd7a7ba5e5e8b3c4257c48e53ddbe11b436e37462a43aa8425bfdae26e5a50a2e83a8e153e23dd0150aacb6c65fabbc770387c682a8d73549b92857f525012f40d6199bbd039349d6a996c821dbcea021c389f70d6aa5cbf0a4b454c658fab70336bbbae515e8bc2d4875ba74fd06949c34f5343c88135dc9785d897cf9532599e1e6c117cd7c8be3dab14fdaf03551a9941aa0e30857d535ba1b5e6ab3bcc0da86fa6de8a265134ed7c2d29ffa672c37b5447f21ff1b9e01b2428c67d63cc5981b3dc81dd52c5a494185e41b9628f003552ffc83c1f4bf5d0f074392d4b6bab8e99fa00ad33673e0208ad40a9e64784ff9f3f5369fcbdd20667928546f67e11fd440441b3c9ab7878df62e1a55188ee1ac3a909127d45b63060308085a905675c718231e7001fed392590c3088378a601bd59aeea967e024c7ecf06b9b51100ad0ab23bf27fcbbebfa4e4176540a5e359a3311692def3dc969241b857e3a7af36f14816b975f2dba301e6f8880c7c4a6e209449fc5179d7679ab48d86b96dccf706e0acc803a96816fc5984341e7447e8ae8d2595db9ca92d2eeefca4271e17a36c725a443e4b8be302c46d004f5c95d749a5117b299b89b629c758ab662a7f4a83da2e2a60a2967107e9c0ef775a10136dcd69d2d50ad5efec262cd687b4ee326f978676d7cb3b09adff1e2f36847ab07837983ab33c8e45399e3d0b570afa1ea87fdf9c1f7fd954803d73ff3c43c81ce038e39bd9a31086a7eea6e59125c73715c55aac3986254c8f4165be33824f7861ada418785f43eadac5fd6ada0566a2d517cebb1026f220b8afdf248fa49cf3614b1530b3af10a4e0908240bf62a72f2a50dbef1227d202290145ce043cd88a67c65dff6b691c27db57db5c3da3aee9af5d96ac0678f0d797b5f3bcd7c712f1070adc11837741f24876c42e3b1c5a5f134c0d5ffcd4b931301349ba06b27d9dedd877febe0f2e654eca7fbd860f1edadc1f63e58b334ac10222dba80627fd9599351932b2dae15e97ce087b80173f7d3542d6586464a48c47fe14ecd5b6a079d227d201d8eb264ea69cc17a83ce7c13bd5ff75adb3fb64d537070ce7e61f772d6705a37a946f0b83bf3d4aa9a82ee5815b839e5231a3f70c802d254f011072d7ccad62fa187c35540e9ab9bb3267a24076cf024e9b0b296305c52a0f4188e34367d090d3bd9be4ec834c4de4af2fd75277d32500f61b10b5298461b62e915d7eed67650e5f195d03cb16324cbc69eb1834b3f08225920f6e292cb964fcf869494fe117bb6af16cf45709a53f0089bade23e54d70161fb137162718ff2f09ab0c4f757f93bd7a7d9217a20d5f65239bf8d613a7517776d21946e7e3bca5720d1fff059e0279014a380305ffe3d035d6726014b062e827105411dac05bd5b7b4d31088c0f67c07aa71780675260e9168d824d5b4f8d526c95af06d1c9721fc1d9333f3ab35303f1d633bd777275dd20b9440cf6c4079ee5fa4dce973623eaeae9bb25edf8ed983d8a003bb65da4d0cad045ad02f31fce5564b0dd8ca7a398cd9b7c4f16fd0f4db23ef3027a458d1e9b1e215f6e79c497fe6b76ffaf77cef9095e8c6da739ea0ccf5bbb1e2721a186d2aea606ae419fda332a12a31922947ebecf856b24d311bfc3e5de50b1971afca7e69dc011c9db0150f6429b4b6e002b1742029a75f2e95c7a04695cf63795467f4386557cf3c35c83ebdbf7dc8042546051ed40bf2c84f98b928872a3c928646ac492e342f669a5295131ce53e6050b548e41cc28af47ca58615d27ae2e5fbfe1755b3e41c2a9f8810a8092b4f90c4267bdcd6dbdaef00b5d7455f51c20bb46650b5081731909daafc018aa8239a2154dcff850c62d6ed783eea28fa544fbe35a3dd81e9cd7b82a218f9fc9291a0536d03417f25d7da53eb4b87a59dcd1ed152ad22a56f3b0b8ef63807110bd30f55c43c852bb55c2667fb55aa218c3a49bac97fe321ac6d4a4b10799bb3518760c249894e2d968849b12fe25acb641290c076a6608a33ad510c9bff673352ee684394172aacedb1a255daad43baef3d90343ba847fa80be6dc17dc2bf767b89f1d7c39525cdcede8449c1f4eedb568b5828c8a01ea0652e909196e7c1d4b482666ec81fd0fe0b6f0c9bf0894c8d902b89e46b1706c2109ad05232d434cd17e6bced81da06ddbe99d7738b17f786e7965282fd6a8f9fe97430801743f2d259a844463ab71e6e528ff0bbb29e467b620425c2e95132b49fb36bf189817194b54b926845a0a9f1fb097c97ca1f219b824ae79c9929cdaeec271e43767a804a5ad67874172eada327bddb7295236750729b7bf013be09a34e5564c298000c7d591f999b7e525af44c77c793d8e5397ac5ebb14fa4f3e556fc668594a15f95983fbed2fefdbd2924829bae643032dea195cc34db288658222e67769b2c6a68536f34c952a8af14367067d9c23812c92e548c187c20143e9917fe8b54261e4e6a7b80a5ce3341548a8cfb40313f649b78b019630082bbd354a6c17ee56e0a9def017464e99e3e1015dd90efad84610e56dbfabb19ec66e3de96f2de3236f5db5d9cec9485c9dd9422835c6db06fec26a3e26deca65fdddfe8942387346f0edb39441e483beaa873265845a6d4e2d7ad26eea21a7ce4721e310255c777b460aa2440f2ca2ad2442bee47f90fd1c232ffd811da68f821dbc9fc0d02abf5889f50520cebd3c8999ec3ff6bfb3e8bb2df21b324bcefd1975ecafa3c71dc3c5f57bf9438651143ded6daad1c8e12eaad65ac66f67c304a883a854c502f3d0b0cf85764fe5c1986b96990b005e022743c945e98d627944418bfec0016d7e19f7470266200350467dd038c79292816e0df5bc2668893da6b5a0a3e30d250637297c20a314003d737179781752b3dc10f8f86c605b1701d1ced7954aac7ae5fb393f2c6e28e4ce337325741b98a9af0bd6615dc5a33c7a1448d158849dfa105b920a6f503ce51e37fe58001b0ff38525a7780cb70e2dd55e569dbe6f1da2649735e6c745d212003c92c303659a2f309ebe940954cc265f35c8e7a1d48ec66b7a457f1a30dfbea95bb331e8dc88115d7212153792ab86fc039af92ecf0fb8d4b53d80daac62e6276f4fd46248a3a0c91a6a52736c5ebe216eb8dcb9147ef33dc0821bc40435baadba2e6b91d2c425c86319a49529136f5ea54784f19d752600927aacee2a1466c9c9e2d388b23ce2be22ac3e8c2dca39450d2efef9d3d46845b521e72867fcf4df6997d7f5c3cd810e761f63c5cfaa6121a41390860d6b5d55e43c83ec135463ed927425c313de2f91740645d5baeab2db078eb5f7cce5ac472f26ad6b90fc86460c336da655f0e286c461c40a172feff430fbe9cf0b264d1c2ec651ee6083b7d2691efd6697df15ba328f642e7de489337d7e30d1604c220bcd5dcd55130754bc12b61f710164e050deb4a0e054ab301beb5ee6b19c12470a78eebfa5a654a5c51a42131ef8727766fbe8b9b431965e42e52cf372098f525bd132e774bf5ceadc2b266950e573af573ba4b71bea6b52149c7f56b09dae0e09f75a73102005b1b3e55121b6b217d96a225084ab220cdd699e4173f0c8ac32d17b7c4af02db7def508e8869b5af075403d9b2bf56a7df8916aaecf6bd7ca8cea03c51346a429731f68d85d4b93f4f2d592e20017522ff893c09f6d4ad6cad87fff6ad967a85c1439b8f7dc9a58f33d430d555bcfc7d1488c2d6eb42fbeaac2af2f3c428033830ae126fa0e1e68818b45053d1e263caeba2e1e4ba5db493aec19a67fce917fe2132679e29373d24b5e23c823c90aae8a635e91f400c68202a9cc8787392e784857017745769cf185afd00633514bffb2558b4129f2c3434129d858fa12a25c3ad75628766ee51ad78190a0ac07d6aff67d86cd8db3b4e3e72f37c4547a76fc42cde544429f0fc2b490b542d0cc959f3c10d6de1c47c57c1a8aab5669989018242fe6d440abbce05501ea7631ca6a69b9d8253f4ef56bbda31da3abeb89e8631ac90c039615a7e308dd96a4455ce7842ebe8a23dc18e8799601e47c315012dceb94ffa79862d6c5bb0a0eea6172af8224eb5a53563abd62e1926cce5ec368e7456d34fa9324cbc2dc7346f724fa174c332e561d5ded3eac47406b78eaf07e6d3d95d2ce970cc0748560956d4795c9fc4c8bef98424d53c9d59e8ee14b57fdff7617d76566c18a877e17f87c7337ff7e1ad07a46a65d914d46ae8a8476b1da911b461c0c90d193ce61ee6d05b55aa8732c0bcdde4aae34cc47bef722bed1c8e0f33e47dad4f5cf917ba59ed0cf6ebb4511fd2b609b3e949e4df7295d9556ffb9e12b71cfe19e6babd468fb1728c43d3aa7927b49a5cc5457498dd0120762272e300a5fd1a2ebe22b29be04eb7b9cb36e948e323262c3d165f563250232fb371a9b2f004c8ae4a31d6969eb617cd4a574e51a4d789cf17b73a3e54fffb8b93e212e4dadf8ba75e5b9803db1f8f833d4ac5016d25bcebd438740d0fefe1a3c0d60e6b18c77185870d630fc4de7e9072f5d93e5d76e039672574e7152cd96218900560859c4df738d6c17390e81e184846dc8c8ca9b7489e3c5fc8f9bc6fcc88e5edaca699626950a06d7b2c9d3245f4ba1340ac555a1aa9a7f65911e3649fd3a60f198ec63e0cbc58e4be249e76ef04566eb16c7ae10e5b5a367012ff2fef27af72ad8c3713a89eb3d21a0726cc06fe91af4f77f297fa8c232b0425ec023bf67cdc27a2188a89d567216d534ce34e919b4e1e2263974bb299836f18107dfd4dac4809d14df902950101b9029039381a0515f46ce8ffd9388493734be1f7e61ccc5c42be501248d2519a3c824697bfc022cb60667519099abcb7445d9c282a05066a64961cb902ab35357f929350201985c35188d499cf5667b0465207bda93556c483309b3d1276f30c82270e75a1786c15e6a2a2693dee47f319d6ef628ec7bbf7d0859c795542265c6c567d5e2da7310882317550f0896bff1a68648dfb4423f2a8d4c9c7f27998b8ab02a1b61aa8072f85bf93158db7f7f31d7ef5129c2aabebb3ca370fbadfff2e67378386e4a579a7c32e85aedcbb3cfe1cc8a3293425d0c010792e3dce8223c9ba6ed024d2da0b97f123cce35b16c9299c96dd087298277959c512955dc440498e2a7eed55616f4fc68adf4318f791c6ded1582aaed34075956ddc1e87295a601c7d6d762a8d4ca024374a4f4a8f858da26cf1b5c56f3afdfe5a5c26b90e9fce312b3f2d4a532073be1de950b7c44c8e1f7db4cb94e4e62fec87282eaf1127cbf836f63a4bb71f964830e42d85f2137ce3438621ea8be087e0bc76d799586df89a451d392e99751e60f0e166189406bf3596d1602b0f93fbf39a565917fe7deb303da715b75e1f741646c6335e86b445b0a75ccf8c2da62bc29229cd1589b68ed9a7ae860e40d0d1582964f577249b6df12c50365ee80264fd64919614ebaa788c93f193f13caa94d1cd10d86a2658e1cc4669ac72715a8dc2925d9bdc62162c7624baabcccb22eab9678a216c3b9c90f6612d3c61b06152dbc7ba444e5d761d44d3d6a94939004774daccfd2e50418f94ee4b83600e4e23fe4d56a9997ab7cbdabb21f51c7d658b5b138da5d8747a77a46aa50f9e83cd9094fad96684ba2ff4781e39ddffbbb7f34878a0c9473a486b1b5957adcaeee6b205f3656f3cd5b68cd82203cb5b70ce5ef5524f4fe6df1563d197a8f91eb50201b91eb023c8fbd9206c2c1e5bc2ab173fc7348e49bbbd8b161abc8b9387c5cedf6f76c7e7e67dbc607f6349a965e2b65628c646c989e8bc338e4aefe033619c669994ce98988d3f9938f1e49182f85e2c565c85d245ea6a907a5c82b22670b40fedf2887749c6014b9d2898908f6b68659c12f212b552896d89b72df2ae112e12171de09663cb39f5713c4862f49e821dda6500e1b63aa1f80a7a84e459e23e0c3c23b3fc67d426776e423f3bbdad1df9370c93415b1fdb13127597dcca915b7d6957cbb1d7c0eedded088fa8344fc46e300d1622c6dc6b40a4bba7b691f2fa42d5276a30c66e5b4cddfd813af29dda81e8b3b3c5b6875118c9428952b0f09cc083763644b618cf8fd2cf730f208264001b7595e74747fe8cc08b2453de64a83385d251911559853c0ec148bad5e74245e6db77b4a0c286aa05f3a385b467e875d6152f75e979dc7801d8553993d4dfc400d69b6bd898e40ac753afbc5acad8dc44c93e4c6ae491eb2a20d82eab36971c6f4bf1c05f3d8d8a3b84b4e2ea75a1c358e280625319ddb0bb83cd9405fc5bb06e045b32f9212791d81f097706d0b76efe2aec204d7cfd7de0cb90993aa60c9fa02067e7f5880dc9a15ec0a65132085e216d172f08e63dcf8e86c9c4d2528b2bf9626f6635b7c5665b1e48a39724358b48f459378455d8ccf3d5539ed6e626a9079a17c69db5a27c86bfcb3412cfdcf6b044a91c0b07b3ddcbdae39aa9d15ab240517540de7fd800494b4a2f3cf033d4a877411adecdda9e2f3a7c2e2b4546a6ed93cf7f6dd920e6040214adb135c0d9d21012b200f8c441121c24873d4f54ef949d23e834c40f2ca54a4bfc53b19d06565d246b64d542e4084698167511cbc60dfc76f0a42b1741be180276dbe6f9b64690f6221d71d9dd9df644e2bf8a10c86fb3c7ce2e471527a351e2b8acdb67d9d0cae618758b973f3f761f7897cd642deda882534c6785cc14874748f3593785c2f1ea0dbae9e08a93747b8a4e874e435172053a5ff6df4db99dd6e3f452aa43882528adcf9a1c41254cec754ea3f3337e39c1113e69d2e49a8f019bf7afd8ebbbdc06c09f17caf2af054ae69530aacc0413eeda6acca31a05a83b56ad11ab248c702dd20958bb121ec0b51eaa3485414908b0f0805b6bb01450a45b6463d69cadbdfb1f44c881423ff96ede1f6ceee8864c4212e002d0abaa49198de248c5894acd6a1bf7ca544ffa230648c0a8a648c8ae9e052d410652dd7511ae034737f413b796a810e04867db4fb13c1fbc1d065c611ac1527405572a64d720ddf7cdc6c9d45b83e3be415188590c5b66d2a4c57cda16e788bc9f73933930e8f37a96177239b1a3ae41446344de095c1d5f5d78245c0ce0d8a7ebdee12bd278eb760c2494e36fcc71781347ebacbfa9b1a35dd83c2ac3c3d4a2cc34a0fba96dbf56886e562c12ca0e6a07ee68f42b7dc8032db109e9cd72bc49c930e8a9f37418b158f8533a7c24c9dd2a14943ded7c9f2dd4702c86368d7746305b768638e800fa94dee5b7f94572295b041667d52fd2fc7d76f695bb529e7866ae78d8e40274a3f9b7b609fc75f7babf79a5dbfeab9f55aab90491b7867fcf2e033c6a59ad250431bc9fa0952e540297d0ce365dff37897f549856bba11f18a975052fb6b11e287dc88a93594fd2fb73e683d14338cd93fc4aa997d7d7574767cff5c7232af02972376b15187ef471211005ff81921a6c7900eced4cc1fd1045ba82f3fc446b6c9d225d406188eae95060a37bcd85a79a359000b03a0b032fe1cf458418a30bce78911b569e133236f91dd30ffe805ede06662b541312ea37f19d4039039ddc03e668fd40f8661b05deceb972c0a5538912d2877ab77648d39280bc9d40516b266087243a2be29344ef901e33ba0312e1355e95accbc1019ef6fd3b6abf6c5d9ea8bf7f3aedc3882380afb37df63609be069e21ef7f7dbbd4777d4e002993151cce93a08df03ad5aa2234fad1f9aeed6d25b23a0525c92e3d76864510f8f4a54a148f013e83e4305123cbc9cb25dbc8df610f9748f269a3a972e7ab0e5060584e1899c2967ead59ed42a49b9175ffaf9ab3d3d203749b03a9d194daa19a6d5234f5633742ffd14b571d6ac6692fe77d57a7a9aefc8ab115c928df4a1796556a60ebad2cb875db58306b950b9d40ab152b7e5bca26c3c15516841265bfc3269010ee90959b829bbfc04f3fe7a12f9432ad3d1605217c4a329aa7f43d100e81a3471ba4bd3f9523854fefab251306893c7f08cfdd0646c69f6c81972a0124d0a606f18f4ee61d3e6ae7ee93116c4091afbf3d4ffbd022aae5bf0e5a919a59aa36a0a31f35be0f6813ab8c7ee6a157493bb105e07f9c1143c4c4ad06ed4c8d0d8ce30622e9fa0d9bc24812966b232aba931f7d81eef49012b4772efffe10553aa040caa0209f42ca53dd73d84d61ff8db0e0ada0074f09b3ae09d89820ab921be90f874a297b81e84e66e42e90705c0c144ce089ba4d1668af086c77d1afe9b88be250bddb3700b441d6c370243cb315552e3968852a5cffcdd6beb6dfab6e80af08f8ac545a14bbc12bf8178acfd57f8a0ba2f6c7ca411b2fbd1dc2618a494682c68ceafccf9e05037a382538758d8f3395670782f5e1d615cb4fb92a9575babf45e45872e13a24754cc71fd505de81531ddf43d20554a4280c66b4c9aa8c398391915849ac481e3e8e1fea76ad50bebeed729c8bc65167cc65952b8028c0925f4b66ada797c8478d417dea5871ff1b2c3595e22fd52a79f36ee9cce228317f041b0f482ca23457e38f3dc5baae3d5418432e576241501ba2156ce847844fd7d0f42255edd14c869b0f878787861998ad175462e71ef413b019ed176b2930bb13cdd6a7d1e33029056587222a6af5440f3558d6b8406b47d8a34c62b772368a4fa5802cf8f38eae3b672d0a85e65645215f4db490fcd7702efa3b17215e058af13e30ebab6010712dbdf25d55e042f8e650f87fef0e649a40d473997cfe471fa6b1774b076471f2e4fca12ff2b68ab0dc4151fa81ba47b4a3da50f2c4cb263800c976ac6750ea09045838a90771cb5be0f7cda51abc135380b49b3a765d082137f4b222a39cdee348f1c3fcd7abfc6847fae0ff1e7b4b838b7066f7789a1f58c5f4f2fdad7d70cd2a703a0088d5e17a9c7784b69ce39fcbc1680b97e5cdbfe7e445807315fb9560ebe81ce078f378af56ba689061bf5282b470bab38fa9b3f618815c76a5eef761dac457aa41172113d19376518ddf61d71d3c85108c287e1797be67028429ab0722a7c94a20afd3859b4ca04520324aea47e3e4f4fba3f04cbdc333f7fa7434065eb017259873035896012013e7316cef71ad58d0c7c0ea18732a6e21287891866121433afbd4cb91c681f7613ffabaa44042b4963714a75ba4554c3c8a3786c121dec6054b8e839375fa9119bc46fb7a5bb6d9cc3c23b581679c96482c07b36830794e2b256ddd5dc23f1547cc5eb2f4e1ed9b94f298839ce3205d192db2808bd0e68a2a1c4814bee4a50d7defb76091050348bb4edf284c1877c38649ba01ec42b4d8ebb3b61d64fb96a71f646972df2678ae243f9649b80025ffe4fd6817918e205a0444abc99c79055cc8f3ea61c9f08d51582804a20da82139db4978147e325f95106f86324da20d8929f9d814c9c80a70528ed722386bc9f8aa3cfe27dc6a65e6cb8bd7ffce142b7a3f7f69d8d6d315eb7a9cfb2abaf5d0336c43e083d183dee7b7fa2ac55c263d62923795aab41d98dce28db1aad3ed94d058c5e82aac617340cc69aeb7c1211c5129588efc3648aca43b1ff417e0fbef0ae9b4f3a3cc7f3a83be780b270a005649647016c3e9f5f58d33bb261c98f426ff3002e73c40e12060cb8bf1a186bad70044ea5a79ee0643aa6fd889f2d1ba96052302a9d7c7d024f2edc91b826256613f78ebae3080136ff3586e931bfbfdd46696bad2feb56742473295f9e889d5165a69adfd624d1c957eb2a5fc432ad4527151628a15ce112e07bee1175af3974b1e41eee6ff1f7f10ed5ce3565854e62643cee56b8dc384c45a95725e7a47b36e5110ad4ca6dc083519cc7017c3c6fe5ec891e80eae2cf3ae38745c97e1babbb5e442a6569245aca62befbc7d6f49f2aa0679a2801bbd362d96a2d7593965aac2e29de0dfbe7e10e768cbf4b3e62bd3fb448b0735b8c985ad176aa98400f56f725848a96a8a6a7ed37a3d2aa33edf68848681f867e3fbe1dadd8bf16cc8fc86626459b63b3e120917d32a44cfe42962389343a0ed20dcd543628614a5588ac0a0674a0f38bddb362950c0f1339938324cc5e44b6f165bfd630f18470794e4e0e7c5fb250f08cd0338697d410d72c35457a4c3fb0aaf2dcdb45296cc53db744dfc34674f13abcf0580416908864268f9be45d6936aa2254ae3e9445082fea979a039958842932bdabc8c6e5cc890d7a307e630aa46fbc2b20a19cae348516e61901adbb00ffe36c09ec7b9d59f7a80a0f7fb945f1f359f939e7d1d1339e7e59067d4ebf3e7c1367e97fed9ae7278db50ee0d22624704152915b370b41d520e0c4c7d5a8544b131f2942506af778bf87d2cf93ea21cc77ea8a2646586504c7e593ea5871ae5739b8062781e264e95c03a9c70d5b87e97edbafbbf2e457a092db48884fa662741e268477de0a99b01356c130cb4c4f351d1d92c0b4e4ba05d120b08e516c63aea7600d06f153162193e7274d4ecdaea263f88755f17ddf0790c2d72b08fab558139288af4dcdfbbc29a3c74489032f571cefc45db93fddfe76b4f32776a9cdfee16b486c9c554e730312a47ae65edbb4dfaf5653dd038e0c9577536f43b30c0a7e6733085a1b31c8bea4c45f39e1ac0ae81e02cb01c96b0a7988a4e499622c8c87ee1d3385d464cb7357ebb8d0a2ad62d85b5d91ddda4d0f59ed21668f72ca20a450cd8645f561db161d1d1cac68bb1d7c89ab07cf0518fd5c419501aadce8cff0c60f24997ab46c6dfafc750f32ff31b338feebac4a43923556deea0ed227913182ef5b61c57f7288727171a6b6916ef9a312ffd87b3053842217895769428b5e79b82bcfdf2661bca2e34731ac5b15f7445df4c610af9a0bd2256d9bddbac56c2a5934d5d646c0ff94c932b341ed89ba1f9f773384168368fe9657a7dc20a968bde4ac6a0809d6c69edc6d8686f71d4e494303537bda18e1299d16b827401f81d3e0a028e5acfac81618a7ac9a2298c1fe88ea17954b4a81b761c517ba63e8746488ae57104584845bf158d513055a797c581ba41cb764baa7a11deaa7f2c87b3b7f4bc2f2331bf23562a795c520589d8a71e1cca67b40ffcbd9a212f475b71e1f033aed532de9e4f6e9f7e9f95828ac69f0c982605fba03eaa816d25ed53d4bbb8905feb63c8e2f941249a42b5c9399ea99b50946c7278711d743916ca9b71216db37355b6e72c9e6ddc2fb3e4c1147e3d0b348982a3ae5367661d386a01c045c2d9741edfa35ab2ec22460fc8aba32e3c8968933f318de75ea66d7dbfd22d187b2ab7df8a1098fcb6e3a95b4a5e1a955a1a03f8d3164fed6b46d46b132bc3625a21270a9375a783e91eb059ba9a45b729418ea68eece65c9ce4550ffb81ab2011b1b0d2b152614d33f711c0226cdb02927a297d912799154d2aed7c06023e0afb4ba9e1e28c58974d6f528572a2f69ecf43e403a94999e0d406ea081ab03fd4ffb8e96647ea2ff00ed518712c0715083793db83f7d8268220c795e24e83ac4306e42a9a55922ee7b1b0b822433e2a6920cc99e1e896ebb08383d2eaf33a1510d14a54a8de56bb1bd29eaec11e4b4c4410bcd4a576caa6054b913369e37ddf2e169ec293fef1053add082a094edcc5fe697ff0cd1fda586407de2796eea5606ab640e36b4c3b27d7ffc0a2965b52d31d51d80a2aef187d74f04f9a4e2c089fe94e848f62a03d6a14d276bc4e2008e92459a376a8d377392bb65c3f362d2d0a6ad24b87650472d023a879f5b58cbd3a003038c4670acc755198a1d6de098b64a69aaa04846a7d37c15725961555245c2e2419921ab3beb789cfa5dafecb920dd9198dbef86c5f9961a0970a28b77b5e9a98034723240c2f5c1d45a0205498f69ecffe36af65d99c5e4b44d5783b7b2a3b1d8caedfe1e6d9b1fb847393bb3f1f359e6a8aae1428afe093b4ba98d05ec6c02c1abe4f3fde5b9201d69a8b89ed605b1a7840b42d4c5a46ad0da4fe51df41a272866e931a96629838024f572791450fa7adfb1650189d3bbba1df6032f4fc21b2b93bb7462303f518aabcb675f4d28504daa448b59aa1e968e81180bbdd14b72ac0eefbe4a951a2d1d1a62d43f1711e4852c26c81c87f3a054d7d45163c3cbb6939f47db8ecb5c4bebc9ead8dfb1f6efa48fd7fc712385ecb26b03b384ff5184819fe3edce158dc561054b39f70c82389f47b7e0ae8a50f581c1581780f5164241a962ac2decf6ec5ad2499ca11d5199305865d441ed0b36602776a1814f3408fb7707496ec28186989f269a07a288e30c41197a58c0ed16502dadea98f228250f82ef654a1c7aa11d4c0eccffc4f2e052c4f23b49988cad563a0e439603f4fa5628a710c8d56fa688eb634d0c27eb4debd68e482217c5e2fbfe63ffe87e48294c13043876eb8d180b84534aa6f59f881df4b3c57e21e4c41c67e1251457eb5d4748b8f16fe53287e6c4b0539f71dc5eaafb15702a18547e1534f41656ed3efafe2490e7d4567645e71de9ed7f8ed81aaaff3d4ab234088bdbc8900d6b4dcaa5751991e60f420eeb01d3ec6eb1cc3297c3e14b03669731c46580ed7d84d25108d5338e418b1eaf513a58c28cb63ff661a0ea60c6761604668ce242345d20c5da3c6be811e837f941cc6339b7f06cc73761b8131525aab25a32a4dc19d697096fdf8dda90cc8d700316dbdbab5b9def6b09ef4d81425e687872ca5e3c716d368daa019b8bc13da5cc76da153aa2de14223b46af0246a8bbee4fe09134c81e83f73e4eefec63b65a34f9a6bccfd341458a78c7659ce1f002a067313e6ccda7e20edfe115532cbc4915761e545fbef215511d4b989214eb8ed12451c5768809f557026603d4e6664bb6d2e2dc2091240adbb55361ef8f4e6d108f7558638ae5bf84d7099775bcd8f7400f14b427409af0d654d76f27b69e1798c4d6d7d64d82f73c60a8b7ceecccc1700a0f35b04818bb62706dd0f4d746fd2055714a32c1777e7bf4a3b79accbfe916bb8a44eb1b819e6d0c0925d2dc6b1c7ac17779cb4547607a866277657c79b49fdab410d9ac650666317f141d0b5d8104e14623b31dc3152f5eadd20994ee72d37ed2c2b5cd436f96b9974c4286f53f517e0084377da3e280dea141e0b3b74e23afe739c264453549e8ac06626c310470fee82fc99adb3a72e7a535b86ffa9aaf0ab9a0fef086cc3254574ffcfd669f6a66d9c53b8ce1d6ea9015a0a4c5c8a591f56137abb75a9fec5af481fb97d0cb12fd98067ec9fc81da628d0d63bba4504784c42eedd9e15cfa0f76edcdc4e96b4d161eaa70dd279f97833a4a6110be9ec9020617673c5c62ae8a8e129ffb0cbc341cdeebcc445233c179be3aa7eb2f489a5cd32c3aebb395486b9aeea1721fa4e2e0aa08e4cff2c1fa24233aa74ae1ac0ad4afe30cc85c4fbd3fed90d77ae0da9e8fe30383e988008d6129cf800dbf1c76fbed83620894949d8d3ed69e6e13969b9349763bf451dba7c0ce74d45c0ed6f400313bd3769c456bbd91cdb8ede0bcdf46983116daf0e6d9706b796dd31897792ee0e07dbc79a05250910cc81ea206aba66ea3a9b643ad18d72eaf59e4a9d6343e7013be765f2ceaeb0f00b2d20930337825152ff413a7066a8c6217ea835f1f320e56832cc71e4fc823edf06a56a9da02da9ad10d6e8a8a1f3b09c1f58a61348aee509d6a57178857b14a919aa23ba8dceeb959ef9d2f2bb1c14f16387db16d401a4c7ae2f4528b2f58e29e552a33d7aba80df8e9e0a181709590a5291a87dd6d30701274f8c6d741dbe2cae8a355a84fe69f7817c3c8665b1564e317e15c3eae97518a750d402471cfe58de57d7e142d69d1f4701bfe1f7e288e1cee6375a469ff6fce3781055d5f93aac349dabee5f5118f181a701451b8fd6f1a355c609fe767353e5f6efc24073f8738ff5b8d24acd4e43662be51ae2dd99d66b696d203a5675eebe57834032a30c97441097c805ecfc98e058bbe57dbba61c4a6357f778ece2cad480e8e42a5d315dffeae8925931c073469c55f9fc036e6c875ef80e25a9c387f0921e7914a1f63ff785f6d6bbafdcde634d8e02ac43a5c1c13d527d4719640a777e65e98c1cc554b81b28a31bf6e296db71d9c99622d06227541b8de6de6f03d6037037f7c9513cb8f1c85a64c60d841f247ecdfb434ba8da65b5610759c0d585d6b69e126f05fe063a2499290417df5ffdc8c388e9daee939a75bc8cd916d0bc0bea076883ba1938f9b54b311f643a37bf24d353bdefbfa659e395b4e5e6803779021943f8d7c1146941fc6552df51a134b7da3b8a576faa56df7bd4573941f8ba18b84100611af9be002c79cd15866d211957147c66eaaa920b30b288c5c2e6ce6a152d8cfb1e8eb0209dc01d02d0b24307313ce197e2873db1b73291c14bad4152bc3fc48abc7860c71d467aef6abb635b605f48a36a28a21148c79ab6c2d4345773e8079dc03dedd3cbf0b8da8d0d6a0ef084354831a23658f6297aa502931d8ef6486f44fd7e575c0e7e48eb385cf04214a91a315c48b5bd64c1344f6d58fb947301f134c187759a7e7090075db3c10349071494ed0929170d33017de5e2782695df9ecdb5d36b2a61d6a1456eb290632dc602935eb04d681fcec8fb44a437f9f306dad9f47ff1a481a43843098ceb7c2c74f8d624ddaf1ed02b2c06dbdf1726372b9509aa91ad31ab86ebf705cb1e920b3dce13e37dcec0eb55901dd4278eaf52427f519485451b59307d2e51a698f698e23015363d0610f746b295e1e10d34ec310dd2787373f8f62e57b7b236268f05051220d77b475afef25049d6000f15dd82f275329c9894b965fb5ad317faf34551b89394ee7422fddcd04541a8acd9622d0eb0675a50a342fcefb1c12b213007f7c6f0ba7d5d26beb9400f53c704992296ba462f391cd31b49ba8ab3c487c6159364668fa6cf9196d2199a88bede10591106f830afa4f4d603fc9c65ef50b00936b049dd9a41236207ef41efaf85a9677f4cd41bed19746c27e44c7cfff1fde71dbe80f4c2f98ab113dbd806ddbb9bbd4a366ab5656594e68554e2f5bf0e4cd81bdd1e1d1270b0379c53ee4db42cfc5f4c020fe364a0d0b61c21973d37f21f687a7684189b3e0423c8f677c6686e666da35dceeb6ea855f88e94e9dc0c3bad0b3c936188dbf1d4acb76589fcc7eb33b79f089b80be3ab088694e60e24831594f13618b5b95fb6497f9282546482269c7d683f9e52eef5243bc7a7567c24ad8bace0affd9f99ee92602150062b9f6d193392606b293266e65d9de0850e79c38b167716563943eeb31cd4dbdde348f643ce9f30c23a8a2e15965fb876a64aa24582a85932ee61695731ab01c1f33f515755878acb5ff7d04f3918a9b30fea2fb0103a071fde63826ce8bd2db96ae51332a5db824eedfe54549a1e2865fdb155aa29284f9280c5372b51423d6f65ee68d10d45e014e2ecb1e1196e0f3ddd1f53c6a5dd217ebafc9e1f07b0e7e7716303066f41782056bfae76896cbd1110f2e036babb14a561721488b3e0c3f3658f93ac30894ac316cb6d5ad1790da7193503bf208f09136c7fe1bf406f45d42a2f193f8204b1dbc2029bde363fc2138c4e48bade094ad918aa68139ca714638082b6247c4bdafe9b8ca0a5a12a8d08c3594298809aa07be41e057eb5824fd6917da26a721e9f443e35628564c9d1ed8191193752d21957dfc1f3d843a776bdff26aceed110ae57300e91cbeeacffe8cffda68cbead2f5371e3a2a823713ff9a3c610ff88eed3f5951d7f508f9e94b8dbcab0550fa1c6b4eb62effbe3f855e5479edef4870f88bdf655b2ffe7abd01ae7cd894fcb9357b5d735c8761ae2978e50f6d9153f099f5f97b09e6d89870dfc87463b6642bf4742437ad5a06fc9c178f7af6acf16c6c891a6089968d0a55bd046cd99ef95560c86143869f7e7aa8866d0e539436b957c457c3dabaf3af8e5c2632911d9dcf2370cec83544a8a0d858abc93d6ee6ddde568812e97ebe2811ac1fd03a4df68e18a6b47a54463a23a6b7a038b185cfa1ea2dd051f3eed7129ae69ecb9166d7476b094e73d71cafef803436cfd626f97072bb95d20ae44d06f99d2281b8acb43ae30f5ba658a163c87b6586d4713f5f90e3776b9ab2d9d9bbd8ec910ea6a7fcce17c52cd71f9775382c087331952abcad07d5bf47540aa529d6f121ac02c5608264bd034abc7323107357ef59771f5b0b481c0a289b06e88b8df98677ee85ad11b0db5b660e3c9f837e13a68f2485cbed2746f87851bd1bbbcee86aa308a0c34ad567326d05b451c1a6369da2cec40fd1453de3590229901dcddb4a73ca7ffefd42089b5ff917148c530e6459c5156c40350f53d3e63fb25b71614f02877b90bf54a23f89e52c8b6ab11f1a19b6fb933702769b47810543cfd64804f60b8f1daa69b6ec52e443d50498777fe6b182dd748dd58c637b6f6b4b811591e882e46c71c696a85952510600674cf2d70d8ed9ea05524f5ef6d3928cd64f7d06a717a465fa7ac0605fae9395927dea11513b12a42e5c4b9cfcd85038fe06d6650b828fb158cc506c5d82feb90b862122c0c7c70b15fdb3458490a4a0ca2d7e540b92867b55500ac8b8f496686035a95b4fce79d7b16f97e36f1e4e158ec76dc3a98e641e3e0645e280c10309848cac8507461471020bd3b41866b7e942d5a346d2d660213ac69459890c6d9adc4b85cbd76536209f662ee9778d3700bf292505a967d120904fd6b81f5e8b22779a7f730fa001c0d5010bdf6708626b4f3909cccf650a453e460521cc9d412051d2819858ccd37b57a5dfac2b56d96f8da1496ec66bfcc5214e17673b70a05fbcaa5b0cee71f902960102b9029139b753971aba47f01384baf7c4ba68ccc66553df957bf3d8bdaa8a0dffe59670c1b1fb1f76d1c6f2a5264268ad2cfec1864b1d4479f1c5d5d05371d1a77bdfeb7e3841b1d157226a4e671909f4be2a96415f2a49dcd7c9e306cb00de97dc819f15198664ac3aec534aba5351285eef7d853c50992d1a6ae53cfb36011f7dd2c4912fa7a29c193e11b7a232bba7b5d0ca21ad5cdd6a8f58376a0340c30f5c8560bcdc1d92c908485a194498ab5ed29ab3d695652523f4519c5e698a2f4a009a8c2faba8d5e0165a96762cb4be04faefb1cc632aabad2f82775e0a4da38ec1231591253694349f14dde4ae7e7ee401bd2b58d429b36934588a1d323c83f11f871cceb20e1da5c4a216fc03364397647a049395ff6c0c8fb76b351a279967481e98546e3519b7ce43ad3cdc5413cd83bdea3b92bbdf9a1bfd59ecff9e94b22abec917372c97d376355f3652d71d307502a8f2e1e5ba245da6c5e08e63086cc76b0a7a26b2db46d206d11427cfd501363b46356fa1575b3c51a8dca72f67dbb3bc9fe77315b8ef6bdf9cabc0122d5b4dae7028ca1600f4b04d279487a2cb91619c798e9a38d5a5b868acb777c36d70aaac87d90e6fadd3f7e58b652dcd45410f72ebfcadff1eaadf27d2a7e232c3964ef5ada973fb5efc18ed54f71a7b26aedbe66bd1cd598b86e520abaee4eec60d5705d0652244ebb2961a97c50c6548ab2e33daf3b915ca6cdb73eddda73386361940cffff0d01927338f20d9b9932154805ca89028ad221741b9d8988f050b4ac1a81f3bea789856fb0bd68e1472304f46c3d0f32bf8c4a5012c55da5aa058b913beaaedb06d726611c69444d915a7643243105b49573b999c9ff7b96e27d3927533d982c90662cdecfb3f74b84bfbec097624acb9424956e66095be5a193b297e691db8f91eb50202b91eb0fc23d4451fef5742f639835974e1e18f18cda8465a7653b376943acd73001c930e5bb1d6dd09a0bf02b0884ec76987aba9e04e0efa35f3513aec250ee895b2c47c3a7e65cc6c7598fa2f1e41851cb3a9e4ff40fa67434ab940233e14a29bbb6f492c7fb03ca78456b907debb95e9136ae4faccf04b0abc85d56a880f514e92c92c3874dbfa36379a1fb844ce5ae2ada204351c24cc21820e09b7d91409162bae035c6de8260b78594ba2ce3010f931e95e4dbaadad68d4342ad1b2c20fb822feb51909a759394d25e6af79056f757815dcc5a75c05498e54b4ad5aa829a9dd66d7d9a5d2bdf8553ecc2d7d7dfe90693d8509add9f1f027527946060c629fc334e34e6d3102d0c8a2883ad85a78bb7d7b7b8d0c44ab4a62bc84f520c6fb22097bf496308c58f4a7c05823fa6dd5c2f7ceb18202707f71094c506aaed0f12db1e7b38723b91b394102068a56faac2b19c35f3cc3bd42bd00ee7baa570b29346709f483d5d3e9d0c44621e0c910deefb8c4cfc4a233d9a1fe9640a1508b0e95e9af83558e1a51471003c918d60cbd3a97789b4ef418d1555f23558f6ebaf87c65e7219aae621d1658e96d47314cf7c4e42380a94167d1aaccdd63ace13fc1fcfde8a0e6515a3518a3437b62b084364304eb9f2ce630e21ca4f64b6ec2816804e8783c116d12dca779ee17a8cef04a70ae429c4b8565e8840444092408489aa67df08ff7ae03942873f6f5964c68f814fab3332d2d441b8971f6a616e008e328bb94e71f7199d3047a6a637e1a575aa7a725316fafbf31fd7ebc6ccaa308eb795d67c6a7f352cc185ffbffdbf7abd0bc6a49a486735ed043bbfb65c90c51149e85b45cfb61d2f129bef617f74c29505b079e413701cc5cd75de49dadb0ec40c9e026c7350db0263f82aa317e75c6499566538f034383bb018eaa3b7397ccb3f4d8f195a0ced5e78ea8d5167502f66992540f00da6f9914d88016c4494e7f331acd497813ac91aae0417e801400f8b9811b89ecc7c8295f5a91ce5a9d4a2ff573f6db0646c489951d8f90cd9542cf8691427a94e0e904219694b65983c2061fc84c5fb0aa255addf0dd245e50169e99f9da91842e6dff5bb0069751c222e4c6461cc4bff9890cb19dda6a246931253ef26117c3db1532537a7db374e894972809882e5ff0aa35695beeb2d6b96b251c47450fbb6ca47695b33953e545969567502bd3127b29e78f5018be6303a81ca3944a8f77cda82c18e78acceaf092becfef364ff252abec1e7a72b73b3cd871e71e7817f8c9193bc8191162dbd6e7e6cb67d9c936ece6b04acd108b15f9d604aa1bbb3f49a903f47d66e7be0b430def5cbf9ec47b541a5dc24108227c7f91711a632fbcb5d952e9a6684080780a4b46bfad31949925e37662acc8de5d0cfd62d1f867f90cc6be3e86bb6b58a19fe366e173d963378e40216cad7844a90de10f38c94e4881af8f4d9fb078dec4304158470d178fc51484db4243b8b77cb70109c6d7d88c34f1d6da9fd382e850ea15e43a2528452ee16cb49b82d17e2d9d52d8ed8bdc36a5bef5c7199e460ecbd45f415e5a93b7ecee5992b9585e0c3278dc62df64f596903444f2debb00326fc30db7a509ff38b92c788c904a20c14bf78a5a4f1ad079d05cea8eda2b204353f4dfe72f02361f26b61ef91d9a4045e7addff5e5bf72b54a931eddf971c4d3c59e27f853140af0d8438ecadcc061b5a79537db7b028e9a8f9aa1679c0e0ecc07c609478b73d38f47228123672e9a21f69e478584eb58445c99439ab640d26710c9ff79815fd5e86e9ca4fadc3f0938f4c3ed2efc5fd82afa529b9a899f629088325082902e8ab6211289c696ae684a48d10951b22b42ec5c08ed77ad22e63183d24586bb56dff58c88c611dc162a384f62a0542c3b7d0acb15b20abb0d3f89d34ee6bafc9aa19dc237c4349b8f9c6cba219bea2ae1de76f4c9daf56af288bf9ff92e3dd71d83d838c09b89b0c52d73356728e6767b55878d000f29ae670b3f25dc5ee6cda7fe5244ad2112463b311301b465272e590e6580c9d0555bb3007c50fbbba9d4e85d2e9210368a5c7550169f06a0214680f0e61a1e5e31a75ce975df2a812a72e52273d7e487404b3d151512ee261d3a2b4b44c38510727af8ec31001c2d2f7fafcba5db8053af1f324993ec130bb0f2996e49c731714a170ee4cfb042b9660f415df466f054f1168b54dd2dfae3a459e03afaa412b6fc51bbbde845acc9d734be1bafe49e18d1b87193da013c928c5411fa6d7a0e984f8ae9cc7b5632f1d6946de9a6d36d7b21d7c4049821c25084817aeb89704b4e921c143e36805bb7a770e5a8f8c3057033d076d55aefc5070f8f2e1d33473a7b2174b8ffa1bd199a1b436b0dd37d244ede79e1536a26d59863a3d19f68d12bd7273a05a8f820bbd455eafe9fa3667e7a4d604033fc4f461c381d4c7cc1c0de02bbc59e7ede9fb0c30b5610db340383c1f760c0836e1686dde7a47b38bb5e36fbbb50d954a36e4fbf9964c709e43c627111a6697635959116a1ba5405be227ae690a2443c7144cea72c0899a275559db1e32d3baed18bce84fe11461b28c1b359938ed428606ca42ccbdb84368cd14310eda8c08a75d6cacd7b9e30c112679b65642e1a5fbca7f3114af27149af90293368196a1036c35cb25b3dbe5b90a75838efd61a0531e1741226aac2dd2f56a92e97c7ad6e7d07ca23fc6f53f0e1c39a2133c92cba1f060b62b72cd6e1091a0160a79f9e85d64041fb5cdd0ffe3df74fa6c5dfbde3e302e52001d2b7338a1b5b24d68d7175e1705ea77177ef0f09932c2834b58958a52e1315d04fb6573efcc14e1dfd7bfcaa7840fcee04c3a0293894a58600b4abf959e2bceee68edfd4f74584f015aadbf52126665fe8604f868cbccac512aba5b790887ec1ce06544db3f582bf02658b0c460d7900fe15c19f1dc6c558372e5224362ef0a555cfaedea8021f3993bd454d93efe4ef91fce99c1627800c91a5effcc1f1ce8ec4c3de1f73c51f63bb0c934af03d872d589352eccbb09383a80a3ab0100f699464187f3141c941e14806eb744f3c2582b2622a9e4007a3890cc3d1e0be5ddc6d7fafc3a60116e4c02825bf7bc587b48386c1814544ee4d86adfeb7de09b30272d637f4107a85cd11526df2e4fd857219ffbd84484e58258b5d2b22784323482cb15ddfeed93dcc6b131df880cb0124acaddc53a6a97c60f679d69086f9acc5daa7c9d7066a46d52ae247ae4dad22c8015b44f47ecdaa504fcd5f91d5b93e0ac1dab23a52e93aaca9e28098d9a4d1746daee3c3a177cb23cbd846d779e7e8d2390a9cc0e1ecc4b1aa9865c7c53e7683147f6ec4c380eb03362bdea6c3f4f1a73a5293a2d64f8d8a42b223291c52879e06904d98e5d734a7d9917eb1ebd76db033bc1d02394fc221fda881f581fff3c2b12c4748bb781112ca574f4deeb13637aa0ecf148802e52444e24a27977459056621d5ec6278e59bca52e4d2ef3aa133e1c96ecd7041771ecdf5c31610ba218feff28b9308579d6561ca2422706e4e12ba355cc362c20cc24f048a918a5e73238d577023a3cf58c1a6ece8bd27c67d098a58f25d13115146a0c3067ce2b9cd082a7b509a6a280529c45458328ac307b55f8d59d12cd2f4c8c06c33cb35c22126b7382955df18ab4da4e65b02c9a38b5338d80c3210b02761943bf986041dd90d106a59c6c25d64a32e05ddcf094a851fd4875ca6ba7075682005bf95ab06afd061d86f1b53cb183b49b5875d91c682f27edad8f3aceaeaacb07ca4ab785bf64a1a2c166cc1be9deac0dc34b0e47c6d697029516a6ad1781187e62ef4369a4048a1dc1657261dfe8545120a1ed2e06929d3c4f8e7f72197d9321abdc08c9d6b9dcfcaed5a9d9812a108ee55720e0e7af43756bdca240ea7e445671b32a509f50e8d6d0610e12d8f05bba3b5e6267da3bfea46e35b8743b5bff2f66ae8429e3b408380dbc75ba6e3d61cc4a9cde230cc231d2435b65daa6178f4e3b1c5bf01d4a3366d359bfa32a667e07f2a3e765c958bb50e83121d13f157c35ccc1e508fd3228a6de05b59e77503017285ac2c3aaeead1d6e9aa3de703e8601e364c1cd3c848efbd587a848fb5d0d6c695bf2548aaf79c1daed771016767dbc4fb42049663f08e6ff248f52674b6492cd3e14c0785fc8f58d6ec3a427e59cae2d976ae917ece0c272db207829c87fb29ed80c7ba61e466347b2b08e217c5451f95cd6b82c1ad37821251ba068cecd96228a555282f3d35efc534c9804be02bd1243cef7559b431c23f6eb57ae5aa05666a48f3834302f78930edc9669e7be3d3be690eb59f5ad99a9996683e29baecbf750a5c5c391740845928b8e196bd49b57072c73d58758057d16ecd27172bdc93f617bde878ce12cfd7f934bae0c33554528d84b72d11e47012911c9e88e5ef561be6e0ac06f0b76685fb5fcbdb56f25958c6db1ff72a639ddcef29e6ec0ea81f0c82fccf514ea0e0223f84fe673091157f829fad4c91bab9c18250adb55848523a9c0490f5933f30670c4d95f658ef17ed41a7ea4c8f1475ac16d13caf9db7022348169f8384e74abba1abbfd07f9dc42205732a3a6bbcafc66b7ec8c1a08131bf58cf6d3044b616f7c72186632097ded4167e6be2ede9ef9f7f5e77b92a80e2da05db8e2f0ce10f5be4b0d30ca57d89b6fd5177b9b9e46f53ac9f19c1062b670d3db8a30c4537b13e5e3d6a5e1123e0f6ed4721566fcd884ed0b547ba5ec71da113520a1294d6ea6899a39e4aa4f91c541df03b45f1e82a2290e12b228fd5b3676c7433d20c9e4e6038e7d8de009daf7fd5db6baceb6ef57f3aa53a62cc126fa23aa234e6f91b689ba255b4181598b8736ed3ebff33b261ed8a8ca8bb17d421598e49a0d7e1bed521d2e9d3903c8664ae67abf72ac23d7b215d31ff863f54aa340823ae9a2fc187de742a569cdda2b611d90eb436177e5977fb48360bb17d26e605a4d74c859f08e9fc9800e6dd0b3c3b0078019539bdb55122bfdd4e2bbe842daab76910f9cfc16a6e1aba2447beadff823ef2af2637baea70b10ba33063dd9de100fffa5e10ac4375e1cdace5321f26c83e8b3b9d30c95a0d9850d526aa4eb6c89c39c991a82d51079aa9c73e1fe6a75d8eb927b6cb8d95daa819e253cf6b5ab2bd2c56730eaf3c521729698d5ff5f7452d1ce8d0880aee1215e71632777f3279f88fdf99478bee4099cf9609e1574266acb4dedaa792686041259ab9f2b75d5fbaf219c09eab4d453fc56120a41be5f397afda9711afba405259eb79c8c1b8234b6d99724ba925c29665085fa1ece1663dfd0182b618c9d20aac6df1e53577e108aa0e5c30d6a78da75c83d8f58381f71415992a2db7010d0bcb7ffaceb56191f8e7e57284033efbd27753df04cb851dec773d873b216cd287becac7b9841878902a6f9520c5d2ec225a01bc0ede9ba4ebe88c42b73bdcb53cd37898ac25bdaf00cb8fe954b54d8dfa6a72e4ff2f487d3a7c45405bb8ee14bfcf569959ead582b00f03b489c2efbbe5cc11c97ccb94e4c5b7c1163955d8df6a60d082e7820174ff2d83e00721b279f82adb981b69a6812931b6b3eb295e4bcbeec6c4e4e2d9167a561825eb4b206b08c71b2a0bb1ee019a6b51a6039aadf45adb5469c607d2f745afbfa74c3d73cd44e3bf9457f84f65da9ec4a871cb58e1e251aa61db7d7fdeafea38d0289f7bfaa43675098e196059b2da99a67b700eb504c7129aa5f992763bfe7ad171adf49e02d47ea26f62b5a92fd1d54ad28019bad00ba39aaf71377ab6e8890f5826526730790e8c8790d326ccaf55c778ca8237d1caaa8b723b98e7d9cdf1cb540d7ff43765bdc73fa66f3267caf30a1720422f5afa92d86ee669403f9186f7f41d0f4db41280db7713056eb72d505ef905c436f81938dbd53a081366c53a0f80bc34c11f8397cca32cab55d42509282211ade162cd74f84a0f173c0cc8581afb3272d4408816aec52b276538398787269002e5f7c5665337db90be521f5f5aeda1ff91ca00c730d6ab3ccb03b4983acbc47fb4826cb386b53f2a1fcfab794faf429521b5516e54579203b04948ac8ef1abb26968fc127b2f1cdbbc7e5de23f06961cf0464207172dc8f7cdf1bb40dc4d531c35cc7e20ce4197b2313a8ba8e8a754f09c8c05bb43c8cb918e67978d22a27f6b902db7371891c56b16b5317bbb5789a646df092eeae6352a3f53389f1148b50efb841e69a382b2d5fb5581c9b372485536ba684adc2dee6112faa1e86862c7ff1672899f3537408eec18f252cedf480561f19f7bdd4c67b81d37581e3f044fa2fefe705c75d5c19a8fd857c0995ad6d9719ab40e56fb720cef3b5b834162b2c8987b5d639ba6f11c70764972ad8359a87615955345b738cf78fad270152bd38a53fd5e680cf911e271c29305c294da79b9d69fd0b95bcbc3bc9830ec1a41fcd7c02689e2e8bf757b57b875eb6eba0b467bfbb5a1b48f0d031aad5b470ebfeb17dd5c85557cae1061d35053b981f53b555f0ae9b92ee77601104f65a6789e10e2f1ec8eafe7b16404ef8fa2c66cd368f6450ec95362bffaae9b3fc9029e693464227990ef61b4d459eecd0deb541e4070454e3f6c520516dde67ca6480cd80e4868163b3f1e3fbdd38c9d35eb3f610c24caca04a69abf35f3a88b5330335b460ca854768dea25df99133ad1605ebd6445f6f0c2c8fac63e5804541d0b7087382c56ea2d62f263ad14697b1aa83e94a33d67aca48e8e574248ad89e2b18df5f383b9d8907b66eba6fd8a5fdc3e67965de5ff8d9af672ec5391bf110ca89e9a24f2e46ecf50962201d0332f545699d01d24af096d0fbd5ae5448bb9c9d09e82c540f3ee540a7fc1482e4795af6271507c015736d6d9ad62967345619d95aac013fe80e737eed96d8d6ddf89313d6bdf1add8ced9c47d6f1b4ba3616998552851029a16dca2e4e2e2c23121f1223a707fba75966c2cfa77633905a09ec706140b66e8bf5b05547bdfad0e75bb510edd23b568c09656b3809b7a49899f1f12a1048a6da6e770e7b58c27982eccc5ce7fa9812e68c8317342c4c529fc6a4448c221fbfa583b0b219dc502bb2c64152ddc2a955819db63391613cfcef78ced47d72b8fc7a6a7630d73dbe03accce559439541717000ae7db0d586edc63e16dd934319bd6f164a3e245206a0a10d83e790ec3f2e65580d1bb71b9440be29f69ae94ae4a04980acb74acc655d8069dfd68d87aef0a2f2dbe6583286155c3af5a5561d710a906831670407ba22d87bf570897e360a668160711ce7db50192f64389f3388388c810b1ec20ebbb39cc276cbda96516889a20c29033f7a59d5dd345353c2ca8e2d9dc5f9dcd0b6a707d054d4bd8d9bfc7f24ae0be24cabc6840254d0e371d72fea9a7ebb4fe2bca7b4e57464b4f703d1f53c568cf067d4831cfce047280ccfeb463a18aa64122138614f31c17a50e4da0f39707df18388ca511e608fb5a03665b5e0160fd2880d8c1cc0ea65da762ddf0e08843f5d62137ec9bb5baa8bd2a96f751d4570d0992337991a9a33cf1dacc5198dcd7644a5dc716bc34895b3e973a0eb2dcf4bf8ccbc3def0deabaa6b8ceaedb5f310c219d129327aab931d5c087e0fb3474f2a075966db81dd4488c84c848ccb1f71462a08e4a334ca13e66b03e067954a5f935c0a71d5165fd8d22c043d3b2a7048ea5b879fd62251f5a90c83281b7b41df1d69865418947cf302050e8e8edc69dc200cf0f9b47adb27dbdd328109591d4ed496dbc54377c85f08f9b4ad86f42d61ed540117a931b07a6146dddeef14d875813456f146c5b8e3960878f66a1f5aaa169580e547ad6db306791b134e64185499d53145a49da80aa546a1c637ce23ccf25f0126bf25d7b457ee455c20582dc1a3f6b974d3677a70d18362a5a69004762ecf3479462b7a9df333e93daf43c96bb302df9fb5fc1f5980dae91f11c5f5cadb99f7e937ae26e655727858a1856041ca23784bbd79b867c02eaff61f7c0d4feeaa149918ed4f275782623f9dac273d65d8732ec4927de045144193e63991e82d4655cae9782aa559643f8fc63c31afe7775b75a0392da3e3815101132464407759d78f2bebf9863da79bb1717952b43ea6bc51f6971bbcdee0ab6b7779f1a16a4ba1a4121fdb0e058a165a15daab7910b369bbfd4d4882ea4edad4a2aae72d07718885c32e3f8015a9a746bbab6a9e9a5d3db2b21f3ebba117df693238a327edd4340629c5a6256ba70e1e77dafdbeb229829d2bdb7f523023d20e2e5202098d7861aff917803b95ea653fb7e8db58d26be65856856ef45a1ee53c72a6fba7b055e5f21b1a3977244d1b9655c9b94875d1d76aaba47c8a67f99179b0fd19c69a136a54dfbf70c00d12775b41b3e03ecbb65567b4764381b3112ca0255bb591db954c686cf6058530751c844a3859758f6a05db0b334494477f29c6fd4d2ca97e811d3abed8103a69b888e201cba4646abb770e95e594c1c8496dbc6bf1dee700ef43326eefe175985b26ddd246564c59f561147176587ae51232bee15c7382ae7607a69396fc8e34b757c6d55b3b29ce9efa027f8dd03814cb2be777693880f0ac47af8c595e92aabf588acacc2c9a6bad78c1d334d14c7352fb56dafcde7ca973440fdf5e0d966e3f3447d6271888c3e8aba767f2b170b57a643405b05555a4ef43832489db2a2e2071acd7a85a1c301b964f75e735e2ec08a8aba1ec917e1b4080b0820f83be4b5b8a806e588e30c892dace33e88284dc8fda3599be060132cc92aca1cbe0567d4bce1fd8afe73a457eea4c6c8bd4165e58ba968b28abd175f42444f083e05c7bda05d56e6ecf6eb074b49e4ab14cc1bcc6762a59a96889a3f5551fbaa29180dddf9a10de41cdcc1dd19ebc09fe2dafb1aa2d39e16a1a61e4f5cfa79df13671eca5a5ae12949afe0bf224eeaf04edfea094a6efe0e7be340e245f3db3d55779b1ad5612b8180eab4254498e3b23bace323f57f5e6659e4a9963c3e2823f8088c5e02c6318203ce844e3de55b99a62bc16651b149391e48a4b95685bb52c3b16ad5dd23a1b1147a733ad0649fb67161c170e170ecd096a5b05f60f6593305833da14aea0c7ce36eb669ab09310d65000be2ac9ada247ac29b1b4e6667d2be457638975de474065fe2e71e8d0ffb919fd24120c834954dffe2a4fb2941967c9c358c1e1438e56f1f448657806435c6688e1c8800a71ca932a8ff6066097ba81833738274cab485442710b3d772456bc3e626bed171e60d576c843ea004e0d2c64529fda1c5d734c7243dbe9e0748cd7be2960411d89f333889fd8cd0e0312790956516bb228a13b14fd735e9e6d20a6dbedc613512aeae540154fb3111e6aa8180423bd9cf804fc5a04186992a9a7675fcd760efedcabff7da55e244eaf76fd386865909fe5ca5110f3511effdcab2b2dc98b08b7f0ed22106e0962fb44cc03742e9a206ce85325b09c16f6975500f851ba0ab5a7efd54661213bc11e18a2bdfaf7823559ac0aa3c6434e79b63ed584000f58011f55dab97404802fd50c36e4b735f52fab2d602d9a0a2de6ddf5a27af66f36c14ac87ff9e15d485b7de9a564d028f0656fdf021a4d15c330721a5e72dfa9e5e36062949d2403ab222ef84c629357be9c24365ddb21ed93ac2fbd48e4cef75cd599a40279db0fa6432a130b421a82499e5b32b44aa8e2716b0eb10eb127c3b450d59fbee78a1c672a7f114442e4fcf19b3d2f4b3352e77bee0b24611a3b1bb2bf25822769d633a13f36e18997eb2878c227befa7dd1925afdb959214db6a5c1d4f5a604603aafa1816da0caf24e657fca43cf799a48ca1b2e07a94a7f71a8c1c1bfb88906b4dbba8297beb17c35580017c07d2b212eee67c8896f311d4d109d25cebb57ddfcf5710965050ca34381f84e272b9404bb982b50db656807e9f549d4e4abbcb9c469ccab83eff461ab3738e59b6e2ca04ed9e9451f66785088eb728baeda53b83f91a7f31eb08fff72cbcef2e6aeb6a4bd28a75a6b92a9cb9d6a94f71e36ec7ee14232ca26b82541566f0d4b35a025071e5ef9e450740722f893c6790ecf4614fe5e4e71cae91efb45c050b6b15f467d4f124442e926b7a87f42ec4d0f1b32141a27826062d3fc3eb1d17eb4fc8bb9ff7661cc3e41b28729b8bbd0015eb3c8af4863ef038809cfd4dc80eff6985266f0305402453a34a1c9031e64f166c29e5897aecf430c1f208cd6ce634ae870376549e0474587080483f6e5854aa3a895b2b4a47f9a01d678863e794d66f2e1522792271edc01e92ec42327d015a4a63cea845900074484446f2d73f5118c8be7b4adbc8772e91317d11b1c4dec2b09c8fbf840be94bf4e337a31e7ab99e8d01232ed201c249a96711e5dc7815925a9d7d7894c2df3d992038b8dc89caac6802c6e58eb856c0c1037f1c38b9ede9ebb4e13938ff43900f67e0bff15d5c57a0bfb1d767af47679bcbadb8c45b484a68aa150d221ca47ec3996daf20d74c33890f34d7410551b3dc13c36223eb23c5f93ab948ecca33fdde8dc37cfdc819595eba30777d113b03568a576f47b26a77198dd59fc8f24b264b9d6faa906685469812ae685aa001087902d08030fe7b78d674f5ab0b8e376354bb9cf39fc0c6a12986f3bdbe89ba6591e7817b143cff6e2e75bfc1afa7eb279028b64a0c3ba9eab702979fa6f8853febc35083389b54a18ecb633a575adfad9e28bcbf2001196cbfa6c0af4ef2464f881419c4cf6f857f54a6bc0bf66ad8e48eb3fb22d0f217ee1c2a3c186d612edacc6801a026f9c934a796560423a1b30eae2005ce0e35842e04bd3d06f209b83755fd1b0f82fcfeeff67971e113d829cd9278002e14e0c26d350c6cef957b60d3871bde460903e09009a89d98fe4789204d55516ffe7d9fd0767343b00adaa9d25ced547f04aa68d9a07e5ce016ed014a15a3b97f0df8b30966cb7d4647099b698bca89443fe6964b5f7173b1da5ca26d169f52104c57cdf307746d22d4b836963e022aee714f9cd6da9e90cf7fb1e4b7af4e21eab56358c00721dff902950103b9029039ae6820f3f8f1d44dcee83da7b7c4bdd7ba8fecc64c7c58c0509a7a777d4a1db41c31d3a1935dea37ba67da562bda7f3e1af6378b8d8ebc54c8f57e1f545f91534cff7af785eb02677d7e528b526321314d910233e91a10ff90a50a98af2ac429e4e7ff15fbcbb958f0dea5cf2c7d1aa425d0c0e68fe63126b2dd3e15bd393d10443685ae70c4732a67dba4837b177119545d7c4357b459e3253b6cdd7289c8ce39fde705a6a57eedbb89055f25d76cb43c858dba866626bda77950ae55d45a4b7d35ad43540dd88915883f6a2080634cb68d38714d769ef38ab7656338b4805568bc6663db51747869137d9f6b096edf34783d0e6d7345b2a734ba969579fceae6cb1fc2517d854d20832240e0169d23dcc1ae3ddd9751fa8453b0c8bc3ea7274fb3794e9513e163353a4c6f52bb984bd42c0cab0a330c2efe69399a170e7febdf227513066d65573e54c50352d5cfbf081b717ebd4860b5d8a1ab54e3888957de928a7a018a3719ddc33304a344320ed3892569f04e6468a1d9730e3cf1c570a8a69bc4e94a30fd8cbb318fd3af68ea84e097b7f6eb16eb6a5878dc2d61ee494e0d6d86345f3e3126df50a5d01cf615d0fb6c13173da8dba5506edde77917d7564deb638b1305b30f97683d69417d8d2b0612d068848fe240509d2b2080adca4a1887621bdcf0e04d5459638d317ff18451416e2a8eee04635bc7485d71ad96eaaa2f906ee71676bd3e799b160578aafb222bacc0ff13b7ea418e4430ff5278cf9aa42962914ae3b1570f39d93d460861eece8ce3dae0ebbead8a7447a2e5777049f474b3c6c8aa7dcbb296dbe752c4d49677e119d6366afad99b9c1d2dc6de41930674c9e4542cefb7d9478161fceb1a74f49cb78265722468134175f43131a4e07c993e965a0eb0d3f069b643f9f91eb50203b91eb0e51245f1ea558862306f79ced8236af36da27e26c90e66fb0ff4edf492481701463a2269084463e134ee29ad7ace09ec7ef772c7c57c401fb6701c9e54790d59e917dbe67641836c0655c2e450a05f46d6c0759d0118294bcdb02d991c6e2cbb92ab6b6a88681ea204b3a2deca44451fb8157f8a5a51096bfb17016a21e9f9d9e02228f76532ab3a2d25dcd3602ee6e8a0c05faa7b79f22aa2c950e75a6493e60d686011eeff36554f46fea436c0e335e667b5ba58e6a5f15c3e1241793d43038ce1ae140cb70d7d1c35d46a1c3ef86097919b7f64a0ef80c344d676bc4c573f8ad3f63ce5ca1edfe007731e4cfcc09b1db1efd44d963ddbe4bf6fd708cc331e271b4fe3c2353929457db9adce361d1fbc13c19b6c3addcaf7bd1b6e21b4c9b07f63048a5ff7229dbc81d15dc615233130e5e6cdfcacc93c018f9cd0a2e4fe18913b0b9d6fe5aa968d750e67ed7cb2c2df347099f6d83651599791249c4c157faf821e0ba608f8de1dc667dea5ded3d2725884d4583a0f98477c2c50adc6df12d1230519722196ba15b8cc014a57758d84429e9eb5abf665629fefb93012345cb1e4808aa9ec6d44d761c4f06041b467c2a5c8aa95e52e42a52ca4890b3e8a177f61ba39481d40eb09c602ab986bde6c7c818738b03315a264427f8ddc162dec902963a29383caa078244fdbe075c8a12e113bc5efe44a462987e4cbaa2ae91da9a40ebea453817c41817de7a9ff90799dc2e946c057339abffb160f8dbc547a333485fc6aa3f6e14fc46d3d2440871c49cb5e7d87ccc60baa2bb00cdbc6a3f6ef183517b1bb906b11b3a7861eb40e0c0efa24d4bf63e56e44ceb0c8bb6d859d7570c4298a244833dd37f5ada8186ddf8f8be872c5570abca0ccf8144a231e9814275263bd0ecd47b08361447ec9065fb914e61200045a1f62ec57c067e8870df1374f6b7d5f78bce102efc7412c4146172714331854341a5e99368d6573ac29e6253a1f189aed4a6dbc6d51423f5cdd8cc622a23cc166b8c364437f60f384051046dc57e8d2f3ab5e83bab54ac259e6b6d909d05b7c870dc2ed78fed6339d7afb11af69ed0d42781feed72589fa9a301f5c02e8d3b69c174696c2802bf531cd77a89793562236d86aa5a7e5d0c8faaebf6a4a9c93cf226a4d94ee0ec9da416b61631feb9ab19331662e2ba218c68de755bedc8486f7e1244068697d84cbe77660c5053d4e301ccc5c49870c323a22406e32a3992476c22e9b3422834bab5e3cee6d003321024f34ad3ce5e67354b6a667acbef922bf95aaed00d9f858e1d4ce515fbedf026b93f82b7be8fc4ad75a60a6d4b01e56eaab7f86908b2bd3a63ad641e959dd252fc44fb067485072b6bda865ae8f6c807173710dc86fabd10e8aba12ed057a95020520c65c4e7fc3675044dd782d8e2b393cad10290aca08c7e5b5bde2eba7082c5381b01a75851dfd833bcb59c832450aa2d8cb583186f1786a8f8ea798ad46f1c2411ade8adebb435c299f42924e6b3a3259ef69f891e3fa311ae5f5d7a0365bf958d220e4e7408113aa14c1e20d0ba88844f9cbed93f466045d4feff57fabfdf6800b27a8f0b79d88d197918c78c2f576e97fd627cc68abf8aee6a48712a733da2f9093f76b595a745e1cbdb2fc65a75b44000b2deb7633e24a369e6aff8451dc93eef559b68f53d7760a8d24f161dfa1e85485be9ad1f40cc81bf636c42f6bdc6ffc89ff61297030a8cc946ba4e54d2ab8cd475fee51da3af171945b6d39bbe419e5b8e72b34c9a64fa8e81156dbac56f5f8a3d16b95341ee11b2b7f3add63e37501e574f64efd30c92bedfcff732d701717c5d9bd5c44217ffd00b8e5284093fee35e6c76d140a7eb35ca62ea1c015a7993abb71332dc8414869754cc3d2bab2aea664b77995e9d6dc9dfdbdcc3047e5458ca1401c79e9298c757e0e1cffdf89d919cfdeb17b73da207ddbfd88a99a03aa081dfe5a20ae217db9567b1ad8163c1a0b2e527c93acd08f663466cffa951f05394fcfcab425e92e2f39ef2cfba7763d77aa7d5a0bd33a552e85a795a0733abe5820be263b63548ee25ec6cbed60fc868ace77d06263676eda089149f0564a6dee9970f77db3807c05c46a012ba4097b16c27b4a973ef2e7edcfa67eaf8d182f051e4828bec785caadcfa5640b77aeb5b6066e467b853357eeaadd6d52f02755b42bc65e59411ec8171f7d33a664ed1d8b4a92e71d6d6e8e2f8f59763b62a4df159f1dbf7eb8e674991077405053c807d058c983dcd671832b46f56432a0a4d47e3f8d231a802612936017a12fec0d78f427f3a899f4da5bbdea3a12baa36c88376b5c407a0b8fc225ac05bd194ebfb758432ca88f6f28a15bb9740fd92bca16c511f68192e472c4fc8391587315da5b8fa8802c0b385224ccf83acd7376588fdce07f0a92f56aa328b770c0d112ef4856c476a06737eb56cf14cb03bd282cc9c85e3e7814a022634576fdb4234f46e83164a0e6b747add2b397eae33d634fcc1aa65d1d0248dbc0018af78027033c086a4520bd11e8a742c166931f3135d967475a7be9b1168621c2455e83eddf333e21d9dbee95538bbae3fe5cd31e2cc6fc092645140799e04304388551da2826767eecc0a1da88bb26bca7977cbb7efbab899aa7ca22d1aa4a73f4f10b3412abd1076b185ff760c6d5dd9429f99c23b511ff060fca5cf80cb51a837021d5efc02a72f4eb11a5c29926a1a0caa5a2c2345d11ebbc6c131b0ec778ae58799ff7cb226813a086f04e878ab8fa05153aba91aba05ef6e9516905c7870661fce246169ddacca566a2be776e9808c906d6a107412a000d9ae964348c42c59cdb1ebbef03829127177316b1da7150429c060d18504be43daff09a3b3f0e17e5bccc059ace441bc49c3a6b6c63a28b218efb0e18d00136e6ff6ccd3682f65add731c09f5cabdabcb38477746a9da574141ecdbf443a495a97136cfe699a3ecf9a285afc2a994b533b17b48f615a02a9d19bd7f8e74ce177c4629660ce4f692d9aac10cbc86751d8dd73e2c78339bed19b76e12317468bd9229f328133d6580c9cba157725176d3e71fce5b8af72f1a0ecc7b5a8143adc51e82423eb72cfcc0810f149a9a3a4db704c62fe833aab0b8d05e8b35c81ebaf267eab01864b56b7283304111c17090531dc8382d7feb0a59c565e375bfd7c027762db449b26b7925c325c19dccc95f9a67ba4508338418ba5858366aeebff9db1fb527884a3b458e961c65020de8b80c1c849770e5d1685625f5e2bc6280777dfdf89cc9280c027686aa7da2e1a62c044dbf10f3ae1c8471a885363f09acb5f578c0b8d6ca8a5c9e1ad121c3f677ecc11c3a922d282017359b51437800378fa35fbcc3d4ece85d554d43a34ab82703973180f93ff7e48bf4da31375b372a0d66d4168be1c9ca95ea5ecad387d3e7c3b2af5fe682cc1a6dc62413ea74bc44bbc715728f322e2023af56306405d5081cfe676498e67448f8ad2dcd10183c123cc8ac86564ac07dd82a0b4d0ef47d31640a4fbaa7b553a4f840b9843cd6964c372f90759ab004def811ebfd37194fdd263db479ba0dd745b56d34bf3c480bf353d17e341c49af861cb85c636b75095c0a08b72b701421aa8c63a3996813bc6c49321036a6b690738d3336a81162dc8c8fc97ad9f7baeef31517b028c0868916110ce6cccb614fdf8db3f9e97730df78055280088cd14a8d97901c5283a799ed949908ab0e5c1c3b1fb8a3eb5c9d7e6e69729d5c49f206610693932e064242a2eeec48d06e90e8da891ce2e6f21e8f22734bdfda4faafe04d3933b18ddb60ec44a2709612c61b1d89c195ffacd532d5c5c3985501411e19e1f6c01fa7ed16908aade883c85f2c457032dab5b479e76bc6619810db654f7a220e2e56b71a54cde02487192bcfdbf2abbdd7817ba1967fd4a347f29c87160a472218fe97c4f8b8d73d00c16f1a765132edfbbea23ae67153ec16f14b611f307e39a82c403f4d14c593d7d660dd40436e2c01e3987aca7e5e24e4ee2dd9e7a6a625caef7faf1e351c6411708b65448a353e904e4c535119dbad431f7548f10fab3e92a6fd56bd373618ecf8d246ae90d9a4f578edc2cedec5f630948af640bd97c7b83a16ff93a3ef0cb560f3a34e34a61cfdc498f263b58fc5876db931986093bbb92188d36cd9e2aeadda95fc354f13d797ae341ef1d822dcfec0b27ed13f4b89bbce3546fb95cb1b0cd630baa97afcc6fc230e3701119ab600127436183e49e563cc64f8b84f3332ccce9eab2ebf9324b974289d5f52c3c8548e40fa87936f0aa468cb80e36fabd475c910e6079ad7ac967df741031b45e59572df86a9481d8d7176a213e5bc24668ca1511d18f6dddee19e410195e51ecfd2f4c835f77034d0fd04d00808702e0ab8e6b660cfffde72b59a89bf9cd53af06e4ce33cfc478c3a4971b4e14b5d46ecb04a05c9042df7106cbb1f586629cb274c51c12990708c434803525df4e4afa9f5f49876002f54fe2ed78d465575c9e63259384d1147c4b659a815c12c4ccc185848a03f2fc9872bd1ebb22a7df4cc7d32ab5393851a119fc2c8c112b782655822a24707c1f71b7ccc2155d94c4b3f4bc1ee29b84d9215e8c00238274561e37bf5d29b4afc91d3c6a298fd89ee818634f9bc68b977731e6123ce2b9ce6d897f5b74d231c036c932bc6d25e234ba48503032b9f888431b60d9ea3ab19fc6cfea8de31774b14aaef081f34e41a8c0ac708e828c1f763a7360a077ba21970563b2dbdc8884da11fd5d633d1fe8932a6845972cab9aadb9313a30b96a8f84125f16bb29e0402f9f6800f71da00d7096d16e28c6e9f06286cc78d2246f024c412ce245274d141b007b1e8947f99c0e2e8b066002ba920d253a135a25399c678eab410bd75eaf4de608bd08cf5cc463786dbe557d663a30f0c770b1d824861453be6139633cf4103ac30db9a7f2cdcf114eb5635f4ef5d7af7576925977a987cc6a035401c42bd9d3b67b5c6570d3677d95a7f62f36e202d5f4cc890987c6aaf60a4f550f9c772c23172c172156caaab2b28210b67c191e17f370a2e87cb7125eb65e19d93f4b596fa212352db8aa6378e4aa87bf73d7e673e515646af238c2e2dce0296f5ff95a1a5152522e4c90de604eb173dac8fbc09b9f9ca6ed6003e9cc15dc6acc89c0fd17714e51d1f8d548b2d9b02b98930e84cc3affc6100cc182b9ce56683171fa6701dcb1a039350a9dd23a85b4d7d66d2dad3e44f20325bf81b58267415cf3adad279052f7c13fe96d11593a17efda28de84cf2869d4419ac342dc06adcc36a5f87499719f14f7f1b818ef953519668ea8686c9268f8c91646632a7c29f7a3fa48b9d551d9c635e414e02c4f953d3b33a583ce3fcd9a73fc3152c2392e89f6736e64f2c2a5c792d48e2581fc756f08cc1332b4370d16f35a51b981df2910e09a125e135965f603475b5c36be26acebe2a85933e3f9424df2c188d25d181f0007acbeef3bab8037c92d15607646dd7160236d6debecd4fca4d18a65c39d1f826fbf390101121033c00ff79e817851b92516429f07c11bd0d467797df0177273f8dece867a5dce27053396ad0fd9b29f020e4b89461f7758504692247a0347f300f1c8869dbddd9ca45165ae42fa5492d866356b3a9c23a6061a9c11e25a88c6f7e219f86018245e563ea88fd41683e0223ef8c6392e7bf66ba68ad56981521cd45e90d80aee5f3047cbbc80b71990d43d2b9f7558f5e10757a045fa0cf21d7674b8c6e1fd78893062a0a2195e7c8f76c36b87e43632c044426094123d08e34b1dcffae267eb2028052df17b9358553ef424ff8a9d069ad52628446b50ca63be8cbc7684005f2c3105fb02bdd646327666059e493619da09147dde07397320f734aa163f1f76c6c0fb113083f1ef01170a4348837736b9647110a8cc126195fcfa94dfda352f062cb90d1122ae9f33fccb2cb805c2e42216b3892da94a99dd2dec5b0fb6883cd9ab5f0938c1dd06ce5f8d5fa894e9572236e4376034672d35f62fa17d9d58a5417ec5c3b7bd8ee919bf787a2e1e6f67be4fa560423e106298ffc3c5d9787680feaafa224d851d187b661cf9c7c6148f6710932bd06b7b4a8c5b1a72d2e8636629830029db411f9154d3a704f937a51728dd472a3e051e69febcd7436b18a6dc831ab34cad6fac1ccedcb33c53bfe83bdeb0cb975b69654160f5d92f1fb8646fc6f3063e98aa48bbd9eaf848182ff6a3ba43eb7336d2b88b7ba865087f617693a8f90ec61032a705758e78ca5eb35461cc108fc3532e62249ceec938ed6d63c8c1befee1a069897fa26bb56b601c1cd18120b77556dcde7a2b4593d9a9cfe448735458f8704a9c86e012e657df78cf3274bc72646c60d3221b4202f21ff7fc78fe2d01f2662b7d5db071374d8108e22c05f22b579270827080b69cd49d01b52c104e5facec547fea0bdfff85893951d081c701743f8225b8b86fe001b937d33ca12bcf80a3f357f9ad4f065ad91a43b266149d4578268b557821355faa5854895a5832164eb76691f869770149b5475787c539f9f5134366b67185e942b6c16461c7a16aea06daaab36f04c8c77b965567c6a6a3bba35b4b6a64ae1545a218a87c589d25c497787d5227df28481d9c50e31974f4b9480202d70506aeb3e3c6f023c85e8892cde406ef5d7541489fc85c288e29bb6cb6689f6b6664098f9fb422abce1a55376398079ce31a114aee02efe6fda62f4820136aad5b67170936723c36181febecd20ab9a159ca8f7099ef54cbca6494c01fcb116e688fb0fe9dfcc6999fd02d83793cabfffc97aaf82db6c4b97c1e87ba710d1b0465275365e0ade866f6038536f28cdaf9da408dffc3673f5c372aac6c6a95836d202cb25814c1d451362fbc29b66079277721ebe29892b5b3508bde1b1df6cef954054d14295a0602de099fd03c5958d10a8733b95d6700db4c8287d76fef82914112f542cc32ea7e81d07b246631512a240d20456893719cc863997aa18d7f72d80089cab96bb1d76b07fc72b60ddc002f1f690cabaa32f99c52cb447d54ddf1b4760055a644e85fca68d48f82bab3e1ba48b029931d78c855097a829a11912506582048305611f0c891f29ff6a7c1903a801fc84c06534a0e7e808e5ff3ffbd253624dec9767830bdaaef3aa766a0e979d25fad4f0af69a0ceb881acef663f9e7e643bbc51ed7d70ff7a13d70d03b59d8b820bbf90965df51e584e99759e1cc46269575a49bfc4bd78c194126bcaddeedf37cb0026172b38fe9265eb9d86d2a4658495d194f31849d6e664aacde3a904bb1bb95a5bad515b50ff314ad3e94960435131a49218eb31c54e9e368ffded26805f9e0ea141aa9478eb39be659539b0a3b80c71db0e9e5d6b2be8c2d69a772a083e4289cc7f3927a72570b765e680f4d318788a339c85b32fd78db6608459fffebc17cd85f34f522ae10f1b63edd796681a9f4c90b787f9668588967f809367200e761e862b04cb91531dd10f12228c92fbdb4869996b8f50accd975c945cb105e164414b6484b5b9afd2296706e6df6a4f110cf7dc2f34df46ea262fd1e827ea5eb53bfef09463de25259787bad24b4a0fec47e5d6e1b247016ff9f392e557f251d30caee5139546999c57684a4ad61644d42a91a185ed8d0493357d1a1362bbdf17b333eaba692356fea8ae038e5956ca194a45f4b7827775d994dc8bc5774e8dc64b3798ada1b8ed4895af9d0558113415bb69a9cc6737125891d3900f4e9dc08c1733c21fd547bc71a2643077afe845b2b666bf3c53babc8986f5d6ef51bebc31cf030074773dacc8b83169b50d00f2f521eb1e6a5d89e28c3a2ab78b3b0beece966a2ace435856bd87339bbc6355694e3c5a4bd519e1b50461a51ae792df57cac06b93da3ab7c57f9db08f1aad762ca995fb51a7ee724fcfd74a11f4114debec10636e64a8830f6c196ba8e217429bb7e5d376a3d08429da22dbcab568a8e16acc90e0565b06aa983e3b14fc6fb394a4f8278ed05a307d4aba4847426cf4d69021c7bf929002e0c6e50de7c113f4956f020ce53a1d8182ae317f0439be8bb234284974a34f24984cfa8e0635e5cf794bb8bc207fab334ff0cb99e66e5261bcb1bce3cdaa4e055c49625761d8c1b8f5ea881f0c4a60df4c7d5fbae22378c229c1b836706f6941909f1c10c801c929de52b78fa1145917031f43a8e7e2d0739ea878278581ed1a49d4ddd6344e7768f86919757f8de62e96ea5dd979c4d1b887487ded4cddd53c65db8848f57d5f62816a3504a96e26e5b9794531bc0d9c99e562758edb49fd5aeb334de69bd55e6bf8ec2d319367e34cae46a8c075b3e070225f878e41611a2977af72d928576a552fdac311515d8a24863046a6ef2c5dbe089857b842ab71fdf1ce700f8f49ee38bea1113e6cbec6d5df2fcc5b86b4c328aec5b6845152b36e33eae9e1f3d1dbdb74c93ad95e342575298c11a167b099aea096441e77f0cfb48be3e3cb319080e27586d0aa61c8e2a0f6907472ee37dac826119bddc0b428e2ba8719bace30004ad30e18cadd4975fc03c93fd06ff12064a0da84f7f62c38bcbc8fa2348e5b3bc7ce8069ce15d5d1ebaace9eb7ab00e984dd67c4d1a79d1fe7784737d9a9c70626393743f66349aa8de8070972af066c88f0ad849a61e8b6834e4b866d17bcc5367d2852181caf0cf6a36cdfcc4bb34cb796ef96d55cdeff0c55064cfcc21f83f0d955b71851d5057c5a0dbebd5046edad5cfc9fb2718eef63f73d6c011a0308d949bd3d157b13b5d11f2859922ed2b529c5f8eb4120fa2c654e3dbb4270966385a6a4450a0718a124e4bf6363969b07694409ae9e9c066b2008e78e202db243a4a06a73193b4ba4cfaceb65bfcd71bdfa03139cca60f431e95a377ed6e684c892ad6425dd5677101523e34bd84d40aa9c4705b17a09aa23d5d84b9968a9635e0dbba66dd0a779d4dc459557c58b0565d7778cba00bf6b337c37cad79fc397009f9c0f7beed79976e2367693081b9e25028f63789c6464f1640cb44afc95cd7cba3eac717b4c0c22ef67c68acd936068fc91931612f07e8b291aaa1fa77aaf8d908081fd39524bad9db0d8af2d73455b1b25fb453f12fba87181acd580243695001e96034232732235ff4d042df1e313653071b0b1efd7c244d37e3324da65b6fdd167c9865f90ae396c793201e22efe01448bfffc4e87a5f79f50a302d83eba9a8222a5b3ba35aeaa4aad9dbf3c35bdce6adb638b0c7bd57a1358dacdfdb8068d338be5db0fb96a6dbef073e34b38f4f2ab08db31e0b00a171b094376199a209ae628b2c02d3c715cd43a5ee45c62fca5dd3ae368bf0d814b0cb12552509ff7b1685957cf072f1c64afae63aeb5b09f9c72cb11f95710633c995ef952b8c61f502a660bd711a9a37f7feecd67ef6e7285d9405972ccb2818f797500d2251f2c840640254809826403cb1b5532424921dd245f9622e10e45792dd130a224cda559d9582329a2037cb2cb929aa54294aca9dfd158e2ea22b2258f4ca9bda9921f05aa0a63c6aaa092ece6fb5c8665a56bc611efeebd258c7a1b1362f650d6d4d8b0c1bbe561ef06810fa763642145b933cf7be6baef5ba91a16ccb0b961f4996028a7acddac7f7b6ae15833ccd54a60bc44336f4a4036edafbfe4c53e4b0157115a1a5af55fefe3558c725c76a887901dfba4524b7cb0bb5c5ad4235ba29c09d993a47ea3fef1bc18ca1a7440191ef902381c81f440b5c6cd2131723bfe2922b0659774f3da650442f7670edc2cd979690a2014f3286d124d1a865687d79fa0d4367f107b32013f5a088d7a0f9e36a3904eaba76684d44e65fde921bd36a694a8b76893bbbb73b65ead95bf27a331e9c0e55e102626e211de5c615dd891261a382f0a9cfa50928d58dcca4040de0ea0d6bb3139f595d350c8282975d367940ed93e4f7985b3a806296ae4f23a4e7f35fa86b2c245c5b021b595a4e2cedf0925d390040aee391e21444eea7e8fd51b5dd325fa2da6b2fcd726d3bdef541708250f8b99060de111f00c1689a70daf493285ffa73f45d54b3597488ef15386b5345292a946c8e3f81c248c72b3d77713df6a287402f3b00d9427f7990b7819a9fd43d90fd531df91aef3eb9f63e32fc79e957e8efaf75fe508904b0b92e026af7ca67193221e1051f91e04ba74a09b6999226bc9dc310d53033e3b79f06062f64b3d64e7373a3ee82598bf3fd6937f2a0d6138b26f62690fa2e128f0f205acecd2d2bbf6c382ecb2ebb6418b31f985ac75301a7877c1e4ebad6e54b7d9a0f0261a86cf38a1fa59801141f6916f33f770f2da57d16905ba17d436068e437dcabf2fddca6cf406f0ab1ab8db88c4e4ecc78f91d8e4364fb9ac4b8e3df5eb591fe2e2e34826daf077e6ba95b61f3f7d397cd4111f4c85a3e89cedc8c1c700d1611732da1b1ad96147c1f956dcb90d4418a575483a84d8b38650eeb38cd196f98ee48d8b369b328ee135786ed6cdedf1722b247f965341aab6d9408da1f7a16a410806f1127d6ccfd84d168921ac9e702fa22ca501053dbe4381428e7475281ae9e1b858ac07a7a4e0007e7d4e2e957196ac2219d8a72c2bbd08a399c704f1064524ef8015e03c464c1d59ea971fe01a405b5603824d8c762f26f8890262f2cfe87a66aedb36c095147ff7ca6aca38021802d8039194faef1a59340f03c9605fda72e856671fdbdd463d8e3682d88d1469f666b72e860b21497a274c1f7402c8390d5269ae046b0779579c38eae8629eca23d783aa852068633924447121e2a9d4230b8164d6f18918782c5a8337a3462809bfa9f5dae02987e0c59049cf967fad477a702bf9561bdadcf929b9d736b2e49a7b7c933e758cda6d7b4334746317c99ea4cd70fb6f4347336dd8a07076a175039f087a3112d9c8d3ba5b15f26dd49b1df183d6893336bbe242f4fe68d57c4a664971d8f493a5a997691858aab71f9c1458b11901c8842299d0e13d40be763ef9eb38bc4c3762f582c0f1f6991b4c5468d1fc60174233450e57cef09bfcaacefad667c98623fdf902940105b9028f39ff23c41bf55117b62cad364d8d51bfcca0b6dca187a5307c5c6aca0df697f6135d61a3b05621b7c397c012f9bb3257f0b5812cdd4f6588c72a6f2cd26a29cb925e416b4ccd821f45d419fca57fb4ec5be0ddb82946b1e36396255263058c173d4208e53938f8c5ab0233b0ba8d79e17075bbb8ab1bcc1f14d1c748099daaf4b6a77ca626e7a465ac0eecb7109d51a853dc92f78b3acadc4a5b2fca15b9b24e8e41b4041756e3eb6ac4f49ea633a8350f0ee7b003d528af313373233c2b1e58d717c10145ca44ca6cc38832e155da18475d81775ebfce108f6207e11cff753af429a3f9b33165313287bcee059dbfa845182fe569d0e7147a6555b9d6c20d278b9cbc28fbe4aa2e9a71e2fe8d6236c220487eff2b55e66c21d2f75dc149cf531927b761cb8e22648f344c940b1249e83d84479ef7e41ac972d700615095090fab31c87fc2cec5ae87631033593f0e6ebf92ec4d13a67f67025a94621b47432cfe1a0b0ee9dd2855113bd3481cdd73992ab7dfeb9f04f22d0076f0d4aa89168828ab3c367f0d5c21281a67f39f304a1ca25f8d361d990c4512dea0ce73f8bd93bc2cb9184cd35a16e34e72a376d71fa521a361d504de1ddf59395fca1c319bf62bad644f30aed7d0bf52bd34ee4c3907bec8d932adf51b4e8223096a857aa5a15ec6018fccb396855a98837d9a5854e88426feb4d1485f767ee8fc822c78ec248f0a80cbd87357c49fb164398b650ef98458982e7e289729e81a54b035042a8c66b775a52f6e6310a9c318e563654b5528dde2385dfd7218803cf994e27efdcde7addf8626eab5aca3f92bd19fbd77b46fa5951a76dba89610d8bf20632147bd7fb234a812ce8128fdf270cdcb789b28dd470e7a5bcffe91dca15dad3cfd4618aec337dfbdd5969bb8cc0c609af0d0f91eb50205b91eb0e311695ef44feb9cbc76a5b915dd805ccafe521e4e82fb3f383d76d2a2eb4c6ec52f1062a288defd86e46e61ce1cf1cb4cec310e664939c6037818452dfefc47acc2868f1687f9ab8ca8cfec37cc2441091b0a2b9629f042faa2638ac106e5f568fb3426883e4f724ea243045bf33f743b50af407b8ab75cbba65b6490e23c2a3162339f93307526c36faca048144bde4da9258672a4929950d23834e5f292073479928e91bc521333992755315aa0c6e86cc0721903cff2aba600ba936a392af7fa9e3537dec36fe77b4d5c35a2a465092f5f1988502ea70cc84a9bb682d0e8bbc127c28c20e4c485211daea203fc763ef0339aac9fcdfa2a5e4969016dd4e46929288a0ba0a275464bb186e2ce62323a80e2d11fb098a343e0c1cf0aa8224e9416f86c348b0c0ab9ab0953fd889d93d16bcc6a5501cc951ee4d1fdf64ac4ad4915e9908d468057d15df059ce099168b2bdef2ff4b23aa30bf8f01b7678516372e17072a4aa51cf18cc5893e2d673ca940a1f3a0f784e404a7b50e0b6748fc85532f4e9259c00ccf4ead1ff2e5130c08dad92fe420f7efb04af89f3fd16b637b02d1d51215c6abe389f14ed4a233eebeb2cdebab673cf83c90dd0f96f578e0eb6e588869b2c3d95b4a6995d9c24aa271fe9daf61c0da5be780a51f44320f7c3c893f6446951a6c34836c19e9a4d9ae16f56770c9690aaed98736d2f60f4f9a3ea7324ddeaeab15cad5db7a3fa0536e441a633b79a1944d3e16dedbb586cca0a286eec085f08e1516e7e93e3da227b24e7fa2c4c75b8b0170a658284b201cc3488c13a2c0c8f2391060b432ed6dacb3b299a1bcb25501ec77874e697538d94b2f53950576b8ab59fb38c874a458dbb584a821b212dc34bfa0a47e7a4d8aaa028658805aa9b2c490a677bf8d826ca77c0034b185dbb71a5e74de5fb72dd6cf2409f752798bfc693e938c007d443707fdd8caa9c1bd8ab4be0d858bf240821e606ac39d4988fb5ece0fb1103793ca7397dbbf395f7564e74bdba1034a74ebb34886d37381a9a281553b3c5d4853b6e6236c86181449a1b0f4941f1abb5f1166833d3aba13ad01443f7db4ce84f4c1c61314717adcc76c920e8a9c63e60bbb59babc0a242ba3a62cc47a4e25984604d7f5c5f5157b1327def6e83121e6078707e0d8fbee3da255d95f20f842bd75132d718a83dc96729c5e7ee09d80e6b1d1c6582deaa21e625cf73803fc23c8a70c3c6188dd800b0ea9cac49ffdcb2f98ae7e928f9eb8449d116514d7d0a7c74fb492600169accabcb06f5bf59701cbf6f5a474a4b935290df339bf92af90a613fb56e98c54500cc3e11dfcd0f1cccf100a66e6f160d740a94d2274c65431b1fa42f3e6703dd23ef1107a66c17ef7e83416f59fde683f822cf456711dbc39eb363e102f4f60a1cb41d8422883c1b987b957ac44a63ca4f5f1ed5d611769acd68514b681c0ca3227ce35d4e13c05376aa8cf0809f2bd4c3dd80313371020b47f4c5177c42c6cc281c2b1e3236735e01a4e1039a4d6914c19c5884ab1eb122ab1f2e93907518646dd1af62dfbe9e4117ec5b5d5ffc337fd305b466e6cbe2acb1361ab2801c5196304ee51a074f5f0c446a671b501a8db3f840314395fd9ad1ba76402677b18f19be11bb518c1b045989462d1f651c29fa7cb1f5aa2bea18333606f4ef9094dcbdc7b9fe6c58892ddbd2a186be60d726b159d84d24c363768aee51b651c744d49ab8e27220d3cb004ba9e78636ecf213717fad7bfd7b61e258a583781691013182a1b27b6a889362010a57737bf46317180ebbc5a531dcf5098462a1f9302b909b4a37fb2910a7943db254b2b1dba78b2da754eae3c928bdfafe6a160e6a12b11d798a505a3ec4da06cea1e9317cd51c76e70e5dfcf9f4be856762a508ff981b118aebfc367777801e9056b38b55843dd9aed5e016d4833d96b467a7266060fd948da5f04a404a2c97df63d637204e9302573b62a6a4ade2b5cd2f6bf922a526da23ac2c3c227cd0480fb21b2759ca13ad5055a8d30669d3ec3432f56e362d5ccdda1ec2f47006b6fffbfd250910c4783e26446efb07260bd811c1d21e8af0f8efe7498806bb735800d58a0af5267ee6b7bdac268cf66cfe70da046a384cbad7c99644673186dbb0f2ab245d5b601a3cf1fb644dd99182ad8c98efdbd9bacac60f0c3eb45a27b4d2129a5902156c77fe45bb5525069bc40c278487fb4675b4b577c5fa3733583f601c0f9755d709a03422a05c70b6cfe647d07278644e536717777d9fe8566941984b4937d4b5c05460bb515fd26748d0915f87bedf5dd006bf7057f9310fd93f3171b873a2bed248ce9c3691400ec441d8adcf8360be0f0753075b402c1d8d4cf5978e197c5f1b2edd98185220be08e830e155e3a51d43d3ad2f77d0235c5920ae9c23d706d08170876b25480ef33acdfbe25b2cfe4de86a7ed093abe4db830dd51bb9963c2cc156b4039f60ecfe71a96163a798673062383f34ca05f5e811fd74491fa48c4770559c0ba9ee2fb9d4e4b82f58a94ce3906e473baa6c1ec07ed2700d65cbd24e184b4173f18944b9c0fa39747460baa6965c3fb01c5fc3b9a1649bdfe2b44ca20053f3e88da47ea03a573d3dcc80851245a8649973dd14149d548668bd68226946a4190f6470976a0944a6134393bccfed2647ad63133adbb8bf7df79ef9f04c19551080c0762597cec7465c5810a4563325fa9e3a9aeb85fcd2f2d8d410cfde9459618d2f2463e5cfa23e6b280dc35bc9091e6ac2e37398cad0b162d4fd4d5c98cf7db92d98cf1a9d3f4d31d0cf75da98126b5ce6002b331cd7e26a46475aac7629946347cd97b430bfa28f954f1fa6a0af9ea108b19953c2a4d57978e2e99bfdc708ef9ea50bd5798bf89b3f62d355ce806d608fac0810a4df35b157b1144815eaad96e9ee74f6dbe93b1f57109d965611969fb2ddf24cc76802d6567e0cbf42e406e1c68d2edb357da628dd46f38a73a22c171993307cb5b43d43e03fc23e1bf0dcb3ae17943a6df59274ff016a59f2530d8de03c6db5e1e2be10204202cb384f954dcfd61c17f7ca213cb2e15609ac67967ed317a23f6649b81000b38e39d2c097468315de695a9dd42d79f4dab5bdbd54b39203740ae87881f9aa38d16a328f2d16a93c6999ba6bd5803942d0b0521608a185de8b2125dd0282c6dbcddae4dca01b0c98171447cb1bf948aa0b373f9a4487450a1f9be341239024fd0d6e926da2a4360fc22805a18451e428c92852ad719c00c57e31784c8faec337b7a29eda092dc65e308e0096456e97b20353565851bcaacee6d715cc26e3fc1a1d8ecf04b9cc59b8e4c0b9ac37f05cb25c2cec0f6f2588f2e75418406ff35167ab34234a0e412eb08e362273904a6a8c62921080d57752c49f5fd727075084cfe3e20b6fdb4d876f16d04264fe852adb1e424b13642d6911f7c98518c2169f7e488000e6e807e6e4b1228a913cc8d462fe91faf3c2c02fafde35fe6ca902779935f4ecc6b5fca71f998dfa33acbd7994b6f9f3d3086adfef3d261ae78d313001dba9701998377f4081555a7d1c0777c42d38057e9f9e02d3eea5e862be0956c91f3a46b0ebde5dbf3ea96964c3ffd5dc147f989402ff99d0c7c3f17e86190f8f7d373ebe75b410e74383493db867b7ce7e06bd3a4bf0c7d723bf5ac3cd60e0f68215d7d31fa2249c6be053666bedb69196c2b8e6fb2abbaf70cb251b32db0804a4b15898223f72cc777c9928e32d68d2305f2686123944867012401f48670ca43eed8e8258282f427ef929f44111b1f0178bb622f6893beeb2891a4f31da6e523a5156014672a06f969f78c6f1b9ed216242aa981533bc3ea00366cc9e3f078a0882431847b0dbfacbd23736212be8eb1f6dad64d847233de29bf4895eea986beb1832a06c31f09cb7f7d9db2f0ad471744c45f62b0326b775352611f03ab08b3ec98c540754d765127d154b04fb506d3d32e02905a51b4b74476e91654bff78bf56cef146adc386fe9c9ba33d84846f6957ef654918b369a7ca48bca8c6c9446d2aaaf9ca1bb195cbd1c0d9284fa4382273107962a1acefe2bd9b75b6ab2630f5abb877a9bfd118993289f485ccea94fdbba48459f3ef96ad5e6addd6c567194688b9a9776fd1610cdf7682ebf2f826253d35161753c22e97e7a191a755706ba224229c588390685c7bfd6e91de612f8e16d84c1080e778cb4cf6a508751f7e205e4c0ce32c2c3e43ceed4a5b2e037e75d72fdf5f3936edd84be2c3746fb258c4fd86c964f7c022ee512d315f5986ab755f4942a7d4e08c17e5bd43afdecdbfd76a57f0077258d16a8e806b62675bf15d8a687c517354ed7e4b4ea8ed4541414b0599dea564e2a24ecb8e3439a12b8e337a5036b5da541f656321cdb90c77bde5b76fda61514a62c2752395e7e2a908ee28a12da18200048caa0e3a600efda87d6c5089eccb878ca46d9d0c4dc17dba56532e0852b08f26ba1bbf15fcceb84c1654229a55a44bad865619ecfc353544e75986873b5371de0c71e6e8de24b1dfd8485bb7ca68dab6678c64c539785021707635b8a0e0fa1490c8ad2e4ee4039cc3cbae0faf66c18e88eef12855852da2bb485ca1c03c962e20678b943a2d0e504b6bf35f7baafedfd66b63bac85c11ac227f5a7bf5c98d2bb162b9510bb6dd6d8e1eb57801caa67d4102dd0cb77a7e17f33ea46d0923d88cb7f34452b5f76ede07517195d520cd9609ee7725e00e838ca5cc4f2fa88e2191b28f95635caa503c3edd7431b8b7e0522b785e1ac940e2558025455eccb3faeff2ba1767e2e5f60b95de70c857ada13f1a1103a99b7a0ccce268616baf32ec0a6b395d7af8208db402164f7b2dcd4706bef939b8378973998ebd308c350f6ebed8c7188e14615a71244ad59960377d97c3fa448a627927cf031b3dbe94730b8e1e4e889a5be4e9a68e5116e0b0ab7e218addd73f1296fd169c3bbd71949875eecaf419209bc293ba39656f62685d4e60908a45c56ec18ed3ae408e947fbf4d0552e7490cdc91b514f08b7f2022a036180bfbfe4106f263d66f654d4c655be5a0d062ad6e347b0ce0f1d8a97ed35883dd196e882bc7835e8928edd29d23f20b2dafc0e1aaae20b48b81ccdd176b5f628ae095d6335a3b457826f1234c1000b0b0a1ab83ec157c450070de50e5e35a377c970a4378a7a5479b5fc39abe2cc48cc8a34b5df8fe216959dd9e4e6d757d7c79f9ebd84aaf6aa99b56b679c0e7fdd7d21856ec261bc074b0cec240d98527df4c9954e9ffbfd060c19152deaefc02ad08cd712b240b5baa3f3a4e97135693599b10156dd1876b4f86b0c6f82efbe611fa456afbcbed3ce19383400f5480b6a0fb09feb5ce236366cebc2da133df2725a72cfdf8331d6748d29054ac106b22810fa3d07e6ddcacdb3ff595ef5779a6294b500f3e7e401a1fad63d7706074ebfad3043f12201a2ef6c6b94a8cce3dbd9b5fb227c50e603a3b315b2c8ffe0538924b088446f2a2fd6fb466a3f4d474320c4a5433ac0265112751cfc13aea0b31077a2659411297126312d71acc5e14ad0f1931ad6484ff42111c5a94f26487444a1d1dbfa12192a4eb96af4d915289f69c6697a98c03a460d2f3ab398f191dda7d877236ef8aaf079fef54a14d646e22c10e1b57f45f53d640c6b5e562166ff52a810a0a5163dac16f5f6af9bdb912335398ce83625a740369eeb41198cf785adefc8f73fc93f6d07ab383fcd4d900e218f443bdc1c79ea039488185ba1babe15993e2a779030640692489333df1f971dd0c2801a412c8426bd79599d26552b7e57331d9059e3b10d13efec7a16b43a6ac97a078988b71f7cb5b960133279bfd308ce0f0447de6fece172f6333f8612b569638412e9f107166df4042213c9cac4b3c04bf6675cda9b3e49372e90dff4882e04af214c416817b04ebb645e643b68545e58c2734ac20aad55c9cb544dc3c5f0d50b78914205ac59c166f5b6c029a3c2f7c06635be093d82e539553a149dbea3c1f81cb9e22abeaba0d6e2a410ed4eb1293471d052f939fd8507697e45c8f85d52da7cba8834847fb8c185e6529251e9010dd3f2a8e1857144e157addac384ee01af03bb684e062b04c0854f216cecd6890f73dd91c4301387991118e906f9284813377b22acef02aed33d0e34cd32b47cecd7169b9d9dd82c231392d1a53e1c77b3235c8e7df0c7d1e9346b41b7ae4e1b95f4f731b055cf8f6b322148ab44f24e34607584a3ae002b2ce55ac1b60833cd1cb1c5313e6e6f4ea59cbe6f78edd131b299e768552a229a7cd887df9523b85a74b5ab62ace1b36a385f06e4e8d14c82cafb70191546a409f326e5a9e503849a113243d0d244e214835f17c8db598a308839e2b666800af8a13d757c1c507eb86565054d42b677d5159cb22f017869cb12f7f22c9ebf56d7a3ec943be6f0e215b0d5948243ea2157556512e6b81aedd3b69cfad5a7771039c51dc1b5e843caae4d7c986b85d654f618f5b6e77b6f48eb07b71f690d818b561c133c6e5c5076d36158671c31c496195e17732c2c203c1f58ec8df676a759e6cbfa3861402f472ffada3a23aa106f4912f7b5cd45db7806b55f4caf1a1a654881dabc5132b832ec28d2d5cefdd3cb0f55ab29ccf6c46d7523fe143bfdee42038a985d5c9bbaf74962ca90513985a6ec265ebe2241695c5fab89ae852f7eb0ee508d50d278ff4fb923db47951e0014bcb1cd14f96f96c8192f2c70c0f1f13a82acd8c8f900f1879c2417137b8f731e11ca94a6223a7d3b49bc4a0aaf49419be3f4ebef853a39723274f6a93650018e821c4d2656f931eaa205c13b48c3f2d7def757dee800c584218fa0b71a0af6d4fda04a2d730e3e11e03f66a2d67ac0bbc7a6de6948246c894edd59c6785f0d275546715079b559f09d66eca726fd82bb1b28990ec6f719a07515940a54e266de6af624306d617d53d7c80ecc1434dce82552dad144cca376cd368c637d8a5d9fb3bbcdbbff077fc2b2b0b7ea4395ee1ab0eaeb0b9b6bc33ec1ec754d3a0f7d8c324634f3e3f1999231216a13aeed0d4e30c17aef8147811e2671320f263437502dc0f541eb0655ea2acb680fbab6dc7805027acf706043fe9ba7ee93af05c4eb0fdf256c174e47d980f529fac8a6df8db3606b04ed30c606b83678f98348b8df3f686f123156c23a49c4d2231382d511509bf9f68471a16eee3737672c811a71a42edd31490989e8236048e97d4c638cac7d44fa66a81173005adb4e29e3c0428f4187b782b88cb2ce99f2cc351c9590679bab1f73cf2b0171ff1d185abc2eb04c5a879edc036b992493489a4383c15641f1e850db293d356edf94808b5228215e1a640687048341922c9ec29ba8c4cd578459545c2ffdfe43c99f7c841c48ac5501f0d2c00de969bb0e896be4628c59321c48b57a042e9ef2fbe02487f99651af9abddd2a353f49130104e6bcef03b33062804334fe8f4caf37e90f5d86fbe9a7833a6402100ea96f5bf6fc935dd258108e2b6f3f8d617f47a8a26080777068769cd9bd3933a5da9eda8bd32586f3c7251f4c33c148b8f25bf7401320be1a67529c2b2b6a7bb9bdacba5fb2d75eb74f2df74db6f722de00574dde40e3a5a6fdfdbbd29137cf66eba1dbb29a9fe38e97d8756493c53fc32186bc1d5f332b61076d94167814bc18c61e788d3a2df61a171ad2464a76f426b3cdc6d485f9c452f369f40e283a46d72d9029f114e805ab61069a260209c9d9ade1206081f261e1712dad2df0047165083d590ec4de864adbf72e8d9e7931f0ece0e75d1690c2ae534edb41c8d3b7454428d1c153378b9fe59b7c8d1937e420c8cda80b1eff3aec250bd41b4beaa3f2689be12ecb9854ad73547bc1a83d06c273260fdd50dc05aae55cc0e87681558d3e8bf28c3c817ed101a0a788b4c237e0247ef9f9acced75db4dbfd6f34471424a2b25c84aaea9b7251bb629d351a7dd5cdf293dd231469f96036c9221170a35b0ff841cd74602c1275a3fbdda11bc522411689f08bfc54da378326158929937afee4f13d59497ba5695e65bc306e173b00217305400ecb33d8ae24a9ea8ae11eb8cc68b97917f4c94352c02cff880243b2c9a872ee22ec7d1f3b8514fe2e6b0a17aa174c8233bab36a571633ea2bd00db10beca5040ef5a25777198b393ebded1cb15422ddfebacd91ff344de9e58b5732afb30d829cf43661d9f4aae2d1a1b86115c5e73ac85b0a3674bce31f7568d8abb8ff421ab193153815700739b0d1fb3bffa2a12f4fc18469b6bbf3996afe6621162b6e3af960617aebda9a1cccb4f88629ccc8c45b496347ff22510e32d4a35c8179e723e775eca340885030adb22e95161aee996ccc4b5fd4715514171faf50240512cef0d6392d8e141cfa80616259cdf4ddbc81a34acbd19dbd43cdfa55b76df7dd94bfc670a7f56bac77a2e118df366dde5670cb656c389c89f840c8ef35d1a5bd8d50bb6a1f89fdc78a92bd9e7b88647f97d3e7a12e29018ff5b5f86b8983d4063df242cced9c6e87080620cc2f4cf7d84200d1aa059238ee15268c9d802277f693c0d9e3c89820f06d082a8ffc60023a326d5a90f48ae1f242dce0cdd80ac91e635ab12b3e28dd81e5284b292b263c42383beba8d236ac58251fb566136a332aa5c8e4e5ed0c89a521d60567eaee62d7488581d0609bfa86c6d688e8477e6f478252bbee4a89ca3c220024aae0a66db17c754a74076c09a1254bbfb86584196b203a14f193543abbe736732babbff53b443bb0612011cb95e8f724c5086fc3a1992654e1ba5e930f931501fe5bc8db26cb1dc46237fb8ec1780984d7bad12d66fced799c6a3f79a401d9341f76e0d6418a099e8a700eb680858a69a5044c9607fd6ad286961f78512a54a7404b77065de28c1b5ca5d79af7fee22b14c8be4a0e43797fca412a81ba369c3a715bbb33f1a2f74eac588a7dca9e70b99dc4694125b7eec462ebbca44a845a33706df4809eaa879e257873ae17a055c5f9255a9d1878fe24b249c6ff0075e2e361a9a425988c7ad78065df80b3e911c6b6a2496f5905c4729d8c562b31e16c2987da0ce090f1a86edff1d4fb465bd09f8b1746790c02f677d11e2e545c5a331e5aef326cc97647c0b426389e036147cd9c56df6f43a077e92c4bc7f1445cc0eebb0f4676dbf0bc55f54cf7254f4a9bb65b663e11a0ef2ec799807e67f4f6d7a5e68cd469f3c8d18ec5bc7017cb2797f5651eca1d5d5b7e81050da5280e89d7ad8fadff0e82aae99b159df7cc1c8c0f7c017b85fb6ba4a2e78a0b99c342a0a01548753edf2ea82e6d6167ae85f1a0d6074cab66d47edbdd06e57acf8df30a13631871208d23e2310078eda470a10c222dd0b095609e61ba3eb1034c0694e4c0a5366161658304db664bca8ac76ad07868d4c7a4ea3ed7509e6a6ca964fb8814530dad4dd646bf8a267d45a4fc12d2358b1cde6ea540ce317927870c659a331417fc1a5f5bb43b4c3dbf99521d3ac1584337d68ce6062059e4e493bafaad1c591bb23cf174bc5210fe340d0ee36e4eb93ccbccabdd0995d3ce0febe09d27f454448854a98d1520705d1989fe9d22b72247fd9343b4cb9bb2a3353326892cdbce110d57e04012581908303be32b0ab216e553b6ec11c21e59a044a2ef93c4487626730414398093ae92bf3b49740be73d01d1c98a4ecfd38a96e33ba6f83c3b5732278c1fd41382f6f58a8e2c7ab20170679c68a80e074dbb30ce20fe4ad8cd288c96e6db2963aadadb0e52da8f924331a4e7ced8161b8ea8c5b397123f75c1c0d9a74ef863514d55a6e2331e494c9f5d5083954b29340f5ed1ac211dd46ad7cb88423c114ca064b4271c3b12965e8feb54e530c1c37d42201b3f972fe42beb73d7158c2e1d4ef6ec5ccfbe2b7a9af6f10c68854dec766b272fe71b2547cc7f9746143ec073e7a0b296de845565740d8c770b672de5d7f742bbac7f6d89111c7dc320cb9e048c763f43c85d2c4d3986ba6fe9300d3516881f720579152704a376d22fe895fbac5e331b1371deab5d44894250cbdd64b4a31172623eca54c42326186849ccbb5d54e16a506702aa9c4888667f4223fe479e512ff26fc078cc0ebc4d35b67c642b3ac56aeef817ec16890abaa05840016dfa39e8f34c86bc6bfafc5d47f4358b8464d32f93cb03a1e04d3d96b26f70a1372df0e568410f2c5a43e6138cc74d6ad001d5e1c9d290ad6dba68c8190601ad330cd916137c88d7b7a875add31c68824143191f3a78cfd6d4c75e29e76088ea22a07f8dda5cfd4c15505bcea475559ddfafeb3152fd67b89978c67aa8821b6ac0c3d3537e5d3912bd34391b1c721d0615e1b0475285868339e89515503412aec56159c92568c1372fd6d222ee97b1b34540b4284097ce87e49d3071d11fedd6fae6d4a54b230bf7d9a1948c63eb109c6d8ffac592200290c0da6ccae124483e9e072579c0cce1f4441ccb90bb6c416b4f0eb25ab7f366dd76024334fdbdf8a97e29c217bc09fe12eab0009140b3164b5bab98793c0a3b95e6c5cd94ad6f178380b2a9e296435d9a695d3246ec0ec7d5a477b62af52ac0ae7028a8df1c94ebe6cbc6efea015d21f91ad9b2dca94a1bed076b3c2cd792a1c6e0fbe600fe7bdc6f43b715e61e1f6a32a227ffd15a79f6a7d1f613c5f207c9b6136ceb464b67d81fb41da3b5d6ba13331372bb1045472d8349ae61bec6c421ee4029a9852aaba088c2caef4ed1528af6489ee0ac1e8102905f6161b56e98407d0e840394a3d823f503896a70058705b9e436c0839a50f5dd88332589381314afb5298f62fb91c79745a7dc3812b39b9115d2488f985ecda2d0fbaf1afb512dac8f3e000c53124f72b618644d40c61829a589eb7784dd88cbdd12b1159e42bdffd73c34d2431716e1f8635fa2621aa5d78ba6b55184cf5d3196d127db3984e0a126b4655ff07c6da812ca3480cce7a6548858b16f1233f6409bd100fbdb1b0e4f810fafd6464b16d447a9d4827b1830d153ded14bf503548ff8ba38696bd27e26b9b6dd97cd73b1fbcd784ab1f23a02e500664f902970106b9029239e823923cbdd0f296ca6d6fcf69bd44c7f3cdd40a1c69fdc0ac86d7fb91c7cfb9e1ef08c5dd8bcfe5b48450ad35c23ac642d1574f3c27d90ea3ccc33c89e2772cc150f196c5192899a30cbb7725ea2ae8649977eed6d19651b987467f1f85b6cd499cc1993520fa360d35aef6a720a461bac134b84fdb36846de618f3975b8f998c7b08fa61094281d56b14538eda36dd22ca8f4252fe3edd5553a94fe7796c98cc4c54eb60ff48610fe37f098194cba428ab9906baa3d26db103d97987f8330f56dcc22a344ed463e31db570430da6c419c7d62d3bf5f66ed47620eb21e9fdf1c4dc5118767adbe0ec7f997233832533249f54c7a07e3e065ae8d02e68b1d0e2374eb608f374a54a14138fae94fba9f725ab4f9c4d714f5300c020d77cb4a257caa4f37b8e218251322a88952567f9be40f51c86f61b98521b36bf10d19df84d5f6af2b7edfc596a95720a223bfb5fd026090d9b120e46ad3a6fa24d68f53409e6ab24fd4393b41ac3cc72a2ab76cc8977e70c708d25a632bf9486d7a97e0912faa1a7cdc75f80a4af6ec11340d2498aaf3887312c27c9c54a7b1689fd954a71e077031509c9309594d595bcc4be24f3e1b188532fac4dcb3d57e5b7108f2e3ea7472ace76c1c9c7478dff53a519a7324e3e15d0b99f3a8b71a64ad232b0b73c846536773348ca5194652d199c9de8f2f54d7f7a45b9670e6f82537b921ab5fb60e59a3e8b22c7e7d1bd966b77bb401ba240eba569bf599e671e2611ca899b955e079830f42c810658b6d314f27291b1aae0fd7020269d2ccbced8a54dbb70ccb5cd8285e3bdcca3fcbab0ee0b8d8f746533aaa14996635a080e413860cdfb5912e477730865b84b1adc238540b22599f6e08da33b2f1611a4831fff3db90835e559afc139b4373e0a1c8cdb4fe99a6e90f91eb50206b91eb0ca9e4193ef4bdb3037a51fe44efed4da6809052e94e6a0f2603170626eed06b08cb2d5592bdf7306c5f631dbb12c3bfb67ca82a52bb4dc11483d59f71ae6781087c88a50ae82c9fc4b93e879e81e199936074a5c12e212f8cafb6ea5fe94883ffa5ceb0597ba7c3fd2bd2f52c4c2ebc3032027d451e68c704797a2f505482a21054854a64e943330842589ae1d158a7c8bf7b30fde0ad33fe86a9aa1b60f7a62c7c43c2739a07f16b57d9c6b3c8f70ba4bbdcfa6f2f798333c35acf2929e332c41cba7a70211c38b8adf3a1afc589fed5aaa4ae74fe5e7a0ac04a61db3c849272d2fbeb98b047e1a2264899918589ca91805dd714cdab5d3e77fd608a5a7b843ab09ad97839646c39d3832e40add50f106fb741617bd97421f7c5ed3bfafcaf55e5ed71a6b688096bc707886f4ef816c4d7c9fd8fa4b649104ec74c760acdab5d80f323db7bc54529d92d4b4d4a1347d149c711a93614dfc375f23ac2c7dbc16f58509d7a28431ea7ed5d01b031a5607e9a2515a6fd906bcd6c5f74ee1baef944aacefa4327b3c53fccd76388cda097649cd3fe095a3006e238ad2075376a0145b8a8e27a4e23058646279ee4edca2e14cefda3580be423879f58ef739b535c0a1209d2013299fac98dadfae79d56de72503fdb56546d0083093a4ca2f97b1f6d77533bcbcaaf6a51970ced0f13293f5ea83015e61cabdbc92cc27073ed6fe71374124f089c6c64194c1b171d4e6999c35e851d794127cc9e472a7f97a626fb09a0b5e2e275b28f52621c1b5e1f2938d854b554e03c71951db41039dc3d6c6d7f4033e4cf838313850b8f3fe6007f088458addc29ab20db2720ee4891d95b9270640511b8af2fb7a1e0bb569f81929d9f3d683ad01adb9b025e1014261ff287f37c816c12c9148bc4c3395c1bf316527bceae3e1cf44e56edc2ed527c32f69c7b82f8e4ac5c312542dedc6448dd4eb2f0b49b8c9eca0481bb65eedabb3bf877eb348451ce09ff6565b0c1732eaae7db3e53636ebe8f329533856b8a5a721715bb1286cb296f9ae621c871df83cf47dd961c560423e0ed2c5ad9b58b595be8701d267987fc187680128b241f905290f88d75f5e8dfbc4af0a3d5e24b7e15b7cb3b0bba691673cb2aae91df6f784b2b530599ca02b148729e254e612cf3afa4eb2b2ed3fa7b74597b3bb2ff66d2b546cb0a9ed593435719be0818ffe4207f8a80f690cb326139e2cbbf9dfe88274ba410e89602583ea575a62a2bb006681191500f5ceb5fcaf7a58d2ddaadcebe51386cf8fc2781045e351738c9464f808ac513a86de8a544f83eabf78411538f7ebd2db7e433000baab8d4ab94e3948699604ba10b8256bc169bf7f69fa86604e1c1c6aa7e931216247ba1231add85a3e153dbea96539a80d70fb28102a74bcbf5d875fd8bd0439383b8721d2906430cd7b244a2e7b9f14c873f2b3e41fd9b5df5326b8e938b0f62e496c6b20c7f8fac840a8e5968066e1db31fa77e93eac48719ca515a81aee913608e86f89e12de483a31ab6a3bf3553f678b2970630c30a4de9de2c6e4a26d23d8dda37ad4dd5305a310e194fc4e133b17d752bd2ece3edf76ce7942c756171ebfaa352330a9c865cc8ea3133d258211183d5d9d6e50891b881373b8dd1bb1e94bb078e4ab143c548cf10430b9ed6c4e151965e5fb22ce2215ef849e56655059c2717d84ad761eb00634e743fe6e6ead49cd60ece6e3d768c5fb03641f3d8d093b779fabfd9144beaaeaaef1bdcfaae9279bd9c28f29c53ea2b38301992d1664e9f24129a2168178895fcd59599bfd9e15e688e17743c115328b2df4582a531d222722e76d837f05d1978a084661090988392918bd09226885f8ee4c1d09f6934d5d37560addc79595bc89b726c36bf25590f33cc850411c61a7d361a17aa5eeecf2eaca9e596509c2e87c94cfb80ed8ff812e287b6ad01d33912175469f4c6f15f54f66a469c91908320a4b78b83fe3910c43ca9ae10c25c7cccf5d6f4c4093254ba9c0e5f68f05d18d7a1df6b151de7e0fb0fb9c80b75dfbcfbc84853e22b231e768db2d95328605b299bc2deef2cc86a72946a24a59d9247b28dfa027fa62b5b7f4ce0867d910692311a05b2d6626289dcb6d02e4860bb58f3067371fbbd650657aae6aedad0f3078e44f2cadae6a17f97bd53224792a6267f604f20202430a2e4e5db0571396132ad28dca8f17b649521745cf2eb39ad5ab7f03613d75af8db6d7edbb3faa624a2321f7fa9f758504af90d9c308a8dec19942fbd84118f45891d0f2986a75bfdebf4ba7e73e0e688246f6d1248f9f59f14ff64f8e3288d16fd22281dd2865c4fe2b66632999fa6e3a5db316d46822fbee54cbde84455efc9690b5766dbe5ddd6ce909b9d669420f936a2d7d0e20884598b60730f2f4cd670a9bba49fa068ba6ceb54f42bfc1912ddaba84a54abc8731cc08a8fc92bf7eaafecf8ff0fa314b73c4e25c0ecbb87e033ee566ee67245d81df4153c0bca29e14fc2e783263cbee1294ce97a88eb28410bf516875a9a9bf0815380edc2c9876bbd96aa896b0f61fffdc82819e145f51d1d23f028c2d287c1f249cc75fbf537513b7b650c7297ab8677dddd36f668194bfa5e3951f1e989656f5272695c6b9a6df33295fbfb824a037466a060710c2783c5a4d6fbbce52edd4c59f1714ff1e9d7ae7bb139f8a8be4911fbbdeea4b08766fa66a7f2fabe0fde600834222cc5d239dd2459101a2f6c5494f04b4112cb9af61f5b50a8029f13e50d9ab87e4711622ceaaa66365c597d44d978914d43c02a1fecfa60cd963144d0750a275bce57c5907df2628e2f5d6af33d9ae9db81c4e0afd5d2c1e1a51e546a745b59d7839822dac14266ceacf1df765a796090b45c220004694d0e2ff300ce7203b5d9c683be2a0ede69d14c8af0aa8458f924339ef50f37c726d0497420b3af86b4df2086d7d347dd41fd4cdd067d628520ccd591eae397045da2545178709f9da14fe1a38836912ab8ddcc4042ffc417cd4579e69182f5f72edff4a075e612b9a6b94dbc1cd456bd49b1fa1f1227d816dd7d4e15ce7ad3b763a47e0f3b18c6298532d12327d378c43883a5b0d5f5a7f00967cd7b7f92e69196d7a0ae361f482bf80670fa25569c836d150cc05464db6a670f75315a8b555955e83f3b119813c13d1c3d59c7ef2edc17a0f84b21955aced581ffd5e350f431ce3ad7e3645bf245db94fce25ae91f2a6bf0bd8a66d4cfbb6c6a0013ba3beb6bc9a486de3ca0574e6002b9f4ef94aee638ca5437bf5a7acfd19ece37aae54303249d932cc2c9d13172f61a44491b3a01f47301e65a67c7c701bd2f05018158d821230e818adc2fd36771961662956a67e6de1aae8de0a55bcafdac83f286e6d29b921a20f4c8f88c0ab2758213f22ccdf78e85866be29e53ccde7f9ba52044c912a98fdf4534ec2e0a6f60858e117c9a15432dac4210cbf7f6b7321892832a511d5456b673d13f2c17ef6acefd317ab6d7a613cb871c9be253c3cfda60180ac586df661758244da247dd293c2c501a848cb7a842c4c2349a505c5b56a23d3ce1de27d424adf6721e264d4b5c5aa13f4d03f8f106d81a05fa5691828ed6c0a93e1bf77737a97ff0f52d46142b0a51860b44034cf7dbfc1970e4a7d40b0030f31e7594e160098757aabe2cad440645fde53ba04e8881f4983d9f3be101fbb0bd5b6233a8b8c615b9e67027043283a5b493b0397a36826ade11deff63b2a2ebc90855693884e583b2cd3b00288100264bf12699917d7ef14ea350c2e2e95ba42d74170459d77d0eceed46a1018f44502642ea75f7308b1f72959ad2f3dd1f80222274916d1428866f1191d663a9461bdf56f1e64d4b961788b9c8b561e408c4f13cc280303ea2c457575c4ce4020e90afffcbc83f26f5d3759e5084edc9388885e83abb72f39305ebb595a01ae67e2a8317e5cb605b7cfbd71aa3ad40f4e5cf8d21e6f6c1041b77f946b76f10b414c2542bf6b5ea59a1faf6c2d6246aeb24c26540d68bd3f1f1fc2f017e46c5e2773231db76702ea1fad52bffa364f9c7b2b4e8cd5f174789b6e431b0e37624f8eb3da31de5704e40d8ad4c277acecc3edd04635adc1619bdbc69ea73db6c2c1dddbb899aef920c4a21eadeac92402e7758b34b574c27708aa81e86fecbfc36f4d679c5f163fd64b54beeba2a8d946600d9ad8d6360c4f735da77b7083143f07c878d44538e2087ebaa9602dc5c9401318c23faddfc87f0649483b84a9db35051434e96d8e0cda38fa9f59fc38fee54bbeec94ed7be4cf7fc370555eb1915525716c133a0328817319f80fce47795f687bfc6f3e3da4e86d0904bdb69614f3a1e1be6e0dd60ef3b2f5f64a58ca88bd60e3ca3d613565d5cf4a9a0ba7479302e456cf402514ed31356502d83ab3e3b636b5f24d8b5923c587b949acd109ebc2c6444d4952812d9483709bfe126fc77141ea56eb6d442e5397ea71e6d13829277fbef2d91980cb13c192d0ddbc1e0650aa0ac9f6c8e5f2c62ef2d323b7cfeb701081613e19f59d6ab0217c2051937d3b65342ecc8f49628d2dfa33dd0148cc37c000fa4eaaebc10dff9851d1970c9f7adacf138c106d7c4925991fad8d7932a311a929c22c558d2d4ebbb1b837fb43947cc70c46f540603dcf5ad0cdf1cc33e5911eadd44b9d7a174fdbb3b3853f8528bfe9f596909a45adcb89b31cc7d68ec7f102f74030e1569d940df78689eabc5fbe4385fcf93f9ed6fbc7773d6343ba079db58ad164905859197e8e9a08b2ef7e6ff7f1d79abfa5c0ccd9c0404f2e151c4f426284c5edeef023d2ea14dbbe135046786284301971f16e441945b2602b7fb6d6e4c909cf4017dbfd87b5b1b5bf7a0e09158c7d5be0b464609c71c883aea7e0dfa1d426b64ad67c84ad740c678234ff297c81b314999a932256c4e5a43479bd32c4b1f097d90863f1499de52d9651be207962c0cf5c7c357cc174a8e677f031da28387f2325ed616afddc45168b125bec80d921aaaf9817c57922bc423c7db7245c3606566c6eb63a0a4f71ed402632b5253840043422215ed78e4849750931e3b118bdaa0e3696e88b5823b9d559c11f3dd59680fe3f8f7ab320dcfb599c859073009a61e186c5fd38acd25902d1dc43737ceac270689f7d5f002effa5e22f490d28cad6b6bb4bc851393c8295297db8f81a377f20c9f0f1c5b896d52ca878c55bf3b7fe612582458b4695fa66771baada4118722a1b2b20e00d1243dc770f2548cde7e71fa1cf3d91cfe031c61492012c79822dd7f3997591cfdb1361a65d94b05bb746170460cd4c70219344d7fbbf65ce938095014722964611cbb2a87d6a63f918555de320ed6189bd0d968f804c95f9adb7e48689a7cce6476c9c3f5102616a1ae76d3b830e8bd9017bf686ff7b5c144ee66f857a958e3c0ab0d4c032a835a5b0d60bd9d0ef2518f5530f88b343b720287ddecc5ba3154975becbd5e0773926c7b8a6dd1fabed3897de2136baef5d09b879c7ca2578a12f4ba2edfdb45f1d10aaefe4d827f7b3325851aa337871a08efd95de3462d1465eab51c9441c61fca81a35b8abdd755648d3762f1126067f4dece7730a32eb6a78ee337807c4ab84417cfb3a630a6558bad0d022b8f4053eebe8ccc91da36a65a5144c62504ca8f130a2b9c25f6cd9a726ff14e0d0cfe0db7d8041b834c3c2da8394f4399f35597eeac548153385be073e5a5f623575a8c3d15d9c1a5d4d43e96ecc68856bd891f8c01d3814a3891ac1cf6dac911f01a522a17edb5b18efd9df50484bba31f71237ad0b14766cfe52c7f2ac592a58bb9e41e2aaaecdf4085ccdb00e114ea5adcadec086d2ff4243aea66abcf8451278d2c7330413ebbd7a9f903d35132ee0b3c4c3b13f0e8d64aee8256e9e3e0fcafee43bcdba03b98aeb12673a274687bf9029298507007059761755a400345b4fcc7199280016ba588f79401d88d5c8b0c998ec67a577583ff3400b15fd5c60591c8f8aeb5141dcbdcc09bf55b64eae78cb9627b89c85c4139a78a1415d995a0b356952d0479a539b44eb1935ccc684e8f718e561754a01fee7a57bed4b6469505ef887e0174ce8757279417c3a53475c25dd760ae553c2f778717c50ac5293a5b486bbf7fb0606e8a1fd96c711713531e45d9346695a419696f937bbf98cf2563061fd905c06e1cdf6c1469d65941e61f7c0171835584c64dbd36c5596640fe26cbbd540a0d0ec1c30b3f2e598f34479f58fe4ab2c2088e229c9daa013060b2121a04647a827792cd27992536f8b99dbe73d8d3b23984dba382a3573081e46f3b3023794992213062fc19fd93e4294fa9a8211412f372b389a1b78f02f533c4fa3a4bf4f1aa093c968ed93d3e954d02cd14e25aa614a9d55fec0e3690e1a8c5fd91b20fbddf0ead774282d6f74d678a5f9384875ccb4cd0d46815045bd627834f23ccbce918f3c6da828a6c78fdd21dd2499e6fbc960b28ae650c1a1f8f9b3c06bb95faae6b7783ff1a3a9c9b9b3cbe2bc990ec94fdceccb557a10daf23a90867adf1f20e399e92cd513d0e7216374d635f8557c095c9364bbe2de10725d745281026c452710cde90bd775def3d40972434569552ac404a81d5e8811dfc276885daa7ebf2c9fd22a7cc3ef00e9c7713a57e9f0ec678d1a69e0f4845af3eed83d6ad811462606d8d6d2461e9b812ee7f462a735a4b66e0527a3646bf1adc549d85e660b51b20a425e14ec2939f4e91f63adb119168910f578c6df30d969be03b0c06739e373b177c93356a2bd28945c9b9365db52e9f9f74ba20042ed19370988f604e73b486c43156b4eb2a9d2ae4de4da34ad9ad1252d6be7e51aca92cc085d25df494afa41de696079dbcdaadf46109c840b80c2e95cc218006e865b75a904d7ddb6cd8d1e1e9a0b8051bd96ec8244674a1c14c64820c2ad3e9175bedf684fbc9b743ce909381c71740e8ea5e260ec9d10d037a7b404f87c8d6cc56ce6f25cd484bbd13ea094812da012048d58ca24762f49e09fe86ac2002c8790cb65470faab4f144c2750d43f5ddd6f2fe310dd228f91e6e5937cd63e91e1e9438b0122ad7a2257dc7f9528c82849b51d89e83c4bfb687a5b0e88a6d87a121e36e6c3bacba16ecc8207621b2f2fcee0515c3a24837e7aedd636ae8f122c085e24886ce8649be90705d41a05049102356237ad2bb1344c83688760d3d31851b6005f39948bb364eee6b3e18b2fbbbb7715a3adf2fe6e1252c6ecd2093edc5c2236b5517fd0ec0eee668e5377906413912b8f8eab72ddca66566866a4d0c1f998a94f414d9e8b02374f4d1d4ccd9b011d6592ea5c62ef6e7668e92fe417cb807ebdc7220328484fc4fedd228a8fc9d0ec034c358aa5307c02342b13d8af73f0b34d53a8732ed2a004216ea70a4c4adc9a01ee696afa13edd3f2b6231d2f730abe80a5b958af1649d5b57a0e7724a45362281bef42d9c7e2b5c2d647206a6ddcc16ac12c96192c8f22a9703064180115e3c1589ba3c995e854990053eb4a957462118974469723594ea115ed451bee9f20b508f476d6a1093f7f9f4c807411c14bfb1a74a7cb91765c27d6997dbe39fa7f46878ff4fabfe4d210962e65ed43d19cc83c9196d9c568619af25c57327fab8411b6c97a41775da238e1da0a8c2b78bf57db97459c6bc655a436188d2f64b24027174bf7bb0c114cd35a850ad4af40fe371c63965b87f469411448b59f49ac45e4284d9a4f95978355c33c84ecefc4b6b33653515219526072ad19a2feb2d25e201b5fd221a1d3c7d89c81bc1ac323cbe0bfde1c736bfddadaaebfff6a78066b06ed08dac8c3f5b82ae1a4a7de2e6c4a8a61e9a5515904b90c3d1f5b1d1e7124f9d01817b04d9021dedfcb525f0cf9e57b472e0e54d1b62219b0466d77f9815dbf782f9f82ff3bfd91e98354fa1143cd08bc90e2da8d9fd8d31a59579f995db8274ffddfb2feca6bbb1de5f7061d31dcc59e9e88624b5086542d9b976bd1850e67faadb8f2fc1a4caae6806a82f3cceaa0f3049991e25288bfadc9298a98b03445817410c6b43c20485b850620006d2ef0d687faf0c207b4dd31d3aaf16ceafe05eda22e25cd42740787c79c737440b41bcc50cd35ebd3868eb36f99fbf6c12534bb88cf912d01bfab24a1c72c216b78a3f68f24d7599585cbda4adb51eae6a49898f0c9496ba2b524f6004ba576309f068979a32d696c3076460b00d75d49b94ee01c826a448a5a579397e8a5c72f6dee2b854fd1f6edf166eeb54c479c4a177d21fb39d5426811afea335d50324bef7918514fa9e4e149a0b6cd26ba5b33910cf1cd4fb4286a306a26a747bc3a3f7a88bf6615fc78faa95322de20c4b8ef944352bf8d3abd24373cb2de16b0e50aa7ae36e517a0e26d081597abf740accf7472b6352b4b86e01216926a03308be638e1ab21046794efc25c57ccee1ae7575e52a6d48d5f3a7299bf99a341349948771e98b17c392d7da0e2b8b6bb5439119b6f008865dfb80466b7f7fc0a7b5c4352dc0dea91dbd764e170af073710660c2d524a32521fefa2df1b0b97976dc35a710f1f816959278c4cd25bbc62d7ec94cd01f3146b7d50daa00a5f9852fb1e076fc481ed325cf222a2b6b430e5488e55d44fee8677208aee764d804da24e3e734652c4608a001aabed8a50c0d3b9ec07504d2df01fdec7489d6e56d2d545885a6bbfaec6d1104c1741791f06f603fb4c10efd42f80b282f7a6e5e9b691c244cc1fc745be970327e230246ef7f304ed3ab7d93691da61fe39d0b3aae3bacdf2803dc6e6bc7eadcbeff6c3607a379d9344c1519ffa8141f3df8d882feaf68933ecb69b733ee2a3905586f659ba7358d85273784a2e78c1eccaa2899a7f3f214c03840e5aa6904164d32083f8f32a2260bbe47dfe7d246f9340fe2d6315efd278b507bf170cecc51298f545559bc1ebda0ad1ff7886d12e9ae51338398cd6ffaab9fbe395c949c7852d46a78242e4bfb0a30f4414dcd412ccc3bc1b3fe3a8dbb2a7f0205a39f4f9184706e0080f9abe219ed707fe980695e923929ef8f4029a8c38744e6d18ca76236b1c32c59a35739bf3955fe31fab89ddaec64a79b47382ae4709b8b9846e52b5e10e8a547925af220a14ad0e0e6cf66be9ee40eb60b11c67bbc629bb02b7fa4c86bc3d9775ea0a3fa714aa1726cc295b2677212aa7804bbdae91892fc6ae08b2df89380130fdfe3fadac306a2225c07f9d9de24f1b35a15545ac3f55e5b9b884baeaadef20a36c1c1ba7437249c8e8f83e6b39b19917477f3fa0889a5afe5211568720a8d93390e2585e6efb445ebf11d23892405f49cbefe475b4183a9d8772362a146bc02299e6c3edbae1256a5c6a6d21e96035dabbd262fa3d2031299823f2d51bb32fa5ed8dea6af5043ca8f078b5fb5b0551826126eb935eccf2bd09811e1e6410271ff704303270d972301567c03f2431bb0cd7d07b657ea87b0e738c288de2f46de76dd50f0a47a2863c505d03ff47300aee951c45b3ca6e119ddfbec3cc9392d85662681460559ce9a496f15264cd549c882de5edef425aaa1054f2bf24fc8303c9d0a246aa203030133ca50b3d7f26434743faa68543018798ce22683ffa5907c093942fd4dd29f4f27ea1017e41013b497e547f2f3ff9ebcc569f0e1167a193b6c6d9043de9063201ff65275dc0e17abbf7adca55cd25221b9eee9a0bb0ed522c7a586c7cfa9e8701cd463d78f71ecc344cd6537712094ff365eb115181506dc7d8a0398f78195d5e0784d915e008290625005a01f7e3a70bfa2e551e31bc13f50e64c19b50c2991465a772ed19adc844e4c1074ff8114d827a3466cc34d46dbddf42614b9c6768b4dcd369dd747473a50b8723a52e2b431ac9db0a96834644f1bfa9ce0441e15d06287a2e21507aec356438f6bded56d7ef31a5e6d6be09b512d1ce7fcfb6440092daa70265b2523229e1770869c956f90a8ec6745855252dee5c52370aaa73e3143e96e755742237d7dd06805907aba583b79cf0f04df08672e7bc444621e1df9dc0c609f6cf5eea99669e0b204feadda4c9bd8ff31376b743074288e65b9281585842b45663816b8bd36d815eec4c4b4b7d54b39fe00b78938de2c6df0b666f97f95f15f0bcdf93a5e07bc2c1550b7e13dcc2a32850c153c744926fb2e20f7febd745d6834373e0ae7d86617b1079e4e9958c6cb8a3798b8deef4b7f2e959f8564bc5bf35f13d388daae6e76bfe404cd6c9b38ada34c2db36523f4f6341f33a9496231ede1a5d9b992e352142900b2da107dfc58dde1b669203953176e58b79d0b2a45b19ff035fdc1a4ce8df0e2a71183ead26af9de8450855fdf46f21711e1709d7ef5271155aa8d5b75755b9519759fed51d908de1a0bf19048b34cce48490354405728bfb28b246c772c1da15a80454fceee87172fbb6661c6d007a6109b9afd1179b24433963253b07f145a483b5dd30398600668c8252fd7ce0c5df17d5fb4da37ec920747123cd9c76d90c92018ff4eba3848804b7827e7fe6f897c411914ceb3c79cbafd0cb0710f4273b527bead340ef4cb563cc178e52505df463281e76c7450ee4010aa672d140c270fb298ecc86536349c6fb61f314fbea05aa18821949d4af2e47797e9a7d4ef49284cf14120b098d34901b5137b82d469a23f3a69e66c930eab93f48516d1575a0b8986cc46e619f3045f489bbf7f3ef346b99952913449406a143529abe32e8361d04ea8a7e6baaef6674a209a5864579f48028d433d3bc263ee27b77c45567461be8f79a127f18c41caa84a0dd06a9e4ee156a2df6ccc1539edcd67bbbcd0090f78a430f360043ff3217445092c3cf32452daf1189183d1282d62001c9a2735f71e9f8fc272736b7ec8c398e03e6157370efa3831cc7411115de9543b1fa4d4007b851932cb31939c4feea6796698367808667432c2ede5257a313d60af4b7eb290e97b01fd68b32b21d5fddd869cce24f04429c1d70fcecbb76dd6e232ed34d44e724ee89081e35f6ec937b7524e013dc027fe4343e661e8e46de3dcccb23d105bec0e949ee90f860c65b6e3fbcd80ce01ff902950107b9029039f087d6a6a10636fb5e62205bbed17e2cda835912c155aa9ea3493022657eaf124d43829819c733d2a95cdacf3cc22ff3f43753a1ad30ae9ed71a93b1e642c160e6b505292696619764a6ad4390a4fda5165aebb3d35e3248670da349264acca407258eb9d0fc910babc1f8fcbd18318252de9c4d0306d7d5702c125daed2e7246fd62db63a5156920ab0a8dd2f5ced01250c82704c26d9f4bb10d4e54487749350543c0b92b275b87dab298b6df75e163162359da29e99fa23de1ebb658c60dc02951e22f0648faf734c657d36dfbbe7580ca0dac6aca5df590d6fa67014571a7833b87e37ba4f8f3835f9dcb931af5f2f68566abd5d8f1264d97fe9d755b78f90efdeb3ecea45c585e404d1d2ce60c8eafdd9441ec9f12783c00c9c957e53357064e350c437f68410e4acedca0de6ff73f9ef1713a87e6ed61876676ed8b9994bd26e96af5ebb5c20c7a5f96db40254f1d84c942ac976a7240d7934388a1ced3c4cf347208b10174af255f31d1740d0da30d1b34f82ce946717ebf06aec13b456631bcf582abb2ceb3a46a1c9f61cbef522ff34811fcbe28ee61792c3251f58345a9c6ae51d3d0e09346761f6344d1b56a49aa2b961d3cf68e892389ece1489f33ca8e1476a0760479c151cc0f4c9a7188fe94c2b38a7647082a11536e8465e76cfe662db4c0c0cfefd96ab6cdf1f484627e9d623a51e6ba5b8663236ce27b75d2a4c90202d8c29a5569fa617d944e377e7cc4b270f8bca93885a0d14a9b49efd9ce36150dfd74dfe29c15a9806692f8dc914bdc933e9b5f107a947841de763303405123e6bf07e222abd4b111390dfa3692e5b20fc32f6d6a4d3cc5cfc84733c40a61d0842678ae6a14983edb96fd06f3450a56ff5487c8787bc5533a835d2711b90a94837fa53ad8a10e279cb80f91eb50207b91eb099aefc960f87dd6380b34dad7a5bf7d5f89357d46bc6db20a7ae0809809c6e18a058d5b17d6f5063096fbdc8f87f05324658549c60fef7eee7c25c6a5ed7e8c6a79c9f9ca1615cd51663fec56df5402703f4bb64547a0d258ac03789731d32a5cb8e85c0927883d8dbaf6d219760781b4d7509662baccd0eacdaf3155d7609cc9e918b31cb7556a8ce2d2d3d5cf7ee1aee040297dd1293c6098151e77e69b8e4eb135b1840dda70ce1e0a096351283f836f216662ac8e5fadb61883cec15c358139df53beb4bdf9c1aeba72d7cc9c8d82e9cb70d2d30303ef32f06a1c3abe6f75eee05ebd883645c8fae6502320c325c62292e243e5d59a54a6836a105dff98d1c3593e9db8c75c01038a0834d0e3695186ccfc304f9594bcd9169b00f72078e76af381b1fdfb0a4a44c57df3c3889fc48829100416484ae8b77ee2a544b9f043d99e817c5767d7918750fed44d9e815a1524a6d2e9007a11470d9fe617051891b5c69b76ec4264c23efde0e5452acdacd5b7f590c813c0d25ea34847ced4de5995ed87e403f941851798891a2d55301d6f27d3a1540a0b6286a73e414c8c0648a60a5731b299a67b8173384752495b99fd988af106b6bfe7a5138f7021871ada12dc37ad0f710ab4b6d317a5dca9d1c4f8050becc2130e90c801aa3b6df67b5a3e62707428db25afb115a0c6d7ad10741689c5d3804249f3eac63be3185411baea3f4bf3d04995407acd194d7204b6c0e7c8ae3bca176e7c923d40cdbff5f62abdc2bf627e185d8f820fa93abb7e0ff204f5f373f62753bc694174b15ae499cfe769613e18f4bd20b740c467f66acdeb1a7e49c1460f97f64880d025b0047341d4571d457423af7f812a481984af4d639b4f5bddee8b685744e16108b214b0ba9239f7a6859ee2cd15d5ca407a798b676c1816479b39123af4f9ad1c6a6a64fde5fb35ac4ff3461bd3087606d32435367f1abbe3925e362a09b61b4ba79ae73699bf367d9e302e7186e7f2dd894d6277d642126f8a45b8cf22d93d69c43c2325a39da72fad7a28f23666f0197da73e34591da11f87bdca167205eef16403caf6cde8f38aa6d3ee28cf6179c4fbd77c671644e93a7f0c34c69d81dcac5db42a081de5d7df4184c1ddfc365b9f0476f590a90738c22f58f93dd1eb3e2d45abe33c782ea5283324880c998159821f765fb57cdbb791104cb576cce9fbbb997c959f38c293269d1e3d3bb53f71a31b648ce0ac5750c69acee6c390b0934548536c48d20a1735bdb2cf46f3adba5da6ba9790144d3f8c0b9fb5b42e13317643c135def63c962b8c5c21e0bd4e1ed1ed72f24d551132b85b24c2b3e3b4728b19792a39aa4d2c3d8cf951e2842e8e0dba7a2d9262e7fc90ce1c242facdc58191e42039db0e3ad91ebfb1d771265d9df0676ad3d6183693b37b8daf28e64364010329450a1117ca79ff9224df881d739d814f7321c830a5a1687eb4e590e92b0ea63f8fca6edfafe9051d2d29b4dc0ffd9b1f44883f356d3e31530851c993c59aef125b311feef3e29d9cd50c8f4a01bda97c2de48e026cd991d96f7d99058b1e56559289b5ca4f9a8d2ef39bf0b9311dcba7a66c83047bca955e914309d5256e7ee3af28e1fd0ccb64b338c0907e89c0acc516e3839c373a235f17331ae6989967ab821b239298cc8a7bf2f623e325f8289aa1a898e5ac62b02861617e7cdb3748ea34b14d9585533ac7c4ce65792618c01800e8b403c4101713e17aae8d6c3d30343d13fb3a51187abf158ca9a86af469cdeae4ab55fbe9fa773b32aeff735077e00fa63dd668b4b3881661a1c467e0d9b703c8b21167d0769b7bd7f9315fed929852849729d027a8e6acfd56de406ad26cf727b175e26249bb282f9967f7fa374a537c420cfa8aa8581bebae8a81e46ee775a4b93943476d054e0354a1afbee2e08ddf35c27ef7f93227c4582de30d4e8831b9a195ea4f210abadc29e0c24a61a27466c082f811624e1bb5d150e6fb09481fe5520eddebc303633fa397d176d5ffec64cf1659c0b6de51b243d957cd9ee508ef06e81e0b3a49cb9f0f0c8d5255c5b875602f2ece383fa03ba9b3499eba997b9bc241b8c2114b8721eb372b8093fc6515f417be05b73281334a3f0fdede2d174a2a65b898d766c8124a02cf4563daf6eab93333861069cfd6a6e7070340a1ccb1f1464f03ca35c962797c790e8a0c7705f860a6c969ea6c10703f96f1fb8df1ff770f7c5df245666fa56938e7ba972715337d9dfe2ee2df1026980f65570cf49c6217522849c917247050da080d7b2a25b966bbe6909ffc0c37354ef317b7d3be1fdf0ac71a7e17ecc6fecc89bd1eae17e1b0fabbcddd043700e34e801dcd4b4632d9015e174fd00cc59b370c7478de9325e32c2636d76b8cfb341efb6ca01cbe36610b489e8da1564e8ece8bcf72c453155cf90b2e8d000196774efab051630a53db54f7ef83faddc8f179a2a4a11dd994ce3fc2faecebe7965cae3d03fb0231f35f4b605ca2bfe94674054c2bb4e23b696f8ab2601e692e0ae38d8226c59549e8e11c1b1fcf1f7b3e09bae064ef68702bcb024f095b74dd62c41675adc5716e001d534c17f54d5f729f57213cfccbb558b02075bda8598b9438dd036a849fcd9cfa044316370ceda3f144bbe71201280ce7c01f79467704e684f5d1a05d3cfc9e046f45eeeff890fd4f674197e89d4f27b0097dd726fd840527fca0c4a523cb726459a9c1b33716bc57b98eb74bde414edb2c0e34a69ea8431d6c72f3d43a0598507b7c2225133aed3c24f7394ddf4a7d357fdd70ed30ebefd2d5acfbee47e503b4a4a5d20b61c308ec03e2b68e2c1706f82c4633ff286dd9322c72450defe7bcb95b7b0a089aee84a19b4a967560a17953df5e21323a133307f21e9526d9c22275553a0dfe73232612641f91541a87adf9c8c03f891a95e65b5c74c2cf77eaa87935872239737427219d54135d0a6769fecc3a3405dce930c9a72361bf7184109a390d8054cd6e19a6ca5ba4efe625fe6dc08c0066d3682a4160445b83884b643a4bbb4d9bc31c0b1f592daa9437a6655626ae2841319e768aea9be59bf41f0ba1a0cbf6f22317d5cd320f6c563fd54b5185d83c0f24ccd7cdaa98f5ca0991192eeba6586546b8fc99909b68e553ade3f9ff8176d61a58c9c6cde0366a77a27fdbbfe9507b99c1a8f2853b086bc5126039a1f8e6dbae2d921dbbe35271000c7c780a539508e8d4138716a68f4772c5dab73b0e4ecbe43a02955db2b4898ddc045c35a8898a468e160ee1e5a027936d2912c7f9c7cc33007cfced7590a556b84b7b2e886d2af13390fe98ad95ebb58a06a73fb362cb9fc74e719bd9b3978d9b9fe283eb0e6c350ee32ef845dc1df7b14e3950624060b34ea91a510b7f4059833748a45424b815651b8007a5962e9ba6f80521c74f48b056d1d225c8f4e2b4396d6e1c003eecf518ceee1b5cee2ebd6fae1eb97110291de7121d6d4ded74dbe983131dd2c19163b78497ab40204b7fada344d16fa3f988a150367e36e59166daf16f5133521cf2a8e6e9176ba539dd736b93e4dfef4e2bb05a66ea2a76a7d9714f9e9805d242924231d3944e39d1fe0f47e3c97388d6ed61bfcb7a01adb10dd68e08499909cb8fc3439aca575635a1870dc9745dac22a4c889af0326431b261e48129d41a969def3ba88640bff6994f4ef630929836f5f466196cb179b0c53e3507a3ef53f9f680e03a7f8d02958717c25adedafb79c0402f30f2fb51d06d5991d527d49f30cc403b5b562dfa07b09d5a82ab7ce297ca5dd7d1f20e4008dabb7250a875aad6cf220eca470d433cd9041f0bdaab92959757fd1f54e4a57234b3b2a67c93253349e03c2e1c5bf4218de198959f0514c74796c14f10642e6acdf7d0cb1e639c834139ac51f64a57494ff721cc743105080d336b79f5ddc1809e11a01f37f733e7a9385296b835ac8d9b93a1d29439d9dadaf47947ad5f4b791cb1e2a0db64f37858b185897d5795d58d6e767e8767138ab0e48940aece613442cff5e88c3348be828c7acf5442373b540e6993e3e2b1bb4e6195c377eb8d5adaf2fc488f835073a942c06ea66140b9ef2b5d986de82da92678c90b0f01710d5c0afcc7081e867443f21f657f639dec209d25f5c88895276b8bad8db9a9cec6abb69a94acc24dd4ff2fdc8b2163e05b694589373f76557dca1f440343db0996951db0b62a4325389ce108b2eca40f381845e97886f98fc47f2061e19a72a6873b75e89a746ee849fe88a7d87a2096f345ff46b75ceb9d725fe742b22b9a4ce8de1ce94b3e9bd4832d008f52a538aeffd5d8cb5a083d74fa73a5da89a88606242162ccb4ae7751b2a9db6d9851b7edd716bf8cdc4f35851b4dba88f2cb72f78ba9b774bce747d2e9c0143f356627fcf797e1cacebd606bd67cad17ab82462b8227bb940c93c9be6733dbad8759529f2f3c778d51d52892e8b57cfef398223c0469805dcc70173aded3f0d80d06b46708fcb3d1e9a5016c4fdcc4cb308d484a4298ae4ea2787bf56cf3317d2a52373ba6d3bba51f94e9d3c7d91ac20ee9d2e2f0762adaab2a9597e95c1bea497b399c1652c21e29535c86de233c2b76e75c3228294b4fbbdd27d4443c3d859a49f3688bf3ed2dadaafe03f620105f95563428906c60d1e85a2bfe35c906cf88de37ba663ad6b24a38d79daf0893f98ce938681898a01f9a5848cdc28a8db742b0f0ae1f7e60d8cc69201cfd11a9575eebd32e4283b025bf6f4fe42598eb87ade9168c03b00dc0511d42660f1fc372760bc45296af0fabe25fc5c4a6dc284bdb04980acec835b9752c3fbbf0e4a04e9a8cabf7f92c750eddc851a36e51eb0197af0d95c29b9701b2464f371421e02ad70c09de3e7fd0a51cf963ad72ba24eed1f9cfefb0128fdc683592c4147109c2ca34596de8eb201701113f66793d8e346c56ed0b8b8f5f970a51f4b9e55de4e69477a6adfd26081a36403c6005e0faeb39cfbbd3d0292fc12af363ca3673e4ad582c7343c44f481cf71032fc3df31f8f106cf0c32c1feda25580e106036759236f44145e7bb80df6921d42f5d61a6c5072f1fa9a590ce2b713fbe281dd4814950bc6501c86c81077e7ef6ed078e87ae5b65a7dca8b8a8446c7773c691b09f6eefdea74a3f27e278b6b3ddfff3676babcd7e14426db904baafc5b8e2f4142c29f002f7b99579db3376c76768e2744f32e9d124923ff4425730f1c33f5257d77c6d169426ecd193704e6b16a23789dc7a5339a0f06b8d1849e8e7c2e20b71827a7696dd6e127965090277b4ed0d4f531cbc6db5a4fe23a57d4d1b7889646aa17c57d09e6c82d952cc77bac2f95609ff2e0827f01889509fc3aa4f3f92356b88906c09ef7ed4ba14717ff5909a17e39c5a3f9a76e2e59a76f0b455c5264b8628819ea696e7f6a6c10653c33dc6174e743af69953db14c0c12f6971f53c360983f08b37fa172576ee4447925caffb73d251c608dd1808c1b0bf49be9af4c6a5e28e0d61aaa0de2716f8249eeab0df7fbe613963e0ad47e8278068261a5008a30e35e97fd8c163bb9069009b75270c6f1ea0f7f7f717c7050e2b4b527883a6bdc4d82dbaf4238c02b11c8224c2cfd1ff1c254c83aa7a609b17073dc44ce0eef2e3ac4b34d1775fd987587f6f86e976f4c8340a1d169b8ed0bd36dce82170a617af37480b411d1928fc5618d300846707208ae043b219d0c98594129896d7af687d6b2e9c321fd1485cfb3c88d08cc94c3fdb8d4dc8aa2c8fc53927c1556b811e420c7a6cf85211375861750ec0fc1bdd63d12680ee8ee7f2bd840ddfb94781ded47cb65576fef85b6026d646e7a8a01ccf8969ba185114a15dc4e0d382768c9d33c54aec2c3e60809285102a6984b425f06bf5792cbcd01707d0096a0806ba71451a4280576b8206b3f59994cca899e83e6033334e6807fe44795b0b701b132b4f8f8c217e6e7d05fbf1c3ff1c376ef209ef750052441726d469051e3f76278ae33ac339dc4f834905aecf2c343eb41c7b65316db84f38c313da311ecb8f1ce92d0f9a4963930db32b06c5f2ed17a3e154a651ccaa2a18ca8e1c37de74f638d7b32831f9a7b99b0ebf1ffadf9a1a48c956fcfad4e6d62759cb9ecc77db01b32966e9cef2732462fd808458d4656c5d60aa132c13481e8c0738a7ef0df043258d536c7b65e3fbbdb63d04845b26d88fefaafcfbcc5e995692dd5898cebfa9b1e8df3fa1541c9a3a59925ef9de2599b4b5e22168c667914d54a83f9abb9c8e3d3f29c53d2669eda131ffdfd0f5d33aa0ea411e9b10bcac907f08e556bfa192e53f18704dd25cdbf57d0cfd56c4c8f53fb1c6e5b910942f63c7b05f759a36959e49142c3d0e8a15508d36c270e7e7a90a852caab4c38f19f382b7ecaf5ea0eb286913d88e2190161df00d8548f40c14a0a0703a9fe5b4257b3b2e1a9c117972c4e9eadb3e77067bcdc23770eafa5dbf5b3cf3cda2bfca33aaee8e6edc1890a2f47fbd4f2339ce6978e71927be3c14cb8cad79ae8b93cdd31afce5a0f33865a5ad2b3142aa8d49056a0993360420f79890c18853da107698716c03a4f97a700ae7a175ba7e53d22313a8e1b293af21cd1f49f3b64a01c1c230b3038bbb4fe9c3928debc20c7d06b34d02599eb0152170be1b0cf78a3e0f2561c673c52ab8a692c3658a815523ebd4852305f25870a56ae78f3097831ffa48b24ec4cb7dea64730855cc4d8da902a82b783ed375bc0d8b5f12609e51861cdd9676bd437a856e0ceb8f177ed7899788f8d81d260a8bd99c7978edc2522149f8704b47602b06c2c71709093e3130af1dd5ac31458c8dc2b555b7ead7884e81d020c0184b97ed0bde2ab883f41f1a9522abb3590001c9a56f7fc1438c004afc4cf757e96037987b1d8204b12c228859e0566d25b78bb8b9e4cddc4bd134e6908d19e7faeb520d569af7bfd47005e6d28804ef45d2e2f956242e46bd8d7d4e63b0ddbb338e97102cf6a31a00f43fb423f32511e03208d5898bbcb609228cff30d2a741e8c1fb7b1238e1a70d5cd6a65faf4f8dc09e67ec72fbcd4a44011247806dfcb19d9aa28e0050feadeef81a77ba2886e1bad17dda45f9b3128e996477047242831aa6b062e19714410d34bbf56870e8e6fcb639412aa7d56c16107226445aea998a1d6b17b78daa049daabe5af5ec3def7c5630c1d81ad5f5ccf88f952a0cbe8ff7f0e830ac6452ab895cd5b0bbbea8b9a3771cb4132a4ea2d46aa9d5a56aa2f16967353a8667f434b1b4982265293345021603b08043254cc5818b4ef47cf966b58cd887309dcfbd44bae64a1bd11800f5c7888fa25c6848cef486afef8801b781e0e5cf35c0d9bc75df21b2b01e36d266d9bd12ee6e78ce1701d9060a7e22854e3346cccf2cede0011cf811656af4ea236b404d582b9502e073430359740c1b7a754eeab62856d6b05e59a89d4175ee897033486f5a9f54ac8224fc4879f6415e6d60f8ebb27c515b66b32ff4d6eefe4ce1998df2d311057a20827b93583fb0679754b8dbcf5a02f1d8476f83e554a56108e790ff42d2415b5798e5bff49438d817c75cc1ff14e493937dd202a6eb5288eb4502942468ce263c38387c049a882d7bd650bdbdb1e37f6b5f9f49e45c98433006d8d3012d3b7d3eaee9e2dfe0801442422f3d52910c57d0aa659e7d74b86d1a8ce5e2ff058c2cbbc2acb486889059b47dd56dbc56d4d82d7f36f73e04967ed2e2f33d9930916ca61ff84186a75cd681faea0025d0e6dc5e74933bba4a456b6ebed44be1493f0cefccf5280d6e9409a50644db6260cb56ee34dac32d82cea27c1080f2cf7a8b024a9163b31ad0ec3cf5adfce3b1a20441466857b5933af892590f36d399170a0915f449540187c144dd6b2533f7bcc8dd1453dc897264c7e6b265f91dc8755936f2a71aa73fe3c507a151aa73d9f4c899454ee2e48cd0efb595a4b5cf4b06dfe53d93ed258658e923d028a848f78b6efe19f4b82495e75af0e83c245e03dcf5422839d7f17284aa4b8372901ec0c76270d716884229cb438fd68cf8d310e15233ef05caf6824d813d2c4e8ea0b271a91510300205852b7999eb31e9d9539e948b0adb9a1ec2765c1a200d3331b1d16d86acde99e0f9ff258140c4a21ccb797bf3852f9a262a092dac71e7fb10a6dafa62a137fa0b4e6046b95e74f290e472b4ed128c469af02e5bfd9f76a849ba8e626f1264f49267ac98bca78b33c874b663dfad99c03e86b9b1eb42bbcdd082dd096c192095065b1ad352dd38bbd3ee2f15f57543216cd83243667ce1d6757b1857f87e9a53f432d8d73b8560e422002d2f248ed9a6da5bd0efefb18931391fe11f3887949ab74174ae4f63d4655088510de14a11fe75b05a69604e71e2ae2867721ce0d94bd13c2a4dea1a207698fa09c5f93e54d597f45a39b993c30fa7c5bfd8ee04e2e1279966cf1ade392235c3feeef7494eb3cbe924b86a208b76b8d5df7b5a0a0126aeb80c2668a6e69855a65c9a54d237320a83452db48f5b56e7e99d52cc489621293db97ebadd18927eef08fab049eba40a6afbde873c128690c1a0bf27a1f0fc1749c4845edcbfad448a5f10538d94b99d0e4a21fa8f168ce8b59312027a8c605ed260c86b941ccb0ca5760c8ea20c4e73973cb6763f8cd6adb0d21e915f2d5b46b9be790d14bbd1b17c26a69bfc89d05e17524a63e26b66d346d80dd0028b6a84fb2092e04491a2fb92433d7daeeedaf0a65c579aba4902b0b818abe65fc3862ff53c2ee59cf78cdf1362b6cf2404d44986357383a6785a99a0c1303b33e7012a384cdd4f6b82ad6b126376e23b12428ca970610c0f8c4eed85779a497cf7180aa2d718e43fe29ee097824c493c74f7ac2aaf1ae9a8dcc5131ff440b0eef4c082953818d07f142425c21d315d04846e9febdff943d2852e98f64527225a005f93d114d9a6a434b9f5ea39b0e9d7363bc958b7b660eded3c3165844f32de7a3cdea25a7bef81651d11f71362c87a729e5f71fc964cd4ea91a7ab8cb16e71a1b7224f9760679c033471a2ef5627db9ba9c8659122e5570e9ca2b68c7912662714b1a58de8684634d871059c2d4efa3dbb9a5cb17fd3a229e1ea4c06478dde8eccaddce1a5db638a9e86462423b54551d79b8bb83b5f23e8dee259c31ca2e9ef9e37d67c30b5eeca6cced2b20ee70cdba8d94da75253a374377880e4cc541a51c3885e8226dc0e9dc962d7de3808d6e22e7fbc41b33c51992416c26ca10a7e582bfcbcc39e85c09a2bd5ce1120c86c4c83fc6f4409ce5e69c9d6296af30e5544b667187b74dc871e4d6f3eb15a6a520bd6ecb4d89de9cc8e1b3c6f00a71e56d72532b7039ad678f8d3cb953fdfa55b739438bcf458455a5fdd3c8ff222ef390f25544e0aa4c623e64dadc8ac7269c245c3813d631aa1d71a8dd71e28ac8d6202f917eaa6636e9b15f154c183bd0c30a5389f2e044ea59ef2fe8f044a817c787e4e164b80e0fb85147232d07c9fc709e7f1201b6b5b2d4a7991c0783582f7327f774aac047ade8e762d9711b32317865b2e12900d04015e456d04cd69608bd8ab87f58509d30f5cb525ef6b3fd95a15b81954a6158c056fedccccc9f2ccf4d7da0a36fffb52ce8088924f6cada4221558ffbfe989ce6f15a86101de21b957f724f4c43d987d1014c4a09d1794020c25334390402f87c85c9228c57ed5b23e60d8e05922d841435aab4adf90af8cc50a85e5457b860bd94a89b2d5dac9d26481970d418e93485504af79a7f722079fe7adb7f9909acfd2c2486be3467b9c20e22765150c7df88ff349c0a4f01fc25cbcb154ed9db4344bbbb263e82c8f47f766699443c14fd119ae33f01ecfe376a8465f14429be8e0e50de3c0d6ab0bc41b2f21409d0d692a5edf5c389255df898b8ecad00c0a05e430db5700b7c53a48465338e1f2b1d354c368a6972393e7426ec0ce71d9f13a34c1a143abde9d56ac03aca9067981e95c5cbf1f0d2e8c44a391d284c473b76b5423fcbfb40890ee5ce59c9e9a69941638d032ee25f68ee14243b30c555ebb23d30a8ae183de6793cd940bb4aabd2a2605e3686186f034d151989328321c4848a3dcb59603f3b4fd831294fd5d57b41a4a00ac4af6ba854ef740a90fb98bf17b0acb5f1e16fa9a7cec16773987db4d902a7ecdd7bf830aaeca7f88cdbaad3584217bbcb190107863ae83a4c8f91c6f26232e3dd5bfca0e27c2b8212deceab7a76f93c8e12622e5b9ddc145503b9a07c84afa6366be899eb84ed3ed700e33e10199e6988fb03c807860ead1fafd836dbd611615dbc0c6902a8b9da2e0a8b1946ea560e701ab8cd758c71fb86a8f0ef7e3142f5c30f54e7708602af30fc9351ece9abeb424b5d7d93bd8bbc644fb1fe77f06a231823fc1d0ad7d009ce6487038677eadabc8027a12d3daea30ff5ccee13335f436d3684e3cddfd7ec1f101c99faad0bd6907119807320e565ed631f55a4a2b8f665ef22b7f3b05b8aba53990aff6af90c708af3850d2e1b6160ba7ab26274524b2c34146f4464f7f323c9849f2692085e5012f049d9aa55fd6455604c50821a3dbf4c8f86e3eba9edf6f57ccc190fcdbddb2b3de762919f6482b99e3f2e5f07e56b42ad7c7b67821c056a12b140789afb13480ac26b736e8228c2e5204b3a026f6d1d70e53e8beaf84127ff8e4391aae8175051af814e1fae2809f74d6ef63f5218e9714e9ccbdf55df79c67901387b124fe5f9ebaf87867f8ae0770f628e9b782ac44af07e8d022ec7c493a3fe68af86548dd0915205f91b821a3f3b517908a30125d15651a8f0102bb385cdc953d7749209e8205e895abe8fe6b783feff47773e40c54e08ad4286ec7d3069f500eb2ff89b8ff119b960972f0fa3d8bdce99de63d67e83bdaedbd9265324d42a19069b25295454d68216ad6378ef6d74c24c84e3852c9eed5b4984b3714aa8530b90a569b7a25db707400e8edb2d69eb02af2d77abce0ebb81b34452f83a79e39db4d437305244f2a00d37aa426b026f915579ded734df4ab05e866a5f991924d99e7973bfdf8deeb95f4d7db1b546cbcb4e8f902940108b9028f39b765b40ea267ef9116fcb0bd15a726e88c57afb20a04374b345852a61b2d7f91d34dd7e538eb960b07d8a7b6380c11134a725edfe2831ed32c082cdf6681bfcfce5f5bb4312497dda084a14bc701e0e2bb4dd59362ded197b79ca3bd05dc82312994c32d5c780c3dd540c459393e486ed2a0dfa64e527efb409306bf4ba07df44b9d4eb9bf4c68a11ce0eba44d5bb7b84564a4808fe577b2f7ba623e5b26259ae1ec153df434dd2213a4696199f49fddda29396e2b995d4a2ec95c7688cea704cb4461bd6d7d768d0e7d575caf798880c3245fce2f2ae2644e872796ccabead5e2844c5eec1cb1ae25130d3a1e4dbf53b7d5b9d967692e03228fdf5c6a433d5ddc30969795c8c1532dd8c5efb7e986a255d4fdbda5ec8c4d34a0149cf4418cc3ac92b8b8d2cd26afd1ff4e5c388c54f8570b4a0093aeaf4c451259a8552c7aae62a0ca2150f9645487fa65e920ec7e9222e35a249528ff97a8ce591006abb1ae46aff6a66212426a7a7c7fa2632d8a615e1ebd97389eeaf3b1e49139449d561546f6562dc6594ac29bb802932a77696d07475506f6e2d4c495e0d012cea5c988467b9478e335f47658a24bb3614e23cb97888a5bc4ca79f77991f38e4ed47a0776a71f681b89f65a03bd2271a58935d5ccaced5e84d23e92eb4ee5424da7b999037f8cd0457edfb6cbbfc01e7b22f5c759b2d3a3faa7d430066e3889af9c8a1320a1431aa8ec2ae99ca7a3471f1e27a88b02ec30a6e9d89396984aee9b90bcab24fa113922368f39be1aa459c0ce146739e040e33448730934c450f865477fc9afe75e0d1ee9d683f7906b3fad5d629a0487df8363b7a4b0a6c60cd913cfa21b8f178fb76d7391931f4336e6a7a72e49217154a14a9c4beab3df92927a3a3d884a2849714f35caf6921c04c93b40f91eb50208b91eb092976d4f1cef86772e6862a2b0c6db43294da4ada36168d57a48c163ace4119c7968b794c9f037202c9b23e1f7743af3b93f42ff8ecbb8d1c476517237c3501c17bea11bd8d43970397d6cc931b9bfe502a08c63861b2aec98635a6c3964dcc20995431b5be09b4430531f94e152b7d29a87c50d833a6564d2eeeba3a9177b258a4d974e2bc54f108401b1bd015c9561191e2b5f44aca28bac2aba83bd96adafb6738beef9ef5a7bc1c65a3bc4f1572a5f88365db867e40cc66eef5c4fba895b6ff2abdd18585c22fc6bbd7751b1c15f93e1f3f008e8ba398d842dc908950d0aa730eb4b7f36f820f5e308e6f0967605d1ddaceb347b01e2869244ffb6caea27b0ee445aaa3b170a6c6a29f0acaf90472085431bf4a1394ac4206752918efe986657b88086cb73bd25b3f9c3ac8bbe0bcd80b9185d9bfde25cabfc3dee624cb15b5e1e9efa3237b2d698b191065a5c64c6e2749caafab2cbd83bf58c3d3b007870035da3b27ee3de5eb1320f14bfc71bd12c14cbf24608674beebfab1b78dd43131eaff322a6aa4b7ff789abf2a443a0ec8185de967de6602e747d56a25179a7a46c9d7221811c2ee84455120213363e42f48801c87199af89bc23842b9e0dbdfc400c11b8271ba2e961cfd1927e7130d57255aa09fbc571b71eab1d3eef0a7a20e99937800f95e90c4732bc010a23e6bfbc83be8d6c6d24f3e242daa791ed8edae75aff49eebe56cc466855c0a37eb559c960d22daf9dff46b9588779d6c5f15e77ed93a61a0469bbd9f621e665e81d7740c40c1ce1e3838388a2b490a26c2d0ca44ee66f299fd1f3c9ca845c8d4034a77ad71392693d1db7e52cd40865bb087c5fdbae1111230b7109ea512046a8efb0508944b8bcbc61ac900b6639e653fe0953e1846c9a1a16c6fbee150ebb29f4a7b40a2fbaa148389d2f19868342e08f8e7b6db4552ffa01e5b59cb0545de89f886e7ab81891604dd3dff6d000a67cfc3058bf93cb7cb911773cf9982fc5d70e8b69afcfe44c8a211261783ffec1eb1c9c3ff69933b47637654ce80d19573e0f50f313e93f6279200a6a43e92f09ed07c520c38eb65b59e5a3f33e72df834817ae3e537a66c9eb3b3633b350e84ce48903868462327dd7aecca9eb2bba5d31385ca886bfd7de7f41df7a8ebc4cf0a3e5d4fec0e88f8b60f9f5b865e6086b9f1771573e803692d62a879659b6ee901eba7df155836d81aed46edf41f773cf97065fe39811410b500e11b95029a587de68f41ccb6eaab073591ae2dd51bc452ce1046b620db77d514d49f5ba3cec965de3f192e1dd075c932db69db18d3e182ff9b861a87d5d9fcb4a9a2ccc2f69afa4b4dda074325dd9521fd5c649423cef7e90b941e13b246dbda6dfee2ba7d74c2873ff8ff7ba4f6fb7118653818da23807c3cb58496bb7eba41b9fb29c88efbc11e401b9864e2fb26759244a178f93d3bdd9d8415177b88e381621405b1b56673d2588a5e379c0c5f893094eb85f6ba7cad3b416ac4f7f3dcca226d2c6612156d95577a4c9eedf856e4b2bffdad3a691a316ca737e2de7c8eba72058f286318bdbc4f1affc4bc6907142b760cb2b4c38d3c481e438b5585dc031da08df2d402a063188ba023307cb659c3ba4d176c90ed5297638f2806d0b7c15d7914544e2410e997936f314cb711807a28ea5027d5edff77358d702201e2cecc0ddb8167d324affcf62a5102d7fc2ffcfdf3e6fc714f6e64ef94634ffcb7484b369e5202d9b9dafa8ddd6dcfc018e0032ed7e831a5ffbf68fe50795ffb18599e8bfad8533a4dd5434714b60a643ed755f9553ff3da31879c913d8e1460c40d3afc2ef0f2337eebb51046a5c5782cb3b4ea1829505bb4d0f71d8c6f3d973a18061fda8818b7d43a468ac76182b115dea915cc4bc9ba8ae9e9ff20cb7204a6f59b660de3cad46c721c6d21c0656b09748dd6ff3ecb9b40b3f42017889fa8589f07b4f1add624adf0a3b4168211c7eb69fa2c984c8335993951cfec584669b509282cf0da2578e5a295765545df2fbf010df5e9f2fd0f23f1a7dd338af16253960116be58506404352a76cc277ff20de6c2930a4d718e1e08132f55ced55dc108d891e289ee3372c7914f3b3196fb92d9c9b030e78d238d89c8a4afb53c19b017f76628f56413f20cc2fec27b0b701e35a70e4118ace980f17507748c40acce46c15b193f160fb9755554041a59336370f4e4ab8dd64f96a5db80a82ae146e906fd54d1c469526489dfc7ce98f61c0d87191bd0fe6afea19af11f593a9569aeda554c84eb6ea8d343f6d487c5b6582987a1232eb4ab5873ecf8e798bbd7a681d71817737f7bb0ad30d09501729f3c38cd1fbb28764442923054c3c8b9d15449f12a8bc7397c0e08a286717f5c5aef47464baeeba35d6571c373ffdaeaa3775b20123a9ee8449743384c19559f66c8c2f1519d7e7debaeb468a62775722ff83e6aa5736fb3b286ce39ce78d2065ecf6ce0cd825960050b38c3673f7dd331309ef58e3e6910ff95c9ae77fab09c3194c8d0a3d2ca26944197d72be4257069bf7db7f8a8de2b4f5372bd301f6e9b983dfd53e4366b249a46338e53eefdc6808e5bf8b40e5f3213ff3732a604218287cfbf90707f38649eea91c33939e97df65b9e780ee323f197e0c017833caedf906a4dd5abd78da4ee5ce7610f3ec3440fba4bb75c3e107ca2ed62e7829fec497ebc517a4ba79e454476012079c506ba63c6c5ad857f275535978d3673ceb516246921e02c2a50f8ccc738fa00aed04443fe9033520ffa9f29691b9604f98734c131de7245de5e11645f67c8a279b79401ab42a4498f14bdbb700ce1ecb65aeb758d961234d96a723157c4f3c580e819ad6f1629c312281e2fc1e209052462a8ff4dba8d5e95a96f72f0d37023ee258daaff063a74ce1e9f9c94982823f2a06430291c5732035b2f41859db9053618c0cd819812baf24a4bc1c30e403b0e17fe023ff9a1f3152f38ccad89b184ace9c55bd058feaf22a688c5492ca6efc9b662fe8873602b9163e50d32a95fe068879aadf4d519578ada2c4f2f843bbb6aba9f495fedbaacc8c510028ecbd8057b11bce51df905f105edfcca99a0cc56640744d2bed56e6af24f156424604dc3446d4e65a490df4924a3e3739fe14997f7179d751c1778d64fd9eb33a9c3ed7ba75ba393d934c7df6cb3bf50e7dc1cf027ff41e58eff482a72fa9200bf519a3f4b254ba1b99b5e5ccd7d7aa3655a28942276f20225b8b9c3d795714e810956f99800ab8c22a132087a4720417483f70f82128a0cc6fb60f7c7e715b9019d52268ae0d3159d285476bbb820126252148e3f0153fb05ed1c5271579537a642375cff96093b474c2dddd3fd2f62add7cbfa6244ece16af0d684fb27970ab876351213adda83b2ef14b8e80150e899d0059e9d0e937aaee8a6a4553c123ac6bc6d033d6973ac00382d18aae8860a569a79951eb80bd63d6aedfcf111d54a2dbec00f780f9354eea3f9848f878cb8f1877fca5df335814306bc50871fbdb10f8dee9929d395f926f72f13f32aed65d5b1888b8aa0f4fca8f950e1ddee060a0a03fb95bd8147534879c5d101f5ab8adeef2f9e5f74e435cb82cad2e562200aeedaa696ebe0273833b641e4ec94527bcb0e6dd2e21bb38afa47b37a5e83d105de2576912e27023419ad26055ae4109839186e62bb363122cae18298d689c432500f3127b17afedbd5042aa59fbe33da99f791f58ac38b724680ed2499c99546dcba7a910ae8545c1cda4912447b79695ed92b3caead5091129d06bfb3c411309c289a2411a06b51913972dbed7b5e93282882a19396366c19fc22d205324dbef03d7d7ca51630eb4b689a4d77231f8f780b01630cfab9dfda1507b0d54379e2b06540305b2fcd6bb7ccc1f3d32976a1dbb64c9b22bd003ce73ab457a1805e28f9910ebbeca99ec8aec167877d14c59369a55d9b234caf341efd2dab466af1a6d9a17ceff2af860b7fddf8da9d9699e7c407c29606331e2f0092481d27dad3ad99bdd66b0593ec878ac554095e16c49eb95ed3e027c287cb4cec09b8dee4967ac3e82723546140853f6030dc18a4dd1050bad68dd0235a7a21aa8abe13c1b21a5f5686bf921c0c96a37937cd2c043ae366c3305f810b3299d2568697c19871f9313be685d18a317a3d2d076039f062fa99c8e88b0af2409e04b69d0e03c086164722cf4448809fd3a6c99aa00cf1b26e836d89e6ef743d8aab0edfddb1b114d4f0680b5df01336e2f0dd08f2e5613dcd899c581b8f18883d2df31835314dda64e66bf31e4e21e20102e75286399e9be7da216fb061e93a721e4230325f656964694caf457b803fbb5bb1f16a90e5a9481429bf5e7687dc64fbf6fc2b840cf576928f1710688aa86dd07f2194feafbb756c321a97c076857cfd8717cebf0befe66cbd52a92c6e7aaeb07a34c17f493608de5a7b650aba9cd3cdee7a4866e68b0c3a1a7ad8310f0f71a3a17a33ea170da3038cac0d843e51e6aa347a1cec85cde9c34d2c2c9fdf1bbe991afa1639ca21f5b292fc877ef8aafb201d2f799232db0b2150564776dd5cf198ce73ebc5941b0fd4b248363c8d2f41ce1f314302bd21c12645ae3832e8acf6aab908d35d6f2a50bb2faf666d2b161cac48c5aefb04bec0fadbf7f1b928914461f0b6e829ffa5642f07849bcfd576804caf94a7d2b21466be161f5dfeef7cacc15176f30771c53b1cd4aa2d2c57af7d82b88ef99d8aca9499a4e2fd8e2c894da59ba8532c75c4764b281777bb1db7111c3c07926b3ba5566970ddb69779b9873b866e931deff48af09db150c68fd99f5bf0f4ae4ff9ac4c2b929c41d1f7f21504cb049b2474991b758af5c34c1b2edfee14b41e1b26253668d9cf905f095e8ed761f308016fd4f4d4da1e390339ffb0bc9d0024714fdb5b359787070eaccdc4b7aa422aba625d1fa704bedb524bb3a770d987ebf2cf7eddd705f5c1f251dc1db4bde4d79b326409a4dd9154cee681277ca0e928f2a3e94703fbe638af05830e82ef516e6aafd2c41f6d30ba0fa6e6d2a1b1dd6eec499907fd1882727a7a58d096c700600fc4abedadd7089fc1f2c9c0d9a24b54e5a84cda9af9fa162e947663f1729343f1aff70da6fa32399df720f123e8bc59ce04029b46f2dbc434a678471ce5c756acafc805363d288988dfeae008d2ebf93413a5ef6f36814c072955fb405b7f573c68aead9933cdfbe9c55c3c9fcf1eab71a32a1bd28960aa9e349d552a234ffd6a68176a4d954aa4aff26c18ed2aec2fcb67e8c04b4d09e847ac0526110dbfe66c22d2bd750009a0f690a077f3f6121a02691bc71694ef1bae6f2faf5eeb1dec57096b5aab38f835512713dad58a63c37094347828f8a723ce518b0ab9f43cec26fb205153f1a1db7fadd8fed1a4b71e984a9f08ac806a9a54012bfbab680f91688166d8c3f1dd89c945caa26415820dcb7e75e5b38e1be1251baedd6efd71d796e799e9bb76f2d5992faf0f985fc6a3c7b8f63f195115fe3dd7fe5b984c75f9520eb143f6b1b901d0c326ee82b41fa43cb26f985ebf3e1ca4df19ae5f41c99533bd69ce1c887360553bb94d4f90df3e5da1a2a95196157d8e6b3c8e8b50dd2d0cf62cfe1702a35c2ebf717379d23269035d7a4108b10af44588bacce9a7af9721e62c94e824cdd9da7fc9951ff314b47e6d01edf36053927d7427a83c3c14c022c563fa7239a7f62ce4f4263ae6cd5f5c6c0d03c39c623dccb9bbf4462897c60d381c6dd967cc9a072f5aaf5424103fc48ea4be48bffb8f1d35075876d9a19bd3430bdebe8702cb959267afb05afaaade1839a83e3403bb466c2df65dedf1846fcb61c694376d039c577612e08b5cf248afc47f832e998ac53bc5eeaa5621f6836418a0195bdb49fb311bd5bdf96b1019fc92f1cdbb6c06eadf2e60c6a41fd82c2cb9ad598d193eaebca48195b0ae1c0d420bb7565714af4b16b58d5c00c59b1411dd5e9b23329bb833f2a4e3b9e6727fef2ed428570f3872aba6ab27684cdd0eb57306d994f839cb9bd9349b0233925c6fab33b0943cdf3fe1adde08a2a523d0a38d6c09568bb3f3ecfc53cb8b2c4250d49f6cfa8cd781c7216021817128b8942e571ca91dbfd0808fe41f2d38c17f09aa31ecd58fa2bdf402f8d1dd8a9b70acc2260c62bf645632e6fa4eb48b2fd370f655ba0923f07f28cbfa53de348ccd572dbaaef087f42a1fcb7d30dee2d3d8875bae777e4ccc3703312fa6789a7309198588265ac3e9485b04f94c9b60314c330c99241a7f2b62422ea09b9dcf3bf425aaeb4d826a574ce1d643636d3fab6aa352df1d86ab6a819e99fe1420ccea814880ce790b804db5b0906e249a39cdefc9d14e5d3e4a75051d8f86d7abae7e119eb5fd92f8d4f22f37638379d89d3a99d99081fd1d24388565756818ced103c5270ec40825e8fb3ba3fccdb8ac7637314e928f10098050c7563f59241c904db626e76c3919f6089626bdf0c21ab699e8cc972f9f5c369a55e532ba7bf7e66d2ae4a85e2d87ea09581ac0256d52c3e569e2ab7ac4159a7cde4bb22517942635739b8077e2dfc0813dd14176240ca6ccc408692129d3c3814293a390e7f8a32e85eab808e8c3f5f09e296f6b9ac93e237b5d86e9df942e5e4d16d886ea7ad55471c8402701cbc472570c7c3a6df8ab7eb1c7470760b87deb93b303c62ac397f4dec0b165d8dcb846beec29bd8c5bc0ecf1c1fdff443d813fdfe4871daa010a4715a5e4b52364395f8738937f2495011cb0eb67b616c2ba6549a03d7dd5943da10a77a84c1551df3827976f5010e0198a19d99ef687200b12ea5f6d89ad91bcc7afed45c3f8b7532956d1523d7a3b6a59480dd5e71c3706b5673266955734deebd40df00feb40a6595f6e32021ec119cc6c73a11f2576a68ffdedbb84aded4ac2781341f35e534066ed0e6852610695067ca0920b4101996bf7d3d530945f326887111b553a1f10a78311f654a8cbe4e9a1edc6db67850aaa2a17ce27fa9515b0eee0ef307b1536023eb87b69f3acceb2fb50ed427c64266fbe45d2db016cc00bb23f2709a1449cd8eedbd0496bab03b7a0c18a91b85c30d8e7c0b4d4280496a69d05a18e2173596f203b4d5510b7274de6d10f29a4fe828e280b01a4983377d8746653cfdf250ea35cc7680d87bf4aafca198767ab21208e7eba06ec0c6e77aa5f841f8aad34624ff989d9af4e6cc494c2969ffb922b94592969ce9152fcd5a947b5150c1033cb9d7e51415290847f9a99ebed5104918cb05756de8e545f3f15e4bb030ae7ae9ded8702f297d3e32cc84a580459e082f952ef6dd08bac47271976c92de4b52f10c8bc282dfc375803f31e8f0336390afb0d3e44830a7cd916fdae33b1c6c032aef49ee7e2d7d8ee0d80b2f4282e030bd2a5bd4a96e39845446c2fdb2f3dd85666727bfd61c38db86a1739922f853b706ab8509be785a1c5564e7ff19d8cbc3b46fe5a92a8ec5e44ddf38679b4fb4ae80961676371e16a487c15de3bd59f6348077e29d6685c3408d7ec8469f33842f1043045747d8c13b375442133855cb3de183255d9aa2cc4ac1fe50d1100bc8893c637307249b5533064bb0b3ea31c651f702344ac91d0a0964ae39e39128a8e28e2ddcdcee3712a2bc184674de92ef0d290c4c0292de47b5d587aa1a5e2777b61e7357940a6fb3c6f7cc631e548ced93e02c810f9a8ccdc9481cfb8a75e94df819fc4949c0d50968ea84f1afc98db0db99f9470c7eb2b62a21951e8cb45b8d7fc44567724a67c9f840323c08e6fc57291906ad2411f1d9e1925aee0996e138b22ab46b1c1f87da180958d1461e84bfc6e7c75c376b6f470e2131806c8feb0f98ad6dccf537ae276631d7cd7deb20d8d4ddab3198f9f3a9fbc588c69fd1c4d17693d3fd9bee6cbeeb833aff4c9c705c9f6a1120193a229e8e4580f3fd9bda2cdef1842fe146bf736c9a939b6ce6cacfa62d0ef5350611403e9bb7d2a03c7530e6ced72650fb4b8abe0eaf13cbd1de378f60c3f2118f1d54e727a012f8934d27f99ff72f9b57001d40be88c707c982025230df252fd710b5c968f2a5d216bece978936cc03a97537d3a0f58e953a87d11edd0d9726e849d3e83e75026878c4b828ab0c49d635b7c2bd0f308c8a1e40fd80e4efa0cc552e606f067d2f5b0fff60af838c7f2e1298cd6eda3b406d91f5665b6bf7fbc096d6734fb9f44b653a761fb7b1fed18471d5314c5b0b1f1fd14e464d3450fe92deab4149d025320ec7a652169ac5a5b29f8bfcd818cce17491c2de3faeaa95790960cdf4bcccf3bf70f4eab90c07c1487f028f872ff8a94b1457def3ba4ef576e95de640c915edb4dd61181e3f92122f7ea3d953161f940417da83d0d47f7245b789d4bdf09ade347f107c6f912ed434522b2e059e9ac4310b5c7c661cade5deaa9753f16bf48b1107f1a1e67cdd9181aecc6d7eeff9744c43dd3396e1acd6982f16d37dbd2c8b239643571892aed368270494e8a05873c8d7e5094561ea04ff82d84277cb252d8f16b18b9b1952ff9b750689bd94a0dc109ae4ce6303f1ed8f57d68d7b3b44a9d1fb0111322e3f5606d4d25826adc4465f25d51290cf15c437f94fa28ffbbb1eba0ba9f2be582ffdbc79e8edc74484185541258ff17e27c4e866b5e99961b05acb5e49c10231ed5f918debf53103b69ca4286f6cc51231d1a7f0ed0228ef300e0d0309c65cd21c6de4368784cae0e822f7ad54bccf8ba42d8667677899b8097ed73768c736e4a706a2600bca40d031d0bead1d158f1fa108e7c0d30423d7dcc225a52e2b68bcfa27227d8c2c83aa2c7674545a60a05e5af25d6094463c67ac44ca2ba54b1401e2b40281f588a9357d74fe7227a9f8c1b0f30f577dd253a7590e09acbd725cbe166be37f4dcc3e3f3f3473cebaf630407a7ea6e05385e1d4eb0302e8a3ed3f2830a6a86b4f6d8f1c22d4c507a9ef197ff3239272706c9bb7ce57f208d77098bbf0aacafa32da7777c890389e5f514bb6162e643510ed29bf0e48f35c1e848b4c89865504add88d117fc9a25a2ac6c4d6ab80f9cf50fc936bbe126dbfc8355b4fb84ee602b5a7cce450bfcc890682a505abdc3489eac951a2970eaab102ad1925b083f4cab588e0c95e5f3639af9956296e899a604c1e090abce7b05dda25a201c01cd99f60d338cef167260709e2676d101f62eea3e82a72df387e82bf37fc85ed9ece91543cc02520d6a16c02c96de38904b2f19f77511aaa05c568206cca6f3f5cf9fc600413c1f5d07eba1f7b4e252aa115731e4e988c91eb0188791d35e7e7e49646690ae736964ef10bdc9cde507e48bc35f7adad03e30da4d920f00d053eabcae375644c93a9529bb6edeedd9f3caf3d5c71948817ed4ff01ee3a637e199e8626288fad7ded7bdd85fea7064393934acf18dd08cd5536e91e130b8b181359a69d1b96465fe99f248c6ef4463a48431766feb931338768180a78b421f23604dafdd779ca31c9fb961710b9b5c81ca203684071dcf632f21f2a32226063ff9ac9dc0673cd75794622e1cf50688f60b9e55fbdb5a59666b984a9c7fcfbec32954591edac82851885716f8bce4c79830fc7292fd8a538ca4d80f1f1c5d26d302d369206bdf1075187489d34bd9980d48bc24b988a928f813d468c96c112c9338c11db2ac593d2ac801218a04b0abfceb91dafe442d6de9831d27a40b9c823f28f5e8e7ce9ed7c6e5f4c9e240b8e733d9f91b032de81c9685d6464c2a67a0398c8fa8438e54c6ce5ccc2ae52ea4c7991cd1f35a7737e40cb9a456609ca3725389a15cc708cb53386bebf3e742a91db289abf78100b2f4fb2545ffd715fae5c702fc1c9d8af43b437837963ab0dde7765aeb842d42925adb3d7e2c437864a8b6e6aa5eabcf76adb5a5b3af463306302e46e49b6cfe98d9be6f2d70295a028f3e1de0f9eb8f0c3514405a88b9001f8d4f49f8d4125b273a2ac8fa7560374eae6ed84dc2557397f47844b41daf580504ea4921c9265f3979b29e1a2190faa67a3209bac0b4d2e1b4dc48d9ce85960500218623be8f6f36caada9cdff39110beb53c23ac4545e4c887030f074b42075e3c7898d9654dc506d797b9bda86f0135e6b747919b34a94eff3d1524c5861f44a31ce207a404b65b47d877ede6e9539077708f854d6a58132d5054bb34fef5bdecce96190ab023bb93b93888ae56b79a07aeeaea6b00b5b6fa0ac0fc08616fb5edbcfde3663e8265a3ea8351b4fe7c29efa23ec288cf7066f990a34f3e97a18bd2eadf6d620306eeb698d9db7a09367b21cf1358b77126b4ad3021cd0ea0fc8433e94fff8913593bd8c9d18c65eefb1229d16fc7289af6b62c1fa4d02c72316808b7d16be646b4db01c9323bf6899d7faccf8749af8d1ca40c8b94cf48128ba0bd671b5805f0c3348d9c686e3c1e50f331fd5a42b28e6387d73e4d97b7068ab69e50e98b6d4eb7c165ac77989547aa858a55f03679ca8593b530cbd1719a9577d025e321dcb483663addbcfece1ebcdf59f6dccbc45dfb91a37a08005b8de5c92175022b1888249c730c8973c1b2298cd8b0286a5a1a3d5c9d3f6e8604945baab388b987fd9f0a0b455d997e715a2d3e6fc299a63054b230321d01cb7ec64b2786d18396b51c93cac636a775c47e3aba0cddfa02c9654435cfb28c72c0aae0011c40f0696f8c9194ee7982a9caa830351947bb1e50f691f71f2e6206404b3150198361e18390e095369685971b0ad4eee0c6629d54cae24053769f2f8b03522f028718f98e0f982e18e0272ac1200d8e60a62358709bede84390a72ab4a140f19558f8042921c60b413b6942bf8e86a786dca983ef73a2b8a3d7a89a3181d23d40950d8dbe4b5fc979fbfd4aa58a4e720c3c53af2bab470cefb7d12e688db471fc3356666b721d80d063f216f2d530997e2bb27d3e7953c4a52f03081141cb07b8459bc39f07b5ee30a964eef51de0407b13d1ac4b1b697648cbaa64ac678e6de90d33665c35463a5a2b003d827748c402631771ed0b7bfaef13272dca1c624df8bc1302a11037cbf4a5ea620e63b618c7a3287f902900109b9028b39318a5b6590638c04058aeb54e971fa7d1266c7f8096fb6c2a9d3bea8ae117de2632981ca9ba46c5aefaae2084f82230890adaa4e01bc9eddb484e75f4ae66d1259367e08f5c46b11160732b1646e7b3b647d75c6f68da6cebcb2c9e00afc020087a77c4ccb3f0e9ae47bb02a4aa4ebdab150d37ec70c569d9decd1fa478b8e6f3b9243c7cd69dc3616deb06d4e56973d07c2b9361dcb38f2ba6ea50b8cb8c2d758ce3b9df3d5925de9ca61a8c6f64701c2411dc323f54ca46ca4badb7f8cb41276594a6a685d4bde3ad5d4ae30c91207afda253b9cf5eb05f4ce3ff744a719114787d9325f93f42635470e3908814363b93ceaeb82740f6f9ac0979cdda494e7cd25fb92af106ea268640d7fcb90ee2ab08ae6a4043b03e15cb6288da66c81b00ba8c73428c4110956c9ca30ee47fff3fd443fad9d7ef6270db6d24637dac440a7b093fe1c215abbae88cb8071d125032496db74a53a67d288c0519ed2e2be48315fcccdbbbc41898b25884cd398ee77874663ccfdf30a8a636ca9873b18d87e98d6fba56c643dcb4485c6dbf28af3a387e67dacf2570978c7a24f7fa317889e763fbb63dd9058273b3cee091cfcf7d64c3dc133272f7f8f10a1ec3905ab148ab7d46259f1dbfdb5ad8b8244d4451e3a446187d1adc7d560944b8762e95ab743726e1d8665a41f3e291fb110a6014ef7e348efe7c083df4b6313fb9a792db324a08be284fa2f8edb237ef479da2254628deee2626538c81ef7c6842958845d3bd4460cd8d1f5792fa7ab42560e041d026c4cd408d5a977bd4392d7f712b62247d09be997243ba2ac4af0b3d6d29f5c788b17756ec7b25694c983ef64eb5c2c5f14dae7f637a4a9c9d36fd2651e6fe654e9f35dc74641f9a264e03b98536dcb9518fc75a2c0c4cf58787af91eb50209b91eb002db452af32d00a64944078b67e6102583ac3f2bd9eb51671b416ba1dd600602ca0f79d7fcddf5399fe53412504e4e2dd2f961086c42b16f495ca17aa51eae11edbda1a0f8a622f9eb408736512d05215f0e3c0edeeb38e2fd5ebaa39ee568725ff610aa66f708e32b71bc1104569db88d3f6032aef34d427d9573e473b3ea13f218986a27cf10be9972bbf33ebd715099ca05ca4285f4c48b264d300293d6f60df3ebd66a4139834794a5f0db247442d464464a6ebc4ee85bc96954319c1cb009d874d2857c4d6f389901e6e9589b785b3690491aa0c62f9e5ca901e1092abb8151c3bdac501f844bffd2239a81f415f10ca26650525ed0c05fe1673ebc1d2c8c792aa61abd32ebb3204dbde0af18b3d7148e530a04b3748765cdfdf22eb5cb612de154b0d6cd6e235b535e8918bcf714ac197f9fbcb02721328a340e8269dbc2b18235729c92c001a4ff0a3de17aac6ac82715b7a2b458b5f28ee526877382698bd4543cd06ec75a7e7975bbace9c8c36b31f181029b93ab1c6d61b9deb520ad2f62714802525f190ed4580ae042b95a816a67a4a0b57cb15a830bdd1670a5d1b3190eacde831fc8ce008bc509a2c805b0296dd8b808d38f42be8529e244c09c36b25eeea6dfcbd579e4c4da3e350117c91f7a785ac7894fa752c717ac1385c1a5fde262f6b26182f4af4af0b51eac3f5ed3a763b32177cca6be7d3236df83553885ac70ff065ccaaa52a30dbf9ba08caa6273d460011c80bb5e9db7103c66bfe09aefd117944a0e30b3ffbc28dd1a0ad6dbd8e305581f54c5bbf5ff3867eac55c99b27f22c44ece78528f593f96c94024bdfa4fd13042fa647ba421104543d1ca953ed6a8548a78d68e95096087904d45d1b509a5f03e5f40d9366f5d16a16b6a6767ca2eed57131f572ebc3daded319f16111264a9dee3ce87feda9665211b2b826ae42abd1336a8d6ed47d00b87cd5f44f038132ce3c46fc3687a4169ec61334275370daeee1ef636e1ead986bbebbe38f498707ea41684a8a55ff2052923052e34a3da399280aac030175c1114ba3c81d9f39c337c442e5ed3b2601ac015500bf7fffe4dc52f836870ebaa20abd23d129bdec1022f86d2af62fc7a587a0f49f2e7c8b9bff4ef737142117601c035c299b32cdef176d83b3556538b0469acbac2b7c094e0cf251c0da9aeb26c2520198390b4fab0010a4a5f1c2f604ac6df616d2351fdeb0acec8bb086bb8c0cb7eac1eee66d7c9eda13d7369aadbd055bdb5d4147ea33f3d0d6222c860a889b81ad3872582df1ae525439bf410c6b5e78c23ec9f6a70ff2c03984e25ef345ec1411c049c22d55716ab3c2aabca9f1f58af8e354b1cedb8b19b9e1d74863c7bf894b0fc19d78a14d5534123646bded34b16d810a12ccc8d2f02eb0fd33f28a1e9aefe443a1cae9399633d8c60dffeab361c7535c4630b9e8a19fe3b190cc0daa3f744781f94a340a47c7bceff754f21cd4917a70a67af648cb42545eff538f5a8a1b9e9abe1c8a2c3f23362e6662933b4b14254838cfe7be88540976d15eb0874cd0731ac32e3ac04744f4e28b169f20c93142df966d8d57c500725e163721007c8ac9378f0f55aad8de1539aa8b7c8670cd55590f2b3b11bcfcd4a38c159c3cae4f1a5365a5709195c13c7b9c188b42e7a8190c4f0f09fcaf04876bb08cad395d1d77fc39d287d54c5af8acc112458f1143891216e9f43a2aa3f3043516941431244c86df21250197619b0e7bb7f38cbed9acb237d59919199620b273e41e840e7dafcc0156644a54f9c262fb3248506ce51d52d09ab5d5db793b1be5aa394a698d136460de7c66ee88fdacdba7d0ff0fb5d6756bc2719b45ee2918fbb32f99c936bde86372dd1cb4bf0a3b8f12ece4bbc1b14cf176b2e39008b743dd72434a860d6597361ea878fd629e2d14b1727479a09189797fe800f228330630758b3ed116c0b926f44c41c892aab583f0405c7ac7e8eec94a30673e002afa81a6cd5d0a02e85ad4ef9f38edad6958017446e4f2a1e1906244643a263b531849da819747f6dc0222c9d0852911373239f327806296f85bc4cc1b7f9bb6b64150ef56a8b603b12db430cf89a9da68e7f72201c6c5129e71bac4f7238d04acee85004ecbb9d358b0f714cde845c39fc98b33e9d6fbab13ed25e4e92b73a16fd4acbacb6f6fc7b5a314961e95dcac33cd954d8a0e22c0a5061bfab54e6afc03f29bdf3275af5d339d947319b85d329f2443b99631a1bc928db2cfc3cf60a693fe4e6c6017b3dfc9c6a3774901ced150252ddb510d526d0b876d58cf83b43e67e335cb00a3519ee056d41160c0eb23c8497111e4e248d3a7c10eccde4b904726b82a96b93333572c156cd86bcdd69ab8650abdffc2f99511c68ff7620f9cbd470a394228355618f70894d4fead73b8ee368bc51aacfbf02b0166141b55339d400ea003509f3297878843d8c914b856bde877ab78752698ff4b530c01f343a2c2b14fc3485d86a8cb3eba869540ff32fa5237c3c3288fa3a8fe428082d50563f2a97c258ffb118897491c424efff27ec2357457033fe6b071f7075c2ac60c1a1d0b58d98e9fb96056c091d71941f2ee5bdd2a072bfab81e2984b4260c50b88b2fadf27064df2248a03478b63029c6e4a22ee815a81ccdeb2dc4a5f75a31ee3cc30faad12fd34583006ef7553e135c70299227e57e2f291a8cd647d2bed9b83559a8f443e16c9c183d159541aec9672baa2801a5d719b486d488cf4e52b12e6d1827d031c8ffffa127bdd656a26e90a303dff08de023c4b21327f486766a0c74b8360daa24d402c2c85d4ac5bc088150effedc582ddd43c32b8adc12eabc13eb7e92e11d3250e0d99de72f70121354a869884ca861561800e54a5598bacd812484a366a3058c9bbb32af1f955012d98b5ff4d9b0db6ac79075ee9271cc4c4fe073a0668199a5fe8602df23ad684a47dd155dfcd4f7a2e8c33ceb8beb0faf2661a9c0c10296cf289a8c8961c7a50c4fc80304ad9aef959f812a5a61b92eafea404ef7c9207f26726b6c7a83f2cc22267e27729869368e05a79981a111465a05472f4a88c15ab99d46ef4edcead632a0e26f5610424b0a591c11c0a64daa04ef1d75c040d0f9546a0031cab1f36e22f9bc4a09a503929e0a1ade6461af24340117ffc59dd197c15890a8f458a2710c0fef98c488bab88423b69ba1a5f094735d8c9692bea2683850287fc4d9efe30bd36798a4bd3d84f59b0041320eea2c321822393c157228c3d5f713bdedcae23a58e63a4c40944dfec6d9ceb8c579d63f1b79b27653095759337d35781b4ef997d8c456e6efcd34e07018b41aaf363458053f0b626308c1d2e73554675c9b30412b30c25e15b9abe18b66ac391d35f84f5adfb24b691746c0343bc43d4e4fc6eb5b1bac3cf04403b30fc1507c3db4ae11167786a63429f2ebfa823f1896decc683ef1c6219c2f83725a526f370f6308c6b21761421626abd1f4dd6c908f43f277e0c3be0a55926be2f0d933e44dfb817483a28ba697451a21a4a0b0147b8d10082acfa87f4438fff8eceddd0b5dce46da5a2ae930212655422b390acf0169511d00a3855f317ada08a2b3f88af1a7663ca90659ed88a9d17012b0e17da72ebe3828bf165960477ef768d00f0cfe410eb5373bddd0bb483c64c4e4776aa76eeb5f151ca9a2164f0ccc8281667260e06304f63d65618ff851a574009a209e01a69def6be42d1b0b7b0e49799ca393b62f3acfa44743dd9e4ffb54d9cb98d3192d235b34474f0db43060a76bcde5d708104849b12ded404134efeca7e930b7b79372b1b59181c0178b216acf2b2644370a12de7efc27e444cf425f3a5805f4cfe1e46f1c27c5c408783eda1897c797a101c1a3e2c3fd5cde6a452cd0b6d91d2071d16d01ecd279a99e22aa9c76d787e786df5f7a72a443d5534e1f716dd86045742195cc63aebd7f75bfd6f26180ed05b8ced3b65e20e5dba1915dec5bb1195a2218a982c7f952070df26bc689b02fea5ef7a552cbea38fa9da758bf69dbcda9306babc9c0b2a1670a2177621e7004e885ec5c86edb325e5862cf1bf1d193057b769fd9408653a714a644b319482575b17318b08bff17d3e61e520baeaeb09bad54f1f7d6643dcf64ac7336bf4d78f4d9fef0f4ee3193dc926b8f64f62a051f658c4e1bd6c3d47a68d31b49c349fab42cf56e1a8882598ea680c17ed079bfa11e7ecdc0d62082750f629d2f2b2569f7b7fe0f88f40f2f65798e927f52b76c4aff42c6b13ed7d3af5981d706ce9461894cf3d8bb687f973dfc3f97aaebce2ff9e03f4facd1ab7a1b2460978fde32b9230cb9e615d435514a95382f7e5f910f8638cdf626131b403253ca6c8df5707611f32987f07f7d7f24e0bded1a4919ccd107a2aae4cfded34957fb9106837bfbc0d790263e6d30ccacbe98a3337bdbda6e276b7a8edb93005916c1aec7812045fb8408ad64d48bf70c8d88338403ba830c7a8cc2d63a3daed7abb6508a8afd96e3819680c078c608e40bad477cf17750fbb2a9424a7846d55fa790a9e7a63fe366bfe8c927ce734c86ee42a9d93c1a10080723c19cdbd7f490f99d9ec5c32044ead507e129624625051028e3caa9bc5c45f4d15a3761fb1bb22038f6a1c73d5b6d5a88d8295b4a98c4de413a7d8df2833993cd6a0e27db7702515fa9f95c470f63b11da3f4b3f3f2a750ccfd8bbda66d5ff47fd4cf48b48f43ff273c74e55ab122466efa85791a70761770a015c66f95bc74008ca74ee2d5c940666ec51a0440970d1119005517012ecb8482ef543e00e5a44d51fb3e9099f4a2426319ffd32b3bd7f5a64739bfa66ca68add78994882d3ad842bdfe622dd99d41bc7ff9801489f41b6157919d22145298e1ebaa158214dd0717d28e2f408ab62e613e49973bb9d09acb6676dfb412c94257567f9edab4e913f7fffaf527f724c8d60262b04b971ce2b8accd88176dc73d2134e64cdeca0cba8179ce3899824b654387812caa58c623f5ae7a639de21144aef8a06dc1b2cac793715e147c62821a212cb435adffca951dfcc432a1e860ac98114615957b7b57cd9d45dcacb5242a376a0895334a901030bd654638b8384315d45adc4403b6e1251e63b632e998f771285024ae261a4213adca7626502d050048e49428f24199be469cee1cf6b03db26ff37a9f59038524049230675445b04c7b357e555d3892446f4187801c1f531ab19e8a97dee2c89d1bfd277c0c4c0a2cbd509f6053ad90df1ebe80a6608c5d17a1b30bf200dc8ce1a2c4e3bdb302fcef9e938f3a564c047b40791a7b09f6ef956106b55ee92a6ee9833d8def582ada399745669093a6420c563e321557bb242aa0c1ad80d337f4e226720bca02ad9fc77f3c3b1967cddf8783044255cc3f57b339a6af664c2a3ce1282397fd88793be6d0b331978ad03f3405f52c835ede1b95fe06ff50029376bb020d1f776d3ef6d0871b690f0d6784201075ea6e5179117aeedf09743cd45766198e3667bd2a3b7655b6220783db004ef91cedd6411a1e38065722e52163801f8f3469c24cdb4b5a15e7eda3321e44f78b8de4a23be0ed50d2aac5406d25811fb4b79c93c99d6d76976f1998921630f6cb8911076e20c37b0630030a58e16e14e37507a24985d764af7cce63593c6449bf60ba61013040e61426c84530e0024328bdaeaa081ac6cb793de529cb090005b5bac249dc8361b68f653bebc4ee844ff62057b2380ff7dd7ded8d394c6dca9c21232f055245cba8380045d31aa28fa2cbf4486febb62e0cfc45402f14e13d883e6405043ebed6e7c14caeb8cf6f14a00a8bf1a021bf9dda3913a6f3e434734ab877cb477e6e8d7ea2af53de62fef530f9acd0eff8535b0e0251adfbff361f54cc7e2beedbc1f4e0bf443a8cdfd133382977725ebf1c0f794dd23c62cf35333627458ee67fc3bde0f133f7026cc2a68a5615c5a799635b25bfc76c2ff71662f456a2ff000686b9fd4445d98c60a026d0856ab736db6f3a71e12b137a36c9d5b3af8edbb17b771c1067387bfd0e5b8fa7b286641af5bc567b5e2e3a5cc5b15e2754f08aa5445583bbf43d79f93e5bd202f730be26694204214b3ed2cef0a3a7f2e0bea328dab681c852e5a6b78b71156e35feadfcf110768803a2ca23451227454d44ad001f3c399ab1594cc210feeb3a0c40577db4b1cbb0d9785b8a03b4afcf4e2677cf6d383870d378aeeb2d4c1967cbc4e1e412533716efbf123cb12d22a066465ba04277b51270e9f6977c79299655ba0a94ecacac576343e8f1adfa7c969ad31373c74ddbeae686c70aceb91a47562c89575a0ec66c7fea18c38e9bc112b67be7490fd0283de03ae6b4c03447dcabf9506642e65985392fddec8d8a46caf855174ab3640c18995897ce9af6b4930b808a3fc29792d26b3cbf45c473077cf023935644025bb18bb4880818bbf0678dac62e23f9c6c9833001357e702272abc589f17f3493dfede47e176fa41e63770d5e66cb1d2f09cd1e1e8d01ccb231d8b10b63256bfdb5a3feeee31e999063fe4c1634979216d78f99b254f7e8fb0d1010f0e3a731c22b3e280ac2f6ab770d1336c837403a80379965bdea8704dcbc0c1f89ca13e6dffc9c9d072006d7a67e48d8247daae6d24c08f1e286e0a9a665ed208738f3a0acd12bb96793630edd372a6618e0f865812a25395c5187ff2b708a7d3f89b29ca574b2d261d1c0bd564a52955a3417ef0763ecaaa7bf97190b0ee352e7198ea87f4e4c672dbcf16f56965cb3bfb38c356bf11a96afc3444e430ab69ff60b7ef4fe5175ce0b3d6858c37b3584324831c6083a3d374e00bcf0189c6fe28593199f9350b992c5920c3f0cca17e7a564f1c2c75123e9927bd9d219cb4beec89bb66e87afc3a7f0d8b218d61f87295bae72ff17df1a7855a93beebb52d9c593a8585d54bda200376b0af6bba97eb246afe08403e19a4866da8bb73065970ed7dddbbc9cc6b83817580f943caa2e660a74585e1e5b56088cb9a5718f1995d03f2c32ad247b3e4e1718d732561c0de2cf4c06b4aedd7bbe1fe68cacf5843307446ed54e799230e83fd16362dfa2860da4e9aab712d316ac762c7eb8fcb4cc47e7bd10336725d3b32f5250aa52a351b84a4c6ea427db43319ba29c7ff96165f0e408e51f3836c2d9a7a393ba6f7d4b618923ff917dee7e82d216139db477c8a7125fb843a6512c9edc54cb4f2f3cae9539a91248a0893457f2c755c91f4540fa701c0496bb1d72f8ac57bf2337c99a9647d488f8bf1955c36533b05f1dbf6d2b6e3ad64cebb794ec56a920f93689b603285e73bd5c8f2186c6727f0d54cc9161adb97d1c3e5ba4a274fe64c4c98e1ddfbae29039a77b90e254c96321cca9566218b595e31ca838f994322b478673259b643316601f68eec18d58b799b09bdcb0498c533c87dc937c503ee82685a20e238ba7ee5c53872da30ab61db09616152eff7975b6b2499c6ea0c64f9c5bd792c0489fd0ccb670def0b1caab8d33e9cbcd7820aff337bb7c13c17db1a1fa29c1704a1fa1a32f6fa7a7b2f8a23a6b23eed6913f5175fd1b93ca149a7432cc30e120cb655f5d481f1908a5b1fc05501dcde6287b28a288c58dc21b273a2fec497557ba0b736bc0fccf4c3dc844018e004c901886d7dd2fa89a21caf156e99cb694b6145f17cabc463ab8f926db3710d34b3e4fb43f603e6019e2bdbc57ab9bc2566d88c740c01d754fb0fe406857d53a706aec77df90afd9a9073ee2a3da8584122c9a67f09759d5482a7e157ee59db6e9f236a4163c3623cd9a9d7b59d04c56b8244cbc5f2286abca38982d3bd9415fee024f11584028fd79ef33be7476700bc6b6e73cd5f59ac74fe5188877b38baa1cdf948daf700bfba8f23d56d1649191833c4ad76ff174bbb1e425103f7b2cda4321965c1c335f5a1b3a3aeec59d77a1a738dcab614216b49a0f5eab2cb66adde5a62523fa7b67cb91b19199503e038d3ee485c4c239e270738d69377611c291e3e6f87917e81ce9203cf505f432fcf2ec87a7d8028201022ca64d420bf23b708b25dfb8ad90830595be0b908d634dc0a48f77b4da25d2b629dccdc90232c55bb2c0ce7043a2e58041342f64196b4be6cbbf2003cf66eb907e5a52aa4ad9d0d890ae96b39b0d25b0e4583572c0ef4ede0c3483bcb2e25c956c88da581c12c1fb954caed4d20b151539584130ec92c92ccd8ae3ae7c05d824328029a290051264b0c032cd2e15b51d509aaaab3e4fa9e448f22b2d77bea57be07056fe252cdfa0a6035670ef7931d3d044f3e5f00ab3c3c1fb8e3ab7e4f34a8d397cdcbc77689cf1ceb4d1d6d91c72803f045d09cb61cce8baa816cf2c5b516f67fc7eda3e57430f51eb5b3490dd9fbc6d40c979de4f1a864665f9bd70db891c28bc34b0a71f8697eb56905b099bb48f5fc81cd5646e1d1abebf38fc4bb2d07ac666cb1b1716933a1fc01f4d64f351b47ad26449af17cdad69676638fed4155564c962f6e359b8ecc2b5877b1ffda043d4525e59f51e3000a1d4a5806cf66575d7f36633f1a2e4f9f3c4ddd241e88c060f2c6cf8ad099abfc09fa876a170dc4308e05a6efa2c9381b33da9f3c52f344e83a3f26c17271780c520ed9c50b8a2dd772630f51db1749443b5d66121c40b78011638867a5431d3fd4a5f22c5c1561da17a4b8464cc0edbd1d5ad4265bec75dab64fd7ce95ca5e6fca50cf94444c266eb5fccf9e8cbaeac9d5758b2b4e4a4c28e3f9dc97b84e5d624d18049c3a0ff0c8637a8ab4a7e34523939049e57ee6ca6532fa7cb80ee0a282f86e2fa238bfbdf7ec77dc9c901ce14e6a8630a8f83b273df13aaba3cebb0ea4c2e61e8fbe1ad289133822c9c926f8a75d87b2c9db80b44198fa4de845e3e170a21d3a969ec941d1a0bc2dbde6f6868bc6b1d3a8f390236e60af74a0df9a4e3ae28273f23a6e516c22636d086dbc41b68efcf1e24d3a9e36e22a6424d49ba8c5e5179aa97e1d498a0e8a895bf1c5085ae3d68f1fb324bbb5200d053bb817f9ea9beea5139445f369350c8ea72199296de6c7907bb40316e915a600b482919282b4a3830bcd9d48c1296599a527462004406d75becc4386b0d33e92a1a526fa1b460755fdf7f7a4a6ab850e9974d10003e87ad56aa7c7582c72baba76cc93117b35bf9a9d9997e28a412228613955542582e9874e3fff506e99be49aa069195397b006cb367439dfb113c5e82547fc58c0144f602872c0deef4dde915df75692a894ac19204260942c960ebcf4ae3b6a0cb59b846a0f83fb3ea29acdbfa3286ccb9aed8e987a0c0b25e32a0ad6bc1bfa1a225b0940eef81c80d242a8ae2adefd159c681ff0814714d06beeb5491db5457417c216b8144057f4ee04232ceca6a13aa652fb1376f1c0efb5a2e97680f31afb88185d76f2a8b1d0f17faf702574fabcca411283a6e332a0be4ce277dc7991c46f8368942ac9f3883da042630c4f3ae25e475a5cc5e522c45576eb5c4ebd14ed57e5a79a308e1342db3586d83a207b82600f47ecc3af8b1cf10a202f62aa95ac14084a39d76487f2fd4faa6afefb8301e3239b3f12607dccba1d1337c08d9ccd25485141714d1c264e269fd334695ac588d34db5c31099dde72a21434942cfd55f9b16c77c8d09d5cb1f9b4cd96a9cfca490d269dc56cf355c626cdf3f08eb881af7b355d0298e70a237008c5d28f5888ae7c92cd5b5f9776aad125d86fc07225344fab178ee138a588d38ced8a656dbc1be12609b36876cf5e1e2cb4655304e3c179c4cf0a1030ec67b81d31ba1d43d27327db2f54ca6ca5a346913b48535503c0ed12d35d715c7038881b08a711ddd64e2b67693ac12cc9d83d58e0146eb168172b4469d27680642d411ec8afd7848b3e8b34ab3f1f2c69ecd8359d274bf22ac80ab720a3f2b5d822d4fd395a862a2ec4e8cb0fab24d8e7c398788d6644d77c322183be898f5b8f0e3ae0bc72c8fdb7d89403e7e7748e174c1ad85a10970212c738edf337ba6c062d53d92dce13b9ef7c5e55f63e0e1d18e83e5c21318596c1a4a305c5186e894fd58c51a1f04b54264670a54e1efc6f99b8445330104437cbb6e37b1030617da6ee0bf15c2589beca2d9dc8afe93ffc56b3d142d050e8c4c5f22a6b1cf03431868d381d4aa18d56baed59b261a0b14412142772192f5c2c5844efe3fe7f8964098d6a7db1e229a17cf2479d52d58e95df10255ac7d1b359f35b1c3c333bfb4b0bbbf191eee784283875a67addcde6030f23f6d8ac152091a11a3dda1ce64a89356592fe7654bca18e01eb01b88c2d3438df2c7e7f6a80400779493266474cad3f688c57e05bba7fc2e583ad5da4a9c7f6ed45a8322add178d3e3eeb065141e0b7412e184628ce37ab35ca86bda6b0486a39f0ffdeaa887a0fd85e673ea1d3b0a0f1817f23e3136861817bcd04f99180081511ea1dea158827b63748cca8981f82a6165434650eaafb6ed167bf90ea97f848b5ebedf4607454ab9d4b0d85cd94ba942dbd9cecc5c397dbac846e4cfc97df6951553dbed8c0b7ba05456288314e4701d481e733c99e715c1b446745b6dcb1c9cd98c38fa41c5152e7dd17ef8e1e3bff6754406c401a1fb94bd8b81b0c10e01a7672bea19e36fe2a1d45e6c6178d9bb15caad21ab343db6c06e4eb8ed426c2f539db5b7fc783bc5fde2849e622eaabc303c3fc925117516d0dea61157b235dbdffff7e2a668b1bb141286de89a8971aa456f709d47661a079ef0bd32acb5de8d5edbd9bf2f694ffb9e094880bb91e2c578ddf9bbd20f14ad82d52054a3e0ca100c3d6a65955c1de647df28cef07bbc6eea12ebf7f4d2003db94eb7ab1128d95a03b38e7a1480ecefc1c87bde069ac40827b02ed17f2a55896fe346f776e0a8be823e6f8d43bc0c96afbbf5ad64548c3592df759d8fd60fb1de89a8abf2fcdfc110dd343678ab728f9fad809c55ecdd9642cb64cbe75020dc812cc70924eb5f9542e7f8d0a4b38eca5bbb32578c6f2d223709b22b665713490b92cc32d71189681c8944c66579cf1b9145ef3b6b03fd002ee3f9989cdeb82f528b0ae8974",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xd415d819d3e46a676f680be0b52f601098942efe52ccb1dbad23489fabf8681a",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x97473985d04723299559f49b856effb47d7abfad",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1375170",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x59c6a628fbe05515da2598d28cbeca17ea6f3997c6ca34d3e2bdef909b636c4c",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "stateRoot": "0x3b81055017e986247ec2f435e38b39ff20b1280eadd8fe5f09e321644169dbb2",
|
|
+ "timestamp": "0x6ab8f379",
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "id": "2800-anchor-20402544-baza",
|
|
+ "sursa": "2800-1"
|
|
+ }
|
|
+ ]
|
|
+}
|
|
diff --git a/consensus/qbft/src/test/resources/aere-d412/blocuri-reale.json b/consensus/qbft/src/test/resources/aere-d412/blocuri-reale.json
|
|
new file mode 100644
|
|
index 0000000000..b4d9fc1f99
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/resources/aere-d412/blocuri-reale.json
|
|
@@ -0,0 +1,339 @@
|
|
+{
|
|
+ "descriere": "anteturi reale [parinte, ancora] din corpusul fuzzerului de ancore (28 sept 2026), pentru D-412 pasul 1",
|
|
+ "surse": {
|
|
+ "fuzz-ancore/iesiri/1/vectori.json": "4ecd676388e3f84764362ea06d53128dbcd15e3dfc7afc93ebf9bb964e45083e",
|
|
+ "fuzz-ancore/iesiri/2800-1/vectori.json": "f0560d679f7dc2ba60cbbaf19e1b4d1cc3f299d488332b45e72e665fb16d7028",
|
|
+ "fuzz-ancore/iesiri/2800v1-1/vectori.json": "985e9fe50243ce8dc6184c285eb935f0f912eddcb42be626ce62d944ca6ec239"
|
|
+ },
|
|
+ "vectori": [
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8411af02cc55bd0e772e5df15c9d67f79b97597c1ac75d08bd1a87ed3dbec36b5d51295b9d0ce2642ab30e06dc37367bad1c02dfcf2f70090ec20ddc3b9c0f9c09f01b841f75e8dd26a796eb48621f62d7c2b8fa4d713b5d4cf977338e74bfbc73c3bf10619a88addfda8c65b6e0ad70da3de156d3ea7a17169691e9a4da096708bca3cc401b8411922222fa2dd031e905a65c026a4c66199c3098518570ec5659b32fab40798f6483c6b6c5e69089ab7e102abda4a8aa758eb63a7af7660d2a297e44bff87c99400b84106c90416f15a7d0ab002a7fafbd315d208eabad1b6e799355cb72b86b3456a09732d710ef8bc9cfbd115419366705cc9143ac2278ec4536cecd8c7ba4c6fe51501b841c1d20b0ce4174fe39251407a5df20adb182e57c406e9ad038b4c5eaa2eeff01f00a19e9c6579d3e0ce2308c1ce843e5d9b65bec6c2d611132a721840e112b18d01b841f74919a73ec63f74aa96fd5360d8b8930741f0eced86c4bdec66fbfd3941888c56458af43af6ab9e7a11532b9b796cd4441f88ccdd1c8fc699f1bc816fb0b6e000",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x3a085dfdb2982b745cb942f694727afd942916c83db1b57dd212e53905a3b318",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xb5e768cb3117ea25175f51aa956b48691025c2a8",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xc9a3ef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xe776b86d416bb82c28b1debdef92c4f4d35713f6b256c37e89ea02673b2958b3",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "size": "0x4ea",
|
|
+ "stateRoot": "0xea4ef19ef4c271edb79cff29daab3574a91dac3df8d605473732c4703eff9774",
|
|
+ "timestamp": "0x6a79b83d",
|
|
+ "totalDifficulty": "0xc9a3f0",
|
|
+ "transactions": [],
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "uncles": [],
|
|
+ "withdrawals": [],
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a42a0ac4583e43b7e13cf2d8b5b49f336f0f220e7001ca2d383524da6462ec5e506eaf8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc001f90192b841bf2fff34f92158a0dff81a0e946d33210ee848b994c1beeb0fb6e21969aaea8c7058d926385085117202ffd075c019fcb469221d997a864fdbd38945260f2d2a00b8416b3ea238105ae82c8d9fc5c49c946c2ebc4c5cad22918cbb9f036a621a629ae70acec9bad3f76943165e8b88f8def9653da3b6a3399add22e34226cd206eca6101b8411ff321917e140d1b9bb7d0b57506158a4ee638f49b028a44043371996963363d5547f9dfe2df7199a5e70da580e8aa20d6ed468a759ffe2fe6cdef47c27d64fb01b84100eb390dd7d9188d7f4578803103f9bae4bfba0206a17a6b42479ea596af81ce22872e92cd6a16292462aa86a4a5276e34bcc7ca83e5e1cb2204d5f84ddf673301b8417a2fc817a4e22c35622be123662b1b220a7ad9dcb25c3931830f67f129a25d25701cf85e2112fb7e3127a03aa810e046fe66ae2452d22c7c6f109c3662bd9cc500b8418db00c79fb5c3d1ae0d33dbff8f3ccdbb2c68475598413a4d3b8fa27f3d46375147a963834476165e9a817e993a4bb8e0f5b89c86be13cb7b692cc413ebe541400f907c8f9029480b90290395d78a75713f5fe1ce496ad7a1047e4ceffbc85844135552a1d580ecbe7cccf299c17268835e4884ae2703dfe044b0bef8c19cbeeae89044c14138bb35ab944669b079cd4f84605e764e76450c3c2c8ef00c0f2334b7fa6977d9b3b9ee489b5f5e6bb1c941d4e4a5408db9874c8a9be22e66c8ef6bb755544e46a488533511cef703fc8ab64d7f95ccf4ce5097eef4b52fcaac55335bf3b959af73894c7289bf2510a7513c7f1749644038ed4b133d6a17e6951c6113a8da9923712498f1599cab5fb89383146fd5c8f4f10d2c12c567fb9c8cd959fb2e48d1443738c3ef038268e58617cadb45e15c0a5e7e45c178f25bf199832ddabb9776bf4b52adb2e688be4bdae6098068318d46fab0da683483e3469f31b3c79969824e7c65ea14537589773e3ca6473538d8f92a2d55e92e770d88ca35c4d54dc891170250ee331984f5022b258aa0d9e20961ee446f5075568c8ce9688fb63385b8806cb14a21f930c492b26aa5d433d0ee42f28bac47f6d0378ad55a0e35c74f2546c1b8131ae64201f9cca6895b074b4b1fac029ee93c38967a7247d926292c854c1943977899b15a54eb07ed9bc43788a5bd718ca1232b5a9d2931b59ac4b55125a9dfc100545d6feeca29c5cae9f618077998448a64f087ee9f04032d7ad129cda4459da594a83455b521bb6cde67aa58e4ba56fc824398a32b42dc7115a38bd1499a374b4b48685b06270ea45677e95946bff6ea38297665f0a46251ce7cf107daf37257cb1c1ae48de11897136cc926ea248590498e1a82392f841ef17656914d233d61e1da634bafd278befbaac811bec84f265c74eb71a5e775d1478203d4fab48e1b5f716a8cb48612293d07ee907db304735e1a3bfd4d0e5b7cfd12ce8aed793f0628332b12f1bee4d57f0a230ef6d96138780f9029301b9028f39ef3590d883b44bb4ddee8970b19e323bba7753f9a75089af0db85ba5cad927b43ccb991143a96c7eac974c24c5223ad3f6a33db2d9c68843a0d9b81de7af8cbbe499562949eb9eecec950ac39f24368cc8228ded099d2b214475d373b1a9f55ea5053baac33087969ccdf3d1e46700f043310ff37f7cb5ea677af5d6a18b377935e619dc49f411bf439047b791136846cd28aa5ab118d551949021347694601e0a9afc22ef77b798ae64191a32f9853738d7dd3edcb0c71138a6564e221db785cd99068b34a91754619868a1d87435f3e7b096af360a1660cda43e1df46d6b0f496e97c8ee764a5b1779b3df364d37264be9ae40fa6d6273a484371e4d15e075a637795c373f0539ddc7de706b7799d7a9e58346ed68775ba10d69e6b97f15020191d0d7a49b3a9674e3ecd5b456fdce34d1e9f51512ab16a56b4a9fa31a683996658e70b5543bfd063052dd897f631542f4611b2b34dd9e92b89158831dd8b228901a27ce8ad4abba2b540cf19baafb0ab31c1d0e31196e94462621f345d8e79dd3499c8bfc7e1097d07e3da6f91ee172bb8a7ff9cd66fcda0185ad468d9df7eeae354688c2a7782afa909996153d976b74f839b7acd1a87c5ce12a4a0ea22fa1687bc4814382642ec8f23a40985afd8fcafb3b2f9e21b5e21055a7715b3c2a771a3dc7f9bd3a8e4e613b831cb39dd1baabc281dd90a9281d3aeb342114994f4291a9618c45cfb7317bf058fd36e5070f637931c371f5d0159e55c79eb3cd8581012e0fdc00c4d371a96d8a4055b176e7727b57f522340afaa790c940722d5312e845288c15471d0057ec79bd5b64d86f04a2c59886678c166aa575792e8e9750b059265f9eff4e2ccaf42e19ef553584c836666d7832efd14e413786275886ec680e41b562624a8a33eafecb08f9029803b90294398517f1331027aff6bca3cfccd10513f85a3396c5a98aee3932ff3312011acdc0260b03e42830e161b5586d8d6214e23bc90b1287c4c5a8982ab0494b93e6828e8a616f9a40263926911b535eee25906952c6999ac2f29186a23bae56221b4c7c2eeecf58a912bc1cc0e0465b8270654561c67a6034c568d73c3018445ee4788c367d2f66150f6ba70032db2cbebd12c79677ae4c889008353de7e56cf0ecf1538fb96181b3248cb4763344cdf8e15c65ffb2242c62ef308e42dc01aad9e1758af42fd9fdecded57cea76dc26b0cf01b54349230230822142460fad637f7ecc55b11853e585664fb5efe5e78560b8d9b28def94e075db7b9b4d20b570b990829366de3094b367e859a2cf5db73d56abb7735f236b14e73a0b7484b73ccb566dffa468a486dc8f95062527a7b0ac4948eed026f3996ffb4caa1bdcf9f9cd364bfa7142cbe95e04758850b246a3a090b5bb66cc9c46910a6e50dd307947c11e7f352d627db072b97baefd77c1c7358f0c98dbee0d2219b5a32ab96d749d8886bde76ed3d418d9c29596c840eb7c45875bbec6635259ee21ab37f0137f9b49e46a2915a44fbe1dfefb2a1c29b926ad7f74bb2664fe3bc8a988843228b8faa5869bbd0756f13b0f1cf9704018024488f87acaf4a0ab563ed30c1b82696fac7709bc844631688b89200ab374d11cbef5f610fa31d875b9d5d7d56bece4971ae94c39fb6f3e4b0a438732768eb66c2c4475ac59bcde1959b07e9de334678b5df70acbb3b954a38b183090bbaf5cd567e4e6b73242185a3ef7cce2c72f13b5d0caea7ab457470257d92437d088b38ce35f97246f6136b1c1d64945fae091ec6c3d19010098743fb2a7dd965015a59529240d3efcbecc7563ceed29b4b5f3b6d61dadd53d7787e57718ca4f136c655656850e674dd9e580",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x8341",
|
|
+ "hash": "0xf187f539f65388b0642161a7bf10d4385736b37f0c5cd88a6d39218e7c1bc6df",
|
|
+ "logsBloom": "0x00000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000010000000000000000000000000000000400002000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000200000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000002000000000100000000000000000000000000000000000000000000000000100000000000",
|
|
+ "miner": "0xdf09b32c761620c5be77da398b97a64f03c3980c",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xc9a3f0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x3a085dfdb2982b745cb942f694727afd942916c83db1b57dd212e53905a3b318",
|
|
+ "receiptsRoot": "0x45e6e2ae5301eff0f18e76b695c6d5cc8a4578cf2f3b979c2d28452e21827674",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "size": "0xd6d",
|
|
+ "stateRoot": "0x4c792d46b0bb21b03599d01808b00d78ab623571a3d620159f21e48f5e8ef651",
|
|
+ "timestamp": "0x6a79b841",
|
|
+ "totalDifficulty": "0xc9a3f1",
|
|
+ "transactions": [
|
|
+ "0x2188b80a5df4278216ddc90974d7e27ba48a22c0b62d1dc587441e122a2b2912"
|
|
+ ],
|
|
+ "transactionsRoot": "0x2adb39fcbbdb4e69fb434c86ca332863b793355aff396329b839b5cb0d66fe41",
|
|
+ "uncles": [],
|
|
+ "withdrawals": [],
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "chainId": 2800,
|
|
+ "id": "2800-v1-A-7chei-anchor-13214704-baza"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8415067d6ac795ab9e5af35a56bfe70ebb2193312a52d84f0989ac933ec6aa3613f5caea07b519c15e5013795c72239ad16f0886e478f91ca205ed04de53737817300b84182e0ff371b382e95c8070135f12f60c92981846f3f1da57daf1e275a29bcce0a63f27435db23fb4d79db549083282ec7ac44fb73cfb575931d3367e0ce3c6d7f00b8416d501b227059b9fe3a1905fe6a75e8712e397c6d8e575657df57c62b97b17dba5b70f7b63d9444ef17cfe6c4291b300e66576876d46da73aa3c1d3e55080a6bc00b84139b02a86852b69035fcca72205c4b35790fa27a1537bf7a61497da9fce47aa7e2cfd3d07b6139e033a74b65802db94a84796c3b184d68c37ed45ee69cb432e0e01b841ff51677f8e9100c4819ad07f0568249e5582f01109500dd98abbe611fc2ab76c1acfc7a0a17724b8d556c194c91e0e3c5297079736c2debf5c909abc2d55368100b84107b3aae736c24fd4cde08ed9ff9c7a58376ea71defdb9cac8144610a1ea03ee70e1683c0e1c332dd23ad9f9af95ebeeae05f666126e2a7959a4b846376ef95b400",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x226af30db5c1c8b324396dd10c04b7fb2d94dfb501d30ae0aa4ea3738137e6d0",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x4bf6f91d84b37454544279cba152581ed6820044",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca23ef",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x01262d7b74756134019d6fc54b6046aa3690ff50d1655a884f08b550d4e470d3",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "size": "0x4ea",
|
|
+ "stateRoot": "0x569d3bada071fb866ecaf82d29db4e3fbf6bb0ab78393219006affadd55dd050",
|
|
+ "timestamp": "0x6a79ff57",
|
|
+ "totalDifficulty": "0xca23f0",
|
|
+ "transactions": [],
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "uncles": [],
|
|
+ "withdrawals": [],
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a3ea0d0b7b4dd8d3c80e8fb4476491deccf85dceb305db891b5e58f6ce2d9feb84138f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc001f90192b84178924bf012503d351d86f3dfd2d976356137cd75b7fe92b1e9f9bc5959496686366a4c4963576f209a1837a98ee128d8270c463210f1608c8544090c7f869c1700b84184a38e80e2a83bd1c5762e2793cd4ce5d56c48ed0ebbf828d8df747f844d757429b568e926e819804117d492d250ab40d77e662b2a85b7b056e3a62985cd399e01b841ab158db610e8c6c1c6f5e0f557af4e898e09213c774fe6f81c8290d733fdc83c24dd1946a98d067327d94dbb4703a5b82b0a1abbcd17cbaffdd35388906ad09900b841467ec28b4a6c7ea3e79091cf6154f9318fd109a736afd132d5ff15ab9e6041eb565dd022862b47bd329f6ad8e3e53416c9c25ad03ff556a89e11aa974db6fd6101b84116fd1a14e97fcee9a8cf0979cef52b9740e50bd2e78109c519b312bbe0cd5d9c387aa94ca73bf4649a67aba22a3e260a71c150aad0b65d282c66135c162efab101b84102881bdf70a8136012e7d77801f2222163188dce8e25a68073671fce51dcb4b527f9805ce4054730e560120d824fa4407da3ba576157e2c91c18ced364393a8c00f907c4f9029402b9029039fa7564a578254c3b878d3873d2bf49309c53fb823b7e6cb8a5bf29c8cc6c36ed8d4b8e2c446d69beae502ada93559e90a2126e7ebb43852765e375b39747e0fbe253b12536fdc6aa756f4216ddafdd126b3588911cedaf541a37b123ec96844b3c7411a40d218c09cc2d7a9cfedc924362c1531e2830be545a1c75a89290df76476a449b38a6e1c9d99aca23d50ecc770e0b8efe2276d345f666a7e6c71f06b669207802af85183b0cffdf03e4ccf26a9c0e8bb9c112087acb07a1499904d3b74d4551964379b61fd98779a14038f8db745e946e59b894d7ef98819b68f52aea88b44b533a8f49e78fa533cef1919e7a7aa2f6a21c1a5491de2fc97e61b9a6aa0f7a18d7364aa6cf075ccbb666ad16cb47a531b591901c7acaf6594aee6bb15df332c3204cda5c3e13c4d66354ea1789ecfac565a84145a6a69c3b9e4d28786eb20532698b6da19bb5bcb649a257f098323a756d1317ab9c5c8cb1091b6724e02727f5342c7604678bd0784f209eca9a6122fa726e09f71914f968756e3c3a16d3b0c6e5fc60129d47e66ebe2618db26959ff65c728e3601f8a4b567f6a93fc43116669641b04f90482ab5a69853eeaea658c526e9eb05c4f08513cd18cc45a737dcf6faca8144927d04826acbf557c863a4dda8d99b6dce1ce32ed519b334e07d2e90463dde57a552eba27c947ee8994b3c1726891236ea0277b706e52f81428b3ea7d8e1f112d91429d5409e8d47f52164f3c9da660bdbfd4b97b070c245ae5e0b5e07c4fde1b43e0d98daa733eb5ed9b29fb46398c2f61975e5b3eb6569df01aba72397243f31779dd5f5b48274d52dc9bc6ed5d3300e85f4b7a231b7db11ff746f71ae4b61ac98a5d9d83bdee03809168ca21d88c9468eb81663668e4c1023a4f033d304570b4186cef41589b4f9029704b9029339f400cf85dee3378512242991713b9d01a5e530509258cb14b48677f26cbe437b0241ec51c60cfe24f3e545957c97fe38d1fbed6d8da7f89ac8d658e93d398a243712fe303f88d1a7b5de92b9aea95e7ecad272ead3d510b6e496dc118cb2e7e9ba46a95ed3b6b4266d23d55d6d594d924acc6818faf7831a4273be0ebd538d3d9614beb29ebea84acfde3752667772da0257958938df68624d17a5e2042f0adac718bdb2a8bc69eff7efec05b1bf6c73597b14ca9450f6329f92645c66ebbda52640e24404eaea7132de229fd68ad93489ab5883d27667ce4856154849284795a67d802fcfd1505521e48a278b620c950fb43643893cdba1524c020226cc633e82c59d8ee6c133476531556d3d94ad942280c41ba28c82a101be8b1a66a48c539dfdf2cf07b6dc29d172d787b0a4c2733823ac8333558e4d0e33e9e3e36875e73f15c3c51ec4618e532dc71a94e120a26f392d90ea5c7911cd2f3b63775756fcef0b885bb1759b2f71209affe928124e4f1fd70fabd5b5cb23c85a396e306cb72ec1d5cf8e65bd1520c9ba0bc19563711f587d15b596324d7cb19b48c98f38481ce36c8f304d5d0dd3bad8202f5687b136ed40a1b2a4f0b8514d3c309d1ef5591480d458596632d942d24eaf37d802eadf1e25037554bd297ec63f498b9d5e31c9977a79f16650643ed79410c5ef16daf7ebe626b3159560da924258a0e8ae01abd0b25e22185fd1bae4a2ff955bde0f14173e2f53d5bd1f33cb147b81b0a9491bd94c3308cfbdd2f6d558e5137a02312667634720d72f7bd690408c8e30cd45d678ddeb38300a424f4266df8914a2d4d1a1c53b8516e15c582441089abe7190a9ec0f5680e1f64cf64c812d5e992b4e6e7c71d77f3719ce4ea23ae67d0f35390627f9428fa24f1bad8581ef1ce7cd85c940f9029005b9028c3958711fb42cf820de73be9d4192034c57883948fb53fec18c26c2a3a0886af159e82872607e1c81543d8443605c9410dec68cd40d43acd61efc9ebfe5329776a1fdf8a61f6c5dedb82375dcd5a0167deac0f2b9621f57f4dc25f4a97a45e2bfff184f4ee2eddcc52c5e024ddcb0432fa6e8c0d7f0b97dad417ad3aa7e3ca1b697781bff459ed5cb8d6537d877f51bdbb68ce4cbd2d313fdbaab9c67b1f37353ca1a9c171335a760d807da66ce49e3130ebc3e09f65ad2ed95bf498b9fe673abada370924cb2250fa5818540b6cc3c6f7293c91ab784a13704c911c276952f0b4291e75f0a62a19e9a6c3f33140a00d621ee4be34fa449c92b0a5812156b201b4db35afb6927c992ffb06373e6866c9d493d2d6990e2625dc4614184fcb66e1764a8eab634cc63349018ae85697dd02727a644be528e3b158dab3a9293128ff1e99756a0f95c37040c8344dbe6318c7f37cffd25c44eb23682788431ea6727f1f34f27ee87f184cf2b7198e35a9eed322d2e132d68e330ba94ba2d37f63eee6f76cbf4d4b6b188dcb6a0d97bf96473d7cd66b7b0e9aa4ffb68b0d88557725e7074658ef518bfda60251a97573c4d84b03f0ca3679644684d442a1104d8155756a9cee9d0d635ed34a95bbc7be257b19b4de88d970512140cdeb2a6ed43eb8f9a933122e49a8c799a5c739778402290caa3bd7cb9c0706c3acbde3297be43831c655ef84d1274f5e059d6df20f92b3d97ef717e515a88914a595e94af334e619b3bb694f5177b07126cfb519e6df4c92fe4d05baa58975ab699ea5cf11c248353533e1b99f46f97919db8bad433c1613dc789f429a89930aefa7d69d7972cbefc7982a520e646b2d3d90f0282707ae5ba3cd1996da2ca8f4eaff901ad4090eb93369fc17a7e5dbc7f759eaea0",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x68171aa479019708e5e62ba9855aeab8ee8c76440b5c9765fa4bfb097bcf1db0",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x97473985d04723299559f49b856effb47d7abfad",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca23f0",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x226af30db5c1c8b324396dd10c04b7fb2d94dfb501d30ae0aa4ea3738137e6d0",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "size": "0xcb1",
|
|
+ "stateRoot": "0xf7dad77291ba6d2ee81e0222b1bbbda94de8a9de6819f0ae298972bc1d0e229a",
|
|
+ "timestamp": "0x6a79ff5b",
|
|
+ "totalDifficulty": "0xca23f1",
|
|
+ "transactions": [],
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "uncles": [],
|
|
+ "withdrawals": [],
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "chainId": 2800,
|
|
+ "id": "2800-v1-A-7chei-anchor-13247472-baza"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90277a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f90192b8417c3fde9ff7d4342e27cb063247f82a99e42d21fc529ab685d5f3dda040d3897b51b1db1fe29c81d4da8c25a26e1f46ce34bfa81d54eb859c3e3fe93fe76dd68c00b841fdaf3d94429317423c74bf4b514ab858ca3571fde06e29c359a4c57041d79606796e792139dac07f7dac1e744400c9ed9bc28d440abdc1fe008e9a3de4665dad01b8418d465c6013284fda736a62a10bbf59941fb6c688e7ccfd87a7181af9da8a36db515235d892331146f49579563059ffeddc2211096eaeacda1bc7ca53343857dc00b841ba6965c9cef9f6aa8588f42a2384fd31c6e951a81dbac6c0315cd21db536bb2a7387e15a567b7fba44775d008ed07e26f2d8a4604b60822f33abdedeae9a2fd301b841397a695c6305c7eca63d13de07692032268e93c5ba3be484401daebda70fed1230eec24c334c9c31476d1fec4aef249ecd2ba8bd888315476b7918954804f97000b8413b8735c7eb1cb795ab1ad33e31a69e85b92f24bcb36f2894f22cedf65e5c3bcb5badd071ed2500c706d0b23414ead650df186de37c212f8f94abc3ec0747b1b700",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x0c6249cc8c2696fedc258c9fe25031c309a69ff5a98afe0d75f462f84892f944",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xf73bbbd26a82dbc769066550d8d4585eab2fc00d",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca736f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x579eb58c0e30d394a5c24c7af542427036c36aea26b0f612e7e9df722ce3558e",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "size": "0x4ea",
|
|
+ "stateRoot": "0xe3c6f8322bbf555693b48960f29263c9e2fb1b5d54866e69d55b956e9aff5ddf",
|
|
+ "timestamp": "0x6a7a2bf5",
|
|
+ "totalDifficulty": "0xca7370",
|
|
+ "transactions": [],
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "uncles": [],
|
|
+ "withdrawals": [],
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90a39a000000000000000626573752032362e372d646576656c6f702d64323033323031f8bd941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc001f90192b8415f08d982ed0b0a5b9c06e803b60bbc65a604f53b008c4c0ed7d38a9a9b9c63eb3ef11bb3067af2b2a75232e3d7fb83fc7f2915bd58193181448977a1d1426e0b01b841f64b1f24665600f6f79c8636d6bba2aa293c69e1de9fc37cb0a17e25bba939c248bcf986a91a6ea5bab5b3708095931dcb1c0aebd535f3c574f1601e5a5aed7201b841671fd4be7450fc9181f0f90a28f9a0be1da6c1a49b1d985fd1f7deb4745560c728fd599a8aa83891ec32fa1691f159141c9d68b44f714fe0fa4317834128b97800b8414c178a0fb8854d5cec142b0a38f1e119212c2704dadd0b861e7f2822befa9bc97295fa77e96517cdeebb37687bdeafcacebc1e62f43e1cf89c8715922c2baf1801b8415580797691984bd03c96fc6f1c2523a6fdb58f5f5ffde735e7c86e8b849ba37541eadecfc95da24a8185ea27327b5c2e23e8ebc63aaebcb59c611c14eeab2a0d00b8410c1e0e35bb3725bb480e9858e8de56b5756de22b104b09abff0a6489bd13b2af78aab70352a267ceca41e8279b6f5596f4d104f3f9fcb857e38c58803d09c54401f907bff9029302b9028f397e46d850639fe02d5a580ba06aba3f344f932b7ecbd962a20d758af765c80b98534a52d1be2de10aa583a71714d32ade22fcd7e759eb3129f5407712ee999419b4a7390aac9e06b8e851cd2eae32df7b50ee53a90b75b55d3856008c7493646a15e76476906292e7b33b463250841836a17db54690158b9133f46a94add1aa8b6da08719c4849b552e1a72555de9c7f9ab3212b28872f137cb9edfa9b5f8e9d0ca66bceff699748dc0aec2d71936896e42b30d8cf90e3ef982c58b428a047d1a43b93ca6d118585bb31c6112f9264504936937bbcfd52d4760cb3b31a0b44a61265f7c7bb3a5111847639f5c510d395f996d99b5966b2e148e7d21de8e768bef2789dde9a618d527152c85c049a4c771c9b2c378b026313ed67ae7572b5753da5fe235a663b37564b70561bf82283b9c9b8731ca40a059362f50beb4e7129afbb33ebbdc3b68c5e719c76a97484e3475b3ab264de66adbc8591c8482051ccda0e667e8c81949beef22b0564dac77c1f59f69e0b3d5ee5f81628496eda2cef2a6fb28a99cb6efb7ba5b1e12739a7d37ac416d6ee49788d0f6e112864a08cfd755ff86da0530520c2fae75b8448e052587a1abb06e76973965aa791f938d0845a9174e855dfa8fb053cd7c00ce891667d7a99c61ca137ecbb9f16862a86b5d34abff5a349eda6dce53466aa3afd65b168471f96492dd9f539eb6a31a9775ad0a5ed768239c68e60bf085bf7b336c40d5b6afc591c67adedcb95c5a7ae96af1c347d7f48d4b779dd29f52a6723db558ef6a7772447abc38f1966b669599b0abe108cb289aa37dbdff37b04d0da2a95c5d9ffe368a1f8112227ea1a5c30ab4aafaa7ed4b5e94eba76dedf12bf85e6d57e7579daed3ed3f7cd3a9dbd11b937e9eb5510e3a9478a383b4749a27226f1c40f9028f06b9028b397a93d74d3c71de9e34f9bea196cf8b7f5e571d325e28590acd4974dd3f8fa373076ba4ce2577460a1d7a13395ad7e7a9d118d7ef756e55a9e993a3ebb5bef2fe678b93e2abe4d39285349d4df70c26235357a5a0bdfaba8d9a61089e697f942bf779f547d7936e9c6aba58f09b76a05a35ac1f2b33c263f25c7b02d94a23cd0dcaef0c582990defdba1795f51903cf1722ad15af50dad6789508cf8283ab215004dbbfaacb0a0ef3bda8c158a469ed3f1b128ceae0cfdc292985ef53553d5e85bf6a9f0ea587da2a98b4bdb3309fc96c599d5bd0d4348aa249cd27ef8cc2d54d12eb70a317621291b674086f5d01a7c94649c54d64524a59eda8b00ec259e9c639cbc135c8d93ff36e25111db4e7ffb9881f3a19618146d0764aa283c6b7b4769a81afe5caa4dc4e45f34eb66c3712694f38c6a167cdd7cc7088231fb8d7dbf5f31401174825af34309f736b923bccadbc24578f8f151e648f95ee1d45cad0740396472777dcf4bd3b5a7bba798ee538313d33233927b59b3bb0f0b24bc652f9f851a34a8a773e505c6ea44f74bbc1f62a910428504ff615459d63d1c21483a6ec1a06bb6352c797d024547d2d2c905bf5ca32a3a39d1132a8e4f1cc1683ed8778b03cd9f9cfeadbaf0c6601fbd85828bb613cd0a49af20177c0a6b3aa46cddf206fe3dec42190b6af1ebb617afe7a3bce2a950f773f4dc6c7d45bdb0a2296ebf21123936464203013f48214021cb5e3eacd796ad0a5d24ed5b53b232a7bddf1ba62481aa7ed8e4bf9c2ea43ddeca258a0e82a129864ecb47f7e6a1d5a82c03c8d54594f9568639b138d9a2c1014e99ed17a75ef021fb8d355bf3392ed09a97a1bef54e75b1bbac1c97b3bff6eb9f5dd365299e2b0347fdd611b6496c6c1f4de11df5aebac6d7944d6b9f9029401b90290395b67bbe1dce532045160eb78703d7ded3a0f9f44d7679c47f8d5f743fb3237a3d87fc456b19db03a49f865934b29b46e8761849f26665488c232b886f4f811e532651978d8e7bd2eb1dd0b7c694539afb34f219927c9c29f04df371cf8632fe4673c79fa1495a74010fe0994409eabb578dbee738db55174f4c8ef889edf4b3315de05770d7dfc25ac9df9c14110d57651b36070556a0ed9089b6779f92af53d996416aed1ca433b0ae0ea6e7ea9eb0ea2bfbc5abb6aa36beee86b039b7be932e59b4530a84e0cf5b60edb507087077cc23045967ee7e5e3332cc6a312f9b1c69ea6cd90e2474ce0d25ef5e15c6ce67df82b58dd5cde64cd8a408e56293edbd97d935ba52c82372c96075e92f2d0bd42468e2a99da4b9dfad5c5b2f2e2224a3e1d3ba64c6a3e0b6e1b831e18352af53fac347d4cfc01ac545315293b2b05504fe6a9f323c93248fe493763b04d3a0a709f5ba405cd40ea7e5c6348c1db27191c9286d81dfa71fd67fca4cf7b48645007637ee87289bd3d41f021f17a725ce409fa3f87afac7ba4cf6b14a71b1ab57bc123d14bcb6200eb12e401b19e8902f498321c9e0429705fa5991682fb8747cd3cd5e0b4a0dfa83133a4c3c6e0d54aecaa578c83c9a8f02df48572fb9168d457f8d4f0314cbfd7da45eb0ea6403a576a7d362b8bde647619ed3262f85258960a50eac4570a7c64ed662434442a0383f25b6b398cf21ced2624979df319730e6dfd3af6790362bdb21c3d4744be67de0f07ab0d1caabbb7c46f02c018a8cd365c8c674ee49594ef64373ad81f7d27acf30d421bb9dc4768acb6b979f96c545356833f1a7ef2d1838519847ae7a65dda28e909cf936bc3ebc64eb9872e6b65bb6aec95031d40d117ac2b4b32cfc0761fdd04e52cffe62a874a2dcebf3f52057880",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x2e80f",
|
|
+ "hash": "0x5048e837440f072ce6e0c1be04370abb62a2bfd2f5612c0704eeef46b64d6ad5",
|
|
+ "logsBloom": "0x00000000040000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000400400100000000000001000000000000000000000000000000000000000000000000000000000000000000800000000000000000200000000000000000002000000000000008000000000000400000000000000000000000000000000000000000200000000000002000000000000000000000000000000000800000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000100100000000000",
|
|
+ "miner": "0x4bf6f91d84b37454544279cba152581ed6820044",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0xca7370",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x0c6249cc8c2696fedc258c9fe25031c309a69ff5a98afe0d75f462f84892f944",
|
|
+ "receiptsRoot": "0x680d21685cda7bfba14ea6b1313d7409149b4ef07668a55b4850274128829bea",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "size": "0x10b0",
|
|
+ "stateRoot": "0x9e9f7bd15dcd563a30fbe250c899870086522be81189f0de04593534012a9058",
|
|
+ "timestamp": "0x6a7a2e13",
|
|
+ "totalDifficulty": "0xca7371",
|
|
+ "transactions": [
|
|
+ "0xf85046405649427d3cdb0fe81a4d34bbdabd8b101d420a31703b5f85a8b16794",
|
|
+ "0x13715ddea9aa2554f9c64eb158a7bd55b8e9ad50fbec425413571ae6fd442066",
|
|
+ "0xe74d76c1da00de939059816789886f2deb26a7f1d2aa61b36c816dcfe076b442",
|
|
+ "0xd5bc7516c606f1ec063f8b05a4ae5d699a8915ab4385c5f3cd4667b703e96ff6",
|
|
+ "0x98f9298c07db326ad18e2502b15036d2568b0fba795ea63d833a8d0615f3f20a",
|
|
+ "0xe4405e93eb2ebef6eb5c15067733acdcacb2af4bdf46b185ddc9e906c72ac881"
|
|
+ ],
|
|
+ "transactionsRoot": "0x31254d9e400993f1e37c31b8c695715d66ae26bea46b7f6148c7ffe8b2620629",
|
|
+ "uncles": [],
|
|
+ "withdrawals": [],
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "chainId": 2800,
|
|
+ "id": "2800-v1-E-reguli-oprite-anchor-13267824-baza"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf902cfa0626573752032362e342e302d616572652e312d643230333230312d7774613037f8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b84109b5ab545b14b3e5f565f796562a70e82bdcd350a908235c271c83ca81fc034309caebcdc1ea84019ff42cd8c4510350bd8f223bd598e567059c542eb2a9697001b841d6a1266b15c53877205f194bbdf9605cb049cb01924712e335d8d3d8da7662ff33c4411dd775b858bf6e17a766579ac6eb32d86dd158c36f8af4b5849882696601b841bdd9cc7b80a30106721f9833f79a2286564ed023aa3a49591efe76b37a85ea7257c3409244971b3c9d314b608d54ca6c4750c8f09c963382cf08316b81cda32a01b841892146f1d290ecc06168979daabd11d74406a43808565c243be2263bf0f3332e103ddde0fa281f22c16daae42bde9481dd3a5569ea5853d0731a4f139395f41001b841e111c16c9d1523fdc9f844e939cf027c0b64a7d35efdb71c9eb5a55a8c5dcd7e0702c9dc285fbcaa609e7aa8e0862fcf60cd17f70bd4a6f640473b1b770337c501b841b820a7379fcfbbc22609b5707428dd3eef8c1a397a271338961520594ed1453869e472e1f74e54be4dc595d7f7e08fdb20ab89a768af35f37ed0dfbe9210b8fa00b841e00d30479e0120706f974727f9439062ba5abfcbb750cffa8b9a30b14379fc9f377dd9a15539b1ed0d5dfc6ed62610960c1274658413201cdaa9f1b40861d56000",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x59c6a628fbe05515da2598d28cbeca17ea6f3997c6ca34d3e2bdef909b636c4c",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x5f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb0",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x137516f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xc434643c512647b22b658c0329f23d197661253b6134211f2b0187c5e453fde0",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "size": "0x543",
|
|
+ "stateRoot": "0x076885d7c7d6311acfe839756b85ec37da9f342bc6c3d9317a789ef99d8ee8d0",
|
|
+ "timestamp": "0x6ab8f378",
|
|
+ "totalDifficulty": "0x1375170",
|
|
+ "transactions": [],
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "uncles": [],
|
|
+ "withdrawals": [],
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xfa012ea5a0f7b037c0736e9ba65ddf1f63144fd64dc13728e9ff38e7911f1c15a243e0488ff8d2941bd5514286f5602a6762b0075266379d29af1c9d944bf6f91d84b37454544279cba152581ed6820044945f50fc4e1b129bbd5e6e9f80c57680b0b4a86eb09497473985d04723299559f49b856effb47d7abfad94b5e768cb3117ea25175f51aa956b48691025c2a894c3314fd768bb68b986e80c0a14175f6f72630d7a94d38cb62a38c1d4a5fccef6bee0f2e177ec3c9aa294df09b32c761620c5be77da398b97a64f03c3980c94e13aa491abbc1252dd714e7ca0e55717a2143eaf94f73bbbd26a82dbc769066550d8d4585eab2fc00dc080f901d5b8419cb831af3dd73fb774d47d240d08fd50d227aa603790f952ea47fa0cbb47bf990edd4a8c1159670846ceb1521cd5748e7e22157f01324a4d48efb80c8cb74ab800b841688980f6c2a6fda513f1842b6e9c8797f160cb5aa154efff731ce5f095ed650a24d0c0a49ae2cd9277d416d8491a62eaabbd7c1cb60ee8f0e7e98ae271517bb600b8411f360b679891c5064759d36945a9b53c569fdf47e776fc24a6376647707ac4815803ccdbec84326e92b83a6c01095ca7a8dd79e07de708863f89d83fcd661bb300b841de4ddf2f6a264d6da9835d3d98a2684a8ff4c4e994284fac4239c075dc37d8fc53bff2e9b399707646914477a9154daa90653b3cb19ee876a21b806b9f1db37000b84180fbe602be6e3dc9869d70093b320f5e4ee86954b018c05b0cda5972371ba57466d44436d17531979a24de6502739846b6b0985445734156ff670b94cfd1a23c00b841b0847dcb70a1f3c210a670c7dc66e5ec960f68eb9e1cdf59bf8c18c73600699b580b446a582531cea5e0cd3a3f7a283e783da137f4fd23d39fd3bd768a30ec6300b841299bf7608c2e4c0419efdcdb8065f4685d5c8bd3d7d03769ec1921d3386748cc2e99a8d9ebb5ff0336e2fdd5175afc3827fb4dd9eb08af7aff7d36a186eeb2a801fa012bd202fa012bcdf902960180b90291399fe60b0f6e43950b3ce5da2efff9e8b50c9b60d1c910b5281d3a1a48c49abb777d9486bb57cfbc00c49fedd1643c4b92843f2b863b1b99b717ef3f4cf973d384657f8f75b2282afa2718c1c5993dca25c03b9b74d323d9f410f707610fb1a01aa984efb29aaf33b3a2876f972b5b7729c83928aba8fa6f63bda8dde7781b68632ad244faa54705ef434d7fc18362200494b6a629326b6c38888745188561380552e5297fea1be8568107a9e26c956a369945660c655fdb4447d6c28124381ff5c1baf3c5459849f219eac67967cc4f51a339a32f8bae47ce447bcb3956d2cd88811ce7ee68392e320d30e2c9a31f4fa3268d444849a244dc32aa6f19dc82ada96111d34890e38d1f24c62b7f245651f683e81be32741561c22c13b853330d7e937c969bf10a2af9bdca56e5288c43abce5bead6d6f1dca42ef6adc63de95e137bcc0695f57537ece32ed3486ca8ecdecf826c125e4e4a2cc6433258198225898a42eeca19dcbf6dae4e420c37d2b55ec2410ce24891695c156f832d49ac389474acad2e4216a426734aff2aded7466ff87d441d45414816655dc29cedb1cb2ef26cbe57d3979a147b3325a8a6242a4c10db64dc9a8cbd9751584ca686b8d322dc4cd220b0ec6551577cfef6458f3a6f65cce2344ddbe435ce232cd761f9f9cfffe35199833f3a4b3da62512ef30ef35829d17ce58a37987a3e4c1b579355fc94b8d511c0da9d2884112c47688d6d0218e4418215386855bc2fb10c6a4c9ff5b6537cf4747a7e81a408f10c90f5bb1746661ae96eb46c5a3fe06a1baecb4fdb8accf74966598dd6f61684845aa2db33a975cdaad1b923ba5f707eb4317b7e50e4fd689644d9c57ad9bc71f4f8e5afc48865f91c41cf2e77d42083e8e28a7ec99a4ffbfe0bad1556a3f3cfdb2b48640629f91eb50280b91eb0b790bfdd9fea601a532bb29241d563d1522f8a06a39083c900455446bc96b2f576e1a096966c6d206f98b76726eb9a3f97a49443e52c9f47f3ca715a2b2657f3499565a54306d2dec4d678e2af5fc9bd127640b19fd00e6f295b8b414f514c760db2ad5b6d3a7c3058c68bba6483b20cbcc8cd9aceeca7e9f4bb0319b8b151fb386382cbde6c4e234750d4e145275fc1b2e114902d684fd7e7f6aa270e64f4de760793b6f719c8bf375520e7ec38843f5df54ba390623400823239bdf76c84eacab05c65c1f4eca78c54d40ba70fd772c19eae7598d493c41d7e4363e5ab19520eedea153bbf38d4042ce6fe1312ab4e347b38c66c7e3a3618ce641acfd4b60f3b33aa8c774c4a2109788f7d0dc2412d3f6c3a607bfb27ee3149d5a4d0ae82158c3c15eb757c1c1380798dafb35fff4d70ebbeb9ceadeded1b55a67befb11c1eb13807c727f773b37a3ee75cb723661d5b92993a09fba147c781c5275110dd7e9b0dd25451be9ba805f87e7d8dc99fa4bd1f7e011f17780b36c59291af85ad243ad2af7864cb59a672395248b3ea84433bc8a9e43a1197e141cb0de3e5952662da369b55c7da12057f585b0bc67c10422ba6df00c34a1362c86d4bf111a12008c995d73218e257a6fd9e847504aa3db8c1792cec5725465ecf47d0f33a20f296f0888045166569a325d4633fe1b4d321482361685e12d2eb5fcdf0058796fb4aab53c24a842b1163498cd7270e300b0d822a9bf06850f4f754f2cbbb1f4f7635f42ca93e505a0b6d78301dbf281789d0fb8e1fb6cfb25329200688035447b4d1f154f0697092caa99292d25363a06ad321f2c820397c1963ec7c62fd597a021043e97ed90f99c15d25ceea39f28cda977a45f3b4f7b934804cf85d4b32873f0184d67d44ed3d5ef62c907742b0eb61587b995b85a537e094f50a6485c0a8df27c638f8c44358628e2f5d0b58ffd9f089b2a2145d14ae122382486ff9828aaf4f0fe3cca551593717e2c20a6b890cff831ba61674f9088dd9a28452123c1898ff36e6aaa926cae5caba6a5f6c9189b440a19fb863ba82470e8652f483eaab8eb90d382a837508c4de531837697913763b9b2622f5713861f55c26ce80246e5be125fdfa353ec11dc32a84a83f8ab5a2d2b44ed49abb4c513be03ad9968e824c0ed4a0ffe45a49692393693106bac78972d5c46ff102ca59879c9b45310414e1b2f3dede3f07f14020a15dba08f09110da1267ddbd16f4274c1e3bfdaa73044d81a8f9c6914e312b3ee3908d1cdf6f9957e5ac7aa449dff4069291936ac96ca289baf65c04a71966f36bc5a4c38abeceb95605d35451a36174ed9c96a7af41df917dd5b2cc35f4e088294f1aa9ef064912f806da33865b125db5d23c5c3efc063a1d9869e76c96ef1e1284c98c1271774f6f97d5135228bebda82893c8d95c23439fd11733216708de7ce7a60447d410d49d90c709a11524d87e1d2b2f83c801bb175ef75cc48afca2276ac2ed7051a72b48ac37b5df855e67d9a667aa0f08abcef15c376795a43483c8c153d77312b09b120fc93fe706dfeba166ed67ba1718a63bb2d03e4731a242023e6153e0bcd0a3db1c2c534cb032c60462422aac19cfcd19bd42ea8639dbb124439fa6581701e8e879ed3d332390254d02ca9fb74f4edc585c30df73549ebb2797c3fc2464be40c9532fbaf543c88a1409a6a7bf61f9611c9b85f60563a43dad0fe771d664ccfa7437011add0a9d07bfb19dc3a89326a255bfc46aa4c3530cc3fe10488117cc6260b2548758c148d8859f3ecb8552922e47ca5dba79874b2c593cae2508b55788b68fc5a14d00477bf8f2dd57622b45e7e54b9d8a2df0ef67a4ed64e073f6c8446f3e9fe7988b3c482b72c09a3fb50f756538231451103fcd3aa401f82408accd9b945472d6d92240f3db8360ad771aa7f74261743092fec7d0eef64ff62af06323f8f078d1cc8a754ebe0b2f6f66f665cd08a6fe86a2c1a159c888609ce249cefaea2bf96e72c1678c37213f737c35b453b9f311951c9b15a9f9fda78fe4e5fc8e73de532610c2ce55a7948d42ce513549931bbeb60d28b7792d6030068d7a72b445d66eeccb2a3518d8490c0350c37620c7b9763866f02691a196a49a70e2f30adde16b486c12714dc77bc5152a9c7594eeb7126a8740c693f756559c1fbd95c900ea09b7685b48a503bc1267d39ab4fda7088c68abc4b4d0d7f5c0c5b3a6ce33ed6fa6567230c8ed7d39c970955843938115ea8e6c86271239896b66c148171997a5d031ce15d94280c4bda24f15815dbe7c58e1dc66128ddb9aaa502295eb7186083b6c2ebf2fb7e90f932000e1e2b03d150cbd612171f146da072275c4ffe4faeda56a7d253d2c2802989e54a423a81e151791f64a36f3c377dd4fad846729aa9f8b77aa9210596e1dd56d6532ebbea02f845d2328993f3e90dfea60fcdd109804833b860e318460b69401dd3c2809484a528b8a87f0e68a1a267f2f7c86735b5935f8326a54272e6cdc318a713d64816121b12e8e6d0ed84c5204f903a4a698c0e0e4867e2cd58af3ce070daf9fdc88338413b741fbb888739a663670ce7a498997790a52fd42577b50cb2c9cfefdf06a1009bfaa31f8e64becc8b615e99203d51957695b4956f86964b5e46e7ca05f830638dfa4abf9bc7e013bd2e7158428c27755cb6fb5b306808b04f86fe4afa9825169305ce083e36526df3200141dcb9a10381ec651396e161a2a8afcad8b1068655d918a8309b0fea43e4611dd76085647f0ad0863b3458a8a79cff43d2e3a1f60b6d49f42759c2bac80cba68d8f57f44db1c3eacfa4ae405b55322154b75e23a8413845a42b473ac1aed1f034faab0e1104c2968c90df8e563c33662fb208a72bafee62596589adfccdd391740ff0756511f81286f853dfd927a6b847379433c31c54064b73870b59df4dcf91ad7574c397ec055d1805c6b260b443129688812c1a25062356ff8c36c88ba3dd5b292769f9927bc206909531e8cedac0f4f3ba5131f3e86a5c85a8537507a8c7b97c0647d38942a08c69a9e907bcd655a746f08b429346d3d108104d839c77ffa504776fdc94d6dc1eb2b40e2db48535748019f290d55a6b73943c2dcaa91c7756cb66683a7a07103b8db40b311e1fb8bfb769d1b77fdc483e715b11320a39123aab14a5bacf39aa82870cd06c9e7dc90743377488f0381889f72e6a3c5a9c1bbd685eaf331792e764e68ee9106a60cee0c8d1dd3ab81e00f9fcc5b24a928d1d4e149d40778f6091f8c7475972b1654d329219d49b4c09a5665cccfaf6fbd7530d4af68f35ced92b5e7e6ebae089b7988ff092365ee823b94fb10d2bb38b8716d5e84074871cc18b29494bd56d1f8a3e599900c4d954734aa6129bc31f0a9798373027a379247e4ab914d4d767fe49ea2d87864b09ef7851169aa2da1e0cec406589fc2cd2e4ff77cc9f2255c3b8e609c6caf25821e228617b76d3051e859d56c3cd13f8327059405e881c655cf716045bd9ec20d7210f1d805a7c6579c56a8a437d5bd92f7ba682a662deba53d2171d1625c4499c4d061a2b9cd8ca3ca400873c3a245f3156deffaf745b439ba2f99dd2dd2f07cccaf767f9bc17307b86bc4da77e35e871837f2ba52f0bf20c2ec333c19f67df29e7477c793048f914ab175107fe93de5fe7e14192bac574df54b9d123ea7f3fab9acfac9114c048e62e9394a3d638ccf91ed49851845a90a065803ee15f7f9aa6263581b6db3ccf8550e2a73ec95da6fd1c95a201c0022e1cb960f919fb80b421319d3a4256d507d4f3a9a0d71f6d6977f044bac8b8f5cb61a8028aeba58aa042018e1d1e657ea530acdc366988dc9289d60e3b5afb207b53b8beed521710476a32c9c32c3ecad510b36caef5ec049f6ff8e3b9184ff26697056b5494880f9c37caa154c27bb6d3146af438ff8da6a8e9a702fa62d9d069af500fbb00c1fc0f6ccc3d67682927da3a456f7f0e6ea086d1a9fca96d2e2f4e4d961cbfc368190773f82b2b868c4011f1df3aa7bc90113aecff370c0ec40732049ec191278daef3bd3a6942cbb91b3cec38f4153469eaed731a7e3f2d7d54892b6dbb85cff1bf716d8b2ab0cfc9976ccee5f27ea1250ab9fd168ba76ff1896fa617db081aba856611fc943b917b39a26648be99ee1a9a56e2038710ed669c3fc5bbcef48b4016cef3e2eaf14a54da74bde346cabe10ff7969ffc2c3093ac2d983431a2d919da8c575ef296f9afcf883c4dd88f8cfa5c0745d2170d2161935f2f3cd67ef3a808da40035db7a2c442d9b780fb96ae18013d6322e26f9ee8d3d49f3ae6952b49790575f2573702a05ca879a56c4095cd0265a86b70f76b84fb609d6bf1605b64716d1a7918286c5eb0c9dcf28d165dcaeabd5c44ee9b63a1fe5bfaa605b300fa7bc9f82ea6da6209eac62898316f6600f1e45081b7820df0f7bb43f44086a8022061f54bd32b6c6eb1b6c01169843996193089b7d73b24bd858bfa3269c1682fc02dc03dd0b37d9be83e3783ee90595aedfa18c78bb9e7f6e878e42424fd8ceba4852dcc496ee1a60087d8f72830bbf3b8c1b481207b653b8dc33c8c4b86cd534e1e4bf0adbda8037bdb85fb46d6662daf3eba61b9b19b8e507e892e637051235f6c81f0e57e56dcf55ccdaedbe786f5a574efb23f7eb066e787efd5694b938bf4666c59f9159102ff93701bcadb7c624fe465214dc462eec78a79ac464f331bd6b3e0eda8d53b466b8c951d2bb2b057f07178719c59561ac6c81d5929e820475bf23dac266aeb2d260e789246cf32ebd7d11b9f96acdf382682d2dc33abf79248a0fe3c6f7806625c1c9a4040c1a5f15d4cb4da512f2a119f2702d991cb7aaa8eb4e2b2f824ea2eca09f2a89070d7176d34a633c46d925612aac55168e4672e24f4733e3cc635e3c81d8033397d7469cfbafec8d698058c612477eccdfde041049b70890802a07dbf07a2a7402d8429d9fb9c445db868bceec8618822898f4ac14c87bfadf7e45a8f6d111960a591810c534da42008d7682664dda29115ed097002f881aa4f64df47b033d48528d8667f1ad2b819bf4f8f1f0f3b2d43c09b0b4f25cb62bc6fb15be4bef418417561c19fab5b8a65f173f70fac0c3f6272758219351050772c62a04a920d19a2e1e6c3b27b73e9ccfbd9a8efe9e7701723bf8d2f9734417526d74187e7ca141c9626b346c9973b740897de62bd5368a5967f1d2c349dc804f2db4704331777771bb392fe1581c79959c0db8b67b78473ce9b224529a039830bed99d9cbd6218555c27d9fb4e0bcbe3a37656558e2f1c00555e285bf871fe503d458c371a6bc28b6bf4f8789c615f38ba8b284658d5b48f6210ee9439c3f6fcb23cc08e0b9ceaaa4218f1917685c5baa8027e4b95e8761170901933851923ee6d76fd365adb1ca60a3d2d69724981411956f4822ef957d17f7e0b08a6e114ca0fe5c103c81ad1cb74fa6369dedccf969cd20dba5beffdbaf3b59efbc6daf28213ff6a69ee8ebdb1ff8e06fdc96610ee065f79260cdd02ffd4dbafcb1acd3a878d9392cf1eed5d0831a7d5a76a4f84c9cf7609dc9300d3c4bf5341a9abbb46428acdaa4a3dffa909563c03df66e42d1ac32eb2ba1c5c35070918b61deb4e934998f50dac460affd9c2c0d396fb1879a1c00f92f741be4a8597f2dbc7e824a0e9134fc2ccd57c2cbdc876ec51fd8991a3378c140706e755b91ff9e9ade84214bf56e8b6e1e2c2b3232e64ae5055aba187549aa8dde8b18564ff1e8fb172a622fa6abfaf485330a155f8a79f936e167f0eadbd2d8217ce089262dd193435274dc8f38dc855af49db92b6dcedbf950752d4f58f1651a29e4d78531ac021e3c1c203935d2eda79f463c98b824056e5ffd1895fc35696f356667c9e3c460770924b593d1ca638af5be83898a538538872faf8e3cac1c341d768b019c075674bda03500df20a997f68115eb3c41853b3a825b6158bb540bb2602f993f6350b5ae6c84311c260047116c668f68b66b842c32a625401b0770c5905da8022e9c17e20d225ebb3ad9d3d4a1efbde9a40f96fbbdab6cfaa25b94a934ee755acd75997277f34033d5e2562112993467983575d53e2a54dc3bde62289cd949dbfc375f51c0ee73b5c48201b0b162792e314c108ebf98ce177d661ef736c893562cf4a747c5b7464da0373f44760a1ce31743f4902f225e022d6a7a1f352d973a6ec81b4f3e8393c0d135e0b14d8ff9b500eb40d5bd377e5f80e418ef62f44492e67fbd7a7ba5e5e8b3c4257c48e53ddbe11b436e37462a43aa8425bfdae26e5a50a2e83a8e153e23dd0150aacb6c65fabbc770387c682a8d73549b92857f525012f40d6199bbd039349d6a996c821dbcea021c389f70d6aa5cbf0a4b454c658fab70336bbbae515e8bc2d4875ba74fd06949c34f5343c88135dc9785d897cf9532599e1e6c117cd7c8be3dab14fdaf03551a9941aa0e30857d535ba1b5e6ab3bcc0da86fa6de8a265134ed7c2d29ffa672c37b5447f21ff1b9e01b2428c67d63cc5981b3dc81dd52c5a494185e41b9628f003552ffc83c1f4bf5d0f074392d4b6bab8e99fa00ad33673e0208ad40a9e64784ff9f3f5369fcbdd20667928546f67e11fd440441b3c9ab7878df62e1a55188ee1ac3a909127d45b63060308085a905675c718231e7001fed392590c3088378a601bd59aeea967e024c7ecf06b9b51100ad0ab23bf27fcbbebfa4e4176540a5e359a3311692def3dc969241b857e3a7af36f14816b975f2dba301e6f8880c7c4a6e209449fc5179d7679ab48d86b96dccf706e0acc803a96816fc5984341e7447e8ae8d2595db9ca92d2eeefca4271e17a36c725a443e4b8be302c46d004f5c95d749a5117b299b89b629c758ab662a7f4a83da2e2a60a2967107e9c0ef775a10136dcd69d2d50ad5efec262cd687b4ee326f978676d7cb3b09adff1e2f36847ab07837983ab33c8e45399e3d0b570afa1ea87fdf9c1f7fd954803d73ff3c43c81ce038e39bd9a31086a7eea6e59125c73715c55aac3986254c8f4165be33824f7861ada418785f43eadac5fd6ada0566a2d517cebb1026f220b8afdf248fa49cf3614b1530b3af10a4e0908240bf62a72f2a50dbef1227d202290145ce043cd88a67c65dff6b691c27db57db5c3da3aee9af5d96ac0678f0d797b5f3bcd7c712f1070adc11837741f24876c42e3b1c5a5f134c0d5ffcd4b931301349ba06b27d9dedd877febe0f2e654eca7fbd860f1edadc1f63e58b334ac10222dba80627fd9599351932b2dae15e97ce087b80173f7d3542d6586464a48c47fe14ecd5b6a079d227d201d8eb264ea69cc17a83ce7c13bd5ff75adb3fb64d537070ce7e61f772d6705a37a946f0b83bf3d4aa9a82ee5815b839e5231a3f70c802d254f011072d7ccad62fa187c35540e9ab9bb3267a24076cf024e9b0b296305c52a0f4188e34367d090d3bd9be4ec834c4de4af2fd75277d32500f61b10b5298461b62e915d7eed67650e5f195d03cb16324cbc69eb1834b3f08225920f6e292cb964fcf869494fe117bb6af16cf45709a53f0089bade23e54d70161fb137162718ff2f09ab0c4f757f93bd7a7d9217a20d5f65239bf8d613a7517776d21946e7e3bca5720d1fff059e0279014a380305ffe3d035d6726014b062e827105411dac05bd5b7b4d31088c0f67c07aa71780675260e9168d824d5b4f8d526c95af06d1c9721fc1d9333f3ab35303f1d633bd777275dd20b9440cf6c4079ee5fa4dce973623eaeae9bb25edf8ed983d8a003bb65da4d0cad045ad02f31fce5564b0dd8ca7a398cd9b7c4f16fd0f4db23ef3027a458d1e9b1e215f6e79c497fe6b76ffaf77cef9095e8c6da739ea0ccf5bbb1e2721a186d2aea606ae419fda332a12a31922947ebecf856b24d311bfc3e5de50b1971afca7e69dc011c9db0150f6429b4b6e002b1742029a75f2e95c7a04695cf63795467f4386557cf3c35c83ebdbf7dc8042546051ed40bf2c84f98b928872a3c928646ac492e342f669a5295131ce53e6050b548e41cc28af47ca58615d27ae2e5fbfe1755b3e41c2a9f8810a8092b4f90c4267bdcd6dbdaef00b5d7455f51c20bb46650b5081731909daafc018aa8239a2154dcff850c62d6ed783eea28fa544fbe35a3dd81e9cd7b82a218f9fc9291a0536d03417f25d7da53eb4b87a59dcd1ed152ad22a56f3b0b8ef63807110bd30f55c43c852bb55c2667fb55aa218c3a49bac97fe321ac6d4a4b10799bb3518760c249894e2d968849b12fe25acb641290c076a6608a33ad510c9bff673352ee684394172aacedb1a255daad43baef3d90343ba847fa80be6dc17dc2bf767b89f1d7c39525cdcede8449c1f4eedb568b5828c8a01ea0652e909196e7c1d4b482666ec81fd0fe0b6f0c9bf0894c8d902b89e46b1706c2109ad05232d434cd17e6bced81da06ddbe99d7738b17f786e7965282fd6a8f9fe97430801743f2d259a844463ab71e6e528ff0bbb29e467b620425c2e95132b49fb36bf189817194b54b926845a0a9f1fb097c97ca1f219b824ae79c9929cdaeec271e43767a804a5ad67874172eada327bddb7295236750729b7bf013be09a34e5564c298000c7d591f999b7e525af44c77c793d8e5397ac5ebb14fa4f3e556fc668594a15f95983fbed2fefdbd2924829bae643032dea195cc34db288658222e67769b2c6a68536f34c952a8af14367067d9c23812c92e548c187c20143e9917fe8b54261e4e6a7b80a5ce3341548a8cfb40313f649b78b019630082bbd354a6c17ee56e0a9def017464e99e3e1015dd90efad84610e56dbfabb19ec66e3de96f2de3236f5db5d9cec9485c9dd9422835c6db06fec26a3e26deca65fdddfe8942387346f0edb39441e483beaa873265845a6d4e2d7ad26eea21a7ce4721e310255c777b460aa2440f2ca2ad2442bee47f90fd1c232ffd811da68f821dbc9fc0d02abf5889f50520cebd3c8999ec3ff6bfb3e8bb2df21b324bcefd1975ecafa3c71dc3c5f57bf9438651143ded6daad1c8e12eaad65ac66f67c304a883a854c502f3d0b0cf85764fe5c1986b96990b005e022743c945e98d627944418bfec0016d7e19f7470266200350467dd038c79292816e0df5bc2668893da6b5a0a3e30d250637297c20a314003d737179781752b3dc10f8f86c605b1701d1ced7954aac7ae5fb393f2c6e28e4ce337325741b98a9af0bd6615dc5a33c7a1448d158849dfa105b920a6f503ce51e37fe58001b0ff38525a7780cb70e2dd55e569dbe6f1da2649735e6c745d212003c92c303659a2f309ebe940954cc265f35c8e7a1d48ec66b7a457f1a30dfbea95bb331e8dc88115d7212153792ab86fc039af92ecf0fb8d4b53d80daac62e6276f4fd46248a3a0c91a6a52736c5ebe216eb8dcb9147ef33dc0821bc40435baadba2e6b91d2c425c86319a49529136f5ea54784f19d752600927aacee2a1466c9c9e2d388b23ce2be22ac3e8c2dca39450d2efef9d3d46845b521e72867fcf4df6997d7f5c3cd810e761f63c5cfaa6121a41390860d6b5d55e43c83ec135463ed927425c313de2f91740645d5baeab2db078eb5f7cce5ac472f26ad6b90fc86460c336da655f0e286c461c40a172feff430fbe9cf0b264d1c2ec651ee6083b7d2691efd6697df15ba328f642e7de489337d7e30d1604c220bcd5dcd55130754bc12b61f710164e050deb4a0e054ab301beb5ee6b19c12470a78eebfa5a654a5c51a42131ef8727766fbe8b9b431965e42e52cf372098f525bd132e774bf5ceadc2b266950e573af573ba4b71bea6b52149c7f56b09dae0e09f75a73102005b1b3e55121b6b217d96a225084ab220cdd699e4173f0c8ac32d17b7c4af02db7def508e8869b5af075403d9b2bf56a7df8916aaecf6bd7ca8cea03c51346a429731f68d85d4b93f4f2d592e20017522ff893c09f6d4ad6cad87fff6ad967a85c1439b8f7dc9a58f33d430d555bcfc7d1488c2d6eb42fbeaac2af2f3c428033830ae126fa0e1e68818b45053d1e263caeba2e1e4ba5db493aec19a67fce917fe2132679e29373d24b5e23c823c90aae8a635e91f400c68202a9cc8787392e784857017745769cf185afd00633514bffb2558b4129f2c3434129d858fa12a25c3ad75628766ee51ad78190a0ac07d6aff67d86cd8db3b4e3e72f37c4547a76fc42cde544429f0fc2b490b542d0cc959f3c10d6de1c47c57c1a8aab5669989018242fe6d440abbce05501ea7631ca6a69b9d8253f4ef56bbda31da3abeb89e8631ac90c039615a7e308dd96a4455ce7842ebe8a23dc18e8799601e47c315012dceb94ffa79862d6c5bb0a0eea6172af8224eb5a53563abd62e1926cce5ec368e7456d34fa9324cbc2dc7346f724fa174c332e561d5ded3eac47406b78eaf07e6d3d95d2ce970cc0748560956d4795c9fc4c8bef98424d53c9d59e8ee14b57fdff7617d76566c18a877e17f87c7337ff7e1ad07a46a65d914d46ae8a8476b1da911b461c0c90d193ce61ee6d05b55aa8732c0bcdde4aae34cc47bef722bed1c8e0f33e47dad4f5cf917ba59ed0cf6ebb4511fd2b609b3e949e4df7295d9556ffb9e12b71cfe19e6babd468fb1728c43d3aa7927b49a5cc5457498dd0120762272e300a5fd1a2ebe22b29be04eb7b9cb36e948e323262c3d165f563250232fb371a9b2f004c8ae4a31d6969eb617cd4a574e51a4d789cf17b73a3e54fffb8b93e212e4dadf8ba75e5b9803db1f8f833d4ac5016d25bcebd438740d0fefe1a3c0d60e6b18c77185870d630fc4de7e9072f5d93e5d76e039672574e7152cd96218900560859c4df738d6c17390e81e184846dc8c8ca9b7489e3c5fc8f9bc6fcc88e5edaca699626950a06d7b2c9d3245f4ba1340ac555a1aa9a7f65911e3649fd3a60f198ec63e0cbc58e4be249e76ef04566eb16c7ae10e5b5a367012ff2fef27af72ad8c3713a89eb3d21a0726cc06fe91af4f77f297fa8c232b0425ec023bf67cdc27a2188a89d567216d534ce34e919b4e1e2263974bb299836f18107dfd4dac4809d14df902950101b9029039381a0515f46ce8ffd9388493734be1f7e61ccc5c42be501248d2519a3c824697bfc022cb60667519099abcb7445d9c282a05066a64961cb902ab35357f929350201985c35188d499cf5667b0465207bda93556c483309b3d1276f30c82270e75a1786c15e6a2a2693dee47f319d6ef628ec7bbf7d0859c795542265c6c567d5e2da7310882317550f0896bff1a68648dfb4423f2a8d4c9c7f27998b8ab02a1b61aa8072f85bf93158db7f7f31d7ef5129c2aabebb3ca370fbadfff2e67378386e4a579a7c32e85aedcbb3cfe1cc8a3293425d0c010792e3dce8223c9ba6ed024d2da0b97f123cce35b16c9299c96dd087298277959c512955dc440498e2a7eed55616f4fc68adf4318f791c6ded1582aaed34075956ddc1e87295a601c7d6d762a8d4ca024374a4f4a8f858da26cf1b5c56f3afdfe5a5c26b90e9fce312b3f2d4a532073be1de950b7c44c8e1f7db4cb94e4e62fec87282eaf1127cbf836f63a4bb71f964830e42d85f2137ce3438621ea8be087e0bc76d799586df89a451d392e99751e60f0e166189406bf3596d1602b0f93fbf39a565917fe7deb303da715b75e1f741646c6335e86b445b0a75ccf8c2da62bc29229cd1589b68ed9a7ae860e40d0d1582964f577249b6df12c50365ee80264fd64919614ebaa788c93f193f13caa94d1cd10d86a2658e1cc4669ac72715a8dc2925d9bdc62162c7624baabcccb22eab9678a216c3b9c90f6612d3c61b06152dbc7ba444e5d761d44d3d6a94939004774daccfd2e50418f94ee4b83600e4e23fe4d56a9997ab7cbdabb21f51c7d658b5b138da5d8747a77a46aa50f9e83cd9094fad96684ba2ff4781e39ddffbbb7f34878a0c9473a486b1b5957adcaeee6b205f3656f3cd5b68cd82203cb5b70ce5ef5524f4fe6df1563d197a8f91eb50201b91eb023c8fbd9206c2c1e5bc2ab173fc7348e49bbbd8b161abc8b9387c5cedf6f76c7e7e67dbc607f6349a965e2b65628c646c989e8bc338e4aefe033619c669994ce98988d3f9938f1e49182f85e2c565c85d245ea6a907a5c82b22670b40fedf2887749c6014b9d2898908f6b68659c12f212b552896d89b72df2ae112e12171de09663cb39f5713c4862f49e821dda6500e1b63aa1f80a7a84e459e23e0c3c23b3fc67d426776e423f3bbdad1df9370c93415b1fdb13127597dcca915b7d6957cbb1d7c0eedded088fa8344fc46e300d1622c6dc6b40a4bba7b691f2fa42d5276a30c66e5b4cddfd813af29dda81e8b3b3c5b6875118c9428952b0f09cc083763644b618cf8fd2cf730f208264001b7595e74747fe8cc08b2453de64a83385d251911559853c0ec148bad5e74245e6db77b4a0c286aa05f3a385b467e875d6152f75e979dc7801d8553993d4dfc400d69b6bd898e40ac753afbc5acad8dc44c93e4c6ae491eb2a20d82eab36971c6f4bf1c05f3d8d8a3b84b4e2ea75a1c358e280625319ddb0bb83cd9405fc5bb06e045b32f9212791d81f097706d0b76efe2aec204d7cfd7de0cb90993aa60c9fa02067e7f5880dc9a15ec0a65132085e216d172f08e63dcf8e86c9c4d2528b2bf9626f6635b7c5665b1e48a39724358b48f459378455d8ccf3d5539ed6e626a9079a17c69db5a27c86bfcb3412cfdcf6b044a91c0b07b3ddcbdae39aa9d15ab240517540de7fd800494b4a2f3cf033d4a877411adecdda9e2f3a7c2e2b4546a6ed93cf7f6dd920e6040214adb135c0d9d21012b200f8c441121c24873d4f54ef949d23e834c40f2ca54a4bfc53b19d06565d246b64d542e4084698167511cbc60dfc76f0a42b1741be180276dbe6f9b64690f6221d71d9dd9df644e2bf8a10c86fb3c7ce2e471527a351e2b8acdb67d9d0cae618758b973f3f761f7897cd642deda882534c6785cc14874748f3593785c2f1ea0dbae9e08a93747b8a4e874e435172053a5ff6df4db99dd6e3f452aa43882528adcf9a1c41254cec754ea3f3337e39c1113e69d2e49a8f019bf7afd8ebbbdc06c09f17caf2af054ae69530aacc0413eeda6acca31a05a83b56ad11ab248c702dd20958bb121ec0b51eaa3485414908b0f0805b6bb01450a45b6463d69cadbdfb1f44c881423ff96ede1f6ceee8864c4212e002d0abaa49198de248c5894acd6a1bf7ca544ffa230648c0a8a648c8ae9e052d410652dd7511ae034737f413b796a810e04867db4fb13c1fbc1d065c611ac1527405572a64d720ddf7cdc6c9d45b83e3be415188590c5b66d2a4c57cda16e788bc9f73933930e8f37a96177239b1a3ae41446344de095c1d5f5d78245c0ce0d8a7ebdee12bd278eb760c2494e36fcc71781347ebacbfa9b1a35dd83c2ac3c3d4a2cc34a0fba96dbf56886e562c12ca0e6a07ee68f42b7dc8032db109e9cd72bc49c930e8a9f37418b158f8533a7c24c9dd2a14943ded7c9f2dd4702c86368d7746305b768638e800fa94dee5b7f94572295b041667d52fd2fc7d76f695bb529e7866ae78d8e40274a3f9b7b609fc75f7babf79a5dbfeab9f55aab90491b7867fcf2e033c6a59ad250431bc9fa0952e540297d0ce365dff37897f549856bba11f18a975052fb6b11e287dc88a93594fd2fb73e683d14338cd93fc4aa997d7d7574767cff5c7232af02972376b15187ef471211005ff81921a6c7900eced4cc1fd1045ba82f3fc446b6c9d225d406188eae95060a37bcd85a79a359000b03a0b032fe1cf458418a30bce78911b569e133236f91dd30ffe805ede06662b541312ea37f19d4039039ddc03e668fd40f8661b05deceb972c0a5538912d2877ab77648d39280bc9d40516b266087243a2be29344ef901e33ba0312e1355e95accbc1019ef6fd3b6abf6c5d9ea8bf7f3aedc3882380afb37df63609be069e21ef7f7dbbd4777d4e002993151cce93a08df03ad5aa2234fad1f9aeed6d25b23a0525c92e3d76864510f8f4a54a148f013e83e4305123cbc9cb25dbc8df610f9748f269a3a972e7ab0e5060584e1899c2967ead59ed42a49b9175ffaf9ab3d3d203749b03a9d194daa19a6d5234f5633742ffd14b571d6ac6692fe77d57a7a9aefc8ab115c928df4a1796556a60ebad2cb875db58306b950b9d40ab152b7e5bca26c3c15516841265bfc3269010ee90959b829bbfc04f3fe7a12f9432ad3d1605217c4a329aa7f43d100e81a3471ba4bd3f9523854fefab251306893c7f08cfdd0646c69f6c81972a0124d0a606f18f4ee61d3e6ae7ee93116c4091afbf3d4ffbd022aae5bf0e5a919a59aa36a0a31f35be0f6813ab8c7ee6a157493bb105e07f9c1143c4c4ad06ed4c8d0d8ce30622e9fa0d9bc24812966b232aba931f7d81eef49012b4772efffe10553aa040caa0209f42ca53dd73d84d61ff8db0e0ada0074f09b3ae09d89820ab921be90f874a297b81e84e66e42e90705c0c144ce089ba4d1668af086c77d1afe9b88be250bddb3700b441d6c370243cb315552e3968852a5cffcdd6beb6dfab6e80af08f8ac545a14bbc12bf8178acfd57f8a0ba2f6c7ca411b2fbd1dc2618a494682c68ceafccf9e05037a382538758d8f3395670782f5e1d615cb4fb92a9575babf45e45872e13a24754cc71fd505de81531ddf43d20554a4280c66b4c9aa8c398391915849ac481e3e8e1fea76ad50bebeed729c8bc65167cc65952b8028c0925f4b66ada797c8478d417dea5871ff1b2c3595e22fd52a79f36ee9cce228317f041b0f482ca23457e38f3dc5baae3d5418432e576241501ba2156ce847844fd7d0f42255edd14c869b0f878787861998ad175462e71ef413b019ed176b2930bb13cdd6a7d1e33029056587222a6af5440f3558d6b8406b47d8a34c62b772368a4fa5802cf8f38eae3b672d0a85e65645215f4db490fcd7702efa3b17215e058af13e30ebab6010712dbdf25d55e042f8e650f87fef0e649a40d473997cfe471fa6b1774b076471f2e4fca12ff2b68ab0dc4151fa81ba47b4a3da50f2c4cb263800c976ac6750ea09045838a90771cb5be0f7cda51abc135380b49b3a765d082137f4b222a39cdee348f1c3fcd7abfc6847fae0ff1e7b4b838b7066f7789a1f58c5f4f2fdad7d70cd2a703a0088d5e17a9c7784b69ce39fcbc1680b97e5cdbfe7e445807315fb9560ebe81ce078f378af56ba689061bf5282b470bab38fa9b3f618815c76a5eef761dac457aa41172113d19376518ddf61d71d3c85108c287e1797be67028429ab0722a7c94a20afd3859b4ca04520324aea47e3e4f4fba3f04cbdc333f7fa7434065eb017259873035896012013e7316cef71ad58d0c7c0ea18732a6e21287891866121433afbd4cb91c681f7613ffabaa44042b4963714a75ba4554c3c8a3786c121dec6054b8e839375fa9119bc46fb7a5bb6d9cc3c23b581679c96482c07b36830794e2b256ddd5dc23f1547cc5eb2f4e1ed9b94f298839ce3205d192db2808bd0e68a2a1c4814bee4a50d7defb76091050348bb4edf284c1877c38649ba01ec42b4d8ebb3b61d64fb96a71f646972df2678ae243f9649b80025ffe4fd6817918e205a0444abc99c79055cc8f3ea61c9f08d51582804a20da82139db4978147e325f95106f86324da20d8929f9d814c9c80a70528ed722386bc9f8aa3cfe27dc6a65e6cb8bd7ffce142b7a3f7f69d8d6d315eb7a9cfb2abaf5d0336c43e083d183dee7b7fa2ac55c263d62923795aab41d98dce28db1aad3ed94d058c5e82aac617340cc69aeb7c1211c5129588efc3648aca43b1ff417e0fbef0ae9b4f3a3cc7f3a83be780b270a005649647016c3e9f5f58d33bb261c98f426ff3002e73c40e12060cb8bf1a186bad70044ea5a79ee0643aa6fd889f2d1ba96052302a9d7c7d024f2edc91b826256613f78ebae3080136ff3586e931bfbfdd46696bad2feb56742473295f9e889d5165a69adfd624d1c957eb2a5fc432ad4527151628a15ce112e07bee1175af3974b1e41eee6ff1f7f10ed5ce3565854e62643cee56b8dc384c45a95725e7a47b36e5110ad4ca6dc083519cc7017c3c6fe5ec891e80eae2cf3ae38745c97e1babbb5e442a6569245aca62befbc7d6f49f2aa0679a2801bbd362d96a2d7593965aac2e29de0dfbe7e10e768cbf4b3e62bd3fb448b0735b8c985ad176aa98400f56f725848a96a8a6a7ed37a3d2aa33edf68848681f867e3fbe1dadd8bf16cc8fc86626459b63b3e120917d32a44cfe42962389343a0ed20dcd543628614a5588ac0a0674a0f38bddb362950c0f1339938324cc5e44b6f165bfd630f18470794e4e0e7c5fb250f08cd0338697d410d72c35457a4c3fb0aaf2dcdb45296cc53db744dfc34674f13abcf0580416908864268f9be45d6936aa2254ae3e9445082fea979a039958842932bdabc8c6e5cc890d7a307e630aa46fbc2b20a19cae348516e61901adbb00ffe36c09ec7b9d59f7a80a0f7fb945f1f359f939e7d1d1339e7e59067d4ebf3e7c1367e97fed9ae7278db50ee0d22624704152915b370b41d520e0c4c7d5a8544b131f2942506af778bf87d2cf93ea21cc77ea8a2646586504c7e593ea5871ae5739b8062781e264e95c03a9c70d5b87e97edbafbbf2e457a092db48884fa662741e268477de0a99b01356c130cb4c4f351d1d92c0b4e4ba05d120b08e516c63aea7600d06f153162193e7274d4ecdaea263f88755f17ddf0790c2d72b08fab558139288af4dcdfbbc29a3c74489032f571cefc45db93fddfe76b4f32776a9cdfee16b486c9c554e730312a47ae65edbb4dfaf5653dd038e0c9577536f43b30c0a7e6733085a1b31c8bea4c45f39e1ac0ae81e02cb01c96b0a7988a4e499622c8c87ee1d3385d464cb7357ebb8d0a2ad62d85b5d91ddda4d0f59ed21668f72ca20a450cd8645f561db161d1d1cac68bb1d7c89ab07cf0518fd5c419501aadce8cff0c60f24997ab46c6dfafc750f32ff31b338feebac4a43923556deea0ed227913182ef5b61c57f7288727171a6b6916ef9a312ffd87b3053842217895769428b5e79b82bcfdf2661bca2e34731ac5b15f7445df4c610af9a0bd2256d9bddbac56c2a5934d5d646c0ff94c932b341ed89ba1f9f773384168368fe9657a7dc20a968bde4ac6a0809d6c69edc6d8686f71d4e494303537bda18e1299d16b827401f81d3e0a028e5acfac81618a7ac9a2298c1fe88ea17954b4a81b761c517ba63e8746488ae57104584845bf158d513055a797c581ba41cb764baa7a11deaa7f2c87b3b7f4bc2f2331bf23562a795c520589d8a71e1cca67b40ffcbd9a212f475b71e1f033aed532de9e4f6e9f7e9f95828ac69f0c982605fba03eaa816d25ed53d4bbb8905feb63c8e2f941249a42b5c9399ea99b50946c7278711d743916ca9b71216db37355b6e72c9e6ddc2fb3e4c1147e3d0b348982a3ae5367661d386a01c045c2d9741edfa35ab2ec22460fc8aba32e3c8968933f318de75ea66d7dbfd22d187b2ab7df8a1098fcb6e3a95b4a5e1a955a1a03f8d3164fed6b46d46b132bc3625a21270a9375a783e91eb059ba9a45b729418ea68eece65c9ce4550ffb81ab2011b1b0d2b152614d33f711c0226cdb02927a297d912799154d2aed7c06023e0afb4ba9e1e28c58974d6f528572a2f69ecf43e403a94999e0d406ea081ab03fd4ffb8e96647ea2ff00ed518712c0715083793db83f7d8268220c795e24e83ac4306e42a9a55922ee7b1b0b822433e2a6920cc99e1e896ebb08383d2eaf33a1510d14a54a8de56bb1bd29eaec11e4b4c4410bcd4a576caa6054b913369e37ddf2e169ec293fef1053add082a094edcc5fe697ff0cd1fda586407de2796eea5606ab640e36b4c3b27d7ffc0a2965b52d31d51d80a2aef187d74f04f9a4e2c089fe94e848f62a03d6a14d276bc4e2008e92459a376a8d377392bb65c3f362d2d0a6ad24b87650472d023a879f5b58cbd3a003038c4670acc755198a1d6de098b64a69aaa04846a7d37c15725961555245c2e2419921ab3beb789cfa5dafecb920dd9198dbef86c5f9961a0970a28b77b5e9a98034723240c2f5c1d45a0205498f69ecffe36af65d99c5e4b44d5783b7b2a3b1d8caedfe1e6d9b1fb847393bb3f1f359e6a8aae1428afe093b4ba98d05ec6c02c1abe4f3fde5b9201d69a8b89ed605b1a7840b42d4c5a46ad0da4fe51df41a272866e931a96629838024f572791450fa7adfb1650189d3bbba1df6032f4fc21b2b93bb7462303f518aabcb675f4d28504daa448b59aa1e968e81180bbdd14b72ac0eefbe4a951a2d1d1a62d43f1711e4852c26c81c87f3a054d7d45163c3cbb6939f47db8ecb5c4bebc9ead8dfb1f6efa48fd7fc712385ecb26b03b384ff5184819fe3edce158dc561054b39f70c82389f47b7e0ae8a50f581c1581780f5164241a962ac2decf6ec5ad2499ca11d5199305865d441ed0b36602776a1814f3408fb7707496ec28186989f269a07a288e30c41197a58c0ed16502dadea98f228250f82ef654a1c7aa11d4c0eccffc4f2e052c4f23b49988cad563a0e439603f4fa5628a710c8d56fa688eb634d0c27eb4debd68e482217c5e2fbfe63ffe87e48294c13043876eb8d180b84534aa6f59f881df4b3c57e21e4c41c67e1251457eb5d4748b8f16fe53287e6c4b0539f71dc5eaafb15702a18547e1534f41656ed3efafe2490e7d4567645e71de9ed7f8ed81aaaff3d4ab234088bdbc8900d6b4dcaa5751991e60f420eeb01d3ec6eb1cc3297c3e14b03669731c46580ed7d84d25108d5338e418b1eaf513a58c28cb63ff661a0ea60c6761604668ce242345d20c5da3c6be811e837f941cc6339b7f06cc73761b8131525aab25a32a4dc19d697096fdf8dda90cc8d700316dbdbab5b9def6b09ef4d81425e687872ca5e3c716d368daa019b8bc13da5cc76da153aa2de14223b46af0246a8bbee4fe09134c81e83f73e4eefec63b65a34f9a6bccfd341458a78c7659ce1f002a067313e6ccda7e20edfe115532cbc4915761e545fbef215511d4b989214eb8ed12451c5768809f557026603d4e6664bb6d2e2dc2091240adbb55361ef8f4e6d108f7558638ae5bf84d7099775bcd8f7400f14b427409af0d654d76f27b69e1798c4d6d7d64d82f73c60a8b7ceecccc1700a0f35b04818bb62706dd0f4d746fd2055714a32c1777e7bf4a3b79accbfe916bb8a44eb1b819e6d0c0925d2dc6b1c7ac17779cb4547607a866277657c79b49fdab410d9ac650666317f141d0b5d8104e14623b31dc3152f5eadd20994ee72d37ed2c2b5cd436f96b9974c4286f53f517e0084377da3e280dea141e0b3b74e23afe739c264453549e8ac06626c310470fee82fc99adb3a72e7a535b86ffa9aaf0ab9a0fef086cc3254574ffcfd669f6a66d9c53b8ce1d6ea9015a0a4c5c8a591f56137abb75a9fec5af481fb97d0cb12fd98067ec9fc81da628d0d63bba4504784c42eedd9e15cfa0f76edcdc4e96b4d161eaa70dd279f97833a4a6110be9ec9020617673c5c62ae8a8e129ffb0cbc341cdeebcc445233c179be3aa7eb2f489a5cd32c3aebb395486b9aeea1721fa4e2e0aa08e4cff2c1fa24233aa74ae1ac0ad4afe30cc85c4fbd3fed90d77ae0da9e8fe30383e988008d6129cf800dbf1c76fbed83620894949d8d3ed69e6e13969b9349763bf451dba7c0ce74d45c0ed6f400313bd3769c456bbd91cdb8ede0bcdf46983116daf0e6d9706b796dd31897792ee0e07dbc79a05250910cc81ea206aba66ea3a9b643ad18d72eaf59e4a9d6343e7013be765f2ceaeb0f00b2d20930337825152ff413a7066a8c6217ea835f1f320e56832cc71e4fc823edf06a56a9da02da9ad10d6e8a8a1f3b09c1f58a61348aee509d6a57178857b14a919aa23ba8dceeb959ef9d2f2bb1c14f16387db16d401a4c7ae2f4528b2f58e29e552a33d7aba80df8e9e0a181709590a5291a87dd6d30701274f8c6d741dbe2cae8a355a84fe69f7817c3c8665b1564e317e15c3eae97518a750d402471cfe58de57d7e142d69d1f4701bfe1f7e288e1cee6375a469ff6fce3781055d5f93aac349dabee5f5118f181a701451b8fd6f1a355c609fe767353e5f6efc24073f8738ff5b8d24acd4e43662be51ae2dd99d66b696d203a5675eebe57834032a30c97441097c805ecfc98e058bbe57dbba61c4a6357f778ece2cad480e8e42a5d315dffeae8925931c073469c55f9fc036e6c875ef80e25a9c387f0921e7914a1f63ff785f6d6bbafdcde634d8e02ac43a5c1c13d527d4719640a777e65e98c1cc554b81b28a31bf6e296db71d9c99622d06227541b8de6de6f03d6037037f7c9513cb8f1c85a64c60d841f247ecdfb434ba8da65b5610759c0d585d6b69e126f05fe063a2499290417df5ffdc8c388e9daee939a75bc8cd916d0bc0bea076883ba1938f9b54b311f643a37bf24d353bdefbfa659e395b4e5e6803779021943f8d7c1146941fc6552df51a134b7da3b8a576faa56df7bd4573941f8ba18b84100611af9be002c79cd15866d211957147c66eaaa920b30b288c5c2e6ce6a152d8cfb1e8eb0209dc01d02d0b24307313ce197e2873db1b73291c14bad4152bc3fc48abc7860c71d467aef6abb635b605f48a36a28a21148c79ab6c2d4345773e8079dc03dedd3cbf0b8da8d0d6a0ef084354831a23658f6297aa502931d8ef6486f44fd7e575c0e7e48eb385cf04214a91a315c48b5bd64c1344f6d58fb947301f134c187759a7e7090075db3c10349071494ed0929170d33017de5e2782695df9ecdb5d36b2a61d6a1456eb290632dc602935eb04d681fcec8fb44a437f9f306dad9f47ff1a481a43843098ceb7c2c74f8d624ddaf1ed02b2c06dbdf1726372b9509aa91ad31ab86ebf705cb1e920b3dce13e37dcec0eb55901dd4278eaf52427f519485451b59307d2e51a698f698e23015363d0610f746b295e1e10d34ec310dd2787373f8f62e57b7b236268f05051220d77b475afef25049d6000f15dd82f275329c9894b965fb5ad317faf34551b89394ee7422fddcd04541a8acd9622d0eb0675a50a342fcefb1c12b213007f7c6f0ba7d5d26beb9400f53c704992296ba462f391cd31b49ba8ab3c487c6159364668fa6cf9196d2199a88bede10591106f830afa4f4d603fc9c65ef50b00936b049dd9a41236207ef41efaf85a9677f4cd41bed19746c27e44c7cfff1fde71dbe80f4c2f98ab113dbd806ddbb9bbd4a366ab5656594e68554e2f5bf0e4cd81bdd1e1d1270b0379c53ee4db42cfc5f4c020fe364a0d0b61c21973d37f21f687a7684189b3e0423c8f677c6686e666da35dceeb6ea855f88e94e9dc0c3bad0b3c936188dbf1d4acb76589fcc7eb33b79f089b80be3ab088694e60e24831594f13618b5b95fb6497f9282546482269c7d683f9e52eef5243bc7a7567c24ad8bace0affd9f99ee92602150062b9f6d193392606b293266e65d9de0850e79c38b167716563943eeb31cd4dbdde348f643ce9f30c23a8a2e15965fb876a64aa24582a85932ee61695731ab01c1f33f515755878acb5ff7d04f3918a9b30fea2fb0103a071fde63826ce8bd2db96ae51332a5db824eedfe54549a1e2865fdb155aa29284f9280c5372b51423d6f65ee68d10d45e014e2ecb1e1196e0f3ddd1f53c6a5dd217ebafc9e1f07b0e7e7716303066f41782056bfae76896cbd1110f2e036babb14a561721488b3e0c3f3658f93ac30894ac316cb6d5ad1790da7193503bf208f09136c7fe1bf406f45d42a2f193f8204b1dbc2029bde363fc2138c4e48bade094ad918aa68139ca714638082b6247c4bdafe9b8ca0a5a12a8d08c3594298809aa07be41e057eb5824fd6917da26a721e9f443e35628564c9d1ed8191193752d21957dfc1f3d843a776bdff26aceed110ae57300e91cbeeacffe8cffda68cbead2f5371e3a2a823713ff9a3c610ff88eed3f5951d7f508f9e94b8dbcab0550fa1c6b4eb62effbe3f855e5479edef4870f88bdf655b2ffe7abd01ae7cd894fcb9357b5d735c8761ae2978e50f6d9153f099f5f97b09e6d89870dfc87463b6642bf4742437ad5a06fc9c178f7af6acf16c6c891a6089968d0a55bd046cd99ef95560c86143869f7e7aa8866d0e539436b957c457c3dabaf3af8e5c2632911d9dcf2370cec83544a8a0d858abc93d6ee6ddde568812e97ebe2811ac1fd03a4df68e18a6b47a54463a23a6b7a038b185cfa1ea2dd051f3eed7129ae69ecb9166d7476b094e73d71cafef803436cfd626f97072bb95d20ae44d06f99d2281b8acb43ae30f5ba658a163c87b6586d4713f5f90e3776b9ab2d9d9bbd8ec910ea6a7fcce17c52cd71f9775382c087331952abcad07d5bf47540aa529d6f121ac02c5608264bd034abc7323107357ef59771f5b0b481c0a289b06e88b8df98677ee85ad11b0db5b660e3c9f837e13a68f2485cbed2746f87851bd1bbbcee86aa308a0c34ad567326d05b451c1a6369da2cec40fd1453de3590229901dcddb4a73ca7ffefd42089b5ff917148c530e6459c5156c40350f53d3e63fb25b71614f02877b90bf54a23f89e52c8b6ab11f1a19b6fb933702769b47810543cfd64804f60b8f1daa69b6ec52e443d50498777fe6b182dd748dd58c637b6f6b4b811591e882e46c71c696a85952510600674cf2d70d8ed9ea05524f5ef6d3928cd64f7d06a717a465fa7ac0605fae9395927dea11513b12a42e5c4b9cfcd85038fe06d6650b828fb158cc506c5d82feb90b862122c0c7c70b15fdb3458490a4a0ca2d7e540b92867b55500ac8b8f496686035a95b4fce79d7b16f97e36f1e4e158ec76dc3a98e641e3e0645e280c10309848cac8507461471020bd3b41866b7e942d5a346d2d660213ac69459890c6d9adc4b85cbd76536209f662ee9778d3700bf292505a967d120904fd6b81f5e8b22779a7f730fa001c0d5010bdf6708626b4f3909cccf650a453e460521cc9d412051d2819858ccd37b57a5dfac2b56d96f8da1496ec66bfcc5214e17673b70a05fbcaa5b0cee71f902960102b9029139b753971aba47f01384baf7c4ba68ccc66553df957bf3d8bdaa8a0dffe59670c1b1fb1f76d1c6f2a5264268ad2cfec1864b1d4479f1c5d5d05371d1a77bdfeb7e3841b1d157226a4e671909f4be2a96415f2a49dcd7c9e306cb00de97dc819f15198664ac3aec534aba5351285eef7d853c50992d1a6ae53cfb36011f7dd2c4912fa7a29c193e11b7a232bba7b5d0ca21ad5cdd6a8f58376a0340c30f5c8560bcdc1d92c908485a194498ab5ed29ab3d695652523f4519c5e698a2f4a009a8c2faba8d5e0165a96762cb4be04faefb1cc632aabad2f82775e0a4da38ec1231591253694349f14dde4ae7e7ee401bd2b58d429b36934588a1d323c83f11f871cceb20e1da5c4a216fc03364397647a049395ff6c0c8fb76b351a279967481e98546e3519b7ce43ad3cdc5413cd83bdea3b92bbdf9a1bfd59ecff9e94b22abec917372c97d376355f3652d71d307502a8f2e1e5ba245da6c5e08e63086cc76b0a7a26b2db46d206d11427cfd501363b46356fa1575b3c51a8dca72f67dbb3bc9fe77315b8ef6bdf9cabc0122d5b4dae7028ca1600f4b04d279487a2cb91619c798e9a38d5a5b868acb777c36d70aaac87d90e6fadd3f7e58b652dcd45410f72ebfcadff1eaadf27d2a7e232c3964ef5ada973fb5efc18ed54f71a7b26aedbe66bd1cd598b86e520abaee4eec60d5705d0652244ebb2961a97c50c6548ab2e33daf3b915ca6cdb73eddda73386361940cffff0d01927338f20d9b9932154805ca89028ad221741b9d8988f050b4ac1a81f3bea789856fb0bd68e1472304f46c3d0f32bf8c4a5012c55da5aa058b913beaaedb06d726611c69444d915a7643243105b49573b999c9ff7b96e27d3927533d982c90662cdecfb3f74b84bfbec097624acb9424956e66095be5a193b297e691db8f91eb50202b91eb0fc23d4451fef5742f639835974e1e18f18cda8465a7653b376943acd73001c930e5bb1d6dd09a0bf02b0884ec76987aba9e04e0efa35f3513aec250ee895b2c47c3a7e65cc6c7598fa2f1e41851cb3a9e4ff40fa67434ab940233e14a29bbb6f492c7fb03ca78456b907debb95e9136ae4faccf04b0abc85d56a880f514e92c92c3874dbfa36379a1fb844ce5ae2ada204351c24cc21820e09b7d91409162bae035c6de8260b78594ba2ce3010f931e95e4dbaadad68d4342ad1b2c20fb822feb51909a759394d25e6af79056f757815dcc5a75c05498e54b4ad5aa829a9dd66d7d9a5d2bdf8553ecc2d7d7dfe90693d8509add9f1f027527946060c629fc334e34e6d3102d0c8a2883ad85a78bb7d7b7b8d0c44ab4a62bc84f520c6fb22097bf496308c58f4a7c05823fa6dd5c2f7ceb18202707f71094c506aaed0f12db1e7b38723b91b394102068a56faac2b19c35f3cc3bd42bd00ee7baa570b29346709f483d5d3e9d0c44621e0c910deefb8c4cfc4a233d9a1fe9640a1508b0e95e9af83558e1a51471003c918d60cbd3a97789b4ef418d1555f23558f6ebaf87c65e7219aae621d1658e96d47314cf7c4e42380a94167d1aaccdd63ace13fc1fcfde8a0e6515a3518a3437b62b084364304eb9f2ce630e21ca4f64b6ec2816804e8783c116d12dca779ee17a8cef04a70ae429c4b8565e8840444092408489aa67df08ff7ae03942873f6f5964c68f814fab3332d2d441b8971f6a616e008e328bb94e71f7199d3047a6a637e1a575aa7a725316fafbf31fd7ebc6ccaa308eb795d67c6a7f352cc185ffbffdbf7abd0bc6a49a486735ed043bbfb65c90c51149e85b45cfb61d2f129bef617f74c29505b079e413701cc5cd75de49dadb0ec40c9e026c7350db0263f82aa317e75c6499566538f034383bb018eaa3b7397ccb3f4d8f195a0ced5e78ea8d5167502f66992540f00da6f9914d88016c4494e7f331acd497813ac91aae0417e801400f8b9811b89ecc7c8295f5a91ce5a9d4a2ff573f6db0646c489951d8f90cd9542cf8691427a94e0e904219694b65983c2061fc84c5fb0aa255addf0dd245e50169e99f9da91842e6dff5bb0069751c222e4c6461cc4bff9890cb19dda6a246931253ef26117c3db1532537a7db374e894972809882e5ff0aa35695beeb2d6b96b251c47450fbb6ca47695b33953e545969567502bd3127b29e78f5018be6303a81ca3944a8f77cda82c18e78acceaf092becfef364ff252abec1e7a72b73b3cd871e71e7817f8c9193bc8191162dbd6e7e6cb67d9c936ece6b04acd108b15f9d604aa1bbb3f49a903f47d66e7be0b430def5cbf9ec47b541a5dc24108227c7f91711a632fbcb5d952e9a6684080780a4b46bfad31949925e37662acc8de5d0cfd62d1f867f90cc6be3e86bb6b58a19fe366e173d963378e40216cad7844a90de10f38c94e4881af8f4d9fb078dec4304158470d178fc51484db4243b8b77cb70109c6d7d88c34f1d6da9fd382e850ea15e43a2528452ee16cb49b82d17e2d9d52d8ed8bdc36a5bef5c7199e460ecbd45f415e5a93b7ecee5992b9585e0c3278dc62df64f596903444f2debb00326fc30db7a509ff38b92c788c904a20c14bf78a5a4f1ad079d05cea8eda2b204353f4dfe72f02361f26b61ef91d9a4045e7addff5e5bf72b54a931eddf971c4d3c59e27f853140af0d8438ecadcc061b5a79537db7b028e9a8f9aa1679c0e0ecc07c609478b73d38f47228123672e9a21f69e478584eb58445c99439ab640d26710c9ff79815fd5e86e9ca4fadc3f0938f4c3ed2efc5fd82afa529b9a899f629088325082902e8ab6211289c696ae684a48d10951b22b42ec5c08ed77ad22e63183d24586bb56dff58c88c611dc162a384f62a0542c3b7d0acb15b20abb0d3f89d34ee6bafc9aa19dc237c4349b8f9c6cba219bea2ae1de76f4c9daf56af288bf9ff92e3dd71d83d838c09b89b0c52d73356728e6767b55878d000f29ae670b3f25dc5ee6cda7fe5244ad2112463b311301b465272e590e6580c9d0555bb3007c50fbbba9d4e85d2e9210368a5c7550169f06a0214680f0e61a1e5e31a75ce975df2a812a72e52273d7e487404b3d151512ee261d3a2b4b44c38510727af8ec31001c2d2f7fafcba5db8053af1f324993ec130bb0f2996e49c731714a170ee4cfb042b9660f415df466f054f1168b54dd2dfae3a459e03afaa412b6fc51bbbde845acc9d734be1bafe49e18d1b87193da013c928c5411fa6d7a0e984f8ae9cc7b5632f1d6946de9a6d36d7b21d7c4049821c25084817aeb89704b4e921c143e36805bb7a770e5a8f8c3057033d076d55aefc5070f8f2e1d33473a7b2174b8ffa1bd199a1b436b0dd37d244ede79e1536a26d59863a3d19f68d12bd7273a05a8f820bbd455eafe9fa3667e7a4d604033fc4f461c381d4c7cc1c0de02bbc59e7ede9fb0c30b5610db340383c1f760c0836e1686dde7a47b38bb5e36fbbb50d954a36e4fbf9964c709e43c627111a6697635959116a1ba5405be227ae690a2443c7144cea72c0899a275559db1e32d3baed18bce84fe11461b28c1b359938ed428606ca42ccbdb84368cd14310eda8c08a75d6cacd7b9e30c112679b65642e1a5fbca7f3114af27149af90293368196a1036c35cb25b3dbe5b90a75838efd61a0531e1741226aac2dd2f56a92e97c7ad6e7d07ca23fc6f53f0e1c39a2133c92cba1f060b62b72cd6e1091a0160a79f9e85d64041fb5cdd0ffe3df74fa6c5dfbde3e302e52001d2b7338a1b5b24d68d7175e1705ea77177ef0f09932c2834b58958a52e1315d04fb6573efcc14e1dfd7bfcaa7840fcee04c3a0293894a58600b4abf959e2bceee68edfd4f74584f015aadbf52126665fe8604f868cbccac512aba5b790887ec1ce06544db3f582bf02658b0c460d7900fe15c19f1dc6c558372e5224362ef0a555cfaedea8021f3993bd454d93efe4ef91fce99c1627800c91a5effcc1f1ce8ec4c3de1f73c51f63bb0c934af03d872d589352eccbb09383a80a3ab0100f699464187f3141c941e14806eb744f3c2582b2622a9e4007a3890cc3d1e0be5ddc6d7fafc3a60116e4c02825bf7bc587b48386c1814544ee4d86adfeb7de09b30272d637f4107a85cd11526df2e4fd857219ffbd84484e58258b5d2b22784323482cb15ddfeed93dcc6b131df880cb0124acaddc53a6a97c60f679d69086f9acc5daa7c9d7066a46d52ae247ae4dad22c8015b44f47ecdaa504fcd5f91d5b93e0ac1dab23a52e93aaca9e28098d9a4d1746daee3c3a177cb23cbd846d779e7e8d2390a9cc0e1ecc4b1aa9865c7c53e7683147f6ec4c380eb03362bdea6c3f4f1a73a5293a2d64f8d8a42b223291c52879e06904d98e5d734a7d9917eb1ebd76db033bc1d02394fc221fda881f581fff3c2b12c4748bb781112ca574f4deeb13637aa0ecf148802e52444e24a27977459056621d5ec6278e59bca52e4d2ef3aa133e1c96ecd7041771ecdf5c31610ba218feff28b9308579d6561ca2422706e4e12ba355cc362c20cc24f048a918a5e73238d577023a3cf58c1a6ece8bd27c67d098a58f25d13115146a0c3067ce2b9cd082a7b509a6a280529c45458328ac307b55f8d59d12cd2f4c8c06c33cb35c22126b7382955df18ab4da4e65b02c9a38b5338d80c3210b02761943bf986041dd90d106a59c6c25d64a32e05ddcf094a851fd4875ca6ba7075682005bf95ab06afd061d86f1b53cb183b49b5875d91c682f27edad8f3aceaeaacb07ca4ab785bf64a1a2c166cc1be9deac0dc34b0e47c6d697029516a6ad1781187e62ef4369a4048a1dc1657261dfe8545120a1ed2e06929d3c4f8e7f72197d9321abdc08c9d6b9dcfcaed5a9d9812a108ee55720e0e7af43756bdca240ea7e445671b32a509f50e8d6d0610e12d8f05bba3b5e6267da3bfea46e35b8743b5bff2f66ae8429e3b408380dbc75ba6e3d61cc4a9cde230cc231d2435b65daa6178f4e3b1c5bf01d4a3366d359bfa32a667e07f2a3e765c958bb50e83121d13f157c35ccc1e508fd3228a6de05b59e77503017285ac2c3aaeead1d6e9aa3de703e8601e364c1cd3c848efbd587a848fb5d0d6c695bf2548aaf79c1daed771016767dbc4fb42049663f08e6ff248f52674b6492cd3e14c0785fc8f58d6ec3a427e59cae2d976ae917ece0c272db207829c87fb29ed80c7ba61e466347b2b08e217c5451f95cd6b82c1ad37821251ba068cecd96228a555282f3d35efc534c9804be02bd1243cef7559b431c23f6eb57ae5aa05666a48f3834302f78930edc9669e7be3d3be690eb59f5ad99a9996683e29baecbf750a5c5c391740845928b8e196bd49b57072c73d58758057d16ecd27172bdc93f617bde878ce12cfd7f934bae0c33554528d84b72d11e47012911c9e88e5ef561be6e0ac06f0b76685fb5fcbdb56f25958c6db1ff72a639ddcef29e6ec0ea81f0c82fccf514ea0e0223f84fe673091157f829fad4c91bab9c18250adb55848523a9c0490f5933f30670c4d95f658ef17ed41a7ea4c8f1475ac16d13caf9db7022348169f8384e74abba1abbfd07f9dc42205732a3a6bbcafc66b7ec8c1a08131bf58cf6d3044b616f7c72186632097ded4167e6be2ede9ef9f7f5e77b92a80e2da05db8e2f0ce10f5be4b0d30ca57d89b6fd5177b9b9e46f53ac9f19c1062b670d3db8a30c4537b13e5e3d6a5e1123e0f6ed4721566fcd884ed0b547ba5ec71da113520a1294d6ea6899a39e4aa4f91c541df03b45f1e82a2290e12b228fd5b3676c7433d20c9e4e6038e7d8de009daf7fd5db6baceb6ef57f3aa53a62cc126fa23aa234e6f91b689ba255b4181598b8736ed3ebff33b261ed8a8ca8bb17d421598e49a0d7e1bed521d2e9d3903c8664ae67abf72ac23d7b215d31ff863f54aa340823ae9a2fc187de742a569cdda2b611d90eb436177e5977fb48360bb17d26e605a4d74c859f08e9fc9800e6dd0b3c3b0078019539bdb55122bfdd4e2bbe842daab76910f9cfc16a6e1aba2447beadff823ef2af2637baea70b10ba33063dd9de100fffa5e10ac4375e1cdace5321f26c83e8b3b9d30c95a0d9850d526aa4eb6c89c39c991a82d51079aa9c73e1fe6a75d8eb927b6cb8d95daa819e253cf6b5ab2bd2c56730eaf3c521729698d5ff5f7452d1ce8d0880aee1215e71632777f3279f88fdf99478bee4099cf9609e1574266acb4dedaa792686041259ab9f2b75d5fbaf219c09eab4d453fc56120a41be5f397afda9711afba405259eb79c8c1b8234b6d99724ba925c29665085fa1ece1663dfd0182b618c9d20aac6df1e53577e108aa0e5c30d6a78da75c83d8f58381f71415992a2db7010d0bcb7ffaceb56191f8e7e57284033efbd27753df04cb851dec773d873b216cd287becac7b9841878902a6f9520c5d2ec225a01bc0ede9ba4ebe88c42b73bdcb53cd37898ac25bdaf00cb8fe954b54d8dfa6a72e4ff2f487d3a7c45405bb8ee14bfcf569959ead582b00f03b489c2efbbe5cc11c97ccb94e4c5b7c1163955d8df6a60d082e7820174ff2d83e00721b279f82adb981b69a6812931b6b3eb295e4bcbeec6c4e4e2d9167a561825eb4b206b08c71b2a0bb1ee019a6b51a6039aadf45adb5469c607d2f745afbfa74c3d73cd44e3bf9457f84f65da9ec4a871cb58e1e251aa61db7d7fdeafea38d0289f7bfaa43675098e196059b2da99a67b700eb504c7129aa5f992763bfe7ad171adf49e02d47ea26f62b5a92fd1d54ad28019bad00ba39aaf71377ab6e8890f5826526730790e8c8790d326ccaf55c778ca8237d1caaa8b723b98e7d9cdf1cb540d7ff43765bdc73fa66f3267caf30a1720422f5afa92d86ee669403f9186f7f41d0f4db41280db7713056eb72d505ef905c436f81938dbd53a081366c53a0f80bc34c11f8397cca32cab55d42509282211ade162cd74f84a0f173c0cc8581afb3272d4408816aec52b276538398787269002e5f7c5665337db90be521f5f5aeda1ff91ca00c730d6ab3ccb03b4983acbc47fb4826cb386b53f2a1fcfab794faf429521b5516e54579203b04948ac8ef1abb26968fc127b2f1cdbbc7e5de23f06961cf0464207172dc8f7cdf1bb40dc4d531c35cc7e20ce4197b2313a8ba8e8a754f09c8c05bb43c8cb918e67978d22a27f6b902db7371891c56b16b5317bbb5789a646df092eeae6352a3f53389f1148b50efb841e69a382b2d5fb5581c9b372485536ba684adc2dee6112faa1e86862c7ff1672899f3537408eec18f252cedf480561f19f7bdd4c67b81d37581e3f044fa2fefe705c75d5c19a8fd857c0995ad6d9719ab40e56fb720cef3b5b834162b2c8987b5d639ba6f11c70764972ad8359a87615955345b738cf78fad270152bd38a53fd5e680cf911e271c29305c294da79b9d69fd0b95bcbc3bc9830ec1a41fcd7c02689e2e8bf757b57b875eb6eba0b467bfbb5a1b48f0d031aad5b470ebfeb17dd5c85557cae1061d35053b981f53b555f0ae9b92ee77601104f65a6789e10e2f1ec8eafe7b16404ef8fa2c66cd368f6450ec95362bffaae9b3fc9029e693464227990ef61b4d459eecd0deb541e4070454e3f6c520516dde67ca6480cd80e4868163b3f1e3fbdd38c9d35eb3f610c24caca04a69abf35f3a88b5330335b460ca854768dea25df99133ad1605ebd6445f6f0c2c8fac63e5804541d0b7087382c56ea2d62f263ad14697b1aa83e94a33d67aca48e8e574248ad89e2b18df5f383b9d8907b66eba6fd8a5fdc3e67965de5ff8d9af672ec5391bf110ca89e9a24f2e46ecf50962201d0332f545699d01d24af096d0fbd5ae5448bb9c9d09e82c540f3ee540a7fc1482e4795af6271507c015736d6d9ad62967345619d95aac013fe80e737eed96d8d6ddf89313d6bdf1add8ced9c47d6f1b4ba3616998552851029a16dca2e4e2e2c23121f1223a707fba75966c2cfa77633905a09ec706140b66e8bf5b05547bdfad0e75bb510edd23b568c09656b3809b7a49899f1f12a1048a6da6e770e7b58c27982eccc5ce7fa9812e68c8317342c4c529fc6a4448c221fbfa583b0b219dc502bb2c64152ddc2a955819db63391613cfcef78ced47d72b8fc7a6a7630d73dbe03accce559439541717000ae7db0d586edc63e16dd934319bd6f164a3e245206a0a10d83e790ec3f2e65580d1bb71b9440be29f69ae94ae4a04980acb74acc655d8069dfd68d87aef0a2f2dbe6583286155c3af5a5561d710a906831670407ba22d87bf570897e360a668160711ce7db50192f64389f3388388c810b1ec20ebbb39cc276cbda96516889a20c29033f7a59d5dd345353c2ca8e2d9dc5f9dcd0b6a707d054d4bd8d9bfc7f24ae0be24cabc6840254d0e371d72fea9a7ebb4fe2bca7b4e57464b4f703d1f53c568cf067d4831cfce047280ccfeb463a18aa64122138614f31c17a50e4da0f39707df18388ca511e608fb5a03665b5e0160fd2880d8c1cc0ea65da762ddf0e08843f5d62137ec9bb5baa8bd2a96f751d4570d0992337991a9a33cf1dacc5198dcd7644a5dc716bc34895b3e973a0eb2dcf4bf8ccbc3def0deabaa6b8ceaedb5f310c219d129327aab931d5c087e0fb3474f2a075966db81dd4488c84c848ccb1f71462a08e4a334ca13e66b03e067954a5f935c0a71d5165fd8d22c043d3b2a7048ea5b879fd62251f5a90c83281b7b41df1d69865418947cf302050e8e8edc69dc200cf0f9b47adb27dbdd328109591d4ed496dbc54377c85f08f9b4ad86f42d61ed540117a931b07a6146dddeef14d875813456f146c5b8e3960878f66a1f5aaa169580e547ad6db306791b134e64185499d53145a49da80aa546a1c637ce23ccf25f0126bf25d7b457ee455c20582dc1a3f6b974d3677a70d18362a5a69004762ecf3479462b7a9df333e93daf43c96bb302df9fb5fc1f5980dae91f11c5f5cadb99f7e937ae26e655727858a1856041ca23784bbd79b867c02eaff61f7c0d4feeaa149918ed4f275782623f9dac273d65d8732ec4927de045144193e63991e82d4655cae9782aa559643f8fc63c31afe7775b75a0392da3e3815101132464407759d78f2bebf9863da79bb1717952b43ea6bc51f6971bbcdee0ab6b7779f1a16a4ba1a4121fdb0e058a165a15daab7910b369bbfd4d4882ea4edad4a2aae72d07718885c32e3f8015a9a746bbab6a9e9a5d3db2b21f3ebba117df693238a327edd4340629c5a6256ba70e1e77dafdbeb229829d2bdb7f523023d20e2e5202098d7861aff917803b95ea653fb7e8db58d26be65856856ef45a1ee53c72a6fba7b055e5f21b1a3977244d1b9655c9b94875d1d76aaba47c8a67f99179b0fd19c69a136a54dfbf70c00d12775b41b3e03ecbb65567b4764381b3112ca0255bb591db954c686cf6058530751c844a3859758f6a05db0b334494477f29c6fd4d2ca97e811d3abed8103a69b888e201cba4646abb770e95e594c1c8496dbc6bf1dee700ef43326eefe175985b26ddd246564c59f561147176587ae51232bee15c7382ae7607a69396fc8e34b757c6d55b3b29ce9efa027f8dd03814cb2be777693880f0ac47af8c595e92aabf588acacc2c9a6bad78c1d334d14c7352fb56dafcde7ca973440fdf5e0d966e3f3447d6271888c3e8aba767f2b170b57a643405b05555a4ef43832489db2a2e2071acd7a85a1c301b964f75e735e2ec08a8aba1ec917e1b4080b0820f83be4b5b8a806e588e30c892dace33e88284dc8fda3599be060132cc92aca1cbe0567d4bce1fd8afe73a457eea4c6c8bd4165e58ba968b28abd175f42444f083e05c7bda05d56e6ecf6eb074b49e4ab14cc1bcc6762a59a96889a3f5551fbaa29180dddf9a10de41cdcc1dd19ebc09fe2dafb1aa2d39e16a1a61e4f5cfa79df13671eca5a5ae12949afe0bf224eeaf04edfea094a6efe0e7be340e245f3db3d55779b1ad5612b8180eab4254498e3b23bace323f57f5e6659e4a9963c3e2823f8088c5e02c6318203ce844e3de55b99a62bc16651b149391e48a4b95685bb52c3b16ad5dd23a1b1147a733ad0649fb67161c170e170ecd096a5b05f60f6593305833da14aea0c7ce36eb669ab09310d65000be2ac9ada247ac29b1b4e6667d2be457638975de474065fe2e71e8d0ffb919fd24120c834954dffe2a4fb2941967c9c358c1e1438e56f1f448657806435c6688e1c8800a71ca932a8ff6066097ba81833738274cab485442710b3d772456bc3e626bed171e60d576c843ea004e0d2c64529fda1c5d734c7243dbe9e0748cd7be2960411d89f333889fd8cd0e0312790956516bb228a13b14fd735e9e6d20a6dbedc613512aeae540154fb3111e6aa8180423bd9cf804fc5a04186992a9a7675fcd760efedcabff7da55e244eaf76fd386865909fe5ca5110f3511effdcab2b2dc98b08b7f0ed22106e0962fb44cc03742e9a206ce85325b09c16f6975500f851ba0ab5a7efd54661213bc11e18a2bdfaf7823559ac0aa3c6434e79b63ed584000f58011f55dab97404802fd50c36e4b735f52fab2d602d9a0a2de6ddf5a27af66f36c14ac87ff9e15d485b7de9a564d028f0656fdf021a4d15c330721a5e72dfa9e5e36062949d2403ab222ef84c629357be9c24365ddb21ed93ac2fbd48e4cef75cd599a40279db0fa6432a130b421a82499e5b32b44aa8e2716b0eb10eb127c3b450d59fbee78a1c672a7f114442e4fcf19b3d2f4b3352e77bee0b24611a3b1bb2bf25822769d633a13f36e18997eb2878c227befa7dd1925afdb959214db6a5c1d4f5a604603aafa1816da0caf24e657fca43cf799a48ca1b2e07a94a7f71a8c1c1bfb88906b4dbba8297beb17c35580017c07d2b212eee67c8896f311d4d109d25cebb57ddfcf5710965050ca34381f84e272b9404bb982b50db656807e9f549d4e4abbcb9c469ccab83eff461ab3738e59b6e2ca04ed9e9451f66785088eb728baeda53b83f91a7f31eb08fff72cbcef2e6aeb6a4bd28a75a6b92a9cb9d6a94f71e36ec7ee14232ca26b82541566f0d4b35a025071e5ef9e450740722f893c6790ecf4614fe5e4e71cae91efb45c050b6b15f467d4f124442e926b7a87f42ec4d0f1b32141a27826062d3fc3eb1d17eb4fc8bb9ff7661cc3e41b28729b8bbd0015eb3c8af4863ef038809cfd4dc80eff6985266f0305402453a34a1c9031e64f166c29e5897aecf430c1f208cd6ce634ae870376549e0474587080483f6e5854aa3a895b2b4a47f9a01d678863e794d66f2e1522792271edc01e92ec42327d015a4a63cea845900074484446f2d73f5118c8be7b4adbc8772e91317d11b1c4dec2b09c8fbf840be94bf4e337a31e7ab99e8d01232ed201c249a96711e5dc7815925a9d7d7894c2df3d992038b8dc89caac6802c6e58eb856c0c1037f1c38b9ede9ebb4e13938ff43900f67e0bff15d5c57a0bfb1d767af47679bcbadb8c45b484a68aa150d221ca47ec3996daf20d74c33890f34d7410551b3dc13c36223eb23c5f93ab948ecca33fdde8dc37cfdc819595eba30777d113b03568a576f47b26a77198dd59fc8f24b264b9d6faa906685469812ae685aa001087902d08030fe7b78d674f5ab0b8e376354bb9cf39fc0c6a12986f3bdbe89ba6591e7817b143cff6e2e75bfc1afa7eb279028b64a0c3ba9eab702979fa6f8853febc35083389b54a18ecb633a575adfad9e28bcbf2001196cbfa6c0af4ef2464f881419c4cf6f857f54a6bc0bf66ad8e48eb3fb22d0f217ee1c2a3c186d612edacc6801a026f9c934a796560423a1b30eae2005ce0e35842e04bd3d06f209b83755fd1b0f82fcfeeff67971e113d829cd9278002e14e0c26d350c6cef957b60d3871bde460903e09009a89d98fe4789204d55516ffe7d9fd0767343b00adaa9d25ced547f04aa68d9a07e5ce016ed014a15a3b97f0df8b30966cb7d4647099b698bca89443fe6964b5f7173b1da5ca26d169f52104c57cdf307746d22d4b836963e022aee714f9cd6da9e90cf7fb1e4b7af4e21eab56358c00721dff902950103b9029039ae6820f3f8f1d44dcee83da7b7c4bdd7ba8fecc64c7c58c0509a7a777d4a1db41c31d3a1935dea37ba67da562bda7f3e1af6378b8d8ebc54c8f57e1f545f91534cff7af785eb02677d7e528b526321314d910233e91a10ff90a50a98af2ac429e4e7ff15fbcbb958f0dea5cf2c7d1aa425d0c0e68fe63126b2dd3e15bd393d10443685ae70c4732a67dba4837b177119545d7c4357b459e3253b6cdd7289c8ce39fde705a6a57eedbb89055f25d76cb43c858dba866626bda77950ae55d45a4b7d35ad43540dd88915883f6a2080634cb68d38714d769ef38ab7656338b4805568bc6663db51747869137d9f6b096edf34783d0e6d7345b2a734ba969579fceae6cb1fc2517d854d20832240e0169d23dcc1ae3ddd9751fa8453b0c8bc3ea7274fb3794e9513e163353a4c6f52bb984bd42c0cab0a330c2efe69399a170e7febdf227513066d65573e54c50352d5cfbf081b717ebd4860b5d8a1ab54e3888957de928a7a018a3719ddc33304a344320ed3892569f04e6468a1d9730e3cf1c570a8a69bc4e94a30fd8cbb318fd3af68ea84e097b7f6eb16eb6a5878dc2d61ee494e0d6d86345f3e3126df50a5d01cf615d0fb6c13173da8dba5506edde77917d7564deb638b1305b30f97683d69417d8d2b0612d068848fe240509d2b2080adca4a1887621bdcf0e04d5459638d317ff18451416e2a8eee04635bc7485d71ad96eaaa2f906ee71676bd3e799b160578aafb222bacc0ff13b7ea418e4430ff5278cf9aa42962914ae3b1570f39d93d460861eece8ce3dae0ebbead8a7447a2e5777049f474b3c6c8aa7dcbb296dbe752c4d49677e119d6366afad99b9c1d2dc6de41930674c9e4542cefb7d9478161fceb1a74f49cb78265722468134175f43131a4e07c993e965a0eb0d3f069b643f9f91eb50203b91eb0e51245f1ea558862306f79ced8236af36da27e26c90e66fb0ff4edf492481701463a2269084463e134ee29ad7ace09ec7ef772c7c57c401fb6701c9e54790d59e917dbe67641836c0655c2e450a05f46d6c0759d0118294bcdb02d991c6e2cbb92ab6b6a88681ea204b3a2deca44451fb8157f8a5a51096bfb17016a21e9f9d9e02228f76532ab3a2d25dcd3602ee6e8a0c05faa7b79f22aa2c950e75a6493e60d686011eeff36554f46fea436c0e335e667b5ba58e6a5f15c3e1241793d43038ce1ae140cb70d7d1c35d46a1c3ef86097919b7f64a0ef80c344d676bc4c573f8ad3f63ce5ca1edfe007731e4cfcc09b1db1efd44d963ddbe4bf6fd708cc331e271b4fe3c2353929457db9adce361d1fbc13c19b6c3addcaf7bd1b6e21b4c9b07f63048a5ff7229dbc81d15dc615233130e5e6cdfcacc93c018f9cd0a2e4fe18913b0b9d6fe5aa968d750e67ed7cb2c2df347099f6d83651599791249c4c157faf821e0ba608f8de1dc667dea5ded3d2725884d4583a0f98477c2c50adc6df12d1230519722196ba15b8cc014a57758d84429e9eb5abf665629fefb93012345cb1e4808aa9ec6d44d761c4f06041b467c2a5c8aa95e52e42a52ca4890b3e8a177f61ba39481d40eb09c602ab986bde6c7c818738b03315a264427f8ddc162dec902963a29383caa078244fdbe075c8a12e113bc5efe44a462987e4cbaa2ae91da9a40ebea453817c41817de7a9ff90799dc2e946c057339abffb160f8dbc547a333485fc6aa3f6e14fc46d3d2440871c49cb5e7d87ccc60baa2bb00cdbc6a3f6ef183517b1bb906b11b3a7861eb40e0c0efa24d4bf63e56e44ceb0c8bb6d859d7570c4298a244833dd37f5ada8186ddf8f8be872c5570abca0ccf8144a231e9814275263bd0ecd47b08361447ec9065fb914e61200045a1f62ec57c067e8870df1374f6b7d5f78bce102efc7412c4146172714331854341a5e99368d6573ac29e6253a1f189aed4a6dbc6d51423f5cdd8cc622a23cc166b8c364437f60f384051046dc57e8d2f3ab5e83bab54ac259e6b6d909d05b7c870dc2ed78fed6339d7afb11af69ed0d42781feed72589fa9a301f5c02e8d3b69c174696c2802bf531cd77a89793562236d86aa5a7e5d0c8faaebf6a4a9c93cf226a4d94ee0ec9da416b61631feb9ab19331662e2ba218c68de755bedc8486f7e1244068697d84cbe77660c5053d4e301ccc5c49870c323a22406e32a3992476c22e9b3422834bab5e3cee6d003321024f34ad3ce5e67354b6a667acbef922bf95aaed00d9f858e1d4ce515fbedf026b93f82b7be8fc4ad75a60a6d4b01e56eaab7f86908b2bd3a63ad641e959dd252fc44fb067485072b6bda865ae8f6c807173710dc86fabd10e8aba12ed057a95020520c65c4e7fc3675044dd782d8e2b393cad10290aca08c7e5b5bde2eba7082c5381b01a75851dfd833bcb59c832450aa2d8cb583186f1786a8f8ea798ad46f1c2411ade8adebb435c299f42924e6b3a3259ef69f891e3fa311ae5f5d7a0365bf958d220e4e7408113aa14c1e20d0ba88844f9cbed93f466045d4feff57fabfdf6800b27a8f0b79d88d197918c78c2f576e97fd627cc68abf8aee6a48712a733da2f9093f76b595a745e1cbdb2fc65a75b44000b2deb7633e24a369e6aff8451dc93eef559b68f53d7760a8d24f161dfa1e85485be9ad1f40cc81bf636c42f6bdc6ffc89ff61297030a8cc946ba4e54d2ab8cd475fee51da3af171945b6d39bbe419e5b8e72b34c9a64fa8e81156dbac56f5f8a3d16b95341ee11b2b7f3add63e37501e574f64efd30c92bedfcff732d701717c5d9bd5c44217ffd00b8e5284093fee35e6c76d140a7eb35ca62ea1c015a7993abb71332dc8414869754cc3d2bab2aea664b77995e9d6dc9dfdbdcc3047e5458ca1401c79e9298c757e0e1cffdf89d919cfdeb17b73da207ddbfd88a99a03aa081dfe5a20ae217db9567b1ad8163c1a0b2e527c93acd08f663466cffa951f05394fcfcab425e92e2f39ef2cfba7763d77aa7d5a0bd33a552e85a795a0733abe5820be263b63548ee25ec6cbed60fc868ace77d06263676eda089149f0564a6dee9970f77db3807c05c46a012ba4097b16c27b4a973ef2e7edcfa67eaf8d182f051e4828bec785caadcfa5640b77aeb5b6066e467b853357eeaadd6d52f02755b42bc65e59411ec8171f7d33a664ed1d8b4a92e71d6d6e8e2f8f59763b62a4df159f1dbf7eb8e674991077405053c807d058c983dcd671832b46f56432a0a4d47e3f8d231a802612936017a12fec0d78f427f3a899f4da5bbdea3a12baa36c88376b5c407a0b8fc225ac05bd194ebfb758432ca88f6f28a15bb9740fd92bca16c511f68192e472c4fc8391587315da5b8fa8802c0b385224ccf83acd7376588fdce07f0a92f56aa328b770c0d112ef4856c476a06737eb56cf14cb03bd282cc9c85e3e7814a022634576fdb4234f46e83164a0e6b747add2b397eae33d634fcc1aa65d1d0248dbc0018af78027033c086a4520bd11e8a742c166931f3135d967475a7be9b1168621c2455e83eddf333e21d9dbee95538bbae3fe5cd31e2cc6fc092645140799e04304388551da2826767eecc0a1da88bb26bca7977cbb7efbab899aa7ca22d1aa4a73f4f10b3412abd1076b185ff760c6d5dd9429f99c23b511ff060fca5cf80cb51a837021d5efc02a72f4eb11a5c29926a1a0caa5a2c2345d11ebbc6c131b0ec778ae58799ff7cb226813a086f04e878ab8fa05153aba91aba05ef6e9516905c7870661fce246169ddacca566a2be776e9808c906d6a107412a000d9ae964348c42c59cdb1ebbef03829127177316b1da7150429c060d18504be43daff09a3b3f0e17e5bccc059ace441bc49c3a6b6c63a28b218efb0e18d00136e6ff6ccd3682f65add731c09f5cabdabcb38477746a9da574141ecdbf443a495a97136cfe699a3ecf9a285afc2a994b533b17b48f615a02a9d19bd7f8e74ce177c4629660ce4f692d9aac10cbc86751d8dd73e2c78339bed19b76e12317468bd9229f328133d6580c9cba157725176d3e71fce5b8af72f1a0ecc7b5a8143adc51e82423eb72cfcc0810f149a9a3a4db704c62fe833aab0b8d05e8b35c81ebaf267eab01864b56b7283304111c17090531dc8382d7feb0a59c565e375bfd7c027762db449b26b7925c325c19dccc95f9a67ba4508338418ba5858366aeebff9db1fb527884a3b458e961c65020de8b80c1c849770e5d1685625f5e2bc6280777dfdf89cc9280c027686aa7da2e1a62c044dbf10f3ae1c8471a885363f09acb5f578c0b8d6ca8a5c9e1ad121c3f677ecc11c3a922d282017359b51437800378fa35fbcc3d4ece85d554d43a34ab82703973180f93ff7e48bf4da31375b372a0d66d4168be1c9ca95ea5ecad387d3e7c3b2af5fe682cc1a6dc62413ea74bc44bbc715728f322e2023af56306405d5081cfe676498e67448f8ad2dcd10183c123cc8ac86564ac07dd82a0b4d0ef47d31640a4fbaa7b553a4f840b9843cd6964c372f90759ab004def811ebfd37194fdd263db479ba0dd745b56d34bf3c480bf353d17e341c49af861cb85c636b75095c0a08b72b701421aa8c63a3996813bc6c49321036a6b690738d3336a81162dc8c8fc97ad9f7baeef31517b028c0868916110ce6cccb614fdf8db3f9e97730df78055280088cd14a8d97901c5283a799ed949908ab0e5c1c3b1fb8a3eb5c9d7e6e69729d5c49f206610693932e064242a2eeec48d06e90e8da891ce2e6f21e8f22734bdfda4faafe04d3933b18ddb60ec44a2709612c61b1d89c195ffacd532d5c5c3985501411e19e1f6c01fa7ed16908aade883c85f2c457032dab5b479e76bc6619810db654f7a220e2e56b71a54cde02487192bcfdbf2abbdd7817ba1967fd4a347f29c87160a472218fe97c4f8b8d73d00c16f1a765132edfbbea23ae67153ec16f14b611f307e39a82c403f4d14c593d7d660dd40436e2c01e3987aca7e5e24e4ee2dd9e7a6a625caef7faf1e351c6411708b65448a353e904e4c535119dbad431f7548f10fab3e92a6fd56bd373618ecf8d246ae90d9a4f578edc2cedec5f630948af640bd97c7b83a16ff93a3ef0cb560f3a34e34a61cfdc498f263b58fc5876db931986093bbb92188d36cd9e2aeadda95fc354f13d797ae341ef1d822dcfec0b27ed13f4b89bbce3546fb95cb1b0cd630baa97afcc6fc230e3701119ab600127436183e49e563cc64f8b84f3332ccce9eab2ebf9324b974289d5f52c3c8548e40fa87936f0aa468cb80e36fabd475c910e6079ad7ac967df741031b45e59572df86a9481d8d7176a213e5bc24668ca1511d18f6dddee19e410195e51ecfd2f4c835f77034d0fd04d00808702e0ab8e6b660cfffde72b59a89bf9cd53af06e4ce33cfc478c3a4971b4e14b5d46ecb04a05c9042df7106cbb1f586629cb274c51c12990708c434803525df4e4afa9f5f49876002f54fe2ed78d465575c9e63259384d1147c4b659a815c12c4ccc185848a03f2fc9872bd1ebb22a7df4cc7d32ab5393851a119fc2c8c112b782655822a24707c1f71b7ccc2155d94c4b3f4bc1ee29b84d9215e8c00238274561e37bf5d29b4afc91d3c6a298fd89ee818634f9bc68b977731e6123ce2b9ce6d897f5b74d231c036c932bc6d25e234ba48503032b9f888431b60d9ea3ab19fc6cfea8de31774b14aaef081f34e41a8c0ac708e828c1f763a7360a077ba21970563b2dbdc8884da11fd5d633d1fe8932a6845972cab9aadb9313a30b96a8f84125f16bb29e0402f9f6800f71da00d7096d16e28c6e9f06286cc78d2246f024c412ce245274d141b007b1e8947f99c0e2e8b066002ba920d253a135a25399c678eab410bd75eaf4de608bd08cf5cc463786dbe557d663a30f0c770b1d824861453be6139633cf4103ac30db9a7f2cdcf114eb5635f4ef5d7af7576925977a987cc6a035401c42bd9d3b67b5c6570d3677d95a7f62f36e202d5f4cc890987c6aaf60a4f550f9c772c23172c172156caaab2b28210b67c191e17f370a2e87cb7125eb65e19d93f4b596fa212352db8aa6378e4aa87bf73d7e673e515646af238c2e2dce0296f5ff95a1a5152522e4c90de604eb173dac8fbc09b9f9ca6ed6003e9cc15dc6acc89c0fd17714e51d1f8d548b2d9b02b98930e84cc3affc6100cc182b9ce56683171fa6701dcb1a039350a9dd23a85b4d7d66d2dad3e44f20325bf81b58267415cf3adad279052f7c13fe96d11593a17efda28de84cf2869d4419ac342dc06adcc36a5f87499719f14f7f1b818ef953519668ea8686c9268f8c91646632a7c29f7a3fa48b9d551d9c635e414e02c4f953d3b33a583ce3fcd9a73fc3152c2392e89f6736e64f2c2a5c792d48e2581fc756f08cc1332b4370d16f35a51b981df2910e09a125e135965f603475b5c36be26acebe2a85933e3f9424df2c188d25d181f0007acbeef3bab8037c92d15607646dd7160236d6debecd4fca4d18a65c39d1f826fbf390101121033c00ff79e817851b92516429f07c11bd0d467797df0177273f8dece867a5dce27053396ad0fd9b29f020e4b89461f7758504692247a0347f300f1c8869dbddd9ca45165ae42fa5492d866356b3a9c23a6061a9c11e25a88c6f7e219f86018245e563ea88fd41683e0223ef8c6392e7bf66ba68ad56981521cd45e90d80aee5f3047cbbc80b71990d43d2b9f7558f5e10757a045fa0cf21d7674b8c6e1fd78893062a0a2195e7c8f76c36b87e43632c044426094123d08e34b1dcffae267eb2028052df17b9358553ef424ff8a9d069ad52628446b50ca63be8cbc7684005f2c3105fb02bdd646327666059e493619da09147dde07397320f734aa163f1f76c6c0fb113083f1ef01170a4348837736b9647110a8cc126195fcfa94dfda352f062cb90d1122ae9f33fccb2cb805c2e42216b3892da94a99dd2dec5b0fb6883cd9ab5f0938c1dd06ce5f8d5fa894e9572236e4376034672d35f62fa17d9d58a5417ec5c3b7bd8ee919bf787a2e1e6f67be4fa560423e106298ffc3c5d9787680feaafa224d851d187b661cf9c7c6148f6710932bd06b7b4a8c5b1a72d2e8636629830029db411f9154d3a704f937a51728dd472a3e051e69febcd7436b18a6dc831ab34cad6fac1ccedcb33c53bfe83bdeb0cb975b69654160f5d92f1fb8646fc6f3063e98aa48bbd9eaf848182ff6a3ba43eb7336d2b88b7ba865087f617693a8f90ec61032a705758e78ca5eb35461cc108fc3532e62249ceec938ed6d63c8c1befee1a069897fa26bb56b601c1cd18120b77556dcde7a2b4593d9a9cfe448735458f8704a9c86e012e657df78cf3274bc72646c60d3221b4202f21ff7fc78fe2d01f2662b7d5db071374d8108e22c05f22b579270827080b69cd49d01b52c104e5facec547fea0bdfff85893951d081c701743f8225b8b86fe001b937d33ca12bcf80a3f357f9ad4f065ad91a43b266149d4578268b557821355faa5854895a5832164eb76691f869770149b5475787c539f9f5134366b67185e942b6c16461c7a16aea06daaab36f04c8c77b965567c6a6a3bba35b4b6a64ae1545a218a87c589d25c497787d5227df28481d9c50e31974f4b9480202d70506aeb3e3c6f023c85e8892cde406ef5d7541489fc85c288e29bb6cb6689f6b6664098f9fb422abce1a55376398079ce31a114aee02efe6fda62f4820136aad5b67170936723c36181febecd20ab9a159ca8f7099ef54cbca6494c01fcb116e688fb0fe9dfcc6999fd02d83793cabfffc97aaf82db6c4b97c1e87ba710d1b0465275365e0ade866f6038536f28cdaf9da408dffc3673f5c372aac6c6a95836d202cb25814c1d451362fbc29b66079277721ebe29892b5b3508bde1b1df6cef954054d14295a0602de099fd03c5958d10a8733b95d6700db4c8287d76fef82914112f542cc32ea7e81d07b246631512a240d20456893719cc863997aa18d7f72d80089cab96bb1d76b07fc72b60ddc002f1f690cabaa32f99c52cb447d54ddf1b4760055a644e85fca68d48f82bab3e1ba48b029931d78c855097a829a11912506582048305611f0c891f29ff6a7c1903a801fc84c06534a0e7e808e5ff3ffbd253624dec9767830bdaaef3aa766a0e979d25fad4f0af69a0ceb881acef663f9e7e643bbc51ed7d70ff7a13d70d03b59d8b820bbf90965df51e584e99759e1cc46269575a49bfc4bd78c194126bcaddeedf37cb0026172b38fe9265eb9d86d2a4658495d194f31849d6e664aacde3a904bb1bb95a5bad515b50ff314ad3e94960435131a49218eb31c54e9e368ffded26805f9e0ea141aa9478eb39be659539b0a3b80c71db0e9e5d6b2be8c2d69a772a083e4289cc7f3927a72570b765e680f4d318788a339c85b32fd78db6608459fffebc17cd85f34f522ae10f1b63edd796681a9f4c90b787f9668588967f809367200e761e862b04cb91531dd10f12228c92fbdb4869996b8f50accd975c945cb105e164414b6484b5b9afd2296706e6df6a4f110cf7dc2f34df46ea262fd1e827ea5eb53bfef09463de25259787bad24b4a0fec47e5d6e1b247016ff9f392e557f251d30caee5139546999c57684a4ad61644d42a91a185ed8d0493357d1a1362bbdf17b333eaba692356fea8ae038e5956ca194a45f4b7827775d994dc8bc5774e8dc64b3798ada1b8ed4895af9d0558113415bb69a9cc6737125891d3900f4e9dc08c1733c21fd547bc71a2643077afe845b2b666bf3c53babc8986f5d6ef51bebc31cf030074773dacc8b83169b50d00f2f521eb1e6a5d89e28c3a2ab78b3b0beece966a2ace435856bd87339bbc6355694e3c5a4bd519e1b50461a51ae792df57cac06b93da3ab7c57f9db08f1aad762ca995fb51a7ee724fcfd74a11f4114debec10636e64a8830f6c196ba8e217429bb7e5d376a3d08429da22dbcab568a8e16acc90e0565b06aa983e3b14fc6fb394a4f8278ed05a307d4aba4847426cf4d69021c7bf929002e0c6e50de7c113f4956f020ce53a1d8182ae317f0439be8bb234284974a34f24984cfa8e0635e5cf794bb8bc207fab334ff0cb99e66e5261bcb1bce3cdaa4e055c49625761d8c1b8f5ea881f0c4a60df4c7d5fbae22378c229c1b836706f6941909f1c10c801c929de52b78fa1145917031f43a8e7e2d0739ea878278581ed1a49d4ddd6344e7768f86919757f8de62e96ea5dd979c4d1b887487ded4cddd53c65db8848f57d5f62816a3504a96e26e5b9794531bc0d9c99e562758edb49fd5aeb334de69bd55e6bf8ec2d319367e34cae46a8c075b3e070225f878e41611a2977af72d928576a552fdac311515d8a24863046a6ef2c5dbe089857b842ab71fdf1ce700f8f49ee38bea1113e6cbec6d5df2fcc5b86b4c328aec5b6845152b36e33eae9e1f3d1dbdb74c93ad95e342575298c11a167b099aea096441e77f0cfb48be3e3cb319080e27586d0aa61c8e2a0f6907472ee37dac826119bddc0b428e2ba8719bace30004ad30e18cadd4975fc03c93fd06ff12064a0da84f7f62c38bcbc8fa2348e5b3bc7ce8069ce15d5d1ebaace9eb7ab00e984dd67c4d1a79d1fe7784737d9a9c70626393743f66349aa8de8070972af066c88f0ad849a61e8b6834e4b866d17bcc5367d2852181caf0cf6a36cdfcc4bb34cb796ef96d55cdeff0c55064cfcc21f83f0d955b71851d5057c5a0dbebd5046edad5cfc9fb2718eef63f73d6c011a0308d949bd3d157b13b5d11f2859922ed2b529c5f8eb4120fa2c654e3dbb4270966385a6a4450a0718a124e4bf6363969b07694409ae9e9c066b2008e78e202db243a4a06a73193b4ba4cfaceb65bfcd71bdfa03139cca60f431e95a377ed6e684c892ad6425dd5677101523e34bd84d40aa9c4705b17a09aa23d5d84b9968a9635e0dbba66dd0a779d4dc459557c58b0565d7778cba00bf6b337c37cad79fc397009f9c0f7beed79976e2367693081b9e25028f63789c6464f1640cb44afc95cd7cba3eac717b4c0c22ef67c68acd936068fc91931612f07e8b291aaa1fa77aaf8d908081fd39524bad9db0d8af2d73455b1b25fb453f12fba87181acd580243695001e96034232732235ff4d042df1e313653071b0b1efd7c244d37e3324da65b6fdd167c9865f90ae396c793201e22efe01448bfffc4e87a5f79f50a302d83eba9a8222a5b3ba35aeaa4aad9dbf3c35bdce6adb638b0c7bd57a1358dacdfdb8068d338be5db0fb96a6dbef073e34b38f4f2ab08db31e0b00a171b094376199a209ae628b2c02d3c715cd43a5ee45c62fca5dd3ae368bf0d814b0cb12552509ff7b1685957cf072f1c64afae63aeb5b09f9c72cb11f95710633c995ef952b8c61f502a660bd711a9a37f7feecd67ef6e7285d9405972ccb2818f797500d2251f2c840640254809826403cb1b5532424921dd245f9622e10e45792dd130a224cda559d9582329a2037cb2cb929aa54294aca9dfd158e2ea22b2258f4ca9bda9921f05aa0a63c6aaa092ece6fb5c8665a56bc611efeebd258c7a1b1362f650d6d4d8b0c1bbe561ef06810fa763642145b933cf7be6baef5ba91a16ccb0b961f4996028a7acddac7f7b6ae15833ccd54a60bc44336f4a4036edafbfe4c53e4b0157115a1a5af55fefe3558c725c76a887901dfba4524b7cb0bb5c5ad4235ba29c09d993a47ea3fef1bc18ca1a7440191ef902381c81f440b5c6cd2131723bfe2922b0659774f3da650442f7670edc2cd979690a2014f3286d124d1a865687d79fa0d4367f107b32013f5a088d7a0f9e36a3904eaba76684d44e65fde921bd36a694a8b76893bbbb73b65ead95bf27a331e9c0e55e102626e211de5c615dd891261a382f0a9cfa50928d58dcca4040de0ea0d6bb3139f595d350c8282975d367940ed93e4f7985b3a806296ae4f23a4e7f35fa86b2c245c5b021b595a4e2cedf0925d390040aee391e21444eea7e8fd51b5dd325fa2da6b2fcd726d3bdef541708250f8b99060de111f00c1689a70daf493285ffa73f45d54b3597488ef15386b5345292a946c8e3f81c248c72b3d77713df6a287402f3b00d9427f7990b7819a9fd43d90fd531df91aef3eb9f63e32fc79e957e8efaf75fe508904b0b92e026af7ca67193221e1051f91e04ba74a09b6999226bc9dc310d53033e3b79f06062f64b3d64e7373a3ee82598bf3fd6937f2a0d6138b26f62690fa2e128f0f205acecd2d2bbf6c382ecb2ebb6418b31f985ac75301a7877c1e4ebad6e54b7d9a0f0261a86cf38a1fa59801141f6916f33f770f2da57d16905ba17d436068e437dcabf2fddca6cf406f0ab1ab8db88c4e4ecc78f91d8e4364fb9ac4b8e3df5eb591fe2e2e34826daf077e6ba95b61f3f7d397cd4111f4c85a3e89cedc8c1c700d1611732da1b1ad96147c1f956dcb90d4418a575483a84d8b38650eeb38cd196f98ee48d8b369b328ee135786ed6cdedf1722b247f965341aab6d9408da1f7a16a410806f1127d6ccfd84d168921ac9e702fa22ca501053dbe4381428e7475281ae9e1b858ac07a7a4e0007e7d4e2e957196ac2219d8a72c2bbd08a399c704f1064524ef8015e03c464c1d59ea971fe01a405b5603824d8c762f26f8890262f2cfe87a66aedb36c095147ff7ca6aca38021802d8039194faef1a59340f03c9605fda72e856671fdbdd463d8e3682d88d1469f666b72e860b21497a274c1f7402c8390d5269ae046b0779579c38eae8629eca23d783aa852068633924447121e2a9d4230b8164d6f18918782c5a8337a3462809bfa9f5dae02987e0c59049cf967fad477a702bf9561bdadcf929b9d736b2e49a7b7c933e758cda6d7b4334746317c99ea4cd70fb6f4347336dd8a07076a175039f087a3112d9c8d3ba5b15f26dd49b1df183d6893336bbe242f4fe68d57c4a664971d8f493a5a997691858aab71f9c1458b11901c8842299d0e13d40be763ef9eb38bc4c3762f582c0f1f6991b4c5468d1fc60174233450e57cef09bfcaacefad667c98623fdf902940105b9028f39ff23c41bf55117b62cad364d8d51bfcca0b6dca187a5307c5c6aca0df697f6135d61a3b05621b7c397c012f9bb3257f0b5812cdd4f6588c72a6f2cd26a29cb925e416b4ccd821f45d419fca57fb4ec5be0ddb82946b1e36396255263058c173d4208e53938f8c5ab0233b0ba8d79e17075bbb8ab1bcc1f14d1c748099daaf4b6a77ca626e7a465ac0eecb7109d51a853dc92f78b3acadc4a5b2fca15b9b24e8e41b4041756e3eb6ac4f49ea633a8350f0ee7b003d528af313373233c2b1e58d717c10145ca44ca6cc38832e155da18475d81775ebfce108f6207e11cff753af429a3f9b33165313287bcee059dbfa845182fe569d0e7147a6555b9d6c20d278b9cbc28fbe4aa2e9a71e2fe8d6236c220487eff2b55e66c21d2f75dc149cf531927b761cb8e22648f344c940b1249e83d84479ef7e41ac972d700615095090fab31c87fc2cec5ae87631033593f0e6ebf92ec4d13a67f67025a94621b47432cfe1a0b0ee9dd2855113bd3481cdd73992ab7dfeb9f04f22d0076f0d4aa89168828ab3c367f0d5c21281a67f39f304a1ca25f8d361d990c4512dea0ce73f8bd93bc2cb9184cd35a16e34e72a376d71fa521a361d504de1ddf59395fca1c319bf62bad644f30aed7d0bf52bd34ee4c3907bec8d932adf51b4e8223096a857aa5a15ec6018fccb396855a98837d9a5854e88426feb4d1485f767ee8fc822c78ec248f0a80cbd87357c49fb164398b650ef98458982e7e289729e81a54b035042a8c66b775a52f6e6310a9c318e563654b5528dde2385dfd7218803cf994e27efdcde7addf8626eab5aca3f92bd19fbd77b46fa5951a76dba89610d8bf20632147bd7fb234a812ce8128fdf270cdcb789b28dd470e7a5bcffe91dca15dad3cfd4618aec337dfbdd5969bb8cc0c609af0d0f91eb50205b91eb0e311695ef44feb9cbc76a5b915dd805ccafe521e4e82fb3f383d76d2a2eb4c6ec52f1062a288defd86e46e61ce1cf1cb4cec310e664939c6037818452dfefc47acc2868f1687f9ab8ca8cfec37cc2441091b0a2b9629f042faa2638ac106e5f568fb3426883e4f724ea243045bf33f743b50af407b8ab75cbba65b6490e23c2a3162339f93307526c36faca048144bde4da9258672a4929950d23834e5f292073479928e91bc521333992755315aa0c6e86cc0721903cff2aba600ba936a392af7fa9e3537dec36fe77b4d5c35a2a465092f5f1988502ea70cc84a9bb682d0e8bbc127c28c20e4c485211daea203fc763ef0339aac9fcdfa2a5e4969016dd4e46929288a0ba0a275464bb186e2ce62323a80e2d11fb098a343e0c1cf0aa8224e9416f86c348b0c0ab9ab0953fd889d93d16bcc6a5501cc951ee4d1fdf64ac4ad4915e9908d468057d15df059ce099168b2bdef2ff4b23aa30bf8f01b7678516372e17072a4aa51cf18cc5893e2d673ca940a1f3a0f784e404a7b50e0b6748fc85532f4e9259c00ccf4ead1ff2e5130c08dad92fe420f7efb04af89f3fd16b637b02d1d51215c6abe389f14ed4a233eebeb2cdebab673cf83c90dd0f96f578e0eb6e588869b2c3d95b4a6995d9c24aa271fe9daf61c0da5be780a51f44320f7c3c893f6446951a6c34836c19e9a4d9ae16f56770c9690aaed98736d2f60f4f9a3ea7324ddeaeab15cad5db7a3fa0536e441a633b79a1944d3e16dedbb586cca0a286eec085f08e1516e7e93e3da227b24e7fa2c4c75b8b0170a658284b201cc3488c13a2c0c8f2391060b432ed6dacb3b299a1bcb25501ec77874e697538d94b2f53950576b8ab59fb38c874a458dbb584a821b212dc34bfa0a47e7a4d8aaa028658805aa9b2c490a677bf8d826ca77c0034b185dbb71a5e74de5fb72dd6cf2409f752798bfc693e938c007d443707fdd8caa9c1bd8ab4be0d858bf240821e606ac39d4988fb5ece0fb1103793ca7397dbbf395f7564e74bdba1034a74ebb34886d37381a9a281553b3c5d4853b6e6236c86181449a1b0f4941f1abb5f1166833d3aba13ad01443f7db4ce84f4c1c61314717adcc76c920e8a9c63e60bbb59babc0a242ba3a62cc47a4e25984604d7f5c5f5157b1327def6e83121e6078707e0d8fbee3da255d95f20f842bd75132d718a83dc96729c5e7ee09d80e6b1d1c6582deaa21e625cf73803fc23c8a70c3c6188dd800b0ea9cac49ffdcb2f98ae7e928f9eb8449d116514d7d0a7c74fb492600169accabcb06f5bf59701cbf6f5a474a4b935290df339bf92af90a613fb56e98c54500cc3e11dfcd0f1cccf100a66e6f160d740a94d2274c65431b1fa42f3e6703dd23ef1107a66c17ef7e83416f59fde683f822cf456711dbc39eb363e102f4f60a1cb41d8422883c1b987b957ac44a63ca4f5f1ed5d611769acd68514b681c0ca3227ce35d4e13c05376aa8cf0809f2bd4c3dd80313371020b47f4c5177c42c6cc281c2b1e3236735e01a4e1039a4d6914c19c5884ab1eb122ab1f2e93907518646dd1af62dfbe9e4117ec5b5d5ffc337fd305b466e6cbe2acb1361ab2801c5196304ee51a074f5f0c446a671b501a8db3f840314395fd9ad1ba76402677b18f19be11bb518c1b045989462d1f651c29fa7cb1f5aa2bea18333606f4ef9094dcbdc7b9fe6c58892ddbd2a186be60d726b159d84d24c363768aee51b651c744d49ab8e27220d3cb004ba9e78636ecf213717fad7bfd7b61e258a583781691013182a1b27b6a889362010a57737bf46317180ebbc5a531dcf5098462a1f9302b909b4a37fb2910a7943db254b2b1dba78b2da754eae3c928bdfafe6a160e6a12b11d798a505a3ec4da06cea1e9317cd51c76e70e5dfcf9f4be856762a508ff981b118aebfc367777801e9056b38b55843dd9aed5e016d4833d96b467a7266060fd948da5f04a404a2c97df63d637204e9302573b62a6a4ade2b5cd2f6bf922a526da23ac2c3c227cd0480fb21b2759ca13ad5055a8d30669d3ec3432f56e362d5ccdda1ec2f47006b6fffbfd250910c4783e26446efb07260bd811c1d21e8af0f8efe7498806bb735800d58a0af5267ee6b7bdac268cf66cfe70da046a384cbad7c99644673186dbb0f2ab245d5b601a3cf1fb644dd99182ad8c98efdbd9bacac60f0c3eb45a27b4d2129a5902156c77fe45bb5525069bc40c278487fb4675b4b577c5fa3733583f601c0f9755d709a03422a05c70b6cfe647d07278644e536717777d9fe8566941984b4937d4b5c05460bb515fd26748d0915f87bedf5dd006bf7057f9310fd93f3171b873a2bed248ce9c3691400ec441d8adcf8360be0f0753075b402c1d8d4cf5978e197c5f1b2edd98185220be08e830e155e3a51d43d3ad2f77d0235c5920ae9c23d706d08170876b25480ef33acdfbe25b2cfe4de86a7ed093abe4db830dd51bb9963c2cc156b4039f60ecfe71a96163a798673062383f34ca05f5e811fd74491fa48c4770559c0ba9ee2fb9d4e4b82f58a94ce3906e473baa6c1ec07ed2700d65cbd24e184b4173f18944b9c0fa39747460baa6965c3fb01c5fc3b9a1649bdfe2b44ca20053f3e88da47ea03a573d3dcc80851245a8649973dd14149d548668bd68226946a4190f6470976a0944a6134393bccfed2647ad63133adbb8bf7df79ef9f04c19551080c0762597cec7465c5810a4563325fa9e3a9aeb85fcd2f2d8d410cfde9459618d2f2463e5cfa23e6b280dc35bc9091e6ac2e37398cad0b162d4fd4d5c98cf7db92d98cf1a9d3f4d31d0cf75da98126b5ce6002b331cd7e26a46475aac7629946347cd97b430bfa28f954f1fa6a0af9ea108b19953c2a4d57978e2e99bfdc708ef9ea50bd5798bf89b3f62d355ce806d608fac0810a4df35b157b1144815eaad96e9ee74f6dbe93b1f57109d965611969fb2ddf24cc76802d6567e0cbf42e406e1c68d2edb357da628dd46f38a73a22c171993307cb5b43d43e03fc23e1bf0dcb3ae17943a6df59274ff016a59f2530d8de03c6db5e1e2be10204202cb384f954dcfd61c17f7ca213cb2e15609ac67967ed317a23f6649b81000b38e39d2c097468315de695a9dd42d79f4dab5bdbd54b39203740ae87881f9aa38d16a328f2d16a93c6999ba6bd5803942d0b0521608a185de8b2125dd0282c6dbcddae4dca01b0c98171447cb1bf948aa0b373f9a4487450a1f9be341239024fd0d6e926da2a4360fc22805a18451e428c92852ad719c00c57e31784c8faec337b7a29eda092dc65e308e0096456e97b20353565851bcaacee6d715cc26e3fc1a1d8ecf04b9cc59b8e4c0b9ac37f05cb25c2cec0f6f2588f2e75418406ff35167ab34234a0e412eb08e362273904a6a8c62921080d57752c49f5fd727075084cfe3e20b6fdb4d876f16d04264fe852adb1e424b13642d6911f7c98518c2169f7e488000e6e807e6e4b1228a913cc8d462fe91faf3c2c02fafde35fe6ca902779935f4ecc6b5fca71f998dfa33acbd7994b6f9f3d3086adfef3d261ae78d313001dba9701998377f4081555a7d1c0777c42d38057e9f9e02d3eea5e862be0956c91f3a46b0ebde5dbf3ea96964c3ffd5dc147f989402ff99d0c7c3f17e86190f8f7d373ebe75b410e74383493db867b7ce7e06bd3a4bf0c7d723bf5ac3cd60e0f68215d7d31fa2249c6be053666bedb69196c2b8e6fb2abbaf70cb251b32db0804a4b15898223f72cc777c9928e32d68d2305f2686123944867012401f48670ca43eed8e8258282f427ef929f44111b1f0178bb622f6893beeb2891a4f31da6e523a5156014672a06f969f78c6f1b9ed216242aa981533bc3ea00366cc9e3f078a0882431847b0dbfacbd23736212be8eb1f6dad64d847233de29bf4895eea986beb1832a06c31f09cb7f7d9db2f0ad471744c45f62b0326b775352611f03ab08b3ec98c540754d765127d154b04fb506d3d32e02905a51b4b74476e91654bff78bf56cef146adc386fe9c9ba33d84846f6957ef654918b369a7ca48bca8c6c9446d2aaaf9ca1bb195cbd1c0d9284fa4382273107962a1acefe2bd9b75b6ab2630f5abb877a9bfd118993289f485ccea94fdbba48459f3ef96ad5e6addd6c567194688b9a9776fd1610cdf7682ebf2f826253d35161753c22e97e7a191a755706ba224229c588390685c7bfd6e91de612f8e16d84c1080e778cb4cf6a508751f7e205e4c0ce32c2c3e43ceed4a5b2e037e75d72fdf5f3936edd84be2c3746fb258c4fd86c964f7c022ee512d315f5986ab755f4942a7d4e08c17e5bd43afdecdbfd76a57f0077258d16a8e806b62675bf15d8a687c517354ed7e4b4ea8ed4541414b0599dea564e2a24ecb8e3439a12b8e337a5036b5da541f656321cdb90c77bde5b76fda61514a62c2752395e7e2a908ee28a12da18200048caa0e3a600efda87d6c5089eccb878ca46d9d0c4dc17dba56532e0852b08f26ba1bbf15fcceb84c1654229a55a44bad865619ecfc353544e75986873b5371de0c71e6e8de24b1dfd8485bb7ca68dab6678c64c539785021707635b8a0e0fa1490c8ad2e4ee4039cc3cbae0faf66c18e88eef12855852da2bb485ca1c03c962e20678b943a2d0e504b6bf35f7baafedfd66b63bac85c11ac227f5a7bf5c98d2bb162b9510bb6dd6d8e1eb57801caa67d4102dd0cb77a7e17f33ea46d0923d88cb7f34452b5f76ede07517195d520cd9609ee7725e00e838ca5cc4f2fa88e2191b28f95635caa503c3edd7431b8b7e0522b785e1ac940e2558025455eccb3faeff2ba1767e2e5f60b95de70c857ada13f1a1103a99b7a0ccce268616baf32ec0a6b395d7af8208db402164f7b2dcd4706bef939b8378973998ebd308c350f6ebed8c7188e14615a71244ad59960377d97c3fa448a627927cf031b3dbe94730b8e1e4e889a5be4e9a68e5116e0b0ab7e218addd73f1296fd169c3bbd71949875eecaf419209bc293ba39656f62685d4e60908a45c56ec18ed3ae408e947fbf4d0552e7490cdc91b514f08b7f2022a036180bfbfe4106f263d66f654d4c655be5a0d062ad6e347b0ce0f1d8a97ed35883dd196e882bc7835e8928edd29d23f20b2dafc0e1aaae20b48b81ccdd176b5f628ae095d6335a3b457826f1234c1000b0b0a1ab83ec157c450070de50e5e35a377c970a4378a7a5479b5fc39abe2cc48cc8a34b5df8fe216959dd9e4e6d757d7c79f9ebd84aaf6aa99b56b679c0e7fdd7d21856ec261bc074b0cec240d98527df4c9954e9ffbfd060c19152deaefc02ad08cd712b240b5baa3f3a4e97135693599b10156dd1876b4f86b0c6f82efbe611fa456afbcbed3ce19383400f5480b6a0fb09feb5ce236366cebc2da133df2725a72cfdf8331d6748d29054ac106b22810fa3d07e6ddcacdb3ff595ef5779a6294b500f3e7e401a1fad63d7706074ebfad3043f12201a2ef6c6b94a8cce3dbd9b5fb227c50e603a3b315b2c8ffe0538924b088446f2a2fd6fb466a3f4d474320c4a5433ac0265112751cfc13aea0b31077a2659411297126312d71acc5e14ad0f1931ad6484ff42111c5a94f26487444a1d1dbfa12192a4eb96af4d915289f69c6697a98c03a460d2f3ab398f191dda7d877236ef8aaf079fef54a14d646e22c10e1b57f45f53d640c6b5e562166ff52a810a0a5163dac16f5f6af9bdb912335398ce83625a740369eeb41198cf785adefc8f73fc93f6d07ab383fcd4d900e218f443bdc1c79ea039488185ba1babe15993e2a779030640692489333df1f971dd0c2801a412c8426bd79599d26552b7e57331d9059e3b10d13efec7a16b43a6ac97a078988b71f7cb5b960133279bfd308ce0f0447de6fece172f6333f8612b569638412e9f107166df4042213c9cac4b3c04bf6675cda9b3e49372e90dff4882e04af214c416817b04ebb645e643b68545e58c2734ac20aad55c9cb544dc3c5f0d50b78914205ac59c166f5b6c029a3c2f7c06635be093d82e539553a149dbea3c1f81cb9e22abeaba0d6e2a410ed4eb1293471d052f939fd8507697e45c8f85d52da7cba8834847fb8c185e6529251e9010dd3f2a8e1857144e157addac384ee01af03bb684e062b04c0854f216cecd6890f73dd91c4301387991118e906f9284813377b22acef02aed33d0e34cd32b47cecd7169b9d9dd82c231392d1a53e1c77b3235c8e7df0c7d1e9346b41b7ae4e1b95f4f731b055cf8f6b322148ab44f24e34607584a3ae002b2ce55ac1b60833cd1cb1c5313e6e6f4ea59cbe6f78edd131b299e768552a229a7cd887df9523b85a74b5ab62ace1b36a385f06e4e8d14c82cafb70191546a409f326e5a9e503849a113243d0d244e214835f17c8db598a308839e2b666800af8a13d757c1c507eb86565054d42b677d5159cb22f017869cb12f7f22c9ebf56d7a3ec943be6f0e215b0d5948243ea2157556512e6b81aedd3b69cfad5a7771039c51dc1b5e843caae4d7c986b85d654f618f5b6e77b6f48eb07b71f690d818b561c133c6e5c5076d36158671c31c496195e17732c2c203c1f58ec8df676a759e6cbfa3861402f472ffada3a23aa106f4912f7b5cd45db7806b55f4caf1a1a654881dabc5132b832ec28d2d5cefdd3cb0f55ab29ccf6c46d7523fe143bfdee42038a985d5c9bbaf74962ca90513985a6ec265ebe2241695c5fab89ae852f7eb0ee508d50d278ff4fb923db47951e0014bcb1cd14f96f96c8192f2c70c0f1f13a82acd8c8f900f1879c2417137b8f731e11ca94a6223a7d3b49bc4a0aaf49419be3f4ebef853a39723274f6a93650018e821c4d2656f931eaa205c13b48c3f2d7def757dee800c584218fa0b71a0af6d4fda04a2d730e3e11e03f66a2d67ac0bbc7a6de6948246c894edd59c6785f0d275546715079b559f09d66eca726fd82bb1b28990ec6f719a07515940a54e266de6af624306d617d53d7c80ecc1434dce82552dad144cca376cd368c637d8a5d9fb3bbcdbbff077fc2b2b0b7ea4395ee1ab0eaeb0b9b6bc33ec1ec754d3a0f7d8c324634f3e3f1999231216a13aeed0d4e30c17aef8147811e2671320f263437502dc0f541eb0655ea2acb680fbab6dc7805027acf706043fe9ba7ee93af05c4eb0fdf256c174e47d980f529fac8a6df8db3606b04ed30c606b83678f98348b8df3f686f123156c23a49c4d2231382d511509bf9f68471a16eee3737672c811a71a42edd31490989e8236048e97d4c638cac7d44fa66a81173005adb4e29e3c0428f4187b782b88cb2ce99f2cc351c9590679bab1f73cf2b0171ff1d185abc2eb04c5a879edc036b992493489a4383c15641f1e850db293d356edf94808b5228215e1a640687048341922c9ec29ba8c4cd578459545c2ffdfe43c99f7c841c48ac5501f0d2c00de969bb0e896be4628c59321c48b57a042e9ef2fbe02487f99651af9abddd2a353f49130104e6bcef03b33062804334fe8f4caf37e90f5d86fbe9a7833a6402100ea96f5bf6fc935dd258108e2b6f3f8d617f47a8a26080777068769cd9bd3933a5da9eda8bd32586f3c7251f4c33c148b8f25bf7401320be1a67529c2b2b6a7bb9bdacba5fb2d75eb74f2df74db6f722de00574dde40e3a5a6fdfdbbd29137cf66eba1dbb29a9fe38e97d8756493c53fc32186bc1d5f332b61076d94167814bc18c61e788d3a2df61a171ad2464a76f426b3cdc6d485f9c452f369f40e283a46d72d9029f114e805ab61069a260209c9d9ade1206081f261e1712dad2df0047165083d590ec4de864adbf72e8d9e7931f0ece0e75d1690c2ae534edb41c8d3b7454428d1c153378b9fe59b7c8d1937e420c8cda80b1eff3aec250bd41b4beaa3f2689be12ecb9854ad73547bc1a83d06c273260fdd50dc05aae55cc0e87681558d3e8bf28c3c817ed101a0a788b4c237e0247ef9f9acced75db4dbfd6f34471424a2b25c84aaea9b7251bb629d351a7dd5cdf293dd231469f96036c9221170a35b0ff841cd74602c1275a3fbdda11bc522411689f08bfc54da378326158929937afee4f13d59497ba5695e65bc306e173b00217305400ecb33d8ae24a9ea8ae11eb8cc68b97917f4c94352c02cff880243b2c9a872ee22ec7d1f3b8514fe2e6b0a17aa174c8233bab36a571633ea2bd00db10beca5040ef5a25777198b393ebded1cb15422ddfebacd91ff344de9e58b5732afb30d829cf43661d9f4aae2d1a1b86115c5e73ac85b0a3674bce31f7568d8abb8ff421ab193153815700739b0d1fb3bffa2a12f4fc18469b6bbf3996afe6621162b6e3af960617aebda9a1cccb4f88629ccc8c45b496347ff22510e32d4a35c8179e723e775eca340885030adb22e95161aee996ccc4b5fd4715514171faf50240512cef0d6392d8e141cfa80616259cdf4ddbc81a34acbd19dbd43cdfa55b76df7dd94bfc670a7f56bac77a2e118df366dde5670cb656c389c89f840c8ef35d1a5bd8d50bb6a1f89fdc78a92bd9e7b88647f97d3e7a12e29018ff5b5f86b8983d4063df242cced9c6e87080620cc2f4cf7d84200d1aa059238ee15268c9d802277f693c0d9e3c89820f06d082a8ffc60023a326d5a90f48ae1f242dce0cdd80ac91e635ab12b3e28dd81e5284b292b263c42383beba8d236ac58251fb566136a332aa5c8e4e5ed0c89a521d60567eaee62d7488581d0609bfa86c6d688e8477e6f478252bbee4a89ca3c220024aae0a66db17c754a74076c09a1254bbfb86584196b203a14f193543abbe736732babbff53b443bb0612011cb95e8f724c5086fc3a1992654e1ba5e930f931501fe5bc8db26cb1dc46237fb8ec1780984d7bad12d66fced799c6a3f79a401d9341f76e0d6418a099e8a700eb680858a69a5044c9607fd6ad286961f78512a54a7404b77065de28c1b5ca5d79af7fee22b14c8be4a0e43797fca412a81ba369c3a715bbb33f1a2f74eac588a7dca9e70b99dc4694125b7eec462ebbca44a845a33706df4809eaa879e257873ae17a055c5f9255a9d1878fe24b249c6ff0075e2e361a9a425988c7ad78065df80b3e911c6b6a2496f5905c4729d8c562b31e16c2987da0ce090f1a86edff1d4fb465bd09f8b1746790c02f677d11e2e545c5a331e5aef326cc97647c0b426389e036147cd9c56df6f43a077e92c4bc7f1445cc0eebb0f4676dbf0bc55f54cf7254f4a9bb65b663e11a0ef2ec799807e67f4f6d7a5e68cd469f3c8d18ec5bc7017cb2797f5651eca1d5d5b7e81050da5280e89d7ad8fadff0e82aae99b159df7cc1c8c0f7c017b85fb6ba4a2e78a0b99c342a0a01548753edf2ea82e6d6167ae85f1a0d6074cab66d47edbdd06e57acf8df30a13631871208d23e2310078eda470a10c222dd0b095609e61ba3eb1034c0694e4c0a5366161658304db664bca8ac76ad07868d4c7a4ea3ed7509e6a6ca964fb8814530dad4dd646bf8a267d45a4fc12d2358b1cde6ea540ce317927870c659a331417fc1a5f5bb43b4c3dbf99521d3ac1584337d68ce6062059e4e493bafaad1c591bb23cf174bc5210fe340d0ee36e4eb93ccbccabdd0995d3ce0febe09d27f454448854a98d1520705d1989fe9d22b72247fd9343b4cb9bb2a3353326892cdbce110d57e04012581908303be32b0ab216e553b6ec11c21e59a044a2ef93c4487626730414398093ae92bf3b49740be73d01d1c98a4ecfd38a96e33ba6f83c3b5732278c1fd41382f6f58a8e2c7ab20170679c68a80e074dbb30ce20fe4ad8cd288c96e6db2963aadadb0e52da8f924331a4e7ced8161b8ea8c5b397123f75c1c0d9a74ef863514d55a6e2331e494c9f5d5083954b29340f5ed1ac211dd46ad7cb88423c114ca064b4271c3b12965e8feb54e530c1c37d42201b3f972fe42beb73d7158c2e1d4ef6ec5ccfbe2b7a9af6f10c68854dec766b272fe71b2547cc7f9746143ec073e7a0b296de845565740d8c770b672de5d7f742bbac7f6d89111c7dc320cb9e048c763f43c85d2c4d3986ba6fe9300d3516881f720579152704a376d22fe895fbac5e331b1371deab5d44894250cbdd64b4a31172623eca54c42326186849ccbb5d54e16a506702aa9c4888667f4223fe479e512ff26fc078cc0ebc4d35b67c642b3ac56aeef817ec16890abaa05840016dfa39e8f34c86bc6bfafc5d47f4358b8464d32f93cb03a1e04d3d96b26f70a1372df0e568410f2c5a43e6138cc74d6ad001d5e1c9d290ad6dba68c8190601ad330cd916137c88d7b7a875add31c68824143191f3a78cfd6d4c75e29e76088ea22a07f8dda5cfd4c15505bcea475559ddfafeb3152fd67b89978c67aa8821b6ac0c3d3537e5d3912bd34391b1c721d0615e1b0475285868339e89515503412aec56159c92568c1372fd6d222ee97b1b34540b4284097ce87e49d3071d11fedd6fae6d4a54b230bf7d9a1948c63eb109c6d8ffac592200290c0da6ccae124483e9e072579c0cce1f4441ccb90bb6c416b4f0eb25ab7f366dd76024334fdbdf8a97e29c217bc09fe12eab0009140b3164b5bab98793c0a3b95e6c5cd94ad6f178380b2a9e296435d9a695d3246ec0ec7d5a477b62af52ac0ae7028a8df1c94ebe6cbc6efea015d21f91ad9b2dca94a1bed076b3c2cd792a1c6e0fbe600fe7bdc6f43b715e61e1f6a32a227ffd15a79f6a7d1f613c5f207c9b6136ceb464b67d81fb41da3b5d6ba13331372bb1045472d8349ae61bec6c421ee4029a9852aaba088c2caef4ed1528af6489ee0ac1e8102905f6161b56e98407d0e840394a3d823f503896a70058705b9e436c0839a50f5dd88332589381314afb5298f62fb91c79745a7dc3812b39b9115d2488f985ecda2d0fbaf1afb512dac8f3e000c53124f72b618644d40c61829a589eb7784dd88cbdd12b1159e42bdffd73c34d2431716e1f8635fa2621aa5d78ba6b55184cf5d3196d127db3984e0a126b4655ff07c6da812ca3480cce7a6548858b16f1233f6409bd100fbdb1b0e4f810fafd6464b16d447a9d4827b1830d153ded14bf503548ff8ba38696bd27e26b9b6dd97cd73b1fbcd784ab1f23a02e500664f902970106b9029239e823923cbdd0f296ca6d6fcf69bd44c7f3cdd40a1c69fdc0ac86d7fb91c7cfb9e1ef08c5dd8bcfe5b48450ad35c23ac642d1574f3c27d90ea3ccc33c89e2772cc150f196c5192899a30cbb7725ea2ae8649977eed6d19651b987467f1f85b6cd499cc1993520fa360d35aef6a720a461bac134b84fdb36846de618f3975b8f998c7b08fa61094281d56b14538eda36dd22ca8f4252fe3edd5553a94fe7796c98cc4c54eb60ff48610fe37f098194cba428ab9906baa3d26db103d97987f8330f56dcc22a344ed463e31db570430da6c419c7d62d3bf5f66ed47620eb21e9fdf1c4dc5118767adbe0ec7f997233832533249f54c7a07e3e065ae8d02e68b1d0e2374eb608f374a54a14138fae94fba9f725ab4f9c4d714f5300c020d77cb4a257caa4f37b8e218251322a88952567f9be40f51c86f61b98521b36bf10d19df84d5f6af2b7edfc596a95720a223bfb5fd026090d9b120e46ad3a6fa24d68f53409e6ab24fd4393b41ac3cc72a2ab76cc8977e70c708d25a632bf9486d7a97e0912faa1a7cdc75f80a4af6ec11340d2498aaf3887312c27c9c54a7b1689fd954a71e077031509c9309594d595bcc4be24f3e1b188532fac4dcb3d57e5b7108f2e3ea7472ace76c1c9c7478dff53a519a7324e3e15d0b99f3a8b71a64ad232b0b73c846536773348ca5194652d199c9de8f2f54d7f7a45b9670e6f82537b921ab5fb60e59a3e8b22c7e7d1bd966b77bb401ba240eba569bf599e671e2611ca899b955e079830f42c810658b6d314f27291b1aae0fd7020269d2ccbced8a54dbb70ccb5cd8285e3bdcca3fcbab0ee0b8d8f746533aaa14996635a080e413860cdfb5912e477730865b84b1adc238540b22599f6e08da33b2f1611a4831fff3db90835e559afc139b4373e0a1c8cdb4fe99a6e90f91eb50206b91eb0ca9e4193ef4bdb3037a51fe44efed4da6809052e94e6a0f2603170626eed06b08cb2d5592bdf7306c5f631dbb12c3bfb67ca82a52bb4dc11483d59f71ae6781087c88a50ae82c9fc4b93e879e81e199936074a5c12e212f8cafb6ea5fe94883ffa5ceb0597ba7c3fd2bd2f52c4c2ebc3032027d451e68c704797a2f505482a21054854a64e943330842589ae1d158a7c8bf7b30fde0ad33fe86a9aa1b60f7a62c7c43c2739a07f16b57d9c6b3c8f70ba4bbdcfa6f2f798333c35acf2929e332c41cba7a70211c38b8adf3a1afc589fed5aaa4ae74fe5e7a0ac04a61db3c849272d2fbeb98b047e1a2264899918589ca91805dd714cdab5d3e77fd608a5a7b843ab09ad97839646c39d3832e40add50f106fb741617bd97421f7c5ed3bfafcaf55e5ed71a6b688096bc707886f4ef816c4d7c9fd8fa4b649104ec74c760acdab5d80f323db7bc54529d92d4b4d4a1347d149c711a93614dfc375f23ac2c7dbc16f58509d7a28431ea7ed5d01b031a5607e9a2515a6fd906bcd6c5f74ee1baef944aacefa4327b3c53fccd76388cda097649cd3fe095a3006e238ad2075376a0145b8a8e27a4e23058646279ee4edca2e14cefda3580be423879f58ef739b535c0a1209d2013299fac98dadfae79d56de72503fdb56546d0083093a4ca2f97b1f6d77533bcbcaaf6a51970ced0f13293f5ea83015e61cabdbc92cc27073ed6fe71374124f089c6c64194c1b171d4e6999c35e851d794127cc9e472a7f97a626fb09a0b5e2e275b28f52621c1b5e1f2938d854b554e03c71951db41039dc3d6c6d7f4033e4cf838313850b8f3fe6007f088458addc29ab20db2720ee4891d95b9270640511b8af2fb7a1e0bb569f81929d9f3d683ad01adb9b025e1014261ff287f37c816c12c9148bc4c3395c1bf316527bceae3e1cf44e56edc2ed527c32f69c7b82f8e4ac5c312542dedc6448dd4eb2f0b49b8c9eca0481bb65eedabb3bf877eb348451ce09ff6565b0c1732eaae7db3e53636ebe8f329533856b8a5a721715bb1286cb296f9ae621c871df83cf47dd961c560423e0ed2c5ad9b58b595be8701d267987fc187680128b241f905290f88d75f5e8dfbc4af0a3d5e24b7e15b7cb3b0bba691673cb2aae91df6f784b2b530599ca02b148729e254e612cf3afa4eb2b2ed3fa7b74597b3bb2ff66d2b546cb0a9ed593435719be0818ffe4207f8a80f690cb326139e2cbbf9dfe88274ba410e89602583ea575a62a2bb006681191500f5ceb5fcaf7a58d2ddaadcebe51386cf8fc2781045e351738c9464f808ac513a86de8a544f83eabf78411538f7ebd2db7e433000baab8d4ab94e3948699604ba10b8256bc169bf7f69fa86604e1c1c6aa7e931216247ba1231add85a3e153dbea96539a80d70fb28102a74bcbf5d875fd8bd0439383b8721d2906430cd7b244a2e7b9f14c873f2b3e41fd9b5df5326b8e938b0f62e496c6b20c7f8fac840a8e5968066e1db31fa77e93eac48719ca515a81aee913608e86f89e12de483a31ab6a3bf3553f678b2970630c30a4de9de2c6e4a26d23d8dda37ad4dd5305a310e194fc4e133b17d752bd2ece3edf76ce7942c756171ebfaa352330a9c865cc8ea3133d258211183d5d9d6e50891b881373b8dd1bb1e94bb078e4ab143c548cf10430b9ed6c4e151965e5fb22ce2215ef849e56655059c2717d84ad761eb00634e743fe6e6ead49cd60ece6e3d768c5fb03641f3d8d093b779fabfd9144beaaeaaef1bdcfaae9279bd9c28f29c53ea2b38301992d1664e9f24129a2168178895fcd59599bfd9e15e688e17743c115328b2df4582a531d222722e76d837f05d1978a084661090988392918bd09226885f8ee4c1d09f6934d5d37560addc79595bc89b726c36bf25590f33cc850411c61a7d361a17aa5eeecf2eaca9e596509c2e87c94cfb80ed8ff812e287b6ad01d33912175469f4c6f15f54f66a469c91908320a4b78b83fe3910c43ca9ae10c25c7cccf5d6f4c4093254ba9c0e5f68f05d18d7a1df6b151de7e0fb0fb9c80b75dfbcfbc84853e22b231e768db2d95328605b299bc2deef2cc86a72946a24a59d9247b28dfa027fa62b5b7f4ce0867d910692311a05b2d6626289dcb6d02e4860bb58f3067371fbbd650657aae6aedad0f3078e44f2cadae6a17f97bd53224792a6267f604f20202430a2e4e5db0571396132ad28dca8f17b649521745cf2eb39ad5ab7f03613d75af8db6d7edbb3faa624a2321f7fa9f758504af90d9c308a8dec19942fbd84118f45891d0f2986a75bfdebf4ba7e73e0e688246f6d1248f9f59f14ff64f8e3288d16fd22281dd2865c4fe2b66632999fa6e3a5db316d46822fbee54cbde84455efc9690b5766dbe5ddd6ce909b9d669420f936a2d7d0e20884598b60730f2f4cd670a9bba49fa068ba6ceb54f42bfc1912ddaba84a54abc8731cc08a8fc92bf7eaafecf8ff0fa314b73c4e25c0ecbb87e033ee566ee67245d81df4153c0bca29e14fc2e783263cbee1294ce97a88eb28410bf516875a9a9bf0815380edc2c9876bbd96aa896b0f61fffdc82819e145f51d1d23f028c2d287c1f249cc75fbf537513b7b650c7297ab8677dddd36f668194bfa5e3951f1e989656f5272695c6b9a6df33295fbfb824a037466a060710c2783c5a4d6fbbce52edd4c59f1714ff1e9d7ae7bb139f8a8be4911fbbdeea4b08766fa66a7f2fabe0fde600834222cc5d239dd2459101a2f6c5494f04b4112cb9af61f5b50a8029f13e50d9ab87e4711622ceaaa66365c597d44d978914d43c02a1fecfa60cd963144d0750a275bce57c5907df2628e2f5d6af33d9ae9db81c4e0afd5d2c1e1a51e546a745b59d7839822dac14266ceacf1df765a796090b45c220004694d0e2ff300ce7203b5d9c683be2a0ede69d14c8af0aa8458f924339ef50f37c726d0497420b3af86b4df2086d7d347dd41fd4cdd067d628520ccd591eae397045da2545178709f9da14fe1a38836912ab8ddcc4042ffc417cd4579e69182f5f72edff4a075e612b9a6b94dbc1cd456bd49b1fa1f1227d816dd7d4e15ce7ad3b763a47e0f3b18c6298532d12327d378c43883a5b0d5f5a7f00967cd7b7f92e69196d7a0ae361f482bf80670fa25569c836d150cc05464db6a670f75315a8b555955e83f3b119813c13d1c3d59c7ef2edc17a0f84b21955aced581ffd5e350f431ce3ad7e3645bf245db94fce25ae91f2a6bf0bd8a66d4cfbb6c6a0013ba3beb6bc9a486de3ca0574e6002b9f4ef94aee638ca5437bf5a7acfd19ece37aae54303249d932cc2c9d13172f61a44491b3a01f47301e65a67c7c701bd2f05018158d821230e818adc2fd36771961662956a67e6de1aae8de0a55bcafdac83f286e6d29b921a20f4c8f88c0ab2758213f22ccdf78e85866be29e53ccde7f9ba52044c912a98fdf4534ec2e0a6f60858e117c9a15432dac4210cbf7f6b7321892832a511d5456b673d13f2c17ef6acefd317ab6d7a613cb871c9be253c3cfda60180ac586df661758244da247dd293c2c501a848cb7a842c4c2349a505c5b56a23d3ce1de27d424adf6721e264d4b5c5aa13f4d03f8f106d81a05fa5691828ed6c0a93e1bf77737a97ff0f52d46142b0a51860b44034cf7dbfc1970e4a7d40b0030f31e7594e160098757aabe2cad440645fde53ba04e8881f4983d9f3be101fbb0bd5b6233a8b8c615b9e67027043283a5b493b0397a36826ade11deff63b2a2ebc90855693884e583b2cd3b00288100264bf12699917d7ef14ea350c2e2e95ba42d74170459d77d0eceed46a1018f44502642ea75f7308b1f72959ad2f3dd1f80222274916d1428866f1191d663a9461bdf56f1e64d4b961788b9c8b561e408c4f13cc280303ea2c457575c4ce4020e90afffcbc83f26f5d3759e5084edc9388885e83abb72f39305ebb595a01ae67e2a8317e5cb605b7cfbd71aa3ad40f4e5cf8d21e6f6c1041b77f946b76f10b414c2542bf6b5ea59a1faf6c2d6246aeb24c26540d68bd3f1f1fc2f017e46c5e2773231db76702ea1fad52bffa364f9c7b2b4e8cd5f174789b6e431b0e37624f8eb3da31de5704e40d8ad4c277acecc3edd04635adc1619bdbc69ea73db6c2c1dddbb899aef920c4a21eadeac92402e7758b34b574c27708aa81e86fecbfc36f4d679c5f163fd64b54beeba2a8d946600d9ad8d6360c4f735da77b7083143f07c878d44538e2087ebaa9602dc5c9401318c23faddfc87f0649483b84a9db35051434e96d8e0cda38fa9f59fc38fee54bbeec94ed7be4cf7fc370555eb1915525716c133a0328817319f80fce47795f687bfc6f3e3da4e86d0904bdb69614f3a1e1be6e0dd60ef3b2f5f64a58ca88bd60e3ca3d613565d5cf4a9a0ba7479302e456cf402514ed31356502d83ab3e3b636b5f24d8b5923c587b949acd109ebc2c6444d4952812d9483709bfe126fc77141ea56eb6d442e5397ea71e6d13829277fbef2d91980cb13c192d0ddbc1e0650aa0ac9f6c8e5f2c62ef2d323b7cfeb701081613e19f59d6ab0217c2051937d3b65342ecc8f49628d2dfa33dd0148cc37c000fa4eaaebc10dff9851d1970c9f7adacf138c106d7c4925991fad8d7932a311a929c22c558d2d4ebbb1b837fb43947cc70c46f540603dcf5ad0cdf1cc33e5911eadd44b9d7a174fdbb3b3853f8528bfe9f596909a45adcb89b31cc7d68ec7f102f74030e1569d940df78689eabc5fbe4385fcf93f9ed6fbc7773d6343ba079db58ad164905859197e8e9a08b2ef7e6ff7f1d79abfa5c0ccd9c0404f2e151c4f426284c5edeef023d2ea14dbbe135046786284301971f16e441945b2602b7fb6d6e4c909cf4017dbfd87b5b1b5bf7a0e09158c7d5be0b464609c71c883aea7e0dfa1d426b64ad67c84ad740c678234ff297c81b314999a932256c4e5a43479bd32c4b1f097d90863f1499de52d9651be207962c0cf5c7c357cc174a8e677f031da28387f2325ed616afddc45168b125bec80d921aaaf9817c57922bc423c7db7245c3606566c6eb63a0a4f71ed402632b5253840043422215ed78e4849750931e3b118bdaa0e3696e88b5823b9d559c11f3dd59680fe3f8f7ab320dcfb599c859073009a61e186c5fd38acd25902d1dc43737ceac270689f7d5f002effa5e22f490d28cad6b6bb4bc851393c8295297db8f81a377f20c9f0f1c5b896d52ca878c55bf3b7fe612582458b4695fa66771baada4118722a1b2b20e00d1243dc770f2548cde7e71fa1cf3d91cfe031c61492012c79822dd7f3997591cfdb1361a65d94b05bb746170460cd4c70219344d7fbbf65ce938095014722964611cbb2a87d6a63f918555de320ed6189bd0d968f804c95f9adb7e48689a7cce6476c9c3f5102616a1ae76d3b830e8bd9017bf686ff7b5c144ee66f857a958e3c0ab0d4c032a835a5b0d60bd9d0ef2518f5530f88b343b720287ddecc5ba3154975becbd5e0773926c7b8a6dd1fabed3897de2136baef5d09b879c7ca2578a12f4ba2edfdb45f1d10aaefe4d827f7b3325851aa337871a08efd95de3462d1465eab51c9441c61fca81a35b8abdd755648d3762f1126067f4dece7730a32eb6a78ee337807c4ab84417cfb3a630a6558bad0d022b8f4053eebe8ccc91da36a65a5144c62504ca8f130a2b9c25f6cd9a726ff14e0d0cfe0db7d8041b834c3c2da8394f4399f35597eeac548153385be073e5a5f623575a8c3d15d9c1a5d4d43e96ecc68856bd891f8c01d3814a3891ac1cf6dac911f01a522a17edb5b18efd9df50484bba31f71237ad0b14766cfe52c7f2ac592a58bb9e41e2aaaecdf4085ccdb00e114ea5adcadec086d2ff4243aea66abcf8451278d2c7330413ebbd7a9f903d35132ee0b3c4c3b13f0e8d64aee8256e9e3e0fcafee43bcdba03b98aeb12673a274687bf9029298507007059761755a400345b4fcc7199280016ba588f79401d88d5c8b0c998ec67a577583ff3400b15fd5c60591c8f8aeb5141dcbdcc09bf55b64eae78cb9627b89c85c4139a78a1415d995a0b356952d0479a539b44eb1935ccc684e8f718e561754a01fee7a57bed4b6469505ef887e0174ce8757279417c3a53475c25dd760ae553c2f778717c50ac5293a5b486bbf7fb0606e8a1fd96c711713531e45d9346695a419696f937bbf98cf2563061fd905c06e1cdf6c1469d65941e61f7c0171835584c64dbd36c5596640fe26cbbd540a0d0ec1c30b3f2e598f34479f58fe4ab2c2088e229c9daa013060b2121a04647a827792cd27992536f8b99dbe73d8d3b23984dba382a3573081e46f3b3023794992213062fc19fd93e4294fa9a8211412f372b389a1b78f02f533c4fa3a4bf4f1aa093c968ed93d3e954d02cd14e25aa614a9d55fec0e3690e1a8c5fd91b20fbddf0ead774282d6f74d678a5f9384875ccb4cd0d46815045bd627834f23ccbce918f3c6da828a6c78fdd21dd2499e6fbc960b28ae650c1a1f8f9b3c06bb95faae6b7783ff1a3a9c9b9b3cbe2bc990ec94fdceccb557a10daf23a90867adf1f20e399e92cd513d0e7216374d635f8557c095c9364bbe2de10725d745281026c452710cde90bd775def3d40972434569552ac404a81d5e8811dfc276885daa7ebf2c9fd22a7cc3ef00e9c7713a57e9f0ec678d1a69e0f4845af3eed83d6ad811462606d8d6d2461e9b812ee7f462a735a4b66e0527a3646bf1adc549d85e660b51b20a425e14ec2939f4e91f63adb119168910f578c6df30d969be03b0c06739e373b177c93356a2bd28945c9b9365db52e9f9f74ba20042ed19370988f604e73b486c43156b4eb2a9d2ae4de4da34ad9ad1252d6be7e51aca92cc085d25df494afa41de696079dbcdaadf46109c840b80c2e95cc218006e865b75a904d7ddb6cd8d1e1e9a0b8051bd96ec8244674a1c14c64820c2ad3e9175bedf684fbc9b743ce909381c71740e8ea5e260ec9d10d037a7b404f87c8d6cc56ce6f25cd484bbd13ea094812da012048d58ca24762f49e09fe86ac2002c8790cb65470faab4f144c2750d43f5ddd6f2fe310dd228f91e6e5937cd63e91e1e9438b0122ad7a2257dc7f9528c82849b51d89e83c4bfb687a5b0e88a6d87a121e36e6c3bacba16ecc8207621b2f2fcee0515c3a24837e7aedd636ae8f122c085e24886ce8649be90705d41a05049102356237ad2bb1344c83688760d3d31851b6005f39948bb364eee6b3e18b2fbbbb7715a3adf2fe6e1252c6ecd2093edc5c2236b5517fd0ec0eee668e5377906413912b8f8eab72ddca66566866a4d0c1f998a94f414d9e8b02374f4d1d4ccd9b011d6592ea5c62ef6e7668e92fe417cb807ebdc7220328484fc4fedd228a8fc9d0ec034c358aa5307c02342b13d8af73f0b34d53a8732ed2a004216ea70a4c4adc9a01ee696afa13edd3f2b6231d2f730abe80a5b958af1649d5b57a0e7724a45362281bef42d9c7e2b5c2d647206a6ddcc16ac12c96192c8f22a9703064180115e3c1589ba3c995e854990053eb4a957462118974469723594ea115ed451bee9f20b508f476d6a1093f7f9f4c807411c14bfb1a74a7cb91765c27d6997dbe39fa7f46878ff4fabfe4d210962e65ed43d19cc83c9196d9c568619af25c57327fab8411b6c97a41775da238e1da0a8c2b78bf57db97459c6bc655a436188d2f64b24027174bf7bb0c114cd35a850ad4af40fe371c63965b87f469411448b59f49ac45e4284d9a4f95978355c33c84ecefc4b6b33653515219526072ad19a2feb2d25e201b5fd221a1d3c7d89c81bc1ac323cbe0bfde1c736bfddadaaebfff6a78066b06ed08dac8c3f5b82ae1a4a7de2e6c4a8a61e9a5515904b90c3d1f5b1d1e7124f9d01817b04d9021dedfcb525f0cf9e57b472e0e54d1b62219b0466d77f9815dbf782f9f82ff3bfd91e98354fa1143cd08bc90e2da8d9fd8d31a59579f995db8274ffddfb2feca6bbb1de5f7061d31dcc59e9e88624b5086542d9b976bd1850e67faadb8f2fc1a4caae6806a82f3cceaa0f3049991e25288bfadc9298a98b03445817410c6b43c20485b850620006d2ef0d687faf0c207b4dd31d3aaf16ceafe05eda22e25cd42740787c79c737440b41bcc50cd35ebd3868eb36f99fbf6c12534bb88cf912d01bfab24a1c72c216b78a3f68f24d7599585cbda4adb51eae6a49898f0c9496ba2b524f6004ba576309f068979a32d696c3076460b00d75d49b94ee01c826a448a5a579397e8a5c72f6dee2b854fd1f6edf166eeb54c479c4a177d21fb39d5426811afea335d50324bef7918514fa9e4e149a0b6cd26ba5b33910cf1cd4fb4286a306a26a747bc3a3f7a88bf6615fc78faa95322de20c4b8ef944352bf8d3abd24373cb2de16b0e50aa7ae36e517a0e26d081597abf740accf7472b6352b4b86e01216926a03308be638e1ab21046794efc25c57ccee1ae7575e52a6d48d5f3a7299bf99a341349948771e98b17c392d7da0e2b8b6bb5439119b6f008865dfb80466b7f7fc0a7b5c4352dc0dea91dbd764e170af073710660c2d524a32521fefa2df1b0b97976dc35a710f1f816959278c4cd25bbc62d7ec94cd01f3146b7d50daa00a5f9852fb1e076fc481ed325cf222a2b6b430e5488e55d44fee8677208aee764d804da24e3e734652c4608a001aabed8a50c0d3b9ec07504d2df01fdec7489d6e56d2d545885a6bbfaec6d1104c1741791f06f603fb4c10efd42f80b282f7a6e5e9b691c244cc1fc745be970327e230246ef7f304ed3ab7d93691da61fe39d0b3aae3bacdf2803dc6e6bc7eadcbeff6c3607a379d9344c1519ffa8141f3df8d882feaf68933ecb69b733ee2a3905586f659ba7358d85273784a2e78c1eccaa2899a7f3f214c03840e5aa6904164d32083f8f32a2260bbe47dfe7d246f9340fe2d6315efd278b507bf170cecc51298f545559bc1ebda0ad1ff7886d12e9ae51338398cd6ffaab9fbe395c949c7852d46a78242e4bfb0a30f4414dcd412ccc3bc1b3fe3a8dbb2a7f0205a39f4f9184706e0080f9abe219ed707fe980695e923929ef8f4029a8c38744e6d18ca76236b1c32c59a35739bf3955fe31fab89ddaec64a79b47382ae4709b8b9846e52b5e10e8a547925af220a14ad0e0e6cf66be9ee40eb60b11c67bbc629bb02b7fa4c86bc3d9775ea0a3fa714aa1726cc295b2677212aa7804bbdae91892fc6ae08b2df89380130fdfe3fadac306a2225c07f9d9de24f1b35a15545ac3f55e5b9b884baeaadef20a36c1c1ba7437249c8e8f83e6b39b19917477f3fa0889a5afe5211568720a8d93390e2585e6efb445ebf11d23892405f49cbefe475b4183a9d8772362a146bc02299e6c3edbae1256a5c6a6d21e96035dabbd262fa3d2031299823f2d51bb32fa5ed8dea6af5043ca8f078b5fb5b0551826126eb935eccf2bd09811e1e6410271ff704303270d972301567c03f2431bb0cd7d07b657ea87b0e738c288de2f46de76dd50f0a47a2863c505d03ff47300aee951c45b3ca6e119ddfbec3cc9392d85662681460559ce9a496f15264cd549c882de5edef425aaa1054f2bf24fc8303c9d0a246aa203030133ca50b3d7f26434743faa68543018798ce22683ffa5907c093942fd4dd29f4f27ea1017e41013b497e547f2f3ff9ebcc569f0e1167a193b6c6d9043de9063201ff65275dc0e17abbf7adca55cd25221b9eee9a0bb0ed522c7a586c7cfa9e8701cd463d78f71ecc344cd6537712094ff365eb115181506dc7d8a0398f78195d5e0784d915e008290625005a01f7e3a70bfa2e551e31bc13f50e64c19b50c2991465a772ed19adc844e4c1074ff8114d827a3466cc34d46dbddf42614b9c6768b4dcd369dd747473a50b8723a52e2b431ac9db0a96834644f1bfa9ce0441e15d06287a2e21507aec356438f6bded56d7ef31a5e6d6be09b512d1ce7fcfb6440092daa70265b2523229e1770869c956f90a8ec6745855252dee5c52370aaa73e3143e96e755742237d7dd06805907aba583b79cf0f04df08672e7bc444621e1df9dc0c609f6cf5eea99669e0b204feadda4c9bd8ff31376b743074288e65b9281585842b45663816b8bd36d815eec4c4b4b7d54b39fe00b78938de2c6df0b666f97f95f15f0bcdf93a5e07bc2c1550b7e13dcc2a32850c153c744926fb2e20f7febd745d6834373e0ae7d86617b1079e4e9958c6cb8a3798b8deef4b7f2e959f8564bc5bf35f13d388daae6e76bfe404cd6c9b38ada34c2db36523f4f6341f33a9496231ede1a5d9b992e352142900b2da107dfc58dde1b669203953176e58b79d0b2a45b19ff035fdc1a4ce8df0e2a71183ead26af9de8450855fdf46f21711e1709d7ef5271155aa8d5b75755b9519759fed51d908de1a0bf19048b34cce48490354405728bfb28b246c772c1da15a80454fceee87172fbb6661c6d007a6109b9afd1179b24433963253b07f145a483b5dd30398600668c8252fd7ce0c5df17d5fb4da37ec920747123cd9c76d90c92018ff4eba3848804b7827e7fe6f897c411914ceb3c79cbafd0cb0710f4273b527bead340ef4cb563cc178e52505df463281e76c7450ee4010aa672d140c270fb298ecc86536349c6fb61f314fbea05aa18821949d4af2e47797e9a7d4ef49284cf14120b098d34901b5137b82d469a23f3a69e66c930eab93f48516d1575a0b8986cc46e619f3045f489bbf7f3ef346b99952913449406a143529abe32e8361d04ea8a7e6baaef6674a209a5864579f48028d433d3bc263ee27b77c45567461be8f79a127f18c41caa84a0dd06a9e4ee156a2df6ccc1539edcd67bbbcd0090f78a430f360043ff3217445092c3cf32452daf1189183d1282d62001c9a2735f71e9f8fc272736b7ec8c398e03e6157370efa3831cc7411115de9543b1fa4d4007b851932cb31939c4feea6796698367808667432c2ede5257a313d60af4b7eb290e97b01fd68b32b21d5fddd869cce24f04429c1d70fcecbb76dd6e232ed34d44e724ee89081e35f6ec937b7524e013dc027fe4343e661e8e46de3dcccb23d105bec0e949ee90f860c65b6e3fbcd80ce01ff902950107b9029039f087d6a6a10636fb5e62205bbed17e2cda835912c155aa9ea3493022657eaf124d43829819c733d2a95cdacf3cc22ff3f43753a1ad30ae9ed71a93b1e642c160e6b505292696619764a6ad4390a4fda5165aebb3d35e3248670da349264acca407258eb9d0fc910babc1f8fcbd18318252de9c4d0306d7d5702c125daed2e7246fd62db63a5156920ab0a8dd2f5ced01250c82704c26d9f4bb10d4e54487749350543c0b92b275b87dab298b6df75e163162359da29e99fa23de1ebb658c60dc02951e22f0648faf734c657d36dfbbe7580ca0dac6aca5df590d6fa67014571a7833b87e37ba4f8f3835f9dcb931af5f2f68566abd5d8f1264d97fe9d755b78f90efdeb3ecea45c585e404d1d2ce60c8eafdd9441ec9f12783c00c9c957e53357064e350c437f68410e4acedca0de6ff73f9ef1713a87e6ed61876676ed8b9994bd26e96af5ebb5c20c7a5f96db40254f1d84c942ac976a7240d7934388a1ced3c4cf347208b10174af255f31d1740d0da30d1b34f82ce946717ebf06aec13b456631bcf582abb2ceb3a46a1c9f61cbef522ff34811fcbe28ee61792c3251f58345a9c6ae51d3d0e09346761f6344d1b56a49aa2b961d3cf68e892389ece1489f33ca8e1476a0760479c151cc0f4c9a7188fe94c2b38a7647082a11536e8465e76cfe662db4c0c0cfefd96ab6cdf1f484627e9d623a51e6ba5b8663236ce27b75d2a4c90202d8c29a5569fa617d944e377e7cc4b270f8bca93885a0d14a9b49efd9ce36150dfd74dfe29c15a9806692f8dc914bdc933e9b5f107a947841de763303405123e6bf07e222abd4b111390dfa3692e5b20fc32f6d6a4d3cc5cfc84733c40a61d0842678ae6a14983edb96fd06f3450a56ff5487c8787bc5533a835d2711b90a94837fa53ad8a10e279cb80f91eb50207b91eb099aefc960f87dd6380b34dad7a5bf7d5f89357d46bc6db20a7ae0809809c6e18a058d5b17d6f5063096fbdc8f87f05324658549c60fef7eee7c25c6a5ed7e8c6a79c9f9ca1615cd51663fec56df5402703f4bb64547a0d258ac03789731d32a5cb8e85c0927883d8dbaf6d219760781b4d7509662baccd0eacdaf3155d7609cc9e918b31cb7556a8ce2d2d3d5cf7ee1aee040297dd1293c6098151e77e69b8e4eb135b1840dda70ce1e0a096351283f836f216662ac8e5fadb61883cec15c358139df53beb4bdf9c1aeba72d7cc9c8d82e9cb70d2d30303ef32f06a1c3abe6f75eee05ebd883645c8fae6502320c325c62292e243e5d59a54a6836a105dff98d1c3593e9db8c75c01038a0834d0e3695186ccfc304f9594bcd9169b00f72078e76af381b1fdfb0a4a44c57df3c3889fc48829100416484ae8b77ee2a544b9f043d99e817c5767d7918750fed44d9e815a1524a6d2e9007a11470d9fe617051891b5c69b76ec4264c23efde0e5452acdacd5b7f590c813c0d25ea34847ced4de5995ed87e403f941851798891a2d55301d6f27d3a1540a0b6286a73e414c8c0648a60a5731b299a67b8173384752495b99fd988af106b6bfe7a5138f7021871ada12dc37ad0f710ab4b6d317a5dca9d1c4f8050becc2130e90c801aa3b6df67b5a3e62707428db25afb115a0c6d7ad10741689c5d3804249f3eac63be3185411baea3f4bf3d04995407acd194d7204b6c0e7c8ae3bca176e7c923d40cdbff5f62abdc2bf627e185d8f820fa93abb7e0ff204f5f373f62753bc694174b15ae499cfe769613e18f4bd20b740c467f66acdeb1a7e49c1460f97f64880d025b0047341d4571d457423af7f812a481984af4d639b4f5bddee8b685744e16108b214b0ba9239f7a6859ee2cd15d5ca407a798b676c1816479b39123af4f9ad1c6a6a64fde5fb35ac4ff3461bd3087606d32435367f1abbe3925e362a09b61b4ba79ae73699bf367d9e302e7186e7f2dd894d6277d642126f8a45b8cf22d93d69c43c2325a39da72fad7a28f23666f0197da73e34591da11f87bdca167205eef16403caf6cde8f38aa6d3ee28cf6179c4fbd77c671644e93a7f0c34c69d81dcac5db42a081de5d7df4184c1ddfc365b9f0476f590a90738c22f58f93dd1eb3e2d45abe33c782ea5283324880c998159821f765fb57cdbb791104cb576cce9fbbb997c959f38c293269d1e3d3bb53f71a31b648ce0ac5750c69acee6c390b0934548536c48d20a1735bdb2cf46f3adba5da6ba9790144d3f8c0b9fb5b42e13317643c135def63c962b8c5c21e0bd4e1ed1ed72f24d551132b85b24c2b3e3b4728b19792a39aa4d2c3d8cf951e2842e8e0dba7a2d9262e7fc90ce1c242facdc58191e42039db0e3ad91ebfb1d771265d9df0676ad3d6183693b37b8daf28e64364010329450a1117ca79ff9224df881d739d814f7321c830a5a1687eb4e590e92b0ea63f8fca6edfafe9051d2d29b4dc0ffd9b1f44883f356d3e31530851c993c59aef125b311feef3e29d9cd50c8f4a01bda97c2de48e026cd991d96f7d99058b1e56559289b5ca4f9a8d2ef39bf0b9311dcba7a66c83047bca955e914309d5256e7ee3af28e1fd0ccb64b338c0907e89c0acc516e3839c373a235f17331ae6989967ab821b239298cc8a7bf2f623e325f8289aa1a898e5ac62b02861617e7cdb3748ea34b14d9585533ac7c4ce65792618c01800e8b403c4101713e17aae8d6c3d30343d13fb3a51187abf158ca9a86af469cdeae4ab55fbe9fa773b32aeff735077e00fa63dd668b4b3881661a1c467e0d9b703c8b21167d0769b7bd7f9315fed929852849729d027a8e6acfd56de406ad26cf727b175e26249bb282f9967f7fa374a537c420cfa8aa8581bebae8a81e46ee775a4b93943476d054e0354a1afbee2e08ddf35c27ef7f93227c4582de30d4e8831b9a195ea4f210abadc29e0c24a61a27466c082f811624e1bb5d150e6fb09481fe5520eddebc303633fa397d176d5ffec64cf1659c0b6de51b243d957cd9ee508ef06e81e0b3a49cb9f0f0c8d5255c5b875602f2ece383fa03ba9b3499eba997b9bc241b8c2114b8721eb372b8093fc6515f417be05b73281334a3f0fdede2d174a2a65b898d766c8124a02cf4563daf6eab93333861069cfd6a6e7070340a1ccb1f1464f03ca35c962797c790e8a0c7705f860a6c969ea6c10703f96f1fb8df1ff770f7c5df245666fa56938e7ba972715337d9dfe2ee2df1026980f65570cf49c6217522849c917247050da080d7b2a25b966bbe6909ffc0c37354ef317b7d3be1fdf0ac71a7e17ecc6fecc89bd1eae17e1b0fabbcddd043700e34e801dcd4b4632d9015e174fd00cc59b370c7478de9325e32c2636d76b8cfb341efb6ca01cbe36610b489e8da1564e8ece8bcf72c453155cf90b2e8d000196774efab051630a53db54f7ef83faddc8f179a2a4a11dd994ce3fc2faecebe7965cae3d03fb0231f35f4b605ca2bfe94674054c2bb4e23b696f8ab2601e692e0ae38d8226c59549e8e11c1b1fcf1f7b3e09bae064ef68702bcb024f095b74dd62c41675adc5716e001d534c17f54d5f729f57213cfccbb558b02075bda8598b9438dd036a849fcd9cfa044316370ceda3f144bbe71201280ce7c01f79467704e684f5d1a05d3cfc9e046f45eeeff890fd4f674197e89d4f27b0097dd726fd840527fca0c4a523cb726459a9c1b33716bc57b98eb74bde414edb2c0e34a69ea8431d6c72f3d43a0598507b7c2225133aed3c24f7394ddf4a7d357fdd70ed30ebefd2d5acfbee47e503b4a4a5d20b61c308ec03e2b68e2c1706f82c4633ff286dd9322c72450defe7bcb95b7b0a089aee84a19b4a967560a17953df5e21323a133307f21e9526d9c22275553a0dfe73232612641f91541a87adf9c8c03f891a95e65b5c74c2cf77eaa87935872239737427219d54135d0a6769fecc3a3405dce930c9a72361bf7184109a390d8054cd6e19a6ca5ba4efe625fe6dc08c0066d3682a4160445b83884b643a4bbb4d9bc31c0b1f592daa9437a6655626ae2841319e768aea9be59bf41f0ba1a0cbf6f22317d5cd320f6c563fd54b5185d83c0f24ccd7cdaa98f5ca0991192eeba6586546b8fc99909b68e553ade3f9ff8176d61a58c9c6cde0366a77a27fdbbfe9507b99c1a8f2853b086bc5126039a1f8e6dbae2d921dbbe35271000c7c780a539508e8d4138716a68f4772c5dab73b0e4ecbe43a02955db2b4898ddc045c35a8898a468e160ee1e5a027936d2912c7f9c7cc33007cfced7590a556b84b7b2e886d2af13390fe98ad95ebb58a06a73fb362cb9fc74e719bd9b3978d9b9fe283eb0e6c350ee32ef845dc1df7b14e3950624060b34ea91a510b7f4059833748a45424b815651b8007a5962e9ba6f80521c74f48b056d1d225c8f4e2b4396d6e1c003eecf518ceee1b5cee2ebd6fae1eb97110291de7121d6d4ded74dbe983131dd2c19163b78497ab40204b7fada344d16fa3f988a150367e36e59166daf16f5133521cf2a8e6e9176ba539dd736b93e4dfef4e2bb05a66ea2a76a7d9714f9e9805d242924231d3944e39d1fe0f47e3c97388d6ed61bfcb7a01adb10dd68e08499909cb8fc3439aca575635a1870dc9745dac22a4c889af0326431b261e48129d41a969def3ba88640bff6994f4ef630929836f5f466196cb179b0c53e3507a3ef53f9f680e03a7f8d02958717c25adedafb79c0402f30f2fb51d06d5991d527d49f30cc403b5b562dfa07b09d5a82ab7ce297ca5dd7d1f20e4008dabb7250a875aad6cf220eca470d433cd9041f0bdaab92959757fd1f54e4a57234b3b2a67c93253349e03c2e1c5bf4218de198959f0514c74796c14f10642e6acdf7d0cb1e639c834139ac51f64a57494ff721cc743105080d336b79f5ddc1809e11a01f37f733e7a9385296b835ac8d9b93a1d29439d9dadaf47947ad5f4b791cb1e2a0db64f37858b185897d5795d58d6e767e8767138ab0e48940aece613442cff5e88c3348be828c7acf5442373b540e6993e3e2b1bb4e6195c377eb8d5adaf2fc488f835073a942c06ea66140b9ef2b5d986de82da92678c90b0f01710d5c0afcc7081e867443f21f657f639dec209d25f5c88895276b8bad8db9a9cec6abb69a94acc24dd4ff2fdc8b2163e05b694589373f76557dca1f440343db0996951db0b62a4325389ce108b2eca40f381845e97886f98fc47f2061e19a72a6873b75e89a746ee849fe88a7d87a2096f345ff46b75ceb9d725fe742b22b9a4ce8de1ce94b3e9bd4832d008f52a538aeffd5d8cb5a083d74fa73a5da89a88606242162ccb4ae7751b2a9db6d9851b7edd716bf8cdc4f35851b4dba88f2cb72f78ba9b774bce747d2e9c0143f356627fcf797e1cacebd606bd67cad17ab82462b8227bb940c93c9be6733dbad8759529f2f3c778d51d52892e8b57cfef398223c0469805dcc70173aded3f0d80d06b46708fcb3d1e9a5016c4fdcc4cb308d484a4298ae4ea2787bf56cf3317d2a52373ba6d3bba51f94e9d3c7d91ac20ee9d2e2f0762adaab2a9597e95c1bea497b399c1652c21e29535c86de233c2b76e75c3228294b4fbbdd27d4443c3d859a49f3688bf3ed2dadaafe03f620105f95563428906c60d1e85a2bfe35c906cf88de37ba663ad6b24a38d79daf0893f98ce938681898a01f9a5848cdc28a8db742b0f0ae1f7e60d8cc69201cfd11a9575eebd32e4283b025bf6f4fe42598eb87ade9168c03b00dc0511d42660f1fc372760bc45296af0fabe25fc5c4a6dc284bdb04980acec835b9752c3fbbf0e4a04e9a8cabf7f92c750eddc851a36e51eb0197af0d95c29b9701b2464f371421e02ad70c09de3e7fd0a51cf963ad72ba24eed1f9cfefb0128fdc683592c4147109c2ca34596de8eb201701113f66793d8e346c56ed0b8b8f5f970a51f4b9e55de4e69477a6adfd26081a36403c6005e0faeb39cfbbd3d0292fc12af363ca3673e4ad582c7343c44f481cf71032fc3df31f8f106cf0c32c1feda25580e106036759236f44145e7bb80df6921d42f5d61a6c5072f1fa9a590ce2b713fbe281dd4814950bc6501c86c81077e7ef6ed078e87ae5b65a7dca8b8a8446c7773c691b09f6eefdea74a3f27e278b6b3ddfff3676babcd7e14426db904baafc5b8e2f4142c29f002f7b99579db3376c76768e2744f32e9d124923ff4425730f1c33f5257d77c6d169426ecd193704e6b16a23789dc7a5339a0f06b8d1849e8e7c2e20b71827a7696dd6e127965090277b4ed0d4f531cbc6db5a4fe23a57d4d1b7889646aa17c57d09e6c82d952cc77bac2f95609ff2e0827f01889509fc3aa4f3f92356b88906c09ef7ed4ba14717ff5909a17e39c5a3f9a76e2e59a76f0b455c5264b8628819ea696e7f6a6c10653c33dc6174e743af69953db14c0c12f6971f53c360983f08b37fa172576ee4447925caffb73d251c608dd1808c1b0bf49be9af4c6a5e28e0d61aaa0de2716f8249eeab0df7fbe613963e0ad47e8278068261a5008a30e35e97fd8c163bb9069009b75270c6f1ea0f7f7f717c7050e2b4b527883a6bdc4d82dbaf4238c02b11c8224c2cfd1ff1c254c83aa7a609b17073dc44ce0eef2e3ac4b34d1775fd987587f6f86e976f4c8340a1d169b8ed0bd36dce82170a617af37480b411d1928fc5618d300846707208ae043b219d0c98594129896d7af687d6b2e9c321fd1485cfb3c88d08cc94c3fdb8d4dc8aa2c8fc53927c1556b811e420c7a6cf85211375861750ec0fc1bdd63d12680ee8ee7f2bd840ddfb94781ded47cb65576fef85b6026d646e7a8a01ccf8969ba185114a15dc4e0d382768c9d33c54aec2c3e60809285102a6984b425f06bf5792cbcd01707d0096a0806ba71451a4280576b8206b3f59994cca899e83e6033334e6807fe44795b0b701b132b4f8f8c217e6e7d05fbf1c3ff1c376ef209ef750052441726d469051e3f76278ae33ac339dc4f834905aecf2c343eb41c7b65316db84f38c313da311ecb8f1ce92d0f9a4963930db32b06c5f2ed17a3e154a651ccaa2a18ca8e1c37de74f638d7b32831f9a7b99b0ebf1ffadf9a1a48c956fcfad4e6d62759cb9ecc77db01b32966e9cef2732462fd808458d4656c5d60aa132c13481e8c0738a7ef0df043258d536c7b65e3fbbdb63d04845b26d88fefaafcfbcc5e995692dd5898cebfa9b1e8df3fa1541c9a3a59925ef9de2599b4b5e22168c667914d54a83f9abb9c8e3d3f29c53d2669eda131ffdfd0f5d33aa0ea411e9b10bcac907f08e556bfa192e53f18704dd25cdbf57d0cfd56c4c8f53fb1c6e5b910942f63c7b05f759a36959e49142c3d0e8a15508d36c270e7e7a90a852caab4c38f19f382b7ecaf5ea0eb286913d88e2190161df00d8548f40c14a0a0703a9fe5b4257b3b2e1a9c117972c4e9eadb3e77067bcdc23770eafa5dbf5b3cf3cda2bfca33aaee8e6edc1890a2f47fbd4f2339ce6978e71927be3c14cb8cad79ae8b93cdd31afce5a0f33865a5ad2b3142aa8d49056a0993360420f79890c18853da107698716c03a4f97a700ae7a175ba7e53d22313a8e1b293af21cd1f49f3b64a01c1c230b3038bbb4fe9c3928debc20c7d06b34d02599eb0152170be1b0cf78a3e0f2561c673c52ab8a692c3658a815523ebd4852305f25870a56ae78f3097831ffa48b24ec4cb7dea64730855cc4d8da902a82b783ed375bc0d8b5f12609e51861cdd9676bd437a856e0ceb8f177ed7899788f8d81d260a8bd99c7978edc2522149f8704b47602b06c2c71709093e3130af1dd5ac31458c8dc2b555b7ead7884e81d020c0184b97ed0bde2ab883f41f1a9522abb3590001c9a56f7fc1438c004afc4cf757e96037987b1d8204b12c228859e0566d25b78bb8b9e4cddc4bd134e6908d19e7faeb520d569af7bfd47005e6d28804ef45d2e2f956242e46bd8d7d4e63b0ddbb338e97102cf6a31a00f43fb423f32511e03208d5898bbcb609228cff30d2a741e8c1fb7b1238e1a70d5cd6a65faf4f8dc09e67ec72fbcd4a44011247806dfcb19d9aa28e0050feadeef81a77ba2886e1bad17dda45f9b3128e996477047242831aa6b062e19714410d34bbf56870e8e6fcb639412aa7d56c16107226445aea998a1d6b17b78daa049daabe5af5ec3def7c5630c1d81ad5f5ccf88f952a0cbe8ff7f0e830ac6452ab895cd5b0bbbea8b9a3771cb4132a4ea2d46aa9d5a56aa2f16967353a8667f434b1b4982265293345021603b08043254cc5818b4ef47cf966b58cd887309dcfbd44bae64a1bd11800f5c7888fa25c6848cef486afef8801b781e0e5cf35c0d9bc75df21b2b01e36d266d9bd12ee6e78ce1701d9060a7e22854e3346cccf2cede0011cf811656af4ea236b404d582b9502e073430359740c1b7a754eeab62856d6b05e59a89d4175ee897033486f5a9f54ac8224fc4879f6415e6d60f8ebb27c515b66b32ff4d6eefe4ce1998df2d311057a20827b93583fb0679754b8dbcf5a02f1d8476f83e554a56108e790ff42d2415b5798e5bff49438d817c75cc1ff14e493937dd202a6eb5288eb4502942468ce263c38387c049a882d7bd650bdbdb1e37f6b5f9f49e45c98433006d8d3012d3b7d3eaee9e2dfe0801442422f3d52910c57d0aa659e7d74b86d1a8ce5e2ff058c2cbbc2acb486889059b47dd56dbc56d4d82d7f36f73e04967ed2e2f33d9930916ca61ff84186a75cd681faea0025d0e6dc5e74933bba4a456b6ebed44be1493f0cefccf5280d6e9409a50644db6260cb56ee34dac32d82cea27c1080f2cf7a8b024a9163b31ad0ec3cf5adfce3b1a20441466857b5933af892590f36d399170a0915f449540187c144dd6b2533f7bcc8dd1453dc897264c7e6b265f91dc8755936f2a71aa73fe3c507a151aa73d9f4c899454ee2e48cd0efb595a4b5cf4b06dfe53d93ed258658e923d028a848f78b6efe19f4b82495e75af0e83c245e03dcf5422839d7f17284aa4b8372901ec0c76270d716884229cb438fd68cf8d310e15233ef05caf6824d813d2c4e8ea0b271a91510300205852b7999eb31e9d9539e948b0adb9a1ec2765c1a200d3331b1d16d86acde99e0f9ff258140c4a21ccb797bf3852f9a262a092dac71e7fb10a6dafa62a137fa0b4e6046b95e74f290e472b4ed128c469af02e5bfd9f76a849ba8e626f1264f49267ac98bca78b33c874b663dfad99c03e86b9b1eb42bbcdd082dd096c192095065b1ad352dd38bbd3ee2f15f57543216cd83243667ce1d6757b1857f87e9a53f432d8d73b8560e422002d2f248ed9a6da5bd0efefb18931391fe11f3887949ab74174ae4f63d4655088510de14a11fe75b05a69604e71e2ae2867721ce0d94bd13c2a4dea1a207698fa09c5f93e54d597f45a39b993c30fa7c5bfd8ee04e2e1279966cf1ade392235c3feeef7494eb3cbe924b86a208b76b8d5df7b5a0a0126aeb80c2668a6e69855a65c9a54d237320a83452db48f5b56e7e99d52cc489621293db97ebadd18927eef08fab049eba40a6afbde873c128690c1a0bf27a1f0fc1749c4845edcbfad448a5f10538d94b99d0e4a21fa8f168ce8b59312027a8c605ed260c86b941ccb0ca5760c8ea20c4e73973cb6763f8cd6adb0d21e915f2d5b46b9be790d14bbd1b17c26a69bfc89d05e17524a63e26b66d346d80dd0028b6a84fb2092e04491a2fb92433d7daeeedaf0a65c579aba4902b0b818abe65fc3862ff53c2ee59cf78cdf1362b6cf2404d44986357383a6785a99a0c1303b33e7012a384cdd4f6b82ad6b126376e23b12428ca970610c0f8c4eed85779a497cf7180aa2d718e43fe29ee097824c493c74f7ac2aaf1ae9a8dcc5131ff440b0eef4c082953818d07f142425c21d315d04846e9febdff943d2852e98f64527225a005f93d114d9a6a434b9f5ea39b0e9d7363bc958b7b660eded3c3165844f32de7a3cdea25a7bef81651d11f71362c87a729e5f71fc964cd4ea91a7ab8cb16e71a1b7224f9760679c033471a2ef5627db9ba9c8659122e5570e9ca2b68c7912662714b1a58de8684634d871059c2d4efa3dbb9a5cb17fd3a229e1ea4c06478dde8eccaddce1a5db638a9e86462423b54551d79b8bb83b5f23e8dee259c31ca2e9ef9e37d67c30b5eeca6cced2b20ee70cdba8d94da75253a374377880e4cc541a51c3885e8226dc0e9dc962d7de3808d6e22e7fbc41b33c51992416c26ca10a7e582bfcbcc39e85c09a2bd5ce1120c86c4c83fc6f4409ce5e69c9d6296af30e5544b667187b74dc871e4d6f3eb15a6a520bd6ecb4d89de9cc8e1b3c6f00a71e56d72532b7039ad678f8d3cb953fdfa55b739438bcf458455a5fdd3c8ff222ef390f25544e0aa4c623e64dadc8ac7269c245c3813d631aa1d71a8dd71e28ac8d6202f917eaa6636e9b15f154c183bd0c30a5389f2e044ea59ef2fe8f044a817c787e4e164b80e0fb85147232d07c9fc709e7f1201b6b5b2d4a7991c0783582f7327f774aac047ade8e762d9711b32317865b2e12900d04015e456d04cd69608bd8ab87f58509d30f5cb525ef6b3fd95a15b81954a6158c056fedccccc9f2ccf4d7da0a36fffb52ce8088924f6cada4221558ffbfe989ce6f15a86101de21b957f724f4c43d987d1014c4a09d1794020c25334390402f87c85c9228c57ed5b23e60d8e05922d841435aab4adf90af8cc50a85e5457b860bd94a89b2d5dac9d26481970d418e93485504af79a7f722079fe7adb7f9909acfd2c2486be3467b9c20e22765150c7df88ff349c0a4f01fc25cbcb154ed9db4344bbbb263e82c8f47f766699443c14fd119ae33f01ecfe376a8465f14429be8e0e50de3c0d6ab0bc41b2f21409d0d692a5edf5c389255df898b8ecad00c0a05e430db5700b7c53a48465338e1f2b1d354c368a6972393e7426ec0ce71d9f13a34c1a143abde9d56ac03aca9067981e95c5cbf1f0d2e8c44a391d284c473b76b5423fcbfb40890ee5ce59c9e9a69941638d032ee25f68ee14243b30c555ebb23d30a8ae183de6793cd940bb4aabd2a2605e3686186f034d151989328321c4848a3dcb59603f3b4fd831294fd5d57b41a4a00ac4af6ba854ef740a90fb98bf17b0acb5f1e16fa9a7cec16773987db4d902a7ecdd7bf830aaeca7f88cdbaad3584217bbcb190107863ae83a4c8f91c6f26232e3dd5bfca0e27c2b8212deceab7a76f93c8e12622e5b9ddc145503b9a07c84afa6366be899eb84ed3ed700e33e10199e6988fb03c807860ead1fafd836dbd611615dbc0c6902a8b9da2e0a8b1946ea560e701ab8cd758c71fb86a8f0ef7e3142f5c30f54e7708602af30fc9351ece9abeb424b5d7d93bd8bbc644fb1fe77f06a231823fc1d0ad7d009ce6487038677eadabc8027a12d3daea30ff5ccee13335f436d3684e3cddfd7ec1f101c99faad0bd6907119807320e565ed631f55a4a2b8f665ef22b7f3b05b8aba53990aff6af90c708af3850d2e1b6160ba7ab26274524b2c34146f4464f7f323c9849f2692085e5012f049d9aa55fd6455604c50821a3dbf4c8f86e3eba9edf6f57ccc190fcdbddb2b3de762919f6482b99e3f2e5f07e56b42ad7c7b67821c056a12b140789afb13480ac26b736e8228c2e5204b3a026f6d1d70e53e8beaf84127ff8e4391aae8175051af814e1fae2809f74d6ef63f5218e9714e9ccbdf55df79c67901387b124fe5f9ebaf87867f8ae0770f628e9b782ac44af07e8d022ec7c493a3fe68af86548dd0915205f91b821a3f3b517908a30125d15651a8f0102bb385cdc953d7749209e8205e895abe8fe6b783feff47773e40c54e08ad4286ec7d3069f500eb2ff89b8ff119b960972f0fa3d8bdce99de63d67e83bdaedbd9265324d42a19069b25295454d68216ad6378ef6d74c24c84e3852c9eed5b4984b3714aa8530b90a569b7a25db707400e8edb2d69eb02af2d77abce0ebb81b34452f83a79e39db4d437305244f2a00d37aa426b026f915579ded734df4ab05e866a5f991924d99e7973bfdf8deeb95f4d7db1b546cbcb4e8f902940108b9028f39b765b40ea267ef9116fcb0bd15a726e88c57afb20a04374b345852a61b2d7f91d34dd7e538eb960b07d8a7b6380c11134a725edfe2831ed32c082cdf6681bfcfce5f5bb4312497dda084a14bc701e0e2bb4dd59362ded197b79ca3bd05dc82312994c32d5c780c3dd540c459393e486ed2a0dfa64e527efb409306bf4ba07df44b9d4eb9bf4c68a11ce0eba44d5bb7b84564a4808fe577b2f7ba623e5b26259ae1ec153df434dd2213a4696199f49fddda29396e2b995d4a2ec95c7688cea704cb4461bd6d7d768d0e7d575caf798880c3245fce2f2ae2644e872796ccabead5e2844c5eec1cb1ae25130d3a1e4dbf53b7d5b9d967692e03228fdf5c6a433d5ddc30969795c8c1532dd8c5efb7e986a255d4fdbda5ec8c4d34a0149cf4418cc3ac92b8b8d2cd26afd1ff4e5c388c54f8570b4a0093aeaf4c451259a8552c7aae62a0ca2150f9645487fa65e920ec7e9222e35a249528ff97a8ce591006abb1ae46aff6a66212426a7a7c7fa2632d8a615e1ebd97389eeaf3b1e49139449d561546f6562dc6594ac29bb802932a77696d07475506f6e2d4c495e0d012cea5c988467b9478e335f47658a24bb3614e23cb97888a5bc4ca79f77991f38e4ed47a0776a71f681b89f65a03bd2271a58935d5ccaced5e84d23e92eb4ee5424da7b999037f8cd0457edfb6cbbfc01e7b22f5c759b2d3a3faa7d430066e3889af9c8a1320a1431aa8ec2ae99ca7a3471f1e27a88b02ec30a6e9d89396984aee9b90bcab24fa113922368f39be1aa459c0ce146739e040e33448730934c450f865477fc9afe75e0d1ee9d683f7906b3fad5d629a0487df8363b7a4b0a6c60cd913cfa21b8f178fb76d7391931f4336e6a7a72e49217154a14a9c4beab3df92927a3a3d884a2849714f35caf6921c04c93b40f91eb50208b91eb092976d4f1cef86772e6862a2b0c6db43294da4ada36168d57a48c163ace4119c7968b794c9f037202c9b23e1f7743af3b93f42ff8ecbb8d1c476517237c3501c17bea11bd8d43970397d6cc931b9bfe502a08c63861b2aec98635a6c3964dcc20995431b5be09b4430531f94e152b7d29a87c50d833a6564d2eeeba3a9177b258a4d974e2bc54f108401b1bd015c9561191e2b5f44aca28bac2aba83bd96adafb6738beef9ef5a7bc1c65a3bc4f1572a5f88365db867e40cc66eef5c4fba895b6ff2abdd18585c22fc6bbd7751b1c15f93e1f3f008e8ba398d842dc908950d0aa730eb4b7f36f820f5e308e6f0967605d1ddaceb347b01e2869244ffb6caea27b0ee445aaa3b170a6c6a29f0acaf90472085431bf4a1394ac4206752918efe986657b88086cb73bd25b3f9c3ac8bbe0bcd80b9185d9bfde25cabfc3dee624cb15b5e1e9efa3237b2d698b191065a5c64c6e2749caafab2cbd83bf58c3d3b007870035da3b27ee3de5eb1320f14bfc71bd12c14cbf24608674beebfab1b78dd43131eaff322a6aa4b7ff789abf2a443a0ec8185de967de6602e747d56a25179a7a46c9d7221811c2ee84455120213363e42f48801c87199af89bc23842b9e0dbdfc400c11b8271ba2e961cfd1927e7130d57255aa09fbc571b71eab1d3eef0a7a20e99937800f95e90c4732bc010a23e6bfbc83be8d6c6d24f3e242daa791ed8edae75aff49eebe56cc466855c0a37eb559c960d22daf9dff46b9588779d6c5f15e77ed93a61a0469bbd9f621e665e81d7740c40c1ce1e3838388a2b490a26c2d0ca44ee66f299fd1f3c9ca845c8d4034a77ad71392693d1db7e52cd40865bb087c5fdbae1111230b7109ea512046a8efb0508944b8bcbc61ac900b6639e653fe0953e1846c9a1a16c6fbee150ebb29f4a7b40a2fbaa148389d2f19868342e08f8e7b6db4552ffa01e5b59cb0545de89f886e7ab81891604dd3dff6d000a67cfc3058bf93cb7cb911773cf9982fc5d70e8b69afcfe44c8a211261783ffec1eb1c9c3ff69933b47637654ce80d19573e0f50f313e93f6279200a6a43e92f09ed07c520c38eb65b59e5a3f33e72df834817ae3e537a66c9eb3b3633b350e84ce48903868462327dd7aecca9eb2bba5d31385ca886bfd7de7f41df7a8ebc4cf0a3e5d4fec0e88f8b60f9f5b865e6086b9f1771573e803692d62a879659b6ee901eba7df155836d81aed46edf41f773cf97065fe39811410b500e11b95029a587de68f41ccb6eaab073591ae2dd51bc452ce1046b620db77d514d49f5ba3cec965de3f192e1dd075c932db69db18d3e182ff9b861a87d5d9fcb4a9a2ccc2f69afa4b4dda074325dd9521fd5c649423cef7e90b941e13b246dbda6dfee2ba7d74c2873ff8ff7ba4f6fb7118653818da23807c3cb58496bb7eba41b9fb29c88efbc11e401b9864e2fb26759244a178f93d3bdd9d8415177b88e381621405b1b56673d2588a5e379c0c5f893094eb85f6ba7cad3b416ac4f7f3dcca226d2c6612156d95577a4c9eedf856e4b2bffdad3a691a316ca737e2de7c8eba72058f286318bdbc4f1affc4bc6907142b760cb2b4c38d3c481e438b5585dc031da08df2d402a063188ba023307cb659c3ba4d176c90ed5297638f2806d0b7c15d7914544e2410e997936f314cb711807a28ea5027d5edff77358d702201e2cecc0ddb8167d324affcf62a5102d7fc2ffcfdf3e6fc714f6e64ef94634ffcb7484b369e5202d9b9dafa8ddd6dcfc018e0032ed7e831a5ffbf68fe50795ffb18599e8bfad8533a4dd5434714b60a643ed755f9553ff3da31879c913d8e1460c40d3afc2ef0f2337eebb51046a5c5782cb3b4ea1829505bb4d0f71d8c6f3d973a18061fda8818b7d43a468ac76182b115dea915cc4bc9ba8ae9e9ff20cb7204a6f59b660de3cad46c721c6d21c0656b09748dd6ff3ecb9b40b3f42017889fa8589f07b4f1add624adf0a3b4168211c7eb69fa2c984c8335993951cfec584669b509282cf0da2578e5a295765545df2fbf010df5e9f2fd0f23f1a7dd338af16253960116be58506404352a76cc277ff20de6c2930a4d718e1e08132f55ced55dc108d891e289ee3372c7914f3b3196fb92d9c9b030e78d238d89c8a4afb53c19b017f76628f56413f20cc2fec27b0b701e35a70e4118ace980f17507748c40acce46c15b193f160fb9755554041a59336370f4e4ab8dd64f96a5db80a82ae146e906fd54d1c469526489dfc7ce98f61c0d87191bd0fe6afea19af11f593a9569aeda554c84eb6ea8d343f6d487c5b6582987a1232eb4ab5873ecf8e798bbd7a681d71817737f7bb0ad30d09501729f3c38cd1fbb28764442923054c3c8b9d15449f12a8bc7397c0e08a286717f5c5aef47464baeeba35d6571c373ffdaeaa3775b20123a9ee8449743384c19559f66c8c2f1519d7e7debaeb468a62775722ff83e6aa5736fb3b286ce39ce78d2065ecf6ce0cd825960050b38c3673f7dd331309ef58e3e6910ff95c9ae77fab09c3194c8d0a3d2ca26944197d72be4257069bf7db7f8a8de2b4f5372bd301f6e9b983dfd53e4366b249a46338e53eefdc6808e5bf8b40e5f3213ff3732a604218287cfbf90707f38649eea91c33939e97df65b9e780ee323f197e0c017833caedf906a4dd5abd78da4ee5ce7610f3ec3440fba4bb75c3e107ca2ed62e7829fec497ebc517a4ba79e454476012079c506ba63c6c5ad857f275535978d3673ceb516246921e02c2a50f8ccc738fa00aed04443fe9033520ffa9f29691b9604f98734c131de7245de5e11645f67c8a279b79401ab42a4498f14bdbb700ce1ecb65aeb758d961234d96a723157c4f3c580e819ad6f1629c312281e2fc1e209052462a8ff4dba8d5e95a96f72f0d37023ee258daaff063a74ce1e9f9c94982823f2a06430291c5732035b2f41859db9053618c0cd819812baf24a4bc1c30e403b0e17fe023ff9a1f3152f38ccad89b184ace9c55bd058feaf22a688c5492ca6efc9b662fe8873602b9163e50d32a95fe068879aadf4d519578ada2c4f2f843bbb6aba9f495fedbaacc8c510028ecbd8057b11bce51df905f105edfcca99a0cc56640744d2bed56e6af24f156424604dc3446d4e65a490df4924a3e3739fe14997f7179d751c1778d64fd9eb33a9c3ed7ba75ba393d934c7df6cb3bf50e7dc1cf027ff41e58eff482a72fa9200bf519a3f4b254ba1b99b5e5ccd7d7aa3655a28942276f20225b8b9c3d795714e810956f99800ab8c22a132087a4720417483f70f82128a0cc6fb60f7c7e715b9019d52268ae0d3159d285476bbb820126252148e3f0153fb05ed1c5271579537a642375cff96093b474c2dddd3fd2f62add7cbfa6244ece16af0d684fb27970ab876351213adda83b2ef14b8e80150e899d0059e9d0e937aaee8a6a4553c123ac6bc6d033d6973ac00382d18aae8860a569a79951eb80bd63d6aedfcf111d54a2dbec00f780f9354eea3f9848f878cb8f1877fca5df335814306bc50871fbdb10f8dee9929d395f926f72f13f32aed65d5b1888b8aa0f4fca8f950e1ddee060a0a03fb95bd8147534879c5d101f5ab8adeef2f9e5f74e435cb82cad2e562200aeedaa696ebe0273833b641e4ec94527bcb0e6dd2e21bb38afa47b37a5e83d105de2576912e27023419ad26055ae4109839186e62bb363122cae18298d689c432500f3127b17afedbd5042aa59fbe33da99f791f58ac38b724680ed2499c99546dcba7a910ae8545c1cda4912447b79695ed92b3caead5091129d06bfb3c411309c289a2411a06b51913972dbed7b5e93282882a19396366c19fc22d205324dbef03d7d7ca51630eb4b689a4d77231f8f780b01630cfab9dfda1507b0d54379e2b06540305b2fcd6bb7ccc1f3d32976a1dbb64c9b22bd003ce73ab457a1805e28f9910ebbeca99ec8aec167877d14c59369a55d9b234caf341efd2dab466af1a6d9a17ceff2af860b7fddf8da9d9699e7c407c29606331e2f0092481d27dad3ad99bdd66b0593ec878ac554095e16c49eb95ed3e027c287cb4cec09b8dee4967ac3e82723546140853f6030dc18a4dd1050bad68dd0235a7a21aa8abe13c1b21a5f5686bf921c0c96a37937cd2c043ae366c3305f810b3299d2568697c19871f9313be685d18a317a3d2d076039f062fa99c8e88b0af2409e04b69d0e03c086164722cf4448809fd3a6c99aa00cf1b26e836d89e6ef743d8aab0edfddb1b114d4f0680b5df01336e2f0dd08f2e5613dcd899c581b8f18883d2df31835314dda64e66bf31e4e21e20102e75286399e9be7da216fb061e93a721e4230325f656964694caf457b803fbb5bb1f16a90e5a9481429bf5e7687dc64fbf6fc2b840cf576928f1710688aa86dd07f2194feafbb756c321a97c076857cfd8717cebf0befe66cbd52a92c6e7aaeb07a34c17f493608de5a7b650aba9cd3cdee7a4866e68b0c3a1a7ad8310f0f71a3a17a33ea170da3038cac0d843e51e6aa347a1cec85cde9c34d2c2c9fdf1bbe991afa1639ca21f5b292fc877ef8aafb201d2f799232db0b2150564776dd5cf198ce73ebc5941b0fd4b248363c8d2f41ce1f314302bd21c12645ae3832e8acf6aab908d35d6f2a50bb2faf666d2b161cac48c5aefb04bec0fadbf7f1b928914461f0b6e829ffa5642f07849bcfd576804caf94a7d2b21466be161f5dfeef7cacc15176f30771c53b1cd4aa2d2c57af7d82b88ef99d8aca9499a4e2fd8e2c894da59ba8532c75c4764b281777bb1db7111c3c07926b3ba5566970ddb69779b9873b866e931deff48af09db150c68fd99f5bf0f4ae4ff9ac4c2b929c41d1f7f21504cb049b2474991b758af5c34c1b2edfee14b41e1b26253668d9cf905f095e8ed761f308016fd4f4d4da1e390339ffb0bc9d0024714fdb5b359787070eaccdc4b7aa422aba625d1fa704bedb524bb3a770d987ebf2cf7eddd705f5c1f251dc1db4bde4d79b326409a4dd9154cee681277ca0e928f2a3e94703fbe638af05830e82ef516e6aafd2c41f6d30ba0fa6e6d2a1b1dd6eec499907fd1882727a7a58d096c700600fc4abedadd7089fc1f2c9c0d9a24b54e5a84cda9af9fa162e947663f1729343f1aff70da6fa32399df720f123e8bc59ce04029b46f2dbc434a678471ce5c756acafc805363d288988dfeae008d2ebf93413a5ef6f36814c072955fb405b7f573c68aead9933cdfbe9c55c3c9fcf1eab71a32a1bd28960aa9e349d552a234ffd6a68176a4d954aa4aff26c18ed2aec2fcb67e8c04b4d09e847ac0526110dbfe66c22d2bd750009a0f690a077f3f6121a02691bc71694ef1bae6f2faf5eeb1dec57096b5aab38f835512713dad58a63c37094347828f8a723ce518b0ab9f43cec26fb205153f1a1db7fadd8fed1a4b71e984a9f08ac806a9a54012bfbab680f91688166d8c3f1dd89c945caa26415820dcb7e75e5b38e1be1251baedd6efd71d796e799e9bb76f2d5992faf0f985fc6a3c7b8f63f195115fe3dd7fe5b984c75f9520eb143f6b1b901d0c326ee82b41fa43cb26f985ebf3e1ca4df19ae5f41c99533bd69ce1c887360553bb94d4f90df3e5da1a2a95196157d8e6b3c8e8b50dd2d0cf62cfe1702a35c2ebf717379d23269035d7a4108b10af44588bacce9a7af9721e62c94e824cdd9da7fc9951ff314b47e6d01edf36053927d7427a83c3c14c022c563fa7239a7f62ce4f4263ae6cd5f5c6c0d03c39c623dccb9bbf4462897c60d381c6dd967cc9a072f5aaf5424103fc48ea4be48bffb8f1d35075876d9a19bd3430bdebe8702cb959267afb05afaaade1839a83e3403bb466c2df65dedf1846fcb61c694376d039c577612e08b5cf248afc47f832e998ac53bc5eeaa5621f6836418a0195bdb49fb311bd5bdf96b1019fc92f1cdbb6c06eadf2e60c6a41fd82c2cb9ad598d193eaebca48195b0ae1c0d420bb7565714af4b16b58d5c00c59b1411dd5e9b23329bb833f2a4e3b9e6727fef2ed428570f3872aba6ab27684cdd0eb57306d994f839cb9bd9349b0233925c6fab33b0943cdf3fe1adde08a2a523d0a38d6c09568bb3f3ecfc53cb8b2c4250d49f6cfa8cd781c7216021817128b8942e571ca91dbfd0808fe41f2d38c17f09aa31ecd58fa2bdf402f8d1dd8a9b70acc2260c62bf645632e6fa4eb48b2fd370f655ba0923f07f28cbfa53de348ccd572dbaaef087f42a1fcb7d30dee2d3d8875bae777e4ccc3703312fa6789a7309198588265ac3e9485b04f94c9b60314c330c99241a7f2b62422ea09b9dcf3bf425aaeb4d826a574ce1d643636d3fab6aa352df1d86ab6a819e99fe1420ccea814880ce790b804db5b0906e249a39cdefc9d14e5d3e4a75051d8f86d7abae7e119eb5fd92f8d4f22f37638379d89d3a99d99081fd1d24388565756818ced103c5270ec40825e8fb3ba3fccdb8ac7637314e928f10098050c7563f59241c904db626e76c3919f6089626bdf0c21ab699e8cc972f9f5c369a55e532ba7bf7e66d2ae4a85e2d87ea09581ac0256d52c3e569e2ab7ac4159a7cde4bb22517942635739b8077e2dfc0813dd14176240ca6ccc408692129d3c3814293a390e7f8a32e85eab808e8c3f5f09e296f6b9ac93e237b5d86e9df942e5e4d16d886ea7ad55471c8402701cbc472570c7c3a6df8ab7eb1c7470760b87deb93b303c62ac397f4dec0b165d8dcb846beec29bd8c5bc0ecf1c1fdff443d813fdfe4871daa010a4715a5e4b52364395f8738937f2495011cb0eb67b616c2ba6549a03d7dd5943da10a77a84c1551df3827976f5010e0198a19d99ef687200b12ea5f6d89ad91bcc7afed45c3f8b7532956d1523d7a3b6a59480dd5e71c3706b5673266955734deebd40df00feb40a6595f6e32021ec119cc6c73a11f2576a68ffdedbb84aded4ac2781341f35e534066ed0e6852610695067ca0920b4101996bf7d3d530945f326887111b553a1f10a78311f654a8cbe4e9a1edc6db67850aaa2a17ce27fa9515b0eee0ef307b1536023eb87b69f3acceb2fb50ed427c64266fbe45d2db016cc00bb23f2709a1449cd8eedbd0496bab03b7a0c18a91b85c30d8e7c0b4d4280496a69d05a18e2173596f203b4d5510b7274de6d10f29a4fe828e280b01a4983377d8746653cfdf250ea35cc7680d87bf4aafca198767ab21208e7eba06ec0c6e77aa5f841f8aad34624ff989d9af4e6cc494c2969ffb922b94592969ce9152fcd5a947b5150c1033cb9d7e51415290847f9a99ebed5104918cb05756de8e545f3f15e4bb030ae7ae9ded8702f297d3e32cc84a580459e082f952ef6dd08bac47271976c92de4b52f10c8bc282dfc375803f31e8f0336390afb0d3e44830a7cd916fdae33b1c6c032aef49ee7e2d7d8ee0d80b2f4282e030bd2a5bd4a96e39845446c2fdb2f3dd85666727bfd61c38db86a1739922f853b706ab8509be785a1c5564e7ff19d8cbc3b46fe5a92a8ec5e44ddf38679b4fb4ae80961676371e16a487c15de3bd59f6348077e29d6685c3408d7ec8469f33842f1043045747d8c13b375442133855cb3de183255d9aa2cc4ac1fe50d1100bc8893c637307249b5533064bb0b3ea31c651f702344ac91d0a0964ae39e39128a8e28e2ddcdcee3712a2bc184674de92ef0d290c4c0292de47b5d587aa1a5e2777b61e7357940a6fb3c6f7cc631e548ced93e02c810f9a8ccdc9481cfb8a75e94df819fc4949c0d50968ea84f1afc98db0db99f9470c7eb2b62a21951e8cb45b8d7fc44567724a67c9f840323c08e6fc57291906ad2411f1d9e1925aee0996e138b22ab46b1c1f87da180958d1461e84bfc6e7c75c376b6f470e2131806c8feb0f98ad6dccf537ae276631d7cd7deb20d8d4ddab3198f9f3a9fbc588c69fd1c4d17693d3fd9bee6cbeeb833aff4c9c705c9f6a1120193a229e8e4580f3fd9bda2cdef1842fe146bf736c9a939b6ce6cacfa62d0ef5350611403e9bb7d2a03c7530e6ced72650fb4b8abe0eaf13cbd1de378f60c3f2118f1d54e727a012f8934d27f99ff72f9b57001d40be88c707c982025230df252fd710b5c968f2a5d216bece978936cc03a97537d3a0f58e953a87d11edd0d9726e849d3e83e75026878c4b828ab0c49d635b7c2bd0f308c8a1e40fd80e4efa0cc552e606f067d2f5b0fff60af838c7f2e1298cd6eda3b406d91f5665b6bf7fbc096d6734fb9f44b653a761fb7b1fed18471d5314c5b0b1f1fd14e464d3450fe92deab4149d025320ec7a652169ac5a5b29f8bfcd818cce17491c2de3faeaa95790960cdf4bcccf3bf70f4eab90c07c1487f028f872ff8a94b1457def3ba4ef576e95de640c915edb4dd61181e3f92122f7ea3d953161f940417da83d0d47f7245b789d4bdf09ade347f107c6f912ed434522b2e059e9ac4310b5c7c661cade5deaa9753f16bf48b1107f1a1e67cdd9181aecc6d7eeff9744c43dd3396e1acd6982f16d37dbd2c8b239643571892aed368270494e8a05873c8d7e5094561ea04ff82d84277cb252d8f16b18b9b1952ff9b750689bd94a0dc109ae4ce6303f1ed8f57d68d7b3b44a9d1fb0111322e3f5606d4d25826adc4465f25d51290cf15c437f94fa28ffbbb1eba0ba9f2be582ffdbc79e8edc74484185541258ff17e27c4e866b5e99961b05acb5e49c10231ed5f918debf53103b69ca4286f6cc51231d1a7f0ed0228ef300e0d0309c65cd21c6de4368784cae0e822f7ad54bccf8ba42d8667677899b8097ed73768c736e4a706a2600bca40d031d0bead1d158f1fa108e7c0d30423d7dcc225a52e2b68bcfa27227d8c2c83aa2c7674545a60a05e5af25d6094463c67ac44ca2ba54b1401e2b40281f588a9357d74fe7227a9f8c1b0f30f577dd253a7590e09acbd725cbe166be37f4dcc3e3f3f3473cebaf630407a7ea6e05385e1d4eb0302e8a3ed3f2830a6a86b4f6d8f1c22d4c507a9ef197ff3239272706c9bb7ce57f208d77098bbf0aacafa32da7777c890389e5f514bb6162e643510ed29bf0e48f35c1e848b4c89865504add88d117fc9a25a2ac6c4d6ab80f9cf50fc936bbe126dbfc8355b4fb84ee602b5a7cce450bfcc890682a505abdc3489eac951a2970eaab102ad1925b083f4cab588e0c95e5f3639af9956296e899a604c1e090abce7b05dda25a201c01cd99f60d338cef167260709e2676d101f62eea3e82a72df387e82bf37fc85ed9ece91543cc02520d6a16c02c96de38904b2f19f77511aaa05c568206cca6f3f5cf9fc600413c1f5d07eba1f7b4e252aa115731e4e988c91eb0188791d35e7e7e49646690ae736964ef10bdc9cde507e48bc35f7adad03e30da4d920f00d053eabcae375644c93a9529bb6edeedd9f3caf3d5c71948817ed4ff01ee3a637e199e8626288fad7ded7bdd85fea7064393934acf18dd08cd5536e91e130b8b181359a69d1b96465fe99f248c6ef4463a48431766feb931338768180a78b421f23604dafdd779ca31c9fb961710b9b5c81ca203684071dcf632f21f2a32226063ff9ac9dc0673cd75794622e1cf50688f60b9e55fbdb5a59666b984a9c7fcfbec32954591edac82851885716f8bce4c79830fc7292fd8a538ca4d80f1f1c5d26d302d369206bdf1075187489d34bd9980d48bc24b988a928f813d468c96c112c9338c11db2ac593d2ac801218a04b0abfceb91dafe442d6de9831d27a40b9c823f28f5e8e7ce9ed7c6e5f4c9e240b8e733d9f91b032de81c9685d6464c2a67a0398c8fa8438e54c6ce5ccc2ae52ea4c7991cd1f35a7737e40cb9a456609ca3725389a15cc708cb53386bebf3e742a91db289abf78100b2f4fb2545ffd715fae5c702fc1c9d8af43b437837963ab0dde7765aeb842d42925adb3d7e2c437864a8b6e6aa5eabcf76adb5a5b3af463306302e46e49b6cfe98d9be6f2d70295a028f3e1de0f9eb8f0c3514405a88b9001f8d4f49f8d4125b273a2ac8fa7560374eae6ed84dc2557397f47844b41daf580504ea4921c9265f3979b29e1a2190faa67a3209bac0b4d2e1b4dc48d9ce85960500218623be8f6f36caada9cdff39110beb53c23ac4545e4c887030f074b42075e3c7898d9654dc506d797b9bda86f0135e6b747919b34a94eff3d1524c5861f44a31ce207a404b65b47d877ede6e9539077708f854d6a58132d5054bb34fef5bdecce96190ab023bb93b93888ae56b79a07aeeaea6b00b5b6fa0ac0fc08616fb5edbcfde3663e8265a3ea8351b4fe7c29efa23ec288cf7066f990a34f3e97a18bd2eadf6d620306eeb698d9db7a09367b21cf1358b77126b4ad3021cd0ea0fc8433e94fff8913593bd8c9d18c65eefb1229d16fc7289af6b62c1fa4d02c72316808b7d16be646b4db01c9323bf6899d7faccf8749af8d1ca40c8b94cf48128ba0bd671b5805f0c3348d9c686e3c1e50f331fd5a42b28e6387d73e4d97b7068ab69e50e98b6d4eb7c165ac77989547aa858a55f03679ca8593b530cbd1719a9577d025e321dcb483663addbcfece1ebcdf59f6dccbc45dfb91a37a08005b8de5c92175022b1888249c730c8973c1b2298cd8b0286a5a1a3d5c9d3f6e8604945baab388b987fd9f0a0b455d997e715a2d3e6fc299a63054b230321d01cb7ec64b2786d18396b51c93cac636a775c47e3aba0cddfa02c9654435cfb28c72c0aae0011c40f0696f8c9194ee7982a9caa830351947bb1e50f691f71f2e6206404b3150198361e18390e095369685971b0ad4eee0c6629d54cae24053769f2f8b03522f028718f98e0f982e18e0272ac1200d8e60a62358709bede84390a72ab4a140f19558f8042921c60b413b6942bf8e86a786dca983ef73a2b8a3d7a89a3181d23d40950d8dbe4b5fc979fbfd4aa58a4e720c3c53af2bab470cefb7d12e688db471fc3356666b721d80d063f216f2d530997e2bb27d3e7953c4a52f03081141cb07b8459bc39f07b5ee30a964eef51de0407b13d1ac4b1b697648cbaa64ac678e6de90d33665c35463a5a2b003d827748c402631771ed0b7bfaef13272dca1c624df8bc1302a11037cbf4a5ea620e63b618c7a3287f902900109b9028b39318a5b6590638c04058aeb54e971fa7d1266c7f8096fb6c2a9d3bea8ae117de2632981ca9ba46c5aefaae2084f82230890adaa4e01bc9eddb484e75f4ae66d1259367e08f5c46b11160732b1646e7b3b647d75c6f68da6cebcb2c9e00afc020087a77c4ccb3f0e9ae47bb02a4aa4ebdab150d37ec70c569d9decd1fa478b8e6f3b9243c7cd69dc3616deb06d4e56973d07c2b9361dcb38f2ba6ea50b8cb8c2d758ce3b9df3d5925de9ca61a8c6f64701c2411dc323f54ca46ca4badb7f8cb41276594a6a685d4bde3ad5d4ae30c91207afda253b9cf5eb05f4ce3ff744a719114787d9325f93f42635470e3908814363b93ceaeb82740f6f9ac0979cdda494e7cd25fb92af106ea268640d7fcb90ee2ab08ae6a4043b03e15cb6288da66c81b00ba8c73428c4110956c9ca30ee47fff3fd443fad9d7ef6270db6d24637dac440a7b093fe1c215abbae88cb8071d125032496db74a53a67d288c0519ed2e2be48315fcccdbbbc41898b25884cd398ee77874663ccfdf30a8a636ca9873b18d87e98d6fba56c643dcb4485c6dbf28af3a387e67dacf2570978c7a24f7fa317889e763fbb63dd9058273b3cee091cfcf7d64c3dc133272f7f8f10a1ec3905ab148ab7d46259f1dbfdb5ad8b8244d4451e3a446187d1adc7d560944b8762e95ab743726e1d8665a41f3e291fb110a6014ef7e348efe7c083df4b6313fb9a792db324a08be284fa2f8edb237ef479da2254628deee2626538c81ef7c6842958845d3bd4460cd8d1f5792fa7ab42560e041d026c4cd408d5a977bd4392d7f712b62247d09be997243ba2ac4af0b3d6d29f5c788b17756ec7b25694c983ef64eb5c2c5f14dae7f637a4a9c9d36fd2651e6fe654e9f35dc74641f9a264e03b98536dcb9518fc75a2c0c4cf58787af91eb50209b91eb002db452af32d00a64944078b67e6102583ac3f2bd9eb51671b416ba1dd600602ca0f79d7fcddf5399fe53412504e4e2dd2f961086c42b16f495ca17aa51eae11edbda1a0f8a622f9eb408736512d05215f0e3c0edeeb38e2fd5ebaa39ee568725ff610aa66f708e32b71bc1104569db88d3f6032aef34d427d9573e473b3ea13f218986a27cf10be9972bbf33ebd715099ca05ca4285f4c48b264d300293d6f60df3ebd66a4139834794a5f0db247442d464464a6ebc4ee85bc96954319c1cb009d874d2857c4d6f389901e6e9589b785b3690491aa0c62f9e5ca901e1092abb8151c3bdac501f844bffd2239a81f415f10ca26650525ed0c05fe1673ebc1d2c8c792aa61abd32ebb3204dbde0af18b3d7148e530a04b3748765cdfdf22eb5cb612de154b0d6cd6e235b535e8918bcf714ac197f9fbcb02721328a340e8269dbc2b18235729c92c001a4ff0a3de17aac6ac82715b7a2b458b5f28ee526877382698bd4543cd06ec75a7e7975bbace9c8c36b31f181029b93ab1c6d61b9deb520ad2f62714802525f190ed4580ae042b95a816a67a4a0b57cb15a830bdd1670a5d1b3190eacde831fc8ce008bc509a2c805b0296dd8b808d38f42be8529e244c09c36b25eeea6dfcbd579e4c4da3e350117c91f7a785ac7894fa752c717ac1385c1a5fde262f6b26182f4af4af0b51eac3f5ed3a763b32177cca6be7d3236df83553885ac70ff065ccaaa52a30dbf9ba08caa6273d460011c80bb5e9db7103c66bfe09aefd117944a0e30b3ffbc28dd1a0ad6dbd8e305581f54c5bbf5ff3867eac55c99b27f22c44ece78528f593f96c94024bdfa4fd13042fa647ba421104543d1ca953ed6a8548a78d68e95096087904d45d1b509a5f03e5f40d9366f5d16a16b6a6767ca2eed57131f572ebc3daded319f16111264a9dee3ce87feda9665211b2b826ae42abd1336a8d6ed47d00b87cd5f44f038132ce3c46fc3687a4169ec61334275370daeee1ef636e1ead986bbebbe38f498707ea41684a8a55ff2052923052e34a3da399280aac030175c1114ba3c81d9f39c337c442e5ed3b2601ac015500bf7fffe4dc52f836870ebaa20abd23d129bdec1022f86d2af62fc7a587a0f49f2e7c8b9bff4ef737142117601c035c299b32cdef176d83b3556538b0469acbac2b7c094e0cf251c0da9aeb26c2520198390b4fab0010a4a5f1c2f604ac6df616d2351fdeb0acec8bb086bb8c0cb7eac1eee66d7c9eda13d7369aadbd055bdb5d4147ea33f3d0d6222c860a889b81ad3872582df1ae525439bf410c6b5e78c23ec9f6a70ff2c03984e25ef345ec1411c049c22d55716ab3c2aabca9f1f58af8e354b1cedb8b19b9e1d74863c7bf894b0fc19d78a14d5534123646bded34b16d810a12ccc8d2f02eb0fd33f28a1e9aefe443a1cae9399633d8c60dffeab361c7535c4630b9e8a19fe3b190cc0daa3f744781f94a340a47c7bceff754f21cd4917a70a67af648cb42545eff538f5a8a1b9e9abe1c8a2c3f23362e6662933b4b14254838cfe7be88540976d15eb0874cd0731ac32e3ac04744f4e28b169f20c93142df966d8d57c500725e163721007c8ac9378f0f55aad8de1539aa8b7c8670cd55590f2b3b11bcfcd4a38c159c3cae4f1a5365a5709195c13c7b9c188b42e7a8190c4f0f09fcaf04876bb08cad395d1d77fc39d287d54c5af8acc112458f1143891216e9f43a2aa3f3043516941431244c86df21250197619b0e7bb7f38cbed9acb237d59919199620b273e41e840e7dafcc0156644a54f9c262fb3248506ce51d52d09ab5d5db793b1be5aa394a698d136460de7c66ee88fdacdba7d0ff0fb5d6756bc2719b45ee2918fbb32f99c936bde86372dd1cb4bf0a3b8f12ece4bbc1b14cf176b2e39008b743dd72434a860d6597361ea878fd629e2d14b1727479a09189797fe800f228330630758b3ed116c0b926f44c41c892aab583f0405c7ac7e8eec94a30673e002afa81a6cd5d0a02e85ad4ef9f38edad6958017446e4f2a1e1906244643a263b531849da819747f6dc0222c9d0852911373239f327806296f85bc4cc1b7f9bb6b64150ef56a8b603b12db430cf89a9da68e7f72201c6c5129e71bac4f7238d04acee85004ecbb9d358b0f714cde845c39fc98b33e9d6fbab13ed25e4e92b73a16fd4acbacb6f6fc7b5a314961e95dcac33cd954d8a0e22c0a5061bfab54e6afc03f29bdf3275af5d339d947319b85d329f2443b99631a1bc928db2cfc3cf60a693fe4e6c6017b3dfc9c6a3774901ced150252ddb510d526d0b876d58cf83b43e67e335cb00a3519ee056d41160c0eb23c8497111e4e248d3a7c10eccde4b904726b82a96b93333572c156cd86bcdd69ab8650abdffc2f99511c68ff7620f9cbd470a394228355618f70894d4fead73b8ee368bc51aacfbf02b0166141b55339d400ea003509f3297878843d8c914b856bde877ab78752698ff4b530c01f343a2c2b14fc3485d86a8cb3eba869540ff32fa5237c3c3288fa3a8fe428082d50563f2a97c258ffb118897491c424efff27ec2357457033fe6b071f7075c2ac60c1a1d0b58d98e9fb96056c091d71941f2ee5bdd2a072bfab81e2984b4260c50b88b2fadf27064df2248a03478b63029c6e4a22ee815a81ccdeb2dc4a5f75a31ee3cc30faad12fd34583006ef7553e135c70299227e57e2f291a8cd647d2bed9b83559a8f443e16c9c183d159541aec9672baa2801a5d719b486d488cf4e52b12e6d1827d031c8ffffa127bdd656a26e90a303dff08de023c4b21327f486766a0c74b8360daa24d402c2c85d4ac5bc088150effedc582ddd43c32b8adc12eabc13eb7e92e11d3250e0d99de72f70121354a869884ca861561800e54a5598bacd812484a366a3058c9bbb32af1f955012d98b5ff4d9b0db6ac79075ee9271cc4c4fe073a0668199a5fe8602df23ad684a47dd155dfcd4f7a2e8c33ceb8beb0faf2661a9c0c10296cf289a8c8961c7a50c4fc80304ad9aef959f812a5a61b92eafea404ef7c9207f26726b6c7a83f2cc22267e27729869368e05a79981a111465a05472f4a88c15ab99d46ef4edcead632a0e26f5610424b0a591c11c0a64daa04ef1d75c040d0f9546a0031cab1f36e22f9bc4a09a503929e0a1ade6461af24340117ffc59dd197c15890a8f458a2710c0fef98c488bab88423b69ba1a5f094735d8c9692bea2683850287fc4d9efe30bd36798a4bd3d84f59b0041320eea2c321822393c157228c3d5f713bdedcae23a58e63a4c40944dfec6d9ceb8c579d63f1b79b27653095759337d35781b4ef997d8c456e6efcd34e07018b41aaf363458053f0b626308c1d2e73554675c9b30412b30c25e15b9abe18b66ac391d35f84f5adfb24b691746c0343bc43d4e4fc6eb5b1bac3cf04403b30fc1507c3db4ae11167786a63429f2ebfa823f1896decc683ef1c6219c2f83725a526f370f6308c6b21761421626abd1f4dd6c908f43f277e0c3be0a55926be2f0d933e44dfb817483a28ba697451a21a4a0b0147b8d10082acfa87f4438fff8eceddd0b5dce46da5a2ae930212655422b390acf0169511d00a3855f317ada08a2b3f88af1a7663ca90659ed88a9d17012b0e17da72ebe3828bf165960477ef768d00f0cfe410eb5373bddd0bb483c64c4e4776aa76eeb5f151ca9a2164f0ccc8281667260e06304f63d65618ff851a574009a209e01a69def6be42d1b0b7b0e49799ca393b62f3acfa44743dd9e4ffb54d9cb98d3192d235b34474f0db43060a76bcde5d708104849b12ded404134efeca7e930b7b79372b1b59181c0178b216acf2b2644370a12de7efc27e444cf425f3a5805f4cfe1e46f1c27c5c408783eda1897c797a101c1a3e2c3fd5cde6a452cd0b6d91d2071d16d01ecd279a99e22aa9c76d787e786df5f7a72a443d5534e1f716dd86045742195cc63aebd7f75bfd6f26180ed05b8ced3b65e20e5dba1915dec5bb1195a2218a982c7f952070df26bc689b02fea5ef7a552cbea38fa9da758bf69dbcda9306babc9c0b2a1670a2177621e7004e885ec5c86edb325e5862cf1bf1d193057b769fd9408653a714a644b319482575b17318b08bff17d3e61e520baeaeb09bad54f1f7d6643dcf64ac7336bf4d78f4d9fef0f4ee3193dc926b8f64f62a051f658c4e1bd6c3d47a68d31b49c349fab42cf56e1a8882598ea680c17ed079bfa11e7ecdc0d62082750f629d2f2b2569f7b7fe0f88f40f2f65798e927f52b76c4aff42c6b13ed7d3af5981d706ce9461894cf3d8bb687f973dfc3f97aaebce2ff9e03f4facd1ab7a1b2460978fde32b9230cb9e615d435514a95382f7e5f910f8638cdf626131b403253ca6c8df5707611f32987f07f7d7f24e0bded1a4919ccd107a2aae4cfded34957fb9106837bfbc0d790263e6d30ccacbe98a3337bdbda6e276b7a8edb93005916c1aec7812045fb8408ad64d48bf70c8d88338403ba830c7a8cc2d63a3daed7abb6508a8afd96e3819680c078c608e40bad477cf17750fbb2a9424a7846d55fa790a9e7a63fe366bfe8c927ce734c86ee42a9d93c1a10080723c19cdbd7f490f99d9ec5c32044ead507e129624625051028e3caa9bc5c45f4d15a3761fb1bb22038f6a1c73d5b6d5a88d8295b4a98c4de413a7d8df2833993cd6a0e27db7702515fa9f95c470f63b11da3f4b3f3f2a750ccfd8bbda66d5ff47fd4cf48b48f43ff273c74e55ab122466efa85791a70761770a015c66f95bc74008ca74ee2d5c940666ec51a0440970d1119005517012ecb8482ef543e00e5a44d51fb3e9099f4a2426319ffd32b3bd7f5a64739bfa66ca68add78994882d3ad842bdfe622dd99d41bc7ff9801489f41b6157919d22145298e1ebaa158214dd0717d28e2f408ab62e613e49973bb9d09acb6676dfb412c94257567f9edab4e913f7fffaf527f724c8d60262b04b971ce2b8accd88176dc73d2134e64cdeca0cba8179ce3899824b654387812caa58c623f5ae7a639de21144aef8a06dc1b2cac793715e147c62821a212cb435adffca951dfcc432a1e860ac98114615957b7b57cd9d45dcacb5242a376a0895334a901030bd654638b8384315d45adc4403b6e1251e63b632e998f771285024ae261a4213adca7626502d050048e49428f24199be469cee1cf6b03db26ff37a9f59038524049230675445b04c7b357e555d3892446f4187801c1f531ab19e8a97dee2c89d1bfd277c0c4c0a2cbd509f6053ad90df1ebe80a6608c5d17a1b30bf200dc8ce1a2c4e3bdb302fcef9e938f3a564c047b40791a7b09f6ef956106b55ee92a6ee9833d8def582ada399745669093a6420c563e321557bb242aa0c1ad80d337f4e226720bca02ad9fc77f3c3b1967cddf8783044255cc3f57b339a6af664c2a3ce1282397fd88793be6d0b331978ad03f3405f52c835ede1b95fe06ff50029376bb020d1f776d3ef6d0871b690f0d6784201075ea6e5179117aeedf09743cd45766198e3667bd2a3b7655b6220783db004ef91cedd6411a1e38065722e52163801f8f3469c24cdb4b5a15e7eda3321e44f78b8de4a23be0ed50d2aac5406d25811fb4b79c93c99d6d76976f1998921630f6cb8911076e20c37b0630030a58e16e14e37507a24985d764af7cce63593c6449bf60ba61013040e61426c84530e0024328bdaeaa081ac6cb793de529cb090005b5bac249dc8361b68f653bebc4ee844ff62057b2380ff7dd7ded8d394c6dca9c21232f055245cba8380045d31aa28fa2cbf4486febb62e0cfc45402f14e13d883e6405043ebed6e7c14caeb8cf6f14a00a8bf1a021bf9dda3913a6f3e434734ab877cb477e6e8d7ea2af53de62fef530f9acd0eff8535b0e0251adfbff361f54cc7e2beedbc1f4e0bf443a8cdfd133382977725ebf1c0f794dd23c62cf35333627458ee67fc3bde0f133f7026cc2a68a5615c5a799635b25bfc76c2ff71662f456a2ff000686b9fd4445d98c60a026d0856ab736db6f3a71e12b137a36c9d5b3af8edbb17b771c1067387bfd0e5b8fa7b286641af5bc567b5e2e3a5cc5b15e2754f08aa5445583bbf43d79f93e5bd202f730be26694204214b3ed2cef0a3a7f2e0bea328dab681c852e5a6b78b71156e35feadfcf110768803a2ca23451227454d44ad001f3c399ab1594cc210feeb3a0c40577db4b1cbb0d9785b8a03b4afcf4e2677cf6d383870d378aeeb2d4c1967cbc4e1e412533716efbf123cb12d22a066465ba04277b51270e9f6977c79299655ba0a94ecacac576343e8f1adfa7c969ad31373c74ddbeae686c70aceb91a47562c89575a0ec66c7fea18c38e9bc112b67be7490fd0283de03ae6b4c03447dcabf9506642e65985392fddec8d8a46caf855174ab3640c18995897ce9af6b4930b808a3fc29792d26b3cbf45c473077cf023935644025bb18bb4880818bbf0678dac62e23f9c6c9833001357e702272abc589f17f3493dfede47e176fa41e63770d5e66cb1d2f09cd1e1e8d01ccb231d8b10b63256bfdb5a3feeee31e999063fe4c1634979216d78f99b254f7e8fb0d1010f0e3a731c22b3e280ac2f6ab770d1336c837403a80379965bdea8704dcbc0c1f89ca13e6dffc9c9d072006d7a67e48d8247daae6d24c08f1e286e0a9a665ed208738f3a0acd12bb96793630edd372a6618e0f865812a25395c5187ff2b708a7d3f89b29ca574b2d261d1c0bd564a52955a3417ef0763ecaaa7bf97190b0ee352e7198ea87f4e4c672dbcf16f56965cb3bfb38c356bf11a96afc3444e430ab69ff60b7ef4fe5175ce0b3d6858c37b3584324831c6083a3d374e00bcf0189c6fe28593199f9350b992c5920c3f0cca17e7a564f1c2c75123e9927bd9d219cb4beec89bb66e87afc3a7f0d8b218d61f87295bae72ff17df1a7855a93beebb52d9c593a8585d54bda200376b0af6bba97eb246afe08403e19a4866da8bb73065970ed7dddbbc9cc6b83817580f943caa2e660a74585e1e5b56088cb9a5718f1995d03f2c32ad247b3e4e1718d732561c0de2cf4c06b4aedd7bbe1fe68cacf5843307446ed54e799230e83fd16362dfa2860da4e9aab712d316ac762c7eb8fcb4cc47e7bd10336725d3b32f5250aa52a351b84a4c6ea427db43319ba29c7ff96165f0e408e51f3836c2d9a7a393ba6f7d4b618923ff917dee7e82d216139db477c8a7125fb843a6512c9edc54cb4f2f3cae9539a91248a0893457f2c755c91f4540fa701c0496bb1d72f8ac57bf2337c99a9647d488f8bf1955c36533b05f1dbf6d2b6e3ad64cebb794ec56a920f93689b603285e73bd5c8f2186c6727f0d54cc9161adb97d1c3e5ba4a274fe64c4c98e1ddfbae29039a77b90e254c96321cca9566218b595e31ca838f994322b478673259b643316601f68eec18d58b799b09bdcb0498c533c87dc937c503ee82685a20e238ba7ee5c53872da30ab61db09616152eff7975b6b2499c6ea0c64f9c5bd792c0489fd0ccb670def0b1caab8d33e9cbcd7820aff337bb7c13c17db1a1fa29c1704a1fa1a32f6fa7a7b2f8a23a6b23eed6913f5175fd1b93ca149a7432cc30e120cb655f5d481f1908a5b1fc05501dcde6287b28a288c58dc21b273a2fec497557ba0b736bc0fccf4c3dc844018e004c901886d7dd2fa89a21caf156e99cb694b6145f17cabc463ab8f926db3710d34b3e4fb43f603e6019e2bdbc57ab9bc2566d88c740c01d754fb0fe406857d53a706aec77df90afd9a9073ee2a3da8584122c9a67f09759d5482a7e157ee59db6e9f236a4163c3623cd9a9d7b59d04c56b8244cbc5f2286abca38982d3bd9415fee024f11584028fd79ef33be7476700bc6b6e73cd5f59ac74fe5188877b38baa1cdf948daf700bfba8f23d56d1649191833c4ad76ff174bbb1e425103f7b2cda4321965c1c335f5a1b3a3aeec59d77a1a738dcab614216b49a0f5eab2cb66adde5a62523fa7b67cb91b19199503e038d3ee485c4c239e270738d69377611c291e3e6f87917e81ce9203cf505f432fcf2ec87a7d8028201022ca64d420bf23b708b25dfb8ad90830595be0b908d634dc0a48f77b4da25d2b629dccdc90232c55bb2c0ce7043a2e58041342f64196b4be6cbbf2003cf66eb907e5a52aa4ad9d0d890ae96b39b0d25b0e4583572c0ef4ede0c3483bcb2e25c956c88da581c12c1fb954caed4d20b151539584130ec92c92ccd8ae3ae7c05d824328029a290051264b0c032cd2e15b51d509aaaab3e4fa9e448f22b2d77bea57be07056fe252cdfa0a6035670ef7931d3d044f3e5f00ab3c3c1fb8e3ab7e4f34a8d397cdcbc77689cf1ceb4d1d6d91c72803f045d09cb61cce8baa816cf2c5b516f67fc7eda3e57430f51eb5b3490dd9fbc6d40c979de4f1a864665f9bd70db891c28bc34b0a71f8697eb56905b099bb48f5fc81cd5646e1d1abebf38fc4bb2d07ac666cb1b1716933a1fc01f4d64f351b47ad26449af17cdad69676638fed4155564c962f6e359b8ecc2b5877b1ffda043d4525e59f51e3000a1d4a5806cf66575d7f36633f1a2e4f9f3c4ddd241e88c060f2c6cf8ad099abfc09fa876a170dc4308e05a6efa2c9381b33da9f3c52f344e83a3f26c17271780c520ed9c50b8a2dd772630f51db1749443b5d66121c40b78011638867a5431d3fd4a5f22c5c1561da17a4b8464cc0edbd1d5ad4265bec75dab64fd7ce95ca5e6fca50cf94444c266eb5fccf9e8cbaeac9d5758b2b4e4a4c28e3f9dc97b84e5d624d18049c3a0ff0c8637a8ab4a7e34523939049e57ee6ca6532fa7cb80ee0a282f86e2fa238bfbdf7ec77dc9c901ce14e6a8630a8f83b273df13aaba3cebb0ea4c2e61e8fbe1ad289133822c9c926f8a75d87b2c9db80b44198fa4de845e3e170a21d3a969ec941d1a0bc2dbde6f6868bc6b1d3a8f390236e60af74a0df9a4e3ae28273f23a6e516c22636d086dbc41b68efcf1e24d3a9e36e22a6424d49ba8c5e5179aa97e1d498a0e8a895bf1c5085ae3d68f1fb324bbb5200d053bb817f9ea9beea5139445f369350c8ea72199296de6c7907bb40316e915a600b482919282b4a3830bcd9d48c1296599a527462004406d75becc4386b0d33e92a1a526fa1b460755fdf7f7a4a6ab850e9974d10003e87ad56aa7c7582c72baba76cc93117b35bf9a9d9997e28a412228613955542582e9874e3fff506e99be49aa069195397b006cb367439dfb113c5e82547fc58c0144f602872c0deef4dde915df75692a894ac19204260942c960ebcf4ae3b6a0cb59b846a0f83fb3ea29acdbfa3286ccb9aed8e987a0c0b25e32a0ad6bc1bfa1a225b0940eef81c80d242a8ae2adefd159c681ff0814714d06beeb5491db5457417c216b8144057f4ee04232ceca6a13aa652fb1376f1c0efb5a2e97680f31afb88185d76f2a8b1d0f17faf702574fabcca411283a6e332a0be4ce277dc7991c46f8368942ac9f3883da042630c4f3ae25e475a5cc5e522c45576eb5c4ebd14ed57e5a79a308e1342db3586d83a207b82600f47ecc3af8b1cf10a202f62aa95ac14084a39d76487f2fd4faa6afefb8301e3239b3f12607dccba1d1337c08d9ccd25485141714d1c264e269fd334695ac588d34db5c31099dde72a21434942cfd55f9b16c77c8d09d5cb1f9b4cd96a9cfca490d269dc56cf355c626cdf3f08eb881af7b355d0298e70a237008c5d28f5888ae7c92cd5b5f9776aad125d86fc07225344fab178ee138a588d38ced8a656dbc1be12609b36876cf5e1e2cb4655304e3c179c4cf0a1030ec67b81d31ba1d43d27327db2f54ca6ca5a346913b48535503c0ed12d35d715c7038881b08a711ddd64e2b67693ac12cc9d83d58e0146eb168172b4469d27680642d411ec8afd7848b3e8b34ab3f1f2c69ecd8359d274bf22ac80ab720a3f2b5d822d4fd395a862a2ec4e8cb0fab24d8e7c398788d6644d77c322183be898f5b8f0e3ae0bc72c8fdb7d89403e7e7748e174c1ad85a10970212c738edf337ba6c062d53d92dce13b9ef7c5e55f63e0e1d18e83e5c21318596c1a4a305c5186e894fd58c51a1f04b54264670a54e1efc6f99b8445330104437cbb6e37b1030617da6ee0bf15c2589beca2d9dc8afe93ffc56b3d142d050e8c4c5f22a6b1cf03431868d381d4aa18d56baed59b261a0b14412142772192f5c2c5844efe3fe7f8964098d6a7db1e229a17cf2479d52d58e95df10255ac7d1b359f35b1c3c333bfb4b0bbbf191eee784283875a67addcde6030f23f6d8ac152091a11a3dda1ce64a89356592fe7654bca18e01eb01b88c2d3438df2c7e7f6a80400779493266474cad3f688c57e05bba7fc2e583ad5da4a9c7f6ed45a8322add178d3e3eeb065141e0b7412e184628ce37ab35ca86bda6b0486a39f0ffdeaa887a0fd85e673ea1d3b0a0f1817f23e3136861817bcd04f99180081511ea1dea158827b63748cca8981f82a6165434650eaafb6ed167bf90ea97f848b5ebedf4607454ab9d4b0d85cd94ba942dbd9cecc5c397dbac846e4cfc97df6951553dbed8c0b7ba05456288314e4701d481e733c99e715c1b446745b6dcb1c9cd98c38fa41c5152e7dd17ef8e1e3bff6754406c401a1fb94bd8b81b0c10e01a7672bea19e36fe2a1d45e6c6178d9bb15caad21ab343db6c06e4eb8ed426c2f539db5b7fc783bc5fde2849e622eaabc303c3fc925117516d0dea61157b235dbdffff7e2a668b1bb141286de89a8971aa456f709d47661a079ef0bd32acb5de8d5edbd9bf2f694ffb9e094880bb91e2c578ddf9bbd20f14ad82d52054a3e0ca100c3d6a65955c1de647df28cef07bbc6eea12ebf7f4d2003db94eb7ab1128d95a03b38e7a1480ecefc1c87bde069ac40827b02ed17f2a55896fe346f776e0a8be823e6f8d43bc0c96afbbf5ad64548c3592df759d8fd60fb1de89a8abf2fcdfc110dd343678ab728f9fad809c55ecdd9642cb64cbe75020dc812cc70924eb5f9542e7f8d0a4b38eca5bbb32578c6f2d223709b22b665713490b92cc32d71189681c8944c66579cf1b9145ef3b6b03fd002ee3f9989cdeb82f528b0ae8974",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xd415d819d3e46a676f680be0b52f601098942efe52ccb1dbad23489fabf8681a",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0x97473985d04723299559f49b856effb47d7abfad",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x1375170",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0x59c6a628fbe05515da2598d28cbeca17ea6f3997c6ca34d3e2bdef909b636c4c",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "size": "0x1311d",
|
|
+ "stateRoot": "0x3b81055017e986247ec2f435e38b39ff20b1280eadd8fe5f09e321644169dbb2",
|
|
+ "timestamp": "0x6ab8f379",
|
|
+ "totalDifficulty": "0x1375171",
|
|
+ "transactions": [],
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "uncles": [],
|
|
+ "withdrawals": [],
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "chainId": 2800,
|
|
+ "id": "2800-anchor-20402544-baza"
|
|
+ },
|
|
+ {
|
|
+ "blocks": [
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf90327a0626573752032362e342e302d616572652e312d643230333230312d7774396239f869945fb56304084a625a9a0eac9686c07cf2f9aba44694a0a55ee6109da671e0ab8e10e4e7de58ad26bc3794ac23c7e741af9bcc42e82729e3abaa64c809ae5794d15fe33d96494a36ff79aa4817f9618c14b67b8b94e7e6b4d336121966dba59a9dbe640a888c69c6a3c080c0c0f9029480b90290391249fb2968b0e71d8723372f8ce6f0fab9655ddb4bcb0ec016202d37b9f860141130910fe98781735e694999b1b26874b13ec1927b7f8c01d478f323bc9953fa391cc195ef276b35bd9320d6755141f1398a1d86029fac2d5b388f8a919bd930edcd133b5db9a933dffd2d4c89f5a02402b4a4e5d6df6377dc36733df6b76b8a78b1d90a1ad58757555a43816359f634f96bbd85b518768179cbe92859c985555aff3225aa5951f7e2da3f54a7331250ac897c1564e64953a7690e3c703de7ef47177cf6fe0719141c66f60174ce75542d34cee72b53f3c356f70f8324ad417994e508e4d7daaededf698c7be80594af113986b933431cf782bbe0e373be78bd80dffcfb63bffa1d9c5db79e892f31fa0a84724ba35082ecca322f96ef5b29e587e56dd734d8aa1c0e2f22c2b045ce17a9e030727a3d34c3edf94b70d7a187248d957717c88ea79c6efd07ef3156f9d438ea3e6c9c76be3bd12422c85b3a9e99d53ee93fe6c0e0265d3ffea065efdec7f5d5361fa2f85c9836763712ce5f60f8a4f0d1d64d0a3540b5a3fcbd0e8da71032a391f015ef04b101c24877d59915916098cc95483113891769fbe3ec8fddb1e5767c5fa79bb755db511cd6c95e7e5dedd2c3f7cb22a79d01d462199d9f060668d5fe0eb87f8ff987ffe533c1004f5059e70f271975a2910fd473b718edcef039625f47b4ba2da47172d945780c1a6cc1408cd7ad999f2733e35637cc69ae4cf7a4d72d3b6dd1b7a6327c3738badee18b94aa98239522d654b1d4451a2747de7e5c858a38d17a31f187435ca0734b86771edbbdd16dc94edbd323e497155be774ecc3e8d93f9b2607007318e7823ce5b7261d27b544a6f6ad6de92e50a6ca5e2db8cab09dc7cf9389272d07d89a2a77c5b528484b54c35b8281571a3fdd3d",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0xceedc8c63f445c91271071845d2a46092706a7b504612745ce67d5c8312bab1f",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xa0a55ee6109da671e0ab8e10e4e7de58ad26bc37",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x32113f",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xec5989a3ff7f72ae534f50aaf8685593b68512f5789dfed5870358c5abb80623",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "size": "0x59a",
|
|
+ "stateRoot": "0xee49117e16a797f4fae774c03b65bf33c061f8ff9cbdb7e0cb647d0cbf19f1a7",
|
|
+ "timestamp": "0x6ab59f53",
|
|
+ "totalDifficulty": "0x321140",
|
|
+ "transactions": [],
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "uncles": [],
|
|
+ "withdrawals": [],
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ },
|
|
+ {
|
|
+ "baseFeePerGas": "0x3b9aca00",
|
|
+ "blobGasUsed": "0x0",
|
|
+ "difficulty": "0x1",
|
|
+ "excessBlobGas": "0x0",
|
|
+ "extraData": "0xf9a9c4a045ca4e62d2084e1034f47a5ab3b41a157c8ab4574d5836b17ef84407383feb14f869945fb56304084a625a9a0eac9686c07cf2f9aba44694a0a55ee6109da671e0ab8e10e4e7de58ad26bc3794ac23c7e741af9bcc42e82729e3abaa64c809ae5794d15fe33d96494a36ff79aa4817f9618c14b67b8b94e7e6b4d336121966dba59a9dbe640a888c69c6a3c080c0f9a69a02f9a696f902950180b9029039a1b6e561f5ba843c19da1359d828cc0536a331ef8d2a65720b6d27331730ffacda96547aad6c6224697ee4b698114b453a1ff8c7db3e812dd91384c0c30f1b104da075a6d5c0270ec20d2c9da1f011d8b8a2687d40f975740eaca518d02333066a77354e15a678af59ee5fe631852f5b8765b9bb26b3fe6f3da7f033ccc3067c88626fc9ffa52c9e1e94c2374f0e49bc94a1f3fa8f35fec2e7bfdbeaf7c1a030a87b70589d36597f89107d7a19903cfd2d8c91e787c1d30b3624d137e94429deaf70463cd85d9c259ca4f1ef146f326dd65984950d99a2bbccab5569c29957010dc5d62016bf892985115306a210f85c9780ae47714cb761aa6d55ddbd678eadb589c62540ad913e196c39b5bab5ee2f6094d4734d5fd72b5684c4932201a8c5aa1d4e74b7d7ec409dd979cee7c0e79126b98fe361dd0b448df560a159e872839f2157cd69183d59163f73362a13ea8e84f6cc7838067de0cdbbd46512815b41f812279dca71132a21ec8da30f0c14454b0487453bc44532c873cbc7eecb112bf1c0d2255427a101fddd29d0ca6e25ac87d161145605f51c8b5a1ccf4b280aaae2e2a4526384a1b73760f9731bf81f2dcf4ae4bff35a4ad8e9f1639b607c6adf1a6643e5287b82412638fd2ed52c8d34f7ec673ed7f04a8cd28fcc6f3085f3c921fab6d6264d4648ee967469d88cd5372ddff9a2874938e26aba11c44da9a4226eace9b6dcfbd9bc86f0955e541e6c33a7c1aaac785cf23dd17b3ed35a8b85fa2388cfa5ef9bbd4c3476dbf7632615bd738f01f0f5963ffe5e37d478abc9a95dcfc8d1ca9d624c9ce9b225eaa78724123d8706c300a3fe8e0b81385b18b6be1a13943689ab139aec2bd6883bfa556e706d7687da7145cd0406135983a17af65dd82a48bcc9664d3fccabfd56c3c6e0f91eb50280b91eb0825f10dc0beac7de71bc28edc3f8fafb1d35ffeb47f556dd5694e95ec11146c47dc3f47f39f792de3883747f773003aa1d04af78ace2a42729cef741670c278f09753ad6a9cdbc585f9bf893171e63722c657fb2d6e7092840093481ef98d98d535e4efb30586ef7ffe938dace1128086be5b13d176b54c8fbbe4e077620d77342fdb7ae2957bc5c1a12631f8b7dd0e0790f1bfecdfaf6f14e10270650bd4adc45ca4b8c57d2154716201bc74088aa6937e6e63b3ef627c46804cbbd64cbc29750fb347517272336d9e12bba81c1e08b5285b932b3e51e1b419f66d286a5d5b5fd19322309591ca4bea9c11662b5dceeba283bcfff218fd834f473eaa967abc933a140eea20c3d7e9997eab0f9e2fd7cf03f413e85e0203ef7a8bac05f9f6d6b39bace614db9ae2db02b620c5178f753d996f9fa2583d1f56265278d6b4d5d729d56d6fb51e67f5eef5446c14364b8b716378fb27895de9b658e8e41b0f00ad33730049c5b84aa4023b7aa0fed0defedffca4727784d02b78ff64b2fd6f80a4f86c2f0f6f44c504b95df981ef71d6ce0632aa7817e507a9c72607de02955470b77331db005323a35db305f066701e12ce11f070325937b4e2f1449010878d9c4226a1ad302b3eef0777888aff21697c98b333a3e9c2e3934a6a4d0cec19a410dc564a434fa0f11c7cf7f4072f8a47fe604b1a14f5761dd7921f8c5cbf6f153ccf3adae0288afa922ba887895779c711759dac5d501b5f58e0805f9fc579b24e677b2752739cc85b838cf76efcb055fb786cdde5b049f74beb0355d06c749ec318d61f29b5a729c6c6618ba59e021ef918872b1159f0e7c24ee0253d5102d7d9000ad60d3630b8f108156ea5fdcf4c2726089d8f05b25c6d24f0385c09de9e2c3be39c2e2cdb825b2ac96cf7a311a0424eb1de3b4f8ff80407d812adcd6387bbbe7a63cb67bf64504534b62eedeb0c7b23c115ace60bb722be6594aec9010d0d5bd289ebd926aa3b098150b594dd8f044a23641ff23c651c496d11be6c3e1d7d7ad884ec3a5a8483481ba1e00265ba323c63d14bf1830794feb774bf785ee750ef366899c6222464483d1b33aec0bdb8f9181a6cbdd21d35c78e3d607e8b702edf42d5cecfbc94c7fcd1c39aa37238a3c5e392d0fa7fc89eea07e0015bb83a9ecac1c21de2feebcc4e67274040c650496c7000ee66c2bd8b7b9bf33be549d820919171245f6fa4a6e2c6eadc72c639347e9bccf75d95fb79cf09c674b4bd2959669782dfa8c7533f82c62aa951371ee3b77e7386a7ee1bbf5f57af680bc84f90ae0995286fb272fba49fb1e51083f3d662ed71d9d54ec216d4fde443effff74a3e7e04a8f8d37a0ec29550b288e128a51d6209d0a5037fc12789b8b869b52dbbb410c747bee593c6e935bfb867013eba88023129ed7ca14fb90fa058564d711652c26f0447d0c418763eac69807bfb3bf566a780da0c367943de6b5b442b111fefdbb2e322799029702fa558d53b60fdb769cc666d693cc29a38069618e46305f76530b65d18fe7b97e24e0f1f821e629e701c8784e6e3fc35ba9e137840fd6bfeae62b0c674bb54505100ae8e6daa6da834eef3876254da56b8134c376ff169c7ef23b54a9cb7edce52b32127114a252ef124143f699a61cf1f7d73e186e82f59259de7ac8dcffbb77bf57b0000cdd65945ecc38aac3e404dbfa16be25a09f10d8192df00b5afd874ff2bd4249fea9fe426966ccf9f394ede32b929083f571eb65cbd86e9c2b919378b2c0aca8e49234a3f50f273872cc4879e4f7e1255642636362875f63c55a639dda5141cb6380000528653e0f428ca7efb643de331233188038910afb0cf67ae8d5649b96c8d003dbd9a0c73c3da47fe253c3aeff4197344c2cc71b9628c2c39ba83b704f40e2e1696d4cbc59384f75b6ee0475ca1f151420b090e6ea4bdd1551f426fa43e081021c2c7b0a30ad5c140501a562babbe0960a7602bad371455bd52d4826fc4602f29e0ac58224639853649349c9f66f8710233cdfe47c4ea000c3b9309591f0cc6e32e4d52ea905447bd3507e280d6bc87a11cf22fdef45213331af3b970a75c945c1918def7e760b5e910942b097065b0598c88df122a252dfe3fd672320a361dc212323b51d70eb999a9a2a4928d5f623b411b8b6f3065e920f6a380856e2bcb8052c9ef8bbf31035c4ca5158449c6aabfdc33d8f77fe14bd0a8f35246b8b45f4463091060e0880a7ac0f2b8bcba19a50f2a61856825478e5e29aa8fdef96f764cac3f04169ba14eaa1bc32994bd69331a8968766ffc424693fe65628c684d8999e45c4ca0ffd63a90dc363cc34f9562977f0b203a9ba24cd6be8ef63dfcf896658ae77b0ead819081266da09a41aed8ecfd3300e633e2f704e1658eaffbede3a88eeffc847204d6b46a36814d43268af5730b2802eb60ea6699b03eda89f56d6a1831eca5d9a7f7703187600adbce514675627c0b2c0cf7548ed4ee31b1f26b24d404877d1798cb63bd48e3c08680f633ae4b4b9857965729cd2ffef56b6b8e1fd2390e4cfa74cfe3e37e2ea627926cca23498d45e77d6029916b5d15b854016d4515dcbda0da5d8c6d414d4ad06fee95d0f557e8368a7ffcd6c8559605df9ff9aa86eb3e9bdb0a1521c4c2da6362280a0c6ce8da9ccd3572e05dd4bb391f1c233f53a8757ad0e422788bed96fce6af6859878764fb2d75b10abab9864fbbd0d59693fdfd9461a00c8d9e00c1ea5681e0fad640a1e763a878131644db0fc195f915fae02d70a5d1d2bc8c653890c36021f349e123bcf56a087be7bdb5fb0a6676c089779f959a193965b888f81f3e24318e0bc0bce54bcf5d04f65414381aad4bd67b94c60dee849e2a533556ab285f849ee64d6d21c46c9239ad829bd8de0dc5f9520972e1348a4fadab1f21120284f7cf0693635a4ec1b77fe2c85deec375ac785bd1a9a66637d1d32a1fa58b84b7226a05afd122d8e353f54b5d00f823c9bbc563232eb75820048c47285774a7d73eae312129be4f3ca26eb2562d71794dc8756fbda466a501364d48c13578d64215b12ea7b1433b47fcea231a110638d55a25a32aefd6233e2c3c6de2abe7e7665e8661d3140936d385abbe199accd6dd318915229053eacd102ae0c6d1eb64d932839791b4d5643e2bad1e7b76babf180846cab07540bb85fda81cca8b998ca3cdb6679c260e9a8341bd7cfa63a68412ec39e6d42c37984a9715b431dd6ef35185926cc7f348e52b5795ead36997c3a26dc8b73fd322ed48b0b8425312c3474f38ae636c531a431c5af6258e28c7434327720d9c49ef69d6e541a141c831cbde6255fa00a412826fbb64ec1fe61e92915dd23f33833ba2e678aefcb6210b5ffbc85f042f33d10f01c7f22fcbbe692ae64a41190eeb33aee0d3af8e1fcc50b1860e3380789751e7a873521d71c6d0260c8cf1c81b6935780ab20c7a7b319b87ca8341a841758e75c23b24df98648f0f2dd41c0986af3324ff40675df76bb3a5e97cac2cdd11a754f601378f05c800da53b7f01c28725f3a4700db1528254ba2465f66202c092d7417062c65cf7ee60e7edde0cced1e8d6a6b8a76b63fb1da1a289de9675070b505b2eaeb01f4ac96ea2fa61981acd05fcdadbcdcdeb642c4af4153d48506691a43cb470dcb71f0d4d6006b303118da5d97eafc154d5ee42a739190f090568f99f239e64464c60dc895b038ef12fdc35347bcbce154ba991174af6c412f4c7b6833d5ddf64e3390704873517abac69d8866b9a91335fbf3c2696ccf2df03173c49985ee60e90e237e74c0adc0d2c41f74f491bec97b8d657f11fbd74a28e64b7edf673a20b1408e7305e817a949d3a222fdf01baefc98d042688a92d6e6edc7a479bf85a2f73411760e1abd63bbffe7169b1caa69ec9ba8ec4380f91009459a17ba442962232bd1dbf6ea19f81c4d2e99271a7ef077c17c5ed76556d2e36a6d35de675481d026541cbb2b4035e8e92458063245ef3ed83f5536a0387b4be756f74cb5444ee8cf2621694383cd1ef8be9cadb14a7e9f57a4a7b2c4ef622c171fd4155c808ed59f2f2876a1dbac992bc90721b1a3fa68217d3a03c32e1dd895f3c80d17f436a0d83b5da1ee4cce9881d57351606815e4168f4df12e3899a74a7ec9c7e2c9fc5df014183423f5bdeec60200f289bb8b83722e30d8b95997f4c01c89d6f42b6cdfdbf64f7cdc4c0ea9b5ab9f65a5d42709a37e7ca46f5d329a54599fa55e7703192458e35248a1ae4f530670ca7a3fe8811ff948c5f0974e5d24216f4dd162c61e6b2b2428ce85e8a3cc95be54801964c60200a7cf6c4efde068abbaa89a155ea09f5cdec3843ac203a1036fa64aa60fcb996e84d6c6ec409d9e04f00af7de957584a863926e937b77685afc3d4e6d90a0bbe194a29c681d4c5d3c93b66f5e8bbd94df4f69a12e200a350cac20872785ab76fba23e27d427d8785ec2bcefe9e39c9e2a17e0366fc7ff460316dae0bd67f466801d772fd61bab4cb50687614a1ca091120e1a0bec102256b3e74596f26c8abed3e7dea9e7e11dde8e8092bf4203ebf71be88ff7bfb6ea0aaa6eebb612fe9c99e344f6e3b63ada6e49bf5bac71c45d328c268ee052b568b1f4c72ee2270b7f75be4732eb43a2f82964da05a893a202446fabb6ce42e12a7e211fca29b38eaac79f34786be67e297f092bdbc9805a20b8afe525f1b712f968873ff39d52d3d1f04f010d3449c0c456208082be188c9fe81df7224c8bb5e0557a8bb073d724dbab084957977fe9ae86caa2a019ae9a0663e620594dc0a98c44e9872ede048553e1203dc5c4f3eca1a5b015bfeaa70b6166ebb4f65b9113d86ecc6cb60dc540c1831419506beebe4ecf9180b76faab58a8c21bf22410a3699b49e91ef6a5d049ee9e718a4ffb1cf1be1c932c1ff0b3b88540adefa397dff0b26bf1a6c79014aa2d69088646109517f352657231c9f543efb4c44c549b348ad0b92642b742e76598a695b89575c1e8de23948a1e4247b72c2d1af37a5230e509cc253a25a20cd23f3ed7d1d0e3ee62ed8e025e317560a341047d9772b4701b9406667adbf71e4ca0b668836822400087fc8e614cd48d46b14bc93dcc95dd4dcfe46bf4018a6be00b41f6a9e4df320ab6d978c015d4a75100827474477673b094964568888abde1276032c4e1aef272163aca85cb9700c7afb6368b7030a14d2cdc2d79ca777f2cc741aceda447a63b17f16522c0edad67ced43041b774e3a0b9c63dd626b9d8ac9d7fd008f323e678908ab5dfe0c4f3154c61b95db81df4fce33aeb1638c3d52be8fd0d8b96bc24f2f6d3459248c4799aaa23ae31891decf2f8c6d6847860df8d1528eb5a40b2bb66f5f4d4a595a764f1d9bde21dc30df121ad7a95ffb3257d430c322c4dd83c2a16cd4b53a6c93965726ab270a322fdcf5af8a1eb693d313769c57b317b5e85641dd7146bf65ef9535777bbea3e3df1879c5bd0faefaf52f67965f6a3e1985c33dc22b26b88175bebe7d3c7cfd3c360c60365bb15298a978f7f627d42cb9e5392783ed0569a9384fd0913bb9153c1212094481d7e5cbe3f8357bb26a1cf146d115706eaa4fb01e45423f4b4eddccd470eeba71bb8d58e333011f3d843b8908e68fcacee15a229575d0fd56a9ec2b3f7ed5773566676e75b7826d003adeb4561c83a763d6b21bed493ff8ad1a5e7206ef2728013b5fb771fcbf1c53430fcc778878d14753b8ffa78481b064bed336d3e278a470381059f000e4ae670787a70e060432762dd11f02c68ad56bc78d8aa111d722fb533910df6cec8b257631b1481d17714d8e4cb8d7a89d97ae9d7b0b035f9bd71070a125b4d0529415eb895c315f949f1373c225e64a58ee1d99e4c05eaf3fb29a87a5fc40b1ab40823c5b483b153777cd584e842f199e75fe283d534b044b9ff11629f6c2a76ca28d38c484307c30dd21f10c6ba48136e740520ea29e7b6b87b45e00f7d29a586dbc6ad7498ec878feae8f5a933d6627562352358af6b0c0d6c59fe9d00268c9af24ae2c816fefdcb0e3b5de56c946bfde5d533a59919a9f16b29f9e7997f1d7597e409fd6882fe99c17b197f232d3172489edef323800ac31735e4de5ff0d4ed44e227ab17aa8e7bdd6c391b44ca1bbc05be214321bc94a041edf3dfd9ae4adaf283b2ddd61233a3d770f397ae764354f8be5b95f473d1a6b34ca6cf35635d8f2cf4d58a76c39b68ccde75cb96fb91a70924b57fb92ed72e3e7d9ffe903687c8cddf4e4f01afe670c74662528e4e7c898e9c79ed84fa51fee0a259a17a9622ae35114f0edebda5fe2b7a3a48fe5e1495de947288b309a4078596152e68a5f2e4625e7c47a8c00c846e8448718c448db655c1a69d028a310e3931f019d7094cd29db51986c3b9b65552ec91e3eb12f59dd1233a5218af15fd61114f502619730c3dec6153094f51425a662953aa27349295098ba31d6297dd06ff18ac5c85dd557e2ae42537b0b2d163083a4002ad592e131648d02a89e1b2a32354658c731541f0c4ac1e602c3f343052b785cea6a9b17da8536d2042fcd3015738d89c3c20303375688f5532610995209dd334a0903aec6bbb0c58313b1af791169c0caebc15e5c1c36d744d997e60bb40b86364e6b8973b6fbeaf5f7608bed1316e2392a1905244a31a87f5e71ff1e4c3213878844d710284fc62e9bc5503f81967508cd63a96afb781d69b607704ed10bd85f2fd8ab2684beb8229ad58a1826205f26bbd441a09cafadbd643674ea8ea49567070c7d4a504fabfeab4532c15857aaa0baa920186d692ba657d524075952fc75e1d0c990e5101333d0d06b4a08e91cc828831ebe871fb88cfdb7dddee35d5e745448115b962d4321a3e8371c27a3bb3390aa94b1dc2887151c69929f19f65529f8fde049a9e9034e421b98ae97398164869466e1051a602c47161a24e64a885fce85f706ccbe53a07eec62dbe496a9dd27f18ff3de531269890eaa939ca1ab0679458fd5e5cdf979187f79d43f9eec2a316425d84670f64be4884570b0d4a09738401f59e8d0c3d55c0c6e845fc1f22265b05a3de24e577d4329fcd270411c9109c4711830186280aad779a57f813dce5bcf25bbbd07c2e5f8d499a0972efed26ec0afcbd386d45e01fa1ec1b30bc2521f553cd70883ace760e2d7dc9f7677846287fd6f738cbf665654c1c2c3ecec338b10b839daac93314b70ab29f19705a5b0a5f53a7d8848ca5d4208e6e74c61fefe6c349a55925162e3b2ba2250c004b888a65c98fbaca3c4e9dddf816013639d748269c271226ddcfc6093e80be0f44eb2ac3fb4bbb8d6f3a011bfb867481aa1ad4a91195e73f21ddb7659050287cb2edf3ee579be8abc8fb7a73cb39d53eac654e70d2aa0c8253612cdb533f74479410e9deaa39db29752fd26abc68abcf6a1e80e2c8250ba638065814df5cc20a3452b9d65d63f77095d7ffacfd50f0a3546d7ab42911a9be89cacb3ebbfe4d5eb683f6a4c640c040383fe1b0bd9b2ecdad523bcdcff6fbcd5db1c83c8501fa0c96b5abdd773204bb3ed188db835e187f89714cee0b2d176617c7b383dac4af481271c7ccd1b3b02fbe7ee96ba43554e8a942e9f696316bc6b72093aff9147c31c2e9cd214b12c0d6e5b94704330ca106df543885a3d4f20cc35035c9f2a65234d482c762a0bbbff100afd801ebefc2a2f3e4c04c9cc37d1429bd66a1a3a57b16429b9503172561245f10ef5b53b777ab89a971ea7cd1e879c3b20576a3a9eb130042bf5ed2edc7473e86d13f12969c2ce63e4e92bc9da859cd5891fba7d13b3f856abfb7abfb2ad5c7aa5ace1a96600c5171d857f688c14d8ef4386cd9e1e3a72790be0c1aa3548a87fd718a2969a0fc1e7fe78e3e552d40cdd784f6ab73cabf137631daec59bef461eb6219f41e3fecbc5decd6868f6a10c682a1165b2ab883ddcfcee47c70c996e17bcedb7399e19fa8b1eae136f79b6d231a485bc554b976efa1b15aaaa15380854d276a5994df6a4d1fe5309c4b51e9586625598809f80111fe703e9750c2820f225fe84850bedffbb2bd789d4a53e0ec8b2f9110017f8e23b6859fa2bea4df68791154d79c82a9b03c57a18ae5e2933559a5a359bc0cd23404c344c012954e269d6ff9662848ea32969a54d06a742482d0ceacac09b7f957f44abe7dd80f8f0d52234dc5ee9102af5eca474b5a0f186df7141aaed5eeed4156d8ad79dfce5450c139823f1bae5d8d1888319929228e6f7e39dfe6eaa93cd933f9ea54bb55659e10d0e4908faa21cd20e7e3df3e227f0f1a31cfe753567845a9aa7397b8ca832ace53af6d0e3de022478809ffdaa39aad3d2f815a6eaf983b0a12598c58705eb19daa13ce34899aaa14e0b72c032fab9031348d7459d555fd5a6a35c7b327350a14324539c268a125312c42c5609491afbdd1d32c8eb61087ba3c2bd10c4e60b18f4db81c2f0522796c5021c4bb7dd9cc1a24bf5ec7d0d4695be6629b0a347dea4a49d728b7bb10e9688b20357e362e33e16800635be80397f2674f6f8833de9d0948ccedb08811464a8c9fdf2892c41a17e3270d8dd3f6ede778791ff63be55839dfd62906180e6881ea8d5fd43472b7c5a9c1881f5e034d0dd0022112b5b7dd7b6fc85f6f575c03fa1d8121befa209b8f7086fbefe6903edae1506c825ec040d7a7e15764457637fdc497eb5629133468dde250d15aeaddaff9552ef6e25293053a075ca59a4ac9d373b2eb285cbfe7f0dbc011542c44ffaa527029ab667469f978fca16d9bf3870dca505dfbde4a92f1b3d9e5c2952ba7071e3b724b7fbe693451c5da0460ea6374b9880353675fb9f48265285f751ced2e22546aef1f801625bbe5afb822aad56ffc91986512f5eec0a3fb9f54b84a48c07bc2e041f3ef491b3f67b5c02c76434585e71e84b10f7557137546be9e90d9e0ebfc86d496f7922bb176cabad183d607b8c9d1239d4e4d24ba92e76d755fba79994df4c49ae7e44d58d0acc6c0340172e3e781f7a41f1c9afafe04b5e369e59d138a760473eab03c6e44639b67f9c382bd3e70d691eac83c06efde4a0bea4220d17b0c2101d7f26ff6ffc1e041906da48c7513948077a78de7b9e922899f7111c6dfaffcb85d9fdba86a39301d8898e979685dedbc54083b0639ee49d2ccf955c088d9580080ec08c090dfedb32d2881bf4ffdf2515c299735fd28007cf5ba640b752ce1a9d1f108cbad6dc679c552b6be65da7c4bf337137379868a05f2c38a777f93dc9bb9076ab8f4aba05a9f2720e3c41b2cdc8a1d379b1ca3478def56a732b12e791621efbe74c26edbfe303f85a26d65028c22737e29089c5d27ad5934f71b3453284275f4eb4e9f945947dc8972e700a6d4dd50d00c6659b1d58a06a7b2ebea60083dbe5b760e3a2991edb450942e4ad28241fc1c9c91a22e7cefe29519b669043d30e742840b78cd9df6e65ab729149e1e424b3a7040add5b320da715d3fcb5dcde71e4db30ee569602e2019bbc585544356760997cfc7123282b7597dadcbe54388f017f59bfa3c999e221dd1523d7856076fea859781f7ba151c023649c7697db0ce0263e09c465b52f74f6f5cfd2497826bc0a9288e30fcdc62ba10ac7ce52b4d0100b277fe6bbd74a7a68c43554fb666524ac0ae80f872db0591b07d2a5211b9c1d2d03b6846b7e8ab13a56a3f4192f4c261c49deac7efefbd68dae63cc450f47188d02e5bf48602c92fb46b98dbdbe82e609a281f1910783129545272719191a02c844f30a6bdaf58f15cc43bfc960c0e71967083cc36b747a5f7c0fb77cc6b6854eb4bb0c595dc4daa3ecd6957e540427efe99c2dd14e1e983a4c9e54681ba9e604e26351faebb0c8058b3e80363b34d4c1b90b863e6fd4a5ea01065945bf91920ac9829fb4895f6aae58095fd74a7e418b4947946389332580f8d86762261d16574e040510e6b65373a0d1dda9216c5f5df684ddb8987025f4379e48d960036aeed79cbf70bfd1a4675473a7adee7d8e06755eefc61a198f66b98114aa2e97de7575364bb65ef7f21f2b48506be2aa24c072204f52203b955de05d509cf73876434d4cd0126870fe79b693c2398ca7a498aac3e43c091e4d7b2462d14a70d2bcb2468b6dc09ea3c6bc5fcd98692a4a84225c361b78e79b1648b4ba54e3ea18b25643a14ec0a214a4e82a767bbb0d814af9a010d68f84308f0e0da75b23889f6dc3a9d317cc330f0e9c5ded1444309684cf7c33dea1090f752988e0c7714187542969129fe7dc0ff3d7d0046c73650f655bbd1f18a538af8cdee0618832f3237f5e192f154eaee2db92ff226170556b53b5c517182c818ae7134fd097e7ae434d6ed043cdf7a397fc6be277e543313685228ccee4f60d410d545a75bcf4d59fc6227803e4ecb47ae679bdf145a21c56773fe05a40dcad5192526638e259e0671fa97ae35830331c3f364aef742360adbc4d1d2eaea618a4a0e5247c5cef86d52a20151bb717dba5f87dfc53372a5e608579f569f1804d705b80863a9633cb80422ff6f353f651d797666b7170257dd31422183edd41ac17a7ba35580e5cf8864a1567daf4d219fe371a3a7bce4b49e6093f645fc66e8d2344e044c51e89c1a55a34a34b61a98e01df8e3797eb4506a268f6ab9b68dc681dce19d4df1a8b4bfc5545256451350937a1385292a542f03e7b9ece249233e2251bba672ca63b893284b204a4dd8774d3ea713c3214f9c1d4ce4a299472e4719647f39e8abdfa4834d1f66fef48fa74b107067660349ae24598466b20081586e33d4dd6edfed6648764914c4b33612f432c4c15e58f1dd48a05abdc16a571c4211f22c8e13b4a226a687d5a167441bd411e8ca759e4d15e12101bc99c6801532f58dc041206b7998e5250d95c5dc96ca50e852e3f2cdd53b898c1cea24b3996308bdf856e375c3b74441b520c18625937c332fca1b0540f1b4cd89e52360a5ddaf5298e97ff029706cb4ca2ed043aa6da4bd3a0d90d55f66a50cc319a9447f4b7e8a0a36827a00775ba5e0f4f85065bac7767d43242b8b651091193109ed265e69ce163e71bb74442507f902970101b9029239375bd1ef8232828026e4778748e361fcb145ed089535a640994ee1b4454c1d5eb1ed7af2e9685198c16f79a73a60c78c9e98813b9b06f3c25a63dac7b9e7495142a6cb4d7e3a7d4e254ca41246816ef6c16664ae37b0ba9d35a55ad8d055378702a9d738ed822143d4b3aceb426a9953838e35d099645e7f3085f5096df3ddc18b5b134ced4b7e973738167186e57af34eb51726e9d169ea14d5ead5acb3d6ce4b9c6054a6c973e2a09b381b5f8f8973f07746e86ddc9965132d105770cced3728334bc1648ff7a2420528d1a2aa7b249f2111b7ed326288ee2e67a08f608268c54aae1856ec8d249855c2e895cb113655f3cb9a9cd42732281cf772b2ffa43536e4d334c9d499b76c53f9b17412e23a2f150f0c0d35c8e1b2e6c1a2e0b5f336f3066331389461c084e0aeda86d8e164790d0f2d50ce73371d0e1c77f6e5139a623110c9346dcad30e4cd6364dac72322dbe3ec8d1a137c71a06d4b7a3346e2525a0fc14c19ecc7ef5bd7eaa0a51c88d1a2871e33898bac305e760503a31ef1591e0425af4e297f48a92e305d991c53cac139ebaf6eb7238cc6773031c2617c88ea72cd628a150ec480f9681a622ce7d3991b120e9f2d97d2a7ea76241ffdd57b11389a21f778ee39bde9459a8192cb45e7db24eb6f3f5c69326c17551639de7325849a962ba2aac318f8dc01ed8db3ced4a3c885c4dc1f93e777e5cfbbec47312eadbaf0d279c3e2763776e7a6aa5d39d5e84ae311eece3532477a02ddacbc6db24afafaec7532e29fb8342562bf1493993717c69dd1baf876db2ed0e064c21b1353959812a4621dca3697569eb7866c8c22548204c4e7a9ad590e16497a218277a02b3da62d2f38dd396c8fa7526d7b48dbad2d760d3b27a06a364e35cb16f5125ae6409d63d0acf61b0981d620282c0f91eb50201b91eb043897e9c0a38711bd7b80eecc6da9bc72585c48d6967d6dd3451426227d58558181f87862501cec3fa415bc910477fd4a3e89745624cf634b2dd7e27c2f8de46311e35e37ff4a6d342182ff8b4ea3e2cf99408e41c3ea0f97fa33c00e50d72b9752664f2e1df204a1c464d2112921896561f922a017588b0cff4dd1545c0d0586c7fde3ed52d679c2d540d008c5c9cc4d01ac7f39c7109c5231952ed8fd8c50fce56f146904424823609b935d017d22b8882fcd896fd3fe926255691d3cd73a53fe80fb97491b255d0616aa9342489459ddcf50fedc7bc4fda5644629cbdd918c90badd3f51ab4bd0fc6bd6faf69110028a94b24a2c6f983b24078956007281025735694987185df1b71d5b721dfcafcafffe8e935bb0be1f0c91e6d669c203e41eb2290fb69d3284b28163fa4138412559e8ab02206913f5c7cc7a9cd3c8ed139d609ad81f029e482c27d61461c05e77bb289a8f372d1cde1f83068ba1faa403277af977cba742fd808341f1431634b09bd2182c993c9442af8f37facc879ddd2c5597af32de5ebe5153769c9f06e5cd48f54bdcc6f5f0c9eb35e0085e92c12b0dabfc774796d798947344e14fcc20a8c5d2bcf8340eddfb9d40147c4c7886ec08faca9f8b064a76b1fe9cc6d3d53ea8998ebf09035711bc2b13e56b600e4c12587987451c26905ad1825641cdec3658fe96f8fcb1dc0e73edba73e81f4d5f4bdd60e5253bebcefb08ba9a8e77bad4ab1f8b7dea1944943fc57dc105105309a04e5467336e02a9261667ae2b7b976fac186aeb0354a25bbb37fb85dd23144561583f02196f7f5bbf5d7fe78f055cff1249484b21373d8bd837aa302bda0aa76838cb5ac18fc393ae4d3a65a12e81b75a708912689c91f5f66793885abaef6b855e2b6a4568e3fad7236780ad175ffadac036f149e18c6c0f9e228f1c7bd4a38306326bf7fc664022f69f09f15ad137cfb57500c0292054235e7d31b7c3d13f72c659e14063920c8b0d649c871e7369b1e19ef1bf18c9524d0d6b1f9b36c8ffd2302c7d40d7c4a72b6f87dbced2d2535bcaf3829582791e11565daa5339369c609da2ef37590356e5ba482fab7c7306d0374c9637581d87b99c4e04ba3d44da58ef76e915056b22f9fbb466880aa0bc3ca73b30a6076a1e080e19fd46b9bc432b0c91860f1f572ca3da636f8c13ae50aaf42f7e67dda0b37145085d96ec857de4ae9291c36ca54c6caa982913314096ac78a44f49cd0d1d7ff003d1054c27a8560383ca86b5ca601630be122b2ccc95d4e9f57300c1b839cefc00061e8da13a7adf01a0b7bd7b9903dbe6341be383fee4a4907f9a95278492d68c9143182fea246b7f3af3fe29f04f71697ff4cc62c6e1fe16faeef631e3159e42766080f6dd72e7affa80fe6cae6cb18f711c5134d5c9d496c4c24c90faa863b1ec4b81c782d60a2721045105b6591c325deab5e69cabcba226ab2b88d333fed0ead3e2533d7d29b8ad6a1f13cfa60bb8340a4a6cfa4c7a37285c3a560d097a19649a7508add6d519e8a3d7026fec8d3b46b1cf673b1b3197c38339a4167e6f535b07c78064983de3fb5a864cb30ae84ae9d7ae41d404f87b8d62ef9f12fa609408e314063d4a9e71a25f825d0f655a6be66406010213683ebad4994dff09592a7aa05f7c6ce9b0f0d91924ef8271dd00b5503464df29a99039a201ff4aa61660565066acb92da9f70210c7bfc7e0c560f491c0f0f8ea33f609923a6e042c97eb8327b12faa5e58ab537f1cc2b766486df9f8203b99fe34903731bbf64a65a1418f2aaf102e2c0421be4ce479cebce4ce802a177b16e246ac8761b8ac0988ad4c8b8a37869f8c90752b1c09778dee16c688fef85b9dcbf82054a8cb9956dc3d86eb1141b2bfefaebca42c25b955e9c0a51426257d5807d6d81ec05aa2c28168430abeb6662eb433dff5a123c4286fd9f25d8515733bd57ea78a9639f60849c2939d556bbc172656799275d269ddcb877f8e33f789160fb788ec3e51280adb792a7f34542177d7e37f6bcec967b83065b358d29b9cec9e0df919fbccef82281b119278b1b787487f8d7109aa5cfa56e5f3476ff2c7075a941a07feb6f3d84c5f57b3510ac145a6bbe1811b2ce75d62c3eb0365501b9e44442dab22108f7f04956a913092cf7201f31e7254afd849310a70e6f3ee4a6ea38245ba54ce3215586f7070be3aeede24c279746324de7ec109df9448449ca73bcc5d2b5e9155ff9027b7ae1f9c48f1bee565102cacc808e6c610fdb7d2afbab954d8c4def7e93067d19afc23e3cf4a9b59e98069482eade47be1afc38bd02280de0f00f6f11e3b76a0326aecb9cac48841b7e931414c6d70de02ad3d3ae2840e969f4c1a769208b040ce558ee9a66613b969f6364437323610c51e2bccc9bd8bc57970a1c4ef6ba8f84def79835d192bf82230f7a08fa6af8c62b8193933da7c867ecc5672546447f68fce3ddc4805497aa2dba6e0e81fc26d1d4441eee97175f936015fcc30ed15f0040c1db9af4dcb67ddd59c967df55ab7b5dd40a05c671659940b6692f666479c336af68c4b771f87415670843150daa3cb8ed298d49901bd49ef7dac7b8278c7ace220549ba0b2c66a3cbe395d268d4209ada61524df27fa1f16e4581979186c7e8b227cda7a31ace81ba63d0debfd99023776dabd98d2c7420628700e283cd9ca04d44c71c0551d9fa1da0c11e5aa7c83d3c839633d8264971391dab64a0bdefca40ac0a8f89317bce6ec24500822d3e096d860df609b10bf0e63eb3f92ced7631360d27460ece9779526f9b67ae4db4b07f8046538266d126979f73cceed9af684830c8889fdca27035dab30c57ac00564b77c9c2a03972d3e2445abc89fb4ede800afc36889dd158429390c3c78f4e09830e1b2f6ecfb9ea31359cd093b535cb8c8920539e37c9edca39c4840f963961c25306b73556833c915654331a5005dbc288f0ddf61499d374a7d0d3519d98f60e79c67c0ea077f6f9ec8313acc82873a38b3a294578fbd271c5b9a57f757e8a93178e69c1b48f162911c21c145f4b5e87f6c820a038c3ee955560f9fe953332ab0f693e66712c3d18bace8122fdb200927886bcba7cb3d5767d88be3212681231403577a364d0ace9f05788f5a41bc01c03e961f66b47b6d2278838796c67a062d98e30a5bd5095b1c8efe58f947d43a8f263c494cd26f2792bd0ea2a76d98f071c5d86c194901c7d42c085d732c580f6773225d0a6431d82702941b9866ac6861fab7bf078126b1e9887899af4f650a87042c3d3ae2d3e7b8da26a95592a9379d75576ac3445cfffa704a3e91a74211f1d190f774b163b2c090a292faf1c042929a265a44589c821af75cc855b5f5882722060904eab3bdaa533e725617e323513d992d2794dc048987b534ff40ea74f25c3e30c601422c7f9829c5381202aa36c0514d840905b1f5282a0143ea10ba3e49ae2ce04533014ef49206e53267bef669e5670528230d9c6c1054f753d6f02211c128ab9e10175921ca37104a496e287f8e7a41e141cf6617e6615ceac9cbcec3f05555a740a8fc755d756d187175661f47c66b44128df795e45f8dea16033aee856f27f87d408dae02950221740b340d2a247f9557000676947a049b2b6c4565661b3dc211ba684ea9e7c9fd86af81d3ebb8a77503fdf7c397556bdd443f445c52b04d6600100d614bce58b762a18896859cf447fbf98685fb86900b05d4093520f3ea9ccdfe7f8ae78bd3b14a0a18aa4297b4461ffaff8f5bce71c68c4033701a30f7c4be562475b01b2cdc7bfc717b2e17558116bc5215714615c1871ba00cd56d7cd515a04f5b498145771f51559100f4c30881e6f29d0a6d47bbc789627e3f8a3eb465557c691a3545c2cf9e15a991dd36b3902e2538f4568ade96d6342bdccda9e5eeaeed7684f102649d44d8bfcd4824f8b119bd67972fc29e441036afacd5f3ec222046766a86669ce493322dc9cb3c251ce2a90001cde18ae48a619926a3af2c405e3ece351f7622e9868c924d3fc2c454a8dea2291b04a7ce9289bcc630eeb49749cc93936421d835fbefb82ff5a07b513be8979621972e422fd446b1818b99c3c675bbd8293464ed43a44778a1cd3b2eed5dc792dc4dbf9887841be927b1513e4c2ee3cdcc228f9a79767b0066aeab071e4ab8bd5d0b7b7804b05affcbb3241572d254a27ff4ff867000afe9aee10f7534a365d0d4320eef734cb01d8b92bc17d1e23be954473d8b3c538e6eceac1037cf013107db603acd50c171634c6cd90825bd15603385e6bfbc56bb88c7da496172ac6eb3b2fb41865d0a60accef6abfbd13579bdc3380e568c995a2016b8ada89b0d2ba0c085b84377d7a49ab611ce00f7684e0f60aa32d20e89fb3da90725dbb5344cb7e7d2756111c54a08d4013255727026ad253f3bb587b930f5cb3df0123f10ed24a99969d45c0f6473e572e8aa2f17d4184dfe4c0628ba8ee5a7f4505d357ea45434dc52ab60d70e5da11b509c5717fc154b6857f3b3fe24eb3968c22cf9cc08717e3aaee5998672460224efb4fc4894c3214de56203ce01b7cf6b3a2de95b0f91e5a674e2b3847449c10935e70c85ea3282fbe905f91d9d15f91a8cd9dda76047659a96656376b10848e712132a895f640d7055b62f4056ea25c1af94f1b35be80fcd9e232de2954d5c8f77b3193a2d0166a85ad9590c9f391ad1b35b9fa028ae044d98950eb18b8972287c34d1c57e1356f7a64b7f80b85840b08903244fa63fd3dcd7f6f5890ff13e1001b020db8207b51a08f88881dd261ac7ff105eada7876251748e2b2926acdd781843f56724d9da822c2cc0b6b30372cc97c7e44c11f061e8f4cd9d2f00fc53bbf9f5b063c6ac23a2850a635abcc481d8f60bd1544339f9904d5611898380507aa175607ca87082252d467a7c3d86d664a2eaa93a35cbd49fde9dd3bea105ce3b9648e1a8d23b7b1ef7102e65273ff9eae122d963d96e115e2d5b659699a44341abebfe33b90acf312ec1f76ebcd6e52f146294ea459802256a682deef7f7811d696798ff1c6d04d17b142cec1542f0b503979948311ff94c1bd2a507b6ed27e1c8125f814a5bdfc7c5b7ce1e7aa83da2f36a9d7cd1240ae7fe397cb6277aca27d5f0d9228aa3237c709a8bf13115b6cb1eaf893701d8ff0d9dea558adc65799d2b8512d515befe3b346de523b4719621732ad6d990a7a6b54a8a376061d813a91f8f958e6ce0c8d6df253f5e582120147e92ad40acedc1c40f0c3a89f3ed0bd17b140a43cef62780954e9c3f1134ad794f289cc67377b2eaceb8447dcf00b1612944ad5b9a94c9fa2776ae9aff0f5bf9a5f79858539c8ba976c9b875a34ff1c73dfe4e6d61b3e85f4a11e9cb04b1a3787309ff3a9b552bfc0c8c3a379d4e36a311fd85bb9dcae3c30980dbd19712f57eb48be55fb2230ac0f34f17094d2e2401724a8ed3687f7fbc670e9e4b9b6a2e0425e163ea57f99a5b2194da2286275e13518a4c10298324539b82dac4fda30ff264b7006a6696a9f33bf4c291cdcb05f1b019f7dd25cb4e748ca33097bc50c1a13216237e1cade984d1475cd00fb5fa7d3b5b62f32012e1796517b142655dc659650c7668e4972227089ae3946a317ba57cc3204ad1444858482002e8afc420a7fb5d38f870da86f0071c98387c40aca64c69e9d6e49394849583331fe6a9602bd54567a07bb09c6f304e411faf511965ec4e9edf7e447b23d1281a7650df5d0afb1c0012e19e00ea7fa0ab454dfad9be6ae68a63cb359c36ce3e10889eff431bab16c0a4661fff1b54f6382ef7528be70028ddb69f9f2f8bf07749afc83ea6b73dbea5147c84a85a848bb992acf212edaa8dce75497f3a776cfd084f2c508ef8e49a71d4d183ab3ce0f27ebae693cffb00571ac131d2a7128f45b4b4cb92cfabb9c262687cfb85cc9a9a63e7528dae7d9dc6de7ee13915423773dcefb3420ccfc55ccdf39daf447e1022ea51b1f73e1ffe04f3ef1f792c8487b1063871866bfc07b56f6ae72d95c1dbb20f9f8321a85f3700ca8375dbb4ada5f0e7934373c4fcbaa1b02d6cfe06911ecf86db62db723fe5c2945857196dda24fe92edc46c1334df5a6fa1a9b4a1907ca644486f3f5492119fe4691a40523d0f03648d5f44aa724a1529010d17475fa77e7bffec110fd137be1cda566e4ee364f69d9ebe04d769002ee25d841ba224f9aaa68dd83f79445bcf8c85ede8347375ff5ee8d18ac20f551cba0732417b31617890a33c4ef9cbc0aae75f217bfa70aa79b1054d9d0311df9c2d2a15a63caf3628619a2cd52af7438c2c698f2670b928fa55f4721b9a5e316c235f71401b0080e0b9c42422b64a67d88ae94f05bfd59999c358099d75f636ec84d8d2e752acbb2627d43f3434f125b8e0a866e3f33c15947194df3a532288ec9101a2df12579485ddd07c7c9232ce02460169b897f1e002ad2889a634c3ab35c3147413afa7dc9cca48fc1988997c22fcbc430db1eb5912602eaeab8e4ae0b6b2dfbaa27f0bdf9a82d52c4abc8ef929e183bd89a28315b947b256971935509586fdbc6dab42877d3145270a5db04b14e42b629e6947190fd8eadf2f4f81db8239e419359226e13ff2eb38508b013d45aecab16133daab9749c59628c1e4d216c009a1eca875c872f250182c72c0b75053cdb486c1fe095348c11c396ad4062193fca6f113a155fd4f37d32b72e5126af678137438d90ebee055877bd8de5775df14158762a93664226672f9c3ed371a62d81dcd21982460ab8e76997c8d0375a352dc967df2cd2d16ab17c74af603a5a7d97abe21d4ff438d03db872fbd9ea225332252c187f72f935bdab76d960c743270b2dc9792c81efd5834e5a4a43644100fda80dca81e5c064252875a3474e150c89d82ec309b09b7012d29816b01e952d5a8874e7c58dfaf38c280251dea0ccf4dfcc0fd5dfe22db1045ac3a51afe8c24f44c8803dc4940352ff2a26a66496dedc3a3bcfef599296d63e7c30f5dfe4da09397ff926335e0d2684d817a11adb0fc06335d71a6ed903ad5993f6ffd85da5d1c6f8dd29069183f789bc5295d6d91e8d9958c4ab191252f3f96cd2d3923dbeae33ddf22aef367becc6abef439269b906dafcfb7c92de81e28f049eda168ee6c412e06422c24fa3fbe225cc3943a8d6cc5cc161c904191a8fc80fa0fa74bff5bc1a097de77b7b5ca262fa32b9b90ea546ae4bb049eb7712af95ae6e3bbc1a9248cb4db4bcd65eb80972269db35fefb007d158fb1ba2ee88e09974cf72626e8e7b8121ccf8e9091e58b4b508c72a6008a2d55188d3a22b94fdbb72cdcdd1488adef610b8b71888ca2595fa78fa8c57f4ff76af32ab09d9e9bf879e9f2befdc3d0e6c29bde062391df933e0c10556c7ff29312f7ceacad4a7f391b8e5ddbce3fca2817134efd099c976cc660e59d6c491bd0e3933a2db904ddb9c3794c58deb439aa7553f62c5cf15bcf963f1e836ca62816ff1140a16625b5bd7de3347220ab117d7bca69d98d5713be1211adde17d18a1c51c71cb403a1fd97cef546eeaf49a05b7b13212c14217c074221f560b1d9e977c93c0c447f6720cfc185d65d721e816e507a9e5392845d7bb2316f47160eb2210a580eaad22f6b8a534192f5209aa3f6955bee400937069f65d938cab17edf0779848bce0f7a6bb86ad5764a818f2f19ea970f63207f3ec2f162a9fc14e6dbf97ae5896eec942d14800f6bbf45f9220ea691cba3be7bec31b260b216ada3cd7811c72ab255996b010483eb08523ec707481724240ef3adf0b0401a641b026a774b4f4de903bcc4b77103fbcc5b0d5ecd101995c7cb919b9cf470647b6f5ac06ace926bbc5150e76359f760235d83a0644f279f653dffd168c65392be1f7bebbd51cf84b58d1bbb2404ab9d4d9dc5715bb5a8ec06b56a1d42a24848d125b6f9fc42e9dcaefae778e876e79b13856952484987e18d4906191354c3959b7277f97547edd43ba8cd671823cdde2a5a5832fd79f7ab9038ee5688e6c7c88338d43289de4f09c775d9943157970c9bcbbdc4a223cf8ab70eea8df182ef60583f7d3da411b0610139e70ff926657f08bfa283569964424abd9d0db18a3a8ddec54e094e55db930546110a95ea6f21907bc1441dde796342117de38972a1227fbc2bcbc0f7904ced9f3d52a292d75c3c80ddce6085a18f08f218a6763e1a42cecb82cd9e4e1032c5777655fca24cd8aa6c11ea4d334427efad7bcedcc099034cb7cb1b388ceb8eb24cbfa1b8ac91c016f1df21d15a437ceff12c9269ba9a74b45b3a416636e0f319ab3d1ec54eebece68c6593476b28926630448a140e899843be3a0d064d0fa5d842300c424378f8200da1262bb52cef1f185b00f5a1154b7de37a3f45ea0ae1cf25b06da70ec5d38eeb9fd54fdf0c5ba9bfc415be60c10b169f375e4f256d8017f2298edaea5ce3512cb585bd03167398e785d02f4872f4859176c1dfc3978fd867b521633f163b842ea674f292530aae00604adffb2591a6b8621a62732e7d9a2f02b16c15f71c422beb61327ed763945074fc26e8d5bfc24ef5ce70373b7002567304d2ddaf9c467507623619adecaa7d3859b2e66dc2e22f21bdb523a697d36b09b75fa95ed8e602534306de5eeec72f5f03886d5edfa2df265da48764087ad4989dfddf111571595b4aeb3613198dc5dc69db2dcda980607245e34837374001889609478519ac9c4a120beeb55b2616232ae2a17ea1407bb18daed64e581276072f9c108c64d1ed629b4733f92e477813bf886aec6b22c237be30869c58b17f516be931c6b6cf4935a43f5c96cc9ac17813501efce4dcdc8a9506474b88bfe2438f44a5197fb840441d449de1fbe248327cd41ad132f8e3dac0051cbee55f5feb47f68cc4c9b30d6f8808a2f92a7806a1c2d7e7ca9d04c75ac2eb9feb43b2459362095a897eaa62fbe63362be262b490b48bfcc6385e4cdda66f574ce4d3ddfb2332a1d5edbbebe4794ff26265dbe1230ea4cb61fa8f6d8c61b10a6ce429db89583c73afe90d333fe71729881b502acc8e15a93f7655c4423f55774ae71fab643d051d28102ac7b6f8aafa25fa2a4d7ba3b9eea8deb2939d0781bcaef83e7a4a9134d454397f0f5aa53422568a622bc9ba593f684b7e19c28905a30b03edcb6093ebc723000be5bbc1843fe062cdd986c16b25ca3df6395a8afc39d5d7d7e5f9d3ccf12a1a627890492e4db9582a8ed89ae013e1854fa8146fd3e08a74d9dcf73f82a20968dca78939ea0033299f4f9b7bc3729153e802716996354844da0fc95e45bc7e63fa6e0d12f5929f531a7ded8c904ee52cfed48f4ee5fdf1c2bf05b232b15153b96ca7a6425e97cf7713104f295f8f80f9876f12dc95319b9cf3fd556beab6ef698a382b268f5d859a2cf578b13a5e8703f950268e4939fbd6caf8916c619005ae91e0d645097bdded1295a67452abcc047ecd5f5723e9ee72a59aeffa99cc5058b072a86679c991dbbdbc3275ec09e52f27e3645f771458ed23b16c82b6118572d033bb543a308e8e7c74fe7d371653dc8f3664988ab7787404d43405f0ef417b98308ed2436eeb8def462fa5ffa6333177c30c226d6ff9ce5ac1faaf921f3e616f3fd2996aca4f4fcc036576ebf46889791717b48362455b1c40c1c08dc2bb393b8a2b5bd9b17e1df885343383a1913cf30792768bc19279208996ed8407023b38872f22df2a4bb3ccd99c2fa1981e0437e7cd576eccf71e5bf0a1da02414b248b505bf957b2ac4acb2304557a3e6574c6f0606bab43c7b6065b1317e85542002822201b7d60b6f5415a25ecc674b6643c85dcc46c47aab08c427acbdfc50a4820701603ca529f1d190436efdc23c289172d4b102ed1d3cfca49e2050265a3502e925e9a1f0297fae794bfca4e0a11b976f17825928aae305cb088ee4b8e2bbd8c4e90d6031754603e581bfdf1ca27da9e34aace850a5729334efc9427d82f2b6daaaacc993ccde249176bdd3a37b0e3fa56b6bbe3daaa60a12fcb8787792cab298e1730a284373bfe1cec038df45ca25ce321092516e849c162bb5835e2cf2908ff441d964a2e204f38e2ed9048adbd3aa1280cf7883727e5044913b22de43bc50e6d52794a66bad8786fded8e32baf376e69369d7afd77e7d4266a9c44d3afc30916cc23c9a066bf20f1a23f33d2a8ae3761b5a631d198bf9d2115a848b1d6d0f773b1c79bd2ce853382c5f869ed3709e96a6c380cbe73d9d7f67693f789788c8c3bf55fa5abb4c720426d1177fd7cd7b5e69d3a22660fd701acc482c3be1591297493c1a4d605f9d49235e40368098499b0e676f53d39adf26c2364a8e8ad5b79a3a26b07268045bd8150c8bc029d1ab1d0611b1dbf9791e886f9078acdb27b93dc908f81a3dc94f13bcdc5eeb6f6254fa55d7a521126f77fca78212aa7cc2ba3cd79cc91607442937a0733067a4f8b99dd1b019e26491b0f271d33bdfb37cd2dd26ab63bdec4e7f2bf226edbdda5e7268bf4c0951d706cec5f81607fffc1b5249441ab7b326163c7a182595226eb246caa11cd333d6e47ad72dedf9e2d6cdf0d7f2c8084a38b7d2df98a1991c74dfb740e8cb4762487a707395117df1715c4a8f7bd9a24a061da23441796aa9a9897b8fa634bb37dc455529d0bc7b774305dce4d66d64a8e7dabb3fcae651af3ee916daab9c1cfe3459e50dbd9b7bdd0b82c5077b1d6d99118becd0c040a302207dee418df5b0fd2ec47a449745bfa220e81269b0a9bb271d0c577f7559e80724a88986f62c67b6563042a40fb1008adeb0933f64c48b041c8775bf0fc0c7e493560d138846bf241f77b4021d00324043ff7a2f35a9b86ebc16fccd2a91e751987d4deddd03d71f6d5749dbc9add0424d28220f86caf3cf4caa75992c9589340aff11bc0c6930055607d4d97971de613b9f3d3884f1ab912931cdb73207da5dd8297f85013600bca6a1473f926b5bc93825d28ce058c1ae460777311bd0d73e486895f2547fe30411deaef4b6c159afe17da5aa982842a90bb7b41357f56c461c6e29d92daabeec9a5b360fa6549a126410f902950102b90290390baa78f1c5d4fcbe5b5e9c0dd8df08b9c3ad85fc2d2c0c53bc47ff0900924ae4fd5144ed9eae04e71f5259d49a090298daae2c52068f289d3b2dbffd8ae83cbc4242c3da26872725a5ef97d4cf238a2976d9adbd9a9497ed04e171391469c048d5b61ba1c6d1a7902c1d4f24bb76b7936c6f01217120adc6bde09f67a4b2bfd24345591558822d0951384791be59d62bb271bc71ebdc5b5de178c130643ac988354c4129755824baa68ca178e6133a77528f7caf03026d7a4b3a274b439b0dde52352a7f5cb93295c87dc87c33e761c9d88b68da13c6fbcfd76ae928b9c19521f618d52200c118a9348b4cd3b915ec4c6203a081906608c1a7355229787ddf99679a02bd27e8ce8dd485a49bb540a358604b46e6f58d186fedd9c73c1e177c78ddfeea5f4387141299f4e651f72936da8363934e98929d1f8fe26b7805e56b710e0a9f52b8f223de6c7fc34230bbd782b28a124c64d99b4f5ad8dfd4e23e7099ba6c4374529df1cbef547859bca5922670897987a2aa8caa5d0b7a2979f22191f875885ff6bd2757edd13e7c83eef85ab22631b160d34877465b62679862f552eed790b3f9b5ffa85992071ea34b453d818f4a0b3b811146b69515b65b1ad8bbc8b79e45cc12cf2b8c6a54f854678d165cbf643e038ba4bfaa2b23a5cc99339338419abec083a3aa3eaa6581771a69921e658f9fbe104efb43d95e4120ca577d166f3839aed20ea7cf538952749ca3ac0fa26adf41da718a40191b120fd9eade3d9aa1edfe21fdade64f3864487f4deac666c35c717ce9862a6388d4f1268743ad1961cac56a585e58ffb52a4d874fe1f002e6a6409404ae9705220d7e5a0875a3bb159e0bd066251137713c49ea69419330b907cb5b016e4d472136e3d7210b64fa36317e6b33f550baa95bcdf726f91eb50202b91eb05411a883170c589d4e9f6c597f0a06caa345e10c03823c8da4b5d81838db6ac496b57b5930962cf139dcb27c6c7c6873766485a83aa68eece4cdb0bf8cb79a5f5e41f870af8924325521394862ce098bc7867f743bd4fcc9fe163e90ee024acab9480f172e9507f473a4d8b2d3665721964b48586ee091ff61bdc90a53790cc8d43beca0fc34cc49b9f824bff68967456f1301eb30f0c90128f81248f0287ac8a39cde6a58c038a96458c3139eaa2b90c50ccc03c1a28a746dd0a526b724cdf9acfe8ec564b028bbdb57fa7593c162d59fb61fc9e976aa384bf53b65890556c271fe56cdbf6659b46531baa7b6f3b9842e291353e4aa990b0e0e17565dd507a9c333c8ceff165b980ca4ec7b7b89e51620f31e549fc497cc0143d447de4c7b7f6ce8c1353050d754a2c8d1f5d289141f27179b458b77bd225b932d4249ff4d8a3eb5427b400d5b77ce43804ead032661950ad75d519e532b6893c40012fa861b1c1aeacea5c7fb2422c70e01137b685920a6d1f1ac4c0937276939d2cce68f3192ce36703e6341e4421edccab74171bc61aeaed8ed8096bb0d188b3212b75faa23d7abc005b110b186428b0d2a7ba7c33c8e58a79e1262cec9639c4667da58d9c761ed22f8fbfd5c588a3459c01951a66d91616a2f1df2dc6cc66c7a00a860506b64f431567d0b11d80f1d3f2494469ee190e252a7f292dd02554ed7cef529f9fba550bb8ca97f8e104ce13bf1cefad34f5a175fd16485fab4d24f102f7ceb0515fa1e8bf9ca2793ae620f9c1843e2023ed6fa7c16d83d782bd3c304af314e5d7228acb825d664252d4de0256e559e54c08b00301cd129228071302bb488a61f58ac74739301803300ff9f0770b62a1871db9276a3be76e5211626a257a8fd2ac72ccdb7fc2b11f125ccf0e59d508100a9d214203fdc471ef23144bea34535756e53f122fd024ba5bf2e41c6b67287ee18b62c4cfc3d0f26d3ce00739da96ccec76edecafe6ce1b402672802240e95743dd501bc77d67bc2f36d544820fc0b664a900dd9e8a46e4b440b56a862903dee3532838d750174b6d124fe8cfb4c47106dd56447e4db2fc26e1d6d47a7283c498d64ca50b02e3e8fb99d0a9539b8269f80038092cc197ab97fc3fa142b7a452d50654939909f8c737793d6687bdf54b65f679345667807a5c0785f013889aa64676d2a577678989018a30c103c7d4d54a6fcbef3dcfc95d81399f31cb55de9dae14f38dd666452e8307afb4d7a3c87569d175528acbfd2ab50350b2090ae55777586a071dd1dfcf9c35d0337c9a1531b0c10444ce24825702c65d5dd660bd9b3a61f975493e559337e1ce3e56d1112ff14782baea0e8204d57fd2024c1b9289e27abd138c93e5b64af02e5f5843814a1783c6d04ffff359e5dfbc409133504ea3bf4d1d1433a8fb4bc6e185d7b83407a947bc4ab03902fa284a62f4f245799bec7713f9ed8107a5a7bfd36a5439f219faa685c36b3bb4eb555d58f39de26086a05dc5f94997d1671ad28f643f91384387bd2af187e1a44c32033fb1a0888088c19f8bc8c4eae0b1c29454eafbb8d4bed9177ed0bb74f13728e3547fa6ac955dd9ab189de75082601a59649691f365562bee4c2f2dfd9bf5a4327b6824f0e324edf5d5a2d86028a22579874eae7215e874bf1a855d5572a525a8dad926024f36aecc6beb23645f49609bbda79273689426015f5448e55633906063d0f506ae625e195ae424ea77fed332edd4c74c469fec63eefe7eaec837c3004b3f70b7ad67af02ddd90c6de559c51cb318dbff619d451987072e66409232e4bd9be3e6594e6bb46751e1948629e256144270504860b42881ed5886bab4cd05146b4d5f547c13286c657fa10d3672692902ea6354ecc02677e27cc37b3ce2eb4f422f5ec0645fd3ab2e48a569bd615d1c98d740834c22bf86de9e5b9bc399f8cc0c561db8bb29a164e2b69f899b7cc8ca0955315ffaaaf40dcbf164d7e7dc7713e69ecff6c9e2e292016506b70e7d427010e720dedf233283822cf9e86097fedbd96e5830ee35f2584eee9d9ef98c98fd899fc346ffd16668dcc07299d3c783968f32f3d75ee2202bbc37580bafd706fa91759fc6f185ae09bb310b38fcd43d0382fa0cdb430bafe1f93d93dee4f8b108cc32d7a1cb78313b5f472d617ed47103d34917f8eb85e5525db1d0c8066f89bcb499161c10d9c868730e53f1be1219488e62c912e86adfa6f0995fd192c1fd184e8b846141ddb80a751bda1392d55955d4434be984fd0717bd7e430e725b4497ab4b15140f5d5c0b38b9f5d09fda8b00a309d77b6497b5a490741169b31a422f111b67d101ac2571690d26dd3ae050029b022e5ada223ae9ff3e1e28211c12d46ba4022c190e1fc699829e53701c355a688b05af6671aa042f88afc80350ce9796702c8c919ac0e55915b3de09fa1e11835fff8a197e8009a78c541a9833cc2c4456cb8aaad6a110df077b0336bf4a38e89f8c560c27449704a27557edb66f4877638f8cf0ca0a4373927933e1ff7cfee186960f21af533200efff855d237d99e39a5616767a20b98092dfef00259a3bd5bc88a6754c2bd20f6d5e526ba89de51d60ab056676d99c1a070942c585fd1194af1c957ef972300871c42ec2588edf2a704a31942bdc584d695dacd76e6d46da222e3ae6e0093a07a776569b04b1f393ac6effa6f889c6420f998c1e3427c796779338c0de262032a025d063b6bb8c872a006b6f3bcec0617a6522c127c9c304f10134cc37fc0df43cdd9569beb4c851747cb8c3c358c5022d7692261ec69aaccb7f7c382cd6b0d219223e7d8713e6b1ce5b8a5385cfbf78b352c2ab05cfdc25b149de2f2985be2eab7709f29019dabe3a04b9a9bbdbe0d689ad733e976207ebfdba5bbd808a2d946e400a937c2565be31bc8de29652413c33631c65fa2fbcbadcf83b11b0a2284fb596c91540d79c18aecc95ce45598c0a57b8aec63cf6efdbc365a995605cf57705f65e18e775e7ee0e0fa32772b8b40c22b4286c4c22ce4cfd7adbd90272e80fe953b21b18ef022444c4b820f68a49a12a86787ecad2c1ae3ba2db2a035994a949e823e67ec51f3a214a2a6b5103a5fde8a5f8c8ee85f9fdc10f476c991d7c6c420f9564905919c21f939ef183b510ac8d5efa27fa3577f1356a3a999277390907ca1aa2e24d6d6224990333a77db6dd514230efe1b4d3adac0a0949b078096bd93bdb712db42a2a945d8dc3e2b4ae982b1d2b67c85e0e7395c4b4c6868113f62a674ecfae88ea86c7bce0e196973842b009a92b49398075fcd56ff9438be097eeec420c56d0b6510b1f3192ea01353bd21aa261105b185ceee8d74e374aab9ce78f2b584104024a24f622d75ff62baba3b9a568f9bbf845d809fd57d55597c695ba4cde40257691510ece3801d6b95b45d81726eef1571cbd8686dd7206e5457609e78f1a9929974ace76814dfa68e41fdcf724cb0ecc6badac410238ee0aa3ae19ded0b04b0013d5c445f6693a47de54696b8a029b6284c99a74b56cf69ae882535aff859711252eaa58f3e441e02b48ccbeee952ef7dea2a96e234e51d1526269003e2f55320f309aa5830a37723851abea8aaa44c0c3512f3b8777515346573fded4a7fb6a667f2c79f30926db346115ffddb256a5a8a840a61edcf2d193ec3ed29adb822542f8ef72ad663c37e09e19173c7ef7d71823b224e5e59797ab3cc5ee34250a563c5aff6392e3b81199b326b5017afcf95a6eccd34daecffe8b898bf259965020751a255accd1aa68c1dc15e0d5a3bff43ca9c26ecbc1e2264448ef493911eaf4d553088ff83ae6823a5e60a2a1488b2c19a9175cce1f5512aa411622bab9ed7210a52a776a7f240f049077bba75646617baaa7af255eacb7d5c66f71db4f08ecc781c8eec150463cde4c0548affa48a18daef3729be5ecff0decf725f0636825c5e41ba2f35bbdf755020ab749f662912e2f9832b5e87f1f9661aefff5c27b754e955d20e93e272979ea3a8cf38de393100010ab2d35c84babff6b389f5002be8fc4c01aa51454ac3b9c69211d5722175cfc0d4fe22d0c91abc2d469ebfbc6a0aa068730a512b4692c57232b882703cc98af18c85fb8a3055f5d78cb7a296e57b9eb09257aaa61ddf192d0230a1456c5a8a620e4fb0fd4e7371267e1e82d03b3fec9d143603ca1ebc14cda8a3cbaabf3ea3ecbf1787b4791e1031a735668acaf7f6a0a47b9d7eb2d619586a48664dae68c4a58155f43b6496dd5ec0d188fb7533688c135fb4f265acddf7a5af239a78d55a6e5e06eae435e4d2469668a0376a4c31d63677a334b1f9471b20fbc5ce601385237e5a4cff3ad50c86eb422b86ec2c785b4107c6ebd131ab01cd99496a43dc806302936b9436d023bd4dfb13cd60e6cb8c417a492230af84be3ff4eb28e22951ebe0831787a9b381de4444bc4aa866f0567060e294457892e8b470981c4b6b36b104573deec0015f2f1bd55f0b475b6b96006c5666f1e4a6f2454ebb4dae808b88a19d585f95b21d37e5cb5a721645657af67889ff685e9016ab142a779c5d7be9666b5369689baac06b4656d37cda0f00fb5c061cd77d5b9ab8917667679e7325507277597e82031001400e25c153892f46480f3afb041ff2157a05982f2f066cc6dc2d9479d6e24404e104039f51083d8b5d216e9e2a82e453514363700b0424d4756984ed9f372ea8687895494bcb93fee8c900a096c088992dce9c5025a83920c05cb2ba36493da36397a135f54b570bbc697076119629ed4db5c38f26f3b5e81786c8f5a4a298eef5c3ddfec394d1b89825c823310b7f232f140760ad53d7c3118b6d352ceeada893cdd73a3953f62868407bf9dd542d3c4fb5a6f0c44a72cc2d3e0f096ca6bf1fccb40fe2c03bda215c9dcaa9e8d8729984c08afa6232f0e85f1aaae740fe6e99e7af6ceb751788a16fca08c0ed266ff672b4f9b498dde842bf2388aad259addc96a2c5d4c4ede03c4d736e69abf9a5c7a3d6f57e92a62804f13db376f41282380cbe3a843c6125e0a2f0d0ec41c479d4f33ed417304f519bf7bb881c4eeb73ceba34a5109e941bc9ed1268bdbdf9ba92e73e28a3cd6969eea94d6b2d2ee167b0d2780be31706cf1393911433d38dba7a0a180bcf0ecdfd4a8eb8e9aed370a7b77d411585164658ea79c0e60690f295a6e565926aaf014a119227e37fdd9f9ded8cc318204282f6ea068764542af8c3111f9b7aad2d81e01d184b2fb10c59bfdc7d2233b536590c9710c46514a0aee8fe4a50c0fe21e5d29ba3ef9aae7e09a2c98c2367c53b172aaf6faf3324190677a752f6790698f2d44fd9171dbf12db9b62e0f4f61cc3a55f55f64e34a9717c98e766f29a20ce198ad42de1d84efa93dc91bfda3e2640ea85eb3804ad0b6ad6b3a5941309fcff2a20f5c0c0993687ca827063e9eb0f0a0e3f9d26b56f8d440833deffc96c591114f695e58f606b7060569e424a5c5988fdc283b013ebc8c36d3f9f76325a2927709023cb0a3f3fab5816c2bbb5f29a031dcb8821e64993bf2b349565e8d3b7b28ee8f0b424238aec1ffbe4f70bca3fa3bc70fc4628be65297985d7eb961be115f809e05561bc51bc1629c33ebe608de9aea9138305997dbdb1e7a3e67d1ce0c50655d3fb85380fe4dd4da7b62152931b2d7af5be7c4f297d47437c835821e878f50aaa5ebffc8f5189f5b4adf14abf244569c15df00c340d466792a01ee66039adde814dc70cdce7fb4b35c919c1d831b394da68e9b11052a18f9c2f327318aaacf602891584de721cf162e2a240d74176ec9a15edc945f6fa99a76f4b628c80e84a90623bd137546f67f6586c82e88f4673f949312e7623724e7ff429f593231b66956874d1d39ae0bf36332be3f5452d52f937c5429ab0b826073dc0ab66ea879c16925899bb07a05cde5b48427854d84ca162c7a7d4b13b39b2b0b0d184ac19f01d7ac0358022edcf9ec6f7fdfbc62480c1a3511c1273c140410b2bf54287e96c0ab755cc2924ab55ed01e4b0a5a75a478ba688dfbf0b29f1bf6e68f1afc00f90456610e207f57c833f8c25f4a8d3eb1a5df6c628bae7f790c989fc4ed0b37b0d20925d1f53f6af611a86157aace9719ae754d4e5b4e1be4d4daba0b24bca3620b2828b3a3b368e342174a7ddd13b04b98dcf56c76d065925dd10955ee2d1e79b6a51bc36a3600ae00b7a6eb52db955e3ace658887d530535d19685cada95337591ff7a5b7c0a9b8e81b3d450fba596fb94e12ab8c51cdba81391b877265cad2fca73a8e36e1bdfd31ce64a0504f8c21c41315059b9b863438255b2885cea804c676f727c6e27a724230061130cd3742b5a42a508de5fcd3d24d69572676da3262c87c656ad8ee478947e22feab3c2a6aa7712a5ceecdbae6112ea1c9bd7e43c1f9aeb176cfb1a08f41d0fbb9c0beda6c6e00b70ea3622f3bf5121cd9c2ef54f210f7d47bd9fa339b72f0bda6cbbe4b07de0131145840096ef4d3939306a8995cac3828d7ae2d03d3b56a19e9b217de47f8ce3e51a5aa6d31f49e5cf82cb68bbcb9683dca39a6b3eb0abd9e0bbc093ebdd396a182120b44dcc69410fdf8b6482abdf800c309db66522029deb6e086e7bce9f4e14983a4ed0f2194f315fe8424a7d090318db76a56a3b475a876541e05bac0a7ec2f0c5d26b69c7496815e7decd3afad79335e4239f34f80ffa646447cf15282f22755537490e88a1f614c04142d2238140da97884cf629a1f2f2c3ba29add20976f3e9a7bd90ab2aa2d5db320daa78ba6943af533a78db3e3c92801529a2bc57bc19780f7094608a62d84c0da13ccf89995b2a32f0bbedb93ea8a7543e8fdffefa1c89e6f50b8427e04ffcceafa13f0097ed961519fbb937edff884566319fd06548e5fd25de4ede9403c7bd30f7cb63b8e2eda9cd38ab9f6611f2e33317b90b0c43d20accd2c271a4cd327521901417e4c4bce8dabad5487d4a01ff65a8c8c6df3d08e7d1c8fa46cbd2c8491a587724af01171c83d7b1090b561e9467645805837530c711feb978a46e3bebdf737fac46508ba1c9b0aa140ec1dd0539cc7a86d037bddebf700806da84b28e993dc5d61da68c6d6291cd68813ac1aa2d56f79b2f0dc0421c813071a2bca6a280afd1f602c918ece078d2f1d8db965d60b45634c5693b40fd2cb9a70fb2bf3f0f962c334ffdf571a9877a4a4a87745477ebc7e58cc72b51d4b599f5fb9a288a4ac7452772ec01e321b6a0dddf57787b6862e427cf4693a6180214a62a3ceb80421c6508311eb0d09a11f8045e4e4128a6c6c1869c5fe394b63505490e2e852823a82d0bf943426bbdbe2306c3ced957027684504cec20214e92c13a2caecc04dc23c4a92bd8e6d384656addeb864452c1cd0202e590a8efc2c1d894f8b2e9af9ea40d4642a1ee4beb02c2592d196cdbaa05829380867a6d425561342768e8952ac291d6267bc3ecdb8f94cf8ac92e377842b51b73334c381b400d43c578c636394de5efbf35ed3b85d7a5fa2e0570b05c9882fcc5564be25a2272f3abec690160e04b76d0caaee5d69a8418c32dae980f70291d96d9e4ad2854ff1b0acecfa09edc907804e79f69473564835a5fecdd8bc2dc7e4cfd85c1aee61052bb985d6d561f01f20b3988a34f0f6f2624e43958ada5e063a71150b3dd2269022d3d9407e1cb9ea53699e4ae62caa8eb4196ab2342ea063a4f82189df77ca929c5ed4b6955f731553a645a6aabc1d487595a011d00083737c1d82f0f59612d5848e62da3686f37d5ee52db70c7aa19d93e6fb3fc091da49b1cad3b881e69f92342bd39d16eaa0ea14d7513729e24ac45b82a936341816399524b65f89e6058046e990c64ebf229ecc7cd7fc62dd9263d5860ee00fd63960d7b346cda9d1f7a62ae8665d914169373462d7241c41953cfa67f1f93fcb52322ec8583345f616db84306aa3b6383105536ae6a646db9f0338de2300310c8629dd6b935072d755f1d154fd942881d056ceb23bd1cbc2ef3a65dd174e954f067bf9d1ec9c4c15eb2015324650859ed3b591e8e2047b2a8fc397e2289a17da6e01f28f354ed18e6251bee410a17c2d6f21b41d02cbc7f3b6c87bee50446f3b1585691ce992cad46581ae3bbbda44e4dcece9aa79ea8d84def18f81070d3c3c2529bf6c7f1f0135c6e822af933daa0f28c5dd2d144a149e09a01b9f7207f0e6c4b7c502da98849cc41ce1cfc27183e5ce4fdc6ffa7b4b15698403b0b3a4bfdafe60e7a147d0a31af4f528001b7d0dc6b804f030a7ddcd2bcda1d58f9971b678fc662f701b07ef703c791f0e281a7c3f968cfa3e3a19a38b68d1923bffe617597eac9985cd590a224da8810cbc051982859cdf424e24d23dd0f553e0491c0e42f9847097a02f3463c40cd87949a110e28c405269046e3b0e15e2d37be26ef910648bd73172b3e6010929842f1a6d8a947d9e6bc62debd074090341a7291cb7671b4c33aabc222b0d04ff66de1880f9748ea100f9ae996bb6d824d1ab0913037f5e825494a223052467a6cf5c1d07213fa9521f25642ed206bce58c14a9ae50d4816789debcd2a2ef4945fb360a24261dc652e9d15b76d620c14a26b23fe4a4364bc78c2b8d3669c7744051b50424461abb5e4bf5e8cabdea37fcd9f23075800cb7c30f411d4415b906e77a6e813197168976ef88b3135aa1a8db13201721df6419af3de0c6922414f03a308952439ce3005765820c25032c029d9b42e3be72e6e6a8ee67cf1076c7f60104fbad69d63b5e102928dc50f842e191d3de8381f304a9ae623d5d3b41e6326b6c453fe5bc041ca64babb8d158e7d6060b92850f4351ca94822262d15ed029d1f7058723d7650c9506153e81c9c3d24ba4daa7e122a9f6b382e927e7c6d176246ef266f9a45212f2789a632126bb646355f78150dad0ea60a179a6d15495378ec0ab7a70431e2cd747642dc5927c73acae4dad1de918e7675568eeb8c4283ee01c275463aedc5979ddf88e2685463521de072532917d66813da23f1aa217f2142073c8d2ec7aa34bd6533aea37750b2322bc4a28696eb3031b86f51047febfd6c2c7474bf9cc1a104e77343279731f85493354acdaa640295f2605271f3e4b01a52693a5fcd56e276af779a36af4b724f3cd0be6481150724647ab0f428bf34ce6d8e1a5d2eeb4f0f0258f7cf42fa808f6acf2550dab1fe9f3418d3460c7729a9327197f2512230c97b9a62af26cc2bafe52293e9641d21ad56fd46953cd782845585ac298c05310fed85320c826fb66e365674753e1a1038ede69c0947926fa61fd6a3450206c8e937fa8c89b2e78cfee00866bdee15647d68e462b76216f956666566af3cba81cbfbc850f824d287e8aa9a16e46a61e888733a236f3634e63fc6e06fd2977e2cd8c83d117acc6b48f35a3c7dd54740efff4c1919e7c00682f5cb70836abb10eb4eeac61dfe4884aef929464376e082c88140210bfee00c6d64164fcf5666697382e0f716aa7632e6b53aa5ae99ab3f88935c7d1a3c5efc3f95ddf0d75a28c085c78488ed6fc9e0fe4ed8946dfcab2d173466563d2e8192e2f0cf4ee962d66bc7f03829f45886880c055ff9ee4268bd1bf2d0d88b0576f0ea701e81a122f9e47070390e7d025854d323a3d2dfa5f9c19923ca68fd27e5d407ba32a6271a8726b9fa2108c099918aec4746cbac029390dffe7f0568deace66c8809dff6d658b9c364e93f2bb44c260beac6cbff16153361dbe0473bf2063d9b5e0b14fc91e70189dddc852efbbd7f24ecfdf7ba7708c14844b1cf8b3a802a5b117138e80d6ea822ab09cb48204f724c36746616f4898274af31dc78211319277b835f82cda3e4dc3335b80099ca7523ea9f01442e16eff60f623f8d59b4008798b77801ccd06d7f8b3c130f2636df76ab24271f7fe6f0c467ab51d181fb9e997bb1fb864975bd4ad1f78984b0b49606d5870dec37b861fbef7a810f0ee125e5f0e76ecac87181c35235881ba31f6204631aa7366b6ab7e55abd494dc79bbe6c1996c4578f346f13bb2d1953db448acf5b223d298bee71e3cab30b7243d51f168efe75031d7095365fdb3102920e61830a358b6753d9bd792e7ff05486d9ea443e6d55ba8b5ee0ada26368afa9e2cdf997d540d5bb3e43c3048bd05841805fbc2c80d16d68f7dc74c1716286489da86dc8b739e8867f3b20f3dda1763b4a73ef9d8f8b2e81b5e7357ae47f0c6cc0d4cdf137b8fc6baaddae817daa880337b8d61f4290f09e6ad9c00d87e14f771439b8a6110668312e691a151f76932cf9ed722f07250e85a3b37363f7027c6c83a21db15131656197f6b7ec6656262ca5a4dcdf9ca190bb8bff377819cf060be2e77b85f1af9f5b067db39c4f9b93463f3984772a52537a98b31a2a21e7ef849d0683157c5deccfc4899b2cbee79b042df05116ee0ef72be14f643d32dc04f5ea93dc84a81390c4d0d8e9dd5227bce3288e6d0fff2dfde6df40176433718aff944ab24d4a68b2c641417665b5c7f98ebe758441c96781dd4c78003766a373e1171e4e8556337ed6550f41c8c17c6e5fedac6c87cf957533433defce9fdaf0be64a976a527ca7aa3b3115373d34c219aaa97b5d060acbcdaf77b4f0f45ddc7988d5891cf52509d11bb9ad4c9f7f2e4ecf7b7127b3fa4c469038b35e7d660fb482a9a5f7e65aef3c42d33e74040a8f3c14d0a3410daca0f5c8b08057412f84729c8bae9822453ed87c884ab9d9402236604c877049fce9e4c364e98b527da2d3ce6d64dfb65614fafb21375a0e8623313a38de54e2eca8d7af5f5fb7445a4683178968be4a3c2e95f4f90193cb861589058a9fa529ad5c83530c14973f40f2d4150807b435ca80c5ac94e71aae2911c97352cca7f2736f882de747a2aefb97d855e3766751a16f4fe9350df5fbf43c94e4e4f0811508f1ada44e5852680121dc8ab4e532ca99934f490b4a68df9cbf143a2ad96554c83624197539907a586e020da5efcdfaa6777067aac1f02032f840ba8281929b0d5663b67c031406517c89126317970cf6c3a339e754df2a454fffa8fce86577151eef4532988f88f902960103b9029139d1717b6455d17ded00be39773c4b6ae8f6b6ee61bbbdccd87d2c3f061cd6f8502330091ff0015a619e5677d5ac364de0fbc594b45da55adb4db1f5c95c548bebe5c26352820e8beeb9fb2496718784b20a2aa58d93e59355dd17beba8613a87f1b434bf37f1fbc9986d33334649933f15765bb58be9c4a6218d67f61a8df4df6e250bdb3d10457499ec42ab1451e6a6688a452eae2a4a25b377eabf9244a1ecb71cd4681b046e33fdf4c61f873b34dc3a092513b9874a2a9c95759def288d9fea0840cca515a3e6376d818e4871ce3c1f4a3a89a1cdeb53512b75252819025575a3472f799a238ba2db725c26f1def6bb6eeb475c328d5f67c29a12a24b36ea2a6c7b0286ef68fb1fcfb1f4d9a0ccc53170f039738cf4461be62b5eae6f61c236ec623069da96b93bc5f01387609e31e535d876733c069955895008bda3ddd8edabd3e9a7474240fc61814d58551329b742cf5cb71a39958f21b2801a52b72cc1a9f3cf16e6f4b761ba85ba4eafddb21a3144f83f328c86454699331c9ad6a279985cb1b2ac96e5b89870a77c1d6a71a53738945917648c3546bdca6cca2c408d12d324b541bcb88a8f34cf523aee3c8a9ac9dbf7f6fce3a6a8a0ceebe958cbb3f129a117267729711067f9a8ac6ff0a620da7799f4843e85abd5bef3b0f8478e22517a74f75e2831dd16c672ed64e90f2a965388c691ffa8cd59394cc9617a5413303aacbfda1c908f26db20b6204fac82add1d0eef388c1389bdce0b3a23488101c8e2ff5dbfcf4db3cec5f18417093396a71b976775724a376dd74bc137dd59abad38852232311aa098838af8c0fb4c92b6aedc573a44a1726e6855041dbd81277f0bcc5b479aec8cb455adf0fe5ef648b3e8e578ae9562b50256a07d4d55a774915d5a87c72add63f73073949908f91eb50203b91eb05a7e33f353e105f05f584154889f05f89de0f20f533b1560b108f682db8ffec14405a937403c16b01784a665e522166f685008b1db7c8295593a8d3557f2e168d26838004881654ce8a939ee37ef8b314f45addb597e3868d336affa379c55c4eb5cd243ed88b3805b622220055144c4418a0ff64b28001a5fd3daf32fa74e1fc5e7ecc8f3495be133e62cf20b1c4669a2839fea60a0c58d45096637f0b154e9120adedb0ba9a297d94cdeeb245cdb3ce938c4a21f05599574fdaa2859fe45d74aa281f1e0470d5a860ad3d44eee2d77217ac33a3c9442f323e31c102312271226c4aed6325b9bc4be497612eea04f9e8ac03f946ea7cc501e9d8f91a0a522be24913325a1839915962ac7ead80b8fed1f0c946ddf5859b5ebcef298e7df35dd12c4bf06f5246e547b84a1e8c11a950871aa1a1c3c0f2c9d021e7be1fa84f60ffc679371b942227fd6451a3a9e0bf1929c50ef894741b2fb5bf513726ebaa796839828dc774603c4ba325f0b1cfb0490dd8c0a975daf84ff33b21ec605be70314bcf3f27305f0a5c3954ce94e1df4519e57e0191bab4fc13a73f35581bb0ad6832327083a0aa2339115b3b2d03bfcc389b037ec7bbbb36ea0a06bc5b08db51f3021fac17b2b938f898ef1723465029d861c6c5e0b34c2ff9ddbd43849997ae9dc0c418ea9a8a79399f20db93c8257661970b6c97be3fea5c2e028f3e7b1adc200495cd29fb5db652568ee2af46f9a423b3d6f725c05af954f9ac4ac770d9c8c570500a9f4c1207bc478eee7dfe898fbf90053838a907de01e80d8fe48c1eb880681e317874f1eb7b70b54eb0cccac2e7b699d889b69d916feae95cc982d50b6a4a7df2a8ab2cabbadcd811e3c7679fdb51a3e77e0e9d621cfa390defc826051d3f7704e418618ed1033dcb49162b1ec463bcbfbfe703fcf48f086027ebcb41a9e335fcc0b209a1776f85676acf1035c4f4777486b658a4603362fd5954f5fe7ccbe3ab6639b8de0e3d443dd46ad0a6255605d40a7cc02745aee6d9bdcee98df0ea91d1deff4998812c7c15491468437480568edb574a3b3e177e99cabbe3d1481cb6f9d2626d2f56bacb0f000e2b91cbd77236ddb3e17bcec7c71ed7fbade2f3d4ab880cce35ae8f35940a99e59e380cc776256bd9766fec8027b9af8d913cda6a3dc12ebe8654484ccc3c9222df70037521a07569e19cdc1b5df032835a94c1f59a91843112c20bb05c1a87eb86c5dddbf38d5e833d3b4d8fb90251593930c019586f0af0ebab126e32881ffc6058cb5cae885a501edb89fe0a28c58098e847a7e1b39fc028eaa293f8c35b33ae6dbf8cb4f229e48c723c34598d679db398cce3c055b36e66bd13108dd071272c489c2c5f4bcc61c2efe17d53e40b83e341efe4b080e158f455dae20779cfff3f777899492edbe2299ba0eb564f593c7316f81c64e8d97d19f4ec76f490ae1071482bbb413d096de65d8a53db2e61b1a601a908a9ec35e0e9bb96e40ce639fe460d5c9c83c686a7908ac93cb918b09e508e0747d90362a3c260ced53b8d92fcf1f89a583af3abd994ba509b8883ce93b14d07af0cacc731a776f509654873a3ce9f3c30c085d8c9266a3280cc49ac97f11a36885e573b0418b74663caefdaa01c01eac139ffd5e326ab40be076c3871765ec0a1fd14358ff90bfe4d9e18fcb9eaee14673b650d1588296af3cab1a404c93a3a1113c457e5e64224cf968d68cc6f814d23019a977dc7ebb26baccc9ad9b307a4e1ddff7c1c3c6cc59080b6f7ae93d5d1f6c6bba752bbb94d9b0427a4f50ea296be223ff0b13e60c21bf32edb4b37456d9c1cb260c26089d1ee4a34b96756599ae88d92531d848d86f8491a787401e6edd7b57e47732fa0f86ac5cd00b143b3967c61e1c20cf9a0f49f8f86a68a7fdb9119bfd191c6d1bbefb6d6d39febe9afbd53fdb600c94c2b22bfe57760176222e87b3713dcd430cbab4bb19a5d3f9db8bee0f9db061123097c11c08aa387bd11a8a35e1c43c4767509129ddf1a9b2c141a5c5119f9533b5dfc020e642acd8e2c4d959ed2998576a018cc1b8cc2f8d8d86c1614b7f8e5de7f6ab6c8b1fc9e01d24ed7df3f896b1598f734de64e52f92934fe590ce46a83f500ac0a1316d7def6af6d6da0ec9bf0637d69949717205b383e30c448f19f63fc2b6abf02ad346d595b58268e3ab5bdecbbd23d20e086cbd3eade3d5d9c090ff416e4efd344a1be2cfc6c13b133db3e21fa170aee0ddd64d3ff888b1d810942913e3c0b6a7ed6ab13d6c47f54e6ef08337ee6013ceea3a52c0448c3e124d465717de2802ecd705005b4f57b7e3b095d68fa7fc7f26e5e76c54dc444e45bfbb7c3afb0437eef7c276aab0704c0955fdb61e499a80526b2dabf2303554113e98b21070e72675af31fa3ea477953e22deb84ea3c3c20d47708a13f7ea75d7de2a174a6e5dfe003335ecc849e7b1246966eda1d575c29c25318706add39539ea99587b5469f67568095589024506a6cac107e6cc6a3f3c0f5d19aa224c118930dd0893ad9aacfd62385c97c39eea519d2f0e551923209c9a41274c81182de03b3ea853f529bfa7ee112b89cec5750290cbde016ee67407f62b2b19518804a418fe157d04a8f75d970428ba6a40d0de8f8d5136e57750d23b021a2cf74d800b26f987d4086ab26bf23bc54d0ffdd81de1554ed849522d22a36084c253af18717e06d15416dc148ee65a65cfb6544629c7578324efd4312a1380365fc848546caad1845da736682e068064954449fdc1ed3ada6434cece584efcf277bf017f8144a28b7ff576954b07d81c37022bd3f8a4da68746a1a43c92a997701465a25a25504070b6d844a56285e73a83c25e6fd93097f27634f763a16e0113d6bb523013da526af29c3a8126302918be632ea6efe269b312a4cbc2bd3bb6a9f3b60b56a58dd0b52a07d93856e29200f012692b0373394f6e1fc70e6ccd2f7ac9a5862943ba083ced5e2d2e3d73fab763454d5f3d9d2ec2edda1a8aef85c190a6270b24827748771dbf609e652d7b21edfdd6acd97087a4bd62edd6a8539c17f6bc859e374229c59b91cb40dab581443d21d8fdf509e4a5e9e2fa1d1ba091f1bcd05afcce77cd0eab394b22deb8a0c7ba2350d13ebb9c7e6a7d8ab1f20fd3dc701e1dc99ce709d7c5546722af262701637e4929143fcb2ced91ee2dc89194ac2f89b786d67d537bd81b9784124abea882afc631be23563d984be9b03e7c520e61d20b15024fcb2ad15d5c82be3d7e82b7eca782d538ddea85c7736774fd1204c229178c0035302afcfe50af0daf39dead90729e15123efc9f575804a54cd7e952cc6783a13185578e16b46c7bcedb463f559990e80ed160439f6ad96a676757fa4d6524b3f4bf3d60907151183371ddc53687b61a2e409bbca8b78a505fb875eb3280a63ed4fd9b47cd525bc71ea57b89d23edfdca66ccc20d12a8d820d8513618f159728b570ca856cf1fa9df4ae96982b03bd2e26c287da74c444ad69dd134f61b60d4cf54db8f6a01d3c1142efe493a94b6d7fb2527f8435e7cca1195c4a082bd48d35a9e1d8573f5df0d9934c5a19a5b9b6a537b4537b57b54843adcd408ac50e64efb08bbfff67aa39e52093d0f0acd75172b07e6537dbefc58d17ee94bc9deaeabe6a8ba5830169db730a993f3e84f3523d3f02497c8f0b23b11e584a146636c2befa706d8f80ae607aab42dbf3c17218b0a15a6c155313cc43085fb8759596e19406cd1e5ad08a47a193ffa0e9aff40f95974bc2bc9e3b4bb674b6f21e7da3d3a4239ae71389832eaa1e06bf0438e8133b654373620b772b164a89dd58101297f249bcdc7f2a575541c37e4db9c9fb2578ae2052dcb266cf708f3fe9544478126cad84f91e6028640900787efee61a05992be4273b491ee139e090f814ce7a0dd680c62e7ebc36d537ec196538900c0b9a8b5fe379d555698257f40ae05b069358e182d8cc76da4a769a376f3d3aedcd2e9b0dc49922a587b123d0319f052e9171d49acfcc5e8a0b7db22602579bfe378eb8ed53a3538e3afc9963b2827e0484da03668f8dacb000a51cf05b67b5c5e4a6e2c50cc87e0fd4c4d083dac9f8de85fc67fd50fe9bda4148ee99e10a327a50ad2131e0ad5d10b6ab933c327427d4951a6a1658b2851de9bc156b69558a2b720e4a6de45fb9bca6152d7fc3d19bc8079c20829a4ac0fd982f9cc7cfe37eb21d35926beb1173eff91892324a2b3c4876d0dea92ea03e804a94208dc4f82ec8669987fe9e0e5ea82fd7c5f3f72ba89f50274291d37843a6f6102734db6a26f9a40c9531323899f5aa6231015f62a1c8b3ef4946b6e7c8f31c3b958a0d697f7080cdf8b43e66a69980521501ac57041bb18b85bd59c4da6926e8aef5d1ffd468437fe3606f2fd7e7ecd3053889f8407db019da436768b848bba1a786e67653e5b3c6cb192c31ed9d301d67e5ca1cc1fa899d0b218b4e914eca045ed94c6a302aaf42bb90b91d69542cc2cb6d5ca9c555873eebcf2bc4d5aa2bba3b8db9973646b2e8801f57890e6cdb31df00719dd914330438e9e90412b563dcd3f62bc84a88205c5928ae9b4c90fbc935e74f03b27618fdca44b6ac52dda402273793cdffac724d3c1ddfec9e6d1300916386a0401b62328f9b3354d7d4bb421c41370a75b19988b4362f7fadc05a1a6ef44c81b8526af3b86a2e50eefec9accf7575d7edf45b9533c687bd464b85c6ce94cd8f738a7e845fa4070a6a05dab87d8f4ce13802a8eb0403ef4d6cd3c975334af86953fda3d8cc4f633c04f522db028eb95a9583c146ea73f68f8cf1a0013bfb0317785e440d7075060ff2ba50dfc44c43022c5412b5d12b8438272f30dc1e62320d559b7dcfbb1debb71d27eb5c05e2cb28fc764859fcc610dfa19a18a4f3099cf9ecdc673b78830e167c437e99e6ffd58abbc3ba616133a823ba43300b1c6db685cbe9ca51a13e95b98db262dd13ab6a2ce58ff9cbb75d556fc857c4dd75a74019ed0128786973cf043e2e4ff32f8ef2c7a01f8c57d738d0f56b2a7f749eed41affa00158c4b22462fe1f2049db445385e512f3789514ce6e6bda8fe6c88e8c2848bde959f1193123282ae3999e5232d8ebf92788fa213ab3850a3cc4715a358b6e6079d27bf2a00ba9564b5992626dad9b1294857dcb6b6c9029642c858d9b73e1ada0e27b72772badc88bb0ab2cf073176bd716ba73b40d1e72f6bb3caa7eff8b1efa07b5a676f34f8cafe27b205ff6198597d79b8c47d6dc5555eb1739b29848efe454fff6d8dbc66710f8e6838711c143fb3f1ad705001ef05a6544cea1810cc16f1251d94c4fe8bcca32eaaf84455ad7a73eacef70aa7a7c0df09a6f0997fcf9e75762b02208a3ea744b4488d04511001f0de44ee747b2461ee09efc403d26d145ca26406389c6931152193d6fd2fe41d42c29e117ce2b7c2937d9b2a4cd79c109b983047952778dfb291fbf726e0b0d80865a0182f310e936b204381c140eb9d6b5af32f1808c9f2ed73d531a6deecd5250ce93644c6e2140b44d66e17cc1c20f2db2d4a1780d6a3636099b72bbeb9b6bb4cfde9e894705d1d807f7dc162dd75421ee73279e1cc8abf666312bb5302cdf223e1badd98551b80d78efc5f5c2be5915737f8a453de478030c7daf0870695763bba97678dc4f374f6615f4c3b6b604d5372de38a702353ea4de94004f84ba6fdcc187004ba0b71e229b5494b5611db2dca4edf4b1891e3e0f552fdb4f46b78d436077ea6d317cbc5ae9be2ec1eeb195ef82c567a92a80f2991c96461d6504809c0a91e5f91c2da0dc3e1a20ea3da05f81efd24f3f13b2e47e3f410b098da915805534133ae291664414303289cbbc951a245099373003b7066f9766af73725651bba6f8747bed2a4df3d4b74d60d1528be081fe3ea6c4b789be43a5e37444ad243a11420317e04fdcc12fb019b32ab800d21c13c724428bfcef9a5cc8bf8f74efd167eeb465e122be404c809da37ce072e0628b63db79f99ea9ae74813f979d2c7fc6597f7e2211a24ac217192b6ec6b1476b116f713debeded082b0825c903e58fa0f03fae8bfe33fdd29bb6e690810978b05b9ec15ec70ea98707b7ef4bc08c6b70cb49d4a1c02dfbb3d655274927bf7b17e9b3c5c78e11d62d6875adedf99257029d9136eee5c92c9a2474c1ef00edd74964e0979467ac42756e0d481e214c6d2e035f9734a6f1432b0d46fa070dce20dd67d9c091f802bff528ddd958f9fda5282906fb7662cecd6d767de074e198207ae9308be403c9c1637112e18117165ab52a2e14415ace5b911f94a06e798913d35059e0929730c9b6e1bfb21a33560daf5d7e08e4603a4ccf41c5531dec44391ce92961b47abb3effbec2f5a6da69e3ab6b3f624a45f1ffcd12d2f0e8e86a75038e3707095dd4482e912af4c56116fc955ec279d461da54f1b0b06e8bf627e4c245eaff27f5c235c8e2cb4b13d6438b86b0b801a593adc86f3f9805d02e05a0315bbf9084cd4afd31f1dad8d888b960429f822a8ba0861d85ab878f56481eb2c783358c4c272c8c7e5fb0a52b1c0e07569012661856dadb27430c66eaf4860bf7a98e09b3d232952a2c0ce51f363bd13629ea85b13c0236781a246cc728124775c668db91b1f2cec575bd6b0fa9be2ec44718d90b6c5473b126e0ea9d42f5880c185f7fe8f1da0bfa6d2c6b013ba71d2028db619e22ef0dbc5b81800f854e4dc57c2852951178eb95f0ff37a79974e2a1f6f775e8b20180b3267650f2a82783105ece5402918ad34b7c7f5277501f09d3fa7f89b3a8e45c81a6fdafce70876a918a1f317a41c79d99aa3fb4d6795c8ffc62dce112883743153e7f9856da524cd154e29f6975fe2902561ea27d665c1f935b7031365d624cd5df57291c6c9ee23d0a2a11e0a042c2c8c35e4979bb8dd663780640fa4d4b22c3ccb50266b3c1e46eb01d03aef60da10813dbef1867aaadfafb2ac50968180212dfbb95f63eaa0abe5b38961dc1f47e369ac46de2baedde60ecb8f110ec36cf0e011546e9cdf57b58543b24e08cbd4816f61438b59bb31f360f66565033aa260ced17544db2570a5538ad1f27190dd3767e74d27f155a664fac63c246bb5e8dbf247a14d22df3f30f2925bc6d37e43f1c28a325dc220c21b837b42a69ac9893ca482fe95df709ef7f77366b76644281cdc928aee21f7fcf13ac72416fc16bbe4573d0148e1a6e52013f1725e9def105d59652f419569b99b9219344728016c9db31f37ca02082793090abb13316fc2bc8a31b8aae531916ea89f99ce103133f7ca918147dd4ab79a830a9f67cb629aeb0f367c29a89b9ec9b5e8385f5f75e81d0e96ce89f44ca2cbe562eae5b6e847d5fbaef47c03852b61dab96dfdbbaa238a82918ba955ded61c4145b2f9774a7f97ff971fe0edcf1616f0415de735937c02b12071bd1f54064af94b1e8a2593061c22a0b501a56471a06a66f25c9eca12ed7f695f86529b9c6618c48618f4aab33ec336237c8223fc5a843c16fda71fc24c93b41241df5b22fc2e4d56470e165d5eb3d426422f2d47e83bee9fe656695ad1af93f047d7424ceba8f89144c1be8d13d21d5b74500617f1a95f951287faa31a32440bdaf8a261b191695b77c8ccef85b9c65948089b9090a98e1dd7985c4140eb08c04e24ea9bd9557d7b56e08a0f1ae522afb2c3e40d19fb5c70721da2182fa4bfa173c9d56722dc8f43d8252af4dccb7112f5ad3a45abe9b140deae9dbde09cc3648ec603adb29c4b3c4eba09fbfb0f90c698e36d503135f3808e35cd6d6515cb50929d17889a2997a84324c4d52cabb793defceb383b53e40d8ea691725924a5841bcf53c7cb38a3d8e53420c54d672c78a29dc6ddebc9596d1033a9ff321d3f6781bb472373d6d50d923f6583984443ad51daf744c9fff5a684bc11c421635694f09cda9f718cae67ce29e465e8ea4a24d6617419426a05afe00ff5b59412769ebe86f164c608bcf0c1d4edc56d3b8ae13c72111be689018d0915cdfa1e91f1ba9b104cab70602420127077c1418e4b18ae8cf5dda1fd05cef6e32c259020da95286676c48ac1b1613d0c0a26d1474fc5bedc66f67d79662d82ca61de99bfe252f3ec87b7cd0c38f613ee6472cfebaab1d4f2949665b249d12f7b38df7d5e00ddccc53047bba0c8c19efd27e9f544608b02aed7456d2e6451df2a71aeb82aa7c05ffef599bcf16a9dacd4ffe6dbe6dd2818033707000f72cda6856b3504568f372447f96610be92fe9eeb0283e4648d6a05a7051811113a37a54a2b488755caca9c2a8e47054903af434bf96e1f8c63ddaeea2708fe4076d5bf10b25ee6e465d82ea257a86f9fc17de594bd0d701f807e707e0268f5d8cf9acc78918d358310180bab328a33e61b7f5da30fefb1e0dbbbd8e57617e3793b93286c380c14d86b7b3fedecfd82a8f2d55ddf3e52bf622bbc9a33231cc17191345cb24220bc013d21163b9a7eabc1619e1e277265df7189d273d2c24f986feaf620f28d9ea42d5a8a0e9927aaddf7adfa0710f19fc59a63ed46af5ccf929b2d0c988a1494c4bc56580e2173cbda740a366f4dc61e7b70dcf9d7c1c55b4fddeeb0ef7d1ffe7f1f4428ce043ffe3dd789cf213e705a6f0f42f00bd2d7630d6f84412ed89e6ebd4fb9aa1bdf253691f2b7f339a03afda19c667d4d5babde9b0156d9a9608e45a68fd5700358d9b01e758ae98b26164774e2f4c89844908d3bdd6b604f6bb14b0ad8e3c01dc55079ff306f9e95f533e34eff480e5b890023a031edc9252450e0b6c6a39013716eb43f20361eeb1fdd2bb266192b608eb3a848ead62c0f57ee5ceb747ddc465b6dffab947ab15026dab778f824625797ef4aa46c0101bc3b5e1629e97d64c6c88ad5e902f6bc8e6902d3793a71c39a21f07cc763bc47bea67f0de421aec87cc4d89176d788a0d31142bf02f7fd170b3f8feaa1f46532d67ea8dda89981ee4a7f2b65f0612a29dc35f688fb8fe64f5a808bf6159240d7b20383a08903d73faec8c1d2375ee6ca476324de26e3ca605c9bbffa57d69377659702a2e817e1a44eae73e013ca6cff281855a34e3bf884f84a49e93cc02eba54a61c6f49883376cddd83c58e87e5c33f28bc4e1546f28600ea87abe4df37ae803ff1e89c2ef64daf3892de1087b42c8718e849ee32422951ea31eb8153af0b6c200b2d255fbc5b37126b3ce21d1d8e00d3e01397eaf4eb2cdf2138bfe6146a89264b01c3d17da9c27c4149fb4d4ff8438e2de889116cb83516fd74e3294ca1e06c9abe816d23341a055b988d21d0a2cf47afdeccc60249b53cd78882f6afe1cc7d42c5dcf7939b3630fae389adca4e05a5eac7cdd2f51526f1f1b2e8c2a0efdd5c5b924ac5d4c9134396a2b0458f3991146d0a9adf3f2ae91adde8598c634ec349bc98407812a71535dfab9fe8f3c8f31e4e1794faa824bcf9783e05e3f07b3d5f336efcf9e7872235dbdb1d2305f2a6e68c62539dcbaa64a32f69985f79527f3330d03b7f01f8d82fc968ff841824b22376c0232bb9e40d0ca69703aaab40d864ed0e4f173e8d0ac7fd08d169af4bca0d9a2755a4ada4f0f2ef23ad9bb6aa72c4e3651fe38bb96a72594aba113a6e31ec3acb2b38ca903de96b850db75de84c9e0f9d4ff296537ef78dd5d25fd088e1c12f62d9a45945e40fa4522456fcdea7b0f79c26a950c20e17bf35e8469f3bedb071fad01db9d24b4cb3c372cc51a74bf592ef91e1a1b2bcbed73b8442b6e16d9298b0d1ec6fd3c415c19c9c0915d8c498873db7e46d16a968e1bc52f09abb8b8106a7bb41d91cb691e6a8c77988f9eff3de71b9ee537ceed3df4e70c4ccbfed459a1ea60272dc4565009bf21d653127a1d875e866fc23dbbd242edfb9c765c1af9dad0b569584ef1b2f484f3a50e59ddba5153c43195cb231e5548979aceb64acb051ea1c7cb4414eeac831e05abd141f62ed7f7af47a0df7f58e25f22704769c05de68fcce8a227148f0ea5d6016969d163b9af24b063d9ee15d7ca24f75993682be158b86306b58646a041dc1ca6ab29211543036d5ed6b2632ef03deee8d5f47d0d289e6bc419c635d176e3ec55a5626a8f758e768873ab34ce083e9fee166b9fbc34a529d75874d8e108e1609e94c18bb0fd1e4a1f4baea78b619aa0545466031311972cb13cf6b422d855c64039e83c41b6ed7e456f952a2bd61c9bfad9e74a73921778a622e2f60b9f2c3632a7054690a47b0f4312d4345fb64ff6ae3a56b4e08199b1e37c26b837b83854e7e8914b3608de38104ae773261e6e8dbf91d3f61fead9b965e6a28fe50107797568f0407895227943443e2609abb8dea64105531916f5dbacebec2925bd4304d1e2ad999a808f4fb059ce1bce1decce2af9b8d9adbaca0b30886f5c8f630c970b51018e7a220576b2195285f948d834e87680f5547cc8b69f11ad0fef84da044de159de386c2e5b53eabb71894e64fbc53e804dce194c45a898e1cdc62faaafb5f3fb471d6cc772e3ffe46e9f26a608564c2a2922d3b084913f35f3c902577c56b651b7c677484263530d99e9944267e3e3d1e7ddd500cbe6314c6d13fc14ef7210acdc8cd4355d0c4f7017ec99a716c50e7d975ffd830a1d003e163ebf4bb413056b944ed0d694f108b72cc0be899bc81a431b6cfc717ff9a38483951720644fad657c8ba3ee9a8f1fd6c2f22e4203a86c09c9dbbbe0dca99683e86fadbd0ccbf9a722578e90585fbd2fd4b708f0739e5fb67aa32a1d2f948376499a470ad8eb9fd1974d8b093acdf6b3ebaeb249531b145f56bcb0cfbdafe8d3ef07405adc67b38f9087603dcba249996b383f936f2a5df7b44bc373c07ebed2eb6ac56c40571341aece6e8b8847ae3db3b9e39bf7be47a65276d4c343ce0fe51b6a293b6fe597d6df3237718f9e4a862a926a48987beca23d1cbee0b7133503ba04de6386df5bc1b4818dcf62cd2e704f069251d58be2ec4a877619cdb86fc03a884c5ad55abcc9732d5f7db9c709a9e930d9701caf3057db832417a56c3b5ad3bed531173002677cfad2befaf6a2f137822db294674edae26e5835f37f902980104b9029339beee83474739dc6bd824bada97e3288604f93a6f3d8770e677594d90498ae030a65f55c756d0fc9962ad7fab1208467d1bb0b63ae50dadcfd42e93ff14b57265fb43c9b789b1facd3aa70962e393435ca7dd60d23f035789e12d2c09afb9a2d0fd84f8f060934716aac3e120fc369a6b5bd931e850a73bbea1d0f9ad94d0fa4b8bc2ab8bf4f30cb95d28bca7c48c20253e2be84e693249be42368ee20a9de60ecab50b5e511f7712a628b0afdec1909c1b994905d2ee721b5eea977afa550aae086be5544e92d733a226b0c93b8de69524fb315d8919084a72971d3c7fcae1c11c748f944c09be55722313d68f9697c133f87e62d98e3d98f767b6d6d871c289ca4fac6cf217562648359e8aa0b11aeb1e3f870a4f5d5ef4318ff7b730240ec158e8d3895af307468dbee7c2a5ea6c13222cd14a52b4444212573117720aab2ff055146293d64b938e56be9d88b54da6ddc653ea83910f9dee4db23e5d243d5c29d0fa8b271150d1a4ccc57bc4f54711ddbd2e6c8cb02d762503776a384d5f89c0d1cb75dfaefe73009156b14c00931115699685369dbbb324820d84bce42865975d724e7cb825d882a74d9a437bddf5a05722a93dd76922337c79a1e93488599f3da8da7bea7521518c214cac7db3c81e7f0a80a09bbf5a8abfffa0ed50d0c68d79ac46cefbb115e39c58d313d08c721e7a9783b166211072aa6e1a52ae81d97507c886296d31a6a6a6641da9613e945dd66790f4d1380c1b8b59debad2a4426a3a1fd422d296bd4ae2aaf84191aa22c7d96a0e67bde99a6921328c9bd0975b09e12e4393599eabde87e7b1881c36033d3a8527a512ba60aeb0433f65eaf0a176481b78a1c062272997a3307925527f961507aa69ccd7aa31172ae7086b79f8285a39714af3a84b194febea1384c09e49c8f91eb50204b91eb0a7412585f0175929195ac5d933eb5fda1db31c845836d60ea6c9e05869bf6e3cf14ec4564707c927657b1a403bc9cc63c6545e202e305277e0a2223a45cfaccedc8f846e026a57e84289d2c5edb19b8dd60acbce3812001916851f30e86a7db5c520618bcb2e73b8fd1dd9a0be9be49c9b1496f4361408a4dbc066e76e7f0517032de15d33d4a800c4789e9e8ea71af019b2a3be54f9fa867bccabac900a13641aea385d4ccf5b72f399f0840aec265f34290d7eb7b7272a6803da31f75b9b3e29e06fa8e711f0ca7efb9204391fa2c5c2d415208c6a8f2b02ca3007d65d62456304c941107b343c0ac89b7d806efb8e65725255f53d1a0bfa74c69a7728655320acacb52e9be6882109e49c5b1a78d73bab101394a74a7384b869330c9be7af045d6c3b5d2562285dcf28ee60db63ff23bd448323a3e138cbb877ec9c5d54072c0539be7c3443695dad68741a306bf72fff75bfbb620470872796624a87a7ba50e5aa0dbc1454cdf1993234e0ed3a610965c95e55b658e8a4ef5de3fe39c5fd77a7b8e1101b35a1bcf87e6a1a99a706bd808063ca38ed3dc9e8699ff28a6b1736636fc0bc3fb4136052093a62aa25ad8e0848fb4d2388770b4805d73dcaa24e3aeab9a3321b5ad8daf92c9513d74374c0052a66b67edbfafcd537ce8f0f1ee52231cb3c18686ba9fc1b82869c13b67641974d356d39585975957c86aa5bc4d91d5dc11b72ec0ab17b307a86ab047720030fe30e64fb0080060158be2ab04c65316b626c64b992ce2a0da014bbc151f473420717e092d940da5eac78921d63c18fd45ae78ba2ac8514ad43c28973e9af9b2fe581190e4a4787d0cb86af58ed319f51855b803420084e2674d9c036c5c60b004c5eb247f4185eff3a965838d30dce6502f3a4ccd26948e1839acc47b5e49627aec9eb86bce5ac8cb10c64e5fed393ab100961c435cbb62100454431b0fca464690a53effc08012c78ef0e1089c695b05e27262b5c73cea2ea7670a7a9a7d5f0a0ee6fdf032dd78dcf8add0534262a524f94ac5618eb23f58116e90511c0677308b02cf8bfd884bceda92db0a5df85f82ede5ca9ba534a0ab313c767f9161ba223ae31c4a7c79d8b57389d194c774fedb54b8056024c075d5174b5deca8335755cc4a60610d7ce301ef2094245a72aae1513fb0818aaf1cd2080d017f13d0a6bd368ec623f654f096e0188f6cbc6e2f1978a8a294fb07e6d92189ebe111a93bc009a94ca82ac20f334120b53124616aff17c151ef2b320cc68d6467049875f4067ef2063720f5d3143bbdac654b01b5034502bf76dccc70cc9ec0b9221c66068339e14bd42f66144e0f270941363cc57223f8fc9c4a78229698ac99020cc3466dc029dfc9a3811e26b496599cb99df03a8cffa880054028e62ed233d26796d8151ab78922f9f4f91efcdf45d920b1cd3ccc35a7ac03e2f35e8ab735adb30cec39725b9214e105ac12d7b796a4653ed7267247fda230ab2622d781febb9c932e4f8c77f4c6171030a04a8c160ac8ce6526766f0cac780739f172a3dab80c435e5791f48f14d2a3f5f8047d408a33e63b57fe6e0429f1f6d176fe615abde13034ffb742bfe9ef6eca70f46ece365a3a1a7b50ff65e8b39a36b263c71eb5595d4f1039f4f7baeb7a520269caeb59d59003746c29aec015156f0816f82f50aa8a237f56a0ec070c0bbd641285e96c34230de1668b1e1e0a3ab07457b5a39b853c7087855c2182e39cd58c6c16d8b65cba83f72509c1d0c7dc1b83c6de92efb075079b0d22c0d5c66a13eb9b5752a6233be607363b5a8f02469fbe1c6242fada0c7687a56f42d8b547183d8f7c5e60e2c72b78f982bd50f322e85fbf1134ac7a952bf72e309189cc81a09d7063a336e489bd96ddbc2f811e0930dbe9b909bc0d306a3375ca9dc7cade97ef576b73ca693e9d96d13bc5fa12561ddf44aadae8b1913cf3d50c1f5169d3ae63c52691323ecadf28df36c547b95a068b68a8f70ce219ff53953b4569b2fa90b97e41bec55e5a232a28692943baeeef6401da071761ecc92e8df66396326e0776d5e3154102a34aba9476d43897f93552f7b96dec341b8fe83d64cfa82c398a1d808e712e9034834b62a016d77403aa22c7899f1b648e2fa360ac9a64a4f2100fa859dcb6ca260c442e190692463598bbff65ec7ef8d52f4f153ba57c1010b5f5f951ba361a8e23de9d92922a12667ae0c6fd2fb2077f524b528c0f5bfa33614f6eed84c6b5190e34f26f773a703f2301e89eaf47ed4b9fb6465aaa0d1caba889502f36a3cc6a418c452e63fb384957feb4e06f1cdb80dc6aab4e29d54ad90780f89a4d880e9ecc9170556ba4012b317dd062b3458ab5c45487a986d1bde390a6abadf727c096c5604ce4fe846f98b6f06f675b0b612c7a2a412e9c3076380be9727c0cc212d886749a26a22d0542d2bc4c75fad1446549de047ab045950826fa9d37103ccdd1afc36fbd288686a1d5b7951f158c7e8875e57ba85770113e0072da3036f7824ffdc7becec524729604f97983f177598d591181f8a4b4da4e102585ff3042f960176b631002c00864e1d757f98f5e1c5d995d58060224193852885b3293c4a4ae6722848d33ebbf2f2aaad93e8cb1c65770464e9f394663fa0ef4ae271c60770a74c3cecba2007e68aa1489aa480e7337d59ede37b0d3989d09b8e00773260a90126b3d6c306452aa2509f9f1d14107a9b200655a9e83444700717893e7b84196536f6814634c63af6b34c96bdf6c7cc69c4860e0ec24ef44448152d7b59ec9176caa311f471f75ddb103b985e39930f857a238a431c820800bcd7cf5a6c4b83e5a81024ada06bbfd1f47b368fe380f359adf098c63dcdcd9e1b789ecffdf9c9b6666d30f9cc0ca833e1a64567e3334e75d26dabff1dcd12ec34601d8a53537b2200ed6d1c87344a0f226dd55c5d116b51a59c91bbe279dd7254d656c8a1a335f895d0de2c3c1892b2e475e3d34ac6a7875bd145e44599405d0e25c27fed7a082d825a7a4c95959c5fc21740a555d5cc0987c0996929c83f758d744a8c313c8e4c3bd2d8d323ade9d8cc0743f5824373627b53be9998763395a114ad4cfc06d9dacf6a0f8bcc73133224ae3c512a474e42d9a532d1811829234e1dd6e8cc85051b9565f1aa37d0fc2b6f6a12cc1533081d3b4c9656c4ed7668d2c243590017387d8a55d3f289138f759901a5a22025d18cb815940768756651d187b03806e44e686fd55632410234b3d3c7dccd713cfff3fc064d4524c03229e9968b51097e49bfed8c97e4db3c020507cee6cf01eb9c612886d9a2c00bd38b4a8fa2f5903d6cad3230bc3e724b62b61e2a223594e3b4777126e6173f6e54dbec1240fdcd79abe8419498c134cb9e4f3ef16aad8b0a06a35f4e4fff6740c25bc3044475f2d275c8bb8bd791357256f4061f9b6f1eaa8b029b173e5440a9b3751df59d45a6f622f54b2f7a1b98c9eba5454332f50c31b415059181b50b21903b6a6a0b77490fd44efdc7e113d609a03c10e297a58cd54e3eff0cbbd89d85d5f3f8a04e9c841fea45a88616461d95a7c9b832f804f9bc1af4f0ab43efe4b113aaf0de758cc8a2949bb469b8da7e80079b337562be08309d440d79fea412d4faa852efa3cb36025c6805415d2ebd4cf63a13abc5ae6fa3f007ec5abe39ea1be94702a2f07ff508792838775ae96ee40779905dafdc58d8c6493a5bbdb5d945c1e340336528904ddc863f368a89442fa43c842db23482ce4eb31ab5f169cac9952cab641cf67012cd253df5c2acd19e9feb2ac7246876820fc87019bbfe587b0878e74596d3497c26ddd2cf3e19dcddb1c801b849a55741f7c4df526e7a1233601c546a3f95ca1a5b4d2d6931502bf9e994944747334efc772f652e41df857036fcf95a2ef048dfa57102a06e78fa0a7d603eb2d2bfc711b26a7d33a23409f590219af144985c049e86263b953fa5a4ba5871d332e4752841be5b2d522ffeb7543208b02343966f61526a43026b75f5a2951adadd32c3daae76b6f295e9887ab11044e9be331ee5f64b67513c01fa57c436577b0d8587aba83bda38ae473791bcdc202382f5ccb54381c009c06043cca72977fe1c3afd60830daceadc844bfe3d3850774ca8a733293b5efa92752c1a4f6b5d9523397c418644080b117865c78f70946ad706dcdf7a0a74167beea13ce535f164143cd3774604b05e4cbcb322a378b89230bf3c923f760559baa1bd4507fa1a9f6a09c118d366ceb8b65ca63f7fac465599ec75ac72b067ed7f3a6a3fc89c112ee7144d8d11e3716eb6ba051b409644f0d4e9da31576fd8290005a2f6ce87558206e6bded2850730faa00ea1564e2a57a1cb20e9401b9e66d4083d0bcd9d9cc6c76fc8ff9d7a3a83d9d458328b6cda1323b245171689053eb5ec5e50bae70abfa65edd18b3bca45de5d4eaa279cf3d9d183c749a14ca582c2d3e95a726023e01b9b0c22b190ea4d9cd319c023d71a772950a208d4f8271d7f149f7ff59a871a13420c21863bc1f7d933ee8fd5bf70d1f132132a6506eee012ede4f643b22914c64fc088ed18bcaae2e49b4532a1f979f3bea33452bf8c50a878df09019a98080f3dbc19936e858c306618c97ec19da04464995d84a5cd8113aa4e34292a8c71d95a7d8deeb8cafd6cf05149923d449217e7cb11f11e7d2fe215b39fa65185ee4c394f14585935c7ba8aa816862c6eb9b4247ea172a4faef699bcfc43ad6a315bbeb706ebff05ee6ab831631af0e985839d849df2c4f920362c704172b00149d4d73dc4df6785f77be721bd719725b8741e2f4a70bf9258cd799fbfb7ae943ea6050704e22d8c3f478264d38461d0526a9f46608c9a6605391157c2d33480f1e3c9b0cd9052e63104e03c7e253f51f9bbce59be1325e78df635ef34378b947e96615ecb46ee26970e75896810d44b786d38891d5f8cda172b521595fac07d33359a18657ea2869df87fbe7560f9d8bbe8a363bcec0947e9db28b27abe394457d1692fa44a2d5e60b7f17d6445840a3244cc7aec8e1773e506fb4f07fe649ca48a0cf61c26580dbd404adcd84bed2810551bb00c0e9e55d7db6124c0fd24b149a76ae578b48f353a200f6cb907c26ddcd99dd3d279ca95f2b5780fd5f799c8e46149e1fb978977da1604ac26877b95e8596fe09287d7f11fd31ecac258ecddcfffc975b8900b59f1543a4842874ca6d7024d98382f99f5571930f9805bed9fde05673325d58b4d93d1738a0450b7ebe53bf346c8399acf9e007116ee03af4eeabd6ca607fffb9b06a298ef435b7b296653c027c896fd36e78ba980186d8d947d5da2db4e8d0277e5acd443381f5b71c59bbd1748eafbb917058f99dc92e28e9e4e587af8ce0fe371602c7a07a78c0a5f2b9bc82a3735f3302a9e617dbc11497e8951f829a1511820246d26e14d0ffaccfed64fed412c4e31186f56bb25930123f6e331cc1343205b2d74345b02ac133f7d003f68ed3d19145156107637848b6abc9a81144819468d0e35993ba56daa2cc7fd026bcef44ffc4ba618d6354906dc8c7dc7e59ae03170902774710d04e7929d536644bbe44311923d5c3ddc9ad677d69231543325e1bc7ce214537d524f2857dabb0218981f3d553463db24621673ec17f1e64d15d938c7934157d768273d2c46c8c5680bc6567bfeca1cd61ce04eeb22feecc0652bf390bdc39e268af7e787ba4873fc3c2842a8b3860c31f995989660be32f0491f5d8ad36dffac9d85e2a11908a20bab45e3871d02987df244e1135415cf538827b04b0ad0165bc6203533ac6da8a0b162ce73d6b22145afaef0447fb55b413b149846cdf0d0e224cd5723309742692080009fd316761615b15099ae1989a1fd3515ec917e3b3e0f2efd11928ff366891d25d1ed9047dbef57c0b7cdebb378e7b19b3d8d0c1ea404afd3701caea53285f4f5bd6f8d79753877a20dd52ef2f8b4863cd9d28debf73c0ebcd0c9d6a67c1873b6f6bd1bf6b6a07acae4922a69c29a5bed53e17b9fd582ae4e1432753a6487829ef4ed5349c268b779c938b1babeb95246a8f1e43a7015e38f52f9d78dc947d4078e51b8881d7c765f76d1ad413e21fb1c670d8fb0d826a05c42f263c6a3668ae5b3e26405a0315f4693535ee157b060f6f10d8ebdb5d7a7f3c3b462095c447fcd7e6e512951eb9fd30e1cef9fb376739aa700a0d190f6bd673608d685b3708614b01bc32fcaba02252ddc5f936e262b3fa390bd6275e35cc6afdba9faf920edc323d25d678a8fa9cc92972099c29f8cbc36f4c3d49ca868aeff94b41ea050e113e0709640de0ebd63eb77f24beeed085cdd7c0d739b33891ee8c314b7bc60aa4fc806fe5d0ee203cd7055f3dcdf1293212dd0d6107be373911769de292065668720a670a070ee9dfd7d62efa32307d4484b040d7924a2ef3092a497495f4c9bbb2d50fc23597a2570feaaba32945159066c69cc89e8cb33440e29803d4b6e16c4e4e8e27d8b0bf1437c379cd45f20624f03aabae8534e8fc640852cbe9f25377e968018e5d1f8d9096a5f054be5d19f119d45e3f804fbc1a49c1dd4d2275b2e3ad65d2892f5face26d02ef27ccb19393a531bfc8c8c0124c3b6cb421ef00724d079348214d7c02c486a7ce3c63b8a58318d9b1dc6b86ce2bc67f72bead6bdf9d3a57f59738348079c357caff94a3255d54cb42872c29b5857e69586b45ea13852fb2b006367052d279d79cb4f84549968d78430c950511b9f527e8f9655eea6c329f19f7547707c0a221606c386504da90196d6879029f2620de0ee071f9cfc8c6c1c5dcbc9d64fba3b6229d7799a30b2e8b7db870531dc14c018ee49f5e6dedcdb38a0735394ef472711e2b2aa329279b59e085f614207231d88945031a9563a939a1892a3cb76fd28dd18c8d332001d4776ce44629aa00c691871e07f95102aac94f25cc025d91566631bb26c738b57eb6ec418b37f13361b70dc278a6572ec17c07699f6c512d1c6d5dcfbb4501d24d8c61413c5ca6bfb6abf49464d7b5b2210439cec09444627de376ee169c1c655e9302990944494c577572d9710a5af131fbc1f51141dfda77eaf4831e8ac12b51914b41961f8b4a36b056e9f867f8031f5f1430fcbf010746584410080ccbcee1dfdeacc7a170914b4c3ac9123d6998b4376442ab7a07f67d1920c31a3b2ecb82fb13c9d21ec80ccb218913ee1c7395fb8aa192070fa6d0186ac2ae868709fef3bca2183f6457dc1621338c245b984268c63ad4ae1c65b8e4f1959875d7de5b05fa8a7ddfdfe10b8cff9b792c6f4896d7f25e9da32589d22a3633c5503f338550de966661ff3164040d6b8400b1522a77a1f3cb52748db30a0189ed5351d33064878020ab9570588ebaf5c624fe7baa65893b7df35c09c85b34378914fee26f3db477d4fc9e8abf23278308128bb70748dd7165eb6b893b70e24c4fd54c98c83b274ea3d89aafbcb4a0ab07f2d027b2e11509466439f792ac368229887402fc5d4ecfdbc1804ccfbf40b929cbc7ea17c4d404c9c2893743b22ed29d9480039fc044f4458a4b9e6a59aaaa348bd8b95cf3ceffbe87232ad00667241436da9350ec11e7aab928891788196d2864e616b89d0c95e52383462a737bc4e121371b1a9e55fa7d5b007a3dcb70670c248bf3ef07c8a94cc9cf4685acd27d0416cf1f248b42e71daae642a47703b321290b85e6fb450e5c4fda7c80e2738f9f9b8b8443e4cf4fc8512054314d7e2842d4a2a47c9519483f5311ef535d14a5573352ecd9aae0f8a833d68b2ad7cfa0a49cbc8cdf88ec7f4868c8f79b92731971f94bb10e1207ef446f011f544138f3d800e9c17133e46598d8e828fcda54ab9cd4ebf9cbb59a2ff347c5b2aebd36545cf7f0277afc945e10a9b6eac393ada2b62e2cc750d697748931958d45a1eea36472099e5cc9e6571d091ef2d0207ecf96b230bafce61cdf2add63dffb8006ecf22d0bfab4a9b3c872d95d1946cdae2c1bac23a6db8edbbe67762050e46ec85291a5573c12d037e3497e63c5441ef64afb6d579c55216a03a86877c3ccd0a488cf3f79fa30069176b5849cd80a1941ac3ee87a6a32d7ab9b9f21acf293dab8c862963584192c3e162779e3e7c7aa2f71359e8e840356e423f03735109288bd7945aef36ef9846a5bda327797c32ef2f4e7c60066e6f6b0d1341abda21c2c3ad996e706b7f739febfc889fe0fb73f1013ecd447572aa8ecaad93b813c8416124ddad3373c1796e2922d9fd8a49a5b707e4af5f2f9628fe9d1bc6ed595b2b821495ad4ce4b035c4e95d3e78478c246bc069cab30d77534ed6c66e749b2378848c9061167e0ba1fff4f8e67f33d08947ee155da6390f536f14967e70f324c88e66be1ddce28b30d5431b3fc93ef14f948f7a8f5485200661ea45d68d909b97c9de964fdb40e1878034769e8ac89da290bdf8437133c871a4fe93f00329c3897f07d7b54b7c59e6256a25d68170610414de09072947ef48a96b483b6aca082c8f92554e2da647228228de8e8b5e8add6a5dc4cbd6ccc24500342954d3bccf5f523ef3ed5375353e1acb98f9df3e80bf017fdf6305c0bfba125538e30a7c4c4a9887d906b4c709ff3a2de54d2dd7c9723b7601c63525990bc79f9206fa3d8b77faadf07848170c96613c061b0368fdd89f6b0ba79ebde5b030024b78cc241f3c6fa062d59204803c7f7d1edb8487e53920b2179d3fb5c7b9c719927ea5e1bdc9262becabbbc6fc117b0746cd741f8f480921ced8384187477d79cbdbee1093232da33ae5b5c040ff56122444f2c32bf10a594ef17e0f008cd93c8c0b9e7fc6fae7df20e530f8e16d311becce1c651b9668361639ff8de7fd07fc9daa50380ca5a87495bec091d1f21d1371c2f46a07d9e243800db1ba3b65b0546e62a0333ec492a87451bbd11a684e1f7ca013d28faab412d303e8b08cb99c9629b8e260ce16072f906f96b5a4ac26021dddf3b71718d8f16a62f0629f7edf19f6650e41827cbb83992c767b886793ee0d8a1aaec201d3befe7acdc7884721dcf82b7430d06d08d21a17496b4aab7c982056bb5e232c6ab7ea0d43e5c4d4a09d8e43a2ae8723a7ee94b61daf9a2500395a3af49025fab912691d4a4d3071c5201d454ed7cea9e620a902ed190aa8f86f091da0a9a8e9c8f607239e75bf999bc7d10f9de0efde55ba00aebc88ffdb61f4095935eb968614e7b93e50a99afde67cb8849a2e3c2f7a59ac4e8ee824142c9f2c157f736b1b1092be7feefb04ada3c6fee2d4c98b7c4c64ea022794d7f955af162e5cf37bb12b34e4b3cc8eb6e5886b7bd6c066f3f0b006b1df1c89f08318b8871860d85fddfcc883165351af929ef66d9e34f416db68dd4f2d316ef879e998139d2f7825d78b338c683be0ca051ef859accecaa1c84908b9c59f94e7e72e28a0aabfa9dfa1a55fae0d5539bc40b2887c1db220899e07801a5140f99b91eec074dbff7d57fabb16cdaeb6aa62b87fdcba1f908a3796dca87f80f6e603554ab67c8e12b995049e8e9492a2b617fce011e17e58b86d5daed9ae0263589af41732bf27b1e93c789302149e1519b588d2459a917f6d0bdaa73e9d778a0ad38c3d60f148b6497637bc5ef2782d19c7c1adc0afe8a004038c60240b9700f5541d480ef37fc75c7620cc44f47c57e9a5de4c7fe1d38ae425e4248b40571d9b6f26fa27e0233a4346cdfc4920fe1611711b2fc4dbf64505778870d8ddfe363d66e0585e52fffa5c51294ad05609b3dfe7eada86e4c1f71a83ad3ac3220c55e7be530bd33010cbf595e3c0fba053eef1ba907d1098784de31ca5aafebe4c33ce87d50d549b5f9ac1a0de4c153943c9f52872258fc20659cb328a1b2a74a05f54153eedf63ff3032fd075ad7397a7eddc0d6aba16dd2291744d2f2c1b44e471e6a255eb0190da8090aeb83dd8c091b6c6d1b780e84154f1465ae2906cf2a0595cfc527fe8abf1cecb25d00f2f95d7467e336b2ebd945dfa53e417ad755f19e9d5798bd273d7fc01bff28cb20a812bbe2dffafb323e9a62ed4d51c1c642bce945f9217964fe7b4a275bc19ba498938849dd117a112294aeddd43233cb881ad35c9440bbc7284d9ef9330c2042a115566575a75857bddd37e303217a534062bb8177b1aa2907ed51a4e10a13f73f50c0d88989dd7366d83ef9f456bf4372cd34617aeba891e4421ef6c7d606df961eabd877b8b41c55a3991e3195f0e55f1008ffda115a504bb8864db01cad88cca3fdf9312a9600fdafa2ec9f574f0f795b2b699665bec39ada6c2058a7504ead5d5256bdfaa96dc41f8e93f93594753158fc656a82f8160d314dfc62ac76aa70fe228de2f69449e44aa1853715a78655da1dd1ae1af79ddc93e40f89a70767168432268ae842f1457ef7236ffbd2a3ae5d0d8ece823d28f43de2d5771e4631cd227e6bcfadcc727cb6ce6cb86ca6bb8f8790de834fabe6a9e8fecf79b53dec55b0af3ad89f6f5699879b29db7aa8459d48150d5151bde4be96c04160de64ae2921aad7536332fc9e177d13dc94d76c27581718c6742fbbe5192abb8485642526caa06d4057bb932e1a8c2a430bf241103554c859dbd20623c0b35087ba554dfb933415c10fb12205e37dd3892820e9586c61ba28efebdd19805e54ad6953b5456bb3cc23c50c9931431070de04d470b508525f90649d065c0e57562618147dc509dc961de146b9d1f4235f963344890d48d557719e38db5875084c3355579d0af7f6e3cdb7c36b3e7f75d71c889690205fd6cbf2f145632fd9d3f6156264f10cd9a1db6b686be289925889e8ade97b4551513f3bac60d596e8ff5a88534d72980abd84766b1adccbb634e82d47bd0bf1fd253f73c35e77d6418e76b0ba1f399b2763eb021233d33c32edf532888c33a14908616d7e1738509fabf7834f81253cb441345ce8df321ba8000f6197ac3a15719b315066c139297fe0de00586735503cf9ed16aed515765cd9a41a211e474ec65468b72de8afd879d15a99a5d70a0aeacb60f9289a81e35313d8b547fa34857e997a208b498e7fab7e7930b2a87cc6fbb29cb1f9029504b9029139e2f39e783de8610adaeb42e662d00a1f8be01749a72afdcaa934ab79f868096e9dcb94b7d83ab87f3adca685617230749d074a138f212cfcf8c49d258e10b04e69c8eb7bfaf07fe62792d1b0ce27a445b7285e8a83bb48f04af6e218ba24eacb7ca6292eca75678cd79f24edf6afbe555a06aaf3018c2ed96c6ce6809013e8ee5a631ea55253cbcafb5bcd90649937fee3dc05520184cb26d5cc49f0cd597fb25362eb421274da5c845669841731f2b5bdd1d36d3c4e3ccc4cf53b84df99439b2d5054685ae5195f5be3cc5b6a16cb5a30d812e9df5255c4afa251cfc733d7b66139709357fce471e7d8ac812fee2d1365210651d2e8c210620a873950926109d4173cb0e2e34661599cf022373d4a5332cf7b948e7380b8112aa4a169f7208972beccc247d9216f96b5d1805aa81939c6edd21416495c4d917e92b0bace0dd5338abc59654a5ce6588da3fa156db28ec53b564f8453eb2f4e8ed62153d0efcb0f7b64d6f51dc58956a976ae545ca9428e90b4b088ca9cc8aa1040b8d13489cb2225298a913e13085a1e1a654f8e72dbbf64cefd44527bfbb44a7918562c7efbac9c9aca13588b5ca3b027466905214ffdaa8d9252b6280348dcec7a524d7731eb51976863c0ed2d08322b1ab0d3cc9380ccd93824f61c63962924fb5775adcd3e7155f5546953ac8cfd1b7d504e76cd95c3a7680fc9b7e52ef952f4c6d723c78e46e856f798772886938aee6095a5a2104184a507f8a77343d429284c109f334c46223696cb902c8e51c0b7c7681d7b2bffce8d5db2ccf91f84cd15ecabcc6bade8f694d5bc788712a3a851e38e6e39955ad84e3e1ab7ba2732447c679965573245d6282d6e7dfa816f282d48a4ae490b9546c7be7fc9f2fd1eeb24c8ffd76fdff7e450acaf434c8946b6ee333ecaa0",
|
|
+ "gasLimit": "0x1fffffffffffff",
|
|
+ "gasUsed": "0x0",
|
|
+ "hash": "0x175e6f11db2489d45eef0aabdc6efd42a35faf516505d576adfa2d6a09372213",
|
|
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "miner": "0xac23c7e741af9bcc42e82729e3abaa64c809ae57",
|
|
+ "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
|
|
+ "nonce": "0x0000000000000000",
|
|
+ "number": "0x321140",
|
|
+ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
+ "parentHash": "0xceedc8c63f445c91271071845d2a46092706a7b504612745ce67d5c8312bab1f",
|
|
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
+ "size": "0xac37",
|
|
+ "stateRoot": "0xd6e96505d280413b24092ba96b8b5ea666f3f6c1ba286afdde27076b893aea5f",
|
|
+ "timestamp": "0x6ab59f55",
|
|
+ "totalDifficulty": "0x321141",
|
|
+ "transactions": [],
|
|
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
+ "uncles": [],
|
|
+ "withdrawals": [],
|
|
+ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
|
+ }
|
|
+ ],
|
|
+ "chainId": 28001,
|
|
+ "id": "28001-anchor-3281216-baza"
|
|
+ }
|
|
+ ]
|
|
+}
|
|
diff --git a/consensus/qbft/src/test/resources/aere-r1b/VECTORI-R1B.json b/consensus/qbft/src/test/resources/aere-r1b/VECTORI-R1B.json
|
|
new file mode 100644
|
|
index 0000000000..8516345029
|
|
--- /dev/null
|
|
+++ b/consensus/qbft/src/test/resources/aere-r1b/VECTORI-R1B.json
|
|
@@ -0,0 +1,1647 @@
|
|
+{
|
|
+ "schema": "aere-r1b-vectori-1",
|
|
+ "spec": "D-470 / 1(b): the round-bound commit seal (AERE-PQ-COMMIT-2), the v3 anchor certificate (AERE-PQ-ANCHOR-3), the per-round seal store and window frames. Common vectors for both clients; classes that need real headers (VR, VSET, VDEC, VL) are added from the rehearsal.",
|
|
+ "generator": "aips/aip22-conformitate/r1b/construieste-vectori-r1b.mjs: hand-written RLP, keccak from @noble/hashes, Falcon-512 and SLH-DSA-SHA2-128s from @noble/post-quantum 0.7.1; every Falcon signature also verified by the public verifier's falcon512.mjs. Keys are SYNTHETIC (AERE-SINTETIC), deterministic from named seeds; Falcon signing is deterministic; a rerun writes the same bytes.",
|
|
+ "constants": {
|
|
+ "MAX_ROUND": 1024,
|
|
+ "MAX_SEALS": 64,
|
|
+ "domains": {
|
|
+ "C1": "AERE-PQ-COMMIT-1",
|
|
+ "C2": "AERE-PQ-COMMIT-2",
|
|
+ "P1": "AERE-PQ-PREPARE-1",
|
|
+ "A2": "AERE-PQ-ANCHOR-2",
|
|
+ "A3": "AERE-PQ-ANCHOR-3",
|
|
+ "ST1": "AERE-PQ-SEALSTORE-1",
|
|
+ "ST2": "AERE-PQ-SEALSTORE-2",
|
|
+ "W1": "AERE-PQ-SEALWINDOW-1",
|
|
+ "W2": "AERE-PQ-SEALWINDOW-2"
|
|
+ },
|
|
+ "schemes": {
|
|
+ "falcon-512": 1,
|
|
+ "slh-dsa-sha2-128s": 2
|
|
+ },
|
|
+ "codes": [
|
|
+ "AERE-PQ-V3-01",
|
|
+ "AERE-PQ-V3-02",
|
|
+ "AERE-PQ-V3-03",
|
|
+ "AERE-PQ-V3-04",
|
|
+ "AERE-PQ-V3-05",
|
|
+ "AERE-PQ-V3-06",
|
|
+ "AERE-PQ-V3-07",
|
|
+ "AERE-PQ-V3-08",
|
|
+ "AERE-PQ-COMMIT-R-01",
|
|
+ "AERE-PQ-COMMIT-R-02",
|
|
+ "AERE-PQ-COMMIT-R-03"
|
|
+ ]
|
|
+ },
|
|
+ "keys": [
|
|
+ {
|
|
+ "index": 0,
|
|
+ "marker": "AERE-SINTETIC",
|
|
+ "address": "0x1e8630cbd37b6f3c1b9ccf77380a25b68e27eb3d",
|
|
+ "falcon-512": {
|
|
+ "publicKeyFull": "0x09907e5eaaae1b77934d09772120320f641bd78d5ad5847d623be3ec273b5af0b41f281a1ae0e8c5b6862748b5d73a6301e8102895e40487e2762e2000656c8a846dec068211093db2315396a71f111667b3a85ba24eb5c274522ead7da017c05dcc747cc46155adcfc54e40f4e7718d08a7ba4050969f4587009eb44c92891392acea1156612aede47373ce048a6ab8bb4a9d469caa482396900d671546bb2d1910b73c3d36c8a312975401d8676ea1216e3fa787685d36a573a2189bd4a5de2b839950f812e24ae21f809c9775c8b624ccc042d672d2b81dae3a85f917bda3a6a2ad0296a1c9aa29444cb69f9e516d9626e90684b93a805243b76a5b746c8a92fd6ee26f718e9091eff976c6b9a6ff0525197095a7e029003e429b67e1d5ee348a3f775262919314da93e5135576d5a251bed8f80810622733662e868a7c9bbec404866c5e75aee66c9b243ef7745a4a0b32a4111189752538bc53f0cfcaa59e8cea3f1c421f9ae26bc299eb54450ad47a5d9940001ca0115bfd563ecea043dac77c9c542144d1b2bce1c48084e9293b566ae08a435eb8dce3f4b4eff4604d7a09f1e4f5349a6c10b55051810d5b24f1a3af865001c57b4b642ecaeb393300a763fca17345efeb64dd66f9a36a0eb2c42d4155dce21feacdc74dcc27a0cc76e91e85b50a88aeb79a463ba18282e1950fbf68d52256086ed3024506867f6ffa0aadc40afc640c526d3ea52604e174c0a860791c92541547c40d274466191db5020631befc8cc0ae8ae38d192f86a08b16372c86eba88eb79fd19ea4d4871f19f8e6e67fd8077101a557dc15a393c48b798fd4166b11f8c9a04522953c32c98e9a8577fe06521c00e9a5d03221c9a57a9742f8cac583cab2548550d70e79705c5980cb957664f5f135ab029531e25169411a663d2acde6daddca64c2ec584198925262ba113bdb33728010b9efcb7636c9390a4b07580e8620215d662b2aa9f6b0fcc879a0b921476980f3703cc552e967e40721e58bd42caa5535aac8572327be5a0157a0827c47844bb51edea5185033d5aa026a942e15f93421f4a4b2224991e51065418cfbb3e2beb9a8ed82da60cf48e144161fa3ba4d915ca10ba1366c20ba3033c8b362850416d242ad2e1ec9061f62c5567d3fb7f16b092628579a3c2cbd342c604521ea334eb285ab4798a0bca8b645c9d73c5f5d4081332fc374a0c8f0b75f39631c6b25561d2c163ed082052d1fa55472b65c5f7d34252bbb09c034",
|
|
+ "publicKeyRegistry": "0x907e5eaaae1b77934d09772120320f641bd78d5ad5847d623be3ec273b5af0b41f281a1ae0e8c5b6862748b5d73a6301e8102895e40487e2762e2000656c8a846dec068211093db2315396a71f111667b3a85ba24eb5c274522ead7da017c05dcc747cc46155adcfc54e40f4e7718d08a7ba4050969f4587009eb44c92891392acea1156612aede47373ce048a6ab8bb4a9d469caa482396900d671546bb2d1910b73c3d36c8a312975401d8676ea1216e3fa787685d36a573a2189bd4a5de2b839950f812e24ae21f809c9775c8b624ccc042d672d2b81dae3a85f917bda3a6a2ad0296a1c9aa29444cb69f9e516d9626e90684b93a805243b76a5b746c8a92fd6ee26f718e9091eff976c6b9a6ff0525197095a7e029003e429b67e1d5ee348a3f775262919314da93e5135576d5a251bed8f80810622733662e868a7c9bbec404866c5e75aee66c9b243ef7745a4a0b32a4111189752538bc53f0cfcaa59e8cea3f1c421f9ae26bc299eb54450ad47a5d9940001ca0115bfd563ecea043dac77c9c542144d1b2bce1c48084e9293b566ae08a435eb8dce3f4b4eff4604d7a09f1e4f5349a6c10b55051810d5b24f1a3af865001c57b4b642ecaeb393300a763fca17345efeb64dd66f9a36a0eb2c42d4155dce21feacdc74dcc27a0cc76e91e85b50a88aeb79a463ba18282e1950fbf68d52256086ed3024506867f6ffa0aadc40afc640c526d3ea52604e174c0a860791c92541547c40d274466191db5020631befc8cc0ae8ae38d192f86a08b16372c86eba88eb79fd19ea4d4871f19f8e6e67fd8077101a557dc15a393c48b798fd4166b11f8c9a04522953c32c98e9a8577fe06521c00e9a5d03221c9a57a9742f8cac583cab2548550d70e79705c5980cb957664f5f135ab029531e25169411a663d2acde6daddca64c2ec584198925262ba113bdb33728010b9efcb7636c9390a4b07580e8620215d662b2aa9f6b0fcc879a0b921476980f3703cc552e967e40721e58bd42caa5535aac8572327be5a0157a0827c47844bb51edea5185033d5aa026a942e15f93421f4a4b2224991e51065418cfbb3e2beb9a8ed82da60cf48e144161fa3ba4d915ca10ba1366c20ba3033c8b362850416d242ad2e1ec9061f62c5567d3fb7f16b092628579a3c2cbd342c604521ea334eb285ab4798a0bca8b645c9d73c5f5d4081332fc374a0c8f0b75f39631c6b25561d2c163ed082052d1fa55472b65c5f7d34252bbb09c034"
|
|
+ },
|
|
+ "slh-dsa-sha2-128s": {
|
|
+ "publicKey": "0x47f965d096ad83f700a93901371f03d4a5e87601fbcca4e1dd05bdec4ea65e3e"
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "index": 1,
|
|
+ "marker": "AERE-SINTETIC",
|
|
+ "address": "0x92253d235aae6fce64524698594062a74e32e604",
|
|
+ "falcon-512": {
|
|
+ "publicKeyFull": "0x09957e196011a27e4a6576b6f2df8679d48125c7aa6e5aacbac9210eda50959ed4725a473bb2d8618283943bad1821af641abe7887e5fe9983aae564d425ed0021ae95a90997a78872a77a025e812c2eb1f9070a6b9ec6f0745e1293a1bcf47a249fce1592c0b415873f5901ad45d7afa9015dfb79d717419b1af8f5cd4067921d62a6ee482f40987a70aa2a0c49c50717e05998a1d560bb03c6cc53f195563d9fea8d2826ab764baf5a1aa7d97fea4a3ac9db561dee6b4f3e51417810c22918fb8198aa8746cef7c2eaa5ec8a3ecc91bf0ab666b4e7849445a5ab6c35bb025509442cccb7c560971f1c490998a6e6a71197f64d231eafa487772426e60e409572d4c529ad8ca6ab3a90401ee9e5b47e4f3e2b68563166871abe6cdb37afe87749d4d25833a21d7e70cb08fb128e4a393c72e2c1d32da09328abcb3aa6b5a5cbae12f67558519547494a95f17b048dc0d76a5d571283630a3aa61b501c161a2a66a0e714dcf70d646d118584fda2e6c553bd042f1256bde2455107b01ae2faaee9eb18d08152ce028126b1e514d7145689c51d81b080785e85e7e17d8ab1ab4d788653d70d6432692ab72ce8a5ed1121f8563a4345af28556242028612f047979e3a129c4681eb4f1a65d03bd2aaff4df5bc8abc2f7130ba67b3db280f11da3672962fdd78125d5160d10603d566b13b239a2a52f2754f47e0a6012e56ead07e9f85a006e8933a6c6965c374dccb50d0fed745470850ec6ba19d5b7838b15f03af1566501522f003c3edbc16576172c3c3ab6500485108039d6271b6911e58bd9d3dbbb78e3a91a95c9252954c7cdae843a784849fbded6b6250ab7b528a3041940343a4b8477c88595d4a41a7f31b8220dee7cb4000022c469b13efd19e271a56f9ad51b215164fe7d9d11291acd7255a2ba5029a9490d9999a1caaa36082616b73a0288889cc00bbc6b61128dcdd77e411524a2adb22f0e0d0d1e85413a80c63640c8b2b090b0bebca763fa218b07e86e31aa5be9a95c1811310fa7b0890e5b47ac4127947f89189f6d7cc5a317101ec213ee7e508fd5fc121e6571aa40929978f900380b3593fd83e4da9a64455c03f9658b2e7ff8e081d76e9f3099d7b725653c3ae6881aedc61024107967e09c542721f45a4300e95a7255f6db159e933670f9c84487a042334355a251410ae9156b92b104b8aab929864d77ed41bb7d848c07ac317b49d2ca8be02857e80e9da6aacd6a429f415ab9586369c8f07714168",
|
|
+ "publicKeyRegistry": "0x957e196011a27e4a6576b6f2df8679d48125c7aa6e5aacbac9210eda50959ed4725a473bb2d8618283943bad1821af641abe7887e5fe9983aae564d425ed0021ae95a90997a78872a77a025e812c2eb1f9070a6b9ec6f0745e1293a1bcf47a249fce1592c0b415873f5901ad45d7afa9015dfb79d717419b1af8f5cd4067921d62a6ee482f40987a70aa2a0c49c50717e05998a1d560bb03c6cc53f195563d9fea8d2826ab764baf5a1aa7d97fea4a3ac9db561dee6b4f3e51417810c22918fb8198aa8746cef7c2eaa5ec8a3ecc91bf0ab666b4e7849445a5ab6c35bb025509442cccb7c560971f1c490998a6e6a71197f64d231eafa487772426e60e409572d4c529ad8ca6ab3a90401ee9e5b47e4f3e2b68563166871abe6cdb37afe87749d4d25833a21d7e70cb08fb128e4a393c72e2c1d32da09328abcb3aa6b5a5cbae12f67558519547494a95f17b048dc0d76a5d571283630a3aa61b501c161a2a66a0e714dcf70d646d118584fda2e6c553bd042f1256bde2455107b01ae2faaee9eb18d08152ce028126b1e514d7145689c51d81b080785e85e7e17d8ab1ab4d788653d70d6432692ab72ce8a5ed1121f8563a4345af28556242028612f047979e3a129c4681eb4f1a65d03bd2aaff4df5bc8abc2f7130ba67b3db280f11da3672962fdd78125d5160d10603d566b13b239a2a52f2754f47e0a6012e56ead07e9f85a006e8933a6c6965c374dccb50d0fed745470850ec6ba19d5b7838b15f03af1566501522f003c3edbc16576172c3c3ab6500485108039d6271b6911e58bd9d3dbbb78e3a91a95c9252954c7cdae843a784849fbded6b6250ab7b528a3041940343a4b8477c88595d4a41a7f31b8220dee7cb4000022c469b13efd19e271a56f9ad51b215164fe7d9d11291acd7255a2ba5029a9490d9999a1caaa36082616b73a0288889cc00bbc6b61128dcdd77e411524a2adb22f0e0d0d1e85413a80c63640c8b2b090b0bebca763fa218b07e86e31aa5be9a95c1811310fa7b0890e5b47ac4127947f89189f6d7cc5a317101ec213ee7e508fd5fc121e6571aa40929978f900380b3593fd83e4da9a64455c03f9658b2e7ff8e081d76e9f3099d7b725653c3ae6881aedc61024107967e09c542721f45a4300e95a7255f6db159e933670f9c84487a042334355a251410ae9156b92b104b8aab929864d77ed41bb7d848c07ac317b49d2ca8be02857e80e9da6aacd6a429f415ab9586369c8f07714168"
|
|
+ },
|
|
+ "slh-dsa-sha2-128s": {
|
|
+ "publicKey": "0x97b3e5119fa40a74aa17f23662430fa759adc106bef8eb738f1ab7a76b73f694"
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "index": 2,
|
|
+ "marker": "AERE-SINTETIC",
|
|
+ "address": "0xfe7df8ea09662aab17cd0926e24333ab4c514560",
|
|
+ "falcon-512": {
|
|
+ "publicKeyFull": "0x0991153454ea8b852d5c17b700ef3a5c58fdd1d664d23949db875b83d56c32aa2610ea435d71f6cb9b11a608a69836cd8d27acb92787431f9745e97713b8084144562899d51b916c6e4824e46968acd9152a01e30f95d0567782dd3708c08ee8a529b871fe3715ca19f821166e66028a235409f4e7e0eaf58929ba12f143cc13a559b6588efeb60d6f53d72b063fd250c0faae74621a0044f28ba63dea3838324fbd769290a9161f481a3953f5a467eaa9ddae2590e4206fdcdab345c9565afc43e36218bf3ecd4fd029dda11eb4c1cb35104b6d88dcd81dc8738636d7c9c768ff579d7dc6e3c713a5da8a71f36edbb4ee2855ddc6d806840a587bddba73dab934ef0d44790cbde76895d507c8ad090cc1f5440ae2259f8f0b71422f28349c0ab8a96d47168667815d7143e42b1d737545d52b13d28a29f8f9cadce0a02a82d618944c3a6c05c69f9d0cb4c9a9336e2a955c2a0e568ad30246861eb2b7dafd9ca4df07b0aac114b4c426bd9f5abffa0e70da00a234389e52af20e58874cfc0d7c41c7576e0096aedc8b5051639dcea062e34f3c8dd0f66174472a606a51c78367567cf2413ab6059073154791c98f6b382dc6eb5543d483c0ebc15edb970e609ad2f99ec911202e02e68487551852b426019802b9935ba1958d9a64f57a6d6bf96ca94093c2893a26190c99efa3ef9391ccd1e960333912932078167b0e9ce823ea2a634934c9458593d451593c360c14b037c9fd57714fbb3eca9de113679a21826fa480803a513223814e26117cf55202331de8a10de027e850e00fec636a190b5389d99832a644eb6a8cc02357eb9169a6858b54e3ef4fe590a44d1a6c5d7098c15d6a2d7df2b878ac65162b52c652658a688d023c84bc214949b6dd42e329f934dc53022bd3be88b11216e35fd00ab5db909aeeec532cd8bab2022e26c23176e258a193cabf91010ff854f97488801cbf11e63184e1d1517068a9b07c53350feed0a02ed4bf3ba12b0285ead3a65058d781cb023351ac8195d519460e1d644885eb18ed15455086d4748d4ae8f1ee1c3a31d0026f4bba3bd507ba265008b60559967b595790c414f247c7853c94eb065967f59660b6e7385e6a976dd798fcd19f4ad658506dc25b512a1ae9585cfb94f2dcc815a64d60093326774b52625c83da0410c7082df24759de8003ca10d74e25db5e9ed7ea1cee9ead85734bb24883abea9c04670cca8a703b96fbeabf3df0dfb847d02903b22d4a85acbd881a258",
|
|
+ "publicKeyRegistry": "0x91153454ea8b852d5c17b700ef3a5c58fdd1d664d23949db875b83d56c32aa2610ea435d71f6cb9b11a608a69836cd8d27acb92787431f9745e97713b8084144562899d51b916c6e4824e46968acd9152a01e30f95d0567782dd3708c08ee8a529b871fe3715ca19f821166e66028a235409f4e7e0eaf58929ba12f143cc13a559b6588efeb60d6f53d72b063fd250c0faae74621a0044f28ba63dea3838324fbd769290a9161f481a3953f5a467eaa9ddae2590e4206fdcdab345c9565afc43e36218bf3ecd4fd029dda11eb4c1cb35104b6d88dcd81dc8738636d7c9c768ff579d7dc6e3c713a5da8a71f36edbb4ee2855ddc6d806840a587bddba73dab934ef0d44790cbde76895d507c8ad090cc1f5440ae2259f8f0b71422f28349c0ab8a96d47168667815d7143e42b1d737545d52b13d28a29f8f9cadce0a02a82d618944c3a6c05c69f9d0cb4c9a9336e2a955c2a0e568ad30246861eb2b7dafd9ca4df07b0aac114b4c426bd9f5abffa0e70da00a234389e52af20e58874cfc0d7c41c7576e0096aedc8b5051639dcea062e34f3c8dd0f66174472a606a51c78367567cf2413ab6059073154791c98f6b382dc6eb5543d483c0ebc15edb970e609ad2f99ec911202e02e68487551852b426019802b9935ba1958d9a64f57a6d6bf96ca94093c2893a26190c99efa3ef9391ccd1e960333912932078167b0e9ce823ea2a634934c9458593d451593c360c14b037c9fd57714fbb3eca9de113679a21826fa480803a513223814e26117cf55202331de8a10de027e850e00fec636a190b5389d99832a644eb6a8cc02357eb9169a6858b54e3ef4fe590a44d1a6c5d7098c15d6a2d7df2b878ac65162b52c652658a688d023c84bc214949b6dd42e329f934dc53022bd3be88b11216e35fd00ab5db909aeeec532cd8bab2022e26c23176e258a193cabf91010ff854f97488801cbf11e63184e1d1517068a9b07c53350feed0a02ed4bf3ba12b0285ead3a65058d781cb023351ac8195d519460e1d644885eb18ed15455086d4748d4ae8f1ee1c3a31d0026f4bba3bd507ba265008b60559967b595790c414f247c7853c94eb065967f59660b6e7385e6a976dd798fcd19f4ad658506dc25b512a1ae9585cfb94f2dcc815a64d60093326774b52625c83da0410c7082df24759de8003ca10d74e25db5e9ed7ea1cee9ead85734bb24883abea9c04670cca8a703b96fbeabf3df0dfb847d02903b22d4a85acbd881a258"
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "index": 3,
|
|
+ "marker": "AERE-SINTETIC",
|
|
+ "address": "0x0a1f732db9f0a1f53b932e7d3dda365698e3e617",
|
|
+ "falcon-512": {
|
|
+ "publicKeyFull": "0x09b532d3b13ea7a507fcd2e449ee2085d1eb891861fd8b750eb170ec4a7c9edf11c704a61281dea8a417509626ef368624026502a906db4f470d8c94cbb50e426f4566537283b2898d6308ba12405f8a9a36c82dd8880cdd108167f04762ad473e4ea0afa08bb1ee0e8c6d12a7e97cc647b214e83180a0f19f45f0d0a5e6f06f00f75281d382abb6626a92e7031025c184430fa591854adaab96f068a2ffd2d0ee64777aa667d1264f079af0d9ed294c5924415ae18016a8c6d7aadcc58182908c8b5c00f02fec99c0255fa615aa99d3a2ac87a6dd6f74f7491f142c1d718a2be41ebef50923c0ae9d81c256885171074266552564e18675372493a9d86a7e05963aa5280ef616a24e0b53157ab268804ef0522893e2eb1f2bb4189247e9561c30f5eb635fd916b811dc90264c621ed2188891d6d5b42cfd0867823b7f29d055551ab1109c1bdb3d8119215a2b03ead28a9af24925c61f846a083c1b67ea23a4fcebc93b59500b9110b272a59032e20ae5dc09d69cee8f9b378b29afac94235ca5841b72e0b8169ba8872ce0167fc33e4a9a303af16dbf75517970582e4fb57e029592a5bf497e0e546c217f967e2df1b89d16006ae2e5c545a543a1d7d575a475a4dd82ba3a49740655b008c698857ead1ce3dee7cc928c63d32aa7d4ac2d972602df1845ba7f14f76b9b7ee2c4c80be09e47089780fd104e5d020470a490ea1eca7fd2d047f3621c6835212f3745bc0f560bac940c64f72b290c9d53b4537167094e56fde9f856ed19019d9067661724675edc29be017fb2fee853a917a6874af5cac766f44a0142854b8c812ea1d979b1056130c862e763431d99fc57e24dab043d799591dea06760307990d645e0b736e44a1455067d124f68ecc9eb60d06e3add88b382297948a0a1e45bb23185fee32433c62ebb030d46430867f5e3e41b96aee53343d7b89dba8d03f82e0c52562f501419ea3e227c01d31be58a56780b08440a64fa187504ec21a834aa08435e0dbb7e05183490fb10761a8788c5867a5ee79618922a8866427405615d2df62b002f511289b96b2049ae49b8169f670f4a2953ae32b1f521a88c7242d4f89064a1f5fd764cdd68a936f4d7668f424651e6786ca648a6d843f387895f5fe25e475f981e645d021a8f14db920932f1f4195d7cc23953bf83b753901545c96c281eee9f03da43c563f18459a6a9de09640647148b50a1940aa99a6dff9c04a5b6be5962449c94c71b668c3966c531d34afb",
|
|
+ "publicKeyRegistry": "0xb532d3b13ea7a507fcd2e449ee2085d1eb891861fd8b750eb170ec4a7c9edf11c704a61281dea8a417509626ef368624026502a906db4f470d8c94cbb50e426f4566537283b2898d6308ba12405f8a9a36c82dd8880cdd108167f04762ad473e4ea0afa08bb1ee0e8c6d12a7e97cc647b214e83180a0f19f45f0d0a5e6f06f00f75281d382abb6626a92e7031025c184430fa591854adaab96f068a2ffd2d0ee64777aa667d1264f079af0d9ed294c5924415ae18016a8c6d7aadcc58182908c8b5c00f02fec99c0255fa615aa99d3a2ac87a6dd6f74f7491f142c1d718a2be41ebef50923c0ae9d81c256885171074266552564e18675372493a9d86a7e05963aa5280ef616a24e0b53157ab268804ef0522893e2eb1f2bb4189247e9561c30f5eb635fd916b811dc90264c621ed2188891d6d5b42cfd0867823b7f29d055551ab1109c1bdb3d8119215a2b03ead28a9af24925c61f846a083c1b67ea23a4fcebc93b59500b9110b272a59032e20ae5dc09d69cee8f9b378b29afac94235ca5841b72e0b8169ba8872ce0167fc33e4a9a303af16dbf75517970582e4fb57e029592a5bf497e0e546c217f967e2df1b89d16006ae2e5c545a543a1d7d575a475a4dd82ba3a49740655b008c698857ead1ce3dee7cc928c63d32aa7d4ac2d972602df1845ba7f14f76b9b7ee2c4c80be09e47089780fd104e5d020470a490ea1eca7fd2d047f3621c6835212f3745bc0f560bac940c64f72b290c9d53b4537167094e56fde9f856ed19019d9067661724675edc29be017fb2fee853a917a6874af5cac766f44a0142854b8c812ea1d979b1056130c862e763431d99fc57e24dab043d799591dea06760307990d645e0b736e44a1455067d124f68ecc9eb60d06e3add88b382297948a0a1e45bb23185fee32433c62ebb030d46430867f5e3e41b96aee53343d7b89dba8d03f82e0c52562f501419ea3e227c01d31be58a56780b08440a64fa187504ec21a834aa08435e0dbb7e05183490fb10761a8788c5867a5ee79618922a8866427405615d2df62b002f511289b96b2049ae49b8169f670f4a2953ae32b1f521a88c7242d4f89064a1f5fd764cdd68a936f4d7668f424651e6786ca648a6d843f387895f5fe25e475f981e645d021a8f14db920932f1f4195d7cc23953bf83b753901545c96c281eee9f03da43c563f18459a6a9de09640647148b50a1940aa99a6dff9c04a5b6be5962449c94c71b668c3966c531d34afb"
|
|
+ }
|
|
+ }
|
|
+ ],
|
|
+ "control": [
|
|
+ {
|
|
+ "id": "COMMIT-1(28001,1000,0x11)",
|
|
+ "value": "0xe710f04a8517e5af495f33d47bd3dc19e20afaaec3435ce7124cb1d56ef5e27b"
|
|
+ },
|
|
+ {
|
|
+ "id": "PREPARE-1(28001,1000,r=2,0x11)",
|
|
+ "value": "0x6ea2394db1ccded2dc5107d9aacf5be6c5a769218ba2eb4b004088466da4ba84"
|
|
+ },
|
|
+ {
|
|
+ "id": "PREPARE-1(28001,1000,r=0,0x11)",
|
|
+ "value": "0x10f5d7f8368a2533c05df0bc5cc39fabdc055c9d60fc8bc7e1ff403ea9e64909"
|
|
+ }
|
|
+ ],
|
|
+ "VM": [
|
|
+ {
|
|
+ "id": "vm-28001-1000-r0",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": 0,
|
|
+ "hash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commit2": "0x5fdbfd2f4066eacbc275682817f0e4410d3d762ea8a6c5061586041010298eeb",
|
|
+ "commit1": "0xe710f04a8517e5af495f33d47bd3dc19e20afaaec3435ce7124cb1d56ef5e27b"
|
|
+ },
|
|
+ {
|
|
+ "id": "vm-28001-1000-r1",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": 1,
|
|
+ "hash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commit2": "0x921fab44cf68919646c8bba40c37c1d0211a14654e777b6dd516fc74c7a7c715",
|
|
+ "commit1": "0xe710f04a8517e5af495f33d47bd3dc19e20afaaec3435ce7124cb1d56ef5e27b"
|
|
+ },
|
|
+ {
|
|
+ "id": "vm-28001-1000-r2",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": 2,
|
|
+ "hash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commit2": "0x28d5e1e414ea100e42db14144e5a7721b0137994a1461d2d71a554c18b782a0a",
|
|
+ "commit1": "0xe710f04a8517e5af495f33d47bd3dc19e20afaaec3435ce7124cb1d56ef5e27b"
|
|
+ },
|
|
+ {
|
|
+ "id": "vm-28001-1000-r3",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": 3,
|
|
+ "hash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commit2": "0xb247791ed3715ee9a9974a23c135331bf094d0681fa6131fc44eb1fa26b89062",
|
|
+ "commit1": "0xe710f04a8517e5af495f33d47bd3dc19e20afaaec3435ce7124cb1d56ef5e27b"
|
|
+ },
|
|
+ {
|
|
+ "id": "vm-28001-1000-r127",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": 127,
|
|
+ "hash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commit2": "0x6b926d6c5afc90bdca785dc3a744234bfbfa7979fcf9839bebff39bcff513ff4",
|
|
+ "commit1": "0xe710f04a8517e5af495f33d47bd3dc19e20afaaec3435ce7124cb1d56ef5e27b"
|
|
+ },
|
|
+ {
|
|
+ "id": "vm-28001-1000-r128",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": 128,
|
|
+ "hash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commit2": "0x4df364d8deaeb218976a342a4b10954d3c5f41e2c1863e51fb664c7a8f5181de",
|
|
+ "commit1": "0xe710f04a8517e5af495f33d47bd3dc19e20afaaec3435ce7124cb1d56ef5e27b"
|
|
+ },
|
|
+ {
|
|
+ "id": "vm-28001-1000-r1000",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": 1000,
|
|
+ "hash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commit2": "0xe5c8b97d504ebd57a5c74000e37ffe8dd4c0a70d64c43c5faf43ac7975feef5f",
|
|
+ "commit1": "0xe710f04a8517e5af495f33d47bd3dc19e20afaaec3435ce7124cb1d56ef5e27b"
|
|
+ },
|
|
+ {
|
|
+ "id": "vm-28001-1000-r1024",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": 1024,
|
|
+ "hash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commit2": "0xb10b5e143e201dc0f538db90dd4cea7dd21c174b7ab575b0a353270f2cba5083",
|
|
+ "commit1": "0xe710f04a8517e5af495f33d47bd3dc19e20afaaec3435ce7124cb1d56ef5e27b"
|
|
+ },
|
|
+ {
|
|
+ "id": "vm-2800-21000000-r0",
|
|
+ "chainId": 2800,
|
|
+ "n": 21000000,
|
|
+ "round": 0,
|
|
+ "hash": "0x2222222222222222222222222222222222222222222222222222222222222222",
|
|
+ "commit2": "0x9edb252de1978b0d7eded7a9df0584a36e16eb9eab7b1fa4bdc30ac2496401a2",
|
|
+ "commit1": "0x84c859aba10282d049a02e0f5bc4e5290f7809be8f5bc20722ec65aa2ccf3aae"
|
|
+ },
|
|
+ {
|
|
+ "id": "vm-2800-21000000-r3",
|
|
+ "chainId": 2800,
|
|
+ "n": 21000000,
|
|
+ "round": 3,
|
|
+ "hash": "0x2222222222222222222222222222222222222222222222222222222222222222",
|
|
+ "commit2": "0x2290c0ef39679154fac1b81e6baeabc21928ff4be5bad6d1344eefd960896f1d",
|
|
+ "commit1": "0x84c859aba10282d049a02e0f5bc4e5290f7809be8f5bc20722ec65aa2ccf3aae"
|
|
+ }
|
|
+ ],
|
|
+ "VMF": [
|
|
+ {
|
|
+ "id": "vmf-sub-forma-ancorei",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 62,
|
|
+ "round": 0,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ECDSA_DIGEST",
|
|
+ "message": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "anchorMessage": null,
|
|
+ "code": null
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-prima-forma-ancorei",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 63,
|
|
+ "round": 0,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ROUND_FREE",
|
|
+ "message": "0x846d66aa91cd24e636ef448f81644e6a3357cba87430e7edee57bd1f576e6e1b",
|
|
+ "anchorMessage": "0x846d66aa91cd24e636ef448f81644e6a3357cba87430e7edee57bd1f576e6e1b",
|
|
+ "code": null
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-H_r-2",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 998,
|
|
+ "round": 2,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ROUND_FREE",
|
|
+ "message": "0x4adfc6303cba6f63575d27571d35dab5b6e7149d46392b69c0599040933a37d9",
|
|
+ "anchorMessage": "0x4adfc6303cba6f63575d27571d35dab5b6e7149d46392b69c0599040933a37d9",
|
|
+ "code": null
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-H_r-2-runda-1025",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 998,
|
|
+ "round": 1025,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ROUND_FREE",
|
|
+ "message": "0x4adfc6303cba6f63575d27571d35dab5b6e7149d46392b69c0599040933a37d9",
|
|
+ "anchorMessage": "0x4adfc6303cba6f63575d27571d35dab5b6e7149d46392b69c0599040933a37d9",
|
|
+ "code": null
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-H_r-1",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 999,
|
|
+ "round": 2,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ROUND_BOUND",
|
|
+ "message": "0x8456d2e42a843ad59e833ef6d8db12f39e6160a170b5c7a7db113b56f905f239",
|
|
+ "anchorMessage": "0x8456d2e42a843ad59e833ef6d8db12f39e6160a170b5c7a7db113b56f905f239",
|
|
+ "code": null
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-H_r-1-runda-0",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 999,
|
|
+ "round": 0,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ROUND_BOUND",
|
|
+ "message": "0x6773d14e263051c70708a039c3d8742b13d6fc1115c56c750a1c1b0e0bf6a861",
|
|
+ "anchorMessage": "0x6773d14e263051c70708a039c3d8742b13d6fc1115c56c750a1c1b0e0bf6a861",
|
|
+ "code": null
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-H_r",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 1000,
|
|
+ "round": 0,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ROUND_BOUND",
|
|
+ "message": "0x5fdbfd2f4066eacbc275682817f0e4410d3d762ea8a6c5061586041010298eeb",
|
|
+ "anchorMessage": "0x5fdbfd2f4066eacbc275682817f0e4410d3d762ea8a6c5061586041010298eeb",
|
|
+ "code": null
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-H_r-1-runda-1024",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 999,
|
|
+ "round": 1024,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ROUND_BOUND",
|
|
+ "message": "0x478927028074b30abc32ff89e49448bcda247430c5ae6ad27e17824b1e39e9cd",
|
|
+ "anchorMessage": "0x478927028074b30abc32ff89e49448bcda247430c5ae6ad27e17824b1e39e9cd",
|
|
+ "code": null
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-H_r-1-runda-1025",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 999,
|
|
+ "round": 1025,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ROUND_BOUND",
|
|
+ "message": null,
|
|
+ "anchorMessage": null,
|
|
+ "code": "AERE-PQ-COMMIT-R-03"
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-H_r-1-runda-minus-1",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 999,
|
|
+ "round": -1,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ROUND_BOUND",
|
|
+ "message": null,
|
|
+ "anchorMessage": null,
|
|
+ "code": "AERE-PQ-COMMIT-R-03"
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-H_r-nesetat",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": null,
|
|
+ "anchorDisabled": false,
|
|
+ "n": 5000,
|
|
+ "round": 3,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ROUND_FREE",
|
|
+ "message": "0x76d4e8d9eedf4c6b59895536b5790a2698c4cbc80eab2531422e2f60e90bf996",
|
|
+ "anchorMessage": "0x76d4e8d9eedf4c6b59895536b5790a2698c4cbc80eab2531422e2f60e90bf996",
|
|
+ "code": null
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vmf-ancora-dezarmata",
|
|
+ "chainId": 28001,
|
|
+ "anchorBlock": 64,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "anchorDisabled": true,
|
|
+ "n": 5000,
|
|
+ "round": 3,
|
|
+ "onchainHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "commitDigest": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "expected": {
|
|
+ "form": "ECDSA_DIGEST",
|
|
+ "message": "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c",
|
|
+ "anchorMessage": null,
|
|
+ "code": null
|
|
+ }
|
|
+ }
|
|
+ ],
|
|
+ "VC": [
|
|
+ {
|
|
+ "id": "vc-r0",
|
|
+ "valid": true,
|
|
+ "round": 0,
|
|
+ "rows": [
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 0,
|
|
+ "signature": "0xaaaaaaaa"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 2,
|
|
+ "signature": "0xbbbbbbbb"
|
|
+ }
|
|
+ ],
|
|
+ "bytes": "0xd30380d0c7018084aaaaaaaac7010284bbbbbbbb"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-r3",
|
|
+ "valid": true,
|
|
+ "round": 3,
|
|
+ "rows": [
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 0,
|
|
+ "signature": "0xaaaaaaaa"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 2,
|
|
+ "signature": "0xbbbbbbbb"
|
|
+ }
|
|
+ ],
|
|
+ "bytes": "0xd30303d0c7018084aaaaaaaac7010284bbbbbbbb"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-r128",
|
|
+ "valid": true,
|
|
+ "round": 128,
|
|
+ "rows": [
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 0,
|
|
+ "signature": "0xaaaaaaaa"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 2,
|
|
+ "signature": "0xbbbbbbbb"
|
|
+ }
|
|
+ ],
|
|
+ "bytes": "0xd4038180d0c7018084aaaaaaaac7010284bbbbbbbb"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-r1024",
|
|
+ "valid": true,
|
|
+ "round": 1024,
|
|
+ "rows": [
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 0,
|
|
+ "signature": "0xaaaaaaaa"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 2,
|
|
+ "signature": "0xbbbbbbbb"
|
|
+ }
|
|
+ ],
|
|
+ "bytes": "0xd503820400d0c7018084aaaaaaaac7010284bbbbbbbb"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-gol-r0",
|
|
+ "valid": true,
|
|
+ "round": 0,
|
|
+ "rows": [],
|
|
+ "bytes": "0xc30380c0"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-r1-hibrid",
|
|
+ "valid": true,
|
|
+ "round": 1,
|
|
+ "rows": [
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 0,
|
|
+ "signature": "0xaaaaaaaa"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 2,
|
|
+ "index": 0,
|
|
+ "signature": "0xcccccccc"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 3,
|
|
+ "signature": "0xbbbbbbbb"
|
|
+ }
|
|
+ ],
|
|
+ "bytes": "0xdb0301d8c7018084aaaaaaaac7028084ccccccccc7010384bbbbbbbb"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-r0-hibrid",
|
|
+ "valid": true,
|
|
+ "round": 0,
|
|
+ "rows": [
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 0,
|
|
+ "signature": "0xa0a0a0a0"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 2,
|
|
+ "signature": "0xa2a2a2a2"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 2,
|
|
+ "index": 2,
|
|
+ "signature": "0xb2b2b2b2"
|
|
+ }
|
|
+ ],
|
|
+ "bytes": "0xdb0380d8c7018084a0a0a0a0c7010284a2a2a2a2c7020284b2b2b2b2"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-64-randuri",
|
|
+ "valid": true,
|
|
+ "round": 0,
|
|
+ "rows": [
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 0,
|
|
+ "signature": "0x1010"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 1,
|
|
+ "signature": "0x1111"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 2,
|
|
+ "signature": "0x1212"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 3,
|
|
+ "signature": "0x1313"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 4,
|
|
+ "signature": "0x1414"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 5,
|
|
+ "signature": "0x1515"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 6,
|
|
+ "signature": "0x1616"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 7,
|
|
+ "signature": "0x1717"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 8,
|
|
+ "signature": "0x1818"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 9,
|
|
+ "signature": "0x1919"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 10,
|
|
+ "signature": "0x1a1a"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 11,
|
|
+ "signature": "0x1b1b"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 12,
|
|
+ "signature": "0x1c1c"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 13,
|
|
+ "signature": "0x1d1d"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 14,
|
|
+ "signature": "0x1e1e"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 15,
|
|
+ "signature": "0x1f1f"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 16,
|
|
+ "signature": "0x2020"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 17,
|
|
+ "signature": "0x2121"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 18,
|
|
+ "signature": "0x2222"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 19,
|
|
+ "signature": "0x2323"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 20,
|
|
+ "signature": "0x2424"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 21,
|
|
+ "signature": "0x2525"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 22,
|
|
+ "signature": "0x2626"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 23,
|
|
+ "signature": "0x2727"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 24,
|
|
+ "signature": "0x2828"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 25,
|
|
+ "signature": "0x2929"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 26,
|
|
+ "signature": "0x2a2a"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 27,
|
|
+ "signature": "0x2b2b"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 28,
|
|
+ "signature": "0x2c2c"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 29,
|
|
+ "signature": "0x2d2d"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 30,
|
|
+ "signature": "0x2e2e"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 31,
|
|
+ "signature": "0x2f2f"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 32,
|
|
+ "signature": "0x3030"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 33,
|
|
+ "signature": "0x3131"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 34,
|
|
+ "signature": "0x3232"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 35,
|
|
+ "signature": "0x3333"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 36,
|
|
+ "signature": "0x3434"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 37,
|
|
+ "signature": "0x3535"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 38,
|
|
+ "signature": "0x3636"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 39,
|
|
+ "signature": "0x3737"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 40,
|
|
+ "signature": "0x3838"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 41,
|
|
+ "signature": "0x3939"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 42,
|
|
+ "signature": "0x3a3a"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 43,
|
|
+ "signature": "0x3b3b"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 44,
|
|
+ "signature": "0x3c3c"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 45,
|
|
+ "signature": "0x3d3d"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 46,
|
|
+ "signature": "0x3e3e"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 47,
|
|
+ "signature": "0x3f3f"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 48,
|
|
+ "signature": "0x4040"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 49,
|
|
+ "signature": "0x4141"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 50,
|
|
+ "signature": "0x4242"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 51,
|
|
+ "signature": "0x4343"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 52,
|
|
+ "signature": "0x4444"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 53,
|
|
+ "signature": "0x4545"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 54,
|
|
+ "signature": "0x4646"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 55,
|
|
+ "signature": "0x4747"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 56,
|
|
+ "signature": "0x4848"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 57,
|
|
+ "signature": "0x4949"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 58,
|
|
+ "signature": "0x4a4a"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 59,
|
|
+ "signature": "0x4b4b"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 60,
|
|
+ "signature": "0x4c4c"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 61,
|
|
+ "signature": "0x4d4d"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 62,
|
|
+ "signature": "0x4e4e"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 63,
|
|
+ "signature": "0x4f4f"
|
|
+ }
|
|
+ ],
|
|
+ "bytes": "0xf901850380f90180c50180821010c50101821111c50102821212c50103821313c50104821414c50105821515c50106821616c50107821717c50108821818c50109821919c5010a821a1ac5010b821b1bc5010c821c1cc5010d821d1dc5010e821e1ec5010f821f1fc50110822020c50111822121c50112822222c50113822323c50114822424c50115822525c50116822626c50117822727c50118822828c50119822929c5011a822a2ac5011b822b2bc5011c822c2cc5011d822d2dc5011e822e2ec5011f822f2fc50120823030c50121823131c50122823232c50123823333c50124823434c50125823535c50126823636c50127823737c50128823838c50129823939c5012a823a3ac5012b823b3bc5012c823c3cc5012d823d3dc5012e823e3ec5012f823f3fc50130824040c50131824141c50132824242c50133824343c50134824444c50135824545c50136824646c50137824747c50138824848c50139824949c5013a824a4ac5013b824b4bc5013c824c4cc5013d824d4dc5013e824e4ec5013f824f4f"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-doua-elemente",
|
|
+ "valid": false,
|
|
+ "bytes": "0xd203d0c7018084aaaaaaaac7010284bbbbbbbb",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "two elements with version 3 (the v2 shape)"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-patru-elemente",
|
|
+ "valid": false,
|
|
+ "bytes": "0xd40380d0c7018084aaaaaaaac7010284bbbbbbbb01",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "four elements"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-runda-lista",
|
|
+ "valid": false,
|
|
+ "bytes": "0xd303c0d0c7018084aaaaaaaac7010284bbbbbbbb",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "the round is a list"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-runda-1025",
|
|
+ "valid": false,
|
|
+ "bytes": "0xd503820401d0c7018084aaaaaaaac7010284bbbbbbbb",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "round above 1024"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-runda-820005",
|
|
+ "valid": false,
|
|
+ "bytes": "0xd503820005d0c7018084aaaaaaaac7010284bbbbbbbb",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "round 0x820005: a leading zero byte (non-canonical scalar)"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-runda-trei-octeti",
|
|
+ "valid": false,
|
|
+ "bytes": "0xd60383010000d0c7018084aaaaaaaac7010284bbbbbbbb",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "round on three bytes (65536)"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-runda-00",
|
|
+ "valid": false,
|
|
+ "bytes": "0xd30300d0c7018084aaaaaaaac7010284bbbbbbbb",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "round written as the single byte 0x00 instead of 0x80"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-gol-r1",
|
|
+ "valid": false,
|
|
+ "bytes": "0xc30301c0",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "an empty list is valid only with round 0"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-ordine",
|
|
+ "valid": false,
|
|
+ "bytes": "0xd30380d0c7010284bbbbbbbbc7018084aaaaaaaa",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "rows not in strictly increasing (index, scheme) order"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-dublura",
|
|
+ "valid": false,
|
|
+ "bytes": "0xd30380d0c7018084aaaaaaaac7018084aaaaaaaa",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "a repeated row"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-schema-09",
|
|
+ "valid": false,
|
|
+ "bytes": "0xcb0380c8c7098084aaaaaaaa",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "unknown scheme tag 0x09"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-65-randuri",
|
|
+ "valid": false,
|
|
+ "bytes": "0xf9018b0380f90186c50180821010c50101821010c50102821010c50103821010c50104821010c50105821010c50106821010c50107821010c50108821010c50109821010c5010a821010c5010b821010c5010c821010c5010d821010c5010e821010c5010f821010c50110821010c50111821010c50112821010c50113821010c50114821010c50115821010c50116821010c50117821010c50118821010c50119821010c5011a821010c5011b821010c5011c821010c5011d821010c5011e821010c5011f821010c50120821010c50121821010c50122821010c50123821010c50124821010c50125821010c50126821010c50127821010c50128821010c50129821010c5012a821010c5012b821010c5012c821010c5012d821010c5012e821010c5012f821010c50130821010c50131821010c50132821010c50133821010c50134821010c50135821010c50136821010c50137821010c50138821010c50139821010c5013a821010c5013b821010c5013c821010c5013d821010c5013e821010c5013f821010c50140821010",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "more than 64 rows"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-semnatura-goala",
|
|
+ "valid": false,
|
|
+ "bytes": "0xc70380c4c3018080",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "an empty signature"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-index-necanonic",
|
|
+ "valid": false,
|
|
+ "bytes": "0xcd0380cac90182000284aaaaaaaa",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "row index with a leading zero byte"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-versiune-necanonica",
|
|
+ "valid": false,
|
|
+ "bytes": "0xd4810380d0c7018084aaaaaaaac7010284bbbbbbbb",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "version 3 written as 0x8103 (non-canonical RLP)"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-rand-doua-elemente",
|
|
+ "valid": false,
|
|
+ "bytes": "0xc60380c3c20180",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "a row of two elements"
|
|
+ },
|
|
+ {
|
|
+ "id": "vc-lungime-necanonica",
|
|
+ "valid": false,
|
|
+ "bytes": "0xf8130380d0c7018084aaaaaaaac7010284bbbbbbbb",
|
|
+ "code": "AERE-PQ-V3-03",
|
|
+ "why": "outer list with a long-form length for a short payload (round trip differs)"
|
|
+ }
|
|
+ ],
|
|
+ "VD": [
|
|
+ {
|
|
+ "id": "vd-r0-28001-999",
|
|
+ "chainId": 28001,
|
|
+ "parentNumber": 999,
|
|
+ "parentHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "certificate": "0xd30380d0c7018084aaaaaaaac7010284bbbbbbbb",
|
|
+ "d3": "0x1897321916421f85c4f8dfbe4c8175b6ae471289ed36f979b9beff0d18380058"
|
|
+ },
|
|
+ {
|
|
+ "id": "vd-r1-hibrid-28001-1000",
|
|
+ "chainId": 28001,
|
|
+ "parentNumber": 1000,
|
|
+ "parentHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "certificate": "0xdb0301d8c7018084aaaaaaaac7028084ccccccccc7010384bbbbbbbb",
|
|
+ "d3": "0x86dce0ecc8add933368a081470f5df3b73f9c93e1d56a69e9fd1abd14d26122d"
|
|
+ },
|
|
+ {
|
|
+ "id": "vd-r0-hibrid-28001-1000",
|
|
+ "chainId": 28001,
|
|
+ "parentNumber": 1000,
|
|
+ "parentHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "certificate": "0xdb0380d8c7018084a0a0a0a0c7010284a2a2a2a2c7020284b2b2b2b2",
|
|
+ "d3": "0x949513ad3546ae8c66716adbd38e653c4e6c4d78677fe76a2e8e3313f3230a39"
|
|
+ },
|
|
+ {
|
|
+ "id": "vd-r3-hibrid-28001-1000",
|
|
+ "chainId": 28001,
|
|
+ "parentNumber": 1000,
|
|
+ "parentHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "certificate": "0xdb0303d8c7018084a0a0a0a0c7010284a2a2a2a2c7020284b2b2b2b2",
|
|
+ "d3": "0x8cce761fab70ab5159df6d09e2e7e8fd20ec7ba442765a9bab6e9abbe86e3320"
|
|
+ },
|
|
+ {
|
|
+ "id": "vd-gol-28001-1000",
|
|
+ "chainId": 28001,
|
|
+ "parentNumber": 1000,
|
|
+ "parentHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "certificate": "0xc30380c0",
|
|
+ "d3": "0x5fe600bc94da68fed339b7c9999fc8f4e402017559f3642c6df010d7138cedde"
|
|
+ },
|
|
+ {
|
|
+ "id": "vd-control-d2",
|
|
+ "chainId": 28001,
|
|
+ "parentNumber": 1000,
|
|
+ "parentHash": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
+ "certificateV2": "0xda02d8c7018084a0a0a0a0c7010284a2a2a2a2c7020284b2b2b2b2",
|
|
+ "d2": "0x233b4974075d102e94e660aae44ed9abca1c63b127aa3497a5cbeb465faf5ded",
|
|
+ "mustDifferFrom": "vd-r0-hibrid-28001-1000"
|
|
+ }
|
|
+ ],
|
|
+ "VS": [
|
|
+ {
|
|
+ "id": "vs-28001-1000-r0-r2",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "hash": "0x3333333333333333333333333333333333333333333333333333333333333333",
|
|
+ "groups": [
|
|
+ {
|
|
+ "round": 0,
|
|
+ "rows": [
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 0,
|
|
+ "signature": "0x39bd3aadc5f485f3f17ab3ef996de30f40a4dbb98f4c70db2fbf505d86835dcfd8e1b067a325d98da059a8597b2e5ee62751d4fd8efc9985223f68c9b2725df62d7af9b091a129944bb0d86464ae20b5bd1c5cf3b29bec1fce23c562d6d8d3ea81215b2a061f05e1ea271c4f5da79f528ae113bb9ba6afdaa1eebb715d3171344fd4bce746d22de14f5a0454a7e371086667b9d586907f6b6969a528ba9ce5ceb7c8cbe30c939b4d76d3eaee2882cc898f374b94355329fae7e6d591e9166d7f71d9c58defb0bcade36ce313d62519c41a7973b149b4f2f8e51d6afd5154eb794343a3acdcc7436e4ff22dda41b236295314daef2a4b98c5343684e20ee7f1f6d27e4a66eaa79ce6a32b2fecf43c43237a40f3545f4af5f6d93109d8e15da5f28db19eac72f8641d14a079198fdf9f8ee292b2d0fc7d3fccd68525dbcfafff2a9d29a3cc361e4674d29e5af5ee408adc0d9725f7939065d0ceef4a4b64c0972943a69739b0aaf57562533888315d7a5d24fa759ed5661454ee58ce491e5f2fcf0d07608f524c50f36cab968c1d8cbee3313a7854744d1cd7e5ac70e20092bab2e5c59736351d014d71af7c19926b232bf1bc36676f81a1a6f7166e97d8e066f6a78d98f13974beed35449f3d9506fab1c0ab356b092273b42d4aedb6cdbedb736e6928fd2d4926b94106fbbf0923e3b759e1fb89ecaf24bea45bd406d509d611550061897b71c39ea3fa6a8f47a50a31849546df90137114491b55ce36fe1d6f64851c8647eb5906d13369b97ab5721a44db1f9d7712aa45c87f5f8b8bef5c92a9f715c432ef6262c8d22af0eb2943e40cda27921cb865b7d79a4b70ec14f7deb96916cc13eeb764a5f3f35189a9bace816de3f88b57aecea4ad102412e121f84ab7474a04d0c0d92526178821f0dce4"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 2,
|
|
+ "index": 0,
|
|
+ "signature": "0xb04a645ad8d00ab495a1abf55dcdc235878fec9db0c64b021945e225e20fe4dbd3f148227ec3f11a5241706c3941ffff52adca321f313d8155be79374ea93e2ee9fc8e91b95cf14324d936cdc4cd2a54f5d499562370820a04d141492a0e8cf43aff6ede6640aadc4d978d41025bab7d9a76d7b593cbb3d1753bb84fcad1bfb64ce0a9a708fb3c183b39e94582c983805fa040dc6063f3311c3e932085b964ad6d608c689ba5d7ef452c7ae27bb66bb706a6e413182d029285acaac3252c309fa9eb7da2bbfca67359d74947416a5d399a50cef4493a6ba27dfd43a60945e7a709d0c0332bb1f581e40ec93b62acde90caffbafd1e12738b6873ec38bd33908f94302058298a1154c48454796f73ff325faf6c435405a9bd6d6c3453af15186974c311d8f4fc384314a88932629c141779bfb8b039183d550c9d65f840c64b97fc81d672b91e5db8c2f11e6e910893c67c5bf8db89b209d699a4ff7c02c96b5e791ae65c2afb94baf1d9e6277f7c4583d3a504a932892f8e5ecb92e217d0161c32e643c3ec6e86adb91d1da9bdbb1399b50008e2ed446a719a63196e0bb4ea7b548df66c93e1e9bc65c5149db54d8e2fb97ae5573182b56373463fd259cad0f36b54f853b0178d0959ad4941e63658525c1489f45eeaf173dc8cb24be5d6cdc6690fccf42d53ea72171ebff5090cca10e3e7ced1d33a8b7a8afc3427c6bc3360dc7f111c62ab2c65109332315c672c983966c4b6fecd36242605bf81722e0c570354bae6eea7eec53b55fcc4160c2e6f2b6cb712ca31fa5a21f8ae785da5fe0560a3f87d7fcbffe06540f2adc5489feceb1777613715c50605f22bc291cbbd74ea037e2c749b76574bfd9b14499b62828bbf12a19d43ad41fbf761b089f47420a618e7b59138bafb843b7e64dc15b672f05705062f42655b0ea4d21dc5b326b5f038a550c2b5b956e19995d8ae6d0aa580cba6034dbfe55fd0600e824fbabab3e195c329b0c99b61d7c0691d72147c614e93dd8bee087d2a501db32a65fb11b6a2e5f983babda2406a5f409ffd531fe9446f2bf468b132fa662c8f476fe35061c73824a7d2f6e6bc5483aa5f97c1a816e1131dcca03e98bf347fe6fa66f7c08eb5f4000ebedd6d1f5f74847bcd17d07c66ab8ec09ac7a9e9fda156efab32ee478b41b1676c61d69b9e8612118712f0998a4f2b3384c1a4fb55d71146a15986b461a93f549895a1c9d2a32c8f6acc60f926f6f24450a8d281eba1d42184ce6670a052c289c9f00bc52610792d4327244c984e6d789faf36c3b15d3298f2b9d0205c66fbcb302097ad29a0d98c943233f75e22c40436e08868e17e5c29f249ea500e4d381e2b0c949a51b98b3e8ed3fe0c94f5801d58cfa78fa96239c97b4278183d68b9d0fc17be277036513f8593285aaf46ac566aef4c5390b68d2dc937f2f704dff3e675cf3def2216ac9b1148aef653be944c185eb642b2ab9d8edc9d5dcebb41ea33887aaf1d6df7c92593dbe38f308e3b6fe4c5dee0d81f08cd86a721a7c1feb4ac7c4abaa65c5a9e5f41b17be59b449b46e5d271b343baa346c24598e15f9ecab7c9de5862a7b78f75f5079926760cb1ad6e3851c248e12eb2b657a7adddb4ddf415cfb5585045639ccb7e4a9d02791b37c43891e040243151d68bb91547f6a53889090402ba84b0ec43b5cfb27a7ff01f349101b50d338831867623bf2886d5c679bdeebb714d8686321b0be9e2ede4605fa3c6fe6d55d82c8982d9f2356e9e0665570552206370fd635221f637dadf48dbc89f8cba78511cd49c88227d238069d73b04d0b7f57150827946ed44d391a79609f8b18443c445b8c690e6c98145fdf47fd99ba62de46705886d6b8e23001bc01920dd38304f37c94e895dfcade604cbb5780d1f19f2dba3aaa45daea0559c91ab896568b6daa4c854c906a5ebd01ce7a038a71b9fbac5e9856a0f50b62326b8bcf17956a627ececbdd1b922c0ba2963919b988a4b1289b8e45c92741e94b1b8317f4a1e47566bf53fea4bef7697ee04522bc43f90f605646e0e2cf7bb49e499c8f2395a6cda3d55fe1218cdf0139c52c4ea5d556397dd77f1d53c31cb040a52d66dcaa4cabcaae83b9d1fa807dac16ad18b487cc3b2c026189ac4a0b3724cacb6f008928bf8d361ec5c3098b528444296a45f142dba8696db82b596b8ddc420763acaf68a738967260e592677d5fe24b31b99e2884aafd11dc22c28b0ed0e3dad21b6545f587c0a7d04b77f5a1bf170d7c50c3c5b9505a8dba065b488eafbff7e1dec22850e10fc97715948768b0d63edd7748616cb22013f4b49a6c1581beed6ac019fb941b93b3cea858f05d3f75a59f430d0b44f1bbc20bab919558efe3f6a5ae52026e460d0eb8cfdb3a2d1cc728d44f5819f52a0c7331563ae1bad62b2fb49136de8030ef1dcd745e4e1c9c2f3db86e6c9ea6ae1dccdcae62541d01de5b7c1069396141a7be3559f1195160a38269a26f14f925f39ea52e9444bd4c2f68e767e9b197ecbc25218b7c8b60d1530496afed51fa58e230641221bded814d9610b8b1f472b7b9b0fbeb2a288549dae98521a4e958e8e50c7e1c6551152296205703ee5cb8ce85161f47e8a480b126ea96b2d63c8c2cf83b45d54120f49627d011bb8bf039804ec588e7a16b97b21f9f12bd811af15c07de4ac369b182da0bd71dac83d544fd181be78d29cf111cec43d496b514d5e1b40fd5103f3fa260ee6f161f6b4faf3fd6c9b39e5076b1f131e519abab53b5e421890b0754f3afd85213eaf0a092af028ee2c94a894e5938c59e777857b1d3a728c2c986ed03a6f4ff1c1de439b61100a0e6523d9ebb62c812315be304d19975f9560f5fd7b1a82b02dffab6db711df8462978effcf011203edd2a8f34223c47cbee141b3b39780e43708c8fa76d34a862536d91ba7422c5e65052e42678872a80a9669d5083280440bc90725bdb067181bb7a5e4088d03358022527bf1f626ede6b37deb7bd496211855272256d00e2ebb308d3982893e878ab67d5814afdb24af656f0968f0bc0c063a64ceb0431d048c3032c55dcc8680e113f046a223fd2d3b23a8134f8be07c509e18bc70c52e93102a8d32fdd8a9c3cf50d807ee979571afbf9f08dd23ff0ce4116fc4b823147193cc67f8b922c1be6892d276e0dbac473db17f1003c38c34c07da91091c3af5f3e4c423be6d526a9b8b37684da5cffc1552faddf4d0f60dc591bf9edd213402f4b4ef635c92bef5132e4343d0b065332d7e98b9c70e364b889cd970290edbc80325ba4bee26bc39044428746b502f3a9a58f1a7797cc6df8711bbd8a38bab0416caa5b0e2022810b1024e3520cb587df8c5f6eed2dd6bfb941f550b3872e15d024c2c75e4e80fc15f78e2083cd08ee1595e34e75c02c12024cf1f34a5bc6f7bbdb9c7d2bcd0620d7840143ab28d08907fe8a214765da83d42566991fb0eaa3f2fb4515038b9b824aaf29e34da9040f9bb2f2e06b95f2767a6264b163205abf3bf0aef569b9c47493752e5a664ab55ed75ae5937245a390b6266da873e098c61883e86e4ec832e42e8f1c763bb8e99fd389c7db7eacbe9c270c1327527d232cd2bbdd0b3f0357b1725f41c2f4fc772c0ee1ac40f62e34480547bd7ff705074585d131e57da8e320611f95710af1c5c266a0430b0021e2c27d039803e575fb0d424a29af75fd3dcea32700de27e5472ae8395090cc2ca40f39bfa53cb79d3598f4bb96b0f8e9a60543ed954e45282be914443649befaad010fd19ec21472ec7e1b69d2f7033a65c07549c22584c1ae358b007e52d20164dcc13a787db5f512ac845ee0324833fa24f416a778578ef3aa0d6dd209473719286b35b8460ad0568d954ee5c3e17d709188d9ce4f87f2e7ff0d01adaf766649b4539f7f9b336d54c0761bfd0c15c1526a8c0cca95665aea6907f0a6e58643dc20d400f46a2fba86a31bd13f7908912093557174a985f1fdb91b68a30ccee379385e339b983c1d2660f93d1c030f041ba4a23efdba9da621d957673d66705dd502bb7f1ddb760e926794878260828e6a0951d8d77a90fb1fead9d3ed55e48fd3a2289564814e62f216186cee9306850e19adde3cebe220b570e3f6950553fbf7f9767075c0dc456ddd3ca9c29e994de5b513709ecb8e610db6802a3de15b6b5b4963394b7c7b062869e1f8829f70ad2c075a7fb44777842389a5204811fb30dc1173b7c53449d2d6d50b32c73825e27be01c73b42f229e134e7417cf5621e023b9d2f3556bc02fec6a0a86614bd3b62e31f436321e8a2e1be9733e94e84db8ae4cc3ab40dc035779af21e4c2357ac72ac5f79d6decfd00a38101ec3074a4bbfcd55cf2afb3cdb4f44c53834b08e6aaafa51caebc463d315cdce59e0de67df69bbe68235fd9351f26c4e3eabcdc1d6130e44742a18435e96313852630cc9342a2b49a4b875fcf1830936aa0368cba7d954aabd1e9abcf044874b3c650b78a3925f3f01dcd959618ece352a1346203f70aacb3f45ad2d15d6a2d8b22b99f55057b8efd22fd8d1cf950a3b7703e3f7a9d5d62af451b9ba32a199dcd345c39647609c58e6f7ad0340165f850176c8e8a1f8b20a96e3654457e20afe0b30db2ff6c72770383ee75a910f676332bf6d35a6310336b2a23bf0d1dc30e7b144207f5b9dc1be181632190c53913d18b6644c3ae00ba5b3eb6a8350a22c87da65fccc233a814c8fb21c3c56b137a3bc6e1ff9fabd32f27c693c043158e445ae9434972083bf45bbd6d5d185aa32e85524147bbf026d686ff54b8b9c2e4de35d32072b394867cb126ddefcf26b63d37a7d3c09b38040aa7c006ed6713c769857354aa7d9b95e3c6d58edd7eaeed2208d41bbc5cda78440aa747dec89259c1644e4d7a41d50cc8d46c3d10efaa9791874a9f3df9738c66ffc6d638736daa1302d70a8919598b15b3b3fad18590321c11998bc3161b033601f5fcebc1df369232270a16a6cc9998035c1c49792211e9941e362e8db5623e24280e5db8d8e6605c0b5a91212b7993b84ea2970c524bbaa78a05406b9282a8a86cc529b6c128b99b637197cfac7d0b730fda3f80c7ba72dfc82c1092bae4efd4e169220cbcec19cc88031aa9b402b4d2c20dce8a24ac33b6dc501852a29d595f337ec82bf16021065a7375483e1b3ea58d0fcce31537f24e640b0607e736bb8f4b83d18c3bced0819680e78fc46b6ee6c10a72d01fa7b9d5f8d6b3d834b5d0c881262e5a44d4ddb4fa19927adf705824de725467817ba6a3fd987cd976c6e6b6c196b50b2bbcc5f6e976b13b26881c41acedce5ebe075020007ca737c21138b98f7625ef4a7fe19f56721cdf21f786f396ee7abf62295a37ff1ddb1c65287dabfc7491dfa061060c6e9458ea231d868cb1c6863988a0014ed6b152438c79c2b74468f07d0de1351172345a9a31049f52c38840b42e67bf68fad5871cff9983bcbd1293f3c1e9bdbb658a1401fbe2bfa9d3cc32de3ca5156256269a6930e40aab9d1a2b06e57959d541694a4d6ef918f1aded4554694b67ad67086da6d43a0e9df85ef5d30d91f1d1f789b444e6e164a0cfef372e5f98892fceb2b5909301f51989bf1e5877eabf3a13e7cc09c68f441e80417b341a7bfb575c4c5ca9ae540a73787ce707b51e03bae956503936d17dc6129b6f83215bd409a5bd9a74b878358d360e311090a1c706244a58a9023c9f94b1bbbeb5e4246bb36e863e9b39bc0a717dbd957c43234cd0c5e9b95a1a0b7a16c47ce07be6bc3f855f7ecd542311cd2081f8bfbd1950b1495de54b15defdb9c3725535a68814d804912fec0488bf1f6f992f9b1ae3467ddc98efd1e7d8690ad4c31743342ea094ac481cec9bf755260e67dc28e4f25def2782c6b1396feea479ad04f61797e1b5bcbb9a826c8db993b8cd56ffcd575890aaf3b24e2f300348a708fa1236dfa2245176014bb3799aa30a6ede2b10bfdadc1fceb863039e0db2e45191b64158cceaf090071f5cd3f95ab7b8f6b6406e6e7d486bbff9d0d298fa8b8cad2c69438951b2abf744428f9e0e1f838e6709cdc4fed2bfa1b5c43ce2ca68edf4f77b5faf89a5a5e41fbb7b599a08fa59419326447c507fe4e3f425eacc26c6a7334a9600250e0cb598d1b1830f1e92c145a03f1c695e31a1540604ea6a7848aee653cd501fe2d9ccf777a655a25acb08e0cc49f039c0975a4189dc7158d35343eefc1959b2a320b82322ea5aa93d9c803816ae01093069b8dd9544b06c7555d5bd74e6c2abf2e2ef6ff04aa1a5c16a7be046d8dbf3a2796df0057a4c012f0df58b55112528630e70caa28b805fda123733de937afe2157c00b8fb026b75cd1787fab07ede1531a0111713566956772a026461ad6fb23c5b56d89c36c7ccf4191641c8400a400b61b83772a4958b86ed63b9d4a528ec85d4b4e72c853cf4079046b05df723bb3fe4f3d5587cbddad1f11ee21df03fcfd312bee42e0c9863009213142b48647691b2b55bb4f102223c033222c8c26fe69282505d8d9d1515e0d302c439a840bc57831e4edd751c27b62cc9dc28f5aaa6d43eb2271e02a3332c885964db0513a9eee7a22fb7733fbe311e815d178d5df6e1801756d4a9602ecf9f3b71b80c82a3997d0b2892c3b0cc0b86d36bf2fdfa132e5e99a446a33c1777ff01c92bf3888f62d9f518004ea21c75bf6de90089224cd0a92d00f9493f1650dc736c5f9fd25d7c54e3ad2f584bdb5ded06673bfc41d213cccedd945b02c0140f2b93906e7f1f3d73905ad4250a2fc1f8a3b63b8557ad9f9d6e2814ab316b37134292de3180caf1bafdfbf307a993cddcea6e02641ed147cbf9743c25d816236c0a37b0ac01086d21d755c4ee3a6eef1c2005d99fb361cf19ea0df5501ff757ef33c0e20dcd317a033e51659af249e1257e7ab177e80573f66a8755d8adf08e69cbc22d11c87105ab56aff00e96591811e19b27ce7a7caab152710df5f3412e525f70933ad3a3bfd9f627d30bdcf34495e493b4e74cdc91cf4920803cbf8120439ec3159ee9600617c2f2043f84617ddd8e31f82c1a413d3abb21b53ff64afbb5a2a42863ee021c8ba4154d8e017374a6ca281f17fc88b1606af64828dc7114ea8bef8b39b5d24b848aa3106f8bb8f09a00a4795aa0d8b9a1e39cd081c4afc773a7959d22adf2b92a316009a24686834f64273d529d156dbcda127c44115897743b34ac26f1ddadc09db5cb27cd946dbb66a846381dc4d7b4c5768429b5ca03c16c19476b83bf01258bf48aa564605652b87fd51fa4252527dff906c51f5304fcd32199db884a5f487ba0de118f0033774b456b4112dd6079754c05a9269ddc4a905a415ef44a1a24d00e918b3dc3ff57d91f4e33a61c0a282cd9521bed291149f1dd37a7a748b0265d00137a8f28e648ee632febec505d1072c542cfbb561836f0146a17dcff0855fd237efd802c2d81591c2d5a46a140e5a571fa16e563220393da247d3e842683b3eedfe885e33b63d942e65b1861c5fc08a31a81a4341c795d4dc9cd19233816317ce826bc3cdde411ada45e62fda38909c7ea8e891801a85a81ebd58a2ecee99266855793c448dc4fec234b0e5e39661de62ce31ae723692dca2d7309749fdaad058f55f6337b6db5d3eff49ff39c441222bbdd14a2f84d997d58a4227acd0853699600f065942d3064096553dfcd6e4b3e6802823c907a0598201be0727b62263d879d170383ed4b4ffc296dbc32ddf619a14148f27c1518f192c1f2280af4b1397a3adda07a5f3482526ed2cf9c1ac4af9191e9271db6c3ebf8d63adaa88bd36aa04a0fe34f7c3cbed5175258b0f028727e713dd04980eef58d669cf9758d6701e68e3225e8a34a410e2b57350c4f5c37f4b547a1ce677a5a204d068cdedafbf44f63657eaf60b27ec276d4ea560faf3f4074e8d0489d293ad84dc742fd63d4c00597007c53fc45f83647def72163de949f906cbfc0509ceb468376e220743fdef733dd3f0f97f46d530fae025941c7868963e2bae5f94ad980a72dfd781dd52b7f2f77e9d22d4c735644f46391ef8a9d22b02bfc302956691330b096993b5d1626d86fbc823cd617130286c1b7e47604c29fcfe52e76af83ea3e78937b1e54abd5d284f276c9e9b80a0ac165af9c4faca72a64928d6e86e795a6f01a047f87a890e1ffc60b390046ad7036afd996bf9ff2db53406c0ce0e333152178a32012db88b02726162e4e356b859dacd183eb9ab5d478ab1a5e5e5579893f591ce3c02f9b64d26dea2ce034ad06502c4ccd0a44483c4ab0cd621fa8683455b133e103c5fe2181f93f5681fac0bde7e849398ab302988c0654b40d91b69d18e32675d8e32b35cdd73efeea37e49cc2efd8d31e5a722ba04d56c57975af32fc0085d2866f06daae82fdd23479f6221896a8888962ec78c485343941ee76162551b0fdcbdbddc14fead4767144f3c92fccd31e79b86f5157337c5c2da9194fe3f2adc6ef388d0ad9b670944a790a58723cab465f89e9285268e84d0395f9286b947c0c9936da548cdef820a8f60fe3938fc70d0304103319c43f122b5fd04a0a3b90f22826c267c94fac91e36ab2572dfc211f45094f4aa7d2672955c73723decf4167698e27d330861520fc3ec4e081933e4dea66c513770254a9113910417fb90c004e11d439b39da7578de0547f98d141f15497395d1799df29dff1d074cb49d119d1e743629a1e1f810285e4d0ef32ac3e086368c5a465bf6afd8bc787dd8d5d7f1f0ad9d218ab6a83b2f233a147405eee13f9b1499ab2de89f5b8da0c3db11c4d8f2d02d7274b97ceaa3f561545baac10c6a0b2fd95ee8ace160f561b285bf5ef6c393b13e3a9ac42cd1a9ec94c5a1bea7c7734ffb4a51c58f0ce98c5414c0c76d5d2d5b8ca1c3a256f3113d9fd04213488ba16ade9cd92149d4a19ae849347fc2108e569a0f2289347d78a825ec1a05f2c8b11097439c0da067476b6d19a12ea866dfa6942c5ac460fcf77710aeb9b61f434b8666f35ab54fc07662f8a38b8b3c2534bf6bc01540de7d0ade8c975d4528775ed799b93652f5542158398e8d348ec32be403b7c15d7a482ce0990efe0e034e65cba275c242c802f0a7ed1494369efc95870c2daef748672cc9b7d68bab41b5aeebdc9cf8168d15b2301ab21e3a11a30c2a1561c2834639d8a398b629d4a8a5619a1d2ca5a2498ed8afcacc4fac615c61c4cabd4b7a93cc91b126df93852a94da379e8a144571fc4430da3f38beada24b1ad654f795ea04175f1d2e77d2bbb7b1b6c8b36d14e251caedf7adacf58b26bda3e57856348ce3d4efd41bf2f5c17f0db9f689044e6ff1eba4ff11cb4bd545e11fcad281a4f10b9d6637e2f027c4b07d8a93a1ef174d636000fa30b38cfbd2a65553e24e45050482438bfd65125a1bc5f289cb4e821bc2cfa82b1287bd2d2680bb0111c56a1bd731cefb21a7ffd58a8eb027d42928833be272c741a67f5c75e74b3169c6f5119592e2c736ee23430c79926476b3c455e37f0b788218044b49a5912153660939d9d1bb2ba481c2c3bd2c2f5ffc35210eab8f48b23adb999912390c8d38bccbd5704f7c95b7ce33ed1d8621b5c249df16ed02899f4a8de149ec6bf485ad49c744f3dab7b24a21c977b6156b060071a305af2f6b5a7dfda458be4f8aaf007d71cb326a52815d2a8b8688adc0991199634a75997732ea1cecddebc8275c623b094795d5029a8dee5135e767569f72166bbe06c7f15e5cb0756bfe17f2c5a96756971bb640ada85ac15711a6abec03f4e0bf067eecf7e1ab44714ba511efdc5af11726cbeb6eff38c16bd6d5e24916139c434e52c789a3d76da81f27cf5d5c7a4a01e0fadb8441b6e3f938aa6dd75c772fcd3b66ba5cb2eeb1b66d8f343805712bdbe1dbc359907263f90a7fdc7958e7fc514ad914383aed1fea67b6351ea4a0f22b98d67c9d607c89fcc05717dbb3f67ec43beb9f387cbc7e1ee214ad02c0401a198f2c5bd7d9e7945d0f7b8818990a9bdc87f5b123a342458acf27dca726290cc027c874ff03f57d13f840293773a63f0f4aaafbd961938b18480bf8b140ccf6cfe57bbca7e693e15b4c504bd3d3e4bfdf5051ee10fe540cae980ccf5bf7db196fbef7142dfac744aaa1660f86c8df21551497e14532de29377b9708656250567b127020c2923172c4519109c99260411799a21815a41d35e984d9af778d83be0c42b8d3790c84a2bdd61ca8bc53efdbb7ccc1c0bd3b5918e3d3e7c8cc67a54e5de558059140741aa9ddc75a3306153e8d5f63a10843cac5e81dddf8949be87423677ffaff9a8a7473e5d7dea5c23f300981817fb2955ef5ad27becf3e488f7f3f6f4c4b5054aa778844638705ac4f8bdd701c38d58562cbbeddc85bc9694a289921b071c650f46f8736cfb0bc6ed1b9104a515db7814f9f7f1ec5415782b69f64e85bc5b959f49fd9eceb08ec4f70c0b605f16fbededa35aedbc4463368d77694b4f4b683e472eef36de641a39e09f835c7b627106a285a084de8a8b8f8b0d065428404c5e4b5054bc018f526b0d8ad3969c15acf779bbaaaee96e9d8f2d690d163f2e1d75e7d064d4d304d8754779c66c7483f6a1a7541acdd118ad0999108fe7fe2fcde3dfdafa64cb7a9df117733b27bada89b92932bc29b2b33ccbb62e544e9b50223b8a44d807b3c328f763cbf4e6084d1fa03866d1a295b894195be5e11b88082c26044e17b870ad8a1e822c65f34fe0b8cf59e5d21f98adb5585ff4f52c86511911f512f31b41d1114edf2b60965963a43366c08b8f1aad223b9d8494b676190160fbe82350b9010e8750a7a8af183aaa3b1913c34e1f8f51982ac74616a6036bb03510c67db65950bf12f3df281b31f48ef7256b08d8bb89faea78784435e40c203eba007504b9e1e1317069cb0da8c5f9d15191494c2dfc4f6bb5778d4220ddbd87d4a0e03c89e72d04c29f4cb0581cf43be3894624f4822741da52f9cb4a37bb5cee591279d7bb75e7d4861afd69515889318176daffb49fe2e95a4832ebbb974a118d069c39e69d568470a48dcb063c250653387afc3cf41ed437f8bfaa436a513a26f357c"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 2,
|
|
+ "signature": "0x396a36b66a0a22e592388270709d8157c2723ef44785eb78273e04d136262e2363f336309e5b727f3678f3e4a9762eaa10ab21b3126953c5444ae59d76a6f2b752a2166e0ed214ba9468e116ffbbdda85c03c762a2b9682a6e93f0520235067a15119c620d3c8cd56c69064277a3d7510df62cc91cbcfce9ff20b36c22c19f633ff97f7fdf63b756ec3289b9a8d7adb4c385164a6828b665f14e1dd7c7319dadf51fe90658945a902d0a29b8f7fc38395847baff0983ba3928069988906b99751d12aa3c536e4efe87032cdad83b91506e080182df4151ca2abf9887ca157599469c28f549b8d343786c7666531cc4e18e6235d54962acc31e711318dc619eaf29d4ccdf3b06b430e2b82fd975e73e38e10532fae497c64e13e8622c5f9aa41a3d5ce655a3c2f58c824bcceb1548c662e1cd9272c631268b8eb91471d0acd73add4bc2eccab8d36c6c27030ab175146abafbbcf0e62bd1c8d6715ea34df30c090de1f4a9ccb3d7bd5cb05b4c855bcadd5c96e43a89c7934d49e294d954e0ca75d677a0695cb7734f8d404872c9fa64b20f3283523d1f2f9a657a69d89a9923bc3ba9873e9d1481e89b8d46cc6b72f8df5f0e66f346e859a429547f6e102f8342bf5c25695b5cecb508dc8941934af2a48d04451048d4060a92cb3a8e648262f0fa3b13abe7758d250c85f657c0c7ec7cc8d1b722c233404e8b3792d718b423c40133fe5250a2cbbd6e10f42f555670e378236ff4452a04d29116bfe1a38c2593215a23e6a90f6c083cd84866554e86069d2e797b6f7c877b40370ed1077ecd03d19859dbe4a4989b47d60691776353a9b17ec1644e0f0481356c923a4118458f9cc29ca6c57aed3f0cdb10f079216523c4b5d83e333618e815f3423bcc37a923266bce432b35ea1b168671accf68adbf74"
|
|
+ }
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "round": 2,
|
|
+ "rows": [
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 1,
|
|
+ "signature": "0x392d747efa5df9ec7976b575ebbbbc4e50e48f494255067d00c8fb6ab805f5dde05d0240f101c33dd0aadb317a173e25a7dec0ceb77ce150099f5ca19dc2df6e44a5b5fc87cab441dc4e6ee717e77d3ffc2bc57ea828567dcbcdb8831dbbb613c0f747fc497e218f903efb5f5c5a2c4e61879bfb069a67eec30acb8af36d1f4a245b9f120c6bea336d8ba3eba72be78a3ded415117b3ed0babab6ce775e1c1ebee9d08f4a0923ef969747533a3a9fc13d19b4c5b1eabe6ade431ad5731c5ccfe98681c31ade95e7d5bf469024456082d06df3fd4e6970fc2533bb9cf6688bb595edacd95f68d1b31a396d8af954e37fd43d6a366757853a1185d62e18587e2cdb51f0a7023f2b3cb9646ffda39e46e98c47f68bb3954a140f5bce405977eb8974c229305c2ca3c7017891f208a041a89d48d3344695cd9106bff8b80a0a48dde46ba4ecb942344cd1887e2f889a5b97e96651dfe7d3116a2b17a86bf11be8ab8bb69f214b7a0dce316367e827192ec0e9a0ac2199b1c4f1042655ca7cf3d1f8da99341afe8f0b1f21338492ecff73f65239f4ea6a5dfcbd08ca9bcadd559dff34a6a8cd9a28a579fd54384f35ceaabab930b87b14779fdc822a587d04910b4d693f288b26d56688e5ffb2d65d9374a32c27dab9778f618df54c15f555f54828113a595fc1ce107ad2ae7592b41e944b0cfe48cd21d36d4fb35dad4de5ffe9531f9e927a25942461a4c9726a292d2ef9dbc0b1d0456b703037b4df9d0c446d707285b9489e8845211cf0e8a3f0a32a5cfc713902df29af2813293a48c2f02b8dc336befa797d3d3f67d90cd4fa25466bbe70d394713fa06b606de967d5a5aa9f8d0310363f7be1a75708d4c72511f67eb2b0495c43e75ca6e085d35c53cdac3cc09142647e68fcbbe921ad25080"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 2,
|
|
+ "index": 1,
|
|
+ "signature": "0xe85ef5afbd04ae28867b1e81b818d79445b1a8e98c272154ab5e8a7797af50d972b241bc0d536481095419bb18be70860dbe9c5d355d74451f31e27209f3d43cd2a633cd961971c381058ad667a9b2e69f0fe9c2a557ba89835fabb16decc1915b54de7b5f00aa5787a39e8d97fdff315a7a0d2aaa5d3e10fc1a02ae74797c43a2719d3361805f5415dbceb716bfb7b07ff4a415a938008f0f9a668395801ee590a83b20d5749facd7f99bece768e7e3adc0e036b82604cf9a9e5c7010db9b54965d094ba9c248f9f4e29045be7962aa6e7243d450caee40bc4dfb9b333e6c289509f899b254d85539a78f1194553bbed9dfca1044372ba2530f2b05ed4a467728474a1d603eba54e4fcf2295c6a559e9c606b6b70c40d4c8cee286f2d79d6f46a8c0079130c2f58cbf4b3ec7fc109cc1ca3dea2ddfaf377eb357ac6b5877aa6f2e1f56df3421daa6ed5d043b5188c6ef1c71d765b3d94815027ea7838d8f448d0fc008d3a0189958ae6fafac687990f5b7d43c103ab97780087f48bc3b7a19f76a945a0d90e1ff279ceef8d32e2b5fdaf3c5d1a5ba52e60dd934cdfdc2492330a5f150f2106ecad186cf1f6ca3907707e34becc8b442ad3dc5ecaa7abfc7bc19cb7a7664ecc127c1d4d0f0515eaa3099def31f3ba376c30d4044ce8cf7669ca465f140ac5ca43f9e856721be03231e6b0cbc655c03b9f237036a504ba29da42b5959029b68f0171ccb5d1a2ca379250d3eb5591ddb52333b954e152e644bf8c8c22ed3c3b471021eeb4a25f2adc63f792c01382e9c01693c4dd9ad333c198e4da0b8af182bd87d2919f2bf4ae94130931cebe0524c1df1cdaed0767ae040ee0f042ae8b2e0674fedaac068db64ae2998f1e29d4fe208f3ca498a1832634f7183a8d6902d86823e12f5bbecdcaf9935f808d72e18e62c1a117ab27bc9acc3287afbd6f7442f4eb48063a381495170171af2d76e3672c37462bcb6c1710afcc873b9168e4bb6887117a9925e3a2b2bc33d0db4fb33809e3768d47ab3b52bd655c71539d8a7e391bcaeafafc71c554e0616d6f6d9ddac0285ce5b9dd9bfe015739925705edf72abe615a376e3fadf3e5807d97a7ca5e4a378ead2a466db9773d3a7d3f7627b29f1183816edb236b4b20af6a212b9ba1b86ed143974777a3de41aaa3a17371aae38dffd3779f254a0da8d9219d98d89049ad55d71e731192bb769ae72e466a67e82dc1b133b9e5129192e2e611d8d8035f6e0dba92d6cade096c56b248237d9405a534d6205e59186c1e5ffdb1dfaafeadc15eb2d11c736b0e57ceee75c6ebdc78c2ce24fd852e87eeb969e14d8d2aef1ed623914bd1932d8dc26bad8e6b3b2afcf8139ee97a4afb1db36a23a94f0ba00c6c6ecd072851c456e72a69af515c7e7d872ec112729168879f1812c9de0cc380a994182a80e4195765d53eac82085ea751cb09eac5f9db99aecf51e9111515b083ba65cad1d6687363c3155f39e5c7124602a879f1ff153f4ecddad23ba9d99384840272613f40e8975118e17a50a27029b5714cf9f3db14c3ded35e31b45fe73fc06a7fe8cc96937ba3e82dcb226be47e45bb6e971ef5e7ba2013cbccb6edaa51d3611452f3c26860232193512e1ca915ca1e82d1e81da1a84b228d92d855a09721f662ff3d58eda5846977f40d2f6fe0845ad3c8cc2c9e6d9e673673d9245f5e55a2f02b6e47e01d27e809572a003809b75177880cc5ded3fde42ac59eeac1f0508eda86e4b4eb7f2de0f9b8500f766798ac7f9583cef34c7faca5efc97ded5585b0c39e0f16fb2401fc50a588017ebcdae043bc236f9309bc4d6c04f089a898263c7897feb006a6af16240547c96bb52d275130bfbeb20f2493713f29eef0455c41134f4f9f27c38d29dd1a2fbb6ecc40bf41d9f32e33352443c299ca7ef6881575dcd4f18ecbe874dde9e796628b21e6a7dc6827587c61fad8a8fc63b886c6f383243a20dcd95fea8e323d0e9811bccc2fd97cb0a347097ef1b5296ea8da5361c3df81672bb179e51f41082ccbc4c4f0c2e2eed5f8f131a2d58aa68caf0aa1a6d9c8aac9f424f7cdd2acd2875d4e0238f35c70ce48c966e114344ba6c5403545a4e8a467bf9cf7ebba117701a5e69a2e71a546d3b674468d4a31bedfc6e70fc0c4c8c3efff332b4b8e1dc604541091dd34a584d333d7291304c08286542b0075f371429605798bbd71ed7ca52ba6b812c7ca91c8c35c2a4f853eb7509c12049150eb7abca4498f5ef4d8dafef8998afb4527b65cd3e6ef1399041887f204cbc81fc030e6242c4395e7752a6545da4996b69740922c07881c1d5bbdc79beab8b17b5b0980d8fad7eeeb5785fbab08a7963bff7e95aa7b526dbe201b968a40f8db9399e7ff8aa18e6f095b9aa4cf4c41e57a78f10f6fc580a955e84f48a8c2b16d13b8b8efa525f1d51426a13325ea3384a5638577f32267f00e2e262f08d46bdeea4891ac5acaa3e3a31fd503dc76a3c92ded39edaa65043b60d52ffb6ea27cbf810899552d4dd5a55e95e172e267be645a3f2c6468b5b1ce76a0b951b85f98efb93aca8b3948c43cbefe76504f90128788e7e08f7f6685ee03b70ac35314d3a64a57a4a8cb7512a9254f3a9aa7e9c1990606ce8ca25e6b9c816b56903e10d7ca1db41a7f991f292acb51337230d0a0ac5604259d7daf5b684493ce3344a8892152fb6baca94f5b02237bfdeef0f9dc6fd372b078a05489f81ee232e63a27726746d52c3d9531bdec03f2d4d56b604231b233592babfe12c64b915200f1e16672b0798982293d768278909bb1352dd42381d7e87c15ba92aae469fae5ed023c643b45c08a5d15b29f34714016ce5c52ac648d4a32a4bb02c701f3a68fb873581ac392ea34277ff3262fba6ecbe274c840751ff28235fb3168cf30bee0fab5cb92c89c8ae3ffd8b03c4253078c31ce19864c8b6f128f6e3e80efda9141bedef5b60adc0d6f8357fe6cb6828b3605e02275deabb5326eff3d52861f072523c5695333b4d51c58c08a44be8e90ff8244da37295e1a1550ce715d08fe600349a9f9870ac83fbaada48cc392b75ab1ab456429e5b236f6b3b1751063b274bf6a75dc2283ca0ae8db757fb856e8c7442e4a3cf6f26e608bca09235f05dc6a2a53862cbae5a5bdcf1bff925ff3c25e38d5ee04591b8c228b215e5f82c21f39462aaa6c548c8d581b4df4386b97fd832a46e2212a3bc5ef4716a10e75cd5e46797dc12241bdec3074d19f971caea7a8f24bc522faf8322301e3e4d2188136ddccc53c6488d5d9df6298befecaf637a2693e8d3db2ed2f8e120e6f1ef5a52471e905bc7f62a3b93b534c9e234d72a75f38e443a05ff62ca45cd25293c23e4ae71784fd1649c61b9469eb152642d8fa2db77b85c26340f4b21b1e8ec7ab58b66fea1397e69665dd9116ce6ecb7d642ec9c2114a4c893b795c1be06893697924c42ed8bc97e0c930898d80e71536dedd3ddcd9b4b35ef5eb462ab984b28925aef1cb524439e36273f7056b17036a1f3ab44eed99199dd6d53b564d2f210a7d52ca896ef0af8de172415b518e92c578d256729744bf79ef3ab444960189cc0cddb9c961bc0a7f0bc51be6ffdf2e057331dd7d05eacd8e6e81e08f90b96539b9d323455428e9abcea706fa357949f2d1067b600af355d435bc71094ed8e29d699504d24427639b4d612d3d2c7e50129145a161cbed02955a0f32615b30cc968c41f2d062c32f796da497b379f5955a0ed5a653ee51f52e6a702b478a9a7af4d48fa25353a258e575c2e0c475b169df4471c22e2ccb1ed607bf831eb28e4487ab655f07520391309d3590ad63436ba31d1c37ecbf586dcaefb56d6110386d6a6a5d785b365701ae291b0a3d13b3dec21729e42591de8ef9f7a7216d9dc23489a3fe8d874a76f146aa26536c1dab083681cc00e9dc9e6603d53d74a1c79558c6fc7bf32d98a485dd562f261e7d2751fefc320c5a2c9a536c84ba467d7a82df93b5803cf60a2726ed8fe7287863fa2a674d01c77b053bcf88a9a502b0fb786f47e50401aa643394624968fb5d5dca34b009a3a32bdce673fd2d0c8e05238b82ee1479cb9b8b7007ca03974e1c56e9bf903c2d0c274cae9f588fcc6b47e02754dc0e7de3cb5a80ace5f98ae68244082144ecbac94d53abb9c89e7d102063107c0ddbb6633d0f987b14217a9d9378007cebdb260a9a89596b11422ec3f1136d469e3c188dfc94ebb1cf8c7f7decfef77995e8334d4321525ad76f32a2efd4c953a319e18c4da8981ee89415f7e2f07914d4fe63d6246504b90fbf03b54bd905661705fb65d00d28c530b7b3c690fb5f88aa1edc6f6dc861d79a1e8c4a6dc1df27b7c2f0b897f1231f176adafae599f4aa29c6a5070103a24468677320b9462cb9a2d40696a5966ca205af33e350742e7e50b27252d2ecf50420cd4fbff8e4570e04b2137722814c64ce0b81d13c14af64eaf36207ae8f9224a47b3c3c0c0996db171544bbe11f2407203eddde94614c9d41945645dcdcabff12cf2fcd01cf062b942bede9184d830fea37df7576b10bbfabdb4a4626979576f403f33060ddfc6f53df73ca618654768001f1e08bbd66de39e8eac625d4f1deb25681c2dc67c6764d555338b4293102191a96cffd8859eb08ecda0489af07c301c12913762fa3f9d192f74c762f50556726c3bacfccc66a038536e913d95186d8aecf381312733beb68b6cedad321fa4e3fdcdcfc5553548a30e1ecf0041f823ec863086c34b3b6e6a7af8a2214122332a4d27392e64cfabb1a9c66c498efb6515f32f01f23073693a37a72240df9709d577b3e184cccc8b9cbf34669b0653e16848ad0a9dbc9d7b0ce3ab88e98616492c83d8b88673aa6a1b93d2f7866caf1984da384145361fcad93640c7481a085b0be84ffb4870705371cabe56f82a233b3d5aab737a2f2b9877fe2885d48163e6c55a53627e6db0a9c7103c867bf829633af2e1379a537267a15765c5ffbf7457eb853d0049f497a7823c0489dd0a1490667b600ccc80f9ebf9afbc007280e4a93b4c20dbb07c10ec4646ce9cd1b3dddacf5ec7bb07d588501daa9ee422da47b4f69f6cb49b3201e1b461b5d4d60d4230995acc88dcc8c928251ebc8d37f3e0dcf8218bbac5e47653e510b270586859238c526c46b7db46e817e467c7fe3f41066e234f4756ac833c9d010fe800e51106deae8eae63d2d9d02c2eda4ab19d63600a5261e69075cc0e28220a3ca4cbfd53f14f654c09a62f6c70fa75368678a7e3936aaae6a3c94d800f95888777bfd394907860ff4446b285345768556f34b1c62cacf50b4ab820d02a18cacfa3a42f086906213e170f26a21a0c7f478d7dff393d68989622e4f89a46845984d1d28ef6584f13f135d6a18fa438e635f7670e3b9e0236d7dc9f99328a807e4468fd7438c56449556c1c13e478072602172f923d0cdff16786fec072f0629a0423025594808ca65d0ee3144947a44519e04b6abd779dc2d119ee4473103e1d608c0e254e0b7698bc876f2d810e4b41f37c9884648d0536069a80f9891d0e2ec4394446b70bb0ffb8032959bb04b82e75f577b8c136b6c87d1f98a962955af7286e4f1a098adb1bef56655757dc5e24cfea40eeb8f37b57edc8b85685c7f1681108f793b7c12df1a203596b57c92f9fa62bc9a1db3e7ed9c802500c7e305606fb82ac11df65c7e40c1fb09084fdd390f55a94873c7a32c0c9d389206d7695220951ff3fcc62cdb39a015649bb65040a06e54111127fd947f344d782f99b59392660917838f2dde4b04038b0baac6966593a8ea2eefa1423c4e9537eb804cb7d58fcbb1eef505ba06b1682cfffc4eab227161bbb9c3aabaec99f2e08fa650ce99e9c02745927ebaaef4f2c70713c97b34b734016a65a0e69db084101289443770fce47722a4c1af6ce554d09aeb9b3e2f076fada5f5fd9c772ee2cb65fff9da7b33e1b2f6a08f1536a403188c771fff5a84c8bc1509ef2dacd23cc699a242f5492bbdb82f13f4b9766cb1465d3d79e5ff9499fd812d346b8ac6e7c8cb83a603250a52daa0a55e04521f22a4246c5c149bb3426639d84dc651f7246d11ff49a2597b9a77104bc2cb1880f0347f2110b2cf33866aaa6bcce8e058e03aee01191adfee651694b506d952210398513a9313836e1457e5e8de9bdf26ed7301c3b6578a291d73cdf2602f6493e7685dff5e7b4db4c0fc151e253009234b251ecebeb10c2facce66e125b8fc8c6a78926dff9dd250037a12aa32c086c155f980601ab25de4bac8ce364c7fa8fdd965ddd03dedc8de498dfd3cfdc86b0b56398b10245dce984f2c5087610efd29aadec6eb78c18956d6912203f7016f3f47452578d1b718b6d221b38782bab9e29b344dee9deb594d8798a6a01296f5da1f143743c61c402700fd33904b43d8d6a44dc6fc04fcb9841544dd9116a5b908f06dd39be385750a4371f7dbce8b9b75aa01fcb4d2a1a94f22b7bf876153543f410e7f8c1504aced875a2e054dd5a2138eec9607d5d5ae7bae91da662c415ac6f0a9bb981393f660695e4b65b16dbaf35ec0d40c68ff4fd991e8152e03152c332e92a62c2bea76c0a239387148409b6a7c2c98c24b506b059869cb911a30cf15c22e0ea0f86db884040f7cc8f58b1d3fcdc251d223a285f191ee4bb2de83365ef74726c7abfaa9146c308530edde09be20e9d6eaeef850d00b165e768463b8793a914c421bb81e8905938540c64b77e82ee6a4a6a15f5cfb1df20a41305ad3dffafc7e8d882a3c9e3635d115c9314d8f3602ba752734e34e188c3cf46b3dd5cd83bb46b12e1ec2a8b9d7dd5b61c5a9f4f0704504e2882068034db62e8a9abf3c7c5b9a8bfde509d36899fc5b4e5bef940fd447b9275024febdc9a91d6d56012f1c6a44f94b96397ff2c78fd617870bf089067c6343ae4270f6e6dc495a260bc1ccd0a1c0771821895d26dd66a203825d19e621b86b57f9a51bceae9bb14d1f9961c5a904a64a1dad73c89129ac4920cc4e86e3696959be3305f6d5e33baee00c7f978bf7a1a7864ed89132ff350b45226e6e4db39122bd344c315208edafdfe6b567677f869b64532bed2f7f9087e3c6c1137004f205ce1485f1b9c3ec798b0509c00f6a2b6663048492caa3889328ea6216e34b959fd244249048cec8c0f7de2ff97105ad030a536ec6c4103b33c26acf4539a1b74a0792b9b6c80f95ee4326b09934e068429242495e51a49a712f8513ce91da60573e83443a0e12ac2a174b82d090813b930e10ed7cd44ed72d20b061e9eb253d715408d79d8a77d67919bb196dadcfb84bdc4eb647a4ae09c436d220e0ce914188c49fe9ffaa2fb87f08809d5021cb632a6642bdc1e3664e84dc0afca031f0150c4190893da6462dd917655930a6d1deebdf4a0b1e461126fb2d54d374e4d5a455a6207291d03d2d138e34260ca0ba2286044afc4d95822bead1eefdf0509cb4a0c09c3425c8b0e9236703cbdf4ba833ebea4942d4e0ea84df284c438ffae28b3ec7ded12dda8bbbeabdd07bd1925912aeb74bfda42a62f8a5e716949f4a195f38c9f7a041776c69a7a1599d6880299f50c3b75e6a9b5e0314731611154d1f755a1381fd7575a6b34019d37c40aabb4bcd6965411f48f3b893e5627748deed82de02e9d47af8d3a087f661dc5f2c65ea16fdb6455a6211c77fd41532017ac4aa17bdc43e33aa4bf6ebdd453fb90b863aefe4281691a736594d714bdc26520fb954fa4a3c8d8f5620316e7b8a3b736b28859514bb2ac434001a129975e0f53f473c41ad752670598a2b356feacdb9e4a609a44e83167539d4e3223143d19f79738b96a27171009f17fca174a8821c3f0bd7dd15b2e98eb3fe1437dbdbe881f9c86c0844db5ee82b627c519fae5ea7b5dabc382c9938529dc031f8cdf0ab320f479d8793081f1ecf45a2af3d339db470bea05607148a060348cfb344edcd773efff7645f021d67db2dc0abbe9a8fc343016e9e57933f642f487d649e3a01ad4f815fe3701750d67b1db3c74c6b30f7923d08a807e78e58aeec28691475bbe4260db35b8f850330fbf68f73f944b745208748261f32a9ee5929cf924193fbca8f7d15d0118e3ef205f6a639e4a25bb23c28f036764ba7dfb4f8203eb0b69e757fe5a40b560cae416eda6195f15330aa7f4ea8cd113c30583675a94c486da43a0f26dc5d922aeaa8b084124f5c5dbd0ef31e4ed52de942b1f8ec6b494fa9e730e8f0cac9ea3153610e13ab589d8840e5ecef5570b619574477e457c529d431a48fd3679f0a831832b9a1ad4cb6c99c25e0c1bcd2cc73ed79b2a589501e2abab2d2a64c9fbc4cd8bf14800f8a67d46ef10a68db32411d63fc36e8125bd0e79b27d861324afa6929be5cee98c245f0af5755595f60d29d485222c4a43e2614d315723c5eecbc836242a028053ff8a4c83324edbd6899887c3ab3394d5725effbb55ff056c35fdde91c28a34362aa8ab06f0f1da408e7be1863ef007b57ee062c5e660e2bd221a306774e7b7ed5fe5d04e3a2fa49a61a9d15e4aea12bfe588f7f7fe357581772356998126b1deb48988b56506eb805be01c07f3706100658b5be1e96b1531f8838d78cbb849a4e51c1a80d3776987407c0a1610d43178962c5a34cac6a62e8aaa963b8833549f8ef954e155f962b6d6ea4ceaa9f711959fdab71a74e8ef57ab16b477bbe47b78718f8aeb29239958220b079e13dab8f77ec24be4c3df3db9d9e306c9da8bcff284c27becdeba20ccbdf94f7853069c936ebb209f2dcef4d5b0c73a68c5bfa67a2366f68ea00603ce2b1fbcb897e80b1f7013d50355df6e989c660aabfecf886ccd69d86352c81350520bced1a2beaa0dffb1362c8b3857f1f1c17393fbf45ef639b1f6be41ace5f1e132e257a96af92727bfdba6b1cc09864c5b085d13be7986a4e720a49065f1c70e140f69cc462ab7bec075108d1384f6935781bec4dce9efad2c8e238e7f41b8e430ba231e9e23c6af52bb0dea07e6a0ffb0a3549db69ff05b1c7d57b1fb5f98b75122b0d53d038a37f3c499d9c891fe571015bf6fae1f27cd1c4790f633cc88b9f018bcc79e1857328fdb72eb7e0fc50558e2ab338fb902be7535c12c0235b21ccc3102454e75b20d5652231393ee2f14b5c0bf2ec8a485c02fdead3fb371b41f43d69a518444a92a6967ef3846db7661d973206eab07fd08f69b5a3a36cfe749acf67c2db8df7994821df76a74d8a36521cc6f4de3e1035e18e9640417363427082daf240e71f60df231fc22b8175620c74e2899eccc35387901cf57f8ea34d3f2a4165a4b7f9c41082ce46980480608c539d7f248a41c1ac1a7d5d28884b7ef5d184938d94dd473fa28ba674ce934807f56276fa821da3dfe5f932bef6565aed54f5c3517ace0c9221214417b2d523ddb65eb4bf68c547b4c40ec52ce09c51e1fa64422b21b412a8cb416db685469ed047e2ae26ca06de8e10abb64bec6ca07884927b51968daa05573e35fed3d2ae343126287069190029b9a7a724c177057dba050c3b18c0222de84a50e2413eea9a12f50d94ceefe48995ddf907de29a46ce561cd8242946eaed26474e50984ac005be37fb745254f3df97f880cd24732a46626bf4975bc6c749ac1c75833ed99b4dbab1d71267b82758229bdcb11cd234b8c990478de16160cf4989df335f646f6286d6f62f350811942df2f645afb14768f50ddf221d8e029674d40994c2ec2c4eb12f9ea6aa14d81a0bd8c3b62aea41877104ba9f50ed75c53b5f0cf4d913b7878b38dac9dd45abc35feacc53dd9cbb3029689cef401df37529318390341babe225094f268a886ce3bd6c6e5bee7849ab4f37c11505c9fb71ea7ca9db1c882dff90d91f1c046bc0b2306f341126b6becc475c6dee4d5aa9bd77852316b72a9189a6c309002f9be5296a0307895a6f729d7e3386cc9b18aed6b2168847a160c11db23400a80d3121febde4e480f2c7399dc71594ddfafcf868e60cc97ce8dd6861efefd9f92e61987ea7aa5baec0117866c387e07a798a1efce156b5ec8ddb3794b3035e34544e9d9a447c9a57aaaa63766fad9be9bf6ea08aff67c90792613b5b54b483f2965cde93f4b9bafc90e3510bbe1d3bc13ef88b08fdabce53bfec8b26eba2f09f5701915cf72c095388b635c8a6aa14d9c1d836367860450591c35230ed1759928b80575ac152b97ece0e025a283f62ef90ecfa1f3a3eed39068ca91d6b0f35f22edbd54637e29382244c8dc62e4714d6c729a1825dbc13e4e245ea5ce221e98a8d25aff7f65336f634f944c5e33fd99cc20202fce700fe053207ec9a73237da10ab2da53ff5f0ac0adcbcdfd31a642dd69541b7661469a97e87fdb91f1c9a533e0cabfd12e0a015e96fb3f5154d6cdf4e2a593780bcc79f918bd1844ffa62a0637c7957866e779e491d864b409627129fd5442cceab809755ba78aa08885e7daca24366554dc75839e75a66c30c5937987f197c9bdf377b3eddc8f24447e96f17bf8633645ac81ca2baf52f4738a52afbe0b12068ff44d5bc35a3f83986825aefaba9fc29ae57f74dba2d3f24d3692bfa33beb46b75449dfdb162b0ca5afe93d3f54d897c8aa7e3f7fc9f632cd348a47e1837e3aec9da2fb675b169af643854a2714daeb2f060480d18f0fc84eb1becde4368c2886867a9b621ac3966222ea1a5c1b2e2aad5a6d24ed21533c91f9a8b019195529a6e08eccf10f40563c65ca50bfa78d83ae54ca01cc21925375ac8d10de1adbe763ca9d885e5b28565332d184878947f6b89a51db652ecd0155625e4cd472e5f366dcf79b36e79465ca7a3c236f3ef8c4acbd83ccceb8b19b91855dee1122f15627c57eebc26967f4263434b321bd4cec915975821e08f9095ce6d7705493d850c0da356fb8cfe51395d1d7ba7efa5d4f1cda7b735f13d0183f8f1a282f28a24ca0f0e719b5e567186ee1255d241e66790bcab2e55846085d1f025e38a2d36ee014b40cc2c5afe253b858774e34c026bd8dd65264e08df28f22498f88e64aa4d42eed7f98d9b81b593b9adbbe99cccf617f5bc2809198bdfb460e8335eb8d6d94e278a50"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 3,
|
|
+ "signature": "0x3941e6e79ed44f046543182b5bc91c08ba91a53a50351470a6a64215b1b87c4487df0d23a191f8eb1429db96776bcf42b0ee0556ad1fbe54589ed283901d3269a783e1ffad95d3b98c52b6d6de730edd4c93a652f53d76f8f3d343f04953d81c43c9e96934df194297fbfda8098baf1a277fa49615b9e429562f2b5cc029a76da5915d35c96922639f5d2f3157f5edb63918b663d299a2ebba2727117c328d73f83959a82cfb392161c98ceb2b1d6b8f0b78ded12dcad63da02414be8c853c5a7186f13d6c8d9f7f738356fdfbda49449bd2873e7fc5e3d7135d59cad6abd758dd954c72b9ac2a52a9f4d40e675f17807f69af4c7119f4dbd26492d194d64a18334c5afdb8d4ed18eef34578d9a4f9bca31ab5c6c6219a3a2fa5b9d29feaca1b37c24115d4fbb2f8a8282df604b24a18cc56215c791042a7f28eb859d2e57d43ce6cc50edc48688a0e449ad4aa6f5c00c72dcf0322d2a022b7fe495028bbc89ab53982595755f384b4bd723a7f49d77a7288b2b5b51ab4871624132bacc0fc1315250635bfb8bab3efa73b75b890b8701a48eb67ba421c64e50d2d6c823b7ba0e8a6bf7b371f65e08da37ab9424b876910fcae73aec09b44210aa4a4b8e401d055a9dcd5bf5e4869c72b0eb51a9d0a1e3405cf91564554a549b16e1a6b9fd90f435e2d652b45be313ac6b7bdeacd499bbbc61a00f4efa6932b3f01c0c24f7eac31955296677a50fee299536aa9df12168f3e91edcd2b634eb8fd6570f99a24abddf4d94cd77f2f087dc905dfd0eaa228c436935cd1a74f6f9d72f0ca11283e15632403d786258cab7d224e99e7fa7b59db465f26965532450cc5260e3951a32102795e2d0d5cd968fb356e142103f5204762e194d130789caa35995091faaf9167d3e3d144159b659a0f673dfdf2c6a0"
|
|
+ }
|
|
+ ]
|
|
+ }
|
|
+ ],
|
|
+ "messages": {
|
|
+ "0": "0xcce50ac23422233040f0fda9105a626e3160b12064ec678b34819b029fc204a1",
|
|
+ "2": "0x9b03be36eb916bd6ff4868240bfc66a2631dc806818ae44db48178aefb6a997b"
|
|
+ },
|
|
+ "bytes": "0xf9481a93414552452d50512d5345414c53544f52452d32826d618203e8a03333333333333333333333333333333333333333333333333333333333333333f947dcf923ed80f923e9f902950180b9029039bd3aadc5f485f3f17ab3ef996de30f40a4dbb98f4c70db2fbf505d86835dcfd8e1b067a325d98da059a8597b2e5ee62751d4fd8efc9985223f68c9b2725df62d7af9b091a129944bb0d86464ae20b5bd1c5cf3b29bec1fce23c562d6d8d3ea81215b2a061f05e1ea271c4f5da79f528ae113bb9ba6afdaa1eebb715d3171344fd4bce746d22de14f5a0454a7e371086667b9d586907f6b6969a528ba9ce5ceb7c8cbe30c939b4d76d3eaee2882cc898f374b94355329fae7e6d591e9166d7f71d9c58defb0bcade36ce313d62519c41a7973b149b4f2f8e51d6afd5154eb794343a3acdcc7436e4ff22dda41b236295314daef2a4b98c5343684e20ee7f1f6d27e4a66eaa79ce6a32b2fecf43c43237a40f3545f4af5f6d93109d8e15da5f28db19eac72f8641d14a079198fdf9f8ee292b2d0fc7d3fccd68525dbcfafff2a9d29a3cc361e4674d29e5af5ee408adc0d9725f7939065d0ceef4a4b64c0972943a69739b0aaf57562533888315d7a5d24fa759ed5661454ee58ce491e5f2fcf0d07608f524c50f36cab968c1d8cbee3313a7854744d1cd7e5ac70e20092bab2e5c59736351d014d71af7c19926b232bf1bc36676f81a1a6f7166e97d8e066f6a78d98f13974beed35449f3d9506fab1c0ab356b092273b42d4aedb6cdbedb736e6928fd2d4926b94106fbbf0923e3b759e1fb89ecaf24bea45bd406d509d611550061897b71c39ea3fa6a8f47a50a31849546df90137114491b55ce36fe1d6f64851c8647eb5906d13369b97ab5721a44db1f9d7712aa45c87f5f8b8bef5c92a9f715c432ef6262c8d22af0eb2943e40cda27921cb865b7d79a4b70ec14f7deb96916cc13eeb764a5f3f35189a9bace816de3f88b57aecea4ad102412e121f84ab7474a04d0c0d92526178821f0dce4f91eb50280b91eb0b04a645ad8d00ab495a1abf55dcdc235878fec9db0c64b021945e225e20fe4dbd3f148227ec3f11a5241706c3941ffff52adca321f313d8155be79374ea93e2ee9fc8e91b95cf14324d936cdc4cd2a54f5d499562370820a04d141492a0e8cf43aff6ede6640aadc4d978d41025bab7d9a76d7b593cbb3d1753bb84fcad1bfb64ce0a9a708fb3c183b39e94582c983805fa040dc6063f3311c3e932085b964ad6d608c689ba5d7ef452c7ae27bb66bb706a6e413182d029285acaac3252c309fa9eb7da2bbfca67359d74947416a5d399a50cef4493a6ba27dfd43a60945e7a709d0c0332bb1f581e40ec93b62acde90caffbafd1e12738b6873ec38bd33908f94302058298a1154c48454796f73ff325faf6c435405a9bd6d6c3453af15186974c311d8f4fc384314a88932629c141779bfb8b039183d550c9d65f840c64b97fc81d672b91e5db8c2f11e6e910893c67c5bf8db89b209d699a4ff7c02c96b5e791ae65c2afb94baf1d9e6277f7c4583d3a504a932892f8e5ecb92e217d0161c32e643c3ec6e86adb91d1da9bdbb1399b50008e2ed446a719a63196e0bb4ea7b548df66c93e1e9bc65c5149db54d8e2fb97ae5573182b56373463fd259cad0f36b54f853b0178d0959ad4941e63658525c1489f45eeaf173dc8cb24be5d6cdc6690fccf42d53ea72171ebff5090cca10e3e7ced1d33a8b7a8afc3427c6bc3360dc7f111c62ab2c65109332315c672c983966c4b6fecd36242605bf81722e0c570354bae6eea7eec53b55fcc4160c2e6f2b6cb712ca31fa5a21f8ae785da5fe0560a3f87d7fcbffe06540f2adc5489feceb1777613715c50605f22bc291cbbd74ea037e2c749b76574bfd9b14499b62828bbf12a19d43ad41fbf761b089f47420a618e7b59138bafb843b7e64dc15b672f05705062f42655b0ea4d21dc5b326b5f038a550c2b5b956e19995d8ae6d0aa580cba6034dbfe55fd0600e824fbabab3e195c329b0c99b61d7c0691d72147c614e93dd8bee087d2a501db32a65fb11b6a2e5f983babda2406a5f409ffd531fe9446f2bf468b132fa662c8f476fe35061c73824a7d2f6e6bc5483aa5f97c1a816e1131dcca03e98bf347fe6fa66f7c08eb5f4000ebedd6d1f5f74847bcd17d07c66ab8ec09ac7a9e9fda156efab32ee478b41b1676c61d69b9e8612118712f0998a4f2b3384c1a4fb55d71146a15986b461a93f549895a1c9d2a32c8f6acc60f926f6f24450a8d281eba1d42184ce6670a052c289c9f00bc52610792d4327244c984e6d789faf36c3b15d3298f2b9d0205c66fbcb302097ad29a0d98c943233f75e22c40436e08868e17e5c29f249ea500e4d381e2b0c949a51b98b3e8ed3fe0c94f5801d58cfa78fa96239c97b4278183d68b9d0fc17be277036513f8593285aaf46ac566aef4c5390b68d2dc937f2f704dff3e675cf3def2216ac9b1148aef653be944c185eb642b2ab9d8edc9d5dcebb41ea33887aaf1d6df7c92593dbe38f308e3b6fe4c5dee0d81f08cd86a721a7c1feb4ac7c4abaa65c5a9e5f41b17be59b449b46e5d271b343baa346c24598e15f9ecab7c9de5862a7b78f75f5079926760cb1ad6e3851c248e12eb2b657a7adddb4ddf415cfb5585045639ccb7e4a9d02791b37c43891e040243151d68bb91547f6a53889090402ba84b0ec43b5cfb27a7ff01f349101b50d338831867623bf2886d5c679bdeebb714d8686321b0be9e2ede4605fa3c6fe6d55d82c8982d9f2356e9e0665570552206370fd635221f637dadf48dbc89f8cba78511cd49c88227d238069d73b04d0b7f57150827946ed44d391a79609f8b18443c445b8c690e6c98145fdf47fd99ba62de46705886d6b8e23001bc01920dd38304f37c94e895dfcade604cbb5780d1f19f2dba3aaa45daea0559c91ab896568b6daa4c854c906a5ebd01ce7a038a71b9fbac5e9856a0f50b62326b8bcf17956a627ececbdd1b922c0ba2963919b988a4b1289b8e45c92741e94b1b8317f4a1e47566bf53fea4bef7697ee04522bc43f90f605646e0e2cf7bb49e499c8f2395a6cda3d55fe1218cdf0139c52c4ea5d556397dd77f1d53c31cb040a52d66dcaa4cabcaae83b9d1fa807dac16ad18b487cc3b2c026189ac4a0b3724cacb6f008928bf8d361ec5c3098b528444296a45f142dba8696db82b596b8ddc420763acaf68a738967260e592677d5fe24b31b99e2884aafd11dc22c28b0ed0e3dad21b6545f587c0a7d04b77f5a1bf170d7c50c3c5b9505a8dba065b488eafbff7e1dec22850e10fc97715948768b0d63edd7748616cb22013f4b49a6c1581beed6ac019fb941b93b3cea858f05d3f75a59f430d0b44f1bbc20bab919558efe3f6a5ae52026e460d0eb8cfdb3a2d1cc728d44f5819f52a0c7331563ae1bad62b2fb49136de8030ef1dcd745e4e1c9c2f3db86e6c9ea6ae1dccdcae62541d01de5b7c1069396141a7be3559f1195160a38269a26f14f925f39ea52e9444bd4c2f68e767e9b197ecbc25218b7c8b60d1530496afed51fa58e230641221bded814d9610b8b1f472b7b9b0fbeb2a288549dae98521a4e958e8e50c7e1c6551152296205703ee5cb8ce85161f47e8a480b126ea96b2d63c8c2cf83b45d54120f49627d011bb8bf039804ec588e7a16b97b21f9f12bd811af15c07de4ac369b182da0bd71dac83d544fd181be78d29cf111cec43d496b514d5e1b40fd5103f3fa260ee6f161f6b4faf3fd6c9b39e5076b1f131e519abab53b5e421890b0754f3afd85213eaf0a092af028ee2c94a894e5938c59e777857b1d3a728c2c986ed03a6f4ff1c1de439b61100a0e6523d9ebb62c812315be304d19975f9560f5fd7b1a82b02dffab6db711df8462978effcf011203edd2a8f34223c47cbee141b3b39780e43708c8fa76d34a862536d91ba7422c5e65052e42678872a80a9669d5083280440bc90725bdb067181bb7a5e4088d03358022527bf1f626ede6b37deb7bd496211855272256d00e2ebb308d3982893e878ab67d5814afdb24af656f0968f0bc0c063a64ceb0431d048c3032c55dcc8680e113f046a223fd2d3b23a8134f8be07c509e18bc70c52e93102a8d32fdd8a9c3cf50d807ee979571afbf9f08dd23ff0ce4116fc4b823147193cc67f8b922c1be6892d276e0dbac473db17f1003c38c34c07da91091c3af5f3e4c423be6d526a9b8b37684da5cffc1552faddf4d0f60dc591bf9edd213402f4b4ef635c92bef5132e4343d0b065332d7e98b9c70e364b889cd970290edbc80325ba4bee26bc39044428746b502f3a9a58f1a7797cc6df8711bbd8a38bab0416caa5b0e2022810b1024e3520cb587df8c5f6eed2dd6bfb941f550b3872e15d024c2c75e4e80fc15f78e2083cd08ee1595e34e75c02c12024cf1f34a5bc6f7bbdb9c7d2bcd0620d7840143ab28d08907fe8a214765da83d42566991fb0eaa3f2fb4515038b9b824aaf29e34da9040f9bb2f2e06b95f2767a6264b163205abf3bf0aef569b9c47493752e5a664ab55ed75ae5937245a390b6266da873e098c61883e86e4ec832e42e8f1c763bb8e99fd389c7db7eacbe9c270c1327527d232cd2bbdd0b3f0357b1725f41c2f4fc772c0ee1ac40f62e34480547bd7ff705074585d131e57da8e320611f95710af1c5c266a0430b0021e2c27d039803e575fb0d424a29af75fd3dcea32700de27e5472ae8395090cc2ca40f39bfa53cb79d3598f4bb96b0f8e9a60543ed954e45282be914443649befaad010fd19ec21472ec7e1b69d2f7033a65c07549c22584c1ae358b007e52d20164dcc13a787db5f512ac845ee0324833fa24f416a778578ef3aa0d6dd209473719286b35b8460ad0568d954ee5c3e17d709188d9ce4f87f2e7ff0d01adaf766649b4539f7f9b336d54c0761bfd0c15c1526a8c0cca95665aea6907f0a6e58643dc20d400f46a2fba86a31bd13f7908912093557174a985f1fdb91b68a30ccee379385e339b983c1d2660f93d1c030f041ba4a23efdba9da621d957673d66705dd502bb7f1ddb760e926794878260828e6a0951d8d77a90fb1fead9d3ed55e48fd3a2289564814e62f216186cee9306850e19adde3cebe220b570e3f6950553fbf7f9767075c0dc456ddd3ca9c29e994de5b513709ecb8e610db6802a3de15b6b5b4963394b7c7b062869e1f8829f70ad2c075a7fb44777842389a5204811fb30dc1173b7c53449d2d6d50b32c73825e27be01c73b42f229e134e7417cf5621e023b9d2f3556bc02fec6a0a86614bd3b62e31f436321e8a2e1be9733e94e84db8ae4cc3ab40dc035779af21e4c2357ac72ac5f79d6decfd00a38101ec3074a4bbfcd55cf2afb3cdb4f44c53834b08e6aaafa51caebc463d315cdce59e0de67df69bbe68235fd9351f26c4e3eabcdc1d6130e44742a18435e96313852630cc9342a2b49a4b875fcf1830936aa0368cba7d954aabd1e9abcf044874b3c650b78a3925f3f01dcd959618ece352a1346203f70aacb3f45ad2d15d6a2d8b22b99f55057b8efd22fd8d1cf950a3b7703e3f7a9d5d62af451b9ba32a199dcd345c39647609c58e6f7ad0340165f850176c8e8a1f8b20a96e3654457e20afe0b30db2ff6c72770383ee75a910f676332bf6d35a6310336b2a23bf0d1dc30e7b144207f5b9dc1be181632190c53913d18b6644c3ae00ba5b3eb6a8350a22c87da65fccc233a814c8fb21c3c56b137a3bc6e1ff9fabd32f27c693c043158e445ae9434972083bf45bbd6d5d185aa32e85524147bbf026d686ff54b8b9c2e4de35d32072b394867cb126ddefcf26b63d37a7d3c09b38040aa7c006ed6713c769857354aa7d9b95e3c6d58edd7eaeed2208d41bbc5cda78440aa747dec89259c1644e4d7a41d50cc8d46c3d10efaa9791874a9f3df9738c66ffc6d638736daa1302d70a8919598b15b3b3fad18590321c11998bc3161b033601f5fcebc1df369232270a16a6cc9998035c1c49792211e9941e362e8db5623e24280e5db8d8e6605c0b5a91212b7993b84ea2970c524bbaa78a05406b9282a8a86cc529b6c128b99b637197cfac7d0b730fda3f80c7ba72dfc82c1092bae4efd4e169220cbcec19cc88031aa9b402b4d2c20dce8a24ac33b6dc501852a29d595f337ec82bf16021065a7375483e1b3ea58d0fcce31537f24e640b0607e736bb8f4b83d18c3bced0819680e78fc46b6ee6c10a72d01fa7b9d5f8d6b3d834b5d0c881262e5a44d4ddb4fa19927adf705824de725467817ba6a3fd987cd976c6e6b6c196b50b2bbcc5f6e976b13b26881c41acedce5ebe075020007ca737c21138b98f7625ef4a7fe19f56721cdf21f786f396ee7abf62295a37ff1ddb1c65287dabfc7491dfa061060c6e9458ea231d868cb1c6863988a0014ed6b152438c79c2b74468f07d0de1351172345a9a31049f52c38840b42e67bf68fad5871cff9983bcbd1293f3c1e9bdbb658a1401fbe2bfa9d3cc32de3ca5156256269a6930e40aab9d1a2b06e57959d541694a4d6ef918f1aded4554694b67ad67086da6d43a0e9df85ef5d30d91f1d1f789b444e6e164a0cfef372e5f98892fceb2b5909301f51989bf1e5877eabf3a13e7cc09c68f441e80417b341a7bfb575c4c5ca9ae540a73787ce707b51e03bae956503936d17dc6129b6f83215bd409a5bd9a74b878358d360e311090a1c706244a58a9023c9f94b1bbbeb5e4246bb36e863e9b39bc0a717dbd957c43234cd0c5e9b95a1a0b7a16c47ce07be6bc3f855f7ecd542311cd2081f8bfbd1950b1495de54b15defdb9c3725535a68814d804912fec0488bf1f6f992f9b1ae3467ddc98efd1e7d8690ad4c31743342ea094ac481cec9bf755260e67dc28e4f25def2782c6b1396feea479ad04f61797e1b5bcbb9a826c8db993b8cd56ffcd575890aaf3b24e2f300348a708fa1236dfa2245176014bb3799aa30a6ede2b10bfdadc1fceb863039e0db2e45191b64158cceaf090071f5cd3f95ab7b8f6b6406e6e7d486bbff9d0d298fa8b8cad2c69438951b2abf744428f9e0e1f838e6709cdc4fed2bfa1b5c43ce2ca68edf4f77b5faf89a5a5e41fbb7b599a08fa59419326447c507fe4e3f425eacc26c6a7334a9600250e0cb598d1b1830f1e92c145a03f1c695e31a1540604ea6a7848aee653cd501fe2d9ccf777a655a25acb08e0cc49f039c0975a4189dc7158d35343eefc1959b2a320b82322ea5aa93d9c803816ae01093069b8dd9544b06c7555d5bd74e6c2abf2e2ef6ff04aa1a5c16a7be046d8dbf3a2796df0057a4c012f0df58b55112528630e70caa28b805fda123733de937afe2157c00b8fb026b75cd1787fab07ede1531a0111713566956772a026461ad6fb23c5b56d89c36c7ccf4191641c8400a400b61b83772a4958b86ed63b9d4a528ec85d4b4e72c853cf4079046b05df723bb3fe4f3d5587cbddad1f11ee21df03fcfd312bee42e0c9863009213142b48647691b2b55bb4f102223c033222c8c26fe69282505d8d9d1515e0d302c439a840bc57831e4edd751c27b62cc9dc28f5aaa6d43eb2271e02a3332c885964db0513a9eee7a22fb7733fbe311e815d178d5df6e1801756d4a9602ecf9f3b71b80c82a3997d0b2892c3b0cc0b86d36bf2fdfa132e5e99a446a33c1777ff01c92bf3888f62d9f518004ea21c75bf6de90089224cd0a92d00f9493f1650dc736c5f9fd25d7c54e3ad2f584bdb5ded06673bfc41d213cccedd945b02c0140f2b93906e7f1f3d73905ad4250a2fc1f8a3b63b8557ad9f9d6e2814ab316b37134292de3180caf1bafdfbf307a993cddcea6e02641ed147cbf9743c25d816236c0a37b0ac01086d21d755c4ee3a6eef1c2005d99fb361cf19ea0df5501ff757ef33c0e20dcd317a033e51659af249e1257e7ab177e80573f66a8755d8adf08e69cbc22d11c87105ab56aff00e96591811e19b27ce7a7caab152710df5f3412e525f70933ad3a3bfd9f627d30bdcf34495e493b4e74cdc91cf4920803cbf8120439ec3159ee9600617c2f2043f84617ddd8e31f82c1a413d3abb21b53ff64afbb5a2a42863ee021c8ba4154d8e017374a6ca281f17fc88b1606af64828dc7114ea8bef8b39b5d24b848aa3106f8bb8f09a00a4795aa0d8b9a1e39cd081c4afc773a7959d22adf2b92a316009a24686834f64273d529d156dbcda127c44115897743b34ac26f1ddadc09db5cb27cd946dbb66a846381dc4d7b4c5768429b5ca03c16c19476b83bf01258bf48aa564605652b87fd51fa4252527dff906c51f5304fcd32199db884a5f487ba0de118f0033774b456b4112dd6079754c05a9269ddc4a905a415ef44a1a24d00e918b3dc3ff57d91f4e33a61c0a282cd9521bed291149f1dd37a7a748b0265d00137a8f28e648ee632febec505d1072c542cfbb561836f0146a17dcff0855fd237efd802c2d81591c2d5a46a140e5a571fa16e563220393da247d3e842683b3eedfe885e33b63d942e65b1861c5fc08a31a81a4341c795d4dc9cd19233816317ce826bc3cdde411ada45e62fda38909c7ea8e891801a85a81ebd58a2ecee99266855793c448dc4fec234b0e5e39661de62ce31ae723692dca2d7309749fdaad058f55f6337b6db5d3eff49ff39c441222bbdd14a2f84d997d58a4227acd0853699600f065942d3064096553dfcd6e4b3e6802823c907a0598201be0727b62263d879d170383ed4b4ffc296dbc32ddf619a14148f27c1518f192c1f2280af4b1397a3adda07a5f3482526ed2cf9c1ac4af9191e9271db6c3ebf8d63adaa88bd36aa04a0fe34f7c3cbed5175258b0f028727e713dd04980eef58d669cf9758d6701e68e3225e8a34a410e2b57350c4f5c37f4b547a1ce677a5a204d068cdedafbf44f63657eaf60b27ec276d4ea560faf3f4074e8d0489d293ad84dc742fd63d4c00597007c53fc45f83647def72163de949f906cbfc0509ceb468376e220743fdef733dd3f0f97f46d530fae025941c7868963e2bae5f94ad980a72dfd781dd52b7f2f77e9d22d4c735644f46391ef8a9d22b02bfc302956691330b096993b5d1626d86fbc823cd617130286c1b7e47604c29fcfe52e76af83ea3e78937b1e54abd5d284f276c9e9b80a0ac165af9c4faca72a64928d6e86e795a6f01a047f87a890e1ffc60b390046ad7036afd996bf9ff2db53406c0ce0e333152178a32012db88b02726162e4e356b859dacd183eb9ab5d478ab1a5e5e5579893f591ce3c02f9b64d26dea2ce034ad06502c4ccd0a44483c4ab0cd621fa8683455b133e103c5fe2181f93f5681fac0bde7e849398ab302988c0654b40d91b69d18e32675d8e32b35cdd73efeea37e49cc2efd8d31e5a722ba04d56c57975af32fc0085d2866f06daae82fdd23479f6221896a8888962ec78c485343941ee76162551b0fdcbdbddc14fead4767144f3c92fccd31e79b86f5157337c5c2da9194fe3f2adc6ef388d0ad9b670944a790a58723cab465f89e9285268e84d0395f9286b947c0c9936da548cdef820a8f60fe3938fc70d0304103319c43f122b5fd04a0a3b90f22826c267c94fac91e36ab2572dfc211f45094f4aa7d2672955c73723decf4167698e27d330861520fc3ec4e081933e4dea66c513770254a9113910417fb90c004e11d439b39da7578de0547f98d141f15497395d1799df29dff1d074cb49d119d1e743629a1e1f810285e4d0ef32ac3e086368c5a465bf6afd8bc787dd8d5d7f1f0ad9d218ab6a83b2f233a147405eee13f9b1499ab2de89f5b8da0c3db11c4d8f2d02d7274b97ceaa3f561545baac10c6a0b2fd95ee8ace160f561b285bf5ef6c393b13e3a9ac42cd1a9ec94c5a1bea7c7734ffb4a51c58f0ce98c5414c0c76d5d2d5b8ca1c3a256f3113d9fd04213488ba16ade9cd92149d4a19ae849347fc2108e569a0f2289347d78a825ec1a05f2c8b11097439c0da067476b6d19a12ea866dfa6942c5ac460fcf77710aeb9b61f434b8666f35ab54fc07662f8a38b8b3c2534bf6bc01540de7d0ade8c975d4528775ed799b93652f5542158398e8d348ec32be403b7c15d7a482ce0990efe0e034e65cba275c242c802f0a7ed1494369efc95870c2daef748672cc9b7d68bab41b5aeebdc9cf8168d15b2301ab21e3a11a30c2a1561c2834639d8a398b629d4a8a5619a1d2ca5a2498ed8afcacc4fac615c61c4cabd4b7a93cc91b126df93852a94da379e8a144571fc4430da3f38beada24b1ad654f795ea04175f1d2e77d2bbb7b1b6c8b36d14e251caedf7adacf58b26bda3e57856348ce3d4efd41bf2f5c17f0db9f689044e6ff1eba4ff11cb4bd545e11fcad281a4f10b9d6637e2f027c4b07d8a93a1ef174d636000fa30b38cfbd2a65553e24e45050482438bfd65125a1bc5f289cb4e821bc2cfa82b1287bd2d2680bb0111c56a1bd731cefb21a7ffd58a8eb027d42928833be272c741a67f5c75e74b3169c6f5119592e2c736ee23430c79926476b3c455e37f0b788218044b49a5912153660939d9d1bb2ba481c2c3bd2c2f5ffc35210eab8f48b23adb999912390c8d38bccbd5704f7c95b7ce33ed1d8621b5c249df16ed02899f4a8de149ec6bf485ad49c744f3dab7b24a21c977b6156b060071a305af2f6b5a7dfda458be4f8aaf007d71cb326a52815d2a8b8688adc0991199634a75997732ea1cecddebc8275c623b094795d5029a8dee5135e767569f72166bbe06c7f15e5cb0756bfe17f2c5a96756971bb640ada85ac15711a6abec03f4e0bf067eecf7e1ab44714ba511efdc5af11726cbeb6eff38c16bd6d5e24916139c434e52c789a3d76da81f27cf5d5c7a4a01e0fadb8441b6e3f938aa6dd75c772fcd3b66ba5cb2eeb1b66d8f343805712bdbe1dbc359907263f90a7fdc7958e7fc514ad914383aed1fea67b6351ea4a0f22b98d67c9d607c89fcc05717dbb3f67ec43beb9f387cbc7e1ee214ad02c0401a198f2c5bd7d9e7945d0f7b8818990a9bdc87f5b123a342458acf27dca726290cc027c874ff03f57d13f840293773a63f0f4aaafbd961938b18480bf8b140ccf6cfe57bbca7e693e15b4c504bd3d3e4bfdf5051ee10fe540cae980ccf5bf7db196fbef7142dfac744aaa1660f86c8df21551497e14532de29377b9708656250567b127020c2923172c4519109c99260411799a21815a41d35e984d9af778d83be0c42b8d3790c84a2bdd61ca8bc53efdbb7ccc1c0bd3b5918e3d3e7c8cc67a54e5de558059140741aa9ddc75a3306153e8d5f63a10843cac5e81dddf8949be87423677ffaff9a8a7473e5d7dea5c23f300981817fb2955ef5ad27becf3e488f7f3f6f4c4b5054aa778844638705ac4f8bdd701c38d58562cbbeddc85bc9694a289921b071c650f46f8736cfb0bc6ed1b9104a515db7814f9f7f1ec5415782b69f64e85bc5b959f49fd9eceb08ec4f70c0b605f16fbededa35aedbc4463368d77694b4f4b683e472eef36de641a39e09f835c7b627106a285a084de8a8b8f8b0d065428404c5e4b5054bc018f526b0d8ad3969c15acf779bbaaaee96e9d8f2d690d163f2e1d75e7d064d4d304d8754779c66c7483f6a1a7541acdd118ad0999108fe7fe2fcde3dfdafa64cb7a9df117733b27bada89b92932bc29b2b33ccbb62e544e9b50223b8a44d807b3c328f763cbf4e6084d1fa03866d1a295b894195be5e11b88082c26044e17b870ad8a1e822c65f34fe0b8cf59e5d21f98adb5585ff4f52c86511911f512f31b41d1114edf2b60965963a43366c08b8f1aad223b9d8494b676190160fbe82350b9010e8750a7a8af183aaa3b1913c34e1f8f51982ac74616a6036bb03510c67db65950bf12f3df281b31f48ef7256b08d8bb89faea78784435e40c203eba007504b9e1e1317069cb0da8c5f9d15191494c2dfc4f6bb5778d4220ddbd87d4a0e03c89e72d04c29f4cb0581cf43be3894624f4822741da52f9cb4a37bb5cee591279d7bb75e7d4861afd69515889318176daffb49fe2e95a4832ebbb974a118d069c39e69d568470a48dcb063c250653387afc3cf41ed437f8bfaa436a513a26f357cf902960102b90291396a36b66a0a22e592388270709d8157c2723ef44785eb78273e04d136262e2363f336309e5b727f3678f3e4a9762eaa10ab21b3126953c5444ae59d76a6f2b752a2166e0ed214ba9468e116ffbbdda85c03c762a2b9682a6e93f0520235067a15119c620d3c8cd56c69064277a3d7510df62cc91cbcfce9ff20b36c22c19f633ff97f7fdf63b756ec3289b9a8d7adb4c385164a6828b665f14e1dd7c7319dadf51fe90658945a902d0a29b8f7fc38395847baff0983ba3928069988906b99751d12aa3c536e4efe87032cdad83b91506e080182df4151ca2abf9887ca157599469c28f549b8d343786c7666531cc4e18e6235d54962acc31e711318dc619eaf29d4ccdf3b06b430e2b82fd975e73e38e10532fae497c64e13e8622c5f9aa41a3d5ce655a3c2f58c824bcceb1548c662e1cd9272c631268b8eb91471d0acd73add4bc2eccab8d36c6c27030ab175146abafbbcf0e62bd1c8d6715ea34df30c090de1f4a9ccb3d7bd5cb05b4c855bcadd5c96e43a89c7934d49e294d954e0ca75d677a0695cb7734f8d404872c9fa64b20f3283523d1f2f9a657a69d89a9923bc3ba9873e9d1481e89b8d46cc6b72f8df5f0e66f346e859a429547f6e102f8342bf5c25695b5cecb508dc8941934af2a48d04451048d4060a92cb3a8e648262f0fa3b13abe7758d250c85f657c0c7ec7cc8d1b722c233404e8b3792d718b423c40133fe5250a2cbbd6e10f42f555670e378236ff4452a04d29116bfe1a38c2593215a23e6a90f6c083cd84866554e86069d2e797b6f7c877b40370ed1077ecd03d19859dbe4a4989b47d60691776353a9b17ec1644e0f0481356c923a4118458f9cc29ca6c57aed3f0cdb10f079216523c4b5d83e333618e815f3423bcc37a923266bce432b35ea1b168671accf68adbf74f923e902f923e5f902920101b9028d392d747efa5df9ec7976b575ebbbbc4e50e48f494255067d00c8fb6ab805f5dde05d0240f101c33dd0aadb317a173e25a7dec0ceb77ce150099f5ca19dc2df6e44a5b5fc87cab441dc4e6ee717e77d3ffc2bc57ea828567dcbcdb8831dbbb613c0f747fc497e218f903efb5f5c5a2c4e61879bfb069a67eec30acb8af36d1f4a245b9f120c6bea336d8ba3eba72be78a3ded415117b3ed0babab6ce775e1c1ebee9d08f4a0923ef969747533a3a9fc13d19b4c5b1eabe6ade431ad5731c5ccfe98681c31ade95e7d5bf469024456082d06df3fd4e6970fc2533bb9cf6688bb595edacd95f68d1b31a396d8af954e37fd43d6a366757853a1185d62e18587e2cdb51f0a7023f2b3cb9646ffda39e46e98c47f68bb3954a140f5bce405977eb8974c229305c2ca3c7017891f208a041a89d48d3344695cd9106bff8b80a0a48dde46ba4ecb942344cd1887e2f889a5b97e96651dfe7d3116a2b17a86bf11be8ab8bb69f214b7a0dce316367e827192ec0e9a0ac2199b1c4f1042655ca7cf3d1f8da99341afe8f0b1f21338492ecff73f65239f4ea6a5dfcbd08ca9bcadd559dff34a6a8cd9a28a579fd54384f35ceaabab930b87b14779fdc822a587d04910b4d693f288b26d56688e5ffb2d65d9374a32c27dab9778f618df54c15f555f54828113a595fc1ce107ad2ae7592b41e944b0cfe48cd21d36d4fb35dad4de5ffe9531f9e927a25942461a4c9726a292d2ef9dbc0b1d0456b703037b4df9d0c446d707285b9489e8845211cf0e8a3f0a32a5cfc713902df29af2813293a48c2f02b8dc336befa797d3d3f67d90cd4fa25466bbe70d394713fa06b606de967d5a5aa9f8d0310363f7be1a75708d4c72511f67eb2b0495c43e75ca6e085d35c53cdac3cc09142647e68fcbbe921ad25080f91eb50201b91eb0e85ef5afbd04ae28867b1e81b818d79445b1a8e98c272154ab5e8a7797af50d972b241bc0d536481095419bb18be70860dbe9c5d355d74451f31e27209f3d43cd2a633cd961971c381058ad667a9b2e69f0fe9c2a557ba89835fabb16decc1915b54de7b5f00aa5787a39e8d97fdff315a7a0d2aaa5d3e10fc1a02ae74797c43a2719d3361805f5415dbceb716bfb7b07ff4a415a938008f0f9a668395801ee590a83b20d5749facd7f99bece768e7e3adc0e036b82604cf9a9e5c7010db9b54965d094ba9c248f9f4e29045be7962aa6e7243d450caee40bc4dfb9b333e6c289509f899b254d85539a78f1194553bbed9dfca1044372ba2530f2b05ed4a467728474a1d603eba54e4fcf2295c6a559e9c606b6b70c40d4c8cee286f2d79d6f46a8c0079130c2f58cbf4b3ec7fc109cc1ca3dea2ddfaf377eb357ac6b5877aa6f2e1f56df3421daa6ed5d043b5188c6ef1c71d765b3d94815027ea7838d8f448d0fc008d3a0189958ae6fafac687990f5b7d43c103ab97780087f48bc3b7a19f76a945a0d90e1ff279ceef8d32e2b5fdaf3c5d1a5ba52e60dd934cdfdc2492330a5f150f2106ecad186cf1f6ca3907707e34becc8b442ad3dc5ecaa7abfc7bc19cb7a7664ecc127c1d4d0f0515eaa3099def31f3ba376c30d4044ce8cf7669ca465f140ac5ca43f9e856721be03231e6b0cbc655c03b9f237036a504ba29da42b5959029b68f0171ccb5d1a2ca379250d3eb5591ddb52333b954e152e644bf8c8c22ed3c3b471021eeb4a25f2adc63f792c01382e9c01693c4dd9ad333c198e4da0b8af182bd87d2919f2bf4ae94130931cebe0524c1df1cdaed0767ae040ee0f042ae8b2e0674fedaac068db64ae2998f1e29d4fe208f3ca498a1832634f7183a8d6902d86823e12f5bbecdcaf9935f808d72e18e62c1a117ab27bc9acc3287afbd6f7442f4eb48063a381495170171af2d76e3672c37462bcb6c1710afcc873b9168e4bb6887117a9925e3a2b2bc33d0db4fb33809e3768d47ab3b52bd655c71539d8a7e391bcaeafafc71c554e0616d6f6d9ddac0285ce5b9dd9bfe015739925705edf72abe615a376e3fadf3e5807d97a7ca5e4a378ead2a466db9773d3a7d3f7627b29f1183816edb236b4b20af6a212b9ba1b86ed143974777a3de41aaa3a17371aae38dffd3779f254a0da8d9219d98d89049ad55d71e731192bb769ae72e466a67e82dc1b133b9e5129192e2e611d8d8035f6e0dba92d6cade096c56b248237d9405a534d6205e59186c1e5ffdb1dfaafeadc15eb2d11c736b0e57ceee75c6ebdc78c2ce24fd852e87eeb969e14d8d2aef1ed623914bd1932d8dc26bad8e6b3b2afcf8139ee97a4afb1db36a23a94f0ba00c6c6ecd072851c456e72a69af515c7e7d872ec112729168879f1812c9de0cc380a994182a80e4195765d53eac82085ea751cb09eac5f9db99aecf51e9111515b083ba65cad1d6687363c3155f39e5c7124602a879f1ff153f4ecddad23ba9d99384840272613f40e8975118e17a50a27029b5714cf9f3db14c3ded35e31b45fe73fc06a7fe8cc96937ba3e82dcb226be47e45bb6e971ef5e7ba2013cbccb6edaa51d3611452f3c26860232193512e1ca915ca1e82d1e81da1a84b228d92d855a09721f662ff3d58eda5846977f40d2f6fe0845ad3c8cc2c9e6d9e673673d9245f5e55a2f02b6e47e01d27e809572a003809b75177880cc5ded3fde42ac59eeac1f0508eda86e4b4eb7f2de0f9b8500f766798ac7f9583cef34c7faca5efc97ded5585b0c39e0f16fb2401fc50a588017ebcdae043bc236f9309bc4d6c04f089a898263c7897feb006a6af16240547c96bb52d275130bfbeb20f2493713f29eef0455c41134f4f9f27c38d29dd1a2fbb6ecc40bf41d9f32e33352443c299ca7ef6881575dcd4f18ecbe874dde9e796628b21e6a7dc6827587c61fad8a8fc63b886c6f383243a20dcd95fea8e323d0e9811bccc2fd97cb0a347097ef1b5296ea8da5361c3df81672bb179e51f41082ccbc4c4f0c2e2eed5f8f131a2d58aa68caf0aa1a6d9c8aac9f424f7cdd2acd2875d4e0238f35c70ce48c966e114344ba6c5403545a4e8a467bf9cf7ebba117701a5e69a2e71a546d3b674468d4a31bedfc6e70fc0c4c8c3efff332b4b8e1dc604541091dd34a584d333d7291304c08286542b0075f371429605798bbd71ed7ca52ba6b812c7ca91c8c35c2a4f853eb7509c12049150eb7abca4498f5ef4d8dafef8998afb4527b65cd3e6ef1399041887f204cbc81fc030e6242c4395e7752a6545da4996b69740922c07881c1d5bbdc79beab8b17b5b0980d8fad7eeeb5785fbab08a7963bff7e95aa7b526dbe201b968a40f8db9399e7ff8aa18e6f095b9aa4cf4c41e57a78f10f6fc580a955e84f48a8c2b16d13b8b8efa525f1d51426a13325ea3384a5638577f32267f00e2e262f08d46bdeea4891ac5acaa3e3a31fd503dc76a3c92ded39edaa65043b60d52ffb6ea27cbf810899552d4dd5a55e95e172e267be645a3f2c6468b5b1ce76a0b951b85f98efb93aca8b3948c43cbefe76504f90128788e7e08f7f6685ee03b70ac35314d3a64a57a4a8cb7512a9254f3a9aa7e9c1990606ce8ca25e6b9c816b56903e10d7ca1db41a7f991f292acb51337230d0a0ac5604259d7daf5b684493ce3344a8892152fb6baca94f5b02237bfdeef0f9dc6fd372b078a05489f81ee232e63a27726746d52c3d9531bdec03f2d4d56b604231b233592babfe12c64b915200f1e16672b0798982293d768278909bb1352dd42381d7e87c15ba92aae469fae5ed023c643b45c08a5d15b29f34714016ce5c52ac648d4a32a4bb02c701f3a68fb873581ac392ea34277ff3262fba6ecbe274c840751ff28235fb3168cf30bee0fab5cb92c89c8ae3ffd8b03c4253078c31ce19864c8b6f128f6e3e80efda9141bedef5b60adc0d6f8357fe6cb6828b3605e02275deabb5326eff3d52861f072523c5695333b4d51c58c08a44be8e90ff8244da37295e1a1550ce715d08fe600349a9f9870ac83fbaada48cc392b75ab1ab456429e5b236f6b3b1751063b274bf6a75dc2283ca0ae8db757fb856e8c7442e4a3cf6f26e608bca09235f05dc6a2a53862cbae5a5bdcf1bff925ff3c25e38d5ee04591b8c228b215e5f82c21f39462aaa6c548c8d581b4df4386b97fd832a46e2212a3bc5ef4716a10e75cd5e46797dc12241bdec3074d19f971caea7a8f24bc522faf8322301e3e4d2188136ddccc53c6488d5d9df6298befecaf637a2693e8d3db2ed2f8e120e6f1ef5a52471e905bc7f62a3b93b534c9e234d72a75f38e443a05ff62ca45cd25293c23e4ae71784fd1649c61b9469eb152642d8fa2db77b85c26340f4b21b1e8ec7ab58b66fea1397e69665dd9116ce6ecb7d642ec9c2114a4c893b795c1be06893697924c42ed8bc97e0c930898d80e71536dedd3ddcd9b4b35ef5eb462ab984b28925aef1cb524439e36273f7056b17036a1f3ab44eed99199dd6d53b564d2f210a7d52ca896ef0af8de172415b518e92c578d256729744bf79ef3ab444960189cc0cddb9c961bc0a7f0bc51be6ffdf2e057331dd7d05eacd8e6e81e08f90b96539b9d323455428e9abcea706fa357949f2d1067b600af355d435bc71094ed8e29d699504d24427639b4d612d3d2c7e50129145a161cbed02955a0f32615b30cc968c41f2d062c32f796da497b379f5955a0ed5a653ee51f52e6a702b478a9a7af4d48fa25353a258e575c2e0c475b169df4471c22e2ccb1ed607bf831eb28e4487ab655f07520391309d3590ad63436ba31d1c37ecbf586dcaefb56d6110386d6a6a5d785b365701ae291b0a3d13b3dec21729e42591de8ef9f7a7216d9dc23489a3fe8d874a76f146aa26536c1dab083681cc00e9dc9e6603d53d74a1c79558c6fc7bf32d98a485dd562f261e7d2751fefc320c5a2c9a536c84ba467d7a82df93b5803cf60a2726ed8fe7287863fa2a674d01c77b053bcf88a9a502b0fb786f47e50401aa643394624968fb5d5dca34b009a3a32bdce673fd2d0c8e05238b82ee1479cb9b8b7007ca03974e1c56e9bf903c2d0c274cae9f588fcc6b47e02754dc0e7de3cb5a80ace5f98ae68244082144ecbac94d53abb9c89e7d102063107c0ddbb6633d0f987b14217a9d9378007cebdb260a9a89596b11422ec3f1136d469e3c188dfc94ebb1cf8c7f7decfef77995e8334d4321525ad76f32a2efd4c953a319e18c4da8981ee89415f7e2f07914d4fe63d6246504b90fbf03b54bd905661705fb65d00d28c530b7b3c690fb5f88aa1edc6f6dc861d79a1e8c4a6dc1df27b7c2f0b897f1231f176adafae599f4aa29c6a5070103a24468677320b9462cb9a2d40696a5966ca205af33e350742e7e50b27252d2ecf50420cd4fbff8e4570e04b2137722814c64ce0b81d13c14af64eaf36207ae8f9224a47b3c3c0c0996db171544bbe11f2407203eddde94614c9d41945645dcdcabff12cf2fcd01cf062b942bede9184d830fea37df7576b10bbfabdb4a4626979576f403f33060ddfc6f53df73ca618654768001f1e08bbd66de39e8eac625d4f1deb25681c2dc67c6764d555338b4293102191a96cffd8859eb08ecda0489af07c301c12913762fa3f9d192f74c762f50556726c3bacfccc66a038536e913d95186d8aecf381312733beb68b6cedad321fa4e3fdcdcfc5553548a30e1ecf0041f823ec863086c34b3b6e6a7af8a2214122332a4d27392e64cfabb1a9c66c498efb6515f32f01f23073693a37a72240df9709d577b3e184cccc8b9cbf34669b0653e16848ad0a9dbc9d7b0ce3ab88e98616492c83d8b88673aa6a1b93d2f7866caf1984da384145361fcad93640c7481a085b0be84ffb4870705371cabe56f82a233b3d5aab737a2f2b9877fe2885d48163e6c55a53627e6db0a9c7103c867bf829633af2e1379a537267a15765c5ffbf7457eb853d0049f497a7823c0489dd0a1490667b600ccc80f9ebf9afbc007280e4a93b4c20dbb07c10ec4646ce9cd1b3dddacf5ec7bb07d588501daa9ee422da47b4f69f6cb49b3201e1b461b5d4d60d4230995acc88dcc8c928251ebc8d37f3e0dcf8218bbac5e47653e510b270586859238c526c46b7db46e817e467c7fe3f41066e234f4756ac833c9d010fe800e51106deae8eae63d2d9d02c2eda4ab19d63600a5261e69075cc0e28220a3ca4cbfd53f14f654c09a62f6c70fa75368678a7e3936aaae6a3c94d800f95888777bfd394907860ff4446b285345768556f34b1c62cacf50b4ab820d02a18cacfa3a42f086906213e170f26a21a0c7f478d7dff393d68989622e4f89a46845984d1d28ef6584f13f135d6a18fa438e635f7670e3b9e0236d7dc9f99328a807e4468fd7438c56449556c1c13e478072602172f923d0cdff16786fec072f0629a0423025594808ca65d0ee3144947a44519e04b6abd779dc2d119ee4473103e1d608c0e254e0b7698bc876f2d810e4b41f37c9884648d0536069a80f9891d0e2ec4394446b70bb0ffb8032959bb04b82e75f577b8c136b6c87d1f98a962955af7286e4f1a098adb1bef56655757dc5e24cfea40eeb8f37b57edc8b85685c7f1681108f793b7c12df1a203596b57c92f9fa62bc9a1db3e7ed9c802500c7e305606fb82ac11df65c7e40c1fb09084fdd390f55a94873c7a32c0c9d389206d7695220951ff3fcc62cdb39a015649bb65040a06e54111127fd947f344d782f99b59392660917838f2dde4b04038b0baac6966593a8ea2eefa1423c4e9537eb804cb7d58fcbb1eef505ba06b1682cfffc4eab227161bbb9c3aabaec99f2e08fa650ce99e9c02745927ebaaef4f2c70713c97b34b734016a65a0e69db084101289443770fce47722a4c1af6ce554d09aeb9b3e2f076fada5f5fd9c772ee2cb65fff9da7b33e1b2f6a08f1536a403188c771fff5a84c8bc1509ef2dacd23cc699a242f5492bbdb82f13f4b9766cb1465d3d79e5ff9499fd812d346b8ac6e7c8cb83a603250a52daa0a55e04521f22a4246c5c149bb3426639d84dc651f7246d11ff49a2597b9a77104bc2cb1880f0347f2110b2cf33866aaa6bcce8e058e03aee01191adfee651694b506d952210398513a9313836e1457e5e8de9bdf26ed7301c3b6578a291d73cdf2602f6493e7685dff5e7b4db4c0fc151e253009234b251ecebeb10c2facce66e125b8fc8c6a78926dff9dd250037a12aa32c086c155f980601ab25de4bac8ce364c7fa8fdd965ddd03dedc8de498dfd3cfdc86b0b56398b10245dce984f2c5087610efd29aadec6eb78c18956d6912203f7016f3f47452578d1b718b6d221b38782bab9e29b344dee9deb594d8798a6a01296f5da1f143743c61c402700fd33904b43d8d6a44dc6fc04fcb9841544dd9116a5b908f06dd39be385750a4371f7dbce8b9b75aa01fcb4d2a1a94f22b7bf876153543f410e7f8c1504aced875a2e054dd5a2138eec9607d5d5ae7bae91da662c415ac6f0a9bb981393f660695e4b65b16dbaf35ec0d40c68ff4fd991e8152e03152c332e92a62c2bea76c0a239387148409b6a7c2c98c24b506b059869cb911a30cf15c22e0ea0f86db884040f7cc8f58b1d3fcdc251d223a285f191ee4bb2de83365ef74726c7abfaa9146c308530edde09be20e9d6eaeef850d00b165e768463b8793a914c421bb81e8905938540c64b77e82ee6a4a6a15f5cfb1df20a41305ad3dffafc7e8d882a3c9e3635d115c9314d8f3602ba752734e34e188c3cf46b3dd5cd83bb46b12e1ec2a8b9d7dd5b61c5a9f4f0704504e2882068034db62e8a9abf3c7c5b9a8bfde509d36899fc5b4e5bef940fd447b9275024febdc9a91d6d56012f1c6a44f94b96397ff2c78fd617870bf089067c6343ae4270f6e6dc495a260bc1ccd0a1c0771821895d26dd66a203825d19e621b86b57f9a51bceae9bb14d1f9961c5a904a64a1dad73c89129ac4920cc4e86e3696959be3305f6d5e33baee00c7f978bf7a1a7864ed89132ff350b45226e6e4db39122bd344c315208edafdfe6b567677f869b64532bed2f7f9087e3c6c1137004f205ce1485f1b9c3ec798b0509c00f6a2b6663048492caa3889328ea6216e34b959fd244249048cec8c0f7de2ff97105ad030a536ec6c4103b33c26acf4539a1b74a0792b9b6c80f95ee4326b09934e068429242495e51a49a712f8513ce91da60573e83443a0e12ac2a174b82d090813b930e10ed7cd44ed72d20b061e9eb253d715408d79d8a77d67919bb196dadcfb84bdc4eb647a4ae09c436d220e0ce914188c49fe9ffaa2fb87f08809d5021cb632a6642bdc1e3664e84dc0afca031f0150c4190893da6462dd917655930a6d1deebdf4a0b1e461126fb2d54d374e4d5a455a6207291d03d2d138e34260ca0ba2286044afc4d95822bead1eefdf0509cb4a0c09c3425c8b0e9236703cbdf4ba833ebea4942d4e0ea84df284c438ffae28b3ec7ded12dda8bbbeabdd07bd1925912aeb74bfda42a62f8a5e716949f4a195f38c9f7a041776c69a7a1599d6880299f50c3b75e6a9b5e0314731611154d1f755a1381fd7575a6b34019d37c40aabb4bcd6965411f48f3b893e5627748deed82de02e9d47af8d3a087f661dc5f2c65ea16fdb6455a6211c77fd41532017ac4aa17bdc43e33aa4bf6ebdd453fb90b863aefe4281691a736594d714bdc26520fb954fa4a3c8d8f5620316e7b8a3b736b28859514bb2ac434001a129975e0f53f473c41ad752670598a2b356feacdb9e4a609a44e83167539d4e3223143d19f79738b96a27171009f17fca174a8821c3f0bd7dd15b2e98eb3fe1437dbdbe881f9c86c0844db5ee82b627c519fae5ea7b5dabc382c9938529dc031f8cdf0ab320f479d8793081f1ecf45a2af3d339db470bea05607148a060348cfb344edcd773efff7645f021d67db2dc0abbe9a8fc343016e9e57933f642f487d649e3a01ad4f815fe3701750d67b1db3c74c6b30f7923d08a807e78e58aeec28691475bbe4260db35b8f850330fbf68f73f944b745208748261f32a9ee5929cf924193fbca8f7d15d0118e3ef205f6a639e4a25bb23c28f036764ba7dfb4f8203eb0b69e757fe5a40b560cae416eda6195f15330aa7f4ea8cd113c30583675a94c486da43a0f26dc5d922aeaa8b084124f5c5dbd0ef31e4ed52de942b1f8ec6b494fa9e730e8f0cac9ea3153610e13ab589d8840e5ecef5570b619574477e457c529d431a48fd3679f0a831832b9a1ad4cb6c99c25e0c1bcd2cc73ed79b2a589501e2abab2d2a64c9fbc4cd8bf14800f8a67d46ef10a68db32411d63fc36e8125bd0e79b27d861324afa6929be5cee98c245f0af5755595f60d29d485222c4a43e2614d315723c5eecbc836242a028053ff8a4c83324edbd6899887c3ab3394d5725effbb55ff056c35fdde91c28a34362aa8ab06f0f1da408e7be1863ef007b57ee062c5e660e2bd221a306774e7b7ed5fe5d04e3a2fa49a61a9d15e4aea12bfe588f7f7fe357581772356998126b1deb48988b56506eb805be01c07f3706100658b5be1e96b1531f8838d78cbb849a4e51c1a80d3776987407c0a1610d43178962c5a34cac6a62e8aaa963b8833549f8ef954e155f962b6d6ea4ceaa9f711959fdab71a74e8ef57ab16b477bbe47b78718f8aeb29239958220b079e13dab8f77ec24be4c3df3db9d9e306c9da8bcff284c27becdeba20ccbdf94f7853069c936ebb209f2dcef4d5b0c73a68c5bfa67a2366f68ea00603ce2b1fbcb897e80b1f7013d50355df6e989c660aabfecf886ccd69d86352c81350520bced1a2beaa0dffb1362c8b3857f1f1c17393fbf45ef639b1f6be41ace5f1e132e257a96af92727bfdba6b1cc09864c5b085d13be7986a4e720a49065f1c70e140f69cc462ab7bec075108d1384f6935781bec4dce9efad2c8e238e7f41b8e430ba231e9e23c6af52bb0dea07e6a0ffb0a3549db69ff05b1c7d57b1fb5f98b75122b0d53d038a37f3c499d9c891fe571015bf6fae1f27cd1c4790f633cc88b9f018bcc79e1857328fdb72eb7e0fc50558e2ab338fb902be7535c12c0235b21ccc3102454e75b20d5652231393ee2f14b5c0bf2ec8a485c02fdead3fb371b41f43d69a518444a92a6967ef3846db7661d973206eab07fd08f69b5a3a36cfe749acf67c2db8df7994821df76a74d8a36521cc6f4de3e1035e18e9640417363427082daf240e71f60df231fc22b8175620c74e2899eccc35387901cf57f8ea34d3f2a4165a4b7f9c41082ce46980480608c539d7f248a41c1ac1a7d5d28884b7ef5d184938d94dd473fa28ba674ce934807f56276fa821da3dfe5f932bef6565aed54f5c3517ace0c9221214417b2d523ddb65eb4bf68c547b4c40ec52ce09c51e1fa64422b21b412a8cb416db685469ed047e2ae26ca06de8e10abb64bec6ca07884927b51968daa05573e35fed3d2ae343126287069190029b9a7a724c177057dba050c3b18c0222de84a50e2413eea9a12f50d94ceefe48995ddf907de29a46ce561cd8242946eaed26474e50984ac005be37fb745254f3df97f880cd24732a46626bf4975bc6c749ac1c75833ed99b4dbab1d71267b82758229bdcb11cd234b8c990478de16160cf4989df335f646f6286d6f62f350811942df2f645afb14768f50ddf221d8e029674d40994c2ec2c4eb12f9ea6aa14d81a0bd8c3b62aea41877104ba9f50ed75c53b5f0cf4d913b7878b38dac9dd45abc35feacc53dd9cbb3029689cef401df37529318390341babe225094f268a886ce3bd6c6e5bee7849ab4f37c11505c9fb71ea7ca9db1c882dff90d91f1c046bc0b2306f341126b6becc475c6dee4d5aa9bd77852316b72a9189a6c309002f9be5296a0307895a6f729d7e3386cc9b18aed6b2168847a160c11db23400a80d3121febde4e480f2c7399dc71594ddfafcf868e60cc97ce8dd6861efefd9f92e61987ea7aa5baec0117866c387e07a798a1efce156b5ec8ddb3794b3035e34544e9d9a447c9a57aaaa63766fad9be9bf6ea08aff67c90792613b5b54b483f2965cde93f4b9bafc90e3510bbe1d3bc13ef88b08fdabce53bfec8b26eba2f09f5701915cf72c095388b635c8a6aa14d9c1d836367860450591c35230ed1759928b80575ac152b97ece0e025a283f62ef90ecfa1f3a3eed39068ca91d6b0f35f22edbd54637e29382244c8dc62e4714d6c729a1825dbc13e4e245ea5ce221e98a8d25aff7f65336f634f944c5e33fd99cc20202fce700fe053207ec9a73237da10ab2da53ff5f0ac0adcbcdfd31a642dd69541b7661469a97e87fdb91f1c9a533e0cabfd12e0a015e96fb3f5154d6cdf4e2a593780bcc79f918bd1844ffa62a0637c7957866e779e491d864b409627129fd5442cceab809755ba78aa08885e7daca24366554dc75839e75a66c30c5937987f197c9bdf377b3eddc8f24447e96f17bf8633645ac81ca2baf52f4738a52afbe0b12068ff44d5bc35a3f83986825aefaba9fc29ae57f74dba2d3f24d3692bfa33beb46b75449dfdb162b0ca5afe93d3f54d897c8aa7e3f7fc9f632cd348a47e1837e3aec9da2fb675b169af643854a2714daeb2f060480d18f0fc84eb1becde4368c2886867a9b621ac3966222ea1a5c1b2e2aad5a6d24ed21533c91f9a8b019195529a6e08eccf10f40563c65ca50bfa78d83ae54ca01cc21925375ac8d10de1adbe763ca9d885e5b28565332d184878947f6b89a51db652ecd0155625e4cd472e5f366dcf79b36e79465ca7a3c236f3ef8c4acbd83ccceb8b19b91855dee1122f15627c57eebc26967f4263434b321bd4cec915975821e08f9095ce6d7705493d850c0da356fb8cfe51395d1d7ba7efa5d4f1cda7b735f13d0183f8f1a282f28a24ca0f0e719b5e567186ee1255d241e66790bcab2e55846085d1f025e38a2d36ee014b40cc2c5afe253b858774e34c026bd8dd65264e08df28f22498f88e64aa4d42eed7f98d9b81b593b9adbbe99cccf617f5bc2809198bdfb460e8335eb8d6d94e278a50f902950103b902903941e6e79ed44f046543182b5bc91c08ba91a53a50351470a6a64215b1b87c4487df0d23a191f8eb1429db96776bcf42b0ee0556ad1fbe54589ed283901d3269a783e1ffad95d3b98c52b6d6de730edd4c93a652f53d76f8f3d343f04953d81c43c9e96934df194297fbfda8098baf1a277fa49615b9e429562f2b5cc029a76da5915d35c96922639f5d2f3157f5edb63918b663d299a2ebba2727117c328d73f83959a82cfb392161c98ceb2b1d6b8f0b78ded12dcad63da02414be8c853c5a7186f13d6c8d9f7f738356fdfbda49449bd2873e7fc5e3d7135d59cad6abd758dd954c72b9ac2a52a9f4d40e675f17807f69af4c7119f4dbd26492d194d64a18334c5afdb8d4ed18eef34578d9a4f9bca31ab5c6c6219a3a2fa5b9d29feaca1b37c24115d4fbb2f8a8282df604b24a18cc56215c791042a7f28eb859d2e57d43ce6cc50edc48688a0e449ad4aa6f5c00c72dcf0322d2a022b7fe495028bbc89ab53982595755f384b4bd723a7f49d77a7288b2b5b51ab4871624132bacc0fc1315250635bfb8bab3efa73b75b890b8701a48eb67ba421c64e50d2d6c823b7ba0e8a6bf7b371f65e08da37ab9424b876910fcae73aec09b44210aa4a4b8e401d055a9dcd5bf5e4869c72b0eb51a9d0a1e3405cf91564554a549b16e1a6b9fd90f435e2d652b45be313ac6b7bdeacd499bbbc61a00f4efa6932b3f01c0c24f7eac31955296677a50fee299536aa9df12168f3e91edcd2b634eb8fd6570f99a24abddf4d94cd77f2f087dc905dfd0eaa228c436935cd1a74f6f9d72f0ca11283e15632403d786258cab7d224e99e7fa7b59db465f26965532450cc5260e3951a32102795e2d0d5cd968fb356e142103f5204762e194d130789caa35995091faaf9167d3e3d144159b659a0f673dfdf2c6a0",
|
|
+ "note": "rounds strictly increasing; rows canonical as in v2 (index, then scheme); every Falcon row verifies over M_r of its round with the key of its index (keys below), the SLH-DSA rows likewise"
|
|
+ },
|
|
+ {
|
|
+ "id": "vs-28001-1000-numai-r2",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "hash": "0x3333333333333333333333333333333333333333333333333333333333333333",
|
|
+ "groups": [
|
|
+ {
|
|
+ "round": 2,
|
|
+ "rows": [
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 1,
|
|
+ "signature": "0x392d747efa5df9ec7976b575ebbbbc4e50e48f494255067d00c8fb6ab805f5dde05d0240f101c33dd0aadb317a173e25a7dec0ceb77ce150099f5ca19dc2df6e44a5b5fc87cab441dc4e6ee717e77d3ffc2bc57ea828567dcbcdb8831dbbb613c0f747fc497e218f903efb5f5c5a2c4e61879bfb069a67eec30acb8af36d1f4a245b9f120c6bea336d8ba3eba72be78a3ded415117b3ed0babab6ce775e1c1ebee9d08f4a0923ef969747533a3a9fc13d19b4c5b1eabe6ade431ad5731c5ccfe98681c31ade95e7d5bf469024456082d06df3fd4e6970fc2533bb9cf6688bb595edacd95f68d1b31a396d8af954e37fd43d6a366757853a1185d62e18587e2cdb51f0a7023f2b3cb9646ffda39e46e98c47f68bb3954a140f5bce405977eb8974c229305c2ca3c7017891f208a041a89d48d3344695cd9106bff8b80a0a48dde46ba4ecb942344cd1887e2f889a5b97e96651dfe7d3116a2b17a86bf11be8ab8bb69f214b7a0dce316367e827192ec0e9a0ac2199b1c4f1042655ca7cf3d1f8da99341afe8f0b1f21338492ecff73f65239f4ea6a5dfcbd08ca9bcadd559dff34a6a8cd9a28a579fd54384f35ceaabab930b87b14779fdc822a587d04910b4d693f288b26d56688e5ffb2d65d9374a32c27dab9778f618df54c15f555f54828113a595fc1ce107ad2ae7592b41e944b0cfe48cd21d36d4fb35dad4de5ffe9531f9e927a25942461a4c9726a292d2ef9dbc0b1d0456b703037b4df9d0c446d707285b9489e8845211cf0e8a3f0a32a5cfc713902df29af2813293a48c2f02b8dc336befa797d3d3f67d90cd4fa25466bbe70d394713fa06b606de967d5a5aa9f8d0310363f7be1a75708d4c72511f67eb2b0495c43e75ca6e085d35c53cdac3cc09142647e68fcbbe921ad25080"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 2,
|
|
+ "index": 1,
|
|
+ "signature": "0xe85ef5afbd04ae28867b1e81b818d79445b1a8e98c272154ab5e8a7797af50d972b241bc0d536481095419bb18be70860dbe9c5d355d74451f31e27209f3d43cd2a633cd961971c381058ad667a9b2e69f0fe9c2a557ba89835fabb16decc1915b54de7b5f00aa5787a39e8d97fdff315a7a0d2aaa5d3e10fc1a02ae74797c43a2719d3361805f5415dbceb716bfb7b07ff4a415a938008f0f9a668395801ee590a83b20d5749facd7f99bece768e7e3adc0e036b82604cf9a9e5c7010db9b54965d094ba9c248f9f4e29045be7962aa6e7243d450caee40bc4dfb9b333e6c289509f899b254d85539a78f1194553bbed9dfca1044372ba2530f2b05ed4a467728474a1d603eba54e4fcf2295c6a559e9c606b6b70c40d4c8cee286f2d79d6f46a8c0079130c2f58cbf4b3ec7fc109cc1ca3dea2ddfaf377eb357ac6b5877aa6f2e1f56df3421daa6ed5d043b5188c6ef1c71d765b3d94815027ea7838d8f448d0fc008d3a0189958ae6fafac687990f5b7d43c103ab97780087f48bc3b7a19f76a945a0d90e1ff279ceef8d32e2b5fdaf3c5d1a5ba52e60dd934cdfdc2492330a5f150f2106ecad186cf1f6ca3907707e34becc8b442ad3dc5ecaa7abfc7bc19cb7a7664ecc127c1d4d0f0515eaa3099def31f3ba376c30d4044ce8cf7669ca465f140ac5ca43f9e856721be03231e6b0cbc655c03b9f237036a504ba29da42b5959029b68f0171ccb5d1a2ca379250d3eb5591ddb52333b954e152e644bf8c8c22ed3c3b471021eeb4a25f2adc63f792c01382e9c01693c4dd9ad333c198e4da0b8af182bd87d2919f2bf4ae94130931cebe0524c1df1cdaed0767ae040ee0f042ae8b2e0674fedaac068db64ae2998f1e29d4fe208f3ca498a1832634f7183a8d6902d86823e12f5bbecdcaf9935f808d72e18e62c1a117ab27bc9acc3287afbd6f7442f4eb48063a381495170171af2d76e3672c37462bcb6c1710afcc873b9168e4bb6887117a9925e3a2b2bc33d0db4fb33809e3768d47ab3b52bd655c71539d8a7e391bcaeafafc71c554e0616d6f6d9ddac0285ce5b9dd9bfe015739925705edf72abe615a376e3fadf3e5807d97a7ca5e4a378ead2a466db9773d3a7d3f7627b29f1183816edb236b4b20af6a212b9ba1b86ed143974777a3de41aaa3a17371aae38dffd3779f254a0da8d9219d98d89049ad55d71e731192bb769ae72e466a67e82dc1b133b9e5129192e2e611d8d8035f6e0dba92d6cade096c56b248237d9405a534d6205e59186c1e5ffdb1dfaafeadc15eb2d11c736b0e57ceee75c6ebdc78c2ce24fd852e87eeb969e14d8d2aef1ed623914bd1932d8dc26bad8e6b3b2afcf8139ee97a4afb1db36a23a94f0ba00c6c6ecd072851c456e72a69af515c7e7d872ec112729168879f1812c9de0cc380a994182a80e4195765d53eac82085ea751cb09eac5f9db99aecf51e9111515b083ba65cad1d6687363c3155f39e5c7124602a879f1ff153f4ecddad23ba9d99384840272613f40e8975118e17a50a27029b5714cf9f3db14c3ded35e31b45fe73fc06a7fe8cc96937ba3e82dcb226be47e45bb6e971ef5e7ba2013cbccb6edaa51d3611452f3c26860232193512e1ca915ca1e82d1e81da1a84b228d92d855a09721f662ff3d58eda5846977f40d2f6fe0845ad3c8cc2c9e6d9e673673d9245f5e55a2f02b6e47e01d27e809572a003809b75177880cc5ded3fde42ac59eeac1f0508eda86e4b4eb7f2de0f9b8500f766798ac7f9583cef34c7faca5efc97ded5585b0c39e0f16fb2401fc50a588017ebcdae043bc236f9309bc4d6c04f089a898263c7897feb006a6af16240547c96bb52d275130bfbeb20f2493713f29eef0455c41134f4f9f27c38d29dd1a2fbb6ecc40bf41d9f32e33352443c299ca7ef6881575dcd4f18ecbe874dde9e796628b21e6a7dc6827587c61fad8a8fc63b886c6f383243a20dcd95fea8e323d0e9811bccc2fd97cb0a347097ef1b5296ea8da5361c3df81672bb179e51f41082ccbc4c4f0c2e2eed5f8f131a2d58aa68caf0aa1a6d9c8aac9f424f7cdd2acd2875d4e0238f35c70ce48c966e114344ba6c5403545a4e8a467bf9cf7ebba117701a5e69a2e71a546d3b674468d4a31bedfc6e70fc0c4c8c3efff332b4b8e1dc604541091dd34a584d333d7291304c08286542b0075f371429605798bbd71ed7ca52ba6b812c7ca91c8c35c2a4f853eb7509c12049150eb7abca4498f5ef4d8dafef8998afb4527b65cd3e6ef1399041887f204cbc81fc030e6242c4395e7752a6545da4996b69740922c07881c1d5bbdc79beab8b17b5b0980d8fad7eeeb5785fbab08a7963bff7e95aa7b526dbe201b968a40f8db9399e7ff8aa18e6f095b9aa4cf4c41e57a78f10f6fc580a955e84f48a8c2b16d13b8b8efa525f1d51426a13325ea3384a5638577f32267f00e2e262f08d46bdeea4891ac5acaa3e3a31fd503dc76a3c92ded39edaa65043b60d52ffb6ea27cbf810899552d4dd5a55e95e172e267be645a3f2c6468b5b1ce76a0b951b85f98efb93aca8b3948c43cbefe76504f90128788e7e08f7f6685ee03b70ac35314d3a64a57a4a8cb7512a9254f3a9aa7e9c1990606ce8ca25e6b9c816b56903e10d7ca1db41a7f991f292acb51337230d0a0ac5604259d7daf5b684493ce3344a8892152fb6baca94f5b02237bfdeef0f9dc6fd372b078a05489f81ee232e63a27726746d52c3d9531bdec03f2d4d56b604231b233592babfe12c64b915200f1e16672b0798982293d768278909bb1352dd42381d7e87c15ba92aae469fae5ed023c643b45c08a5d15b29f34714016ce5c52ac648d4a32a4bb02c701f3a68fb873581ac392ea34277ff3262fba6ecbe274c840751ff28235fb3168cf30bee0fab5cb92c89c8ae3ffd8b03c4253078c31ce19864c8b6f128f6e3e80efda9141bedef5b60adc0d6f8357fe6cb6828b3605e02275deabb5326eff3d52861f072523c5695333b4d51c58c08a44be8e90ff8244da37295e1a1550ce715d08fe600349a9f9870ac83fbaada48cc392b75ab1ab456429e5b236f6b3b1751063b274bf6a75dc2283ca0ae8db757fb856e8c7442e4a3cf6f26e608bca09235f05dc6a2a53862cbae5a5bdcf1bff925ff3c25e38d5ee04591b8c228b215e5f82c21f39462aaa6c548c8d581b4df4386b97fd832a46e2212a3bc5ef4716a10e75cd5e46797dc12241bdec3074d19f971caea7a8f24bc522faf8322301e3e4d2188136ddccc53c6488d5d9df6298befecaf637a2693e8d3db2ed2f8e120e6f1ef5a52471e905bc7f62a3b93b534c9e234d72a75f38e443a05ff62ca45cd25293c23e4ae71784fd1649c61b9469eb152642d8fa2db77b85c26340f4b21b1e8ec7ab58b66fea1397e69665dd9116ce6ecb7d642ec9c2114a4c893b795c1be06893697924c42ed8bc97e0c930898d80e71536dedd3ddcd9b4b35ef5eb462ab984b28925aef1cb524439e36273f7056b17036a1f3ab44eed99199dd6d53b564d2f210a7d52ca896ef0af8de172415b518e92c578d256729744bf79ef3ab444960189cc0cddb9c961bc0a7f0bc51be6ffdf2e057331dd7d05eacd8e6e81e08f90b96539b9d323455428e9abcea706fa357949f2d1067b600af355d435bc71094ed8e29d699504d24427639b4d612d3d2c7e50129145a161cbed02955a0f32615b30cc968c41f2d062c32f796da497b379f5955a0ed5a653ee51f52e6a702b478a9a7af4d48fa25353a258e575c2e0c475b169df4471c22e2ccb1ed607bf831eb28e4487ab655f07520391309d3590ad63436ba31d1c37ecbf586dcaefb56d6110386d6a6a5d785b365701ae291b0a3d13b3dec21729e42591de8ef9f7a7216d9dc23489a3fe8d874a76f146aa26536c1dab083681cc00e9dc9e6603d53d74a1c79558c6fc7bf32d98a485dd562f261e7d2751fefc320c5a2c9a536c84ba467d7a82df93b5803cf60a2726ed8fe7287863fa2a674d01c77b053bcf88a9a502b0fb786f47e50401aa643394624968fb5d5dca34b009a3a32bdce673fd2d0c8e05238b82ee1479cb9b8b7007ca03974e1c56e9bf903c2d0c274cae9f588fcc6b47e02754dc0e7de3cb5a80ace5f98ae68244082144ecbac94d53abb9c89e7d102063107c0ddbb6633d0f987b14217a9d9378007cebdb260a9a89596b11422ec3f1136d469e3c188dfc94ebb1cf8c7f7decfef77995e8334d4321525ad76f32a2efd4c953a319e18c4da8981ee89415f7e2f07914d4fe63d6246504b90fbf03b54bd905661705fb65d00d28c530b7b3c690fb5f88aa1edc6f6dc861d79a1e8c4a6dc1df27b7c2f0b897f1231f176adafae599f4aa29c6a5070103a24468677320b9462cb9a2d40696a5966ca205af33e350742e7e50b27252d2ecf50420cd4fbff8e4570e04b2137722814c64ce0b81d13c14af64eaf36207ae8f9224a47b3c3c0c0996db171544bbe11f2407203eddde94614c9d41945645dcdcabff12cf2fcd01cf062b942bede9184d830fea37df7576b10bbfabdb4a4626979576f403f33060ddfc6f53df73ca618654768001f1e08bbd66de39e8eac625d4f1deb25681c2dc67c6764d555338b4293102191a96cffd8859eb08ecda0489af07c301c12913762fa3f9d192f74c762f50556726c3bacfccc66a038536e913d95186d8aecf381312733beb68b6cedad321fa4e3fdcdcfc5553548a30e1ecf0041f823ec863086c34b3b6e6a7af8a2214122332a4d27392e64cfabb1a9c66c498efb6515f32f01f23073693a37a72240df9709d577b3e184cccc8b9cbf34669b0653e16848ad0a9dbc9d7b0ce3ab88e98616492c83d8b88673aa6a1b93d2f7866caf1984da384145361fcad93640c7481a085b0be84ffb4870705371cabe56f82a233b3d5aab737a2f2b9877fe2885d48163e6c55a53627e6db0a9c7103c867bf829633af2e1379a537267a15765c5ffbf7457eb853d0049f497a7823c0489dd0a1490667b600ccc80f9ebf9afbc007280e4a93b4c20dbb07c10ec4646ce9cd1b3dddacf5ec7bb07d588501daa9ee422da47b4f69f6cb49b3201e1b461b5d4d60d4230995acc88dcc8c928251ebc8d37f3e0dcf8218bbac5e47653e510b270586859238c526c46b7db46e817e467c7fe3f41066e234f4756ac833c9d010fe800e51106deae8eae63d2d9d02c2eda4ab19d63600a5261e69075cc0e28220a3ca4cbfd53f14f654c09a62f6c70fa75368678a7e3936aaae6a3c94d800f95888777bfd394907860ff4446b285345768556f34b1c62cacf50b4ab820d02a18cacfa3a42f086906213e170f26a21a0c7f478d7dff393d68989622e4f89a46845984d1d28ef6584f13f135d6a18fa438e635f7670e3b9e0236d7dc9f99328a807e4468fd7438c56449556c1c13e478072602172f923d0cdff16786fec072f0629a0423025594808ca65d0ee3144947a44519e04b6abd779dc2d119ee4473103e1d608c0e254e0b7698bc876f2d810e4b41f37c9884648d0536069a80f9891d0e2ec4394446b70bb0ffb8032959bb04b82e75f577b8c136b6c87d1f98a962955af7286e4f1a098adb1bef56655757dc5e24cfea40eeb8f37b57edc8b85685c7f1681108f793b7c12df1a203596b57c92f9fa62bc9a1db3e7ed9c802500c7e305606fb82ac11df65c7e40c1fb09084fdd390f55a94873c7a32c0c9d389206d7695220951ff3fcc62cdb39a015649bb65040a06e54111127fd947f344d782f99b59392660917838f2dde4b04038b0baac6966593a8ea2eefa1423c4e9537eb804cb7d58fcbb1eef505ba06b1682cfffc4eab227161bbb9c3aabaec99f2e08fa650ce99e9c02745927ebaaef4f2c70713c97b34b734016a65a0e69db084101289443770fce47722a4c1af6ce554d09aeb9b3e2f076fada5f5fd9c772ee2cb65fff9da7b33e1b2f6a08f1536a403188c771fff5a84c8bc1509ef2dacd23cc699a242f5492bbdb82f13f4b9766cb1465d3d79e5ff9499fd812d346b8ac6e7c8cb83a603250a52daa0a55e04521f22a4246c5c149bb3426639d84dc651f7246d11ff49a2597b9a77104bc2cb1880f0347f2110b2cf33866aaa6bcce8e058e03aee01191adfee651694b506d952210398513a9313836e1457e5e8de9bdf26ed7301c3b6578a291d73cdf2602f6493e7685dff5e7b4db4c0fc151e253009234b251ecebeb10c2facce66e125b8fc8c6a78926dff9dd250037a12aa32c086c155f980601ab25de4bac8ce364c7fa8fdd965ddd03dedc8de498dfd3cfdc86b0b56398b10245dce984f2c5087610efd29aadec6eb78c18956d6912203f7016f3f47452578d1b718b6d221b38782bab9e29b344dee9deb594d8798a6a01296f5da1f143743c61c402700fd33904b43d8d6a44dc6fc04fcb9841544dd9116a5b908f06dd39be385750a4371f7dbce8b9b75aa01fcb4d2a1a94f22b7bf876153543f410e7f8c1504aced875a2e054dd5a2138eec9607d5d5ae7bae91da662c415ac6f0a9bb981393f660695e4b65b16dbaf35ec0d40c68ff4fd991e8152e03152c332e92a62c2bea76c0a239387148409b6a7c2c98c24b506b059869cb911a30cf15c22e0ea0f86db884040f7cc8f58b1d3fcdc251d223a285f191ee4bb2de83365ef74726c7abfaa9146c308530edde09be20e9d6eaeef850d00b165e768463b8793a914c421bb81e8905938540c64b77e82ee6a4a6a15f5cfb1df20a41305ad3dffafc7e8d882a3c9e3635d115c9314d8f3602ba752734e34e188c3cf46b3dd5cd83bb46b12e1ec2a8b9d7dd5b61c5a9f4f0704504e2882068034db62e8a9abf3c7c5b9a8bfde509d36899fc5b4e5bef940fd447b9275024febdc9a91d6d56012f1c6a44f94b96397ff2c78fd617870bf089067c6343ae4270f6e6dc495a260bc1ccd0a1c0771821895d26dd66a203825d19e621b86b57f9a51bceae9bb14d1f9961c5a904a64a1dad73c89129ac4920cc4e86e3696959be3305f6d5e33baee00c7f978bf7a1a7864ed89132ff350b45226e6e4db39122bd344c315208edafdfe6b567677f869b64532bed2f7f9087e3c6c1137004f205ce1485f1b9c3ec798b0509c00f6a2b6663048492caa3889328ea6216e34b959fd244249048cec8c0f7de2ff97105ad030a536ec6c4103b33c26acf4539a1b74a0792b9b6c80f95ee4326b09934e068429242495e51a49a712f8513ce91da60573e83443a0e12ac2a174b82d090813b930e10ed7cd44ed72d20b061e9eb253d715408d79d8a77d67919bb196dadcfb84bdc4eb647a4ae09c436d220e0ce914188c49fe9ffaa2fb87f08809d5021cb632a6642bdc1e3664e84dc0afca031f0150c4190893da6462dd917655930a6d1deebdf4a0b1e461126fb2d54d374e4d5a455a6207291d03d2d138e34260ca0ba2286044afc4d95822bead1eefdf0509cb4a0c09c3425c8b0e9236703cbdf4ba833ebea4942d4e0ea84df284c438ffae28b3ec7ded12dda8bbbeabdd07bd1925912aeb74bfda42a62f8a5e716949f4a195f38c9f7a041776c69a7a1599d6880299f50c3b75e6a9b5e0314731611154d1f755a1381fd7575a6b34019d37c40aabb4bcd6965411f48f3b893e5627748deed82de02e9d47af8d3a087f661dc5f2c65ea16fdb6455a6211c77fd41532017ac4aa17bdc43e33aa4bf6ebdd453fb90b863aefe4281691a736594d714bdc26520fb954fa4a3c8d8f5620316e7b8a3b736b28859514bb2ac434001a129975e0f53f473c41ad752670598a2b356feacdb9e4a609a44e83167539d4e3223143d19f79738b96a27171009f17fca174a8821c3f0bd7dd15b2e98eb3fe1437dbdbe881f9c86c0844db5ee82b627c519fae5ea7b5dabc382c9938529dc031f8cdf0ab320f479d8793081f1ecf45a2af3d339db470bea05607148a060348cfb344edcd773efff7645f021d67db2dc0abbe9a8fc343016e9e57933f642f487d649e3a01ad4f815fe3701750d67b1db3c74c6b30f7923d08a807e78e58aeec28691475bbe4260db35b8f850330fbf68f73f944b745208748261f32a9ee5929cf924193fbca8f7d15d0118e3ef205f6a639e4a25bb23c28f036764ba7dfb4f8203eb0b69e757fe5a40b560cae416eda6195f15330aa7f4ea8cd113c30583675a94c486da43a0f26dc5d922aeaa8b084124f5c5dbd0ef31e4ed52de942b1f8ec6b494fa9e730e8f0cac9ea3153610e13ab589d8840e5ecef5570b619574477e457c529d431a48fd3679f0a831832b9a1ad4cb6c99c25e0c1bcd2cc73ed79b2a589501e2abab2d2a64c9fbc4cd8bf14800f8a67d46ef10a68db32411d63fc36e8125bd0e79b27d861324afa6929be5cee98c245f0af5755595f60d29d485222c4a43e2614d315723c5eecbc836242a028053ff8a4c83324edbd6899887c3ab3394d5725effbb55ff056c35fdde91c28a34362aa8ab06f0f1da408e7be1863ef007b57ee062c5e660e2bd221a306774e7b7ed5fe5d04e3a2fa49a61a9d15e4aea12bfe588f7f7fe357581772356998126b1deb48988b56506eb805be01c07f3706100658b5be1e96b1531f8838d78cbb849a4e51c1a80d3776987407c0a1610d43178962c5a34cac6a62e8aaa963b8833549f8ef954e155f962b6d6ea4ceaa9f711959fdab71a74e8ef57ab16b477bbe47b78718f8aeb29239958220b079e13dab8f77ec24be4c3df3db9d9e306c9da8bcff284c27becdeba20ccbdf94f7853069c936ebb209f2dcef4d5b0c73a68c5bfa67a2366f68ea00603ce2b1fbcb897e80b1f7013d50355df6e989c660aabfecf886ccd69d86352c81350520bced1a2beaa0dffb1362c8b3857f1f1c17393fbf45ef639b1f6be41ace5f1e132e257a96af92727bfdba6b1cc09864c5b085d13be7986a4e720a49065f1c70e140f69cc462ab7bec075108d1384f6935781bec4dce9efad2c8e238e7f41b8e430ba231e9e23c6af52bb0dea07e6a0ffb0a3549db69ff05b1c7d57b1fb5f98b75122b0d53d038a37f3c499d9c891fe571015bf6fae1f27cd1c4790f633cc88b9f018bcc79e1857328fdb72eb7e0fc50558e2ab338fb902be7535c12c0235b21ccc3102454e75b20d5652231393ee2f14b5c0bf2ec8a485c02fdead3fb371b41f43d69a518444a92a6967ef3846db7661d973206eab07fd08f69b5a3a36cfe749acf67c2db8df7994821df76a74d8a36521cc6f4de3e1035e18e9640417363427082daf240e71f60df231fc22b8175620c74e2899eccc35387901cf57f8ea34d3f2a4165a4b7f9c41082ce46980480608c539d7f248a41c1ac1a7d5d28884b7ef5d184938d94dd473fa28ba674ce934807f56276fa821da3dfe5f932bef6565aed54f5c3517ace0c9221214417b2d523ddb65eb4bf68c547b4c40ec52ce09c51e1fa64422b21b412a8cb416db685469ed047e2ae26ca06de8e10abb64bec6ca07884927b51968daa05573e35fed3d2ae343126287069190029b9a7a724c177057dba050c3b18c0222de84a50e2413eea9a12f50d94ceefe48995ddf907de29a46ce561cd8242946eaed26474e50984ac005be37fb745254f3df97f880cd24732a46626bf4975bc6c749ac1c75833ed99b4dbab1d71267b82758229bdcb11cd234b8c990478de16160cf4989df335f646f6286d6f62f350811942df2f645afb14768f50ddf221d8e029674d40994c2ec2c4eb12f9ea6aa14d81a0bd8c3b62aea41877104ba9f50ed75c53b5f0cf4d913b7878b38dac9dd45abc35feacc53dd9cbb3029689cef401df37529318390341babe225094f268a886ce3bd6c6e5bee7849ab4f37c11505c9fb71ea7ca9db1c882dff90d91f1c046bc0b2306f341126b6becc475c6dee4d5aa9bd77852316b72a9189a6c309002f9be5296a0307895a6f729d7e3386cc9b18aed6b2168847a160c11db23400a80d3121febde4e480f2c7399dc71594ddfafcf868e60cc97ce8dd6861efefd9f92e61987ea7aa5baec0117866c387e07a798a1efce156b5ec8ddb3794b3035e34544e9d9a447c9a57aaaa63766fad9be9bf6ea08aff67c90792613b5b54b483f2965cde93f4b9bafc90e3510bbe1d3bc13ef88b08fdabce53bfec8b26eba2f09f5701915cf72c095388b635c8a6aa14d9c1d836367860450591c35230ed1759928b80575ac152b97ece0e025a283f62ef90ecfa1f3a3eed39068ca91d6b0f35f22edbd54637e29382244c8dc62e4714d6c729a1825dbc13e4e245ea5ce221e98a8d25aff7f65336f634f944c5e33fd99cc20202fce700fe053207ec9a73237da10ab2da53ff5f0ac0adcbcdfd31a642dd69541b7661469a97e87fdb91f1c9a533e0cabfd12e0a015e96fb3f5154d6cdf4e2a593780bcc79f918bd1844ffa62a0637c7957866e779e491d864b409627129fd5442cceab809755ba78aa08885e7daca24366554dc75839e75a66c30c5937987f197c9bdf377b3eddc8f24447e96f17bf8633645ac81ca2baf52f4738a52afbe0b12068ff44d5bc35a3f83986825aefaba9fc29ae57f74dba2d3f24d3692bfa33beb46b75449dfdb162b0ca5afe93d3f54d897c8aa7e3f7fc9f632cd348a47e1837e3aec9da2fb675b169af643854a2714daeb2f060480d18f0fc84eb1becde4368c2886867a9b621ac3966222ea1a5c1b2e2aad5a6d24ed21533c91f9a8b019195529a6e08eccf10f40563c65ca50bfa78d83ae54ca01cc21925375ac8d10de1adbe763ca9d885e5b28565332d184878947f6b89a51db652ecd0155625e4cd472e5f366dcf79b36e79465ca7a3c236f3ef8c4acbd83ccceb8b19b91855dee1122f15627c57eebc26967f4263434b321bd4cec915975821e08f9095ce6d7705493d850c0da356fb8cfe51395d1d7ba7efa5d4f1cda7b735f13d0183f8f1a282f28a24ca0f0e719b5e567186ee1255d241e66790bcab2e55846085d1f025e38a2d36ee014b40cc2c5afe253b858774e34c026bd8dd65264e08df28f22498f88e64aa4d42eed7f98d9b81b593b9adbbe99cccf617f5bc2809198bdfb460e8335eb8d6d94e278a50"
|
|
+ },
|
|
+ {
|
|
+ "scheme": 1,
|
|
+ "index": 3,
|
|
+ "signature": "0x3941e6e79ed44f046543182b5bc91c08ba91a53a50351470a6a64215b1b87c4487df0d23a191f8eb1429db96776bcf42b0ee0556ad1fbe54589ed283901d3269a783e1ffad95d3b98c52b6d6de730edd4c93a652f53d76f8f3d343f04953d81c43c9e96934df194297fbfda8098baf1a277fa49615b9e429562f2b5cc029a76da5915d35c96922639f5d2f3157f5edb63918b663d299a2ebba2727117c328d73f83959a82cfb392161c98ceb2b1d6b8f0b78ded12dcad63da02414be8c853c5a7186f13d6c8d9f7f738356fdfbda49449bd2873e7fc5e3d7135d59cad6abd758dd954c72b9ac2a52a9f4d40e675f17807f69af4c7119f4dbd26492d194d64a18334c5afdb8d4ed18eef34578d9a4f9bca31ab5c6c6219a3a2fa5b9d29feaca1b37c24115d4fbb2f8a8282df604b24a18cc56215c791042a7f28eb859d2e57d43ce6cc50edc48688a0e449ad4aa6f5c00c72dcf0322d2a022b7fe495028bbc89ab53982595755f384b4bd723a7f49d77a7288b2b5b51ab4871624132bacc0fc1315250635bfb8bab3efa73b75b890b8701a48eb67ba421c64e50d2d6c823b7ba0e8a6bf7b371f65e08da37ab9424b876910fcae73aec09b44210aa4a4b8e401d055a9dcd5bf5e4869c72b0eb51a9d0a1e3405cf91564554a549b16e1a6b9fd90f435e2d652b45be313ac6b7bdeacd499bbbc61a00f4efa6932b3f01c0c24f7eac31955296677a50fee299536aa9df12168f3e91edcd2b634eb8fd6570f99a24abddf4d94cd77f2f087dc905dfd0eaa228c436935cd1a74f6f9d72f0ca11283e15632403d786258cab7d224e99e7fa7b59db465f26965532450cc5260e3951a32102795e2d0d5cd968fb356e142103f5204762e194d130789caa35995091faaf9167d3e3d144159b659a0f673dfdf2c6a0"
|
|
+ }
|
|
+ ]
|
|
+ }
|
|
+ ],
|
|
+ "messages": {
|
|
+ "2": "0x9b03be36eb916bd6ff4868240bfc66a2631dc806818ae44db48178aefb6a997b"
|
|
+ },
|
|
+ "bytes": "0xf9242a93414552452d50512d5345414c53544f52452d32826d618203e8a03333333333333333333333333333333333333333333333333333333333333333f923ecf923e902f923e5f902920101b9028d392d747efa5df9ec7976b575ebbbbc4e50e48f494255067d00c8fb6ab805f5dde05d0240f101c33dd0aadb317a173e25a7dec0ceb77ce150099f5ca19dc2df6e44a5b5fc87cab441dc4e6ee717e77d3ffc2bc57ea828567dcbcdb8831dbbb613c0f747fc497e218f903efb5f5c5a2c4e61879bfb069a67eec30acb8af36d1f4a245b9f120c6bea336d8ba3eba72be78a3ded415117b3ed0babab6ce775e1c1ebee9d08f4a0923ef969747533a3a9fc13d19b4c5b1eabe6ade431ad5731c5ccfe98681c31ade95e7d5bf469024456082d06df3fd4e6970fc2533bb9cf6688bb595edacd95f68d1b31a396d8af954e37fd43d6a366757853a1185d62e18587e2cdb51f0a7023f2b3cb9646ffda39e46e98c47f68bb3954a140f5bce405977eb8974c229305c2ca3c7017891f208a041a89d48d3344695cd9106bff8b80a0a48dde46ba4ecb942344cd1887e2f889a5b97e96651dfe7d3116a2b17a86bf11be8ab8bb69f214b7a0dce316367e827192ec0e9a0ac2199b1c4f1042655ca7cf3d1f8da99341afe8f0b1f21338492ecff73f65239f4ea6a5dfcbd08ca9bcadd559dff34a6a8cd9a28a579fd54384f35ceaabab930b87b14779fdc822a587d04910b4d693f288b26d56688e5ffb2d65d9374a32c27dab9778f618df54c15f555f54828113a595fc1ce107ad2ae7592b41e944b0cfe48cd21d36d4fb35dad4de5ffe9531f9e927a25942461a4c9726a292d2ef9dbc0b1d0456b703037b4df9d0c446d707285b9489e8845211cf0e8a3f0a32a5cfc713902df29af2813293a48c2f02b8dc336befa797d3d3f67d90cd4fa25466bbe70d394713fa06b606de967d5a5aa9f8d0310363f7be1a75708d4c72511f67eb2b0495c43e75ca6e085d35c53cdac3cc09142647e68fcbbe921ad25080f91eb50201b91eb0e85ef5afbd04ae28867b1e81b818d79445b1a8e98c272154ab5e8a7797af50d972b241bc0d536481095419bb18be70860dbe9c5d355d74451f31e27209f3d43cd2a633cd961971c381058ad667a9b2e69f0fe9c2a557ba89835fabb16decc1915b54de7b5f00aa5787a39e8d97fdff315a7a0d2aaa5d3e10fc1a02ae74797c43a2719d3361805f5415dbceb716bfb7b07ff4a415a938008f0f9a668395801ee590a83b20d5749facd7f99bece768e7e3adc0e036b82604cf9a9e5c7010db9b54965d094ba9c248f9f4e29045be7962aa6e7243d450caee40bc4dfb9b333e6c289509f899b254d85539a78f1194553bbed9dfca1044372ba2530f2b05ed4a467728474a1d603eba54e4fcf2295c6a559e9c606b6b70c40d4c8cee286f2d79d6f46a8c0079130c2f58cbf4b3ec7fc109cc1ca3dea2ddfaf377eb357ac6b5877aa6f2e1f56df3421daa6ed5d043b5188c6ef1c71d765b3d94815027ea7838d8f448d0fc008d3a0189958ae6fafac687990f5b7d43c103ab97780087f48bc3b7a19f76a945a0d90e1ff279ceef8d32e2b5fdaf3c5d1a5ba52e60dd934cdfdc2492330a5f150f2106ecad186cf1f6ca3907707e34becc8b442ad3dc5ecaa7abfc7bc19cb7a7664ecc127c1d4d0f0515eaa3099def31f3ba376c30d4044ce8cf7669ca465f140ac5ca43f9e856721be03231e6b0cbc655c03b9f237036a504ba29da42b5959029b68f0171ccb5d1a2ca379250d3eb5591ddb52333b954e152e644bf8c8c22ed3c3b471021eeb4a25f2adc63f792c01382e9c01693c4dd9ad333c198e4da0b8af182bd87d2919f2bf4ae94130931cebe0524c1df1cdaed0767ae040ee0f042ae8b2e0674fedaac068db64ae2998f1e29d4fe208f3ca498a1832634f7183a8d6902d86823e12f5bbecdcaf9935f808d72e18e62c1a117ab27bc9acc3287afbd6f7442f4eb48063a381495170171af2d76e3672c37462bcb6c1710afcc873b9168e4bb6887117a9925e3a2b2bc33d0db4fb33809e3768d47ab3b52bd655c71539d8a7e391bcaeafafc71c554e0616d6f6d9ddac0285ce5b9dd9bfe015739925705edf72abe615a376e3fadf3e5807d97a7ca5e4a378ead2a466db9773d3a7d3f7627b29f1183816edb236b4b20af6a212b9ba1b86ed143974777a3de41aaa3a17371aae38dffd3779f254a0da8d9219d98d89049ad55d71e731192bb769ae72e466a67e82dc1b133b9e5129192e2e611d8d8035f6e0dba92d6cade096c56b248237d9405a534d6205e59186c1e5ffdb1dfaafeadc15eb2d11c736b0e57ceee75c6ebdc78c2ce24fd852e87eeb969e14d8d2aef1ed623914bd1932d8dc26bad8e6b3b2afcf8139ee97a4afb1db36a23a94f0ba00c6c6ecd072851c456e72a69af515c7e7d872ec112729168879f1812c9de0cc380a994182a80e4195765d53eac82085ea751cb09eac5f9db99aecf51e9111515b083ba65cad1d6687363c3155f39e5c7124602a879f1ff153f4ecddad23ba9d99384840272613f40e8975118e17a50a27029b5714cf9f3db14c3ded35e31b45fe73fc06a7fe8cc96937ba3e82dcb226be47e45bb6e971ef5e7ba2013cbccb6edaa51d3611452f3c26860232193512e1ca915ca1e82d1e81da1a84b228d92d855a09721f662ff3d58eda5846977f40d2f6fe0845ad3c8cc2c9e6d9e673673d9245f5e55a2f02b6e47e01d27e809572a003809b75177880cc5ded3fde42ac59eeac1f0508eda86e4b4eb7f2de0f9b8500f766798ac7f9583cef34c7faca5efc97ded5585b0c39e0f16fb2401fc50a588017ebcdae043bc236f9309bc4d6c04f089a898263c7897feb006a6af16240547c96bb52d275130bfbeb20f2493713f29eef0455c41134f4f9f27c38d29dd1a2fbb6ecc40bf41d9f32e33352443c299ca7ef6881575dcd4f18ecbe874dde9e796628b21e6a7dc6827587c61fad8a8fc63b886c6f383243a20dcd95fea8e323d0e9811bccc2fd97cb0a347097ef1b5296ea8da5361c3df81672bb179e51f41082ccbc4c4f0c2e2eed5f8f131a2d58aa68caf0aa1a6d9c8aac9f424f7cdd2acd2875d4e0238f35c70ce48c966e114344ba6c5403545a4e8a467bf9cf7ebba117701a5e69a2e71a546d3b674468d4a31bedfc6e70fc0c4c8c3efff332b4b8e1dc604541091dd34a584d333d7291304c08286542b0075f371429605798bbd71ed7ca52ba6b812c7ca91c8c35c2a4f853eb7509c12049150eb7abca4498f5ef4d8dafef8998afb4527b65cd3e6ef1399041887f204cbc81fc030e6242c4395e7752a6545da4996b69740922c07881c1d5bbdc79beab8b17b5b0980d8fad7eeeb5785fbab08a7963bff7e95aa7b526dbe201b968a40f8db9399e7ff8aa18e6f095b9aa4cf4c41e57a78f10f6fc580a955e84f48a8c2b16d13b8b8efa525f1d51426a13325ea3384a5638577f32267f00e2e262f08d46bdeea4891ac5acaa3e3a31fd503dc76a3c92ded39edaa65043b60d52ffb6ea27cbf810899552d4dd5a55e95e172e267be645a3f2c6468b5b1ce76a0b951b85f98efb93aca8b3948c43cbefe76504f90128788e7e08f7f6685ee03b70ac35314d3a64a57a4a8cb7512a9254f3a9aa7e9c1990606ce8ca25e6b9c816b56903e10d7ca1db41a7f991f292acb51337230d0a0ac5604259d7daf5b684493ce3344a8892152fb6baca94f5b02237bfdeef0f9dc6fd372b078a05489f81ee232e63a27726746d52c3d9531bdec03f2d4d56b604231b233592babfe12c64b915200f1e16672b0798982293d768278909bb1352dd42381d7e87c15ba92aae469fae5ed023c643b45c08a5d15b29f34714016ce5c52ac648d4a32a4bb02c701f3a68fb873581ac392ea34277ff3262fba6ecbe274c840751ff28235fb3168cf30bee0fab5cb92c89c8ae3ffd8b03c4253078c31ce19864c8b6f128f6e3e80efda9141bedef5b60adc0d6f8357fe6cb6828b3605e02275deabb5326eff3d52861f072523c5695333b4d51c58c08a44be8e90ff8244da37295e1a1550ce715d08fe600349a9f9870ac83fbaada48cc392b75ab1ab456429e5b236f6b3b1751063b274bf6a75dc2283ca0ae8db757fb856e8c7442e4a3cf6f26e608bca09235f05dc6a2a53862cbae5a5bdcf1bff925ff3c25e38d5ee04591b8c228b215e5f82c21f39462aaa6c548c8d581b4df4386b97fd832a46e2212a3bc5ef4716a10e75cd5e46797dc12241bdec3074d19f971caea7a8f24bc522faf8322301e3e4d2188136ddccc53c6488d5d9df6298befecaf637a2693e8d3db2ed2f8e120e6f1ef5a52471e905bc7f62a3b93b534c9e234d72a75f38e443a05ff62ca45cd25293c23e4ae71784fd1649c61b9469eb152642d8fa2db77b85c26340f4b21b1e8ec7ab58b66fea1397e69665dd9116ce6ecb7d642ec9c2114a4c893b795c1be06893697924c42ed8bc97e0c930898d80e71536dedd3ddcd9b4b35ef5eb462ab984b28925aef1cb524439e36273f7056b17036a1f3ab44eed99199dd6d53b564d2f210a7d52ca896ef0af8de172415b518e92c578d256729744bf79ef3ab444960189cc0cddb9c961bc0a7f0bc51be6ffdf2e057331dd7d05eacd8e6e81e08f90b96539b9d323455428e9abcea706fa357949f2d1067b600af355d435bc71094ed8e29d699504d24427639b4d612d3d2c7e50129145a161cbed02955a0f32615b30cc968c41f2d062c32f796da497b379f5955a0ed5a653ee51f52e6a702b478a9a7af4d48fa25353a258e575c2e0c475b169df4471c22e2ccb1ed607bf831eb28e4487ab655f07520391309d3590ad63436ba31d1c37ecbf586dcaefb56d6110386d6a6a5d785b365701ae291b0a3d13b3dec21729e42591de8ef9f7a7216d9dc23489a3fe8d874a76f146aa26536c1dab083681cc00e9dc9e6603d53d74a1c79558c6fc7bf32d98a485dd562f261e7d2751fefc320c5a2c9a536c84ba467d7a82df93b5803cf60a2726ed8fe7287863fa2a674d01c77b053bcf88a9a502b0fb786f47e50401aa643394624968fb5d5dca34b009a3a32bdce673fd2d0c8e05238b82ee1479cb9b8b7007ca03974e1c56e9bf903c2d0c274cae9f588fcc6b47e02754dc0e7de3cb5a80ace5f98ae68244082144ecbac94d53abb9c89e7d102063107c0ddbb6633d0f987b14217a9d9378007cebdb260a9a89596b11422ec3f1136d469e3c188dfc94ebb1cf8c7f7decfef77995e8334d4321525ad76f32a2efd4c953a319e18c4da8981ee89415f7e2f07914d4fe63d6246504b90fbf03b54bd905661705fb65d00d28c530b7b3c690fb5f88aa1edc6f6dc861d79a1e8c4a6dc1df27b7c2f0b897f1231f176adafae599f4aa29c6a5070103a24468677320b9462cb9a2d40696a5966ca205af33e350742e7e50b27252d2ecf50420cd4fbff8e4570e04b2137722814c64ce0b81d13c14af64eaf36207ae8f9224a47b3c3c0c0996db171544bbe11f2407203eddde94614c9d41945645dcdcabff12cf2fcd01cf062b942bede9184d830fea37df7576b10bbfabdb4a4626979576f403f33060ddfc6f53df73ca618654768001f1e08bbd66de39e8eac625d4f1deb25681c2dc67c6764d555338b4293102191a96cffd8859eb08ecda0489af07c301c12913762fa3f9d192f74c762f50556726c3bacfccc66a038536e913d95186d8aecf381312733beb68b6cedad321fa4e3fdcdcfc5553548a30e1ecf0041f823ec863086c34b3b6e6a7af8a2214122332a4d27392e64cfabb1a9c66c498efb6515f32f01f23073693a37a72240df9709d577b3e184cccc8b9cbf34669b0653e16848ad0a9dbc9d7b0ce3ab88e98616492c83d8b88673aa6a1b93d2f7866caf1984da384145361fcad93640c7481a085b0be84ffb4870705371cabe56f82a233b3d5aab737a2f2b9877fe2885d48163e6c55a53627e6db0a9c7103c867bf829633af2e1379a537267a15765c5ffbf7457eb853d0049f497a7823c0489dd0a1490667b600ccc80f9ebf9afbc007280e4a93b4c20dbb07c10ec4646ce9cd1b3dddacf5ec7bb07d588501daa9ee422da47b4f69f6cb49b3201e1b461b5d4d60d4230995acc88dcc8c928251ebc8d37f3e0dcf8218bbac5e47653e510b270586859238c526c46b7db46e817e467c7fe3f41066e234f4756ac833c9d010fe800e51106deae8eae63d2d9d02c2eda4ab19d63600a5261e69075cc0e28220a3ca4cbfd53f14f654c09a62f6c70fa75368678a7e3936aaae6a3c94d800f95888777bfd394907860ff4446b285345768556f34b1c62cacf50b4ab820d02a18cacfa3a42f086906213e170f26a21a0c7f478d7dff393d68989622e4f89a46845984d1d28ef6584f13f135d6a18fa438e635f7670e3b9e0236d7dc9f99328a807e4468fd7438c56449556c1c13e478072602172f923d0cdff16786fec072f0629a0423025594808ca65d0ee3144947a44519e04b6abd779dc2d119ee4473103e1d608c0e254e0b7698bc876f2d810e4b41f37c9884648d0536069a80f9891d0e2ec4394446b70bb0ffb8032959bb04b82e75f577b8c136b6c87d1f98a962955af7286e4f1a098adb1bef56655757dc5e24cfea40eeb8f37b57edc8b85685c7f1681108f793b7c12df1a203596b57c92f9fa62bc9a1db3e7ed9c802500c7e305606fb82ac11df65c7e40c1fb09084fdd390f55a94873c7a32c0c9d389206d7695220951ff3fcc62cdb39a015649bb65040a06e54111127fd947f344d782f99b59392660917838f2dde4b04038b0baac6966593a8ea2eefa1423c4e9537eb804cb7d58fcbb1eef505ba06b1682cfffc4eab227161bbb9c3aabaec99f2e08fa650ce99e9c02745927ebaaef4f2c70713c97b34b734016a65a0e69db084101289443770fce47722a4c1af6ce554d09aeb9b3e2f076fada5f5fd9c772ee2cb65fff9da7b33e1b2f6a08f1536a403188c771fff5a84c8bc1509ef2dacd23cc699a242f5492bbdb82f13f4b9766cb1465d3d79e5ff9499fd812d346b8ac6e7c8cb83a603250a52daa0a55e04521f22a4246c5c149bb3426639d84dc651f7246d11ff49a2597b9a77104bc2cb1880f0347f2110b2cf33866aaa6bcce8e058e03aee01191adfee651694b506d952210398513a9313836e1457e5e8de9bdf26ed7301c3b6578a291d73cdf2602f6493e7685dff5e7b4db4c0fc151e253009234b251ecebeb10c2facce66e125b8fc8c6a78926dff9dd250037a12aa32c086c155f980601ab25de4bac8ce364c7fa8fdd965ddd03dedc8de498dfd3cfdc86b0b56398b10245dce984f2c5087610efd29aadec6eb78c18956d6912203f7016f3f47452578d1b718b6d221b38782bab9e29b344dee9deb594d8798a6a01296f5da1f143743c61c402700fd33904b43d8d6a44dc6fc04fcb9841544dd9116a5b908f06dd39be385750a4371f7dbce8b9b75aa01fcb4d2a1a94f22b7bf876153543f410e7f8c1504aced875a2e054dd5a2138eec9607d5d5ae7bae91da662c415ac6f0a9bb981393f660695e4b65b16dbaf35ec0d40c68ff4fd991e8152e03152c332e92a62c2bea76c0a239387148409b6a7c2c98c24b506b059869cb911a30cf15c22e0ea0f86db884040f7cc8f58b1d3fcdc251d223a285f191ee4bb2de83365ef74726c7abfaa9146c308530edde09be20e9d6eaeef850d00b165e768463b8793a914c421bb81e8905938540c64b77e82ee6a4a6a15f5cfb1df20a41305ad3dffafc7e8d882a3c9e3635d115c9314d8f3602ba752734e34e188c3cf46b3dd5cd83bb46b12e1ec2a8b9d7dd5b61c5a9f4f0704504e2882068034db62e8a9abf3c7c5b9a8bfde509d36899fc5b4e5bef940fd447b9275024febdc9a91d6d56012f1c6a44f94b96397ff2c78fd617870bf089067c6343ae4270f6e6dc495a260bc1ccd0a1c0771821895d26dd66a203825d19e621b86b57f9a51bceae9bb14d1f9961c5a904a64a1dad73c89129ac4920cc4e86e3696959be3305f6d5e33baee00c7f978bf7a1a7864ed89132ff350b45226e6e4db39122bd344c315208edafdfe6b567677f869b64532bed2f7f9087e3c6c1137004f205ce1485f1b9c3ec798b0509c00f6a2b6663048492caa3889328ea6216e34b959fd244249048cec8c0f7de2ff97105ad030a536ec6c4103b33c26acf4539a1b74a0792b9b6c80f95ee4326b09934e068429242495e51a49a712f8513ce91da60573e83443a0e12ac2a174b82d090813b930e10ed7cd44ed72d20b061e9eb253d715408d79d8a77d67919bb196dadcfb84bdc4eb647a4ae09c436d220e0ce914188c49fe9ffaa2fb87f08809d5021cb632a6642bdc1e3664e84dc0afca031f0150c4190893da6462dd917655930a6d1deebdf4a0b1e461126fb2d54d374e4d5a455a6207291d03d2d138e34260ca0ba2286044afc4d95822bead1eefdf0509cb4a0c09c3425c8b0e9236703cbdf4ba833ebea4942d4e0ea84df284c438ffae28b3ec7ded12dda8bbbeabdd07bd1925912aeb74bfda42a62f8a5e716949f4a195f38c9f7a041776c69a7a1599d6880299f50c3b75e6a9b5e0314731611154d1f755a1381fd7575a6b34019d37c40aabb4bcd6965411f48f3b893e5627748deed82de02e9d47af8d3a087f661dc5f2c65ea16fdb6455a6211c77fd41532017ac4aa17bdc43e33aa4bf6ebdd453fb90b863aefe4281691a736594d714bdc26520fb954fa4a3c8d8f5620316e7b8a3b736b28859514bb2ac434001a129975e0f53f473c41ad752670598a2b356feacdb9e4a609a44e83167539d4e3223143d19f79738b96a27171009f17fca174a8821c3f0bd7dd15b2e98eb3fe1437dbdbe881f9c86c0844db5ee82b627c519fae5ea7b5dabc382c9938529dc031f8cdf0ab320f479d8793081f1ecf45a2af3d339db470bea05607148a060348cfb344edcd773efff7645f021d67db2dc0abbe9a8fc343016e9e57933f642f487d649e3a01ad4f815fe3701750d67b1db3c74c6b30f7923d08a807e78e58aeec28691475bbe4260db35b8f850330fbf68f73f944b745208748261f32a9ee5929cf924193fbca8f7d15d0118e3ef205f6a639e4a25bb23c28f036764ba7dfb4f8203eb0b69e757fe5a40b560cae416eda6195f15330aa7f4ea8cd113c30583675a94c486da43a0f26dc5d922aeaa8b084124f5c5dbd0ef31e4ed52de942b1f8ec6b494fa9e730e8f0cac9ea3153610e13ab589d8840e5ecef5570b619574477e457c529d431a48fd3679f0a831832b9a1ad4cb6c99c25e0c1bcd2cc73ed79b2a589501e2abab2d2a64c9fbc4cd8bf14800f8a67d46ef10a68db32411d63fc36e8125bd0e79b27d861324afa6929be5cee98c245f0af5755595f60d29d485222c4a43e2614d315723c5eecbc836242a028053ff8a4c83324edbd6899887c3ab3394d5725effbb55ff056c35fdde91c28a34362aa8ab06f0f1da408e7be1863ef007b57ee062c5e660e2bd221a306774e7b7ed5fe5d04e3a2fa49a61a9d15e4aea12bfe588f7f7fe357581772356998126b1deb48988b56506eb805be01c07f3706100658b5be1e96b1531f8838d78cbb849a4e51c1a80d3776987407c0a1610d43178962c5a34cac6a62e8aaa963b8833549f8ef954e155f962b6d6ea4ceaa9f711959fdab71a74e8ef57ab16b477bbe47b78718f8aeb29239958220b079e13dab8f77ec24be4c3df3db9d9e306c9da8bcff284c27becdeba20ccbdf94f7853069c936ebb209f2dcef4d5b0c73a68c5bfa67a2366f68ea00603ce2b1fbcb897e80b1f7013d50355df6e989c660aabfecf886ccd69d86352c81350520bced1a2beaa0dffb1362c8b3857f1f1c17393fbf45ef639b1f6be41ace5f1e132e257a96af92727bfdba6b1cc09864c5b085d13be7986a4e720a49065f1c70e140f69cc462ab7bec075108d1384f6935781bec4dce9efad2c8e238e7f41b8e430ba231e9e23c6af52bb0dea07e6a0ffb0a3549db69ff05b1c7d57b1fb5f98b75122b0d53d038a37f3c499d9c891fe571015bf6fae1f27cd1c4790f633cc88b9f018bcc79e1857328fdb72eb7e0fc50558e2ab338fb902be7535c12c0235b21ccc3102454e75b20d5652231393ee2f14b5c0bf2ec8a485c02fdead3fb371b41f43d69a518444a92a6967ef3846db7661d973206eab07fd08f69b5a3a36cfe749acf67c2db8df7994821df76a74d8a36521cc6f4de3e1035e18e9640417363427082daf240e71f60df231fc22b8175620c74e2899eccc35387901cf57f8ea34d3f2a4165a4b7f9c41082ce46980480608c539d7f248a41c1ac1a7d5d28884b7ef5d184938d94dd473fa28ba674ce934807f56276fa821da3dfe5f932bef6565aed54f5c3517ace0c9221214417b2d523ddb65eb4bf68c547b4c40ec52ce09c51e1fa64422b21b412a8cb416db685469ed047e2ae26ca06de8e10abb64bec6ca07884927b51968daa05573e35fed3d2ae343126287069190029b9a7a724c177057dba050c3b18c0222de84a50e2413eea9a12f50d94ceefe48995ddf907de29a46ce561cd8242946eaed26474e50984ac005be37fb745254f3df97f880cd24732a46626bf4975bc6c749ac1c75833ed99b4dbab1d71267b82758229bdcb11cd234b8c990478de16160cf4989df335f646f6286d6f62f350811942df2f645afb14768f50ddf221d8e029674d40994c2ec2c4eb12f9ea6aa14d81a0bd8c3b62aea41877104ba9f50ed75c53b5f0cf4d913b7878b38dac9dd45abc35feacc53dd9cbb3029689cef401df37529318390341babe225094f268a886ce3bd6c6e5bee7849ab4f37c11505c9fb71ea7ca9db1c882dff90d91f1c046bc0b2306f341126b6becc475c6dee4d5aa9bd77852316b72a9189a6c309002f9be5296a0307895a6f729d7e3386cc9b18aed6b2168847a160c11db23400a80d3121febde4e480f2c7399dc71594ddfafcf868e60cc97ce8dd6861efefd9f92e61987ea7aa5baec0117866c387e07a798a1efce156b5ec8ddb3794b3035e34544e9d9a447c9a57aaaa63766fad9be9bf6ea08aff67c90792613b5b54b483f2965cde93f4b9bafc90e3510bbe1d3bc13ef88b08fdabce53bfec8b26eba2f09f5701915cf72c095388b635c8a6aa14d9c1d836367860450591c35230ed1759928b80575ac152b97ece0e025a283f62ef90ecfa1f3a3eed39068ca91d6b0f35f22edbd54637e29382244c8dc62e4714d6c729a1825dbc13e4e245ea5ce221e98a8d25aff7f65336f634f944c5e33fd99cc20202fce700fe053207ec9a73237da10ab2da53ff5f0ac0adcbcdfd31a642dd69541b7661469a97e87fdb91f1c9a533e0cabfd12e0a015e96fb3f5154d6cdf4e2a593780bcc79f918bd1844ffa62a0637c7957866e779e491d864b409627129fd5442cceab809755ba78aa08885e7daca24366554dc75839e75a66c30c5937987f197c9bdf377b3eddc8f24447e96f17bf8633645ac81ca2baf52f4738a52afbe0b12068ff44d5bc35a3f83986825aefaba9fc29ae57f74dba2d3f24d3692bfa33beb46b75449dfdb162b0ca5afe93d3f54d897c8aa7e3f7fc9f632cd348a47e1837e3aec9da2fb675b169af643854a2714daeb2f060480d18f0fc84eb1becde4368c2886867a9b621ac3966222ea1a5c1b2e2aad5a6d24ed21533c91f9a8b019195529a6e08eccf10f40563c65ca50bfa78d83ae54ca01cc21925375ac8d10de1adbe763ca9d885e5b28565332d184878947f6b89a51db652ecd0155625e4cd472e5f366dcf79b36e79465ca7a3c236f3ef8c4acbd83ccceb8b19b91855dee1122f15627c57eebc26967f4263434b321bd4cec915975821e08f9095ce6d7705493d850c0da356fb8cfe51395d1d7ba7efa5d4f1cda7b735f13d0183f8f1a282f28a24ca0f0e719b5e567186ee1255d241e66790bcab2e55846085d1f025e38a2d36ee014b40cc2c5afe253b858774e34c026bd8dd65264e08df28f22498f88e64aa4d42eed7f98d9b81b593b9adbbe99cccf617f5bc2809198bdfb460e8335eb8d6d94e278a50f902950103b902903941e6e79ed44f046543182b5bc91c08ba91a53a50351470a6a64215b1b87c4487df0d23a191f8eb1429db96776bcf42b0ee0556ad1fbe54589ed283901d3269a783e1ffad95d3b98c52b6d6de730edd4c93a652f53d76f8f3d343f04953d81c43c9e96934df194297fbfda8098baf1a277fa49615b9e429562f2b5cc029a76da5915d35c96922639f5d2f3157f5edb63918b663d299a2ebba2727117c328d73f83959a82cfb392161c98ceb2b1d6b8f0b78ded12dcad63da02414be8c853c5a7186f13d6c8d9f7f738356fdfbda49449bd2873e7fc5e3d7135d59cad6abd758dd954c72b9ac2a52a9f4d40e675f17807f69af4c7119f4dbd26492d194d64a18334c5afdb8d4ed18eef34578d9a4f9bca31ab5c6c6219a3a2fa5b9d29feaca1b37c24115d4fbb2f8a8282df604b24a18cc56215c791042a7f28eb859d2e57d43ce6cc50edc48688a0e449ad4aa6f5c00c72dcf0322d2a022b7fe495028bbc89ab53982595755f384b4bd723a7f49d77a7288b2b5b51ab4871624132bacc0fc1315250635bfb8bab3efa73b75b890b8701a48eb67ba421c64e50d2d6c823b7ba0e8a6bf7b371f65e08da37ab9424b876910fcae73aec09b44210aa4a4b8e401d055a9dcd5bf5e4869c72b0eb51a9d0a1e3405cf91564554a549b16e1a6b9fd90f435e2d652b45be313ac6b7bdeacd499bbbc61a00f4efa6932b3f01c0c24f7eac31955296677a50fee299536aa9df12168f3e91edcd2b634eb8fd6570f99a24abddf4d94cd77f2f087dc905dfd0eaa228c436935cd1a74f6f9d72f0ca11283e15632403d786258cab7d224e99e7fa7b59db465f26965532450cc5260e3951a32102795e2d0d5cd968fb356e142103f5204762e194d130789caa35995091faaf9167d3e3d144159b659a0f673dfdf2c6a0"
|
|
+ },
|
|
+ {
|
|
+ "id": "vs-sealstore-1-peste-forma-noua",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "hash": "0x3333333333333333333333333333333333333333333333333333333333333333",
|
|
+ "commitRoundBlock": 1000,
|
|
+ "bytes": "0xf902d593414552452d50512d5345414c53544f52452d31826d618203e8a03333333333333333333333333333333333333333333333333333333333333333f90297f9029480b9029039bd3aadc5f485f3f17ab3ef996de30f40a4dbb98f4c70db2fbf505d86835dcfd8e1b067a325d98da059a8597b2e5ee62751d4fd8efc9985223f68c9b2725df62d7af9b091a129944bb0d86464ae20b5bd1c5cf3b29bec1fce23c562d6d8d3ea81215b2a061f05e1ea271c4f5da79f528ae113bb9ba6afdaa1eebb715d3171344fd4bce746d22de14f5a0454a7e371086667b9d586907f6b6969a528ba9ce5ceb7c8cbe30c939b4d76d3eaee2882cc898f374b94355329fae7e6d591e9166d7f71d9c58defb0bcade36ce313d62519c41a7973b149b4f2f8e51d6afd5154eb794343a3acdcc7436e4ff22dda41b236295314daef2a4b98c5343684e20ee7f1f6d27e4a66eaa79ce6a32b2fecf43c43237a40f3545f4af5f6d93109d8e15da5f28db19eac72f8641d14a079198fdf9f8ee292b2d0fc7d3fccd68525dbcfafff2a9d29a3cc361e4674d29e5af5ee408adc0d9725f7939065d0ceef4a4b64c0972943a69739b0aaf57562533888315d7a5d24fa759ed5661454ee58ce491e5f2fcf0d07608f524c50f36cab968c1d8cbee3313a7854744d1cd7e5ac70e20092bab2e5c59736351d014d71af7c19926b232bf1bc36676f81a1a6f7166e97d8e066f6a78d98f13974beed35449f3d9506fab1c0ab356b092273b42d4aedb6cdbedb736e6928fd2d4926b94106fbbf0923e3b759e1fb89ecaf24bea45bd406d509d611550061897b71c39ea3fa6a8f47a50a31849546df90137114491b55ce36fe1d6f64851c8647eb5906d13369b97ab5721a44db1f9d7712aa45c87f5f8b8bef5c92a9f715c432ef6262c8d22af0eb2943e40cda27921cb865b7d79a4b70ec14f7deb96916cc13eeb764a5f3f35189a9bace816de3f88b57aecea4ad102412e121f84ab7474a04d0c0d92526178821f0dce4",
|
|
+ "expected": "ignored"
|
|
+ }
|
|
+ ],
|
|
+ "VJ": [
|
|
+ {
|
|
+ "id": "vj-28001-1000-r2",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": 2,
|
|
+ "hash": "0x3333333333333333333333333333333333333333333333333333333333333333",
|
|
+ "seals": [
|
|
+ {
|
|
+ "index": 1,
|
|
+ "signature": "0x392d747efa5df9ec7976b575ebbbbc4e50e48f494255067d00c8fb6ab805f5dde05d0240f101c33dd0aadb317a173e25a7dec0ceb77ce150099f5ca19dc2df6e44a5b5fc87cab441dc4e6ee717e77d3ffc2bc57ea828567dcbcdb8831dbbb613c0f747fc497e218f903efb5f5c5a2c4e61879bfb069a67eec30acb8af36d1f4a245b9f120c6bea336d8ba3eba72be78a3ded415117b3ed0babab6ce775e1c1ebee9d08f4a0923ef969747533a3a9fc13d19b4c5b1eabe6ade431ad5731c5ccfe98681c31ade95e7d5bf469024456082d06df3fd4e6970fc2533bb9cf6688bb595edacd95f68d1b31a396d8af954e37fd43d6a366757853a1185d62e18587e2cdb51f0a7023f2b3cb9646ffda39e46e98c47f68bb3954a140f5bce405977eb8974c229305c2ca3c7017891f208a041a89d48d3344695cd9106bff8b80a0a48dde46ba4ecb942344cd1887e2f889a5b97e96651dfe7d3116a2b17a86bf11be8ab8bb69f214b7a0dce316367e827192ec0e9a0ac2199b1c4f1042655ca7cf3d1f8da99341afe8f0b1f21338492ecff73f65239f4ea6a5dfcbd08ca9bcadd559dff34a6a8cd9a28a579fd54384f35ceaabab930b87b14779fdc822a587d04910b4d693f288b26d56688e5ffb2d65d9374a32c27dab9778f618df54c15f555f54828113a595fc1ce107ad2ae7592b41e944b0cfe48cd21d36d4fb35dad4de5ffe9531f9e927a25942461a4c9726a292d2ef9dbc0b1d0456b703037b4df9d0c446d707285b9489e8845211cf0e8a3f0a32a5cfc713902df29af2813293a48c2f02b8dc336befa797d3d3f67d90cd4fa25466bbe70d394713fa06b606de967d5a5aa9f8d0310363f7be1a75708d4c72511f67eb2b0495c43e75ca6e085d35c53cdac3cc09142647e68fcbbe921ad25080"
|
|
+ },
|
|
+ {
|
|
+ "index": 3,
|
|
+ "signature": "0x3941e6e79ed44f046543182b5bc91c08ba91a53a50351470a6a64215b1b87c4487df0d23a191f8eb1429db96776bcf42b0ee0556ad1fbe54589ed283901d3269a783e1ffad95d3b98c52b6d6de730edd4c93a652f53d76f8f3d343f04953d81c43c9e96934df194297fbfda8098baf1a277fa49615b9e429562f2b5cc029a76da5915d35c96922639f5d2f3157f5edb63918b663d299a2ebba2727117c328d73f83959a82cfb392161c98ceb2b1d6b8f0b78ded12dcad63da02414be8c853c5a7186f13d6c8d9f7f738356fdfbda49449bd2873e7fc5e3d7135d59cad6abd758dd954c72b9ac2a52a9f4d40e675f17807f69af4c7119f4dbd26492d194d64a18334c5afdb8d4ed18eef34578d9a4f9bca31ab5c6c6219a3a2fa5b9d29feaca1b37c24115d4fbb2f8a8282df604b24a18cc56215c791042a7f28eb859d2e57d43ce6cc50edc48688a0e449ad4aa6f5c00c72dcf0322d2a022b7fe495028bbc89ab53982595755f384b4bd723a7f49d77a7288b2b5b51ab4871624132bacc0fc1315250635bfb8bab3efa73b75b890b8701a48eb67ba421c64e50d2d6c823b7ba0e8a6bf7b371f65e08da37ab9424b876910fcae73aec09b44210aa4a4b8e401d055a9dcd5bf5e4869c72b0eb51a9d0a1e3405cf91564554a549b16e1a6b9fd90f435e2d652b45be313ac6b7bdeacd499bbbc61a00f4efa6932b3f01c0c24f7eac31955296677a50fee299536aa9df12168f3e91edcd2b634eb8fd6570f99a24abddf4d94cd77f2f087dc905dfd0eaa228c436935cd1a74f6f9d72f0ca11283e15632403d786258cab7d224e99e7fa7b59db465f26965532450cc5260e3951a32102795e2d0d5cd968fb356e142103f5204762e194d130789caa35995091faaf9167d3e3d144159b659a0f673dfdf2c6a0"
|
|
+ }
|
|
+ ],
|
|
+ "message": "0x9b03be36eb916bd6ff4868240bfc66a2631dc806818ae44db48178aefb6a997b",
|
|
+ "bytes": "0xf9056b94414552452d50512d5345414c57494e444f572d32826d618203e802a03333333333333333333333333333333333333333333333333333333333333333f9052bf9029101b9028d392d747efa5df9ec7976b575ebbbbc4e50e48f494255067d00c8fb6ab805f5dde05d0240f101c33dd0aadb317a173e25a7dec0ceb77ce150099f5ca19dc2df6e44a5b5fc87cab441dc4e6ee717e77d3ffc2bc57ea828567dcbcdb8831dbbb613c0f747fc497e218f903efb5f5c5a2c4e61879bfb069a67eec30acb8af36d1f4a245b9f120c6bea336d8ba3eba72be78a3ded415117b3ed0babab6ce775e1c1ebee9d08f4a0923ef969747533a3a9fc13d19b4c5b1eabe6ade431ad5731c5ccfe98681c31ade95e7d5bf469024456082d06df3fd4e6970fc2533bb9cf6688bb595edacd95f68d1b31a396d8af954e37fd43d6a366757853a1185d62e18587e2cdb51f0a7023f2b3cb9646ffda39e46e98c47f68bb3954a140f5bce405977eb8974c229305c2ca3c7017891f208a041a89d48d3344695cd9106bff8b80a0a48dde46ba4ecb942344cd1887e2f889a5b97e96651dfe7d3116a2b17a86bf11be8ab8bb69f214b7a0dce316367e827192ec0e9a0ac2199b1c4f1042655ca7cf3d1f8da99341afe8f0b1f21338492ecff73f65239f4ea6a5dfcbd08ca9bcadd559dff34a6a8cd9a28a579fd54384f35ceaabab930b87b14779fdc822a587d04910b4d693f288b26d56688e5ffb2d65d9374a32c27dab9778f618df54c15f555f54828113a595fc1ce107ad2ae7592b41e944b0cfe48cd21d36d4fb35dad4de5ffe9531f9e927a25942461a4c9726a292d2ef9dbc0b1d0456b703037b4df9d0c446d707285b9489e8845211cf0e8a3f0a32a5cfc713902df29af2813293a48c2f02b8dc336befa797d3d3f67d90cd4fa25466bbe70d394713fa06b606de967d5a5aa9f8d0310363f7be1a75708d4c72511f67eb2b0495c43e75ca6e085d35c53cdac3cc09142647e68fcbbe921ad25080f9029403b902903941e6e79ed44f046543182b5bc91c08ba91a53a50351470a6a64215b1b87c4487df0d23a191f8eb1429db96776bcf42b0ee0556ad1fbe54589ed283901d3269a783e1ffad95d3b98c52b6d6de730edd4c93a652f53d76f8f3d343f04953d81c43c9e96934df194297fbfda8098baf1a277fa49615b9e429562f2b5cc029a76da5915d35c96922639f5d2f3157f5edb63918b663d299a2ebba2727117c328d73f83959a82cfb392161c98ceb2b1d6b8f0b78ded12dcad63da02414be8c853c5a7186f13d6c8d9f7f738356fdfbda49449bd2873e7fc5e3d7135d59cad6abd758dd954c72b9ac2a52a9f4d40e675f17807f69af4c7119f4dbd26492d194d64a18334c5afdb8d4ed18eef34578d9a4f9bca31ab5c6c6219a3a2fa5b9d29feaca1b37c24115d4fbb2f8a8282df604b24a18cc56215c791042a7f28eb859d2e57d43ce6cc50edc48688a0e449ad4aa6f5c00c72dcf0322d2a022b7fe495028bbc89ab53982595755f384b4bd723a7f49d77a7288b2b5b51ab4871624132bacc0fc1315250635bfb8bab3efa73b75b890b8701a48eb67ba421c64e50d2d6c823b7ba0e8a6bf7b371f65e08da37ab9424b876910fcae73aec09b44210aa4a4b8e401d055a9dcd5bf5e4869c72b0eb51a9d0a1e3405cf91564554a549b16e1a6b9fd90f435e2d652b45be313ac6b7bdeacd499bbbc61a00f4efa6932b3f01c0c24f7eac31955296677a50fee299536aa9df12168f3e91edcd2b634eb8fd6570f99a24abddf4d94cd77f2f087dc905dfd0eaa228c436935cd1a74f6f9d72f0ca11283e15632403d786258cab7d224e99e7fa7b59db465f26965532450cc5260e3951a32102795e2d0d5cd968fb356e142103f5204762e194d130789caa35995091faaf9167d3e3d144159b659a0f673dfdf2c6a0"
|
|
+ },
|
|
+ {
|
|
+ "id": "vj-28001-1000-r0",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": 0,
|
|
+ "hash": "0x3333333333333333333333333333333333333333333333333333333333333333",
|
|
+ "seals": [
|
|
+ {
|
|
+ "index": 0,
|
|
+ "signature": "0x39bd3aadc5f485f3f17ab3ef996de30f40a4dbb98f4c70db2fbf505d86835dcfd8e1b067a325d98da059a8597b2e5ee62751d4fd8efc9985223f68c9b2725df62d7af9b091a129944bb0d86464ae20b5bd1c5cf3b29bec1fce23c562d6d8d3ea81215b2a061f05e1ea271c4f5da79f528ae113bb9ba6afdaa1eebb715d3171344fd4bce746d22de14f5a0454a7e371086667b9d586907f6b6969a528ba9ce5ceb7c8cbe30c939b4d76d3eaee2882cc898f374b94355329fae7e6d591e9166d7f71d9c58defb0bcade36ce313d62519c41a7973b149b4f2f8e51d6afd5154eb794343a3acdcc7436e4ff22dda41b236295314daef2a4b98c5343684e20ee7f1f6d27e4a66eaa79ce6a32b2fecf43c43237a40f3545f4af5f6d93109d8e15da5f28db19eac72f8641d14a079198fdf9f8ee292b2d0fc7d3fccd68525dbcfafff2a9d29a3cc361e4674d29e5af5ee408adc0d9725f7939065d0ceef4a4b64c0972943a69739b0aaf57562533888315d7a5d24fa759ed5661454ee58ce491e5f2fcf0d07608f524c50f36cab968c1d8cbee3313a7854744d1cd7e5ac70e20092bab2e5c59736351d014d71af7c19926b232bf1bc36676f81a1a6f7166e97d8e066f6a78d98f13974beed35449f3d9506fab1c0ab356b092273b42d4aedb6cdbedb736e6928fd2d4926b94106fbbf0923e3b759e1fb89ecaf24bea45bd406d509d611550061897b71c39ea3fa6a8f47a50a31849546df90137114491b55ce36fe1d6f64851c8647eb5906d13369b97ab5721a44db1f9d7712aa45c87f5f8b8bef5c92a9f715c432ef6262c8d22af0eb2943e40cda27921cb865b7d79a4b70ec14f7deb96916cc13eeb764a5f3f35189a9bace816de3f88b57aecea4ad102412e121f84ab7474a04d0c0d92526178821f0dce4"
|
|
+ }
|
|
+ ],
|
|
+ "message": "0xcce50ac23422233040f0fda9105a626e3160b12064ec678b34819b029fc204a1",
|
|
+ "bytes": "0xf902d794414552452d50512d5345414c57494e444f572d32826d618203e880a03333333333333333333333333333333333333333333333333333333333333333f90297f9029480b9029039bd3aadc5f485f3f17ab3ef996de30f40a4dbb98f4c70db2fbf505d86835dcfd8e1b067a325d98da059a8597b2e5ee62751d4fd8efc9985223f68c9b2725df62d7af9b091a129944bb0d86464ae20b5bd1c5cf3b29bec1fce23c562d6d8d3ea81215b2a061f05e1ea271c4f5da79f528ae113bb9ba6afdaa1eebb715d3171344fd4bce746d22de14f5a0454a7e371086667b9d586907f6b6969a528ba9ce5ceb7c8cbe30c939b4d76d3eaee2882cc898f374b94355329fae7e6d591e9166d7f71d9c58defb0bcade36ce313d62519c41a7973b149b4f2f8e51d6afd5154eb794343a3acdcc7436e4ff22dda41b236295314daef2a4b98c5343684e20ee7f1f6d27e4a66eaa79ce6a32b2fecf43c43237a40f3545f4af5f6d93109d8e15da5f28db19eac72f8641d14a079198fdf9f8ee292b2d0fc7d3fccd68525dbcfafff2a9d29a3cc361e4674d29e5af5ee408adc0d9725f7939065d0ceef4a4b64c0972943a69739b0aaf57562533888315d7a5d24fa759ed5661454ee58ce491e5f2fcf0d07608f524c50f36cab968c1d8cbee3313a7854744d1cd7e5ac70e20092bab2e5c59736351d014d71af7c19926b232bf1bc36676f81a1a6f7166e97d8e066f6a78d98f13974beed35449f3d9506fab1c0ab356b092273b42d4aedb6cdbedb736e6928fd2d4926b94106fbbf0923e3b759e1fb89ecaf24bea45bd406d509d611550061897b71c39ea3fa6a8f47a50a31849546df90137114491b55ce36fe1d6f64851c8647eb5906d13369b97ab5721a44db1f9d7712aa45c87f5f8b8bef5c92a9f715c432ef6262c8d22af0eb2943e40cda27921cb865b7d79a4b70ec14f7deb96916cc13eeb764a5f3f35189a9bace816de3f88b57aecea4ad102412e121f84ab7474a04d0c0d92526178821f0dce4"
|
|
+ },
|
|
+ {
|
|
+ "id": "vj-cadru-1-sub-hr",
|
|
+ "chainId": 28001,
|
|
+ "n": 900,
|
|
+ "round": null,
|
|
+ "hash": "0x3333333333333333333333333333333333333333333333333333333333333333",
|
|
+ "commitRoundBlock": 1000,
|
|
+ "message": "0x02cddf26d98250e54a2447f107b76a0a9d76c8530ba82a599cbf7e798c4e88c3",
|
|
+ "seals": [
|
|
+ {
|
|
+ "index": 0,
|
|
+ "signature": "0x39a3460081ebf9704527062c06e3b80a50032c21a0fff93a9ecee2ef463fe82837f3271af1898d432914220e9ad9d947e5e828a4b26410d7bbd31bce84921edc5479a84eb7881745c0a14bec262a0e94247e699e3f9475251089ca8a220b242ed7da59191b66e58f139369996de1a981f939aace4799242bc22eff59b68896eb7754804bf8889d2a619dc451f6d408f9b3411b87392f4a76b1dd61a1cfa1b6a7a398b1a0ba7a8c3a56dfbe51eb246f0f906658e8f6ecc63c6b54c724ec42a5ac426903c6f3f1b2f41a7463941709eb48194cd50157ae7b7939fd373533f3e0ba87936523e2c49a3a9105f3799ce7ab947ed2031d5aa17fce47a2835b96422986ae0a89a1a9666f59dc6b3844d4bdaf720a5125c45afaf558ecee8958c0ae48944d4ce224142dbbdfb625f2b61f773c64e99e3d9db14d4274f20dbbd2c549db648275f0ead6ad5d3b2f0fbd07b4f2e834b61a97839a1be8c7195eba384393a08ab551a78b70de6c3c6d7915535574958cfae4b65025a30f1c8172a330fe17b243a3f5aa2b99839fb16f2620a718e312c877627e466db9426792994591195a12d5c10a4ca39c77ac83cef0bdf561f86f9add7b3742d1c634ad0474cec688558f507132ff1b2b30dc103b2a49515eb7a985065f86fefc39bd8c4b2684da96bf666ec52d6f94c1bebcb44be78e3ac861290ed2cb55626dac02dd8033484190a3366a0ed52ab85c704576664e3355b912409c3b32870380a5f6c9e3d787cf77fb50d3e28379553cc2c96b15891f050b6ae71745491f5cfd592c3b83ef88a40ede773f5f61b71a3cc16deb626db00dea08c77fae10799c82329284faf3a8e76687035552b3c45a377ab8765e6d5ed147275554275898ba288ccce862186515bb349f225f9186204b3abae2e3a928592b40"
|
|
+ }
|
|
+ ],
|
|
+ "bytes": "0xf902d494414552452d50512d5345414c57494e444f572d31826d61820384a03333333333333333333333333333333333333333333333333333333333333333f90295f9029280b9028e39a3460081ebf9704527062c06e3b80a50032c21a0fff93a9ecee2ef463fe82837f3271af1898d432914220e9ad9d947e5e828a4b26410d7bbd31bce84921edc5479a84eb7881745c0a14bec262a0e94247e699e3f9475251089ca8a220b242ed7da59191b66e58f139369996de1a981f939aace4799242bc22eff59b68896eb7754804bf8889d2a619dc451f6d408f9b3411b87392f4a76b1dd61a1cfa1b6a7a398b1a0ba7a8c3a56dfbe51eb246f0f906658e8f6ecc63c6b54c724ec42a5ac426903c6f3f1b2f41a7463941709eb48194cd50157ae7b7939fd373533f3e0ba87936523e2c49a3a9105f3799ce7ab947ed2031d5aa17fce47a2835b96422986ae0a89a1a9666f59dc6b3844d4bdaf720a5125c45afaf558ecee8958c0ae48944d4ce224142dbbdfb625f2b61f773c64e99e3d9db14d4274f20dbbd2c549db648275f0ead6ad5d3b2f0fbd07b4f2e834b61a97839a1be8c7195eba384393a08ab551a78b70de6c3c6d7915535574958cfae4b65025a30f1c8172a330fe17b243a3f5aa2b99839fb16f2620a718e312c877627e466db9426792994591195a12d5c10a4ca39c77ac83cef0bdf561f86f9add7b3742d1c634ad0474cec688558f507132ff1b2b30dc103b2a49515eb7a985065f86fefc39bd8c4b2684da96bf666ec52d6f94c1bebcb44be78e3ac861290ed2cb55626dac02dd8033484190a3366a0ed52ab85c704576664e3355b912409c3b32870380a5f6c9e3d787cf77fb50d3e28379553cc2c96b15891f050b6ae71745491f5cfd592c3b83ef88a40ede773f5f61b71a3cc16deb626db00dea08c77fae10799c82329284faf3a8e76687035552b3c45a377ab8765e6d5ed147275554275898ba288ccce862186515bb349f225f9186204b3abae2e3a928592b40",
|
|
+ "expected": "read below H_r"
|
|
+ },
|
|
+ {
|
|
+ "id": "vj-cadru-2-sub-hr",
|
|
+ "chainId": 28001,
|
|
+ "n": 900,
|
|
+ "round": 0,
|
|
+ "hash": "0x3333333333333333333333333333333333333333333333333333333333333333",
|
|
+ "commitRoundBlock": 1000,
|
|
+ "bytes": "0xf902d594414552452d50512d5345414c57494e444f572d32826d6182038480a03333333333333333333333333333333333333333333333333333333333333333f90295f9029280b9028e39a3460081ebf9704527062c06e3b80a50032c21a0fff93a9ecee2ef463fe82837f3271af1898d432914220e9ad9d947e5e828a4b26410d7bbd31bce84921edc5479a84eb7881745c0a14bec262a0e94247e699e3f9475251089ca8a220b242ed7da59191b66e58f139369996de1a981f939aace4799242bc22eff59b68896eb7754804bf8889d2a619dc451f6d408f9b3411b87392f4a76b1dd61a1cfa1b6a7a398b1a0ba7a8c3a56dfbe51eb246f0f906658e8f6ecc63c6b54c724ec42a5ac426903c6f3f1b2f41a7463941709eb48194cd50157ae7b7939fd373533f3e0ba87936523e2c49a3a9105f3799ce7ab947ed2031d5aa17fce47a2835b96422986ae0a89a1a9666f59dc6b3844d4bdaf720a5125c45afaf558ecee8958c0ae48944d4ce224142dbbdfb625f2b61f773c64e99e3d9db14d4274f20dbbd2c549db648275f0ead6ad5d3b2f0fbd07b4f2e834b61a97839a1be8c7195eba384393a08ab551a78b70de6c3c6d7915535574958cfae4b65025a30f1c8172a330fe17b243a3f5aa2b99839fb16f2620a718e312c877627e466db9426792994591195a12d5c10a4ca39c77ac83cef0bdf561f86f9add7b3742d1c634ad0474cec688558f507132ff1b2b30dc103b2a49515eb7a985065f86fefc39bd8c4b2684da96bf666ec52d6f94c1bebcb44be78e3ac861290ed2cb55626dac02dd8033484190a3366a0ed52ab85c704576664e3355b912409c3b32870380a5f6c9e3d787cf77fb50d3e28379553cc2c96b15891f050b6ae71745491f5cfd592c3b83ef88a40ede773f5f61b71a3cc16deb626db00dea08c77fae10799c82329284faf3a8e76687035552b3c45a377ab8765e6d5ed147275554275898ba288ccce862186515bb349f225f9186204b3abae2e3a928592b40",
|
|
+ "expected": "dropped: a frame in the wrong form for its height"
|
|
+ },
|
|
+ {
|
|
+ "id": "vj-cadru-1-peste-hr",
|
|
+ "chainId": 28001,
|
|
+ "n": 1000,
|
|
+ "round": null,
|
|
+ "hash": "0x3333333333333333333333333333333333333333333333333333333333333333",
|
|
+ "commitRoundBlock": 1000,
|
|
+ "bytes": "0xf902d694414552452d50512d5345414c57494e444f572d31826d618203e8a03333333333333333333333333333333333333333333333333333333333333333f90297f9029480b9029039bd3aadc5f485f3f17ab3ef996de30f40a4dbb98f4c70db2fbf505d86835dcfd8e1b067a325d98da059a8597b2e5ee62751d4fd8efc9985223f68c9b2725df62d7af9b091a129944bb0d86464ae20b5bd1c5cf3b29bec1fce23c562d6d8d3ea81215b2a061f05e1ea271c4f5da79f528ae113bb9ba6afdaa1eebb715d3171344fd4bce746d22de14f5a0454a7e371086667b9d586907f6b6969a528ba9ce5ceb7c8cbe30c939b4d76d3eaee2882cc898f374b94355329fae7e6d591e9166d7f71d9c58defb0bcade36ce313d62519c41a7973b149b4f2f8e51d6afd5154eb794343a3acdcc7436e4ff22dda41b236295314daef2a4b98c5343684e20ee7f1f6d27e4a66eaa79ce6a32b2fecf43c43237a40f3545f4af5f6d93109d8e15da5f28db19eac72f8641d14a079198fdf9f8ee292b2d0fc7d3fccd68525dbcfafff2a9d29a3cc361e4674d29e5af5ee408adc0d9725f7939065d0ceef4a4b64c0972943a69739b0aaf57562533888315d7a5d24fa759ed5661454ee58ce491e5f2fcf0d07608f524c50f36cab968c1d8cbee3313a7854744d1cd7e5ac70e20092bab2e5c59736351d014d71af7c19926b232bf1bc36676f81a1a6f7166e97d8e066f6a78d98f13974beed35449f3d9506fab1c0ab356b092273b42d4aedb6cdbedb736e6928fd2d4926b94106fbbf0923e3b759e1fb89ecaf24bea45bd406d509d611550061897b71c39ea3fa6a8f47a50a31849546df90137114491b55ce36fe1d6f64851c8647eb5906d13369b97ab5721a44db1f9d7712aa45c87f5f8b8bef5c92a9f715c432ef6262c8d22af0eb2943e40cda27921cb865b7d79a4b70ec14f7deb96916cc13eeb764a5f3f35189a9bace816de3f88b57aecea4ad102412e121f84ab7474a04d0c0d92526178821f0dce4",
|
|
+ "expected": "dropped: a frame in the wrong form for its height"
|
|
+ }
|
|
+ ],
|
|
+ "VF": [
|
|
+ {
|
|
+ "id": "vf-r0-4-r2-3-q7",
|
|
+ "n": 1000,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "quorum": 7,
|
|
+ "store": [
|
|
+ {
|
|
+ "round": 0,
|
|
+ "heard": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3
|
|
+ ],
|
|
+ "verified": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "round": 2,
|
|
+ "heard": [
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ],
|
|
+ "verified": [
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ }
|
|
+ ],
|
|
+ "expected": {
|
|
+ "sealForm": "anchor-round",
|
|
+ "finality": "partial",
|
|
+ "decidedRound": null,
|
|
+ "recordRound": 0,
|
|
+ "falconSealsVerified": 4,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3
|
|
+ ],
|
|
+ "rounds": [
|
|
+ {
|
|
+ "round": 0,
|
|
+ "falconSealsHeard": 4,
|
|
+ "falconSealsVerified": 4,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "round": 2,
|
|
+ "falconSealsHeard": 3,
|
|
+ "falconSealsVerified": 3,
|
|
+ "verifiedIndexes": [
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ }
|
|
+ ]
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vf-r0-4-r2-7-q7",
|
|
+ "n": 1000,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "quorum": 7,
|
|
+ "store": [
|
|
+ {
|
|
+ "round": 0,
|
|
+ "heard": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3
|
|
+ ],
|
|
+ "verified": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "round": 2,
|
|
+ "heard": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ],
|
|
+ "verified": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ }
|
|
+ ],
|
|
+ "expected": {
|
|
+ "sealForm": "anchor-round",
|
|
+ "finality": "post-quantum",
|
|
+ "decidedRound": 2,
|
|
+ "recordRound": 2,
|
|
+ "falconSealsVerified": 7,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ],
|
|
+ "rounds": [
|
|
+ {
|
|
+ "round": 0,
|
|
+ "falconSealsHeard": 4,
|
|
+ "falconSealsVerified": 4,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "round": 2,
|
|
+ "falconSealsHeard": 7,
|
|
+ "falconSealsVerified": 7,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ }
|
|
+ ]
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vf-r0-7-r1-7-q7",
|
|
+ "n": 1000,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "quorum": 7,
|
|
+ "store": [
|
|
+ {
|
|
+ "round": 1,
|
|
+ "heard": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ],
|
|
+ "verified": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "round": 0,
|
|
+ "heard": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 9
|
|
+ ],
|
|
+ "verified": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 9
|
|
+ ]
|
|
+ }
|
|
+ ],
|
|
+ "expected": {
|
|
+ "sealForm": "anchor-round",
|
|
+ "finality": "post-quantum",
|
|
+ "decidedRound": 0,
|
|
+ "recordRound": 0,
|
|
+ "falconSealsVerified": 7,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 9
|
|
+ ],
|
|
+ "rounds": [
|
|
+ {
|
|
+ "round": 0,
|
|
+ "falconSealsHeard": 7,
|
|
+ "falconSealsVerified": 7,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 9
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "round": 1,
|
|
+ "falconSealsHeard": 7,
|
|
+ "falconSealsVerified": 7,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ }
|
|
+ ]
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vf-r1-3-r3-3-egal",
|
|
+ "n": 1000,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "quorum": 7,
|
|
+ "store": [
|
|
+ {
|
|
+ "round": 3,
|
|
+ "heard": [
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ],
|
|
+ "verified": [
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "round": 1,
|
|
+ "heard": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2
|
|
+ ],
|
|
+ "verified": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2
|
|
+ ]
|
|
+ }
|
|
+ ],
|
|
+ "expected": {
|
|
+ "sealForm": "anchor-round",
|
|
+ "finality": "partial",
|
|
+ "decidedRound": null,
|
|
+ "recordRound": 1,
|
|
+ "falconSealsVerified": 3,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2
|
|
+ ],
|
|
+ "rounds": [
|
|
+ {
|
|
+ "round": 1,
|
|
+ "falconSealsHeard": 3,
|
|
+ "falconSealsVerified": 3,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2
|
|
+ ]
|
|
+ },
|
|
+ {
|
|
+ "round": 3,
|
|
+ "falconSealsHeard": 3,
|
|
+ "falconSealsVerified": 3,
|
|
+ "verifiedIndexes": [
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ }
|
|
+ ]
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vf-nimic-auzit",
|
|
+ "n": 1000,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "quorum": 7,
|
|
+ "store": [],
|
|
+ "expected": {
|
|
+ "sealForm": "anchor-round",
|
|
+ "finality": "unavailable",
|
|
+ "decidedRound": null,
|
|
+ "recordRound": null,
|
|
+ "falconSealsVerified": 0,
|
|
+ "verifiedIndexes": [],
|
|
+ "rounds": []
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vf-auzite-neverificate",
|
|
+ "n": 1000,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "quorum": 7,
|
|
+ "store": [
|
|
+ {
|
|
+ "round": 0,
|
|
+ "heard": [
|
|
+ 0,
|
|
+ 1
|
|
+ ],
|
|
+ "verified": []
|
|
+ }
|
|
+ ],
|
|
+ "expected": {
|
|
+ "sealForm": "anchor-round",
|
|
+ "finality": "none",
|
|
+ "decidedRound": null,
|
|
+ "recordRound": 0,
|
|
+ "falconSealsVerified": 0,
|
|
+ "verifiedIndexes": [],
|
|
+ "rounds": [
|
|
+ {
|
|
+ "round": 0,
|
|
+ "falconSealsHeard": 2,
|
|
+ "falconSealsVerified": 0,
|
|
+ "verifiedIndexes": []
|
|
+ }
|
|
+ ]
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vf-sub-hr-4-plus-3",
|
|
+ "n": 998,
|
|
+ "commitRoundBlock": 1000,
|
|
+ "quorum": 7,
|
|
+ "store": [
|
|
+ {
|
|
+ "round": null,
|
|
+ "heard": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ],
|
|
+ "verified": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ }
|
|
+ ],
|
|
+ "expected": {
|
|
+ "sealForm": "anchor",
|
|
+ "finality": "post-quantum",
|
|
+ "falconSealsVerified": 7,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ "id": "vf-hr-nesetat",
|
|
+ "n": 5000,
|
|
+ "commitRoundBlock": null,
|
|
+ "quorum": 7,
|
|
+ "store": [
|
|
+ {
|
|
+ "round": null,
|
|
+ "heard": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ],
|
|
+ "verified": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ }
|
|
+ ],
|
|
+ "expected": {
|
|
+ "sealForm": "anchor",
|
|
+ "finality": "post-quantum",
|
|
+ "falconSealsVerified": 7,
|
|
+ "verifiedIndexes": [
|
|
+ 0,
|
|
+ 1,
|
|
+ 2,
|
|
+ 3,
|
|
+ 4,
|
|
+ 5,
|
|
+ 6
|
|
+ ]
|
|
+ }
|
|
+ }
|
|
+ ]
|
|
+}
|
|
diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java
|
|
index 02ce695006..2b555fa1e1 100644
|
|
--- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java
|
|
+++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java
|
|
@@ -1,39 +1,39 @@
|
|
/*
|
|
* Copyright ConsenSys AG.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
- * found, as section 4(c) requires. The change itself is in patches/0008-aere-pq-aip22.patch.
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0009-aere-pq-seal-judge-snap-cap.patch.
|
|
*/
|
|
package org.hyperledger.besu.ethereum.api.query;
|
|
|
|
import static com.google.common.base.Preconditions.checkArgument;
|
|
import static org.hyperledger.besu.ethereum.api.query.cache.TransactionLogBloomCacher.BLOCKS_PER_BLOOM_CACHE;
|
|
import static org.hyperledger.besu.ethereum.mainnet.feemarket.ExcessBlobGasCalculator.calculateExcessBlobGasForParent;
|
|
import static org.hyperledger.besu.ethereum.trie.pathbased.common.provider.WorldStateQueryParams.withBlockHeaderAndNoUpdateNodeHead;
|
|
|
|
import org.hyperledger.besu.datatypes.Address;
|
|
import org.hyperledger.besu.datatypes.Hash;
|
|
import org.hyperledger.besu.datatypes.LogsBloomFilter;
|
|
import org.hyperledger.besu.datatypes.Wei;
|
|
import org.hyperledger.besu.ethereum.api.ApiConfiguration;
|
|
import org.hyperledger.besu.ethereum.api.ImmutableApiConfiguration;
|
|
import org.hyperledger.besu.ethereum.api.query.cache.TransactionLogBloomCacher;
|
|
import org.hyperledger.besu.ethereum.chain.Blockchain;
|
|
import org.hyperledger.besu.ethereum.chain.TransactionLocation;
|
|
import org.hyperledger.besu.ethereum.core.Block;
|
|
import org.hyperledger.besu.ethereum.core.BlockBody;
|
|
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java
|
|
index 9f86268d42..1a57af38ae 100755
|
|
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java
|
|
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java
|
|
@@ -1,39 +1,39 @@
|
|
/*
|
|
* Copyright contributors to Hyperledger Besu.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
- * found, as section 4(c) requires. The change itself is in patches/0008-aere-pq-aip22.patch.
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0009-aere-pq-seal-judge-snap-cap.patch.
|
|
*/
|
|
package org.hyperledger.besu.ethereum.mainnet;
|
|
|
|
import static org.hyperledger.besu.evm.account.Account.MAX_NONCE;
|
|
import static org.hyperledger.besu.evm.internal.Words.clampedAdd;
|
|
import static org.hyperledger.besu.evm.worldstate.CodeDelegationHelper.hasCodeDelegation;
|
|
|
|
import org.hyperledger.besu.crypto.SECPSignature;
|
|
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
|
import org.hyperledger.besu.datatypes.BlobType;
|
|
import org.hyperledger.besu.datatypes.CodeDelegation;
|
|
import org.hyperledger.besu.datatypes.Hash;
|
|
import org.hyperledger.besu.datatypes.TransactionType;
|
|
import org.hyperledger.besu.datatypes.Wei;
|
|
import org.hyperledger.besu.ethereum.GasLimitCalculator;
|
|
import org.hyperledger.besu.ethereum.core.Transaction;
|
|
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
|
|
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
|
|
import org.hyperledger.besu.evm.account.Account;
|
|
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
|
|
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalsValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalsValidator.java
|
|
index 2f4bff8200..40a05ddc19 100755
|
|
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalsValidator.java
|
|
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalsValidator.java
|
|
@@ -1,39 +1,39 @@
|
|
/*
|
|
* Copyright contributors to Hyperledger Besu.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
- * found, as section 4(c) requires. The change itself is in patches/0008-aere-pq-aip22.patch.
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0009-aere-pq-seal-judge-snap-cap.patch.
|
|
*/
|
|
package org.hyperledger.besu.ethereum.mainnet;
|
|
|
|
import static com.google.common.base.Preconditions.checkArgument;
|
|
|
|
import org.hyperledger.besu.datatypes.Hash;
|
|
import org.hyperledger.besu.ethereum.core.Block;
|
|
import org.hyperledger.besu.ethereum.core.Withdrawal;
|
|
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
public interface WithdrawalsValidator {
|
|
|
|
boolean validateWithdrawals(Optional<List<Withdrawal>> withdrawals);
|
|
|
|
boolean validateWithdrawalsRoot(Block block);
|
|
diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeers.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeers.java
|
|
index 11cc885291..1a9aa54b76 100644
|
|
--- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeers.java
|
|
+++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeers.java
|
|
@@ -1,39 +1,39 @@
|
|
/*
|
|
* Copyright ConsenSys AG.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
- * found, as section 4(c) requires. The change itself is in patches/0008-aere-pq-aip22.patch.
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0009-aere-pq-seal-judge-snap-cap.patch.
|
|
*/
|
|
package org.hyperledger.besu.ethereum.eth.manager;
|
|
|
|
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
import org.hyperledger.besu.ethereum.eth.EthProtocol;
|
|
import org.hyperledger.besu.ethereum.eth.SnapProtocol;
|
|
import org.hyperledger.besu.ethereum.eth.manager.EthPeer.DisconnectCallback;
|
|
import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerSelector;
|
|
import org.hyperledger.besu.ethereum.eth.peervalidation.PeerValidator;
|
|
import org.hyperledger.besu.ethereum.eth.sync.ChainHeadTracker;
|
|
import org.hyperledger.besu.ethereum.eth.sync.SnapServerChecker;
|
|
import org.hyperledger.besu.ethereum.eth.sync.SyncMode;
|
|
import org.hyperledger.besu.ethereum.eth.sync.TrailingPeerRequirements;
|
|
import org.hyperledger.besu.ethereum.forkid.ForkId;
|
|
import org.hyperledger.besu.ethereum.forkid.ForkIdManager;
|
|
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
|
|
import org.hyperledger.besu.ethereum.p2p.peers.Peer;
|
|
import org.hyperledger.besu.ethereum.p2p.peers.PeerId;
|
|
import org.hyperledger.besu.ethereum.p2p.rlpx.RlpxAgent;
|
|
import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection;
|
|
diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/state/SyncState.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/state/SyncState.java
|
|
index 40256dbcb0..a1dd0819fe 100755
|
|
--- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/state/SyncState.java
|
|
+++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/state/SyncState.java
|
|
@@ -1,39 +1,39 @@
|
|
/*
|
|
* Copyright ConsenSys AG.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
- * found, as section 4(c) requires. The change itself is in patches/0008-aere-pq-aip22.patch.
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0009-aere-pq-seal-judge-snap-cap.patch.
|
|
*/
|
|
package org.hyperledger.besu.ethereum.eth.sync.state;
|
|
|
|
import org.hyperledger.besu.datatypes.Address;
|
|
import org.hyperledger.besu.ethereum.chain.Blockchain;
|
|
import org.hyperledger.besu.ethereum.chain.ChainHead;
|
|
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
|
import org.hyperledger.besu.ethereum.core.DefaultSyncStatus;
|
|
import org.hyperledger.besu.ethereum.core.Synchronizer;
|
|
import org.hyperledger.besu.ethereum.core.Synchronizer.InSyncListener;
|
|
import org.hyperledger.besu.ethereum.eth.manager.ChainHeadEstimate;
|
|
import org.hyperledger.besu.ethereum.eth.manager.EthPeer;
|
|
import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
|
|
import org.hyperledger.besu.ethereum.eth.sync.common.checkpoint.Checkpoint;
|
|
import org.hyperledger.besu.ethereum.eth.sync.worldstate.WorldStateDownloadStatus;
|
|
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason;
|
|
import org.hyperledger.besu.plugin.data.SyncStatus;
|
|
import org.hyperledger.besu.plugin.services.BesuEvents.InitialSyncCompletionListener;
|
|
import org.hyperledger.besu.plugin.services.BesuEvents.SyncStatusListener;
|
|
import org.hyperledger.besu.plugin.services.BesuEvents.TTDReachedListener;
|
|
diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/state/SyncStateTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/state/SyncStateTest.java
|
|
index d8498f37fd..ee50e8e7cc 100644
|
|
--- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/state/SyncStateTest.java
|
|
+++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/state/SyncStateTest.java
|
|
@@ -1,39 +1,39 @@
|
|
/*
|
|
* Copyright ConsenSys AG.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
- * found, as section 4(c) requires. The change itself is in patches/0008-aere-pq-aip22.patch.
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0009-aere-pq-seal-judge-snap-cap.patch.
|
|
*/
|
|
package org.hyperledger.besu.ethereum.eth.sync.state;
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat;
|
|
import static org.mockito.ArgumentMatchers.any;
|
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
|
import static org.mockito.Mockito.doReturn;
|
|
import static org.mockito.Mockito.lenient;
|
|
import static org.mockito.Mockito.mock;
|
|
import static org.mockito.Mockito.never;
|
|
import static org.mockito.Mockito.spy;
|
|
import static org.mockito.Mockito.times;
|
|
import static org.mockito.Mockito.verify;
|
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
|
|
|
import org.hyperledger.besu.datatypes.Address;
|
|
import org.hyperledger.besu.datatypes.Hash;
|
|
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
import org.hyperledger.besu.ethereum.core.Block;
|
|
import org.hyperledger.besu.ethereum.core.BlockDataGenerator;
|
|
diff --git a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPInput.java b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPInput.java
|
|
index 7401d1ae50..602a6b7513 100755
|
|
--- a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPInput.java
|
|
+++ b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPInput.java
|
|
@@ -1,39 +1,39 @@
|
|
/*
|
|
* Copyright ConsenSys AG.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
- * found, as section 4(c) requires. The change itself is in patches/0008-aere-pq-aip22.patch.
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0009-aere-pq-seal-judge-snap-cap.patch.
|
|
*/
|
|
package org.hyperledger.besu.ethereum.rlp;
|
|
|
|
import java.math.BigInteger;
|
|
import java.net.InetAddress;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.function.Function;
|
|
|
|
import org.apache.tuweni.bytes.Bytes;
|
|
import org.apache.tuweni.bytes.Bytes32;
|
|
import org.apache.tuweni.bytes.Bytes48;
|
|
import org.apache.tuweni.units.bigints.UInt256;
|
|
import org.apache.tuweni.units.bigints.UInt64;
|
|
|
|
/**
|
|
* An input used to decode data in RLP encoding.
|
|
*
|
|
* <p>An RLP "value" is fundamentally an {@code Item} defined the following way:
|
|
*
|
|
diff --git a/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java b/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java
|
|
index 59c16a5215..3f53751cdb 100644
|
|
--- a/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java
|
|
+++ b/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java
|
|
@@ -1,39 +1,39 @@
|
|
/*
|
|
* Copyright ConsenSys AG.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
- * found, as section 4(c) requires. The change itself is in patches/0008-aere-pq-aip22.patch.
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0009-aere-pq-seal-judge-snap-cap.patch.
|
|
*/
|
|
package org.hyperledger.besu.evm.frame;
|
|
|
|
import static com.google.common.base.Preconditions.checkState;
|
|
import static java.util.Collections.emptySet;
|
|
|
|
import org.hyperledger.besu.collections.undo.UndoSet;
|
|
import org.hyperledger.besu.datatypes.Address;
|
|
import org.hyperledger.besu.datatypes.Log;
|
|
import org.hyperledger.besu.datatypes.VersionedHash;
|
|
import org.hyperledger.besu.datatypes.Wei;
|
|
import org.hyperledger.besu.evm.Code;
|
|
import org.hyperledger.besu.evm.blockhash.BlockHashLookup;
|
|
import org.hyperledger.besu.evm.internal.MemoryEntry;
|
|
import org.hyperledger.besu.evm.internal.OperandStack;
|
|
import org.hyperledger.besu.evm.internal.StorageEntry;
|
|
import org.hyperledger.besu.evm.internal.UnderflowException;
|
|
import org.hyperledger.besu.evm.operation.Operation;
|
|
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
|
|
|
|
diff --git a/evm/src/main/java/org/hyperledger/besu/evm/frame/TxValues.java b/evm/src/main/java/org/hyperledger/besu/evm/frame/TxValues.java
|
|
index f9ad92e1f1..9814ab393d 100644
|
|
--- a/evm/src/main/java/org/hyperledger/besu/evm/frame/TxValues.java
|
|
+++ b/evm/src/main/java/org/hyperledger/besu/evm/frame/TxValues.java
|
|
@@ -1,39 +1,39 @@
|
|
/*
|
|
* Copyright contributors to Hyperledger Besu.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
- * found, as section 4(c) requires. The change itself is in patches/0008-aere-pq-aip22.patch.
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0009-aere-pq-seal-judge-snap-cap.patch.
|
|
*/
|
|
package org.hyperledger.besu.evm.frame;
|
|
|
|
import org.hyperledger.besu.collections.undo.UndoScalar;
|
|
import org.hyperledger.besu.collections.undo.UndoSet;
|
|
import org.hyperledger.besu.collections.undo.UndoTable;
|
|
import org.hyperledger.besu.datatypes.Address;
|
|
import org.hyperledger.besu.datatypes.VersionedHash;
|
|
import org.hyperledger.besu.datatypes.Wei;
|
|
import org.hyperledger.besu.evm.blockhash.BlockHashLookup;
|
|
|
|
import java.util.ArrayDeque;
|
|
import java.util.Deque;
|
|
import java.util.TreeSet;
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
|
|
import com.google.common.collect.TreeBasedTable;
|
|
import org.apache.tuweni.bytes.Bytes32;
|
|
|
|
diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/P256VerifyPrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/P256VerifyPrecompiledContract.java
|
|
index fe0b01a825..ef31095fc0 100644
|
|
--- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/P256VerifyPrecompiledContract.java
|
|
+++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/P256VerifyPrecompiledContract.java
|
|
@@ -1,39 +1,39 @@
|
|
/*
|
|
* Copyright contributors to Besu.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Modifications Copyright contributors to the Aere Network.
|
|
*
|
|
* This file was modified by contributors to the Aere Network, as required by section 4(b) of the
|
|
* Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was
|
|
- * found, as section 4(c) requires. The change itself is in patches/0008-aere-pq-aip22.patch.
|
|
+ * found, as section 4(c) requires. The change itself is in patches/0009-aere-pq-seal-judge-snap-cap.patch.
|
|
*/
|
|
package org.hyperledger.besu.evm.precompile;
|
|
|
|
import org.hyperledger.besu.crypto.SECP256R1;
|
|
import org.hyperledger.besu.crypto.SECPPublicKey;
|
|
import org.hyperledger.besu.crypto.SECPSignature;
|
|
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
|
import org.hyperledger.besu.evm.frame.MessageFrame;
|
|
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
|
|
import org.hyperledger.besu.nativelib.boringssl.BoringSSLPrecompiles;
|
|
|
|
import java.math.BigInteger;
|
|
|
|
import com.github.benmanes.caffeine.cache.Cache;
|
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
|
import jakarta.validation.constraints.NotNull;
|
|
import org.apache.tuweni.bytes.Bytes;
|
|
import org.apache.tuweni.bytes.Bytes32;
|
|
import org.bouncycastle.asn1.sec.SECNamedCurves;
|
|
import org.bouncycastle.asn1.x9.X9ECParameters;
|